LLVM 24.0.0git
IndirectCallPromotion.cpp
Go to the documentation of this file.
1//===- IndirectCallPromotion.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 promotes indirect calls to
10// conditional direct calls when the indirect-call value profile metadata is
11// available.
12//
13//===----------------------------------------------------------------------===//
14
16#include "llvm/ADT/ArrayRef.h"
17#include "llvm/ADT/DenseMap.h"
18#include "llvm/ADT/Statistic.h"
19#include "llvm/ADT/StringRef.h"
26#include "llvm/IR/Dominators.h"
27#include "llvm/IR/Function.h"
28#include "llvm/IR/InstrTypes.h"
30#include "llvm/IR/LLVMContext.h"
31#include "llvm/IR/MDBuilder.h"
32#include "llvm/IR/PassManager.h"
34#include "llvm/IR/Value.h"
39#include "llvm/Support/Debug.h"
40#include "llvm/Support/Error.h"
45#include <cassert>
46#include <cstdint>
47#include <set>
48#include <string>
49#include <utility>
50#include <vector>
51
52using namespace llvm;
53
54#define DEBUG_TYPE "pgo-icall-prom"
55
56STATISTIC(NumOfPGOICallPromotion, "Number of indirect call promotions.");
57STATISTIC(NumOfPGOICallsites, "Number of indirect call candidate sites.");
58
59namespace llvm {
61} // namespace llvm
62
63namespace {
64
65// The key is a vtable global variable, and the value is a map.
66// In the inner map, the key represents address point offsets and the value is a
67// constant for this address point.
68using VTableAddressPointOffsetValMap =
70
71// A struct to collect type information for a virtual call site.
72struct VirtualCallSiteInfo {
73 // The offset from the address point to virtual function in the vtable.
74 uint64_t FunctionOffset;
75 // The instruction that computes the address point of vtable.
76 Instruction *VPtr;
77 // The compatible type used in LLVM type intrinsics.
78 StringRef CompatibleTypeStr;
79};
80
81// The key is a virtual call, and value is its type information.
82using VirtualCallSiteTypeInfoMap =
84
85// The key is vtable GUID, and value is its value profile count.
86using VTableGUIDCountsMap = SmallDenseMap<uint64_t, uint64_t, 16>;
87
88// Return the address point offset of the given compatible type.
89//
90// Type metadata of a vtable specifies the types that can contain a pointer to
91// this vtable, for example, `Base*` can be a pointer to an derived type
92// but not vice versa. See also https://llvm.org/docs/TypeMetadata.html
93static std::optional<uint64_t>
94getAddressPointOffset(const GlobalVariable &VTableVar,
95 StringRef CompatibleType) {
97 VTableVar.getMetadata(LLVMContext::MD_type, Types);
98
99 for (MDNode *Type : Types)
100 if (auto *TypeId = dyn_cast<MDString>(Type->getOperand(1).get());
101 TypeId && TypeId->getString() == CompatibleType)
102 return cast<ConstantInt>(
103 cast<ConstantAsMetadata>(Type->getOperand(0))->getValue())
104 ->getZExtValue();
105
106 return std::nullopt;
107}
108
109// Return a constant representing the vtable's address point specified by the
110// offset.
111static Constant *getVTableAddressPointOffset(GlobalVariable *VTable,
112 uint32_t AddressPointOffset) {
113 Module &M = *VTable->getParent();
114 LLVMContext &Context = M.getContext();
115 assert(AddressPointOffset < VTable->getGlobalSize(M.getDataLayout()) &&
116 "Out-of-bound access");
117
119 VTable,
120 llvm::ConstantInt::get(Type::getInt32Ty(Context), AddressPointOffset));
121}
122
123// Return the basic block in which Use `U` is used via its `UserInst`.
124static BasicBlock *getUserBasicBlock(Use &U, Instruction *UserInst) {
125 if (PHINode *PN = dyn_cast<PHINode>(UserInst))
126 return PN->getIncomingBlock(U);
127
128 return UserInst->getParent();
129}
130
131// `DestBB` is a suitable basic block to sink `Inst` into when `Inst` have users
132// and all users are in `DestBB`. The caller guarantees that `Inst->getParent()`
133// is the sole predecessor of `DestBB` and `DestBB` is dominated by
134// `Inst->getParent()`.
135static bool isDestBBSuitableForSink(Instruction *Inst, BasicBlock *DestBB) {
136 // 'BB' is used only by assert.
137 [[maybe_unused]] BasicBlock *BB = Inst->getParent();
138
139 assert(BB != DestBB && BB->getTerminator()->getNumSuccessors() == 2 &&
140 DestBB->getUniquePredecessor() == BB &&
141 "Guaranteed by ICP transformation");
142
143 BasicBlock *UserBB = nullptr;
144 for (Use &Use : Inst->uses()) {
145 User *User = Use.getUser();
146 // Do checked cast since IR verifier guarantees that the user of an
147 // instruction must be an instruction. See `Verifier::visitInstruction`.
149 UserBB = getUserBasicBlock(Use, UserInst);
150 // Do not sink if Inst is used in a basic block that is not DestBB.
151 // TODO: Sink to the common dominator of all user blocks.
152 if (UserBB != DestBB)
153 return false;
154 }
155 return UserBB != nullptr;
156}
157
158// For the virtual call dispatch sequence, try to sink vtable load instructions
159// to the cold indirect call fallback.
160// FIXME: Move the sink eligibility check below to a utility function in
161// Transforms/Utils/ directory.
162static bool tryToSinkInstruction(Instruction *I, BasicBlock *DestBlock) {
163 if (!isDestBBSuitableForSink(I, DestBlock))
164 return false;
165
166 // Do not move control-flow-involving, volatile loads, vaarg, alloca
167 // instructions, etc.
168 if (isa<PHINode>(I) || I->isEHPad() || I->mayThrow() || !I->willReturn() ||
170 return false;
171
172 // Do not sink convergent call instructions.
173 if (const auto *C = dyn_cast<CallBase>(I))
174 if (C->isInlineAsm() || C->cannotMerge() || C->isConvergent())
175 return false;
176
177 // Do not move an instruction that may write to memory.
178 if (I->mayWriteToMemory())
179 return false;
180
181 // We can only sink load instructions if there is nothing between the load and
182 // the end of block that could change the value.
183 if (I->mayReadFromMemory()) {
184 // We already know that SrcBlock is the unique predecessor of DestBlock.
185 for (BasicBlock::iterator Scan = std::next(I->getIterator()),
186 E = I->getParent()->end();
187 Scan != E; ++Scan) {
188 // Note analysis analysis can tell whether two pointers can point to the
189 // same object in memory or not thereby find further opportunities to
190 // sink.
191 if (Scan->mayWriteToMemory())
192 return false;
193 }
194 }
195
196 BasicBlock::iterator InsertPos = DestBlock->getFirstInsertionPt();
197 I->moveBefore(*DestBlock, InsertPos);
198
199 // TODO: Sink debug intrinsic users of I to 'DestBlock'.
200 // 'InstCombinerImpl::tryToSinkInstructionDbgValues' and
201 // 'InstCombinerImpl::tryToSinkInstructionDbgVariableRecords' already have
202 // the core logic to do this.
203 return true;
204}
205
206// Try to sink instructions after VPtr to the indirect call fallback.
207// Return the number of sunk IR instructions.
208static int tryToSinkInstructions(BasicBlock *OriginalBB,
209 BasicBlock *IndirectCallBB) {
210 int SinkCount = 0;
211 // Do not sink across a critical edge for simplicity.
212 if (IndirectCallBB->getUniquePredecessor() != OriginalBB)
213 return SinkCount;
214 // Sink all eligible instructions in OriginalBB in reverse order.
215 for (Instruction &I :
217 if (tryToSinkInstruction(&I, IndirectCallBB))
218 SinkCount++;
219
220 return SinkCount;
221}
222
223// Promote indirect calls to conditional direct calls, keeping track of
224// thresholds.
225class IndirectCallPromoter {
226private:
227 const InstrumentationOptions &Opts;
228 Function &F;
229 Module &M;
230
231 // Symtab that maps indirect call profile values to function names and
232 // defines.
233 InstrProfSymtab *const Symtab;
234
235 const bool SamplePGO;
236
237 // A map from a virtual call to its type information.
238 const VirtualCallSiteTypeInfoMap &VirtualCSInfo;
239
240 VTableAddressPointOffsetValMap &VTableAddressPointOffsetVal;
241
242 OptimizationRemarkEmitter &ORE;
243
244 const DenseSet<StringRef> &IgnoredBaseTypes;
245
246 // A struct that records the direct target and it's call count.
247 struct PromotionCandidate {
248 Function *const TargetFunction;
249 const uint64_t Count;
250 const uint32_t Index;
251
252 // The following fields only exists for promotion candidates with vtable
253 // information.
254 //
255 // Due to class inheritance, one virtual call candidate can come from
256 // multiple vtables. `VTableGUIDAndCounts` tracks the vtable GUIDs and
257 // counts for 'TargetFunction'. `AddressPoints` stores the vtable address
258 // points for comparison.
259 VTableGUIDCountsMap VTableGUIDAndCounts;
260 SmallVector<Constant *> AddressPoints;
261
262 PromotionCandidate(Function *F, uint64_t C, uint32_t I)
263 : TargetFunction(F), Count(C), Index(I) {}
264 };
265
266 // Check if the indirect-call call site should be promoted. Return the number
267 // of promotions. Inst is the candidate indirect call, ValueDataRef
268 // contains the array of value profile data for profiled targets,
269 // TotalCount is the total profiled count of call executions, and
270 // NumCandidates is the number of candidate entries in ValueDataRef.
271 std::vector<PromotionCandidate> getPromotionCandidatesForCallSite(
272 const CallBase &CB, ArrayRef<InstrProfValueData> ValueDataRef,
273 uint64_t TotalCount, uint32_t NumCandidates);
274
275 // Promote a list of targets for one indirect-call callsite by comparing
276 // indirect callee with functions. Return true if there are IR
277 // transformations and false otherwise.
278 bool tryToPromoteWithFuncCmp(
279 CallBase &CB, Instruction *VPtr, ArrayRef<PromotionCandidate> Candidates,
280 uint64_t TotalCount, MutableArrayRef<InstrProfValueData> ICallProfDataRef,
281 uint32_t NumCandidates, VTableGUIDCountsMap &VTableGUIDCounts);
282
283 // Promote a list of targets for one indirect call by comparing vtables with
284 // functions. Return true if there are IR transformations and false
285 // otherwise.
286 bool tryToPromoteWithVTableCmp(
287 CallBase &CB, Instruction *VPtr, ArrayRef<PromotionCandidate> Candidates,
288 uint64_t TotalFuncCount, uint32_t NumCandidates,
290 VTableGUIDCountsMap &VTableGUIDCounts);
291
292 // Return true if it's profitable to compare vtables for the callsite.
293 bool isProfitableToCompareVTables(const CallBase &CB,
295
296 // Return true if the vtable corresponding to VTableGUID should be skipped
297 // for vtable-based comparison.
298 bool shouldSkipVTable(uint64_t VTableGUID);
299
300 // Given an indirect callsite and the list of function candidates, compute
301 // the following vtable information in output parameters and return vtable
302 // pointer if type profiles exist.
303 // - Populate `VTableGUIDCounts` with <vtable-guid, count> using !prof
304 // metadata attached on the vtable pointer.
305 // - For each function candidate, finds out the vtables from which it gets
306 // called and stores the <vtable-guid, count> in promotion candidate.
307 Instruction *computeVTableInfos(const CallBase *CB,
308 VTableGUIDCountsMap &VTableGUIDCounts,
309 std::vector<PromotionCandidate> &Candidates);
310
311 Constant *getOrCreateVTableAddressPointVar(GlobalVariable *GV,
312 uint64_t AddressPointOffset);
313
314 void updateFuncValueProfiles(CallBase &CB,
316 uint64_t Sum, uint32_t MaxMDCount);
317
318 void updateVPtrValueProfiles(Instruction *VPtr,
319 VTableGUIDCountsMap &VTableGUIDCounts);
320
321 bool isValidTarget(uint64_t, Function *, const CallBase &, uint64_t);
322
323public:
324 IndirectCallPromoter(
325 const InstrumentationOptions &Opts, Function &Func, Module &M,
326 InstrProfSymtab *Symtab, bool SamplePGO,
327 const VirtualCallSiteTypeInfoMap &VirtualCSInfo,
328 VTableAddressPointOffsetValMap &VTableAddressPointOffsetVal,
329 const DenseSet<StringRef> &IgnoredBaseTypes,
330 OptimizationRemarkEmitter &ORE)
331 : Opts(Opts), F(Func), M(M), Symtab(Symtab), SamplePGO(SamplePGO),
332 VirtualCSInfo(VirtualCSInfo),
333 VTableAddressPointOffsetVal(VTableAddressPointOffsetVal), ORE(ORE),
334 IgnoredBaseTypes(IgnoredBaseTypes) {}
335 IndirectCallPromoter(const IndirectCallPromoter &) = delete;
336 IndirectCallPromoter &operator=(const IndirectCallPromoter &) = delete;
337
338 bool processFunction(ProfileSummaryInfo *PSI);
339};
340
341} // end anonymous namespace
342
343bool IndirectCallPromoter::isValidTarget(uint64_t Target,
344 Function *TargetFunction,
345 const CallBase &CB, uint64_t Count) {
346 // Don't promote if the symbol is not defined in the module. This avoids
347 // creating a reference to a symbol that doesn't exist in the module
348 // This can happen when we compile with a sample profile collected from
349 // one binary but used for another, which may have profiled targets that
350 // aren't used in the new binary. We might have a declaration initially in
351 // the case where the symbol is globally dead in the binary and removed by
352 // ThinLTO.
353 using namespace ore;
354 if (TargetFunction == nullptr) {
355 LLVM_DEBUG(dbgs() << " Not promote: Cannot find the target\n");
356 ORE.emit([&]() {
357 return OptimizationRemarkMissed(DEBUG_TYPE, "UnableToFindTarget", &CB)
358 << "Cannot promote indirect call: target with md5sum "
359 << NV("target md5sum", Target)
360 << " not found (count=" << NV("Count", Count) << ")";
361 });
362 return false;
363 }
364 if (!Opts.icp_allow_decls && TargetFunction->isDeclaration()) {
365 LLVM_DEBUG(dbgs() << " Not promote: target definition is not available\n");
366 ORE.emit([&]() {
367 return OptimizationRemarkMissed(DEBUG_TYPE, "NoTargetDef", &CB)
368 << "Do not promote indirect call: target with md5sum "
369 << NV("target md5sum", Target)
370 << " definition not available (count=" << ore::NV("Count", Count)
371 << ")";
372 });
373 return false;
374 }
375
376 const char *Reason = nullptr;
377 if (!isLegalToPromote(CB, TargetFunction, &Reason)) {
378
379 ORE.emit([&]() {
380 return OptimizationRemarkMissed(DEBUG_TYPE, "UnableToPromote", &CB)
381 << "Cannot promote indirect call to "
382 << NV("TargetFunction", TargetFunction)
383 << " (count=" << NV("Count", Count) << "): " << Reason;
384 });
385 return false;
386 }
387 return true;
388}
389
390// Indirect-call promotion heuristic. The direct targets are sorted based on
391// the count. Stop at the first target that is not promoted.
392std::vector<IndirectCallPromoter::PromotionCandidate>
393IndirectCallPromoter::getPromotionCandidatesForCallSite(
394 const CallBase &CB, ArrayRef<InstrProfValueData> ValueDataRef,
395 uint64_t TotalCount, uint32_t NumCandidates) {
396 std::vector<PromotionCandidate> Ret;
397
398 LLVM_DEBUG(dbgs() << " \nWork on callsite #" << NumOfPGOICallsites << CB
399 << " Num_targets: " << ValueDataRef.size()
400 << " Num_candidates: " << NumCandidates << "\n");
401 NumOfPGOICallsites++;
402 if (Opts.icp_csskip != 0 && NumOfPGOICallsites <= Opts.icp_csskip) {
403 LLVM_DEBUG(dbgs() << " Skip: User options.\n");
404 return Ret;
405 }
406
407 for (uint32_t I = 0; I < NumCandidates; I++) {
408 uint64_t Count = ValueDataRef[I].Count;
409 assert(Count <= TotalCount);
410 (void)TotalCount;
411 uint64_t Target = ValueDataRef[I].Value;
412 LLVM_DEBUG(dbgs() << " Candidate " << I << " Count=" << Count
413 << " Target_func: " << Target << "\n");
414
415 if (Opts.icp_invoke_only && isa<CallInst>(CB)) {
416 LLVM_DEBUG(dbgs() << " Not promote: User options.\n");
417 ORE.emit([&]() {
418 return OptimizationRemarkMissed(DEBUG_TYPE, "UserOptions", &CB)
419 << " Not promote: User options";
420 });
421 break;
422 }
423 if (Opts.icp_call_only && isa<InvokeInst>(CB)) {
424 LLVM_DEBUG(dbgs() << " Not promote: User option.\n");
425 ORE.emit([&]() {
426 return OptimizationRemarkMissed(DEBUG_TYPE, "UserOptions", &CB)
427 << " Not promote: User options";
428 });
429 break;
430 }
431 if (Opts.icp_cutoff != 0 && NumOfPGOICallPromotion >= Opts.icp_cutoff) {
432 LLVM_DEBUG(dbgs() << " Not promote: Cutoff reached.\n");
433 ORE.emit([&]() {
434 return OptimizationRemarkMissed(DEBUG_TYPE, "CutOffReached", &CB)
435 << " Not promote: Cutoff reached";
436 });
437 break;
438 }
439
440 Function *TargetFunction = Symtab->getFunction(Target);
441 if (!isValidTarget(Target, TargetFunction, CB, Count)) {
442 if (Opts.icp_allow_candidate_skip)
443 continue;
444 else
445 break;
446 }
447
448 Ret.push_back(PromotionCandidate(TargetFunction, Count, I));
449 TotalCount -= Count;
450 }
451 return Ret;
452}
453
454Constant *IndirectCallPromoter::getOrCreateVTableAddressPointVar(
455 GlobalVariable *GV, uint64_t AddressPointOffset) {
456 auto [Iter, Inserted] =
457 VTableAddressPointOffsetVal[GV].try_emplace(AddressPointOffset, nullptr);
458 if (Inserted)
459 Iter->second = getVTableAddressPointOffset(GV, AddressPointOffset);
460 return Iter->second;
461}
462
463Instruction *IndirectCallPromoter::computeVTableInfos(
464 const CallBase *CB, VTableGUIDCountsMap &GUIDCountsMap,
465 std::vector<PromotionCandidate> &Candidates) {
467 return nullptr;
468
469 // Take the following code sequence as an example, here is how the code works
470 // @vtable1 = {[n x ptr] [... ptr @func1]}
471 // @vtable2 = {[m x ptr] [... ptr @func2]}
472 //
473 // %vptr = load ptr, ptr %d, !prof !0
474 // %0 = tail call i1 @llvm.type.test(ptr %vptr, metadata !"vtable1")
475 // tail call void @llvm.assume(i1 %0)
476 // %vfn = getelementptr inbounds ptr, ptr %vptr, i64 1
477 // %1 = load ptr, ptr %vfn
478 // call void %1(ptr %d), !prof !1
479 //
480 // !0 = !{!"VP", i32 2, i64 100, i64 123, i64 50, i64 456, i64 50}
481 // !1 = !{!"VP", i32 0, i64 100, i64 789, i64 50, i64 579, i64 50}
482 //
483 // Step 1. Find out the %vptr instruction for indirect call and use its !prof
484 // to populate `GUIDCountsMap`.
485 // Step 2. For each vtable-guid, look up its definition from symtab. LTO can
486 // make vtable definitions visible across modules.
487 // Step 3. Compute the byte offset of the virtual call, by adding vtable
488 // address point offset and function's offset relative to vtable address
489 // point. For each function candidate, this step tells us the vtable from
490 // which it comes from, and the vtable address point to compare %vptr with.
491
492 // Only virtual calls have virtual call site info.
493 auto Iter = VirtualCSInfo.find(CB);
494 if (Iter == VirtualCSInfo.end())
495 return nullptr;
496
497 LLVM_DEBUG(dbgs() << "\nComputing vtable infos for callsite #"
498 << NumOfPGOICallsites << "\n");
499
500 const auto &VirtualCallInfo = Iter->second;
501 Instruction *VPtr = VirtualCallInfo.VPtr;
502
503 SmallDenseMap<Function *, int, 4> CalleeIndexMap;
504 for (size_t I = 0; I < Candidates.size(); I++)
505 CalleeIndexMap[Candidates[I].TargetFunction] = I;
506
507 uint64_t TotalVTableCount = 0;
508 auto VTableValueDataArray = getValueProfDataFromInst(
509 *VirtualCallInfo.VPtr, IPVK_VTableTarget,
510 getMaxNumVTableAnnotations(VPtr->getContext()), TotalVTableCount);
511 if (VTableValueDataArray.empty())
512 return VPtr;
513
514 // Compute the functions and counts from by each vtable.
515 for (const auto &V : VTableValueDataArray) {
516 uint64_t VTableVal = V.Value;
517 GUIDCountsMap[VTableVal] = V.Count;
518 GlobalVariable *VTableVar = Symtab->getGlobalVariable(VTableVal);
519 if (!VTableVar) {
520 LLVM_DEBUG(dbgs() << " Cannot find vtable definition for " << VTableVal
521 << "; maybe the vtable isn't imported\n");
522 continue;
523 }
524
525 std::optional<uint64_t> MaybeAddressPointOffset =
526 getAddressPointOffset(*VTableVar, VirtualCallInfo.CompatibleTypeStr);
527 if (!MaybeAddressPointOffset)
528 continue;
529
530 const uint64_t AddressPointOffset = *MaybeAddressPointOffset;
531
532 Function *Callee = nullptr;
533 std::tie(Callee, std::ignore) = getFunctionAtVTableOffset(
534 VTableVar, AddressPointOffset + VirtualCallInfo.FunctionOffset, M);
535 if (!Callee)
536 continue;
537 auto CalleeIndexIter = CalleeIndexMap.find(Callee);
538 if (CalleeIndexIter == CalleeIndexMap.end())
539 continue;
540
541 auto &Candidate = Candidates[CalleeIndexIter->second];
542 // There should never be duplicate GUIDs in one !prof metdata, as this is
543 // an IR invariant enforced by the verifier. Assigning counters directly
544 // won't cause overwrite or counter loss.
545 Candidate.VTableGUIDAndCounts[VTableVal] = V.Count;
546 Candidate.AddressPoints.push_back(
547 getOrCreateVTableAddressPointVar(VTableVar, AddressPointOffset));
548 }
549
550 return VPtr;
551}
552
553// Creates 'branch_weights' prof metadata using TrueWeight and FalseWeight.
554// Scales uint64_t counters down to uint32_t if necessary to prevent overflow.
555static MDNode *createBranchWeights(LLVMContext &Context, uint64_t TrueWeight,
556 uint64_t FalseWeight) {
557 MDBuilder MDB(Context);
558 uint64_t Scale = calculateCountScale(std::max(TrueWeight, FalseWeight));
559 return MDB.createBranchWeights(scaleBranchCount(TrueWeight, Scale),
560 scaleBranchCount(FalseWeight, Scale));
561}
562
564 uint64_t Count, uint64_t TotalCount,
565 bool AttachProfToDirectCall,
568 CB, DirectCallee,
569 createBranchWeights(CB.getContext(), Count, TotalCount - Count));
570
571 if (AttachProfToDirectCall)
572 setFittedBranchWeights(NewInst, {Count},
573 /*IsExpected=*/false);
574
575 using namespace ore;
576
577 if (ORE)
578 ORE->emit([&]() {
579 return OptimizationRemark(DEBUG_TYPE, "Promoted", &CB)
580 << "Promote indirect call to " << NV("DirectCallee", DirectCallee)
581 << " with count " << NV("Count", Count) << " out of "
582 << NV("TotalCount", TotalCount);
583 });
584 return NewInst;
585}
586
587// Promote indirect-call to conditional direct-call for one callsite.
588bool IndirectCallPromoter::tryToPromoteWithFuncCmp(
590 uint64_t TotalCount, MutableArrayRef<InstrProfValueData> ICallProfDataRef,
591 uint32_t NumCandidates, VTableGUIDCountsMap &VTableGUIDCounts) {
592 uint32_t NumPromoted = 0;
593
594 for (const auto &C : Candidates) {
595 uint64_t FuncCount = C.Count;
596 pgo::promoteIndirectCall(CB, C.TargetFunction, FuncCount, TotalCount,
597 SamplePGO, &ORE);
598 assert(TotalCount >= FuncCount);
599 TotalCount -= FuncCount;
600 NumOfPGOICallPromotion++;
601 NumPromoted++;
602
603 // Update the count and this entry will be erased later.
604 ICallProfDataRef[C.Index].Count = 0;
605 if (!EnableVTableProfileUse || C.VTableGUIDAndCounts.empty())
606 continue;
607
608 // After a virtual call candidate gets promoted, update the vtable's counts
609 // proportionally. Each vtable-guid in `C.VTableGUIDAndCounts` represents
610 // a vtable from which the virtual call is loaded. Compute the sum and use
611 // 128-bit APInt to improve accuracy.
612 uint64_t SumVTableCount = 0;
613 for (const auto &[GUID, VTableCount] : C.VTableGUIDAndCounts)
614 SumVTableCount += VTableCount;
615
616 for (const auto &[GUID, VTableCount] : C.VTableGUIDAndCounts) {
617 APInt APFuncCount((unsigned)128, FuncCount, false /*signed*/);
618 APFuncCount *= VTableCount;
619 VTableGUIDCounts[GUID] -= APFuncCount.udiv(SumVTableCount).getZExtValue();
620 }
621 }
622 if (NumPromoted == 0)
623 return false;
624
625 assert(NumPromoted <= ICallProfDataRef.size() &&
626 "Number of promoted functions should not be greater than the number "
627 "of values in profile metadata");
628
629 updateFuncValueProfiles(CB, ICallProfDataRef, TotalCount, NumCandidates);
630 updateVPtrValueProfiles(VPtr, VTableGUIDCounts);
631 return true;
632}
633
634void IndirectCallPromoter::updateFuncValueProfiles(
635 CallBase &CB, MutableArrayRef<InstrProfValueData> CallVDs,
636 uint64_t TotalCount, uint32_t MaxMDCount) {
637 // First clear the existing !prof.
638 CB.setMetadata(LLVMContext::MD_prof, nullptr);
639
640 // Sort value profiles by count in descending order.
641 llvm::stable_sort(CallVDs, [](const InstrProfValueData &LHS,
642 const InstrProfValueData &RHS) {
643 return LHS.Count > RHS.Count;
644 });
645 // Drop the <target-value, count> pair if count is zero.
647 CallVDs.begin(),
648 llvm::upper_bound(CallVDs, 0U,
649 [](uint64_t Count, const InstrProfValueData &ProfData) {
650 return ProfData.Count <= Count;
651 }));
652
653 // Annotate the remaining value profiles if counter is not zero.
654 if (TotalCount != 0)
655 annotateValueSite(M, CB, VDs, TotalCount, IPVK_IndirectCallTarget,
656 MaxMDCount);
657}
658
659void IndirectCallPromoter::updateVPtrValueProfiles(
660 Instruction *VPtr, VTableGUIDCountsMap &VTableGUIDCounts) {
661 if (!EnableVTableProfileUse || VPtr == nullptr ||
662 !VPtr->getMetadata(LLVMContext::MD_prof))
663 return;
664 VPtr->setMetadata(LLVMContext::MD_prof, nullptr);
665 std::vector<InstrProfValueData> VTableValueProfiles;
666 uint64_t TotalVTableCount = 0;
667 for (auto [GUID, Count] : VTableGUIDCounts) {
668 if (Count == 0)
669 continue;
670
671 VTableValueProfiles.push_back({GUID, Count});
672 TotalVTableCount += Count;
673 }
674 llvm::sort(VTableValueProfiles,
675 [](const InstrProfValueData &LHS, const InstrProfValueData &RHS) {
676 return LHS.Count > RHS.Count;
677 });
678
679 annotateValueSite(M, *VPtr, VTableValueProfiles, TotalVTableCount,
680 IPVK_VTableTarget, VTableValueProfiles.size());
681}
682
683bool IndirectCallPromoter::tryToPromoteWithVTableCmp(
684 CallBase &CB, Instruction *VPtr, ArrayRef<PromotionCandidate> Candidates,
685 uint64_t TotalFuncCount, uint32_t NumCandidates,
687 VTableGUIDCountsMap &VTableGUIDCounts) {
688 SmallVector<std::pair<uint32_t, uint64_t>, 4> PromotedFuncCount;
689
690 for (const auto &Candidate : Candidates) {
691 for (auto &[GUID, Count] : Candidate.VTableGUIDAndCounts)
692 VTableGUIDCounts[GUID] -= Count;
693
694 // 'OriginalBB' is the basic block of indirect call. After each candidate
695 // is promoted, a new basic block is created for the indirect fallback basic
696 // block and indirect call `CB` is moved into this new BB.
697 BasicBlock *OriginalBB = CB.getParent();
699 CB, VPtr, Candidate.TargetFunction, Candidate.AddressPoints,
700 createBranchWeights(CB.getContext(), Candidate.Count,
701 TotalFuncCount - Candidate.Count));
702
703 int SinkCount = tryToSinkInstructions(OriginalBB, CB.getParent());
704
705 ORE.emit([&]() {
706 OptimizationRemark Remark(DEBUG_TYPE, "Promoted", &CB);
707
708 const auto &VTableGUIDAndCounts = Candidate.VTableGUIDAndCounts;
709 Remark << "Promote indirect call to "
710 << ore::NV("DirectCallee", Candidate.TargetFunction)
711 << " with count " << ore::NV("Count", Candidate.Count)
712 << " out of " << ore::NV("TotalCount", TotalFuncCount) << ", sink "
713 << ore::NV("SinkCount", SinkCount)
714 << " instruction(s) and compare "
715 << ore::NV("VTable", VTableGUIDAndCounts.size())
716 << " vtable(s): {";
717
718 // Sort GUIDs so remark message is deterministic.
719 std::set<uint64_t> GUIDSet;
720 for (auto [GUID, Count] : VTableGUIDAndCounts)
721 GUIDSet.insert(GUID);
722 for (auto Iter = GUIDSet.begin(); Iter != GUIDSet.end(); Iter++) {
723 if (Iter != GUIDSet.begin())
724 Remark << ", ";
725 Remark << ore::NV("VTable", Symtab->getGlobalVariable(*Iter));
726 }
727
728 Remark << "}";
729
730 return Remark;
731 });
732
733 PromotedFuncCount.push_back({Candidate.Index, Candidate.Count});
734
735 assert(TotalFuncCount >= Candidate.Count &&
736 "Within one prof metadata, total count is the sum of counts from "
737 "individual <target, count> pairs");
738 // Use std::min since 'TotalFuncCount' is the saturated sum of individual
739 // counts, see
740 // https://github.com/llvm/llvm-project/blob/abedb3b8356d5d56f1c575c4f7682fba2cb19787/llvm/lib/ProfileData/InstrProf.cpp#L1281-L1288
741 TotalFuncCount -= std::min(TotalFuncCount, Candidate.Count);
742 NumOfPGOICallPromotion++;
743 }
744
745 if (PromotedFuncCount.empty())
746 return false;
747
748 // Update value profiles for 'CB' and 'VPtr', assuming that each 'CB' has a
749 // a distinct 'VPtr'.
750 // FIXME: When Clang `-fstrict-vtable-pointers` is enabled, a vtable might be
751 // used to load multiple virtual functions. The vtable profiles needs to be
752 // updated properly in that case (e.g, for each indirect call annotate both
753 // type profiles and function profiles in one !prof).
754 for (size_t I = 0; I < PromotedFuncCount.size(); I++) {
755 uint32_t Index = PromotedFuncCount[I].first;
756 ICallProfDataRef[Index].Count -=
757 std::max(PromotedFuncCount[I].second, ICallProfDataRef[Index].Count);
758 }
759 updateFuncValueProfiles(CB, ICallProfDataRef, TotalFuncCount, NumCandidates);
760 updateVPtrValueProfiles(VPtr, VTableGUIDCounts);
761 return true;
762}
763
764// Traverse all the indirect-call callsite and get the value profile
765// annotation to perform indirect-call promotion.
766bool IndirectCallPromoter::processFunction(ProfileSummaryInfo *PSI) {
767 bool Changed = false;
768 ICallPromotionAnalysis ICallAnalysis;
769 for (auto *CB : findIndirectCalls(F)) {
770 uint32_t NumCandidates;
771 uint64_t TotalCount;
772 auto ICallProfDataRef = ICallAnalysis.getPromotionCandidatesForInstruction(
773 CB, TotalCount, NumCandidates);
774 if (!NumCandidates)
775 continue;
776 if (PSI && PSI->hasProfileSummary()) {
777 // Don't promote cold candidates.
778 if (PSI->isColdCount(TotalCount)) {
779 LLVM_DEBUG(dbgs() << "Don't promote the cold candidate: TotalCount="
780 << TotalCount << "\n");
781 continue;
782 }
783 // Only promote hot if -icp-allow-hot-only is true. ICP has its own cutoff
784 // threshold for hotness, which defaults to ProfileSummaryCutoffHot if
785 // unspecified.
786 if (Opts.icp_allow_hot_only &&
787 !PSI->isHotCountNthPercentile(Opts.hot_func_cutoff_for_icp == -1
789 : Opts.hot_func_cutoff_for_icp,
790 TotalCount)) {
791 LLVM_DEBUG(dbgs() << "Don't promote the non-hot candidate: TotalCount="
792 << TotalCount << "\n");
793 continue;
794 }
795 }
796
797 auto PromotionCandidates = getPromotionCandidatesForCallSite(
798 *CB, ICallProfDataRef, TotalCount, NumCandidates);
799
800 VTableGUIDCountsMap VTableGUIDCounts;
801 Instruction *VPtr =
802 computeVTableInfos(CB, VTableGUIDCounts, PromotionCandidates);
803
804 if (isProfitableToCompareVTables(*CB, PromotionCandidates))
805 Changed |= tryToPromoteWithVTableCmp(*CB, VPtr, PromotionCandidates,
806 TotalCount, NumCandidates,
807 ICallProfDataRef, VTableGUIDCounts);
808 else
809 Changed |= tryToPromoteWithFuncCmp(*CB, VPtr, PromotionCandidates,
810 TotalCount, ICallProfDataRef,
811 NumCandidates, VTableGUIDCounts);
812 }
813 return Changed;
814}
815
816// TODO: Return false if the function addressing and vtable load instructions
817// cannot sink to indirect fallback.
818bool IndirectCallPromoter::isProfitableToCompareVTables(
819 const CallBase &CB, ArrayRef<PromotionCandidate> Candidates) {
820 if (!EnableVTableProfileUse || Candidates.empty())
821 return false;
822 LLVM_DEBUG(dbgs() << "\nEvaluating vtable profitability for callsite #"
823 << NumOfPGOICallsites << CB << "\n");
824 const size_t CandidateSize = Candidates.size();
825 for (size_t I = 0; I < CandidateSize; I++) {
826 auto &Candidate = Candidates[I];
827 auto &VTableGUIDAndCounts = Candidate.VTableGUIDAndCounts;
828
829 LLVM_DEBUG({
830 dbgs() << " Candidate " << I << " FunctionCount: " << Candidate.Count
831 << ", VTableCounts:";
832 for (const auto &[GUID, Count] : VTableGUIDAndCounts)
833 dbgs() << " {" << Symtab->getGlobalVariable(GUID)->getName() << ", "
834 << Count << "}";
835 dbgs() << "\n";
836 });
837
838 uint64_t CandidateVTableCount = 0;
839
840 for (auto &[GUID, Count] : VTableGUIDAndCounts) {
841 CandidateVTableCount += Count;
842
843 if (shouldSkipVTable(GUID))
844 return false;
845 }
846
847 if (CandidateVTableCount <
848 Candidate.Count * Opts.icp_vtable_percentage_threshold) {
850 dbgs() << " function count " << Candidate.Count
851 << " and its vtable sum count " << CandidateVTableCount
852 << " have discrepancies. Bail out vtable comparison.\n");
853 return false;
854 }
855
856 // 'MaxNumVTable' limits the number of vtables to make vtable comparison
857 // profitable. Comparing multiple vtables for one function candidate will
858 // insert additional instructions on the hot path, and allowing more than
859 // one vtable for non last candidates may or may not elongate the dependency
860 // chain for the subsequent candidates. Set its value to 1 for non-last
861 // candidate and allow option to override it for the last candidate.
862 int MaxNumVTable = 1;
863 if (I == CandidateSize - 1)
864 MaxNumVTable = Opts.icp_max_num_vtable_last_candidate;
865
866 if ((int)Candidate.AddressPoints.size() > MaxNumVTable) {
867 LLVM_DEBUG(dbgs() << " allow at most " << MaxNumVTable << " and got "
868 << Candidate.AddressPoints.size()
869 << " vtables. Bail out for vtable comparison.\n");
870 return false;
871 }
872 }
873
874 return true;
875}
876
877bool IndirectCallPromoter::shouldSkipVTable(uint64_t VTableGUID) {
878 if (IgnoredBaseTypes.empty())
879 return false;
880
881 auto *VTableVar = Symtab->getGlobalVariable(VTableGUID);
882
883 assert(VTableVar && "VTableVar must exist for GUID in VTableGUIDAndCounts");
884
886 VTableVar->getMetadata(LLVMContext::MD_type, Types);
887
888 for (auto *Type : Types)
889 if (auto *TypeId = dyn_cast<MDString>(Type->getOperand(1).get()))
890 if (IgnoredBaseTypes.contains(TypeId->getString())) {
891 LLVM_DEBUG(dbgs() << " vtable profiles should be ignored. Bail "
892 "out of vtable comparison.");
893 return true;
894 }
895 return false;
896}
897
898// For virtual calls in the module, collect per-callsite information which will
899// be used to associate an ICP candidate with a vtable and a specific function
900// in the vtable. With type intrinsics (llvm.type.test), we can find virtual
901// calls in a compile-time efficient manner (by iterating its users) and more
902// importantly use the compatible type later to figure out the function byte
903// offset relative to the start of vtables.
904static void
906 VirtualCallSiteTypeInfoMap &VirtualCSInfo) {
907 // Right now only llvm.type.test is used to find out virtual call sites.
908 // With ThinLTO and whole-program-devirtualization, llvm.type.test and
909 // llvm.public.type.test are emitted, and llvm.public.type.test is either
910 // refined to llvm.type.test or dropped before indirect-call-promotion pass.
911 //
912 // FIXME: For fullLTO with VFE, `llvm.type.checked.load intrinsic` is emitted.
913 // Find out virtual calls by looking at users of llvm.type.checked.load in
914 // that case.
915 Function *TypeTestFunc =
916 Intrinsic::getDeclarationIfExists(&M, Intrinsic::type_test);
917 if (!TypeTestFunc || TypeTestFunc->use_empty())
918 return;
919
920 auto &FAM = MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
921 auto LookupDomTree = [&FAM](Function &F) -> DominatorTree & {
922 return FAM.getResult<DominatorTreeAnalysis>(F);
923 };
924 // Iterate all type.test calls to find all indirect calls.
925 for (Use &U : llvm::make_early_inc_range(TypeTestFunc->uses())) {
926 auto *CI = dyn_cast<CallInst>(U.getUser());
927 if (!CI)
928 continue;
929 auto *TypeMDVal = cast<MetadataAsValue>(CI->getArgOperand(1));
930 if (!TypeMDVal)
931 continue;
932 auto *CompatibleTypeId = dyn_cast<MDString>(TypeMDVal->getMetadata());
933 if (!CompatibleTypeId)
934 continue;
935
936 // Find out all devirtualizable call sites given a llvm.type.test
937 // intrinsic call.
940 auto &DT = LookupDomTree(*CI->getFunction());
941 findDevirtualizableCallsForTypeTest(DevirtCalls, Assumes, CI, DT);
942
943 for (auto &DevirtCall : DevirtCalls) {
944 CallBase &CB = DevirtCall.CB;
945 // Given an indirect call, try find the instruction which loads a
946 // pointer to virtual table.
947 Instruction *VTablePtr =
949 if (!VTablePtr)
950 continue;
951 VirtualCSInfo[&CB] = {DevirtCall.Offset, VTablePtr,
952 CompatibleTypeId->getString()};
953 }
954 }
955}
956
957// A wrapper function that does the actual work.
958static bool promoteIndirectCalls(const InstrumentationOptions &Opts, Module &M,
959 ProfileSummaryInfo *PSI, bool InLTO,
960 bool SamplePGO, ModuleAnalysisManager &MAM) {
961 if (Opts.disable_icp)
962 return false;
963 InstrProfSymtab Symtab;
964 if (Error E = Symtab.create(M, InLTO)) {
965 std::string SymtabFailure = toString(std::move(E));
966 M.getContext().emitError("Failed to create symtab: " + SymtabFailure);
967 return false;
968 }
969 bool Changed = false;
970 VirtualCallSiteTypeInfoMap VirtualCSInfo;
971
972 DenseSet<StringRef> IgnoredBaseTypes;
973
975 computeVirtualCallSiteTypeInfoMap(M, MAM, VirtualCSInfo);
976
977 IgnoredBaseTypes.insert_range(Opts.icp_ignored_base_types);
978 }
979
980 // VTableAddressPointOffsetVal stores the vtable address points. The vtable
981 // address point of a given <vtable, address point offset> is static (doesn't
982 // change after being computed once).
983 // IndirectCallPromoter::getOrCreateVTableAddressPointVar creates the map
984 // entry the first time a <vtable, offset> pair is seen, as
985 // promoteIndirectCalls processes an IR module and calls IndirectCallPromoter
986 // repeatedly on each function.
987 VTableAddressPointOffsetValMap VTableAddressPointOffsetVal;
988
989 for (auto &F : M) {
990 if (F.isDeclaration() || F.hasOptNone())
991 continue;
992
993 auto &FAM =
994 MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
995 auto &ORE = FAM.getResult<OptimizationRemarkEmitterAnalysis>(F);
996
997 IndirectCallPromoter CallPromoter(
998 Opts, F, M, &Symtab, SamplePGO, VirtualCSInfo,
999 VTableAddressPointOffsetVal, IgnoredBaseTypes, ORE);
1000 bool FuncChanged = CallPromoter.processFunction(PSI);
1001 if (Opts.icp_dumpafter && FuncChanged) {
1002 LLVM_DEBUG(dbgs() << "\n== IR Dump After =="; F.print(dbgs()));
1003 LLVM_DEBUG(dbgs() << "\n");
1004 }
1005 Changed |= FuncChanged;
1006 if (Opts.icp_cutoff != 0 && NumOfPGOICallPromotion >= Opts.icp_cutoff) {
1007 LLVM_DEBUG(dbgs() << " Stop: Cutoff reached.\n");
1008 break;
1009 }
1010 }
1011 return Changed;
1012}
1013
1016 ProfileSummaryInfo *PSI = &MAM.getResult<ProfileSummaryAnalysis>(M);
1017
1018 const InstrumentationOptions &Opts = getInstrumentationOptions(M);
1019 if (!promoteIndirectCalls(Opts, M, PSI, InLTO | Opts.icp_lto,
1020 SamplePGO | Opts.icp_samplepgo, MAM))
1021 return PreservedAnalyses::all();
1022
1023 return PreservedAnalyses::none();
1024}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t uint64_t
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file defines the DenseMap class.
#define DEBUG_TYPE
This header defines various interfaces for pass management in LLVM.
Interface to identify indirect call promotion candidates.
static void computeVirtualCallSiteTypeInfoMap(Module &M, ModuleAnalysisManager &MAM, VirtualCallSiteTypeInfoMap &VirtualCSInfo)
static MDNode * createBranchWeights(LLVMContext &Context, uint64_t TrueWeight, uint64_t FalseWeight)
static bool promoteIndirectCalls(const InstrumentationOptions &Opts, Module &M, ProfileSummaryInfo *PSI, bool InLTO, bool SamplePGO, ModuleAnalysisManager &MAM)
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
static bool processFunction(Function &F, NVPTXTargetMachine &TM)
This file provides the interface for IR based instrumentation passes ( (profile-gen,...
FunctionAnalysisManager FAM
ModuleAnalysisManager MAM
This file contains the declarations for profiling metadata utility functions.
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:119
Value * RHS
Value * LHS
Class for arbitrary precision integers.
Definition APInt.h:78
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_t size() const
Get the array size.
Definition ArrayRef.h:141
bool empty() const
Check if the array is empty.
Definition ArrayRef.h:136
LLVM Basic Block Representation.
Definition BasicBlock.h:62
LLVM_ABI const_iterator getFirstInsertionPt() const
Returns an iterator to the first instruction in this block that is suitable for inserting a non-PHI i...
LLVM_ABI const BasicBlock * getUniquePredecessor() const
Return the predecessor of this block if it has a unique predecessor block.
InstListType::iterator iterator
Instruction iterators...
Definition BasicBlock.h:170
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
Definition BasicBlock.h:237
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
static LLVM_SUPPRESS_DEPRECATED_DECLARATIONS_POP Constant * getInBoundsPtrAdd(Constant *Ptr, Constant *Offset)
Create a getelementptr inbounds i8, ptr, offset constant expression.
Definition Constants.h:1550
This is an important base class in LLVM.
Definition Constant.h:44
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:766
iterator end()
Definition DenseMap.h:686
Implements a dense probed hash-table based set.
Definition DenseSet.h:281
Analysis pass which computes a DominatorTree.
Definition Dominators.h:241
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
Definition Dominators.h:122
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this GlobalObject.
LLVM_ABI bool isDeclaration() const
Return true if the primary definition of this global value is outside of the current translation unit...
Definition Globals.cpp:408
LLVM_ABI MutableArrayRef< InstrProfValueData > getPromotionCandidatesForInstruction(const Instruction *I, uint64_t &TotalCount, uint32_t &NumCandidates, unsigned MaxNumValueData=0)
Returns reference to array of InstrProfValueData for the given instruction I.
A symbol table used for function [IR]PGO name look-up with keys (such as pointers,...
Definition InstrProf.h:500
GlobalVariable * getGlobalVariable(uint64_t MD5Hash) const
Return the global variable corresponding to md5 hash.
Definition InstrProf.h:796
LLVM_ABI Error create(object::SectionRef &Section)
Create InstrProfSymtab from an object file section which contains function PGO names.
Function * getFunction(uint64_t FuncMD5Hash) const
Return function from the name's md5 hash. Return nullptr if not found.
Definition InstrProf.h:786
LLVM_ABI unsigned getNumSuccessors() const LLVM_READONLY
Return the number of successors that this instruction has.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
LLVM_ABI void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:76
LLVM_ABI MDNode * createBranchWeights(uint32_t TrueWeight, uint32_t FalseWeight, bool IsExpected=false)
Return metadata containing two branch weights.
Definition MDBuilder.cpp:38
Metadata node.
Definition Metadata.h:1081
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
Represent a mutable reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:294
iterator begin() const
Definition ArrayRef.h:338
The optimization diagnostic interface.
LLVM_ABI void emit(DiagnosticInfoOptimizationBase &OptDiag)
Output the remark via the diagnostic handler and to the optimization record file.
Diagnostic information for applied optimization remarks.
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM)
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition Analysis.h:115
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
An analysis pass based on the new PM to deliver ProfileSummaryInfo.
Analysis providing profile information.
bool hasProfileSummary() const
Returns true if profile summary is available.
LLVM_ABI bool isColdCount(uint64_t C) const
Returns true if count C is considered cold.
LLVM_ABI bool isHotCountNthPercentile(int PercentileCutoff, uint64_t C) const
Returns true if count C is considered hot with regard to a given hot percentile cutoff value.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
Target - Wrapper for Target specific information.
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
Definition Type.cpp:299
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
User * getUser() const
Returns the User that contains this Use.
Definition Use.h:61
LLVMContext & getContext() const
All values hold a context through their type.
Definition Value.h:260
bool use_empty() const
Definition Value.h:348
iterator_range< use_iterator > uses()
Definition Value.h:382
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:315
void insert_range(Range &&R)
Definition DenseSet.h:235
const ParentTy * getParent() const
Definition ilist_node.h:34
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:83
LLVM_ABI Function * getDeclarationIfExists(const Module *M, ID id)
Look up the Function declaration of the intrinsic id in the Module M and return it if it exists.
Add a small namespace to avoid name clashes with the classes used in the streaming interface.
DiagnosticInfoOptimizationBase::Argument NV
LLVM_ABI CallBase & promoteIndirectCall(CallBase &CB, Function *F, uint64_t Count, uint64_t TotalCount, bool AttachProfToDirectCall, OptimizationRemarkEmitter *ORE)
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.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition STLExtras.h:316
const InstrumentationOptions & getInstrumentationOptions(const LLVMContext &C)
void stable_sort(R &&Range)
Definition STLExtras.h:2132
LLVM_ABI bool isLegalToPromote(const CallBase &CB, Function *Callee, const char **FailureReason=nullptr)
Return true if the given indirect call site can be made to call Callee.
std::vector< CallBase * > findIndirectCalls(Function &F)
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
LLVM_ABI CallBase & promoteCallWithIfThenElse(CallBase &CB, Function *Callee, MDNode *BranchWeights=nullptr)
Promote the given indirect call site to conditionally call Callee.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition STLExtras.h:649
InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy
Provide the FunctionAnalysisManager to Module proxy.
auto upper_bound(R &&Range, T &&Value)
Provide wrappers to std::upper_bound which take ranges instead of having to pass begin/end explicitly...
Definition STLExtras.h:2081
cl::opt< bool > EnableVTableProfileUse("enable-vtable-profile-use", cl::init(false), cl::desc("If ThinLTO and WPD is enabled and this option is true, vtable " "profiles will be used by ICP pass for more efficient indirect " "call sequence. If false, type profiles won't be used."))
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...
auto reverse(ContainerTy &&C)
Definition STLExtras.h:408
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1652
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
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:547
MutableArrayRef(T &OneElt) -> MutableArrayRef< T >
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
Definition InstrProf.h:145
LLVM_ABI cl::opt< int > ProfileSummaryCutoffHot
ArrayRef(const T &OneElt) -> ArrayRef< T >
std::string toString(const APInt &I, unsigned Radix, bool Signed, bool formatAsCLiteral=false, bool UpperCase=true, bool InsertSeparators=false)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
uint32_t scaleBranchCount(uint64_t Count, uint64_t Scale)
Scale an individual branch count.
LLVM_ABI unsigned getMaxNumVTableAnnotations(const LLVMContext &C)
Return -icp-max-num-vtables.
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.
uint64_t calculateCountScale(uint64_t MaxCount)
Calculate what to divide by to scale counts.
LLVM_ABI CallBase & promoteCallWithVTableCmp(CallBase &CB, Instruction *VPtr, Function *Callee, ArrayRef< Constant * > AddressPoints, MDNode *BranchWeights)
This is similar to promoteCallWithIfThenElse except that the condition to promote a virtual call is t...
LLVM_ABI void findDevirtualizableCallsForTypeTest(SmallVectorImpl< DevirtCallSite > &DevirtCalls, SmallVectorImpl< CallInst * > &Assumes, const CallInst *CI, DominatorTree &DT)
Given a call to the intrinsic @llvm.type.test, find all devirtualizable call sites based on the call ...
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Definition MIRParser.h:39
LLVM_ABI std::pair< Function *, Constant * > getFunctionAtVTableOffset(GlobalVariable *GV, uint64_t Offset, Module &M)
Given a vtable and a specified offset, returns the function and the trivial pointer at the specified ...
static Instruction * tryGetVTableInstruction(CallBase *CB)