/* Chains of recurrences.
- Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009
+ Free Software Foundation, Inc.
Contributed by Sebastian Pop <pop@cri.ensmp.fr>
This file is part of GCC.
#include "tree-chrec.h"
#include "tree-pass.h"
#include "params.h"
+#include "flags.h"
#include "tree-scalar-evolution.h"
\f
/* "a*c". */
t0 = chrec_fold_multiply (type, CHREC_LEFT (poly0), CHREC_LEFT (poly1));
- /* "a*d + b*c + b*d". */
+ /* "a*d + b*c". */
t1 = chrec_fold_multiply (type, CHREC_LEFT (poly0), CHREC_RIGHT (poly1));
t1 = chrec_fold_plus (type, t1, chrec_fold_multiply (type,
CHREC_RIGHT (poly0),
CHREC_LEFT (poly1)));
- t1 = chrec_fold_plus (type, t1, chrec_fold_multiply (type,
- CHREC_RIGHT (poly0),
- CHREC_RIGHT (poly1)));
- /* "2*b*d". */
+ /* "b*d". */
t2 = chrec_fold_multiply (type, CHREC_RIGHT (poly0), CHREC_RIGHT (poly1));
+ /* "a*d + b*c + b*d". */
+ t1 = chrec_fold_plus (type, t1, t2);
+ /* "2*b*d". */
t2 = chrec_fold_multiply (type, SCALAR_FLOAT_TYPE_P (type)
? build_real (type, dconst2)
: build_int_cst (type, 2), t2);
}
}
-/* Returns true if TYPE is a type in that we cannot directly perform
- arithmetics, even though it is a scalar type. */
-
-static bool
-avoid_arithmetics_in_type_p (const_tree type)
-{
- /* Ada frontend uses subtypes -- an arithmetic cannot be directly performed
- in the subtype, but a base type must be used, and the result then can
- be casted to the subtype. */
- if (TREE_CODE (type) == INTEGER_TYPE && TREE_TYPE (type) != NULL_TREE)
- return true;
-
- return false;
-}
-
static tree chrec_convert_1 (tree, tree, gimple, bool);
/* Converts BASE and STEP of affine scev to TYPE. LOOP is the loop whose iv
tree new_base, new_step;
tree step_type = POINTER_TYPE_P (type) ? sizetype : type;
- /* If we cannot perform arithmetic in TYPE, avoid creating an scev. */
- if (avoid_arithmetics_in_type_p (type))
- return false;
-
/* In general,
(TYPE) (BASE + STEP * i) = (TYPE) BASE + (TYPE -- sign extend) STEP * i,
but we must check some assumptions.
/* If we cannot propagate the cast inside the chrec, just keep the cast. */
keep_cast:
- res = fold_convert (type, chrec);
+ /* Fold will not canonicalize (long)(i - 1) to (long)i - 1 because that
+ may be more expensive. We do want to perform this optimization here
+ though for canonicalization reasons. */
+ if (use_overflow_semantics
+ && (TREE_CODE (chrec) == PLUS_EXPR
+ || TREE_CODE (chrec) == MINUS_EXPR)
+ && TYPE_PRECISION (type) > TYPE_PRECISION (ct)
+ && TYPE_OVERFLOW_UNDEFINED (ct))
+ res = fold_build2 (TREE_CODE (chrec), type,
+ fold_convert (type, TREE_OPERAND (chrec, 0)),
+ fold_convert (type, TREE_OPERAND (chrec, 1)));
+ else
+ res = fold_convert (type, chrec);
/* Don't propagate overflows. */
if (CONSTANT_CLASS_P (res))
if (TYPE_PRECISION (type) > TYPE_PRECISION (inner_type))
return NULL_TREE;
- /* If we cannot perform arithmetic in TYPE, avoid creating an scev. */
- if (avoid_arithmetics_in_type_p (type))
- return NULL_TREE;
-
rtype = POINTER_TYPE_P (type) ? sizetype : type;
left = CHREC_LEFT (chrec);