forked from OSchip/llvm-project
[X86] Move findDeadCallerSavedReg() into X86RegisterInfo
The findDeadCallerSavedReg() function has utility outside of X86FrameLowering.cpp Differential Revision: https://reviews.llvm.org/D88924
This commit is contained in:
parent
93db4a8ce6
commit
dc3dba7dbd
|
@ -148,60 +148,6 @@ static unsigned getLEArOpcode(bool IsLP64) {
|
||||||
return IsLP64 ? X86::LEA64r : X86::LEA32r;
|
return IsLP64 ? X86::LEA64r : X86::LEA32r;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// findDeadCallerSavedReg - Return a caller-saved register that isn't live
|
|
||||||
/// when it reaches the "return" instruction. We can then pop a stack object
|
|
||||||
/// to this register without worry about clobbering it.
|
|
||||||
static unsigned findDeadCallerSavedReg(MachineBasicBlock &MBB,
|
|
||||||
MachineBasicBlock::iterator &MBBI,
|
|
||||||
const X86RegisterInfo *TRI,
|
|
||||||
bool Is64Bit) {
|
|
||||||
const MachineFunction *MF = MBB.getParent();
|
|
||||||
if (MF->callsEHReturn())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
const TargetRegisterClass &AvailableRegs = *TRI->getGPRsForTailCall(*MF);
|
|
||||||
|
|
||||||
if (MBBI == MBB.end())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
switch (MBBI->getOpcode()) {
|
|
||||||
default: return 0;
|
|
||||||
case TargetOpcode::PATCHABLE_RET:
|
|
||||||
case X86::RET:
|
|
||||||
case X86::RETL:
|
|
||||||
case X86::RETQ:
|
|
||||||
case X86::RETIL:
|
|
||||||
case X86::RETIQ:
|
|
||||||
case X86::TCRETURNdi:
|
|
||||||
case X86::TCRETURNri:
|
|
||||||
case X86::TCRETURNmi:
|
|
||||||
case X86::TCRETURNdi64:
|
|
||||||
case X86::TCRETURNri64:
|
|
||||||
case X86::TCRETURNmi64:
|
|
||||||
case X86::EH_RETURN:
|
|
||||||
case X86::EH_RETURN64: {
|
|
||||||
SmallSet<uint16_t, 8> Uses;
|
|
||||||
for (unsigned i = 0, e = MBBI->getNumOperands(); i != e; ++i) {
|
|
||||||
MachineOperand &MO = MBBI->getOperand(i);
|
|
||||||
if (!MO.isReg() || MO.isDef())
|
|
||||||
continue;
|
|
||||||
Register Reg = MO.getReg();
|
|
||||||
if (!Reg)
|
|
||||||
continue;
|
|
||||||
for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI)
|
|
||||||
Uses.insert(*AI);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto CS : AvailableRegs)
|
|
||||||
if (!Uses.count(CS) && CS != X86::RIP && CS != X86::RSP &&
|
|
||||||
CS != X86::ESP)
|
|
||||||
return CS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool isEAXLiveIn(MachineBasicBlock &MBB) {
|
static bool isEAXLiveIn(MachineBasicBlock &MBB) {
|
||||||
for (MachineBasicBlock::RegisterMaskPair RegMask : MBB.liveins()) {
|
for (MachineBasicBlock::RegisterMaskPair RegMask : MBB.liveins()) {
|
||||||
unsigned Reg = RegMask.PhysReg;
|
unsigned Reg = RegMask.PhysReg;
|
||||||
|
@ -288,7 +234,7 @@ void X86FrameLowering::emitSPUpdate(MachineBasicBlock &MBB,
|
||||||
if (isSub && !isEAXLiveIn(MBB))
|
if (isSub && !isEAXLiveIn(MBB))
|
||||||
Reg = Rax;
|
Reg = Rax;
|
||||||
else
|
else
|
||||||
Reg = findDeadCallerSavedReg(MBB, MBBI, TRI, Is64Bit);
|
Reg = TRI->findDeadCallerSavedReg(MBB, MBBI);
|
||||||
|
|
||||||
unsigned MovRIOpc = Is64Bit ? X86::MOV64ri : X86::MOV32ri;
|
unsigned MovRIOpc = Is64Bit ? X86::MOV64ri : X86::MOV32ri;
|
||||||
unsigned AddSubRROpc =
|
unsigned AddSubRROpc =
|
||||||
|
@ -345,7 +291,7 @@ void X86FrameLowering::emitSPUpdate(MachineBasicBlock &MBB,
|
||||||
// need to find a dead register when using pop.
|
// need to find a dead register when using pop.
|
||||||
unsigned Reg = isSub
|
unsigned Reg = isSub
|
||||||
? (unsigned)(Is64Bit ? X86::RAX : X86::EAX)
|
? (unsigned)(Is64Bit ? X86::RAX : X86::EAX)
|
||||||
: findDeadCallerSavedReg(MBB, MBBI, TRI, Is64Bit);
|
: TRI->findDeadCallerSavedReg(MBB, MBBI);
|
||||||
if (Reg) {
|
if (Reg) {
|
||||||
unsigned Opc = isSub
|
unsigned Opc = isSub
|
||||||
? (Is64Bit ? X86::PUSH64r : X86::PUSH32r)
|
? (Is64Bit ? X86::PUSH64r : X86::PUSH32r)
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "X86Subtarget.h"
|
#include "X86Subtarget.h"
|
||||||
#include "llvm/ADT/BitVector.h"
|
#include "llvm/ADT/BitVector.h"
|
||||||
#include "llvm/ADT/STLExtras.h"
|
#include "llvm/ADT/STLExtras.h"
|
||||||
|
#include "llvm/ADT/SmallSet.h"
|
||||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||||
#include "llvm/CodeGen/MachineFunction.h"
|
#include "llvm/CodeGen/MachineFunction.h"
|
||||||
#include "llvm/CodeGen/MachineFunctionPass.h"
|
#include "llvm/CodeGen/MachineFunctionPass.h"
|
||||||
|
@ -790,6 +791,55 @@ X86RegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned X86RegisterInfo::findDeadCallerSavedReg(
|
||||||
|
MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI) const {
|
||||||
|
const MachineFunction *MF = MBB.getParent();
|
||||||
|
if (MF->callsEHReturn())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
const TargetRegisterClass &AvailableRegs = *getGPRsForTailCall(*MF);
|
||||||
|
|
||||||
|
if (MBBI == MBB.end())
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
switch (MBBI->getOpcode()) {
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
case TargetOpcode::PATCHABLE_RET:
|
||||||
|
case X86::RET:
|
||||||
|
case X86::RETL:
|
||||||
|
case X86::RETQ:
|
||||||
|
case X86::RETIL:
|
||||||
|
case X86::RETIQ:
|
||||||
|
case X86::TCRETURNdi:
|
||||||
|
case X86::TCRETURNri:
|
||||||
|
case X86::TCRETURNmi:
|
||||||
|
case X86::TCRETURNdi64:
|
||||||
|
case X86::TCRETURNri64:
|
||||||
|
case X86::TCRETURNmi64:
|
||||||
|
case X86::EH_RETURN:
|
||||||
|
case X86::EH_RETURN64: {
|
||||||
|
SmallSet<uint16_t, 8> Uses;
|
||||||
|
for (unsigned I = 0, E = MBBI->getNumOperands(); I != E; ++I) {
|
||||||
|
MachineOperand &MO = MBBI->getOperand(I);
|
||||||
|
if (!MO.isReg() || MO.isDef())
|
||||||
|
continue;
|
||||||
|
Register Reg = MO.getReg();
|
||||||
|
if (!Reg)
|
||||||
|
continue;
|
||||||
|
for (MCRegAliasIterator AI(Reg, this, true); AI.isValid(); ++AI)
|
||||||
|
Uses.insert(*AI);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto CS : AvailableRegs)
|
||||||
|
if (!Uses.count(CS) && CS != X86::RIP && CS != X86::RSP && CS != X86::ESP)
|
||||||
|
return CS;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
Register X86RegisterInfo::getFrameRegister(const MachineFunction &MF) const {
|
Register X86RegisterInfo::getFrameRegister(const MachineFunction &MF) const {
|
||||||
const X86FrameLowering *TFI = getFrameLowering(MF);
|
const X86FrameLowering *TFI = getFrameLowering(MF);
|
||||||
return TFI->hasFP(MF) ? FramePtr : StackPtr;
|
return TFI->hasFP(MF) ? FramePtr : StackPtr;
|
||||||
|
|
|
@ -128,6 +128,12 @@ public:
|
||||||
int SPAdj, unsigned FIOperandNum,
|
int SPAdj, unsigned FIOperandNum,
|
||||||
RegScavenger *RS = nullptr) const override;
|
RegScavenger *RS = nullptr) const override;
|
||||||
|
|
||||||
|
/// findDeadCallerSavedReg - Return a caller-saved register that isn't live
|
||||||
|
/// when it reaches the "return" instruction. We can then pop a stack object
|
||||||
|
/// to this register without worry about clobbering it.
|
||||||
|
unsigned findDeadCallerSavedReg(MachineBasicBlock &MBB,
|
||||||
|
MachineBasicBlock::iterator &MBBI) const;
|
||||||
|
|
||||||
// Debug information queries.
|
// Debug information queries.
|
||||||
Register getFrameRegister(const MachineFunction &MF) const override;
|
Register getFrameRegister(const MachineFunction &MF) const override;
|
||||||
unsigned getPtrSizedFrameRegister(const MachineFunction &MF) const;
|
unsigned getPtrSizedFrameRegister(const MachineFunction &MF) const;
|
||||||
|
|
Loading…
Reference in New Issue