2008-10-09 Jakub Jelinek * rtl.h (locator_eq): New decl. * cfglayout.c (locator_scope): New function. (insn_scope): Use it. (locator_eq): New function. (fixup_reorder_chain): Search for last insn in src bb that has locator set or first insn in dest bb. Use locator_eq instead of == to compare locators. * cfgrtl.c (cfg_layout_merge_blocks): Likewise. * cfgcleanup.c (try_forward_edges): Use locator_eq instead of == to compare locators. --- gcc/cfglayout.c.jj 2008-10-07 21:35:33.000000000 +0200 +++ gcc/cfglayout.c 2008-10-09 11:18:51.000000000 +0200 @@ -448,13 +448,12 @@ change_scope (rtx orig_insn, tree s1, tr } } -/* Return lexical scope block insn belong to. */ +/* Return lexical scope block locator belongs to. */ static tree -insn_scope (const_rtx insn) +locator_scope (int loc) { int max = VEC_length (int, block_locators_locs); int min = 0; - int loc = INSN_LOCATOR (insn); /* When block_locators_locs was initialized, the pro- and epilogue insns didn't exist yet and can therefore not be found this way. @@ -488,6 +487,13 @@ insn_scope (const_rtx insn) return VEC_index (tree, block_locators_blocks, min); } +/* Return lexical scope block insn belongs to. */ +static tree +insn_scope (const_rtx insn) +{ + return locator_scope (INSN_LOCATOR (insn)); +} + /* Return line number of the statement specified by the locator. */ static location_t locator_location (int loc) @@ -551,6 +557,17 @@ insn_file (const_rtx insn) return locator_file (INSN_LOCATOR (insn)); } +/* Return true if LOC1 and LOC2 locators have the same location and scope. */ +bool +locator_eq (int loc1, int loc2) +{ + if (loc1 == loc2) + return true; + if (locator_location (loc1) != locator_location (loc2)) + return false; + return locator_scope (loc1) == locator_scope (loc2); +} + /* Rebuild all the NOTE_INSN_BLOCK_BEG and NOTE_INSN_BLOCK_END notes based on the scope tree and the newly reordered instructions. */ @@ -901,24 +918,30 @@ fixup_reorder_chain (void) if (e->goto_locus && !(e->flags & EDGE_ABNORMAL)) { basic_block nb; + rtx end; - if (simplejump_p (BB_END (e->src))) + insn = BB_END (e->src); + end = PREV_INSN (BB_HEAD (e->src)); + while (insn != end + && (!INSN_P (insn) || INSN_LOCATOR (insn) == 0)) + insn = PREV_INSN (insn); + if (insn != end + && locator_eq (INSN_LOCATOR (insn), (int) e->goto_locus)) + continue; + if (simplejump_p (BB_END (e->src)) + && INSN_LOCATOR (BB_END (e->src)) == 0) { - if (INSN_LOCATOR (BB_END (e->src)) == (int) e->goto_locus) - continue; - if (INSN_LOCATOR (BB_END (e->src)) == 0) - { - INSN_LOCATOR (BB_END (e->src)) = e->goto_locus; - continue; - } + INSN_LOCATOR (BB_END (e->src)) = e->goto_locus; + continue; } if (e->dest != EXIT_BLOCK_PTR) { insn = BB_HEAD (e->dest); - if (!INSN_P (insn)) - insn = next_insn (insn); - if (insn && INSN_P (insn) - && INSN_LOCATOR (insn) == (int) e->goto_locus) + end = NEXT_INSN (BB_END (e->dest)); + while (insn != end && !INSN_P (insn)) + insn = NEXT_INSN (insn); + if (insn != end && INSN_LOCATOR (insn) + && locator_eq (INSN_LOCATOR (insn), (int) e->goto_locus)) continue; } nb = split_edge (e); --- gcc/rtl.h.jj 2008-10-07 21:25:44.000000000 +0200 +++ gcc/rtl.h 2008-10-09 11:15:57.000000000 +0200 @@ -1622,6 +1622,7 @@ extern int insn_line (const_rtx); extern const char * insn_file (const_rtx); extern int locator_line (int); extern const char * locator_file (int); +extern bool locator_eq (int, int); extern int prologue_locator, epilogue_locator; /* In jump.c */ --- gcc/cfgrtl.c.jj 2008-10-07 21:35:33.000000000 +0200 +++ gcc/cfgrtl.c 2008-10-09 10:37:03.000000000 +0200 @@ -2623,19 +2623,21 @@ cfg_layout_merge_blocks (basic_block a, some unique locus, emit a nop with that locus in between. */ if (!optimize && EDGE_SUCC (a, 0)->goto_locus) { - rtx insn = BB_END (a); + rtx insn = BB_END (a), end = PREV_INSN (BB_HEAD (a)); int goto_locus = EDGE_SUCC (a, 0)->goto_locus; - if (NOTE_P (insn)) - insn = prev_nonnote_insn (insn); - if (insn && INSN_P (insn) && INSN_LOCATOR (insn) == goto_locus) + while (insn != end && (!INSN_P (insn) || INSN_LOCATOR (insn) == 0)) + insn = PREV_INSN (insn); + if (insn != end && locator_eq (INSN_LOCATOR (insn), goto_locus)) goto_locus = 0; else { insn = BB_HEAD (b); - if (!INSN_P (insn)) - insn = next_insn (insn); - if (insn && INSN_P (insn) && INSN_LOCATOR (insn) == goto_locus) + end = NEXT_INSN (BB_END (b)); + while (insn != end && !INSN_P (insn)) + insn = NEXT_INSN (insn); + if (insn != end && INSN_LOCATOR (insn) != 0 + && locator_eq (INSN_LOCATOR (insn), goto_locus)) goto_locus = 0; } if (goto_locus) --- gcc/cfgcleanup.c.jj 2008-10-07 21:35:33.000000000 +0200 +++ gcc/cfgcleanup.c 2008-10-09 11:07:40.000000000 +0200 @@ -482,7 +482,7 @@ try_forward_edges (int mode, basic_block blocks with different locus are not optimized out. */ int locus = single_succ_edge (target)->goto_locus; - if (locus && goto_locus && locus != goto_locus) + if (locus && goto_locus && !locator_eq (locus, goto_locus)) counter = n_basic_blocks; else if (locus) goto_locus = locus; @@ -491,7 +491,8 @@ try_forward_edges (int mode, basic_block { locus = INSN_LOCATOR (BB_END (target)); - if (locus && goto_locus && locus != goto_locus) + if (locus && goto_locus + && !locator_eq (locus, goto_locus)) counter = n_basic_blocks; else if (locus) goto_locus = locus;