summaryrefslogtreecommitdiff
path: root/gcc/emit-rtl.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/emit-rtl.c')
-rw-r--r--gcc/emit-rtl.c118
1 files changed, 55 insertions, 63 deletions
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c
index 55ed2054e4e..32741dc6b80 100644
--- a/gcc/emit-rtl.c
+++ b/gcc/emit-rtl.c
@@ -38,6 +38,7 @@ along with GCC; see the file COPYING3. If not see
#include "system.h"
#include "coretypes.h"
#include "tm.h"
+#include "diagnostic-core.h"
#include "toplev.h"
#include "rtl.h"
#include "tree.h"
@@ -60,6 +61,13 @@ along with GCC; see the file COPYING3. If not see
#include "params.h"
#include "target.h"
+struct target_rtl default_target_rtl;
+#if SWITCHABLE_TARGET
+struct target_rtl *this_target_rtl = &default_target_rtl;
+#endif
+
+#define initial_regno_reg_rtx (this_target_rtl->x_initial_regno_reg_rtx)
+
/* Commonly used modes. */
enum machine_mode byte_mode; /* Mode whose width is BITS_PER_UNIT. */
@@ -83,19 +91,6 @@ rtx * regno_reg_rtx;
static GTY(()) int label_num = 1;
-/* Commonly used rtx's, so that we only need space for one copy.
- These are initialized once for the entire compilation.
- All of these are unique; no other rtx-object will be equal to any
- of these. */
-
-rtx global_rtl[GR_MAX];
-
-/* Commonly used RTL for hard registers. These objects are not necessarily
- unique, so we allocate them separately from global_rtl. They are
- initialized once per compilation unit, then copied into regno_reg_rtx
- at the beginning of each function. */
-static GTY(()) rtx static_regno_reg_rtx[FIRST_PSEUDO_REGISTER];
-
/* We record floating-point CONST_DOUBLEs in each floating-point mode for
the values of 0, 1, and 2. For the integer entries and VOIDmode, we
record a copy of const[012]_rtx. */
@@ -114,30 +109,6 @@ REAL_VALUE_TYPE dconsthalf;
FIXED_VALUE_TYPE fconst0[MAX_FCONST0];
FIXED_VALUE_TYPE fconst1[MAX_FCONST1];
-/* All references to the following fixed hard registers go through
- these unique rtl objects. On machines where the frame-pointer and
- arg-pointer are the same register, they use the same unique object.
-
- After register allocation, other rtl objects which used to be pseudo-regs
- may be clobbered to refer to the frame-pointer register.
- But references that were originally to the frame-pointer can be
- distinguished from the others because they contain frame_pointer_rtx.
-
- When to use frame_pointer_rtx and hard_frame_pointer_rtx is a little
- tricky: until register elimination has taken place hard_frame_pointer_rtx
- should be used if it is being set, and frame_pointer_rtx otherwise. After
- register elimination hard_frame_pointer_rtx should always be used.
- On machines where the two registers are same (most) then these are the
- same.
-
- In an inline procedure, the stack and frame pointer rtxs may not be
- used for anything else. */
-rtx pic_offset_table_rtx; /* (REG:Pmode PIC_OFFSET_TABLE_REGNUM) */
-
-/* This is used to implement __builtin_return_address for some machines.
- See for instance the MIPS port. */
-rtx return_address_pointer_rtx; /* (REG:Pmode RETURN_ADDRESS_POINTER_REGNUM) */
-
/* We make one copy of (const_int C) where C is in
[- MAX_SAVED_CONST_INT, MAX_SAVED_CONST_INT]
to save space during the compilation and simplify comparisons of
@@ -1610,19 +1581,45 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp,
/* We can set the alignment from the type if we are making an object,
this is an INDIRECT_REF, or if TYPE_ALIGN_OK. */
- if (objectp || TREE_CODE (t) == INDIRECT_REF
- || TREE_CODE (t) == ALIGN_INDIRECT_REF
- || TYPE_ALIGN_OK (type))
+ if (objectp || TREE_CODE (t) == INDIRECT_REF || TYPE_ALIGN_OK (type))
align = MAX (align, TYPE_ALIGN (type));
- else
- if (TREE_CODE (t) == MISALIGNED_INDIRECT_REF)
- {
- if (integer_zerop (TREE_OPERAND (t, 1)))
- /* We don't know anything about the alignment. */
- align = BITS_PER_UNIT;
- else
- align = tree_low_cst (TREE_OPERAND (t, 1), 1);
- }
+
+ else if (TREE_CODE (t) == MEM_REF)
+ {
+ tree op0 = TREE_OPERAND (t, 0);
+ unsigned HOST_WIDE_INT aoff = BITS_PER_UNIT;
+ if (host_integerp (TREE_OPERAND (t, 1), 1))
+ {
+ unsigned HOST_WIDE_INT ioff = TREE_INT_CST_LOW (TREE_OPERAND (t, 1));
+ aoff = (ioff & -ioff) * BITS_PER_UNIT;
+ }
+ if (TREE_CODE (op0) == ADDR_EXPR && DECL_P (TREE_OPERAND (op0, 0)))
+ align = MAX (align, DECL_ALIGN (TREE_OPERAND (op0, 0)));
+ else if (TREE_CODE (op0) == ADDR_EXPR
+ && CONSTANT_CLASS_P (TREE_OPERAND (op0, 0)))
+ {
+ align = TYPE_ALIGN (TREE_TYPE (TREE_OPERAND (op0, 0)));
+#ifdef CONSTANT_ALIGNMENT
+ align = CONSTANT_ALIGNMENT (TREE_OPERAND (op0, 0), align);
+#endif
+ }
+ else
+ /* ??? This isn't fully correct, we can't set the alignment from the
+ type in all cases. */
+ align = MAX (align, TYPE_ALIGN (type));
+
+ if (!integer_zerop (TREE_OPERAND (t, 1)) && aoff < align)
+ align = aoff;
+ }
+
+ else if (TREE_CODE (t) == MISALIGNED_INDIRECT_REF)
+ {
+ if (integer_zerop (TREE_OPERAND (t, 1)))
+ /* We don't know anything about the alignment. */
+ align = BITS_PER_UNIT;
+ else
+ align = tree_low_cst (TREE_OPERAND (t, 1), 1);
+ }
/* If the size is known, we can set that. */
if (TYPE_SIZE_UNIT (type) && host_integerp (TYPE_SIZE_UNIT (type), 1))
@@ -1654,6 +1651,9 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp,
|| TREE_CODE (base) == BIT_FIELD_REF)
base = TREE_OPERAND (base, 0);
+ if (TREE_CODE (base) == MEM_REF
+ && TREE_CODE (TREE_OPERAND (base, 0)) == ADDR_EXPR)
+ base = TREE_OPERAND (TREE_OPERAND (base, 0), 0);
if (DECL_P (base))
{
if (CODE_CONTAINS_STRUCT (TREE_CODE (base), TS_DECL_WITH_VIS))
@@ -1774,7 +1774,7 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp,
}
/* If this is an indirect reference, record it. */
- else if (TREE_CODE (t) == INDIRECT_REF
+ else if (TREE_CODE (t) == MEM_REF
|| TREE_CODE (t) == MISALIGNED_INDIRECT_REF)
{
expr = t;
@@ -1784,7 +1784,7 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp,
}
/* If this is an indirect reference, record it. */
- else if (TREE_CODE (t) == INDIRECT_REF
+ else if (TREE_CODE (t) == MEM_REF
|| TREE_CODE (t) == MISALIGNED_INDIRECT_REF)
{
expr = t;
@@ -1810,14 +1810,6 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp,
size = plus_constant (size, apply_bitpos / BITS_PER_UNIT);
}
- if (TREE_CODE (t) == ALIGN_INDIRECT_REF)
- {
- /* Force EXPR and OFFSET to NULL, since we don't know exactly what
- we're overlapping. */
- offset = NULL;
- expr = NULL;
- }
-
/* Now set the attributes we computed above. */
MEM_ATTRS (ref)
= get_mem_attrs (alias, expr, offset, size, align,
@@ -2383,7 +2375,7 @@ unshare_all_rtl_again (rtx insn)
set_used_decls (DECL_INITIAL (cfun->decl));
/* Make sure that virtual parameters are not shared. */
- for (decl = DECL_ARGUMENTS (cfun->decl); decl; decl = TREE_CHAIN (decl))
+ for (decl = DECL_ARGUMENTS (cfun->decl); decl; decl = DECL_CHAIN (decl))
set_used_flags (DECL_RTL (decl));
reset_used_flags (stack_slot_list);
@@ -2593,7 +2585,7 @@ set_used_decls (tree blk)
tree t;
/* Mark decls. */
- for (t = BLOCK_VARS (blk); t; t = TREE_CHAIN (t))
+ for (t = BLOCK_VARS (blk); t; t = DECL_CHAIN (t))
if (DECL_RTL_SET_P (t))
set_used_flags (DECL_RTL (t));
@@ -5554,7 +5546,7 @@ init_emit (void)
/* Put copies of all the hard registers into regno_reg_rtx. */
memcpy (regno_reg_rtx,
- static_regno_reg_rtx,
+ initial_regno_reg_rtx,
FIRST_PSEUDO_REGISTER * sizeof (rtx));
/* Put copies of all the virtual register rtx into regno_reg_rtx. */
@@ -5681,7 +5673,7 @@ init_emit_regs (void)
/* Initialize RTL for commonly used hard registers. These are
copied into regno_reg_rtx as we begin to compile each function. */
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
- static_regno_reg_rtx[i] = gen_raw_REG (reg_raw_mode[i], i);
+ initial_regno_reg_rtx[i] = gen_raw_REG (reg_raw_mode[i], i);
#ifdef RETURN_ADDRESS_POINTER_REGNUM
return_address_pointer_rtx