1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-24 11:42:57 +01:00

If call frame is not part of stack frame and no dynamic alloc, eliminateFrameIndex() must adjust SP offset with size of call frames.

llvm-svn: 36625
This commit is contained in:
Evan Cheng 2007-05-01 09:01:42 +00:00
parent e7bd8c76db
commit 17f967eb52
2 changed files with 48 additions and 17 deletions

View File

@ -26,6 +26,7 @@
#include "llvm/Target/TargetFrameInfo.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Support/Compiler.h"
#include "llvm/ADT/STLExtras.h"
#include <climits>
using namespace llvm;
@ -151,9 +152,14 @@ void PEI::calculateCalleeSavedRegisters(MachineFunction &Fn) {
MachineFrameInfo *FFI = Fn.getFrameInfo();
FFI->setHasCalls(HasCalls);
FFI->setMaxCallFrameSize(MaxCallFrameSize);
for (unsigned i = 0, e = FrameSDOps.size(); i != e; ++i) {
MachineBasicBlock::iterator I = FrameSDOps[i];
RegInfo->eliminateCallFramePseudoInstr(Fn, *I->getParent(), I);
// If call frames are not being included as part of the stack frame,
// and there is no dynamic allocation (therefore referencing frame slots
// off sp), leave the pseudo ops alone. We'll eliminate them later.
if (RegInfo->hasReservedCallFrame(Fn) || RegInfo->hasFP(Fn))
RegInfo->eliminateCallFramePseudoInstr(Fn, *I->getParent(), I);
}
// Now figure out which *callee saved* registers are modified by the current
@ -491,25 +497,49 @@ void PEI::replaceFrameIndices(MachineFunction &Fn) {
const TargetMachine &TM = Fn.getTarget();
assert(TM.getRegisterInfo() && "TM::getRegisterInfo() must be implemented!");
const MRegisterInfo &MRI = *TM.getRegisterInfo();
const TargetFrameInfo *TFI = TM.getFrameInfo();
bool StackGrowsDown =
TFI->getStackGrowthDirection() == TargetFrameInfo::StackGrowsDown;
int FrameSetupOpcode = MRI.getCallFrameSetupOpcode();
int FrameDestroyOpcode = MRI.getCallFrameDestroyOpcode();
for (MachineFunction::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) {
int SPAdj = 0; // SP offset due to call frame setup / destroy.
if (RS) RS->enterBasicBlock(BB);
for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ) {
MachineInstr *MI = I++;
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i)
if (MI->getOperand(i).isFrameIndex()) {
// If this instruction has a FrameIndex operand, we need to use that
// target machine register info object to eliminate it.
MRI.eliminateFrameIndex(MI, RS);
MachineInstr *MI = I;
// Revisit the instruction in full. Some instructions (e.g. inline
// asm instructions) can have multiple frame indices.
--I;
MI = 0;
break;
}
// Remember how much SP has been adjustment to create the call frame.
if (I->getOpcode() == FrameSetupOpcode ||
I->getOpcode() == FrameDestroyOpcode) {
int Size = I->getOperand(0).getImmedValue();
if ((!StackGrowsDown && I->getOpcode() == FrameSetupOpcode) ||
(StackGrowsDown && I->getOpcode() == FrameDestroyOpcode))
Size = -Size;
SPAdj += Size;
MachineBasicBlock::iterator PrevI = prior(I);
MRI.eliminateCallFramePseudoInstr(Fn, *BB, I);
// Visit the instructions created by eliminateCallFramePseudoInstr().
I = next(PrevI);
MI = NULL;
} else {
I++;
for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i)
if (MI->getOperand(i).isFrameIndex()) {
// If this instruction has a FrameIndex operand, we need to use that
// target machine register info object to eliminate it.
MRI.eliminateFrameIndex(MI, SPAdj, RS);
// Revisit the instruction in full. Some instructions (e.g. inline
// asm instructions) can have multiple frame indices.
--I;
MI = 0;
break;
}
}
// Update register states.
if (RS && MI) RS->forward(MI);
}
assert(SPAdj == 0 && "Unbalanced call frame setup / destroy pairs?");
}
}

View File

@ -75,7 +75,7 @@ void RegScavenger::restoreScavengedReg() {
RegInfo->loadRegFromStackSlot(*MBB, MBBI, ScavengedReg,
ScavengingFrameIndex, ScavengedRC);
MachineBasicBlock::iterator II = prior(MBBI);
RegInfo->eliminateFrameIndex(II, this);
RegInfo->eliminateFrameIndex(II, 0, this);
setUsed(ScavengedReg);
ScavengedReg = 0;
ScavengedRC = NULL;
@ -243,7 +243,8 @@ static unsigned calcDistanceToUse(MachineBasicBlock *MBB,
}
unsigned RegScavenger::scavengeRegister(const TargetRegisterClass *RC,
MachineBasicBlock::iterator I) {
MachineBasicBlock::iterator I,
int SPAdj) {
assert(ScavengingFrameIndex >= 0 &&
"Cannot scavenge a register without an emergency spill slot!");
@ -277,12 +278,12 @@ unsigned RegScavenger::scavengeRegister(const TargetRegisterClass *RC,
RegInfo->loadRegFromStackSlot(*MBB, I, ScavengedReg,
ScavengingFrameIndex, ScavengedRC);
MachineBasicBlock::iterator II = prior(I);
RegInfo->eliminateFrameIndex(II, this);
RegInfo->eliminateFrameIndex(II, SPAdj, this);
}
RegInfo->storeRegToStackSlot(*MBB, I, SReg, ScavengingFrameIndex, RC);
MachineBasicBlock::iterator II = prior(I);
RegInfo->eliminateFrameIndex(II, this);
RegInfo->eliminateFrameIndex(II, SPAdj, this);
ScavengedReg = SReg;
ScavengedRC = RC;