diff options
Diffstat (limited to 'gcc/emit-rtl.c')
-rw-r--r-- | gcc/emit-rtl.c | 118 |
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 |