From f39e46bac1fa7fa916b9d415d323fa7353c5e91a Mon Sep 17 00:00:00 2001 From: Steven Bosscher Date: Wed, 24 Nov 2004 11:32:24 +0000 Subject: cfgrtl.c (rtl_delete_block): Fix comment. * cfgrtl.c (rtl_delete_block): Fix comment. * emit-rtl.c (remove_unnecessary_notes): Die if we see BLOCK_BEG or BLOCK_END insn notes. * jump.c (squeeze_notes): Likewise. * haifa-sched.c (reemit_notes): Don't "re-emit" EH_REGION_BEG and EH_REGION_END notes, we never have them to begin with. * sched-deps.c (sched_analyze_insn): When updating loop notes, verify that we have indeed only recorded loop notes. (sched_analyze): Die if we see EH_REGION_BEG or EH_REGION_END notes. Only record loop notes. * cfgexpand.c (tree_expand_cfg): Fix comment. * passes.c (rest_of_compilation): Don't do a second call to convert_from_eh_region_ranges from here, it's already called from cfgexpand.c. * except.c (resolve_fixup_regions): Remove. (remove_fixup_regions): Remove. (convert_from_eh_region_ranges_1): Remove. (convert_from_eh_region_ranges): Remove the case where EH is not already lowered at the tree level. We always lower there. From-SVN: r91148 --- gcc/ChangeLog | 25 +++++- gcc/cfgexpand.c | 4 +- gcc/cfgrtl.c | 9 +-- gcc/emit-rtl.c | 62 ++------------- gcc/except.c | 230 +++--------------------------------------------------- gcc/haifa-sched.c | 5 -- gcc/jump.c | 4 + gcc/passes.c | 4 - gcc/sched-deps.c | 35 +++------ 9 files changed, 60 insertions(+), 318 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0e96f07..e9e7ebc 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,7 +1,30 @@ +2004-11-24 Steven Bosscher + + * cfgrtl.c (rtl_delete_block): Fix comment. + * emit-rtl.c (remove_unnecessary_notes): Die if we see BLOCK_BEG + or BLOCK_END insn notes. + * jump.c (squeeze_notes): Likewise. + * haifa-sched.c (reemit_notes): Don't "re-emit" EH_REGION_BEG and + EH_REGION_END notes, we never have them to begin with. + * sched-deps.c (sched_analyze_insn): When updating loop notes, + verify that we have indeed only recorded loop notes. + (sched_analyze): Die if we see EH_REGION_BEG or EH_REGION_END notes. + Only record loop notes. + + * cfgexpand.c (tree_expand_cfg): Fix comment. + + * passes.c (rest_of_compilation): Don't do a second call to + convert_from_eh_region_ranges from here, it's already called + from cfgexpand.c. + * except.c (resolve_fixup_regions): Remove. + (remove_fixup_regions): Remove. + (convert_from_eh_region_ranges_1): Remove. + (convert_from_eh_region_ranges): Remove the case where EH is + not already lowered at the tree level. We always lower there. + 2004-11-24 Paolo Bonzini PR c++/16882 - * tree.c (make_vector_type): Move qualifiers to the vector type, use the inner type's main variant and build a main variant for the vector type if necessary. diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index df0c695..f710aed 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -1310,8 +1310,8 @@ tree_expand_cfg (void) /* We're done expanding trees to RTL. */ currently_expanding_to_rtl = 0; - /* Convert from NOTE_INSN_EH_REGION style notes, and do other - sorts of eh initialization. */ + /* Convert tree EH labels to RTL EH labels, and clean out any unreachable + EH regions. */ convert_from_eh_region_ranges (); rebuild_jump_labels (get_insns ()); diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c index 0bb181a..3c2dc96 100644 --- a/gcc/cfgrtl.c +++ b/gcc/cfgrtl.c @@ -368,14 +368,9 @@ rtl_delete_block (basic_block b) rtx insn, end, tmp; /* If the head of this block is a CODE_LABEL, then it might be the - label for an exception handler which can't be reached. - - We need to remove the label from the exception_handler_label list - and remove the associated NOTE_INSN_EH_REGION_BEG and - NOTE_INSN_EH_REGION_END notes. */ - + label for an exception handler which can't be reached. We need + to remove the label from the exception_handler_label list. */ insn = BB_HEAD (b); - if (LABEL_P (insn)) maybe_remove_eh_handler (insn); diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index 98dec5f..fba2412 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -3728,7 +3728,6 @@ find_line_note (rtx insn) void remove_unnecessary_notes (void) { - rtx block_stack = NULL_RTX; rtx eh_stack = NULL_RTX; rtx insn; rtx next; @@ -3767,66 +3766,17 @@ remove_unnecessary_notes (void) break; case NOTE_INSN_BLOCK_BEG: - /* By now, all notes indicating lexical blocks should have - NOTE_BLOCK filled in. */ - gcc_assert (NOTE_BLOCK (insn)); - block_stack = alloc_INSN_LIST (insn, block_stack); - break; - case NOTE_INSN_BLOCK_END: - /* Too many end notes. */ - gcc_assert (block_stack); - /* Mismatched nesting. */ - gcc_assert (NOTE_BLOCK (XEXP (block_stack, 0)) == NOTE_BLOCK (insn)); - tmp = block_stack; - block_stack = XEXP (block_stack, 1); - free_INSN_LIST_node (tmp); + /* BLOCK_END and BLOCK_BEG notes only exist in the `final' pass. */ + gcc_unreachable (); - /* Scan back to see if there are any non-note instructions - between INSN and the beginning of this block. If not, - then there is no PC range in the generated code that will - actually be in this block, so there's no point in - remembering the existence of the block. */ - for (tmp = PREV_INSN (insn); tmp; tmp = PREV_INSN (tmp)) - { - /* This block contains a real instruction. Note that we - don't include labels; if the only thing in the block - is a label, then there are still no PC values that - lie within the block. */ - if (INSN_P (tmp)) - break; - - /* We're only interested in NOTEs. */ - if (!NOTE_P (tmp)) - continue; - - if (NOTE_LINE_NUMBER (tmp) == NOTE_INSN_BLOCK_BEG) - { - /* We just verified that this BLOCK matches us with - the block_stack check above. Never delete the - BLOCK for the outermost scope of the function; we - can refer to names from that scope even if the - block notes are messed up. */ - if (! is_body_block (NOTE_BLOCK (insn)) - && (*debug_hooks->ignore_block) (NOTE_BLOCK (insn))) - { - remove_insn (tmp); - remove_insn (insn); - } - break; - } - else if (NOTE_LINE_NUMBER (tmp) == NOTE_INSN_BLOCK_END) - /* There's a nested block. We need to leave the - current block in place since otherwise the debugger - wouldn't be able to show symbols from our block in - the nested block. */ - break; - } + default: + break; } } - /* Too many begin notes. */ - gcc_assert (!block_stack && !eh_stack); + /* Too many EH_REGION_BEG notes. */ + gcc_assert (!eh_stack); } diff --git a/gcc/except.c b/gcc/except.c index c399eb1..b906cf0 100644 --- a/gcc/except.c +++ b/gcc/except.c @@ -260,10 +260,7 @@ static hashval_t t2r_hash (const void *); static void add_type_for_runtime (tree); static tree lookup_type_for_runtime (tree); -static void resolve_fixup_regions (void); -static void remove_fixup_regions (void); static void remove_unreachable_regions (rtx); -static void convert_from_eh_region_ranges_1 (rtx *, int *, int); static int ttypes_filter_eq (const void *, const void *); static hashval_t ttypes_filter_hash (const void *); @@ -668,123 +665,6 @@ collect_eh_region_array (void) } } -static void -resolve_one_fixup_region (struct eh_region *fixup) -{ - struct eh_region *cleanup, *real; - int j, n; - - n = cfun->eh->last_region_number; - cleanup = 0; - - for (j = 1; j <= n; ++j) - { - cleanup = cfun->eh->region_array[j]; - if (cleanup && cleanup->type == ERT_CLEANUP - && cleanup->u.cleanup.exp == fixup->u.fixup.cleanup_exp) - break; - } - gcc_assert (j <= n); - - real = cleanup->outer; - if (real && real->type == ERT_FIXUP) - { - if (!real->u.fixup.resolved) - resolve_one_fixup_region (real); - real = real->u.fixup.real_region; - } - - fixup->u.fixup.real_region = real; - fixup->u.fixup.resolved = true; -} - -static void -resolve_fixup_regions (void) -{ - int i, n = cfun->eh->last_region_number; - - for (i = 1; i <= n; ++i) - { - struct eh_region *fixup = cfun->eh->region_array[i]; - - if (!fixup || fixup->type != ERT_FIXUP || fixup->u.fixup.resolved) - continue; - - resolve_one_fixup_region (fixup); - } -} - -/* Now that we've discovered what region actually encloses a fixup, - we can shuffle pointers and remove them from the tree. */ - -static void -remove_fixup_regions (void) -{ - int i; - rtx insn, note; - struct eh_region *fixup; - - /* Walk the insn chain and adjust the REG_EH_REGION numbers - for instructions referencing fixup regions. This is only - strictly necessary for fixup regions with no parent, but - doesn't hurt to do it for all regions. */ - for (insn = get_insns(); insn ; insn = NEXT_INSN (insn)) - if (INSN_P (insn) - && (note = find_reg_note (insn, REG_EH_REGION, NULL)) - && INTVAL (XEXP (note, 0)) > 0 - && (fixup = cfun->eh->region_array[INTVAL (XEXP (note, 0))]) - && fixup->type == ERT_FIXUP) - { - if (fixup->u.fixup.real_region) - XEXP (note, 0) = GEN_INT (fixup->u.fixup.real_region->region_number); - else - remove_note (insn, note); - } - - /* Remove the fixup regions from the tree. */ - for (i = cfun->eh->last_region_number; i > 0; --i) - { - fixup = cfun->eh->region_array[i]; - if (! fixup) - continue; - - /* Allow GC to maybe free some memory. */ - if (fixup->type == ERT_CLEANUP) - fixup->u.cleanup.exp = NULL_TREE; - - if (fixup->type != ERT_FIXUP) - continue; - - if (fixup->inner) - { - struct eh_region *parent, *p, **pp; - - parent = fixup->u.fixup.real_region; - - /* Fix up the children's parent pointers; find the end of - the list. */ - for (p = fixup->inner; ; p = p->next_peer) - { - p->outer = parent; - if (! p->next_peer) - break; - } - - /* In the tree of cleanups, only outer-inner ordering matters. - So link the children back in anywhere at the correct level. */ - if (parent) - pp = &parent->inner; - else - pp = &cfun->eh->region_tree; - p->next_peer = *pp; - *pp = fixup->inner; - fixup->inner = NULL; - } - - remove_eh_handler (fixup); - } -} - /* Remove all regions whose labels are not reachable from insns. */ static void @@ -868,113 +748,23 @@ remove_unreachable_regions (rtx insns) free (uid_region_num); } -/* Turn NOTE_INSN_EH_REGION notes into REG_EH_REGION notes for each - can_throw instruction in the region. */ - -static void -convert_from_eh_region_ranges_1 (rtx *pinsns, int *orig_sp, int cur) -{ - int *sp = orig_sp; - rtx insn, next; - - for (insn = *pinsns; insn ; insn = next) - { - next = NEXT_INSN (insn); - if (NOTE_P (insn)) - { - int kind = NOTE_LINE_NUMBER (insn); - if (kind == NOTE_INSN_EH_REGION_BEG - || kind == NOTE_INSN_EH_REGION_END) - { - if (kind == NOTE_INSN_EH_REGION_BEG) - { - struct eh_region *r; - - *sp++ = cur; - cur = NOTE_EH_HANDLER (insn); - - r = cfun->eh->region_array[cur]; - if (r->type == ERT_FIXUP) - { - r = r->u.fixup.real_region; - cur = r ? r->region_number : 0; - } - else if (r->type == ERT_CATCH) - { - r = r->outer; - cur = r ? r->region_number : 0; - } - } - else - cur = *--sp; - - if (insn == *pinsns) - *pinsns = next; - remove_insn (insn); - continue; - } - } - else if (INSN_P (insn)) - { - if (cur > 0 - && ! find_reg_note (insn, REG_EH_REGION, NULL_RTX) - /* Calls can always potentially throw exceptions, unless - they have a REG_EH_REGION note with a value of 0 or less. - Which should be the only possible kind so far. */ - && (CALL_P (insn) - /* If we wanted exceptions for non-call insns, then - any may_trap_p instruction could throw. */ - || (flag_non_call_exceptions - && GET_CODE (PATTERN (insn)) != CLOBBER - && GET_CODE (PATTERN (insn)) != USE - && may_trap_p (PATTERN (insn))))) - { - REG_NOTES (insn) = alloc_EXPR_LIST (REG_EH_REGION, GEN_INT (cur), - REG_NOTES (insn)); - } - } - } - - gcc_assert (sp == orig_sp); -} - -static void -collect_rtl_labels_from_trees (void) -{ - int i, n = cfun->eh->last_region_number; - for (i = 1; i <= n; ++i) - { - struct eh_region *reg = cfun->eh->region_array[i]; - if (reg && reg->tree_label) - reg->label = DECL_RTL_IF_SET (reg->tree_label); - } -} +/* Set up EH labels for RTL. */ void convert_from_eh_region_ranges (void) { rtx insns = get_insns (); + int i, n = cfun->eh->last_region_number; - if (cfun->eh->region_array) - { - /* If the region array already exists, assume we're coming from - optimize_function_tree. In this case all we need to do is - collect the rtl labels that correspond to the tree labels - that we allocated earlier. */ - collect_rtl_labels_from_trees (); - } - else + /* Most of the work is already done at the tree level. All we need to + do is collect the rtl labels that correspond to the tree labels that + collect the rtl labels that correspond to the tree labels + we allocated earlier. */ + for (i = 1; i <= n; ++i) { - int *stack; - - collect_eh_region_array (); - resolve_fixup_regions (); - - stack = xmalloc (sizeof (int) * (cfun->eh->last_region_number + 1)); - convert_from_eh_region_ranges_1 (&insns, stack, 0); - free (stack); - - remove_fixup_regions (); + struct eh_region *region = cfun->eh->region_array[i]; + if (region && region->tree_label) + region->label = DECL_RTL_IF_SET (region->tree_label); } remove_unreachable_regions (insns); diff --git a/gcc/haifa-sched.c b/gcc/haifa-sched.c index d413137..9b3ed5e 100644 --- a/gcc/haifa-sched.c +++ b/gcc/haifa-sched.c @@ -1648,11 +1648,6 @@ reemit_notes (rtx insn, rtx last) last = emit_note_before (note_type, last); remove_note (insn, note); - note = XEXP (note, 1); - if (note_type == NOTE_INSN_EH_REGION_BEG - || note_type == NOTE_INSN_EH_REGION_END) - NOTE_EH_HANDLER (last) = INTVAL (XEXP (note, 0)); - remove_note (insn, note); } } return retval; diff --git a/gcc/jump.c b/gcc/jump.c index 0378cf7..85c1f6b2 100644 --- a/gcc/jump.c +++ b/gcc/jump.c @@ -248,6 +248,10 @@ squeeze_notes (rtx* startp, rtx* endp) || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END)) { + /* BLOCK_BEG or BLOCK_END notes only exist in the `final' pass. */ + gcc_assert (NOTE_LINE_NUMBER (insn) != NOTE_INSN_BLOCK_BEG + && NOTE_LINE_NUMBER (insn) != NOTE_INSN_BLOCK_END); + if (insn == start) start = next; else diff --git a/gcc/passes.c b/gcc/passes.c index 36b13d1..37e84c8 100644 --- a/gcc/passes.c +++ b/gcc/passes.c @@ -1538,10 +1538,6 @@ rest_of_clean_state (void) static void rest_of_compilation (void) { - /* Convert from NOTE_INSN_EH_REGION style notes, and do other - sorts of eh initialization. */ - convert_from_eh_region_ranges (); - /* If we're emitting a nested function, make sure its parent gets emitted as well. Doing otherwise confuses debug info. */ { diff --git a/gcc/sched-deps.c b/gcc/sched-deps.c index 5e23a93..32d0fdb 100644 --- a/gcc/sched-deps.c +++ b/gcc/sched-deps.c @@ -976,18 +976,14 @@ sched_analyze_insn (struct deps *deps, rtx x, rtx insn, rtx loop_notes) { rtx link; - /* Update loop_notes with any notes from this insn. Also determine - if any of the notes on the list correspond to instruction scheduling - barriers (loop, eh & setjmp notes, but not range notes). */ + /* Update loop_notes with any notes from this insn. */ link = loop_notes; while (XEXP (link, 1)) { - if (INTVAL (XEXP (link, 0)) == NOTE_INSN_LOOP_BEG - || INTVAL (XEXP (link, 0)) == NOTE_INSN_LOOP_END - || INTVAL (XEXP (link, 0)) == NOTE_INSN_EH_REGION_BEG - || INTVAL (XEXP (link, 0)) == NOTE_INSN_EH_REGION_END) - reg_pending_barrier = MOVE_BARRIER; + gcc_assert (INTVAL (XEXP (link, 0)) == NOTE_INSN_LOOP_BEG + || INTVAL (XEXP (link, 0)) == NOTE_INSN_LOOP_END); + reg_pending_barrier = MOVE_BARRIER; link = XEXP (link, 1); } XEXP (link, 1) = REG_NOTES (insn); @@ -1323,26 +1319,19 @@ sched_analyze (struct deps *deps, rtx head, rtx tail) deps->in_post_call_group_p = post_call; } + /* EH_REGION insn notes can not appear until well after we complete + scheduling. */ + if (NOTE_P (insn)) + gcc_assert (NOTE_LINE_NUMBER (insn) != NOTE_INSN_EH_REGION_BEG + && NOTE_LINE_NUMBER (insn) != NOTE_INSN_EH_REGION_END); + /* See comments on reemit_notes as to why we do this. ??? Actually, the reemit_notes just say what is done, not why. */ if (NOTE_P (insn) - && (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG - || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END - || NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG - || NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END)) + && (NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_BEG + || NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END)) { - rtx rtx_region; - - if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_BEG - || NOTE_LINE_NUMBER (insn) == NOTE_INSN_EH_REGION_END) - rtx_region = GEN_INT (NOTE_EH_HANDLER (insn)); - else - rtx_region = const0_rtx; - - loop_notes = alloc_EXPR_LIST (REG_SAVE_NOTE, - rtx_region, - loop_notes); loop_notes = alloc_EXPR_LIST (REG_SAVE_NOTE, GEN_INT (NOTE_LINE_NUMBER (insn)), loop_notes); -- cgit v1.1