diff options
author | kan <kan@FreeBSD.org> | 2003-07-11 03:40:53 +0000 |
---|---|---|
committer | kan <kan@FreeBSD.org> | 2003-07-11 03:40:53 +0000 |
commit | b2a8872fbe1ec1c49094559ac7b78e6ea4ab7180 (patch) | |
tree | f6b0610f4a17fd26aa234354f050080f789861a4 /contrib/gcc/global.c | |
parent | 52e69d78eee5612ac195e0701a5cebe40d1ab0e1 (diff) | |
download | FreeBSD-src-b2a8872fbe1ec1c49094559ac7b78e6ea4ab7180.zip FreeBSD-src-b2a8872fbe1ec1c49094559ac7b78e6ea4ab7180.tar.gz |
Gcc 3.3.1-pre as of 2003-07-11.
Diffstat (limited to 'contrib/gcc/global.c')
-rw-r--r-- | contrib/gcc/global.c | 133 |
1 files changed, 60 insertions, 73 deletions
diff --git a/contrib/gcc/global.c b/contrib/gcc/global.c index 383f6c4..0840b87 100644 --- a/contrib/gcc/global.c +++ b/contrib/gcc/global.c @@ -52,7 +52,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA 1. Assign allocation-numbers (allocnos) to the pseudo-registers still needing allocations and to the pseudo-registers currently allocated by local-alloc which may be spilled by reload. - Set up tables reg_allocno and allocno_reg to map + Set up tables reg_allocno and allocno_reg to map reg numbers to allocnos and vice versa. max_allocno gets the number of allocnos in use. @@ -176,10 +176,6 @@ static int allocno_row_words; (conflicts[(I) * allocno_row_words + (unsigned) (J) / INT_BITS] \ & ((INT_TYPE) 1 << ((unsigned) (J) % INT_BITS))) -#define SET_CONFLICT(I, J) \ - (conflicts[(I) * allocno_row_words + (unsigned) (J) / INT_BITS] \ - |= ((INT_TYPE) 1 << ((unsigned) (J) % INT_BITS))) - /* For any allocno set in ALLOCNO_SET, set ALLOCNO to that allocno, and execute CODE. */ #define EXECUTE_IF_SET_IN_ALLOCNO_SET(ALLOCNO_SET, ALLOCNO, CODE) \ @@ -236,12 +232,8 @@ static int local_reg_freq[FIRST_PSEUDO_REGISTER]; static int local_reg_live_length[FIRST_PSEUDO_REGISTER]; -/* Test a bit in TABLE, a vector of HARD_REG_SETs, - for vector element I, and hard register number J. */ - -#define REGBITP(TABLE, I, J) TEST_HARD_REG_BIT (allocno[I].TABLE, J) - -/* Set to 1 a bit in a vector of HARD_REG_SETs. Works like REGBITP. */ +/* Set to 1 a bit in a vector TABLE of HARD_REG_SETs, for vector + element I, and hard register number J. */ #define SET_REGBIT(TABLE, I, J) SET_HARD_REG_BIT (allocno[I].TABLE, J) @@ -252,10 +244,6 @@ static INT_TYPE *allocnos_live; /* Test, set or clear bit number I in allocnos_live, a bit vector indexed by allocno. */ -#define ALLOCNO_LIVE_P(I) \ - (allocnos_live[(unsigned) (I) / INT_BITS] \ - & ((INT_TYPE) 1 << ((unsigned) (I) % INT_BITS))) - #define SET_ALLOCNO_LIVE(I) \ (allocnos_live[(unsigned) (I) / INT_BITS] \ |= ((INT_TYPE) 1 << ((unsigned) (I) % INT_BITS))) @@ -384,8 +372,8 @@ global_alloc (file) that need a register window. So prefer the ones that can be used in a leaf function. */ { - char *cheap_regs; - char *leaf_regs = LEAF_REGISTERS; + const char *cheap_regs; + const char *const leaf_regs = LEAF_REGISTERS; if (only_leaf_regs_used () && leaf_function_p ()) cheap_regs = leaf_regs; @@ -488,7 +476,7 @@ global_alloc (file) for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) if (regs_ever_live[i]) local_reg_n_refs[i] = 0, local_reg_freq[i] = 0; - + allocno_row_words = (max_allocno + INT_BITS - 1) / INT_BITS; /* We used to use alloca here, but the size of what it would try to @@ -554,7 +542,7 @@ global_alloc (file) } qsort (allocno_order, max_allocno, sizeof (int), allocno_compare); - + prune_preferences (); if (file) @@ -641,7 +629,8 @@ allocno_compare (v1p, v2p) static void global_conflicts () { - int b, i; + int i; + basic_block b; rtx insn; int *block_start_allocnos; @@ -650,7 +639,7 @@ global_conflicts () block_start_allocnos = (int *) xmalloc (max_allocno * sizeof (int)); - for (b = 0; b < n_basic_blocks; b++) + FOR_EACH_BB (b) { memset ((char *) allocnos_live, 0, allocno_row_words * sizeof (INT_TYPE)); @@ -669,7 +658,7 @@ global_conflicts () are explicitly marked in basic_block_live_at_start. */ { - regset old = BASIC_BLOCK (b)->global_live_at_start; + regset old = b->global_live_at_start; int ax = 0; REG_SET_TO_HARD_REG_SET (hard_regs_live, old); @@ -718,23 +707,23 @@ global_conflicts () that is reached by an abnormal edge. */ edge e; - for (e = BASIC_BLOCK (b)->pred; e ; e = e->pred_next) + for (e = b->pred; e ; e = e->pred_next) if (e->flags & EDGE_ABNORMAL) break; if (e != NULL) - { - EXECUTE_IF_SET_IN_ALLOCNO_SET (allocnos_live, ax, - { - allocno[ax].no_stack_reg = 1; - }); - for (ax = FIRST_STACK_REG; ax <= LAST_STACK_REG; ax++) - record_one_conflict (ax); - } + { + EXECUTE_IF_SET_IN_ALLOCNO_SET (allocnos_live, ax, + { + allocno[ax].no_stack_reg = 1; + }); + for (ax = FIRST_STACK_REG; ax <= LAST_STACK_REG; ax++) + record_one_conflict (ax); + } } #endif } - insn = BLOCK_HEAD (b); + insn = b->head; /* Scan the code of this basic block, noting which allocnos and hard regs are born or die. When one is born, @@ -834,7 +823,7 @@ global_conflicts () } } - if (insn == BLOCK_END (b)) + if (insn == b->end) break; insn = NEXT_INSN (insn); } @@ -894,18 +883,18 @@ expand_preferences () /* Prune the preferences for global registers to exclude registers that cannot be used. - + Compute `regs_someone_prefers', which is a bitmask of the hard registers that are preferred by conflicting registers of lower priority. If possible, we will avoid using these registers. */ - + static void prune_preferences () { int i; int num; int *allocno_to_order = (int *) xmalloc (max_allocno * sizeof (int)); - + /* Scan least most important to most important. For each allocno, remove from preferences registers that cannot be used, either because of conflicts or register type. Then compute all registers @@ -973,7 +962,7 @@ prune_preferences () of a long enough stretch of hard regs none of which conflicts with ALLOCNO. The registers marked in PREFREGS are tried first. - LOSERS, if non-zero, is a HARD_REG_SET indicating registers that cannot + LOSERS, if nonzero, is a HARD_REG_SET indicating registers that cannot be used for this allocation. If ALT_REGS_P is zero, consider only the preferred class of ALLOCNO's reg. @@ -996,10 +985,7 @@ find_reg (num, losers, alt_regs_p, accept_call_clobbered, retrying) int retrying; { int i, best_reg, pass; -#ifdef HARD_REG_SET - register /* Declare it register if it's a scalar. */ -#endif - HARD_REG_SET used, used1, used2; + HARD_REG_SET used, used1, used2; enum reg_class class = (alt_regs_p ? reg_alternate_class (allocno[num].reg) @@ -1023,10 +1009,8 @@ find_reg (num, losers, alt_regs_p, accept_call_clobbered, retrying) IOR_HARD_REG_SET (used1, allocno[num].hard_reg_conflicts); -#ifdef CLASS_CANNOT_CHANGE_MODE - if (REG_CHANGES_MODE (allocno[num].reg)) - IOR_HARD_REG_SET (used1, - reg_class_contents[(int) CLASS_CANNOT_CHANGE_MODE]); +#ifdef CANNOT_CHANGE_MODE_CLASS + cannot_change_mode_set_regs (&used1, mode, allocno[num].reg); #endif /* Try each hard reg to see if it fits. Do this in two passes. @@ -1038,7 +1022,7 @@ find_reg (num, losers, alt_regs_p, accept_call_clobbered, retrying) COPY_HARD_REG_SET (used, used1); IOR_COMPL_HARD_REG_SET (used, regs_used_so_far); IOR_HARD_REG_SET (used, allocno[num].regs_someone_prefers); - + best_reg = -1; for (i = FIRST_PSEUDO_REGISTER, pass = 0; pass <= 1 && i >= FIRST_PSEUDO_REGISTER; @@ -1083,7 +1067,7 @@ find_reg (num, losers, alt_regs_p, accept_call_clobbered, retrying) Remove from the preferred registers and conflicting registers. Note that additional conflicts may have been added after `prune_preferences' was - called. + called. First do this for those register with copy preferences, then all preferred registers. */ @@ -1166,7 +1150,7 @@ find_reg (num, losers, alt_regs_p, accept_call_clobbered, retrying) } no_prefs: - /* If we haven't succeeded yet, try with caller-saves. + /* If we haven't succeeded yet, try with caller-saves. We need not check to see if the current function has nonlocal labels because we don't put any pseudos that are live over calls in registers in that case. */ @@ -1186,7 +1170,7 @@ find_reg (num, losers, alt_regs_p, accept_call_clobbered, retrying) CLEAR_HARD_REG_SET (new_losers); else COPY_HARD_REG_SET (new_losers, losers); - + IOR_HARD_REG_SET(new_losers, losing_caller_save_reg_set); find_reg (num, new_losers, alt_regs_p, 1, retrying); if (reg_renumber[allocno[num].reg] >= 0) @@ -1219,25 +1203,28 @@ find_reg (num, losers, alt_regs_p, accept_call_clobbered, retrying) /* Don't use a reg no good for this pseudo. */ && ! TEST_HARD_REG_BIT (used2, regno) && HARD_REGNO_MODE_OK (regno, mode) + /* The code below assumes that we need only a single + register, but the check of allocno[num].size above + was not enough. Sometimes we need more than one + register for a single-word value. */ + && HARD_REGNO_NREGS (regno, mode) == 1 && (allocno[num].calls_crossed == 0 || accept_call_clobbered || ! HARD_REGNO_CALL_PART_CLOBBERED (regno, mode)) -#ifdef CLASS_CANNOT_CHANGE_MODE - && ! (REG_CHANGES_MODE (allocno[num].reg) - && (TEST_HARD_REG_BIT - (reg_class_contents[(int) CLASS_CANNOT_CHANGE_MODE], - regno))) +#ifdef CANNOT_CHANGE_MODE_CLASS + && ! invalid_mode_change_p (regno, REGNO_REG_CLASS (regno), + mode) #endif #ifdef STACK_REGS - && (!allocno[num].no_stack_reg - || regno < FIRST_STACK_REG || regno > LAST_STACK_REG) + && (!allocno[num].no_stack_reg + || regno < FIRST_STACK_REG || regno > LAST_STACK_REG) #endif ) { /* We explicitly evaluate the divide results into temporary variables so as to avoid excess precision problems that occur on an i386-unknown-sysv4.2 (unixware) host. */ - + double tmp1 = ((double) local_reg_freq[regno] / local_reg_live_length[regno]); double tmp2 = ((double) allocno[num].freq @@ -1607,7 +1594,7 @@ mark_reg_live_nc (regno, mode) that SRC is a register. If SRC or the first operand of SRC is a register, try to set a preference. If one of the two is a hard register and the other is a pseudo-register, mark the preference. - + Note that we are not as aggressive as local-alloc in trying to tie a pseudo-register to a hard register. */ @@ -1723,11 +1710,11 @@ void mark_elimination (from, to) int from, to; { - int i; + basic_block bb; - for (i = 0; i < n_basic_blocks; i++) + FOR_EACH_BB (bb) { - regset r = BASIC_BLOCK (i)->global_live_at_start; + regset r = bb->global_live_at_start; if (REGNO_REG_SET_P (r, from)) { CLEAR_REGNO_REG_SET (r, from); @@ -1755,7 +1742,7 @@ reg_becomes_live (reg, setter, regs_set) if (GET_CODE (reg) != REG) return; - + regno = REGNO (reg); if (regno < FIRST_PSEUDO_REGISTER) { @@ -1809,7 +1796,7 @@ build_insn_chain (first) { struct insn_chain **p = &reload_insn_chain; struct insn_chain *prev = 0; - int b = 0; + basic_block b = ENTRY_BLOCK_PTR->next_bb; regset_head live_relevant_regs_head; live_relevant_regs = INITIALIZE_REG_SET (live_relevant_regs_head); @@ -1818,21 +1805,21 @@ build_insn_chain (first) { struct insn_chain *c; - if (first == BLOCK_HEAD (b)) + if (first == b->head) { int i; CLEAR_REG_SET (live_relevant_regs); EXECUTE_IF_SET_IN_BITMAP - (BASIC_BLOCK (b)->global_live_at_start, 0, i, + (b->global_live_at_start, 0, i, { if (i < FIRST_PSEUDO_REGISTER ? ! TEST_HARD_REG_BIT (eliminable_regset, i) : reg_renumber[i] >= 0) SET_REGNO_REG_SET (live_relevant_regs, i); }); - } + } if (GET_CODE (first) != NOTE && GET_CODE (first) != BARRIER) { @@ -1842,7 +1829,7 @@ build_insn_chain (first) *p = c; p = &c->next; c->insn = first; - c->block = b; + c->block = b->index; if (INSN_P (first)) { @@ -1880,8 +1867,8 @@ build_insn_chain (first) } } - if (first == BLOCK_END (b)) - b++; + if (first == b->end) + b = b->next_bb; /* Stop after we pass the end of the last basic block. Verify that no real insns are after the end of the last basic block. @@ -1889,7 +1876,7 @@ build_insn_chain (first) We may want to reorganize the loop somewhat since this test should always be the right exit test. Allow an ADDR_VEC or ADDR_DIF_VEC if the previous real insn is a JUMP_INSN. */ - if (b == n_basic_blocks) + if (b == EXIT_BLOCK_PTR) { for (first = NEXT_INSN (first) ; first; first = NEXT_INSN (first)) if (INSN_P (first) @@ -1920,7 +1907,7 @@ dump_conflicts (file) for (i = 0; i < max_allocno; i++) { if (reg_renumber[allocno[allocno_order[i]].reg] >= 0) - continue; + continue; nregs++; } fprintf (file, ";; %d regs to allocate:", nregs); @@ -1972,13 +1959,13 @@ dump_global_regs (file) FILE *file; { int i, j; - + fprintf (file, ";; Register dispositions:\n"); for (i = FIRST_PSEUDO_REGISTER, j = 0; i < max_regno; i++) if (reg_renumber[i] >= 0) { fprintf (file, "%d in %d ", i, reg_renumber[i]); - if (++j % 6 == 0) + if (++j % 6 == 0) fprintf (file, "\n"); } |