72 #define DEBUG_TYPE "shrink-wrap"
76 STATISTIC(NumFunc,
"Number of functions");
77 STATISTIC(NumCandidates,
"Number of shrink-wrapping candidates");
79 "Number of shrink-wrapping candidates dropped because of frequency");
111 unsigned FrameSetupOpcode;
113 unsigned FrameDestroyOpcode;
131 RCI.runOnMachineFunction(MF);
132 MDT = &getAnalysis<MachineDominatorTree>();
133 MPDT = &getAnalysis<MachinePostDominatorTree>();
136 MBFI = &getAnalysis<MachineBlockFrequencyInfo>();
137 MLI = &getAnalysis<MachineLoopInfo>();
138 EntryFreq = MBFI->getEntryFreq();
149 bool ArePointsInteresting()
const {
return Save != Entry && Save && Restore; }
167 const char *getPassName()
const override {
168 return "Shrink Wrapping analysis";
189 if (MI.getOpcode() == FrameSetupOpcode ||
190 MI.getOpcode() == FrameDestroyOpcode) {
191 DEBUG(
dbgs() <<
"Frame instruction: " << MI <<
'\n');
197 unsigned PhysReg = MO.getReg();
201 "Unallocated register?!");
202 UseCSR = RCI.getLastCalleeSavedAlias(PhysReg);
206 if (UseCSR || MO.isFI() || MO.isRegMask()) {
207 DEBUG(
dbgs() <<
"Use or define CSR(" << UseCSR <<
") or FI(" << MO.isFI()
208 <<
"): " << MI <<
'\n');
216 template <
typename ListOfBBs,
typename DominanceAnalysis>
218 DominanceAnalysis &Dom) {
221 IDom = Dom.findNearestCommonDominator(IDom, BB);
233 Save = MDT->findNearestCommonDominator(Save, &MBB);
236 DEBUG(
dbgs() <<
"Found a block that is not reachable from Entry\n");
243 Restore = MPDT->findNearestCommonDominator(Restore, &MBB);
247 if (Restore == &MBB) {
258 Restore = FindIDom<>(*Restore, Restore->successors(), *MPDT);
264 DEBUG(
dbgs() <<
"Restore point needs to be spanned on several blocks\n");
275 bool SaveDominatesRestore =
false;
276 bool RestorePostDominatesSave =
false;
277 while (Save && Restore &&
278 (!(SaveDominatesRestore = MDT->dominates(Save, Restore)) ||
279 !(RestorePostDominatesSave = MPDT->dominates(Restore, Save)) ||
280 MLI->getLoopFor(Save) != MLI->getLoopFor(Restore))) {
282 if (!SaveDominatesRestore) {
283 Save = MDT->findNearestCommonDominator(Save, Restore);
287 if (!RestorePostDominatesSave)
288 Restore = MPDT->findNearestCommonDominator(Restore, Save);
291 if (Save && Restore && Save != Restore &&
292 MLI->getLoopFor(Save) != MLI->getLoopFor(Restore)) {
293 if (MLI->getLoopDepth(Save) > MLI->getLoopDepth(Restore))
295 Save = FindIDom<>(*Save, Save->predecessors(), *MDT);
298 Restore = FindIDom<>(*Restore, Restore->successors(), *MPDT);
315 if (!useOrDefCSROrFI(MI))
319 updateSaveRestorePoints(MBB);
322 if (!ArePointsInteresting()) {
323 DEBUG(
dbgs() <<
"No Shrink wrap candidate found\n");
331 if (!ArePointsInteresting()) {
335 assert(!Save && !Restore &&
"We miss a shrink-wrap opportunity?!");
336 DEBUG(
dbgs() <<
"Nothing to shrink-wrap\n");
340 DEBUG(
dbgs() <<
"\n ** Results **\nFrequency of the Entry: " << EntryFreq
345 DEBUG(
dbgs() <<
"Shrink wrap candidates (#, Name, Freq):\nSave: "
346 << Save->getNumber() <<
' ' << Save->getName() <<
' '
347 << MBFI->getBlockFreq(Save).getFrequency() <<
"\nRestore: "
348 << Restore->getNumber() <<
' ' << Restore->getName() <<
' '
349 << MBFI->getBlockFreq(Restore).getFrequency() <<
'\n');
351 bool IsSaveCheap, TargetCanUseSaveAsPrologue =
false;
352 if (((IsSaveCheap = EntryFreq >= MBFI->getBlockFreq(Save).getFrequency()) &&
353 EntryFreq >= MBFI->getBlockFreq(Restore).getFrequency()) &&
357 DEBUG(
dbgs() <<
"New points are too expensive or invalid for the target\n");
359 if (!IsSaveCheap || !TargetCanUseSaveAsPrologue) {
360 Save = FindIDom<>(*Save, Save->predecessors(), *MDT);
366 Restore = FindIDom<>(*Restore, Restore->successors(), *MPDT);
371 updateSaveRestorePoints(*NewBB);
372 }
while (Save && Restore);
374 if (!ArePointsInteresting()) {
375 ++NumCandidatesDropped;
379 DEBUG(
dbgs() <<
"Final shrink wrap candidates:\nSave: " << Save->getNumber()
380 <<
' ' << Save->getName() <<
"\nRestore: "
381 << Restore->getNumber() <<
' ' << Restore->getName() <<
'\n');
385 MFI->setRestorePoint(Restore);
Pass interface - Implemented by all 'passes'.
void setSavePoint(MachineBasicBlock *NewSave)
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
STATISTIC(NumFunctions,"Total number of functions")
int getNumber() const
getNumber - MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a M...
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...
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
unsigned getCallFrameDestroyOpcode() const
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
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
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.
LLVMTargetDataRef wrap(const DataLayout *P)
const MachineBasicBlock & front() const
unsigned getCallFrameSetupOpcode() const
These methods return the opcode of the frame setup/destroy instructions if they exist (-1 otherwise)...
TargetInstrInfo - Interface to description of machine instruction set.
INITIALIZE_PASS_BEGIN(ShrinkWrap,"shrink-wrap","Shrink Wrap Pass", false, false) bool ShrinkWrap
initializer< Ty > init(const Ty &Val)
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
MachineBasicBlock * FindIDom(MachineBasicBlock &Block, ListOfBBs BBs, DominanceAnalysis &Dom)
Helper function to find the immediate (post) dominator.
Represent the analysis usage information of a pass.
void initializeShrinkWrapPass(PassRegistry &)
PostDominatorTree Class - Concrete subclass of DominatorTree that is used to compute the post-dominat...
MachineOperand class - Representation of each machine instruction operand.
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
getName - 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)
isPhysicalRegister - Return true if the specified register number is in the physical register namespa...
virtual const TargetInstrInfo * getInstrInfo() const
char & ShrinkWrapID
ShrinkWrap pass. Look for the best place to insert save and restore.
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...