diff options
author | Zdenek Dvorak <dvorakz@suse.cz> | 2005-02-19 10:26:09 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2005-02-19 10:26:09 +0100 |
commit | f10a665465304f407bd6ad159b07e52b515c9f5e (patch) | |
tree | 2b023726d21f6bfcb73860fcbf31cc52aa54697e /gcc/tree-ssa-loop-im.c | |
parent | ad8228bd350b55db13960a809b9995ec9588605a (diff) | |
download | gcc-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.c | 44 |
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; } |