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/TargetFrameInfo.h"
#include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Support/Compiler.h" #include "llvm/Support/Compiler.h"
#include "llvm/ADT/STLExtras.h"
#include <climits> #include <climits>
using namespace llvm; using namespace llvm;
@ -151,9 +152,14 @@ void PEI::calculateCalleeSavedRegisters(MachineFunction &Fn) {
MachineFrameInfo *FFI = Fn.getFrameInfo(); MachineFrameInfo *FFI = Fn.getFrameInfo();
FFI->setHasCalls(HasCalls); FFI->setHasCalls(HasCalls);
FFI->setMaxCallFrameSize(MaxCallFrameSize); FFI->setMaxCallFrameSize(MaxCallFrameSize);
for (unsigned i = 0, e = FrameSDOps.size(); i != e; ++i) { for (unsigned i = 0, e = FrameSDOps.size(); i != e; ++i) {
MachineBasicBlock::iterator I = FrameSDOps[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 // 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(); const TargetMachine &TM = Fn.getTarget();
assert(TM.getRegisterInfo() && "TM::getRegisterInfo() must be implemented!"); assert(TM.getRegisterInfo() && "TM::getRegisterInfo() must be implemented!");
const MRegisterInfo &MRI = *TM.getRegisterInfo(); 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) { 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); if (RS) RS->enterBasicBlock(BB);
for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ) { for (MachineBasicBlock::iterator I = BB->begin(); I != BB->end(); ) {
MachineInstr *MI = I++; 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);
// Revisit the instruction in full. Some instructions (e.g. inline // Remember how much SP has been adjustment to create the call frame.
// asm instructions) can have multiple frame indices. if (I->getOpcode() == FrameSetupOpcode ||
--I; I->getOpcode() == FrameDestroyOpcode) {
MI = 0; int Size = I->getOperand(0).getImmedValue();
break; 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. // Update register states.
if (RS && MI) RS->forward(MI); 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, RegInfo->loadRegFromStackSlot(*MBB, MBBI, ScavengedReg,
ScavengingFrameIndex, ScavengedRC); ScavengingFrameIndex, ScavengedRC);
MachineBasicBlock::iterator II = prior(MBBI); MachineBasicBlock::iterator II = prior(MBBI);
RegInfo->eliminateFrameIndex(II, this); RegInfo->eliminateFrameIndex(II, 0, this);
setUsed(ScavengedReg); setUsed(ScavengedReg);
ScavengedReg = 0; ScavengedReg = 0;
ScavengedRC = NULL; ScavengedRC = NULL;
@ -243,7 +243,8 @@ static unsigned calcDistanceToUse(MachineBasicBlock *MBB,
} }
unsigned RegScavenger::scavengeRegister(const TargetRegisterClass *RC, unsigned RegScavenger::scavengeRegister(const TargetRegisterClass *RC,
MachineBasicBlock::iterator I) { MachineBasicBlock::iterator I,
int SPAdj) {
assert(ScavengingFrameIndex >= 0 && assert(ScavengingFrameIndex >= 0 &&
"Cannot scavenge a register without an emergency spill slot!"); "Cannot scavenge a register without an emergency spill slot!");
@ -277,12 +278,12 @@ unsigned RegScavenger::scavengeRegister(const TargetRegisterClass *RC,
RegInfo->loadRegFromStackSlot(*MBB, I, ScavengedReg, RegInfo->loadRegFromStackSlot(*MBB, I, ScavengedReg,
ScavengingFrameIndex, ScavengedRC); ScavengingFrameIndex, ScavengedRC);
MachineBasicBlock::iterator II = prior(I); MachineBasicBlock::iterator II = prior(I);
RegInfo->eliminateFrameIndex(II, this); RegInfo->eliminateFrameIndex(II, SPAdj, this);
} }
RegInfo->storeRegToStackSlot(*MBB, I, SReg, ScavengingFrameIndex, RC); RegInfo->storeRegToStackSlot(*MBB, I, SReg, ScavengingFrameIndex, RC);
MachineBasicBlock::iterator II = prior(I); MachineBasicBlock::iterator II = prior(I);
RegInfo->eliminateFrameIndex(II, this); RegInfo->eliminateFrameIndex(II, SPAdj, this);
ScavengedReg = SReg; ScavengedReg = SReg;
ScavengedRC = RC; ScavengedRC = RC;