/* 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>.
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
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"
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))
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;
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). */
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;
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))
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);
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)
{
}
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
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);
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;
}