/* Operations with affine combinations of trees.
- Copyright (C) 2005, 2007 Free Software Foundation, Inc.
-
+ Copyright (C) 2005, 2007, 2008 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 3, or (at your option) any
later version.
-
+
GCC is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
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 COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "tree-dump.h"
#include "pointer-set.h"
#include "tree-affine.h"
-#include "tree-gimple.h"
+#include "gimple.h"
#include "flags.h"
/* Extends CST as appropriate for the affine combinations COMB. */
comb->n++;
}
else
- comb->rest = fold_build2 (MULT_EXPR, type, comb->rest,
+ comb->rest = fold_build2 (MULT_EXPR, type, comb->rest,
double_int_to_tree (type, scale));
}
}
else
elt = fold_build2 (MULT_EXPR, type,
fold_convert (type, elt),
- double_int_to_tree (type, scale));
+ double_int_to_tree (type, scale));
if (comb->rest)
comb->rest = fold_build2 (PLUS_EXPR, type, comb->rest,
/* Adds C * COEF * VAL to R. VAL may be NULL, in that case only
C * COEF is added to R. */
-
+
static void
aff_combination_add_product (aff_tree *c, double_int coef, tree val,
/* Returns the element of COMB whose value is VAL, or NULL if no such
element exists. If IDX is not NULL, it is set to the index of VAL in
COMB. */
-
+
static struct aff_comb_elt *
aff_combination_find_elt (aff_tree *comb, tree val, unsigned *idx)
{
results. */
void
-aff_combination_expand (aff_tree *comb, struct pointer_map_t **cache)
+aff_combination_expand (aff_tree *comb ATTRIBUTE_UNUSED,
+ struct pointer_map_t **cache ATTRIBUTE_UNUSED)
{
unsigned i;
aff_tree to_add, current, curre;
- tree e, def, rhs;
+ tree e, rhs;
+ gimple def;
double_int scale;
void **slot;
struct name_expansion *exp;
for (i = 0; i < comb->n; i++)
{
tree type, name;
+ enum tree_code code;
+
e = comb->elts[i].val;
type = TREE_TYPE (e);
name = e;
if (TREE_CODE (name) != SSA_NAME)
continue;
def = SSA_NAME_DEF_STMT (name);
- if (TREE_CODE (def) != GIMPLE_MODIFY_STMT
- || GIMPLE_STMT_OPERAND (def, 0) != name)
+ if (!is_gimple_assign (def) || gimple_assign_lhs (def) != name)
continue;
- rhs = GIMPLE_STMT_OPERAND (def, 1);
- if (TREE_CODE (rhs) != SSA_NAME
- && !EXPR_P (rhs)
- && !is_gimple_min_invariant (rhs))
+ code = gimple_assign_rhs_code (def);
+ if (code != SSA_NAME
+ && !IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (code))
+ && (get_gimple_rhs_class (code) != GIMPLE_SINGLE_RHS
+ || !is_gimple_min_invariant (gimple_assign_rhs1 (def))))
continue;
/* We do not know whether the reference retains its value at the
place where the expansion is used. */
- if (REFERENCE_CLASS_P (rhs))
+ if (TREE_CODE_CLASS (code) == tcc_reference)
continue;
if (!*cache)
*cache = pointer_map_create ();
slot = pointer_map_insert (*cache, e);
- exp = *slot;
+ exp = (struct name_expansion *) *slot;
if (!exp)
{
exp = XNEW (struct name_expansion);
exp->in_progress = 1;
*slot = exp;
- if (e != name)
+ /* In principle this is a generally valid folding, but
+ it is not unconditionally an optimization, so do it
+ here and not in fold_unary. */
+ /* Convert (T1)(X *+- CST) into (T1)X *+- (T1)CST if T1 is wider
+ than the type of X and overflow for the type of X is
+ undefined. */
+ if (e != name
+ && INTEGRAL_TYPE_P (type)
+ && INTEGRAL_TYPE_P (TREE_TYPE (name))
+ && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (name))
+ && TYPE_PRECISION (type) > TYPE_PRECISION (TREE_TYPE (name))
+ && (code == PLUS_EXPR || code == MINUS_EXPR || code == MULT_EXPR)
+ && TREE_CODE (gimple_assign_rhs2 (def)) == INTEGER_CST)
+ rhs = fold_build2 (code, type,
+ fold_convert (type, gimple_assign_rhs1 (def)),
+ fold_convert (type, gimple_assign_rhs2 (def)));
+ else
{
- /* In principle this is a generally valid folding, but
- it is not unconditionally an optimization, so do it
- here and not in fold_unary. */
- /* Convert (T1)(X *+- CST) into (T1)X *+- (T1)CST if T1 is wider
- than the type of X and overflow for the type of X is
- undefined. */
- if (INTEGRAL_TYPE_P (type)
- && INTEGRAL_TYPE_P (TREE_TYPE (rhs))
- && TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (rhs))
- && TYPE_PRECISION (type) > TYPE_PRECISION (TREE_TYPE (rhs))
- && (TREE_CODE (rhs) == PLUS_EXPR
- || TREE_CODE (rhs) == MINUS_EXPR
- || TREE_CODE (rhs) == MULT_EXPR)
- && TREE_CODE (TREE_OPERAND (rhs, 1)) == INTEGER_CST)
- {
- rhs = fold_build2 (TREE_CODE (rhs), type,
- fold_convert (type, TREE_OPERAND (rhs, 0)),
- fold_convert (type, TREE_OPERAND (rhs, 1)));
- }
- else
- rhs = fold_convert (type, rhs);
+ rhs = gimple_assign_rhs_to_tree (def);
+ if (e != name)
+ rhs = fold_convert (type, rhs);
}
tree_to_aff_combination_expand (rhs, comb->type, ¤t, cache);
exp->expansion = current;
free_name_expansion (const void *key ATTRIBUTE_UNUSED, void **value,
void *data ATTRIBUTE_UNUSED)
{
- struct name_expansion *exp = *value;
+ struct name_expansion *const exp = (struct name_expansion *) *value;
free (exp);
return true;
{
fprintf (file, " [%d] = ", i);
print_generic_expr (file, val->elts[i].val, TDF_VOPS|TDF_MEMSYMS);
-
+
fprintf (file, " * ");
dump_double_int (file, val->elts[i].coef, uns);
if (i != val->n - 1)