[multiple changes]

2001-01-20  Jakub Jelinek  <jakub@redhat.com>

	* function.c (fixup_var_refs): Move CALL_PLACEHOLDER handling...
	(fixup_var_refs_insns): ...here.

	* gcc.c-torture/compile/20010118-1.c: New test.

2001-01-20  Zack Weinberg  <zack@wolery.stanford.edu>

	* function.c (fixup_var_refs_insns): Break up into
	fixup_var_refs_insn [body of loop], fixup_var_refs_insns
	[loop over entire insn list], and fixup_var_refs_insns_with_hash
	[loop over hash table entries].
	(fixup_var_refs): Adjust calls to fixup_var_refs_insns and/or
	fixup_var_refs_insns_with_hash, to match above changes.

From-SVN: r39151
This commit is contained in:
Zack Weinberg 2001-01-20 09:12:08 +00:00
parent 1b7f6755f9
commit a42a5f59d0
3 changed files with 361 additions and 293 deletions

View File

@ -1,3 +1,19 @@
2001-01-20 Jakub Jelinek <jakub@redhat.com>
* function.c (fixup_var_refs): Move CALL_PLACEHOLDER handling...
(fixup_var_refs_insns): ...here.
* gcc.c-torture/compile/20010118-1.c: New test.
2001-01-20 Zack Weinberg <zack@wolery.stanford.edu>
* function.c (fixup_var_refs_insns): Break up into
fixup_var_refs_insn [body of loop], fixup_var_refs_insns
[loop over entire insn list], and fixup_var_refs_insns_with_hash
[loop over hash table entries].
(fixup_var_refs): Adjust calls to fixup_var_refs_insns and/or
fixup_var_refs_insns_with_hash, to match above changes.
2001-01-19 John David Anglin <dave@hiauly1.hia.nrc.ca>
* Makefile.in (ORDINARY_FLAGS_TO_PASS): Add MAKEOVERRIDES variable.

View File

@ -253,8 +253,13 @@ static void fixup_var_refs PARAMS ((rtx, enum machine_mode, int,
struct hash_table *));
static struct fixup_replacement
*find_fixup_replacement PARAMS ((struct fixup_replacement **, rtx));
static void fixup_var_refs_insns PARAMS ((rtx, enum machine_mode, int,
rtx, int, struct hash_table *));
static void fixup_var_refs_insns PARAMS ((rtx, rtx, enum machine_mode,
int, int));
static void fixup_var_refs_insns_with_hash
PARAMS ((struct hash_table *, rtx,
enum machine_mode, int));
static void fixup_var_refs_insn PARAMS ((rtx, rtx, enum machine_mode,
int, int));
static void fixup_var_refs_1 PARAMS ((rtx, enum machine_mode, rtx *, rtx,
struct fixup_replacement **));
static rtx fixup_memory_subreg PARAMS ((rtx, rtx, int));
@ -1542,21 +1547,25 @@ fixup_var_refs (var, promoted_mode, unsignedp, ht)
rtx first_insn = get_insns ();
struct sequence_stack *stack = seq_stack;
tree rtl_exps = rtl_expr_chain;
rtx insn;
/* Must scan all insns for stack-refs that exceed the limit. */
fixup_var_refs_insns (var, promoted_mode, unsignedp, first_insn,
stack == 0, ht);
/* If there's a hash table, it must record all uses of VAR. */
if (ht)
{
if (stack != 0)
abort ();
fixup_var_refs_insns_with_hash (ht, var, promoted_mode, unsignedp);
return;
}
fixup_var_refs_insns (first_insn, var, promoted_mode, unsignedp,
stack == 0);
/* Scan all pending sequences too. */
for (; stack; stack = stack->next)
{
push_to_full_sequence (stack->first, stack->last);
fixup_var_refs_insns (var, promoted_mode, unsignedp,
stack->first, stack->next != 0, 0);
fixup_var_refs_insns (stack->first, var, promoted_mode, unsignedp,
stack->next != 0);
/* Update remembered end of sequence
in case we added an insn at the end. */
stack->last = get_last_insn ();
@ -1570,40 +1579,15 @@ fixup_var_refs (var, promoted_mode, unsignedp, ht)
if (seq != const0_rtx && seq != 0)
{
push_to_sequence (seq);
fixup_var_refs_insns (var, promoted_mode, unsignedp, seq, 0, 0);
fixup_var_refs_insns (seq, var, promoted_mode, unsignedp, 0);
end_sequence ();
}
}
/* Scan the catch clauses for exception handling too. */
push_to_full_sequence (catch_clauses, catch_clauses_last);
fixup_var_refs_insns (var, promoted_mode, unsignedp, catch_clauses, 0, 0);
fixup_var_refs_insns (catch_clauses, var, promoted_mode, unsignedp, 0);
end_full_sequence (&catch_clauses, &catch_clauses_last);
/* Scan sequences saved in CALL_PLACEHOLDERS too. */
for (insn = first_insn; insn; insn = NEXT_INSN (insn))
{
if (GET_CODE (insn) == CALL_INSN
&& GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
{
int i;
/* Look at the Normal call, sibling call and tail recursion
sequences attached to the CALL_PLACEHOLDER. */
for (i = 0; i < 3; i++)
{
rtx seq = XEXP (PATTERN (insn), i);
if (seq)
{
push_to_sequence (seq);
fixup_var_refs_insns (var, promoted_mode, unsignedp,
seq, 0, 0);
XEXP (PATTERN (insn), i) = get_insns ();
end_sequence ();
}
}
}
}
}
/* REPLACEMENTS is a pointer to a list of the struct fixup_replacement and X is
@ -1638,35 +1622,96 @@ find_fixup_replacement (replacements, x)
main chain of insns for the current function. */
static void
fixup_var_refs_insns (var, promoted_mode, unsignedp, insn, toplevel, ht)
fixup_var_refs_insns (insn, var, promoted_mode, unsignedp, toplevel)
rtx insn;
rtx var;
enum machine_mode promoted_mode;
int unsignedp;
rtx insn;
int toplevel;
struct hash_table *ht;
{
rtx call_dest = 0;
rtx insn_list = NULL_RTX;
/* If we already know which INSNs reference VAR there's no need
to walk the entire instruction chain. */
if (ht)
{
insn_list = ((struct insns_for_mem_entry *)
hash_lookup (ht, var, /*create=*/0, /*copy=*/0))->insns;
insn = insn_list ? XEXP (insn_list, 0) : NULL_RTX;
insn_list = XEXP (insn_list, 1);
}
while (insn)
{
/* fixup_var_refs_insn might modify insn, so save its next
pointer now. */
rtx next = NEXT_INSN (insn);
/* CALL_PLACEHOLDERs are special; we have to switch into each of
the three sequences they (potentially) contain, and process
them recursively. The CALL_INSN itself is not interesting. */
if (GET_CODE (insn) == CALL_INSN
&& GET_CODE (PATTERN (insn)) == CALL_PLACEHOLDER)
{
int i;
/* Look at the Normal call, sibling call and tail recursion
sequences attached to the CALL_PLACEHOLDER. */
for (i = 0; i < 3; i++)
{
rtx seq = XEXP (PATTERN (insn), i);
if (seq)
{
push_to_sequence (seq);
fixup_var_refs_insns (seq, var, promoted_mode, unsignedp, 0);
XEXP (PATTERN (insn), i) = get_insns ();
end_sequence ();
}
}
}
else if (INSN_P (insn))
fixup_var_refs_insn (insn, var, promoted_mode, unsignedp, toplevel);
insn = next;
}
}
/* Look up the insns which reference VAR in HT and fix them up. Other
arguments are the same as fixup_var_refs_insns.
N.B. No need for special processing of CALL_PLACEHOLDERs here,
because the hash table will point straight to the interesting insn
(inside the CALL_PLACEHOLDER). */
static void
fixup_var_refs_insns_with_hash (ht, var, promoted_mode, unsignedp)
struct hash_table *ht;
rtx var;
enum machine_mode promoted_mode;
int unsignedp;
{
struct insns_for_mem_entry *ime = (struct insns_for_mem_entry *)
hash_lookup (ht, var, /*create=*/0, /*copy=*/0);
rtx insn_list = ime->insns;
while (insn_list)
{
rtx insn = XEXP (insn_list, 0);
if (INSN_P (insn))
fixup_var_refs_insn (insn, var, promoted_mode, unsignedp, 0);
insn_list = XEXP (insn_list, 1);
}
}
/* Per-insn processing by fixup_var_refs_insns(_with_hash). INSN is
the insn under examination, VAR is the variable to fix up
references to, PROMOTED_MODE and UNSIGNEDP describe VAR, and
TOPLEVEL is nonzero if this is the main insn chain for this
function. */
static void
fixup_var_refs_insn (insn, var, promoted_mode, unsignedp, toplevel)
rtx insn;
rtx var;
enum machine_mode promoted_mode;
int unsignedp;
int toplevel;
{
rtx call_dest = 0;
rtx set, prev, prev_set;
rtx note;
if (INSN_P (insn))
{
/* Remember the notes in case we delete the insn. */
note = REG_NOTES (insn);
@ -1718,8 +1763,6 @@ fixup_var_refs_insns (var, promoted_mode, unsignedp, insn, toplevel, ht)
PUT_CODE (insn, NOTE);
NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
NOTE_SOURCE_FILE (insn) = 0;
if (insn == last_parm_insn)
last_parm_insn = PREV_INSN (next);
}
else
{
@ -1839,18 +1882,6 @@ fixup_var_refs_insns (var, promoted_mode, unsignedp, insn, toplevel, ht)
= walk_fixup_memory_subreg (XEXP (note, 0), insn, 1);
note = XEXP (note, 1);
}
}
if (!ht)
insn = next;
else if (insn_list)
{
insn = XEXP (insn_list, 0);
insn_list = XEXP (insn_list, 1);
}
else
insn = NULL_RTX;
}
}
/* VAR is a MEM that used to be a pseudo register with mode PROMOTED_MODE.
@ -1861,7 +1892,7 @@ fixup_var_refs_insns (var, promoted_mode, unsignedp, insn, toplevel, ht)
to modify this insn by replacing a memory reference with a pseudo or by
making a new MEM to implement a SUBREG, we consult that list to see if
we have already chosen a replacement. If none has already been allocated,
we allocate it and update the list. fixup_var_refs_insns will copy VAR
we allocate it and update the list. fixup_var_refs_insn will copy VAR
or the SUBREG, as appropriate, to the pseudo. */
static void
@ -4564,7 +4595,7 @@ assign_parms (fndecl)
&& GET_CODE (XEXP (XVECEXP (entry_parm, 0, i), 0)) == REG
&& (GET_MODE (XEXP (XVECEXP (entry_parm, 0, i), 0))
== passed_mode)
&& INTVAL (XEXP (XVECEXP (entry_parm, 0, i), 1)) == 0)
&& XINT (XEXP (XVECEXP (entry_parm, 0, i), 1), 0) == 0)
{
entry_parm = XEXP (XVECEXP (entry_parm, 0, i), 0);
DECL_INCOMING_RTL (parm) = entry_parm;

View File

@ -0,0 +1,21 @@
static unsigned int bar(void *h, unsigned int n)
{
static int i;
return i++;
}
static void baz(unsigned int *x)
{
(*x)++;
}
long
foo(void *h, unsigned int l)
{
unsigned int n;
long m;
n = bar(h, 0);
n = bar(h, n);
m = ({ baz(&n); 21; });
return m;
}