30 if (
auto Call = dyn_cast<CallBase>(&
I))
36 if (findCallInst(*BB.getTerminator()) ||
37 llvm::any_of(BB.instructionsWithoutDebug(), findCallInst))
53 assert(BB !=
nullptr &&
"Traversing Null BB to find calls?");
56 auto CalledValue = Call->getCalledOperand()->stripPointerCasts();
57 if (
auto DirectCall = dyn_cast<Function>(CalledValue))
61 if (
auto CI = dyn_cast<CallInst>(&
I))
76size_t BlockFreqQuery::numBBToGet(
size_t numBB) {
84 return (numBB / 2) + (numBB / 4);
96 auto IBBs = findBBwithCalls(
F);
103 for (
const auto I : IBBs)
104 BBFreqs.
push_back({
I, BFI.getBlockFreq(
I).getFrequency()});
106 assert(IBBs.size() == BBFreqs.
size() &&
"BB Count Mismatch");
108 llvm::sort(BBFreqs, [](
decltype(BBFreqs)::const_reference BBF,
109 decltype(BBFreqs)::const_reference BBS) {
110 return BBF.second > BBS.second ?
true :
false;
114 auto Topk = numBBToGet(BBFreqs.
size());
116 for (
size_t i = 0; i < Topk; i++)
119 assert(!Calles.
empty() &&
"Running Analysis on Function with no calls?");
121 CallerAndCalles.
insert({
F.getName(), std::move(Calles)});
123 return CallerAndCalles;
127std::size_t SequenceBBQuery::getHottestBlocks(std::size_t TotalBlocks) {
128 if (TotalBlocks == 1)
130 return TotalBlocks / 2;
135SequenceBBQuery::rearrangeBB(
const Function &
F,
const BlockListTy &BBList) {
140 RearrangedBBSet.push_back(&
Block);
142 assert(RearrangedBBSet.size() == BBList.size() &&
143 "BasicBlock missing while rearranging?");
144 return RearrangedBBSet;
147void SequenceBBQuery::traverseToEntryBlock(
const BasicBlock *AtBB,
148 const BlockListTy &CallerBlocks,
149 const BackEdgesInfoTy &BackEdgesInfo,
151 VisitedBlocksInfoTy &VisitedBlocks) {
152 auto Itr = VisitedBlocks.find(AtBB);
153 if (Itr != VisitedBlocks.end()) {
154 if (!Itr->second.Upward)
156 Itr->second.Upward =
false;
159 WalkDirection BlockHint;
160 BlockHint.Upward =
false;
163 BlockHint.CallerBlock =
true;
164 VisitedBlocks.insert(std::make_pair(AtBB, BlockHint));
178 for (
auto &
I : BackEdgesInfo)
179 if (
I.second == AtBB)
183 for (; PIt != EIt; ++PIt)
186 traverseToEntryBlock(*PIt, CallerBlocks, BackEdgesInfo, BPI,
190void SequenceBBQuery::traverseToExitBlock(
const BasicBlock *AtBB,
191 const BlockListTy &CallerBlocks,
192 const BackEdgesInfoTy &BackEdgesInfo,
194 VisitedBlocksInfoTy &VisitedBlocks) {
195 auto Itr = VisitedBlocks.find(AtBB);
196 if (Itr != VisitedBlocks.end()) {
197 if (!Itr->second.Downward)
199 Itr->second.Downward =
false;
202 WalkDirection BlockHint;
203 BlockHint.Downward =
false;
206 BlockHint.CallerBlock =
true;
207 VisitedBlocks.insert(std::make_pair(AtBB, BlockHint));
219 for (
auto &
I : BackEdgesInfo)
221 SuccSkipNodes.
insert(
I.second);
223 for (; PIt != EIt; ++PIt)
225 traverseToExitBlock(*PIt, CallerBlocks, BackEdgesInfo, BPI,
233SequenceBBQuery::queryCFG(
Function &
F,
const BlockListTy &CallerBlocks) {
247 for (
const auto I : CallerBlocks)
248 BBFreqs.push_back({
I,
BFI.getBlockFreq(
I).getFrequency()});
250 llvm::sort(BBFreqs, [](
decltype(BBFreqs)::const_reference Bbf,
251 decltype(BBFreqs)::const_reference Bbs) {
252 return Bbf.second > Bbs.second;
257 HotBlocksRef.drop_back(BBFreqs.size() - getHottestBlocks(BBFreqs.size()));
266 for (
auto I : HotBlocksRef) {
267 traverseToEntryBlock(
I.first, CallerBlocks, BackEdgesInfo, BPI,
269 traverseToExitBlock(
I.first, CallerBlocks, BackEdgesInfo, BPI,
274 for (
auto &
I : VisitedBlocks)
275 if (
I.second.CallerBlock)
276 MinCallerBlocks.push_back(std::move(
I.first));
278 return rearrangeBB(
F, MinCallerBlocks);
288 CallerBlocks = findBBwithCalls(
F);
289 if (CallerBlocks.
empty())
293 SequencedBlocks = rearrangeBB(
F, CallerBlocks);
295 SequencedBlocks = queryCFG(
F, CallerBlocks);
297 for (
const auto *BB : SequencedBlocks)
300 CallerAndCalles.
insert({
F.getName(), std::move(Calles)});
301 return CallerAndCalles;
This file defines the DenseMap class.
static const Function * getCalledFunction(const Value *V)
uint64_t IntrinsicInst * II
FunctionAnalysisManager FAM
PassBuilder PB(Machine, PassOpts->PTO, std::nullopt, &PIC)
This header defines various interfaces for pass management in LLVM.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallVector class.
Contains the Analyses and Result Interpretation to select likely functions to Speculatively compile b...
A container for analyses that lazily runs them and caches their results.
PassT::Result * getCachedResult(IRUnitT &IR) const
Get the cached result of an analysis pass for a given IR unit.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
LLVM Basic Block Representation.
iterator_range< filter_iterator< BasicBlock::const_iterator, std::function< bool(const Instruction &)> > > instructionsWithoutDebug(bool SkipPseudoOp=true) const
Return a const iterator range over the instructions in the block, skipping any debug instructions.
const BasicBlock * getSingleSuccessor() const
Return the successor of this block if it has a single successor.
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
Analysis pass which computes BlockFrequencyInfo.
Analysis pass which computes BranchProbabilityInfo.
Analysis providing branch probability information.
bool isEdgeHot(const BasicBlock *Src, const BasicBlock *Dst) const
Test if an edge is hot relative to other out-edges of the Src.
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Implements a dense probed hash-table based set.
This class provides access to building LLVM's passes.
void registerFunctionAnalyses(FunctionAnalysisManager &FAM)
Registers all available function analysis passes.
reference emplace_back(ArgTypes &&... Args)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
std::pair< iterator, bool > insert(const ValueT &V)
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
ResultTy operator()(Function &F)
ResultTy operator()(Function &F)
SmallVector< std::pair< const BasicBlock *, uint64_t >, 8 > BlockFreqInfoTy
DenseMap< const BasicBlock *, WalkDirection > VisitedBlocksInfoTy
SmallVector< std::pair< const BasicBlock *, const BasicBlock * >, 8 > BackEdgesInfoTy
SmallVector< const BasicBlock *, 8 > BlockListTy
std::optional< DenseMap< StringRef, DenseSet< StringRef > > > ResultTy
bool isStraightLine(const Function &F)
void findCalles(const BasicBlock *, DenseSet< StringRef > &)
Interfaces for registering analysis passes, producing common pass manager configurations,...
This is an optimization pass for GlobalISel generic memory operations.
pred_iterator pred_end(BasicBlock *BB)
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
pred_iterator pred_begin(BasicBlock *BB)
void sort(IteratorTy Start, IteratorTy End)
RNSuccIterator< NodeRef, BlockT, RegionT > succ_begin(NodeRef Node)
RNSuccIterator< NodeRef, BlockT, RegionT > succ_end(NodeRef Node)
bool is_contained(R &&Range, const E &Element)
Returns true if Element is found in Range.
void FindFunctionBackedges(const Function &F, SmallVectorImpl< std::pair< const BasicBlock *, const BasicBlock * > > &Result)
Analyze the specified function to find all of the loop backedges in the function and return them.