X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fcfgbuild.c;h=692fea8a17b3d87b1e7e6ef9b8a1f28228eb120c;hb=610928b8e49f37f69c44928401c26ab339dbb76d;hp=7d87a7a184e4ed619871b340014f545cd9abb531;hpb=e38def9ca7953bb5611d08ce8617249516ba5a99;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/cfgbuild.c b/gcc/cfgbuild.c index 7d87a7a184e..692fea8a17b 100644 --- a/gcc/cfgbuild.c +++ b/gcc/cfgbuild.c @@ -1,6 +1,6 @@ /* Control flow graph building code for GNU compiler. Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008 + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007, 2008, 2009, 2010 Free Software Foundation, Inc. This file is part of GCC. @@ -34,8 +34,9 @@ along with GCC; see the file COPYING3. If not see #include "function.h" #include "except.h" #include "expr.h" -#include "toplev.h" +#include "diagnostic-core.h" #include "timevar.h" +#include "sbitmap.h" static void make_edges (basic_block, basic_block, int); static void make_label_edge (sbitmap, basic_block, rtx, int); @@ -111,7 +112,7 @@ control_flow_insn_p (const_rtx insn) if (GET_CODE (PATTERN (insn)) == TRAP_IF && XEXP (PATTERN (insn), 0) == const1_rtx) return true; - if (!flag_non_call_exceptions) + if (!cfun->can_throw_non_call_exceptions) return false; break; @@ -303,6 +304,15 @@ make_edges (basic_block min, basic_block max, int update_p) else if (returnjump_p (insn)) cached_make_edge (edge_cache, bb, EXIT_BLOCK_PTR, 0); + /* Recognize asm goto and do the right thing. */ + else if ((tmp = extract_asm_operands (PATTERN (insn))) != NULL) + { + int i, n = ASM_OPERANDS_LABEL_LENGTH (tmp); + for (i = 0; i < n; ++i) + make_label_edge (edge_cache, bb, + XEXP (ASM_OPERANDS_LABEL (tmp, i), 0), 0); + } + /* Otherwise, we have a plain conditional or unconditional jump. */ else { @@ -323,23 +333,35 @@ make_edges (basic_block min, basic_block max, int update_p) handler for this CALL_INSN. If we're handling non-call exceptions then any insn can reach any of the active handlers. Also mark the CALL_INSN as reaching any nonlocal goto handler. */ - else if (code == CALL_INSN || flag_non_call_exceptions) + else if (code == CALL_INSN || cfun->can_throw_non_call_exceptions) { /* Add any appropriate EH edges. */ rtl_make_eh_edge (edge_cache, bb, insn); - if (code == CALL_INSN && nonlocal_goto_handler_labels) + if (code == CALL_INSN) { - /* ??? This could be made smarter: in some cases it's possible - to tell that certain calls will not do a nonlocal goto. - For example, if the nested functions that do the nonlocal - gotos do not have their addresses taken, then only calls to - those functions or to other nested functions that use them - could possibly do nonlocal gotos. */ if (can_nonlocal_goto (insn)) - for (x = nonlocal_goto_handler_labels; x; x = XEXP (x, 1)) - make_label_edge (edge_cache, bb, XEXP (x, 0), - EDGE_ABNORMAL | EDGE_ABNORMAL_CALL); + { + /* ??? This could be made smarter: in some cases it's + possible to tell that certain calls will not do a + nonlocal goto. For example, if the nested functions + that do the nonlocal gotos do not have their addresses + taken, then only calls to those functions or to other + nested functions that use them could possibly do + nonlocal gotos. */ + for (x = nonlocal_goto_handler_labels; x; x = XEXP (x, 1)) + make_label_edge (edge_cache, bb, XEXP (x, 0), + EDGE_ABNORMAL | EDGE_ABNORMAL_CALL); + } + + if (flag_tm) + { + rtx note; + for (note = REG_NOTES (insn); note; note = XEXP (note, 1)) + if (REG_NOTE_KIND (note) == REG_TM) + make_label_edge (edge_cache, bb, XEXP (note, 0), + EDGE_ABNORMAL | EDGE_ABNORMAL_CALL); + } } } @@ -468,6 +490,14 @@ find_bb_boundaries (basic_block bb) if (code == CODE_LABEL && LABEL_ALT_ENTRY_P (insn)) make_edge (ENTRY_BLOCK_PTR, bb, 0); } + else if (code == BARRIER) + { + /* __builtin_unreachable () may cause a barrier to be emitted in + the middle of a BB. We need to split it in the same manner as + if the barrier were preceded by a control_flow_insn_p insn. */ + if (!flow_transfer_insn) + flow_transfer_insn = prev_nonnote_insn_bb (insn); + } if (control_flow_insn_p (insn)) flow_transfer_insn = insn;