mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-25 23:00:15 +00:00
MachineFrameInfo: Simplify pristine register calculation.
About pristine regsiters: Pristine registers "hold a value that is useless to the current function, but that must be preserved - they are callee saved registers that have not been saved." This concept saves compile time as it frees the prologue/epilogue inserter from adding every such register to every basic blocks live-in list. However the current code in getPristineRegs is formulated in a complicated way: Inside the function prologue and epilogue all callee saves are considered pristine, while in the rest of the code only the non-saved ones are considered pristine. This requires logic to differentiate between prologue/epilogue and the rest and in the presence of shrink-wrapping this even becomes complicated/expensive. It's also unnecessary because the prologue epilogue inserters already mark callee-save registers that are saved/restores properly in the respective blocks in the prologue/epilogue (see updateLiveness() in PrologueEpilogueInserter.cpp). So only declaring non-saved/restored callee saved registers as pristine just works. Differential Revision: http://reviews.llvm.org/D10101 llvm-svn: 238524
This commit is contained in:
parent
536f0a95e5
commit
111f5d88fb
@ -256,11 +256,6 @@ class MachineFrameInfo {
|
|||||||
/// Not null, if shrink-wrapping found a better place for the epilogue.
|
/// Not null, if shrink-wrapping found a better place for the epilogue.
|
||||||
MachineBasicBlock *Restore;
|
MachineBasicBlock *Restore;
|
||||||
|
|
||||||
/// Check if it exists a path from \p MBB leading to the basic
|
|
||||||
/// block with a SavePoint (a.k.a. prologue).
|
|
||||||
bool isBeforeSavePoint(const MachineFunction &MF,
|
|
||||||
const MachineBasicBlock &MBB) const;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit MachineFrameInfo(unsigned StackAlign, bool isStackRealign,
|
explicit MachineFrameInfo(unsigned StackAlign, bool isStackRealign,
|
||||||
bool RealignOpt)
|
bool RealignOpt)
|
||||||
@ -627,16 +622,15 @@ public:
|
|||||||
MachineBasicBlock *getRestorePoint() const { return Restore; }
|
MachineBasicBlock *getRestorePoint() const { return Restore; }
|
||||||
void setRestorePoint(MachineBasicBlock *NewRestore) { Restore = NewRestore; }
|
void setRestorePoint(MachineBasicBlock *NewRestore) { Restore = NewRestore; }
|
||||||
|
|
||||||
/// getPristineRegs - Return a set of physical registers that are pristine on
|
/// Return a set of physical registers that are pristine.
|
||||||
/// entry to the MBB.
|
|
||||||
///
|
///
|
||||||
/// Pristine registers hold a value that is useless to the current function,
|
/// Pristine registers hold a value that is useless to the current function,
|
||||||
/// but that must be preserved - they are callee saved registers that have not
|
/// but that must be preserved - they are callee saved registers that are not
|
||||||
/// been saved yet.
|
/// saved.
|
||||||
///
|
///
|
||||||
/// Before the PrologueEpilogueInserter has placed the CSR spill code, this
|
/// Before the PrologueEpilogueInserter has placed the CSR spill code, this
|
||||||
/// method always returns an empty set.
|
/// method always returns an empty set.
|
||||||
BitVector getPristineRegs(const MachineBasicBlock *MBB) const;
|
BitVector getPristineRegs(const MachineFunction &MF) const;
|
||||||
|
|
||||||
/// print - Used by the MachineFunction printer to print information about
|
/// print - Used by the MachineFunction printer to print information about
|
||||||
/// stack objects. Implemented in MachineFunction.cpp
|
/// stack objects. Implemented in MachineFunction.cpp
|
||||||
|
@ -163,7 +163,7 @@ void AggressiveAntiDepBreaker::StartBlock(MachineBasicBlock *BB) {
|
|||||||
// all callee-saved registers. In non-return this is any
|
// all callee-saved registers. In non-return this is any
|
||||||
// callee-saved register that is not saved in the prolog.
|
// callee-saved register that is not saved in the prolog.
|
||||||
const MachineFrameInfo *MFI = MF.getFrameInfo();
|
const MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||||
BitVector Pristine = MFI->getPristineRegs(BB);
|
BitVector Pristine = MFI->getPristineRegs(MF);
|
||||||
for (const MCPhysReg *I = TRI->getCalleeSavedRegs(&MF); *I; ++I) {
|
for (const MCPhysReg *I = TRI->getCalleeSavedRegs(&MF); *I; ++I) {
|
||||||
unsigned Reg = *I;
|
unsigned Reg = *I;
|
||||||
if (!IsReturnBlock && !Pristine.test(Reg)) continue;
|
if (!IsReturnBlock && !Pristine.test(Reg)) continue;
|
||||||
|
@ -71,7 +71,7 @@ void CriticalAntiDepBreaker::StartBlock(MachineBasicBlock *BB) {
|
|||||||
// all callee-saved registers. In non-return this is any
|
// all callee-saved registers. In non-return this is any
|
||||||
// callee-saved register that is not saved in the prolog.
|
// callee-saved register that is not saved in the prolog.
|
||||||
const MachineFrameInfo *MFI = MF.getFrameInfo();
|
const MachineFrameInfo *MFI = MF.getFrameInfo();
|
||||||
BitVector Pristine = MFI->getPristineRegs(BB);
|
BitVector Pristine = MFI->getPristineRegs(MF);
|
||||||
for (const MCPhysReg *I = TRI->getCalleeSavedRegs(&MF); *I; ++I) {
|
for (const MCPhysReg *I = TRI->getCalleeSavedRegs(&MF); *I; ++I) {
|
||||||
if (!IsReturnBlock && !Pristine.test(*I)) continue;
|
if (!IsReturnBlock && !Pristine.test(*I)) continue;
|
||||||
for (MCRegAliasIterator AI(*I, TRI, true); AI.isValid(); ++AI) {
|
for (MCRegAliasIterator AI(*I, TRI, true); AI.isValid(); ++AI) {
|
||||||
|
@ -584,12 +584,8 @@ int MachineFrameInfo::CreateFixedSpillStackObject(uint64_t Size,
|
|||||||
return -++NumFixedObjects;
|
return -++NumFixedObjects;
|
||||||
}
|
}
|
||||||
|
|
||||||
BitVector
|
BitVector MachineFrameInfo::getPristineRegs(const MachineFunction &MF) const {
|
||||||
MachineFrameInfo::getPristineRegs(const MachineBasicBlock *MBB) const {
|
const TargetRegisterInfo *TRI = MF.getSubtarget().getRegisterInfo();
|
||||||
assert(MBB && "MBB must be valid");
|
|
||||||
const MachineFunction *MF = MBB->getParent();
|
|
||||||
assert(MF && "MBB must be part of a MachineFunction");
|
|
||||||
const TargetRegisterInfo *TRI = MF->getSubtarget().getRegisterInfo();
|
|
||||||
BitVector BV(TRI->getNumRegs());
|
BitVector BV(TRI->getNumRegs());
|
||||||
|
|
||||||
// Before CSI is calculated, no registers are considered pristine. They can be
|
// Before CSI is calculated, no registers are considered pristine. They can be
|
||||||
@ -597,14 +593,10 @@ MachineFrameInfo::getPristineRegs(const MachineBasicBlock *MBB) const {
|
|||||||
if (!isCalleeSavedInfoValid())
|
if (!isCalleeSavedInfoValid())
|
||||||
return BV;
|
return BV;
|
||||||
|
|
||||||
for (const MCPhysReg *CSR = TRI->getCalleeSavedRegs(MF); CSR && *CSR; ++CSR)
|
for (const MCPhysReg *CSR = TRI->getCalleeSavedRegs(&MF); CSR && *CSR; ++CSR)
|
||||||
BV.set(*CSR);
|
BV.set(*CSR);
|
||||||
|
|
||||||
// Each MBB before the save point has all CSRs pristine.
|
// Saved CSRs are not pristine.
|
||||||
if (isBeforeSavePoint(*MF, *MBB))
|
|
||||||
return BV;
|
|
||||||
|
|
||||||
// On other MBBs the saved CSRs are not pristine.
|
|
||||||
const std::vector<CalleeSavedInfo> &CSI = getCalleeSavedInfo();
|
const std::vector<CalleeSavedInfo> &CSI = getCalleeSavedInfo();
|
||||||
for (std::vector<CalleeSavedInfo>::const_iterator I = CSI.begin(),
|
for (std::vector<CalleeSavedInfo>::const_iterator I = CSI.begin(),
|
||||||
E = CSI.end(); I != E; ++I)
|
E = CSI.end(); I != E; ++I)
|
||||||
@ -613,40 +605,6 @@ MachineFrameInfo::getPristineRegs(const MachineBasicBlock *MBB) const {
|
|||||||
return BV;
|
return BV;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: We could use some sort of caching mecanism, but we lack the ability
|
|
||||||
// to know when the cache is invalid, i.e., the CFG changed.
|
|
||||||
// Assuming we have that, we can simply compute all the set of MBBs
|
|
||||||
// that are before the save point.
|
|
||||||
bool MachineFrameInfo::isBeforeSavePoint(const MachineFunction &MF,
|
|
||||||
const MachineBasicBlock &MBB) const {
|
|
||||||
// Early exit if shrink-wrapping did not kick.
|
|
||||||
if (!Save)
|
|
||||||
return &MBB == &MF.front();
|
|
||||||
|
|
||||||
// Starting from MBB, check if there is a path leading to Save that do
|
|
||||||
// not cross Restore.
|
|
||||||
SmallPtrSet<const MachineBasicBlock *, 8> Visited;
|
|
||||||
SmallVector<const MachineBasicBlock *, 8> WorkList;
|
|
||||||
WorkList.push_back(&MBB);
|
|
||||||
Visited.insert(&MBB);
|
|
||||||
do {
|
|
||||||
const MachineBasicBlock *CurBB = WorkList.pop_back_val();
|
|
||||||
// By construction, the region that is after the save point is
|
|
||||||
// dominated by the Save and post-dominated by the Restore.
|
|
||||||
// If we do not reach Restore and still reach Save, this
|
|
||||||
// means MBB is before Save.
|
|
||||||
if (CurBB == Save)
|
|
||||||
return true;
|
|
||||||
if (CurBB == Restore)
|
|
||||||
continue;
|
|
||||||
// Enqueue all the successors not already visited.
|
|
||||||
for (MachineBasicBlock *SuccBB : CurBB->successors())
|
|
||||||
if (Visited.insert(SuccBB).second)
|
|
||||||
WorkList.push_back(SuccBB);
|
|
||||||
} while (!WorkList.empty());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned MachineFrameInfo::estimateStackSize(const MachineFunction &MF) const {
|
unsigned MachineFrameInfo::estimateStackSize(const MachineFunction &MF) const {
|
||||||
const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
|
const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
|
||||||
const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
|
const TargetRegisterInfo *RegInfo = MF.getSubtarget().getRegisterInfo();
|
||||||
|
@ -694,7 +694,7 @@ MachineVerifier::visitMachineBasicBlockBefore(const MachineBasicBlock *MBB) {
|
|||||||
|
|
||||||
const MachineFrameInfo *MFI = MF->getFrameInfo();
|
const MachineFrameInfo *MFI = MF->getFrameInfo();
|
||||||
assert(MFI && "Function has no frame info");
|
assert(MFI && "Function has no frame info");
|
||||||
BitVector PR = MFI->getPristineRegs(MBB);
|
BitVector PR = MFI->getPristineRegs(*MF);
|
||||||
for (int I = PR.find_first(); I>0; I = PR.find_next(I)) {
|
for (int I = PR.find_first(); I>0; I = PR.find_next(I)) {
|
||||||
for (MCSubRegIterator SubRegs(I, TRI, /*IncludeSelf=*/true);
|
for (MCSubRegIterator SubRegs(I, TRI, /*IncludeSelf=*/true);
|
||||||
SubRegs.isValid(); ++SubRegs)
|
SubRegs.isValid(); ++SubRegs)
|
||||||
|
@ -55,7 +55,8 @@ void RegScavenger::initRegState() {
|
|||||||
setRegUsed(*I);
|
setRegUsed(*I);
|
||||||
|
|
||||||
// Pristine CSRs are also unavailable.
|
// Pristine CSRs are also unavailable.
|
||||||
BitVector PR = MBB->getParent()->getFrameInfo()->getPristineRegs(MBB);
|
const MachineFunction &MF = *MBB->getParent();
|
||||||
|
BitVector PR = MF.getFrameInfo()->getPristineRegs(MF);
|
||||||
for (int I = PR.find_first(); I>0; I = PR.find_next(I))
|
for (int I = PR.find_first(); I>0; I = PR.find_next(I))
|
||||||
setRegUsed(I);
|
setRegUsed(I);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user