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