summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2016-07-14 13:52:21 +0000
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2016-07-14 13:52:21 +0000
commit531f0ff8f6e986e340d9df9601a658a4ef03edf0 (patch)
treec64e3b6ecc0d7508eecfd453d8dd19500d078863 /gcc
parentd1242c9468f2504d4eba69a2009293706d390ff9 (diff)
downloadgcc-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/ChangeLog8
-rw-r--r--gcc/gimple.h1
-rw-r--r--gcc/tree-cfg.c24
-rw-r--r--gcc/tree-ssa-loop-niter.c14
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);