aboutsummaryrefslogtreecommitdiff
path: root/gcc/expr.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/expr.c')
-rw-r--r--gcc/expr.c26
1 files changed, 21 insertions, 5 deletions
diff --git a/gcc/expr.c b/gcc/expr.c
index fd0c437..cf81842 100644
--- a/gcc/expr.c
+++ b/gcc/expr.c
@@ -54,6 +54,7 @@ along with GCC; see the file COPYING3. If not see
#include "timevar.h"
#include "df.h"
#include "diagnostic.h"
+#include "ssaexpand.h"
/* Decide whether a function's arguments should be processed
from first to last or from last to first.
@@ -4284,12 +4285,13 @@ expand_assignment (tree to, tree from, bool nontemporal)
Don't do this if TO is a VAR_DECL or PARM_DECL whose DECL_RTL is REG
since it might be a promoted variable where the zero- or sign- extension
needs to be done. Handling this in the normal way is safe because no
- computation is done before the call. */
+ computation is done before the call. The same is true for SSA names. */
if (TREE_CODE (from) == CALL_EXPR && ! aggregate_value_p (from, from)
&& COMPLETE_TYPE_P (TREE_TYPE (from))
&& TREE_CODE (TYPE_SIZE (TREE_TYPE (from))) == INTEGER_CST
- && ! ((TREE_CODE (to) == VAR_DECL || TREE_CODE (to) == PARM_DECL)
- && REG_P (DECL_RTL (to))))
+ && ! (((TREE_CODE (to) == VAR_DECL || TREE_CODE (to) == PARM_DECL)
+ && REG_P (DECL_RTL (to)))
+ || TREE_CODE (to) == SSA_NAME))
{
rtx value;
@@ -7223,8 +7225,21 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
}
case SSA_NAME:
- return expand_expr_real_1 (SSA_NAME_VAR (exp), target, tmode, modifier,
- NULL);
+ /* ??? ivopts calls expander, without any preparation from
+ out-of-ssa. So fake instructions as if this was an access to the
+ base variable. This unnecessarily allocates a pseudo, see how we can
+ reuse it, if partition base vars have it set already. */
+ if (!currently_expanding_to_rtl)
+ return expand_expr_real_1 (SSA_NAME_VAR (exp), target, tmode, modifier, NULL);
+ {
+ gimple g = get_gimple_for_ssa_name (exp);
+ if (g)
+ return expand_expr_real_1 (gimple_assign_rhs_to_tree (g), target,
+ tmode, modifier, NULL);
+ }
+ decl_rtl = get_rtx_for_ssa_name (exp);
+ exp = SSA_NAME_VAR (exp);
+ goto expand_decl_rtl;
case PARM_DECL:
case VAR_DECL:
@@ -7250,6 +7265,7 @@ expand_expr_real_1 (tree exp, rtx target, enum machine_mode tmode,
case FUNCTION_DECL:
case RESULT_DECL:
decl_rtl = DECL_RTL (exp);
+ expand_decl_rtl:
gcc_assert (decl_rtl);
decl_rtl = copy_rtx (decl_rtl);