current function performs nonlocal memory memory references for the
purposes of marking the function as a constant function. */
-static GTY(()) varray_type reg_base_value;
+static GTY(()) VEC(rtx,gc) *reg_base_value;
static rtx *new_reg_base_value;
/* We preserve the copy of old array around to avoid amount of garbage
produced. About 8% of garbage produced were attributed to this
array. */
-static GTY((deletable)) varray_type old_reg_base_value;
+static GTY((deletable)) VEC(rtx,gc) *old_reg_base_value;
/* Static hunks of RTL used by the aliasing code; these are initialized
once per function to avoid unnecessary RTL allocations. */
static GTY (()) rtx static_reg_base_value[FIRST_PSEUDO_REGISTER];
-#define REG_BASE_VALUE(X) \
- (reg_base_value && REGNO (X) < VARRAY_SIZE (reg_base_value) \
- ? VARRAY_RTX (reg_base_value, REGNO (X)) : 0)
-
-/* Vector of known invariant relationships between registers. Set in
- loop unrolling. Indexed by register number, if nonzero the value
- is an expression describing this register in terms of another.
-
- The length of this array is REG_BASE_VALUE_SIZE.
-
- Because this array contains only pseudo registers it has no effect
- after reload. */
-static GTY((length("alias_invariant_size"))) rtx *alias_invariant;
-static GTY(()) unsigned int alias_invariant_size;
+#define REG_BASE_VALUE(X) \
+ (REGNO (X) < VEC_length (rtx, reg_base_value) \
+ ? VEC_index (rtx, reg_base_value, REGNO (X)) : 0)
/* Vector indexed by N giving the initial (unchanging) value known for
pseudo-register N. This array is initialized in init_alias_analysis,
NOTE_INSN_FUNCTION_BEG note. */
static bool copying_arguments;
+DEF_VEC_P(alias_set_entry);
+DEF_VEC_ALLOC_P(alias_set_entry,gc);
+
/* The splay-tree used to store the various alias set entries. */
-static GTY ((param_is (struct alias_set_entry))) varray_type alias_sets;
+static GTY (()) VEC(alias_set_entry,gc) *alias_sets;
\f
/* Returns a pointer to the alias set entry for ALIAS_SET, if there is
such an entry, or NULL otherwise. */
static inline alias_set_entry
get_alias_set_entry (HOST_WIDE_INT alias_set)
{
- return (alias_set_entry)VARRAY_GENERIC_PTR (alias_sets, alias_set);
+ return VEC_index (alias_set_entry, alias_sets, alias_set);
}
/* Returns nonzero if the alias sets for MEM1 and MEM2 are such that
/* Return a brand-new alias set. */
-static GTY(()) HOST_WIDE_INT last_alias_set;
-
HOST_WIDE_INT
new_alias_set (void)
{
if (flag_strict_aliasing)
{
- if (!alias_sets)
- VARRAY_GENERIC_PTR_INIT (alias_sets, 10, "alias sets");
- else
- VARRAY_GROW (alias_sets, last_alias_set + 2);
- return ++last_alias_set;
+ if (alias_sets == 0)
+ VEC_safe_push (alias_set_entry, gc, alias_sets, 0);
+ VEC_safe_push (alias_set_entry, gc, alias_sets, 0);
+ return VEC_length (alias_set_entry, alias_sets) - 1;
}
else
return 0;
superset_entry->children
= splay_tree_new_ggc (splay_tree_compare_ints);
superset_entry->has_zero_child = 0;
- VARRAY_GENERIC_PTR (alias_sets, superset) = superset_entry;
+ VEC_replace (alias_set_entry, alias_sets, superset, superset_entry);
}
if (subset == 0)
The test above is not sufficient because the scheduler may move
a copy out of an arg reg past the NOTE_INSN_FUNCTION_BEGIN. */
if ((regno >= FIRST_PSEUDO_REGISTER || fixed_regs[regno])
- && regno < VARRAY_SIZE (reg_base_value))
+ && regno < VEC_length (rtx, reg_base_value))
{
/* If we're inside init_alias_analysis, use new_reg_base_value
to reduce the number of relaxation iterations. */
&& REG_N_SETS (regno) == 1)
return new_reg_base_value[regno];
- if (VARRAY_RTX (reg_base_value, regno))
- return VARRAY_RTX (reg_base_value, regno);
+ if (VEC_index (rtx, reg_base_value, regno))
+ return VEC_index (rtx, reg_base_value, regno);
}
return 0;
regno = REGNO (dest);
- gcc_assert (regno < VARRAY_SIZE (reg_base_value));
+ gcc_assert (regno < VEC_length (rtx, reg_base_value));
/* If this spans multiple hard registers, then we must indicate that every
register has an unusable value. */
reg_seen[regno] = 1;
}
-/* Called from loop optimization when a new pseudo-register is
- created. It indicates that REGNO is being set to VAL. f INVARIANT
- is true then this value also describes an invariant relationship
- which can be used to deduce that two registers with unknown values
- are different. */
-
-void
-record_base_value (unsigned int regno, rtx val, int invariant)
-{
- if (invariant && alias_invariant && regno < alias_invariant_size)
- alias_invariant[regno] = val;
-
- if (regno >= VARRAY_SIZE (reg_base_value))
- VARRAY_GROW (reg_base_value, max_reg_num ());
-
- if (REG_P (val))
- {
- VARRAY_RTX (reg_base_value, regno)
- = REG_BASE_VALUE (val);
- return;
- }
- VARRAY_RTX (reg_base_value, regno)
- = find_base_value (val);
-}
-
/* Clear alias info for a register. This is used if an RTL transformation
changes the value of a register. This is used in flow by AUTO_INC_DEC
optimizations. We don't need to clear reg_base_value, since flow only
return memrefs_conflict_p (xsize, x0, ysize, y0, c);
}
- case REG:
- /* Are these registers known not to be equal? */
- if (alias_invariant)
- {
- unsigned int r_x = REGNO (x), r_y = REGNO (y);
- rtx i_x, i_y; /* invariant relationships of X and Y */
-
- i_x = r_x >= alias_invariant_size ? 0 : alias_invariant[r_x];
- i_y = r_y >= alias_invariant_size ? 0 : alias_invariant[r_y];
-
- if (i_x == 0 && i_y == 0)
- break;
-
- if (! memrefs_conflict_p (xsize, i_x ? i_x : x,
- ysize, i_y ? i_y : y, c))
- return 0;
- }
- break;
-
default:
break;
}
reg_known_value = ggc_calloc (reg_known_value_size, sizeof (rtx));
reg_known_equiv_p = xcalloc (reg_known_value_size, sizeof (bool));
- /* Overallocate reg_base_value to allow some growth during loop
- optimization. Loop unrolling can create a large number of
- registers. */
+ /* If we have memory allocated from the previous run, use it. */
if (old_reg_base_value)
- {
- reg_base_value = old_reg_base_value;
- /* If varray gets large zeroing cost may get important. */
- if (VARRAY_SIZE (reg_base_value) > 256
- && VARRAY_SIZE (reg_base_value) > 4 * maxreg)
- VARRAY_GROW (reg_base_value, maxreg);
- VARRAY_CLEAR (reg_base_value);
- if (VARRAY_SIZE (reg_base_value) < maxreg)
- VARRAY_GROW (reg_base_value, maxreg);
- }
- else
- {
- VARRAY_RTX_INIT (reg_base_value, maxreg, "reg_base_value");
- }
+ reg_base_value = old_reg_base_value;
+
+ if (reg_base_value)
+ VEC_truncate (rtx, reg_base_value, 0);
+
+ VEC_safe_grow (rtx, gc, reg_base_value, maxreg);
+ memset (VEC_address (rtx, reg_base_value), 0,
+ sizeof (rtx) * VEC_length (rtx, reg_base_value));
- new_reg_base_value = xmalloc (maxreg * sizeof (rtx));
- reg_seen = xmalloc (maxreg);
+ new_reg_base_value = XNEWVEC (rtx, maxreg);
+ reg_seen = XNEWVEC (char, maxreg);
/* The basic idea is that each pass through this loop will use the
"constant" information from the previous pass to propagate alias
for (ui = 0; ui < maxreg; ui++)
{
if (new_reg_base_value[ui]
- && new_reg_base_value[ui] != VARRAY_RTX (reg_base_value, ui)
+ && new_reg_base_value[ui] != VEC_index (rtx, reg_base_value, ui)
&& ! rtx_equal_p (new_reg_base_value[ui],
- VARRAY_RTX (reg_base_value, ui)))
+ VEC_index (rtx, reg_base_value, ui)))
{
- VARRAY_RTX (reg_base_value, ui) = new_reg_base_value[ui];
+ VEC_replace (rtx, reg_base_value, ui, new_reg_base_value[ui]);
changed = 1;
}
}
pass++;
for (ui = 0; ui < maxreg; ui++)
{
- rtx base = VARRAY_RTX (reg_base_value, ui);
+ rtx base = VEC_index (rtx, reg_base_value, ui);
if (base && REG_P (base))
{
unsigned int base_regno = REGNO (base);
if (base_regno == ui) /* register set from itself */
- VARRAY_RTX (reg_base_value, ui) = 0;
+ VEC_replace (rtx, reg_base_value, ui, 0);
else
- VARRAY_RTX (reg_base_value, ui)
- = VARRAY_RTX (reg_base_value, base_regno);
+ VEC_replace (rtx, reg_base_value, ui,
+ VEC_index (rtx, reg_base_value, base_regno));
changed = 1;
}
}
reg_known_value_size = 0;
free (reg_known_equiv_p);
reg_known_equiv_p = 0;
- if (alias_invariant)
- {
- ggc_free (alias_invariant);
- alias_invariant = 0;
- alias_invariant_size = 0;
- }
-}
-\f
-/* Do control and data flow analysis; write some of the results to the
- dump file. */
-static void
-rest_of_handle_cfg (void)
-{
- if (dump_file)
- dump_flow_info (dump_file);
- if (optimize)
- cleanup_cfg (CLEANUP_EXPENSIVE
- | (flag_thread_jumps ? CLEANUP_THREADING : 0));
}
-struct tree_opt_pass pass_cfg =
-{
- "cfg", /* name */
- NULL, /* gate */
- rest_of_handle_cfg, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_FLOW, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_dump_func, /* todo_flags_finish */
- 'f' /* letter */
-};
-
-
#include "gt-alias.h"