diff options
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/double-int.c | 33 | ||||
-rw-r--r-- | gcc/double-int.h | 1 | ||||
-rw-r--r-- | gcc/tree-ssa-sccvn.c | 30 |
4 files changed, 53 insertions, 20 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 879c0244054..0dc66003fb4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,14 @@ 2013-05-07 Richard Biener <rguenther@suse.de> + * double-int.h (rshift): New overload. + * double-int.c (rshift): New function. + * tree-ssa-sccvn.c (copy_reference_ops_from_ref): Optimize. + (create_reference_ops_from_ref): Remove. + (vn_reference_insert): Use shared ops for constructing the + reference and copy it. + +2013-05-07 Richard Biener <rguenther@suse.de> + PR middle-end/57190 * tree-eh.c (sink_clobbers): Properly propagate SSA_NAME_OCCURS_IN_ABNORMAL_PHI. diff --git a/gcc/double-int.c b/gcc/double-int.c index b098f57b65c..fe3c096619a 100644 --- a/gcc/double-int.c +++ b/gcc/double-int.c @@ -1116,6 +1116,39 @@ double_int::lshift (HOST_WIDE_INT count) const return ret; } +/* Shift A right by COUNT places. */ + +double_int +double_int::rshift (HOST_WIDE_INT count) const +{ + double_int ret; + + gcc_checking_assert (count >= 0); + + if (count >= HOST_BITS_PER_DOUBLE_INT) + { + /* Shifting by the host word size is undefined according to the + ANSI standard, so we must handle this as a special case. */ + ret.high = 0; + ret.low = 0; + } + else if (count >= HOST_BITS_PER_WIDE_INT) + { + ret.high = 0; + ret.low + = (unsigned HOST_WIDE_INT) (high >> (count - HOST_BITS_PER_WIDE_INT)); + } + else + { + ret.high = high >> count; + ret.low = ((low >> count) + | ((unsigned HOST_WIDE_INT) high + << (HOST_BITS_PER_WIDE_INT - count - 1) << 1)); + } + + return ret; +} + /* Shift A left by COUNT places keeping only PREC bits of result. Shift right if COUNT is negative. ARITH true specifies arithmetic shifting; otherwise use logical shift. */ diff --git a/gcc/double-int.h b/gcc/double-int.h index 39929d2b5bf..8e709e6d415 100644 --- a/gcc/double-int.h +++ b/gcc/double-int.h @@ -130,6 +130,7 @@ struct double_int double_int lshift (HOST_WIDE_INT count) const; double_int lshift (HOST_WIDE_INT count, unsigned int prec, bool arith) const; + double_int rshift (HOST_WIDE_INT count) const; double_int rshift (HOST_WIDE_INT count, unsigned int prec, bool arith) const; double_int alshift (HOST_WIDE_INT count, unsigned int prec) const; double_int arshift (HOST_WIDE_INT count, unsigned int prec) const; diff --git a/gcc/tree-ssa-sccvn.c b/gcc/tree-ssa-sccvn.c index 07bfdcccb81..49d61b0c239 100644 --- a/gcc/tree-ssa-sccvn.c +++ b/gcc/tree-ssa-sccvn.c @@ -728,6 +728,8 @@ copy_reference_ops_from_ref (tree ref, vec<vn_reference_op_s> *result) { vn_reference_op_s temp; + result->reserve (3); + memset (&temp, 0, sizeof (temp)); temp.type = TREE_TYPE (ref); temp.opcode = TREE_CODE (ref); @@ -735,21 +737,21 @@ copy_reference_ops_from_ref (tree ref, vec<vn_reference_op_s> *result) temp.op1 = TMR_STEP (ref); temp.op2 = TMR_OFFSET (ref); temp.off = -1; - result->safe_push (temp); + result->quick_push (temp); memset (&temp, 0, sizeof (temp)); temp.type = NULL_TREE; temp.opcode = ERROR_MARK; temp.op0 = TMR_INDEX2 (ref); temp.off = -1; - result->safe_push (temp); + result->quick_push (temp); memset (&temp, 0, sizeof (temp)); temp.type = NULL_TREE; temp.opcode = TREE_CODE (TMR_BASE (ref)); temp.op0 = TMR_BASE (ref); temp.off = -1; - result->safe_push (temp); + result->quick_push (temp); return; } @@ -802,9 +804,8 @@ copy_reference_ops_from_ref (tree ref, vec<vn_reference_op_s> *result) double_int off = tree_to_double_int (this_offset) + tree_to_double_int (bit_offset) - .arshift (BITS_PER_UNIT == 8 - ? 3 : exact_log2 (BITS_PER_UNIT), - HOST_BITS_PER_DOUBLE_INT); + .rshift (BITS_PER_UNIT == 8 + ? 3 : exact_log2 (BITS_PER_UNIT)); if (off.fits_shwi ()) temp.off = off.low; } @@ -846,7 +847,7 @@ copy_reference_ops_from_ref (tree ref, vec<vn_reference_op_s> *result) temp.off = 0; result->safe_push (temp); temp.opcode = ADDR_EXPR; - temp.op0 = build_fold_addr_expr (ref); + temp.op0 = build1 (ADDR_EXPR, TREE_TYPE (temp.op0), ref); temp.type = TREE_TYPE (temp.op0); temp.off = -1; break; @@ -1114,18 +1115,6 @@ copy_reference_ops_from_call (gimple call, } } -/* Create a vector of vn_reference_op_s structures from REF, a - REFERENCE_CLASS_P tree. The vector is not shared. */ - -static vec<vn_reference_op_s> -create_reference_ops_from_ref (tree ref) -{ - vec<vn_reference_op_s> result = vNULL; - - copy_reference_ops_from_ref (ref, &result); - return result; -} - /* Create a vector of vn_reference_op_s structures from CALL, a call statement. The vector is not shared. */ @@ -2096,6 +2085,7 @@ vn_reference_insert (tree op, tree result, tree vuse, tree vdef) { vn_reference_s **slot; vn_reference_t vr1; + bool tem; vr1 = (vn_reference_t) pool_alloc (current_info->references_pool); if (TREE_CODE (result) == SSA_NAME) @@ -2103,7 +2093,7 @@ vn_reference_insert (tree op, tree result, tree vuse, tree vdef) else vr1->value_id = get_or_alloc_constant_value_id (result); vr1->vuse = vuse ? SSA_VAL (vuse) : NULL_TREE; - vr1->operands = valueize_refs (create_reference_ops_from_ref (op)); + vr1->operands = valueize_shared_reference_ops_from_ref (op, &tem).copy (); vr1->type = TREE_TYPE (op); vr1->set = get_alias_set (op); vr1->hashcode = vn_reference_compute_hash (vr1); |