Commit 5a7d7f9c by Richard Guenther Committed by Richard Biener

re PR tree-optimization/48317 (SCCVN does not handle vector constructors)

2011-09-06  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/48317
	* tree-ssa-sccvn.h (struct vn_nary_op_s): Make op a true
	trailing array.
	(sizeof_vn_nary_op): New inline function.
	(vn_nary_op_lookup_pieces): Adjust.
	(vn_nary_op_insert_pieces): Likewise.
	* tree-ssa-sccvn.c (vn_nary_op_eq): Also compare the length.
	(init_vn_nary_op_from_pieces): Adjust signature.  Deal with
	any number of operands.
	(vn_nary_length_from_stmt): New function.
	(init_vn_nary_op_from_stmt): Adjust for CONSTRUCTOR handling.
	(vn_nary_op_lookup_pieces): Adjust signature and allocate properly
	sized temporary.
	(vn_nary_op_lookup): Likewise.
	(vn_nary_op_lookup_stmt): Likewise.
	(vn_nary_op_insert_into): Likewise.
	(vn_nary_op_insert_stmt): Likewise.
	(visit_use): Handle CONSTRUCTOR as nary.
	* tree-ssa-pre.c (phi_translate_1): Adjust.
	(create_expression_by_pieces): Likewise.
	(compute_avail): Likewise.

	* gcc.dg/tree-ssa/ssa-fre-31.c: New testcase.

From-SVN: r178595
parent 0a034606
2011-09-06 Richard Guenther <rguenther@suse.de>
PR tree-optimization/48317
* tree-ssa-sccvn.h (struct vn_nary_op_s): Make op a true
trailing array.
(sizeof_vn_nary_op): New inline function.
(vn_nary_op_lookup_pieces): Adjust.
(vn_nary_op_insert_pieces): Likewise.
* tree-ssa-sccvn.c (vn_nary_op_eq): Also compare the length.
(init_vn_nary_op_from_pieces): Adjust signature. Deal with
any number of operands.
(vn_nary_length_from_stmt): New function.
(init_vn_nary_op_from_stmt): Adjust for CONSTRUCTOR handling.
(vn_nary_op_lookup_pieces): Adjust signature and allocate properly
sized temporary.
(vn_nary_op_lookup): Likewise.
(vn_nary_op_lookup_stmt): Likewise.
(vn_nary_op_insert_into): Likewise.
(vn_nary_op_insert_stmt): Likewise.
(visit_use): Handle CONSTRUCTOR as nary.
* tree-ssa-pre.c (phi_translate_1): Adjust.
(create_expression_by_pieces): Likewise.
(compute_avail): Likewise.
2011-09-06 Ira Rosen <ira.rosen@linaro.org> 2011-09-06 Ira Rosen <ira.rosen@linaro.org>
* config/arm/arm.c (arm_preferred_simd_mode): Check * config/arm/arm.c (arm_preferred_simd_mode): Check
2011-09-06 Richard Guenther <rguenther@suse.de>
PR tree-optimization/48317
* gcc.dg/tree-ssa/ssa-fre-31.c: New testcase.
2011-09-06 Ira Rosen <ira.rosen@linaro.org> 2011-09-06 Ira Rosen <ira.rosen@linaro.org>
* lib/target-supports.exp (check_effective_target_vect_multiple_sizes): * lib/target-supports.exp (check_effective_target_vect_multiple_sizes):
......
/* { dg-do compile } */
/* { dg-options "-O -fdump-tree-fre1-details" } */
typedef double d128 __attribute__((vector_size(16)));
typedef float f128 __attribute__((vector_size(16)));
typedef short s128 __attribute__((vector_size(16)));
typedef char c256 __attribute__((vector_size(32)));
d128 d;
f128 f;
s128 s;
c256 c;
void test1 (double x)
{
d = (d128){x + x, x + x};
d = (d128){x + x, x + x};
}
void test2 (float x)
{
f = (f128){x + x, x + x, x + x, x + x};
f = (f128){x + x, x + x, x + x, x + x};
}
void test3 (short x)
{
s = (s128){x + x, x + x, x + x, x + x, x + x, x + x, x + x, x + x};
s = (s128){x + x, x + x, x + x, x + x, x + x, x + x, x + x, x + x};
}
void test4 (unsigned char x)
{
c = (c256){x + x, x + x, x + x, x + x, x + x, x + x, x + x, x + x,
x + x, x + x, x + x, x + x, x + x, x + x, x + x, x + x,
x + x, x + x, x + x, x + x, x + x, x + x, x + x, x + x,
x + x, x + x, x + x, x + x, x + x, x + x, x + x, x + x};
c = (c256){x + x, x + x, x + x, x + x, x + x, x + x, x + x, x + x,
x + x, x + x, x + x, x + x, x + x, x + x, x + x, x + x,
x + x, x + x, x + x, x + x, x + x, x + x, x + x, x + x,
x + x, x + x, x + x, x + x, x + x, x + x, x + x, x + x};
}
/* { dg-final { scan-tree-dump-times "Replaced \{" 4 "fre1" } } */
/* { dg-final { scan-tree-dump-times "Deleted redundant store" 4 "fre1" } } */
/* { dg-final { cleanup-tree-dump "fre1" } } */
...@@ -1443,20 +1443,18 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2, ...@@ -1443,20 +1443,18 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
unsigned int i; unsigned int i;
bool changed = false; bool changed = false;
vn_nary_op_t nary = PRE_EXPR_NARY (expr); vn_nary_op_t nary = PRE_EXPR_NARY (expr);
struct vn_nary_op_s newnary; vn_nary_op_t newnary = XALLOCAVAR (struct vn_nary_op_s,
/* The NARY structure is only guaranteed to have been sizeof_vn_nary_op (nary->length));
allocated to the nary->length operands. */ memcpy (newnary, nary, sizeof_vn_nary_op (nary->length));
memcpy (&newnary, nary, (sizeof (struct vn_nary_op_s)
- sizeof (tree) * (4 - nary->length)));
for (i = 0; i < newnary.length; i++) for (i = 0; i < newnary->length; i++)
{ {
if (TREE_CODE (newnary.op[i]) != SSA_NAME) if (TREE_CODE (newnary->op[i]) != SSA_NAME)
continue; continue;
else else
{ {
pre_expr leader, result; pre_expr leader, result;
unsigned int op_val_id = VN_INFO (newnary.op[i])->value_id; unsigned int op_val_id = VN_INFO (newnary->op[i])->value_id;
leader = find_leader_in_sets (op_val_id, set1, set2); leader = find_leader_in_sets (op_val_id, set1, set2);
result = phi_translate (leader, set1, set2, pred, phiblock); result = phi_translate (leader, set1, set2, pred, phiblock);
if (result && result != leader) if (result && result != leader)
...@@ -1464,12 +1462,12 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2, ...@@ -1464,12 +1462,12 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
tree name = get_representative_for (result); tree name = get_representative_for (result);
if (!name) if (!name)
return NULL; return NULL;
newnary.op[i] = name; newnary->op[i] = name;
} }
else if (!result) else if (!result)
return NULL; return NULL;
changed |= newnary.op[i] != nary->op[i]; changed |= newnary->op[i] != nary->op[i];
} }
} }
if (changed) if (changed)
...@@ -1477,13 +1475,10 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2, ...@@ -1477,13 +1475,10 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
pre_expr constant; pre_expr constant;
unsigned int new_val_id; unsigned int new_val_id;
tree result = vn_nary_op_lookup_pieces (newnary.length, tree result = vn_nary_op_lookup_pieces (newnary->length,
newnary.opcode, newnary->opcode,
newnary.type, newnary->type,
newnary.op[0], &newnary->op[0],
newnary.op[1],
newnary.op[2],
newnary.op[3],
&nary); &nary);
if (result && is_gimple_min_invariant (result)) if (result && is_gimple_min_invariant (result))
return get_or_alloc_expr_for_constant (result); return get_or_alloc_expr_for_constant (result);
...@@ -1507,13 +1502,10 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2, ...@@ -1507,13 +1502,10 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
VEC_safe_grow_cleared (bitmap_set_t, heap, VEC_safe_grow_cleared (bitmap_set_t, heap,
value_expressions, value_expressions,
get_max_value_id() + 1); get_max_value_id() + 1);
nary = vn_nary_op_insert_pieces (newnary.length, nary = vn_nary_op_insert_pieces (newnary->length,
newnary.opcode, newnary->opcode,
newnary.type, newnary->type,
newnary.op[0], &newnary->op[0],
newnary.op[1],
newnary.op[2],
newnary.op[3],
result, new_val_id); result, new_val_id);
PRE_EXPR_NARY (expr) = nary; PRE_EXPR_NARY (expr) = nary;
constant = fully_constant_expression (expr); constant = fully_constant_expression (expr);
...@@ -1708,9 +1700,7 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2, ...@@ -1708,9 +1700,7 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
nresult = vn_nary_op_lookup_pieces (1, TREE_CODE (result), nresult = vn_nary_op_lookup_pieces (1, TREE_CODE (result),
TREE_TYPE (result), TREE_TYPE (result),
TREE_OPERAND (result, 0), &TREE_OPERAND (result, 0),
NULL_TREE, NULL_TREE,
NULL_TREE,
&nary); &nary);
if (nresult && is_gimple_min_invariant (nresult)) if (nresult && is_gimple_min_invariant (nresult))
return get_or_alloc_expr_for_constant (nresult); return get_or_alloc_expr_for_constant (nresult);
...@@ -1734,9 +1724,8 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2, ...@@ -1734,9 +1724,8 @@ phi_translate_1 (pre_expr expr, bitmap_set_t set1, bitmap_set_t set2,
get_max_value_id() + 1); get_max_value_id() + 1);
nary = vn_nary_op_insert_pieces (1, TREE_CODE (result), nary = vn_nary_op_insert_pieces (1, TREE_CODE (result),
TREE_TYPE (result), TREE_TYPE (result),
TREE_OPERAND (result, 0), &TREE_OPERAND (result, 0),
NULL_TREE, NULL_TREE, NULL_TREE,
NULL_TREE, NULL_TREE,
new_val_id); new_val_id);
PRE_EXPR_NARY (expr) = nary; PRE_EXPR_NARY (expr) = nary;
constant = fully_constant_expression (expr); constant = fully_constant_expression (expr);
...@@ -3087,50 +3076,49 @@ create_expression_by_pieces (basic_block block, pre_expr expr, ...@@ -3087,50 +3076,49 @@ create_expression_by_pieces (basic_block block, pre_expr expr,
case NARY: case NARY:
{ {
vn_nary_op_t nary = PRE_EXPR_NARY (expr); vn_nary_op_t nary = PRE_EXPR_NARY (expr);
switch (nary->length) tree genop[4];
unsigned i;
for (i = 0; i < nary->length; ++i)
{ {
case 2: pre_expr op = get_or_alloc_expr_for (nary->op[i]);
{ genop[i] = find_or_generate_expression (block, op,
pre_expr op1 = get_or_alloc_expr_for (nary->op[0]); stmts, domstmt);
pre_expr op2 = get_or_alloc_expr_for (nary->op[1]); if (!genop[i])
tree genop1 = find_or_generate_expression (block, op1, return NULL_TREE;
stmts, domstmt); /* Ensure genop[1] is a ptrofftype for POINTER_PLUS_EXPR. It
tree genop2 = find_or_generate_expression (block, op2, may be a constant with the wrong type. */
stmts, domstmt); if (i == 1
if (!genop1 || !genop2) && nary->opcode == POINTER_PLUS_EXPR)
return NULL_TREE; genop[i] = convert_to_ptrofftype (genop[i]);
/* Ensure op2 is a ptrofftype for POINTER_PLUS_EXPR. It else
may be a constant with the wrong type. */ genop[i] = fold_convert (TREE_TYPE (nary->op[i]), genop[i]);
if (nary->opcode == POINTER_PLUS_EXPR) }
{ if (nary->opcode == CONSTRUCTOR)
genop1 = fold_convert (nary->type, genop1); {
genop2 = convert_to_ptrofftype (genop2); VEC(constructor_elt,gc) *elts = NULL;
} for (i = 0; i < nary->length; ++i)
else CONSTRUCTOR_APPEND_ELT (elts, NULL_TREE, genop[i]);
{ folded = build_constructor (nary->type, elts);
genop1 = fold_convert (TREE_TYPE (nary->op[0]), genop1); }
genop2 = fold_convert (TREE_TYPE (nary->op[1]), genop2); else
} {
switch (nary->length)
folded = fold_build2 (nary->opcode, nary->type, {
genop1, genop2); case 1:
} folded = fold_build1 (nary->opcode, nary->type,
break; genop[0]);
case 1: break;
{ case 2:
pre_expr op1 = get_or_alloc_expr_for (nary->op[0]); folded = fold_build2 (nary->opcode, nary->type,
tree genop1 = find_or_generate_expression (block, op1, genop[0], genop[1]);
stmts, domstmt); break;
if (!genop1) case 3:
return NULL_TREE; folded = fold_build3 (nary->opcode, nary->type,
genop1 = fold_convert (TREE_TYPE (nary->op[0]), genop1); genop[0], genop[1], genop[3]);
break;
folded = fold_build1 (nary->opcode, nary->type, default:
genop1); gcc_unreachable ();
} }
break;
default:
return NULL_TREE;
} }
} }
break; break;
...@@ -4053,9 +4041,8 @@ compute_avail (void) ...@@ -4053,9 +4041,8 @@ compute_avail (void)
vn_nary_op_lookup_pieces (gimple_num_ops (stmt) - 1, vn_nary_op_lookup_pieces (gimple_num_ops (stmt) - 1,
gimple_assign_rhs_code (stmt), gimple_assign_rhs_code (stmt),
gimple_expr_type (stmt), gimple_expr_type (stmt),
gimple_assign_rhs1 (stmt), gimple_assign_rhs1_ptr (stmt),
gimple_assign_rhs2 (stmt), &nary);
NULL_TREE, NULL_TREE, &nary);
if (!nary) if (!nary)
continue; continue;
......
...@@ -1923,6 +1923,9 @@ vn_nary_op_eq (const void *p1, const void *p2) ...@@ -1923,6 +1923,9 @@ vn_nary_op_eq (const void *p1, const void *p2)
if (vno1->hashcode != vno2->hashcode) if (vno1->hashcode != vno2->hashcode)
return false; return false;
if (vno1->length != vno2->length)
return false;
if (vno1->opcode != vno2->opcode if (vno1->opcode != vno2->opcode
|| !types_compatible_p (vno1->type, vno2->type)) || !types_compatible_p (vno1->type, vno2->type))
return false; return false;
...@@ -1938,22 +1941,12 @@ vn_nary_op_eq (const void *p1, const void *p2) ...@@ -1938,22 +1941,12 @@ vn_nary_op_eq (const void *p1, const void *p2)
static void static void
init_vn_nary_op_from_pieces (vn_nary_op_t vno, unsigned int length, init_vn_nary_op_from_pieces (vn_nary_op_t vno, unsigned int length,
enum tree_code code, tree type, tree op0, enum tree_code code, tree type, tree *ops)
tree op1, tree op2, tree op3)
{ {
vno->opcode = code; vno->opcode = code;
vno->length = length; vno->length = length;
vno->type = type; vno->type = type;
switch (length) memcpy (&vno->op[0], ops, sizeof (tree) * length);
{
/* The fallthrus here are deliberate. */
case 4: vno->op[3] = op3;
case 3: vno->op[2] = op2;
case 2: vno->op[1] = op1;
case 1: vno->op[0] = op0;
default:
break;
}
} }
/* Initialize VNO from OP. */ /* Initialize VNO from OP. */
...@@ -1970,6 +1963,26 @@ init_vn_nary_op_from_op (vn_nary_op_t vno, tree op) ...@@ -1970,6 +1963,26 @@ init_vn_nary_op_from_op (vn_nary_op_t vno, tree op)
vno->op[i] = TREE_OPERAND (op, i); vno->op[i] = TREE_OPERAND (op, i);
} }
/* Return the number of operands for a vn_nary ops structure from STMT. */
static unsigned int
vn_nary_length_from_stmt (gimple stmt)
{
switch (gimple_assign_rhs_code (stmt))
{
case REALPART_EXPR:
case IMAGPART_EXPR:
case VIEW_CONVERT_EXPR:
return 1;
case CONSTRUCTOR:
return CONSTRUCTOR_NELTS (gimple_assign_rhs1 (stmt));
default:
return gimple_num_ops (stmt) - 1;
}
}
/* Initialize VNO from STMT. */ /* Initialize VNO from STMT. */
static void static void
...@@ -1978,14 +1991,27 @@ init_vn_nary_op_from_stmt (vn_nary_op_t vno, gimple stmt) ...@@ -1978,14 +1991,27 @@ init_vn_nary_op_from_stmt (vn_nary_op_t vno, gimple stmt)
unsigned i; unsigned i;
vno->opcode = gimple_assign_rhs_code (stmt); vno->opcode = gimple_assign_rhs_code (stmt);
vno->length = gimple_num_ops (stmt) - 1;
vno->type = gimple_expr_type (stmt); vno->type = gimple_expr_type (stmt);
for (i = 0; i < vno->length; ++i) switch (vno->opcode)
vno->op[i] = gimple_op (stmt, i + 1); {
if (vno->opcode == REALPART_EXPR case REALPART_EXPR:
|| vno->opcode == IMAGPART_EXPR case IMAGPART_EXPR:
|| vno->opcode == VIEW_CONVERT_EXPR) case VIEW_CONVERT_EXPR:
vno->op[0] = TREE_OPERAND (vno->op[0], 0); vno->length = 1;
vno->op[0] = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
break;
case CONSTRUCTOR:
vno->length = CONSTRUCTOR_NELTS (gimple_assign_rhs1 (stmt));
for (i = 0; i < vno->length; ++i)
vno->op[i] = CONSTRUCTOR_ELT (gimple_assign_rhs1 (stmt), i)->value;
break;
default:
vno->length = gimple_num_ops (stmt) - 1;
for (i = 0; i < vno->length; ++i)
vno->op[i] = gimple_op (stmt, i + 1);
}
} }
/* Compute the hashcode for VNO and look for it in the hash table; /* Compute the hashcode for VNO and look for it in the hash table;
...@@ -2023,12 +2049,12 @@ vn_nary_op_lookup_1 (vn_nary_op_t vno, vn_nary_op_t *vnresult) ...@@ -2023,12 +2049,12 @@ vn_nary_op_lookup_1 (vn_nary_op_t vno, vn_nary_op_t *vnresult)
tree tree
vn_nary_op_lookup_pieces (unsigned int length, enum tree_code code, vn_nary_op_lookup_pieces (unsigned int length, enum tree_code code,
tree type, tree op0, tree op1, tree op2, tree type, tree *ops, vn_nary_op_t *vnresult)
tree op3, vn_nary_op_t *vnresult)
{ {
struct vn_nary_op_s vno1; vn_nary_op_t vno1 = XALLOCAVAR (struct vn_nary_op_s,
init_vn_nary_op_from_pieces (&vno1, length, code, type, op0, op1, op2, op3); sizeof_vn_nary_op (length));
return vn_nary_op_lookup_1 (&vno1, vnresult); init_vn_nary_op_from_pieces (vno1, length, code, type, ops);
return vn_nary_op_lookup_1 (vno1, vnresult);
} }
/* Lookup OP in the current hash table, and return the resulting value /* Lookup OP in the current hash table, and return the resulting value
...@@ -2040,9 +2066,11 @@ vn_nary_op_lookup_pieces (unsigned int length, enum tree_code code, ...@@ -2040,9 +2066,11 @@ vn_nary_op_lookup_pieces (unsigned int length, enum tree_code code,
tree tree
vn_nary_op_lookup (tree op, vn_nary_op_t *vnresult) vn_nary_op_lookup (tree op, vn_nary_op_t *vnresult)
{ {
struct vn_nary_op_s vno1; vn_nary_op_t vno1
init_vn_nary_op_from_op (&vno1, op); = XALLOCAVAR (struct vn_nary_op_s,
return vn_nary_op_lookup_1 (&vno1, vnresult); sizeof_vn_nary_op (TREE_CODE_LENGTH (TREE_CODE (op))));
init_vn_nary_op_from_op (vno1, op);
return vn_nary_op_lookup_1 (vno1, vnresult);
} }
/* Lookup the rhs of STMT in the current hash table, and return the resulting /* Lookup the rhs of STMT in the current hash table, and return the resulting
...@@ -2053,17 +2081,11 @@ vn_nary_op_lookup (tree op, vn_nary_op_t *vnresult) ...@@ -2053,17 +2081,11 @@ vn_nary_op_lookup (tree op, vn_nary_op_t *vnresult)
tree tree
vn_nary_op_lookup_stmt (gimple stmt, vn_nary_op_t *vnresult) vn_nary_op_lookup_stmt (gimple stmt, vn_nary_op_t *vnresult)
{ {
struct vn_nary_op_s vno1; vn_nary_op_t vno1
init_vn_nary_op_from_stmt (&vno1, stmt); = XALLOCAVAR (struct vn_nary_op_s,
return vn_nary_op_lookup_1 (&vno1, vnresult); sizeof_vn_nary_op (vn_nary_length_from_stmt (stmt)));
} init_vn_nary_op_from_stmt (vno1, stmt);
return vn_nary_op_lookup_1 (vno1, vnresult);
/* Return the size of a vn_nary_op_t with LENGTH operands. */
static size_t
sizeof_vn_nary_op (unsigned int length)
{
return sizeof (struct vn_nary_op_s) - sizeof (tree) * (4 - length);
} }
/* Allocate a vn_nary_op_t with LENGTH operands on STACK. */ /* Allocate a vn_nary_op_t with LENGTH operands on STACK. */
...@@ -2114,15 +2136,11 @@ vn_nary_op_insert_into (vn_nary_op_t vno, htab_t table, bool compute_hash) ...@@ -2114,15 +2136,11 @@ vn_nary_op_insert_into (vn_nary_op_t vno, htab_t table, bool compute_hash)
vn_nary_op_t vn_nary_op_t
vn_nary_op_insert_pieces (unsigned int length, enum tree_code code, vn_nary_op_insert_pieces (unsigned int length, enum tree_code code,
tree type, tree op0, tree type, tree *ops,
tree op1, tree op2, tree op3, tree result, unsigned int value_id)
tree result,
unsigned int value_id)
{ {
vn_nary_op_t vno1; vn_nary_op_t vno1 = alloc_vn_nary_op (length, result, value_id);
init_vn_nary_op_from_pieces (vno1, length, code, type, ops);
vno1 = alloc_vn_nary_op (length, result, value_id);
init_vn_nary_op_from_pieces (vno1, length, code, type, op0, op1, op2, op3);
return vn_nary_op_insert_into (vno1, current_info->nary, true); return vn_nary_op_insert_into (vno1, current_info->nary, true);
} }
...@@ -2147,10 +2165,9 @@ vn_nary_op_insert (tree op, tree result) ...@@ -2147,10 +2165,9 @@ vn_nary_op_insert (tree op, tree result)
vn_nary_op_t vn_nary_op_t
vn_nary_op_insert_stmt (gimple stmt, tree result) vn_nary_op_insert_stmt (gimple stmt, tree result)
{ {
unsigned length = gimple_num_ops (stmt) - 1; vn_nary_op_t vno1
vn_nary_op_t vno1; = alloc_vn_nary_op (vn_nary_length_from_stmt (stmt),
result, VN_INFO (result)->value_id);
vno1 = alloc_vn_nary_op (length, result, VN_INFO (result)->value_id);
init_vn_nary_op_from_stmt (vno1, stmt); init_vn_nary_op_from_stmt (vno1, stmt);
return vn_nary_op_insert_into (vno1, current_info->nary, true); return vn_nary_op_insert_into (vno1, current_info->nary, true);
} }
...@@ -3171,14 +3188,17 @@ visit_use (tree use) ...@@ -3171,14 +3188,17 @@ visit_use (tree use)
case tcc_declaration: case tcc_declaration:
changed = visit_reference_op_load (lhs, rhs1, stmt); changed = visit_reference_op_load (lhs, rhs1, stmt);
break; break;
case tcc_expression: default:
if (code == ADDR_EXPR) if (code == ADDR_EXPR)
{ {
changed = visit_nary_op (lhs, stmt); changed = visit_nary_op (lhs, stmt);
break; break;
} }
/* Fallthrough. */ else if (code == CONSTRUCTOR)
default: {
changed = visit_nary_op (lhs, stmt);
break;
}
changed = defs_to_varying (stmt); changed = defs_to_varying (stmt);
} }
break; break;
......
...@@ -42,10 +42,18 @@ typedef struct vn_nary_op_s ...@@ -42,10 +42,18 @@ typedef struct vn_nary_op_s
hashval_t hashcode; hashval_t hashcode;
tree result; tree result;
tree type; tree type;
tree op[4]; tree op[1];
} *vn_nary_op_t; } *vn_nary_op_t;
typedef const struct vn_nary_op_s *const_vn_nary_op_t; typedef const struct vn_nary_op_s *const_vn_nary_op_t;
/* Return the size of a vn_nary_op_t with LENGTH operands. */
static inline size_t
sizeof_vn_nary_op (unsigned int length)
{
return sizeof (struct vn_nary_op_s) + sizeof (tree) * (length - 1);
}
/* Phi nodes in the hashtable consist of their non-VN_TOP phi /* Phi nodes in the hashtable consist of their non-VN_TOP phi
arguments, and the basic block the phi is in. Result is the value arguments, and the basic block the phi is in. Result is the value
number of the operation, and hashcode is stored to avoid having to number of the operation, and hashcode is stored to avoid having to
...@@ -176,13 +184,11 @@ void free_scc_vn (void); ...@@ -176,13 +184,11 @@ void free_scc_vn (void);
tree vn_nary_op_lookup (tree, vn_nary_op_t *); tree vn_nary_op_lookup (tree, vn_nary_op_t *);
tree vn_nary_op_lookup_stmt (gimple, vn_nary_op_t *); tree vn_nary_op_lookup_stmt (gimple, vn_nary_op_t *);
tree vn_nary_op_lookup_pieces (unsigned int, enum tree_code, tree vn_nary_op_lookup_pieces (unsigned int, enum tree_code,
tree, tree, tree, tree, tree, tree, tree *, vn_nary_op_t *);
vn_nary_op_t *);
vn_nary_op_t vn_nary_op_insert (tree, tree); vn_nary_op_t vn_nary_op_insert (tree, tree);
vn_nary_op_t vn_nary_op_insert_stmt (gimple, tree); vn_nary_op_t vn_nary_op_insert_stmt (gimple, tree);
vn_nary_op_t vn_nary_op_insert_pieces (unsigned int, enum tree_code, vn_nary_op_t vn_nary_op_insert_pieces (unsigned int, enum tree_code,
tree, tree, tree, tree, tree, tree *, tree, unsigned int);
tree, tree, unsigned int);
void vn_reference_fold_indirect (VEC (vn_reference_op_s, heap) **, void vn_reference_fold_indirect (VEC (vn_reference_op_s, heap) **,
unsigned int *); unsigned int *);
void copy_reference_ops_from_ref (tree, VEC(vn_reference_op_s, heap) **); void copy_reference_ops_from_ref (tree, VEC(vn_reference_op_s, heap) **);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment