#include "splay-tree.h"
#include "ggc.h"
#include "langhooks.h"
+#include "target.h"
/* The alias sets assigned to MEMs assist the back-end in determining
which MEMs can alias which other MEMs. In general, two MEMs in
current function performs nonlocal memory memory references for the
purposes of marking the function as a constant function. */
-static rtx *reg_base_value;
+static GTY((length ("reg_base_value_size"))) rtx *reg_base_value;
static rtx *new_reg_base_value;
static unsigned int reg_base_value_size; /* size of reg_base_value array */
+/* 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) \
(REGNO (X) < reg_base_value_size \
? reg_base_value[REGNO (X)] : 0)
and references to functions, but that's different.) */
else if (TREE_CODE (t) == FUNCTION_TYPE)
set = 0;
+
+ /* Unless the language specifies otherwise, let vector types alias
+ their components. This avoids some nasty type punning issues in
+ normal usage. And indeed lets vectors be treated more like an
+ array slice. */
+ else if (TREE_CODE (t) == VECTOR_TYPE)
+ set = get_alias_set (TREE_TYPE (t));
+
else
/* Otherwise make a new alias set for this type. */
set = new_alias_set ();
/* If we don't know the size of the lower-offset value, we can't tell
if they conflict. Otherwise, we do the test. */
- return sizex >= 0 && offsety > offsetx + sizex;
+ return sizex >= 0 && offsety >= offsetx + sizex;
}
/* True dependence: X is read after store in MEM takes place. */
rtx insn;
int nonlocal_memory_referenced;
- if (TREE_PUBLIC (current_function_decl)
- || TREE_READONLY (current_function_decl)
+ if (TREE_READONLY (current_function_decl)
|| DECL_IS_PURE (current_function_decl)
|| TREE_THIS_VOLATILE (current_function_decl)
|| TYPE_MODE (TREE_TYPE (current_function_decl)) == VOIDmode
- || current_function_has_nonlocal_goto)
+ || current_function_has_nonlocal_goto
+ || !(*targetm.binds_local_p) (current_function_decl))
return;
/* A loop might not return which counts as a side effect. */
}
\f
-static HARD_REG_SET argument_registers;
-
void
init_alias_once ()
{
numbers, so translate if necessary due to register windows. */
if (FUNCTION_ARG_REGNO_P (OUTGOING_REGNO (i))
&& HARD_REGNO_MODE_OK (i, Pmode))
- SET_HARD_REG_BIT (argument_registers, i);
+ static_reg_base_value[i]
+ = gen_rtx_ADDRESS (VOIDmode, gen_rtx_REG (Pmode, i));
+
+ static_reg_base_value[STACK_POINTER_REGNUM]
+ = gen_rtx_ADDRESS (Pmode, stack_pointer_rtx);
+ static_reg_base_value[ARG_POINTER_REGNUM]
+ = gen_rtx_ADDRESS (Pmode, arg_pointer_rtx);
+ static_reg_base_value[FRAME_POINTER_REGNUM]
+ = gen_rtx_ADDRESS (Pmode, frame_pointer_rtx);
+#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
+ static_reg_base_value[HARD_FRAME_POINTER_REGNUM]
+ = gen_rtx_ADDRESS (Pmode, hard_frame_pointer_rtx);
+#endif
alias_sets = splay_tree_new (splay_tree_compare_ints, 0, 0);
}
optimization. Loop unrolling can create a large number of
registers. */
reg_base_value_size = maxreg * 2;
- reg_base_value = (rtx *) xcalloc (reg_base_value_size, sizeof (rtx));
- ggc_add_rtx_root (reg_base_value, reg_base_value_size);
+ reg_base_value = (rtx *) ggc_alloc_cleared (reg_base_value_size
+ * sizeof (rtx));
new_reg_base_value = (rtx *) xmalloc (reg_base_value_size * sizeof (rtx));
reg_seen = (char *) xmalloc (reg_base_value_size);
The address expression is VOIDmode for an argument and
Pmode for other registers. */
- for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- if (TEST_HARD_REG_BIT (argument_registers, i))
- new_reg_base_value[i] = gen_rtx_ADDRESS (VOIDmode,
- gen_rtx_REG (Pmode, i));
-
- new_reg_base_value[STACK_POINTER_REGNUM]
- = gen_rtx_ADDRESS (Pmode, stack_pointer_rtx);
- new_reg_base_value[ARG_POINTER_REGNUM]
- = gen_rtx_ADDRESS (Pmode, arg_pointer_rtx);
- new_reg_base_value[FRAME_POINTER_REGNUM]
- = gen_rtx_ADDRESS (Pmode, frame_pointer_rtx);
-#if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
- new_reg_base_value[HARD_FRAME_POINTER_REGNUM]
- = gen_rtx_ADDRESS (Pmode, hard_frame_pointer_rtx);
-#endif
+ memcpy (new_reg_base_value, static_reg_base_value,
+ FIRST_PSEUDO_REGISTER * sizeof (rtx));
/* Walk the insns adding values to the new_reg_base_value array. */
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
reg_known_value_size = 0;
free (reg_known_equiv_p + FIRST_PSEUDO_REGISTER);
reg_known_equiv_p = 0;
- if (reg_base_value)
- {
- ggc_del_root (reg_base_value);
- free (reg_base_value);
- reg_base_value = 0;
- }
+ reg_base_value = 0;
reg_base_value_size = 0;
if (alias_invariant)
{
alias_invariant = 0;
}
}
+
+#include "gt-alias.h"