LLVM 22.0.0git
PGOMemOPSizeOpt.cpp
Go to the documentation of this file.
1//===-- PGOMemOPSizeOpt.cpp - Optimizations based on value profiling ===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements the transformation that optimizes memory intrinsics
10// such as memcpy using the size value profile. When memory intrinsic size
11// value profile metadata is available, a single memory intrinsic is expanded
12// to a sequence of guarded specialized versions that are called with the
13// hottest size(s), for later expansion into more optimal inline sequences.
14//
15//===----------------------------------------------------------------------===//
16
17#include "llvm/ADT/ArrayRef.h"
18#include "llvm/ADT/Statistic.h"
19#include "llvm/ADT/StringRef.h"
20#include "llvm/ADT/Twine.h"
25#include "llvm/IR/BasicBlock.h"
27#include "llvm/IR/Dominators.h"
28#include "llvm/IR/Function.h"
29#include "llvm/IR/IRBuilder.h"
30#include "llvm/IR/InstVisitor.h"
31#include "llvm/IR/Instruction.h"
33#include "llvm/IR/LLVMContext.h"
34#include "llvm/IR/PassManager.h"
35#include "llvm/IR/Type.h"
37#define INSTR_PROF_VALUE_PROF_MEMOP_API
41#include "llvm/Support/Debug.h"
46#include <cassert>
47#include <cstdint>
48#include <vector>
49
50using namespace llvm;
51
52#define DEBUG_TYPE "pgo-memop-opt"
53
54STATISTIC(NumOfPGOMemOPOpt, "Number of memop intrinsics optimized.");
55STATISTIC(NumOfPGOMemOPAnnotate, "Number of memop intrinsics annotated.");
56
57namespace llvm {
58
59// The minimum call count to optimize memory intrinsic calls.
61 MemOPCountThreshold("pgo-memop-count-threshold", cl::Hidden, cl::init(1000),
62 cl::desc("The minimum count to optimize memory "
63 "intrinsic calls"));
64
65// Command line option to disable memory intrinsic optimization. The default is
66// false. This is for debug purpose.
67static cl::opt<bool> DisableMemOPOPT("disable-memop-opt", cl::init(false),
68 cl::Hidden, cl::desc("Disable optimize"));
69
70// The percent threshold to optimize memory intrinsic calls.
72 MemOPPercentThreshold("pgo-memop-percent-threshold", cl::init(40),
74 cl::desc("The percentage threshold for the "
75 "memory intrinsic calls optimization"));
76
77// Maximum number of versions for optimizing memory intrinsic call.
79 MemOPMaxVersion("pgo-memop-max-version", cl::init(3), cl::Hidden,
80 cl::desc("The max version for the optimized memory "
81 " intrinsic calls"));
82
83// Scale the counts from the annotation using the BB count value.
84static cl::opt<bool>
85 MemOPScaleCount("pgo-memop-scale-count", cl::init(true), cl::Hidden,
86 cl::desc("Scale the memop size counts using the basic "
87 " block count value"));
88
90 MemOPOptMemcmpBcmp("pgo-memop-optimize-memcmp-bcmp", cl::init(true),
92 cl::desc("Size-specialize memcmp and bcmp calls"));
93
95 MemOpMaxOptSize("memop-value-prof-max-opt-size", cl::Hidden, cl::init(128),
96 cl::desc("Optimize the memop size <= this value"));
97
98} // end namespace llvm
99
100namespace {
101
102static const char *getMIName(const MemIntrinsic *MI) {
103 switch (MI->getIntrinsicID()) {
104 case Intrinsic::memcpy:
105 return "memcpy";
106 case Intrinsic::memmove:
107 return "memmove";
108 case Intrinsic::memset:
109 return "memset";
110 default:
111 return "unknown";
112 }
113}
114
115// A class that abstracts a memop (memcpy, memmove, memset, memcmp and bcmp).
116struct MemOp {
117 Instruction *I;
118 MemOp(MemIntrinsic *MI) : I(MI) {}
119 MemOp(CallInst *CI) : I(CI) {}
120 MemIntrinsic *asMI() { return dyn_cast<MemIntrinsic>(I); }
121 CallInst *asCI() { return cast<CallInst>(I); }
122 MemOp clone() {
123 if (auto MI = asMI())
124 return MemOp(cast<MemIntrinsic>(MI->clone()));
125 return MemOp(cast<CallInst>(asCI()->clone()));
126 }
127 Value *getLength() {
128 if (auto MI = asMI())
129 return MI->getLength();
130 return asCI()->getArgOperand(2);
131 }
132 void setLength(Value *Length) {
133 if (auto MI = asMI())
134 return MI->setLength(Length);
135 asCI()->setArgOperand(2, Length);
136 }
137 StringRef getFuncName() {
138 if (auto MI = asMI())
139 return MI->getCalledFunction()->getName();
140 return asCI()->getCalledFunction()->getName();
141 }
142 bool isMemmove() {
143 if (auto MI = asMI())
144 if (MI->getIntrinsicID() == Intrinsic::memmove)
145 return true;
146 return false;
147 }
148 bool isMemcmp(TargetLibraryInfo &TLI) {
150 if (asMI() == nullptr && TLI.getLibFunc(*asCI(), Func) &&
151 Func == LibFunc_memcmp) {
152 return true;
153 }
154 return false;
155 }
156 bool isBcmp(TargetLibraryInfo &TLI) {
158 if (asMI() == nullptr && TLI.getLibFunc(*asCI(), Func) &&
159 Func == LibFunc_bcmp) {
160 return true;
161 }
162 return false;
163 }
164 const char *getName(TargetLibraryInfo &TLI) {
165 if (auto MI = asMI())
166 return getMIName(MI);
168 if (TLI.getLibFunc(*asCI(), Func)) {
169 if (Func == LibFunc_memcmp)
170 return "memcmp";
171 if (Func == LibFunc_bcmp)
172 return "bcmp";
173 }
174 llvm_unreachable("Must be MemIntrinsic or memcmp/bcmp CallInst");
175 return nullptr;
176 }
177};
178
179class MemOPSizeOpt : public InstVisitor<MemOPSizeOpt> {
180public:
181 MemOPSizeOpt(Function &Func, BlockFrequencyInfo &BFI,
182 OptimizationRemarkEmitter &ORE, DominatorTree *DT,
183 TargetLibraryInfo &TLI)
184 : Func(Func), BFI(BFI), ORE(ORE), DT(DT), TLI(TLI), Changed(false) {}
185 bool isChanged() const { return Changed; }
186 void perform() {
187 WorkList.clear();
188 visit(Func);
189
190 for (auto &MO : WorkList) {
191 ++NumOfPGOMemOPAnnotate;
192 if (perform(MO)) {
193 Changed = true;
194 ++NumOfPGOMemOPOpt;
195 LLVM_DEBUG(dbgs() << "MemOP call: " << MO.getFuncName()
196 << "is Transformed.\n");
197 }
198 }
199 }
200
201 void visitMemIntrinsic(MemIntrinsic &MI) {
202 Value *Length = MI.getLength();
203 // Not perform on constant length calls.
205 return;
206 WorkList.push_back(MemOp(&MI));
207 }
208
209 void visitCallInst(CallInst &CI) {
210 LibFunc Func;
211 if (TLI.getLibFunc(CI, Func) &&
212 (Func == LibFunc_memcmp || Func == LibFunc_bcmp) &&
214 WorkList.push_back(MemOp(&CI));
215 }
216 }
217
218private:
219 Function &Func;
220 BlockFrequencyInfo &BFI;
221 OptimizationRemarkEmitter &ORE;
222 DominatorTree *DT;
223 TargetLibraryInfo &TLI;
224 bool Changed;
225 std::vector<MemOp> WorkList;
226 bool perform(MemOp MO);
227};
228
229static bool isProfitable(uint64_t Count, uint64_t TotalCount) {
230 assert(Count <= TotalCount);
232 return false;
233 if (Count < TotalCount * MemOPPercentThreshold / 100)
234 return false;
235 return true;
236}
237
238static inline uint64_t getScaledCount(uint64_t Count, uint64_t Num,
239 uint64_t Denom) {
240 if (!MemOPScaleCount)
241 return Count;
242 bool Overflowed;
243 uint64_t ScaleCount = SaturatingMultiply(Count, Num, &Overflowed);
244 return ScaleCount / Denom;
245}
246
247bool MemOPSizeOpt::perform(MemOp MO) {
248 assert(MO.I);
249 if (MO.isMemmove())
250 return false;
251 if (!MemOPOptMemcmpBcmp && (MO.isMemcmp(TLI) || MO.isBcmp(TLI)))
252 return false;
253
254 uint32_t MaxNumVals = INSTR_PROF_NUM_BUCKETS;
255 uint64_t TotalCount;
256 auto VDs =
257 getValueProfDataFromInst(*MO.I, IPVK_MemOPSize, MaxNumVals, TotalCount);
258 if (VDs.empty())
259 return false;
260
261 uint64_t ActualCount = TotalCount;
262 uint64_t SavedTotalCount = TotalCount;
263 if (MemOPScaleCount) {
264 auto BBEdgeCount = BFI.getBlockProfileCount(MO.I->getParent());
265 if (!BBEdgeCount)
266 return false;
267 ActualCount = *BBEdgeCount;
268 }
269
270 LLVM_DEBUG(dbgs() << "Read one memory intrinsic profile with count "
271 << ActualCount << "\n");
273 for (auto &VD
274 : VDs) { dbgs() << " (" << VD.Value << "," << VD.Count << ")\n"; });
275
276 if (ActualCount < MemOPCountThreshold)
277 return false;
278 // Skip if the total value profiled count is 0, in which case we can't
279 // scale up the counts properly (and there is no profitable transformation).
280 if (TotalCount == 0)
281 return false;
282
283 TotalCount = ActualCount;
284 if (MemOPScaleCount)
285 LLVM_DEBUG(dbgs() << "Scale counts: numerator = " << ActualCount
286 << " denominator = " << SavedTotalCount << "\n");
287
288 // Keeping track of the count of the default case:
289 uint64_t RemainCount = TotalCount;
290 uint64_t SavedRemainCount = SavedTotalCount;
291 SmallVector<uint64_t, 16> SizeIds;
292 SmallVector<uint64_t, 16> CaseCounts;
293 SmallDenseSet<uint64_t, 16> SeenSizeId;
294 uint64_t MaxCount = 0;
295 unsigned Version = 0;
296 // Default case is in the front -- save the slot here.
297 CaseCounts.push_back(0);
299 for (auto I = VDs.begin(), E = VDs.end(); I != E; ++I) {
300 auto &VD = *I;
301 int64_t V = VD.Value;
302 uint64_t C = VD.Count;
303 if (MemOPScaleCount)
304 C = getScaledCount(C, ActualCount, SavedTotalCount);
305
306 if (!InstrProfIsSingleValRange(V) || V > MemOpMaxOptSize) {
307 RemainingVDs.push_back(VD);
308 continue;
309 }
310
311 // ValueCounts are sorted on the count. Break at the first un-profitable
312 // value.
313 if (!isProfitable(C, RemainCount)) {
314 RemainingVDs.insert(RemainingVDs.end(), I, E);
315 break;
316 }
317
318 if (!SeenSizeId.insert(V).second) {
319 errs() << "warning: Invalid Profile Data in Function " << Func.getName()
320 << ": Two identical values in MemOp value counts.\n";
321 return false;
322 }
323
324 SizeIds.push_back(V);
325 CaseCounts.push_back(C);
326 if (C > MaxCount)
327 MaxCount = C;
328
329 assert(RemainCount >= C);
330 RemainCount -= C;
331 assert(SavedRemainCount >= VD.Count);
332 SavedRemainCount -= VD.Count;
333
334 if (++Version >= MemOPMaxVersion && MemOPMaxVersion != 0) {
335 RemainingVDs.insert(RemainingVDs.end(), I + 1, E);
336 break;
337 }
338 }
339
340 if (Version == 0)
341 return false;
342
343 CaseCounts[0] = RemainCount;
344 if (RemainCount > MaxCount)
345 MaxCount = RemainCount;
346
347 uint64_t SumForOpt = TotalCount - RemainCount;
348
349 LLVM_DEBUG(dbgs() << "Optimize one memory intrinsic call to " << Version
350 << " Versions (covering " << SumForOpt << " out of "
351 << TotalCount << ")\n");
352
353 // mem_op(..., size)
354 // ==>
355 // switch (size) {
356 // case s1:
357 // mem_op(..., s1);
358 // goto merge_bb;
359 // case s2:
360 // mem_op(..., s2);
361 // goto merge_bb;
362 // ...
363 // default:
364 // mem_op(..., size);
365 // goto merge_bb;
366 // }
367 // merge_bb:
368
369 BasicBlock *BB = MO.I->getParent();
370 LLVM_DEBUG(dbgs() << "\n\n== Basic Block Before ==\n");
371 LLVM_DEBUG(dbgs() << *BB << "\n");
372 auto OrigBBFreq = BFI.getBlockFreq(BB);
373
374 BasicBlock *DefaultBB = SplitBlock(BB, MO.I, DT);
375 BasicBlock::iterator It(*MO.I);
376 ++It;
377 assert(It != DefaultBB->end());
378 BasicBlock *MergeBB = SplitBlock(DefaultBB, &(*It), DT);
379 MergeBB->setName("MemOP.Merge");
380 BFI.setBlockFreq(MergeBB, OrigBBFreq);
381 DefaultBB->setName("MemOP.Default");
382
383 DomTreeUpdater DTU(DT, DomTreeUpdater::UpdateStrategy::Eager);
384 auto &Ctx = Func.getContext();
385 IRBuilder<> IRB(BB);
387 Value *SizeVar = MO.getLength();
388 SwitchInst *SI = IRB.CreateSwitch(SizeVar, DefaultBB, SizeIds.size());
389 Type *MemOpTy = MO.I->getType();
390 PHINode *PHI = nullptr;
391 if (!MemOpTy->isVoidTy()) {
392 // Insert a phi for the return values at the merge block.
393 IRBuilder<> IRBM(MergeBB, MergeBB->getFirstNonPHIIt());
394 PHI = IRBM.CreatePHI(MemOpTy, SizeIds.size() + 1, "MemOP.RVMerge");
395 MO.I->replaceAllUsesWith(PHI);
396 PHI->addIncoming(MO.I, DefaultBB);
397 }
398
399 // Clear the value profile data.
400 MO.I->setMetadata(LLVMContext::MD_prof, nullptr);
401 // If all promoted, we don't need the MD.prof metadata.
402 if (SavedRemainCount > 0 || Version != VDs.size()) {
403 // Otherwise we need update with the un-promoted records back.
404 annotateValueSite(*Func.getParent(), *MO.I, RemainingVDs, SavedRemainCount,
405 IPVK_MemOPSize, VDs.size());
406 }
407
408 LLVM_DEBUG(dbgs() << "\n\n== Basic Block After==\n");
409
410 std::vector<DominatorTree::UpdateType> Updates;
411 if (DT)
412 Updates.reserve(2 * SizeIds.size());
413
414 for (uint64_t SizeId : SizeIds) {
416 Ctx, Twine("MemOP.Case.") + Twine(SizeId), &Func, DefaultBB);
417 MemOp NewMO = MO.clone();
418 // Fix the argument.
419 auto *SizeType = dyn_cast<IntegerType>(NewMO.getLength()->getType());
420 assert(SizeType && "Expected integer type size argument.");
421 ConstantInt *CaseSizeId = ConstantInt::get(SizeType, SizeId);
422 NewMO.setLength(CaseSizeId);
423 NewMO.I->insertInto(CaseBB, CaseBB->end());
424 IRBuilder<> IRBCase(CaseBB);
425 IRBCase.CreateBr(MergeBB);
426 SI->addCase(CaseSizeId, CaseBB);
427 if (!MemOpTy->isVoidTy())
428 PHI->addIncoming(NewMO.I, CaseBB);
429 if (DT) {
430 Updates.push_back({DominatorTree::Insert, CaseBB, MergeBB});
431 Updates.push_back({DominatorTree::Insert, BB, CaseBB});
432 }
433 LLVM_DEBUG(dbgs() << *CaseBB << "\n");
434 }
435 DTU.applyUpdates(Updates);
436 Updates.clear();
437
438 if (MaxCount)
439 setProfMetadata(SI, CaseCounts, MaxCount);
440
441 LLVM_DEBUG(dbgs() << *BB << "\n");
442 LLVM_DEBUG(dbgs() << *DefaultBB << "\n");
443 LLVM_DEBUG(dbgs() << *MergeBB << "\n");
444
445 ORE.emit([&]() {
446 using namespace ore;
447 return OptimizationRemark(DEBUG_TYPE, "memopt-opt", MO.I)
448 << "optimized " << NV("Memop", MO.getName(TLI)) << " with count "
449 << NV("Count", SumForOpt) << " out of " << NV("Total", TotalCount)
450 << " for " << NV("Versions", Version) << " versions";
451 });
452
453 return true;
454}
455} // namespace
456
460 if (DisableMemOPOPT)
461 return false;
462
463 if (F.hasOptSize())
464 return false;
465 MemOPSizeOpt MemOPSizeOpt(F, BFI, ORE, DT, TLI);
466 MemOPSizeOpt.perform();
467 return MemOPSizeOpt.isChanged();
468}
469
472 auto &BFI = FAM.getResult<BlockFrequencyAnalysis>(F);
473 auto &ORE = FAM.getResult<OptimizationRemarkEmitterAnalysis>(F);
474 auto *DT = FAM.getCachedResult<DominatorTreeAnalysis>(F);
475 auto &TLI = FAM.getResult<TargetLibraryAnalysis>(F);
476 bool Changed = PGOMemOPSizeOptImpl(F, BFI, ORE, DT, TLI);
477 if (!Changed)
478 return PreservedAnalyses::all();
479 auto PA = PreservedAnalyses();
480 PA.preserve<DominatorTreeAnalysis>();
481 return PA;
482}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Rewrite undef for PHI
Function Alias Analysis false
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
#define DEBUG_TYPE
IRTranslator LLVM IR MI
This header defines various interfaces for pass management in LLVM.
#define F(x, y, z)
Definition MD5.cpp:55
#define I(x, y, z)
Definition MD5.cpp:58
This file provides the interface for IR based instrumentation passes ( (profile-gen,...
static bool PGOMemOPSizeOptImpl(Function &F, BlockFrequencyInfo &BFI, OptimizationRemarkEmitter &ORE, DominatorTree *DT, TargetLibraryInfo &TLI)
FunctionAnalysisManager FAM
static StringRef getName(Value *V)
void visit(MachineFunction &MF, MachineBasicBlock &Start, std::function< void(MachineBasicBlock *)> op)
static bool isProfitable(const StableFunctionMap::StableFunctionEntries &SFS)
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
#define LLVM_DEBUG(...)
Definition Debug.h:114
iterator end()
Definition BasicBlock.h:472
LLVM_ABI InstListType::const_iterator getFirstNonPHIIt() const
Returns an iterator to the first instruction in this block that is not a PHINode instruction.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition BasicBlock.h:206
InstListType::iterator iterator
Instruction iterators...
Definition BasicBlock.h:170
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...
Definition BasicBlock.h:233
Analysis pass which computes BlockFrequencyInfo.
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
LLVM_ABI void setBlockFreq(const BasicBlock *BB, BlockFrequency Freq)
LLVM_ABI std::optional< uint64_t > getBlockProfileCount(const BasicBlock *BB, bool AllowSynthetic=false) const
Returns the estimated profile count of BB.
LLVM_ABI BlockFrequency getBlockFreq(const BasicBlock *BB) const
getblockFreq - Return block frequency.
Value * getArgOperand(unsigned i) const
Analysis pass which computes a DominatorTree.
Definition Dominators.h:284
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:165
Base class for instruction visitors.
Definition InstVisitor.h:78
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
This is the common base class for memset/memcpy/memmove.
The optimization diagnostic interface.
LLVM_ABI void emit(DiagnosticInfoOptimizationBase &OptDiag)
Output the remark via the diagnostic handler and to the optimization record file.
LLVM_ABI PreservedAnalyses run(Function &F, FunctionAnalysisManager &MAM)
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
iterator insert(iterator I, T &&Elt)
void push_back(const T &Elt)
Analysis pass providing the TargetLibraryInfo.
Provides information about what library functions are available for the current target.
bool getLibFunc(StringRef funcName, LibFunc &F) const
Searches for a particular function name.
bool isVoidTy() const
Return true if this is 'void'.
Definition Type.h:139
LLVM_ABI void setName(const Twine &Name)
Change the name of the value.
Definition Value.cpp:390
std::pair< iterator, bool > insert(const ValueT &V)
Definition DenseSet.h:202
Changed
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:81
initializer< Ty > init(const Ty &Val)
DiagnosticInfoOptimizationBase::Argument NV
NodeAddr< FuncNode * > Func
Definition RDFGraph.h:393
friend class Instruction
Iterator for Instructions in a `BasicBlock.
Definition BasicBlock.h:73
This is an optimization pass for GlobalISel generic memory operations.
@ Length
Definition DWP.cpp:477
FunctionAddr VTableAddr Value
Definition InstrProf.h:137
LLVM_ABI void setProfMetadata(Instruction *TI, ArrayRef< uint64_t > EdgeCounts, uint64_t MaxCount)
static cl::opt< bool > MemOPScaleCount("pgo-memop-scale-count", cl::init(true), cl::Hidden, cl::desc("Scale the memop size counts using the basic " " block count value"))
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:644
static cl::opt< bool > DisableMemOPOPT("disable-memop-opt", cl::init(false), cl::Hidden, cl::desc("Disable optimize"))
static cl::opt< unsigned > MemOPCountThreshold("pgo-memop-count-threshold", cl::Hidden, cl::init(1000), cl::desc("The minimum count to optimize memory " "intrinsic calls"))
static cl::opt< unsigned > MemOpMaxOptSize("memop-value-prof-max-opt-size", cl::Hidden, cl::init(128), cl::desc("Optimize the memop size <= this value"))
FunctionAddr VTableAddr uintptr_t uintptr_t Version
Definition InstrProf.h:302
LLVM_ABI void annotateValueSite(Module &M, Instruction &Inst, const InstrProfRecord &InstrProfR, InstrProfValueKind ValueKind, uint32_t SiteIndx, uint32_t MaxMDCount=3)
Get the value profile data for value site SiteIdx from InstrProfR and annotate the instruction Inst w...
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:207
FunctionAddr VTableAddr Count
Definition InstrProf.h:139
cl::opt< bool > MemOPOptMemcmpBcmp("pgo-memop-optimize-memcmp-bcmp", cl::init(true), cl::Hidden, cl::desc("Size-specialize memcmp and bcmp calls"))
LLVM_ABI SmallVector< InstrProfValueData, 4 > getValueProfDataFromInst(const Instruction &Inst, InstrProfValueKind ValueKind, uint32_t MaxNumValueData, uint64_t &TotalC, bool GetNoICPValue=false)
Extract the value profile data from Inst and returns them if Inst is annotated with value profile dat...
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:548
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
std::enable_if_t< std::is_unsigned_v< T >, T > SaturatingMultiply(T X, T Y, bool *ResultOverflowed=nullptr)
Multiply two unsigned integers, X and Y, of type T.
Definition MathExtras.h:649
static cl::opt< unsigned > MemOPMaxVersion("pgo-memop-max-version", cl::init(3), cl::Hidden, cl::desc("The max version for the optimized memory " " intrinsic calls"))
static cl::opt< unsigned > MemOPPercentThreshold("pgo-memop-percent-threshold", cl::init(40), cl::Hidden, cl::desc("The percentage threshold for the " "memory intrinsic calls optimization"))
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:560
LLVM_ABI BasicBlock * SplitBlock(BasicBlock *Old, BasicBlock::iterator SplitPt, DominatorTree *DT, LoopInfo *LI=nullptr, MemorySSAUpdater *MSSAU=nullptr, const Twine &BBName="", bool Before=false)
Split the specified block at the specified instruction.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
uint64_t size() const