[Bug tree-optimization/61607] DOM missed jump threading and destroyed loops

2015-03-05 Thread yroux at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61607

--- Comment #11 from Yvan Roux  ---
Author: yroux
Date: Thu Mar  5 14:28:05 2015
New Revision: 221216

URL: https://gcc.gnu.org/viewcvs?rev=221216&root=gcc&view=rev
Log:
gcc/
2015-03-05  Yvan Roux  

Backport from trunk r212011, r214942, r214957, r215012, r215016, r218115,
r218733, r218746, r220491.
2015-02-06  Sebastian Pop  
Brian Rzycki  

PR tree-optimization/64878
* tree-ssa-threadedge.c: Include tree-ssa-loop.h.
(fsm_find_control_statement_thread_paths): Add parameter seen_loop_phi.
Stop recursion at loop phi nodes after having visited a loop phi node.

2014-12-15  Richard Biener  

PR middle-end/64246
* cfgloop.c (mark_loop_for_removal): Make safe against multiple
invocations on the same loop.

2014-12-15  Richard Biener  

PR tree-optimization/64284
* tree-ssa-threadupdate.c (duplicate_seme_region): Mark
the loop for removal if we copied the loop header.

2014-11-27  Richard Biener  

PR tree-optimization/64083
* tree-ssa-threadupdate.c (thread_through_all_blocks): Do not
forcibly mark loop for removal the wrong way.

2014-09-08  Richard Biener  

PR ipa/63196
* tree-inline.c (copy_loops): The source loop header should
always be non-NULL.
(tree_function_versioning): If loops need fixup after removing
unreachable blocks fix them.
* omp-low.c (simd_clone_adjust): Do not add incr block to
loop under construction.

2014-09-08  Richard Biener  

PR bootstrap/63204
* cfgloop.c (mark_loop_for_removal): Track former header
unconditionally.
* cfgloop.h (struct loop): Add former_header member unconditionally.
* loop-init.c (fix_loop_structure): Enable bogus loop removal
diagnostic unconditionally.

2014-09-05  Richard Biener  

* cfgloop.c (mark_loop_for_removal): Record former header
when ENABLE_CHECKING.
* cfgloop.h (strut loop): Add former_header member when
ENABLE_CHECKING.
* loop-init.c (fix_loop_structure): Sanity check loops
marked for removal if they re-appeared.

2014-09-05  Richard Biener  

* cfgloop.c (mark_loop_for_removal): New function.
* cfgloop.h (mark_loop_for_removal): Declare.
* cfghooks.c (delete_basic_block): Use mark_loop_for_removal.
(merge_blocks): Likewise.
(duplicate_block): Likewise.
* except.c (sjlj_emit_dispatch_table): Likewise.
* tree-eh.c (cleanup_empty_eh_merge_phis): Likewise.
* tree-ssa-threadupdate.c (ssa_redirect_edges): Likewise.
(thread_through_loop_header): Likewise.

2014-06-26  Richard Biener  

PR tree-optimization/61607
* tree-ssa-threadupdate.c (ssa_redirect_edges): Cancel the
loop if we redirected its latch edge.
(thread_block_1): Do not cancel loops prematurely.

gcc/testsuite/
2015-03-05  Yvan Roux  

Backport from trunk r218115, r218733, r218746, r220491.
2015-02-06  Sebastian Pop  
Brian Rzycki  

PR tree-optimization/64878
* testsuite/gcc.dg/tree-ssa/ssa-dom-thread-8.c: New.

2014-12-15  Richard Biener  

PR middle-end/64246
* gnat.dg/opt46.adb: New testcase.
* gnat.dg/opt46.ads: Likewise.
* gnat.dg/opt46_pkg.adb: Likewise.
* gnat.dg/opt46_pkg.ads: Likewise.

2014-12-15  Richard Biener  

PR tree-optimization/64284
* gcc.dg/torture/pr64284.c: New testcase.

2014-11-27  Richard Biener  

PR tree-optimization/64083
* gcc.dg/torture/pr64083.c: New testcase.


Added:
branches/linaro/gcc-4_9-branch/gcc/testsuite/gcc.dg/torture/pr64083.c
branches/linaro/gcc-4_9-branch/gcc/testsuite/gcc.dg/torture/pr64284.c
   
branches/linaro/gcc-4_9-branch/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-8.c
branches/linaro/gcc-4_9-branch/gcc/testsuite/gnat.dg/opt46.adb
branches/linaro/gcc-4_9-branch/gcc/testsuite/gnat.dg/opt46.ads
branches/linaro/gcc-4_9-branch/gcc/testsuite/gnat.dg/opt46_pkg.adb
branches/linaro/gcc-4_9-branch/gcc/testsuite/gnat.dg/opt46_pkg.ads
Modified:
branches/linaro/gcc-4_9-branch/gcc/ChangeLog.linaro
branches/linaro/gcc-4_9-branch/gcc/cfghooks.c
branches/linaro/gcc-4_9-branch/gcc/cfgloop.c
branches/linaro/gcc-4_9-branch/gcc/cfgloop.h
branches/linaro/gcc-4_9-branch/gcc/except.c
branches/linaro/gcc-4_9-branch/gcc/loop-init.c
branches/linaro/gcc-4_9-branch/gcc/omp-low.c
branches/linaro/gcc-4_9-branch/gcc/testsuite/ChangeLog.linaro
branches/linaro/gcc-4_9-branch/gcc/tree-eh.c
branches/linaro/gcc-4_9-branch/gcc/tree-inline.c
branches/linaro/gcc-4_9-branch/gcc/tree-ssa-threadedge.c
branches/linaro/gcc-4_9-branch/gcc/tree-ssa-threadupdate.c


[Bug tree-optimization/61607] DOM missed jump threading and destroyed loops

2014-06-29 Thread law at redhat dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61607

Jeffrey A. Law  changed:

   What|Removed |Added

 Status|UNCONFIRMED |RESOLVED
 Resolution|--- |FIXED

--- Comment #10 from Jeffrey A. Law  ---
Fixed by change to follow SSA_NAME_VALUE chains on the trunk + richi's
improvements.


[Bug tree-optimization/61607] DOM missed jump threading and destroyed loops

2014-06-27 Thread law at redhat dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61607

--- Comment #9 from Jeffrey A. Law  ---
So, the length of the SSA_NAME_VALUE chains is pretty much as expected.  The
overwhelming majority of the time there is nothing in the SSA_NAME_VALUE chain
or a single entry.  Then there's a very small percentage with a length of 2 and
roughly the same very small percentage that have a loop.

So we can reasonably iterate over the chain and break if we hit > 2 entries in
the chain.


[Bug tree-optimization/61607] DOM missed jump threading and destroyed loops

2014-06-27 Thread law at redhat dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61607

--- Comment #8 from Jeffrey A. Law  ---
FWIW, I vaguely recall experimenting with following the SSA_NAME_VALUE chains
in the past and having problems with cycles.  IIRC we can get cycles from
things like recording equivalences created by equality tests.

We could put a (small) upper limit on the number of SSA_NAME_VALUEs we walk. 
I'd expect the vast majority of the time we'd be walking just one node.  I
guess that's worth investigating.


[Bug tree-optimization/61607] DOM missed jump threading and destroyed loops

2014-06-26 Thread law at redhat dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61607

Jeffrey A. Law  changed:

   What|Removed |Added

 CC||law at redhat dot com

--- Comment #7 from Jeffrey A. Law  ---
In my testing, the missed thread is due to not following the chain of
SSA_NAME_VALUEs.  We ought to easily discover that the two conditionals outside
the loop are in fact equivalent and fully threadable.


With a quick hack to follow the chain of values we're able to trivially
discover both of the interesting jump threading opportunities:

k.c.079t.dom1:  Registering jump thread: (6, 7) incoming edge;  (7, 8) normal;
k.c.079t.dom1:  Registering jump thread: (5, 7) incoming edge;  (7, 9) normal;


[Bug tree-optimization/61607] DOM missed jump threading and destroyed loops

2014-06-26 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61607

--- Comment #6 from Richard Biener  ---
The bogus loop cancelling is fixed as well as the equivalence recording.  Still
DOM does

  Registering jump thread: (3, 4) incoming edge;  (4, 5) joiner;  (5, 6)
normal;
  Registering jump thread: (5, 7) incoming edge;  (7, 9) normal;
  Registering jump thread: (2, 4) incoming edge;  (4, 5) joiner;  (5, 7)
normal;
  Cancelling jump thread: (2, 4) incoming edge;  (4, 5) joiner;  (5, 7) normal;
  Threaded jump 5 --> 7 to 10

with result

  :
  # inter_I_lsm.3_24 = PHI 
  # inter_I_lsm.4_25 = PHI 
  # inter_I_lsm.5_26 = PHI 
  # inter_I_lsm.6_27 = PHI 
  if (inter_I_lsm.4_25 != 0)
goto ;
  else
goto ;

  :
  inter[0] = inter_I_lsm.3_24;

  :
  if (inter_I_lsm.4_25 != 0)
goto ;
  else
goto ;

  :
  inter[1] = inter_I_lsm.5_26;

  :
  foo (&inter);
  inter ={v} {CLOBBER};
  return;

  :
  goto ;

but no attempt at threading of

  (5, 6) incoming edge -> (6->7) joiner -> (7 -> 8) normal

VRP simplfies the conditional to true afterwards - so maybe this is just
a missed simplification-after-threading in DOM?  Without VRP the
redundant conditional stays.  It still looks like a trivial missing thing to
adjust the jump we thread through ...?


[Bug tree-optimization/61607] DOM missed jump threading and destroyed loops

2014-06-26 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61607

--- Comment #5 from Richard Biener  ---
Author: rguenth
Date: Thu Jun 26 11:29:34 2014
New Revision: 212026

URL: https://gcc.gnu.org/viewcvs?rev=212026&root=gcc&view=rev
Log:
2014-06-26  Richard Biener  

PR tree-optimization/61607
* tree-ssa-copy.c (copy_prop_visit_phi_node): Adjust comment
explaining why we restrict copies on loop depth.
* tree-ssa-dom.c (cprop_operand): Remove restriction on
on loop depth.
(record_equivalences_from_phis): Instead add it here.

* gcc.dg/tree-ssa/ssa-dom-thread-5.c: New testcase.

Added:
trunk/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-thread-5.c
Modified:
trunk/gcc/ChangeLog
trunk/gcc/testsuite/ChangeLog
trunk/gcc/tree-ssa-copy.c
trunk/gcc/tree-ssa-dom.c


[Bug tree-optimization/61607] DOM missed jump threading and destroyed loops

2014-06-26 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61607

--- Comment #4 from Richard Biener  ---
Author: rguenth
Date: Thu Jun 26 07:44:10 2014
New Revision: 212011

URL: https://gcc.gnu.org/viewcvs?rev=212011&root=gcc&view=rev
Log:
2014-06-26  Richard Biener  

PR tree-optimization/61607
* tree-ssa-threadupdate.c (ssa_redirect_edges): Cancel the
loop if we redirected its latch edge.
(thread_block_1): Do not cancel loops prematurely.

Modified:
trunk/gcc/ChangeLog
trunk/gcc/tree-ssa-threadupdate.c


[Bug tree-optimization/61607] DOM missed jump threading and destroyed loops

2014-06-25 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61607

--- Comment #3 from Richard Biener  ---
Like with

Index: gcc/tree-ssa-threadupdate.c
===
--- gcc/tree-ssa-threadupdate.c (revision 211969)
+++ gcc/tree-ssa-threadupdate.c (working copy)
@@ -764,6 +764,14 @@ ssa_redirect_edges (struct redirection_d
  if ((*path)[1]->type != EDGE_COPY_SRC_JOINER_BLOCK)
EDGE_SUCC (rd->dup_blocks[0], 0)->count += e->count;

+ /* If we redirect a loop latch edge cancel its loop.  */
+ if (e->src == e->src->loop_father->latch)
+   {
+ e->src->loop_father->header = NULL;
+ e->src->loop_father->latch = NULL;
+ loops_state_set (LOOPS_NEED_FIXUP);
+   }
+
  /* Redirect the incoming edge (possibly to the joiner block) to the
 appropriate duplicate block.  */
  e2 = redirect_edge_and_branch (e, rd->dup_blocks[0]);
@@ -853,32 +861,6 @@ thread_block_1 (basic_block bb, bool nol
   redirection_data
 = new hash_table (EDGE_COUNT (bb->succs));

-  /* If we thread the latch of the loop to its exit, the loop ceases to
- exist.  Make sure we do not restrict ourselves in order to preserve
- this loop.  */
-  if (loop->header == bb)
-{
-  e = loop_latch_edge (loop);
-  vec *path = THREAD_PATH (e);
-
-  if (path
- && (((*path)[1]->type == EDGE_COPY_SRC_JOINER_BLOCK && joiners)
- || ((*path)[1]->type == EDGE_COPY_SRC_BLOCK && !joiners)))
-   {
- for (unsigned int i = 1; i < path->length (); i++)
-   {
- edge e2 = (*path)[i]->e;
-
- if (loop_exit_edge_p (loop, e2))
-   {
- loop->header = NULL;
- loop->latch = NULL;
- loops_state_set (LOOPS_NEED_FIXUP);
-   }
-   }
-   }
-}
-
   /* Record each unique threaded destination into a hash table for
  efficient lookups.  */
   FOR_EACH_EDGE (e, ei, bb->preds)


[Bug tree-optimization/61607] DOM missed jump threading and destroyed loops

2014-06-25 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61607

--- Comment #2 from Richard Biener  ---
With the propagation limitation removed we get

  Registering jump thread: (2, 4) incoming edge;  (4, 5) joiner;  (5, 7)
normal;
  Cancelling jump thread: (2, 4) incoming edge;  (4, 5) joiner;  (5, 7) normal;
Jump threading proved probability of edge 7->9 too small (it is 3900, should be
5000).
  Threaded jump 5 --> 7 to 10
fix_loop_structure: removing loop 1
flow_loops_find: discovered new loop 2 with header 4

  :
  # inter0p_13 = PHI 
  # inter1p_14 = PHI 
  if (inter0p_2 != 0)
goto ;
  else
goto ;

  :
  inter[0] = 1;

  :
  if (inter0p_2 != 0)
goto ;
  else
goto ;

  :
  inter[1] = 1;

  :
  foo (&inter);
  inter ={v} {CLOBBER};
  return;

  :
  goto ;

that still misses the threading of the true path.  And it still destroys
loop info from:

static bool
thread_block_1 (basic_block bb, bool noloop_only, bool joiners)
{
...
  /* If we thread the latch of the loop to its exit, the loop ceases to
 exist.  Make sure we do not restrict ourselves in order to preserve
 this loop.  */
  if (loop->header == bb)
{
  e = loop_latch_edge (loop);
  vec *path = THREAD_PATH (e);

  if (path
  && (((*path)[1]->type == EDGE_COPY_SRC_JOINER_BLOCK && joiners)
  || ((*path)[1]->type == EDGE_COPY_SRC_BLOCK && !joiners)))
{
  for (unsigned int i = 1; i < path->length (); i++)
{
  edge e2 = (*path)[i]->e;

  if (loop_exit_edge_p (loop, e2))
{
  loop->header = NULL;
  loop->latch = NULL;
  loops_state_set (LOOPS_NEED_FIXUP);

but it seems we cancel the threading later...

(gdb) 
913   delete_jump_thread_path (path);

so it would be better if we destroyed the loop only if necessary
(I would have expected the actual edge redirection code takes care of that).
Cancelling loops unnecessarily is very bad.


[Bug tree-optimization/61607] DOM missed jump threading and destroyed loops

2014-06-25 Thread rguenth at gcc dot gnu.org
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61607

--- Comment #1 from Richard Biener  ---
Optimizing block #5

1>>> COND 1 = i_1 ge_expr R_6(D)
1>>> COND 0 = i_1 lt_expr R_6(D)
LKUP STMT inter0p_13 = PHI 
  inter0p_13 = PHI 
2>>> STMT inter0p_13 = PHI 
  inter0p_13 = PHI 
LKUP STMT inter1p_14 = PHI 
  inter1p_14 = PHI 
FIND: inter0p_2
0>>> COPY inter1p_14 = inter0p_2

At least record_equivalences_from_phis sets the SSA value of both to inter0p_2.

But we don't propagate inter0p_2 into the conditionals because of

  /* Do not propagate copies if the propagated value is at a deeper loop
 depth than the propagatee.  Otherwise, this may move loop variant
 variables outside of their loops and prevent coalescing
 opportunities.  If the value was loop invariant, it will be hoisted
 by LICM and exposed for copy propagation.  */
  if (loop_depth_of_name (val) > loop_depth_of_name (op))
return;

as inter0p_2 is defined inside the loop.  Note that we don't replace
inter1p_14 by inter0p_13 either because we recorded inter0p_2 for that
as well ...

So it seems the above limitation should be enforced in a different way
(or removed).  I don't get what the comment is after anyway...  both
FRE and PRE don't care and do the propagation (and the CSE).