78 #define DEBUG_TYPE "shrink-wrap"
82 STATISTIC(NumFunc,
"Number of functions");
83 STATISTIC(NumCandidates,
"Number of shrink-wrapping candidates");
85 "Number of shrink-wrapping candidates dropped because of frequency");
89 cl::desc(
"enable the shrink-wrapping pass"));
121 unsigned FrameSetupOpcode;
123 unsigned FrameDestroyOpcode;
128 mutable SetOfRegs CurrentCSRs;
137 const SetOfRegs &getCurrentCSRs(
RegScavenger *RS)
const {
138 if (CurrentCSRs.empty()) {
141 MachineFunc->getSubtarget().getFrameLowering();
147 CurrentCSRs.insert((
unsigned)
Reg);
161 RCI.runOnMachineFunction(MF);
162 MDT = &getAnalysis<MachineDominatorTree>();
163 MPDT = &getAnalysis<MachinePostDominatorTree>();
166 MBFI = &getAnalysis<MachineBlockFrequencyInfo>();
167 MLI = &getAnalysis<MachineLoopInfo>();
168 EntryFreq = MBFI->getEntryFreq();
181 bool ArePointsInteresting()
const {
return Save != Entry && Save && Restore; }
202 StringRef getPassName()
const override {
return "Shrink Wrapping analysis"; }
223 if (MI.getOpcode() == FrameSetupOpcode ||
224 MI.getOpcode() == FrameDestroyOpcode) {
225 DEBUG(
dbgs() <<
"Frame instruction: " << MI <<
'\n');
229 bool UseOrDefCSR =
false;
231 unsigned PhysReg = MO.getReg();
235 "Unallocated register?!");
236 UseOrDefCSR = RCI.getLastCalleeSavedAlias(PhysReg);
237 }
else if (MO.isRegMask()) {
239 for (
unsigned Reg : getCurrentCSRs(RS)) {
240 if (MO.clobbersPhysReg(
Reg)) {
246 if (UseOrDefCSR || MO.isFI()) {
247 DEBUG(
dbgs() <<
"Use or define CSR(" << UseOrDefCSR <<
") or FI("
248 << MO.isFI() <<
"): " << MI <<
'\n');
256 template <
typename ListOfBBs,
typename DominanceAnalysis>
258 DominanceAnalysis &Dom) {
261 IDom = Dom.findNearestCommonDominator(IDom, BB);
276 Save = MDT->findNearestCommonDominator(Save, &MBB);
279 DEBUG(
dbgs() <<
"Found a block that is not reachable from Entry\n");
286 Restore = MPDT->findNearestCommonDominator(Restore, &MBB);
290 if (Restore == &MBB) {
301 Restore = FindIDom<>(*Restore, Restore->successors(), *MPDT);
307 DEBUG(
dbgs() <<
"Restore point needs to be spanned on several blocks\n");
318 bool SaveDominatesRestore =
false;
319 bool RestorePostDominatesSave =
false;
320 while (Save && Restore &&
321 (!(SaveDominatesRestore = MDT->dominates(Save, Restore)) ||
322 !(RestorePostDominatesSave = MPDT->dominates(Restore, Save)) ||
340 MLI->getLoopFor(Save) || MLI->getLoopFor(Restore))) {
342 if (!SaveDominatesRestore) {
343 Save = MDT->findNearestCommonDominator(Save, Restore);
347 if (!RestorePostDominatesSave)
348 Restore = MPDT->findNearestCommonDominator(Restore, Save);
351 if (Save && Restore &&
352 (MLI->getLoopFor(Save) || MLI->getLoopFor(Restore))) {
353 if (MLI->getLoopDepth(Save) > MLI->getLoopDepth(Restore)) {
356 Save = FindIDom<>(*Save, Save->predecessors(), *MDT);
363 MLI->getLoopFor(Restore)->getExitingBlocks(ExitBlocks);
368 IPdom = FindIDom<>(*IPdom, LoopExitBB->
successors(), *MPDT);
375 if (IPdom && MLI->getLoopDepth(IPdom) < MLI->getLoopDepth(Restore))
409 if (!VisitedBB.test(SuccBB->getNumber()))
422 if (MF.
empty() || !isShrinkWrapEnabled(MF))
436 DEBUG(
dbgs() <<
"Irreducible CFGs are not supported yet\n");
441 std::unique_ptr<RegScavenger> RS(
449 DEBUG(
dbgs() <<
"EH Funclets are not supported yet.\n");
454 if (!useOrDefCSROrFI(MI, RS.get()))
458 updateSaveRestorePoints(MBB, RS.get());
461 if (!ArePointsInteresting()) {
462 DEBUG(
dbgs() <<
"No Shrink wrap candidate found\n");
470 if (!ArePointsInteresting()) {
474 assert(!Save && !Restore &&
"We miss a shrink-wrap opportunity?!");
475 DEBUG(
dbgs() <<
"Nothing to shrink-wrap\n");
479 DEBUG(
dbgs() <<
"\n ** Results **\nFrequency of the Entry: " << EntryFreq
484 DEBUG(
dbgs() <<
"Shrink wrap candidates (#, Name, Freq):\nSave: "
485 << Save->getNumber() <<
' ' << Save->getName() <<
' '
486 << MBFI->getBlockFreq(Save).getFrequency() <<
"\nRestore: "
487 << Restore->getNumber() <<
' ' << Restore->getName() <<
' '
488 << MBFI->getBlockFreq(Restore).getFrequency() <<
'\n');
490 bool IsSaveCheap, TargetCanUseSaveAsPrologue =
false;
491 if (((IsSaveCheap = EntryFreq >= MBFI->getBlockFreq(Save).getFrequency()) &&
492 EntryFreq >= MBFI->getBlockFreq(Restore).getFrequency()) &&
496 DEBUG(
dbgs() <<
"New points are too expensive or invalid for the target\n");
498 if (!IsSaveCheap || !TargetCanUseSaveAsPrologue) {
499 Save = FindIDom<>(*Save, Save->predecessors(), *MDT);
505 Restore = FindIDom<>(*Restore, Restore->successors(), *MPDT);
510 updateSaveRestorePoints(*NewBB, RS.get());
511 }
while (Save && Restore);
513 if (!ArePointsInteresting()) {
514 ++NumCandidatesDropped;
518 DEBUG(
dbgs() <<
"Final shrink wrap candidates:\nSave: " << Save->getNumber()
519 <<
' ' << Save->getName() <<
"\nRestore: "
520 << Restore->getNumber() <<
' ' << Restore->getName() <<
'\n');
524 MFI.setRestorePoint(Restore);
Pass interface - Implemented by all 'passes'.
static bool isIrreducibleCFG(const MachineFunction &MF, const MachineLoopInfo &MLI)
Check if the CFG of MF is irreducible.
void setSavePoint(MachineBasicBlock *NewSave)
int find_first() const
find_first - Returns the index of the first set bit, -1 if none of the bits are set.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
STATISTIC(NumFunctions,"Total number of functions")
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
int find_next(unsigned Prev) const
find_next - Returns the index of the next set bit following the "Prev" bit.
virtual bool canUseAsEpilogue(const MachineBasicBlock &MBB) const
Check whether or not the given MBB can be used as a epilogue for the target.
MachineBlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate machine basic b...
LoopT * getParentLoop() const
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
static bool isProperBackedge(const MachineLoopInfo &MLI, const MachineBasicBlock *SrcBB, const MachineBasicBlock *DestBB)
Check whether the edge (SrcBB, DestBB) is a backedge according to MLI.
BlockT * getHeader() const
iterator_range< succ_iterator > successors()
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
unsigned getCallFrameDestroyOpcode() const
unsigned getNumBlockIDs() const
getNumBlockIDs - Return the number of MBB ID's allocated.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
const MCAsmInfo * getMCAsmInfo() const
Return target specific asm information.
Reg
All possible values of the reg field in the ModR/M byte.
iterator_range< iterator > terminators()
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
virtual bool canUseAsPrologue(const MachineBasicBlock &MBB) const
Check whether or not the given MBB can be used as a prologue for the target.
const MachineBasicBlock & front() const
unsigned getCallFrameSetupOpcode() const
These methods return the opcode of the frame setup/destroy instructions if they exist (-1 otherwise)...
virtual bool requiresRegisterScavenging(const MachineFunction &MF) const
Returns true if the target requires (and can make use of) the register scavenger. ...
TargetInstrInfo - Interface to description of machine instruction set.
INITIALIZE_PASS_BEGIN(ShrinkWrap,"shrink-wrap","Shrink Wrap Pass", false, false) bool ShrinkWrap
MachineLoop * getLoopFor(const MachineBasicBlock *BB) const
Return the innermost loop that BB lives in.
initializer< Ty > init(const Ty &Val)
This file declares the machine register scavenger class.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
static cl::opt< cl::boolOrDefault > EnableShrinkWrapOpt("enable-shrink-wrap", cl::Hidden, cl::desc("enable the shrink-wrapping pass"))
Represent the analysis usage information of a pass.
bool isEHFuncletEntry() const
Returns true if this is the entry block of an EH funclet.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE,"Assign register bank of generic virtual registers", false, false) RegBankSelect
void initializeShrinkWrapPass(PassRegistry &)
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
static MachineBasicBlock * FindIDom(MachineBasicBlock &Block, ListOfBBs BBs, DominanceAnalysis &Dom)
Helper function to find the immediate (post) dominator.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
virtual void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
virtual const TargetFrameLowering * getFrameLowering() const
A SetVector that performs no allocations if smaller than a certain size.
PostDominatorTree Class - Concrete subclass of DominatorTree that is used to compute the post-dominat...
MachineOperand class - Representation of each machine instruction operand.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Information about stack frame layout on the target.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
StringRef getName() const
Return the name of the corresponding LLVM basic block, or "(null)".
void setPreservesAll()
Set by analyses that do not transform their input at all.
Representation of each machine instruction.
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
LLVMAttributeRef wrap(Attribute Attr)
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Represents a single loop in the control flow graph.
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
virtual bool enableShrinkWrapping(const MachineFunction &MF) const
Returns true if the target will correctly handle shrink wrapping.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
virtual const TargetInstrInfo * getInstrInfo() const
char & ShrinkWrapID
ShrinkWrap pass. Look for the best place to insert save and restore.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
StringRef - Represent a constant reference to a string, i.e.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
bool usesWindowsCFI() const