@@ -98,6 +98,15 @@ along with GCC; see the file COPYING3. If not see
array CONST_VAL[i].VALUE. That is fed into substitute_and_fold for
final substitution and folding.
+ This algorithm uses wide-ints at the max precision of the target.
+ This means that, with one uninteresting exception, variables with
+ UNSIGNED types never go to VARYING because the bits above the
+ precision of the type of the variable are always zero. The
+ uninteresting case is a variable of UNSIGNED type that has the
+ maximum precision of the target. Such variables can go to VARYING,
+ but this causes no loss of infomation since these variables will
+ never be extended.
+
I don't understand this. In CCP a SSA name drops to varying when
it's not constant. How is that related to signedness or precision?!
@@ -511,21 +523,21 @@ set_lattice_value (tree var, prop_value_t new_val)
static prop_value_t get_value_for_expr (tree, bool);
static prop_value_t bit_value_binop (enum tree_code, tree, tree, tree);
-static void bit_value_binop_1 (enum tree_code, tree, double_int *,
double_int *,
- tree, double_int, double_int,
- tree, double_int, double_int);
+static void bit_value_binop_1 (enum tree_code, tree, widest_int *,
widest_int *,
+ tree, widest_int, widest_int,
+ tree, widest_int, widest_int);
please don't pass widest_int by value but instead pass it by const reference.
compared to double_int it is really large (most targets passed double_int
in two registers).
+/* Return a widest_int that can be used for bitwise simplifications
from VAL. */
-static double_int
-value_to_double_int (prop_value_t val)
+static widest_int
+value_to_wide_int (prop_value_t val)
{
if (val.value
&& TREE_CODE (val.value) == INTEGER_CST)
- return tree_to_double_int (val.value);
- else
- return double_int_zero;
+ return wi::to_widest (val.value);
+
+ return 0;
}
you also get to hope that we optimize all the widest_int return-by-value
code to elide the implied copying ... (not sure if you can do that by
adding a not implemented copy / assignment constructor - C++ folks?)
+ val.lattice_val = val.mask == -1 ? VARYING : CONSTANT;
if (val.lattice_val == CONSTANT)
you mean this check wrt the toplevel VARYING comment? It would
be bad if that no longer ends up VARYING. OTOH I don't know whether
the current check is correct either - we extend the mask according to
the sign of the lattice element. Thus the wide-int variant looks equivalent.
Note that for unsigned values we have knowledge about the bits
outside of the precision - they are zero, so techincally unsigneds
never go VARYING.
case LT_EXPR:
case LE_EXPR:
{
+ widest_int o1val, o2val, o1mask, o2mask;
int minmax, maxmin;
+
+ if ((code == GE_EXPR) || (code == GT_EXPR))
+ {
+ o1val = r2val;
+ o1mask = r2mask;
+ o2val = r1val;
+ o2mask = r1mask;
+ code = swap_tree_comparison (code);
+ }
+ else
+ {
+ o1val = r1val;
+ o1mask = r1mask;
+ o2val = r2val;
+ o2mask = r2mask;
+ }
that are pretty expensive copies, no? Consider using
const widest_int &o1val = swap ? r2val : r1val;
and so on. (C++ folks? Any idea how to avoid the repeated
conditional init in favor of sth that more resembles the original?)
@@ -1643,7 +1643,7 @@ mem_refs_may_alias_p (mem_ref_p mem1, mem_ref_p mem2,
/* Perform BASE + OFFSET analysis -- if MEM1 and MEM2 are based on the same
object and their offset differ in such a way that the locations cannot
overlap, then they cannot alias. */
- double_int size1, size2;
+ widest_int size1, size2;
aff_tree off1, off2;
from the names you can know this is offset_int.
@@ -944,7 +944,7 @@ alloc_iv (tree base, tree step)
&& !DECL_P (TREE_OPERAND (base_object, 0)))
{
aff_tree comb;
- double_int size;
+ widest_int size;
base_object = get_inner_reference_aff (TREE_OPERAND (base_object, 0),
&comb, &size);
gcc_assert (base_object != NULL_TREE);
likewise.
@@ -529,15 +526,15 @@ end:
difference of two values in TYPE. */
static void
-bounds_add (bounds *bnds, double_int delta, tree type)
+bounds_add (bounds *bnds, widest_int delta, tree type)
{
mpz_t mdelta, max;
const widest_int &delta please (please double-check the patches for
widest-int-by-value passing).
@@ -2592,7 +2587,7 @@ derive_constant_upper_bound_ops (tree type, tree op0,
static void
do_warn_aggressive_loop_optimizations (struct loop *loop,
- double_int i_bound, gimple stmt)
+ widest_int i_bound, gimple stmt)
{
/* Don't warn if the loop doesn't have known constant bound. */
if (!loop->nb_iterations
Likewise.
@@ -2628,13 +2623,13 @@ do_warn_aggressive_loop_optimizations (struct
loop *loop,
is taken at last when the STMT is executed BOUND + 1 times.
REALISTIC is true if BOUND is expected to be close to the real number
of iterations. UPPER is true if we are sure the loop iterates at most
- BOUND times. I_BOUND is an unsigned double_int upper estimate on BOUND. */
+ BOUND times. I_BOUND is an unsigned wide_int upper estimate on BOUND. */
static void
-record_estimate (struct loop *loop, tree bound, double_int i_bound,
+record_estimate (struct loop *loop, tree bound, widest_int i_bound,
gimple at_stmt, bool is_exit, bool realistic, bool upper)
{
- double_int delta;
+ widest_int delta;
if (dump_file && (dump_flags & TDF_DETAILS))
{
Likewise. (this is also about stack-usage in deep call frames, even if
the actual copies might end up being cheap)
/* Return index of BOUND in BOUNDS array sorted in increasing order.
Lookup by binary search. */
static int
-bound_index (vec<double_int> bounds, double_int bound)
+bound_index (vec<widest_int> bounds, const widest_int &bound)
{
unsigned int end = bounds.length ();
unsigned int begin = 0;
eh... a vec of widest_int ... you know this is of the order of O (# statements)?
Oh well. At least it's temporary.
@@ -49,11 +49,11 @@ struct GTY(()) ptr_info_def
struct GTY (()) range_info_def {
/* Minimum for value range. */
- double_int min;
+ widest_int min;
/* Maximum for value range. */
- double_int max;
+ widest_int max;
/* Non-zero bits - bits not set are guaranteed to be always zero. */
- double_int nonzero_bits;
+ widest_int nonzero_bits;
};