aboutsummaryrefslogtreecommitdiff
path: root/gcc/integrate.c
diff options
context:
space:
mode:
authorGavin Romig-Koch <gavin@cygnus.com>1998-10-01 13:00:21 +0000
committerGavin Romig-Koch <gavin@gcc.gnu.org>1998-10-01 13:00:21 +0000
commitc36fce9a4283f71b9613e1923fbb6cea2c0d64a2 (patch)
tree9b145af594c102bee9b10b504ce7129d9016e08b /gcc/integrate.c
parent38f01e5a57f979f7427e99be377b4717a330cf7a (diff)
downloadgcc-c36fce9a4283f71b9613e1923fbb6cea2c0d64a2.tar.gz
gcc-c36fce9a4283f71b9613e1923fbb6cea2c0d64a2.tar.bz2
gcc-c36fce9a4283f71b9613e1923fbb6cea2c0d64a2.zip
calls.c (expand_call): Encapsulate code into copy_blkmode_from_reg.
* calls.c (expand_call) : Encapsulate code into copy_blkmode_from_reg. * expr.c (copy_blkmode_from_reg): New function. * expr.h (copy_blkmode_from_reg): New function. * integrate.c (function_cannot_inline_p): We can inline these now. (expand_inline_function): Use copy_blkmode_from_reg if needed. Avoid creating BLKmode REGs. (copy_rtx_and_substitute): Don't try to SUBREG a BLKmode object. From-SVN: r22714
Diffstat (limited to 'gcc/integrate.c')
-rw-r--r--gcc/integrate.c32
1 files changed, 25 insertions, 7 deletions
diff --git a/gcc/integrate.c b/gcc/integrate.c
index d3fb05bbbfc..db82e322b06 100644
--- a/gcc/integrate.c
+++ b/gcc/integrate.c
@@ -154,11 +154,6 @@ function_cannot_inline_p (fndecl)
if (current_function_returns_pcc_struct)
return "inline functions not supported for this return value type";
- /* We can't inline functions that return BLKmode structures in registers. */
- if (TYPE_MODE (TREE_TYPE (TREE_TYPE (fndecl))) == BLKmode
- && ! aggregate_value_p (TREE_TYPE (TREE_TYPE (fndecl))))
- return "inline functions not supported for this return value type";
-
/* We can't inline functions that return structures of varying size. */
if (int_size_in_bytes (TREE_TYPE (TREE_TYPE (fndecl))) < 0)
return "function with varying-size return value cannot be inline";
@@ -1804,7 +1799,23 @@ expand_inline_function (fndecl, parms, target, ignore, type,
Let the combiner substitute the MEM if that is valid. */
if (target == 0 || GET_CODE (target) != REG
|| GET_MODE (target) != departing_mode)
+ {
+ /* Don't make BLKmode registers. If this looks like
+ a BLKmode object being returned in a register, get
+ the mode from that, otherwise abort. */
+ if (departing_mode == BLKmode)
+ {
+ if (REG == GET_CODE (DECL_RTL (DECL_RESULT (fndecl))))
+ {
+ departing_mode = GET_MODE (DECL_RTL (DECL_RESULT (fndecl)));
+ arriving_mode = departing_mode;
+ }
+ else
+ abort();
+ }
+
target = gen_reg_rtx (departing_mode);
+ }
/* If function's value was promoted before return,
avoid machine mode mismatch when we substitute INLINE_TARGET.
@@ -2164,6 +2175,12 @@ expand_inline_function (fndecl, parms, target, ignore, type,
emit_line_note (input_filename, lineno);
+ /* If the function returns a BLKmode object in a register, copy it
+ out of the temp register into a BLKmode memory object. */
+ if (TYPE_MODE (TREE_TYPE (TREE_TYPE (fndecl))) == BLKmode
+ && ! aggregate_value_p (TREE_TYPE (TREE_TYPE (fndecl))))
+ target = copy_blkmode_from_reg (0, target, TREE_TYPE (TREE_TYPE (fndecl)));
+
if (structure_value_addr)
{
target = gen_rtx_MEM (TYPE_MODE (type),
@@ -2428,12 +2445,13 @@ copy_rtx_and_substitute (orig, map)
{
/* This is a reference to the function return value. If
the function doesn't have a return value, error. If the
- mode doesn't agree, make a SUBREG. */
+ mode doesn't agree, and it ain't BLKmode, make a SUBREG. */
if (map->inline_target == 0)
/* Must be unrolling loops or replicating code if we
reach here, so return the register unchanged. */
return orig;
- else if (mode != GET_MODE (map->inline_target))
+ else if (GET_MODE (map->inline_target) != BLKmode
+ && mode != GET_MODE (map->inline_target))
return gen_lowpart (mode, map->inline_target);
else
return map->inline_target;