aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-loop-im.c
diff options
context:
space:
mode:
authorZdenek Dvorak <dvorakz@suse.cz>2005-02-19 10:26:09 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2005-02-19 10:26:09 +0100
commitf10a665465304f407bd6ad159b07e52b515c9f5e (patch)
tree2b023726d21f6bfcb73860fcbf31cc52aa54697e /gcc/tree-ssa-loop-im.c
parentad8228bd350b55db13960a809b9995ec9588605a (diff)
downloadgcc-f10a665465304f407bd6ad159b07e52b515c9f5e.zip
gcc-f10a665465304f407bd6ad159b07e52b515c9f5e.tar.gz
gcc-f10a665465304f407bd6ad159b07e52b515c9f5e.tar.bz2
re PR tree-optimization/19828 (LIM is pulling out a pure function even though there is something which can modify global memory)
PR tree-optimization/19828 * tree-ssa-loop-im.c: Add a TODO comment. (movement_possibility): Return MOVE_PRESERVE_EXECUTION for calls without side-effects. * gcc.dg/tree-ssa/loop-7.c: New test. * gcc.c-torture/execute/20050218-1.c: New test. Co-Authored-By: Jakub Jelinek <jakub@redhat.com> From-SVN: r95275
Diffstat (limited to 'gcc/tree-ssa-loop-im.c')
-rw-r--r--gcc/tree-ssa-loop-im.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/gcc/tree-ssa-loop-im.c b/gcc/tree-ssa-loop-im.c
index 65a2a5f..770b71b 100644
--- a/gcc/tree-ssa-loop-im.c
+++ b/gcc/tree-ssa-loop-im.c
@@ -38,6 +38,28 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "tree-pass.h"
#include "flags.h"
+/* TODO: Support for predicated code motion. I.e.
+
+ while (1)
+ {
+ if (cond)
+ {
+ a = inv;
+ something;
+ }
+ }
+
+ Where COND and INV are is invariants, but evaluating INV may trap or be
+ invalid from some other reason if !COND. This may be transformed to
+
+ if (cond)
+ a = inv;
+ while (1)
+ {
+ if (cond)
+ something;
+ } */
+
/* A type for the list of statements that have to be moved in order to be able
to hoist an invariant computation. */
@@ -227,6 +249,28 @@ movement_possibility (tree stmt)
|| tree_could_trap_p (rhs))
return MOVE_PRESERVE_EXECUTION;
+ if (get_call_expr_in (stmt))
+ {
+ /* While pure or const call is guaranteed to have no side effects, we
+ cannot move it arbitrarily. Consider code like
+
+ char *s = something ();
+
+ while (1)
+ {
+ if (s)
+ t = strlen (s);
+ else
+ t = 0;
+ }
+
+ Here the strlen call cannot be moved out of the loop, even though
+ s is invariant. In addition to possibly creating a call with
+ invalid arguments, moving out a function call that is not executed
+ may cause performance regressions in case the call is costly and
+ not executed at all. */
+ return MOVE_PRESERVE_EXECUTION;
+ }
return MOVE_POSSIBLE;
}