diff options
author | Andrew Hsieh <andrewhsieh@google.com> | 2013-01-22 14:53:50 -0800 |
---|---|---|
committer | Andrew Hsieh <andrewhsieh@google.com> | 2013-01-22 21:36:40 -0800 |
commit | 7f9f4477cbebb22723af8c0fac55aefc1228e02c (patch) | |
tree | fab0a353af6415f7b6ccdaecd35d0db4ad4eeae8 /gcc-4.7/gcc | |
parent | 4a0927423d51f594b870e58b3eb51574327f8b0e (diff) | |
download | toolchain_gcc-7f9f4477cbebb22723af8c0fac55aefc1228e02c.tar.gz toolchain_gcc-7f9f4477cbebb22723af8c0fac55aefc1228e02c.tar.bz2 toolchain_gcc-7f9f4477cbebb22723af8c0fac55aefc1228e02c.zip |
Fix x86 GCC4.7 segfault in i386.c distance_non_agu_define_in_bb()
line #16514 "if (prev == BB_HEAD(bb))" causes segfault due to bb==NULL
when compiling external/llvm/lib/Transforms/Scalar/SROA.cpp
BUG: 8047767
------------------------------------------------------------------
r186451 | vries | 2012-04-14 05:17:41 -0700 (Sat, 14 Apr 2012) | 13 lines
2012-04-14 Tom de Vries <tom@codesourcery.com>
* cfgcleanup.c (try_optimize_cfg): Replace call to delete_insn_chain by
call to delete_insn. Remove code to reorder BASIC_BLOCK note and
DELETED_LABEL note, and move it to ...
* cfgrtl.c (delete_insn): ... here. Change return type to void.
(delete_insn_and_edges): Likewise.
(delete_insn_chain): Handle new return type of delete_insn. Delete
chain backwards rather than forwards.
* rtl.h (delete_insn, delete_insn_and_edges): Change return type to
void.
* cfglayout.c (fixup_reorder_chain): Delete unused label.
Change-Id: Ibc069a4267d063586003d49a805fb794f4041465
Diffstat (limited to 'gcc-4.7/gcc')
-rw-r--r-- | gcc-4.7/gcc/cfgcleanup.c | 15 | ||||
-rw-r--r-- | gcc-4.7/gcc/cfglayout.c | 3 | ||||
-rw-r--r-- | gcc-4.7/gcc/cfgrtl.c | 41 | ||||
-rw-r--r-- | gcc-4.7/gcc/rtl.h | 4 |
4 files changed, 30 insertions, 33 deletions
diff --git a/gcc-4.7/gcc/cfgcleanup.c b/gcc-4.7/gcc/cfgcleanup.c index b59cf7bc9..fb90ef6f5 100644 --- a/gcc-4.7/gcc/cfgcleanup.c +++ b/gcc-4.7/gcc/cfgcleanup.c @@ -2632,20 +2632,7 @@ try_optimize_cfg (int mode) || ! label_is_jump_target_p (BB_HEAD (b), BB_END (single_pred (b))))) { - rtx label = BB_HEAD (b); - - delete_insn_chain (label, label, false); - /* If the case label is undeletable, move it after the - BASIC_BLOCK note. */ - if (NOTE_KIND (BB_HEAD (b)) == NOTE_INSN_DELETED_LABEL) - { - rtx bb_note = NEXT_INSN (BB_HEAD (b)); - - reorder_insns_nobb (label, label, bb_note); - BB_HEAD (b) = bb_note; - if (BB_END (b) == bb_note) - BB_END (b) = label; - } + delete_insn (BB_HEAD (b)); if (dump_file) fprintf (dump_file, "Deleted label in block %i.\n", b->index); diff --git a/gcc-4.7/gcc/cfglayout.c b/gcc-4.7/gcc/cfglayout.c index 22d3d87e6..c6e1f8324 100644 --- a/gcc-4.7/gcc/cfglayout.c +++ b/gcc-4.7/gcc/cfglayout.c @@ -857,6 +857,9 @@ fixup_reorder_chain (void) (e_taken->src, e_taken->dest)); e_taken->flags |= EDGE_FALLTHRU; update_br_prob_note (bb); + if (LABEL_NUSES (ret_label) == 0 + && single_pred_p (e_taken->dest)) + delete_insn (ret_label); continue; } } diff --git a/gcc-4.7/gcc/cfgrtl.c b/gcc-4.7/gcc/cfgrtl.c index 65a4ffcb4..79ceee5eb 100644 --- a/gcc-4.7/gcc/cfgrtl.c +++ b/gcc-4.7/gcc/cfgrtl.c @@ -111,12 +111,11 @@ can_delete_label_p (const_rtx label) && !in_expr_list_p (forced_labels, label)); } -/* Delete INSN by patching it out. Return the next insn. */ +/* Delete INSN by patching it out. */ -rtx +void delete_insn (rtx insn) { - rtx next = NEXT_INSN (insn); rtx note; bool really_delete = true; @@ -128,11 +127,22 @@ delete_insn (rtx insn) if (! can_delete_label_p (insn)) { const char *name = LABEL_NAME (insn); + basic_block bb = BLOCK_FOR_INSN (insn); + rtx bb_note = NEXT_INSN (insn); really_delete = false; PUT_CODE (insn, NOTE); NOTE_KIND (insn) = NOTE_INSN_DELETED_LABEL; NOTE_DELETED_LABEL_NAME (insn) = name; + + if (bb_note != NULL_RTX && NOTE_INSN_BASIC_BLOCK_P (bb_note) + && BLOCK_FOR_INSN (bb_note) == bb) + { + reorder_insns_nobb (insn, insn, bb_note); + BB_HEAD (bb) = bb_note; + if (BB_END (bb) == bb_note) + BB_END (bb) = insn; + } } remove_node_from_expr_list (insn, &nonlocal_goto_handler_labels); @@ -190,26 +200,22 @@ delete_insn (rtx insn) LABEL_NUSES (label)--; } } - - return next; } /* Like delete_insn but also purge dead edges from BB. */ -rtx +void delete_insn_and_edges (rtx insn) { - rtx x; bool purge = false; if (INSN_P (insn) && BLOCK_FOR_INSN (insn) && BB_END (BLOCK_FOR_INSN (insn)) == insn) purge = true; - x = delete_insn (insn); + delete_insn (insn); if (purge) purge_dead_edges (BLOCK_FOR_INSN (insn)); - return x; } /* Unlink a chain of insns between START and FINISH, leaving notes @@ -219,25 +225,26 @@ delete_insn_and_edges (rtx insn) void delete_insn_chain (rtx start, rtx finish, bool clear_bb) { - rtx next; + rtx prev, current; /* Unchain the insns one by one. It would be quicker to delete all of these with a single unchaining, rather than one at a time, but we need to keep the NOTE's. */ + current = finish; while (1) { - next = NEXT_INSN (start); - if (NOTE_P (start) && !can_delete_note_p (start)) + prev = PREV_INSN (current); + if (NOTE_P (current) && !can_delete_note_p (current)) ; else - next = delete_insn (start); + delete_insn (current); - if (clear_bb && !INSN_DELETED_P (start)) - set_block_for_insn (start, NULL); + if (clear_bb && !INSN_DELETED_P (current)) + set_block_for_insn (current, NULL); - if (start == finish) + if (current == start) break; - start = next; + current = prev; } } diff --git a/gcc-4.7/gcc/rtl.h b/gcc-4.7/gcc/rtl.h index b1b681be5..5b43e05d4 100644 --- a/gcc-4.7/gcc/rtl.h +++ b/gcc-4.7/gcc/rtl.h @@ -2447,12 +2447,12 @@ extern void add_insn_before (rtx, rtx, struct basic_block_def *); extern void add_insn_after (rtx, rtx, struct basic_block_def *); extern void remove_insn (rtx); extern rtx emit (rtx); -extern rtx delete_insn (rtx); +extern void delete_insn (rtx); extern rtx entry_of_function (void); extern void emit_insn_at_entry (rtx); extern void delete_insn_chain (rtx, rtx, bool); extern rtx unlink_insn_chain (rtx, rtx); -extern rtx delete_insn_and_edges (rtx); +extern void delete_insn_and_edges (rtx); extern rtx gen_lowpart_SUBREG (enum machine_mode, rtx); extern rtx gen_const_mem (enum machine_mode, rtx); extern rtx gen_frame_mem (enum machine_mode, rtx); |