Commit f5416098 by Roger Sayle Committed by Roger Sayle

builtins.c (expand_builtin_mathfn): Always stabilize the argument list against re-evaluation.


	* builtins.c (expand_builtin_mathfn): Always stabilize the argument
	list against re-evaluation.  If expand_unop fails, call expand_call
	with the stabilized argument list rather than return NULL_RTX.
	(expand_builtin_mathfn2): Likewise, always stabilize the argument
	list, and call expand_call ourselves if expand_binop fails.

Co-Authored-By: Richard Henderson <rth@redhat.com>

From-SVN: r68526
parent 998c7773
2003-06-26 Roger Sayle <roger@eyesopen.com>
Richard Henderson <rth@redhat.com>
* builtins.c (expand_builtin_mathfn): Always stabilize the argument
list against re-evaluation. If expand_unop fails, call expand_call
with the stabilized argument list rather than return NULL_RTX.
(expand_builtin_mathfn2): Likewise, always stabilize the argument
list, and call expand_call ourselves if expand_binop fails.
2003-06-26 Eric Botcazou <ebotcazou@libertysurf.fr> 2003-06-26 Eric Botcazou <ebotcazou@libertysurf.fr>
PR optimization/11210 PR optimization/11210
......
...@@ -1701,7 +1701,7 @@ expand_builtin_mathfn (tree exp, rtx target, rtx subtarget) ...@@ -1701,7 +1701,7 @@ expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
tree arglist = TREE_OPERAND (exp, 1); tree arglist = TREE_OPERAND (exp, 1);
enum machine_mode mode; enum machine_mode mode;
bool errno_set = false; bool errno_set = false;
tree arg; tree arg, narg;
if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE)) if (!validate_arglist (arglist, REAL_TYPE, VOID_TYPE))
return 0; return 0;
...@@ -1771,25 +1771,15 @@ expand_builtin_mathfn (tree exp, rtx target, rtx subtarget) ...@@ -1771,25 +1771,15 @@ expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
if (! flag_errno_math || ! HONOR_NANS (mode)) if (! flag_errno_math || ! HONOR_NANS (mode))
errno_set = false; errno_set = false;
/* Stabilize and compute the argument. */ /* Wrap the computation of the argument in a SAVE_EXPR, as we may
if (errno_set) need to expand the argument again. This way, we will not perform
switch (TREE_CODE (arg)) side-effects more the once. */
{ narg = save_expr (arg);
case VAR_DECL: if (narg != arg)
case PARM_DECL: {
case SAVE_EXPR: arglist = build_tree_list (NULL_TREE, arg);
case REAL_CST: exp = build_function_call_expr (fndecl, arglist);
break; }
default:
/* Wrap the computation of the argument in a SAVE_EXPR, as we
need to expand the argument again in expand_errno_check. This
way, we will not perform side-effects more the once. */
arg = save_expr (arg);
arglist = build_tree_list (NULL_TREE, arg);
exp = build_function_call_expr (fndecl, arglist);
break;
}
op0 = expand_expr (arg, subtarget, VOIDmode, 0); op0 = expand_expr (arg, subtarget, VOIDmode, 0);
...@@ -1800,13 +1790,13 @@ expand_builtin_mathfn (tree exp, rtx target, rtx subtarget) ...@@ -1800,13 +1790,13 @@ expand_builtin_mathfn (tree exp, rtx target, rtx subtarget)
Set TARGET to wherever the result comes back. */ Set TARGET to wherever the result comes back. */
target = expand_unop (mode, builtin_optab, op0, target, 0); target = expand_unop (mode, builtin_optab, op0, target, 0);
/* If we were unable to expand via the builtin, stop the /* If we were unable to expand via the builtin, stop the sequence
sequence (without outputting the insns) and return 0, causing (without outputting the insns) and call to the library function
a call to the library function. */ with the stabilized argument list. */
if (target == 0) if (target == 0)
{ {
end_sequence (); end_sequence ();
return 0; return expand_call (exp, target, target == const0_rtx);
} }
if (errno_set) if (errno_set)
...@@ -1834,7 +1824,7 @@ expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget) ...@@ -1834,7 +1824,7 @@ expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
rtx op0, op1, insns; rtx op0, op1, insns;
tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0); tree fndecl = TREE_OPERAND (TREE_OPERAND (exp, 0), 0);
tree arglist = TREE_OPERAND (exp, 1); tree arglist = TREE_OPERAND (exp, 1);
tree arg0, arg1, temp; tree arg0, arg1, temp, narg;
enum machine_mode mode; enum machine_mode mode;
bool errno_set = true; bool errno_set = true;
bool stable = true; bool stable = true;
...@@ -1866,45 +1856,27 @@ expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget) ...@@ -1866,45 +1856,27 @@ expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
if (! flag_errno_math || ! HONOR_NANS (mode)) if (! flag_errno_math || ! HONOR_NANS (mode))
errno_set = false; errno_set = false;
/* Stabilize the arguments. */ /* Alway stabilize the argument list. */
if (errno_set) narg = save_expr (arg1);
if (narg != arg1)
{ {
switch (TREE_CODE (arg1)) temp = build_tree_list (NULL_TREE, narg);
{ stable = false;
case VAR_DECL: }
case PARM_DECL: else
case SAVE_EXPR: temp = TREE_CHAIN (arglist);
case REAL_CST:
temp = TREE_CHAIN (arglist);
break;
default:
stable = false;
arg1 = save_expr (arg1);
temp = build_tree_list (NULL_TREE, arg1);
break;
}
switch (TREE_CODE (arg0))
{
case VAR_DECL:
case PARM_DECL:
case SAVE_EXPR:
case REAL_CST:
if (! stable)
arglist = tree_cons (NULL_TREE, arg0, temp);
break;
default:
stable = false;
arg0 = save_expr (arg0);
arglist = tree_cons (NULL_TREE, arg0, temp);
break;
}
if (! stable) narg = save_expr (arg0);
exp = build_function_call_expr (fndecl, arglist); if (narg != arg0)
{
arglist = tree_cons (NULL_TREE, narg, temp);
stable = false;
} }
else if (! stable)
arglist = tree_cons (NULL_TREE, arg0, temp);
if (! stable)
exp = build_function_call_expr (fndecl, arglist);
op0 = expand_expr (arg0, subtarget, VOIDmode, 0); op0 = expand_expr (arg0, subtarget, VOIDmode, 0);
op1 = expand_expr (arg1, 0, VOIDmode, 0); op1 = expand_expr (arg1, 0, VOIDmode, 0);
...@@ -1917,13 +1889,13 @@ expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget) ...@@ -1917,13 +1889,13 @@ expand_builtin_mathfn_2 (tree exp, rtx target, rtx subtarget)
target = expand_binop (mode, builtin_optab, op0, op1, target = expand_binop (mode, builtin_optab, op0, op1,
target, 0, OPTAB_DIRECT); target, 0, OPTAB_DIRECT);
/* If we were unable to expand via the builtin, stop the /* If we were unable to expand via the builtin, stop the sequence
sequence (without outputting the insns) and return 0, causing (without outputting the insns) and call to the library function
a call to the library function. */ with the stabilized argument list. */
if (target == 0) if (target == 0)
{ {
end_sequence (); end_sequence ();
return 0; return expand_call (exp, target, target == const0_rtx);
} }
if (errno_set) if (errno_set)
......
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