Commit dd27116b by Richard Kenner

(expand_expr): Set IGNORE if target is const0_rtx or result type is VOID.

Move most IGNORE processing to one place to avoid expanding things that don't
need to be expanded.
(expand_expr, case CONSTRUCTOR, case COND_EXPR): If IGNORE, don't expand
anything we don't have to.
(expand_expr, case CONVERT_EXPR): Don't deal with IGNORE here.

From-SVN: r4714
parent bd5f197a
...@@ -3263,7 +3263,10 @@ expand_expr (exp, target, tmode, modifier) ...@@ -3263,7 +3263,10 @@ expand_expr (exp, target, tmode, modifier)
/* Use subtarget as the target for operand 0 of a binary operation. */ /* Use subtarget as the target for operand 0 of a binary operation. */
rtx subtarget = (target != 0 && GET_CODE (target) == REG ? target : 0); rtx subtarget = (target != 0 && GET_CODE (target) == REG ? target : 0);
rtx original_target = target; rtx original_target = target;
int ignore = target == const0_rtx; int ignore = (target == const0_rtx
|| ((code == NON_LVALUE_EXPR || code == NOP_EXPR
|| code == CONVERT_EXPR || code == REFERENCE_EXPR)
&& TREE_CODE (type) == VOID_TYPE));
tree context; tree context;
/* Don't use hard regs as subtargets, because the combiner /* Don't use hard regs as subtargets, because the combiner
...@@ -3275,29 +3278,54 @@ expand_expr (exp, target, tmode, modifier) ...@@ -3275,29 +3278,54 @@ expand_expr (exp, target, tmode, modifier)
if (preserve_subexpressions_p ()) if (preserve_subexpressions_p ())
subtarget = 0; subtarget = 0;
if (ignore) target = 0, original_target = 0; /* If we are going to ignore this result, we need only do something
if there is a side-effect somewhere in the expression. If there
is, short-circuit the most common cases here. */
/* If will do cse, generate all results into pseudo registers if (ignore)
since 1) that allows cse to find more things {
and 2) otherwise cse could produce an insn the machine if (! TREE_SIDE_EFFECTS (exp))
cannot support. */ return const0_rtx;
/* Ensure we reference a volatile object even if value is ignored. */
if (TREE_THIS_VOLATILE (exp)
&& TREE_CODE (exp) != FUNCTION_DECL
&& mode != VOIDmode && mode != BLKmode)
{
temp = expand_expr (exp, NULL_RTX, VOIDmode, modifier);
if (GET_CODE (temp) == MEM)
temp = copy_to_reg (temp);
return const0_rtx;
}
if (TREE_CODE_CLASS (code) == '1')
return expand_expr (TREE_OPERAND (exp, 0), const0_rtx,
VOIDmode, modifier);
else if (TREE_CODE_CLASS (code) == '2'
|| TREE_CODE_CLASS (code) == '<')
{
expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode, modifier);
expand_expr (TREE_OPERAND (exp, 1), const0_rtx, VOIDmode, modifier);
return const0_rtx;
}
else if ((code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR)
&& ! TREE_SIDE_EFFECTS (TREE_OPERAND (exp, 1)))
/* If the second operand has no side effects, just evaluate
the first. */
return expand_expr (TREE_OPERAND (exp, 0), const0_rtx,
VOIDmode, modifier);
/* If will do cse, generate all results into pseudo registers
since 1) that allows cse to find more things
and 2) otherwise cse could produce an insn the machine
cannot support. */
target = 0, original_target = 0;
}
if (! cse_not_expected && mode != BLKmode && target if (! cse_not_expected && mode != BLKmode && target
&& (GET_CODE (target) != REG || REGNO (target) < FIRST_PSEUDO_REGISTER)) && (GET_CODE (target) != REG || REGNO (target) < FIRST_PSEUDO_REGISTER))
target = subtarget; target = subtarget;
/* Ensure we reference a volatile object even if value is ignored. */
if (ignore && TREE_THIS_VOLATILE (exp)
&& TREE_CODE (exp) != FUNCTION_DECL
&& mode != VOIDmode && mode != BLKmode)
{
target = gen_reg_rtx (mode);
temp = expand_expr (exp, target, VOIDmode, modifier);
if (temp != target)
emit_move_insn (target, temp);
return target;
}
switch (code) switch (code)
{ {
case LABEL_DECL: case LABEL_DECL:
...@@ -3596,11 +3624,23 @@ expand_expr (exp, target, tmode, modifier) ...@@ -3596,11 +3624,23 @@ expand_expr (exp, target, tmode, modifier)
return RTL_EXPR_RTL (exp); return RTL_EXPR_RTL (exp);
case CONSTRUCTOR: case CONSTRUCTOR:
/* If we don't need the result, just ensure we evaluate any
subexpressions. */
if (ignore)
{
tree elt;
for (elt = CONSTRUCTOR_ELTS (exp); elt; elt = TREE_CHAIN (elt))
expand_expr (TREE_VALUE (elt), const0_rtx, VOIDmode, 0);
return const0_rtx;
}
/* All elts simple constants => refer to a constant in memory. But /* All elts simple constants => refer to a constant in memory. But
if this is a non-BLKmode mode, let it store a field at a time if this is a non-BLKmode mode, let it store a field at a time
since that should make a CONST_INT or CONST_DOUBLE when we since that should make a CONST_INT or CONST_DOUBLE when we
fold. */ fold. If we are making an initializer and all operands are
if (TREE_STATIC (exp) && (mode == BLKmode || TREE_ADDRESSABLE (exp))) constant, put it in memory as well. */
else if ((TREE_STATIC (exp)
&& (mode == BLKmode || TREE_ADDRESSABLE (exp)))
|| (modifier == EXPAND_INITIALIZER && TREE_CONSTANT (exp)))
{ {
rtx constructor = output_constant_def (exp); rtx constructor = output_constant_def (exp);
if (modifier != EXPAND_CONST_ADDRESS if (modifier != EXPAND_CONST_ADDRESS
...@@ -3613,13 +3653,6 @@ expand_expr (exp, target, tmode, modifier) ...@@ -3613,13 +3653,6 @@ expand_expr (exp, target, tmode, modifier)
return constructor; return constructor;
} }
if (ignore)
{
tree elt;
for (elt = CONSTRUCTOR_ELTS (exp); elt; elt = TREE_CHAIN (elt))
expand_expr (TREE_VALUE (elt), const0_rtx, VOIDmode, 0);
return const0_rtx;
}
else else
{ {
if (target == 0 || ! safe_from_p (target, exp)) if (target == 0 || ! safe_from_p (target, exp))
...@@ -4121,11 +4154,6 @@ expand_expr (exp, target, tmode, modifier) ...@@ -4121,11 +4154,6 @@ expand_expr (exp, target, tmode, modifier)
case NOP_EXPR: case NOP_EXPR:
case CONVERT_EXPR: case CONVERT_EXPR:
case REFERENCE_EXPR: case REFERENCE_EXPR:
if (TREE_CODE (type) == VOID_TYPE || ignore)
{
expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode, modifier);
return const0_rtx;
}
if (mode == TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0)))) if (mode == TYPE_MODE (TREE_TYPE (TREE_OPERAND (exp, 0))))
return expand_expr (TREE_OPERAND (exp, 0), target, VOIDmode, modifier); return expand_expr (TREE_OPERAND (exp, 0), target, VOIDmode, modifier);
if (TREE_CODE (type) == UNION_TYPE) if (TREE_CODE (type) == UNION_TYPE)
...@@ -4781,6 +4809,13 @@ expand_expr (exp, target, tmode, modifier) ...@@ -4781,6 +4809,13 @@ expand_expr (exp, target, tmode, modifier)
&& integer_zerop (TREE_OPERAND (exp, 2)) && integer_zerop (TREE_OPERAND (exp, 2))
&& TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (exp, 0))) == '<') && TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (exp, 0))) == '<')
{ {
if (ignore)
{
expand_expr (TREE_OPERAND (exp, 0), const0_rtx, VOIDmode,
modifier);
return const0_rtx;
}
op0 = expand_expr (TREE_OPERAND (exp, 0), target, mode, modifier); op0 = expand_expr (TREE_OPERAND (exp, 0), target, mode, modifier);
if (GET_MODE (op0) == mode) if (GET_MODE (op0) == mode)
return op0; return op0;
...@@ -4795,7 +4830,7 @@ expand_expr (exp, target, tmode, modifier) ...@@ -4795,7 +4830,7 @@ expand_expr (exp, target, tmode, modifier)
intermediate target unless it is safe. If no target, use a intermediate target unless it is safe. If no target, use a
temporary. */ temporary. */
if (mode == VOIDmode || ignore) if (ignore)
temp = 0; temp = 0;
else if (original_target else if (original_target
&& safe_from_p (original_target, TREE_OPERAND (exp, 0))) && safe_from_p (original_target, TREE_OPERAND (exp, 0)))
...@@ -4839,7 +4874,7 @@ expand_expr (exp, target, tmode, modifier) ...@@ -4839,7 +4874,7 @@ expand_expr (exp, target, tmode, modifier)
/* If we had X ? A + 1 : A and we can do the test of X as a store-flag /* If we had X ? A + 1 : A and we can do the test of X as a store-flag
operation, do this as A + (X != 0). Similarly for other simple operation, do this as A + (X != 0). Similarly for other simple
binary operators. */ binary operators. */
if (singleton && binary_op if (temp && singleton && binary_op
&& ! TREE_SIDE_EFFECTS (TREE_OPERAND (exp, 0)) && ! TREE_SIDE_EFFECTS (TREE_OPERAND (exp, 0))
&& (TREE_CODE (binary_op) == PLUS_EXPR && (TREE_CODE (binary_op) == PLUS_EXPR
|| TREE_CODE (binary_op) == MINUS_EXPR || TREE_CODE (binary_op) == MINUS_EXPR
......
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