X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fcfgrtl.c;h=13e0e5c40d6c5242b9440640dde1f49659d718d4;hb=3fa661c420a097dd38a7a231c5df9b0a8b8a28ec;hp=4c4b3b72cc76acf6de88bb02e613033881c9785d;hpb=9845d1202fec65574ca05d780859eb8c25489566;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c index 4c4b3b72cc7..13e0e5c40d6 100644 --- a/gcc/cfgrtl.c +++ b/gcc/cfgrtl.c @@ -1,6 +1,6 @@ /* Control flow graph manipulation code for GNU compiler. Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. This file is part of GCC. @@ -433,7 +433,7 @@ struct rtl_opt_pass pass_free_cfg = { { RTL_PASS, - NULL, /* name */ + "*free_cfg", /* name */ NULL, /* gate */ rest_of_pass_free_cfg, /* execute */ NULL, /* sub */ @@ -470,7 +470,7 @@ emit_insn_at_entry (rtx insn) } /* Update BLOCK_FOR_INSN of insns between BEGIN and END - (or BARRIER if found) and notify df of the bb change. + (or BARRIER if found) and notify df of the bb change. The insn chain range is inclusive (i.e. both BEGIN and END will be updated. */ @@ -956,6 +956,45 @@ patch_jump_insn (rtx insn, rtx old_label, basic_block new_bb) ++LABEL_NUSES (new_label); } } + else if ((tmp = extract_asm_operands (PATTERN (insn))) != NULL) + { + int i, n = ASM_OPERANDS_LABEL_LENGTH (tmp); + rtx new_label, note; + + if (new_bb == EXIT_BLOCK_PTR) + return false; + new_label = block_label (new_bb); + + for (i = 0; i < n; ++i) + { + rtx old_ref = ASM_OPERANDS_LABEL (tmp, i); + gcc_assert (GET_CODE (old_ref) == LABEL_REF); + if (XEXP (old_ref, 0) == old_label) + { + ASM_OPERANDS_LABEL (tmp, i) + = gen_rtx_LABEL_REF (Pmode, new_label); + --LABEL_NUSES (old_label); + ++LABEL_NUSES (new_label); + } + } + + if (JUMP_LABEL (insn) == old_label) + { + JUMP_LABEL (insn) = new_label; + note = find_reg_note (insn, REG_LABEL_TARGET, new_label); + if (note) + remove_note (insn, note); + } + else + { + note = find_reg_note (insn, REG_LABEL_TARGET, old_label); + if (note) + remove_note (insn, note); + if (JUMP_LABEL (insn) != new_label + && !find_reg_note (insn, REG_LABEL_TARGET, new_label)) + add_reg_note (insn, REG_LABEL_TARGET, new_label); + } + } else { /* ?? We may play the games with moving the named labels from @@ -1217,7 +1256,7 @@ force_nonfallthru_and_redirect (edge e, basic_block target) if (abnormal_edge_flags) make_edge (src, target, abnormal_edge_flags); - df_mark_solutions_dirty (); + df_mark_solutions_dirty (); return new_bb; } @@ -1465,24 +1504,11 @@ commit_one_edge_insertion (edge e) && targetm.have_named_sections && e->src != ENTRY_BLOCK_PTR && BB_PARTITION (e->src) == BB_COLD_PARTITION - && !(e->flags & EDGE_CROSSING)) - { - rtx bb_note, cur_insn; - - bb_note = NULL_RTX; - for (cur_insn = BB_HEAD (bb); cur_insn != NEXT_INSN (BB_END (bb)); - cur_insn = NEXT_INSN (cur_insn)) - if (NOTE_INSN_BASIC_BLOCK_P (cur_insn)) - { - bb_note = cur_insn; - break; - } - - if (JUMP_P (BB_END (bb)) - && !any_condjump_p (BB_END (bb)) - && (single_succ_edge (bb)->flags & EDGE_CROSSING)) - add_reg_note (BB_END (bb), REG_CROSSING_JUMP, NULL_RTX); - } + && !(e->flags & EDGE_CROSSING) + && JUMP_P (after) + && !any_condjump_p (after) + && (single_succ_edge (bb)->flags & EDGE_CROSSING)) + add_reg_note (after, REG_CROSSING_JUMP, NULL_RTX); } } @@ -1586,7 +1612,7 @@ rtl_dump_bb (basic_block bb, FILE *outf, int indent, int flags ATTRIBUTE_UNUSED) s_indent = (char *) alloca ((size_t) indent + 1); memset (s_indent, ' ', (size_t) indent); s_indent[indent] = '\0'; - + if (df) { df_dump_top (bb, outf); @@ -1653,7 +1679,7 @@ print_rtl_with_bb (FILE *outf, const_rtx rtx_first) { edge e; edge_iterator ei; - + fprintf (outf, ";; Start of basic block ("); FOR_EACH_EDGE (e, ei, bb->preds) fprintf (outf, " %d", e->src->index); @@ -1873,12 +1899,16 @@ rtl_verify_flow_info_1 (void) n_abnormal++; } - if (n_eh && GET_CODE (PATTERN (BB_END (bb))) != RESX - && !find_reg_note (BB_END (bb), REG_EH_REGION, NULL_RTX)) + if (n_eh && !find_reg_note (BB_END (bb), REG_EH_REGION, NULL_RTX)) { error ("missing REG_EH_REGION note in the end of bb %i", bb->index); err = 1; } + if (n_eh > 1) + { + error ("too many eh edges %i", bb->index); + err = 1; + } if (n_branch && (!JUMP_P (BB_END (bb)) || (n_branch > 1 && (any_uncondjump_p (BB_END (bb)) @@ -1894,7 +1924,8 @@ rtl_verify_flow_info_1 (void) } if (n_branch != 1 && any_uncondjump_p (BB_END (bb))) { - error ("wrong amount of branch edges after unconditional jump %i", bb->index); + error ("wrong number of branch edges after unconditional jump %i", + bb->index); err = 1; } if (n_branch != 1 && any_condjump_p (BB_END (bb)) @@ -2217,39 +2248,33 @@ purge_dead_edges (basic_block bb) /* Cleanup abnormal edges caused by exceptions or non-local gotos. */ for (ei = ei_start (bb->succs); (e = ei_safe_edge (ei)); ) { + bool remove = false; + /* There are three types of edges we need to handle correctly here: EH edges, abnormal call EH edges, and abnormal call non-EH edges. The latter can appear when nonlocal gotos are used. */ - if (e->flags & EDGE_EH) + if (e->flags & EDGE_ABNORMAL_CALL) { - if (can_throw_internal (insn) - /* If this is a call edge, verify that this is a call insn. */ - && (! (e->flags & EDGE_ABNORMAL_CALL) - || CALL_P (insn))) - { - ei_next (&ei); - continue; - } + if (!CALL_P (insn)) + remove = true; + else if (can_nonlocal_goto (insn)) + ; + else if ((e->flags & EDGE_EH) && can_throw_internal (insn)) + ; + else + remove = true; } - else if (e->flags & EDGE_ABNORMAL_CALL) + else if (e->flags & EDGE_EH) + remove = !can_throw_internal (insn); + + if (remove) { - if (CALL_P (insn) - && (! (note = find_reg_note (insn, REG_EH_REGION, NULL)) - || INTVAL (XEXP (note, 0)) >= 0)) - { - ei_next (&ei); - continue; - } + remove_edge (e); + df_set_bb_dirty (bb); + purged = true; } else - { - ei_next (&ei); - continue; - } - - remove_edge (e); - df_set_bb_dirty (bb); - purged = true; + ei_next (&ei); } if (JUMP_P (insn)) @@ -3000,7 +3025,7 @@ rtl_lv_add_condition_to_bb (basic_block first_head , op0 = force_operand (op0, NULL_RTX); op1 = force_operand (op1, NULL_RTX); do_compare_rtx_and_jump (op0, op1, comp, 0, - mode, NULL_RTX, NULL_RTX, label); + mode, NULL_RTX, NULL_RTX, label, -1); jump = get_last_insn (); JUMP_LABEL (jump) = label; LABEL_NUSES (label)++;