53#define DEBUG_TYPE "indirectbr-expand"
68 : FunctionPass(ID), OptLevel(OptLevel) {}
70 IndirectBrExpandLegacyPass()
73 void getAnalysisUsage(AnalysisUsage &AU)
const override {
74 if (OptLevel != CodeGenOptLevel::None)
86 bool PreserveProfile);
90 auto *STI = TM->getSubtargetImpl(
F);
91 if (!STI->enableIndirectBrExpand())
94 auto *TLI = STI->getTargetLowering();
99 F, TLI, DT ? &DTU :
nullptr,
109char IndirectBrExpandLegacyPass::ID = 0;
112 "Expand indirectbr instructions",
false,
false)
118 return new IndirectBrExpandLegacyPass(OptLevel);
123 bool PreserveProfile) {
124 auto &
DL =
F.getDataLayout();
129 bool SkipProfileUpdates = !PreserveProfile;
132 struct IndirectBrSuccessor {
135 size_t IndirectBrIndex = 0;
141 IndirectBrSuccToIndirectBr;
148 if (IBr->getNumSuccessors() == 0) {
155 const size_t CurrentIndirectBrIndex = IndirectBrs.
size() - 1;
156 for (
const BasicBlock *SuccessorBB : IBr->successors())
157 IndirectBrSuccToIndirectBr.
insert({SuccessorBB, {}});
159 if (SkipProfileUpdates)
165 SkipProfileUpdates =
true;
170 bool HasBranchWeights =
172 if (!HasBranchWeights) {
173 SkipProfileUpdates =
true;
176 for (
const auto [SuccessorBB, SuccessorBranchWeight] :
177 zip_equal(IBr->successors(), IndirectBrBranchWeights))
178 IndirectBrSuccToIndirectBr[SuccessorBB].push_back(
179 {CurrentIndirectBrIndex, SuccessorBranchWeight});
180 IndirectBrsBranchWeightSums.
push_back(
sum_of(IndirectBrBranchWeights));
181 assert(IndirectBrsBranchWeightSums.
size() == IndirectBrs.
size() &&
182 "expected an identical number of blocks in both vectors");
185 if (IndirectBrs.
empty())
198 auto IndirectBrSuccToIndirectBrIt = IndirectBrSuccToIndirectBr.
find(&BB);
199 if (IndirectBrSuccToIndirectBrIt == IndirectBrSuccToIndirectBr.
end())
206 if (!BA || !BA->isConstantUsed())
211 int BBIndex = BBs.
size() + 1;
215 ConstantInt *BBIndexC = ConstantInt::get(ITy, BBIndex);
223 if (SkipProfileUpdates)
226 for (
uint64_t BranchWeightSum : IndirectBrsBranchWeightSums)
229 for (
const auto &[IndirectBrIndex, BlockBranchProbability] :
230 IndirectBrSuccToIndirectBrIt->second) {
233 const uint64_t CurrentBranchWeightSum =
234 IndirectBrsBranchWeightSums[IndirectBrIndex];
235 if (CurrentBranchWeightSum == 0)
238 IndirectBrsBlockFrequencies[IndirectBrIndex], 0) *
240 (BranchWeightSumsProduct /
251 Updates.
reserve(IndirectBrSuccToIndirectBr.
size());
252 for (
auto *IBr : IndirectBrs) {
262 "Got unexpected update count.");
273 for (
auto *IBr : IndirectBrs) {
282 Twine(IBr->getAddress()->getName()) +
289 if (IndirectBrs.
size() == 1) {
294 SwitchValue = GetSwitchValue(IBr);
296 Updates.
reserve(IndirectBrSuccToIndirectBr.
size());
300 "Got unexpected update count.");
309 "switch_value_phi", SwitchBB);
310 SwitchValue = SwitchPN;
316 2 * IndirectBrSuccToIndirectBr.
size());
317 for (
auto *IBr : IndirectBrs) {
318 SwitchPN->addIncoming(GetSwitchValue(IBr), IBr->getParent());
325 IBr->eraseFromParent();
335 SI->addCase(ConstantInt::get(CommonITy, i + 1), BBs[i]);
343 if (UniqueSuccessors.
insert(BB).second)
359 int16_t MaxScale = 0;
361 MaxScale = std::max(MaxScale, BBWeight.getScale());
365 int16_t Shift = MaxScale - BBWeight.getScale();
366 assert(Shift >= 0 &&
"expected non-negative shift");
367 ExtractedBBWeights.
push_back(BBWeight.getDigits() >> Shift);
374bool IndirectBrExpandLegacyPass::runOnFunction(
Function &
F) {
375 auto *TPC = getAnalysisIfAvailable<TargetPassConfig>();
381 if (!STI.enableIndirectBrExpand())
383 auto *TLI = STI.getTargetLowering();
385 std::optional<DomTreeUpdater> DTU;
386 if (
auto *DTWP = getAnalysisIfAvailable<DominatorTreeWrapperPass>())
387 DTU.emplace(DTWP->getDomTree(), DomTreeUpdater::UpdateStrategy::Lazy);
390 F, TLI, DTU ? &*DTU :
nullptr,
391 [&]() {
return &getAnalysis<LazyBlockFrequencyInfoPass>().getBFI(); },
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static bool runImpl(MachineFunction &MF)
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static bool runOnFunction(Function &F, bool PostInlining)
static bool runImpl(Function &F, const TargetLowering *TLI, DomTreeUpdater *DTU, function_ref< BlockFrequencyInfo *()> GetBFI, bool PreserveProfile)
FunctionAnalysisManager FAM
#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 contains the declarations for profiling metadata utility functions.
Provides some synthesis utilities to produce sequences of values.
This file defines the SmallVector class.
Target-Independent Code Generator Pass Configuration Options pass.
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM Basic Block Representation.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
static LLVM_ABI BlockAddress * lookup(const BasicBlock *BB)
Lookup an existing BlockAddress constant for the given BasicBlock.
Analysis pass which computes BlockFrequencyInfo.
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
LLVM_ABI std::optional< uint64_t > getBlockProfileCount(const BasicBlock *BB) const
Returns the estimated profile count of BB.
static LLVM_ABI CastInst * CreatePointerCast(Value *S, Type *Ty, const Twine &Name="", InsertPosition InsertBefore=nullptr)
Create a BitCast, AddrSpaceCast or a PtrToInt cast instruction.
static LLVM_ABI Constant * getIntToPtr(Constant *C, Type *Ty, bool OnlyIfReduced=false)
This is the shared class of boolean and integer constants.
iterator find(const_arg_type_t< KeyT > Val)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Analysis pass which computes a DominatorTree.
static constexpr UpdateKind Delete
static constexpr UpdateKind Insert
Legacy analysis pass which computes a DominatorTree.
FunctionPass class - This class is used to implement most global optimizations.
void applyUpdates(ArrayRef< UpdateT > Updates)
Submit updates to all available trees.
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM)
Indirect Branch Instruction.
iterator_range< succ_iterator > successors()
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
Class to represent integer types.
unsigned getBitWidth() const
Get the number of bits in this IntegerType.
static void getLazyBFIAnalysisUsage(AnalysisUsage &AU)
Helper for client passes to set up the analysis usage on behalf of this pass.
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
PreservedAnalyses & preserve()
Mark an analysis as preserved.
Simple representation of a scaled number.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
void reserve(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
static SwitchInst * Create(Value *Value, BasicBlock *Default, unsigned NumCases, InsertPosition InsertBefore=nullptr)
This class defines information used to lower LLVM code to legal SelectionDAG operators that the targe...
Primary interface to the complete machine description for the target machine.
virtual const TargetSubtargetInfo * getSubtargetImpl(const Function &) const
Virtual method implemented by subclasses that returns a reference to that target's TargetSubtargetInf...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static UncondBrInst * Create(BasicBlock *Target, InsertPosition InsertBefore=nullptr)
This function has undefined behavior.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
self_iterator getIterator()
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI cl::opt< bool > ProfcheckDisableMetadataFixes
detail::zippy< detail::zip_first, T, U, Args... > zip_equal(T &&t, U &&u, Args &&...args)
zip iterator that assumes that all iteratees have the same length.
LLVM_ABI void setExplicitlyUnknownBranchWeightsIfProfiled(Instruction &I, StringRef PassName, const Function *F=nullptr)
Like setExplicitlyUnknownBranchWeights(...), but only sets unknown branch weights in the new instruct...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
LLVM_ABI FunctionPass * createIndirectBrExpandPass(CodeGenOptLevel OptLevel)
CodeGenOptLevel
Code generation optimization level.
auto sum_of(R &&Range, E Init=E{0})
Returns the sum of all values in Range with Init initial value.
LLVM_ABI bool extractBranchWeights(const MDNode *ProfileData, SmallVectorImpl< uint32_t > &Weights)
Extract branch weights from MD_prof metadata.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
constexpr auto seq(T Begin, T End)
Iterate over an integral type from Begin up to - but not including - End.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI void setFittedBranchWeights(Instruction &I, ArrayRef< uint64_t > Weights, bool IsExpected, bool ElideAllZero=false)
Variant of setBranchWeights where the Weights will be fit first to uint32_t by shifting right.