OSDN Git Service

2009-05-29 Kai Tietz <kai.tietz@onevision.com>
[pf3gnuchains/gcc-fork.git] / gcc / tree-parloops.c
index 0373205..2ec2619 100644 (file)
@@ -1,5 +1,5 @@
 /* Loop autoparallelization.
-   Copyright (C) 2006, 2007, 2008 Free Software Foundation, Inc.
+   Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
    Contributed by Sebastian Pop <pop@cri.ensmp.fr> and
    Zdenek Dvorak <dvorakz@suse.cz>.
 
@@ -7,7 +7,7 @@ This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
+Software Foundation; either version 3, or (at your option) any later
 version.
 
 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -16,9 +16,8 @@ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 for more details.
 
 You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING.  If not, write to the Free
-Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301, USA.  */
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
 #include "system.h"
@@ -278,6 +277,7 @@ loop_parallel_p (struct loop *loop, htab_t reduction_list,
       return false;
     }
 
+  vect_dump = NULL;
   simple_loop_info = vect_analyze_loop_form (loop);
 
   for (gsi = gsi_start_phis (loop->header); !gsi_end_p (gsi); gsi_next (&gsi))
@@ -385,7 +385,7 @@ loop_parallel_p (struct loop *loop, htab_t reduction_list,
       tree def = PHI_RESULT (phi);
       affine_iv iv;
 
-      if (is_gimple_reg (def) && !simple_iv (loop, phi, def, &iv, true))
+      if (is_gimple_reg (def) && !simple_iv (loop, loop, def, &iv, true))
        {
          struct reduction_info *red;
 
@@ -1193,7 +1193,7 @@ separate_decls_in_region (edge entry, edge exit, htab_t reduction_list,
 
   VEC_free (basic_block, heap, body);
 
-  if (htab_elements (name_copies) == 0)
+  if (htab_elements (name_copies) == 0 && reduction_list == 0) 
     {
       /* It may happen that there is nothing to copy (if there are only
          loop carried and external variables in the loop).  */
@@ -1321,15 +1321,20 @@ create_loop_fn (void)
   return decl;
 }
 
-/* Bases all the induction variables in LOOP on a single induction variable
-   (unsigned with base 0 and step 1), whose final value is compared with
-   NIT.  The induction variable is incremented in the loop latch.  
-   REDUCTION_LIST describes the reductions in LOOP.  */
-
-static void
-canonicalize_loop_ivs (struct loop *loop, htab_t reduction_list, tree nit)
+/* Bases all the induction variables in LOOP on a single induction
+   variable (unsigned with base 0 and step 1), whose final value is
+   compared with *NIT.  When the IV type precision has to be larger
+   than *NIT type precision, *NIT is converted to the larger type, the
+   conversion code is inserted before the loop, and *NIT is updated to
+   the new definition.  The induction variable is incremented in the
+   loop latch.  REDUCTION_LIST describes the reductions in LOOP.
+   Return the induction variable that was created.  */
+
+tree
+canonicalize_loop_ivs (struct loop *loop, htab_t reduction_list, tree *nit)
 {
-  unsigned precision = TYPE_PRECISION (TREE_TYPE (nit));
+  unsigned precision = TYPE_PRECISION (TREE_TYPE (*nit));
+  unsigned original_precision = precision;
   tree res, type, var_before, val, atype, mtype;
   gimple_stmt_iterator gsi, psi;
   gimple phi, stmt;
@@ -1337,6 +1342,7 @@ canonicalize_loop_ivs (struct loop *loop, htab_t reduction_list, tree nit)
   affine_iv iv;
   edge exit = single_dom_exit (loop);
   struct reduction_info *red;
+  gimple_seq stmts;
 
   for (psi = gsi_start_phis (loop->header);
        !gsi_end_p (psi); gsi_next (&psi))
@@ -1350,6 +1356,14 @@ canonicalize_loop_ivs (struct loop *loop, htab_t reduction_list, tree nit)
 
   type = lang_hooks.types.type_for_size (precision, 1);
 
+  if (original_precision != precision)
+    {
+      *nit = fold_convert (type, *nit);
+      *nit = force_gimple_operand (*nit, &stmts, true, NULL_TREE);
+      if (stmts)
+       gsi_insert_seq_on_edge_immediate (loop_preheader_edge (loop), stmts);
+    }
+
   gsi = gsi_last_bb (loop->latch);
   create_iv (build_int_cst_type (type, 0), build_int_cst (type, 1), NULL_TREE,
             loop, &gsi, true, &var_before, NULL);
@@ -1366,8 +1380,13 @@ canonicalize_loop_ivs (struct loop *loop, htab_t reduction_list, tree nit)
          continue;
        }
 
-      ok = simple_iv (loop, phi, res, &iv, true);
-      red = reduction_phi (reduction_list, phi);
+      ok = simple_iv (loop, loop, res, &iv, true);
+
+      if (reduction_list)
+       red = reduction_phi (reduction_list, phi);
+      else
+       red = NULL;
+
       /* We preserve the reduction phi nodes.  */
       if (!ok && red)
        {
@@ -1404,7 +1423,10 @@ canonicalize_loop_ivs (struct loop *loop, htab_t reduction_list, tree nit)
     }
   gimple_cond_set_code (stmt, LT_EXPR);
   gimple_cond_set_lhs (stmt, var_before);
-  gimple_cond_set_rhs (stmt, nit);
+  gimple_cond_set_rhs (stmt, *nit);
+  update_stmt (stmt);
+
+  return var_before;
 }
 
 /* Moves the exit condition of LOOP to the beginning of its header, and
@@ -1751,7 +1773,7 @@ gen_parallel_loop (struct loop *loop, htab_t reduction_list,
   free_original_copy_tables ();
 
   /* Base all the induction variables in LOOP on a single control one.  */
-  canonicalize_loop_ivs (loop, reduction_list, nit);
+  canonicalize_loop_ivs (loop, reduction_list, &nit);
 
   /* Ensure that the exit condition is the first statement in the loop.  */
   transform_to_exit_first_loop (loop, reduction_list, nit);
@@ -1864,6 +1886,16 @@ parallelize_loops (void)
 
   free_stmt_vec_info_vec ();
   htab_delete (reduction_list);
+
+  /* Parallelization will cause new function calls to be inserted through
+     which local variables will escape.  Reset the points-to solutions
+     for ESCAPED and CALLUSED.  */
+  if (changed)
+    {
+      pt_solution_reset (&cfun->gimple_df->escaped);
+      pt_solution_reset (&cfun->gimple_df->callused);
+    }
+
   return changed;
 }