llvm.org GIT mirror llvm / 5c3885c
Under normal circumstances, when a frame pointer is not required, we reserve argument space for call sites in the function immediately on entry to the current function. This eliminates the need for add/sub sp brackets around call sites. However, this is not always a good idea. If the "call frame" is large and the target load / store instructions have small immediate field to encode sp offset, this can cause poor codegen. In the worst case, this can make it impossible to scavenge a register if the reserved spill slot is pushed too far apart from sp / fp. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36607 91177308-0d34-0410-b5e6-96231b3b80d8 Evan Cheng 13 years ago
3 changed file(s) with 43 addition(s) and 20 deletion(s). Raw diff Collapse all Expand all
134134 unsigned MaxCallFrameSize = 0;
135135 bool HasCalls = false;
136136
137 std::vector FrameSDOps;
137138 for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB)
138 for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); )
139 for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ++I)
139140 if (I->getOpcode() == FrameSetupOpcode ||
140141 I->getOpcode() == FrameDestroyOpcode) {
141142 assert(I->getNumOperands() >= 1 && "Call Frame Setup/Destroy Pseudo"
143144 unsigned Size = I->getOperand(0).getImmedValue();
144145 if (Size > MaxCallFrameSize) MaxCallFrameSize = Size;
145146 HasCalls = true;
146 RegInfo->eliminateCallFramePseudoInstr(Fn, *BB, I++);
147 } else {
148 ++I;
147 FrameSDOps.push_back(I);
149148 }
150149
151150 MachineFrameInfo *FFI = Fn.getFrameInfo();
152151 FFI->setHasCalls(HasCalls);
153152 FFI->setMaxCallFrameSize(MaxCallFrameSize);
153 for (unsigned i = 0, e = FrameSDOps.size(); i != e; ++i) {
154 MachineBasicBlock::iterator I = FrameSDOps[i];
155 RegInfo->eliminateCallFramePseudoInstr(Fn, *I->getParent(), I);
156 }
154157
155158 // Now figure out which *callee saved* registers are modified by the current
156159 // function, thus needing to be saved and restored in the prolog/epilog.
332335 // First assign frame offsets to stack objects that are used to spill
333336 // callee saved registers.
334337 if (StackGrowsDown) {
335 for (unsigned i = 0, e = FFI->getObjectIndexEnd(); i != e; ++i) {
336 if (i < MinCSFrameIndex || i > MaxCSFrameIndex)
337 continue;
338
338 for (unsigned i = MinCSFrameIndex; i <= MaxCSFrameIndex; ++i) {
339339 // If stack grows down, we need to add size of find the lowest
340340 // address of the object.
341341 Offset += FFI->getObjectSize(i);
350350 FFI->setObjectOffset(i, -Offset); // Set the computed offset
351351 }
352352 } else {
353 for (int i = FFI->getObjectIndexEnd()-1; i >= 0; --i) {
354 if ((unsigned)i < MinCSFrameIndex || (unsigned)i > MaxCSFrameIndex)
355 continue;
356
353 for (unsigned i = MaxCSFrameIndex; i >= MinCSFrameIndex; --i) {
357354 unsigned Align = FFI->getObjectAlignment(i);
358355 // If the alignment of this object is greater than that of the stack, then
359356 // increase the stack alignment to match.
372369 if (RS && RegInfo->hasFP(Fn)) {
373370 int SFI = RS->getScavengingFrameIndex();
374371 if (SFI >= 0) {
375 // If stack grows down, we need to add size of find the lowest
372 // If stack grows down, we need to add size of the lowest
376373 // address of the object.
377374 if (StackGrowsDown)
378375 Offset += FFI->getObjectSize(SFI);
446443 // subroutines have their stack frames suitable aligned.
447444 if (!RegInfo->targetHandlesStackFrameRounding() &&
448445 (FFI->hasCalls() || FFI->hasVarSizedObjects())) {
449 // When we have no frame pointer, we reserve argument space for call sites
450 // in the function immediately on entry to the current function. This
451 // eliminates the need for add/sub sp brackets around call sites.
452 if (!RegInfo->hasFP(Fn))
446 // If we have reserved argument space for call sites in the function
447 // immediately on entry to the current function, count it as part of the
448 // overall stack size.
449 if (RegInfo->hasReservedCallFrame(Fn))
453450 Offset += FFI->getMaxCallFrameSize();
454451
455452 unsigned AlignMask = TFI.getStackAlignment() - 1;
385385 return NoFramePointerElim || MF.getFrameInfo()->hasVarSizedObjects();
386386 }
387387
388 // hasReservedCallFrame - Under normal circumstances, when a frame pointer is
389 // not required, we reserve argument space for call sites in the function
390 // immediately on entry to the current function. This eliminates the need for
391 // add/sub sp brackets around call sites. Returns true if the call frame is
392 // included as part of the stack frame.
393 bool ARMRegisterInfo::hasReservedCallFrame(MachineFunction &MF) const {
394 const MachineFrameInfo *FFI = MF.getFrameInfo();
395 unsigned CFSize = FFI->getMaxCallFrameSize();
396 ARMFunctionInfo *AFI = MF.getInfo();
397 // It's not always a good idea to include the call frame as part of the
398 // stack frame. ARM (especially Thumb) has small immediate offset to
399 // address the stack frame. So a large call frame can cause poor codegen
400 // and may even makes it impossible to scavenge a register.
401 if (AFI->isThumbFunction()) {
402 if (CFSize >= ((1 << 8) - 1) * 4 / 2) // Half of imm8 * 4
403 return false;
404 } else {
405 if (CFSize >= ((1 << 12) - 1) / 2) // Half of imm12
406 return false;
407 }
408 return !hasFP(MF);
409 }
410
388411 /// emitARMRegPlusImmediate - Emits a series of instructions to materialize
389412 /// a destreg = basereg + immediate in ARM code.
390413 static
604627 void ARMRegisterInfo::
605628 eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
606629 MachineBasicBlock::iterator I) const {
607 if (hasFP(MF)) {
630 if (!hasReservedCallFrame(MF)) {
608631 // If we have alloca, convert as follows:
609632 // ADJCALLSTACKDOWN -> sub, sp, sp, amount
610633 // ADJCALLSTACKUP -> add, sp, sp, amount
11451168 Limit = (1 << 8) - 1;
11461169 goto DoneEstimating;
11471170 } else if (AddrMode == ARMII::AddrMode5) {
1148 Limit = ((1 << 8) - 1) * 4;
1149 goto DoneEstimating;
1171 unsigned ThisLimit = ((1 << 8) - 1) * 4;
1172 if (ThisLimit < Limit)
1173 Limit = ThisLimit;
11501174 }
11511175 }
11521176 }
7777
7878 bool hasFP(const MachineFunction &MF) const;
7979
80 bool hasReservedCallFrame(MachineFunction &MF) const;
81
8082 void eliminateCallFramePseudoInstr(MachineFunction &MF,
8183 MachineBasicBlock &MBB,
8284 MachineBasicBlock::iterator I) const;