bitmap rvuse_gen;
bitmap rvuse_kill;
- /* For actually occuring loads, as long as they occur before all the
+ /* For actually occurring loads, as long as they occur before all the
other stores in the block, we know they are antic at the top of
the block, regardless of RVUSE_KILL. */
value_set_t antic_safe_loads;
case PARM_DECL:
case RESULT_DECL:
case SSA_NAME:
+ case STRING_CST:
return genop;
default:
gcc_unreachable ();
}
temp = pretemp;
- add_referenced_tmp_var (temp);
+ add_referenced_var (temp);
if (TREE_CODE (TREE_TYPE (expr)) == COMPLEX_TYPE)
DECL_COMPLEX_GIMPLE_REG_P (temp) = 1;
}
temp = prephitemp;
- add_referenced_tmp_var (temp);
+ add_referenced_var (temp);
if (TREE_CODE (type) == COMPLEX_TYPE)
DECL_COMPLEX_GIMPLE_REG_P (temp) = 1;
if (op == NULL_TREE)
continue;
- /* If OP is a constant that has overflowed, do not value number
- this expression. */
- if (CONSTANT_CLASS_P (op)
- && TREE_OVERFLOW (op))
- {
- pool_free (pool, vexpr);
- return NULL;
- }
-
/* Recursively value-numberize reference ops and tree lists. */
if (REFERENCE_CLASS_P (op))
{
fprintf (dump_file, " to merge available but not dominating values ");
}
- add_referenced_tmp_var (temp);
+ add_referenced_var (temp);
temp = create_phi_node (temp, block);
NECESSARY (temp) = 0;
VEC_safe_push (tree, heap, inserted_exprs, temp);
tree newstmt;
/* Mark the temp variable as referenced */
- add_referenced_tmp_var (SSA_NAME_VAR (TREE_OPERAND (stmt, 0)));
+ add_referenced_var (SSA_NAME_VAR (TREE_OPERAND (stmt, 0)));
- /* Put the new statement in GC memory, fix up the annotation
- and SSA_NAME_DEF_STMT on it, and then put it in place of
- the old statement in the IR stream. */
- newstmt = unshare_expr (stmt);
+ /* Put the new statement in GC memory, fix up the
+ SSA_NAME_DEF_STMT on it, and then put it in place of
+ the old statement before the store in the IR stream
+ as a plain ssa name copy. */
+ bsi = bsi_for_stmt (stmt);
+ bsi_prev (&bsi);
+ newstmt = build2 (MODIFY_EXPR, void_type_node,
+ TREE_OPERAND (stmt, 0),
+ TREE_OPERAND (bsi_stmt (bsi), 1));
SSA_NAME_DEF_STMT (TREE_OPERAND (newstmt, 0)) = newstmt;
-
- newstmt->common.ann = stmt->common.ann;
-
+ bsi_insert_before (&bsi, newstmt, BSI_SAME_STMT);
bsi = bsi_for_stmt (stmt);
- bsi_replace (&bsi, newstmt, true);
+ bsi_remove (&bsi, true);
}
else
release_defs (stmt);
}
}
+/* Tree-combine a value number expression *EXPR_P that does a type
+ conversion with the value number expression of its operand.
+ Returns true, if *EXPR_P simplifies to a value number or
+ gimple min-invariant expression different from EXPR_P and
+ sets *EXPR_P to the simplified expression value number.
+ Otherwise returns false and does not change *EXPR_P. */
+
+static bool
+try_combine_conversion (tree *expr_p)
+{
+ tree expr = *expr_p;
+ tree t;
+
+ if (!((TREE_CODE (expr) == NOP_EXPR
+ || TREE_CODE (expr) == CONVERT_EXPR)
+ && TREE_CODE (TREE_OPERAND (expr, 0)) == VALUE_HANDLE
+ && !VALUE_HANDLE_VUSES (TREE_OPERAND (expr, 0))))
+ return false;
+
+ t = fold_unary (TREE_CODE (expr), TREE_TYPE (expr),
+ VALUE_HANDLE_EXPR_SET (TREE_OPERAND (expr, 0))->head->expr);
+
+ /* Disallow value expressions we have no value number for already, as
+ we would miss a leader for it here. */
+ if (t
+ && !(TREE_CODE (t) == VALUE_HANDLE
+ || is_gimple_min_invariant (t)))
+ t = vn_lookup (t, NULL);
+
+ if (t && t != expr)
+ {
+ *expr_p = t;
+ return true;
+ }
+ return false;
+}
/* Compute the AVAIL set for all basic blocks.
tree newt = create_value_expr_from (rhs, block, stmt);
if (newt)
{
- add_to_sets (lhs, newt, stmt, TMP_GEN (block),
- AVAIL_OUT (block));
- value_insert_into_set (EXP_GEN (block), newt);
+ /* If we can combine a conversion expression
+ with the expression for its operand just
+ record the value number for it. */
+ if (try_combine_conversion (&newt))
+ vn_add (lhs, newt);
+ else
+ {
+ tree val = vn_lookup_or_add (newt, stmt);
+ vn_add (lhs, val);
+ value_insert_into_set (EXP_GEN (block), newt);
+ }
+ bitmap_insert_into_set (TMP_GEN (block), lhs);
+ bitmap_value_insert_into_set (AVAIL_OUT (block), lhs);
continue;
}
}