diff options
author | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-07-14 13:52:21 +0000 |
---|---|---|
committer | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2016-07-14 13:52:21 +0000 |
commit | 531f0ff8f6e986e340d9df9601a658a4ef03edf0 (patch) | |
tree | c64e3b6ecc0d7508eecfd453d8dd19500d078863 /gcc | |
parent | d1242c9468f2504d4eba69a2009293706d390ff9 (diff) | |
download | gcc-531f0ff8f6e986e340d9df9601a658a4ef03edf0.tar.gz |
* gimple.h (stmt_can_terminate_bb_p): New function.
* tree-cfg.c (need_fake_edge_p): Rename to ...
(stmt_can_terminate_bb_p): ... this; return true if stmt can
throw external; handle const and pure calls.
* tree-ssa-loop-niter.c (loop_only_exit_p): Use it.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@238336 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/gimple.h | 1 | ||||
-rw-r--r-- | gcc/tree-cfg.c | 24 | ||||
-rw-r--r-- | gcc/tree-ssa-loop-niter.c | 14 |
4 files changed, 29 insertions, 18 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 24b929812b6..5830663300f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2016-07-14 Jan Hubicka <hubicka@ucw.cz> + + * gimple.h (stmt_can_terminate_bb_p): New function. + * tree-cfg.c (need_fake_edge_p): Rename to ... + (stmt_can_terminate_bb_p): ... this; return true if stmt can + throw external; handle const and pure calls. + * tree-ssa-loop-niter.c (loop_only_exit_p): Use it. + 2016-07-14 Richard Biener <rguenther@suse.de> PR tree-optimization/71866 diff --git a/gcc/gimple.h b/gcc/gimple.h index 1da719c52e0..980bdf8314c 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -1526,6 +1526,7 @@ extern void gimple_seq_set_location (gimple_seq, location_t); extern void gimple_seq_discard (gimple_seq); extern void maybe_remove_unused_call_args (struct function *, gimple *); extern bool gimple_inexpensive_call_p (gcall *); +extern bool stmt_can_terminate_bb_p (gimple *); /* Formal (expression) temporary table handling: multiple occurrences of the same scalar expression are evaluated into the same temporary. */ diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 6d6943503fe..07280202ba3 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -7919,15 +7919,20 @@ gimple_block_ends_with_condjump_p (const_basic_block bb) } -/* Return true if we need to add fake edge to exit at statement T. - Helper function for gimple_flow_call_edges_add. */ +/* Return true if statement T may terminate execution of BB in ways not + explicitly represtented in the CFG. */ -static bool -need_fake_edge_p (gimple *t) +bool +stmt_can_terminate_bb_p (gimple *t) { tree fndecl = NULL_TREE; int call_flags = 0; + /* Eh exception not handled internally terminates execution of the whole + function. */ + if (stmt_can_throw_external (t)) + return true; + /* NORETURN and LONGJMP calls already have an edge to exit. CONST and PURE calls do not need one. We don't currently check for CONST and PURE here, although @@ -7960,6 +7965,13 @@ need_fake_edge_p (gimple *t) edge e; basic_block bb; + if (call_flags & (ECF_PURE | ECF_CONST) + && !(call_flags & ECF_LOOPING_CONST_OR_PURE)) + return false; + + /* Function call may do longjmp, terminate program or do other things. + Special case noreturn that have non-abnormal edges out as in this case + the fact is sufficiently represented by lack of edges out of T. */ if (!(call_flags & ECF_NORETURN)) return true; @@ -8024,7 +8036,7 @@ gimple_flow_call_edges_add (sbitmap blocks) if (!gsi_end_p (gsi)) t = gsi_stmt (gsi); - if (t && need_fake_edge_p (t)) + if (t && stmt_can_terminate_bb_p (t)) { edge e; @@ -8059,7 +8071,7 @@ gimple_flow_call_edges_add (sbitmap blocks) do { stmt = gsi_stmt (gsi); - if (need_fake_edge_p (stmt)) + if (stmt_can_terminate_bb_p (stmt)) { edge e; diff --git a/gcc/tree-ssa-loop-niter.c b/gcc/tree-ssa-loop-niter.c index 732e06a3553..182753cef3d 100644 --- a/gcc/tree-ssa-loop-niter.c +++ b/gcc/tree-ssa-loop-niter.c @@ -2159,7 +2159,6 @@ loop_only_exit_p (const struct loop *loop, const_edge exit) basic_block *body; gimple_stmt_iterator bsi; unsigned i; - gimple *call; if (exit != single_exit (loop)) return false; @@ -2168,17 +2167,8 @@ loop_only_exit_p (const struct loop *loop, const_edge exit) for (i = 0; i < loop->num_nodes; i++) { for (bsi = gsi_start_bb (body[i]); !gsi_end_p (bsi); gsi_next (&bsi)) - { - call = gsi_stmt (bsi); - if (gimple_code (call) != GIMPLE_CALL) - continue; - - if (gimple_has_side_effects (call)) - { - free (body); - return false; - } - } + if (stmt_can_terminate_bb_p (gsi_stmt (bsi))) + return true; } free (body); |