Skip to content
This repository was archived by the owner on Jun 20, 2019. It is now read-only.

Commit eb9c8d6

Browse files
committed
Use target_expr based stabilize in build_struct_comparison
1 parent 48b809b commit eb9c8d6

File tree

1 file changed

+68
-23
lines changed

1 file changed

+68
-23
lines changed

gcc/d/d-codegen.cc

+68-23
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,26 @@ d_save_expr (tree exp)
517517
return exp;
518518
}
519519

520+
/* Adjust LVALUE, a MODIFY_EXPR, PREINCREMENT_EXPR or PREDECREMENT_EXPR, so
521+
that it is a valid lvalue, and can be evaluated multiple times. */
522+
523+
static tree
524+
genericize_compound_lvalue (tree lvalue)
525+
{
526+
const tree_code code = TREE_CODE (lvalue);
527+
528+
gcc_assert (code == MODIFY_EXPR
529+
|| code == PREINCREMENT_EXPR
530+
|| code == PREDECREMENT_EXPR);
531+
532+
if (TREE_SIDE_EFFECTS (TREE_OPERAND (lvalue, 0)))
533+
lvalue = build2 (TREE_CODE (lvalue), TREE_TYPE (lvalue),
534+
stabilize_reference (TREE_OPERAND (lvalue, 0)),
535+
TREE_OPERAND (lvalue, 1));
536+
537+
return compound_expr (lvalue, TREE_OPERAND (lvalue, 0));
538+
}
539+
520540
/* Build an unary op CODE to the expression ARG. If the expression can be
521541
broken down so that the operation is applied only to the part whose value we
522542
care about, then handle lowering to keep lvalues trivial. */
@@ -536,17 +556,7 @@ build_unary_op (tree_code code, tree type, tree arg)
536556
if (TREE_CODE (arg) == MODIFY_EXPR
537557
|| TREE_CODE (arg) == PREINCREMENT_EXPR
538558
|| TREE_CODE (arg) == PREDECREMENT_EXPR)
539-
{
540-
if (TREE_SIDE_EFFECTS (TREE_OPERAND (arg, 0)))
541-
{
542-
arg = build2 (TREE_CODE (arg), TREE_TYPE (arg),
543-
stabilize_reference (TREE_OPERAND (arg, 0)),
544-
TREE_OPERAND (arg, 1));
545-
gcc_unreachable ();
546-
}
547-
return build_unary_op (code, type,
548-
compound_expr (arg, TREE_OPERAND (arg, 0)));
549-
}
559+
return build_unary_op (code, type, genericize_compound_lvalue (arg));
550560

551561
if (code == ADDR_EXPR)
552562
{
@@ -587,6 +597,16 @@ stabilize_expr2 (tree *valuep)
587597
|| VOID_TYPE_P (TREE_TYPE (expr)))
588598
return NULL_TREE;
589599

600+
/* Stabilize only the right hand side of compound expressions. */
601+
if (TREE_CODE (expr) == COMPOUND_EXPR)
602+
{
603+
tree lhs = TREE_OPERAND (expr, 0);
604+
tree rhs = TREE_OPERAND (expr, 1);
605+
lhs = compound_expr (lhs, stabilize_expr2 (&rhs));
606+
*valuep = rhs;
607+
return lhs;
608+
}
609+
590610
tree init = force_target_expr (expr);
591611
*valuep = TARGET_EXPR_SLOT (init);
592612

@@ -929,13 +949,10 @@ build_struct_comparison (tree_code code, StructDeclaration *sd,
929949
return build_boolop (code, integer_zero_node, integer_zero_node);
930950

931951
/* Make temporaries to prevent multiple evaluations. */
932-
tree t1init = stabilize_expr (&t1);
933-
tree t2init = stabilize_expr (&t2);
952+
tree t1init = stabilize_expr2 (&t1);
953+
tree t2init = stabilize_expr2 (&t2);
934954
tree result;
935955

936-
t1 = d_save_expr (t1);
937-
t2 = d_save_expr (t2);
938-
939956
/* Bitwise comparison of structs not returned in memory may not work
940957
due to data holes loosing its zero padding upon return.
941958
As a heuristic, small structs are not compared using memcmp either. */
@@ -1337,6 +1354,12 @@ component_ref (tree object, tree field)
13371354
if (error_operand_p (object) || error_operand_p (field))
13381355
return error_mark_node;
13391356

1357+
if (TREE_CODE (object) == COMPOUND_EXPR)
1358+
{
1359+
tree result = component_ref (TREE_OPERAND (object, 1), field);
1360+
return compound_expr (TREE_OPERAND (object, 0), result);
1361+
}
1362+
13401363
gcc_assert (TREE_CODE (field) == FIELD_DECL);
13411364

13421365
/* If the FIELD is from an anonymous aggregate, generate a reference
@@ -1359,8 +1382,21 @@ component_ref (tree object, tree field)
13591382
tree
13601383
build_assign (tree_code code, tree lhs, tree rhs)
13611384
{
1362-
tree init = stabilize_expr (&lhs);
1363-
init = compound_expr (init, stabilize_expr (&rhs));
1385+
/* Handle control structure constructs used as lvalues. */
1386+
if (TREE_CODE (lhs) == COMPOUND_EXPR)
1387+
{
1388+
tree result = build_assign (code, TREE_OPERAND (lhs, 1), rhs);
1389+
return compound_expr (TREE_OPERAND (lhs, 0), result);
1390+
}
1391+
1392+
if (TREE_CODE (lhs) == MODIFY_EXPR
1393+
|| TREE_CODE (lhs) == PREINCREMENT_EXPR
1394+
|| TREE_CODE (lhs) == PREDECREMENT_EXPR)
1395+
lhs = genericize_compound_lvalue (lhs);
1396+
else if (TREE_CODE (lhs) == COND_EXPR)
1397+
gcc_unreachable ();
1398+
1399+
//tree init = stabilize_expr2 (&lhs);
13641400

13651401
/* If initializing the LHS using a function that returns via NRVO. */
13661402
if (code == INIT_EXPR && TREE_CODE (rhs) == CALL_EXPR
@@ -1390,7 +1426,8 @@ build_assign (tree_code code, tree lhs, tree rhs)
13901426

13911427
tree result = fold_build2_loc (input_location, code,
13921428
TREE_TYPE (lhs), lhs, rhs);
1393-
return compound_expr (init, result);
1429+
//return compound_expr (init, result);
1430+
return result;
13941431
}
13951432

13961433
/* Build an assignment expression of lvalue LHS from value RHS. */
@@ -1558,7 +1595,11 @@ indirect_ref (tree type, tree exp)
15581595
return exp;
15591596

15601597
/* Maybe rewrite: *(e1, e2) => (e1, *e2) */
1561-
tree init = stabilize_expr2 (&exp);
1598+
if (TREE_CODE (exp) == COMPOUND_EXPR)
1599+
{
1600+
tree result = indirect_ref (type, TREE_OPERAND (exp, 1));
1601+
return compound_expr (TREE_OPERAND (exp, 0), result);
1602+
}
15621603

15631604
if (TREE_CODE (TREE_TYPE (exp)) == REFERENCE_TYPE)
15641605
exp = fold_build1 (INDIRECT_REF, type, exp);
@@ -1568,7 +1609,7 @@ indirect_ref (tree type, tree exp)
15681609
exp = build_deref (exp);
15691610
}
15701611

1571-
return compound_expr (init, exp);
1612+
return exp;
15721613
}
15731614

15741615
/* Returns indirect reference of EXP, which must be a pointer type. */
@@ -1580,7 +1621,11 @@ build_deref (tree exp)
15801621
return exp;
15811622

15821623
/* Maybe rewrite: *(e1, e2) => (e1, *e2) */
1583-
tree init = stabilize_expr2 (&exp);
1624+
if (TREE_CODE (exp) == COMPOUND_EXPR)
1625+
{
1626+
tree result = build_deref (TREE_OPERAND (exp, 1));
1627+
return compound_expr (TREE_OPERAND (exp, 0), result);
1628+
}
15841629

15851630
gcc_assert (POINTER_TYPE_P (TREE_TYPE (exp)));
15861631

@@ -1589,7 +1634,7 @@ build_deref (tree exp)
15891634
else
15901635
exp = build_fold_indirect_ref (exp);
15911636

1592-
return compound_expr (init, exp);
1637+
return exp;
15931638
}
15941639

15951640
/* Builds pointer offset expression PTR[INDEX]. */

0 commit comments

Comments
 (0)