aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-pre.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-ssa-pre.c')
-rw-r--r--gcc/tree-ssa-pre.c120
1 files changed, 109 insertions, 11 deletions
diff --git a/gcc/tree-ssa-pre.c b/gcc/tree-ssa-pre.c
index a62439f2af2..8293e978d67 100644
--- a/gcc/tree-ssa-pre.c
+++ b/gcc/tree-ssa-pre.c
@@ -1629,12 +1629,28 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
newop.op0 = op0;
newop.op1 = op1;
newop.op2 = op2;
+ /* If it transforms a non-constant ARRAY_REF into a constant
+ one, adjust the constant offset. */
+ if (newop.opcode == ARRAY_REF
+ && newop.off == -1
+ && TREE_CODE (op0) == INTEGER_CST
+ && TREE_CODE (op1) == INTEGER_CST
+ && TREE_CODE (op2) == INTEGER_CST)
+ {
+ double_int off = tree_to_double_int (op0);
+ off = double_int_add (off,
+ double_int_neg
+ (tree_to_double_int (op1)));
+ off = double_int_mul (off, tree_to_double_int (op2));
+ if (double_int_fits_in_shwi_p (off))
+ newop.off = off.low;
+ }
VEC_replace (vn_reference_op_s, newoperands, j, &newop);
/* If it transforms from an SSA_NAME to an address, fold with
a preceding indirect reference. */
if (j > 0 && op0 && TREE_CODE (op0) == ADDR_EXPR
&& VEC_index (vn_reference_op_s,
- newoperands, j - 1)->opcode == INDIRECT_REF)
+ newoperands, j - 1)->opcode == MEM_REF)
vn_reference_fold_indirect (&newoperands, &j);
}
if (i != VEC_length (vn_reference_op_s, operands))
@@ -1661,6 +1677,7 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
{
unsigned int new_val_id;
pre_expr constant;
+ bool converted = false;
tree result = vn_reference_lookup_pieces (newvuse, ref->set,
ref->type,
@@ -1669,6 +1686,13 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
if (result)
VEC_free (vn_reference_op_s, heap, newoperands);
+ if (result
+ && !useless_type_conversion_p (ref->type, TREE_TYPE (result)))
+ {
+ result = fold_build1 (VIEW_CONVERT_EXPR, ref->type, result);
+ converted = true;
+ }
+
if (result && is_gimple_min_invariant (result))
{
gcc_assert (!newoperands);
@@ -1679,7 +1703,54 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
expr->kind = REFERENCE;
expr->id = 0;
- if (newref)
+ if (converted)
+ {
+ vn_nary_op_t nary;
+ tree nresult;
+
+ gcc_assert (CONVERT_EXPR_P (result)
+ || TREE_CODE (result) == VIEW_CONVERT_EXPR);
+
+ nresult = vn_nary_op_lookup_pieces (1, TREE_CODE (result),
+ TREE_TYPE (result),
+ TREE_OPERAND (result, 0),
+ NULL_TREE, NULL_TREE,
+ NULL_TREE,
+ &nary);
+ if (nresult && is_gimple_min_invariant (nresult))
+ return get_or_alloc_expr_for_constant (nresult);
+
+ expr->kind = NARY;
+ if (nary)
+ {
+ PRE_EXPR_NARY (expr) = nary;
+ constant = fully_constant_expression (expr);
+ if (constant != expr)
+ return constant;
+
+ new_val_id = nary->value_id;
+ get_or_alloc_expression_id (expr);
+ }
+ else
+ {
+ new_val_id = get_next_value_id ();
+ VEC_safe_grow_cleared (bitmap_set_t, heap,
+ value_expressions,
+ get_max_value_id() + 1);
+ nary = vn_nary_op_insert_pieces (1, TREE_CODE (result),
+ TREE_TYPE (result),
+ TREE_OPERAND (result, 0),
+ NULL_TREE, NULL_TREE,
+ NULL_TREE, NULL_TREE,
+ new_val_id);
+ PRE_EXPR_NARY (expr) = nary;
+ constant = fully_constant_expression (expr);
+ if (constant != expr)
+ return constant;
+ get_or_alloc_expression_id (expr);
+ }
+ }
+ else if (newref)
{
PRE_EXPR_REFERENCE (expr) = newref;
constant = fully_constant_expression (expr);
@@ -1884,7 +1955,10 @@ bitmap_find_leader (bitmap_set_t set, unsigned int val, gimple stmt)
gimple def_stmt = SSA_NAME_DEF_STMT (PRE_EXPR_NAME (val));
if (gimple_code (def_stmt) != GIMPLE_PHI
&& gimple_bb (def_stmt) == gimple_bb (stmt)
- && gimple_uid (def_stmt) >= gimple_uid (stmt))
+ /* PRE insertions are at the end of the basic-block
+ and have UID 0. */
+ && (gimple_uid (def_stmt) == 0
+ || gimple_uid (def_stmt) >= gimple_uid (stmt)))
continue;
}
return val;
@@ -2598,7 +2672,7 @@ can_PRE_operation (tree op)
return UNARY_CLASS_P (op)
|| BINARY_CLASS_P (op)
|| COMPARISON_CLASS_P (op)
- || TREE_CODE (op) == INDIRECT_REF
+ || TREE_CODE (op) == MEM_REF
|| TREE_CODE (op) == COMPONENT_REF
|| TREE_CODE (op) == VIEW_CONVERT_EXPR
|| TREE_CODE (op) == CALL_EXPR
@@ -2674,6 +2748,29 @@ create_component_ref_by_pieces_1 (basic_block block, vn_reference_t ref,
return folded;
}
break;
+ case MEM_REF:
+ {
+ tree baseop = create_component_ref_by_pieces_1 (block, ref, operand,
+ stmts, domstmt);
+ tree offset = currop->op0;
+ if (!baseop)
+ return NULL_TREE;
+ if (TREE_CODE (baseop) == ADDR_EXPR
+ && handled_component_p (TREE_OPERAND (baseop, 0)))
+ {
+ HOST_WIDE_INT off;
+ tree base;
+ base = get_addr_base_and_unit_offset (TREE_OPERAND (baseop, 0),
+ &off);
+ gcc_assert (base);
+ offset = int_const_binop (PLUS_EXPR, offset,
+ build_int_cst (TREE_TYPE (offset),
+ off), 0);
+ baseop = build_fold_addr_expr (base);
+ }
+ return fold_build2 (MEM_REF, currop->type, baseop, offset);
+ }
+ break;
case TARGET_MEM_REF:
{
vn_reference_op_t nextop = VEC_index (vn_reference_op_s, ref->operands,
@@ -2726,9 +2823,7 @@ create_component_ref_by_pieces_1 (basic_block block, vn_reference_t ref,
return folded;
}
break;
- case ALIGN_INDIRECT_REF:
case MISALIGNED_INDIRECT_REF:
- case INDIRECT_REF:
{
tree folded;
tree genop1 = create_component_ref_by_pieces_1 (block, ref,
@@ -2880,7 +2975,7 @@ create_component_ref_by_pieces_1 (basic_block block, vn_reference_t ref,
}
/* For COMPONENT_REF's and ARRAY_REF's, we can't have any intermediates for the
- COMPONENT_REF or INDIRECT_REF or ARRAY_REF portion, because we'd end up with
+ COMPONENT_REF or MEM_REF or ARRAY_REF portion, because we'd end up with
trying to rename aggregates into ssa form directly, which is a no no.
Thus, this routine doesn't create temporaries, it just builds a
@@ -2928,9 +3023,10 @@ find_or_generate_expression (basic_block block, pre_expr expr,
}
/* If it's still NULL, it must be a complex expression, so generate
- it recursively. Not so for FRE though. */
+ it recursively. Not so if inserting expressions for values generated
+ by SCCVN. */
if (genop == NULL
- && !in_fre)
+ && !domstmt)
{
bitmap_set_t exprset;
unsigned int lookfor = get_expr_value_id (expr);
@@ -3131,7 +3227,7 @@ create_expression_by_pieces (basic_block block, pre_expr expr,
VN_INFO (name)->value_id = value_id;
nameexpr = get_or_alloc_expr_for_name (name);
add_to_value (value_id, nameexpr);
- if (!in_fre)
+ if (NEW_SETS (block))
bitmap_value_replace_in_set (NEW_SETS (block), nameexpr);
bitmap_value_replace_in_set (AVAIL_OUT (block), nameexpr);
@@ -3310,6 +3406,8 @@ insert_into_preds_of_block (basic_block block, unsigned int exprnum,
avail[bprime->index] = get_or_alloc_expr_for_name (forcedexpr);
}
}
+ else
+ avail[bprime->index] = get_or_alloc_expr_for_constant (builtexpr);
}
}
else if (eprime->kind == NAME)
@@ -4723,7 +4821,7 @@ execute_pre (bool do_fre)
if (!do_fre)
loop_optimizer_init (LOOPS_NORMAL);
- if (!run_scc_vn (do_fre))
+ if (!run_scc_vn ())
{
if (!do_fre)
loop_optimizer_finalize ();