aboutsummaryrefslogtreecommitdiff
path: root/gcc/lra-spills.c
diff options
context:
space:
mode:
authorVladimir Makarov <vmakarov@redhat.com>2013-11-04 16:12:29 +0000
committerVladimir Makarov <vmakarov@gcc.gnu.org>2013-11-04 16:12:29 +0000
commitefaf512c94161056ad9834cf2d4f53d25e77aa2d (patch)
tree7ba1b744ef9280834c03863b29bc4aac6b0378e3 /gcc/lra-spills.c
parent55a7f02f06688ffea709e2b3de25004f10b8708d (diff)
downloadgcc-efaf512c94161056ad9834cf2d4f53d25e77aa2d.zip
gcc-efaf512c94161056ad9834cf2d4f53d25e77aa2d.tar.gz
gcc-efaf512c94161056ad9834cf2d4f53d25e77aa2d.tar.bz2
re PR rtl-optimization/58968 (Powerpc -mlra cannot compile ormas1.f in gamess Spec 2006 with -m32 -mcpu=power7 -O3 -mlra -w -ffast-math -funroll-loops)
2013-11-04 Vladimir Makarov <vmakarov@redhat.com> PR rtl-optimization/58968 * lra-spills.c (return_regno_p): New function. (lra_final_code_change): Use it. 2013-11-04 Vladimir Makarov <vmakarov@redhat.com> PR rtl-optimization/58968 * gfortran.dg/pr58968.f: New From-SVN: r204353
Diffstat (limited to 'gcc/lra-spills.c')
-rw-r--r--gcc/lra-spills.c69
1 files changed, 46 insertions, 23 deletions
diff --git a/gcc/lra-spills.c b/gcc/lra-spills.c
index 391419f..4ab10c2 100644
--- a/gcc/lra-spills.c
+++ b/gcc/lra-spills.c
@@ -618,6 +618,33 @@ alter_subregs (rtx *loc, bool final_p)
return res;
}
+/* Return true if REGNO is used for return in the current
+ function. */
+static bool
+return_regno_p (unsigned int regno)
+{
+ rtx outgoing = crtl->return_rtx;
+
+ if (! outgoing)
+ return false;
+
+ if (REG_P (outgoing))
+ return REGNO (outgoing) == regno;
+ else if (GET_CODE (outgoing) == PARALLEL)
+ {
+ int i;
+
+ for (i = 0; i < XVECLEN (outgoing, 0); i++)
+ {
+ rtx x = XEXP (XVECEXP (outgoing, 0, i), 0);
+
+ if (REG_P (x) && REGNO (x) == regno)
+ return true;
+ }
+ }
+ return false;
+}
+
/* Final change of pseudos got hard registers into the corresponding
hard registers and removing temporary clobbers. */
void
@@ -625,7 +652,7 @@ lra_final_code_change (void)
{
int i, hard_regno;
basic_block bb;
- rtx insn, curr, set;
+ rtx insn, curr;
int max_regno = max_reg_num ();
for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
@@ -636,7 +663,6 @@ lra_final_code_change (void)
FOR_BB_INSNS_SAFE (bb, insn, curr)
if (INSN_P (insn))
{
- bool change_p;
rtx pat = PATTERN (insn);
if (GET_CODE (pat) == CLOBBER && LRA_TEMP_CLOBBER_P (pat))
@@ -649,12 +675,24 @@ lra_final_code_change (void)
continue;
}
- set = single_set (insn);
- change_p = (set != NULL
- && REG_P (SET_SRC (set)) && REG_P (SET_DEST (set))
- && REGNO (SET_SRC (set)) >= FIRST_PSEUDO_REGISTER
- && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER);
-
+ /* IRA can generate move insns involving pseudos. It is
+ better remove them earlier to speed up compiler a bit.
+ It is also better to do it here as they might not pass
+ final RTL check in LRA, (e.g. insn moving a control
+ register into itself). So remove an useless move insn
+ unless next insn is USE marking the return reg (we should
+ save this as some subsequent optimizations assume that
+ such original insns are saved). */
+ if (NONJUMP_INSN_P (insn) && GET_CODE (pat) == SET
+ && REG_P (SET_SRC (pat)) && REG_P (SET_DEST (pat))
+ && REGNO (SET_SRC (pat)) == REGNO (SET_DEST (pat))
+ && ! return_regno_p (REGNO (SET_SRC (pat))))
+ {
+ lra_invalidate_insn_data (insn);
+ delete_insn (insn);
+ continue;
+ }
+
lra_insn_recog_data_t id = lra_get_insn_recog_data (insn);
struct lra_static_insn_data *static_id = id->insn_static_data;
bool insn_change_p = false;
@@ -668,20 +706,5 @@ lra_final_code_change (void)
}
if (insn_change_p)
lra_update_operator_dups (id);
-
- if (change_p && REGNO (SET_SRC (set)) == REGNO (SET_DEST (set)))
- {
- /* Remove an useless move insn but only involving
- pseudos as some subsequent optimizations are based on
- that move insns involving originally hard registers
- are preserved. IRA can generate move insns involving
- pseudos. It is better remove them earlier to speed
- up compiler a bit. It is also better to do it here
- as they might not pass final RTL check in LRA,
- (e.g. insn moving a control register into
- itself). */
- lra_invalidate_insn_data (insn);
- delete_insn (insn);
- }
}
}