📄 reload1.c
字号:
max_needs[class]--; p = reg_class_superclasses[class]; while (*p != LIM_REG_CLASSES) max_needs[(int) *p++]--; if (! counted_for_groups[spill_regs[i]]) { if (max_nongroups[class] > 0) counted_for_nongroups[spill_regs[i]] = 1; max_nongroups[class]--; p = reg_class_superclasses[class]; while (*p != LIM_REG_CLASSES) { if (max_nongroups[(int) *p] > 0) counted_for_nongroups[spill_regs[i]] = 1; max_nongroups[(int) *p++]--; } } } /* If all needs are met, we win. */ for (i = 0; i < N_REG_CLASSES; i++) if (max_needs[i] > 0 || max_groups[i] > 0 || max_nongroups[i] > 0) break; if (i == N_REG_CLASSES && !new_basic_block_needs) break; /* Not all needs are met; must spill more hard regs. */ /* If any element of basic_block_needs changed from 0 to 1, re-spill all the regs already spilled. This may spill additional pseudos that didn't spill before. */ if (new_basic_block_needs) for (i = 0; i < n_spills; i++) something_changed |= spill_hard_reg (spill_regs[i], global, dumpfile); /* Now find more reload regs to satisfy the remaining need Do it by ascending class number, since otherwise a reg might be spilled for a big class and might fail to count for a smaller class even though it belongs to that class. Count spilled regs in `spills', and add entries to `spill_regs' and `spill_reg_order'. */ for (class = 0; class < N_REG_CLASSES; class++) { /* First get the groups of registers. If we got single registers first, we might fragment possible groups. */ while (max_groups[class] > 0) { /* Groups of size 2 (the only groups used on most machines) are treated specially. */ if (group_size[class] == 2) { /* First, look for a register that will complete a group. */ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) { int j = potential_reload_regs[i]; int other; if (j >= 0 && !fixed_regs[j] && j != FRAME_POINTER_REGNUM && !regs_explicitly_used[j] && ((j > 0 && (other = j - 1, spill_reg_order[other] >= 0) && TEST_HARD_REG_BIT (reg_class_contents[class], j) && TEST_HARD_REG_BIT (reg_class_contents[class], other) && HARD_REGNO_MODE_OK (other, group_mode[class]) && ! counted_for_nongroups[other] /* We don't want one part of another group. We could get "two groups" that overlap! */ && ! counted_for_groups[other]) || (j < FIRST_PSEUDO_REGISTER - 1 && (other = j + 1, spill_reg_order[other] >= 0) && TEST_HARD_REG_BIT (reg_class_contents[class], j) && TEST_HARD_REG_BIT (reg_class_contents[class], other) && HARD_REGNO_MODE_OK (j, group_mode[class]) && ! counted_for_nongroups[other] && ! counted_for_groups[other]))) { register enum reg_class *p; /* We have found one that will complete a group, so count off one group as provided. */ max_groups[class]--; p = reg_class_superclasses[class]; while (*p != LIM_REG_CLASSES) max_groups[(int) *p++]--; /* Indicate both these regs are part of a group. */ counted_for_groups[j] = 1; counted_for_groups[other] = 1; break; } } /* We can't complete a group, so start one. */ if (i == FIRST_PSEUDO_REGISTER) for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) { int j = potential_reload_regs[i]; if (j >= 0 && j + 1 < FIRST_PSEUDO_REGISTER && !fixed_regs[j] && j != FRAME_POINTER_REGNUM && spill_reg_order[j] < 0 && spill_reg_order[j + 1] < 0 && TEST_HARD_REG_BIT (reg_class_contents[class], j) && TEST_HARD_REG_BIT (reg_class_contents[class], j + 1) && HARD_REGNO_MODE_OK (j, group_mode[class]) && ! counted_for_nongroups[j + 1]) break; } /* I should be the index in potential_reload_regs of the new reload reg we have found. */ something_changed |= new_spill_reg (i, class, max_needs, 0, global, dumpfile); } else { /* For groups of more than 2 registers, look for a sufficient sequence of unspilled registers, and spill them all at once. */ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) { int j = potential_reload_regs[i]; int k; if (j >= 0 && j + 1 < FIRST_PSEUDO_REGISTER && HARD_REGNO_MODE_OK (j, group_mode[class])) { /* Check each reg in the sequence. */ for (k = 0; k < group_size[class]; k++) if (! (spill_reg_order[j + k] < 0 && !fixed_regs[j + k] && j + k != FRAME_POINTER_REGNUM && TEST_HARD_REG_BIT (reg_class_contents[class], j + k))) break; /* We got a full sequence, so spill them all. */ if (k == group_size[class]) { register enum reg_class *p; for (k = 0; k < group_size[class]; k++) { int idx; counted_for_groups[j + k] = 1; for (idx = 0; idx < FIRST_PSEUDO_REGISTER; idx++) if (potential_reload_regs[idx] == j + k) break; something_changed |= new_spill_reg (idx, class, max_needs, 0, global, dumpfile); } /* We have found one that will complete a group, so count off one group as provided. */ max_groups[class]--; p = reg_class_superclasses[class]; while (*p != LIM_REG_CLASSES) max_groups[(int) *p++]--; break; } } } } } /* Now similarly satisfy all need for single registers. */ while (max_needs[class] > 0 || max_nongroups[class] > 0) { /* Consider the potential reload regs that aren't yet in use as reload regs, in order of preference. Find the most preferred one that's in this class. */ for (i = 0; i < FIRST_PSEUDO_REGISTER; i++) if (potential_reload_regs[i] >= 0 && TEST_HARD_REG_BIT (reg_class_contents[class], potential_reload_regs[i]) /* If this reg will not be available for groups, pick one that does not foreclose possible groups. This is a kludge, and not very general, but it should be sufficient to make the 386 work, and the problem should not occur on machines with more registers. */ && (max_nongroups[class] == 0 || possible_group_p (potential_reload_regs[i], max_groups))) break; /* I should be the index in potential_reload_regs of the new reload reg we have found. */ something_changed |= new_spill_reg (i, class, max_needs, max_nongroups, global, dumpfile); } } } /* Insert code to save and restore call-clobbered hard regs around calls. */ if (caller_save_needed) save_call_clobbered_regs (); /* Now we know for certain whether we have a frame pointer. If not, correct all references to go through the stack pointer. This must be done before reloading, since reloading could generate insns where sp+const cannot validly replace the frame pointer. *This will lose if an insn might need more spill regs after frame pointer elimination than it needed before.* */ if (! frame_pointer_needed) eliminate_frame_pointer (first); /* Use the reload registers where necessary by generating move instructions to move the must-be-register values into or out of the reload registers. */ if (something_needs_reloads) reload_as_needed (first, global); /* Now eliminate all pseudo regs by modifying them into their equivalent memory references. The REG-rtx's for the pseudos are modified in place, so all insns that used to refer to them now refer to memory. For a reg that has a reg_equiv_address, all those insns were changed by reloading so that no insns refer to it any longer; but the DECL_RTL of a variable decl may refer to it, and if so this causes the debugging info to mention the variable. */ for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++) { rtx addr = 0; if (reg_equiv_mem[i]) addr = XEXP (reg_equiv_mem[i], 0); if (reg_equiv_address[i]) addr = reg_equiv_address[i]; if (addr) { if (! frame_pointer_needed) FIX_FRAME_POINTER_ADDRESS (addr, 0); if (reg_renumber[i] < 0) { rtx reg = regno_reg_rtx[i]; XEXP (reg, 0) = addr; REG_USERVAR_P (reg) = 0; PUT_CODE (reg, MEM); } else if (reg_equiv_mem[i]) XEXP (reg_equiv_mem[i], 0) = addr; } }}/* Nonzero if, after spilling reg REGNO for non-groups, it will still be possible to find a group if we still need one. */static intpossible_group_p (regno, max_groups) int regno; int *max_groups;{ int i; int group = 0; for (i = 0; i < (int) N_REG_CLASSES; i++) group |= max_groups[i]; if (group == 0) return 1; /* Consider each pair of consecutive registers. */ for (i = 0; i < FIRST_PSEUDO_REGISTER - 1; i++) { if (i == regno || i + 1 == regno) continue; /* A pair of consecutive regs we can still spill does the trick. */ if (spill_reg_order[i] < 0 && spill_reg_order[i + 1] < 0 && !regs_explicitly_used[i] && !regs_explicitly_used[i + 1] && !fixed_regs[i] && i != FRAME_POINTER_REGNUM && !fixed_regs[i + 1] && i + 1 != FRAME_POINTER_REGNUM) return 1; /* A pair of one already spilled and one we can spill does it provided the one already spilled is not otherwise reserved. */ if (spill_reg_order[i] < 0 && !regs_explicitly_used[i] && !fixed_regs[i] && i != FRAME_POINTER_REGNUM && spill_reg_order[i + 1] >= 0 && !counted_for_groups[i + 1] && !counted_for_nongroups[i + 1]) return 1; if (spill_reg_order[i + 1] < 0 && !regs_explicitly_used[i + 1] && !fixed_regs[i + 1] && i + 1 != FRAME_POINTER_REGNUM && spill_reg_order[i] >= 0 && !counted_for_groups[i] && !counted_for_nongroups[i]) return 1; } return 0;}/* 1 if two machine modes MODE0 and MODE1 are equivalent as far as HARD_REGNO_MODE_OK is concerned for registers in class CLASS. */static intmodes_equiv_for_class_p (mode0, mode1, class) enum machine_mode mode0, mode1; enum reg_class class;{ register int regno; for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++) { /* If any reg in CLASS allows one mode but not the other, fail. Or if the two modes have different sizes in that reg, fail. */ if (TEST_HARD_REG_BIT (reg_class_contents[(int) class], regno) && (HARD_REGNO_MODE_OK (regno, mode0) != HARD_REGNO_MODE_OK (regno, mode1)) && (HARD_REGNO_NREGS (regno, mode0) != HARD_REGNO_NREGS (regno, mode1))) return 0; } return 1;}/* Add a new register to the tables of available spill-registers (as well as spilling all pseudos allocated to the register). I is the index of this register in potential_reload_regs. CLASS is the regclass whose need is being satisfied. MAX_NEEDS and MAX_NONGROUPS are the vectors of needs, so that this register can count off against them. MAX_NONGROUPS is 0 if this register is part of a group. GLOBAL and DUMPFILE are the same as the args that `reload' got. */static intnew_spill_reg (i, class, max_needs, max_nongroups, global, dumpfile) int i; int class; int *max_needs; int *max_nongroups; int global; FILE *dumpfile;{ register enum reg_class *p; int val; int regno = potential_reload_regs[i]; if (i >= FIRST_PSEUDO_REGISTER) abort (); /* Caller failed to find any register. */#if 0 /* This causes errors on the 386 for code that works ok. */ if (regs_explicitly_used[regno]) { error ("spilling register %s, which is explicitly used", reg_names[regno]); error ("(Probably too many explicit register variables"); error (" are used in this function)"); }#endif /* Make reg REGNO an additional reload reg. */ potential_reload_regs[i] = -1; spill_regs[n_spills] = regno; spill_reg_order[regno] = n_spills; forbidden_regs[regno] = 1; if (dumpfile) fprintf (dumpfile, "Spilling reg %d.\n", spill_regs[n_spills]); /* Clear off the needs we just satisfied. */ max_needs[class]--; p = reg_class_superclasses[class]; while (*p != LIM_REG_CLASSES) max_needs[(int) *p++]--; if (max_nongroups && max_nongroups[class] > 0) { counted_for_nongroups[regno] = 1; max_nongroups[class]--; p = reg_class_superclasses[class]; while (*p != LIM_REG_CLASSES) max_nongroups[(int) *p++]--; } /* Spill every pseudo reg that was allocated to this reg or to something that overlaps this reg. */ val = spill_hard_reg (spill_regs[n_spills], global, dumpfile); regs_ever_live[spill_regs[n_spills]] = 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -