diff options
author | rearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-08-05 17:58:22 +0000 |
---|---|---|
committer | rearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4> | 2013-08-05 17:58:22 +0000 |
commit | cdbf60c9b10cc26cc0db84078d0725de865fb09b (patch) | |
tree | 3587b9b99a17949bd6632984ba58cb5ef4ee7daa /gcc | |
parent | 69c554056b0b456f6b2dc57e5b3d96640de5d19e (diff) | |
download | gcc-cdbf60c9b10cc26cc0db84078d0725de865fb09b.tar.gz |
PR rtl-optimization/57708
* recog.c (peep2_find_free_register): Validate all regs in a
multi-reg mode.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@201501 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/recog.c | 64 |
2 files changed, 49 insertions, 21 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a40d4a0afbf..eece522af1a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2013-08-05 Richard Earnshaw <rearnsha@arm.com> + + PR rtl-optimization/57708 + * recog.c (peep2_find_free_register): Validate all regs in a + multi-reg mode. + 2013-08-05 Jan Hubicka <jh@suse.cz> PR lto/57602 diff --git a/gcc/recog.c b/gcc/recog.c index 6a607ba2a5a..aa026a27d59 100644 --- a/gcc/recog.c +++ b/gcc/recog.c @@ -3124,32 +3124,53 @@ peep2_find_free_register (int from, int to, const char *class_str, regno = raw_regno; #endif - /* Don't allocate fixed registers. */ - if (fixed_regs[regno]) - continue; - /* Don't allocate global registers. */ - if (global_regs[regno]) - continue; - /* Make sure the register is of the right class. */ - if (! TEST_HARD_REG_BIT (reg_class_contents[cl], regno)) - continue; - /* And can support the mode we need. */ + /* Can it support the mode we need? */ if (! HARD_REGNO_MODE_OK (regno, mode)) continue; - /* And that we don't create an extra save/restore. */ - if (! call_used_regs[regno] && ! df_regs_ever_live_p (regno)) - continue; - if (! targetm.hard_regno_scratch_ok (regno)) - continue; - - /* And we don't clobber traceback for noreturn functions. */ - if ((regno == FRAME_POINTER_REGNUM || regno == HARD_FRAME_POINTER_REGNUM) - && (! reload_completed || frame_pointer_needed)) - continue; success = 1; - for (j = hard_regno_nregs[regno][mode] - 1; j >= 0; j--) + for (j = 0; success && j < hard_regno_nregs[regno][mode]; j++) { + /* Don't allocate fixed registers. */ + if (fixed_regs[regno + j]) + { + success = 0; + break; + } + /* Don't allocate global registers. */ + if (global_regs[regno + j]) + { + success = 0; + break; + } + /* Make sure the register is of the right class. */ + if (! TEST_HARD_REG_BIT (reg_class_contents[cl], regno + j)) + { + success = 0; + break; + } + /* And that we don't create an extra save/restore. */ + if (! call_used_regs[regno + j] && ! df_regs_ever_live_p (regno + j)) + { + success = 0; + break; + } + + if (! targetm.hard_regno_scratch_ok (regno + j)) + { + success = 0; + break; + } + + /* And we don't clobber traceback for noreturn functions. */ + if ((regno + j == FRAME_POINTER_REGNUM + || regno + j == HARD_FRAME_POINTER_REGNUM) + && (! reload_completed || frame_pointer_needed)) + { + success = 0; + break; + } + if (TEST_HARD_REG_BIT (*reg_set, regno + j) || TEST_HARD_REG_BIT (live, regno + j)) { @@ -3157,6 +3178,7 @@ peep2_find_free_register (int from, int to, const char *class_str, break; } } + if (success) { add_to_hard_reg_set (reg_set, mode, regno); |