156 lines
5.8 KiB
Diff
156 lines
5.8 KiB
Diff
2011-09-06 Jakub Jelinek <jakub@redhat.com>
|
|
|
|
PR debug/50299
|
|
* calls.c (load_register_parameters): Use use_reg_mode instead
|
|
of use_reg when adding a single register CALL_INSN_FUNCTION_USAGE
|
|
entry.
|
|
(expand_call): Set EXPR_LIST mode to TYPE_MODE of the argument
|
|
for stack CALL_INSN_FUNCTION_USAGE uses.
|
|
* expr.h (use_reg_mode): New prototype.
|
|
(use_reg): Changed into inline around use_reg_mode.
|
|
* expr.c (use_reg): Renamed to...
|
|
(use_reg_mode): ... this. Added MODE argument, set EXPR_LIST
|
|
mode to that mode instead of VOIDmode.
|
|
* var-tracking.c (prepare_call_arguments): Don't track parameters
|
|
whose EXPR_LIST mode is VOIDmode, BLKmode or X mode isn't convertible
|
|
to it using lowpart_subreg. Convert VALUE and REG/MEM to the
|
|
EXPR_LIST mode.
|
|
|
|
--- gcc/calls.c.jj 2011-08-22 08:17:07.000000000 +0200
|
|
+++ gcc/calls.c 2011-09-05 19:47:47.000000000 +0200
|
|
@@ -1756,7 +1756,8 @@ load_register_parameters (struct arg_dat
|
|
if (GET_CODE (reg) == PARALLEL)
|
|
use_group_regs (call_fusage, reg);
|
|
else if (nregs == -1)
|
|
- use_reg (call_fusage, reg);
|
|
+ use_reg_mode (call_fusage, reg,
|
|
+ TYPE_MODE (TREE_TYPE (args[i].tree_value)));
|
|
else if (nregs > 0)
|
|
use_regs (call_fusage, REGNO (reg), nregs);
|
|
}
|
|
@@ -2815,10 +2816,10 @@ expand_call (tree exp, rtx target, int i
|
|
}
|
|
|
|
if (args[i].stack)
|
|
- call_fusage = gen_rtx_EXPR_LIST (VOIDmode,
|
|
- gen_rtx_USE (VOIDmode,
|
|
- args[i].stack),
|
|
- call_fusage);
|
|
+ call_fusage
|
|
+ = gen_rtx_EXPR_LIST (TYPE_MODE (TREE_TYPE (args[i].tree_value)),
|
|
+ gen_rtx_USE (VOIDmode, args[i].stack),
|
|
+ call_fusage);
|
|
}
|
|
|
|
/* If we have a parm that is passed in registers but not in memory
|
|
--- gcc/expr.h.jj 2011-07-27 23:25:36.000000000 +0200
|
|
+++ gcc/expr.h 2011-09-05 18:05:31.000000000 +0200
|
|
@@ -321,8 +321,16 @@ extern void emit_group_store (rtx, rtx,
|
|
/* Copy BLKmode object from a set of registers. */
|
|
extern rtx copy_blkmode_from_reg (rtx, rtx, tree);
|
|
|
|
+/* Mark REG as holding a parameter for the next CALL_INSN.
|
|
+ Mode is TYPE_MODE of the non-promoted parameter, or VOIDmode. */
|
|
+extern void use_reg_mode (rtx *, rtx, enum machine_mode);
|
|
+
|
|
/* Mark REG as holding a parameter for the next CALL_INSN. */
|
|
-extern void use_reg (rtx *, rtx);
|
|
+static inline void
|
|
+use_reg (rtx *fusage, rtx reg)
|
|
+{
|
|
+ use_reg_mode (fusage, reg, VOIDmode);
|
|
+}
|
|
|
|
/* Mark NREGS consecutive regs, starting at REGNO, as holding parameters
|
|
for the next CALL_INSN. */
|
|
--- gcc/expr.c.jj 2011-09-02 16:29:39.000000000 +0200
|
|
+++ gcc/expr.c 2011-09-05 19:47:32.000000000 +0200
|
|
@@ -2184,13 +2184,12 @@ copy_blkmode_from_reg (rtx tgtblk, rtx s
|
|
to by CALL_FUSAGE. REG must denote a hard register. */
|
|
|
|
void
|
|
-use_reg (rtx *call_fusage, rtx reg)
|
|
+use_reg_mode (rtx *call_fusage, rtx reg, enum machine_mode mode)
|
|
{
|
|
gcc_assert (REG_P (reg) && REGNO (reg) < FIRST_PSEUDO_REGISTER);
|
|
|
|
*call_fusage
|
|
- = gen_rtx_EXPR_LIST (VOIDmode,
|
|
- gen_rtx_USE (VOIDmode, reg), *call_fusage);
|
|
+ = gen_rtx_EXPR_LIST (mode, gen_rtx_USE (VOIDmode, reg), *call_fusage);
|
|
}
|
|
|
|
/* Add USE expressions to *CALL_FUSAGE for each of NREGS consecutive regs,
|
|
--- gcc/var-tracking.c.jj 2011-08-30 10:52:41.000000000 +0200
|
|
+++ gcc/var-tracking.c 2011-09-05 19:48:10.000000000 +0200
|
|
@@ -5730,11 +5730,18 @@ prepare_call_arguments (basic_block bb,
|
|
{
|
|
rtx item = NULL_RTX;
|
|
x = XEXP (XEXP (link, 0), 0);
|
|
- if (REG_P (x))
|
|
+ if (GET_MODE (link) == VOIDmode
|
|
+ || GET_MODE (link) == BLKmode
|
|
+ || (GET_MODE (link) != GET_MODE (x)
|
|
+ && (GET_MODE_CLASS (GET_MODE (link)) != MODE_INT
|
|
+ || GET_MODE_CLASS (GET_MODE (x)) != MODE_INT)))
|
|
+ /* Can't do anything for these, if the original type mode
|
|
+ isn't known or can't be converted. */;
|
|
+ else if (REG_P (x))
|
|
{
|
|
cselib_val *val = cselib_lookup (x, GET_MODE (x), 0, VOIDmode);
|
|
if (val && cselib_preserved_value_p (val))
|
|
- item = gen_rtx_CONCAT (GET_MODE (x), x, val->val_rtx);
|
|
+ item = val->val_rtx;
|
|
else if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
|
|
{
|
|
enum machine_mode mode = GET_MODE (x);
|
|
@@ -5749,10 +5756,7 @@ prepare_call_arguments (basic_block bb,
|
|
val = cselib_lookup (reg, mode, 0, VOIDmode);
|
|
if (val && cselib_preserved_value_p (val))
|
|
{
|
|
- item = gen_rtx_CONCAT (GET_MODE (x), x,
|
|
- lowpart_subreg (GET_MODE (x),
|
|
- val->val_rtx,
|
|
- mode));
|
|
+ item = val->val_rtx;
|
|
break;
|
|
}
|
|
}
|
|
@@ -5776,7 +5780,7 @@ prepare_call_arguments (basic_block bb,
|
|
}
|
|
val = cselib_lookup (mem, GET_MODE (mem), 0, VOIDmode);
|
|
if (val && cselib_preserved_value_p (val))
|
|
- item = gen_rtx_CONCAT (GET_MODE (x), copy_rtx (x), val->val_rtx);
|
|
+ item = val->val_rtx;
|
|
else if (GET_MODE_CLASS (GET_MODE (mem)) != MODE_INT)
|
|
{
|
|
/* For non-integer stack argument see also if they weren't
|
|
@@ -5787,15 +5791,22 @@ prepare_call_arguments (basic_block bb,
|
|
val = cselib_lookup (adjust_address_nv (mem, imode, 0),
|
|
imode, 0, VOIDmode);
|
|
if (val && cselib_preserved_value_p (val))
|
|
- item = gen_rtx_CONCAT (GET_MODE (x), copy_rtx (x),
|
|
- lowpart_subreg (GET_MODE (x),
|
|
- val->val_rtx,
|
|
- imode));
|
|
+ item = lowpart_subreg (GET_MODE (x), val->val_rtx,
|
|
+ imode);
|
|
}
|
|
}
|
|
}
|
|
if (item)
|
|
- call_arguments = gen_rtx_EXPR_LIST (VOIDmode, item, call_arguments);
|
|
+ {
|
|
+ rtx x2 = x;
|
|
+ if (GET_MODE (item) != GET_MODE (link))
|
|
+ item = lowpart_subreg (GET_MODE (link), item, GET_MODE (item));
|
|
+ if (GET_MODE (x2) != GET_MODE (link))
|
|
+ x2 = lowpart_subreg (GET_MODE (link), x2, GET_MODE (x2));
|
|
+ item = gen_rtx_CONCAT (GET_MODE (link), x2, item);
|
|
+ call_arguments
|
|
+ = gen_rtx_EXPR_LIST (VOIDmode, item, call_arguments);
|
|
+ }
|
|
if (t && t != void_list_node)
|
|
{
|
|
tree argtype = TREE_VALUE (t);
|