parent
d790221795
commit
af929c62a2
|
@ -110,8 +110,8 @@ gen_insn (insn)
|
|||
for (; i >= 0; i--)
|
||||
if (!operand_seen[i])
|
||||
{
|
||||
printf (" recog_operand[%d] = const0_rtx;\n", i);
|
||||
printf (" recog_operand_loc[%d] = &junk;\n", i);
|
||||
printf (" ro[%d] = const0_rtx;\n", i);
|
||||
printf (" ro_loc[%d] = &junk;\n", i);
|
||||
}
|
||||
printf (" break;\n");
|
||||
}
|
||||
|
@ -158,7 +158,7 @@ walk_rtx (x, path)
|
|||
case MATCH_OPERAND:
|
||||
case MATCH_SCRATCH:
|
||||
mark_operand_seen (XINT (x, 0));
|
||||
printf (" recog_operand[%d] = *(recog_operand_loc[%d]\n = &",
|
||||
printf (" ro[%d] = *(ro_loc[%d] = &",
|
||||
XINT (x, 0), XINT (x, 0));
|
||||
print_path (path);
|
||||
printf (");\n");
|
||||
|
@ -175,7 +175,7 @@ walk_rtx (x, path)
|
|||
|
||||
case MATCH_OPERATOR:
|
||||
mark_operand_seen (XINT (x, 0));
|
||||
printf (" recog_operand[%d] = *(recog_operand_loc[%d]\n = &",
|
||||
printf (" ro[%d] = *(ro_loc[%d]\n = &",
|
||||
XINT (x, 0), XINT (x, 0));
|
||||
print_path (path);
|
||||
printf (");\n");
|
||||
|
@ -190,7 +190,7 @@ walk_rtx (x, path)
|
|||
|
||||
case MATCH_PARALLEL:
|
||||
mark_operand_seen (XINT (x, 0));
|
||||
printf (" recog_operand[%d] = *(recog_operand_loc[%d]\n = &",
|
||||
printf (" ro[%d] = *(ro_loc[%d]\n = &",
|
||||
XINT (x, 0), XINT (x, 0));
|
||||
print_path (path);
|
||||
printf (");\n");
|
||||
|
@ -350,11 +350,14 @@ from the machine description file `md'. */\n\n");
|
|||
printf ("extern rtx *recog_operand_loc[];\n");
|
||||
printf ("extern rtx *recog_dup_loc[];\n");
|
||||
printf ("extern char recog_dup_num[];\n");
|
||||
printf ("extern void fatal_insn_not_found ();\n\n");
|
||||
printf ("extern\n#ifdef __GNUC__\nvolatile\n#endif\n");
|
||||
printf ("void fatal_insn_not_found ();\n\n");
|
||||
|
||||
printf ("void\ninsn_extract (insn)\n");
|
||||
printf (" rtx insn;\n");
|
||||
printf ("{\n");
|
||||
printf (" register rtx *ro = recog_operand;\n");
|
||||
printf (" register rtx **ro_loc = recog_operand_loc;\n");
|
||||
printf (" int insn_code = INSN_CODE (insn);\n");
|
||||
printf (" if (insn_code == -1) fatal_insn_not_found (insn);\n");
|
||||
printf (" insn = PATTERN (insn);\n");
|
||||
|
@ -401,7 +404,7 @@ from the machine description file `md'. */\n\n");
|
|||
printf ("#if __GNUC__ > 1 && !defined (bcopy)\n");
|
||||
printf ("#define bcopy(FROM,TO,COUNT) __builtin_memcpy(TO,FROM,COUNT)\n");
|
||||
printf ("#endif\n");
|
||||
printf (" bcopy (&XVECEXP (insn, 0, 0), recog_operand,\n");
|
||||
printf (" bcopy (&XVECEXP (insn, 0, 0), ro,\n");
|
||||
printf (" sizeof (rtx) * XVECLEN (insn, 0));\n");
|
||||
printf (" break;\n");
|
||||
}
|
||||
|
|
40
gcc/reload.c
40
gcc/reload.c
|
@ -4179,6 +4179,46 @@ copy_replacements (x, y)
|
|||
}
|
||||
}
|
||||
|
||||
/* If LOC was scheduled to be replaced by something, return the replacement.
|
||||
Otherwise, return *LOC. */
|
||||
|
||||
rtx
|
||||
find_replacement (loc)
|
||||
rtx *loc;
|
||||
{
|
||||
struct replacement *r;
|
||||
|
||||
for (r = &replacements[0]; r < &replacements[n_replacements]; r++)
|
||||
{
|
||||
rtx reloadreg = reload_reg_rtx[r->what];
|
||||
|
||||
if (reloadreg && r->where == loc)
|
||||
{
|
||||
if (r->mode != VOIDmode && GET_MODE (reloadreg) != r->mode)
|
||||
reloadreg = gen_rtx (REG, r->mode, REGNO (reloadreg));
|
||||
|
||||
return reloadreg;
|
||||
}
|
||||
else if (reloadreg && r->subreg_loc == loc)
|
||||
{
|
||||
/* RELOADREG must be either a REG or a SUBREG.
|
||||
|
||||
??? Is it actually still ever a SUBREG? If so, why? */
|
||||
|
||||
if (GET_CODE (reloadreg) == REG)
|
||||
return gen_rtx (REG, GET_MODE (*loc),
|
||||
REGNO (reloadreg) + SUBREG_WORD (*loc));
|
||||
else if (GET_MODE (reloadreg) == GET_MODE (*loc))
|
||||
return reloadreg;
|
||||
else
|
||||
return gen_rtx (SUBREG, GET_MODE (*loc), SUBREG_REG (reloadreg),
|
||||
SUBREG_WORD (reloadreg) + SUBREG_WORD (*loc));
|
||||
}
|
||||
}
|
||||
|
||||
return *loc;
|
||||
}
|
||||
|
||||
/* Return nonzero if register in range [REGNO, ENDREGNO)
|
||||
appears either explicitly or implicitly in X
|
||||
other than being stored into.
|
||||
|
|
|
@ -110,3 +110,4 @@ extern void find_reloads ();
|
|||
extern void subst_reloads ();
|
||||
extern rtx eliminate_regs ();
|
||||
extern rtx gen_input_reload ();
|
||||
extern rtx find_replacement ();
|
||||
|
|
|
@ -5428,9 +5428,12 @@ gen_input_reload (reloadreg, in, before_insn)
|
|||
`insn_extract'and it is simpler to emit and then delete the insn if
|
||||
not valid than to dummy things up. */
|
||||
|
||||
rtx move_operand, other_operand, insn;
|
||||
rtx op0, op1, tem, insn;
|
||||
int code;
|
||||
|
||||
op0 = find_replacement (&XEXP (in, 0));
|
||||
op1 = find_replacement (&XEXP (in, 1));
|
||||
|
||||
/* Since constraint checking is strict, commutativity won't be
|
||||
checked, so we need to do that here to avoid spurious failure
|
||||
if the add instruction is two-address and the second operand
|
||||
|
@ -5440,7 +5443,10 @@ gen_input_reload (reloadreg, in, before_insn)
|
|||
|
||||
if (GET_CODE (XEXP (in, 1)) == REG
|
||||
&& REGNO (reloadreg) == REGNO (XEXP (in, 1)))
|
||||
in = gen_rtx (PLUS, GET_MODE (in), XEXP (in, 1), XEXP (in, 0));
|
||||
tem = op0, op0 = op1, op1 = tem;
|
||||
|
||||
if (op0 != XEXP (in, 0) || op1 != XEXP (in, 1))
|
||||
in = gen_rtx (PLUS, GET_MODE (in), op0, op1);
|
||||
|
||||
insn = emit_insn_before (gen_rtx (SET, VOIDmode, reloadreg, in),
|
||||
before_insn);
|
||||
|
@ -5463,23 +5469,20 @@ gen_input_reload (reloadreg, in, before_insn)
|
|||
|
||||
/* If that failed, we must use a conservative two-insn sequence.
|
||||
use move to copy constant, MEM, or pseudo register to the reload
|
||||
register since "move" will be able to handle arbitrary operand, unlike
|
||||
add which can't, in general. Then add the registers.
|
||||
register since "move" will be able to handle an arbitrary operand,
|
||||
unlike add which can't, in general. Then add the registers.
|
||||
|
||||
If there is another way to do this for a specific machine, a
|
||||
DEFINE_PEEPHOLE should be specified that recognizes the sequence
|
||||
we emit below. */
|
||||
|
||||
if (CONSTANT_P (XEXP (in, 1))
|
||||
|| GET_CODE (XEXP (in, 1)) == MEM
|
||||
|| (GET_CODE (XEXP (in, 1)) == REG
|
||||
&& REGNO (XEXP (in, 1)) >= FIRST_PSEUDO_REGISTER))
|
||||
move_operand = XEXP (in, 1), other_operand = XEXP (in, 0);
|
||||
else
|
||||
move_operand = XEXP (in, 0), other_operand = XEXP (in, 1);
|
||||
if (CONSTANT_P (op1) || GET_CODE (op1) == MEM
|
||||
|| (GET_CODE (op1) == REG
|
||||
&& REGNO (op1) >= FIRST_PSEUDO_REGISTER))
|
||||
tem = op0, op0 = op1, op1 = tem;
|
||||
|
||||
emit_insn_before (gen_move_insn (reloadreg, move_operand), before_insn);
|
||||
emit_insn_before (gen_add2_insn (reloadreg, other_operand), before_insn);
|
||||
emit_insn_before (gen_move_insn (reloadreg, op0), before_insn);
|
||||
emit_insn_before (gen_add2_insn (reloadreg, op1), before_insn);
|
||||
}
|
||||
|
||||
/* If IN is a simple operand, use gen_move_insn. */
|
||||
|
|
11
gcc/tree.c
11
gcc/tree.c
|
@ -1742,10 +1742,12 @@ save_expr (expr)
|
|||
|
||||
/* If the tree evaluates to a constant, then we don't want to hide that
|
||||
fact (i.e. this allows further folding, and direct checks for constants).
|
||||
However, a read-only object that has side effects cannot be bypassed.
|
||||
Since it is no problem to reevaluate literals, we just return the
|
||||
literal node. */
|
||||
|
||||
if (TREE_CONSTANT (t) || TREE_READONLY (t) || TREE_CODE (t) == SAVE_EXPR)
|
||||
if (TREE_CONSTANT (t) || (TREE_READONLY (t) && ! TREE_SIDE_EFFECTS (t))
|
||||
|| TREE_CODE (t) == SAVE_EXPR)
|
||||
return t;
|
||||
|
||||
t = build (SAVE_EXPR, TREE_TYPE (expr), t, current_function_decl, NULL);
|
||||
|
@ -1852,7 +1854,12 @@ stabilize_reference_1 (e)
|
|||
register int length;
|
||||
register enum tree_code code = TREE_CODE (e);
|
||||
|
||||
if (TREE_CONSTANT (e) || TREE_READONLY (e) || code == SAVE_EXPR)
|
||||
/* We cannot ignore const expressions because it might be a reference
|
||||
to a const array but whose index contains side-effects. But we can
|
||||
ignore things that are actual constant or that already have been
|
||||
handled by this function. */
|
||||
|
||||
if (TREE_CONSTANT (e) || code == SAVE_EXPR)
|
||||
return e;
|
||||
|
||||
switch (TREE_CODE_CLASS (code))
|
||||
|
|
Loading…
Reference in New Issue