1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 03:02:36 +01:00

Move the eliminateCallFramePseudoInstr method from TargetRegisterInfo

to TargetFrameLowering, where it belongs. Incidentally, this allows us
to delete some duplicated (and slightly different!) code in TRI.

There are potentially other layering problems that can be cleaned up
as a result, or in a similar manner.

The refactoring was OK'd by Anton Korobeynikov on llvmdev.

Note: this touches the target interfaces, so out-of-tree targets may
be affected.

llvm-svn: 175788
This commit is contained in:
Eli Bendersky 2013-02-21 20:05:00 +00:00
parent 34f1dacd7d
commit 37f247b8d8
56 changed files with 558 additions and 587 deletions

View File

@ -196,6 +196,21 @@ public:
///
virtual void processFunctionBeforeFrameFinalized(MachineFunction &MF) const {
}
/// eliminateCallFramePseudoInstr - This method is called during prolog/epilog
/// code insertion to eliminate call frame setup and destroy pseudo
/// instructions (but only if the Target is using them). It is responsible
/// for eliminating these instructions, replacing them with concrete
/// instructions. This method need only be implemented if using call frame
/// setup/destroy pseudo instructions.
///
virtual void
eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI) const {
llvm_unreachable("Call Frame Pseudo Instructions do not exist on this "
"target!");
}
};
} // End llvm namespace

View File

@ -733,21 +733,6 @@ public:
llvm_unreachable("isFrameOffsetLegal does not exist on this target");
}
/// eliminateCallFramePseudoInstr - This method is called during prolog/epilog
/// code insertion to eliminate call frame setup and destroy pseudo
/// instructions (but only if the Target is using them). It is responsible
/// for eliminating these instructions, replacing them with concrete
/// instructions. This method need only be implemented if using call frame
/// setup/destroy pseudo instructions.
///
virtual void
eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI) const {
llvm_unreachable("Call Frame Pseudo Instructions do not exist on this "
"target!");
}
/// saveScavengerRegister - Spill the register so it can be used by the
/// register scavenger. Return true if the register was spilled, false

View File

@ -139,7 +139,6 @@ bool PEI::runOnMachineFunction(MachineFunction &Fn) {
/// variables for the function's frame information and eliminate call frame
/// pseudo instructions.
void PEI::calculateCallsInformation(MachineFunction &Fn) {
const TargetRegisterInfo *RegInfo = Fn.getTarget().getRegisterInfo();
const TargetInstrInfo &TII = *Fn.getTarget().getInstrInfo();
const TargetFrameLowering *TFI = Fn.getTarget().getFrameLowering();
MachineFrameInfo *MFI = Fn.getFrameInfo();
@ -186,7 +185,7 @@ void PEI::calculateCallsInformation(MachineFunction &Fn) {
// here. The sub/add sp instruction pairs are still inserted, but we don't
// need to track the SP adjustment for frame index elimination.
if (TFI->canSimplifyCallFramePseudos(Fn))
RegInfo->eliminateCallFramePseudoInstr(Fn, *I->getParent(), I);
TFI->eliminateCallFramePseudoInstr(Fn, *I->getParent(), I);
}
}
@ -747,7 +746,7 @@ void PEI::replaceFrameIndices(MachineFunction &Fn) {
MachineBasicBlock::iterator PrevI = BB->end();
if (I != BB->begin()) PrevI = prior(I);
TRI.eliminateCallFramePseudoInstr(Fn, *BB, I);
TFI->eliminateCallFramePseudoInstr(Fn, *BB, I);
// Visit the instructions created by eliminateCallFramePseudoInstr().
if (PrevI == BB->end())

View File

@ -644,3 +644,43 @@ AArch64FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const {
// variable-sized objects that prevent reservation of a call frame.
return !(hasFP(MF) && MFI->hasVarSizedObjects());
}
void
AArch64FrameLowering::eliminateCallFramePseudoInstr(
MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI) const {
const AArch64InstrInfo &TII =
*static_cast<const AArch64InstrInfo *>(MF.getTarget().getInstrInfo());
DebugLoc dl = MI->getDebugLoc();
int Opcode = MI->getOpcode();
bool IsDestroy = Opcode == TII.getCallFrameDestroyOpcode();
uint64_t CalleePopAmount = IsDestroy ? MI->getOperand(1).getImm() : 0;
if (!hasReservedCallFrame(MF)) {
unsigned Align = getStackAlignment();
int64_t Amount = MI->getOperand(0).getImm();
Amount = RoundUpToAlignment(Amount, Align);
if (!IsDestroy) Amount = -Amount;
// N.b. if CalleePopAmount is valid but zero (i.e. callee would pop, but it
// doesn't have to pop anything), then the first operand will be zero too so
// this adjustment is a no-op.
if (CalleePopAmount == 0) {
// FIXME: in-function stack adjustment for calls is limited to 12-bits
// because there's no guaranteed temporary register available. Mostly call
// frames will be allocated at the start of a function so this is OK, but
// it is a limitation that needs dealing with.
assert(Amount > -0xfff && Amount < 0xfff && "call frame too large");
emitSPUpdate(MBB, MI, dl, TII, AArch64::NoRegister, Amount);
}
} else if (CalleePopAmount != 0) {
// If the calling convention demands that the callee pops arguments from the
// stack, we want to add it back if we have a reserved call frame.
assert(CalleePopAmount < 0xfff && "call frame too large");
emitSPUpdate(MBB, MI, dl, TII, AArch64::NoRegister, -CalleePopAmount);
}
MBB.erase(MI);
}

View File

@ -71,6 +71,10 @@ public:
const std::vector<CalleeSavedInfo> &CSI,
const TargetRegisterInfo *TRI) const;
void eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI) const;
/// If the register is X30 (i.e. LR) and the return address is used in the
/// function then the callee-save store doesn't actually kill the register,
/// otherwise it does.

View File

@ -152,44 +152,6 @@ AArch64RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator MBBI,
MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset / OffsetScale);
}
void
AArch64RegisterInfo::eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI) const {
const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
DebugLoc dl = MI->getDebugLoc();
int Opcode = MI->getOpcode();
bool IsDestroy = Opcode == TII.getCallFrameDestroyOpcode();
uint64_t CalleePopAmount = IsDestroy ? MI->getOperand(1).getImm() : 0;
if (!TFI->hasReservedCallFrame(MF)) {
unsigned Align = TFI->getStackAlignment();
int64_t Amount = MI->getOperand(0).getImm();
Amount = RoundUpToAlignment(Amount, Align);
if (!IsDestroy) Amount = -Amount;
// N.b. if CalleePopAmount is valid but zero (i.e. callee would pop, but it
// doesn't have to pop anything), then the first operand will be zero too so
// this adjustment is a no-op.
if (CalleePopAmount == 0) {
// FIXME: in-function stack adjustment for calls is limited to 12-bits
// because there's no guaranteed temporary register available. Mostly call
// frames will be allocated at the start of a function so this is OK, but
// it is a limitation that needs dealing with.
assert(Amount > -0xfff && Amount < 0xfff && "call frame too large");
emitSPUpdate(MBB, MI, dl, TII, AArch64::NoRegister, Amount);
}
} else if (CalleePopAmount != 0) {
// If the calling convention demands that the callee pops arguments from the
// stack, we want to add it back if we have a reserved call frame.
assert(CalleePopAmount < 0xfff && "call frame too large");
emitSPUpdate(MBB, MI, dl, TII, AArch64::NoRegister, -CalleePopAmount);
}
MBB.erase(MI);
}
unsigned
AArch64RegisterInfo::getFrameRegister(const MachineFunction &MF) const {
const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();

View File

@ -44,10 +44,6 @@ public:
unsigned FIOperandNum,
RegScavenger *Rs = NULL) const;
void eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI) const;
/// getCrossCopyRegClass - Returns a legal register class to copy a register
/// in the specified class to or from. Returns original class if it is
/// possible to copy between a two registers of the specified class.

View File

@ -401,64 +401,6 @@ requiresVirtualBaseRegisters(const MachineFunction &MF) const {
return true;
}
static void
emitSPUpdate(bool isARM,
MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
DebugLoc dl, const ARMBaseInstrInfo &TII,
int NumBytes,
ARMCC::CondCodes Pred = ARMCC::AL, unsigned PredReg = 0) {
if (isARM)
emitARMRegPlusImmediate(MBB, MBBI, dl, ARM::SP, ARM::SP, NumBytes,
Pred, PredReg, TII);
else
emitT2RegPlusImmediate(MBB, MBBI, dl, ARM::SP, ARM::SP, NumBytes,
Pred, PredReg, TII);
}
void ARMBaseRegisterInfo::
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
if (!TFI->hasReservedCallFrame(MF)) {
// If we have alloca, convert as follows:
// ADJCALLSTACKDOWN -> sub, sp, sp, amount
// ADJCALLSTACKUP -> add, sp, sp, amount
MachineInstr *Old = I;
DebugLoc dl = Old->getDebugLoc();
unsigned Amount = Old->getOperand(0).getImm();
if (Amount != 0) {
// We need to keep the stack aligned properly. To do this, we round the
// amount of space needed for the outgoing arguments up to the next
// alignment boundary.
unsigned Align = TFI->getStackAlignment();
Amount = (Amount+Align-1)/Align*Align;
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
assert(!AFI->isThumb1OnlyFunction() &&
"This eliminateCallFramePseudoInstr does not support Thumb1!");
bool isARM = !AFI->isThumbFunction();
// Replace the pseudo instruction with a new instruction...
unsigned Opc = Old->getOpcode();
int PIdx = Old->findFirstPredOperandIdx();
ARMCC::CondCodes Pred = (PIdx == -1)
? ARMCC::AL : (ARMCC::CondCodes)Old->getOperand(PIdx).getImm();
if (Opc == ARM::ADJCALLSTACKDOWN || Opc == ARM::tADJCALLSTACKDOWN) {
// Note: PredReg is operand 2 for ADJCALLSTACKDOWN.
unsigned PredReg = Old->getOperand(2).getReg();
emitSPUpdate(isARM, MBB, I, dl, TII, -Amount, Pred, PredReg);
} else {
// Note: PredReg is operand 3 for ADJCALLSTACKUP.
unsigned PredReg = Old->getOperand(3).getReg();
assert(Opc == ARM::ADJCALLSTACKUP || Opc == ARM::tADJCALLSTACKUP);
emitSPUpdate(isARM, MBB, I, dl, TII, Amount, Pred, PredReg);
}
}
}
MBB.erase(I);
}
int64_t ARMBaseRegisterInfo::
getFrameIndexInstrOffset(const MachineInstr *MI, int Idx) const {
const MCInstrDesc &Desc = MI->getDesc();

View File

@ -168,10 +168,6 @@ public:
virtual bool requiresVirtualBaseRegisters(const MachineFunction &MF) const;
virtual void eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const;
virtual void eliminateFrameIndex(MachineBasicBlock::iterator II,
int SPAdj, unsigned FIOperandNum,
RegScavenger *RS = NULL) const;

View File

@ -119,13 +119,14 @@ static void
emitSPUpdate(bool isARM,
MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
DebugLoc dl, const ARMBaseInstrInfo &TII,
int NumBytes, unsigned MIFlags = MachineInstr::NoFlags) {
int NumBytes, unsigned MIFlags = MachineInstr::NoFlags,
ARMCC::CondCodes Pred = ARMCC::AL, unsigned PredReg = 0) {
if (isARM)
emitARMRegPlusImmediate(MBB, MBBI, dl, ARM::SP, ARM::SP, NumBytes,
ARMCC::AL, 0, TII, MIFlags);
Pred, PredReg, TII, MIFlags);
else
emitT2RegPlusImmediate(MBB, MBBI, dl, ARM::SP, ARM::SP, NumBytes,
ARMCC::AL, 0, TII, MIFlags);
Pred, PredReg, TII, MIFlags);
}
void ARMFrameLowering::emitPrologue(MachineFunction &MF) const {
@ -1430,3 +1431,51 @@ ARMFrameLowering::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
AFI->setLRIsSpilledForFarJump(true);
}
}
void ARMFrameLowering::
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
const ARMBaseInstrInfo &TII =
*static_cast<const ARMBaseInstrInfo*>(MF.getTarget().getInstrInfo());
if (!hasReservedCallFrame(MF)) {
// If we have alloca, convert as follows:
// ADJCALLSTACKDOWN -> sub, sp, sp, amount
// ADJCALLSTACKUP -> add, sp, sp, amount
MachineInstr *Old = I;
DebugLoc dl = Old->getDebugLoc();
unsigned Amount = Old->getOperand(0).getImm();
if (Amount != 0) {
// We need to keep the stack aligned properly. To do this, we round the
// amount of space needed for the outgoing arguments up to the next
// alignment boundary.
unsigned Align = getStackAlignment();
Amount = (Amount+Align-1)/Align*Align;
ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>();
assert(!AFI->isThumb1OnlyFunction() &&
"This eliminateCallFramePseudoInstr does not support Thumb1!");
bool isARM = !AFI->isThumbFunction();
// Replace the pseudo instruction with a new instruction...
unsigned Opc = Old->getOpcode();
int PIdx = Old->findFirstPredOperandIdx();
ARMCC::CondCodes Pred = (PIdx == -1)
? ARMCC::AL : (ARMCC::CondCodes)Old->getOperand(PIdx).getImm();
if (Opc == ARM::ADJCALLSTACKDOWN || Opc == ARM::tADJCALLSTACKDOWN) {
// Note: PredReg is operand 2 for ADJCALLSTACKDOWN.
unsigned PredReg = Old->getOperand(2).getReg();
emitSPUpdate(isARM, MBB, I, dl, TII, -Amount, MachineInstr::NoFlags,
Pred, PredReg);
} else {
// Note: PredReg is operand 3 for ADJCALLSTACKUP.
unsigned PredReg = Old->getOperand(3).getReg();
assert(Opc == ARM::ADJCALLSTACKUP || Opc == ARM::tADJCALLSTACKUP);
emitSPUpdate(isARM, MBB, I, dl, TII, Amount, MachineInstr::NoFlags,
Pred, PredReg);
}
}
}
MBB.erase(I);
}

View File

@ -70,6 +70,11 @@ public:
unsigned LdrOpc, bool isVarArg, bool NoGap,
bool(*Func)(unsigned, bool),
unsigned NumAlignedDPRCS2Regs) const;
virtual void eliminateCallFramePseudoInstr(
MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI) const;
};
} // End llvm namespace

View File

@ -43,6 +43,41 @@ emitSPUpdate(MachineBasicBlock &MBB,
MRI, MIFlags);
}
void Thumb1FrameLowering::
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
const Thumb1InstrInfo &TII =
*static_cast<const Thumb1InstrInfo*>(MF.getTarget().getInstrInfo());
const Thumb1RegisterInfo *RegInfo =
static_cast<const Thumb1RegisterInfo*>(MF.getTarget().getRegisterInfo());
if (!hasReservedCallFrame(MF)) {
// If we have alloca, convert as follows:
// ADJCALLSTACKDOWN -> sub, sp, sp, amount
// ADJCALLSTACKUP -> add, sp, sp, amount
MachineInstr *Old = I;
DebugLoc dl = Old->getDebugLoc();
unsigned Amount = Old->getOperand(0).getImm();
if (Amount != 0) {
// We need to keep the stack aligned properly. To do this, we round the
// amount of space needed for the outgoing arguments up to the next
// alignment boundary.
unsigned Align = getStackAlignment();
Amount = (Amount+Align-1)/Align*Align;
// Replace the pseudo instruction with a new instruction...
unsigned Opc = Old->getOpcode();
if (Opc == ARM::ADJCALLSTACKDOWN || Opc == ARM::tADJCALLSTACKDOWN) {
emitSPUpdate(MBB, I, TII, dl, *RegInfo, -Amount);
} else {
assert(Opc == ARM::ADJCALLSTACKUP || Opc == ARM::tADJCALLSTACKUP);
emitSPUpdate(MBB, I, TII, dl, *RegInfo, Amount);
}
}
}
MBB.erase(I);
}
void Thumb1FrameLowering::emitPrologue(MachineFunction &MF) const {
MachineBasicBlock &MBB = MF.front();
MachineBasicBlock::iterator MBBI = MBB.begin();

View File

@ -45,6 +45,10 @@ public:
const TargetRegisterInfo *TRI) const;
bool hasReservedCallFrame(const MachineFunction &MF) const;
void eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI) const;
};
} // End llvm namespace

View File

@ -296,47 +296,6 @@ void llvm::emitThumbRegPlusImmediate(MachineBasicBlock &MBB,
}
}
static void emitSPUpdate(MachineBasicBlock &MBB,
MachineBasicBlock::iterator &MBBI,
const TargetInstrInfo &TII, DebugLoc dl,
const Thumb1RegisterInfo &MRI,
int NumBytes) {
emitThumbRegPlusImmediate(MBB, MBBI, dl, ARM::SP, ARM::SP, NumBytes, TII,
MRI);
}
void Thumb1RegisterInfo::
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
if (!TFI->hasReservedCallFrame(MF)) {
// If we have alloca, convert as follows:
// ADJCALLSTACKDOWN -> sub, sp, sp, amount
// ADJCALLSTACKUP -> add, sp, sp, amount
MachineInstr *Old = I;
DebugLoc dl = Old->getDebugLoc();
unsigned Amount = Old->getOperand(0).getImm();
if (Amount != 0) {
// We need to keep the stack aligned properly. To do this, we round the
// amount of space needed for the outgoing arguments up to the next
// alignment boundary.
unsigned Align = TFI->getStackAlignment();
Amount = (Amount+Align-1)/Align*Align;
// Replace the pseudo instruction with a new instruction...
unsigned Opc = Old->getOpcode();
if (Opc == ARM::ADJCALLSTACKDOWN || Opc == ARM::tADJCALLSTACKDOWN) {
emitSPUpdate(MBB, I, TII, dl, *this, -Amount);
} else {
assert(Opc == ARM::ADJCALLSTACKUP || Opc == ARM::tADJCALLSTACKUP);
emitSPUpdate(MBB, I, TII, dl, *this, Amount);
}
}
}
MBB.erase(I);
}
/// emitThumbConstant - Emit a series of instructions to materialize a
/// constant.
static void emitThumbConstant(MachineBasicBlock &MBB,

View File

@ -43,11 +43,6 @@ public:
unsigned PredReg = 0,
unsigned MIFlags = MachineInstr::NoFlags) const;
/// Code Generation virtual methods...
void eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const;
// rewrite MI to access 'Offset' bytes from the FP. Update Offset to be
// however much remains to be handled. Return 'true' if no further
// work is required.

View File

@ -327,6 +327,21 @@ bool HexagonFrameLowering::restoreCalleeSavedRegisters(
return true;
}
void HexagonFrameLowering::
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
MachineInstr &MI = *I;
if (MI.getOpcode() == Hexagon::ADJCALLSTACKDOWN) {
// Hexagon_TODO: add code
} else if (MI.getOpcode() == Hexagon::ADJCALLSTACKUP) {
// Hexagon_TODO: add code
} else {
llvm_unreachable("Cannot handle this call frame pseudo instruction");
}
MBB.erase(I);
}
int HexagonFrameLowering::getFrameIndexOffset(const MachineFunction &MF,
int FI) const {
return MF.getFrameInfo()->getObjectOffset(FI);

View File

@ -35,6 +35,11 @@ public:
MachineBasicBlock::iterator MI,
const std::vector<CalleeSavedInfo> &CSI,
const TargetRegisterInfo *TRI) const;
void eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const;
virtual bool
restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,

View File

@ -117,21 +117,6 @@ HexagonRegisterInfo::getCalleeSavedRegClasses(const MachineFunction *MF) const {
"architecture version");
}
void HexagonRegisterInfo::
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
MachineInstr &MI = *I;
if (MI.getOpcode() == Hexagon::ADJCALLSTACKDOWN) {
// Hexagon_TODO: add code
} else if (MI.getOpcode() == Hexagon::ADJCALLSTACKUP) {
// Hexagon_TODO: add code
} else {
llvm_unreachable("Cannot handle this call frame pseudo instruction");
}
MBB.erase(I);
}
void HexagonRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
int SPAdj, unsigned FIOperandNum,
RegScavenger *RS) const {

View File

@ -56,10 +56,6 @@ struct HexagonRegisterInfo : public HexagonGenRegisterInfo {
BitVector getReservedRegs(const MachineFunction &MF) const;
void eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const;
void eliminateFrameIndex(MachineBasicBlock::iterator II,
int SPAdj, unsigned FIOperandNum,
RegScavenger *RS = NULL) const;

View File

@ -426,6 +426,45 @@ void MBlazeFrameLowering::emitEpilogue(MachineFunction &MF,
}
}
// Eliminate ADJCALLSTACKDOWN/ADJCALLSTACKUP pseudo instructions
void MBlazeFrameLowering::
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
const MBlazeInstrInfo &TII =
*static_cast<const MBlazeInstrInfo*>(MF.getTarget().getInstrInfo());
if (!hasReservedCallFrame(MF)) {
// If we have a frame pointer, turn the adjcallstackup instruction into a
// 'addi r1, r1, -<amt>' and the adjcallstackdown instruction into
// 'addi r1, r1, <amt>'
MachineInstr *Old = I;
int Amount = Old->getOperand(0).getImm() + 4;
if (Amount != 0) {
// We need to keep the stack aligned properly. To do this, we round the
// amount of space needed for the outgoing arguments up to the next
// alignment boundary.
unsigned Align = getStackAlignment();
Amount = (Amount+Align-1)/Align*Align;
MachineInstr *New;
if (Old->getOpcode() == MBlaze::ADJCALLSTACKDOWN) {
New = BuildMI(MF,Old->getDebugLoc(), TII.get(MBlaze::ADDIK),MBlaze::R1)
.addReg(MBlaze::R1).addImm(-Amount);
} else {
assert(Old->getOpcode() == MBlaze::ADJCALLSTACKUP);
New = BuildMI(MF,Old->getDebugLoc(), TII.get(MBlaze::ADDIK),MBlaze::R1)
.addReg(MBlaze::R1).addImm(Amount);
}
// Replace the pseudo instruction with a new instruction...
MBB.insert(I, New);
}
}
// Simply discard ADJCALLSTACKDOWN, ADJCALLSTACKUP instructions.
MBB.erase(I);
}
void MBlazeFrameLowering::
processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
RegScavenger *RS) const {

View File

@ -39,6 +39,10 @@ public:
void emitPrologue(MachineFunction &MF) const;
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
void eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const;
bool hasFP(const MachineFunction &MF) const;
int getFrameIndexOffset(const MachineFunction &MF, int FI) const;

View File

@ -83,44 +83,6 @@ getReservedRegs(const MachineFunction &MF) const {
return Reserved;
}
// This function eliminate ADJCALLSTACKDOWN/ADJCALLSTACKUP pseudo instructions
void MBlazeRegisterInfo::
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
if (!TFI->hasReservedCallFrame(MF)) {
// If we have a frame pointer, turn the adjcallstackup instruction into a
// 'addi r1, r1, -<amt>' and the adjcallstackdown instruction into
// 'addi r1, r1, <amt>'
MachineInstr *Old = I;
int Amount = Old->getOperand(0).getImm() + 4;
if (Amount != 0) {
// We need to keep the stack aligned properly. To do this, we round the
// amount of space needed for the outgoing arguments up to the next
// alignment boundary.
unsigned Align = TFI->getStackAlignment();
Amount = (Amount+Align-1)/Align*Align;
MachineInstr *New;
if (Old->getOpcode() == MBlaze::ADJCALLSTACKDOWN) {
New = BuildMI(MF,Old->getDebugLoc(),TII.get(MBlaze::ADDIK),MBlaze::R1)
.addReg(MBlaze::R1).addImm(-Amount);
} else {
assert(Old->getOpcode() == MBlaze::ADJCALLSTACKUP);
New = BuildMI(MF,Old->getDebugLoc(),TII.get(MBlaze::ADDIK),MBlaze::R1)
.addReg(MBlaze::R1).addImm(Amount);
}
// Replace the pseudo instruction with a new instruction...
MBB.insert(I, New);
}
}
// Simply discard ADJCALLSTACKDOWN, ADJCALLSTACKUP instructions.
MBB.erase(I);
}
// FrameIndex represent objects inside a abstract stack.
// We must replace FrameIndex with an stack/frame pointer
// direct reference.

View File

@ -50,10 +50,6 @@ struct MBlazeRegisterInfo : public MBlazeGenRegisterInfo {
BitVector getReservedRegs(const MachineFunction &MF) const;
void eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const;
/// Stack Frame Processing Methods
void eliminateFrameIndex(MachineBasicBlock::iterator II,
int SPAdj, unsigned FIOperandNum,

View File

@ -222,13 +222,73 @@ MSP430FrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
return true;
}
void MSP430FrameLowering::
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
const MSP430InstrInfo &TII =
*static_cast<const MSP430InstrInfo*>(MF.getTarget().getInstrInfo());
unsigned StackAlign = getStackAlignment();
if (!hasReservedCallFrame(MF)) {
// If the stack pointer can be changed after prologue, turn the
// adjcallstackup instruction into a 'sub SPW, <amt>' and the
// adjcallstackdown instruction into 'add SPW, <amt>'
// TODO: consider using push / pop instead of sub + store / add
MachineInstr *Old = I;
uint64_t Amount = Old->getOperand(0).getImm();
if (Amount != 0) {
// We need to keep the stack aligned properly. To do this, we round the
// amount of space needed for the outgoing arguments up to the next
// alignment boundary.
Amount = (Amount+StackAlign-1)/StackAlign*StackAlign;
MachineInstr *New = 0;
if (Old->getOpcode() == TII.getCallFrameSetupOpcode()) {
New = BuildMI(MF, Old->getDebugLoc(),
TII.get(MSP430::SUB16ri), MSP430::SPW)
.addReg(MSP430::SPW).addImm(Amount);
} else {
assert(Old->getOpcode() == TII.getCallFrameDestroyOpcode());
// factor out the amount the callee already popped.
uint64_t CalleeAmt = Old->getOperand(1).getImm();
Amount -= CalleeAmt;
if (Amount)
New = BuildMI(MF, Old->getDebugLoc(),
TII.get(MSP430::ADD16ri), MSP430::SPW)
.addReg(MSP430::SPW).addImm(Amount);
}
if (New) {
// The SRW implicit def is dead.
New->getOperand(3).setIsDead();
// Replace the pseudo instruction with a new instruction...
MBB.insert(I, New);
}
}
} else if (I->getOpcode() == TII.getCallFrameDestroyOpcode()) {
// If we are performing frame pointer elimination and if the callee pops
// something off the stack pointer, add it back.
if (uint64_t CalleeAmt = I->getOperand(1).getImm()) {
MachineInstr *Old = I;
MachineInstr *New =
BuildMI(MF, Old->getDebugLoc(), TII.get(MSP430::SUB16ri),
MSP430::SPW).addReg(MSP430::SPW).addImm(CalleeAmt);
// The SRW implicit def is dead.
New->getOperand(3).setIsDead();
MBB.insert(I, New);
}
}
MBB.erase(I);
}
void
MSP430FrameLowering::processFunctionBeforeFrameFinalized(MachineFunction &MF)
const {
const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
// Create a frame entry for the FPW register that must be saved.
if (TFI->hasFP(MF)) {
if (hasFP(MF)) {
int FrameIdx = MF.getFrameInfo()->CreateFixedObject(2, -4, true);
(void)FrameIdx;
assert(FrameIdx == MF.getFrameInfo()->getObjectIndexBegin() &&

View File

@ -35,6 +35,10 @@ public:
void emitPrologue(MachineFunction &MF) const;
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
void eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const;
bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
const std::vector<CalleeSavedInfo> &CSI,

View File

@ -101,66 +101,6 @@ MSP430RegisterInfo::getPointerRegClass(const MachineFunction &MF, unsigned Kind)
return &MSP430::GR16RegClass;
}
void MSP430RegisterInfo::
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
if (!TFI->hasReservedCallFrame(MF)) {
// If the stack pointer can be changed after prologue, turn the
// adjcallstackup instruction into a 'sub SPW, <amt>' and the
// adjcallstackdown instruction into 'add SPW, <amt>'
// TODO: consider using push / pop instead of sub + store / add
MachineInstr *Old = I;
uint64_t Amount = Old->getOperand(0).getImm();
if (Amount != 0) {
// We need to keep the stack aligned properly. To do this, we round the
// amount of space needed for the outgoing arguments up to the next
// alignment boundary.
Amount = (Amount+StackAlign-1)/StackAlign*StackAlign;
MachineInstr *New = 0;
if (Old->getOpcode() == TII.getCallFrameSetupOpcode()) {
New = BuildMI(MF, Old->getDebugLoc(),
TII.get(MSP430::SUB16ri), MSP430::SPW)
.addReg(MSP430::SPW).addImm(Amount);
} else {
assert(Old->getOpcode() == TII.getCallFrameDestroyOpcode());
// factor out the amount the callee already popped.
uint64_t CalleeAmt = Old->getOperand(1).getImm();
Amount -= CalleeAmt;
if (Amount)
New = BuildMI(MF, Old->getDebugLoc(),
TII.get(MSP430::ADD16ri), MSP430::SPW)
.addReg(MSP430::SPW).addImm(Amount);
}
if (New) {
// The SRW implicit def is dead.
New->getOperand(3).setIsDead();
// Replace the pseudo instruction with a new instruction...
MBB.insert(I, New);
}
}
} else if (I->getOpcode() == TII.getCallFrameDestroyOpcode()) {
// If we are performing frame pointer elimination and if the callee pops
// something off the stack pointer, add it back.
if (uint64_t CalleeAmt = I->getOperand(1).getImm()) {
MachineInstr *Old = I;
MachineInstr *New =
BuildMI(MF, Old->getDebugLoc(), TII.get(MSP430::SUB16ri),
MSP430::SPW).addReg(MSP430::SPW).addImm(CalleeAmt);
// The SRW implicit def is dead.
New->getOperand(3).setIsDead();
MBB.insert(I, New);
}
}
MBB.erase(I);
}
void
MSP430RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
int SPAdj, unsigned FIOperandNum,

View File

@ -42,10 +42,6 @@ public:
const TargetRegisterClass*
getPointerRegClass(const MachineFunction &MF, unsigned Kind = 0) const;
void eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const;
void eliminateFrameIndex(MachineBasicBlock::iterator II,
int SPAdj, unsigned FIOperandNum,
RegScavenger *RS = NULL) const;

View File

@ -139,6 +139,25 @@ bool Mips16FrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
return true;
}
// Eliminate ADJCALLSTACKDOWN, ADJCALLSTACKUP pseudo instructions
void Mips16FrameLowering::
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
if (!hasReservedCallFrame(MF)) {
int64_t Amount = I->getOperand(0).getImm();
if (I->getOpcode() == Mips::ADJCALLSTACKDOWN)
Amount = -Amount;
const Mips16InstrInfo &TII =
*static_cast<const Mips16InstrInfo*>(MF.getTarget().getInstrInfo());
TII.adjustStackPtr(Mips::SP, Amount, MBB, I);
}
MBB.erase(I);
}
bool
Mips16FrameLowering::hasReservedCallFrame(const MachineFunction &MF) const {
const MachineFrameInfo *MFI = MF.getFrameInfo();

View File

@ -27,6 +27,10 @@ public:
void emitPrologue(MachineFunction &MF) const;
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
void eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const;
bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
const std::vector<CalleeSavedInfo> &CSI,

View File

@ -72,27 +72,6 @@ bool Mips16RegisterInfo::saveScavengerRegister
return true;
}
// This function eliminate ADJCALLSTACKDOWN,
// ADJCALLSTACKUP pseudo instructions
void Mips16RegisterInfo::
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
if (!TFI->hasReservedCallFrame(MF)) {
int64_t Amount = I->getOperand(0).getImm();
if (I->getOpcode() == Mips::ADJCALLSTACKDOWN)
Amount = -Amount;
const Mips16InstrInfo *II = static_cast<const Mips16InstrInfo*>(&TII);
II->adjustStackPtr(Mips::SP, Amount, MBB, I);
}
MBB.erase(I);
}
void Mips16RegisterInfo::eliminateFI(MachineBasicBlock::iterator II,
unsigned OpNo, int FrameIndex,
uint64_t StackSize,

View File

@ -25,10 +25,6 @@ public:
Mips16RegisterInfo(const MipsSubtarget &Subtarget,
const Mips16InstrInfo &TII);
void eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const;
bool requiresRegisterScavenging(const MachineFunction &MF) const;
bool requiresFrameIndexScavenging(const MachineFunction &MF) const;

View File

@ -249,6 +249,26 @@ MipsSEFrameLowering::hasReservedCallFrame(const MachineFunction &MF) const {
return isInt<16>(MFI->getMaxCallFrameSize()) && !MFI->hasVarSizedObjects();
}
// Eliminate ADJCALLSTACKDOWN, ADJCALLSTACKUP pseudo instructions
void MipsSEFrameLowering::
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
const MipsSEInstrInfo &TII =
*static_cast<const MipsSEInstrInfo*>(MF.getTarget().getInstrInfo());
if (!hasReservedCallFrame(MF)) {
int64_t Amount = I->getOperand(0).getImm();
if (I->getOpcode() == Mips::ADJCALLSTACKDOWN)
Amount = -Amount;
unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP;
TII.adjustStackPtr(SP, Amount, MBB, I);
}
MBB.erase(I);
}
void MipsSEFrameLowering::
processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
RegScavenger *RS) const {

View File

@ -28,6 +28,10 @@ public:
void emitPrologue(MachineFunction &MF) const;
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
void eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const;
bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
const std::vector<CalleeSavedInfo> &CSI,

View File

@ -54,28 +54,6 @@ requiresFrameIndexScavenging(const MachineFunction &MF) const {
return true;
}
// This function eliminate ADJCALLSTACKDOWN,
// ADJCALLSTACKUP pseudo instructions
void MipsSERegisterInfo::
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
if (!TFI->hasReservedCallFrame(MF)) {
int64_t Amount = I->getOperand(0).getImm();
if (I->getOpcode() == Mips::ADJCALLSTACKDOWN)
Amount = -Amount;
const MipsSEInstrInfo *II = static_cast<const MipsSEInstrInfo*>(&TII);
unsigned SP = Subtarget.isABI_N64() ? Mips::SP_64 : Mips::SP;
II->adjustStackPtr(SP, Amount, MBB, I);
}
MBB.erase(I);
}
void MipsSERegisterInfo::eliminateFI(MachineBasicBlock::iterator II,
unsigned OpNo, int FrameIndex,
uint64_t StackSize,

View File

@ -31,10 +31,6 @@ public:
bool requiresFrameIndexScavenging(const MachineFunction &MF) const;
void eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const;
private:
virtual void eliminateFI(MachineBasicBlock::iterator II, unsigned OpNo,
int FrameIndex, uint64_t StackSize,

View File

@ -74,3 +74,14 @@ void NVPTXFrameLowering::emitPrologue(MachineFunction &MF) const {
void NVPTXFrameLowering::emitEpilogue(MachineFunction &MF,
MachineBasicBlock &MBB) const {
}
// This function eliminates ADJCALLSTACKDOWN,
// ADJCALLSTACKUP pseudo instructions
void NVPTXFrameLowering::
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
// Simply discard ADJCALLSTACKDOWN,
// ADJCALLSTACKUP instructions.
MBB.erase(I);
}

View File

@ -33,6 +33,10 @@ public:
virtual void emitPrologue(MachineFunction &MF) const;
virtual void emitEpilogue(MachineFunction &MF,
MachineBasicBlock &MBB) const;
void eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const;
};
} // End llvm namespace

View File

@ -150,12 +150,3 @@ unsigned NVPTXRegisterInfo::getRARegister() const {
return 0;
}
// This function eliminates ADJCALLSTACKDOWN,
// ADJCALLSTACKUP pseudo instructions
void NVPTXRegisterInfo::
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
// Simply discard ADJCALLSTACKDOWN,
// ADJCALLSTACKUP instructions.
MBB.erase(I);
}

View File

@ -58,10 +58,6 @@ public:
int SPAdj, unsigned FIOperandNum,
RegScavenger *RS=NULL) const;
void eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const;
virtual int getDwarfRegNum(unsigned RegNum, bool isEH) const;
virtual unsigned getFrameRegister(const MachineFunction &MF) const;
virtual unsigned getRARegister() const;

View File

@ -1124,6 +1124,47 @@ restoreCRs(bool isPPC64, bool CR2Spilled, bool CR3Spilled, bool CR4Spilled,
.addReg(MoveReg));
}
void PPCFrameLowering::
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
const PPCInstrInfo &TII =
*static_cast<const PPCInstrInfo*>(MF.getTarget().getInstrInfo());
if (MF.getTarget().Options.GuaranteedTailCallOpt &&
I->getOpcode() == PPC::ADJCALLSTACKUP) {
// Add (actually subtract) back the amount the callee popped on return.
if (int CalleeAmt = I->getOperand(1).getImm()) {
bool is64Bit = Subtarget.isPPC64();
CalleeAmt *= -1;
unsigned StackReg = is64Bit ? PPC::X1 : PPC::R1;
unsigned TmpReg = is64Bit ? PPC::X0 : PPC::R0;
unsigned ADDIInstr = is64Bit ? PPC::ADDI8 : PPC::ADDI;
unsigned ADDInstr = is64Bit ? PPC::ADD8 : PPC::ADD4;
unsigned LISInstr = is64Bit ? PPC::LIS8 : PPC::LIS;
unsigned ORIInstr = is64Bit ? PPC::ORI8 : PPC::ORI;
MachineInstr *MI = I;
DebugLoc dl = MI->getDebugLoc();
if (isInt<16>(CalleeAmt)) {
BuildMI(MBB, I, dl, TII.get(ADDIInstr), StackReg)
.addReg(StackReg, RegState::Kill)
.addImm(CalleeAmt);
} else {
MachineBasicBlock::iterator MBBI = I;
BuildMI(MBB, MBBI, dl, TII.get(LISInstr), TmpReg)
.addImm(CalleeAmt >> 16);
BuildMI(MBB, MBBI, dl, TII.get(ORIInstr), TmpReg)
.addReg(TmpReg, RegState::Kill)
.addImm(CalleeAmt & 0xFFFF);
BuildMI(MBB, MBBI, dl, TII.get(ADDInstr), StackReg)
.addReg(StackReg, RegState::Kill)
.addReg(TmpReg);
}
}
}
// Simply discard ADJCALLSTACKDOWN, ADJCALLSTACKUP instructions.
MBB.erase(I);
}
bool
PPCFrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,

View File

@ -51,6 +51,10 @@ public:
const std::vector<CalleeSavedInfo> &CSI,
const TargetRegisterInfo *TRI) const;
void eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const;
bool restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI,
const std::vector<CalleeSavedInfo> &CSI,

View File

@ -3332,7 +3332,7 @@ PPCTargetLowering::FinishCall(CallingConv::ID CallConv, DebugLoc dl,
// When performing tail call optimization the callee pops its arguments off
// the stack. Account for this here so these bytes can be pushed back on in
// PPCRegisterInfo::eliminateCallFramePseudoInstr.
// PPCFrameLowering::eliminateCallFramePseudoInstr.
int BytesCalleePops =
(CallConv == CallingConv::Fast &&
getTargetMachine().Options.GuaranteedTailCallOpt) ? NumBytes : 0;

View File

@ -222,45 +222,6 @@ PPCRegisterInfo::avoidWriteAfterWrite(const TargetRegisterClass *RC) const {
// Stack Frame Processing methods
//===----------------------------------------------------------------------===//
void PPCRegisterInfo::
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
if (MF.getTarget().Options.GuaranteedTailCallOpt &&
I->getOpcode() == PPC::ADJCALLSTACKUP) {
// Add (actually subtract) back the amount the callee popped on return.
if (int CalleeAmt = I->getOperand(1).getImm()) {
bool is64Bit = Subtarget.isPPC64();
CalleeAmt *= -1;
unsigned StackReg = is64Bit ? PPC::X1 : PPC::R1;
unsigned TmpReg = is64Bit ? PPC::X0 : PPC::R0;
unsigned ADDIInstr = is64Bit ? PPC::ADDI8 : PPC::ADDI;
unsigned ADDInstr = is64Bit ? PPC::ADD8 : PPC::ADD4;
unsigned LISInstr = is64Bit ? PPC::LIS8 : PPC::LIS;
unsigned ORIInstr = is64Bit ? PPC::ORI8 : PPC::ORI;
MachineInstr *MI = I;
DebugLoc dl = MI->getDebugLoc();
if (isInt<16>(CalleeAmt)) {
BuildMI(MBB, I, dl, TII.get(ADDIInstr), StackReg)
.addReg(StackReg, RegState::Kill)
.addImm(CalleeAmt);
} else {
MachineBasicBlock::iterator MBBI = I;
BuildMI(MBB, MBBI, dl, TII.get(LISInstr), TmpReg)
.addImm(CalleeAmt >> 16);
BuildMI(MBB, MBBI, dl, TII.get(ORIInstr), TmpReg)
.addReg(TmpReg, RegState::Kill)
.addImm(CalleeAmt & 0xFFFF);
BuildMI(MBB, MBBI, dl, TII.get(ADDInstr), StackReg)
.addReg(StackReg, RegState::Kill)
.addReg(TmpReg);
}
}
}
// Simply discard ADJCALLSTACKDOWN, ADJCALLSTACKUP instructions.
MBB.erase(I);
}
/// findScratchRegister - Find a 'free' PPC register. Try for a call-clobbered
/// register first and then a spilled callee-saved register if that fails.
static

View File

@ -56,10 +56,6 @@ public:
bool trackLivenessAfterRegAlloc(const MachineFunction &MF) const;
void eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const;
void lowerDynamicAlloc(MachineBasicBlock::iterator II,
int SPAdj, RegScavenger *RS) const;
void lowerCRSpilling(MachineBasicBlock::iterator II, unsigned FrameIndex,

View File

@ -67,6 +67,22 @@ void SparcFrameLowering::emitPrologue(MachineFunction &MF) const {
}
}
void SparcFrameLowering::
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
MachineInstr &MI = *I;
DebugLoc dl = MI.getDebugLoc();
int Size = MI.getOperand(0).getImm();
if (MI.getOpcode() == SP::ADJCALLSTACKDOWN)
Size = -Size;
const SparcInstrInfo &TII =
*static_cast<const SparcInstrInfo*>(MF.getTarget().getInstrInfo());
if (Size)
BuildMI(MBB, I, dl, TII.get(SP::ADDri), SP::O6).addReg(SP::O6).addImm(Size);
MBB.erase(I);
}
void SparcFrameLowering::emitEpilogue(MachineFunction &MF,
MachineBasicBlock &MBB) const {
MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr();

View File

@ -32,6 +32,10 @@ public:
void emitPrologue(MachineFunction &MF) const;
void emitEpilogue(MachineFunction &MF, MachineBasicBlock &MBB) const;
void eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const;
bool hasFP(const MachineFunction &MF) const { return false; }
};

View File

@ -56,19 +56,6 @@ BitVector SparcRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
return Reserved;
}
void SparcRegisterInfo::
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
MachineInstr &MI = *I;
DebugLoc dl = MI.getDebugLoc();
int Size = MI.getOperand(0).getImm();
if (MI.getOpcode() == SP::ADJCALLSTACKDOWN)
Size = -Size;
if (Size)
BuildMI(MBB, I, dl, TII.get(SP::ADDri), SP::O6).addReg(SP::O6).addImm(Size);
MBB.erase(I);
}
void
SparcRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
int SPAdj, unsigned FIOperandNum,

View File

@ -36,10 +36,6 @@ struct SparcRegisterInfo : public SparcGenRegisterInfo {
BitVector getReservedRegs(const MachineFunction &MF) const;
void eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const;
void eliminateFrameIndex(MachineBasicBlock::iterator II,
int SPAdj, unsigned FIOperandNum,
RegScavenger *RS = NULL) const;

View File

@ -55,8 +55,8 @@ bool X86FrameLowering::hasFP(const MachineFunction &MF) const {
MMI.callsUnwindInit() || MMI.callsEHReturn());
}
static unsigned getSUBriOpcode(unsigned isLP64, int64_t Imm) {
if (isLP64) {
static unsigned getSUBriOpcode(unsigned IsLP64, int64_t Imm) {
if (IsLP64) {
if (isInt<8>(Imm))
return X86::SUB64ri8;
return X86::SUB64ri32;
@ -1756,3 +1756,84 @@ void X86FrameLowering::adjustForHiPEPrologue(MachineFunction &MF) const {
MF.verify();
#endif
}
void X86FrameLowering::
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
const X86InstrInfo &TII = *TM.getInstrInfo();
const X86RegisterInfo &RegInfo = *TM.getRegisterInfo();
unsigned StackPtr = RegInfo.getStackRegister();
bool reseveCallFrame = hasReservedCallFrame(MF);
int Opcode = I->getOpcode();
bool isDestroy = Opcode == TII.getCallFrameDestroyOpcode();
bool IsLP64 = STI.isTarget64BitLP64();
DebugLoc DL = I->getDebugLoc();
uint64_t Amount = !reseveCallFrame ? I->getOperand(0).getImm() : 0;
uint64_t CalleeAmt = isDestroy ? I->getOperand(1).getImm() : 0;
I = MBB.erase(I);
if (!reseveCallFrame) {
// If the stack pointer can be changed after prologue, turn the
// adjcallstackup instruction into a 'sub ESP, <amt>' and the
// adjcallstackdown instruction into 'add ESP, <amt>'
// TODO: consider using push / pop instead of sub + store / add
if (Amount == 0)
return;
// We need to keep the stack aligned properly. To do this, we round the
// amount of space needed for the outgoing arguments up to the next
// alignment boundary.
unsigned StackAlign = TM.getFrameLowering()->getStackAlignment();
Amount = (Amount + StackAlign - 1) / StackAlign * StackAlign;
MachineInstr *New = 0;
if (Opcode == TII.getCallFrameSetupOpcode()) {
New = BuildMI(MF, DL, TII.get(getSUBriOpcode(IsLP64, Amount)),
StackPtr)
.addReg(StackPtr)
.addImm(Amount);
} else {
assert(Opcode == TII.getCallFrameDestroyOpcode());
// Factor out the amount the callee already popped.
Amount -= CalleeAmt;
if (Amount) {
unsigned Opc = getADDriOpcode(IsLP64, Amount);
New = BuildMI(MF, DL, TII.get(Opc), StackPtr)
.addReg(StackPtr).addImm(Amount);
}
}
if (New) {
// The EFLAGS implicit def is dead.
New->getOperand(3).setIsDead();
// Replace the pseudo instruction with a new instruction.
MBB.insert(I, New);
}
return;
}
if (Opcode == TII.getCallFrameDestroyOpcode() && CalleeAmt) {
// If we are performing frame pointer elimination and if the callee pops
// something off the stack pointer, add it back. We do this until we have
// more advanced stack pointer tracking ability.
unsigned Opc = getSUBriOpcode(IsLP64, CalleeAmt);
MachineInstr *New = BuildMI(MF, DL, TII.get(Opc), StackPtr)
.addReg(StackPtr).addImm(CalleeAmt);
// The EFLAGS implicit def is dead.
New->getOperand(3).setIsDead();
// We are not tracking the stack pointer adjustment by the callee, so make
// sure we restore the stack pointer immediately after the call, there may
// be spill code inserted between the CALL and ADJCALLSTACKUP instructions.
MachineBasicBlock::iterator B = MBB.begin();
while (I != B && !llvm::prior(I)->isCall())
--I;
MBB.insert(I, New);
}
}

View File

@ -65,6 +65,10 @@ public:
int getFrameIndexReference(const MachineFunction &MF, int FI,
unsigned &FrameReg) const;
uint32_t getCompactUnwindEncoding(MachineFunction &MF) const;
void eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI) const;
};
} // End llvm namespace

View File

@ -447,107 +447,6 @@ bool X86RegisterInfo::hasReservedSpillSlot(const MachineFunction &MF,
return false;
}
static unsigned getSUBriOpcode(unsigned is64Bit, int64_t Imm) {
if (is64Bit) {
if (isInt<8>(Imm))
return X86::SUB64ri8;
return X86::SUB64ri32;
} else {
if (isInt<8>(Imm))
return X86::SUB32ri8;
return X86::SUB32ri;
}
}
static unsigned getADDriOpcode(unsigned is64Bit, int64_t Imm) {
if (is64Bit) {
if (isInt<8>(Imm))
return X86::ADD64ri8;
return X86::ADD64ri32;
} else {
if (isInt<8>(Imm))
return X86::ADD32ri8;
return X86::ADD32ri;
}
}
void X86RegisterInfo::
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
bool reseveCallFrame = TFI->hasReservedCallFrame(MF);
int Opcode = I->getOpcode();
bool isDestroy = Opcode == TII.getCallFrameDestroyOpcode();
DebugLoc DL = I->getDebugLoc();
uint64_t Amount = !reseveCallFrame ? I->getOperand(0).getImm() : 0;
uint64_t CalleeAmt = isDestroy ? I->getOperand(1).getImm() : 0;
I = MBB.erase(I);
if (!reseveCallFrame) {
// If the stack pointer can be changed after prologue, turn the
// adjcallstackup instruction into a 'sub ESP, <amt>' and the
// adjcallstackdown instruction into 'add ESP, <amt>'
// TODO: consider using push / pop instead of sub + store / add
if (Amount == 0)
return;
// We need to keep the stack aligned properly. To do this, we round the
// amount of space needed for the outgoing arguments up to the next
// alignment boundary.
unsigned StackAlign = TM.getFrameLowering()->getStackAlignment();
Amount = (Amount + StackAlign - 1) / StackAlign * StackAlign;
MachineInstr *New = 0;
if (Opcode == TII.getCallFrameSetupOpcode()) {
New = BuildMI(MF, DL, TII.get(getSUBriOpcode(Is64Bit, Amount)),
StackPtr)
.addReg(StackPtr)
.addImm(Amount);
} else {
assert(Opcode == TII.getCallFrameDestroyOpcode());
// Factor out the amount the callee already popped.
Amount -= CalleeAmt;
if (Amount) {
unsigned Opc = getADDriOpcode(Is64Bit, Amount);
New = BuildMI(MF, DL, TII.get(Opc), StackPtr)
.addReg(StackPtr).addImm(Amount);
}
}
if (New) {
// The EFLAGS implicit def is dead.
New->getOperand(3).setIsDead();
// Replace the pseudo instruction with a new instruction.
MBB.insert(I, New);
}
return;
}
if (Opcode == TII.getCallFrameDestroyOpcode() && CalleeAmt) {
// If we are performing frame pointer elimination and if the callee pops
// something off the stack pointer, add it back. We do this until we have
// more advanced stack pointer tracking ability.
unsigned Opc = getSUBriOpcode(Is64Bit, CalleeAmt);
MachineInstr *New = BuildMI(MF, DL, TII.get(Opc), StackPtr)
.addReg(StackPtr).addImm(CalleeAmt);
// The EFLAGS implicit def is dead.
New->getOperand(3).setIsDead();
// We are not tracking the stack pointer adjustment by the callee, so make
// sure we restore the stack pointer immediately after the call, there may
// be spill code inserted between the CALL and ADJCALLSTACKUP instructions.
MachineBasicBlock::iterator B = MBB.begin();
while (I != B && !llvm::prior(I)->isCall())
--I;
MBB.insert(I, New);
}
}
void
X86RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
int SPAdj, unsigned FIOperandNum,

View File

@ -117,10 +117,6 @@ public:
bool hasReservedSpillSlot(const MachineFunction &MF, unsigned Reg,
int &FrameIdx) const;
void eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator MI) const;
void eliminateFrameIndex(MachineBasicBlock::iterator MI,
int SPAdj, unsigned FIOperandNum,
RegScavenger *RS = NULL) const;

View File

@ -332,6 +332,58 @@ bool XCoreFrameLowering::restoreCalleeSavedRegisters(MachineBasicBlock &MBB,
return true;
}
// This function eliminates ADJCALLSTACKDOWN,
// ADJCALLSTACKUP pseudo instructions
void XCoreFrameLowering::
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
const XCoreInstrInfo &TII =
*static_cast<const XCoreInstrInfo*>(MF.getTarget().getInstrInfo());
if (!hasReservedCallFrame(MF)) {
// Turn the adjcallstackdown instruction into 'extsp <amt>' and the
// adjcallstackup instruction into 'ldaw sp, sp[<amt>]'
MachineInstr *Old = I;
uint64_t Amount = Old->getOperand(0).getImm();
if (Amount != 0) {
// We need to keep the stack aligned properly. To do this, we round the
// amount of space needed for the outgoing arguments up to the next
// alignment boundary.
unsigned Align = getStackAlignment();
Amount = (Amount+Align-1)/Align*Align;
assert(Amount%4 == 0);
Amount /= 4;
bool isU6 = isImmU6(Amount);
if (!isU6 && !isImmU16(Amount)) {
// FIX could emit multiple instructions in this case.
#ifndef NDEBUG
errs() << "eliminateCallFramePseudoInstr size too big: "
<< Amount << "\n";
#endif
llvm_unreachable(0);
}
MachineInstr *New;
if (Old->getOpcode() == XCore::ADJCALLSTACKDOWN) {
int Opcode = isU6 ? XCore::EXTSP_u6 : XCore::EXTSP_lu6;
New=BuildMI(MF, Old->getDebugLoc(), TII.get(Opcode))
.addImm(Amount);
} else {
assert(Old->getOpcode() == XCore::ADJCALLSTACKUP);
int Opcode = isU6 ? XCore::LDAWSP_ru6_RRegs : XCore::LDAWSP_lru6_RRegs;
New=BuildMI(MF, Old->getDebugLoc(), TII.get(Opcode), XCore::SP)
.addImm(Amount);
}
// Replace the pseudo instruction with a new instruction...
MBB.insert(I, New);
}
}
MBB.erase(I);
}
void
XCoreFrameLowering::processFunctionBeforeCalleeSavedScan(MachineFunction &MF,
RegScavenger *RS) const {

View File

@ -39,6 +39,10 @@ namespace llvm {
const std::vector<CalleeSavedInfo> &CSI,
const TargetRegisterInfo *TRI) const;
void eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const;
bool hasFP(const MachineFunction &MF) const;
void processFunctionBeforeCalleeSavedScan(MachineFunction &MF,

View File

@ -101,58 +101,6 @@ XCoreRegisterInfo::useFPForScavengingIndex(const MachineFunction &MF) const {
return false;
}
// This function eliminates ADJCALLSTACKDOWN,
// ADJCALLSTACKUP pseudo instructions
void XCoreRegisterInfo::
eliminateCallFramePseudoInstr(MachineFunction &MF, MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const {
const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering();
if (!TFI->hasReservedCallFrame(MF)) {
// Turn the adjcallstackdown instruction into 'extsp <amt>' and the
// adjcallstackup instruction into 'ldaw sp, sp[<amt>]'
MachineInstr *Old = I;
uint64_t Amount = Old->getOperand(0).getImm();
if (Amount != 0) {
// We need to keep the stack aligned properly. To do this, we round the
// amount of space needed for the outgoing arguments up to the next
// alignment boundary.
unsigned Align = TFI->getStackAlignment();
Amount = (Amount+Align-1)/Align*Align;
assert(Amount%4 == 0);
Amount /= 4;
bool isU6 = isImmU6(Amount);
if (!isU6 && !isImmU16(Amount)) {
// FIX could emit multiple instructions in this case.
#ifndef NDEBUG
errs() << "eliminateCallFramePseudoInstr size too big: "
<< Amount << "\n";
#endif
llvm_unreachable(0);
}
MachineInstr *New;
if (Old->getOpcode() == XCore::ADJCALLSTACKDOWN) {
int Opcode = isU6 ? XCore::EXTSP_u6 : XCore::EXTSP_lu6;
New=BuildMI(MF, Old->getDebugLoc(), TII.get(Opcode))
.addImm(Amount);
} else {
assert(Old->getOpcode() == XCore::ADJCALLSTACKUP);
int Opcode = isU6 ? XCore::LDAWSP_ru6_RRegs : XCore::LDAWSP_lru6_RRegs;
New=BuildMI(MF, Old->getDebugLoc(), TII.get(Opcode), XCore::SP)
.addImm(Amount);
}
// Replace the pseudo instruction with a new instruction...
MBB.insert(I, New);
}
}
MBB.erase(I);
}
void
XCoreRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
int SPAdj, unsigned FIOperandNum,

View File

@ -54,10 +54,6 @@ public:
bool useFPForScavengingIndex(const MachineFunction &MF) const;
void eliminateCallFramePseudoInstr(MachineFunction &MF,
MachineBasicBlock &MBB,
MachineBasicBlock::iterator I) const;
void eliminateFrameIndex(MachineBasicBlock::iterator II,
int SPAdj, unsigned FIOperandNum,
RegScavenger *RS = NULL) const;