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:
parent
e7bd8c76db
commit
17f967eb52
@ -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?");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user