#include "opts.h"
#include "cgraph.h"
#include "target-def.h"
+ #include "gimple.h"
+ #include "gimplify.h"
+#include "wide-int-print.h"
cpp_reader *parse_in; /* Declared in c-pragma.h. */
static void
pp_c_character_constant (c_pretty_printer *pp, tree c)
{
- tree type = TREE_TYPE (c);
- if (type == wchar_type_node)
- pp_character (pp, 'L');
pp_quote (pp);
- if (tree_fits_hwi_p (c, TYPE_SIGN (type)))
- pp_c_char (pp, tree_to_hwi (c, TYPE_SIGN (type)));
- else
- pp_scalar (pp, "\\x%x", (unsigned) tree_to_hwi (c));
- pp_c_char (pp, (unsigned) TREE_INT_CST_LOW (c));
++ pp_c_char (pp, (unsigned) tree_to_hwi (c));
pp_quote (pp);
}
static bool
defer_stack_allocation (tree var, bool toplevel)
{
- = (tree_low_cst (DECL_SIZE_UNIT (var), 1)
- < PARAM_VALUE (PARAM_MIN_SIZE_FOR_STACK_SHARING));
+ /* Whether the variable is small enough for immediate allocation not to be
+ a problem with regard to the frame size. */
+ bool smallish
++ = (tree_to_uhwi (DECL_SIZE_UNIT (var))
++ < ((unsigned HOST_WIDE_INT)
++ PARAM_VALUE (PARAM_MIN_SIZE_FOR_STACK_SHARING)));
+
/* If stack protection is enabled, *all* stack variables must be deferred,
so that we can re-order the strings to the top of the frame.
Similarly for Address Sanitizer. */
#include "splay-tree.h"
#include "pointer-set.h"
#include "hash-table.h"
+ #include "gimple.h"
+ #include "gimplify.h"
+#include "wide-int.h"
/* The number of nested classes being processed. If we are not in the
scope of any class, this is zero. */
#include "cp-tree.h"
#include "flags.h"
#include "target.h"
+ #include "gimple.h"
+ #include "gimplify.h"
+#include "wide-int.h"
static bool begin_init_stmts (tree *, tree *);
static tree finish_init_stmts (bool, tree, tree);
#include "convert.h"
#include "cgraph.h"
#include "splay-tree.h"
- #include "gimple.h" /* gimple_has_body_p */
+ #include "gimple.h"
+ #include "gimplify.h"
#include "hash-table.h"
+#include "wide-int.h"
static tree bot_manip (tree *, int *, void *);
static tree bot_replace (tree *, int *, void *);
if (TREE_CODE (value) == CONST_DECL)
value = DECL_INITIAL (value);
- if (tree_fits_hwi_p (value)
- && (simple_type_size_in_bits (TREE_TYPE (value))
- <= HOST_BITS_PER_WIDE_INT || tree_fits_shwi_p (value)))
+ if (simple_type_size_in_bits (TREE_TYPE (value))
- <= HOST_BITS_PER_WIDE_INT || host_integerp (value, 0))
++ <= HOST_BITS_PER_WIDE_INT || tree_fits_shwi_p (value)))
/* DWARF2 does not provide a way of indicating whether or
not enumeration constants are signed or unsigned. GDB
always assumes the values are signed, so we output all
if the new mask might be further optimized. */
if ((TREE_CODE (arg0) == LSHIFT_EXPR
|| TREE_CODE (arg0) == RSHIFT_EXPR)
- && tree_fits_uhwi_p (TREE_OPERAND (arg0, 1))
- && tree_fits_hwi_p (arg1)
- && tree_to_uhwi (TREE_OPERAND (arg0, 1))
- < TYPE_PRECISION (TREE_TYPE (arg0))
&& TYPE_PRECISION (TREE_TYPE (arg0)) <= HOST_BITS_PER_WIDE_INT
- && tree_to_uhwi (TREE_OPERAND (arg0, 1)) > 0)
+ && TREE_CODE (arg1) == INTEGER_CST
- && host_integerp (TREE_OPERAND (arg0, 1), 1)
- && tree_low_cst (TREE_OPERAND (arg0, 1), 1) > 0
- && (tree_low_cst (TREE_OPERAND (arg0, 1), 1)
++ && tree_fits_uhwi_p (TREE_OPERAND (arg0, 1))
++ && tree_to_uhwi (TREE_OPERAND (arg0, 1)) > 0
++ && (tree_to_uhwi (TREE_OPERAND (arg0, 1))
+ < TYPE_PRECISION (TREE_TYPE (arg0))))
{
- unsigned int shiftc = tree_low_cst (TREE_OPERAND (arg0, 1), 1);
- unsigned HOST_WIDE_INT mask = TREE_INT_CST_LOW (arg1);
+ unsigned int shiftc = tree_to_uhwi (TREE_OPERAND (arg0, 1));
- unsigned HOST_WIDE_INT mask
- = tree_to_hwi (arg1, TYPE_SIGN (TREE_TYPE (arg1)));
++ unsigned HOST_WIDE_INT mask = tree_to_hwi (arg1);
unsigned HOST_WIDE_INT newmask, zerobits = 0;
tree shift_type = TREE_TYPE (arg0);
/* Only for gfc_trans_assign and gfc_trans_pointer_assign. */
#include "trans-stmt.h"
#include "dependency.h"
-
+ #include "gimple.h"
+ #include "gimplify.h"
+#include "wide-int.h"
/* Convert a scalar to an array descriptor. To be used for assumed-rank
arrays. */
static const char *const ifiles[] = {
"config.h", "system.h", "coretypes.h", "tm.h",
"hashtab.h", "splay-tree.h", "obstack.h", "bitmap.h", "input.h",
- "tree.h", "rtl.h", "function.h", "insn-config.h", "expr.h",
+ "tree.h", "rtl.h", "wide-int.h", "function.h", "insn-config.h", "expr.h",
"hard-reg-set.h", "basic-block.h", "cselib.h", "insn-addr.h",
"optabs.h", "libfuncs.h", "debug.h", "ggc.h", "cgraph.h",
- "gimple.h", "gimple-ssa.h", "tree-cfg.h", "tree-phinodes.h",
- "ssa-iterators.h", "tree-ssanames.h", "tree-ssa-loop.h",
- "tree-ssa-loop-ivopts.h", "tree-ssa-loop-manip.h",
+ "gimple.h", "gimple-iterator.h", "gimple-ssa.h", "tree-cfg.h",
+ "tree-phinodes.h", "ssa-iterators.h", "tree-ssanames.h",
+ "tree-ssa-loop.h", "tree-ssa-loop-ivopts.h", "tree-ssa-loop-manip.h",
"tree-ssa-loop-niter.h", "tree-into-ssa.h", "tree-dfa.h",
"tree-ssa.h", "reload.h", "cpp-id-data.h", "tree-chrec.h",
"except.h", "output.h", "cfgloop.h",
return false;
}
- if ((TREE_INT_CST_LOW (low) + 1
- != TREE_INT_CST_LOW (high))
- || (TREE_INT_CST_HIGH (low)
- + (TREE_INT_CST_LOW (high) == 0)
- != TREE_INT_CST_HIGH (high)))
+
+ /* Compare two case labels. Because the front end should already have
+ made sure that case ranges do not overlap, it is enough to only compare
+ the CASE_LOW values of each case label. */
+
+ static int
+ compare_case_labels (const void *p1, const void *p2)
+ {
+ const_tree const case1 = *(const_tree const*)p1;
+ const_tree const case2 = *(const_tree const*)p2;
+
+ /* The 'default' case label always goes first. */
+ if (!CASE_LOW (case1))
+ return -1;
+ else if (!CASE_LOW (case2))
+ return 1;
+ else
+ return tree_int_cst_compare (CASE_LOW (case1), CASE_LOW (case2));
+ }
+
+ /* Sort the case labels in LABEL_VEC in place in ascending order. */
+
+ void
+ sort_case_labels (vec<tree> label_vec)
+ {
+ label_vec.qsort (compare_case_labels);
+ }
+ \f
+ /* Prepare a vector of case labels to be used in a GIMPLE_SWITCH statement.
+
+ LABELS is a vector that contains all case labels to look at.
+
+ INDEX_TYPE is the type of the switch index expression. Case labels
+ in LABELS are discarded if their values are not in the value range
+ covered by INDEX_TYPE. The remaining case label values are folded
+ to INDEX_TYPE.
+
+ If a default case exists in LABELS, it is removed from LABELS and
+ returned in DEFAULT_CASEP. If no default case exists, but the
+ case labels already cover the whole range of INDEX_TYPE, a default
+ case is returned pointing to one of the existing case labels.
+ Otherwise DEFAULT_CASEP is set to NULL_TREE.
+
+ DEFAULT_CASEP may be NULL, in which case the above comment doesn't
+ apply and no action is taken regardless of whether a default case is
+ found or not. */
+
+ void
+ preprocess_case_label_vec_for_gimple (vec<tree> labels,
+ tree index_type,
+ tree *default_casep)
+ {
+ tree min_value, max_value;
+ tree default_case = NULL_TREE;
+ size_t i, len;
+
+ i = 0;
+ min_value = TYPE_MIN_VALUE (index_type);
+ max_value = TYPE_MAX_VALUE (index_type);
+ while (i < labels.length ())
+ {
+ tree elt = labels[i];
+ tree low = CASE_LOW (elt);
+ tree high = CASE_HIGH (elt);
+ bool remove_element = FALSE;
+
+ if (low)
+ {
+ gcc_checking_assert (TREE_CODE (low) == INTEGER_CST);
+ gcc_checking_assert (!high || TREE_CODE (high) == INTEGER_CST);
+
+ /* This is a non-default case label, i.e. it has a value.
+
+ See if the case label is reachable within the range of
+ the index type. Remove out-of-range case values. Turn
+ case ranges into a canonical form (high > low strictly)
+ and convert the case label values to the index type.
+
+ NB: The type of gimple_switch_index() may be the promoted
+ type, but the case labels retain the original type. */
+
+ if (high)
+ {
+ /* This is a case range. Discard empty ranges.
+ If the bounds or the range are equal, turn this
+ into a simple (one-value) case. */
+ int cmp = tree_int_cst_compare (high, low);
+ if (cmp < 0)
+ remove_element = TRUE;
+ else if (cmp == 0)
+ high = NULL_TREE;
+ }
+
+ if (! high)
+ {
+ /* If the simple case value is unreachable, ignore it. */
+ if ((TREE_CODE (min_value) == INTEGER_CST
+ && tree_int_cst_compare (low, min_value) < 0)
+ || (TREE_CODE (max_value) == INTEGER_CST
+ && tree_int_cst_compare (low, max_value) > 0))
+ remove_element = TRUE;
+ else
+ low = fold_convert (index_type, low);
+ }
+ else
+ {
+ /* If the entire case range is unreachable, ignore it. */
+ if ((TREE_CODE (min_value) == INTEGER_CST
+ && tree_int_cst_compare (high, min_value) < 0)
+ || (TREE_CODE (max_value) == INTEGER_CST
+ && tree_int_cst_compare (low, max_value) > 0))
+ remove_element = TRUE;
+ else
+ {
+ /* If the lower bound is less than the index type's
+ minimum value, truncate the range bounds. */
+ if (TREE_CODE (min_value) == INTEGER_CST
+ && tree_int_cst_compare (low, min_value) < 0)
+ low = min_value;
+ low = fold_convert (index_type, low);
+
+ /* If the upper bound is greater than the index type's
+ maximum value, truncate the range bounds. */
+ if (TREE_CODE (max_value) == INTEGER_CST
+ && tree_int_cst_compare (high, max_value) > 0)
+ high = max_value;
+ high = fold_convert (index_type, high);
+
+ /* We may have folded a case range to a one-value case. */
+ if (tree_int_cst_equal (low, high))
+ high = NULL_TREE;
+ }
+ }
+
+ CASE_LOW (elt) = low;
+ CASE_HIGH (elt) = high;
+ }
+ else
+ {
+ gcc_assert (!default_case);
+ default_case = elt;
+ /* The default case must be passed separately to the
+ gimple_build_switch routine. But if DEFAULT_CASEP
+ is NULL, we do not remove the default case (it would
+ be completely lost). */
+ if (default_casep)
+ remove_element = TRUE;
+ }
+
+ if (remove_element)
+ labels.ordered_remove (i);
+ else
+ i++;
+ }
+ len = i;
+
+ if (!labels.is_empty ())
+ sort_case_labels (labels);
+
+ if (default_casep && !default_case)
+ {
+ /* If the switch has no default label, add one, so that we jump
+ around the switch body. If the labels already cover the whole
+ range of the switch index_type, add the default label pointing
+ to one of the existing labels. */
+ if (len
+ && TYPE_MIN_VALUE (index_type)
+ && TYPE_MAX_VALUE (index_type)
+ && tree_int_cst_equal (CASE_LOW (labels[0]),
+ TYPE_MIN_VALUE (index_type)))
+ {
+ tree low, high = CASE_HIGH (labels[len - 1]);
+ if (!high)
+ high = CASE_LOW (labels[len - 1]);
+ if (tree_int_cst_equal (high, TYPE_MAX_VALUE (index_type)))
+ {
+ for (i = 1; i < len; i++)
+ {
+ high = CASE_LOW (labels[i]);
+ low = CASE_HIGH (labels[i - 1]);
+ if (!low)
+ low = CASE_LOW (labels[i - 1]);
++ if (wi::add (low, 1) != high)
+ break;
+ }
+ if (i == len)
+ {
+ tree label = CASE_LABEL (labels[0]);
+ default_case = build_case_label (NULL_TREE, NULL_TREE,
+ label);
+ }
+ }
+ }
+ }
+
+ if (default_casep)
+ *default_casep = default_case;
+ }
+
+ /* Set the location of all statements in SEQ to LOC. */
+
+ void
+ gimple_seq_set_location (gimple_seq seq, location_t loc)
+ {
+ for (gimple_stmt_iterator i = gsi_start (seq); !gsi_end_p (i); gsi_next (&i))
+ gimple_set_location (gsi_stmt (i), loc);
+ }
#include "pointer-set.h"
#include "tree-affine.h"
#include "gimple.h"
+ #include "gimplify.h"
#include "flags.h"
#include "dumpfile.h"
+#include "wide-int-print.h"
/* Extends CST as appropriate for the affine combinations COMB. */
{
tree dest = gimple_call_arg (stmt, 0);
tree len = gimple_call_arg (stmt, 2);
- tree base = NULL_TREE;
- HOST_WIDE_INT offset = 0;
- if (!host_integerp (len, 0))
+ if (!tree_fits_shwi_p (len))
return false;
- if (TREE_CODE (dest) == ADDR_EXPR)
- base = get_addr_base_and_unit_offset (TREE_OPERAND (dest, 0),
- &offset);
- else if (TREE_CODE (dest) == SSA_NAME)
- base = dest;
- if (base
- && base == ao_ref_base (ref))
+ tree rbase = ref->base;
- double_int roffset = double_int::from_shwi (ref->offset);
++ offset_int roffset = wi::to_offset (ref->offset);
+ ao_ref dref;
+ ao_ref_init_from_ptr_and_size (&dref, dest, len);
+ tree base = ao_ref_base (&dref);
- double_int offset = double_int::from_shwi (dref.offset);
- double_int bpu = double_int::from_uhwi (BITS_PER_UNIT);
++ offset_int offset = wi::to_offset (dref.offset);
++ offset_int bpu = wi::to_offset (BITS_PER_UNIT);
+ if (!base || dref.size == -1)
+ return false;
+ if (TREE_CODE (base) == MEM_REF)
+ {
+ if (TREE_CODE (rbase) != MEM_REF)
+ return false;
+ // Compare pointers.
+ offset += bpu * mem_ref_offset (base);
+ roffset += bpu * mem_ref_offset (rbase);
+ base = TREE_OPERAND (base, 0);
+ rbase = TREE_OPERAND (rbase, 0);
+ }
+ if (base == rbase)
{
- HOST_WIDE_INT size = tree_to_hwi (len);
- if (offset <= ref->offset / BITS_PER_UNIT
- && (offset + size
- >= ((ref->offset + ref->max_size + BITS_PER_UNIT - 1)
- / BITS_PER_UNIT)))
- double_int size = bpu * tree_to_double_int (len);
- double_int rsize = double_int::from_uhwi (ref->max_size);
- if (offset.sle (roffset)
- && (roffset + rsize).sle (offset + size))
++ wide_int size = bpu * tree_to_hwi (len);
++ if (wi::le_p (offset, roffset, SIGNED)
++ && wi::le_p (roffset + ref->max_size, offset + size, SIGNED))
return true;
}
break;
}
break;
+ CASE_CONVERT:
+ {
+ tree inner_mode, outer_mode;
+ outer_mode = TREE_TYPE (expr);
+ inner_mode = TREE_TYPE (op0);
+ cost = new_cost (convert_cost (TYPE_MODE (outer_mode),
+ TYPE_MODE (inner_mode), speed), 0);
+ }
+ break;
+
case MULT_EXPR:
- if (cst_and_fits_in_hwi (op0))
+ if (cst_fits_shwi_p (op0))
cost = new_cost (mult_by_coeff_cost (int_cst_value (op0),
mode, speed), 0);
- else if (cst_and_fits_in_hwi (op1))
+ else if (cst_fits_shwi_p (op1))
cost = new_cost (mult_by_coeff_cost (int_cst_value (op1),
mode, speed), 0);
else
swap (dr_a2, dr_b2);
}
- if (!operand_equal_p (dr_a1->basic_addr, dr_a2->basic_addr, 0)
+ if (!operand_equal_p (DR_BASE_ADDRESS (dr_a1->dr),
+ DR_BASE_ADDRESS (dr_a2->dr),
+ 0)
- || !host_integerp (dr_a1->offset, 0)
- || !host_integerp (dr_a2->offset, 0))
+ || !tree_fits_shwi_p (dr_a1->offset)
+ || !tree_fits_shwi_p (dr_a2->offset))
continue;
- HOST_WIDE_INT diff = TREE_INT_CST_LOW (dr_a2->offset) -
- TREE_INT_CST_LOW (dr_a1->offset);
+ HOST_WIDE_INT diff = (tree_to_shwi (dr_a2->offset)
+ - tree_to_shwi (dr_a1->offset));
/* Now we check if the following condition is satisfied:
}
if (mode == -2)
continue;
- if (unsignedp)
+ if (sign_p == UNSIGNED)
{
unsigned HOST_WIDE_INT mh;
- unsigned HOST_WIDE_INT d = tree_to_uhwi (cst) & mask;
- unsigned HOST_WIDE_INT d = TREE_INT_CST_LOW (cst) & mask;
++ unsigned HOST_WIDE_INT d = tree_to_hwi (cst) & mask;
if (d >= ((unsigned HOST_WIDE_INT) 1 << (prec - 1)))
/* FIXME: Can transform this into op0 >= op1 ? 1 : 0. */
}
else
{
- HOST_WIDE_INT d = tree_to_shwi (cst);
- HOST_WIDE_INT d = TREE_INT_CST_LOW (cst);
++ HOST_WIDE_INT d = tree_to_hwi (cst);
unsigned HOST_WIDE_INT abs_d;
if (d == -1)
{
unsigned HOST_WIDE_INT mh, ml;
int pre_shift, post_shift;
- unsigned HOST_WIDE_INT d = tree_to_uhwi (oprnd1)
- unsigned HOST_WIDE_INT d = (TREE_INT_CST_LOW (oprnd1)
- & GET_MODE_MASK (TYPE_MODE (itype)));
++ unsigned HOST_WIDE_INT d = tree_to_hwi (oprnd1)
+ & GET_MODE_MASK (TYPE_MODE (itype));
tree t1, t2, t3, t4;
if (d >= ((unsigned HOST_WIDE_INT) 1 << (prec - 1)))
{
unsigned HOST_WIDE_INT ml;
int post_shift;
- HOST_WIDE_INT d = tree_to_shwi (oprnd1);
- HOST_WIDE_INT d = TREE_INT_CST_LOW (oprnd1);
++ HOST_WIDE_INT d = tree_to_hwi (oprnd1);
unsigned HOST_WIDE_INT abs_d;
bool add = false;
tree t1, t2, t3, t4;