diff options
author | spark <spark@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-02-06 19:43:41 +0000 |
---|---|---|
committer | spark <spark@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-02-06 19:43:41 +0000 |
commit | 87861bf1e1e12aa14324fdb7d54eff46f1de0429 (patch) | |
tree | d18dafd48a46a4ba5713391feecc118b46f7533f /gcc/global.c | |
parent | 7e7772509f68756b21537345b9d9f83d1e212d0c (diff) | |
download | gcc-87861bf1e1e12aa14324fdb7d54eff46f1de0429.tar.gz |
2007-02-06 Seongbae Park <seongbae.park@gmail.com>
PR inline-asm/28686
* global.c (compute_regsets): New function.
(global_alloc): Refactored ELIMINABLE_REGSET
and NO_GLOBAL_ALLOC_REGS computation out.
(rest_of_handle_global_alloc): Call compute_regsets()
for non-optimizing case.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@121663 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/global.c')
-rw-r--r-- | gcc/global.c | 78 |
1 files changed, 51 insertions, 27 deletions
diff --git a/gcc/global.c b/gcc/global.c index dfaaacd79eb..2271f3aa21b 100644 --- a/gcc/global.c +++ b/gcc/global.c @@ -326,35 +326,38 @@ static void make_accurate_live_analysis (void); -/* Perform allocation of pseudo-registers not allocated by local_alloc. +/* Look through the list of eliminable registers. Add registers + clobbered by asm statements to LIVE_REGS. Set ELIM_SET to the set of + registers which may be eliminated. Set NO_GLOBAL_SET to the set of + registers which may not be used across blocks. - Return value is nonzero if reload failed - and we must not do any more for this function. */ + ASM_CLOBBERED is the set of registers clobbered by some asm statement. -static int -global_alloc (void) + This will normally be called with LIVE_REGS as the global variable + regs_ever_live, ELIM_SET as the file static variable + eliminable_regset, and NO_GLOBAL_SET as the file static variable + NO_GLOBAL_ALLOC_REGS. */ + +static void +compute_regsets (char asm_clobbered[FIRST_PSEUDO_REGISTER], + char live_regs[FIRST_PSEUDO_REGISTER], + HARD_REG_SET *elim_set, + HARD_REG_SET *no_global_set) { - int retval; #ifdef ELIMINABLE_REGS static const struct {const int from, to; } eliminables[] = ELIMINABLE_REGS; #endif + size_t i; int need_fp = (! flag_omit_frame_pointer || (current_function_calls_alloca && EXIT_IGNORE_STACK) || FRAME_POINTER_REQUIRED); - size_t i; - rtx x; - - make_accurate_live_analysis (); - - max_allocno = 0; - /* A machine may have certain hard registers that are safe to use only within a basic block. */ - CLEAR_HARD_REG_SET (no_global_alloc_regs); - CLEAR_HARD_REG_SET (eliminable_regset); + CLEAR_HARD_REG_SET (*no_global_set); + CLEAR_HARD_REG_SET (*elim_set); /* Build the regset of all eliminable registers and show we can't use those that we already know won't be eliminated. */ @@ -365,45 +368,63 @@ global_alloc (void) = (! CAN_ELIMINATE (eliminables[i].from, eliminables[i].to) || (eliminables[i].to == STACK_POINTER_REGNUM && need_fp)); - if (!regs_asm_clobbered[eliminables[i].from]) + if (!asm_clobbered[eliminables[i].from]) { - SET_HARD_REG_BIT (eliminable_regset, eliminables[i].from); + SET_HARD_REG_BIT (*elim_set, eliminables[i].from); if (cannot_elim) - SET_HARD_REG_BIT (no_global_alloc_regs, eliminables[i].from); + SET_HARD_REG_BIT (*no_global_set, eliminables[i].from); } else if (cannot_elim) error ("%s cannot be used in asm here", reg_names[eliminables[i].from]); else - regs_ever_live[eliminables[i].from] = 1; + live_regs[eliminables[i].from] = 1; } #if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM - if (!regs_asm_clobbered[HARD_FRAME_POINTER_REGNUM]) + if (!asm_clobbered[HARD_FRAME_POINTER_REGNUM]) { - SET_HARD_REG_BIT (eliminable_regset, HARD_FRAME_POINTER_REGNUM); + SET_HARD_REG_BIT (*elim_set, HARD_FRAME_POINTER_REGNUM); if (need_fp) - SET_HARD_REG_BIT (no_global_alloc_regs, HARD_FRAME_POINTER_REGNUM); + SET_HARD_REG_BIT (*no_global_set, HARD_FRAME_POINTER_REGNUM); } else if (need_fp) error ("%s cannot be used in asm here", reg_names[HARD_FRAME_POINTER_REGNUM]); else - regs_ever_live[HARD_FRAME_POINTER_REGNUM] = 1; + live_regs[HARD_FRAME_POINTER_REGNUM] = 1; #endif #else - if (!regs_asm_clobbered[FRAME_POINTER_REGNUM]) + if (!asm_clobbered[FRAME_POINTER_REGNUM]) { - SET_HARD_REG_BIT (eliminable_regset, FRAME_POINTER_REGNUM); + SET_HARD_REG_BIT (*elim_set, FRAME_POINTER_REGNUM); if (need_fp) - SET_HARD_REG_BIT (no_global_alloc_regs, FRAME_POINTER_REGNUM); + SET_HARD_REG_BIT (*no_global_set, FRAME_POINTER_REGNUM); } else if (need_fp) error ("%s cannot be used in asm here", reg_names[FRAME_POINTER_REGNUM]); else - regs_ever_live[FRAME_POINTER_REGNUM] = 1; + live_regs[FRAME_POINTER_REGNUM] = 1; #endif +} + +/* Perform allocation of pseudo-registers not allocated by local_alloc. + + Return value is nonzero if reload failed + and we must not do any more for this function. */ + +static int +global_alloc (void) +{ + int retval; + size_t i; + rtx x; + + make_accurate_live_analysis (); + + compute_regsets (regs_asm_clobbered, regs_ever_live, + &eliminable_regset, &no_global_alloc_regs); /* Track which registers have already been used. Start with registers explicitly in the rtl, then registers allocated by local register @@ -460,6 +481,7 @@ global_alloc (void) reg_may_share[r2] = r1; } + max_allocno = 0; for (i = FIRST_PSEUDO_REGISTER; i < (size_t) max_regno; i++) /* Note that reg_live_length[i] < 0 indicates a "constant" reg that we are supposed to refrain from putting in a hard reg. @@ -2516,6 +2538,8 @@ rest_of_handle_global_alloc (void) failure = global_alloc (); else { + compute_regsets (regs_asm_clobbered, regs_ever_live, + &eliminable_regset, &no_global_alloc_regs); build_insn_chain (get_insns ()); failure = reload (get_insns (), 0); } |