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:
parent
34f1dacd7d
commit
37f247b8d8
@ -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
|
||||
|
@ -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
|
||||
|
@ -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())
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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();
|
||||
|
@ -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.
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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,
|
||||
|
@ -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() &&
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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();
|
||||
|
@ -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; }
|
||||
};
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user