llvm.org GIT mirror llvm / 140e33c
Scavenge a register using the register scavenger when needed. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@34966 91177308-0d34-0410-b5e6-96231b3b80d8 Evan Cheng 13 years ago
2 changed file(s) with 111 addition(s) and 14 deletion(s). Raw diff Collapse all Expand all
8484 : ARMGenRegisterInfo(ARM::ADJCALLSTACKDOWN, ARM::ADJCALLSTACKUP),
8585 TII(tii), STI(sti),
8686 FramePtr(STI.useThumbBacktraces() ? ARM::R7 : ARM::R11) {
87 RS = (EnableScavenging) ? new RegScavenger() : NULL;
88 }
89
90 ARMRegisterInfo::~ARMRegisterInfo() {
91 delete RS;
9287 }
9388
9489 bool ARMRegisterInfo::spillCalleeSavedRegisters(MachineBasicBlock &MBB,
325320 if (MF.getUsedPhysregs() && !MF.isPhysRegUsed((unsigned)ARM::LR))
326321 Reserved.set(ARM::LR);
327322 return Reserved;
323 }
324
325 bool
326 ARMRegisterInfo::isReservedReg(const MachineFunction &MF, unsigned Reg) const {
327 switch (Reg) {
328 default: break;
329 case ARM::SP:
330 case ARM::PC:
331 return true;
332 case ARM::R7:
333 case ARM::R11:
334 if (FramePtr == Reg && (STI.isTargetDarwin() || hasFP(MF)))
335 return true;
336 break;
337 case ARM::R9:
338 return STI.isR9Reserved();
339 }
340
341 return false;
328342 }
329343
330344 bool
917931 // to form it with a series of ADDri's. Do this by taking 8-bit chunks
918932 // out of 'Offset'.
919933 unsigned ScratchReg = findScratchRegister(RS, &ARM::GPRRegClass, AFI);
920 assert(ScratchReg && "Unable to find a free register!");
934 if (ScratchReg == 0)
935 // No register is "free". Scavenge a register.
936 ScratchReg = RS->scavengeRegister(&ARM::GPRRegClass, II);
921937 emitARMRegPlusImmediate(MBB, II, ScratchReg, FrameReg,
922938 isSub ? -Offset : Offset, TII);
923939 MI.getOperand(i).ChangeToRegister(ScratchReg, false, false, true);
924940 }
925941 }
926942
927 void ARMRegisterInfo::
928 processFunctionBeforeCalleeSavedScan(MachineFunction &MF) const {
943 static unsigned estimateStackSize(MachineFunction &MF, MachineFrameInfo *MFI) {
944 const MachineFrameInfo *FFI = MF.getFrameInfo();
945 int Offset = 0;
946 for (int i = FFI->getObjectIndexBegin(); i != 0; ++i) {
947 int FixedOff = -FFI->getObjectOffset(i);
948 if (FixedOff > Offset) Offset = FixedOff;
949 }
950 for (unsigned i = 0, e = FFI->getObjectIndexEnd(); i != e; ++i) {
951 Offset += FFI->getObjectSize(i);
952 unsigned Align = FFI->getObjectAlignment(i);
953 // Adjust to alignment boundary
954 Offset = (Offset+Align-1)/Align*Align;
955 }
956 return (unsigned)Offset;
957 }
958
959 void
960 ARMRegisterInfo::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
961 RegScavenger *RS) const {
929962 // This tells PEI to spill the FP as if it is any other callee-save register
930963 // to take advantage the eliminateFrameIndex machinery. This also ensures it
931964 // is spilled in the order specified by getCalleeSavedRegs() to make it easier
10191052 }
10201053 }
10211054
1055 bool ExtraCSSpill = false;
10221056 if (!CanEliminateFrame || hasFP(MF)) {
10231057 AFI->setHasStackFrame(true);
10241058
10311065 UnspilledCS1GPRs.erase(std::find(UnspilledCS1GPRs.begin(),
10321066 UnspilledCS1GPRs.end(), (unsigned)ARM::LR));
10331067 ForceLRSpill = false;
1068 ExtraCSSpill = true;
10341069 }
10351070
10361071 // Darwin ABI requires FP to point to the stack slot that contains the
10491084 unsigned Reg = UnspilledCS1GPRs.front();
10501085 MF.changePhyRegUsed(Reg, true);
10511086 AFI->setCSRegisterIsSpilled(Reg);
1087 if (!isReservedReg(MF, Reg))
1088 ExtraCSSpill = true;
10521089 } else if (!UnspilledCS2GPRs.empty()) {
10531090 unsigned Reg = UnspilledCS2GPRs.front();
10541091 MF.changePhyRegUsed(Reg, true);
10551092 AFI->setCSRegisterIsSpilled(Reg);
1093 if (!isReservedReg(MF, Reg))
1094 ExtraCSSpill = true;
1095 }
1096 }
1097
1098 // Estimate if we might need to scavenge a register at some point in order
1099 // to materialize a stack offset. If so, either spill one additiona
1100 // callee-saved register or reserve a special spill slot to facilitate
1101 // register scavenging.
1102 if (RS && !ExtraCSSpill && !AFI->isThumbFunction()) {
1103 MachineFrameInfo *MFI = MF.getFrameInfo();
1104 unsigned Size = estimateStackSize(MF, MFI);
1105 unsigned Limit = (1 << 12) - 1;
1106 for (MachineFunction::iterator BB = MF.begin(),E = MF.end();BB != E; ++BB)
1107 for (MachineBasicBlock::iterator I= BB->begin(); I != BB->end(); ++I) {
1108 for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
1109 if (I->getOperand(i).isFrameIndex()) {
1110 unsigned Opcode = I->getOpcode();
1111 const TargetInstrDescriptor &Desc = TII.get(Opcode);
1112 unsigned AddrMode = (Desc.TSFlags & ARMII::AddrModeMask);
1113 if (AddrMode == ARMII::AddrMode3) {
1114 Limit = (1 << 8) - 1;
1115 goto DoneEstimating;
1116 } else if (AddrMode == ARMII::AddrMode5) {
1117 Limit = ((1 << 8) - 1) * 4;
1118 goto DoneEstimating;
1119 }
1120 }
1121 }
1122 DoneEstimating:
1123 if (Size >= Limit) {
1124 // If any non-reserved CS register isn't spilled, just spill one or two
1125 // extra. That should take care of it!
1126 unsigned NumExtras = TargetAlign / 4;
1127 SmallVector Extras;
1128 while (NumExtras && !UnspilledCS1GPRs.empty()) {
1129 unsigned Reg = UnspilledCS1GPRs.back();
1130 UnspilledCS1GPRs.pop_back();
1131 if (!isReservedReg(MF, Reg)) {
1132 Extras.push_back(Reg);
1133 NumExtras--;
1134 }
1135 }
1136 while (NumExtras && !UnspilledCS2GPRs.empty()) {
1137 unsigned Reg = UnspilledCS2GPRs.back();
1138 UnspilledCS2GPRs.pop_back();
1139 if (!isReservedReg(MF, Reg)) {
1140 Extras.push_back(Reg);
1141 NumExtras--;
1142 }
1143 }
1144 if (Extras.size() && NumExtras == 0) {
1145 for (unsigned i = 0, e = Extras.size(); i != e; ++i) {
1146 MF.changePhyRegUsed(Extras[i], true);
1147 AFI->setCSRegisterIsSpilled(Extras[i]);
1148 }
1149 } else {
1150 // Reserve a slot closest to SP or frame pointer.
1151 const TargetRegisterClass *RC = &ARM::GPRRegClass;
1152 RS->setScavengingFrameIndex(MFI->CreateStackObject(RC->getSize(),
1153 RC->getAlignment()));
1154 }
10561155 }
10571156 }
10581157 }
2626 const TargetInstrInfo &TII;
2727 const ARMSubtarget &STI;
2828 private:
29 /// RS - An instance of the register scavenger.
30 RegScavenger *RS;
31
3229 /// FramePtr - ARM physical register used as frame ptr.
3330 unsigned FramePtr;
3431
3532 public:
3633 ARMRegisterInfo(const TargetInstrInfo &tii, const ARMSubtarget &STI);
37
38 ~ARMRegisterInfo();
3934
4035 /// getRegisterNumbering - Given the enum value for some register, e.g.
4136 /// ARM::LR, return the number that it corresponds to (e.g. 14).
7368
7469 BitVector getReservedRegs(const MachineFunction &MF) const;
7570
71 bool isReservedReg(const MachineFunction &MF, unsigned Reg) const;
72
7673 bool requiresRegisterScavenging(const MachineFunction &MF) const;
7774
7875 bool hasFP(const MachineFunction &MF) const;
8481 void eliminateFrameIndex(MachineBasicBlock::iterator II,
8582 RegScavenger *RS = NULL) const;
8683
87 void processFunctionBeforeCalleeSavedScan(MachineFunction &MF) const;
84 void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
85 RegScavenger *RS = NULL) const;
8886
8987 void emitPrologue(MachineFunction &MF) const;
9088 void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;