gcc_unreachable ();
}
-/* Get a representative SSA_NAME for a given expression.
+/* Get a representative SSA_NAME for a given expression that is available in B.
Since all of our sub-expressions are treated as values, we require
them to be SSA_NAME's for simplicity.
Prior versions of GVNPRE used to use "value handles" here, so that
them to be usable without finding leaders). */
static tree
-get_representative_for (const pre_expr e)
+get_representative_for (const pre_expr e, basic_block b = NULL)
{
- tree name;
+ tree name, valnum = NULL_TREE;
unsigned int value_id = get_expr_value_id (e);
switch (e->kind)
{
pre_expr rep = expression_for_id (i);
if (rep->kind == NAME)
- return VN_INFO (PRE_EXPR_NAME (rep))->valnum;
+ {
+ tree name = PRE_EXPR_NAME (rep);
+ valnum = VN_INFO (name)->valnum;
+ gimple *def = SSA_NAME_DEF_STMT (name);
+ /* We have to return either a new representative or one
+ that can be used for expression simplification and thus
+ is available in B. */
+ if (! b
+ || gimple_nop_p (def)
+ || dominated_by_p (CDI_DOMINATORS, b, gimple_bb (def)))
+ return name;
+ }
else if (rep->kind == CONSTANT)
return PRE_EXPR_CONSTANT (rep);
}
to compute it. */
name = make_temp_ssa_name (get_expr_type (e), gimple_build_nop (), "pretmp");
VN_INFO_GET (name)->value_id = value_id;
- VN_INFO (name)->valnum = name;
+ VN_INFO (name)->valnum = valnum ? valnum : name;
/* ??? For now mark this SSA name for release by SCCVN. */
VN_INFO (name)->needs_insertion = true;
add_to_value (value_id, get_or_alloc_expr_for_name (name));
leader = find_leader_in_sets (op_val_id, set1, set2);
result = phi_translate (leader, set1, set2, pred, phiblock);
if (result && result != leader)
- newnary->op[i] = get_representative_for (result);
+ /* Force a leader as well as we are simplifying this
+ expression. */
+ newnary->op[i] = get_representative_for (result, pred);
else if (!result)
return NULL;
return constant;
}
+ /* vn_nary_* do not valueize operands. */
+ for (i = 0; i < newnary->length; ++i)
+ if (TREE_CODE (newnary->op[i]) == SSA_NAME)
+ newnary->op[i] = VN_INFO (newnary->op[i])->valnum;
tree result = vn_nary_op_lookup_pieces (newnary->length,
newnary->opcode,
newnary->type,
PRE_EXPR_NARY (expr) = nary;
new_val_id = nary->value_id;
get_or_alloc_expression_id (expr);
- /* When we end up re-using a value number make sure that
- doesn't have unrelated (which we can't check here)
- range or points-to info on it. */
- if (result
- && INTEGRAL_TYPE_P (TREE_TYPE (result))
- && SSA_NAME_RANGE_INFO (result)
- && ! SSA_NAME_IS_DEFAULT_DEF (result))
- {
- if (! VN_INFO (result)->info.range_info)
- {
- VN_INFO (result)->info.range_info
- = SSA_NAME_RANGE_INFO (result);
- VN_INFO (result)->range_info_anti_range_p
- = SSA_NAME_ANTI_RANGE_P (result);
- }
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "clearing range info of ");
- print_generic_expr (dump_file, result);
- fprintf (dump_file, "\n");
- }
- SSA_NAME_RANGE_INFO (result) = NULL;
- }
- else if (result
- && POINTER_TYPE_P (TREE_TYPE (result))
- && SSA_NAME_PTR_INFO (result)
- && ! SSA_NAME_IS_DEFAULT_DEF (result))
- {
- if (! VN_INFO (result)->info.ptr_info)
- VN_INFO (result)->info.ptr_info
- = SSA_NAME_PTR_INFO (result);
- if (dump_file && (dump_flags & TDF_DETAILS))
- {
- fprintf (dump_file, "clearing points-to info of ");
- print_generic_expr (dump_file, result);
- fprintf (dump_file, "\n");
- }
- SSA_NAME_PTR_INFO (result) = NULL;
- }
}
else
{