90#define DEBUG_TYPE "shrink-wrap"
93STATISTIC(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()) {
173 for (
int Reg = SavedRegs.
find_first(); Reg != -1;
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();
200 FrameSetupOpcode =
TII.getCallFrameSetupOpcode();
201 FrameDestroyOpcode =
TII.getCallFrameDestroyOpcode();
212 bool ArePointsInteresting()
const {
return Save != Entry && Save && Restore; }
236 MachineFunctionProperties::Property::NoVRegs);
248char ShrinkWrap::ID = 0;
268 if (
MI.mayLoadOrStore())
271 if (
MI.getOpcode() == FrameSetupOpcode ||
272 MI.getOpcode() == FrameDestroyOpcode) {
279 bool UseOrDefCSR =
false;
282 if (!MO.isDef() && !MO.readsReg())
298 (!
MI.isCall() && PhysReg == SP) ||
300 (!
MI.isReturn() &&
TRI->isNonallocatableRegisterCalleeSave(PhysReg));
301 }
else if (MO.isRegMask()) {
303 for (
unsigned Reg : getCurrentCSRs(RS)) {
304 if (MO.clobbersPhysReg(Reg)) {
311 if (UseOrDefCSR || (MO.isFI() && !
MI.isDebugValue())) {
312 LLVM_DEBUG(
dbgs() <<
"Use or define CSR(" << UseOrDefCSR <<
") or FI("
313 << MO.isFI() <<
"): " <<
MI <<
'\n');
321template <
typename ListOfBBs,
typename DominanceAnalysis>
323 DominanceAnalysis &Dom) {
326 IDom = Dom.findNearestCommonDominator(IDom, BB);
357 if (Restore == &
MBB) {
359 if (!useOrDefCSROrFI(Terminator, RS))
368 Restore = FindIDom<>(*Restore, Restore->
successors(), *MPDT);
375 dbgs() <<
"Restore point needs to be spanned on several blocks\n");
386 bool SaveDominatesRestore =
false;
387 bool RestorePostDominatesSave =
false;
389 (!(SaveDominatesRestore = MDT->
dominates(Save, Restore)) ||
390 !(RestorePostDominatesSave = MPDT->
dominates(Restore, Save)) ||
410 if (!SaveDominatesRestore) {
415 if (!RestorePostDominatesSave)
435 IPdom = FindIDom<>(*IPdom, LoopExitBB->successors(), *MPDT);
467 if (skipFunction(MF.
getFunction()) || MF.
empty() || !isShrinkWrapEnabled(MF))
475 if (containsIrreducibleCFG<MachineBasicBlock *>(RPOT, *MLI)) {
483 "Irreducible CFGs are not supported yet.",
488 std::unique_ptr<RegScavenger> RS(
497 "EH Funclets are not supported yet.",
506 updateSaveRestorePoints(
MBB, RS.get());
507 if (!ArePointsInteresting()) {
508 LLVM_DEBUG(
dbgs() <<
"EHPad/inlineasm_br prevents shrink-wrapping\n");
515 if (!useOrDefCSROrFI(
MI, RS.get()))
519 updateSaveRestorePoints(
MBB, RS.get());
522 if (!ArePointsInteresting()) {
531 if (!ArePointsInteresting()) {
535 assert(!Save && !Restore &&
"We miss a shrink-wrap opportunity?!");
540 LLVM_DEBUG(
dbgs() <<
"\n ** Results **\nFrequency of the Entry: " << EntryFreq
545 LLVM_DEBUG(
dbgs() <<
"Shrink wrap candidates (#, Name, Freq):\nSave: "
548 <<
"\nRestore: " << Restore->
getNumber() <<
' '
552 bool IsSaveCheap, TargetCanUseSaveAsPrologue =
false;
559 dbgs() <<
"New points are too expensive or invalid for the target\n");
561 if (!IsSaveCheap || !TargetCanUseSaveAsPrologue) {
568 Restore = FindIDom<>(*Restore, Restore->
successors(), *MPDT);
573 updateSaveRestorePoints(*NewBB, RS.get());
574 }
while (Save && Restore);
576 if (!ArePointsInteresting()) {
577 ++NumCandidatesDropped;
583 <<
"\nRestore: " << Restore->
getNumber() <<
' '
584 << Restore->
getName() <<
'\n');
This file contains the simple types necessary to represent the attributes associated with functions a...
This file implements the BitVector class.
const HexagonInstrInfo * TII
unsigned const TargetRegisterInfo * TRI
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
This file declares the machine register scavenger class.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file implements a set that has insertion order iteration characteristics.
static MachineBasicBlock * FindIDom(MachineBasicBlock &Block, ListOfBBs BBs, DominanceAnalysis &Dom)
Helper function to find the immediate (post) dominator.
static bool giveUpWithRemarks(MachineOptimizationRemarkEmitter *ORE, StringRef RemarkName, StringRef RemarkMessage, const DiagnosticLocation &Loc, const MachineBasicBlock *MBB)
static cl::opt< cl::boolOrDefault > EnableShrinkWrapOpt("enable-shrink-wrap", cl::Hidden, cl::desc("enable the shrink-wrapping pass"))
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
This file describes how to lower LLVM code to machine code.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
void setPreservesAll()
Set by analyses that do not transform their input at all.
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.
uint64_t getFrequency() const
Returns the frequency as a fixpoint number scaled by the entry frequency.
DISubprogram * getSubprogram() const
Get the attached subprogram.
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
void getExitingBlocks(SmallVectorImpl< BlockT * > &ExitingBlocks) const
Return all blocks inside the loop that have successors outside of the loop.
bool usesWindowsCFI() const
bool isInlineAsmBrIndirectTarget() const
Returns true if this is the indirect dest of an INLINEASM_BR.
bool isEHPad() const
Returns true if the block is a landing pad.
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
bool isEHFuncletEntry() const
Returns true if this is the entry block of an EH funclet.
iterator_range< iterator > terminators()
iterator_range< succ_iterator > successors()
iterator_range< pred_iterator > predecessors()
StringRef getName() const
Return the name of the corresponding LLVM basic block, or an empty string.
MachineBlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate machine basic b...
BlockFrequency getBlockFreq(const MachineBasicBlock *MBB) const
getblockFreq - Return block frequency.
uint64_t getEntryFreq() const
Divide a block's BlockFrequency::getFrequency() value by this value to obtain the entry block - relat...
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
MachineBasicBlock * findNearestCommonDominator(MachineBasicBlock *A, MachineBasicBlock *B)
findNearestCommonDominator - Find nearest common dominator basic block for basic block A and B.
bool dominates(const MachineDomTreeNode *A, const MachineDomTreeNode *B) const
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
void setRestorePoint(MachineBasicBlock *NewRestore)
void setSavePoint(MachineBasicBlock *NewSave)
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
virtual MachineFunctionProperties getRequiredProperties() const
Properties which a MachineFunction may have at a given point in time.
MachineFunctionProperties & set(Property P)
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
Function & getFunction()
Return the LLVM function that this machine code represents.
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const MachineBasicBlock & front() const
Representation of each machine instruction.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
MachineLoop * getLoopFor(const MachineBasicBlock *BB) const
Return the innermost loop that BB lives in.
unsigned getLoopDepth(const MachineBasicBlock *BB) const
Return the loop nesting level of the specified block.
MachineOperand class - Representation of each machine instruction operand.
MachinePostDominatorTree - an analysis pass wrapper for DominatorTree used to compute the post-domina...
bool dominates(const MachineDomTreeNode *A, const MachineDomTreeNode *B) const
MachineBasicBlock * findNearestCommonDominator(MachineBasicBlock *A, MachineBasicBlock *B) const
MachineDomTreeNode * getNode(MachineBasicBlock *BB) const
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Pass interface - Implemented by all 'passes'.
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
MCRegister getLastCalleeSavedAlias(MCRegister PhysReg) const
getLastCalleeSavedAlias - Returns the last callee saved register that overlaps PhysReg,...
void runOnMachineFunction(const MachineFunction &MF)
runOnFunction - Prepare to answer questions about MF.
Wrapper class representing virtual and physical registers.
bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
A SetVector that performs no allocations if smaller than a certain size.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
Information about stack frame layout on the target.
virtual void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs, RegScavenger *RS=nullptr) const
This method determines which of the registers reported by TargetRegisterInfo::getCalleeSavedRegs() sh...
virtual bool enableShrinkWrapping(const MachineFunction &MF) const
Returns true if the target will correctly handle shrink wrapping.
virtual bool canUseAsEpilogue(const MachineBasicBlock &MBB) const
Check whether or not the given MBB can be used as a epilogue for the target.
virtual bool canUseAsPrologue(const MachineBasicBlock &MBB) const
Check whether or not the given MBB can be used as a prologue for the target.
TargetInstrInfo - Interface to description of machine instruction set.
Register getStackPointerRegisterToSaveRestore() const
If a physical register, this specifies the register that llvm.savestack/llvm.restorestack should save...
const MCAsmInfo * getMCAsmInfo() const
Return target specific asm information.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
TargetSubtargetInfo - Generic base class for all target subtargets.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
virtual const TargetFrameLowering * getFrameLowering() const
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetLowering * getTargetLowering() const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
char & ShrinkWrapID
ShrinkWrap pass. Look for the best place to insert save and restore.
void initializeShrinkWrapPass(PassRegistry &)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.