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

Commit 4ee33cc

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

File tree

1 file changed

+62
-29
lines changed

1 file changed

+62
-29
lines changed

gcc/d/d-codegen.cc

+62-29
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,28 @@ d_save_expr (tree exp)
517517
return exp;
518518
}
519519

520+
/* Adjust EXPR so that it is a valid lvalue, and can be evaluated multiple times
521+
if it has any side effects. */
522+
523+
static tree
524+
compound_lvalue (tree expr)
525+
{
526+
const tree_code code = TREE_CODE (expr);
527+
528+
if (code == MODIFY_EXPR || code == PREINCREMENT_EXPR
529+
|| code == PREDECREMENT_EXPR)
530+
{
531+
if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 0)))
532+
expr = build2 (TREE_CODE (expr), TREE_TYPE (expr),
533+
stabilize_reference (TREE_OPERAND (expr, 0)),
534+
TREE_OPERAND (expr, 1));
535+
536+
return compound_expr (expr, TREE_OPERAND (expr, 0));
537+
}
538+
539+
return expr;
540+
}
541+
520542
/* Build an unary op CODE to the expression ARG. If the expression can be
521543
broken down so that the operation is applied only to the part whose value we
522544
care about, then handle lowering to keep lvalues trivial. */
@@ -532,21 +554,7 @@ build_unary_op (tree_code code, tree type, tree arg)
532554
return compound_expr (TREE_OPERAND (arg, 0), result);
533555
}
534556

535-
/* Given (e1 = e2), (++e1), or (--e1), convert 'e1' into an lvalue. */
536-
if (TREE_CODE (arg) == MODIFY_EXPR
537-
|| TREE_CODE (arg) == PREINCREMENT_EXPR
538-
|| 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-
}
557+
arg = compound_lvalue (arg);
550558

551559
if (code == ADDR_EXPR)
552560
{
@@ -587,6 +595,16 @@ stabilize_expr2 (tree *valuep)
587595
|| VOID_TYPE_P (TREE_TYPE (expr)))
588596
return NULL_TREE;
589597

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

@@ -929,13 +947,10 @@ build_struct_comparison (tree_code code, StructDeclaration *sd,
929947
return build_boolop (code, integer_zero_node, integer_zero_node);
930948

931949
/* Make temporaries to prevent multiple evaluations. */
932-
tree t1init = stabilize_expr (&t1);
933-
tree t2init = stabilize_expr (&t2);
950+
tree t1init = stabilize_expr2 (&t1);
951+
tree t2init = stabilize_expr2 (&t2);
934952
tree result;
935953

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

1355+
if (TREE_CODE (object) == COMPOUND_EXPR)
1356+
{
1357+
tree result = component_ref (TREE_OPERAND (object, 1), field);
1358+
return compound_expr (TREE_OPERAND (object, 0), result);
1359+
}
1360+
13401361
gcc_assert (TREE_CODE (field) == FIELD_DECL);
13411362

13421363
/* If the FIELD is from an anonymous aggregate, generate a reference
@@ -1359,8 +1380,14 @@ component_ref (tree object, tree field)
13591380
tree
13601381
build_assign (tree_code code, tree lhs, tree rhs)
13611382
{
1362-
tree init = stabilize_expr (&lhs);
1363-
init = compound_expr (init, stabilize_expr (&rhs));
1383+
/* Handle control structure constructs used as lvalues. */
1384+
if (TREE_CODE (lhs) == COMPOUND_EXPR)
1385+
{
1386+
tree result = build_assign (code, TREE_OPERAND (lhs, 1), rhs);
1387+
return compound_expr (TREE_OPERAND (lhs, 0), result);
1388+
}
1389+
1390+
lhs = compound_lvalue (lhs);
13641391

13651392
/* If initializing the LHS using a function that returns via NRVO. */
13661393
if (code == INIT_EXPR && TREE_CODE (rhs) == CALL_EXPR
@@ -1388,9 +1415,7 @@ build_assign (tree_code code, tree lhs, tree rhs)
13881415
}
13891416
}
13901417

1391-
tree result = fold_build2_loc (input_location, code,
1392-
TREE_TYPE (lhs), lhs, rhs);
1393-
return compound_expr (init, result);
1418+
return fold_build2_loc (input_location, code, TREE_TYPE (lhs), lhs, rhs);
13941419
}
13951420

13961421
/* Build an assignment expression of lvalue LHS from value RHS. */
@@ -1558,7 +1583,11 @@ indirect_ref (tree type, tree exp)
15581583
return exp;
15591584

15601585
/* Maybe rewrite: *(e1, e2) => (e1, *e2) */
1561-
tree init = stabilize_expr2 (&exp);
1586+
if (TREE_CODE (exp) == COMPOUND_EXPR)
1587+
{
1588+
tree result = indirect_ref (type, TREE_OPERAND (exp, 1));
1589+
return compound_expr (TREE_OPERAND (exp, 0), result);
1590+
}
15621591

15631592
if (TREE_CODE (TREE_TYPE (exp)) == REFERENCE_TYPE)
15641593
exp = fold_build1 (INDIRECT_REF, type, exp);
@@ -1568,7 +1597,7 @@ indirect_ref (tree type, tree exp)
15681597
exp = build_deref (exp);
15691598
}
15701599

1571-
return compound_expr (init, exp);
1600+
return exp;
15721601
}
15731602

15741603
/* Returns indirect reference of EXP, which must be a pointer type. */
@@ -1580,7 +1609,11 @@ build_deref (tree exp)
15801609
return exp;
15811610

15821611
/* Maybe rewrite: *(e1, e2) => (e1, *e2) */
1583-
tree init = stabilize_expr2 (&exp);
1612+
if (TREE_CODE (exp) == COMPOUND_EXPR)
1613+
{
1614+
tree result = build_deref (TREE_OPERAND (exp, 1));
1615+
return compound_expr (TREE_OPERAND (exp, 0), result);
1616+
}
15841617

15851618
gcc_assert (POINTER_TYPE_P (TREE_TYPE (exp)));
15861619

@@ -1589,7 +1622,7 @@ build_deref (tree exp)
15891622
else
15901623
exp = build_fold_indirect_ref (exp);
15911624

1592-
return compound_expr (init, exp);
1625+
return exp;
15931626
}
15941627

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

0 commit comments

Comments
 (0)