re PR tree-optimization/38385 (ICE with -O2 -ftree-loop-distribution)
authorTomas Bily <tbily@suse.cz>
Mon, 12 Jan 2009 15:37:09 +0000 (16:37 +0100)
committerTomas Bily <tomby@gcc.gnu.org>
Mon, 12 Jan 2009 15:37:09 +0000 (16:37 +0100)
        PR middlend/38385
        * tree-loop-distribution.c (prop_phis): New function.
        (generate_builtin): Call prop_phis.
        * testsuite/gcc.dg/tree-ssa/pr38385.c: New file.

From-SVN: r143291

gcc/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/pr38385.c [new file with mode: 0644]
gcc/tree-loop-distribution.c

index 715cbfb..ebe85fa 100644 (file)
@@ -1,3 +1,10 @@
+2009-01-12  Tomas Bily  <tbily@suse.cz>
+
+       PR middlend/38385
+        * tree-loop-distribution.c (prop_phis): New function.
+        (generate_builtin): Call prop_phis.
+        * testsuite/gcc.dg/tree-ssa/pr38385.c: New file.
+
 2009-01-12  Jakub Jelinek  <jakub@redhat.com>
 
        PR tree-optimization/38807
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr38385.c b/gcc/testsuite/gcc.dg/tree-ssa/pr38385.c
new file mode 100644 (file)
index 0000000..a49c93e
--- /dev/null
@@ -0,0 +1,124 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -ftree-loop-distribution" } */
+
+struct rtx_def
+{
+  int a;
+};
+
+typedef struct rtx_def *rtx;
+
+struct rd {
+  int alternative_enabled_p[100];
+  rtx operand[100];
+  int n_operands;
+};
+
+rtx this_insn;
+int n_reloads;
+int n_replacements;
+int n_earlyclobbers;
+int replace_reloads;
+int hard_regs_live_known;
+short* static_reload_reg_p;
+struct rd recog_data;
+
+int
+find_reloads (rtx insn, int replace, int ind_levels, int live_known,
+             short *reload_reg_p)
+{
+  int i, j;
+  int noperands = replace;
+
+  int no_input_reloads = 0;
+  int n_alternatives = replace;
+  char this_alternative_match_win[30];
+  char this_alternative_win[30];
+  char this_alternative_earlyclobber[30];
+  int this_alternative_matches[30];
+  int goal_alternative[30];
+  int this_alternative_number;
+
+  char goal_alternative_match_win[30];
+  char goal_alternative_win[30];
+  int best;
+
+  int operand_mode[30];
+  int retval = 0;
+
+  for (this_alternative_number = 0;
+       this_alternative_number < n_alternatives;
+       this_alternative_number++)
+    {
+
+      int losers = 0;
+      int bad = 0;
+      
+      if (!recog_data.alternative_enabled_p[this_alternative_number])
+       {
+         int i;
+         
+         for (i = 0; i < recog_data.n_operands; i++)
+           ;
+         
+         continue;
+       }
+      
+      for (i = 0; i < noperands; i++)
+       if (this_alternative_earlyclobber[i]
+           && (this_alternative_win[i] || this_alternative_match_win[i]))
+         {
+           if (j != noperands)
+             {
+               losers++;
+               
+               for (j = 0; j < noperands; j++)
+                 if (this_alternative_matches[j] == i
+                     && this_alternative_match_win[j])
+                   {
+                     this_alternative_win[j] = 0;
+                     this_alternative_match_win[j] = 0;
+                     losers++;
+                   }
+             }
+         }
+      
+      if (losers == 0)
+       {
+         for (i = 0; i < noperands; i++)
+           {
+             goal_alternative_win[i] = 0;
+             goal_alternative_match_win[i] = 0;
+           }
+         
+         goto finish;
+       }
+
+      if (! bad && best > losers)
+       {
+         for (i = 0; i < noperands; i++)
+           {
+             goal_alternative[i] = 0;
+             goal_alternative_win[i] = 0;
+           }
+       }
+    }
+  
+
+ finish:
+
+  for (i = 0; i < noperands; i++)
+    if (! goal_alternative_win[i])
+      {
+       rtx op = recog_data.operand[i];
+       int mode = operand_mode[i];
+       
+       if (((ix86_preferred_reload_class ((op), (goal_alternative[i])) == 2)
+            || no_input_reloads)
+           && mode != 0)
+         {}
+      }
+
+  return retval;
+}
+
index 062ab48..745957f 100644 (file)
@@ -331,6 +331,38 @@ generate_memset_zero (gimple stmt, tree op0, tree nb_iter,
   return res;
 }
 
+/* Propagate phis in BB b to their uses and remove them.  */
+
+static void
+prop_phis (basic_block b)
+{
+  gimple_stmt_iterator psi;
+  gimple_seq phis = phi_nodes (b);
+
+  for (psi = gsi_start (phis); !gsi_end_p (psi); )
+    {
+      gimple phi = gsi_stmt (psi);
+      tree def = gimple_phi_result (phi), use = gimple_phi_arg_def (phi, 0);
+
+      gcc_assert (gimple_phi_num_args (phi) == 1);
+
+      if (!is_gimple_reg (def))
+       {
+         imm_use_iterator iter;
+         use_operand_p use_p;
+         gimple stmt;
+
+         FOR_EACH_IMM_USE_STMT (stmt, iter, def)
+           FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
+             SET_USE (use_p, use);
+       }
+      else
+       replace_uses_by (def, use);
+
+      remove_phi_node (&psi, true);
+    }
+}
+
 /* Tries to generate a builtin function for the instructions of LOOP
    pointed to by the bits set in PARTITION.  Returns true when the
    operation succeeded.  */
@@ -400,6 +432,7 @@ generate_builtin (struct loop *loop, bitmap partition, bool copy_p)
       unsigned nbbs = loop->num_nodes;
       basic_block src = loop_preheader_edge (loop)->src;
       basic_block dest = single_exit (loop)->dest;
+      prop_phis (dest);
       make_edge (src, dest, EDGE_FALLTHRU);
       set_immediate_dominator (CDI_DOMINATORS, dest, src);
       cancel_loop_tree (loop);