*** empty log message ***

From-SVN: r726
This commit is contained in:
Richard Kenner 1992-04-11 14:17:54 -04:00
parent d790221795
commit af929c62a2
5 changed files with 76 additions and 22 deletions

View File

@ -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");
}

View File

@ -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.

View File

@ -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 ();

View File

@ -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. */

View File

@ -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))