diff options
author | dberlin <dberlin@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-06-11 18:02:15 +0000 |
---|---|---|
committer | dberlin <dberlin@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-06-11 18:02:15 +0000 |
commit | 3072d30e7983a3ca5ad030f1f98a5c39bcc2c07b (patch) | |
tree | fdb9e9f8a0700a2713dc690fed1a2cf20dae8392 /gcc/emit-rtl.c | |
parent | 8ceb1bfd33bc40bf0cbe1fab8903c2c31efd10ee (diff) | |
download | gcc-3072d30e7983a3ca5ad030f1f98a5c39bcc2c07b.tar.gz |
Merge dataflow branch into mainline
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@125624 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/emit-rtl.c')
-rw-r--r-- | gcc/emit-rtl.c | 197 |
1 files changed, 120 insertions, 77 deletions
diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index f5cea9a6031..2f9ddbf7581 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -57,6 +57,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA #include "debug.h" #include "langhooks.h" #include "tree-pass.h" +#include "df.h" /* Commonly used modes. */ @@ -358,6 +359,21 @@ get_reg_attrs (tree decl, int offset) return *slot; } + +#if !HAVE_blockage +/* Generate an empty ASM_INPUT, which is used to block attempts to schedule + across this insn. */ + +rtx +gen_blockage (void) +{ + rtx x = gen_rtx_ASM_INPUT (VOIDmode, ""); + MEM_VOLATILE_P (x) = true; + return x; +} +#endif + + /* Generate a new REG rtx. Make sure ORIGINAL_REGNO is set properly, and don't attempt to share with the various global pieces of rtl (such as frame_pointer_rtx). */ @@ -2144,7 +2160,6 @@ unshare_all_rtl_again (rtx insn) { reset_used_flags (PATTERN (p)); reset_used_flags (REG_NOTES (p)); - reset_used_flags (LOG_LINKS (p)); } /* Make sure that virtual stack slots are not shared. */ @@ -2222,11 +2237,7 @@ verify_rtx_sharing (rtx orig, rtx insn) break; case CONST: - /* CONST can be shared if it contains a SYMBOL_REF. If it contains - a LABEL_REF, it isn't sharable. */ - if (GET_CODE (XEXP (x, 0)) == PLUS - && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF - && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT) + if (shared_const_p (orig)) return; break; @@ -2307,7 +2318,6 @@ verify_rtl_sharing (void) { reset_used_flags (PATTERN (p)); reset_used_flags (REG_NOTES (p)); - reset_used_flags (LOG_LINKS (p)); if (GET_CODE (PATTERN (p)) == SEQUENCE) { int i; @@ -2319,7 +2329,6 @@ verify_rtl_sharing (void) gcc_assert (INSN_P (q)); reset_used_flags (PATTERN (q)); reset_used_flags (REG_NOTES (q)); - reset_used_flags (LOG_LINKS (q)); } } } @@ -2329,7 +2338,6 @@ verify_rtl_sharing (void) { verify_rtx_sharing (PATTERN (p), p); verify_rtx_sharing (REG_NOTES (p), p); - verify_rtx_sharing (LOG_LINKS (p), p); } } @@ -2344,7 +2352,6 @@ unshare_all_rtl_in_chain (rtx insn) { PATTERN (insn) = copy_rtx_if_shared (PATTERN (insn)); REG_NOTES (insn) = copy_rtx_if_shared (REG_NOTES (insn)); - LOG_LINKS (insn) = copy_rtx_if_shared (LOG_LINKS (insn)); } } @@ -2421,11 +2428,7 @@ repeat: break; case CONST: - /* CONST can be shared if it contains a SYMBOL_REF. If it contains - a LABEL_REF, it isn't sharable. */ - if (GET_CODE (XEXP (x, 0)) == PLUS - && GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF - && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT) + if (shared_const_p (x)) return; break; @@ -3160,6 +3163,10 @@ try_split (rtx pat, rtx trial, int last) insn_last = NEXT_INSN (insn_last); } + /* We will be adding the new sequence to the function. The splitters + may have introduced invalid RTL sharing, so unshare the sequence now. */ + unshare_all_rtl_in_chain (seq); + /* Mark labels. */ for (insn = insn_last; insn ; insn = PREV_INSN (insn)) { @@ -3307,7 +3314,6 @@ make_insn_raw (rtx pattern) INSN_UID (insn) = cur_insn_uid++; PATTERN (insn) = pattern; INSN_CODE (insn) = -1; - LOG_LINKS (insn) = NULL; REG_NOTES (insn) = NULL; INSN_LOCATOR (insn) = curr_insn_locator (); BLOCK_FOR_INSN (insn) = NULL; @@ -3339,7 +3345,6 @@ make_jump_insn_raw (rtx pattern) PATTERN (insn) = pattern; INSN_CODE (insn) = -1; - LOG_LINKS (insn) = NULL; REG_NOTES (insn) = NULL; JUMP_LABEL (insn) = NULL; INSN_LOCATOR (insn) = curr_insn_locator (); @@ -3360,7 +3365,6 @@ make_call_insn_raw (rtx pattern) PATTERN (insn) = pattern; INSN_CODE (insn) = -1; - LOG_LINKS (insn) = NULL; REG_NOTES (insn) = NULL; CALL_INSN_FUNCTION_USAGE (insn) = NULL; INSN_LOCATOR (insn) = curr_insn_locator (); @@ -3393,10 +3397,9 @@ add_insn (rtx insn) SEQUENCE. */ void -add_insn_after (rtx insn, rtx after) +add_insn_after (rtx insn, rtx after, basic_block bb) { rtx next = NEXT_INSN (after); - basic_block bb; gcc_assert (!optimize || !INSN_DELETED_P (after)); @@ -3431,7 +3434,7 @@ add_insn_after (rtx insn, rtx after) { set_block_for_insn (insn, bb); if (INSN_P (insn)) - bb->flags |= BB_DIRTY; + df_insn_rescan (insn); /* Should not happen as first in the BB is always either NOTE or LABEL. */ if (BB_END (bb) == after @@ -3450,15 +3453,15 @@ add_insn_after (rtx insn, rtx after) } /* Add INSN into the doubly-linked list before insn BEFORE. This and - the previous should be the only functions called to insert an insn once - delay slots have been filled since only they know how to update a - SEQUENCE. */ + the previous should be the only functions called to insert an insn + once delay slots have been filled since only they know how to + update a SEQUENCE. If BB is NULL, an attempt is made to infer the + bb from before. */ void -add_insn_before (rtx insn, rtx before) +add_insn_before (rtx insn, rtx before, basic_block bb) { rtx prev = PREV_INSN (before); - basic_block bb; gcc_assert (!optimize || !INSN_DELETED_P (before)); @@ -3490,13 +3493,16 @@ add_insn_before (rtx insn, rtx before) gcc_assert (stack); } - if (!BARRIER_P (before) - && !BARRIER_P (insn) - && (bb = BLOCK_FOR_INSN (before))) + if (!bb + && !BARRIER_P (before) + && !BARRIER_P (insn)) + bb = BLOCK_FOR_INSN (before); + + if (bb) { set_block_for_insn (insn, bb); if (INSN_P (insn)) - bb->flags |= BB_DIRTY; + df_insn_rescan (insn); /* Should not happen as first in the BB is always either NOTE or LABEL. */ gcc_assert (BB_HEAD (bb) != insn @@ -3510,6 +3516,17 @@ add_insn_before (rtx insn, rtx before) PREV_INSN (XVECEXP (PATTERN (before), 0, 0)) = insn; } + +/* Replace insn with an deleted instruction note. */ + +void set_insn_deleted (rtx insn) +{ + df_insn_delete (BLOCK_FOR_INSN (insn), INSN_UID (insn)); + PUT_CODE (insn, NOTE); + NOTE_KIND (insn) = NOTE_INSN_DELETED; +} + + /* Remove an insn from its doubly-linked list. This function knows how to handle sequences. */ void @@ -3519,6 +3536,9 @@ remove_insn (rtx insn) rtx prev = PREV_INSN (insn); basic_block bb; + /* Later in the code, the block will be marked dirty. */ + df_insn_delete (NULL, INSN_UID (insn)); + if (prev) { NEXT_INSN (prev) = next; @@ -3569,7 +3589,7 @@ remove_insn (rtx insn) && (bb = BLOCK_FOR_INSN (insn))) { if (INSN_P (insn)) - bb->flags |= BB_DIRTY; + df_set_bb_dirty (bb); if (BB_HEAD (bb) == insn) { /* Never ever delete the basic block note without deleting whole @@ -3665,14 +3685,14 @@ reorder_insns (rtx from, rtx to, rtx after) && (bb = BLOCK_FOR_INSN (after))) { rtx x; - bb->flags |= BB_DIRTY; + df_set_bb_dirty (bb); if (!BARRIER_P (from) && (bb2 = BLOCK_FOR_INSN (from))) { if (BB_END (bb2) == to) BB_END (bb2) = prev; - bb2->flags |= BB_DIRTY; + df_set_bb_dirty (bb2); } if (BB_END (bb) == after) @@ -3680,7 +3700,10 @@ reorder_insns (rtx from, rtx to, rtx after) for (x = from; x != NEXT_INSN (to); x = NEXT_INSN (x)) if (!BARRIER_P (x)) - set_block_for_insn (x, bb); + { + set_block_for_insn (x, bb); + df_insn_change_bb (x); + } } } @@ -3713,7 +3736,7 @@ reorder_insns (rtx from, rtx to, rtx after) /* Make X be output before the instruction BEFORE. */ rtx -emit_insn_before_noloc (rtx x, rtx before) +emit_insn_before_noloc (rtx x, rtx before, basic_block bb) { rtx last = before; rtx insn; @@ -3735,7 +3758,7 @@ emit_insn_before_noloc (rtx x, rtx before) while (insn) { rtx next = NEXT_INSN (insn); - add_insn_before (insn, before); + add_insn_before (insn, before, bb); last = insn; insn = next; } @@ -3749,7 +3772,7 @@ emit_insn_before_noloc (rtx x, rtx before) default: last = make_insn_raw (x); - add_insn_before (last, before); + add_insn_before (last, before, bb); break; } @@ -3778,7 +3801,7 @@ emit_jump_insn_before_noloc (rtx x, rtx before) while (insn) { rtx next = NEXT_INSN (insn); - add_insn_before (insn, before); + add_insn_before (insn, before, NULL); last = insn; insn = next; } @@ -3792,7 +3815,7 @@ emit_jump_insn_before_noloc (rtx x, rtx before) default: last = make_jump_insn_raw (x); - add_insn_before (last, before); + add_insn_before (last, before, NULL); break; } @@ -3821,7 +3844,7 @@ emit_call_insn_before_noloc (rtx x, rtx before) while (insn) { rtx next = NEXT_INSN (insn); - add_insn_before (insn, before); + add_insn_before (insn, before, NULL); last = insn; insn = next; } @@ -3835,7 +3858,7 @@ emit_call_insn_before_noloc (rtx x, rtx before) default: last = make_call_insn_raw (x); - add_insn_before (last, before); + add_insn_before (last, before, NULL); break; } @@ -3852,7 +3875,7 @@ emit_barrier_before (rtx before) INSN_UID (insn) = cur_insn_uid++; - add_insn_before (insn, before); + add_insn_before (insn, before, NULL); return insn; } @@ -3866,7 +3889,7 @@ emit_label_before (rtx label, rtx before) if (INSN_UID (label) == 0) { INSN_UID (label) = cur_insn_uid++; - add_insn_before (label, before); + add_insn_before (label, before, NULL); } return label; @@ -3883,31 +3906,35 @@ emit_note_before (enum insn_note subtype, rtx before) BLOCK_FOR_INSN (note) = NULL; memset (&NOTE_DATA (note), 0, sizeof (NOTE_DATA (note))); - add_insn_before (note, before); + add_insn_before (note, before, NULL); return note; } /* Helper for emit_insn_after, handles lists of instructions efficiently. */ -static rtx emit_insn_after_1 (rtx, rtx); - static rtx -emit_insn_after_1 (rtx first, rtx after) +emit_insn_after_1 (rtx first, rtx after, basic_block bb) { rtx last; rtx after_after; - basic_block bb; + if (!bb && !BARRIER_P (after)) + bb = BLOCK_FOR_INSN (after); - if (!BARRIER_P (after) - && (bb = BLOCK_FOR_INSN (after))) + if (bb) { - bb->flags |= BB_DIRTY; + df_set_bb_dirty (bb); for (last = first; NEXT_INSN (last); last = NEXT_INSN (last)) if (!BARRIER_P (last)) - set_block_for_insn (last, bb); + { + set_block_for_insn (last, bb); + df_insn_rescan (last); + } if (!BARRIER_P (last)) - set_block_for_insn (last, bb); + { + set_block_for_insn (last, bb); + df_insn_rescan (last); + } if (BB_END (bb) == after) BB_END (bb) = last; } @@ -3928,10 +3955,11 @@ emit_insn_after_1 (rtx first, rtx after) return last; } -/* Make X be output after the insn AFTER. */ +/* Make X be output after the insn AFTER and set the BB of insn. If + BB is NULL, an attempt is made to infer the BB from AFTER. */ rtx -emit_insn_after_noloc (rtx x, rtx after) +emit_insn_after_noloc (rtx x, rtx after, basic_block bb) { rtx last = after; @@ -3948,7 +3976,7 @@ emit_insn_after_noloc (rtx x, rtx after) case CODE_LABEL: case BARRIER: case NOTE: - last = emit_insn_after_1 (x, after); + last = emit_insn_after_1 (x, after, bb); break; #ifdef ENABLE_RTL_CHECKING @@ -3959,7 +3987,7 @@ emit_insn_after_noloc (rtx x, rtx after) default: last = make_insn_raw (x); - add_insn_after (last, after); + add_insn_after (last, after, bb); break; } @@ -3985,7 +4013,7 @@ emit_jump_insn_after_noloc (rtx x, rtx after) case CODE_LABEL: case BARRIER: case NOTE: - last = emit_insn_after_1 (x, after); + last = emit_insn_after_1 (x, after, NULL); break; #ifdef ENABLE_RTL_CHECKING @@ -3996,7 +4024,7 @@ emit_jump_insn_after_noloc (rtx x, rtx after) default: last = make_jump_insn_raw (x); - add_insn_after (last, after); + add_insn_after (last, after, NULL); break; } @@ -4021,7 +4049,7 @@ emit_call_insn_after_noloc (rtx x, rtx after) case CODE_LABEL: case BARRIER: case NOTE: - last = emit_insn_after_1 (x, after); + last = emit_insn_after_1 (x, after, NULL); break; #ifdef ENABLE_RTL_CHECKING @@ -4032,7 +4060,7 @@ emit_call_insn_after_noloc (rtx x, rtx after) default: last = make_call_insn_raw (x); - add_insn_after (last, after); + add_insn_after (last, after, NULL); break; } @@ -4049,7 +4077,7 @@ emit_barrier_after (rtx after) INSN_UID (insn) = cur_insn_uid++; - add_insn_after (insn, after); + add_insn_after (insn, after, NULL); return insn; } @@ -4064,7 +4092,7 @@ emit_label_after (rtx label, rtx after) if (INSN_UID (label) == 0) { INSN_UID (label) = cur_insn_uid++; - add_insn_after (label, after); + add_insn_after (label, after, NULL); } return label; @@ -4080,7 +4108,7 @@ emit_note_after (enum insn_note subtype, rtx after) NOTE_KIND (note) = subtype; BLOCK_FOR_INSN (note) = NULL; memset (&NOTE_DATA (note), 0, sizeof (NOTE_DATA (note))); - add_insn_after (note, after); + add_insn_after (note, after, NULL); return note; } @@ -4088,7 +4116,7 @@ emit_note_after (enum insn_note subtype, rtx after) rtx emit_insn_after_setloc (rtx pattern, rtx after, int loc) { - rtx last = emit_insn_after_noloc (pattern, after); + rtx last = emit_insn_after_noloc (pattern, after, NULL); if (pattern == NULL_RTX || !loc) return last; @@ -4112,7 +4140,7 @@ emit_insn_after (rtx pattern, rtx after) if (INSN_P (after)) return emit_insn_after_setloc (pattern, after, INSN_LOCATOR (after)); else - return emit_insn_after_noloc (pattern, after); + return emit_insn_after_noloc (pattern, after, NULL); } /* Like emit_jump_insn_after_noloc, but set INSN_LOCATOR according to SCOPE. */ @@ -4182,7 +4210,7 @@ rtx emit_insn_before_setloc (rtx pattern, rtx before, int loc) { rtx first = PREV_INSN (before); - rtx last = emit_insn_before_noloc (pattern, before); + rtx last = emit_insn_before_noloc (pattern, before, NULL); if (pattern == NULL_RTX || !loc) return last; @@ -4209,7 +4237,7 @@ emit_insn_before (rtx pattern, rtx before) if (INSN_P (before)) return emit_insn_before_setloc (pattern, before, INSN_LOCATOR (before)); else - return emit_insn_before_noloc (pattern, before); + return emit_insn_before_noloc (pattern, before, NULL); } /* like emit_insn_before_noloc, but set insn_locator according to scope. */ @@ -4482,6 +4510,7 @@ rtx set_unique_reg_note (rtx insn, enum reg_note kind, rtx datum) { rtx note = find_reg_note (insn, kind, NULL_RTX); + rtx new_note = NULL; switch (kind) { @@ -4501,19 +4530,37 @@ set_unique_reg_note (rtx insn, enum reg_note kind, rtx datum) It serves no useful purpose and breaks eliminate_regs. */ if (GET_CODE (datum) == ASM_OPERANDS) return NULL_RTX; + + if (note) + { + XEXP (note, 0) = datum; + df_notes_rescan (insn); + return note; + } break; default: + if (note) + { + XEXP (note, 0) = datum; + return note; + } break; } - if (note) + new_note = gen_rtx_EXPR_LIST (kind, datum, REG_NOTES (insn)); + REG_NOTES (insn) = new_note; + + switch (kind) { - XEXP (note, 0) = datum; - return note; + case REG_EQUAL: + case REG_EQUIV: + df_notes_rescan (insn); + break; + default: + break; } - REG_NOTES (insn) = gen_rtx_EXPR_LIST (kind, datum, REG_NOTES (insn)); return REG_NOTES (insn); } @@ -4787,11 +4834,7 @@ copy_insn_1 (rtx orig) break; case CONST: - /* CONST can be shared if it contains a SYMBOL_REF. If it contains - a LABEL_REF, it isn't sharable. */ - if (GET_CODE (XEXP (orig, 0)) == PLUS - && GET_CODE (XEXP (XEXP (orig, 0), 0)) == SYMBOL_REF - && GET_CODE (XEXP (XEXP (orig, 0), 1)) == CONST_INT) + if (shared_const_p (orig)) return orig; break; |