31#define DEBUG_TYPE "x86-pad-short-functions"
33STATISTIC(NumBBsPadded,
"Number of basic blocks padded");
36 struct VisitedBBInfo {
38 bool HasReturn =
false;
42 unsigned int Cycles = 0;
44 VisitedBBInfo() =
default;
45 VisitedBBInfo(
bool HasReturn,
unsigned int Cycles)
46 : HasReturn(HasReturn), Cycles(Cycles) {}
51 PadShortFunc() : MachineFunctionPass(ID) {}
53 bool runOnMachineFunction(MachineFunction &MF)
override;
55 void getAnalysisUsage(AnalysisUsage &AU)
const override {
57 AU.
addRequired<LazyMachineBlockFrequencyInfoPass>();
62 MachineFunctionProperties getRequiredProperties()
const override {
63 return MachineFunctionProperties().setNoVRegs();
66 StringRef getPassName()
const override {
67 return "X86 Atom pad short functions";
71 void findReturns(MachineBasicBlock *
MBB,
72 unsigned int Cycles = 0);
74 bool cyclesUntilReturn(MachineBasicBlock *
MBB,
75 unsigned int &Cycles);
79 unsigned int NOOPsToAdd);
81 const unsigned int Threshold = 4;
85 DenseMap<MachineBasicBlock*, unsigned int> ReturnBBs;
88 DenseMap<MachineBasicBlock*, VisitedBBInfo> VisitedBBs;
93 char PadShortFunc::ID = 0;
97 return new PadShortFunc();
116 &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
117 auto *MBFI = (PSI && PSI->hasProfileSummary()) ?
118 &getAnalysis<LazyMachineBlockFrequencyInfoPass>().getBFI() :
124 findReturns(&MF.
front());
126 bool MadeChange =
false;
129 for (
const auto &ReturnBB : ReturnBBs) {
131 unsigned Cycles = ReturnBB.second;
136 if (Cycles < Threshold) {
140 "Basic block should contain at least a RET but is empty");
143 while (ReturnLoc->isDebugInstr())
145 assert(ReturnLoc->isReturn() && !ReturnLoc->isCall() &&
146 "Basic block does not end with RET");
159void PadShortFunc::findReturns(MachineBasicBlock *
MBB,
unsigned int Cycles) {
162 if (Cycles >= Threshold)
166 unsigned int &NumCycles = ReturnBBs[
MBB];
167 NumCycles = std::max(NumCycles, Cycles);
174 findReturns(Succ, Cycles);
181bool PadShortFunc::cyclesUntilReturn(MachineBasicBlock *
MBB,
182 unsigned int &Cycles) {
186 VisitedBBInfo BBInfo = It->second;
187 Cycles += BBInfo.Cycles;
188 return BBInfo.HasReturn;
191 unsigned int CyclesToEnd = 0;
193 for (MachineInstr &
MI : *
MBB) {
197 if (
MI.isReturn() && !
MI.isCall()) {
198 It->second = VisitedBBInfo(
true, CyclesToEnd);
199 Cycles += CyclesToEnd;
203 CyclesToEnd += TSM.computeInstrLatency(&
MI);
206 It->second = VisitedBBInfo(
false, CyclesToEnd);
207 Cycles += CyclesToEnd;
213void PadShortFunc::addPadding(MachineBasicBlock *
MBB,
215 unsigned int NOOPsToAdd) {
219 for (
unsigned i = 0, e = IssueWidth * NOOPsToAdd; i !=
e; ++i)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
static void addPadding(BinaryStreamWriter &Writer)
static bool hasReturn(const MachineBasicBlock &MBB)
Returns true if MBB contains an instruction that returns.
===- LazyMachineBlockFrequencyInfo.h - Lazy Block Frequency -*- C++ -*–===//
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
FunctionPass class - This class is used to implement most global optimizations.
bool hasOptSize() const
Optimize this function for size (-Os) or minimum size (-Oz).
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
iterator_range< succ_iterator > successors()
MachineInstrBundleIterator< MachineInstr > iterator
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.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineBasicBlock & front() const
const TargetInstrInfo * getInstrInfo() const
TargetInstrInfo getter.
unsigned getIssueWidth() const
Maximum number of micro-ops that may be scheduled per cycle.
LLVM_ABI void init(const TargetSubtargetInfo *TSInfo, bool EnableSModel=true, bool EnableSItins=true)
Initialize the machine model for instruction scheduling.
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
LLVM_ABI bool shouldOptimizeForSize(const MachineFunction *MF, ProfileSummaryInfo *PSI, const MachineBlockFrequencyInfo *BFI, PGSOQueryType QueryType=PGSOQueryType::Other)
Returns true if machine function MF is suggested to be size-optimized based on the profile.
FunctionPass * createX86PadShortFunctions()
Return a pass that pads short functions with NOOPs.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.