/* Predictive commoning.
- Copyright (C) 2005 Free Software Foundation, Inc.
+ Copyright (C) 2005, 2007 Free Software Foundation, Inc.
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
+Free 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
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/>. */
/* This file implements the predictive commoning optimization. Predictive
commoning can be viewed as CSE around a loop, and with some improvements,
double_int *off)
{
aff_tree diff, baseb, step;
+ tree typea, typeb;
+
+ /* Check that both the references access the location in the same type. */
+ typea = TREE_TYPE (DR_REF (a));
+ typeb = TREE_TYPE (DR_REF (b));
+ if (!useless_type_conversion_p (typeb, typea))
+ return false;
/* Check whether the base address and the step of both references is the
same. */
just fail. */
goto end;
}
- dr->aux = i;
+ dr->aux = (void *) (size_t) i;
comp_father[i] = i;
comp_size[i] = 1;
}
if (!suitable_reference_p (dr, &dummy))
{
- ia = dr->aux;
+ ia = (unsigned) (size_t) dr->aux;
merge_comps (comp_father, comp_size, n, ia);
}
}
dra = DDR_A (ddr);
drb = DDR_B (ddr);
- ia = component_of (comp_father, dra->aux);
- ib = component_of (comp_father, drb->aux);
+ ia = component_of (comp_father, (unsigned) (size_t) dra->aux);
+ ib = component_of (comp_father, (unsigned) (size_t) drb->aux);
if (ia == ib)
continue;
bad = component_of (comp_father, n);
for (i = 0; VEC_iterate (data_reference_p, datarefs, i, dr); i++)
{
- ia = dr->aux;
+ ia = (unsigned) (size_t) dr->aux;
ca = component_of (comp_father, ia);
if (ca == bad)
continue;
remove_phi_node (stmt, NULL_TREE, false);
/* Turn the phi node into GIMPLE_MODIFY_STMT. */
- new_stmt = build_gimple_modify_stmt_stat (val, new);
+ new_stmt = build_gimple_modify_stmt (val, new);
SSA_NAME_DEF_STMT (val) = new_stmt;
bsi_insert_before (&bsi, new_stmt, BSI_NEW_STMT);
return;
NEW = VAL */
}
- new_stmt = build_gimple_modify_stmt_stat (new, unshare_expr (val));
+ new_stmt = build_gimple_modify_stmt (new, unshare_expr (val));
bsi_insert_after (&bsi, new_stmt, BSI_NEW_STMT);
SSA_NAME_DEF_STMT (new) = new_stmt;
}
else
{
type = TREE_TYPE (iv.base);
- val = fold_build2 (MULT_EXPR, type, iv.step,
- build_int_cst_type (type, iter));
- val = fold_build2 (PLUS_EXPR, type, iv.base, val);
+ if (POINTER_TYPE_P (type))
+ {
+ val = fold_build2 (MULT_EXPR, sizetype, iv.step,
+ size_int (iter));
+ val = fold_build2 (POINTER_PLUS_EXPR, type, iv.base, val);
+ }
+ else
+ {
+ val = fold_build2 (MULT_EXPR, type, iv.step,
+ build_int_cst_type (type, iter));
+ val = fold_build2 (PLUS_EXPR, type, iv.base, val);
+ }
*idx_p = unshare_expr (val);
}
/* Marks all virtual operands of statement STMT for renaming. */
-static void
+void
mark_virtual_ops_for_renaming (tree stmt)
{
ssa_op_iter iter;
mark_virtual_ops_for_renaming (tsi_stmt (tsi));
}
+/* Returns a new temporary variable used for the I-th variable carrying
+ value of REF. The variable's uid is marked in TMP_VARS. */
+
+static tree
+predcom_tmp_var (tree ref, unsigned i, bitmap tmp_vars)
+{
+ tree type = TREE_TYPE (ref);
+ tree var = create_tmp_var (type, get_lsm_tmp_name (ref, i));
+
+ /* We never access the components of the temporary variable in predictive
+ commoning. */
+ if (TREE_CODE (type) == COMPLEX_TYPE
+ || TREE_CODE (type) == VECTOR_TYPE)
+ DECL_GIMPLE_REG_P (var) = 1;
+
+ add_referenced_var (var);
+ bitmap_set_bit (tmp_vars, DECL_UID (var));
+ return var;
+}
+
/* Creates the variables for CHAIN, as well as phi nodes for them and
initialization on entry to LOOP. Uids of the newly created
temporary variables are marked in TMP_VARS. */
for (i = 0; i < n + (reuse_first ? 0 : 1); i++)
{
- var = create_tmp_var (TREE_TYPE (ref), get_lsm_tmp_name (ref, i));
- add_referenced_var (var);
- bitmap_set_bit (tmp_vars, DECL_UID (var));
+ var = predcom_tmp_var (ref, i, tmp_vars);
VEC_quick_push (tree, chain->vars, var);
}
if (reuse_first)
init = VEC_index (tree, inits, 0);
*vars = VEC_alloc (tree, heap, written ? 2 : 1);
- var = create_tmp_var (TREE_TYPE (ref), get_lsm_tmp_name (ref, 0));
- add_referenced_var (var);
- bitmap_set_bit (tmp_vars, DECL_UID (var));
+ var = predcom_tmp_var (ref, 0, tmp_vars);
VEC_quick_push (tree, *vars, var);
if (written)
VEC_quick_push (tree, *vars, VEC_index (tree, *vars, 0));
}
else
{
- init = build_gimple_modify_stmt_stat (var, init);
+ init = build_gimple_modify_stmt (var, init);
SSA_NAME_DEF_STMT (var) = init;
mark_virtual_ops_for_renaming (init);
bsi_insert_on_edge_immediate (entry, init);
/* Base all the ssa names in the ud and du chain of NAME on VAR. */
stmt = SSA_NAME_DEF_STMT (use);
- while (TREE_CODE (stmt) == PHI_NODE)
+ while (TREE_CODE (stmt) == PHI_NODE
+ /* In case we could not unroll the loop enough to eliminate
+ all copies, we may reach the loop header before the defining
+ statement (in that case, some register copies will be present
+ in loop latch in the final code, corresponding to the newly
+ created looparound phi nodes). */
+ && bb_for_stmt (stmt) != loop->header)
{
gcc_assert (single_pred_p (bb_for_stmt (stmt)));
use = PHI_ARG_DEF (stmt, 0);
var = create_tmp_var (type, "predreastmp");
add_referenced_var (var);
new_name = make_ssa_name (var, NULL_TREE);
- new_stmt = build_gimple_modify_stmt_stat (new_name,
+ new_stmt = build_gimple_modify_stmt (new_name,
fold_build2 (code, type, name1, name2));
SSA_NAME_DEF_STMT (new_name) = new_stmt;
var = create_tmp_var (type, "predreastmp");
add_referenced_var (var);
tmp_name = make_ssa_name (var, NULL_TREE);
- tmp_stmt = build_gimple_modify_stmt_stat (tmp_name,
+ tmp_stmt = build_gimple_modify_stmt (tmp_name,
GIMPLE_STMT_OPERAND (s1, 1));
SSA_NAME_DEF_STMT (tmp_name) = tmp_stmt;