Mercurial > hg > CbC > CbC_gcc
diff gcc/emit-rtl.c @ 67:f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 22 Mar 2011 17:18:12 +0900 |
parents | b7f97abdc517 |
children | 04ced10e8804 |
line wrap: on
line diff
--- a/gcc/emit-rtl.c Tue May 25 18:58:51 2010 +0900 +++ b/gcc/emit-rtl.c Tue Mar 22 17:18:12 2011 +0900 @@ -38,7 +38,7 @@ #include "system.h" #include "coretypes.h" #include "tm.h" -#include "toplev.h" +#include "diagnostic-core.h" #include "rtl.h" #include "tree.h" #include "tm_p.h" @@ -59,6 +59,14 @@ #include "df.h" #include "params.h" #include "target.h" +#include "tree-flow.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. */ @@ -83,19 +91,6 @@ 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 @@ 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 @@ -167,8 +138,6 @@ static GTY ((if_marked ("ggc_marked_p"), param_is (struct rtx_def))) htab_t const_fixed_htab; -#define first_insn (crtl->emit.x_first_insn) -#define last_insn (crtl->emit.x_last_insn) #define cur_insn_uid (crtl->emit.x_cur_insn_uid) #define cur_debug_insn_uid (crtl->emit.x_cur_debug_insn_uid) #define last_location (crtl->emit.x_last_location) @@ -343,7 +312,7 @@ slot = htab_find_slot (mem_attrs_htab, &attrs, INSERT); if (*slot == 0) { - *slot = ggc_alloc (sizeof (mem_attrs)); + *slot = ggc_alloc_mem_attrs (); memcpy (*slot, &attrs, sizeof (mem_attrs)); } @@ -357,7 +326,7 @@ { const reg_attrs *const p = (const reg_attrs *) x; - return ((p->offset * 1000) ^ (long) p->decl); + return ((p->offset * 1000) ^ (intptr_t) p->decl); } /* Returns nonzero if the value represented by X (which is really a @@ -392,7 +361,7 @@ slot = htab_find_slot (reg_attrs_htab, &attrs, INSERT); if (*slot == 0) { - *slot = ggc_alloc (sizeof (reg_attrs)); + *slot = ggc_alloc_reg_attrs (); memcpy (*slot, &attrs, sizeof (reg_attrs)); } @@ -620,12 +589,12 @@ if (regno == FRAME_POINTER_REGNUM && (!reload_completed || frame_pointer_needed)) return frame_pointer_rtx; -#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM +#if !HARD_FRAME_POINTER_IS_FRAME_POINTER if (regno == HARD_FRAME_POINTER_REGNUM && (!reload_completed || frame_pointer_needed)) return hard_frame_pointer_rtx; #endif -#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM && HARD_FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM +#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM && !HARD_FRAME_POINTER_IS_ARG_POINTER if (regno == ARG_POINTER_REGNUM) return arg_pointer_rtx; #endif @@ -634,6 +603,7 @@ return return_address_pointer_rtx; #endif if (regno == (unsigned) PIC_OFFSET_TABLE_REGNUM + && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM && fixed_regs[PIC_OFFSET_TABLE_REGNUM]) return pic_offset_table_rtx; if (regno == STACK_POINTER_REGNUM) @@ -1490,7 +1460,8 @@ /* This function can't use if (!MEM_EXPR (mem) || !MEM_OFFSET (mem) || !CONST_INT_P (MEM_OFFSET (mem)) - || (get_object_alignment (MEM_EXPR (mem), MEM_ALIGN (mem), align) + || (MAX (MEM_ALIGN (mem), + get_object_alignment (MEM_EXPR (mem), align)) < align)) return -1; else @@ -1570,11 +1541,11 @@ set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp, HOST_WIDE_INT bitpos) { - alias_set_type alias = MEM_ALIAS_SET (ref); - tree expr = MEM_EXPR (ref); - rtx offset = MEM_OFFSET (ref); - rtx size = MEM_SIZE (ref); - unsigned int align = MEM_ALIGN (ref); + alias_set_type alias; + tree expr = NULL; + rtx offset = NULL_RTX; + rtx size = NULL_RTX; + unsigned int align = BITS_PER_UNIT; HOST_WIDE_INT apply_bitpos = 0; tree type; @@ -1610,21 +1581,73 @@ && TREE_CODE (type) != COMPLEX_TYPE) MEM_SCALAR_P (ref) = 1; + /* Default values from pre-existing memory attributes if present. */ + if (MEM_ATTRS (ref)) + { + /* ??? Can this ever happen? Calling this routine on a MEM that + already carries memory attributes should probably be invalid. */ + expr = MEM_EXPR (ref); + offset = MEM_OFFSET (ref); + size = MEM_SIZE (ref); + align = MEM_ALIGN (ref); + } + + /* Otherwise, default values from the mode of the MEM reference. */ + else if (GET_MODE (ref) != BLKmode) + { + /* Respect mode size. */ + size = GEN_INT (GET_MODE_SIZE (GET_MODE (ref))); + /* ??? Is this really necessary? We probably should always get + the size from the type below. */ + + /* Respect mode alignment for STRICT_ALIGNMENT targets if T is a type; + if T is an object, always compute the object alignment below. */ + if (STRICT_ALIGNMENT && TYPE_P (t)) + align = GET_MODE_ALIGNMENT (GET_MODE (ref)); + /* ??? If T is a type, respecting mode alignment may *also* be wrong + e.g. if the type carries an alignment attribute. Should we be + able to simply always use TYPE_ALIGN? */ + } + /* 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); + if (TREE_CODE (op0) == ADDR_EXPR + && (DECL_P (TREE_OPERAND (op0, 0)) + || CONSTANT_CLASS_P (TREE_OPERAND (op0, 0)))) + { + if (DECL_P (TREE_OPERAND (op0, 0))) + align = DECL_ALIGN (TREE_OPERAND (op0, 0)); + else if (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 + } + if (TREE_INT_CST_LOW (TREE_OPERAND (t, 1)) != 0) + { + unsigned HOST_WIDE_INT ioff + = TREE_INT_CST_LOW (TREE_OPERAND (t, 1)); + unsigned HOST_WIDE_INT aoff = (ioff & -ioff) * BITS_PER_UNIT; + align = MIN (aoff, align); + } + } + else + /* ??? This isn't fully correct, we can't set the alignment from the + type in all cases. */ + align = MAX (align, TYPE_ALIGN (type)); + } + + else if (TREE_CODE (t) == TARGET_MEM_REF) + /* ??? This isn't fully correct, we can't set the alignment from the + type in all cases. */ + align = MAX (align, TYPE_ALIGN (type)); /* If the size is known, we can set that. */ if (TYPE_SIZE_UNIT (type) && host_integerp (TYPE_SIZE_UNIT (type), 1)) @@ -1647,35 +1670,15 @@ || TREE_CODE (t) == SAVE_EXPR) t = TREE_OPERAND (t, 0); - /* We may look through structure-like accesses for the purposes of - examining TREE_THIS_NOTRAP, but not array-like accesses. */ - base = t; - while (TREE_CODE (base) == COMPONENT_REF - || TREE_CODE (base) == REALPART_EXPR - || TREE_CODE (base) == IMAGPART_EXPR - || TREE_CODE (base) == BIT_FIELD_REF) - base = TREE_OPERAND (base, 0); - - if (DECL_P (base)) - { - if (CODE_CONTAINS_STRUCT (TREE_CODE (base), TS_DECL_WITH_VIS)) - MEM_NOTRAP_P (ref) = !DECL_WEAK (base); - else - MEM_NOTRAP_P (ref) = 1; - } - else - MEM_NOTRAP_P (ref) = TREE_THIS_NOTRAP (base); - - base = get_base_address (base); + /* Note whether this expression can trap. */ + MEM_NOTRAP_P (ref) = !tree_could_trap_p (t); + + base = get_base_address (t); if (base && DECL_P (base) && TREE_READONLY (base) - && (TREE_STATIC (base) || DECL_EXTERNAL (base))) - { - tree base_type = TREE_TYPE (base); - gcc_assert (!(base_type && TYPE_NEEDS_CONSTRUCTING (base_type)) - || DECL_ARTIFICIAL (base)); - MEM_READONLY_P (ref) = 1; - } + && (TREE_STATIC (base) || DECL_EXTERNAL (base)) + && !TREE_THIS_VOLATILE (base)) + MEM_READONLY_P (ref) = 1; /* If this expression uses it's parent's alias set, mark it such that we won't change it. */ @@ -1781,8 +1784,7 @@ } /* If this is an indirect reference, record it. */ - else if (TREE_CODE (t) == INDIRECT_REF - || TREE_CODE (t) == MISALIGNED_INDIRECT_REF) + else if (TREE_CODE (t) == MEM_REF) { expr = t; offset = const0_rtx; @@ -1791,8 +1793,8 @@ } /* If this is an indirect reference, record it. */ - else if (TREE_CODE (t) == INDIRECT_REF - || TREE_CODE (t) == MISALIGNED_INDIRECT_REF) + else if (TREE_CODE (t) == MEM_REF + || TREE_CODE (t) == TARGET_MEM_REF) { expr = t; offset = const0_rtx; @@ -1801,8 +1803,7 @@ if (!align_computed && !INDIRECT_REF_P (t)) { - unsigned int obj_align - = get_object_alignment (t, align, BIGGEST_ALIGNMENT); + unsigned int obj_align = get_object_alignment (t, BIGGEST_ALIGNMENT); align = MAX (align, obj_align); } } @@ -1817,14 +1818,6 @@ 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, @@ -1853,10 +1846,8 @@ void set_mem_alias_set (rtx mem, alias_set_type set) { -#ifdef ENABLE_CHECKING /* If the new and old alias sets don't conflict, something is wrong. */ - gcc_assert (alias_sets_conflict_p (set, MEM_ALIAS_SET (mem))); -#endif + gcc_checking_assert (alias_sets_conflict_p (set, MEM_ALIAS_SET (mem))); MEM_ATTRS (mem) = get_mem_attrs (set, MEM_EXPR (mem), MEM_OFFSET (mem), MEM_SIZE (mem), MEM_ALIGN (mem), @@ -2254,7 +2245,6 @@ DECL_ARTIFICIAL (d) = 1; DECL_IGNORED_P (d) = 1; TREE_USED (d) = 1; - TREE_THIS_NOTRAP (d) = 1; spill_slot_decl = d; rd = gen_rtx_MEM (BLKmode, frame_pointer_rtx); @@ -2317,8 +2307,8 @@ { rtx insn; - first_insn = first; - last_insn = last; + set_first_insn (first); + set_last_insn (last); cur_insn_uid = 0; if (MIN_NONDEBUG_INSN_UID || MAY_HAVE_DEBUG_INSNS) @@ -2390,7 +2380,7 @@ 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); @@ -2537,11 +2527,13 @@ /* Go through all the RTL insn bodies and check that there is no unexpected sharing in between the subexpressions. */ -void +DEBUG_FUNCTION void verify_rtl_sharing (void) { rtx p; + timevar_push (TV_VERIFY_RTL_SHARING); + for (p = get_insns (); p; p = NEXT_INSN (p)) if (INSN_P (p)) { @@ -2568,6 +2560,8 @@ verify_rtx_sharing (PATTERN (p), p); verify_rtx_sharing (REG_NOTES (p), p); } + + timevar_pop (TV_VERIFY_RTL_SHARING); } /* Go through all the RTL insn bodies and copy any invalid shared structure. @@ -2600,7 +2594,7 @@ 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)); @@ -2745,11 +2739,10 @@ return; } -/* Clear all the USED bits in X to allow copy_rtx_if_shared to be used - to look for shared sub-parts. */ - -void -reset_used_flags (rtx x) +/* Set the USED bit in X and its non-shareable subparts to FLAG. */ + +static void +mark_used_flags (rtx x, int flag) { int i, j; enum rtx_code code; @@ -2795,7 +2788,7 @@ break; } - RTX_FLAG (x, used) = 0; + RTX_FLAG (x, used) = flag; format_ptr = GET_RTX_FORMAT (code); length = GET_RTX_LENGTH (code); @@ -2810,81 +2803,33 @@ x = XEXP (x, i); goto repeat; } - reset_used_flags (XEXP (x, i)); + mark_used_flags (XEXP (x, i), flag); break; case 'E': for (j = 0; j < XVECLEN (x, i); j++) - reset_used_flags (XVECEXP (x, i, j)); + mark_used_flags (XVECEXP (x, i, j), flag); break; } } } +/* Clear all the USED bits in X to allow copy_rtx_if_shared to be used + to look for shared sub-parts. */ + +void +reset_used_flags (rtx x) +{ + mark_used_flags (x, 0); +} + /* Set all the USED bits in X to allow copy_rtx_if_shared to be used to look for shared sub-parts. */ void set_used_flags (rtx x) { - int i, j; - enum rtx_code code; - const char *format_ptr; - - if (x == 0) - return; - - code = GET_CODE (x); - - /* These types may be freely shared so we needn't do any resetting - for them. */ - - switch (code) - { - case REG: - case DEBUG_EXPR: - case VALUE: - case CONST_INT: - case CONST_DOUBLE: - case CONST_FIXED: - case CONST_VECTOR: - case SYMBOL_REF: - case CODE_LABEL: - case PC: - case CC0: - return; - - case DEBUG_INSN: - case INSN: - case JUMP_INSN: - case CALL_INSN: - case NOTE: - case LABEL_REF: - case BARRIER: - /* The chain of insns is not being copied. */ - return; - - default: - break; - } - - RTX_FLAG (x, used) = 1; - - format_ptr = GET_RTX_FORMAT (code); - for (i = 0; i < GET_RTX_LENGTH (code); i++) - { - switch (*format_ptr++) - { - case 'e': - set_used_flags (XEXP (x, i)); - break; - - case 'E': - for (j = 0; j < XVECLEN (x, i); j++) - set_used_flags (XVECEXP (x, i, j)); - break; - } - } + mark_used_flags (x, 1); } /* Copy X if necessary so that it won't be altered by changes in OTHER. @@ -2926,48 +2871,14 @@ /* Emission of insns (adding them to the doubly-linked list). */ -/* Return the first insn of the current sequence or current function. */ - -rtx -get_insns (void) -{ - return first_insn; -} - -/* Specify a new insn as the first in the chain. */ - -void -set_first_insn (rtx insn) -{ - gcc_assert (!PREV_INSN (insn)); - first_insn = insn; -} - -/* Return the last insn emitted in current sequence or current function. */ - -rtx -get_last_insn (void) -{ - return last_insn; -} - -/* Specify a new insn as the last in the chain. */ - -void -set_last_insn (rtx insn) -{ - gcc_assert (!NEXT_INSN (insn)); - last_insn = insn; -} - /* Return the last insn emitted, even if it is in a sequence now pushed. */ rtx get_last_insn_anywhere (void) { struct sequence_stack *stack; - if (last_insn) - return last_insn; + if (get_last_insn ()) + return get_last_insn (); for (stack = seq_stack; stack; stack = stack->next) if (stack->last != 0) return stack->last; @@ -2980,7 +2891,7 @@ rtx get_first_nonnote_insn (void) { - rtx insn = first_insn; + rtx insn = get_insns (); if (insn) { @@ -3006,7 +2917,7 @@ rtx get_last_nonnote_insn (void) { - rtx insn = last_insn; + rtx insn = get_last_insn (); if (insn) { @@ -3027,14 +2938,6 @@ return insn; } -/* Return a number larger than any instruction's uid in this function. */ - -int -get_max_uid (void) -{ - return cur_insn_uid; -} - /* Return the number of actual (non-debug) insns emitted in this function. */ @@ -3192,6 +3095,38 @@ return insn; } +/* Return the next insn after INSN that is not a NOTE nor DEBUG_INSN. + This routine does not look inside SEQUENCEs. */ + +rtx +next_nonnote_nondebug_insn (rtx insn) +{ + while (insn) + { + insn = NEXT_INSN (insn); + if (insn == 0 || (!NOTE_P (insn) && !DEBUG_INSN_P (insn))) + break; + } + + return insn; +} + +/* Return the previous insn before INSN that is not a NOTE nor DEBUG_INSN. + This routine does not look inside SEQUENCEs. */ + +rtx +prev_nonnote_nondebug_insn (rtx insn) +{ + while (insn) + { + insn = PREV_INSN (insn); + if (insn == 0 || (!NOTE_P (insn) && !DEBUG_INSN_P (insn))) + break; + } + + return insn; +} + /* Return the next INSN, CALL_INSN or JUMP_INSN after INSN; or 0, if there is none. This routine does not look inside SEQUENCEs. */ @@ -3625,7 +3560,7 @@ /* Return either the first or the last insn, depending on which was requested. */ return last - ? (after ? PREV_INSN (after) : last_insn) + ? (after ? PREV_INSN (after) : get_last_insn ()) : NEXT_INSN (before); } @@ -3728,16 +3663,16 @@ void add_insn (rtx insn) { - PREV_INSN (insn) = last_insn; + PREV_INSN (insn) = get_last_insn(); NEXT_INSN (insn) = 0; - if (NULL != last_insn) - NEXT_INSN (last_insn) = insn; - - if (NULL == first_insn) - first_insn = insn; - - last_insn = insn; + if (NULL != get_last_insn()) + NEXT_INSN (get_last_insn ()) = insn; + + if (NULL == get_insns ()) + set_first_insn (insn); + + set_last_insn (insn); } /* Add INSN into the doubly-linked list after insn AFTER. This and @@ -3761,8 +3696,8 @@ if (NONJUMP_INSN_P (next) && GET_CODE (PATTERN (next)) == SEQUENCE) PREV_INSN (XVECEXP (PATTERN (next), 0, 0)) = insn; } - else if (last_insn == after) - last_insn = insn; + else if (get_last_insn () == after) + set_last_insn (insn); else { struct sequence_stack *stack = seq_stack; @@ -3826,8 +3761,8 @@ NEXT_INSN (XVECEXP (sequence, 0, XVECLEN (sequence, 0) - 1)) = insn; } } - else if (first_insn == before) - first_insn = insn; + else if (get_insns () == before) + set_first_insn (insn); else { struct sequence_stack *stack = seq_stack; @@ -3898,8 +3833,12 @@ NEXT_INSN (XVECEXP (sequence, 0, XVECLEN (sequence, 0) - 1)) = next; } } - else if (first_insn == insn) - first_insn = next; + else if (get_insns () == insn) + { + if (next) + PREV_INSN (next) = NULL; + set_first_insn (next); + } else { struct sequence_stack *stack = seq_stack; @@ -3920,8 +3859,8 @@ if (NONJUMP_INSN_P (next) && GET_CODE (PATTERN (next)) == SEQUENCE) PREV_INSN (XVECEXP (PATTERN (next), 0, 0)) = prev; } - else if (last_insn == insn) - last_insn = prev; + else if (get_last_insn () == insn) + set_last_insn (prev); else { struct sequence_stack *stack = seq_stack; @@ -3938,7 +3877,7 @@ if (!BARRIER_P (insn) && (bb = BLOCK_FOR_INSN (insn))) { - if (INSN_P (insn)) + if (NONDEBUG_INSN_P (insn)) df_set_bb_dirty (bb); if (BB_HEAD (bb) == insn) { @@ -3982,10 +3921,10 @@ delete_insns_since (rtx from) { if (from == 0) - first_insn = 0; + set_first_insn (0); else NEXT_INSN (from) = 0; - last_insn = from; + set_last_insn (from); } /* This function is deprecated, please use sequences instead. @@ -4001,15 +3940,22 @@ void reorder_insns_nobb (rtx from, rtx to, rtx after) { +#ifdef ENABLE_CHECKING + rtx x; + for (x = from; x != to; x = NEXT_INSN (x)) + gcc_assert (after != x); + gcc_assert (after != to); +#endif + /* Splice this bunch out of where it is now. */ if (PREV_INSN (from)) NEXT_INSN (PREV_INSN (from)) = NEXT_INSN (to); if (NEXT_INSN (to)) PREV_INSN (NEXT_INSN (to)) = PREV_INSN (from); - if (last_insn == to) - last_insn = PREV_INSN (from); - if (first_insn == from) - first_insn = NEXT_INSN (to); + if (get_last_insn () == to) + set_last_insn (PREV_INSN (from)); + if (get_insns () == from) + set_first_insn (NEXT_INSN (to)); /* Make the new neighbors point to it and it to them. */ if (NEXT_INSN (after)) @@ -4018,8 +3964,8 @@ NEXT_INSN (to) = NEXT_INSN (after); PREV_INSN (from) = after; NEXT_INSN (after) = from; - if (after == last_insn) - last_insn = to; + if (after == get_last_insn()) + set_last_insn (to); } /* Same as function above, but take care to update BB boundaries. */ @@ -4344,8 +4290,8 @@ if (after_after) PREV_INSN (after_after) = last; - if (after == last_insn) - last_insn = last; + if (after == get_last_insn()) + set_last_insn (last); return last; } @@ -4842,7 +4788,7 @@ rtx emit_insn (rtx x) { - rtx last = last_insn; + rtx last = get_last_insn(); rtx insn; if (x == NULL_RTX) @@ -4888,7 +4834,7 @@ rtx emit_debug_insn (rtx x) { - rtx last = last_insn; + rtx last = get_last_insn(); rtx insn; if (x == NULL_RTX) @@ -5280,16 +5226,16 @@ free_sequence_stack = tem->next; } else - tem = GGC_NEW (struct sequence_stack); + tem = ggc_alloc_sequence_stack (); tem->next = seq_stack; - tem->first = first_insn; - tem->last = last_insn; + tem->first = get_insns (); + tem->last = get_last_insn (); seq_stack = tem; - first_insn = 0; - last_insn = 0; + set_first_insn (0); + set_last_insn (0); } /* Set up the insn chain starting with FIRST as the current sequence, @@ -5305,8 +5251,8 @@ for (last = first; last && NEXT_INSN (last); last = NEXT_INSN (last)); - first_insn = first; - last_insn = last; + set_first_insn (first); + set_last_insn (last); } /* Like push_to_sequence, but take the last insn as an argument to avoid @@ -5317,8 +5263,8 @@ { start_sequence (); - first_insn = first; - last_insn = last; + set_first_insn (first); + set_last_insn (last); } /* Set up the outer-level insn chain @@ -5334,8 +5280,8 @@ for (stack = seq_stack; stack; stack = stack->next) top = stack; - first_insn = top->first; - last_insn = top->last; + set_first_insn (top->first); + set_last_insn (top->last); } /* After emitting to the outer-level insn chain, update the outer-level @@ -5349,8 +5295,8 @@ for (stack = seq_stack; stack; stack = stack->next) top = stack; - top->first = first_insn; - top->last = last_insn; + top->first = get_insns (); + top->last = get_last_insn (); end_sequence (); } @@ -5373,8 +5319,8 @@ { struct sequence_stack *tem = seq_stack; - first_insn = tem->first; - last_insn = tem->last; + set_first_insn (tem->first); + set_last_insn (tem->last); seq_stack = tem->next; memset (tem, 0, sizeof (*tem)); @@ -5400,6 +5346,8 @@ regno_reg_rtx[VIRTUAL_STACK_DYNAMIC_REGNUM] = virtual_stack_dynamic_rtx; regno_reg_rtx[VIRTUAL_OUTGOING_ARGS_REGNUM] = virtual_outgoing_args_rtx; regno_reg_rtx[VIRTUAL_CFA_REGNUM] = virtual_cfa_rtx; + regno_reg_rtx[VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM] + = virtual_preferred_stack_boundary_rtx; } @@ -5576,8 +5524,8 @@ void init_emit (void) { - first_insn = NULL; - last_insn = NULL; + set_first_insn (NULL); + set_last_insn (NULL); if (MIN_NONDEBUG_INSN_UID) cur_insn_uid = MIN_NONDEBUG_INSN_UID; else @@ -5595,12 +5543,11 @@ crtl->emit.regno_pointer_align = XCNEWVEC (unsigned char, crtl->emit.regno_pointer_align_length); - regno_reg_rtx - = GGC_NEWVEC (rtx, crtl->emit.regno_pointer_align_length); + regno_reg_rtx = ggc_alloc_vec_rtx (crtl->emit.regno_pointer_align_length); /* 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. */ @@ -5723,11 +5670,13 @@ virtual_outgoing_args_rtx = gen_raw_REG (Pmode, VIRTUAL_OUTGOING_ARGS_REGNUM); virtual_cfa_rtx = gen_raw_REG (Pmode, VIRTUAL_CFA_REGNUM); + virtual_preferred_stack_boundary_rtx = + gen_raw_REG (Pmode, VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM); /* 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