diff options
Diffstat (limited to 'gcc/regrename.c')
-rw-r--r-- | gcc/regrename.c | 40 |
1 files changed, 29 insertions, 11 deletions
diff --git a/gcc/regrename.c b/gcc/regrename.c index 0cba8ded8c2..6c7d650ea83 100644 --- a/gcc/regrename.c +++ b/gcc/regrename.c @@ -496,12 +496,20 @@ rename_chains (void) continue; } - if (dump_file) - fprintf (dump_file, ", renamed as %s\n", reg_names[best_new_reg]); - - regrename_do_replace (this_head, best_new_reg); - tick[best_new_reg] = ++this_tick; - df_set_regs_ever_live (best_new_reg, true); + if (regrename_do_replace (this_head, best_new_reg)) + { + if (dump_file) + fprintf (dump_file, ", renamed as %s\n", reg_names[best_new_reg]); + tick[best_new_reg] = ++this_tick; + df_set_regs_ever_live (best_new_reg, true); + } + else + { + if (dump_file) + fprintf (dump_file, ", renaming as %s failed\n", + reg_names[best_new_reg]); + tick[reg] = ++this_tick; + } } } @@ -927,7 +935,13 @@ regrename_analyze (bitmap bb_mask) bb->aux = NULL; } -void +/* Attempt to replace all uses of the register in the chain beginning with + HEAD with REG. Returns true on success and false if the replacement is + rejected because the insns would not validate. The latter can happen + e.g. if a match_parallel predicate enforces restrictions on register + numbering in its subpatterns. */ + +bool regrename_do_replace (struct du_head *head, int reg) { struct du_chain *chain; @@ -941,22 +955,26 @@ regrename_do_replace (struct du_head *head, int reg) int reg_ptr = REG_POINTER (*chain->loc); if (DEBUG_INSN_P (chain->insn) && REGNO (*chain->loc) != base_regno) - INSN_VAR_LOCATION_LOC (chain->insn) = gen_rtx_UNKNOWN_VAR_LOC (); + validate_change (chain->insn, &(INSN_VAR_LOCATION_LOC (chain->insn)), + gen_rtx_UNKNOWN_VAR_LOC (), true); else { - *chain->loc = gen_raw_REG (GET_MODE (*chain->loc), reg); + validate_change (chain->insn, chain->loc, + gen_raw_REG (GET_MODE (*chain->loc), reg), true); if (regno >= FIRST_PSEUDO_REGISTER) ORIGINAL_REGNO (*chain->loc) = regno; REG_ATTRS (*chain->loc) = attr; REG_POINTER (*chain->loc) = reg_ptr; } - - df_insn_rescan (chain->insn); } + if (!apply_change_group ()) + return false; + mode = GET_MODE (*head->first->loc); head->regno = reg; head->nregs = hard_regno_nregs[reg][mode]; + return true; } |