LLVM 22.0.0git
WholeProgramDevirt.cpp
Go to the documentation of this file.
1//===- WholeProgramDevirt.cpp - Whole program virtual call optimization ---===//
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 pass implements whole program optimization of virtual calls in cases
10// where we know (via !type metadata) that the list of callees is fixed. This
11// includes the following:
12// - Single implementation devirtualization: if a virtual call has a single
13// possible callee, replace all calls with a direct call to that callee.
14// - Virtual constant propagation: if the virtual function's return type is an
15// integer <=64 bits and all possible callees are readnone, for each class and
16// each list of constant arguments: evaluate the function, store the return
17// value alongside the virtual table, and rewrite each virtual call as a load
18// from the virtual table.
19// - Uniform return value optimization: if the conditions for virtual constant
20// propagation hold and each function returns the same constant value, replace
21// each virtual call with that constant.
22// - Unique return value optimization for i1 return values: if the conditions
23// for virtual constant propagation hold and a single vtable's function
24// returns 0, or a single vtable's function returns 1, replace each virtual
25// call with a comparison of the vptr against that vtable's address.
26//
27// This pass is intended to be used during the regular and thin LTO pipelines:
28//
29// During regular LTO, the pass determines the best optimization for each
30// virtual call and applies the resolutions directly to virtual calls that are
31// eligible for virtual call optimization (i.e. calls that use either of the
32// llvm.assume(llvm.type.test) or llvm.type.checked.load intrinsics).
33//
34// During hybrid Regular/ThinLTO, the pass operates in two phases:
35// - Export phase: this is run during the thin link over a single merged module
36// that contains all vtables with !type metadata that participate in the link.
37// The pass computes a resolution for each virtual call and stores it in the
38// type identifier summary.
39// - Import phase: this is run during the thin backends over the individual
40// modules. The pass applies the resolutions previously computed during the
41// import phase to each eligible virtual call.
42//
43// During ThinLTO, the pass operates in two phases:
44// - Export phase: this is run during the thin link over the index which
45// contains a summary of all vtables with !type metadata that participate in
46// the link. It computes a resolution for each virtual call and stores it in
47// the type identifier summary. Only single implementation devirtualization
48// is supported.
49// - Import phase: (same as with hybrid case above).
50//
51//===----------------------------------------------------------------------===//
52
54#include "llvm/ADT/ArrayRef.h"
55#include "llvm/ADT/DenseMap.h"
57#include "llvm/ADT/DenseSet.h"
58#include "llvm/ADT/MapVector.h"
60#include "llvm/ADT/Statistic.h"
67#include "llvm/IR/Constants.h"
68#include "llvm/IR/DataLayout.h"
69#include "llvm/IR/DebugLoc.h"
72#include "llvm/IR/Dominators.h"
73#include "llvm/IR/Function.h"
74#include "llvm/IR/GlobalAlias.h"
76#include "llvm/IR/IRBuilder.h"
77#include "llvm/IR/InstrTypes.h"
78#include "llvm/IR/Instruction.h"
80#include "llvm/IR/Intrinsics.h"
81#include "llvm/IR/LLVMContext.h"
82#include "llvm/IR/MDBuilder.h"
83#include "llvm/IR/Metadata.h"
84#include "llvm/IR/Module.h"
86#include "llvm/IR/PassManager.h"
89#include "llvm/Support/Errc.h"
90#include "llvm/Support/Error.h"
94#include "llvm/Transforms/IPO.h"
99#include <algorithm>
100#include <cstddef>
101#include <map>
102#include <set>
103#include <string>
104
105using namespace llvm;
106using namespace wholeprogramdevirt;
107
108#define DEBUG_TYPE "wholeprogramdevirt"
109
110STATISTIC(NumDevirtTargets, "Number of whole program devirtualization targets");
111STATISTIC(NumSingleImpl, "Number of single implementation devirtualizations");
112STATISTIC(NumBranchFunnel, "Number of branch funnels");
113STATISTIC(NumUniformRetVal, "Number of uniform return value optimizations");
114STATISTIC(NumUniqueRetVal, "Number of unique return value optimizations");
115STATISTIC(NumVirtConstProp1Bit,
116 "Number of 1 bit virtual constant propagations");
117STATISTIC(NumVirtConstProp, "Number of virtual constant propagations");
118
120 "wholeprogramdevirt-summary-action",
121 cl::desc("What to do with the summary when running this pass"),
122 cl::values(clEnumValN(PassSummaryAction::None, "none", "Do nothing"),
123 clEnumValN(PassSummaryAction::Import, "import",
124 "Import typeid resolutions from summary and globals"),
125 clEnumValN(PassSummaryAction::Export, "export",
126 "Export typeid resolutions to summary and globals")),
127 cl::Hidden);
128
130 "wholeprogramdevirt-read-summary",
131 cl::desc(
132 "Read summary from given bitcode or YAML file before running pass"),
133 cl::Hidden);
134
136 "wholeprogramdevirt-write-summary",
137 cl::desc("Write summary to given bitcode or YAML file after running pass. "
138 "Output file format is deduced from extension: *.bc means writing "
139 "bitcode, otherwise YAML"),
140 cl::Hidden);
141
143 ClThreshold("wholeprogramdevirt-branch-funnel-threshold", cl::Hidden,
144 cl::init(10),
145 cl::desc("Maximum number of call targets per "
146 "call site to enable branch funnels"));
147
148static cl::opt<bool>
149 PrintSummaryDevirt("wholeprogramdevirt-print-index-based", cl::Hidden,
150 cl::desc("Print index-based devirtualization messages"));
151
152/// Provide a way to force enable whole program visibility in tests.
153/// This is needed to support legacy tests that don't contain
154/// !vcall_visibility metadata (the mere presense of type tests
155/// previously implied hidden visibility).
156static cl::opt<bool>
157 WholeProgramVisibility("whole-program-visibility", cl::Hidden,
158 cl::desc("Enable whole program visibility"));
159
160/// Provide a way to force disable whole program for debugging or workarounds,
161/// when enabled via the linker.
163 "disable-whole-program-visibility", cl::Hidden,
164 cl::desc("Disable whole program visibility (overrides enabling options)"));
165
166/// Provide way to prevent certain function from being devirtualized
168 SkipFunctionNames("wholeprogramdevirt-skip",
169 cl::desc("Prevent function(s) from being devirtualized"),
171
172/// With Clang, a pure virtual class's deleting destructor is emitted as a
173/// `llvm.trap` intrinsic followed by an unreachable IR instruction. In the
174/// context of whole program devirtualization, the deleting destructor of a pure
175/// virtual class won't be invoked by the source code so safe to skip as a
176/// devirtualize target.
177///
178/// However, not all unreachable functions are safe to skip. In some cases, the
179/// program intends to run such functions and terminate, for instance, a unit
180/// test may run a death test. A non-test program might (or allowed to) invoke
181/// such functions to report failures (whether/when it's a good practice or not
182/// is a different topic).
183///
184/// This option is enabled to keep an unreachable function as a possible
185/// devirtualize target to conservatively keep the program behavior.
186///
187/// TODO: Make a pure virtual class's deleting destructor precisely identifiable
188/// in Clang's codegen for more devirtualization in LLVM.
190 "wholeprogramdevirt-keep-unreachable-function",
191 cl::desc("Regard unreachable functions as possible devirtualize targets."),
192 cl::Hidden, cl::init(true));
193
194/// If explicitly specified, the devirt module pass will stop transformation
195/// once the total number of devirtualizations reach the cutoff value. Setting
196/// this option to 0 explicitly will do 0 devirtualization.
198 "wholeprogramdevirt-cutoff",
199 cl::desc("Max number of devirtualizations for devirt module pass"),
200 cl::init(0));
201
202/// Mechanism to add runtime checking of devirtualization decisions, optionally
203/// trapping or falling back to indirect call on any that are not correct.
204/// Trapping mode is useful for debugging undefined behavior leading to failures
205/// with WPD. Fallback mode is useful for ensuring safety when whole program
206/// visibility may be compromised.
209 "wholeprogramdevirt-check", cl::Hidden,
210 cl::desc("Type of checking for incorrect devirtualizations"),
211 cl::values(clEnumValN(WPDCheckMode::None, "none", "No checking"),
212 clEnumValN(WPDCheckMode::Trap, "trap", "Trap when incorrect"),
214 "Fallback to indirect when incorrect")));
215
216namespace {
217struct PatternList {
218 std::vector<GlobPattern> Patterns;
219 template <class T> void init(const T &StringList) {
220 for (const auto &S : StringList)
222 Patterns.push_back(std::move(*Pat));
223 }
224 bool match(StringRef S) {
225 for (const GlobPattern &P : Patterns)
226 if (P.match(S))
227 return true;
228 return false;
229 }
230};
231} // namespace
232
233// Find the minimum offset that we may store a value of size Size bits at. If
234// IsAfter is set, look for an offset before the object, otherwise look for an
235// offset after the object.
238 bool IsAfter, uint64_t Size) {
239 // Find a minimum offset taking into account only vtable sizes.
240 uint64_t MinByte = 0;
241 for (const VirtualCallTarget &Target : Targets) {
242 if (IsAfter)
243 MinByte = std::max(MinByte, Target.minAfterBytes());
244 else
245 MinByte = std::max(MinByte, Target.minBeforeBytes());
246 }
247
248 // Build a vector of arrays of bytes covering, for each target, a slice of the
249 // used region (see AccumBitVector::BytesUsed in
250 // llvm/Transforms/IPO/WholeProgramDevirt.h) starting at MinByte. Effectively,
251 // this aligns the used regions to start at MinByte.
252 //
253 // In this example, A, B and C are vtables, # is a byte already allocated for
254 // a virtual function pointer, AAAA... (etc.) are the used regions for the
255 // vtables and Offset(X) is the value computed for the Offset variable below
256 // for X.
257 //
258 // Offset(A)
259 // | |
260 // |MinByte
261 // A: ################AAAAAAAA|AAAAAAAA
262 // B: ########BBBBBBBBBBBBBBBB|BBBB
263 // C: ########################|CCCCCCCCCCCCCCCC
264 // | Offset(B) |
265 //
266 // This code produces the slices of A, B and C that appear after the divider
267 // at MinByte.
268 std::vector<ArrayRef<uint8_t>> Used;
269 for (const VirtualCallTarget &Target : Targets) {
270 ArrayRef<uint8_t> VTUsed = IsAfter ? Target.TM->Bits->After.BytesUsed
271 : Target.TM->Bits->Before.BytesUsed;
272 uint64_t Offset = IsAfter ? MinByte - Target.minAfterBytes()
273 : MinByte - Target.minBeforeBytes();
274
275 // Disregard used regions that are smaller than Offset. These are
276 // effectively all-free regions that do not need to be checked.
277 if (VTUsed.size() > Offset)
278 Used.push_back(VTUsed.slice(Offset));
279 }
280
281 if (Size == 1) {
282 // Find a free bit in each member of Used.
283 for (unsigned I = 0;; ++I) {
284 uint8_t BitsUsed = 0;
285 for (auto &&B : Used)
286 if (I < B.size())
287 BitsUsed |= B[I];
288 if (BitsUsed != 0xff)
289 return (MinByte + I) * 8 + llvm::countr_zero(uint8_t(~BitsUsed));
290 }
291 } else {
292 // Find a free (Size/8) byte region in each member of Used.
293 // FIXME: see if alignment helps.
294 for (unsigned I = 0;; ++I) {
295 for (auto &&B : Used) {
296 unsigned Byte = 0;
297 while ((I + Byte) < B.size() && Byte < (Size / 8)) {
298 if (B[I + Byte])
299 goto NextI;
300 ++Byte;
301 }
302 }
303 // Rounding up ensures the constant is always stored at address we
304 // can directly load from without misalignment.
305 return alignTo((MinByte + I) * 8, Size);
306 NextI:;
307 }
308 }
309}
310
312 MutableArrayRef<VirtualCallTarget> Targets, uint64_t AllocBefore,
313 unsigned BitWidth, int64_t &OffsetByte, uint64_t &OffsetBit) {
314 if (BitWidth == 1)
315 OffsetByte = -(AllocBefore / 8 + 1);
316 else
317 OffsetByte = -((AllocBefore + 7) / 8 + (BitWidth + 7) / 8);
318 OffsetBit = AllocBefore % 8;
319
320 for (VirtualCallTarget &Target : Targets) {
321 if (BitWidth == 1)
322 Target.setBeforeBit(AllocBefore);
323 else
324 Target.setBeforeBytes(AllocBefore, (BitWidth + 7) / 8);
325 }
326}
327
330 unsigned BitWidth, int64_t &OffsetByte, uint64_t &OffsetBit) {
331 if (BitWidth == 1)
332 OffsetByte = AllocAfter / 8;
333 else
334 OffsetByte = (AllocAfter + 7) / 8;
335 OffsetBit = AllocAfter % 8;
336
337 for (VirtualCallTarget &Target : Targets) {
338 if (BitWidth == 1)
339 Target.setAfterBit(AllocAfter);
340 else
341 Target.setAfterBytes(AllocAfter, (BitWidth + 7) / 8);
342 }
343}
344
346 : Fn(Fn), TM(TM),
347 IsBigEndian(Fn->getDataLayout().isBigEndian()),
348 WasDevirt(false) {}
349
350namespace {
351
352// Tracks the number of devirted calls in the IR transformation.
353static unsigned NumDevirtCalls = 0;
354
355// A slot in a set of virtual tables. The TypeID identifies the set of virtual
356// tables, and the ByteOffset is the offset in bytes from the address point to
357// the virtual function pointer.
358struct VTableSlot {
360 uint64_t ByteOffset;
361};
362
363} // end anonymous namespace
364
365namespace llvm {
366
367template <> struct DenseMapInfo<VTableSlot> {
368 static VTableSlot getEmptyKey() {
371 }
372 static VTableSlot getTombstoneKey() {
375 }
376 static unsigned getHashValue(const VTableSlot &I) {
379 }
380 static bool isEqual(const VTableSlot &LHS,
381 const VTableSlot &RHS) {
382 return LHS.TypeID == RHS.TypeID && LHS.ByteOffset == RHS.ByteOffset;
383 }
384};
385
386template <> struct DenseMapInfo<VTableSlotSummary> {
390 }
394 }
395 static unsigned getHashValue(const VTableSlotSummary &I) {
398 }
399 static bool isEqual(const VTableSlotSummary &LHS,
400 const VTableSlotSummary &RHS) {
401 return LHS.TypeID == RHS.TypeID && LHS.ByteOffset == RHS.ByteOffset;
402 }
403};
404
405} // end namespace llvm
406
407// Returns true if the function must be unreachable based on ValueInfo.
408//
409// In particular, identifies a function as unreachable in the following
410// conditions
411// 1) All summaries are live.
412// 2) All function summaries indicate it's unreachable
413// 3) There is no non-function with the same GUID (which is rare)
416 return false;
417
418 if ((!TheFnVI) || TheFnVI.getSummaryList().empty()) {
419 // Returns false if ValueInfo is absent, or the summary list is empty
420 // (e.g., function declarations).
421 return false;
422 }
423
424 for (const auto &Summary : TheFnVI.getSummaryList()) {
425 // Conservatively returns false if any non-live functions are seen.
426 // In general either all summaries should be live or all should be dead.
427 if (!Summary->isLive())
428 return false;
429 if (auto *FS = dyn_cast<FunctionSummary>(Summary->getBaseObject())) {
430 if (!FS->fflags().MustBeUnreachable)
431 return false;
432 }
433 // Be conservative if a non-function has the same GUID (which is rare).
434 else
435 return false;
436 }
437 // All function summaries are live and all of them agree that the function is
438 // unreachble.
439 return true;
440}
441
442namespace {
443// A virtual call site. VTable is the loaded virtual table pointer, and CS is
444// the indirect virtual call.
445struct VirtualCallSite {
446 Value *VTable = nullptr;
447 CallBase &CB;
448
449 // If non-null, this field points to the associated unsafe use count stored in
450 // the DevirtModule::NumUnsafeUsesForTypeTest map below. See the description
451 // of that field for details.
452 unsigned *NumUnsafeUses = nullptr;
453
454 void
455 emitRemark(const StringRef OptName, const StringRef TargetName,
457 Function *F = CB.getCaller();
458 DebugLoc DLoc = CB.getDebugLoc();
459 BasicBlock *Block = CB.getParent();
460
461 using namespace ore;
462 OREGetter(*F).emit(OptimizationRemark(DEBUG_TYPE, OptName, DLoc, Block)
463 << NV("Optimization", OptName)
464 << ": devirtualized a call to "
465 << NV("FunctionName", TargetName));
466 }
467
468 void replaceAndErase(
469 const StringRef OptName, const StringRef TargetName, bool RemarksEnabled,
471 Value *New) {
472 if (RemarksEnabled)
473 emitRemark(OptName, TargetName, OREGetter);
474 CB.replaceAllUsesWith(New);
475 if (auto *II = dyn_cast<InvokeInst>(&CB)) {
476 BranchInst::Create(II->getNormalDest(), CB.getIterator());
477 II->getUnwindDest()->removePredecessor(II->getParent());
478 }
479 CB.eraseFromParent();
480 // This use is no longer unsafe.
481 if (NumUnsafeUses)
482 --*NumUnsafeUses;
483 }
484};
485
486// Call site information collected for a specific VTableSlot and possibly a list
487// of constant integer arguments. The grouping by arguments is handled by the
488// VTableSlotInfo class.
489struct CallSiteInfo {
490 /// The set of call sites for this slot. Used during regular LTO and the
491 /// import phase of ThinLTO (as well as the export phase of ThinLTO for any
492 /// call sites that appear in the merged module itself); in each of these
493 /// cases we are directly operating on the call sites at the IR level.
494 std::vector<VirtualCallSite> CallSites;
495
496 /// Whether all call sites represented by this CallSiteInfo, including those
497 /// in summaries, have been devirtualized. This starts off as true because a
498 /// default constructed CallSiteInfo represents no call sites.
499 ///
500 /// If at the end of the pass there are still undevirtualized calls, we will
501 /// need to add a use of llvm.type.test to each of the function summaries in
502 /// the vector.
503 bool AllCallSitesDevirted = true;
504
505 // These fields are used during the export phase of ThinLTO and reflect
506 // information collected from function summaries.
507
508 /// CFI-specific: a vector containing the list of function summaries that use
509 /// the llvm.type.checked.load intrinsic and therefore will require
510 /// resolutions for llvm.type.test in order to implement CFI checks if
511 /// devirtualization was unsuccessful.
512 std::vector<FunctionSummary *> SummaryTypeCheckedLoadUsers;
513
514 /// A vector containing the list of function summaries that use
515 /// assume(llvm.type.test).
516 std::vector<FunctionSummary *> SummaryTypeTestAssumeUsers;
517
518 bool isExported() const {
519 return !SummaryTypeCheckedLoadUsers.empty() ||
520 !SummaryTypeTestAssumeUsers.empty();
521 }
522
523 void addSummaryTypeCheckedLoadUser(FunctionSummary *FS) {
524 SummaryTypeCheckedLoadUsers.push_back(FS);
525 AllCallSitesDevirted = false;
526 }
527
528 void addSummaryTypeTestAssumeUser(FunctionSummary *FS) {
529 SummaryTypeTestAssumeUsers.push_back(FS);
530 AllCallSitesDevirted = false;
531 }
532
533 void markDevirt() { AllCallSitesDevirted = true; }
534};
535
536// Call site information collected for a specific VTableSlot.
537struct VTableSlotInfo {
538 // The set of call sites which do not have all constant integer arguments
539 // (excluding "this").
540 CallSiteInfo CSInfo;
541
542 // The set of call sites with all constant integer arguments (excluding
543 // "this"), grouped by argument list.
544 std::map<std::vector<uint64_t>, CallSiteInfo> ConstCSInfo;
545
546 void addCallSite(Value *VTable, CallBase &CB, unsigned *NumUnsafeUses);
547
548private:
549 CallSiteInfo &findCallSiteInfo(CallBase &CB);
550};
551
552CallSiteInfo &VTableSlotInfo::findCallSiteInfo(CallBase &CB) {
553 std::vector<uint64_t> Args;
554 auto *CBType = dyn_cast<IntegerType>(CB.getType());
555 if (!CBType || CBType->getBitWidth() > 64 || CB.arg_empty())
556 return CSInfo;
557 for (auto &&Arg : drop_begin(CB.args())) {
558 auto *CI = dyn_cast<ConstantInt>(Arg);
559 if (!CI || CI->getBitWidth() > 64)
560 return CSInfo;
561 Args.push_back(CI->getZExtValue());
562 }
563 return ConstCSInfo[Args];
564}
565
566void VTableSlotInfo::addCallSite(Value *VTable, CallBase &CB,
567 unsigned *NumUnsafeUses) {
568 auto &CSI = findCallSiteInfo(CB);
569 CSI.AllCallSitesDevirted = false;
570 CSI.CallSites.push_back({VTable, CB, NumUnsafeUses});
571}
572
573struct DevirtModule {
574 Module &M;
577
578 ModuleSummaryIndex *const ExportSummary;
579 const ModuleSummaryIndex *const ImportSummary;
580
581 IntegerType *const Int8Ty;
582 PointerType *const Int8PtrTy;
583 IntegerType *const Int32Ty;
584 IntegerType *const Int64Ty;
585 IntegerType *const IntPtrTy;
586 /// Sizeless array type, used for imported vtables. This provides a signal
587 /// to analyzers that these imports may alias, as they do for example
588 /// when multiple unique return values occur in the same vtable.
589 ArrayType *const Int8Arr0Ty;
590
591 const bool RemarksEnabled;
592 std::function<OptimizationRemarkEmitter &(Function &)> OREGetter;
594
595 // Calls that have already been optimized. We may add a call to multiple
596 // VTableSlotInfos if vtable loads are coalesced and need to make sure not to
597 // optimize a call more than once.
598 SmallPtrSet<CallBase *, 8> OptimizedCalls;
599
600 // Store calls that had their ptrauth bundle removed. They are to be deleted
601 // at the end of the optimization.
602 SmallVector<CallBase *, 8> CallsWithPtrAuthBundleRemoved;
603
604 // This map keeps track of the number of "unsafe" uses of a loaded function
605 // pointer. The key is the associated llvm.type.test intrinsic call generated
606 // by this pass. An unsafe use is one that calls the loaded function pointer
607 // directly. Every time we eliminate an unsafe use (for example, by
608 // devirtualizing it or by applying virtual constant propagation), we
609 // decrement the value stored in this map. If a value reaches zero, we can
610 // eliminate the type check by RAUWing the associated llvm.type.test call with
611 // true.
612 std::map<CallInst *, unsigned> NumUnsafeUsesForTypeTest;
613 PatternList FunctionsToSkip;
614
615 DevirtModule(Module &M, ModuleAnalysisManager &MAM,
616 ModuleSummaryIndex *ExportSummary,
617 const ModuleSummaryIndex *ImportSummary)
618 : M(M), MAM(MAM),
619 FAM(MAM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager()),
620 ExportSummary(ExportSummary), ImportSummary(ImportSummary),
621 Int8Ty(Type::getInt8Ty(M.getContext())),
622 Int8PtrTy(PointerType::getUnqual(M.getContext())),
623 Int32Ty(Type::getInt32Ty(M.getContext())),
624 Int64Ty(Type::getInt64Ty(M.getContext())),
625 IntPtrTy(M.getDataLayout().getIntPtrType(M.getContext(), 0)),
626 Int8Arr0Ty(ArrayType::get(Type::getInt8Ty(M.getContext()), 0)),
627 RemarksEnabled(areRemarksEnabled()),
628 OREGetter([&](Function &F) -> OptimizationRemarkEmitter & {
630 }) {
631 assert(!(ExportSummary && ImportSummary));
632 FunctionsToSkip.init(SkipFunctionNames);
633 }
634
635 bool areRemarksEnabled();
636
637 void
638 scanTypeTestUsers(Function *TypeTestFunc,
639 DenseMap<Metadata *, std::set<TypeMemberInfo>> &TypeIdMap);
640 void scanTypeCheckedLoadUsers(Function *TypeCheckedLoadFunc);
641
642 void buildTypeIdentifierMap(
643 std::vector<VTableBits> &Bits,
644 DenseMap<Metadata *, std::set<TypeMemberInfo>> &TypeIdMap);
645
646 bool
647 tryFindVirtualCallTargets(std::vector<VirtualCallTarget> &TargetsForSlot,
648 const std::set<TypeMemberInfo> &TypeMemberInfos,
649 uint64_t ByteOffset,
650 ModuleSummaryIndex *ExportSummary);
651
652 void applySingleImplDevirt(VTableSlotInfo &SlotInfo, Constant *TheFn,
653 bool &IsExported);
654 bool trySingleImplDevirt(ModuleSummaryIndex *ExportSummary,
656 VTableSlotInfo &SlotInfo,
658
659 void applyICallBranchFunnel(VTableSlotInfo &SlotInfo, Constant *JT,
660 bool &IsExported);
661 void tryICallBranchFunnel(MutableArrayRef<VirtualCallTarget> TargetsForSlot,
662 VTableSlotInfo &SlotInfo,
663 WholeProgramDevirtResolution *Res, VTableSlot Slot);
664
665 bool tryEvaluateFunctionsWithArgs(
667 ArrayRef<uint64_t> Args);
668
669 void applyUniformRetValOpt(CallSiteInfo &CSInfo, StringRef FnName,
670 uint64_t TheRetVal);
671 bool tryUniformRetValOpt(MutableArrayRef<VirtualCallTarget> TargetsForSlot,
672 CallSiteInfo &CSInfo,
674
675 // Returns the global symbol name that is used to export information about the
676 // given vtable slot and list of arguments.
677 std::string getGlobalName(VTableSlot Slot, ArrayRef<uint64_t> Args,
679
680 bool shouldExportConstantsAsAbsoluteSymbols();
681
682 // This function is called during the export phase to create a symbol
683 // definition containing information about the given vtable slot and list of
684 // arguments.
685 void exportGlobal(VTableSlot Slot, ArrayRef<uint64_t> Args, StringRef Name,
686 Constant *C);
687 void exportConstant(VTableSlot Slot, ArrayRef<uint64_t> Args, StringRef Name,
688 uint32_t Const, uint32_t &Storage);
689
690 // This function is called during the import phase to create a reference to
691 // the symbol definition created during the export phase.
692 Constant *importGlobal(VTableSlot Slot, ArrayRef<uint64_t> Args,
694 Constant *importConstant(VTableSlot Slot, ArrayRef<uint64_t> Args,
695 StringRef Name, IntegerType *IntTy,
696 uint32_t Storage);
697
698 Constant *getMemberAddr(const TypeMemberInfo *M);
699
700 void applyUniqueRetValOpt(CallSiteInfo &CSInfo, StringRef FnName, bool IsOne,
701 Constant *UniqueMemberAddr);
702 bool tryUniqueRetValOpt(unsigned BitWidth,
704 CallSiteInfo &CSInfo,
706 VTableSlot Slot, ArrayRef<uint64_t> Args);
707
708 void applyVirtualConstProp(CallSiteInfo &CSInfo, StringRef FnName,
709 Constant *Byte, Constant *Bit);
710 bool tryVirtualConstProp(MutableArrayRef<VirtualCallTarget> TargetsForSlot,
711 VTableSlotInfo &SlotInfo,
712 WholeProgramDevirtResolution *Res, VTableSlot Slot);
713
714 void rebuildGlobal(VTableBits &B);
715
716 // Apply the summary resolution for Slot to all virtual calls in SlotInfo.
717 void importResolution(VTableSlot Slot, VTableSlotInfo &SlotInfo);
718
719 // If we were able to eliminate all unsafe uses for a type checked load,
720 // eliminate the associated type tests by replacing them with true.
721 void removeRedundantTypeTests();
722
723 bool run();
724
725 // Look up the corresponding ValueInfo entry of `TheFn` in `ExportSummary`.
726 //
727 // Caller guarantees that `ExportSummary` is not nullptr.
728 static ValueInfo lookUpFunctionValueInfo(Function *TheFn,
729 ModuleSummaryIndex *ExportSummary);
730
731 // Returns true if the function definition must be unreachable.
732 //
733 // Note if this helper function returns true, `F` is guaranteed
734 // to be unreachable; if it returns false, `F` might still
735 // be unreachable but not covered by this helper function.
736 //
737 // Implementation-wise, if function definition is present, IR is analyzed; if
738 // not, look up function flags from ExportSummary as a fallback.
739 static bool mustBeUnreachableFunction(Function *const F,
740 ModuleSummaryIndex *ExportSummary);
741
742 // Lower the module using the action and summary passed as command line
743 // arguments. For testing purposes only.
744 static bool runForTesting(Module &M, ModuleAnalysisManager &MAM);
745};
746
747struct DevirtIndex {
748 ModuleSummaryIndex &ExportSummary;
749 // The set in which to record GUIDs exported from their module by
750 // devirtualization, used by client to ensure they are not internalized.
751 std::set<GlobalValue::GUID> &ExportedGUIDs;
752 // A map in which to record the information necessary to locate the WPD
753 // resolution for local targets in case they are exported by cross module
754 // importing.
755 std::map<ValueInfo, std::vector<VTableSlotSummary>> &LocalWPDTargetsMap;
756
758
759 PatternList FunctionsToSkip;
760
761 DevirtIndex(
762 ModuleSummaryIndex &ExportSummary,
763 std::set<GlobalValue::GUID> &ExportedGUIDs,
764 std::map<ValueInfo, std::vector<VTableSlotSummary>> &LocalWPDTargetsMap)
765 : ExportSummary(ExportSummary), ExportedGUIDs(ExportedGUIDs),
766 LocalWPDTargetsMap(LocalWPDTargetsMap) {
767 FunctionsToSkip.init(SkipFunctionNames);
768 }
769
770 bool tryFindVirtualCallTargets(std::vector<ValueInfo> &TargetsForSlot,
771 const TypeIdCompatibleVtableInfo TIdInfo,
772 uint64_t ByteOffset);
773
774 bool trySingleImplDevirt(MutableArrayRef<ValueInfo> TargetsForSlot,
775 VTableSlotSummary &SlotSummary,
776 VTableSlotInfo &SlotInfo,
778 std::set<ValueInfo> &DevirtTargets);
779
780 void run();
781};
782} // end anonymous namespace
783
786 if (UseCommandLine) {
787 if (!DevirtModule::runForTesting(M, MAM))
788 return PreservedAnalyses::all();
790 }
791 if (!DevirtModule(M, MAM, ExportSummary, ImportSummary).run())
792 return PreservedAnalyses::all();
794}
795
796// Enable whole program visibility if enabled by client (e.g. linker) or
797// internal option, and not force disabled.
798bool llvm::hasWholeProgramVisibility(bool WholeProgramVisibilityEnabledInLTO) {
799 return (WholeProgramVisibilityEnabledInLTO || WholeProgramVisibility) &&
801}
802
803static bool
805 function_ref<bool(StringRef)> IsVisibleToRegularObj) {
806 // TypeID for member function pointer type is an internal construct
807 // and won't exist in IsVisibleToRegularObj. The full TypeID
808 // will be present and participate in invalidation.
809 if (TypeID.ends_with(".virtual"))
810 return false;
811
812 // TypeID that doesn't start with Itanium mangling (_ZTS) will be
813 // non-externally visible types which cannot interact with
814 // external native files. See CodeGenModule::CreateMetadataIdentifierImpl.
815 if (!TypeID.consume_front("_ZTS"))
816 return false;
817
818 // TypeID is keyed off the type name symbol (_ZTS). However, the native
819 // object may not contain this symbol if it does not contain a key
820 // function for the base type and thus only contains a reference to the
821 // type info (_ZTI). To catch this case we query using the type info
822 // symbol corresponding to the TypeID.
823 std::string TypeInfo = ("_ZTI" + TypeID).str();
824 return IsVisibleToRegularObj(TypeInfo);
825}
826
827static bool
829 function_ref<bool(StringRef)> IsVisibleToRegularObj) {
831 GV.getMetadata(LLVMContext::MD_type, Types);
832
833 for (auto *Type : Types)
834 if (auto *TypeID = dyn_cast<MDString>(Type->getOperand(1).get()))
835 return typeIDVisibleToRegularObj(TypeID->getString(),
836 IsVisibleToRegularObj);
837
838 return false;
839}
840
841/// If whole program visibility asserted, then upgrade all public vcall
842/// visibility metadata on vtable definitions to linkage unit visibility in
843/// Module IR (for regular or hybrid LTO).
845 Module &M, bool WholeProgramVisibilityEnabledInLTO,
846 const DenseSet<GlobalValue::GUID> &DynamicExportSymbols,
847 bool ValidateAllVtablesHaveTypeInfos,
848 function_ref<bool(StringRef)> IsVisibleToRegularObj) {
849 if (!hasWholeProgramVisibility(WholeProgramVisibilityEnabledInLTO))
850 return;
851 for (GlobalVariable &GV : M.globals()) {
852 // Add linkage unit visibility to any variable with type metadata, which are
853 // the vtable definitions. We won't have an existing vcall_visibility
854 // metadata on vtable definitions with public visibility.
855 if (GV.hasMetadata(LLVMContext::MD_type) &&
857 // Don't upgrade the visibility for symbols exported to the dynamic
858 // linker, as we have no information on their eventual use.
859 !DynamicExportSymbols.count(GV.getGUID()) &&
860 // With validation enabled, we want to exclude symbols visible to
861 // regular objects. Local symbols will be in this group due to the
862 // current implementation but those with VCallVisibilityTranslationUnit
863 // will have already been marked in clang so are unaffected.
864 !(ValidateAllVtablesHaveTypeInfos &&
865 skipUpdateDueToValidation(GV, IsVisibleToRegularObj)))
867 }
868}
869
871 bool WholeProgramVisibilityEnabledInLTO) {
872 Function *PublicTypeTestFunc =
873 Intrinsic::getDeclarationIfExists(&M, Intrinsic::public_type_test);
874 if (!PublicTypeTestFunc)
875 return;
876 if (hasWholeProgramVisibility(WholeProgramVisibilityEnabledInLTO)) {
877 Function *TypeTestFunc =
878 Intrinsic::getOrInsertDeclaration(&M, Intrinsic::type_test);
879 for (Use &U : make_early_inc_range(PublicTypeTestFunc->uses())) {
880 auto *CI = cast<CallInst>(U.getUser());
881 auto *NewCI = CallInst::Create(
882 TypeTestFunc, {CI->getArgOperand(0), CI->getArgOperand(1)}, {}, "",
883 CI->getIterator());
884 CI->replaceAllUsesWith(NewCI);
885 CI->eraseFromParent();
886 }
887 } else {
888 auto *True = ConstantInt::getTrue(M.getContext());
889 for (Use &U : make_early_inc_range(PublicTypeTestFunc->uses())) {
890 auto *CI = cast<CallInst>(U.getUser());
891 CI->replaceAllUsesWith(True);
892 CI->eraseFromParent();
893 }
894 }
895}
896
897/// Based on typeID string, get all associated vtable GUIDS that are
898/// visible to regular objects.
900 ModuleSummaryIndex &Index,
901 DenseSet<GlobalValue::GUID> &VisibleToRegularObjSymbols,
902 function_ref<bool(StringRef)> IsVisibleToRegularObj) {
903 for (const auto &TypeID : Index.typeIdCompatibleVtableMap()) {
904 if (typeIDVisibleToRegularObj(TypeID.first, IsVisibleToRegularObj))
905 for (const TypeIdOffsetVtableInfo &P : TypeID.second)
906 VisibleToRegularObjSymbols.insert(P.VTableVI.getGUID());
907 }
908}
909
910/// If whole program visibility asserted, then upgrade all public vcall
911/// visibility metadata on vtable definition summaries to linkage unit
912/// visibility in Module summary index (for ThinLTO).
914 ModuleSummaryIndex &Index, bool WholeProgramVisibilityEnabledInLTO,
915 const DenseSet<GlobalValue::GUID> &DynamicExportSymbols,
916 const DenseSet<GlobalValue::GUID> &VisibleToRegularObjSymbols) {
917 if (!hasWholeProgramVisibility(WholeProgramVisibilityEnabledInLTO))
918 return;
919 for (auto &P : Index) {
920 // Don't upgrade the visibility for symbols exported to the dynamic
921 // linker, as we have no information on their eventual use.
922 if (DynamicExportSymbols.count(P.first))
923 continue;
924 for (auto &S : P.second.SummaryList) {
925 auto *GVar = dyn_cast<GlobalVarSummary>(S.get());
926 if (!GVar ||
927 GVar->getVCallVisibility() != GlobalObject::VCallVisibilityPublic)
928 continue;
929 // With validation enabled, we want to exclude symbols visible to regular
930 // objects. Local symbols will be in this group due to the current
931 // implementation but those with VCallVisibilityTranslationUnit will have
932 // already been marked in clang so are unaffected.
933 if (VisibleToRegularObjSymbols.count(P.first))
934 continue;
935 GVar->setVCallVisibility(GlobalObject::VCallVisibilityLinkageUnit);
936 }
937 }
938}
939
941 ModuleSummaryIndex &Summary, std::set<GlobalValue::GUID> &ExportedGUIDs,
942 std::map<ValueInfo, std::vector<VTableSlotSummary>> &LocalWPDTargetsMap) {
943 DevirtIndex(Summary, ExportedGUIDs, LocalWPDTargetsMap).run();
944}
945
947 ModuleSummaryIndex &Summary,
948 function_ref<bool(StringRef, ValueInfo)> IsExported,
949 std::map<ValueInfo, std::vector<VTableSlotSummary>> &LocalWPDTargetsMap) {
950 for (auto &T : LocalWPDTargetsMap) {
951 auto &VI = T.first;
952 // This was enforced earlier during trySingleImplDevirt.
953 assert(VI.getSummaryList().size() == 1 &&
954 "Devirt of local target has more than one copy");
955 auto &S = VI.getSummaryList()[0];
956 if (!IsExported(S->modulePath(), VI))
957 continue;
958
959 // It's been exported by a cross module import.
960 for (auto &SlotSummary : T.second) {
961 auto *TIdSum = Summary.getTypeIdSummary(SlotSummary.TypeID);
962 assert(TIdSum);
963 auto WPDRes = TIdSum->WPDRes.find(SlotSummary.ByteOffset);
964 assert(WPDRes != TIdSum->WPDRes.end());
965 WPDRes->second.SingleImplName = ModuleSummaryIndex::getGlobalNameForLocal(
966 WPDRes->second.SingleImplName,
967 Summary.getModuleHash(S->modulePath()));
968 }
969 }
970}
971
973 // Check that summary index contains regular LTO module when performing
974 // export to prevent occasional use of index from pure ThinLTO compilation
975 // (-fno-split-lto-module). This kind of summary index is passed to
976 // DevirtIndex::run, not to DevirtModule::run used by opt/runForTesting.
977 const auto &ModPaths = Summary->modulePaths();
980 return createStringError(
982 "combined summary should contain Regular LTO module");
983 return ErrorSuccess();
984}
985
986bool DevirtModule::runForTesting(Module &M, ModuleAnalysisManager &MAM) {
987 std::unique_ptr<ModuleSummaryIndex> Summary =
988 std::make_unique<ModuleSummaryIndex>(/*HaveGVs=*/false);
989
990 // Handle the command-line summary arguments. This code is for testing
991 // purposes only, so we handle errors directly.
992 if (!ClReadSummary.empty()) {
993 ExitOnError ExitOnErr("-wholeprogramdevirt-read-summary: " + ClReadSummary +
994 ": ");
995 auto ReadSummaryFile =
997 if (Expected<std::unique_ptr<ModuleSummaryIndex>> SummaryOrErr =
998 getModuleSummaryIndex(*ReadSummaryFile)) {
999 Summary = std::move(*SummaryOrErr);
1000 ExitOnErr(checkCombinedSummaryForTesting(Summary.get()));
1001 } else {
1002 // Try YAML if we've failed with bitcode.
1003 consumeError(SummaryOrErr.takeError());
1004 yaml::Input In(ReadSummaryFile->getBuffer());
1005 In >> *Summary;
1006 ExitOnErr(errorCodeToError(In.error()));
1007 }
1008 }
1009
1010 bool Changed =
1011 DevirtModule(M, MAM,
1013 : nullptr,
1015 : nullptr)
1016 .run();
1017
1018 if (!ClWriteSummary.empty()) {
1019 ExitOnError ExitOnErr(
1020 "-wholeprogramdevirt-write-summary: " + ClWriteSummary + ": ");
1021 std::error_code EC;
1022 if (StringRef(ClWriteSummary).ends_with(".bc")) {
1024 ExitOnErr(errorCodeToError(EC));
1025 writeIndexToFile(*Summary, OS);
1026 } else {
1028 ExitOnErr(errorCodeToError(EC));
1029 yaml::Output Out(OS);
1030 Out << *Summary;
1031 }
1032 }
1033
1034 return Changed;
1035}
1036
1037void DevirtModule::buildTypeIdentifierMap(
1038 std::vector<VTableBits> &Bits,
1039 DenseMap<Metadata *, std::set<TypeMemberInfo>> &TypeIdMap) {
1041 Bits.reserve(M.global_size());
1043 for (GlobalVariable &GV : M.globals()) {
1044 Types.clear();
1045 GV.getMetadata(LLVMContext::MD_type, Types);
1046 if (GV.isDeclaration() || Types.empty())
1047 continue;
1048
1049 VTableBits *&BitsPtr = GVToBits[&GV];
1050 if (!BitsPtr) {
1051 Bits.emplace_back();
1052 Bits.back().GV = &GV;
1053 Bits.back().ObjectSize =
1054 M.getDataLayout().getTypeAllocSize(GV.getInitializer()->getType());
1055 BitsPtr = &Bits.back();
1056 }
1057
1058 for (MDNode *Type : Types) {
1059 auto *TypeID = Type->getOperand(1).get();
1060
1062 cast<ConstantInt>(
1063 cast<ConstantAsMetadata>(Type->getOperand(0))->getValue())
1064 ->getZExtValue();
1065
1066 TypeIdMap[TypeID].insert({BitsPtr, Offset});
1067 }
1068 }
1069}
1070
1071bool DevirtModule::tryFindVirtualCallTargets(
1072 std::vector<VirtualCallTarget> &TargetsForSlot,
1073 const std::set<TypeMemberInfo> &TypeMemberInfos, uint64_t ByteOffset,
1074 ModuleSummaryIndex *ExportSummary) {
1075 for (const TypeMemberInfo &TM : TypeMemberInfos) {
1076 if (!TM.Bits->GV->isConstant())
1077 return false;
1078
1079 // We cannot perform whole program devirtualization analysis on a vtable
1080 // with public LTO visibility.
1081 if (TM.Bits->GV->getVCallVisibility() ==
1083 return false;
1084
1085 Function *Fn = nullptr;
1086 Constant *C = nullptr;
1087 std::tie(Fn, C) =
1088 getFunctionAtVTableOffset(TM.Bits->GV, TM.Offset + ByteOffset, M);
1089
1090 if (!Fn)
1091 return false;
1092
1093 if (FunctionsToSkip.match(Fn->getName()))
1094 return false;
1095
1096 // We can disregard __cxa_pure_virtual as a possible call target, as
1097 // calls to pure virtuals are UB.
1098 if (Fn->getName() == "__cxa_pure_virtual")
1099 continue;
1100
1101 // We can disregard unreachable functions as possible call targets, as
1102 // unreachable functions shouldn't be called.
1103 if (mustBeUnreachableFunction(Fn, ExportSummary))
1104 continue;
1105
1106 // Save the symbol used in the vtable to use as the devirtualization
1107 // target.
1108 auto *GV = dyn_cast<GlobalValue>(C);
1109 assert(GV);
1110 TargetsForSlot.push_back({GV, &TM});
1111 }
1112
1113 // Give up if we couldn't find any targets.
1114 return !TargetsForSlot.empty();
1115}
1116
1117bool DevirtIndex::tryFindVirtualCallTargets(
1118 std::vector<ValueInfo> &TargetsForSlot,
1119 const TypeIdCompatibleVtableInfo TIdInfo, uint64_t ByteOffset) {
1120 for (const TypeIdOffsetVtableInfo &P : TIdInfo) {
1121 // Find a representative copy of the vtable initializer.
1122 // We can have multiple available_externally, linkonce_odr and weak_odr
1123 // vtable initializers. We can also have multiple external vtable
1124 // initializers in the case of comdats, which we cannot check here.
1125 // The linker should give an error in this case.
1126 //
1127 // Also, handle the case of same-named local Vtables with the same path
1128 // and therefore the same GUID. This can happen if there isn't enough
1129 // distinguishing path when compiling the source file. In that case we
1130 // conservatively return false early.
1131 const GlobalVarSummary *VS = nullptr;
1132 bool LocalFound = false;
1133 for (const auto &S : P.VTableVI.getSummaryList()) {
1134 if (GlobalValue::isLocalLinkage(S->linkage())) {
1135 if (LocalFound)
1136 return false;
1137 LocalFound = true;
1138 }
1139 auto *CurVS = cast<GlobalVarSummary>(S->getBaseObject());
1140 if (!CurVS->vTableFuncs().empty() ||
1141 // Previously clang did not attach the necessary type metadata to
1142 // available_externally vtables, in which case there would not
1143 // be any vtable functions listed in the summary and we need
1144 // to treat this case conservatively (in case the bitcode is old).
1145 // However, we will also not have any vtable functions in the
1146 // case of a pure virtual base class. In that case we do want
1147 // to set VS to avoid treating it conservatively.
1149 VS = CurVS;
1150 // We cannot perform whole program devirtualization analysis on a vtable
1151 // with public LTO visibility.
1152 if (VS->getVCallVisibility() == GlobalObject::VCallVisibilityPublic)
1153 return false;
1154 }
1155 }
1156 // There will be no VS if all copies are available_externally having no
1157 // type metadata. In that case we can't safely perform WPD.
1158 if (!VS)
1159 return false;
1160 if (!VS->isLive())
1161 continue;
1162 for (auto VTP : VS->vTableFuncs()) {
1163 if (VTP.VTableOffset != P.AddressPointOffset + ByteOffset)
1164 continue;
1165
1166 if (mustBeUnreachableFunction(VTP.FuncVI))
1167 continue;
1168
1169 TargetsForSlot.push_back(VTP.FuncVI);
1170 }
1171 }
1172
1173 // Give up if we couldn't find any targets.
1174 return !TargetsForSlot.empty();
1175}
1176
1177void DevirtModule::applySingleImplDevirt(VTableSlotInfo &SlotInfo,
1178 Constant *TheFn, bool &IsExported) {
1179 // Don't devirtualize function if we're told to skip it
1180 // in -wholeprogramdevirt-skip.
1181 if (FunctionsToSkip.match(TheFn->stripPointerCasts()->getName()))
1182 return;
1183 auto Apply = [&](CallSiteInfo &CSInfo) {
1184 for (auto &&VCallSite : CSInfo.CallSites) {
1185 if (!OptimizedCalls.insert(&VCallSite.CB).second)
1186 continue;
1187
1188 // Stop when the number of devirted calls reaches the cutoff.
1189 if (WholeProgramDevirtCutoff.getNumOccurrences() > 0 &&
1190 NumDevirtCalls >= WholeProgramDevirtCutoff)
1191 return;
1192
1193 if (RemarksEnabled)
1194 VCallSite.emitRemark("single-impl",
1195 TheFn->stripPointerCasts()->getName(), OREGetter);
1196 NumSingleImpl++;
1197 NumDevirtCalls++;
1198 auto &CB = VCallSite.CB;
1199 assert(!CB.getCalledFunction() && "devirtualizing direct call?");
1200 IRBuilder<> Builder(&CB);
1201 Value *Callee =
1202 Builder.CreateBitCast(TheFn, CB.getCalledOperand()->getType());
1203
1204 // If trap checking is enabled, add support to compare the virtual
1205 // function pointer to the devirtualized target. In case of a mismatch,
1206 // perform a debug trap.
1207 if (DevirtCheckMode == WPDCheckMode::Trap) {
1208 auto *Cond = Builder.CreateICmpNE(CB.getCalledOperand(), Callee);
1210 Cond, &CB, /*Unreachable=*/false,
1211 MDBuilder(M.getContext()).createUnlikelyBranchWeights());
1212 Builder.SetInsertPoint(ThenTerm);
1213 Function *TrapFn =
1214 Intrinsic::getOrInsertDeclaration(&M, Intrinsic::debugtrap);
1215 auto *CallTrap = Builder.CreateCall(TrapFn);
1216 CallTrap->setDebugLoc(CB.getDebugLoc());
1217 }
1218
1219 // If fallback checking is enabled, add support to compare the virtual
1220 // function pointer to the devirtualized target. In case of a mismatch,
1221 // fall back to indirect call.
1222 if (DevirtCheckMode == WPDCheckMode::Fallback) {
1223 MDNode *Weights = MDBuilder(M.getContext()).createLikelyBranchWeights();
1224 // Version the indirect call site. If the called value is equal to the
1225 // given callee, 'NewInst' will be executed, otherwise the original call
1226 // site will be executed.
1227 CallBase &NewInst = versionCallSite(CB, Callee, Weights);
1228 NewInst.setCalledOperand(Callee);
1229 // Since the new call site is direct, we must clear metadata that
1230 // is only appropriate for indirect calls. This includes !prof and
1231 // !callees metadata.
1232 NewInst.setMetadata(LLVMContext::MD_prof, nullptr);
1233 NewInst.setMetadata(LLVMContext::MD_callees, nullptr);
1234 // Additionally, we should remove them from the fallback indirect call,
1235 // so that we don't attempt to perform indirect call promotion later.
1236 CB.setMetadata(LLVMContext::MD_prof, nullptr);
1237 CB.setMetadata(LLVMContext::MD_callees, nullptr);
1238 }
1239
1240 // In either trapping or non-checking mode, devirtualize original call.
1241 else {
1242 // Devirtualize unconditionally.
1243 CB.setCalledOperand(Callee);
1244 // Since the call site is now direct, we must clear metadata that
1245 // is only appropriate for indirect calls. This includes !prof and
1246 // !callees metadata.
1247 CB.setMetadata(LLVMContext::MD_prof, nullptr);
1248 CB.setMetadata(LLVMContext::MD_callees, nullptr);
1249 if (CB.getCalledOperand() &&
1251 auto *NewCS = CallBase::removeOperandBundle(
1253 CB.replaceAllUsesWith(NewCS);
1254 // Schedule for deletion at the end of pass run.
1255 CallsWithPtrAuthBundleRemoved.push_back(&CB);
1256 }
1257 }
1258
1259 // This use is no longer unsafe.
1260 if (VCallSite.NumUnsafeUses)
1261 --*VCallSite.NumUnsafeUses;
1262 }
1263 if (CSInfo.isExported())
1264 IsExported = true;
1265 CSInfo.markDevirt();
1266 };
1267 Apply(SlotInfo.CSInfo);
1268 for (auto &P : SlotInfo.ConstCSInfo)
1269 Apply(P.second);
1270}
1271
1272static bool addCalls(VTableSlotInfo &SlotInfo, const ValueInfo &Callee) {
1273 // We can't add calls if we haven't seen a definition
1274 if (Callee.getSummaryList().empty())
1275 return false;
1276
1277 // Insert calls into the summary index so that the devirtualized targets
1278 // are eligible for import.
1279 // FIXME: Annotate type tests with hotness. For now, mark these as hot
1280 // to better ensure we have the opportunity to inline them.
1281 bool IsExported = false;
1282 auto &S = Callee.getSummaryList()[0];
1283 CalleeInfo CI(CalleeInfo::HotnessType::Hot, /* HasTailCall = */ false,
1284 /* RelBF = */ 0);
1285 auto AddCalls = [&](CallSiteInfo &CSInfo) {
1286 for (auto *FS : CSInfo.SummaryTypeCheckedLoadUsers) {
1287 FS->addCall({Callee, CI});
1288 IsExported |= S->modulePath() != FS->modulePath();
1289 }
1290 for (auto *FS : CSInfo.SummaryTypeTestAssumeUsers) {
1291 FS->addCall({Callee, CI});
1292 IsExported |= S->modulePath() != FS->modulePath();
1293 }
1294 };
1295 AddCalls(SlotInfo.CSInfo);
1296 for (auto &P : SlotInfo.ConstCSInfo)
1297 AddCalls(P.second);
1298 return IsExported;
1299}
1300
1301bool DevirtModule::trySingleImplDevirt(
1302 ModuleSummaryIndex *ExportSummary,
1303 MutableArrayRef<VirtualCallTarget> TargetsForSlot, VTableSlotInfo &SlotInfo,
1305 // See if the program contains a single implementation of this virtual
1306 // function.
1307 auto *TheFn = TargetsForSlot[0].Fn;
1308 for (auto &&Target : TargetsForSlot)
1309 if (TheFn != Target.Fn)
1310 return false;
1311
1312 // If so, update each call site to call that implementation directly.
1313 if (RemarksEnabled || AreStatisticsEnabled())
1314 TargetsForSlot[0].WasDevirt = true;
1315
1316 bool IsExported = false;
1317 applySingleImplDevirt(SlotInfo, TheFn, IsExported);
1318 if (!IsExported)
1319 return false;
1320
1321 // If the only implementation has local linkage, we must promote to external
1322 // to make it visible to thin LTO objects. We can only get here during the
1323 // ThinLTO export phase.
1324 if (TheFn->hasLocalLinkage()) {
1325 std::string NewName = (TheFn->getName() + ".llvm.merged").str();
1326
1327 // Since we are renaming the function, any comdats with the same name must
1328 // also be renamed. This is required when targeting COFF, as the comdat name
1329 // must match one of the names of the symbols in the comdat.
1330 if (Comdat *C = TheFn->getComdat()) {
1331 if (C->getName() == TheFn->getName()) {
1332 Comdat *NewC = M.getOrInsertComdat(NewName);
1333 NewC->setSelectionKind(C->getSelectionKind());
1334 for (GlobalObject &GO : M.global_objects())
1335 if (GO.getComdat() == C)
1336 GO.setComdat(NewC);
1337 }
1338 }
1339
1340 TheFn->setLinkage(GlobalValue::ExternalLinkage);
1341 TheFn->setVisibility(GlobalValue::HiddenVisibility);
1342 TheFn->setName(NewName);
1343 }
1344 if (ValueInfo TheFnVI = ExportSummary->getValueInfo(TheFn->getGUID()))
1345 // Any needed promotion of 'TheFn' has already been done during
1346 // LTO unit split, so we can ignore return value of AddCalls.
1347 addCalls(SlotInfo, TheFnVI);
1348
1350 Res->SingleImplName = std::string(TheFn->getName());
1351
1352 return true;
1353}
1354
1355bool DevirtIndex::trySingleImplDevirt(MutableArrayRef<ValueInfo> TargetsForSlot,
1356 VTableSlotSummary &SlotSummary,
1357 VTableSlotInfo &SlotInfo,
1359 std::set<ValueInfo> &DevirtTargets) {
1360 // See if the program contains a single implementation of this virtual
1361 // function.
1362 auto TheFn = TargetsForSlot[0];
1363 for (auto &&Target : TargetsForSlot)
1364 if (TheFn != Target)
1365 return false;
1366
1367 // Don't devirtualize if we don't have target definition.
1368 auto Size = TheFn.getSummaryList().size();
1369 if (!Size)
1370 return false;
1371
1372 // Don't devirtualize function if we're told to skip it
1373 // in -wholeprogramdevirt-skip.
1374 if (FunctionsToSkip.match(TheFn.name()))
1375 return false;
1376
1377 // If the summary list contains multiple summaries where at least one is
1378 // a local, give up, as we won't know which (possibly promoted) name to use.
1379 for (const auto &S : TheFn.getSummaryList())
1380 if (GlobalValue::isLocalLinkage(S->linkage()) && Size > 1)
1381 return false;
1382
1383 // Collect functions devirtualized at least for one call site for stats.
1385 DevirtTargets.insert(TheFn);
1386
1387 auto &S = TheFn.getSummaryList()[0];
1388 bool IsExported = addCalls(SlotInfo, TheFn);
1389 if (IsExported)
1390 ExportedGUIDs.insert(TheFn.getGUID());
1391
1392 // Record in summary for use in devirtualization during the ThinLTO import
1393 // step.
1395 if (GlobalValue::isLocalLinkage(S->linkage())) {
1396 if (IsExported)
1397 // If target is a local function and we are exporting it by
1398 // devirtualizing a call in another module, we need to record the
1399 // promoted name.
1401 TheFn.name(), ExportSummary.getModuleHash(S->modulePath()));
1402 else {
1403 LocalWPDTargetsMap[TheFn].push_back(SlotSummary);
1404 Res->SingleImplName = std::string(TheFn.name());
1405 }
1406 } else
1407 Res->SingleImplName = std::string(TheFn.name());
1408
1409 // Name will be empty if this thin link driven off of serialized combined
1410 // index (e.g. llvm-lto). However, WPD is not supported/invoked for the
1411 // legacy LTO API anyway.
1412 assert(!Res->SingleImplName.empty());
1413
1414 return true;
1415}
1416
1417void DevirtModule::tryICallBranchFunnel(
1418 MutableArrayRef<VirtualCallTarget> TargetsForSlot, VTableSlotInfo &SlotInfo,
1419 WholeProgramDevirtResolution *Res, VTableSlot Slot) {
1420 Triple T(M.getTargetTriple());
1421 if (T.getArch() != Triple::x86_64)
1422 return;
1423
1424 if (TargetsForSlot.size() > ClThreshold)
1425 return;
1426
1427 bool HasNonDevirt = !SlotInfo.CSInfo.AllCallSitesDevirted;
1428 if (!HasNonDevirt)
1429 for (auto &P : SlotInfo.ConstCSInfo)
1430 if (!P.second.AllCallSitesDevirted) {
1431 HasNonDevirt = true;
1432 break;
1433 }
1434
1435 if (!HasNonDevirt)
1436 return;
1437
1438 // If any GV is AvailableExternally, not to generate branch.funnel.
1439 // NOTE: It is to avoid crash in LowerTypeTest.
1440 // If the branch.funnel is generated, because GV.isDeclarationForLinker(),
1441 // in LowerTypeTestsModule::lower(), its GlobalTypeMember would NOT
1442 // be saved in GlobalTypeMembers[&GV]. Then crash happens in
1443 // buildBitSetsFromDisjointSet due to GlobalTypeMembers[&GV] is NULL.
1444 // Even doing experiment to save it in GlobalTypeMembers[&GV] and
1445 // making GlobalTypeMembers[&GV] be not NULL, crash could avoid from
1446 // buildBitSetsFromDisjointSet. But still report_fatal_error in Verifier
1447 // or SelectionDAGBuilder later, because operands linkage type consistency
1448 // check of icall.branch.funnel can not pass.
1449 for (auto &T : TargetsForSlot) {
1450 if (T.TM->Bits->GV->hasAvailableExternallyLinkage())
1451 return;
1452 }
1453
1454 FunctionType *FT =
1455 FunctionType::get(Type::getVoidTy(M.getContext()), {Int8PtrTy}, true);
1456 Function *JT;
1457 if (isa<MDString>(Slot.TypeID)) {
1459 M.getDataLayout().getProgramAddressSpace(),
1460 getGlobalName(Slot, {}, "branch_funnel"), &M);
1461 JT->setVisibility(GlobalValue::HiddenVisibility);
1462 } else {
1464 M.getDataLayout().getProgramAddressSpace(),
1465 "branch_funnel", &M);
1466 }
1467 JT->addParamAttr(0, Attribute::Nest);
1468
1469 std::vector<Value *> JTArgs;
1470 JTArgs.push_back(JT->arg_begin());
1471 for (auto &T : TargetsForSlot) {
1472 JTArgs.push_back(getMemberAddr(T.TM));
1473 JTArgs.push_back(T.Fn);
1474 }
1475
1476 BasicBlock *BB = BasicBlock::Create(M.getContext(), "", JT, nullptr);
1478 &M, llvm::Intrinsic::icall_branch_funnel, {});
1479
1480 auto *CI = CallInst::Create(Intr, JTArgs, "", BB);
1481 CI->setTailCallKind(CallInst::TCK_MustTail);
1482 ReturnInst::Create(M.getContext(), nullptr, BB);
1483
1484 bool IsExported = false;
1485 applyICallBranchFunnel(SlotInfo, JT, IsExported);
1486 if (IsExported)
1488}
1489
1490void DevirtModule::applyICallBranchFunnel(VTableSlotInfo &SlotInfo,
1491 Constant *JT, bool &IsExported) {
1492 auto Apply = [&](CallSiteInfo &CSInfo) {
1493 if (CSInfo.isExported())
1494 IsExported = true;
1495 if (CSInfo.AllCallSitesDevirted)
1496 return;
1497
1498 std::map<CallBase *, CallBase *> CallBases;
1499 for (auto &&VCallSite : CSInfo.CallSites) {
1500 CallBase &CB = VCallSite.CB;
1501
1502 if (CallBases.find(&CB) != CallBases.end()) {
1503 // When finding devirtualizable calls, it's possible to find the same
1504 // vtable passed to multiple llvm.type.test or llvm.type.checked.load
1505 // calls, which can cause duplicate call sites to be recorded in
1506 // [Const]CallSites. If we've already found one of these
1507 // call instances, just ignore it. It will be replaced later.
1508 continue;
1509 }
1510
1511 // Jump tables are only profitable if the retpoline mitigation is enabled.
1512 Attribute FSAttr = CB.getCaller()->getFnAttribute("target-features");
1513 if (!FSAttr.isValid() ||
1514 !FSAttr.getValueAsString().contains("+retpoline"))
1515 continue;
1516
1517 NumBranchFunnel++;
1518 if (RemarksEnabled)
1519 VCallSite.emitRemark("branch-funnel",
1520 JT->stripPointerCasts()->getName(), OREGetter);
1521
1522 // Pass the address of the vtable in the nest register, which is r10 on
1523 // x86_64.
1524 std::vector<Type *> NewArgs;
1525 NewArgs.push_back(Int8PtrTy);
1526 append_range(NewArgs, CB.getFunctionType()->params());
1527 FunctionType *NewFT =
1529 CB.getFunctionType()->isVarArg());
1530 IRBuilder<> IRB(&CB);
1531 std::vector<Value *> Args;
1532 Args.push_back(VCallSite.VTable);
1533 llvm::append_range(Args, CB.args());
1534
1535 CallBase *NewCS = nullptr;
1536 if (isa<CallInst>(CB))
1537 NewCS = IRB.CreateCall(NewFT, JT, Args);
1538 else
1539 NewCS =
1540 IRB.CreateInvoke(NewFT, JT, cast<InvokeInst>(CB).getNormalDest(),
1541 cast<InvokeInst>(CB).getUnwindDest(), Args);
1542 NewCS->setCallingConv(CB.getCallingConv());
1543
1545 std::vector<AttributeSet> NewArgAttrs;
1546 NewArgAttrs.push_back(AttributeSet::get(
1547 M.getContext(), ArrayRef<Attribute>{Attribute::get(
1548 M.getContext(), Attribute::Nest)}));
1549 for (unsigned I = 0; I + 2 < Attrs.getNumAttrSets(); ++I)
1550 NewArgAttrs.push_back(Attrs.getParamAttrs(I));
1551 NewCS->setAttributes(
1552 AttributeList::get(M.getContext(), Attrs.getFnAttrs(),
1553 Attrs.getRetAttrs(), NewArgAttrs));
1554
1555 CallBases[&CB] = NewCS;
1556
1557 // This use is no longer unsafe.
1558 if (VCallSite.NumUnsafeUses)
1559 --*VCallSite.NumUnsafeUses;
1560 }
1561 // Don't mark as devirtualized because there may be callers compiled without
1562 // retpoline mitigation, which would mean that they are lowered to
1563 // llvm.type.test and therefore require an llvm.type.test resolution for the
1564 // type identifier.
1565
1566 for (auto &[Old, New] : CallBases) {
1567 Old->replaceAllUsesWith(New);
1568 Old->eraseFromParent();
1569 }
1570 };
1571 Apply(SlotInfo.CSInfo);
1572 for (auto &P : SlotInfo.ConstCSInfo)
1573 Apply(P.second);
1574}
1575
1576bool DevirtModule::tryEvaluateFunctionsWithArgs(
1578 ArrayRef<uint64_t> Args) {
1579 // Evaluate each function and store the result in each target's RetVal
1580 // field.
1581 for (VirtualCallTarget &Target : TargetsForSlot) {
1582 // TODO: Skip for now if the vtable symbol was an alias to a function,
1583 // need to evaluate whether it would be correct to analyze the aliasee
1584 // function for this optimization.
1585 auto *Fn = dyn_cast<Function>(Target.Fn);
1586 if (!Fn)
1587 return false;
1588
1589 if (Fn->arg_size() != Args.size() + 1)
1590 return false;
1591
1592 Evaluator Eval(M.getDataLayout(), nullptr);
1594 EvalArgs.push_back(
1596 for (unsigned I = 0; I != Args.size(); ++I) {
1597 auto *ArgTy =
1598 dyn_cast<IntegerType>(Fn->getFunctionType()->getParamType(I + 1));
1599 if (!ArgTy)
1600 return false;
1601 EvalArgs.push_back(ConstantInt::get(ArgTy, Args[I]));
1602 }
1603
1604 Constant *RetVal;
1605 if (!Eval.EvaluateFunction(Fn, RetVal, EvalArgs) ||
1606 !isa<ConstantInt>(RetVal))
1607 return false;
1608 Target.RetVal = cast<ConstantInt>(RetVal)->getZExtValue();
1609 }
1610 return true;
1611}
1612
1613void DevirtModule::applyUniformRetValOpt(CallSiteInfo &CSInfo, StringRef FnName,
1614 uint64_t TheRetVal) {
1615 for (auto Call : CSInfo.CallSites) {
1616 if (!OptimizedCalls.insert(&Call.CB).second)
1617 continue;
1618 NumUniformRetVal++;
1619 Call.replaceAndErase(
1620 "uniform-ret-val", FnName, RemarksEnabled, OREGetter,
1621 ConstantInt::get(cast<IntegerType>(Call.CB.getType()), TheRetVal));
1622 }
1623 CSInfo.markDevirt();
1624}
1625
1626bool DevirtModule::tryUniformRetValOpt(
1627 MutableArrayRef<VirtualCallTarget> TargetsForSlot, CallSiteInfo &CSInfo,
1629 // Uniform return value optimization. If all functions return the same
1630 // constant, replace all calls with that constant.
1631 uint64_t TheRetVal = TargetsForSlot[0].RetVal;
1632 for (const VirtualCallTarget &Target : TargetsForSlot)
1633 if (Target.RetVal != TheRetVal)
1634 return false;
1635
1636 if (CSInfo.isExported()) {
1638 Res->Info = TheRetVal;
1639 }
1640
1641 applyUniformRetValOpt(CSInfo, TargetsForSlot[0].Fn->getName(), TheRetVal);
1642 if (RemarksEnabled || AreStatisticsEnabled())
1643 for (auto &&Target : TargetsForSlot)
1644 Target.WasDevirt = true;
1645 return true;
1646}
1647
1648std::string DevirtModule::getGlobalName(VTableSlot Slot,
1649 ArrayRef<uint64_t> Args,
1650 StringRef Name) {
1651 std::string FullName = "__typeid_";
1652 raw_string_ostream OS(FullName);
1653 OS << cast<MDString>(Slot.TypeID)->getString() << '_' << Slot.ByteOffset;
1654 for (uint64_t Arg : Args)
1655 OS << '_' << Arg;
1656 OS << '_' << Name;
1657 return FullName;
1658}
1659
1660bool DevirtModule::shouldExportConstantsAsAbsoluteSymbols() {
1661 Triple T(M.getTargetTriple());
1662 return T.isX86() && T.getObjectFormat() == Triple::ELF;
1663}
1664
1665void DevirtModule::exportGlobal(VTableSlot Slot, ArrayRef<uint64_t> Args,
1668 getGlobalName(Slot, Args, Name), C, &M);
1670}
1671
1672void DevirtModule::exportConstant(VTableSlot Slot, ArrayRef<uint64_t> Args,
1673 StringRef Name, uint32_t Const,
1674 uint32_t &Storage) {
1675 if (shouldExportConstantsAsAbsoluteSymbols()) {
1676 exportGlobal(
1677 Slot, Args, Name,
1678 ConstantExpr::getIntToPtr(ConstantInt::get(Int32Ty, Const), Int8PtrTy));
1679 return;
1680 }
1681
1682 Storage = Const;
1683}
1684
1685Constant *DevirtModule::importGlobal(VTableSlot Slot, ArrayRef<uint64_t> Args,
1686 StringRef Name) {
1687 GlobalVariable *GV =
1688 M.getOrInsertGlobal(getGlobalName(Slot, Args, Name), Int8Arr0Ty);
1690 return GV;
1691}
1692
1693Constant *DevirtModule::importConstant(VTableSlot Slot, ArrayRef<uint64_t> Args,
1694 StringRef Name, IntegerType *IntTy,
1695 uint32_t Storage) {
1696 if (!shouldExportConstantsAsAbsoluteSymbols())
1697 return ConstantInt::get(IntTy, Storage);
1698
1699 Constant *C = importGlobal(Slot, Args, Name);
1700 auto *GV = cast<GlobalVariable>(C->stripPointerCasts());
1701 C = ConstantExpr::getPtrToInt(C, IntTy);
1702
1703 // We only need to set metadata if the global is newly created, in which
1704 // case it would not have hidden visibility.
1705 if (GV->hasMetadata(LLVMContext::MD_absolute_symbol))
1706 return C;
1707
1708 auto SetAbsRange = [&](uint64_t Min, uint64_t Max) {
1709 auto *MinC = ConstantAsMetadata::get(ConstantInt::get(IntPtrTy, Min));
1710 auto *MaxC = ConstantAsMetadata::get(ConstantInt::get(IntPtrTy, Max));
1711 GV->setMetadata(LLVMContext::MD_absolute_symbol,
1712 MDNode::get(M.getContext(), {MinC, MaxC}));
1713 };
1714 unsigned AbsWidth = IntTy->getBitWidth();
1715 if (AbsWidth == IntPtrTy->getBitWidth())
1716 SetAbsRange(~0ull, ~0ull); // Full set.
1717 else
1718 SetAbsRange(0, 1ull << AbsWidth);
1719 return C;
1720}
1721
1722void DevirtModule::applyUniqueRetValOpt(CallSiteInfo &CSInfo, StringRef FnName,
1723 bool IsOne,
1724 Constant *UniqueMemberAddr) {
1725 for (auto &&Call : CSInfo.CallSites) {
1726 if (!OptimizedCalls.insert(&Call.CB).second)
1727 continue;
1728 IRBuilder<> B(&Call.CB);
1729 Value *Cmp =
1730 B.CreateICmp(IsOne ? ICmpInst::ICMP_EQ : ICmpInst::ICMP_NE, Call.VTable,
1731 B.CreateBitCast(UniqueMemberAddr, Call.VTable->getType()));
1732 Cmp = B.CreateZExt(Cmp, Call.CB.getType());
1733 NumUniqueRetVal++;
1734 Call.replaceAndErase("unique-ret-val", FnName, RemarksEnabled, OREGetter,
1735 Cmp);
1736 }
1737 CSInfo.markDevirt();
1738}
1739
1740Constant *DevirtModule::getMemberAddr(const TypeMemberInfo *M) {
1741 return ConstantExpr::getGetElementPtr(Int8Ty, M->Bits->GV,
1742 ConstantInt::get(Int64Ty, M->Offset));
1743}
1744
1745bool DevirtModule::tryUniqueRetValOpt(
1746 unsigned BitWidth, MutableArrayRef<VirtualCallTarget> TargetsForSlot,
1747 CallSiteInfo &CSInfo, WholeProgramDevirtResolution::ByArg *Res,
1748 VTableSlot Slot, ArrayRef<uint64_t> Args) {
1749 // IsOne controls whether we look for a 0 or a 1.
1750 auto tryUniqueRetValOptFor = [&](bool IsOne) {
1751 const TypeMemberInfo *UniqueMember = nullptr;
1752 for (const VirtualCallTarget &Target : TargetsForSlot) {
1753 if (Target.RetVal == (IsOne ? 1 : 0)) {
1754 if (UniqueMember)
1755 return false;
1756 UniqueMember = Target.TM;
1757 }
1758 }
1759
1760 // We should have found a unique member or bailed out by now. We already
1761 // checked for a uniform return value in tryUniformRetValOpt.
1762 assert(UniqueMember);
1763
1764 Constant *UniqueMemberAddr = getMemberAddr(UniqueMember);
1765 if (CSInfo.isExported()) {
1767 Res->Info = IsOne;
1768
1769 exportGlobal(Slot, Args, "unique_member", UniqueMemberAddr);
1770 }
1771
1772 // Replace each call with the comparison.
1773 applyUniqueRetValOpt(CSInfo, TargetsForSlot[0].Fn->getName(), IsOne,
1774 UniqueMemberAddr);
1775
1776 // Update devirtualization statistics for targets.
1777 if (RemarksEnabled || AreStatisticsEnabled())
1778 for (auto &&Target : TargetsForSlot)
1779 Target.WasDevirt = true;
1780
1781 return true;
1782 };
1783
1784 if (BitWidth == 1) {
1785 if (tryUniqueRetValOptFor(true))
1786 return true;
1787 if (tryUniqueRetValOptFor(false))
1788 return true;
1789 }
1790 return false;
1791}
1792
1793void DevirtModule::applyVirtualConstProp(CallSiteInfo &CSInfo, StringRef FnName,
1794 Constant *Byte, Constant *Bit) {
1795 for (auto Call : CSInfo.CallSites) {
1796 if (!OptimizedCalls.insert(&Call.CB).second)
1797 continue;
1798 auto *RetType = cast<IntegerType>(Call.CB.getType());
1799 IRBuilder<> B(&Call.CB);
1800 Value *Addr = B.CreatePtrAdd(Call.VTable, Byte);
1801 if (RetType->getBitWidth() == 1) {
1802 Value *Bits = B.CreateLoad(Int8Ty, Addr);
1803 Value *BitsAndBit = B.CreateAnd(Bits, Bit);
1804 auto IsBitSet = B.CreateICmpNE(BitsAndBit, ConstantInt::get(Int8Ty, 0));
1805 NumVirtConstProp1Bit++;
1806 Call.replaceAndErase("virtual-const-prop-1-bit", FnName, RemarksEnabled,
1807 OREGetter, IsBitSet);
1808 } else {
1809 Value *Val = B.CreateLoad(RetType, Addr);
1810 NumVirtConstProp++;
1811 Call.replaceAndErase("virtual-const-prop", FnName, RemarksEnabled,
1812 OREGetter, Val);
1813 }
1814 }
1815 CSInfo.markDevirt();
1816}
1817
1818bool DevirtModule::tryVirtualConstProp(
1819 MutableArrayRef<VirtualCallTarget> TargetsForSlot, VTableSlotInfo &SlotInfo,
1820 WholeProgramDevirtResolution *Res, VTableSlot Slot) {
1821 // TODO: Skip for now if the vtable symbol was an alias to a function,
1822 // need to evaluate whether it would be correct to analyze the aliasee
1823 // function for this optimization.
1824 auto *Fn = dyn_cast<Function>(TargetsForSlot[0].Fn);
1825 if (!Fn)
1826 return false;
1827 // This only works if the function returns an integer.
1828 auto *RetType = dyn_cast<IntegerType>(Fn->getReturnType());
1829 if (!RetType)
1830 return false;
1831 unsigned BitWidth = RetType->getBitWidth();
1832
1833 // TODO: Since we can evaluated these constants at compile-time, we can save
1834 // some space by calculating the smallest range of values that all these
1835 // constants can fit in, then only allocate enough space to fit those values.
1836 // At each callsite, we can get the original type by doing a sign/zero
1837 // extension. For example, if we would store an i64, but we can see that all
1838 // the values fit into an i16, then we can store an i16 before/after the
1839 // vtable and at each callsite do a s/zext.
1840 if (BitWidth > 64)
1841 return false;
1842
1843 Align TypeAlignment = M.getDataLayout().getABIIntegerTypeAlignment(BitWidth);
1844
1845 // Make sure that each function is defined, does not access memory, takes at
1846 // least one argument, does not use its first argument (which we assume is
1847 // 'this'), and has the same return type.
1848 //
1849 // Note that we test whether this copy of the function is readnone, rather
1850 // than testing function attributes, which must hold for any copy of the
1851 // function, even a less optimized version substituted at link time. This is
1852 // sound because the virtual constant propagation optimizations effectively
1853 // inline all implementations of the virtual function into each call site,
1854 // rather than using function attributes to perform local optimization.
1855 for (VirtualCallTarget &Target : TargetsForSlot) {
1856 // TODO: Skip for now if the vtable symbol was an alias to a function,
1857 // need to evaluate whether it would be correct to analyze the aliasee
1858 // function for this optimization.
1859 auto *Fn = dyn_cast<Function>(Target.Fn);
1860 if (!Fn)
1861 return false;
1862
1863 if (Fn->isDeclaration() ||
1866 Fn->arg_empty() || !Fn->arg_begin()->use_empty() ||
1867 Fn->getReturnType() != RetType)
1868 return false;
1869
1870 // This only works if the integer size is at most the alignment of the
1871 // vtable. If the table is underaligned, then we can't guarantee that the
1872 // constant will always be aligned to the integer type alignment. For
1873 // example, if the table is `align 1`, we can never guarantee that an i32
1874 // stored before/after the vtable is 32-bit aligned without changing the
1875 // alignment of the new global.
1876 GlobalVariable *GV = Target.TM->Bits->GV;
1877 Align TableAlignment = M.getDataLayout().getValueOrABITypeAlignment(
1878 GV->getAlign(), GV->getValueType());
1879 if (TypeAlignment > TableAlignment)
1880 return false;
1881 }
1882
1883 for (auto &&CSByConstantArg : SlotInfo.ConstCSInfo) {
1884 if (!tryEvaluateFunctionsWithArgs(TargetsForSlot, CSByConstantArg.first))
1885 continue;
1886
1887 WholeProgramDevirtResolution::ByArg *ResByArg = nullptr;
1888 if (Res)
1889 ResByArg = &Res->ResByArg[CSByConstantArg.first];
1890
1891 if (tryUniformRetValOpt(TargetsForSlot, CSByConstantArg.second, ResByArg))
1892 continue;
1893
1894 if (tryUniqueRetValOpt(BitWidth, TargetsForSlot, CSByConstantArg.second,
1895 ResByArg, Slot, CSByConstantArg.first))
1896 continue;
1897
1898 // Find an allocation offset in bits in all vtables associated with the
1899 // type.
1900 // TODO: If there would be "holes" in the vtable that were added by
1901 // padding, we could place i1s there to reduce any extra padding that
1902 // would be introduced by the i1s.
1903 uint64_t AllocBefore =
1904 findLowestOffset(TargetsForSlot, /*IsAfter=*/false, BitWidth);
1905 uint64_t AllocAfter =
1906 findLowestOffset(TargetsForSlot, /*IsAfter=*/true, BitWidth);
1907
1908 // Calculate the total amount of padding needed to store a value at both
1909 // ends of the object.
1910 uint64_t TotalPaddingBefore = 0, TotalPaddingAfter = 0;
1911 for (auto &&Target : TargetsForSlot) {
1912 TotalPaddingBefore += std::max<int64_t>(
1913 (AllocBefore + 7) / 8 - Target.allocatedBeforeBytes() - 1, 0);
1914 TotalPaddingAfter += std::max<int64_t>(
1915 (AllocAfter + 7) / 8 - Target.allocatedAfterBytes() - 1, 0);
1916 }
1917
1918 // If the amount of padding is too large, give up.
1919 // FIXME: do something smarter here.
1920 if (std::min(TotalPaddingBefore, TotalPaddingAfter) > 128)
1921 continue;
1922
1923 // Calculate the offset to the value as a (possibly negative) byte offset
1924 // and (if applicable) a bit offset, and store the values in the targets.
1925 int64_t OffsetByte;
1926 uint64_t OffsetBit;
1927 if (TotalPaddingBefore <= TotalPaddingAfter)
1928 setBeforeReturnValues(TargetsForSlot, AllocBefore, BitWidth, OffsetByte,
1929 OffsetBit);
1930 else
1931 setAfterReturnValues(TargetsForSlot, AllocAfter, BitWidth, OffsetByte,
1932 OffsetBit);
1933
1934 // In an earlier check we forbade constant propagation from operating on
1935 // tables whose alignment is less than the alignment needed for loading
1936 // the constant. Thus, the address we take the offset from will always be
1937 // aligned to at least this integer alignment. Now, we need to ensure that
1938 // the offset is also aligned to this integer alignment to ensure we always
1939 // have an aligned load.
1940 assert(OffsetByte % TypeAlignment.value() == 0);
1941
1942 if (RemarksEnabled || AreStatisticsEnabled())
1943 for (auto &&Target : TargetsForSlot)
1944 Target.WasDevirt = true;
1945
1946
1947 if (CSByConstantArg.second.isExported()) {
1949 exportConstant(Slot, CSByConstantArg.first, "byte", OffsetByte,
1950 ResByArg->Byte);
1951 exportConstant(Slot, CSByConstantArg.first, "bit", 1ULL << OffsetBit,
1952 ResByArg->Bit);
1953 }
1954
1955 // Rewrite each call to a load from OffsetByte/OffsetBit.
1956 Constant *ByteConst = ConstantInt::get(Int32Ty, OffsetByte);
1957 Constant *BitConst = ConstantInt::get(Int8Ty, 1ULL << OffsetBit);
1958 applyVirtualConstProp(CSByConstantArg.second,
1959 TargetsForSlot[0].Fn->getName(), ByteConst, BitConst);
1960 }
1961 return true;
1962}
1963
1964void DevirtModule::rebuildGlobal(VTableBits &B) {
1965 if (B.Before.Bytes.empty() && B.After.Bytes.empty())
1966 return;
1967
1968 // Align the before byte array to the global's minimum alignment so that we
1969 // don't break any alignment requirements on the global.
1970 Align Alignment = M.getDataLayout().getValueOrABITypeAlignment(
1971 B.GV->getAlign(), B.GV->getValueType());
1972 B.Before.Bytes.resize(alignTo(B.Before.Bytes.size(), Alignment));
1973
1974 // Before was stored in reverse order; flip it now.
1975 for (size_t I = 0, Size = B.Before.Bytes.size(); I != Size / 2; ++I)
1976 std::swap(B.Before.Bytes[I], B.Before.Bytes[Size - 1 - I]);
1977
1978 // Build an anonymous global containing the before bytes, followed by the
1979 // original initializer, followed by the after bytes.
1980 auto *NewInit = ConstantStruct::getAnon(
1981 {ConstantDataArray::get(M.getContext(), B.Before.Bytes),
1982 B.GV->getInitializer(),
1983 ConstantDataArray::get(M.getContext(), B.After.Bytes)});
1984 auto *NewGV =
1985 new GlobalVariable(M, NewInit->getType(), B.GV->isConstant(),
1986 GlobalVariable::PrivateLinkage, NewInit, "", B.GV);
1987 NewGV->setSection(B.GV->getSection());
1988 NewGV->setComdat(B.GV->getComdat());
1989 NewGV->setAlignment(B.GV->getAlign());
1990
1991 // Copy the original vtable's metadata to the anonymous global, adjusting
1992 // offsets as required.
1993 NewGV->copyMetadata(B.GV, B.Before.Bytes.size());
1994
1995 // Build an alias named after the original global, pointing at the second
1996 // element (the original initializer).
1997 auto *Alias = GlobalAlias::create(
1998 B.GV->getInitializer()->getType(), 0, B.GV->getLinkage(), "",
2000 NewInit->getType(), NewGV,
2001 ArrayRef<Constant *>{ConstantInt::get(Int32Ty, 0),
2002 ConstantInt::get(Int32Ty, 1)}),
2003 &M);
2004 Alias->setVisibility(B.GV->getVisibility());
2005 Alias->takeName(B.GV);
2006
2007 B.GV->replaceAllUsesWith(Alias);
2008 B.GV->eraseFromParent();
2009}
2010
2011bool DevirtModule::areRemarksEnabled() {
2012 const auto &FL = M.getFunctionList();
2013 for (const Function &Fn : FL) {
2014 if (Fn.empty())
2015 continue;
2016 auto DI = OptimizationRemark(DEBUG_TYPE, "", DebugLoc(), &Fn.front());
2017 return DI.isEnabled();
2018 }
2019 return false;
2020}
2021
2022void DevirtModule::scanTypeTestUsers(
2023 Function *TypeTestFunc,
2024 DenseMap<Metadata *, std::set<TypeMemberInfo>> &TypeIdMap) {
2025 // Find all virtual calls via a virtual table pointer %p under an assumption
2026 // of the form llvm.assume(llvm.type.test(%p, %md)). This indicates that %p
2027 // points to a member of the type identifier %md. Group calls by (type ID,
2028 // offset) pair (effectively the identity of the virtual function) and store
2029 // to CallSlots.
2030 for (Use &U : llvm::make_early_inc_range(TypeTestFunc->uses())) {
2031 auto *CI = dyn_cast<CallInst>(U.getUser());
2032 if (!CI)
2033 continue;
2034
2035 // Search for virtual calls based on %p and add them to DevirtCalls.
2038 auto &DT = FAM.getResult<DominatorTreeAnalysis>(*CI->getFunction());
2039 findDevirtualizableCallsForTypeTest(DevirtCalls, Assumes, CI, DT);
2040
2041 Metadata *TypeId =
2042 cast<MetadataAsValue>(CI->getArgOperand(1))->getMetadata();
2043 // If we found any, add them to CallSlots.
2044 if (!Assumes.empty()) {
2045 Value *Ptr = CI->getArgOperand(0)->stripPointerCasts();
2046 for (DevirtCallSite Call : DevirtCalls)
2047 CallSlots[{TypeId, Call.Offset}].addCallSite(Ptr, Call.CB, nullptr);
2048 }
2049
2050 auto RemoveTypeTestAssumes = [&]() {
2051 // We no longer need the assumes or the type test.
2052 for (auto *Assume : Assumes)
2053 Assume->eraseFromParent();
2054 // We can't use RecursivelyDeleteTriviallyDeadInstructions here because we
2055 // may use the vtable argument later.
2056 if (CI->use_empty())
2057 CI->eraseFromParent();
2058 };
2059
2060 // At this point we could remove all type test assume sequences, as they
2061 // were originally inserted for WPD. However, we can keep these in the
2062 // code stream for later analysis (e.g. to help drive more efficient ICP
2063 // sequences). They will eventually be removed by a second LowerTypeTests
2064 // invocation that cleans them up. In order to do this correctly, the first
2065 // LowerTypeTests invocation needs to know that they have "Unknown" type
2066 // test resolution, so that they aren't treated as Unsat and lowered to
2067 // False, which will break any uses on assumes. Below we remove any type
2068 // test assumes that will not be treated as Unknown by LTT.
2069
2070 // The type test assumes will be treated by LTT as Unsat if the type id is
2071 // not used on a global (in which case it has no entry in the TypeIdMap).
2072 if (!TypeIdMap.count(TypeId))
2073 RemoveTypeTestAssumes();
2074
2075 // For ThinLTO importing, we need to remove the type test assumes if this is
2076 // an MDString type id without a corresponding TypeIdSummary. Any
2077 // non-MDString type ids are ignored and treated as Unknown by LTT, so their
2078 // type test assumes can be kept. If the MDString type id is missing a
2079 // TypeIdSummary (e.g. because there was no use on a vcall, preventing the
2080 // exporting phase of WPD from analyzing it), then it would be treated as
2081 // Unsat by LTT and we need to remove its type test assumes here. If not
2082 // used on a vcall we don't need them for later optimization use in any
2083 // case.
2084 else if (ImportSummary && isa<MDString>(TypeId)) {
2085 const TypeIdSummary *TidSummary =
2086 ImportSummary->getTypeIdSummary(cast<MDString>(TypeId)->getString());
2087 if (!TidSummary)
2088 RemoveTypeTestAssumes();
2089 else
2090 // If one was created it should not be Unsat, because if we reached here
2091 // the type id was used on a global.
2093 }
2094 }
2095}
2096
2097void DevirtModule::scanTypeCheckedLoadUsers(Function *TypeCheckedLoadFunc) {
2098 Function *TypeTestFunc =
2099 Intrinsic::getOrInsertDeclaration(&M, Intrinsic::type_test);
2100
2101 for (Use &U : llvm::make_early_inc_range(TypeCheckedLoadFunc->uses())) {
2102 auto *CI = dyn_cast<CallInst>(U.getUser());
2103 if (!CI)
2104 continue;
2105
2106 Value *Ptr = CI->getArgOperand(0);
2107 Value *Offset = CI->getArgOperand(1);
2108 Value *TypeIdValue = CI->getArgOperand(2);
2109 Metadata *TypeId = cast<MetadataAsValue>(TypeIdValue)->getMetadata();
2110
2114 bool HasNonCallUses = false;
2115 auto &DT = FAM.getResult<DominatorTreeAnalysis>(*CI->getFunction());
2116 findDevirtualizableCallsForTypeCheckedLoad(DevirtCalls, LoadedPtrs, Preds,
2117 HasNonCallUses, CI, DT);
2118
2119 // Start by generating "pessimistic" code that explicitly loads the function
2120 // pointer from the vtable and performs the type check. If possible, we will
2121 // eliminate the load and the type check later.
2122
2123 // If possible, only generate the load at the point where it is used.
2124 // This helps avoid unnecessary spills.
2125 IRBuilder<> LoadB(
2126 (LoadedPtrs.size() == 1 && !HasNonCallUses) ? LoadedPtrs[0] : CI);
2127
2128 Value *LoadedValue = nullptr;
2129 if (TypeCheckedLoadFunc->getIntrinsicID() ==
2130 Intrinsic::type_checked_load_relative) {
2132 &M, Intrinsic::load_relative, {Int32Ty});
2133 LoadedValue = LoadB.CreateCall(LoadRelFunc, {Ptr, Offset});
2134 } else {
2135 Value *GEP = LoadB.CreatePtrAdd(Ptr, Offset);
2136 LoadedValue = LoadB.CreateLoad(Int8PtrTy, GEP);
2137 }
2138
2139 for (Instruction *LoadedPtr : LoadedPtrs) {
2140 LoadedPtr->replaceAllUsesWith(LoadedValue);
2141 LoadedPtr->eraseFromParent();
2142 }
2143
2144 // Likewise for the type test.
2145 IRBuilder<> CallB((Preds.size() == 1 && !HasNonCallUses) ? Preds[0] : CI);
2146 CallInst *TypeTestCall = CallB.CreateCall(TypeTestFunc, {Ptr, TypeIdValue});
2147
2148 for (Instruction *Pred : Preds) {
2149 Pred->replaceAllUsesWith(TypeTestCall);
2150 Pred->eraseFromParent();
2151 }
2152
2153 // We have already erased any extractvalue instructions that refer to the
2154 // intrinsic call, but the intrinsic may have other non-extractvalue uses
2155 // (although this is unlikely). In that case, explicitly build a pair and
2156 // RAUW it.
2157 if (!CI->use_empty()) {
2158 Value *Pair = PoisonValue::get(CI->getType());
2159 IRBuilder<> B(CI);
2160 Pair = B.CreateInsertValue(Pair, LoadedValue, {0});
2161 Pair = B.CreateInsertValue(Pair, TypeTestCall, {1});
2162 CI->replaceAllUsesWith(Pair);
2163 }
2164
2165 // The number of unsafe uses is initially the number of uses.
2166 auto &NumUnsafeUses = NumUnsafeUsesForTypeTest[TypeTestCall];
2167 NumUnsafeUses = DevirtCalls.size();
2168
2169 // If the function pointer has a non-call user, we cannot eliminate the type
2170 // check, as one of those users may eventually call the pointer. Increment
2171 // the unsafe use count to make sure it cannot reach zero.
2172 if (HasNonCallUses)
2173 ++NumUnsafeUses;
2174 for (DevirtCallSite Call : DevirtCalls) {
2175 CallSlots[{TypeId, Call.Offset}].addCallSite(Ptr, Call.CB,
2176 &NumUnsafeUses);
2177 }
2178
2179 CI->eraseFromParent();
2180 }
2181}
2182
2183void DevirtModule::importResolution(VTableSlot Slot, VTableSlotInfo &SlotInfo) {
2184 auto *TypeId = dyn_cast<MDString>(Slot.TypeID);
2185 if (!TypeId)
2186 return;
2187 const TypeIdSummary *TidSummary =
2188 ImportSummary->getTypeIdSummary(TypeId->getString());
2189 if (!TidSummary)
2190 return;
2191 auto ResI = TidSummary->WPDRes.find(Slot.ByteOffset);
2192 if (ResI == TidSummary->WPDRes.end())
2193 return;
2194 const WholeProgramDevirtResolution &Res = ResI->second;
2195
2197 assert(!Res.SingleImplName.empty());
2198 // The type of the function in the declaration is irrelevant because every
2199 // call site will cast it to the correct type.
2200 Constant *SingleImpl =
2201 cast<Constant>(M.getOrInsertFunction(Res.SingleImplName,
2202 Type::getVoidTy(M.getContext()))
2203 .getCallee());
2204
2205 // This is the import phase so we should not be exporting anything.
2206 bool IsExported = false;
2207 applySingleImplDevirt(SlotInfo, SingleImpl, IsExported);
2208 assert(!IsExported);
2209 }
2210
2211 for (auto &CSByConstantArg : SlotInfo.ConstCSInfo) {
2212 auto I = Res.ResByArg.find(CSByConstantArg.first);
2213 if (I == Res.ResByArg.end())
2214 continue;
2215 auto &ResByArg = I->second;
2216 // FIXME: We should figure out what to do about the "function name" argument
2217 // to the apply* functions, as the function names are unavailable during the
2218 // importing phase. For now we just pass the empty string. This does not
2219 // impact correctness because the function names are just used for remarks.
2220 switch (ResByArg.TheKind) {
2222 applyUniformRetValOpt(CSByConstantArg.second, "", ResByArg.Info);
2223 break;
2225 Constant *UniqueMemberAddr =
2226 importGlobal(Slot, CSByConstantArg.first, "unique_member");
2227 applyUniqueRetValOpt(CSByConstantArg.second, "", ResByArg.Info,
2228 UniqueMemberAddr);
2229 break;
2230 }
2232 Constant *Byte = importConstant(Slot, CSByConstantArg.first, "byte",
2233 Int32Ty, ResByArg.Byte);
2234 Constant *Bit = importConstant(Slot, CSByConstantArg.first, "bit", Int8Ty,
2235 ResByArg.Bit);
2236 applyVirtualConstProp(CSByConstantArg.second, "", Byte, Bit);
2237 break;
2238 }
2239 default:
2240 break;
2241 }
2242 }
2243
2245 // The type of the function is irrelevant, because it's bitcast at calls
2246 // anyhow.
2247 Constant *JT = cast<Constant>(
2248 M.getOrInsertFunction(getGlobalName(Slot, {}, "branch_funnel"),
2249 Type::getVoidTy(M.getContext()))
2250 .getCallee());
2251 bool IsExported = false;
2252 applyICallBranchFunnel(SlotInfo, JT, IsExported);
2253 assert(!IsExported);
2254 }
2255}
2256
2257void DevirtModule::removeRedundantTypeTests() {
2258 auto *True = ConstantInt::getTrue(M.getContext());
2259 for (auto &&U : NumUnsafeUsesForTypeTest) {
2260 if (U.second == 0) {
2261 U.first->replaceAllUsesWith(True);
2262 U.first->eraseFromParent();
2263 }
2264 }
2265}
2266
2268DevirtModule::lookUpFunctionValueInfo(Function *TheFn,
2269 ModuleSummaryIndex *ExportSummary) {
2270 assert((ExportSummary != nullptr) &&
2271 "Caller guarantees ExportSummary is not nullptr");
2272
2273 const auto TheFnGUID = TheFn->getGUID();
2274 const auto TheFnGUIDWithExportedName =
2276 // Look up ValueInfo with the GUID in the current linkage.
2277 ValueInfo TheFnVI = ExportSummary->getValueInfo(TheFnGUID);
2278 // If no entry is found and GUID is different from GUID computed using
2279 // exported name, look up ValueInfo with the exported name unconditionally.
2280 // This is a fallback.
2281 //
2282 // The reason to have a fallback:
2283 // 1. LTO could enable global value internalization via
2284 // `enable-lto-internalization`.
2285 // 2. The GUID in ExportedSummary is computed using exported name.
2286 if ((!TheFnVI) && (TheFnGUID != TheFnGUIDWithExportedName)) {
2287 TheFnVI = ExportSummary->getValueInfo(TheFnGUIDWithExportedName);
2288 }
2289 return TheFnVI;
2290}
2291
2292bool DevirtModule::mustBeUnreachableFunction(
2293 Function *const F, ModuleSummaryIndex *ExportSummary) {
2295 return false;
2296 // First, learn unreachability by analyzing function IR.
2297 if (!F->isDeclaration()) {
2298 // A function must be unreachable if its entry block ends with an
2299 // 'unreachable'.
2300 return isa<UnreachableInst>(F->getEntryBlock().getTerminator());
2301 }
2302 // Learn unreachability from ExportSummary if ExportSummary is present.
2303 return ExportSummary &&
2305 DevirtModule::lookUpFunctionValueInfo(F, ExportSummary));
2306}
2307
2308bool DevirtModule::run() {
2309 // If only some of the modules were split, we cannot correctly perform
2310 // this transformation. We already checked for the presense of type tests
2311 // with partially split modules during the thin link, and would have emitted
2312 // an error if any were found, so here we can simply return.
2313 if ((ExportSummary && ExportSummary->partiallySplitLTOUnits()) ||
2314 (ImportSummary && ImportSummary->partiallySplitLTOUnits()))
2315 return false;
2316
2317 Function *TypeTestFunc =
2318 Intrinsic::getDeclarationIfExists(&M, Intrinsic::type_test);
2319 Function *TypeCheckedLoadFunc =
2320 Intrinsic::getDeclarationIfExists(&M, Intrinsic::type_checked_load);
2321 Function *TypeCheckedLoadRelativeFunc = Intrinsic::getDeclarationIfExists(
2322 &M, Intrinsic::type_checked_load_relative);
2323 Function *AssumeFunc =
2324 Intrinsic::getDeclarationIfExists(&M, Intrinsic::assume);
2325
2326 // Normally if there are no users of the devirtualization intrinsics in the
2327 // module, this pass has nothing to do. But if we are exporting, we also need
2328 // to handle any users that appear only in the function summaries.
2329 if (!ExportSummary &&
2330 (!TypeTestFunc || TypeTestFunc->use_empty() || !AssumeFunc ||
2331 AssumeFunc->use_empty()) &&
2332 (!TypeCheckedLoadFunc || TypeCheckedLoadFunc->use_empty()) &&
2333 (!TypeCheckedLoadRelativeFunc ||
2334 TypeCheckedLoadRelativeFunc->use_empty()))
2335 return false;
2336
2337 // Rebuild type metadata into a map for easy lookup.
2338 std::vector<VTableBits> Bits;
2340 buildTypeIdentifierMap(Bits, TypeIdMap);
2341
2342 if (TypeTestFunc && AssumeFunc)
2343 scanTypeTestUsers(TypeTestFunc, TypeIdMap);
2344
2345 if (TypeCheckedLoadFunc)
2346 scanTypeCheckedLoadUsers(TypeCheckedLoadFunc);
2347
2348 if (TypeCheckedLoadRelativeFunc)
2349 scanTypeCheckedLoadUsers(TypeCheckedLoadRelativeFunc);
2350
2351 if (ImportSummary) {
2352 for (auto &S : CallSlots)
2353 importResolution(S.first, S.second);
2354
2355 removeRedundantTypeTests();
2356
2357 // We have lowered or deleted the type intrinsics, so we will no longer have
2358 // enough information to reason about the liveness of virtual function
2359 // pointers in GlobalDCE.
2360 for (GlobalVariable &GV : M.globals())
2361 GV.eraseMetadata(LLVMContext::MD_vcall_visibility);
2362
2363 // The rest of the code is only necessary when exporting or during regular
2364 // LTO, so we are done.
2365 return true;
2366 }
2367
2368 if (TypeIdMap.empty())
2369 return true;
2370
2371 // Collect information from summary about which calls to try to devirtualize.
2372 if (ExportSummary) {
2374 for (auto &P : TypeIdMap) {
2375 if (auto *TypeId = dyn_cast<MDString>(P.first))
2377 TypeId->getString())]
2378 .push_back(TypeId);
2379 }
2380
2381 for (auto &P : *ExportSummary) {
2382 for (auto &S : P.second.SummaryList) {
2383 auto *FS = dyn_cast<FunctionSummary>(S.get());
2384 if (!FS)
2385 continue;
2386 // FIXME: Only add live functions.
2387 for (FunctionSummary::VFuncId VF : FS->type_test_assume_vcalls()) {
2388 for (Metadata *MD : MetadataByGUID[VF.GUID]) {
2389 CallSlots[{MD, VF.Offset}].CSInfo.addSummaryTypeTestAssumeUser(FS);
2390 }
2391 }
2392 for (FunctionSummary::VFuncId VF : FS->type_checked_load_vcalls()) {
2393 for (Metadata *MD : MetadataByGUID[VF.GUID]) {
2394 CallSlots[{MD, VF.Offset}].CSInfo.addSummaryTypeCheckedLoadUser(FS);
2395 }
2396 }
2397 for (const FunctionSummary::ConstVCall &VC :
2398 FS->type_test_assume_const_vcalls()) {
2399 for (Metadata *MD : MetadataByGUID[VC.VFunc.GUID]) {
2400 CallSlots[{MD, VC.VFunc.Offset}]
2401 .ConstCSInfo[VC.Args]
2402 .addSummaryTypeTestAssumeUser(FS);
2403 }
2404 }
2405 for (const FunctionSummary::ConstVCall &VC :
2406 FS->type_checked_load_const_vcalls()) {
2407 for (Metadata *MD : MetadataByGUID[VC.VFunc.GUID]) {
2408 CallSlots[{MD, VC.VFunc.Offset}]
2409 .ConstCSInfo[VC.Args]
2410 .addSummaryTypeCheckedLoadUser(FS);
2411 }
2412 }
2413 }
2414 }
2415 }
2416
2417 // For each (type, offset) pair:
2418 bool DidVirtualConstProp = false;
2419 std::map<std::string, GlobalValue *> DevirtTargets;
2420 for (auto &S : CallSlots) {
2421 // Search each of the members of the type identifier for the virtual
2422 // function implementation at offset S.first.ByteOffset, and add to
2423 // TargetsForSlot.
2424 std::vector<VirtualCallTarget> TargetsForSlot;
2425 WholeProgramDevirtResolution *Res = nullptr;
2426 const std::set<TypeMemberInfo> &TypeMemberInfos = TypeIdMap[S.first.TypeID];
2427 if (ExportSummary && isa<MDString>(S.first.TypeID) &&
2428 TypeMemberInfos.size())
2429 // For any type id used on a global's type metadata, create the type id
2430 // summary resolution regardless of whether we can devirtualize, so that
2431 // lower type tests knows the type id is not Unsat. If it was not used on
2432 // a global's type metadata, the TypeIdMap entry set will be empty, and
2433 // we don't want to create an entry (with the default Unknown type
2434 // resolution), which can prevent detection of the Unsat.
2435 Res = &ExportSummary
2436 ->getOrInsertTypeIdSummary(
2437 cast<MDString>(S.first.TypeID)->getString())
2438 .WPDRes[S.first.ByteOffset];
2439 if (tryFindVirtualCallTargets(TargetsForSlot, TypeMemberInfos,
2440 S.first.ByteOffset, ExportSummary)) {
2441
2442 if (!trySingleImplDevirt(ExportSummary, TargetsForSlot, S.second, Res)) {
2443 DidVirtualConstProp |=
2444 tryVirtualConstProp(TargetsForSlot, S.second, Res, S.first);
2445
2446 tryICallBranchFunnel(TargetsForSlot, S.second, Res, S.first);
2447 }
2448
2449 // Collect functions devirtualized at least for one call site for stats.
2450 if (RemarksEnabled || AreStatisticsEnabled())
2451 for (const auto &T : TargetsForSlot)
2452 if (T.WasDevirt)
2453 DevirtTargets[std::string(T.Fn->getName())] = T.Fn;
2454 }
2455
2456 // CFI-specific: if we are exporting and any llvm.type.checked.load
2457 // intrinsics were *not* devirtualized, we need to add the resulting
2458 // llvm.type.test intrinsics to the function summaries so that the
2459 // LowerTypeTests pass will export them.
2460 if (ExportSummary && isa<MDString>(S.first.TypeID)) {
2462 cast<MDString>(S.first.TypeID)->getString());
2463 auto AddTypeTestsForTypeCheckedLoads = [&](CallSiteInfo &CSI) {
2464 if (!CSI.AllCallSitesDevirted)
2465 for (auto *FS : CSI.SummaryTypeCheckedLoadUsers)
2466 FS->addTypeTest(GUID);
2467 };
2468 AddTypeTestsForTypeCheckedLoads(S.second.CSInfo);
2469 for (auto &CCS : S.second.ConstCSInfo)
2470 AddTypeTestsForTypeCheckedLoads(CCS.second);
2471 }
2472 }
2473
2474 if (RemarksEnabled) {
2475 // Generate remarks for each devirtualized function.
2476 for (const auto &DT : DevirtTargets) {
2477 GlobalValue *GV = DT.second;
2478 auto *F = dyn_cast<Function>(GV);
2479 if (!F) {
2480 auto *A = dyn_cast<GlobalAlias>(GV);
2481 assert(A && isa<Function>(A->getAliasee()));
2482 F = dyn_cast<Function>(A->getAliasee());
2483 assert(F);
2484 }
2485
2486 using namespace ore;
2487 OREGetter(*F).emit(OptimizationRemark(DEBUG_TYPE, "Devirtualized", F)
2488 << "devirtualized " << NV("FunctionName", DT.first));
2489 }
2490 }
2491
2492 NumDevirtTargets += DevirtTargets.size();
2493
2494 removeRedundantTypeTests();
2495
2496 // Rebuild each global we touched as part of virtual constant propagation to
2497 // include the before and after bytes.
2498 if (DidVirtualConstProp)
2499 for (VTableBits &B : Bits)
2500 rebuildGlobal(B);
2501
2502 // We have lowered or deleted the type intrinsics, so we will no longer have
2503 // enough information to reason about the liveness of virtual function
2504 // pointers in GlobalDCE.
2505 for (GlobalVariable &GV : M.globals())
2506 GV.eraseMetadata(LLVMContext::MD_vcall_visibility);
2507
2508 for (auto *CI : CallsWithPtrAuthBundleRemoved)
2509 CI->eraseFromParent();
2510
2511 return true;
2512}
2513
2514void DevirtIndex::run() {
2515 if (ExportSummary.typeIdCompatibleVtableMap().empty())
2516 return;
2517
2519 for (const auto &P : ExportSummary.typeIdCompatibleVtableMap()) {
2520 NameByGUID[GlobalValue::getGUIDAssumingExternalLinkage(P.first)].push_back(
2521 P.first);
2522 // Create the type id summary resolution regardlness of whether we can
2523 // devirtualize, so that lower type tests knows the type id is used on
2524 // a global and not Unsat. We do this here rather than in the loop over the
2525 // CallSlots, since that handling will only see type tests that directly
2526 // feed assumes, and we would miss any that aren't currently handled by WPD
2527 // (such as type tests that feed assumes via phis).
2528 ExportSummary.getOrInsertTypeIdSummary(P.first);
2529 }
2530
2531 // Collect information from summary about which calls to try to devirtualize.
2532 for (auto &P : ExportSummary) {
2533 for (auto &S : P.second.SummaryList) {
2534 auto *FS = dyn_cast<FunctionSummary>(S.get());
2535 if (!FS)
2536 continue;
2537 // FIXME: Only add live functions.
2538 for (FunctionSummary::VFuncId VF : FS->type_test_assume_vcalls()) {
2539 for (StringRef Name : NameByGUID[VF.GUID]) {
2540 CallSlots[{Name, VF.Offset}].CSInfo.addSummaryTypeTestAssumeUser(FS);
2541 }
2542 }
2543 for (FunctionSummary::VFuncId VF : FS->type_checked_load_vcalls()) {
2544 for (StringRef Name : NameByGUID[VF.GUID]) {
2545 CallSlots[{Name, VF.Offset}].CSInfo.addSummaryTypeCheckedLoadUser(FS);
2546 }
2547 }
2548 for (const FunctionSummary::ConstVCall &VC :
2549 FS->type_test_assume_const_vcalls()) {
2550 for (StringRef Name : NameByGUID[VC.VFunc.GUID]) {
2551 CallSlots[{Name, VC.VFunc.Offset}]
2552 .ConstCSInfo[VC.Args]
2553 .addSummaryTypeTestAssumeUser(FS);
2554 }
2555 }
2556 for (const FunctionSummary::ConstVCall &VC :
2557 FS->type_checked_load_const_vcalls()) {
2558 for (StringRef Name : NameByGUID[VC.VFunc.GUID]) {
2559 CallSlots[{Name, VC.VFunc.Offset}]
2560 .ConstCSInfo[VC.Args]
2561 .addSummaryTypeCheckedLoadUser(FS);
2562 }
2563 }
2564 }
2565 }
2566
2567 std::set<ValueInfo> DevirtTargets;
2568 // For each (type, offset) pair:
2569 for (auto &S : CallSlots) {
2570 // Search each of the members of the type identifier for the virtual
2571 // function implementation at offset S.first.ByteOffset, and add to
2572 // TargetsForSlot.
2573 std::vector<ValueInfo> TargetsForSlot;
2574 auto TidSummary = ExportSummary.getTypeIdCompatibleVtableSummary(S.first.TypeID);
2575 assert(TidSummary);
2576 // The type id summary would have been created while building the NameByGUID
2577 // map earlier.
2579 &ExportSummary.getTypeIdSummary(S.first.TypeID)
2580 ->WPDRes[S.first.ByteOffset];
2581 if (tryFindVirtualCallTargets(TargetsForSlot, *TidSummary,
2582 S.first.ByteOffset)) {
2583
2584 if (!trySingleImplDevirt(TargetsForSlot, S.first, S.second, Res,
2585 DevirtTargets))
2586 continue;
2587 }
2588 }
2589
2590 // Optionally have the thin link print message for each devirtualized
2591 // function.
2593 for (const auto &DT : DevirtTargets)
2594 errs() << "Devirtualized call to " << DT << "\n";
2595
2596 NumDevirtTargets += DevirtTargets.size();
2597}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned Intr
This is the interface for LLVM's primary stateless and local alias analysis.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static std::optional< bool > isBigEndian(const SmallDenseMap< int64_t, int64_t, 8 > &MemOffset2Idx, int64_t LowestIdx)
Given a map from byte offsets in memory to indices in a load/store, determine if that map corresponds...
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
Definition: CommandLine.h:687
This file contains the declarations for the subclasses of Constant, which represent the different fla...
This file defines DenseMapInfo traits for DenseMap.
This file defines the DenseMap class.
This file defines the DenseSet and SmallDenseSet classes.
uint64_t Addr
std::string Name
uint64_t Size
Provides passes for computing function attributes based on interprocedural analyses.
@ CallSiteInfo
#define DEBUG_TYPE
static void emitRemark(const Function &F, OptimizationRemarkEmitter &ORE, bool Skip)
Hexagon Common GEP
Module.h This file contains the declarations for the Module class.
This header defines various interfaces for pass management in LLVM.
static cl::opt< std::string > ClReadSummary("lowertypetests-read-summary", cl::desc("Read summary from given YAML file before running pass"), cl::Hidden)
static cl::opt< PassSummaryAction > ClSummaryAction("lowertypetests-summary-action", cl::desc("What to do with the summary when running this pass"), cl::values(clEnumValN(PassSummaryAction::None, "none", "Do nothing"), clEnumValN(PassSummaryAction::Import, "import", "Import typeid resolutions from summary and globals"), clEnumValN(PassSummaryAction::Export, "export", "Export typeid resolutions to summary and globals")), cl::Hidden)
static cl::opt< std::string > ClWriteSummary("lowertypetests-write-summary", cl::desc("Write summary to given YAML file after running pass"), cl::Hidden)
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
This file implements a map that provides insertion order iteration.
This file contains the declarations for metadata subclasses.
Type::TypeID TypeID
static bool mustBeUnreachableFunction(const Function &F)
uint64_t IntrinsicInst * II
#define P(N)
FunctionAnalysisManager FAM
ModuleAnalysisManager MAM
const SmallVectorImpl< MachineOperand > & Cond
raw_pwrite_stream & OS
This file defines the SmallVector class.
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:167
static cl::opt< bool > DisableWholeProgramVisibility("disable-whole-program-visibility", cl::Hidden, cl::desc("Disable whole program visibility (overrides enabling options)"))
Provide a way to force disable whole program for debugging or workarounds, when enabled via the linke...
WPDCheckMode
Mechanism to add runtime checking of devirtualization decisions, optionally trapping or falling back ...
static cl::opt< PassSummaryAction > ClSummaryAction("wholeprogramdevirt-summary-action", cl::desc("What to do with the summary when running this pass"), cl::values(clEnumValN(PassSummaryAction::None, "none", "Do nothing"), clEnumValN(PassSummaryAction::Import, "import", "Import typeid resolutions from summary and globals"), clEnumValN(PassSummaryAction::Export, "export", "Export typeid resolutions to summary and globals")), cl::Hidden)
static cl::opt< bool > WholeProgramVisibility("whole-program-visibility", cl::Hidden, cl::desc("Enable whole program visibility"))
Provide a way to force enable whole program visibility in tests.
static bool typeIDVisibleToRegularObj(StringRef TypeID, function_ref< bool(StringRef)> IsVisibleToRegularObj)
static Error checkCombinedSummaryForTesting(ModuleSummaryIndex *Summary)
static cl::list< std::string > SkipFunctionNames("wholeprogramdevirt-skip", cl::desc("Prevent function(s) from being devirtualized"), cl::Hidden, cl::CommaSeparated)
Provide way to prevent certain function from being devirtualized.
static cl::opt< std::string > ClWriteSummary("wholeprogramdevirt-write-summary", cl::desc("Write summary to given bitcode or YAML file after running pass. " "Output file format is deduced from extension: *.bc means writing " "bitcode, otherwise YAML"), cl::Hidden)
static bool addCalls(VTableSlotInfo &SlotInfo, const ValueInfo &Callee)
static cl::opt< unsigned > ClThreshold("wholeprogramdevirt-branch-funnel-threshold", cl::Hidden, cl::init(10), cl::desc("Maximum number of call targets per " "call site to enable branch funnels"))
static cl::opt< WPDCheckMode > DevirtCheckMode("wholeprogramdevirt-check", cl::Hidden, cl::desc("Type of checking for incorrect devirtualizations"), cl::values(clEnumValN(WPDCheckMode::None, "none", "No checking"), clEnumValN(WPDCheckMode::Trap, "trap", "Trap when incorrect"), clEnumValN(WPDCheckMode::Fallback, "fallback", "Fallback to indirect when incorrect")))
static cl::opt< bool > WholeProgramDevirtKeepUnreachableFunction("wholeprogramdevirt-keep-unreachable-function", cl::desc("Regard unreachable functions as possible devirtualize targets."), cl::Hidden, cl::init(true))
With Clang, a pure virtual class's deleting destructor is emitted as a llvm.trap intrinsic followed b...
static cl::opt< std::string > ClReadSummary("wholeprogramdevirt-read-summary", cl::desc("Read summary from given bitcode or YAML file before running pass"), cl::Hidden)
static bool skipUpdateDueToValidation(GlobalVariable &GV, function_ref< bool(StringRef)> IsVisibleToRegularObj)
static cl::opt< unsigned > WholeProgramDevirtCutoff("wholeprogramdevirt-cutoff", cl::desc("Max number of devirtualizations for devirt module pass"), cl::init(0))
If explicitly specified, the devirt module pass will stop transformation once the total number of dev...
static cl::opt< bool > PrintSummaryDevirt("wholeprogramdevirt-print-index-based", cl::Hidden, cl::desc("Print index-based devirtualization messages"))
Value * RHS
Value * LHS
A manager for alias analyses.
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:255
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Definition: PassManager.h:412
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:147
ArrayRef< T > slice(size_t N, size_t M) const
slice(n, m) - Chop off the first N elements of the array, and keep M elements in the array.
Definition: ArrayRef.h:191
static LLVM_ABI AttributeList get(LLVMContext &C, ArrayRef< std::pair< unsigned, Attribute > > Attrs)
Create an AttributeList with the specified parameters in it.
static LLVM_ABI AttributeSet get(LLVMContext &C, const AttrBuilder &B)
Definition: Attributes.cpp:921
LLVM_ABI StringRef getValueAsString() const
Return the attribute's value as a string.
Definition: Attributes.cpp:400
bool isValid() const
Return true if the attribute is any kind of attribute.
Definition: Attributes.h:223
LLVM Basic Block Representation.
Definition: BasicBlock.h:62
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition: BasicBlock.h:206
static BranchInst * Create(BasicBlock *IfTrue, InsertPosition InsertBefore=nullptr)
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
Definition: InstrTypes.h:1116
void setCallingConv(CallingConv::ID CC)
Definition: InstrTypes.h:1410
bool arg_empty() const
Definition: InstrTypes.h:1289
std::optional< OperandBundleUse > getOperandBundle(StringRef Name) const
Return an operand bundle by name, if present.
Definition: InstrTypes.h:2083
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
Definition: InstrTypes.h:1348
CallingConv::ID getCallingConv() const
Definition: InstrTypes.h:1406
Value * getCalledOperand() const
Definition: InstrTypes.h:1340
void setAttributes(AttributeList A)
Set the attributes for this call.
Definition: InstrTypes.h:1427
FunctionType * getFunctionType() const
Definition: InstrTypes.h:1205
iterator_range< User::op_iterator > args()
Iteration adapter for range-for loops.
Definition: InstrTypes.h:1283
void setCalledOperand(Value *V)
Definition: InstrTypes.h:1384
static LLVM_ABI CallBase * removeOperandBundle(CallBase *CB, uint32_t ID, InsertPosition InsertPt=nullptr)
Create a clone of CB with operand bundle ID removed.
AttributeList getAttributes() const
Return the attributes for this call.
Definition: InstrTypes.h:1424
LLVM_ABI Function * getCaller()
Helper to get the caller (the parent function).
This class represents a function call, abstracting a target machine's calling convention.
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
@ ICMP_EQ
equal
Definition: InstrTypes.h:699
@ ICMP_NE
not equal
Definition: InstrTypes.h:700
void setSelectionKind(SelectionKind Val)
Definition: Comdat.h:48
static ConstantAsMetadata * get(Constant *C)
Definition: Metadata.h:535
static Constant * get(LLVMContext &Context, ArrayRef< ElementTy > Elts)
get() constructor - Return a constant with array type with an element count and element type matching...
Definition: Constants.h:715
static LLVM_ABI Constant * getIntToPtr(Constant *C, Type *Ty, bool OnlyIfReduced=false)
Definition: Constants.cpp:2314
static Constant * getInBoundsGetElementPtr(Type *Ty, Constant *C, ArrayRef< Constant * > IdxList)
Create an "inbounds" getelementptr.
Definition: Constants.h:1301
static LLVM_ABI Constant * getPtrToInt(Constant *C, Type *Ty, bool OnlyIfReduced=false)
Definition: Constants.cpp:2300
static Constant * getGetElementPtr(Type *Ty, Constant *C, ArrayRef< Constant * > IdxList, GEPNoWrapFlags NW=GEPNoWrapFlags::none(), std::optional< ConstantRange > InRange=std::nullopt, Type *OnlyIfReducedTy=nullptr)
Getelementptr form.
Definition: Constants.h:1274
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
Definition: Constants.cpp:868
static Constant * getAnon(ArrayRef< Constant * > V, bool Packed=false)
Return an anonymous struct that has the specified elements.
Definition: Constants.h:486
This is an important base class in LLVM.
Definition: Constant.h:43
const Constant * stripPointerCasts() const
Definition: Constant.h:219
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
Definition: Constants.cpp:373
A debug info location.
Definition: DebugLoc.h:124
bool empty() const
Definition: DenseMap.h:119
Implements a dense probed hash-table based set.
Definition: DenseSet.h:263
Analysis pass which computes a DominatorTree.
Definition: Dominators.h:284
Subclass of Error for the sole purpose of identifying the success path in the type system.
Definition: Error.h:334
Lightweight error class with error context and mandatory checking.
Definition: Error.h:159
This class evaluates LLVM IR, producing the Constant representing each SSA instruction.
Definition: Evaluator.h:37
Helper for check-and-exit error handling.
Definition: Error.h:1444
Tagged union holding either a T or a Error.
Definition: Error.h:485
Function summary information to aid decisions and implementation of importing.
Type * getParamType(unsigned i) const
Parameter type accessors.
Definition: DerivedTypes.h:137
ArrayRef< Type * > params() const
Definition: DerivedTypes.h:132
bool isVarArg() const
Definition: DerivedTypes.h:125
Type * getReturnType() const
Definition: DerivedTypes.h:126
static LLVM_ABI FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
Definition: Function.h:166
bool empty() const
Definition: Function.h:857
FunctionType * getFunctionType() const
Returns the FunctionType for me.
Definition: Function.h:209
bool arg_empty() const
Definition: Function.h:900
const BasicBlock & front() const
Definition: Function.h:858
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
Definition: Function.cpp:762
Intrinsic::ID getIntrinsicID() const LLVM_READONLY
getIntrinsicID - This method returns the ID number of the specified function, or Intrinsic::not_intri...
Definition: Function.h:244
arg_iterator arg_begin()
Definition: Function.h:866
size_t arg_size() const
Definition: Function.h:899
Type * getReturnType() const
Returns the type of the ret val.
Definition: Function.h:214
This class implements a glob pattern matcher similar to the one found in bash, but with some key diff...
Definition: GlobPattern.h:52
static LLVM_ABI Expected< GlobPattern > create(StringRef Pat, std::optional< size_t > MaxSubPatterns={})
static LLVM_ABI GlobalAlias * create(Type *Ty, unsigned AddressSpace, LinkageTypes Linkage, const Twine &Name, Constant *Aliasee, Module *Parent)
If a parent module is specified, the alias is automatically inserted into the end of the specified mo...
Definition: Globals.cpp:585
bool hasMetadata() const
Return true if this value has any metadata attached to it.
Definition: Value.h:602
LLVM_ABI void setMetadata(unsigned KindID, MDNode *Node)
Set a particular kind of metadata attachment.
Definition: Metadata.cpp:1571
LLVM_ABI VCallVisibility getVCallVisibility() const
Definition: Metadata.cpp:1900
LLVM_ABI bool eraseMetadata(unsigned KindID)
Erase all metadata attachments with the given kind.
Definition: Metadata.cpp:1616
MDNode * getMetadata(unsigned KindID) const
Get the current metadata attachments for the given kind, if any.
Definition: Value.h:576
LLVM_ABI void setVCallVisibilityMetadata(VCallVisibility Visibility)
Definition: Metadata.cpp:1890
static LLVM_ABI GUID getGUIDAssumingExternalLinkage(StringRef GlobalName)
Return a 64-bit global unique ID constructed from the name of a global symbol.
Definition: Globals.cpp:77
static bool isLocalLinkage(LinkageTypes Linkage)
Definition: GlobalValue.h:411
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:316
static bool isAvailableExternallyLinkage(LinkageTypes Linkage)
Definition: GlobalValue.h:381
GUID getGUID() const
Return a 64-bit global unique ID constructed from global value name (i.e.
Definition: GlobalValue.h:600
@ HiddenVisibility
The GV is hidden.
Definition: GlobalValue.h:69
void setVisibility(VisibilityTypes V)
Definition: GlobalValue.h:256
@ PrivateLinkage
Like Internal, but omit from symbol table.
Definition: GlobalValue.h:61
@ InternalLinkage
Rename collisions when linking (static functions).
Definition: GlobalValue.h:60
@ ExternalLinkage
Externally visible function.
Definition: GlobalValue.h:53
Type * getValueType() const
Definition: GlobalValue.h:298
Global variable summary information to aid decisions and implementation of importing.
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
MaybeAlign getAlign() const
Returns the alignment of the given variable.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition: IRBuilder.h:2780
An analysis over an "outer" IR unit that provides access to an analysis manager over an "inner" IR un...
Definition: PassManager.h:585
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
Definition: Instruction.h:513
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
LLVM_ABI void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
Definition: Metadata.cpp:1718
Class to represent integer types.
Definition: DerivedTypes.h:42
unsigned getBitWidth() const
Get the number of bits in this IntegerType.
Definition: DerivedTypes.h:74
LLVM_ABI MDNode * createLikelyBranchWeights()
Return metadata containing two branch weights, with significant bias towards true destination.
Definition: MDBuilder.cpp:43
LLVM_ABI MDNode * createUnlikelyBranchWeights()
Return metadata containing two branch weights, with significant bias towards false destination.
Definition: MDBuilder.cpp:48
Metadata node.
Definition: Metadata.h:1077
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition: Metadata.h:1565
This class implements a map that also provides access to all stored values in a deterministic order.
Definition: MapVector.h:36
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, bool IsVolatile=false, std::optional< Align > Alignment=std::nullopt)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...
bool doesNotAccessMemory() const
Whether this function accesses no memory.
Definition: ModRef.h:215
Root of the metadata hierarchy.
Definition: Metadata.h:63
Class to hold module path string table and global value map, and encapsulate methods for operating on...
const TypeIdSummary * getTypeIdSummary(StringRef TypeId) const
This returns either a pointer to the type id summary (if present in the summary map) or null (if not ...
ValueInfo getValueInfo(const GlobalValueSummaryMapTy::value_type &R) const
Return a ValueInfo for the index value_type (convenient when iterating index).
const ModuleHash & getModuleHash(const StringRef ModPath) const
Get the module SHA1 hash recorded for the given module path.
static constexpr const char * getRegularLTOModuleName()
static std::string getGlobalNameForLocal(StringRef Name, ModuleHash ModHash)
Convenience method for creating a promoted global name for the given value name of a local,...
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
MutableArrayRef - Represent a mutable reference to an array (0 or more elements consecutively in memo...
Definition: ArrayRef.h:303
The optimization diagnostic interface.
Diagnostic information for applied optimization remarks.
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
Definition: Constants.cpp:1885
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
static ReturnInst * Create(LLVMContext &C, Value *retVal=nullptr, InsertPosition InsertBefore=nullptr)
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Definition: SmallPtrSet.h:401
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
Definition: SmallPtrSet.h:541
bool empty() const
Definition: SmallVector.h:82
size_t size() const
Definition: SmallVector.h:79
void push_back(const T &Elt)
Definition: SmallVector.h:414
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
bool contains(StringRef Other) const
Return true if the given string is a substring of *this, and false otherwise.
Definition: StringRef.h:434
Target - Wrapper for Target specific information.
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:47
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
TypeID
Definitions of all of the base types for the Type system.
Definition: Type.h:54
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
A Use represents the edge between a Value definition and its users.
Definition: Use.h:35
LLVM Value Representation.
Definition: Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition: Value.h:256
LLVM_ABI void setName(const Twine &Name)
Change the name of the value.
Definition: Value.cpp:390
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition: Value.cpp:546
bool use_empty() const
Definition: Value.h:346
LLVM_ABI bool eraseMetadata(unsigned KindID)
Erase all metadata attachments with the given kind.
Definition: Metadata.cpp:1616
iterator_range< use_iterator > uses()
Definition: Value.h:380
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:322
std::pair< iterator, bool > insert(const ValueT &V)
Definition: DenseSet.h:194
size_type count(const_arg_type_t< ValueT > V) const
Return 1 if the specified key is in the set, 0 otherwise.
Definition: DenseSet.h:174
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
Definition: ilist_node.h:34
self_iterator getIterator()
Definition: ilist_node.h:134
A raw_ostream that writes to a file descriptor.
Definition: raw_ostream.h:461
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:662
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
constexpr char Attrs[]
Key for Kernel::Metadata::mAttrs.
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > Tys={})
Look up the Function declaration of the intrinsic id in the Module M.
Definition: Intrinsics.cpp:751
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.
Definition: Intrinsics.cpp:762
bool match(Val *V, const Pattern &P)
Definition: PatternMatch.h:49
@ FS
Definition: X86.h:214
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
Definition: CommandLine.h:712
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:444
@ CommaSeparated
Definition: CommandLine.h:164
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
@ Assume
Do not drop type tests (default).
DiagnosticInfoOptimizationBase::Argument NV
@ OF_TextWithCRLF
The file should be opened in text mode and use a carriage linefeed '\r '.
Definition: FileSystem.h:771
LLVM_ABI uint64_t findLowestOffset(ArrayRef< VirtualCallTarget > Targets, bool IsAfter, uint64_t Size)
LLVM_ABI void setAfterReturnValues(MutableArrayRef< VirtualCallTarget > Targets, uint64_t AllocAfter, unsigned BitWidth, int64_t &OffsetByte, uint64_t &OffsetBit)
LLVM_ABI void setBeforeReturnValues(MutableArrayRef< VirtualCallTarget > Targets, uint64_t AllocBefore, unsigned BitWidth, int64_t &OffsetByte, uint64_t &OffsetBit)
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition: STLExtras.h:338
@ Offset
Definition: DWP.cpp:477
LLVM_ABI MemoryEffects computeFunctionBodyMemoryAccess(Function &F, AAResults &AAR)
Returns the memory access properties of this copy of the function.
@ Export
Export information to summary.
@ Import
Import information from summary.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition: STLExtras.h:2155
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:663
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition: Error.h:1305
LLVM_ABI bool hasWholeProgramVisibility(bool WholeProgramVisibilityEnabledInLTO)
int countr_zero(T Val)
Count number of 0's from the least significant bit to the most stopping at the first 1.
Definition: bit.h:157
LLVM_ABI void writeIndexToFile(const ModuleSummaryIndex &Index, raw_ostream &Out, const ModuleToSummariesForIndexTy *ModuleToSummariesForIndex=nullptr, const GVSummaryPtrSet *DecSummaries=nullptr)
Write the specified module summary index to the given raw output stream, where it will be written in ...
LLVM_ABI Expected< std::unique_ptr< ModuleSummaryIndex > > getModuleSummaryIndex(MemoryBufferRef Buffer)
Parse the specified bitcode buffer, returning the module summary index.
LLVM_ABI void updatePublicTypeTestCalls(Module &M, bool WholeProgramVisibilityEnabledInLTO)
LLVM_ABI void getVisibleToRegularObjVtableGUIDs(ModuleSummaryIndex &Index, DenseSet< GlobalValue::GUID > &VisibleToRegularObjSymbols, function_ref< bool(StringRef)> IsVisibleToRegularObj)
Based on typeID string, get all associated vtable GUIDS that are visible to regular objects.
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
void findDevirtualizableCallsForTypeCheckedLoad(SmallVectorImpl< DevirtCallSite > &DevirtCalls, SmallVectorImpl< Instruction * > &LoadedPtrs, SmallVectorImpl< Instruction * > &Preds, bool &HasNonCallUses, const CallInst *CI, DominatorTree &DT)
Given a call to the intrinsic @llvm.type.checked.load, find all devirtualizable call sites based on t...
LLVM_ABI CallBase & versionCallSite(CallBase &CB, Value *Callee, MDNode *BranchWeights)
Predicate and clone the given call site.
LLVM_ABI bool AreStatisticsEnabled()
Check if statistics are enabled.
Definition: Statistic.cpp:139
LLVM_ABI void updateIndexWPDForExports(ModuleSummaryIndex &Summary, function_ref< bool(StringRef, ValueInfo)> isExported, std::map< ValueInfo, std::vector< VTableSlotSummary > > &LocalWPDTargetsMap)
Call after cross-module importing to update the recorded single impl devirt target names for any loca...
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
LLVM_ABI void runWholeProgramDevirtOnIndex(ModuleSummaryIndex &Summary, std::set< GlobalValue::GUID > &ExportedGUIDs, std::map< ValueInfo, std::vector< VTableSlotSummary > > &LocalWPDTargetsMap)
Perform index-based whole program devirtualization on the Summary index.
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition: Alignment.h:155
Expected< T > errorOrToExpected(ErrorOr< T > &&EO)
Convert an ErrorOr<T> to an Expected<T>.
Definition: Error.h:1245
constexpr unsigned BitWidth
Definition: BitmaskEnum.h:223
LLVM_ABI Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
Definition: Error.cpp:111
LLVM_ABI Instruction * SplitBlockAndInsertIfThen(Value *Cond, BasicBlock::iterator SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DomTreeUpdater *DTU=nullptr, LoopInfo *LI=nullptr, BasicBlock *ThenBlock=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
std::vector< TypeIdOffsetVtableInfo > TypeIdCompatibleVtableInfo
List of vtable definitions decorated by a particular type identifier, and their corresponding offsets...
void consumeError(Error Err)
Consume a Error without doing anything.
Definition: Error.h:1083
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 ...
LLVM_ABI void updateVCallVisibilityInModule(Module &M, bool WholeProgramVisibilityEnabledInLTO, const DenseSet< GlobalValue::GUID > &DynamicExportSymbols, bool ValidateAllVtablesHaveTypeInfos, function_ref< bool(StringRef)> IsVisibleToRegularObj)
If whole program visibility asserted, then upgrade all public vcall visibility metadata on vtable def...
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 ...
LLVM_ABI void updateVCallVisibilityInIndex(ModuleSummaryIndex &Index, bool WholeProgramVisibilityEnabledInLTO, const DenseSet< GlobalValue::GUID > &DynamicExportSymbols, const DenseSet< GlobalValue::GUID > &VisibleToRegularObjSymbols)
If whole program visibility asserted, then upgrade all public vcall visibility metadata on vtable def...
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition: BitVector.h:858
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
uint64_t value() const
This is a hole in the type system and should not be abused.
Definition: Alignment.h:85
Class to accumulate and hold information about a callee.
static unsigned getHashValue(const VTableSlotSummary &I)
static bool isEqual(const VTableSlotSummary &LHS, const VTableSlotSummary &RHS)
static bool isEqual(const VTableSlot &LHS, const VTableSlot &RHS)
static unsigned getHashValue(const VTableSlot &I)
An information struct used to provide DenseMap with the various necessary components for a given valu...
Definition: DenseMapInfo.h:54
A call site that could be devirtualized.
A specification for a virtual function call with all constant integer arguments.
An "identifier" for a virtual function.
The following data structures summarize type metadata information.
std::map< uint64_t, WholeProgramDevirtResolution > WPDRes
Mapping from byte offset to whole-program devirt resolution for that (typeid, byte offset) pair.
TypeTestResolution TTRes
@ Unsat
Unsatisfiable type (i.e. no global has this type metadata)
enum llvm::TypeTestResolution::Kind TheKind
Struct that holds a reference to a particular GUID in a global value summary.
ArrayRef< std::unique_ptr< GlobalValueSummary > > getSummaryList() const
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &)
@ UniformRetVal
Uniform return value optimization.
@ VirtualConstProp
Virtual constant propagation.
@ UniqueRetVal
Unique return value optimization.
uint64_t Info
Additional information for the resolution:
enum llvm::WholeProgramDevirtResolution::ByArg::Kind TheKind
enum llvm::WholeProgramDevirtResolution::Kind TheKind
std::map< std::vector< uint64_t >, ByArg > ResByArg
Resolutions for calls with all constant integer arguments (excluding the first argument,...
@ SingleImpl
Single implementation devirtualization.
@ BranchFunnel
When retpoline mitigation is enabled, use a branch funnel that is defined in the merged module.
LLVM_ABI VirtualCallTarget(GlobalValue *Fn, const TypeMemberInfo *TM)