llvm.org GIT mirror llvm / e53abc2
ARM: remove unnecessary state-tracking during frame lowering. ResolveFrameIndex had what appeared to be a very nasty hack for when the frame-index referred to a callee-saved register. In this case it "adjusted" the offset so that the address was correct if (and only if) the MachineInstr immediately followed the respective push. This "worked" for all forms of GPR & DPR but was only ever used to set the frame pointer itself, and once this was put in a more sensible location the entire state-tracking machinery it relied on became redundant. So I stripped it. The only wrinkle is that "add r7, sp, #0" might theoretically be slower (need an actual ALU slot) compared to "mov r7, sp" so I added a micro-optimisation that also makes emitARMRegUpdate and emitT2RegUpdate also work when NumBytes == 0. No test changes since there shouldn't be any functionality change. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@194025 91177308-0d34-0410-b5e6-96231b3b80d8 Tim Northover 6 years ago
6 changed file(s) with 58 addition(s) and 115 deletion(s). Raw diff Collapse all Expand all
18251825 unsigned DestReg, unsigned BaseReg, int NumBytes,
18261826 ARMCC::CondCodes Pred, unsigned PredReg,
18271827 const ARMBaseInstrInfo &TII, unsigned MIFlags) {
1828 if (NumBytes == 0 && DestReg != BaseReg) {
1829 BuildMI(MBB, MBBI, dl, TII.get(ARM::MOVr), DestReg)
1830 .addReg(BaseReg, RegState::Kill)
1831 .addImm((unsigned)Pred).addReg(PredReg).addReg(0)
1832 .setMIFlags(MIFlags);
1833 return;
1834 }
1835
18281836 bool isSub = NumBytes < 0;
18291837 if (isSub) NumBytes = -NumBytes;
18301838
114114 return false;
115115 }
116116
117 static void
118 emitSPUpdate(bool isARM,
119 MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
120 DebugLoc dl, const ARMBaseInstrInfo &TII,
121 int NumBytes, unsigned MIFlags = MachineInstr::NoFlags,
122 ARMCC::CondCodes Pred = ARMCC::AL, unsigned PredReg = 0) {
117 static void emitRegPlusImmediate(bool isARM, MachineBasicBlock &MBB,
118 MachineBasicBlock::iterator &MBBI, DebugLoc dl,
119 const ARMBaseInstrInfo &TII, unsigned DestReg,
120 unsigned SrcReg, int NumBytes,
121 unsigned MIFlags = MachineInstr::NoFlags,
122 ARMCC::CondCodes Pred = ARMCC::AL,
123 unsigned PredReg = 0) {
123124 if (isARM)
124 emitARMRegPlusImmediate(MBB, MBBI, dl, ARM::SP, ARM::SP, NumBytes,
125 emitARMRegPlusImmediate(MBB, MBBI, dl, DestReg, SrcReg, NumBytes,
125126 Pred, PredReg, TII, MIFlags);
126127 else
127 emitT2RegPlusImmediate(MBB, MBBI, dl, ARM::SP, ARM::SP, NumBytes,
128 emitT2RegPlusImmediate(MBB, MBBI, dl, DestReg, SrcReg, NumBytes,
128129 Pred, PredReg, TII, MIFlags);
130 }
131
132 static void emitSPUpdate(bool isARM, MachineBasicBlock &MBB,
133 MachineBasicBlock::iterator &MBBI, DebugLoc dl,
134 const ARMBaseInstrInfo &TII, int NumBytes,
135 unsigned MIFlags = MachineInstr::NoFlags,
136 ARMCC::CondCodes Pred = ARMCC::AL,
137 unsigned PredReg = 0) {
138 emitRegPlusImmediate(isARM, MBB, MBBI, dl, TII, ARM::SP, ARM::SP, NumBytes,
139 MIFlags, Pred, PredReg);
129140 }
130141
131142 void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
185196 case ARM::LR:
186197 if (Reg == FramePtr)
187198 FramePtrSpillFI = FI;
188 AFI->addGPRCalleeSavedArea1Frame(FI);
189199 GPRCS1Size += 4;
190200 break;
191201 case ARM::R8:
195205 case ARM::R12:
196206 if (Reg == FramePtr)
197207 FramePtrSpillFI = FI;
198 if (STI.isTargetIOS()) {
199 AFI->addGPRCalleeSavedArea2Frame(FI);
208 if (STI.isTargetIOS())
200209 GPRCS2Size += 4;
201 } else {
202 AFI->addGPRCalleeSavedArea1Frame(FI);
210 else
203211 GPRCS1Size += 4;
204 }
205212 break;
206213 default:
207214 // This is a DPR. Exclude the aligned DPRCS2 spills.
208215 if (Reg == ARM::D8)
209216 D8SpillFI = FI;
210 if (Reg < ARM::D8 || Reg >= ARM::D8 + AFI->getNumAlignedDPRCS2Regs()) {
211 AFI->addDPRCalleeSavedAreaFrame(FI);
217 if (Reg < ARM::D8 || Reg >= ARM::D8 + AFI->getNumAlignedDPRCS2Regs())
212218 DPRCSSize += 8;
213 }
214219 }
215220 }
216221
217222 // Move past area 1.
218223 if (GPRCS1Size > 0) MBBI++;
219224
220 // Set FP to point to the stack slot that contains the previous FP.
221 // For iOS, FP is R7, which has now been stored in spill area 1.
222 // Otherwise, if this is not iOS, all the callee-saved registers go
223 // into spill area 1, including the FP in R11. In either case, it is
224 // now safe to emit this assignment.
225 // Determine starting offsets of spill areas.
225226 bool HasFP = hasFP(MF);
226 if (HasFP) {
227 unsigned ADDriOpc = !AFI->isThumbFunction() ? ARM::ADDri : ARM::t2ADDri;
228 MachineInstrBuilder MIB =
229 BuildMI(MBB, MBBI, dl, TII.get(ADDriOpc), FramePtr)
230 .addFrameIndex(FramePtrSpillFI).addImm(0)
231 .setMIFlag(MachineInstr::FrameSetup);
232 AddDefaultCC(AddDefaultPred(MIB));
233 }
234
235 // Move past area 2.
236 if (GPRCS2Size > 0) MBBI++;
237
238 // Determine starting offsets of spill areas.
239227 unsigned DPRCSOffset = NumBytes - (GPRCS1Size + GPRCS2Size + DPRCSSize);
240228 unsigned GPRCS2Offset = DPRCSOffset + DPRCSSize;
241229 unsigned GPRCS1Offset = GPRCS2Offset + GPRCS2Size;
245233 AFI->setGPRCalleeSavedArea1Offset(GPRCS1Offset);
246234 AFI->setGPRCalleeSavedArea2Offset(GPRCS2Offset);
247235 AFI->setDPRCalleeSavedAreaOffset(DPRCSOffset);
236
237 // Set FP to point to the stack slot that contains the previous FP.
238 // For iOS, FP is R7, which has now been stored in spill area 1.
239 // Otherwise, if this is not iOS, all the callee-saved registers go
240 // into spill area 1, including the FP in R11. In either case, it is
241 // now safe to emit this assignment.
242 if (HasFP) {
243 int FramePtrOffset = MFI->getObjectOffset(FramePtrSpillFI) + GPRCS1Size;
244 emitRegPlusImmediate(!AFI->isThumbFunction(), MBB, MBBI, dl, TII,
245 FramePtr, ARM::SP, FramePtrOffset,
246 MachineInstr::FrameSetup);
247 }
248
249 // Move past area 2.
250 if (GPRCS2Size > 0) MBBI++;
248251
249252 // Move past area 3.
250253 if (DPRCSSize > 0) {
505508
506509 FrameReg = ARM::SP;
507510 Offset += SPAdj;
508 if (AFI->isGPRCalleeSavedArea1Frame(FI))
509 return Offset - AFI->getGPRCalleeSavedArea1Offset();
510 else if (AFI->isGPRCalleeSavedArea2Frame(FI))
511 return Offset - AFI->getGPRCalleeSavedArea2Offset();
512 else if (AFI->isDPRCalleeSavedAreaFrame(FI))
513 return Offset - AFI->getDPRCalleeSavedAreaOffset();
514511
515512 // SP can move around if there are allocas. We may also lose track of SP
516513 // when emergency spilling inside a non-reserved call frame setup.
8282 unsigned GPRCS1Size;
8383 unsigned GPRCS2Size;
8484 unsigned DPRCSSize;
85
86 /// GPRCS1Frames, GPRCS2Frames, DPRCSFrames - Keeps track of frame indices
87 /// which belong to these spill areas.
88 BitVector GPRCS1Frames;
89 BitVector GPRCS2Frames;
90 BitVector DPRCSFrames;
9185
9286 /// NumAlignedDPRCS2Regs - The number of callee-saved DPRs that are saved in
9387 /// the aligned portion of the stack frame. This is always a contiguous
127121 LRSpilledForFarJump(false),
128122 FramePtrSpillOffset(0), GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0),
129123 GPRCS1Size(0), GPRCS2Size(0), DPRCSSize(0),
130 GPRCS1Frames(0), GPRCS2Frames(0), DPRCSFrames(0),
131124 NumAlignedDPRCS2Regs(0),
132125 JumpTableUId(0), PICLabelUId(0),
133126 VarArgsFrameIndex(0), HasITBlocks(false), GlobalBaseReg(0) {}
140133 LRSpilledForFarJump(false),
141134 FramePtrSpillOffset(0), GPRCS1Offset(0), GPRCS2Offset(0), DPRCSOffset(0),
142135 GPRCS1Size(0), GPRCS2Size(0), DPRCSSize(0),
143 GPRCS1Frames(32), GPRCS2Frames(32), DPRCSFrames(32),
144136 JumpTableUId(0), PICLabelUId(0),
145137 VarArgsFrameIndex(0), HasITBlocks(false), GlobalBaseReg(0) {}
146138
188180 void setGPRCalleeSavedArea1Size(unsigned s) { GPRCS1Size = s; }
189181 void setGPRCalleeSavedArea2Size(unsigned s) { GPRCS2Size = s; }
190182 void setDPRCalleeSavedAreaSize(unsigned s) { DPRCSSize = s; }
191
192 bool isGPRCalleeSavedArea1Frame(int fi) const {
193 if (fi < 0 || fi >= (int)GPRCS1Frames.size())
194 return false;
195 return GPRCS1Frames[fi];
196 }
197 bool isGPRCalleeSavedArea2Frame(int fi) const {
198 if (fi < 0 || fi >= (int)GPRCS2Frames.size())
199 return false;
200 return GPRCS2Frames[fi];
201 }
202 bool isDPRCalleeSavedAreaFrame(int fi) const {
203 if (fi < 0 || fi >= (int)DPRCSFrames.size())
204 return false;
205 return DPRCSFrames[fi];
206 }
207
208 void addGPRCalleeSavedArea1Frame(int fi) {
209 if (fi >= 0) {
210 int Size = GPRCS1Frames.size();
211 if (fi >= Size) {
212 Size *= 2;
213 if (fi >= Size)
214 Size = fi+1;
215 GPRCS1Frames.resize(Size);
216 }
217 GPRCS1Frames[fi] = true;
218 }
219 }
220 void addGPRCalleeSavedArea2Frame(int fi) {
221 if (fi >= 0) {
222 int Size = GPRCS2Frames.size();
223 if (fi >= Size) {
224 Size *= 2;
225 if (fi >= Size)
226 Size = fi+1;
227 GPRCS2Frames.resize(Size);
228 }
229 GPRCS2Frames[fi] = true;
230 }
231 }
232 void addDPRCalleeSavedAreaFrame(int fi) {
233 if (fi >= 0) {
234 int Size = DPRCSFrames.size();
235 if (fi >= Size) {
236 Size *= 2;
237 if (fi >= Size)
238 Size = fi+1;
239 DPRCSFrames.resize(Size);
240 }
241 DPRCSFrames[fi] = true;
242 }
243 }
244183
245184 unsigned createJumpTableUId() {
246185 return JumpTableUId++;
126126 case ARM::LR:
127127 if (Reg == FramePtr)
128128 FramePtrSpillFI = FI;
129 AFI->addGPRCalleeSavedArea1Frame(FI);
130129 GPRCS1Size += 4;
131130 break;
132131 case ARM::R8:
135134 case ARM::R11:
136135 if (Reg == FramePtr)
137136 FramePtrSpillFI = FI;
138 if (STI.isTargetIOS()) {
139 AFI->addGPRCalleeSavedArea2Frame(FI);
137 if (STI.isTargetIOS())
140138 GPRCS2Size += 4;
141 } else {
142 AFI->addGPRCalleeSavedArea1Frame(FI);
139 else
143140 GPRCS1Size += 4;
144 }
145141 break;
146142 default:
147 AFI->addDPRCalleeSavedAreaFrame(FI);
148143 DPRCSSize += 8;
149144 }
150145 }
170165
171166 // Adjust FP so it point to the stack slot that contains the previous FP.
172167 if (HasFP) {
168 int FramePtrOffset = MFI->getObjectOffset(FramePtrSpillFI) + GPRCS1Size;
173169 AddDefaultPred(BuildMI(MBB, MBBI, dl, TII.get(ARM::tADDrSPi), FramePtr)
174 .addFrameIndex(FramePtrSpillFI).addImm(0)
170 .addReg(ARM::SP).addImm(FramePtrOffset / 4)
175171 .setMIFlags(MachineInstr::FrameSetup));
176172 if (NumBytes > 508)
177173 // If offset is > 508 then sp cannot be adjusted in a single instruction,
572572 int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) +
573573 MF.getFrameInfo()->getStackSize() + SPAdj;
574574
575 if (AFI->isGPRCalleeSavedArea1Frame(FrameIndex))
576 Offset -= AFI->getGPRCalleeSavedArea1Offset();
577 else if (AFI->isGPRCalleeSavedArea2Frame(FrameIndex))
578 Offset -= AFI->getGPRCalleeSavedArea2Offset();
579 else if (MF.getFrameInfo()->hasVarSizedObjects()) {
575 if (MF.getFrameInfo()->hasVarSizedObjects()) {
580576 assert(SPAdj == 0 && MF.getTarget().getFrameLowering()->hasFP(MF) &&
581577 "Unexpected");
582578 // There are alloca()'s in this function, must reference off the frame
214214 unsigned DestReg, unsigned BaseReg, int NumBytes,
215215 ARMCC::CondCodes Pred, unsigned PredReg,
216216 const ARMBaseInstrInfo &TII, unsigned MIFlags) {
217 if (NumBytes == 0 && DestReg != BaseReg) {
218 BuildMI(MBB, MBBI, dl, TII.get(ARM::tMOVr), DestReg)
219 .addReg(BaseReg, RegState::Kill)
220 .addImm((unsigned)Pred).addReg(PredReg).setMIFlags(MIFlags);
221 return;
222 }
223
217224 bool isSub = NumBytes < 0;
218225 if (isSub) NumBytes = -NumBytes;
219226