static vec<pre_expr> expressions;
static hash_table<pre_expr_d> *expression_to_id;
static vec<unsigned> name_to_id;
+static obstack pre_expr_obstack;
/* Allocate an expression id for EXPR. */
return result;
}
-/* Given an NARY, get or create a pre_expr to represent it. */
+/* Given an NARY, get or create a pre_expr to represent it. Assign
+ VALUE_ID to it or allocate a new value-id if it is zero. Record
+ LOC as the original location of the expression. */
static pre_expr
-get_or_alloc_expr_for_nary (vn_nary_op_t nary,
+get_or_alloc_expr_for_nary (vn_nary_op_t nary, unsigned value_id,
location_t loc = UNKNOWN_LOCATION)
{
struct pre_expr_d expr;
pre_expr result;
unsigned int result_id;
+ gcc_assert (value_id == 0 || !value_id_constant_p (value_id));
+
expr.kind = NARY;
expr.id = 0;
+ nary->hashcode = vn_nary_op_compute_hash (nary);
PRE_EXPR_NARY (&expr) = nary;
result_id = lookup_expression_id (&expr);
if (result_id != 0)
result = pre_expr_pool.allocate ();
result->kind = NARY;
result->loc = loc;
- result->value_id = nary->value_id;
- PRE_EXPR_NARY (result) = nary;
+ result->value_id = value_id ? value_id : get_next_value_id ();
+ PRE_EXPR_NARY (result)
+ = alloc_vn_nary_op_noinit (nary->length, &pre_expr_obstack);
+ memcpy (PRE_EXPR_NARY (result), nary, sizeof_vn_nary_op (nary->length));
alloc_expression_id (result);
return result;
}
return get_or_alloc_expr_for_constant (result);
if (!nary || nary->predicated_values)
- {
- new_val_id = get_next_value_id ();
- nary = vn_nary_op_insert_pieces (newnary->length,
- newnary->opcode,
- newnary->type,
- &newnary->op[0],
- result, new_val_id);
- }
- expr = get_or_alloc_expr_for_nary (nary, expr_loc);
+ new_val_id = 0;
+ else
+ new_val_id = nary->value_id;
+ expr = get_or_alloc_expr_for_nary (newnary, new_val_id, expr_loc);
add_to_value (get_expr_value_id (expr), expr);
}
return expr;
/* Defer. */
return NULL_TREE;
}
+ gcc_assert (!value_id_constant_p (lookfor));
/* It must be a complex expression, so generate it recursively. Note
that this is only necessary to handle gcc.dg/tree-ssa/ssa-pre28.c
FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_DEF)
{
pre_expr e = get_or_alloc_expr_for_name (op);
+ unsigned value_id = get_expr_value_id (e);
+ if (value_id_constant_p (value_id))
+ {
+ get_or_alloc_expr_for_constant (VN_INFO (op)->valnum);
+ continue;
+ }
- add_to_value (get_expr_value_id (e), e);
+ add_to_value (value_id, e);
bitmap_insert_into_set (TMP_GEN (block), e);
bitmap_value_insert_into_set (AVAIL_OUT (block), e);
}
if (!nary || nary->predicated_values)
continue;
+ unsigned value_id = nary->value_id;
+ if (value_id_constant_p (value_id))
+ continue;
+
+ /* Record the un-valueized expression for EXP_GEN. */
+ nary = XALLOCAVAR (struct vn_nary_op_s,
+ sizeof_vn_nary_op
+ (vn_nary_length_from_stmt (stmt)));
+ init_vn_nary_op_from_stmt (nary, as_a <gassign *> (stmt));
+
/* If the NARY traps and there was a preceding
point in the block that might not return avoid
adding the nary to EXP_GEN. */
continue;
result = get_or_alloc_expr_for_nary
- (nary, gimple_location (stmt));
+ (nary, value_id, gimple_location (stmt));
break;
}
constant_value_expressions.create (get_max_constant_value_id () + 1);
constant_value_expressions.quick_grow_cleared (get_max_constant_value_id () + 1);
name_to_id.create (0);
+ gcc_obstack_init (&pre_expr_obstack);
inserted_exprs = BITMAP_ALLOC (NULL);
delete expression_to_id;
expression_to_id = NULL;
name_to_id.release ();
+ obstack_free (&pre_expr_obstack, NULL);
basic_block bb;
FOR_ALL_BB_FN (bb, cfun)
static struct obstack vn_ssa_aux_obstack;
static vn_nary_op_t vn_nary_op_insert_stmt (gimple *, tree);
-static unsigned int vn_nary_length_from_stmt (gimple *);
-static vn_nary_op_t alloc_vn_nary_op_noinit (unsigned int, obstack *);
static vn_nary_op_t vn_nary_op_insert_into (vn_nary_op_t,
vn_nary_op_table_type *);
-static void init_vn_nary_op_from_stmt (vn_nary_op_t, gassign *);
static void init_vn_nary_op_from_pieces (vn_nary_op_t, unsigned int,
enum tree_code, tree, tree *);
static tree vn_lookup_simplify_result (gimple_match_op *);
/* Compute and return the hash value for nary operation VBO1. */
-static hashval_t
+hashval_t
vn_nary_op_compute_hash (const vn_nary_op_t vno1)
{
inchash::hash hstate;
/* Return the number of operands for a vn_nary ops structure from STMT. */
-static unsigned int
+unsigned int
vn_nary_length_from_stmt (gimple *stmt)
{
switch (gimple_assign_rhs_code (stmt))
/* Initialize VNO from STMT. */
-static void
+void
init_vn_nary_op_from_stmt (vn_nary_op_t vno, gassign *stmt)
{
unsigned i;
/* Allocate a vn_nary_op_t with LENGTH operands on STACK. */
-static vn_nary_op_t
+vn_nary_op_t
alloc_vn_nary_op_noinit (unsigned int length, struct obstack *stack)
{
return (vn_nary_op_t) obstack_alloc (stack, sizeof_vn_nary_op (length));