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

Commit

Permalink
Use target_expr based stabilize in build_struct_comparison
Browse files Browse the repository at this point in the history
  • Loading branch information
ibuclaw committed May 5, 2018
1 parent 48b809b commit eb9c8d6
Showing 1 changed file with 68 additions and 23 deletions.
91 changes: 68 additions & 23 deletions gcc/d/d-codegen.cc
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,26 @@ d_save_expr (tree exp)
return exp;
}

/* Adjust LVALUE, a MODIFY_EXPR, PREINCREMENT_EXPR or PREDECREMENT_EXPR, so
that it is a valid lvalue, and can be evaluated multiple times. */

static tree
genericize_compound_lvalue (tree lvalue)
{
const tree_code code = TREE_CODE (lvalue);

gcc_assert (code == MODIFY_EXPR
|| code == PREINCREMENT_EXPR
|| code == PREDECREMENT_EXPR);

if (TREE_SIDE_EFFECTS (TREE_OPERAND (lvalue, 0)))
lvalue = build2 (TREE_CODE (lvalue), TREE_TYPE (lvalue),
stabilize_reference (TREE_OPERAND (lvalue, 0)),
TREE_OPERAND (lvalue, 1));

return compound_expr (lvalue, TREE_OPERAND (lvalue, 0));
}

/* Build an unary op CODE to the expression ARG. If the expression can be
broken down so that the operation is applied only to the part whose value we
care about, then handle lowering to keep lvalues trivial. */
Expand All @@ -536,17 +556,7 @@ build_unary_op (tree_code code, tree type, tree arg)
if (TREE_CODE (arg) == MODIFY_EXPR
|| TREE_CODE (arg) == PREINCREMENT_EXPR
|| TREE_CODE (arg) == PREDECREMENT_EXPR)
{
if (TREE_SIDE_EFFECTS (TREE_OPERAND (arg, 0)))
{
arg = build2 (TREE_CODE (arg), TREE_TYPE (arg),
stabilize_reference (TREE_OPERAND (arg, 0)),
TREE_OPERAND (arg, 1));
gcc_unreachable ();
}
return build_unary_op (code, type,
compound_expr (arg, TREE_OPERAND (arg, 0)));
}
return build_unary_op (code, type, genericize_compound_lvalue (arg));

if (code == ADDR_EXPR)
{
Expand Down Expand Up @@ -587,6 +597,16 @@ stabilize_expr2 (tree *valuep)
|| VOID_TYPE_P (TREE_TYPE (expr)))
return NULL_TREE;

/* Stabilize only the right hand side of compound expressions. */
if (TREE_CODE (expr) == COMPOUND_EXPR)
{
tree lhs = TREE_OPERAND (expr, 0);
tree rhs = TREE_OPERAND (expr, 1);
lhs = compound_expr (lhs, stabilize_expr2 (&rhs));
*valuep = rhs;
return lhs;
}

tree init = force_target_expr (expr);
*valuep = TARGET_EXPR_SLOT (init);

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

/* Make temporaries to prevent multiple evaluations. */
tree t1init = stabilize_expr (&t1);
tree t2init = stabilize_expr (&t2);
tree t1init = stabilize_expr2 (&t1);
tree t2init = stabilize_expr2 (&t2);
tree result;

t1 = d_save_expr (t1);
t2 = d_save_expr (t2);

/* Bitwise comparison of structs not returned in memory may not work
due to data holes loosing its zero padding upon return.
As a heuristic, small structs are not compared using memcmp either. */
Expand Down Expand Up @@ -1337,6 +1354,12 @@ component_ref (tree object, tree field)
if (error_operand_p (object) || error_operand_p (field))
return error_mark_node;

if (TREE_CODE (object) == COMPOUND_EXPR)
{
tree result = component_ref (TREE_OPERAND (object, 1), field);
return compound_expr (TREE_OPERAND (object, 0), result);
}

gcc_assert (TREE_CODE (field) == FIELD_DECL);

/* If the FIELD is from an anonymous aggregate, generate a reference
Expand All @@ -1359,8 +1382,21 @@ component_ref (tree object, tree field)
tree
build_assign (tree_code code, tree lhs, tree rhs)
{
tree init = stabilize_expr (&lhs);
init = compound_expr (init, stabilize_expr (&rhs));
/* Handle control structure constructs used as lvalues. */
if (TREE_CODE (lhs) == COMPOUND_EXPR)
{
tree result = build_assign (code, TREE_OPERAND (lhs, 1), rhs);
return compound_expr (TREE_OPERAND (lhs, 0), result);
}

if (TREE_CODE (lhs) == MODIFY_EXPR
|| TREE_CODE (lhs) == PREINCREMENT_EXPR
|| TREE_CODE (lhs) == PREDECREMENT_EXPR)
lhs = genericize_compound_lvalue (lhs);
else if (TREE_CODE (lhs) == COND_EXPR)
gcc_unreachable ();

//tree init = stabilize_expr2 (&lhs);

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

tree result = fold_build2_loc (input_location, code,
TREE_TYPE (lhs), lhs, rhs);
return compound_expr (init, result);
//return compound_expr (init, result);
return result;
}

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

/* Maybe rewrite: *(e1, e2) => (e1, *e2) */
tree init = stabilize_expr2 (&exp);
if (TREE_CODE (exp) == COMPOUND_EXPR)
{
tree result = indirect_ref (type, TREE_OPERAND (exp, 1));
return compound_expr (TREE_OPERAND (exp, 0), result);
}

if (TREE_CODE (TREE_TYPE (exp)) == REFERENCE_TYPE)
exp = fold_build1 (INDIRECT_REF, type, exp);
Expand All @@ -1568,7 +1609,7 @@ indirect_ref (tree type, tree exp)
exp = build_deref (exp);
}

return compound_expr (init, exp);
return exp;
}

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

/* Maybe rewrite: *(e1, e2) => (e1, *e2) */
tree init = stabilize_expr2 (&exp);
if (TREE_CODE (exp) == COMPOUND_EXPR)
{
tree result = build_deref (TREE_OPERAND (exp, 1));
return compound_expr (TREE_OPERAND (exp, 0), result);
}

gcc_assert (POINTER_TYPE_P (TREE_TYPE (exp)));

Expand All @@ -1589,7 +1634,7 @@ build_deref (tree exp)
else
exp = build_fold_indirect_ref (exp);

return compound_expr (init, exp);
return exp;
}

/* Builds pointer offset expression PTR[INDEX]. */
Expand Down

0 comments on commit eb9c8d6

Please sign in to comment.