90 #define DEBUG_TYPE "shrink-wrap" 92 STATISTIC(NumFunc,
"Number of functions");
93 STATISTIC(NumCandidates,
"Number of shrink-wrapping candidates");
95 "Number of shrink-wrapping candidates dropped because of frequency");
99 cl::desc(
"enable the shrink-wrapping pass"));
141 unsigned FrameSetupOpcode;
144 unsigned FrameDestroyOpcode;
155 mutable SetOfRegs CurrentCSRs;
165 const SetOfRegs &getCurrentCSRs(
RegScavenger *RS)
const {
166 if (CurrentCSRs.empty()) {
175 CurrentCSRs.insert((
unsigned)
Reg);
190 MDT = &getAnalysis<MachineDominatorTree>();
191 MPDT = &getAnalysis<MachinePostDominatorTree>();
194 MBFI = &getAnalysis<MachineBlockFrequencyInfo>();
195 MLI = &getAnalysis<MachineLoopInfo>();
196 ORE = &getAnalysis<MachineOptimizationRemarkEmitterPass>().getORE();
212 bool ArePointsInteresting()
const {
return Save != Entry && Save && Restore; }
239 StringRef getPassName()
const override {
return "Shrink Wrapping analysis"; }
262 if (MI.getOpcode() == FrameSetupOpcode ||
263 MI.getOpcode() == FrameDestroyOpcode) {
268 bool UseOrDefCSR =
false;
271 if (!MO.isDef() && !MO.readsReg())
273 unsigned PhysReg = MO.getReg();
277 "Unallocated register?!");
283 UseOrDefCSR = (!MI.isCall() && PhysReg == SP) ||
285 }
else if (MO.isRegMask()) {
287 for (
unsigned Reg : getCurrentCSRs(RS)) {
288 if (MO.clobbersPhysReg(
Reg)) {
295 if (UseOrDefCSR || (MO.isFI() && !MI.isDebugValue())) {
296 LLVM_DEBUG(
dbgs() <<
"Use or define CSR(" << UseOrDefCSR <<
") or FI(" 297 << MO.isFI() <<
"): " << MI <<
'\n');
305 template <
typename ListOfBBs,
typename DominanceAnalysis>
307 DominanceAnalysis &Dom) {
310 IDom = Dom.findNearestCommonDominator(IDom, BB);
328 LLVM_DEBUG(
dbgs() <<
"Found a block that is not reachable from Entry\n");
334 else if (MPDT->getNode(&MBB))
339 Restore = MPDT->findNearestCommonDominator(Restore, &MBB);
345 if (Restore == &MBB) {
356 Restore = FindIDom<>(*Restore, Restore->
successors(), *MPDT);
363 dbgs() <<
"Restore point needs to be spanned on several blocks\n");
374 bool SaveDominatesRestore =
false;
375 bool RestorePostDominatesSave =
false;
376 while (Save && Restore &&
377 (!(SaveDominatesRestore = MDT->
dominates(Save, Restore)) ||
378 !(RestorePostDominatesSave = MPDT->dominates(Restore, Save)) ||
396 MLI->getLoopFor(Save) || MLI->getLoopFor(Restore))) {
398 if (!SaveDominatesRestore) {
403 if (!RestorePostDominatesSave)
404 Restore = MPDT->findNearestCommonDominator(Restore, Save);
407 if (Save && Restore &&
408 (MLI->getLoopFor(Save) || MLI->getLoopFor(Restore))) {
409 if (MLI->getLoopDepth(Save) > MLI->getLoopDepth(Restore)) {
412 Save = FindIDom<>(*Save, Save->predecessors(), *MDT);
419 MLI->getLoopFor(Restore)->getExitingBlocks(ExitBlocks);
424 IPdom = FindIDom<>(*IPdom, LoopExitBB->
successors(), *MPDT);
431 if (IPdom && MLI->getLoopDepth(IPdom) < MLI->getLoopDepth(Restore))
456 if (skipFunction(MF.
getFunction()) || MF.
empty() || !isShrinkWrapEnabled(MF))
464 if (containsIrreducibleCFG<MachineBasicBlock *>(RPOT, *MLI)) {
472 "Irreducible CFGs are not supported yet.",
477 std::unique_ptr<RegScavenger> RS(
478 TRI->requiresRegisterScavenging(MF) ?
new RegScavenger() :
nullptr);
486 "EH Funclets are not supported yet.",
497 updateSaveRestorePoints(MBB, RS.get());
498 if (!ArePointsInteresting()) {
506 if (!useOrDefCSROrFI(
MI, RS.get()))
510 updateSaveRestorePoints(MBB, RS.get());
513 if (!ArePointsInteresting()) {
522 if (!ArePointsInteresting()) {
526 assert(!Save && !Restore &&
"We miss a shrink-wrap opportunity?!");
531 LLVM_DEBUG(
dbgs() <<
"\n ** Results **\nFrequency of the Entry: " << EntryFreq
536 LLVM_DEBUG(
dbgs() <<
"Shrink wrap candidates (#, Name, Freq):\nSave: " 537 << Save->getNumber() <<
' ' << Save->getName() <<
' ' 539 <<
"\nRestore: " << Restore->
getNumber() <<
' ' 543 bool IsSaveCheap, TargetCanUseSaveAsPrologue =
false;
550 dbgs() <<
"New points are too expensive or invalid for the target\n");
552 if (!IsSaveCheap || !TargetCanUseSaveAsPrologue) {
553 Save = FindIDom<>(*Save, Save->predecessors(), *MDT);
559 Restore = FindIDom<>(*Restore, Restore->
successors(), *MPDT);
564 updateSaveRestorePoints(*NewBB, RS.get());
565 }
while (Save && Restore);
567 if (!ArePointsInteresting()) {
568 ++NumCandidatesDropped;
573 << Save->getNumber() <<
' ' << Save->getName()
574 <<
"\nRestore: " << Restore->
getNumber() <<
' ' 575 << Restore->
getName() <<
'\n');
579 MFI.setRestorePoint(Restore);
Pass interface - Implemented by all 'passes'.
bool usesWindowsCFI() const
void setSavePoint(MachineBasicBlock *NewSave)
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
virtual bool enableShrinkWrapping(const MachineFunction &MF) const
Returns true if the target will correctly handle shrink wrapping.
This class represents lattice values for constants.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
virtual const TargetLowering * getTargetLowering() const
uint64_t getFrequency() const
Returns the frequency as a fixpoint number scaled by the entry frequency.
MachineBlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate machine basic b...
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
STATISTIC(NumFunctions, "Total number of functions")
unsigned const TargetRegisterInfo * TRI
unsigned getCallFrameDestroyOpcode() const
iterator_range< succ_iterator > successors()
virtual void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
virtual bool canUseAsEpilogue(const MachineBasicBlock &MBB) const
Check whether or not the given MBB can be used as a epilogue for the target.
int find_first() const
find_first - Returns the index of the first set bit, -1 if none of the bits are set.
int find_next(unsigned Prev) const
find_next - Returns the index of the next set bit following the "Prev" bit.
This file contains the simple types necessary to represent the attributes associated with functions a...
iterator_range< iterator > terminators()
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
virtual const TargetInstrInfo * getInstrInfo() const
MachineBasicBlock * findNearestCommonDominator(MachineBasicBlock *A, MachineBasicBlock *B)
findNearestCommonDominator - Find nearest common dominator basic block for basic block A and B...
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
TargetInstrInfo - Interface to description of machine instruction set.
initializer< Ty > init(const Ty &Val)
This file declares the machine register scavenger class.
StringRef getName() const
Return the name of the corresponding LLVM basic block, or an empty string.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
DISubprogram * getSubprogram() const
Get the attached subprogram.
static cl::opt< cl::boolOrDefault > EnableShrinkWrapOpt("enable-shrink-wrap", cl::Hidden, cl::desc("enable the shrink-wrapping pass"))
const MCAsmInfo * getMCAsmInfo() const
Return target specific asm information.
BlockFrequency getBlockFreq(const MachineBasicBlock *MBB) const
getblockFreq - Return block frequency.
unsigned getCallFrameSetupOpcode() const
These methods return the opcode of the frame setup/destroy instructions if they exist (-1 otherwise)...
Represent the analysis usage information of a pass.
void runOnMachineFunction(const MachineFunction &MF)
runOnFunction - Prepare to answer questions about MF.
void initializeShrinkWrapPass(PassRegistry &)
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
const MachineBasicBlock & front() const
static MachineBasicBlock * FindIDom(MachineBasicBlock &Block, ListOfBBs BBs, DominanceAnalysis &Dom)
Helper function to find the immediate (post) dominator.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
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...
bool dominates(const MachineDomTreeNode *A, const MachineDomTreeNode *B) const
Information about stack frame layout on the target.
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
const Function & getFunction() const
Return the LLVM function that this machine code represents.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void setPreservesAll()
Set by analyses that do not transform their input at all.
MachineFunctionProperties & set(Property P)
TargetSubtargetInfo - Generic base class for all target subtargets.
Representation of each machine instruction.
static bool giveUpWithRemarks(MachineOptimizationRemarkEmitter *ORE, StringRef RemarkName, StringRef RemarkMessage, const DiagnosticLocation &Loc, const MachineBasicBlock *MBB)
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
bool isEHPad() const
Returns true if the block is a landing pad.
bool isEHFuncletEntry() const
Returns true if this is the entry block of an EH funclet.
virtual const TargetFrameLowering * getFrameLowering() const
uint64_t getEntryFreq() const
virtual bool canUseAsPrologue(const MachineBasicBlock &MBB) const
Check whether or not the given MBB can be used as a prologue for the target.
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
unsigned getLastCalleeSavedAlias(unsigned PhysReg) const
getLastCalleeSavedAlias - Returns the last callee saved register that overlaps PhysReg, or 0 if Reg doesn't overlap a CalleeSavedAliases.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
unsigned getStackPointerRegisterToSaveRestore() const
If a physical register, this specifies the register that llvm.savestack/llvm.restorestack should save...
char & ShrinkWrapID
ShrinkWrap pass. Look for the best place to insert save and restore.
StringRef - Represent a constant reference to a string, i.e.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
Properties which a MachineFunction may have at a given point in time.
This file describes how to lower LLVM code to machine code.