/* Fake variable for stack pointer. */
tree frame_base_decl;
+/* Stack adjust caused by function prologue. */
+static HOST_WIDE_INT frame_stack_adjust;
+
/* Local function prototypes. */
static void stack_adjust_offset_pre_post (rtx, HOST_WIDE_INT *,
HOST_WIDE_INT *);
static int variable_union (void **, void *);
static void dataflow_set_union (dataflow_set *, dataflow_set *);
static bool variable_part_different_p (variable_part *, variable_part *);
-static bool variable_different_p (variable, variable);
+static bool variable_different_p (variable, variable, bool);
static int dataflow_set_different_1 (void **, void *);
static int dataflow_set_different_2 (void **, void *);
static bool dataflow_set_different (dataflow_set *, dataflow_set *);
else
*post -= INTVAL (XEXP (src, 1));
}
- else if (GET_CODE (dest) == MEM)
+ else if (MEM_P (dest))
{
/* (set (mem (pre_dec (reg sp))) (foo)) */
src = XEXP (dest, 0);
offset += VTI (bb)->mos[i].u.adjust;
else if (VTI (bb)->mos[i].type != MO_CALL)
{
- if (GET_CODE (VTI (bb)->mos[i].u.loc) == MEM)
+ if (MEM_P (VTI (bb)->mos[i].u.loc))
{
VTI (bb)->mos[i].u.loc
= adjust_stack_reference (VTI (bb)->mos[i].u.loc, -offset);
VTI (bb)->out.stack_adjust = offset;
}
-/* Compute stack adjustment caused by function prolog. */
+/* Compute stack adjustment caused by function prologue. */
static HOST_WIDE_INT
prologue_stack_adjust (void)
end = NEXT_INSN (BB_END (bb));
for (insn = BB_HEAD (bb); insn != end; insn = NEXT_INSN (insn))
{
- if (GET_CODE (insn) == NOTE
+ if (NOTE_P (insn)
&& NOTE_LINE_NUMBER (insn) == NOTE_INSN_PROLOGUE_END)
break;
/* Initialize entry block. */
VTI (ENTRY_BLOCK_PTR)->visited = true;
- VTI (ENTRY_BLOCK_PTR)->out.stack_adjust = 0;
+ VTI (ENTRY_BLOCK_PTR)->out.stack_adjust = frame_stack_adjust;
/* Allocate stack for back-tracking up CFG. */
stack = xmalloc ((n_basic_blocks + 1) * sizeof (edge));
rtx adjusted_mem;
rtx tmp;
+ if (adjustment == 0)
+ return mem;
+
adjusted_mem = copy_rtx (mem);
XEXP (adjusted_mem, 0) = replace_rtx (XEXP (adjusted_mem, 0),
stack_pointer_rtx,
node2 = dst->var_part[j].loc_chain; node && node2;
node = node->next, node2 = node2->next)
{
- if (!((GET_CODE (node2->loc) == REG
- && GET_CODE (node->loc) == REG
+ if (!((REG_P (node2->loc)
+ && REG_P (node->loc)
&& REGNO (node2->loc) == REGNO (node->loc))
|| rtx_equal_p (node2->loc, node->loc)))
break;
/* Find location from NODE. */
for (jj = 0; jj < dst_l; jj++)
{
- if ((GET_CODE (vui[jj].lc->loc) == REG
- && GET_CODE (node->loc) == REG
+ if ((REG_P (vui[jj].lc->loc)
+ && REG_P (node->loc)
&& REGNO (vui[jj].lc->loc) == REGNO (node->loc))
|| rtx_equal_p (vui[jj].lc->loc, node->loc))
{
{
for (lc2 = vp2->loc_chain; lc2; lc2 = lc2->next)
{
- if (GET_CODE (lc1->loc) == REG && GET_CODE (lc2->loc) == REG)
+ if (REG_P (lc1->loc) && REG_P (lc2->loc))
{
if (REGNO (lc1->loc) == REGNO (lc2->loc))
break;
return false;
}
-/* Return true if variables VAR1 and VAR2 are different (only the first
- location in the list of locations is checked for each offset,
- i.e. when true is returned a note should be emitted). */
+/* Return true if variables VAR1 and VAR2 are different.
+ If COMPARE_CURRENT_LOCATION is true compare also the cur_loc of each
+ variable part. */
static bool
-variable_different_p (variable var1, variable var2)
+variable_different_p (variable var1, variable var2,
+ bool compare_current_location)
{
int i;
{
if (var1->var_part[i].offset != var2->var_part[i].offset)
return true;
+ if (compare_current_location)
+ {
+ if (!((REG_P (var1->var_part[i].cur_loc)
+ && REG_P (var2->var_part[i].cur_loc)
+ && (REGNO (var1->var_part[i].cur_loc)
+ == REGNO (var2->var_part[i].cur_loc)))
+ || rtx_equal_p (var1->var_part[i].cur_loc,
+ var2->var_part[i].cur_loc)))
+ return true;
+ }
if (variable_part_different_p (&var1->var_part[i], &var2->var_part[i]))
return true;
if (variable_part_different_p (&var2->var_part[i], &var1->var_part[i]))
return 0;
}
- if (variable_different_p (var1, var2))
+ if (variable_different_p (var1, var2, false))
{
dataflow_set_different_value = true;
#ifdef ENABLE_CHECKING
/* If both variables are defined they have been already checked for
equivalence. */
- if (variable_different_p (var1, var2))
+ if (variable_different_p (var1, var2, false))
abort ();
#endif
extern char **_dl_argv_internal __attribute__ ((alias ("_dl_argv")));
char **_dl_argv;
*/
- if (GET_CODE (decl_rtl) == MEM
+ if (MEM_P (decl_rtl)
&& contains_symbol_ref (XEXP (decl_rtl, 0)))
return 0;
/* If RTX is a memory it should not be very large (because it would be
an array or struct). */
- if (GET_CODE (decl_rtl) == MEM)
+ if (MEM_P (decl_rtl))
{
/* Do not track structures and arrays. */
if (GET_MODE (decl_rtl) == BLKmode)
{
basic_block bb = BLOCK_FOR_INSN ((rtx) insn);
- if (GET_CODE (*loc) == REG)
+ if (REG_P (*loc))
{
#ifdef ENABLE_CHECKING
if (REGNO (*loc) >= FIRST_PSEUDO_REGISTER)
#endif
VTI (bb)->n_mos++;
}
- else if (GET_CODE (*loc) == MEM
+ else if (MEM_P (*loc)
&& MEM_EXPR (*loc)
&& track_expr_p (MEM_EXPR (*loc)))
{
static int
add_uses (rtx *loc, void *insn)
{
- if (GET_CODE (*loc) == REG)
+ if (REG_P (*loc))
{
basic_block bb = BLOCK_FOR_INSN ((rtx) insn);
micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
mo->u.loc = *loc;
mo->insn = (rtx) insn;
}
- else if (GET_CODE (*loc) == MEM
+ else if (MEM_P (*loc)
&& MEM_EXPR (*loc)
&& track_expr_p (MEM_EXPR (*loc)))
{
static void
add_stores (rtx loc, rtx expr, void *insn)
{
- if (GET_CODE (loc) == REG)
+ if (REG_P (loc))
{
basic_block bb = BLOCK_FOR_INSN ((rtx) insn);
micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
mo->u.loc = loc;
mo->insn = (rtx) insn;
}
- else if (GET_CODE (loc) == MEM
+ else if (MEM_P (loc)
&& MEM_EXPR (loc)
&& track_expr_p (MEM_EXPR (loc)))
{
{
rtx loc = VTI (bb)->mos[i].u.loc;
- if (GET_CODE (loc) == REG)
+ if (REG_P (loc))
var_reg_delete_and_set (out, loc);
- else if (GET_CODE (loc) == MEM)
+ else if (MEM_P (loc))
var_mem_delete_and_set (out, loc);
}
break;
{
rtx loc = VTI (bb)->mos[i].u.loc;
- if (GET_CODE (loc) == REG)
+ if (REG_P (loc))
var_reg_delete (out, loc);
- else if (GET_CODE (loc) == MEM)
+ else if (MEM_P (loc))
var_mem_delete (out, loc);
}
break;
rtx base;
out->stack_adjust += VTI (bb)->mos[i].u.adjust;
- base = gen_rtx_MEM (Pmode,
- gen_rtx_PLUS (Pmode, stack_pointer_rtx,
- GEN_INT (out->stack_adjust)));
+ base = gen_rtx_MEM (Pmode, plus_constant (stack_pointer_rtx,
+ out->stack_adjust));
set_frame_base_location (out, base);
}
break;
in_worklist = sbitmap_alloc (last_basic_block);
in_pending = sbitmap_alloc (last_basic_block);
sbitmap_zero (in_worklist);
- sbitmap_zero (in_pending);
FOR_EACH_BB (bb)
- {
- fibheap_insert (pending, bb_order[bb->index], bb);
- SET_BIT (in_pending, bb->index);
- }
+ fibheap_insert (pending, bb_order[bb->index], bb);
+ sbitmap_ones (in_pending);
while (!fibheap_empty (pending))
{
}
/* Set the location of frame_base_decl to LOC in dataflow set SET. This
- function expects that
- frame_base_decl has already one location for offset 0 in the variable table.
- */
+ function expects that frame_base_decl has already one location for offset 0
+ in the variable table. */
static void
set_frame_base_location (dataflow_set *set, rtx loc)
node = var->var_part[pos].loc_chain;
if (node
- && ((GET_CODE (node->loc) == REG && GET_CODE (loc) == REG
+ && ((REG_P (node->loc) && REG_P (loc)
&& REGNO (node->loc) == REGNO (loc))
|| rtx_equal_p (node->loc, loc)))
{
for (node = var->var_part[pos].loc_chain; node; node = next)
{
next = node->next;
- if ((GET_CODE (node->loc) == REG && GET_CODE (loc) == REG
+ if ((REG_P (node->loc) && REG_P (loc)
&& REGNO (node->loc) == REGNO (loc))
|| rtx_equal_p (node->loc, loc))
{
for (node = var->var_part[pos].loc_chain; node;
node = node->next)
{
- if ((GET_CODE (node->loc) == REG && GET_CODE (loc) == REG
+ if ((REG_P (node->loc) && REG_P (loc)
&& REGNO (node->loc) == REGNO (loc))
|| rtx_equal_p (node->loc, loc))
{
for (node = *nextp; node; node = next)
{
next = node->next;
- if ((GET_CODE (node->loc) == REG && GET_CODE (loc) == REG
+ if ((REG_P (node->loc) && REG_P (loc)
&& REGNO (node->loc) == REGNO (loc))
|| rtx_equal_p (node->loc, loc))
{
we have to emit new location so add the variable to set
of changed variables. */
if (var->var_part[pos].cur_loc
- && ((GET_CODE (loc) == REG
- && GET_CODE (var->var_part[pos].cur_loc) == REG
+ && ((REG_P (loc)
+ && REG_P (var->var_part[pos].cur_loc)
&& REGNO (loc) == REGNO (var->var_part[pos].cur_loc))
|| rtx_equal_p (loc, var->var_part[pos].cur_loc)))
{
empty_var->n_var_parts = 0;
variable_was_changed (empty_var, NULL);
}
- else if (variable_different_p (old_var, new_var))
+ else if (variable_different_p (old_var, new_var, true))
{
variable_was_changed (new_var, NULL);
}
{
rtx loc = VTI (bb)->mos[i].u.loc;
- if (GET_CODE (loc) == REG)
+ if (REG_P (loc))
var_reg_delete_and_set (&set, loc);
else
var_mem_delete_and_set (&set, loc);
{
rtx loc = VTI (bb)->mos[i].u.loc;
- if (GET_CODE (loc) == REG)
+ if (REG_P (loc))
var_reg_delete (&set, loc);
else
var_mem_delete (&set, loc);
rtx base;
set.stack_adjust += VTI (bb)->mos[i].u.adjust;
- base = gen_rtx_MEM (Pmode,
- gen_rtx_PLUS (Pmode, stack_pointer_rtx,
- GEN_INT (set.stack_adjust)));
+ base = gen_rtx_MEM (Pmode, plus_constant (stack_pointer_rtx,
+ set.stack_adjust));
set_frame_base_location (&set, base);
emit_notes_for_changes (insn, EMIT_NOTE_AFTER_INSN);
}
static bool
vt_get_decl_and_offset (rtx rtl, tree *declp, HOST_WIDE_INT *offsetp)
{
- if (GET_CODE (rtl) == REG)
+ if (REG_P (rtl))
{
if (REG_ATTRS (rtl))
{
return true;
}
}
- else if (GET_CODE (rtl) == MEM)
+ else if (MEM_P (rtl))
{
if (MEM_ATTRS (rtl))
{
vt_add_function_parameters (void)
{
tree parm;
- HOST_WIDE_INT stack_adjust = 0;
- if (!frame_pointer_needed)
- stack_adjust = prologue_stack_adjust ();
-
for (parm = DECL_ARGUMENTS (current_function_decl);
parm; parm = TREE_CHAIN (parm))
{
#endif
incoming = eliminate_regs (incoming, 0, NULL_RTX);
- if (!frame_pointer_needed && GET_CODE (incoming) == MEM)
- incoming = adjust_stack_reference (incoming, -stack_adjust);
out = &VTI (ENTRY_BLOCK_PTR)->out;
- if (GET_CODE (incoming) == REG)
+ if (REG_P (incoming))
{
#ifdef ENABLE_CHECKING
if (REGNO (incoming) >= FIRST_PSEUDO_REGISTER)
parm, offset, incoming);
set_variable_part (out, incoming, parm, offset);
}
- else if (GET_CODE (incoming) == MEM)
+ else if (MEM_P (incoming))
{
set_variable_part (out, incoming, parm, offset);
}
}
note_uses (&PATTERN (insn), count_uses_1, insn);
note_stores (PATTERN (insn), count_stores, insn);
- if (GET_CODE (insn) == CALL_INSN)
+ if (CALL_P (insn))
VTI (bb)->n_mos++;
}
}
}
}
- if (GET_CODE (insn) == CALL_INSN)
+ if (CALL_P (insn))
{
micro_operation *mo = VTI (bb)->mos + VTI (bb)->n_mos++;
DECL_ARTIFICIAL (frame_base_decl) = 1;
/* Set its initial "location". */
- base = gen_rtx_MEM (Pmode, stack_pointer_rtx);
+ frame_stack_adjust = -prologue_stack_adjust ();
+ base = gen_rtx_MEM (Pmode, plus_constant (stack_pointer_rtx,
+ frame_stack_adjust));
set_variable_part (&VTI (ENTRY_BLOCK_PTR)->out, base, frame_base_decl, 0);
}
else