LLVM 24.0.0git
LowerTypeTests.cpp
Go to the documentation of this file.
1//===- LowerTypeTests.cpp - type metadata lowering pass -------------------===//
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 lowers type metadata and calls to the llvm.type.test intrinsic.
10// It also ensures that globals are properly laid out for the
11// llvm.icall.branch.funnel intrinsic.
12// See http://llvm.org/docs/TypeMetadata.html for more information.
13//
14//===----------------------------------------------------------------------===//
15
17#include "llvm/ADT/APInt.h"
18#include "llvm/ADT/ArrayRef.h"
19#include "llvm/ADT/DenseMap.h"
22#include "llvm/ADT/MapVector.h"
24#include "llvm/ADT/STLExtras.h"
25#include "llvm/ADT/SetVector.h"
27#include "llvm/ADT/Statistic.h"
28#include "llvm/ADT/StringMap.h"
29#include "llvm/ADT/StringRef.h"
40#include "llvm/IR/Attributes.h"
41#include "llvm/IR/BasicBlock.h"
42#include "llvm/IR/Constant.h"
43#include "llvm/IR/Constants.h"
44#include "llvm/IR/DIBuilder.h"
45#include "llvm/IR/DataLayout.h"
47#include "llvm/IR/Function.h"
48#include "llvm/IR/GlobalAlias.h"
50#include "llvm/IR/GlobalValue.h"
52#include "llvm/IR/IRBuilder.h"
53#include "llvm/IR/InlineAsm.h"
54#include "llvm/IR/Instruction.h"
57#include "llvm/IR/Intrinsics.h"
58#include "llvm/IR/LLVMContext.h"
59#include "llvm/IR/MDBuilder.h"
60#include "llvm/IR/Metadata.h"
61#include "llvm/IR/Module.h"
64#include "llvm/IR/Operator.h"
65#include "llvm/IR/PassManager.h"
68#include "llvm/IR/Type.h"
69#include "llvm/IR/Use.h"
70#include "llvm/IR/User.h"
71#include "llvm/IR/Value.h"
76#include "llvm/Support/Debug.h"
77#include "llvm/Support/Error.h"
87#include "llvm/Transforms/IPO.h"
90#include <algorithm>
91#include <cassert>
92#include <cstdint>
93#include <set>
94#include <string>
95#include <system_error>
96#include <utility>
97#include <vector>
98
99using namespace llvm;
100using namespace lowertypetests;
101
102#define DEBUG_TYPE "lowertypetests"
103
104STATISTIC(ByteArraySizeBits, "Byte array size in bits");
105STATISTIC(ByteArraySizeBytes, "Byte array size in bytes");
106STATISTIC(NumByteArraysCreated, "Number of byte arrays created");
107STATISTIC(NumTypeTestCallsLowered, "Number of type test calls lowered");
108STATISTIC(NumTypeIdDisjointSets, "Number of disjoint sets of type identifiers");
109
111 "lowertypetests-avoid-reuse",
112 cl::desc("Try to avoid reuse of byte array addresses using aliases"),
113 cl::Hidden, cl::init(true));
114
116 "lowertypetests-summary-action",
117 cl::desc("What to do with the summary when running this pass"),
118 cl::values(clEnumValN(PassSummaryAction::None, "none", "Do nothing"),
120 "Import typeid resolutions from summary and globals"),
122 "Export typeid resolutions to summary and globals")),
123 cl::Hidden);
124
126 ClReadSummary("lowertypetests-read-summary",
127 cl::desc("Read summary from given textual assembly or YAML "
128 "file before running pass"),
129 cl::Hidden);
130
132 "lowertypetests-write-summary",
133 cl::desc("Write summary to given YAML file after running pass"),
134 cl::Hidden);
135
136// FIXME: Remove in clang 24.
138 "lowertypetests-jump-table-debug-info", cl::init(true), cl::Hidden,
139 cl::desc("Enable debug info generation for jump tables"));
140
141// FIXME: Remove in clang 26.
143 "reorder-cfi-jump-tables-profiles", cl::init(true), cl::Hidden,
144 cl::desc("Reorder CFI jump tables using profile information"));
145
147 if (Offset < ByteOffset)
148 return false;
149
150 if ((Offset - ByteOffset) % (uint64_t(1) << AlignLog2) != 0)
151 return false;
152
153 uint64_t BitOffset = (Offset - ByteOffset) >> AlignLog2;
154 if (BitOffset >= BitSize)
155 return false;
156
157 return Bits.count(BitSize - 1 - BitOffset);
158}
159
161 OS << "offset " << ByteOffset << " size " << BitSize << " align "
162 << (1 << AlignLog2);
163
164 if (isAllOnes()) {
165 OS << " all-ones\n";
166 return;
167 }
168
169 OS << " { ";
170 for (uint64_t B : Bits)
171 OS << B << ' ';
172 OS << "}\n";
173}
174
176 if (Min > Max)
177 Min = 0;
178
179 // Normalize each offset against the minimum observed offset, and compute
180 // the bitwise OR of each of the offsets. The number of trailing zeros
181 // in the mask gives us the log2 of the alignment of all offsets, which
182 // allows us to compress the bitset by only storing one bit per aligned
183 // address.
184 uint64_t Mask = 0;
185 for (uint64_t &Offset : Offsets) {
186 Offset -= Min;
187 Mask |= Offset;
188 }
189
190 BitSetInfo BSI;
191 BSI.ByteOffset = Min;
192
193 BSI.AlignLog2 = 0;
194 if (Mask != 0)
195 BSI.AlignLog2 = llvm::countr_zero(Mask);
196
197 // Build the compressed bitset while normalizing the offsets against the
198 // computed alignment.
199 BSI.BitSize = ((Max - Min) >> BSI.AlignLog2) + 1;
200 for (uint64_t Offset : Offsets) {
201 Offset >>= BSI.AlignLog2;
202 // We invert the order of bits when adding them to the bitset. This is
203 // because the offset that we test against is computed by subtracting the
204 // address that we are testing from the global's address, which means that
205 // the offset increases as the tested address decreases.
206 BSI.Bits.insert(BSI.BitSize - 1 - Offset);
207 }
208
209 return BSI;
210}
211
212void GlobalLayoutBuilder::addFragment(const std::set<uint64_t> &F) {
213 assert(Fragments.front().empty() && "Cannot add fragments after build()");
214
215 // Create a new fragment to hold the layout for F.
216 Fragments.emplace_back();
217 std::vector<uint64_t> &Fragment = Fragments.back();
218 uint64_t FragmentIndex = Fragments.size() - 1;
219
220 std::vector<std::vector<uint64_t>> SubFragments;
221 for (auto ObjIndex : F) {
222 uint64_t OldFragmentIndex = FragmentMap[ObjIndex];
223 if (OldFragmentIndex == 0) {
224 // We haven't seen this object index before, so just add it to the current
225 // fragment.
226 SubFragments.push_back({ObjIndex});
227 } else if (!Fragments[OldFragmentIndex].empty()) {
228 // This index belongs to an existing fragment. Copy the elements of the
229 // old fragment into this one and clear the old fragment. We don't update
230 // the fragment map just yet, this ensures that any further references to
231 // indices from the old fragment in this fragment do not insert any more
232 // indices.
233 SubFragments.push_back(std::move(Fragments[OldFragmentIndex]));
234 }
235 }
236
237 if (Less) {
238 llvm::stable_sort(SubFragments, [&](const std::vector<uint64_t> &A,
239 const std::vector<uint64_t> &B) {
240 return Less(A.back(), B.back());
241 });
242 }
243
244 for (auto &SF : SubFragments)
245 llvm::append_range(Fragment, std::move(SF));
246
247 // Update the fragment map to point our object indices to this fragment.
248 for (uint64_t ObjIndex : Fragment)
249 FragmentMap[ObjIndex] = FragmentIndex;
250}
251
252const std::vector<uint64_t> &GlobalLayoutBuilder::build() {
253 if (Less) {
254 // If multiple root fragments remain (e.g. disjoint signatures with no
255 // generalized type), order them so the one containing the hottest function
256 // is placed last.
257 llvm::erase_if(Fragments,
258 [](const std::vector<uint64_t> &F) { return F.empty(); });
259 llvm::stable_sort(Fragments, [&](const std::vector<uint64_t> &FA,
260 const std::vector<uint64_t> &FB) {
261 return Less(FA.back(), FB.back());
262 });
263 }
264
265 std::vector<uint64_t> Layout;
266 Layout.reserve(FragmentMap.size());
267 for (auto &&F : Fragments)
268 llvm::append_range(Layout, F);
269 Fragments.clear();
270 Fragments.push_back(std::move(Layout));
271 return Fragments.front();
272}
273
274void ByteArrayBuilder::allocate(const std::set<uint64_t> &Bits,
275 uint64_t BitSize, uint64_t &AllocByteOffset,
276 uint8_t &AllocMask) {
277 // Find the smallest current allocation.
278 unsigned Bit = 0;
279 for (unsigned I = 1; I != BitsPerByte; ++I)
280 if (BitAllocs[I] < BitAllocs[Bit])
281 Bit = I;
282
283 AllocByteOffset = BitAllocs[Bit];
284
285 // Add our size to it.
286 unsigned ReqSize = AllocByteOffset + BitSize;
287 BitAllocs[Bit] = ReqSize;
288 if (Bytes.size() < ReqSize)
289 Bytes.resize(ReqSize);
290
291 // Set our bits.
292 AllocMask = 1 << Bit;
293 for (uint64_t B : Bits)
294 Bytes[AllocByteOffset + B] |= AllocMask;
295}
296
298 if (F->isDeclarationForLinker())
299 return false;
301 F->getParent()->getModuleFlag("CFI Canonical Jump Tables"));
302 if (!CI || !CI->isZero())
303 return true;
304 return F->hasFnAttribute("cfi-canonical-jump-table");
305}
306
308 if (MDNode *MD = GO.getMetadata(LLVMContext::MD_associated))
309 if (auto *AssocVM = dyn_cast_or_null<ValueAsMetadata>(MD->getOperand(0)))
310 if (auto *AssocGO = dyn_cast<GlobalObject>(AssocVM->getValue()))
311 if (AssocGO->hasMetadata(LLVMContext::MD_type))
312 return true;
313 return GO.hasMetadata(LLVMContext::MD_type);
314}
315
317 SetVector<GlobalValue *> CfiFunctions;
318 for (auto &F : M)
319 if ((!F.hasLocalLinkage() || F.hasAddressTaken()) && hasTypeMetadata(F))
320 CfiFunctions.insert(&F);
321 for (auto &A : M.aliases())
322 if (auto *F = dyn_cast<Function>(A.getAliasee()))
323 if (hasTypeMetadata(*F))
324 CfiFunctions.insert(&A);
325 return CfiFunctions;
326}
327
328/// Extracts a numeric type identifier from an MDNode containing type metadata.
330 // This check excludes vtables for classes inside anonymous namespaces.
331 auto TM = dyn_cast<ValueAsMetadata>(MD.getOperand(1));
332 if (!TM)
333 return nullptr;
334 auto C = dyn_cast_or_null<ConstantInt>(TM->getValue());
335 if (!C)
336 return nullptr;
337 // We are looking for i64 constants.
338 if (C->getBitWidth() != 64)
339 return nullptr;
340
341 return C;
342}
343
345 SetVector<uint64_t> TypeIds;
347 for (const GlobalObject &GO : M.global_objects()) {
348 Types.clear();
349 GO.getMetadata(LLVMContext::MD_type, Types);
350 for (MDNode *Type : Types)
351 if (ConstantInt *TypeId = extractNumericTypeId(*Type))
352 TypeIds.insert(TypeId->getZExtValue());
353 }
354
355 if (NamedMDNode *CfiFunctionsMD = M.getNamedMetadata("cfi.functions")) {
356 for (auto *Func : CfiFunctionsMD->operands()) {
357 assert(Func->getNumOperands() >= 3);
358 assert(isa<ConstantAsMetadata>(Func->getOperand(2)));
359 for (unsigned I = 3; I < Func->getNumOperands(); ++I)
360 if (ConstantInt *TypeId =
361 extractNumericTypeId(*cast<MDNode>(Func->getOperand(I))))
362 TypeIds.insert(TypeId->getZExtValue());
363 }
364 }
365 return TypeIds;
366}
367
368namespace {
369
370/// The type of CFI jumptable needed for a function.
371enum class CfiFunctionLinkage : uint8_t {
372 Definition = 0,
373 Declaration = 1,
374 WeakDeclaration = 2,
375};
376
377/// The hotness of a CFI jumptable function entry.
378class CfiFunctionHotness {
379 enum class Kind : uint8_t {
380 Unknown = 0, // It's higher rank than Cold, but convenient to store as zero.
381 Cold = 1,
382 Other = 2,
383 Hot = 3,
384 };
385
386 Kind Type = Kind::Unknown;
387
388 CfiFunctionHotness(Kind Type) : Type(Type) {}
389
390public:
391 CfiFunctionHotness() = default;
392
393 // Computes the execution weight for F across its entry count and basic block
394 // counts. Placing the hottest function (i.e. the function with the highest
395 // weight) as the last jump table entry makes it more likely to benefit from
396 // the SHT_LLVM_CFI_JUMP_TABLE last-entry optimization and locks the jump
397 // table into the target's section, which is likely hot.
398 // The most important goal is to put functions which end up in .hot at the
399 // end of jumptable, to keep jump table in the same section.
400 static CfiFunctionHotness
401 fromFunction(Function &F, ProfileSummaryInfo &PSI,
402 function_ref<const BlockFrequencyInfo &(Function &)> BFIGetter) {
403 if (F.isDeclaration())
404 return Kind::Unknown;
405
406 // We want to mimic CodeGenPrepare::_run to match section assignments.
407 const BlockFrequencyInfo &BFI = BFIGetter(F);
408 if (F.hasFnAttribute(Attribute::Hot) ||
409 PSI.isFunctionHotInCallGraph(&F, BFI)) {
410 return Kind::Hot;
411 }
412
413 if (PSI.isFunctionColdInCallGraph(&F, BFI) ||
414 F.hasFnAttribute(Attribute::Cold)) {
415 return Kind::Cold;
416 }
417
419 ? Kind::Unknown
420 : Kind::Other;
421 }
422
423 static CfiFunctionHotness fromUint6(uint8_t V) {
424 return CfiFunctionHotness(static_cast<Kind>(V & 0x3));
425 }
426
427 uint8_t asUint6() const { return static_cast<uint8_t>(Type) & 0x3; }
428
429 bool operator==(const CfiFunctionHotness &Other) const {
430 return Type == Other.Type;
431 }
432
433 bool operator<(const CfiFunctionHotness &Other) const {
434 auto Rank = [](Kind K) -> int {
435 return (K == Kind::Cold) ? -1 : static_cast<int>(K);
436 };
437 return Rank(Type) < Rank(Other.Type);
438 }
439};
440
441} // namespace
442
443static CfiFunctionLinkage decodeCfiFunctionLinkage(uint8_t Encoded) {
444 return static_cast<CfiFunctionLinkage>(Encoded & 0x3);
445}
446
447static CfiFunctionHotness decodeCfiFunctionHotness(uint8_t Encoded) {
448 return CfiFunctionHotness::fromUint6(Encoded >> 2);
449}
450
451static uint8_t encodeCfiFunctionLinkage(CfiFunctionLinkage Linkage,
452 CfiFunctionHotness Hotness) {
453 uint8_t Encoded =
454 (Hotness.asUint6() << 2) | (static_cast<uint8_t>(Linkage) & 0x3);
456 assert(decodeCfiFunctionHotness(Encoded) == Hotness);
457 return Encoded;
458}
459
461 Module &DestM, ArrayRef<GlobalValue *> CfiFunctions,
463 function_ref<const BlockFrequencyInfo &(Function &)> BFIGetter) {
464 auto &Ctx = DestM.getContext();
465 SmallVector<MDNode *, 8> CfiFunctionMDs;
466 for (auto *V : CfiFunctions) {
467 Function &F = *cast<Function>(V->getAliaseeObject());
469 F.getMetadata(LLVMContext::MD_type, Types);
470
472 Elts.push_back(MDString::get(Ctx, V->getName()));
473 CfiFunctionLinkage Linkage = CfiFunctionLinkage::Declaration;
475 Linkage = CfiFunctionLinkage::Definition;
476 else if (F.hasExternalWeakLinkage())
477 Linkage = CfiFunctionLinkage::WeakDeclaration;
478
479 CfiFunctionHotness Hotness =
481 ? CfiFunctionHotness::fromFunction(F, PSI, BFIGetter)
482 : CfiFunctionHotness();
483
484 uint8_t EncodedLinkage = encodeCfiFunctionLinkage(Linkage, Hotness);
485
487 llvm::ConstantInt::get(Type::getInt8Ty(Ctx), EncodedLinkage)));
488 GlobalValue::GUID GUID = V->getGUID();
490 llvm::ConstantInt::get(Type::getInt64Ty(Ctx), GUID)));
491 append_range(Elts, Types);
492 CfiFunctionMDs.push_back(MDTuple::get(Ctx, Elts));
493 }
494
495 if (!CfiFunctionMDs.empty()) {
496 NamedMDNode *NMD = DestM.getOrInsertNamedMetadata("cfi.functions");
497 for (auto *MD : CfiFunctionMDs)
498 NMD->addOperand(MD);
499 }
500}
501
502static void createCfiAliasesMetadata(Module &DestM, const Module &SrcM) {
503 auto &Ctx = DestM.getContext();
505 for (const auto &A : SrcM.aliases()) {
506 if (!isa<Function>(A.getAliasee()))
507 continue;
508
509 const auto *F = cast<Function>(A.getAliasee());
510 FunctionAliases[F].push_back(&A);
511 }
512
513 if (!FunctionAliases.empty()) {
514 NamedMDNode *NMD = DestM.getOrInsertNamedMetadata("aliases");
515 for (auto &Alias : FunctionAliases) {
517 Elts.push_back(MDString::get(Ctx, Alias.first->getName()));
518 for (auto *A : Alias.second)
519 Elts.push_back(MDString::get(Ctx, A->getName()));
520 NMD->addOperand(MDTuple::get(Ctx, Elts));
521 }
522 }
523}
524
525static void createCfiSymversMetadata(Module &DestM, const Module &SrcM) {
526 auto &Ctx = DestM.getContext();
529 SrcM, [&](StringRef Name, StringRef Alias) {
530 const Function *F = SrcM.getFunction(Name);
531 if (!F || F->use_empty())
532 return;
533
534 Symvers.push_back(MDTuple::get(
535 Ctx, {MDString::get(Ctx, Name), MDString::get(Ctx, Alias)}));
536 });
537
538 if (!Symvers.empty()) {
539 NamedMDNode *NMD = DestM.getOrInsertNamedMetadata("symvers");
540 for (auto *MD : Symvers)
541 NMD->addOperand(MD);
542 }
543}
544
546 Module &DestM, const Module &SrcM, ArrayRef<GlobalValue *> CfiFunctions,
548 function_ref<const BlockFrequencyInfo &(Function &)> BFIGetter) {
549 createCfiFunctionsMetadata(DestM, CfiFunctions, PSI, BFIGetter);
550 createCfiAliasesMetadata(DestM, SrcM);
551 createCfiSymversMetadata(DestM, SrcM);
552}
553
554namespace {
555
556struct ByteArrayInfo {
557 std::set<uint64_t> Bits;
558 uint64_t BitSize;
559 GlobalVariable *ByteArray;
560 GlobalVariable *MaskGlobal;
561 uint8_t *MaskPtr = nullptr;
562};
563
564/// A POD-like structure that we use to store a global reference together with
565/// its metadata types. In this pass we frequently need to query the set of
566/// metadata types referenced by a global, which at the IR level is an expensive
567/// operation involving a map lookup; this data structure helps to reduce the
568/// number of times we need to do this lookup.
569class GlobalTypeMember final : TrailingObjects<GlobalTypeMember, MDNode *> {
570 friend TrailingObjects;
571
572 GlobalObject *GO;
573 size_t NTypes;
574
575 // For functions: true if the jump table is canonical. This essentially means
576 // whether the canonical address (i.e. the symbol table entry) of the function
577 // is provided by the local jump table. This is normally the same as whether
578 // the function is defined locally, but if canonical jump tables are disabled
579 // by the user then the jump table never provides a canonical definition.
580 bool IsJumpTableCanonical;
581
582 // For functions: true if this function is either defined or used in a thinlto
583 // module and its jumptable entry needs to be exported to thinlto backends.
584 bool IsExported;
585
586public:
587 static GlobalTypeMember *create(BumpPtrAllocator &Alloc, GlobalObject *GO,
588 bool IsJumpTableCanonical, bool IsExported,
589 ArrayRef<MDNode *> Types) {
590 auto *GTM = static_cast<GlobalTypeMember *>(Alloc.Allocate(
591 totalSizeToAlloc<MDNode *>(Types.size()), alignof(GlobalTypeMember)));
592 GTM->GO = GO;
593 GTM->NTypes = Types.size();
594 GTM->IsJumpTableCanonical = IsJumpTableCanonical;
595 GTM->IsExported = IsExported;
596 llvm::copy(Types, GTM->getTrailingObjects());
597 return GTM;
598 }
599
600 GlobalObject *getGlobal() const {
601 return GO;
602 }
603
604 bool isJumpTableCanonical() const {
605 return IsJumpTableCanonical;
606 }
607
608 bool isExported() const {
609 return IsExported;
610 }
611
612 ArrayRef<MDNode *> types() const { return getTrailingObjects(NTypes); }
613};
614
615struct ICallBranchFunnel final
616 : TrailingObjects<ICallBranchFunnel, GlobalTypeMember *> {
617 static ICallBranchFunnel *create(BumpPtrAllocator &Alloc, CallInst *CI,
619 unsigned UniqueId) {
620 auto *Call = static_cast<ICallBranchFunnel *>(
621 Alloc.Allocate(totalSizeToAlloc<GlobalTypeMember *>(Targets.size()),
622 alignof(ICallBranchFunnel)));
623 Call->CI = CI;
624 Call->UniqueId = UniqueId;
625 Call->NTargets = Targets.size();
626 llvm::copy(Targets, Call->getTrailingObjects());
627 return Call;
628 }
629
630 CallInst *CI;
631 ArrayRef<GlobalTypeMember *> targets() const {
632 return getTrailingObjects(NTargets);
633 }
634
635 unsigned UniqueId;
636
637private:
638 size_t NTargets;
639};
640
641struct ScopedSaveAliaseesAndUsed {
642 Module &M;
644 std::vector<std::pair<GlobalAlias *, Function *>> FunctionAliases;
645 std::vector<std::pair<GlobalIFunc *, Function *>> ResolverIFuncs;
646
647 // This function only removes functions from llvm.used and llvm.compiler.used.
648 // We cannot remove global variables because they need to follow RAUW, as
649 // they may be deleted by buildBitSetsFromGlobalVariables.
650 void collectAndEraseUsedFunctions(Module &M,
651 SmallVectorImpl<GlobalValue *> &Vec,
652 bool CompilerUsed) {
653 auto *GV = collectUsedGlobalVariables(M, Vec, CompilerUsed);
654 if (!GV)
655 return;
656 // There's no API to only remove certain array elements from
657 // llvm.used/llvm.compiler.used, so we remove all of them and add back only
658 // the non-functions.
659 GV->eraseFromParent();
660 auto NonFuncBegin =
661 std::stable_partition(Vec.begin(), Vec.end(), [](GlobalValue *GV) {
662 return isa<Function>(GV);
663 });
664 if (CompilerUsed)
665 appendToCompilerUsed(M, {NonFuncBegin, Vec.end()});
666 else
667 appendToUsed(M, {NonFuncBegin, Vec.end()});
668 Vec.resize(NonFuncBegin - Vec.begin());
669 }
670
671 ScopedSaveAliaseesAndUsed(Module &M) : M(M) {
672 // The users of this class want to replace all function references except
673 // for aliases and llvm.used/llvm.compiler.used with references to a jump
674 // table. We avoid replacing aliases in order to avoid introducing a double
675 // indirection (or an alias pointing to a declaration in ThinLTO mode), and
676 // we avoid replacing llvm.used/llvm.compiler.used because these global
677 // variables describe properties of the global, not the jump table (besides,
678 // offseted references to the jump table in llvm.used are invalid).
679 // Unfortunately, LLVM doesn't have a "RAUW except for these (possibly
680 // indirect) users", so what we do is save the list of globals referenced by
681 // llvm.used/llvm.compiler.used and aliases, erase the used lists, let RAUW
682 // replace the aliasees and then set them back to their original values at
683 // the end.
684 collectAndEraseUsedFunctions(M, Used, false);
685 collectAndEraseUsedFunctions(M, CompilerUsed, true);
686
687 for (auto &GA : M.aliases()) {
688 // FIXME: This should look past all aliases not just interposable ones,
689 // see discussion on D65118.
690 if (auto *F = dyn_cast<Function>(GA.getAliasee()->stripPointerCasts()))
691 FunctionAliases.push_back({&GA, F});
692 }
693
694 for (auto &GI : M.ifuncs())
695 if (auto *F = dyn_cast<Function>(GI.getResolver()->stripPointerCasts()))
696 ResolverIFuncs.push_back({&GI, F});
697 }
698
699 ~ScopedSaveAliaseesAndUsed() {
700 appendToUsed(M, Used);
701 appendToCompilerUsed(M, CompilerUsed);
702
703 for (auto P : FunctionAliases)
704 P.first->setAliasee(P.second);
705
706 for (auto P : ResolverIFuncs) {
707 // This does not preserve pointer casts that may have been stripped by the
708 // constructor, but the resolver's type is different from that of the
709 // ifunc anyway.
710 P.first->setResolver(P.second);
711 }
712 }
713};
714
715class LowerTypeTestsModule {
716 Module &M;
717
718 ModuleSummaryIndex *ExportSummary;
719 const ModuleSummaryIndex *ImportSummary;
720
721 Triple::ArchType Arch;
723 Triple::ObjectFormatType ObjectFormat;
724
725 // Determines which kind of Thumb jump table we generate. If arch is
726 // either 'arm' or 'thumb' we need to find this out, because
727 // selectJumpTableArmEncoding may decide to use Thumb in either case.
728 bool CanUseArmJumpTable = false, CanUseThumbBWJumpTable = false;
729
730 // Cache variable used by hasBranchTargetEnforcement().
731 int HasBranchTargetEnforcement = -1;
732
733 // Map from function to hotness passed via cfi.functions metadata.
734 DenseMap<const Function *, CfiFunctionHotness> FunctionSummaryHotness;
735
736 IntegerType *Int1Ty = Type::getInt1Ty(M.getContext());
737 IntegerType *Int8Ty = Type::getInt8Ty(M.getContext());
738 PointerType *PtrTy = PointerType::getUnqual(M.getContext());
739 ArrayType *Int8Arr0Ty = ArrayType::get(Type::getInt8Ty(M.getContext()), 0);
740 IntegerType *Int32Ty = Type::getInt32Ty(M.getContext());
741 IntegerType *Int64Ty = Type::getInt64Ty(M.getContext());
742 IntegerType *IntPtrTy = M.getDataLayout().getIntPtrType(M.getContext(), 0);
743
744 // Indirect function call index assignment counter for WebAssembly
745 uint64_t IndirectIndex = 1;
746
747 // Mapping from type identifiers to the call sites that test them, as well as
748 // whether the type identifier needs to be exported to ThinLTO backends as
749 // part of the regular LTO phase of the ThinLTO pipeline (see exportTypeId).
750 struct TypeIdUserInfo {
751 std::vector<CallInst *> CallSites;
752 bool IsExported = false;
753 };
754 DenseMap<Metadata *, TypeIdUserInfo> TypeIdUsers;
755
756 /// This structure describes how to lower type tests for a particular type
757 /// identifier. It is either built directly from the global analysis (during
758 /// regular LTO or the regular LTO phase of ThinLTO), or indirectly using type
759 /// identifier summaries and external symbol references (in ThinLTO backends).
760 struct TypeIdLowering {
762
763 /// All except Unsat: the address of the last element within the combined
764 /// global.
765 Constant *OffsetedGlobal;
766
767 /// ByteArray, Inline, AllOnes: log2 of the required global alignment
768 /// relative to the start address.
769 Constant *AlignLog2;
770
771 /// ByteArray, Inline, AllOnes: one less than the size of the memory region
772 /// covering members of this type identifier as a multiple of 2^AlignLog2.
773 Constant *SizeM1;
774
775 /// ByteArray: the byte array to test the address against.
776 Constant *TheByteArray;
777
778 /// ByteArray: the bit mask to apply to bytes loaded from the byte array.
779 Constant *BitMask;
780
781 /// Inline: the bit mask to test the address against.
782 Constant *InlineBits;
783 };
784
785 std::vector<ByteArrayInfo> ByteArrayInfos;
786
787 Function *WeakInitializerFn = nullptr;
788
789 GlobalVariable *GlobalAnnotation;
790 DenseSet<Value *> FunctionAnnotations;
791
792 // Cross-DSO CFI emits jumptable entries for exported functions as well as
793 // address taken functions in case they are address taken in other modules.
794 bool CrossDsoCfi = M.getModuleFlag("Cross-DSO CFI") != nullptr;
795
796 bool shouldExportConstantsAsAbsoluteSymbols();
797 uint8_t *exportTypeId(StringRef TypeId, const TypeIdLowering &TIL);
798 TypeIdLowering importTypeId(StringRef TypeId);
799 void importTypeTest(CallInst *CI);
800 void importFunction(Function *F, bool isJumpTableCanonical);
801
802 ByteArrayInfo *createByteArray(const BitSetInfo &BSI);
803 void allocateByteArrays();
804 Value *createBitSetTest(IRBuilder<> &B, const TypeIdLowering &TIL,
805 Value *BitOffset);
806 void lowerTypeTestCalls(
807 ArrayRef<Metadata *> TypeIds, Constant *CombinedGlobalAddr,
808 const DenseMap<GlobalTypeMember *, uint64_t> &GlobalLayout);
809 Value *lowerTypeTestCall(Metadata *TypeId, CallInst *CI,
810 const TypeIdLowering &TIL);
811
812 void buildBitSetsFromGlobalVariables(ArrayRef<Metadata *> TypeIds,
815 selectJumpTableArmEncoding(ArrayRef<GlobalTypeMember *> Functions);
816 bool hasBranchTargetEnforcement();
817 unsigned getJumpTableEntrySize(Triple::ArchType JumpTableArch);
818 InlineAsm *createJumpTableEntryAsm(Triple::ArchType JumpTableArch);
819 void verifyTypeMDNode(GlobalObject *GO, MDNode *Type);
820 void buildBitSetsFromFunctions(ArrayRef<Metadata *> TypeIds,
822 void buildBitSetsFromFunctionsNative(ArrayRef<Metadata *> TypeIds,
824 void buildBitSetsFromFunctionsWASM(ArrayRef<Metadata *> TypeIds,
826 void
827 buildBitSetsFromDisjointSet(ArrayRef<Metadata *> TypeIds,
829 ArrayRef<ICallBranchFunnel *> ICallBranchFunnels);
830
831 void replaceWeakDeclarationWithJumpTablePtr(Function *F, Constant *JT,
832 bool IsJumpTableCanonical);
833 void moveInitializerToModuleConstructor(GlobalVariable *GV);
834 void findGlobalVariableUsersOf(Constant *C,
835 SmallSetVector<GlobalVariable *, 8> &Out);
836
837 void createJumpTable(Function *F, ArrayRef<GlobalTypeMember *> Functions,
838 Triple::ArchType JumpTableArch);
839
840 /// replaceCfiUses - Go through the uses list for this definition and make
841 /// each use point to "New" instead of "Old" when the use is outside the
842 /// block. 'Old's use list is expected to have at least one element. Unlike
843 /// replaceAllUsesWith this function skips blockaddr and direct call uses.
844 void replaceCfiUses(Function *Old, Value *New, bool IsJumpTableCanonical);
845
846 /// replaceDirectCalls - Go through the uses list for this definition and
847 /// replace each use, which is a direct function call.
848 void replaceDirectCalls(Value *Old, Value *New);
849
850 bool isFunctionAnnotation(Value *V) const {
851 return FunctionAnnotations.contains(V);
852 }
853
854 void maybeReplaceComdat(Function *F, StringRef OriginalName);
855
856public:
857 LowerTypeTestsModule(Module &M, ModuleAnalysisManager &AM,
858 ModuleSummaryIndex *ExportSummary,
859 const ModuleSummaryIndex *ImportSummary);
860
861 bool lower();
862
863 // Lower the module using the action and summary passed as command line
864 // arguments. For testing purposes only.
865 static bool runForTesting(Module &M, ModuleAnalysisManager &AM);
866};
867} // end anonymous namespace
868
869/// Build a bit set for list of offsets.
871 // Compute the byte offset of each address associated with this type
872 // identifier.
873 return BitSetBuilder(Offsets).build();
874}
875
876/// Build a test that bit BitOffset mod sizeof(Bits)*8 is set in
877/// Bits. This pattern matches to the bt instruction on x86.
879 Value *BitOffset) {
880 auto BitsType = cast<IntegerType>(Bits->getType());
881 unsigned BitWidth = BitsType->getBitWidth();
882
883 BitOffset = B.CreateZExtOrTrunc(BitOffset, BitsType);
884 Value *BitIndex =
885 B.CreateAnd(BitOffset, ConstantInt::get(BitsType, BitWidth - 1));
886 Value *BitMask = B.CreateShl(ConstantInt::get(BitsType, 1), BitIndex);
887 Value *MaskedBits = B.CreateAnd(Bits, BitMask);
888 return B.CreateICmpNE(MaskedBits, ConstantInt::get(BitsType, 0));
889}
890
891ByteArrayInfo *LowerTypeTestsModule::createByteArray(const BitSetInfo &BSI) {
892 // Create globals to stand in for byte arrays and masks. These never actually
893 // get initialized, we RAUW and erase them later in allocateByteArrays() once
894 // we know the offset and mask to use.
895 auto ByteArrayGlobal = new GlobalVariable(
896 M, Int8Ty, /*isConstant=*/true, GlobalValue::PrivateLinkage, nullptr);
897 auto MaskGlobal = new GlobalVariable(M, Int8Ty, /*isConstant=*/true,
899
900 ByteArrayInfos.emplace_back();
901 ByteArrayInfo *BAI = &ByteArrayInfos.back();
902
903 BAI->Bits = BSI.Bits;
904 BAI->BitSize = BSI.BitSize;
905 BAI->ByteArray = ByteArrayGlobal;
906 BAI->MaskGlobal = MaskGlobal;
907 return BAI;
908}
909
910void LowerTypeTestsModule::allocateByteArrays() {
911 llvm::stable_sort(ByteArrayInfos,
912 [](const ByteArrayInfo &BAI1, const ByteArrayInfo &BAI2) {
913 return BAI1.BitSize > BAI2.BitSize;
914 });
915
916 std::vector<uint64_t> ByteArrayOffsets(ByteArrayInfos.size());
917
919 for (unsigned I = 0; I != ByteArrayInfos.size(); ++I) {
920 ByteArrayInfo *BAI = &ByteArrayInfos[I];
921
922 uint8_t Mask;
923 BAB.allocate(BAI->Bits, BAI->BitSize, ByteArrayOffsets[I], Mask);
924
925 BAI->MaskGlobal->replaceAllUsesWith(
926 ConstantExpr::getIntToPtr(ConstantInt::get(Int8Ty, Mask), PtrTy));
927 BAI->MaskGlobal->eraseFromParent();
928 if (BAI->MaskPtr)
929 *BAI->MaskPtr = Mask;
930 }
931
932 Constant *ByteArrayConst = ConstantDataArray::get(M.getContext(), BAB.Bytes);
933 auto ByteArray =
934 new GlobalVariable(M, ByteArrayConst->getType(), /*isConstant=*/true,
935 GlobalValue::PrivateLinkage, ByteArrayConst);
936
937 for (unsigned I = 0; I != ByteArrayInfos.size(); ++I) {
938 ByteArrayInfo *BAI = &ByteArrayInfos[I];
940 ByteArray, ConstantInt::get(IntPtrTy, ByteArrayOffsets[I]));
941
942 // Create an alias instead of RAUW'ing the gep directly. On x86 this ensures
943 // that the pc-relative displacement is folded into the lea instead of the
944 // test instruction getting another displacement.
945 GlobalAlias *Alias = GlobalAlias::create(
946 Int8Ty, 0, GlobalValue::PrivateLinkage, "bits", GEP, &M);
947 BAI->ByteArray->replaceAllUsesWith(Alias);
948 BAI->ByteArray->eraseFromParent();
949 }
950
951 ByteArraySizeBits = BAB.BitAllocs[0] + BAB.BitAllocs[1] + BAB.BitAllocs[2] +
952 BAB.BitAllocs[3] + BAB.BitAllocs[4] + BAB.BitAllocs[5] +
953 BAB.BitAllocs[6] + BAB.BitAllocs[7];
954 ByteArraySizeBytes = BAB.Bytes.size();
955}
956
957/// Build a test that bit BitOffset is set in the type identifier that was
958/// lowered to TIL, which must be either an Inline or a ByteArray.
959Value *LowerTypeTestsModule::createBitSetTest(IRBuilder<> &B,
960 const TypeIdLowering &TIL,
961 Value *BitOffset) {
962 if (TIL.TheKind == TypeTestResolution::Inline) {
963 // If the bit set is sufficiently small, we can avoid a load by bit testing
964 // a constant.
965 return createMaskedBitTest(B, TIL.InlineBits, BitOffset);
966 } else {
967 Constant *ByteArray = TIL.TheByteArray;
968 if (AvoidReuse && !ImportSummary) {
969 // Each use of the byte array uses a different alias. This makes the
970 // backend less likely to reuse previously computed byte array addresses,
971 // improving the security of the CFI mechanism based on this pass.
972 // This won't work when importing because TheByteArray is external.
974 "bits_use", ByteArray, &M);
975 }
976
977 Value *ByteAddr = B.CreateGEP(Int8Ty, ByteArray, BitOffset);
978 Value *Byte = B.CreateLoad(Int8Ty, ByteAddr);
979
980 Value *ByteAndMask =
981 B.CreateAnd(Byte, ConstantExpr::getPtrToInt(TIL.BitMask, Int8Ty));
982 return B.CreateICmpNE(ByteAndMask, ConstantInt::get(Int8Ty, 0));
983 }
984}
985
986static bool isKnownTypeIdMember(Metadata *TypeId, const DataLayout &DL,
987 Value *V, uint64_t COffset) {
988 if (auto GV = dyn_cast<GlobalObject>(V)) {
990 GV->getMetadata(LLVMContext::MD_type, Types);
991 for (MDNode *Type : Types) {
992 if (Type->getOperand(1) != TypeId)
993 continue;
996 cast<ConstantAsMetadata>(Type->getOperand(0))->getValue())
997 ->getZExtValue();
998 if (COffset == Offset)
999 return true;
1000 }
1001 return false;
1002 }
1003
1004 if (auto GEP = dyn_cast<GEPOperator>(V)) {
1005 APInt APOffset(DL.getIndexSizeInBits(0), 0);
1006 bool Result = GEP->accumulateConstantOffset(DL, APOffset);
1007 if (!Result)
1008 return false;
1009 COffset += APOffset.getZExtValue();
1010 return isKnownTypeIdMember(TypeId, DL, GEP->getPointerOperand(), COffset);
1011 }
1012
1013 if (auto Op = dyn_cast<Operator>(V)) {
1014 if (Op->getOpcode() == Instruction::BitCast)
1015 return isKnownTypeIdMember(TypeId, DL, Op->getOperand(0), COffset);
1016
1017 if (Op->getOpcode() == Instruction::Select)
1018 return isKnownTypeIdMember(TypeId, DL, Op->getOperand(1), COffset) &&
1019 isKnownTypeIdMember(TypeId, DL, Op->getOperand(2), COffset);
1020 }
1021
1022 return false;
1023}
1024
1025/// Lower a llvm.type.test call to its implementation. Returns the value to
1026/// replace the call with.
1027Value *LowerTypeTestsModule::lowerTypeTestCall(Metadata *TypeId, CallInst *CI,
1028 const TypeIdLowering &TIL) {
1029 // Delay lowering if the resolution is currently unknown.
1030 if (TIL.TheKind == TypeTestResolution::Unknown)
1031 return nullptr;
1032 if (TIL.TheKind == TypeTestResolution::Unsat)
1033 return ConstantInt::getFalse(M.getContext());
1034
1035 Value *Ptr = CI->getArgOperand(0);
1036 const DataLayout &DL = M.getDataLayout();
1037 if (isKnownTypeIdMember(TypeId, DL, Ptr, 0))
1038 return ConstantInt::getTrue(M.getContext());
1039
1040 BasicBlock *InitialBB = CI->getParent();
1041
1042 IRBuilder<> B(CI);
1043
1044 Value *PtrAsInt = B.CreatePtrToInt(Ptr, IntPtrTy);
1045
1046 Constant *OffsetedGlobalAsInt =
1047 ConstantExpr::getPtrToInt(TIL.OffsetedGlobal, IntPtrTy);
1048 if (TIL.TheKind == TypeTestResolution::Single)
1049 return B.CreateICmpEQ(PtrAsInt, OffsetedGlobalAsInt);
1050
1051 // Here we compute `last element - address`. The reason why we do this instead
1052 // of computing `address - first element` is that it leads to a slightly
1053 // shorter instruction sequence on x86. Because it doesn't matter how we do
1054 // the subtraction on other architectures, we do so unconditionally.
1055 Value *PtrOffset = B.CreateSub(OffsetedGlobalAsInt, PtrAsInt);
1056
1057 // We need to check that the offset both falls within our range and is
1058 // suitably aligned. We can check both properties at the same time by
1059 // performing a right rotate by log2(alignment) followed by an integer
1060 // comparison against the bitset size. The rotate will move the lower
1061 // order bits that need to be zero into the higher order bits of the
1062 // result, causing the comparison to fail if they are nonzero. The rotate
1063 // also conveniently gives us a bit offset to use during the load from
1064 // the bitset.
1065 Value *BitOffset = B.CreateIntrinsic(IntPtrTy, Intrinsic::fshr,
1066 {PtrOffset, PtrOffset, TIL.AlignLog2});
1067
1068 Value *OffsetInRange = B.CreateICmpULE(BitOffset, TIL.SizeM1);
1069
1070 // If the bit set is all ones, testing against it is unnecessary.
1071 if (TIL.TheKind == TypeTestResolution::AllOnes)
1072 return OffsetInRange;
1073
1074 // See if the intrinsic is used in the following common pattern:
1075 // br(llvm.type.test(...), thenbb, elsebb)
1076 // where nothing happens between the type test and the br.
1077 // If so, create slightly simpler IR.
1078 if (CI->hasOneUse())
1079 if (auto *Br = dyn_cast<CondBrInst>(*CI->user_begin()))
1080 if (CI->getNextNode() == Br) {
1081 BasicBlock *Then = InitialBB->splitBasicBlock(CI->getIterator());
1082 BasicBlock *Else = Br->getSuccessor(1);
1083 CondBrInst *NewBr = CondBrInst::Create(OffsetInRange, Then, Else);
1084 NewBr->setMetadata(LLVMContext::MD_prof,
1085 Br->getMetadata(LLVMContext::MD_prof));
1086 ReplaceInstWithInst(InitialBB->getTerminator(), NewBr);
1087
1088 // Update phis in Else resulting from InitialBB being split
1089 for (auto &Phi : Else->phis())
1090 Phi.addIncoming(Phi.getIncomingValueForBlock(Then), InitialBB);
1091
1092 IRBuilder<> ThenB(CI);
1093 return createBitSetTest(ThenB, TIL, BitOffset);
1094 }
1095
1096 MDBuilder MDB(M.getContext());
1097 IRBuilder<> ThenB(SplitBlockAndInsertIfThen(OffsetInRange, CI, false,
1098 MDB.createLikelyBranchWeights()));
1099
1100 // Now that we know that the offset is in range and aligned, load the
1101 // appropriate bit from the bitset.
1102 Value *Bit = createBitSetTest(ThenB, TIL, BitOffset);
1103
1104 // The value we want is 0 if we came directly from the initial block
1105 // (having failed the range or alignment checks), or the loaded bit if
1106 // we came from the block in which we loaded it.
1107 B.SetInsertPoint(CI);
1108 PHINode *P = B.CreatePHI(Int1Ty, 2);
1109 P->addIncoming(ConstantInt::get(Int1Ty, 0), InitialBB);
1110 P->addIncoming(Bit, ThenB.GetInsertBlock());
1111 return P;
1112}
1113
1114/// Given a disjoint set of type identifiers and globals, lay out the globals,
1115/// build the bit sets and lower the llvm.type.test calls.
1116void LowerTypeTestsModule::buildBitSetsFromGlobalVariables(
1118 // Build a new global with the combined contents of the referenced globals.
1119 // This global is a struct whose even-indexed elements contain the original
1120 // contents of the referenced globals and whose odd-indexed elements contain
1121 // any padding required to align the next element to the next power of 2 plus
1122 // any additional padding required to meet its alignment requirements.
1123 std::vector<Constant *> GlobalInits;
1124 const DataLayout &DL = M.getDataLayout();
1125 DenseMap<GlobalTypeMember *, uint64_t> GlobalLayout;
1126 Align MaxAlign;
1127 uint64_t CurOffset = 0;
1128 uint64_t DesiredPadding = 0;
1129 for (GlobalTypeMember *G : Globals) {
1130 auto *GV = cast<GlobalVariable>(G->getGlobal());
1132 DL.getValueOrABITypeAlignment(GV->getAlign(), GV->getValueType());
1133 MaxAlign = std::max(MaxAlign, Alignment);
1134 uint64_t GVOffset = alignTo(CurOffset + DesiredPadding, Alignment);
1135 GlobalLayout[G] = GVOffset;
1136 if (GVOffset != 0) {
1137 uint64_t Padding = GVOffset - CurOffset;
1138 GlobalInits.push_back(
1139 ConstantAggregateZero::get(ArrayType::get(Int8Ty, Padding)));
1140 }
1141
1142 GlobalInits.push_back(GV->getInitializer());
1143 uint64_t InitSize = GV->getGlobalSize(DL);
1144 CurOffset = GVOffset + InitSize;
1145
1146 // Compute the amount of padding that we'd like for the next element.
1147 DesiredPadding = NextPowerOf2(InitSize - 1) - InitSize;
1148
1149 // Experiments of different caps with Chromium on both x64 and ARM64
1150 // have shown that the 32-byte cap generates the smallest binary on
1151 // both platforms while different caps yield similar performance.
1152 // (see https://lists.llvm.org/pipermail/llvm-dev/2018-July/124694.html)
1153 if (DesiredPadding > 32)
1154 DesiredPadding = alignTo(InitSize, 32) - InitSize;
1155 }
1156
1157 Constant *NewInit = ConstantStruct::getAnon(M.getContext(), GlobalInits);
1158 auto *CombinedGlobal =
1159 new GlobalVariable(M, NewInit->getType(), /*isConstant=*/true,
1161 CombinedGlobal->setAlignment(MaxAlign);
1162
1163 StructType *NewTy = cast<StructType>(NewInit->getType());
1164 lowerTypeTestCalls(TypeIds, CombinedGlobal, GlobalLayout);
1165
1166 // Build aliases pointing to offsets into the combined global for each
1167 // global from which we built the combined global, and replace references
1168 // to the original globals with references to the aliases.
1169 for (unsigned I = 0; I != Globals.size(); ++I) {
1170 GlobalVariable *GV = cast<GlobalVariable>(Globals[I]->getGlobal());
1171
1172 // Multiply by 2 to account for padding elements.
1173 Constant *CombinedGlobalIdxs[] = {ConstantInt::get(Int32Ty, 0),
1174 ConstantInt::get(Int32Ty, I * 2)};
1175 Constant *CombinedGlobalElemPtr = ConstantExpr::getGetElementPtr(
1176 DL, NewInit->getType(), CombinedGlobal, CombinedGlobalIdxs,
1178 assert(GV->getType()->getAddressSpace() == 0);
1179 GlobalAlias *GAlias =
1180 GlobalAlias::create(NewTy->getElementType(I * 2), 0, GV->getLinkage(),
1181 "", CombinedGlobalElemPtr, &M);
1182 GAlias->setVisibility(GV->getVisibility());
1183 GAlias->takeName(GV);
1184 GV->replaceAllUsesWith(GAlias);
1185 GV->eraseFromParent();
1186 }
1187}
1188
1189bool LowerTypeTestsModule::shouldExportConstantsAsAbsoluteSymbols() {
1190 return (Arch == Triple::x86 || Arch == Triple::x86_64) &&
1191 ObjectFormat == Triple::ELF;
1192}
1193
1194/// Export the given type identifier so that ThinLTO backends may import it.
1195/// Type identifiers are exported by adding coarse-grained information about how
1196/// to test the type identifier to the summary, and creating symbols in the
1197/// object file (aliases and absolute symbols) containing fine-grained
1198/// information about the type identifier.
1199///
1200/// Returns a pointer to the location in which to store the bitmask, if
1201/// applicable.
1202uint8_t *LowerTypeTestsModule::exportTypeId(StringRef TypeId,
1203 const TypeIdLowering &TIL) {
1204 TypeTestResolution &TTRes =
1205 ExportSummary->getOrInsertTypeIdSummary(TypeId).TTRes;
1206 TTRes.TheKind = TIL.TheKind;
1207
1208 auto ExportGlobal = [&](StringRef Name, Constant *C) {
1209 GlobalAlias *GA =
1211 "__typeid_" + TypeId + "_" + Name, C, &M);
1213 };
1214
1215 auto ExportConstant = [&](StringRef Name, uint64_t &Storage, Constant *C) {
1216 if (shouldExportConstantsAsAbsoluteSymbols())
1217 ExportGlobal(Name, ConstantExpr::getIntToPtr(C, PtrTy));
1218 else
1219 Storage = cast<ConstantInt>(C)->getZExtValue();
1220 };
1221
1222 if (TIL.TheKind != TypeTestResolution::Unsat)
1223 ExportGlobal("global_addr", TIL.OffsetedGlobal);
1224
1225 if (TIL.TheKind == TypeTestResolution::ByteArray ||
1226 TIL.TheKind == TypeTestResolution::Inline ||
1227 TIL.TheKind == TypeTestResolution::AllOnes) {
1228 ExportConstant("align", TTRes.AlignLog2, TIL.AlignLog2);
1229 ExportConstant("size_m1", TTRes.SizeM1, TIL.SizeM1);
1230
1231 uint64_t BitSize = cast<ConstantInt>(TIL.SizeM1)->getZExtValue() + 1;
1232 if (TIL.TheKind == TypeTestResolution::Inline)
1233 TTRes.SizeM1BitWidth = (BitSize <= 32) ? 5 : 6;
1234 else
1235 TTRes.SizeM1BitWidth = (BitSize <= 128) ? 7 : 32;
1236 }
1237
1238 if (TIL.TheKind == TypeTestResolution::ByteArray) {
1239 ExportGlobal("byte_array", TIL.TheByteArray);
1240 if (shouldExportConstantsAsAbsoluteSymbols())
1241 ExportGlobal("bit_mask", TIL.BitMask);
1242 else
1243 return &TTRes.BitMask;
1244 }
1245
1246 if (TIL.TheKind == TypeTestResolution::Inline)
1247 ExportConstant("inline_bits", TTRes.InlineBits, TIL.InlineBits);
1248
1249 return nullptr;
1250}
1251
1252LowerTypeTestsModule::TypeIdLowering
1253LowerTypeTestsModule::importTypeId(StringRef TypeId) {
1254 const TypeIdSummary *TidSummary = ImportSummary->getTypeIdSummary(TypeId);
1255 if (!TidSummary)
1256 return {}; // Unsat: no globals match this type id.
1257 const TypeTestResolution &TTRes = TidSummary->TTRes;
1258
1259 TypeIdLowering TIL;
1260 TIL.TheKind = TTRes.TheKind;
1261
1262 auto ImportGlobal = [&](StringRef Name) {
1263 // Give the global a type of length 0 so that it is not assumed not to alias
1264 // with any other global.
1265 GlobalVariable *GV = M.getOrInsertGlobal(
1266 ("__typeid_" + TypeId + "_" + Name).str(), Int8Arr0Ty);
1268 return GV;
1269 };
1270
1271 auto ImportConstant = [&](StringRef Name, uint64_t Const, unsigned AbsWidth,
1272 Type *Ty) {
1273 if (!shouldExportConstantsAsAbsoluteSymbols()) {
1274 Constant *C =
1275 ConstantInt::get(isa<IntegerType>(Ty) ? Ty : Int64Ty, Const);
1276 if (!isa<IntegerType>(Ty))
1278 return C;
1279 }
1280
1281 Constant *C = ImportGlobal(Name);
1282 auto *GV = cast<GlobalVariable>(C->stripPointerCasts());
1283 if (isa<IntegerType>(Ty))
1285 if (GV->getMetadata(LLVMContext::MD_absolute_symbol))
1286 return C;
1287
1288 auto SetAbsRange = [&](uint64_t Min, uint64_t Max) {
1289 auto *MinC = ConstantAsMetadata::get(ConstantInt::get(IntPtrTy, Min));
1290 auto *MaxC = ConstantAsMetadata::get(ConstantInt::get(IntPtrTy, Max));
1291 GV->setMetadata(LLVMContext::MD_absolute_symbol,
1292 MDNode::get(M.getContext(), {MinC, MaxC}));
1293 };
1294 if (AbsWidth == IntPtrTy->getBitWidth()) {
1295 uint64_t AllOnes = IntPtrTy->getBitMask();
1296 SetAbsRange(AllOnes, AllOnes); // Full set.
1297 } else {
1298 SetAbsRange(0, 1ull << AbsWidth);
1299 }
1300 return C;
1301 };
1302
1303 if (TIL.TheKind != TypeTestResolution::Unsat) {
1304 auto *GV = ImportGlobal("global_addr");
1305 // This is either a vtable (in .data.rel.ro) or a jump table (in .text).
1306 // Either way it's expected to be in the low 2 GiB, so set the small code
1307 // model.
1308 //
1309 // For .data.rel.ro, we currently place all such sections in the low 2 GiB
1310 // [1], and for .text the sections are expected to be in the low 2 GiB under
1311 // the small and medium code models [2] and this pass only supports those
1312 // code models (e.g. jump tables use jmp instead of movabs/jmp).
1313 //
1314 // [1]https://github.com/llvm/llvm-project/pull/137742
1315 // [2]https://maskray.me/blog/2023-05-14-relocation-overflow-and-code-models
1317 TIL.OffsetedGlobal = GV;
1318 }
1319
1320 if (TIL.TheKind == TypeTestResolution::ByteArray ||
1321 TIL.TheKind == TypeTestResolution::Inline ||
1322 TIL.TheKind == TypeTestResolution::AllOnes) {
1323 TIL.AlignLog2 = ImportConstant("align", TTRes.AlignLog2, 8, IntPtrTy);
1324 TIL.SizeM1 =
1325 ImportConstant("size_m1", TTRes.SizeM1, TTRes.SizeM1BitWidth, IntPtrTy);
1326 }
1327
1328 if (TIL.TheKind == TypeTestResolution::ByteArray) {
1329 TIL.TheByteArray = ImportGlobal("byte_array");
1330 TIL.BitMask = ImportConstant("bit_mask", TTRes.BitMask, 8, PtrTy);
1331 }
1332
1333 if (TIL.TheKind == TypeTestResolution::Inline)
1334 TIL.InlineBits = ImportConstant(
1335 "inline_bits", TTRes.InlineBits, 1 << TTRes.SizeM1BitWidth,
1336 TTRes.SizeM1BitWidth <= 5 ? Int32Ty : Int64Ty);
1337
1338 return TIL;
1339}
1340
1341void LowerTypeTestsModule::importTypeTest(CallInst *CI) {
1342 auto TypeIdMDVal = dyn_cast<MetadataAsValue>(CI->getArgOperand(1));
1343 if (!TypeIdMDVal)
1344 report_fatal_error("Second argument of llvm.type.test must be metadata");
1345
1346 auto TypeIdStr = dyn_cast<MDString>(TypeIdMDVal->getMetadata());
1347 // If this is a local unpromoted type, which doesn't have a metadata string,
1348 // treat as Unknown and delay lowering, so that we can still utilize it for
1349 // later optimizations.
1350 if (!TypeIdStr)
1351 return;
1352
1353 TypeIdLowering TIL = importTypeId(TypeIdStr->getString());
1354 Value *Lowered = lowerTypeTestCall(TypeIdStr, CI, TIL);
1355 if (Lowered) {
1356 CI->replaceAllUsesWith(Lowered);
1357 CI->eraseFromParent();
1358 }
1359}
1360
1361void LowerTypeTestsModule::maybeReplaceComdat(Function *F,
1362 StringRef OriginalName) {
1363 // For COFF we should also rename the comdat if this function also
1364 // happens to be the key function. Even if the comdat name changes, this
1365 // should still be fine since comdat and symbol resolution happens
1366 // before LTO, so all symbols which would prevail have been selected.
1367 if (F->hasComdat() && ObjectFormat == Triple::COFF &&
1368 F->getComdat()->getName() == OriginalName) {
1369 Comdat *OldComdat = F->getComdat();
1370 Comdat *NewComdat = M.getOrInsertComdat(F->getName());
1371 for (GlobalObject &GO : M.global_objects()) {
1372 if (GO.getComdat() == OldComdat)
1373 GO.setComdat(NewComdat);
1374 }
1375 }
1376}
1377
1378// ThinLTO backend: the function F has a jump table entry; update this module
1379// accordingly. isJumpTableCanonical describes the type of the jump table entry.
1380void LowerTypeTestsModule::importFunction(Function *F,
1381 bool isJumpTableCanonical) {
1382 assert(F->getType()->getAddressSpace() == 0);
1383
1384 GlobalValue::VisibilityTypes Visibility = F->getVisibility();
1385 std::string Name = std::string(F->getName());
1386
1387 if (F->isDeclarationForLinker() && isJumpTableCanonical) {
1388 // Non-dso_local functions may be overriden at run time,
1389 // don't short curcuit them
1390 if (!F->isDSOLocal())
1391 return;
1392 if (F->isDeclaration()) {
1393 // Direct calls do not need the type check, so let them skip the jump
1394 // table and call the real function directly.
1395 Function *RealF = Function::Create(F->getFunctionType(),
1397 F->getAddressSpace(),
1398 Name + ".cfi", &M);
1400 replaceDirectCalls(F, RealF);
1401 return;
1402 }
1403 // Otherwise F is an available_externally definition imported from
1404 // another module. Handle it like a local definition below: the body is
1405 // renamed to Name.cfi and stays the target of direct calls, so it remains
1406 // inlinable, while address-taken uses are redirected to the jump table
1407 // entry. If the body is not inlined and is dropped later, the reference
1408 // to Name.cfi resolves to the real function at link time, exactly as for
1409 // a declaration.
1410 }
1411
1412 Function *FDecl;
1413 if (!isJumpTableCanonical) {
1414 // Either a declaration of an external function or a reference to a locally
1415 // defined jump table.
1416 FDecl = Function::Create(F->getFunctionType(), GlobalValue::ExternalLinkage,
1417 F->getAddressSpace(), Name + ".cfi_jt", &M);
1419 } else {
1420 F->setName(Name + ".cfi");
1421 maybeReplaceComdat(F, Name);
1422 FDecl = Function::Create(F->getFunctionType(), GlobalValue::ExternalLinkage,
1423 F->getAddressSpace(), Name, &M);
1424 FDecl->setVisibility(Visibility);
1425 FDecl->setDSOLocal(F->isDSOLocal());
1426 Visibility = GlobalValue::HiddenVisibility;
1427
1428 // Update aliases pointing to this function to also include the ".cfi" suffix,
1429 // We expect the jump table entry to either point to the real function or an
1430 // alias. Redirect all other users to the jump table entry.
1431 for (auto &U : F->uses()) {
1432 if (auto *A = dyn_cast<GlobalAlias>(U.getUser())) {
1433 std::string AliasName = A->getName().str() + ".cfi";
1434 Function *AliasDecl = Function::Create(
1435 F->getFunctionType(), GlobalValue::ExternalLinkage,
1436 F->getAddressSpace(), "", &M);
1437 AliasDecl->takeName(A);
1438 A->replaceAllUsesWith(AliasDecl);
1439 A->setName(AliasName);
1440 AliasDecl->setDSOLocal(A->isDSOLocal());
1441 }
1442 }
1443 }
1444
1445 if (F->hasExternalWeakLinkage())
1446 replaceWeakDeclarationWithJumpTablePtr(F, FDecl, isJumpTableCanonical);
1447 else
1448 replaceCfiUses(F, FDecl, isJumpTableCanonical);
1449
1450 // Set visibility late because it's used in replaceCfiUses() to determine
1451 // whether uses need to be replaced.
1452 F->setVisibility(Visibility);
1453}
1454
1455static auto
1457 const DenseMap<GlobalTypeMember *, uint64_t> &GlobalLayout) {
1459 // Pre-populate the map with interesting type identifiers.
1460 for (Metadata *TypeId : TypeIds)
1461 OffsetsByTypeID[TypeId];
1462 for (const auto &[Mem, MemOff] : GlobalLayout) {
1463 for (MDNode *Type : Mem->types()) {
1464 auto It = OffsetsByTypeID.find(Type->getOperand(1));
1465 if (It == OffsetsByTypeID.end())
1466 continue;
1469 cast<ConstantAsMetadata>(Type->getOperand(0))->getValue())
1470 ->getZExtValue();
1471 It->second.push_back(MemOff + Offset);
1472 }
1473 }
1474
1476 BitSets.reserve(TypeIds.size());
1477 for (Metadata *TypeId : TypeIds) {
1478 BitSets.emplace_back(TypeId, buildBitSet(OffsetsByTypeID[TypeId]));
1479 LLVM_DEBUG({
1480 if (auto MDS = dyn_cast<MDString>(TypeId))
1481 dbgs() << MDS->getString() << ": ";
1482 else
1483 dbgs() << "<unnamed>: ";
1484 BitSets.back().second.print(dbgs());
1485 });
1486 }
1487
1488 return BitSets;
1489}
1490
1491void LowerTypeTestsModule::lowerTypeTestCalls(
1492 ArrayRef<Metadata *> TypeIds, Constant *CombinedGlobalAddr,
1493 const DenseMap<GlobalTypeMember *, uint64_t> &GlobalLayout) {
1494 // For each type identifier in this disjoint set...
1495 for (const auto &[TypeId, BSI] : buildBitSets(TypeIds, GlobalLayout)) {
1496 ByteArrayInfo *BAI = nullptr;
1497 TypeIdLowering TIL;
1498
1499 uint64_t GlobalOffset =
1500 BSI.ByteOffset + ((BSI.BitSize - 1) << BSI.AlignLog2);
1501 TIL.OffsetedGlobal = ConstantExpr::getPtrAdd(
1502 CombinedGlobalAddr, ConstantInt::get(IntPtrTy, GlobalOffset)),
1503 TIL.AlignLog2 = ConstantInt::get(IntPtrTy, BSI.AlignLog2);
1504 TIL.SizeM1 = ConstantInt::get(IntPtrTy, BSI.BitSize - 1);
1505 if (BSI.isAllOnes()) {
1506 TIL.TheKind = (BSI.BitSize == 1) ? TypeTestResolution::Single
1507 : TypeTestResolution::AllOnes;
1508 } else if (BSI.BitSize <= IntPtrTy->getBitWidth()) {
1509 TIL.TheKind = TypeTestResolution::Inline;
1510 uint64_t InlineBits = 0;
1511 for (auto Bit : BSI.Bits)
1512 InlineBits |= uint64_t(1) << Bit;
1513 if (InlineBits == 0)
1514 TIL.TheKind = TypeTestResolution::Unsat;
1515 else
1516 TIL.InlineBits = ConstantInt::get(
1517 (BSI.BitSize <= 32) ? Int32Ty : Int64Ty, InlineBits);
1518 } else {
1519 TIL.TheKind = TypeTestResolution::ByteArray;
1520 ++NumByteArraysCreated;
1521 BAI = createByteArray(BSI);
1522 TIL.TheByteArray = BAI->ByteArray;
1523 TIL.BitMask = BAI->MaskGlobal;
1524 }
1525
1526 TypeIdUserInfo &TIUI = TypeIdUsers[TypeId];
1527
1528 if (TIUI.IsExported) {
1529 uint8_t *MaskPtr = exportTypeId(cast<MDString>(TypeId)->getString(), TIL);
1530 if (BAI)
1531 BAI->MaskPtr = MaskPtr;
1532 }
1533
1534 // Lower each call to llvm.type.test for this type identifier.
1535 for (CallInst *CI : TIUI.CallSites) {
1536 ++NumTypeTestCallsLowered;
1537 Value *Lowered = lowerTypeTestCall(TypeId, CI, TIL);
1538 if (Lowered) {
1539 CI->replaceAllUsesWith(Lowered);
1540 CI->eraseFromParent();
1541 }
1542 }
1543 }
1544}
1545
1546void LowerTypeTestsModule::verifyTypeMDNode(GlobalObject *GO, MDNode *Type) {
1547 if (Type->getNumOperands() != 2)
1548 report_fatal_error("All operands of type metadata must have 2 elements");
1549
1550 if (GO->isThreadLocal())
1551 report_fatal_error("Bit set element may not be thread-local");
1552 if (isa<GlobalVariable>(GO) && GO->hasSection())
1554 "A member of a type identifier may not have an explicit section");
1555
1556 // FIXME: We previously checked that global var member of a type identifier
1557 // must be a definition, but the IR linker may leave type metadata on
1558 // declarations. We should restore this check after fixing PR31759.
1559
1560 auto OffsetConstMD = dyn_cast<ConstantAsMetadata>(Type->getOperand(0));
1561 if (!OffsetConstMD)
1562 report_fatal_error("Type offset must be a constant");
1563 auto OffsetInt = dyn_cast<ConstantInt>(OffsetConstMD->getValue());
1564 if (!OffsetInt)
1565 report_fatal_error("Type offset must be an integer constant");
1566}
1567
1568static const unsigned kX86JumpTableEntrySize = 8;
1569static const unsigned kX86IBTJumpTableEntrySize = 16;
1570static const unsigned kARMJumpTableEntrySize = 4;
1571static const unsigned kARMBTIJumpTableEntrySize = 8;
1572static const unsigned kARMv6MJumpTableEntrySize = 16;
1573static const unsigned kRISCVJumpTableEntrySize = 8;
1574static const unsigned kLOONGARCH64JumpTableEntrySize = 8;
1575static const unsigned kHexagonJumpTableEntrySize = 4;
1576
1577bool LowerTypeTestsModule::hasBranchTargetEnforcement() {
1578 if (HasBranchTargetEnforcement == -1) {
1579 // First time this query has been called. Find out the answer by checking
1580 // the module flags.
1581 if (const auto *BTE = mdconst::extract_or_null<ConstantInt>(
1582 M.getModuleFlag("branch-target-enforcement")))
1583 HasBranchTargetEnforcement = !BTE->isZero();
1584 else
1585 HasBranchTargetEnforcement = 0;
1586 }
1587 return HasBranchTargetEnforcement;
1588}
1589
1590unsigned
1591LowerTypeTestsModule::getJumpTableEntrySize(Triple::ArchType JumpTableArch) {
1592 switch (JumpTableArch) {
1593 case Triple::x86:
1594 case Triple::x86_64:
1595 if (const auto *MD = mdconst::extract_or_null<ConstantInt>(
1596 M.getModuleFlag("cf-protection-branch")))
1597 if (MD->getZExtValue())
1600 case Triple::arm:
1602 case Triple::thumb:
1603 if (CanUseThumbBWJumpTable) {
1604 if (hasBranchTargetEnforcement())
1607 } else {
1609 }
1610 case Triple::aarch64:
1611 if (hasBranchTargetEnforcement())
1614 case Triple::riscv32:
1615 case Triple::riscv64:
1619 case Triple::hexagon:
1621 default:
1622 report_fatal_error("Unsupported architecture for jump tables");
1623 }
1624}
1625
1626// Create an inline asm constant representing a jump table entry for the target.
1627// This consists of an instruction sequence containing a relative branch to
1628// Dest.
1629InlineAsm *
1630LowerTypeTestsModule::createJumpTableEntryAsm(Triple::ArchType JumpTableArch) {
1631 std::string Asm;
1632 raw_string_ostream AsmOS(Asm);
1633
1634 if (JumpTableArch == Triple::x86 || JumpTableArch == Triple::x86_64) {
1635 bool Endbr = false;
1636 if (const auto *MD = mdconst::extract_or_null<ConstantInt>(
1637 M.getModuleFlag("cf-protection-branch")))
1638 Endbr = !MD->isZero();
1639 if (Endbr)
1640 AsmOS << (JumpTableArch == Triple::x86 ? "endbr32\n" : "endbr64\n");
1641 AsmOS << "jmp ${0:c}@plt\n";
1642 if (Endbr)
1643 AsmOS << ".balign 16, 0xcc\n";
1644 else
1645 AsmOS << "int3\nint3\nint3\n";
1646 } else if (JumpTableArch == Triple::arm) {
1647 AsmOS << "b $0\n";
1648 } else if (JumpTableArch == Triple::aarch64) {
1649 if (hasBranchTargetEnforcement())
1650 AsmOS << "bti c\n";
1651 AsmOS << "b $0\n";
1652 } else if (JumpTableArch == Triple::thumb) {
1653 if (!CanUseThumbBWJumpTable) {
1654 // In Armv6-M, this sequence will generate a branch without corrupting
1655 // any registers. We use two stack words; in the second, we construct the
1656 // address we'll pop into pc, and the first is used to save and restore
1657 // r0 which we use as a temporary register.
1658 //
1659 // To support position-independent use cases, the offset of the target
1660 // function is stored as a relative offset (which will expand into an
1661 // R_ARM_REL32 relocation in ELF, and presumably the equivalent in other
1662 // object file types), and added to pc after we load it. (The alternative
1663 // B.W is automatically pc-relative.)
1664 //
1665 // There are five 16-bit Thumb instructions here, so the .balign 4 adds a
1666 // sixth halfword of padding, and then the offset consumes a further 4
1667 // bytes, for a total of 16, which is very convenient since entries in
1668 // this jump table need to have power-of-two size.
1669 AsmOS << "push {r0,r1}\n"
1670 << "ldr r0, 1f\n"
1671 << "0: add r0, r0, pc\n"
1672 << "str r0, [sp, #4]\n"
1673 << "pop {r0,pc}\n"
1674 << ".balign 4\n"
1675 << "1: .word $0 - (0b + 4)\n";
1676 } else {
1677 if (hasBranchTargetEnforcement())
1678 AsmOS << "bti\n";
1679 AsmOS << "b.w $0\n";
1680 }
1681 } else if (JumpTableArch == Triple::riscv32 ||
1682 JumpTableArch == Triple::riscv64) {
1683 AsmOS << "tail $0@plt\n";
1684 } else if (JumpTableArch == Triple::loongarch64) {
1685 AsmOS << "pcalau12i $$t0, %pc_hi20($0)\n"
1686 << "jirl $$r0, $$t0, %pc_lo12($0)\n";
1687 } else if (JumpTableArch == Triple::hexagon) {
1688 AsmOS << "jump $0\n";
1689 } else {
1690 report_fatal_error("Unsupported architecture for jump tables");
1691 }
1692
1693 return InlineAsm::get(
1694 FunctionType::get(Type::getVoidTy(M.getContext()), PtrTy, false),
1695 AsmOS.str(), "s",
1696 /*hasSideEffects=*/true);
1697}
1698
1699/// Given a disjoint set of type identifiers and functions, build the bit sets
1700/// and lower the llvm.type.test calls, architecture dependently.
1701void LowerTypeTestsModule::buildBitSetsFromFunctions(
1703 if (Arch == Triple::x86 || Arch == Triple::x86_64 || Arch == Triple::arm ||
1704 Arch == Triple::thumb || Arch == Triple::aarch64 ||
1705 Arch == Triple::riscv32 || Arch == Triple::riscv64 ||
1706 Arch == Triple::loongarch64 || Arch == Triple::hexagon)
1707 buildBitSetsFromFunctionsNative(TypeIds, Functions);
1708 else if (Arch == Triple::wasm32 || Arch == Triple::wasm64)
1709 buildBitSetsFromFunctionsWASM(TypeIds, Functions);
1710 else
1711 report_fatal_error("Unsupported architecture for jump tables");
1712}
1713
1714void LowerTypeTestsModule::moveInitializerToModuleConstructor(
1715 GlobalVariable *GV) {
1716 if (WeakInitializerFn == nullptr) {
1717 WeakInitializerFn = Function::Create(
1718 FunctionType::get(Type::getVoidTy(M.getContext()),
1719 /* IsVarArg */ false),
1721 M.getDataLayout().getProgramAddressSpace(),
1722 "__cfi_global_var_init", &M);
1723 BasicBlock *BB =
1724 BasicBlock::Create(M.getContext(), "entry", WeakInitializerFn);
1725 ReturnInst::Create(M.getContext(), BB);
1726 WeakInitializerFn->setSection(
1727 ObjectFormat == Triple::MachO
1728 ? "__TEXT,__StaticInit,regular,pure_instructions"
1729 : ".text.startup");
1730 // This code is equivalent to relocation application, and should run at the
1731 // earliest possible time (i.e. with the highest priority).
1732 appendToGlobalCtors(M, WeakInitializerFn, /* Priority */ 0);
1733 }
1734
1735 IRBuilder<> IRB(WeakInitializerFn->getEntryBlock().getTerminator());
1736 GV->setConstant(false);
1737 IRB.CreateAlignedStore(GV->getInitializer(), GV, GV->getAlign());
1739}
1740
1741void LowerTypeTestsModule::findGlobalVariableUsersOf(
1742 Constant *C, SmallSetVector<GlobalVariable *, 8> &Out) {
1743 for (auto *U : C->users()){
1744 if (auto *GV = dyn_cast<GlobalVariable>(U))
1745 Out.insert(GV);
1746 else if (auto *C2 = dyn_cast<Constant>(U))
1747 findGlobalVariableUsersOf(C2, Out);
1748 }
1749}
1750
1751// Replace all uses of F with (F ? JT : 0).
1752void LowerTypeTestsModule::replaceWeakDeclarationWithJumpTablePtr(
1753 Function *F, Constant *JT, bool IsJumpTableCanonical) {
1754 // The target expression can not appear in a constant initializer on most
1755 // (all?) targets. Switch to a runtime initializer.
1756 SmallSetVector<GlobalVariable *, 8> GlobalVarUsers;
1757 findGlobalVariableUsersOf(F, GlobalVarUsers);
1758 for (auto *GV : GlobalVarUsers) {
1759 if (GV == GlobalAnnotation)
1760 continue;
1761 moveInitializerToModuleConstructor(GV);
1762 }
1763
1764 // Can not RAUW F with an expression that uses F. Replace with a temporary
1765 // placeholder first.
1766 Function *PlaceholderFn =
1768 F->getAddressSpace(), "", &M);
1769 replaceCfiUses(F, PlaceholderFn, IsJumpTableCanonical);
1770
1772 // Don't use range based loop, because use list will be modified.
1773 while (!PlaceholderFn->use_empty()) {
1774 Use &U = *PlaceholderFn->use_begin();
1775 auto *InsertPt = dyn_cast<Instruction>(U.getUser());
1776 assert(InsertPt && "Non-instruction users should have been eliminated");
1777 auto *PN = dyn_cast<PHINode>(InsertPt);
1778 if (PN)
1779 InsertPt = PN->getIncomingBlock(U)->getTerminator();
1780 IRBuilder Builder(InsertPt);
1781 Value *ICmp = Builder.CreateICmp(CmpInst::ICMP_NE, F,
1782 Constant::getNullValue(F->getType()));
1783 Value *Select = Builder.CreateSelect(ICmp, JT,
1784 Constant::getNullValue(F->getType()));
1785
1786 if (auto *SI = dyn_cast<SelectInst>(Select))
1788 // For phi nodes, we need to update the incoming value for all operands
1789 // with the same predecessor.
1790 if (PN)
1791 PN->setIncomingValueForBlock(InsertPt->getParent(), Select);
1792 else
1793 U.set(Select);
1794 }
1795 PlaceholderFn->eraseFromParent();
1796}
1797
1798static bool isThumbFunction(Function *F, Triple::ArchType ModuleArch) {
1799 Attribute TFAttr = F->getFnAttribute("target-features");
1800 if (TFAttr.isValid()) {
1802 TFAttr.getValueAsString().split(Features, ',');
1803 for (StringRef Feature : Features) {
1804 if (Feature == "-thumb-mode")
1805 return false;
1806 else if (Feature == "+thumb-mode")
1807 return true;
1808 }
1809 }
1810
1811 return ModuleArch == Triple::thumb;
1812}
1813
1814// Each jump table must be either ARM or Thumb as a whole for the bit-test math
1815// to work. Pick one that matches the majority of members to minimize interop
1816// veneers inserted by the linker.
1817Triple::ArchType LowerTypeTestsModule::selectJumpTableArmEncoding(
1818 ArrayRef<GlobalTypeMember *> Functions) {
1819 if (Arch != Triple::arm && Arch != Triple::thumb)
1820 return Arch;
1821
1822 if (!CanUseThumbBWJumpTable && CanUseArmJumpTable) {
1823 // In architectures that provide Arm and Thumb-1 but not Thumb-2,
1824 // we should always prefer the Arm jump table format, because the
1825 // Thumb-1 one is larger and slower.
1826 return Triple::arm;
1827 }
1828
1829 // Otherwise, go with majority vote.
1830 unsigned ArmCount = 0, ThumbCount = 0;
1831 for (const auto GTM : Functions) {
1832 if (!GTM->isJumpTableCanonical()) {
1833 // PLT stubs are always ARM.
1834 // FIXME: This is the wrong heuristic for non-canonical jump tables.
1835 ++ArmCount;
1836 continue;
1837 }
1838
1839 Function *F = cast<Function>(GTM->getGlobal());
1840 ++(isThumbFunction(F, Arch) ? ThumbCount : ArmCount);
1841 }
1842
1843 return ArmCount > ThumbCount ? Triple::arm : Triple::thumb;
1844}
1845
1846// Create location for each function entry which should look like this:
1847// frame #0: c::c() (.cfi_jt) at sanitizer/ubsan_interface.h:0:0
1848// frame #1: __ubsan_check_cfi_icall_jt at sanitizer/ubsan_interface.h:0
1851 Module &M = *F->getParent();
1852 DICompileUnit *CU = nullptr;
1853 auto CUs = M.debug_compile_units();
1854 if (!CUs.empty())
1855 CU = *CUs.begin();
1856
1857 DIBuilder DIB(M, /*AllowUnresolved=*/true, CU);
1858 DIFile *File = DIB.createFile("ubsan_interface.h", "sanitizer");
1859 if (!CU) {
1860 // Synthetic module (like ld-temp.o), it frequently lacks a DICompileUnit
1861 // even if the rest of the program has debug info.
1862 CU = DIB.createCompileUnit(
1863 DISourceLanguageName(dwarf::DW_LANG_C), File, "llvm", true, "", 0, "",
1865 }
1866
1867 DISubroutineType *DIFnTy = DIB.createSubroutineType(nullptr);
1868
1869 DISubprogram *UbsanSP = DIB.createFunction(
1870 CU, "__ubsan_check_cfi_icall_jt", {}, File, 0, DIFnTy, 0,
1871 DINode::FlagArtificial, DISubprogram::SPFlagDefinition);
1872
1873 F->setSubprogram(UbsanSP);
1874
1875 DILocation *UbsanLoc = DILocation::get(M.getContext(), 0, 0, UbsanSP);
1876
1877 SmallVector<DILocation *> Locations;
1878 Locations.reserve(Functions.size());
1879
1880 for (auto *Func : Functions) {
1881 StringRef FuncName = Func->getGlobal()->getName();
1882 FuncName.consume_back(".cfi");
1883 DISubprogram *JumpSP = DIB.createFunction(
1884 CU, (FuncName + ".cfi_jt").str(), {}, File, 0, DIFnTy, 0,
1885 DINode::FlagArtificial, DISubprogram::SPFlagDefinition);
1886
1887 DILocation *EntryLoc =
1888 DILocation::get(M.getContext(), 0, 0, JumpSP, UbsanLoc);
1889
1890 Locations.push_back(EntryLoc);
1891 }
1892
1893 DIB.finalize();
1894
1895 return Locations;
1896}
1897
1898void LowerTypeTestsModule::createJumpTable(
1900 Triple::ArchType JumpTableArch) {
1901 unsigned JumpTableEntrySize = getJumpTableEntrySize(JumpTableArch);
1902 // Give the jumptable section this type in order to enable jumptable
1903 // relaxation. Only do this if cross-DSO CFI is disabled because jumptable
1904 // relaxation violates cross-DSO CFI's restrictions on the ordering of the
1905 // jumptable relative to other sections.
1906 if (!CrossDsoCfi)
1907 F->setMetadata(LLVMContext::MD_elf_section_properties,
1908 MDNode::get(F->getContext(),
1910 ConstantAsMetadata::get(ConstantInt::get(
1911 Int64Ty, ELF::SHT_LLVM_CFI_JUMP_TABLE)),
1912 ConstantAsMetadata::get(ConstantInt::get(
1913 Int64Ty, JumpTableEntrySize))}));
1914
1915 BasicBlock *BB = BasicBlock::Create(M.getContext(), "entry", F);
1916 IRBuilder<> IRB(BB);
1917
1919 if (M.getDwarfVersion() != 0 && EnableJumpTableDebugInfo)
1920 Locations = createJumpTableDebugInfo(F, Functions);
1921
1922 InlineAsm *JumpTableAsm = createJumpTableEntryAsm(JumpTableArch);
1923
1924 // Check if all entries have the NoUnwind attribute.
1925 // If all entries have it, we can safely mark the
1926 // cfi.jumptable as NoUnwind, otherwise, direct calls
1927 // to the jump table will not handle exceptions properly
1928 bool areAllEntriesNounwind = true;
1929 assert(Locations.empty() || Functions.size() == Locations.size());
1930 for (auto [GTM, Loc] : zip_longest(Functions, Locations)) {
1931 if (Loc.has_value())
1932 IRB.SetCurrentDebugLocation(*Loc);
1933 if (!cast<Function>((*GTM)->getGlobal())
1934 ->hasFnAttribute(Attribute::NoUnwind)) {
1935 areAllEntriesNounwind = false;
1936 }
1937 IRB.CreateCall(JumpTableAsm, (*GTM)->getGlobal());
1938 }
1939 IRB.CreateUnreachable();
1940
1941 // Align the whole table by entry size.
1942 F->setPreferredAlignment(Align(JumpTableEntrySize));
1943 F->addFnAttr(Attribute::Naked);
1944 if (JumpTableArch == Triple::arm)
1945 F->addFnAttr("target-features", "-thumb-mode");
1946 if (JumpTableArch == Triple::thumb) {
1947 if (hasBranchTargetEnforcement()) {
1948 // If we're generating a Thumb jump table with BTI, add a target-features
1949 // setting to ensure BTI can be assembled.
1950 F->addFnAttr("target-features", "+thumb-mode,+pacbti");
1951 } else {
1952 F->addFnAttr("target-features", "+thumb-mode");
1953 if (CanUseThumbBWJumpTable) {
1954 // Thumb jump table assembly needs Thumb2. The following attribute is
1955 // added by Clang for -march=armv7.
1956 F->addFnAttr("target-cpu", "cortex-a8");
1957 }
1958 }
1959 }
1960 // When -mbranch-protection= is used, the inline asm adds a BTI. Suppress BTI
1961 // for the function to avoid double BTI. This is a no-op without
1962 // -mbranch-protection=.
1963 if (JumpTableArch == Triple::aarch64 || JumpTableArch == Triple::thumb) {
1964 if (F->hasFnAttribute("branch-target-enforcement"))
1965 F->removeFnAttr("branch-target-enforcement");
1966 if (F->hasFnAttribute("sign-return-address"))
1967 F->removeFnAttr("sign-return-address");
1968 }
1969 if (JumpTableArch == Triple::riscv32 || JumpTableArch == Triple::riscv64) {
1970 // Make sure the jump table assembly is not modified by the assembler or
1971 // the linker.
1972 F->addFnAttr("target-features", "-c,-relax");
1973 }
1974 // When -fcf-protection= is used, the inline asm adds an ENDBR. Suppress ENDBR
1975 // for the function to avoid double ENDBR. This is a no-op without
1976 // -fcf-protection=.
1977 if (JumpTableArch == Triple::x86 || JumpTableArch == Triple::x86_64)
1978 F->addFnAttr(Attribute::NoCfCheck);
1979
1980 // Make sure we don't emit .eh_frame for this function if it isn't needed.
1981 if (areAllEntriesNounwind)
1982 F->addFnAttr(Attribute::NoUnwind);
1983
1984 // Make sure we do not inline any calls to the cfi.jumptable.
1985 F->addFnAttr(Attribute::NoInline);
1986}
1987
1988/// Given a disjoint set of type identifiers and functions, build a jump table
1989/// for the functions, build the bit sets and lower the llvm.type.test calls.
1990void LowerTypeTestsModule::buildBitSetsFromFunctionsNative(
1992 // Unlike the global bitset builder, the function bitset builder cannot
1993 // re-arrange functions in a particular order and base its calculations on the
1994 // layout of the functions' entry points, as we have no idea how large a
1995 // particular function will end up being (the size could even depend on what
1996 // this pass does!) Instead, we build a jump table, which is a block of code
1997 // consisting of one branch instruction for each of the functions in the bit
1998 // set that branches to the target function, and redirect any taken function
1999 // addresses to the corresponding jump table entry. In the object file's
2000 // symbol table, the symbols for the target functions also refer to the jump
2001 // table entries, so that addresses taken outside the module will pass any
2002 // verification done inside the module.
2003 //
2004 // In more concrete terms, suppose we have three functions f, g, h which are
2005 // of the same type, and a function foo that returns their addresses:
2006 //
2007 // f:
2008 // mov 0, %eax
2009 // ret
2010 //
2011 // g:
2012 // mov 1, %eax
2013 // ret
2014 //
2015 // h:
2016 // mov 2, %eax
2017 // ret
2018 //
2019 // foo:
2020 // mov f, %eax
2021 // mov g, %edx
2022 // mov h, %ecx
2023 // ret
2024 //
2025 // We output the jump table as module-level inline asm string. The end result
2026 // will (conceptually) look like this:
2027 //
2028 // f = .cfi.jumptable
2029 // g = .cfi.jumptable + 4
2030 // h = .cfi.jumptable + 8
2031 // .cfi.jumptable:
2032 // jmp f.cfi ; 5 bytes
2033 // int3 ; 1 byte
2034 // int3 ; 1 byte
2035 // int3 ; 1 byte
2036 // jmp g.cfi ; 5 bytes
2037 // int3 ; 1 byte
2038 // int3 ; 1 byte
2039 // int3 ; 1 byte
2040 // jmp h.cfi ; 5 bytes
2041 // int3 ; 1 byte
2042 // int3 ; 1 byte
2043 // int3 ; 1 byte
2044 //
2045 // f.cfi:
2046 // mov 0, %eax
2047 // ret
2048 //
2049 // g.cfi:
2050 // mov 1, %eax
2051 // ret
2052 //
2053 // h.cfi:
2054 // mov 2, %eax
2055 // ret
2056 //
2057 // foo:
2058 // mov f, %eax
2059 // mov g, %edx
2060 // mov h, %ecx
2061 // ret
2062 //
2063 // Because the addresses of f, g, h are evenly spaced at a power of 2, in the
2064 // normal case the check can be carried out using the same kind of simple
2065 // arithmetic that we normally use for globals.
2066
2067 // FIXME: find a better way to represent the jumptable in the IR.
2068 assert(!Functions.empty());
2069
2070 // Decide on the jump table encoding, so that we know how big the
2071 // entries will be.
2072 Triple::ArchType JumpTableArch = selectJumpTableArmEncoding(Functions);
2073
2074 // Build a simple layout based on the regular layout of jump tables.
2075 DenseMap<GlobalTypeMember *, uint64_t> GlobalLayout;
2076 unsigned EntrySize = getJumpTableEntrySize(JumpTableArch);
2077 for (unsigned I = 0; I != Functions.size(); ++I)
2078 GlobalLayout[Functions[I]] = I * EntrySize;
2079
2080 Function *JumpTableFn =
2082 /* IsVarArg */ false),
2084 M.getDataLayout().getProgramAddressSpace(),
2085 ".cfi.jumptable", &M);
2086 ArrayType *JumpTableEntryType = ArrayType::get(Int8Ty, EntrySize);
2088 ArrayType::get(JumpTableEntryType, Functions.size());
2090 JumpTableFn, PointerType::getUnqual(M.getContext()));
2091
2092 lowerTypeTestCalls(TypeIds, JumpTable, GlobalLayout);
2093
2094 // Build aliases pointing to offsets into the jump table, and replace
2095 // references to the original functions with references to the aliases.
2096 for (unsigned I = 0; I != Functions.size(); ++I) {
2097 Function *F = cast<Function>(Functions[I]->getGlobal());
2098 bool IsJumpTableCanonical = Functions[I]->isJumpTableCanonical();
2099
2100 Constant *CombinedGlobalElemPtr = ConstantExpr::getGetElementPtr(
2101 F->getDataLayout(), JumpTableType, JumpTable,
2102 {ConstantInt::get(IntPtrTy, 0), ConstantInt::get(IntPtrTy, I)},
2104
2105 const bool IsExported = Functions[I]->isExported();
2106 if (!IsJumpTableCanonical) {
2109 GlobalAlias *JtAlias = GlobalAlias::create(JumpTableEntryType, 0, LT,
2110 F->getName() + ".cfi_jt",
2111 CombinedGlobalElemPtr, &M);
2112 if (IsExported)
2114 else
2115 appendToUsed(M, {JtAlias});
2116 }
2117
2118 if (IsExported) {
2119 GlobalValue::GUID GUID = F->getGUID();
2120 if (IsJumpTableCanonical)
2121 ExportSummary->cfiFunctionDefs().addSymbolWithThinLTOGUID(F->getName(),
2122 GUID);
2123 else
2124 ExportSummary->cfiFunctionDecls().addSymbolWithThinLTOGUID(F->getName(),
2125 GUID);
2126 }
2127
2128 if (!IsJumpTableCanonical) {
2129 if (F->hasExternalWeakLinkage())
2130 replaceWeakDeclarationWithJumpTablePtr(F, CombinedGlobalElemPtr,
2131 IsJumpTableCanonical);
2132 else
2133 replaceCfiUses(F, CombinedGlobalElemPtr, IsJumpTableCanonical);
2134 } else {
2135 assert(F->getType()->getAddressSpace() == 0);
2136
2137 GlobalAlias *FAlias =
2138 GlobalAlias::create(JumpTableEntryType, 0, F->getLinkage(), "",
2139 CombinedGlobalElemPtr, &M);
2140 FAlias->setVisibility(F->getVisibility());
2141 FAlias->setDSOLocal(F->isDSOLocal());
2142 FAlias->takeName(F);
2143 if (FAlias->hasName()) {
2144 F->setName(FAlias->getName() + ".cfi");
2145 maybeReplaceComdat(F, FAlias->getName());
2146 }
2147 replaceCfiUses(F, FAlias, IsJumpTableCanonical);
2148 if (!F->hasLocalLinkage())
2149 F->setVisibility(GlobalVariable::HiddenVisibility);
2150 }
2151 }
2152
2153 createJumpTable(JumpTableFn, Functions, JumpTableArch);
2154}
2155
2156/// Assign a dummy layout using an incrementing counter, tag each function
2157/// with its index represented as metadata, and lower each type test to an
2158/// integer range comparison. During generation of the indirect function call
2159/// table in the backend, it will assign the given indexes.
2160/// Note: Dynamic linking is not supported, as the WebAssembly ABI has not yet
2161/// been finalized.
2162void LowerTypeTestsModule::buildBitSetsFromFunctionsWASM(
2164 assert(!Functions.empty());
2165
2166 // Build consecutive monotonic integer ranges for each call target set
2167 DenseMap<GlobalTypeMember *, uint64_t> GlobalLayout;
2168
2169 for (GlobalTypeMember *GTM : Functions) {
2170 Function *F = cast<Function>(GTM->getGlobal());
2171
2172 // Skip functions that are not address taken, to avoid bloating the table
2173 if (!F->hasAddressTaken())
2174 continue;
2175
2176 // Store metadata with the index for each function
2177 MDNode *MD = MDNode::get(F->getContext(),
2179 ConstantInt::get(Int64Ty, IndirectIndex))));
2180 F->setMetadata("wasm.index", MD);
2181
2182 // Assign the counter value
2183 GlobalLayout[GTM] = IndirectIndex++;
2184 }
2185
2186 // The indirect function table index space starts at zero, so pass a NULL
2187 // pointer as the subtracted "jump table" offset.
2188 lowerTypeTestCalls(TypeIds, ConstantPointerNull::get(PtrTy),
2189 GlobalLayout);
2190}
2191
2192void LowerTypeTestsModule::buildBitSetsFromDisjointSet(
2194 ArrayRef<ICallBranchFunnel *> ICallBranchFunnels) {
2195 DenseMap<Metadata *, uint64_t> TypeIdIndices;
2196 for (unsigned I = 0; I != TypeIds.size(); ++I)
2197 TypeIdIndices[TypeIds[I]] = I;
2198
2199 // For each type identifier, build a set of indices that refer to members of
2200 // the type identifier.
2201 std::vector<std::set<uint64_t>> TypeMembers(TypeIds.size());
2202 unsigned GlobalIndex = 0;
2203 DenseMap<GlobalTypeMember *, uint64_t> GlobalIndices;
2204 for (GlobalTypeMember *GTM : Globals) {
2205 for (MDNode *Type : GTM->types()) {
2206 // Type = { offset, type identifier }
2207 auto I = TypeIdIndices.find(Type->getOperand(1));
2208 if (I != TypeIdIndices.end())
2209 TypeMembers[I->second].insert(GlobalIndex);
2210 }
2211 GlobalIndices[GTM] = GlobalIndex;
2212 GlobalIndex++;
2213 }
2214
2215 for (ICallBranchFunnel *JT : ICallBranchFunnels) {
2216 TypeMembers.emplace_back();
2217 std::set<uint64_t> &TMSet = TypeMembers.back();
2218 for (GlobalTypeMember *T : JT->targets())
2219 TMSet.insert(GlobalIndices[T]);
2220 }
2221
2222 // Order the sets of indices by size. The GlobalLayoutBuilder works best
2223 // when given small index sets first.
2224 llvm::stable_sort(TypeMembers, [](const std::set<uint64_t> &O1,
2225 const std::set<uint64_t> &O2) {
2226 return O1.size() < O2.size();
2227 });
2228
2229 bool IsGlobalSet =
2230 Globals.empty() || isa<GlobalVariable>(Globals[0]->getGlobal());
2231
2232 unique_function<bool(uint64_t, uint64_t)> Less;
2233 if (!IsGlobalSet && !FunctionSummaryHotness.empty() &&
2235 // Estimated weight of each jump entry.
2236 std::vector<CfiFunctionHotness> GTMHotness;
2237 GTMHotness.reserve(Globals.size());
2238 for (GlobalTypeMember *GTM : Globals) {
2239 GTMHotness.push_back(
2240 FunctionSummaryHotness.lookup(cast<Function>(GTM->getGlobal())));
2241 }
2242
2243 // Order jump table entries by hotness ascending so that the hottest
2244 // entry is placed at the end of the jump table:
2245 // 1. Under jump table relaxation (SHT_LLVM_CFI_JUMP_TABLE), the linker
2246 // moves the jump table directly before the target of the last entry
2247 // and deletes its branch so the target function body acts as the
2248 // last entry.
2249 // 2. The jump table is placed into the output section of that last
2250 // target. Jump tables are critical to performance; if the last
2251 // entry were a cold function, the jump table would be dragged into a
2252 // cold binary section (such as .text.unlikely). Placing the hottest
2253 // entry at the end ensures the jump table lands in a hot section and
2254 // the hottest callee benefits from fall-through without a branch.
2255 Less = [GTMHotness = std::move(GTMHotness)](uint64_t A, uint64_t B) {
2256 return GTMHotness[A] < GTMHotness[B];
2257 };
2258 }
2259
2260 // Create a GlobalLayoutBuilder and provide it with index sets as layout
2261 // fragments. The GlobalLayoutBuilder tries to lay out members of fragments as
2262 // close together as possible.
2263 GlobalLayoutBuilder GLB(Globals.size(), std::move(Less));
2264 for (auto &&MemSet : TypeMembers)
2265 GLB.addFragment(MemSet);
2266
2267 // Build a vector of globals with the computed layout.
2268 std::vector<GlobalTypeMember *> OrderedGTMs(Globals.size());
2269 auto OGTMI = OrderedGTMs.begin();
2270 for (uint64_t Offset : GLB.build()) {
2271 if (IsGlobalSet != isa<GlobalVariable>(Globals[Offset]->getGlobal()))
2272 report_fatal_error("Type identifier may not contain both global "
2273 "variables and functions");
2274 *OGTMI++ = Globals[Offset];
2275 }
2276
2277 // Build the bitsets from this disjoint set.
2278 if (IsGlobalSet)
2279 buildBitSetsFromGlobalVariables(TypeIds, OrderedGTMs);
2280 else
2281 buildBitSetsFromFunctions(TypeIds, OrderedGTMs);
2282}
2283
2284/// Lower all type tests in this module.
2285LowerTypeTestsModule::LowerTypeTestsModule(
2286 Module &M, ModuleAnalysisManager &AM, ModuleSummaryIndex *ExportSummary,
2287 const ModuleSummaryIndex *ImportSummary)
2288 : M(M), ExportSummary(ExportSummary), ImportSummary(ImportSummary) {
2289 assert(!(ExportSummary && ImportSummary));
2290 Triple TargetTriple(M.getTargetTriple());
2291 Arch = TargetTriple.getArch();
2292 auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
2293
2294 if (Arch == Triple::arm)
2295 CanUseArmJumpTable = true;
2296 if (Arch == Triple::arm || Arch == Triple::thumb) {
2297 for (Function &F : M) {
2298 // Skip declarations since we should not query the TTI for them.
2299 if (F.isDeclaration())
2300 continue;
2301 auto &TTI = FAM.getResult<TargetIRAnalysis>(F);
2302 if (TTI.hasArmWideBranch(false))
2303 CanUseArmJumpTable = true;
2304 if (TTI.hasArmWideBranch(true))
2305 CanUseThumbBWJumpTable = true;
2306 }
2307 }
2308 OS = TargetTriple.getOS();
2309 ObjectFormat = TargetTriple.getObjectFormat();
2310
2311 // Function annotation describes or applies to function itself, and
2312 // shouldn't be associated with jump table thunk generated for CFI.
2313 GlobalAnnotation = M.getGlobalVariable("llvm.global.annotations");
2314 if (GlobalAnnotation && GlobalAnnotation->hasInitializer()) {
2315 const ConstantArray *CA =
2316 cast<ConstantArray>(GlobalAnnotation->getInitializer());
2317 FunctionAnnotations.insert_range(CA->operands());
2318 }
2319}
2320
2321bool LowerTypeTestsModule::runForTesting(Module &M, ModuleAnalysisManager &AM) {
2322 std::unique_ptr<ModuleSummaryIndex> Summary;
2323
2324 // Handle the command-line summary arguments. This code is for testing
2325 // purposes only, so we handle errors directly.
2326 if (!ClReadSummary.empty()) {
2327 ExitOnError ExitOnErr("-lowertypetests-read-summary: " + ClReadSummary +
2328 ": ");
2329 auto ReadSummaryFile = ExitOnErr(errorOrToExpected(
2330 MemoryBuffer::getFile(ClReadSummary, /*IsText=*/true)));
2331 // TODO: Convert the rest of tests (some YAML features are missing from
2332 // textual summary assembly) and remove YAML from this file.
2333 if (ReadSummaryFile->getBuffer().starts_with("---")) {
2334 Summary = std::make_unique<ModuleSummaryIndex>(/*HaveGVs=*/false);
2335 yaml::Input In(ReadSummaryFile->getBuffer());
2336 In >> *Summary;
2337 ExitOnErr(errorCodeToError(In.error()));
2338 } else {
2339 SMDiagnostic Err;
2340 Summary =
2341 parseSummaryIndexAssembly(ReadSummaryFile->getMemBufferRef(), Err);
2342 if (!Summary) {
2343 Err.print(ClReadSummary.c_str(), errs());
2344 report_fatal_error("Failed to parse summary index assembly");
2345 }
2346 }
2347 } else {
2348 Summary = std::make_unique<ModuleSummaryIndex>(/*HaveGVs=*/false);
2349 }
2350
2351 bool Changed =
2352 LowerTypeTestsModule(
2353 M, AM,
2354 ClSummaryAction == PassSummaryAction::Export ? Summary.get()
2355 : nullptr,
2356 ClSummaryAction == PassSummaryAction::Import ? Summary.get()
2357 : nullptr)
2358 .lower();
2359
2360 if (!ClWriteSummary.empty()) {
2361 ExitOnError ExitOnErr("-lowertypetests-write-summary: " + ClWriteSummary +
2362 ": ");
2363 std::error_code EC;
2364 raw_fd_ostream OS(ClWriteSummary, EC, sys::fs::OF_TextWithCRLF);
2365 ExitOnErr(errorCodeToError(EC));
2366
2367 yaml::Output Out(OS);
2368 Out << *Summary;
2369 }
2370
2371 return Changed;
2372}
2373
2374static bool isDirectCall(Use& U) {
2375 auto *Usr = dyn_cast<CallInst>(U.getUser());
2376 return Usr && Usr->isCallee(&U);
2377}
2378
2379void LowerTypeTestsModule::replaceCfiUses(Function *Old, Value *New,
2380 bool IsJumpTableCanonical) {
2381 SmallSetVector<Constant *, 4> Constants;
2382 for (Use &U : llvm::make_early_inc_range(Old->uses())) {
2383 // Skip no_cfi values, which refer to the function body instead of the jump
2384 // table.
2385 if (isa<NoCFIValue>(U.getUser()))
2386 continue;
2387
2388 // Skip direct calls to externally defined or dso_local functions.
2389 if (isDirectCall(U) && (Old->isDSOLocal() || !IsJumpTableCanonical))
2390 continue;
2391
2392 // Skip function annotation.
2393 if (isFunctionAnnotation(U.getUser()))
2394 continue;
2395
2396 // Must handle Constants specially, we cannot call replaceUsesOfWith on a
2397 // constant because they are uniqued.
2398 if (auto *C = dyn_cast<Constant>(U.getUser())) {
2399 if (!isa<GlobalValue>(C)) {
2400 // Save unique users to avoid processing operand replacement
2401 // more than once.
2402 Constants.insert(C);
2403 continue;
2404 }
2405 }
2406
2407 U.set(New);
2408 }
2409
2410 // Process operand replacement of saved constants.
2411 for (auto *C : Constants)
2412 C->handleOperandChange(Old, New);
2413}
2414
2415void LowerTypeTestsModule::replaceDirectCalls(Value *Old, Value *New) {
2417}
2418
2419// Sound wherever the caller has already dropped the type tests: the check
2420// folds to true, the trap branch becomes dead, and later passes fold it
2421// away. Required because the backend cannot select these intrinsics
2422// ("must be lowered by the LowerTypeTests pass before code generation").
2424 bool IsRelative) {
2425 bool Changed = false;
2426 for (User *User : llvm::make_early_inc_range(CheckedLoadFn.users())) {
2428 if (!I)
2429 continue;
2430 IRBuilder<> IRB(I);
2431 Value *Ptr = I->getOperand(0);
2432 Value *Offset = I->getOperand(1);
2433 Type *PtrTy = I->getType()->getStructElementType(0);
2434 ConstantInt *True = ConstantInt::getTrue(M.getContext());
2436 if (IsRelative) {
2438 Intrinsic::load_relative, {Offset->getType()}, {Ptr, Offset},
2439 /*FMFSource=*/nullptr, "rel_load");
2440 } else {
2441 Value *PtrAdd = IRB.CreatePtrAdd(Ptr, Offset);
2442 Load = IRB.CreateLoad(PtrTy, PtrAdd, "vfunc");
2443 }
2444
2445 Value *Replacement = PoisonValue::get(I->getType());
2446 Replacement = IRB.CreateInsertValue(Replacement, True, {1});
2447 Replacement = IRB.CreateInsertValue(Replacement, Load, {0});
2448 I->replaceAllUsesWith(Replacement);
2449
2450 LLVM_DEBUG(dbgs() << DEBUG_TYPE << ": erase " << *I << "\n");
2451 I->eraseFromParent();
2452 Changed = true;
2453 }
2454 if (Changed)
2455 CheckedLoadFn.eraseFromParent();
2456 return Changed;
2457}
2458
2459static void dropTypeTests(Module &M, Function &TypeTestFunc,
2460 bool ShouldDropAll) {
2461 for (Use &U : llvm::make_early_inc_range(TypeTestFunc.uses())) {
2462 auto *CI = cast<CallInst>(U.getUser());
2463 // Find and erase llvm.assume intrinsics for this llvm.type.test call.
2464 for (Use &CIU : llvm::make_early_inc_range(CI->uses()))
2465 if (auto *Assume = dyn_cast<AssumeInst>(CIU.getUser()))
2466 Assume->eraseFromParent();
2467 // If the assume was merged with another assume, we might have a use on a
2468 // phi or select (which will feed the assume). Simply replace the use on
2469 // the phi/select with "true" and leave the merged assume.
2470 //
2471 // If ShouldDropAll is set, then we we need to update any remaining uses,
2472 // regardless of the instruction type.
2473 if (!CI->use_empty()) {
2474 assert(ShouldDropAll || all_of(CI->users(), [](User *U) -> bool {
2475 return isa<PHINode>(U) || isa<SelectInst>(U);
2476 }));
2477 CI->replaceAllUsesWith(ConstantInt::getTrue(M.getContext()));
2478 }
2479 CI->eraseFromParent();
2480 }
2481}
2482
2483static bool dropTypeTests(Module &M, bool ShouldDropAll) {
2484 Function *TypeTestFunc =
2485 Intrinsic::getDeclarationIfExists(&M, Intrinsic::type_test);
2486 if (TypeTestFunc)
2487 dropTypeTests(M, *TypeTestFunc, ShouldDropAll);
2488 // Only drop checked loads when dropping everything: in Assume mode a
2489 // checked load may feed a CFI trap check, which must keep diagnosing
2490 // loudly instead of being turned to true.
2491 bool DroppedCheckedLoads = false;
2492 if (ShouldDropAll) {
2493 if (Function *F =
2494 Intrinsic::getDeclarationIfExists(&M, Intrinsic::type_checked_load))
2495 DroppedCheckedLoads |=
2498 &M, Intrinsic::type_checked_load_relative))
2499 DroppedCheckedLoads |=
2501 }
2502 // Normally we'd have already removed all @llvm.public.type.test calls,
2503 // except for in the case where we originally were performing ThinLTO but
2504 // decided not to in the backend.
2505 Function *PublicTypeTestFunc =
2506 Intrinsic::getDeclarationIfExists(&M, Intrinsic::public_type_test);
2507 if (PublicTypeTestFunc)
2508 dropTypeTests(M, *PublicTypeTestFunc, ShouldDropAll);
2509 if (TypeTestFunc || PublicTypeTestFunc || DroppedCheckedLoads) {
2510 // We have deleted the type intrinsics, so we no longer have enough
2511 // information to reason about the liveness of virtual function pointers
2512 // in GlobalDCE.
2513 for (GlobalVariable &GV : M.globals())
2514 GV.eraseMetadata(LLVMContext::MD_vcall_visibility);
2515 return true;
2516 }
2517 return false;
2518}
2519
2520bool LowerTypeTestsModule::lower() {
2521 Function *TypeTestFunc =
2522 Intrinsic::getDeclarationIfExists(&M, Intrinsic::type_test);
2523
2524 // If only some of the modules were split, we cannot correctly perform
2525 // this transformation. We already checked for the presense of type tests
2526 // with partially split modules during the thin link, and would have emitted
2527 // an error if any were found, so here we can simply return.
2528 if ((ExportSummary && ExportSummary->partiallySplitLTOUnits()) ||
2529 (ImportSummary && ImportSummary->partiallySplitLTOUnits()))
2530 return false;
2531
2532 Function *ICallBranchFunnelFunc =
2533 Intrinsic::getDeclarationIfExists(&M, Intrinsic::icall_branch_funnel);
2534 if ((!TypeTestFunc || TypeTestFunc->use_empty()) &&
2535 (!ICallBranchFunnelFunc || ICallBranchFunnelFunc->use_empty()) &&
2536 !ExportSummary && !ImportSummary)
2537 return false;
2538
2539 if (ImportSummary) {
2540 if (TypeTestFunc)
2541 for (Use &U : llvm::make_early_inc_range(TypeTestFunc->uses()))
2542 importTypeTest(cast<CallInst>(U.getUser()));
2543
2544 if (ICallBranchFunnelFunc && !ICallBranchFunnelFunc->use_empty())
2546 "unexpected call to llvm.icall.branch.funnel during import phase");
2547
2548 // For internal linkage cfiFunction defs/decls, we only needed the alias
2549 // through the linker. We can replace those aliases with the aliased
2550 // function here.
2552 for (auto &A : llvm::make_early_inc_range(M.aliases())) {
2553 if (A.hasLocalLinkage())
2554 continue;
2555 if (ImportSummary->cfiFunctionDefs().contains(A.getName()) ||
2556 ImportSummary->cfiFunctionDecls().contains(A.getName())) {
2557 if (auto *F = dyn_cast_or_null<Function>(A.getAliaseeObject())) {
2558 if (F->hasExternalLinkage()) {
2559 // The original internal linkage function was independently promoted
2560 // by thinlink. While, pre-link, all static references to it
2561 // (implicitly, module-internal) were replaced with references to
2562 // the alias, thinlink might decide to promote it because (for
2563 // example) it turns out to be a hot indirect call target in a
2564 // different module.
2565 // In that case, we need to remember its thinlink-promoted name
2566 // because it's potentially referenced elsewhere, and make sure
2567 // there's an alias to it.
2568 PromotedFuncs.emplace_back(F, F->getName());
2569 } else {
2570 F->setLinkage(GlobalValue::ExternalLinkage);
2571 F->setVisibility(GlobalValue::HiddenVisibility);
2572 }
2573 A.replaceAllUsesWith(F);
2574 F->takeName(&A);
2575 A.eraseFromParent();
2576 }
2577 }
2578 }
2579
2582 for (auto &F : M) {
2583 // CFI functions are either external, or promoted. A local function may
2584 // have the same name, but it's not the one we are looking for.
2585 if (F.hasLocalLinkage())
2586 continue;
2587 if (ImportSummary->cfiFunctionDefs().contains(F.getName()))
2588 Defs.push_back(&F);
2589 else if (ImportSummary->cfiFunctionDecls().contains(F.getName()))
2590 Decls.push_back(&F);
2591 }
2592
2593 {
2594 ScopedSaveAliaseesAndUsed S(M);
2595 for (auto *F : Defs)
2596 importFunction(F, /*isJumpTableCanonical*/ true);
2597 for (auto *F : Decls)
2598 importFunction(F, /*isJumpTableCanonical*/ false);
2599 }
2600 // Add an alias with the thinlink promotion name.
2601 for (auto &[F, Name] : PromotedFuncs)
2602 GlobalAlias::create(GlobalValue::LinkageTypes::ExternalLinkage, Name, F);
2603
2604 return true;
2605 }
2606
2607 // Equivalence class set containing type identifiers and the globals that
2608 // reference them. This is used to partition the set of type identifiers in
2609 // the module into disjoint sets.
2610 using GlobalClassesTy = EquivalenceClasses<
2611 PointerUnion<GlobalTypeMember *, Metadata *, ICallBranchFunnel *>>;
2612 GlobalClassesTy GlobalClasses;
2613
2614 // Verify the type metadata and build a few data structures to let us
2615 // efficiently enumerate the type identifiers associated with a global:
2616 // a list of GlobalTypeMembers (a GlobalObject stored alongside a vector
2617 // of associated type metadata) and a mapping from type identifiers to their
2618 // list of GlobalTypeMembers and last observed index in the list of globals.
2619 // The indices will be used later to deterministically order the list of type
2620 // identifiers.
2622 struct TIInfo {
2623 unsigned UniqueId;
2624 std::vector<GlobalTypeMember *> RefGlobals;
2625 };
2626 DenseMap<Metadata *, TIInfo> TypeIdInfo;
2627 unsigned CurUniqueId = 0;
2629
2630 struct ExportedFunctionInfo {
2631 CfiFunctionLinkage Linkage;
2632 MDNode *FuncMD; // {name, linkage, type[, type...]}
2633 };
2634 MapVector<StringRef, ExportedFunctionInfo> ExportedFunctions;
2635 if (ExportSummary) {
2636 NamedMDNode *CfiFunctionsMD = M.getNamedMetadata("cfi.functions");
2637 if (CfiFunctionsMD) {
2638 // A set of all functions that are address taken by a live global object.
2639 DenseSet<GlobalValue::GUID> AddressTaken;
2640 for (auto &I : *ExportSummary)
2641 for (auto &GVS : I.second.getSummaryList())
2642 if (GVS->isLive())
2643 for (const auto &Ref : GVS->refs()) {
2644 AddressTaken.insert(Ref.getGUID());
2645 for (auto &RefGVS : Ref.getSummaryList())
2646 if (auto Alias = dyn_cast<AliasSummary>(RefGVS.get()))
2647 AddressTaken.insert(Alias->getAliaseeGUID());
2648 }
2650 if (AddressTaken.count(GUID))
2651 return true;
2652 auto VI = ExportSummary->getValueInfo(GUID);
2653 if (!VI)
2654 return false;
2655 for (auto &I : VI.getSummaryList())
2656 if (auto Alias = dyn_cast<AliasSummary>(I.get()))
2657 if (AddressTaken.count(Alias->getAliaseeGUID()))
2658 return true;
2659 return false;
2660 };
2661 for (auto *FuncMD : CfiFunctionsMD->operands()) {
2662 assert(FuncMD->getNumOperands() >= 2);
2663 StringRef FunctionName =
2664 cast<MDString>(FuncMD->getOperand(0))->getString();
2665 CfiFunctionLinkage Linkage = decodeCfiFunctionLinkage(
2666 cast<ConstantAsMetadata>(FuncMD->getOperand(1))
2667 ->getValue()
2668 ->getUniqueInteger()
2669 .getZExtValue());
2670 const GlobalValue::GUID GUID =
2671 cast<ConstantAsMetadata>(FuncMD->getOperand(2))
2672 ->getValue()
2673 ->getUniqueInteger()
2674 .getZExtValue();
2675 // Do not emit jumptable entries for functions that are not-live and
2676 // have no live references (and are not exported with cross-DSO CFI.)
2677 if (!ExportSummary->isGUIDLive(GUID))
2678 continue;
2679 if (!IsAddressTaken(GUID)) {
2680 if (!CrossDsoCfi || Linkage != CfiFunctionLinkage::Definition)
2681 continue;
2682
2683 bool Exported = false;
2684 if (auto VI = ExportSummary->getValueInfo(GUID))
2685 for (const auto &GVS : VI.getSummaryList())
2686 if (GVS->isLive() && !GlobalValue::isLocalLinkage(GVS->linkage()))
2687 Exported = true;
2688
2689 if (!Exported)
2690 continue;
2691 }
2692 auto P = ExportedFunctions.insert({FunctionName, {Linkage, FuncMD}});
2693 if (!P.second &&
2694 P.first->second.Linkage != CfiFunctionLinkage::Definition)
2695 P.first->second = {Linkage, FuncMD};
2696 }
2697
2698 for (const auto &P : ExportedFunctions) {
2699 StringRef FunctionName = P.first;
2700 CfiFunctionLinkage Linkage = P.second.Linkage;
2701 MDNode *FuncMD = P.second.FuncMD;
2702 Function *F = M.getFunction(FunctionName);
2703 if (F && F->hasLocalLinkage()) {
2704 // Locally defined function that happens to have the same name as a
2705 // function defined in a ThinLTO module. Rename it to move it out of
2706 // the way of the external reference that we're about to create.
2707 // Note that setName will find a unique name for the function, so even
2708 // if there is an existing function with the suffix there won't be a
2709 // name collision.
2710 F->setName(F->getName() + ".1");
2711 F = nullptr;
2712 }
2713
2714 if (!F) {
2716 FunctionType::get(Type::getVoidTy(M.getContext()), false),
2717 GlobalVariable::ExternalLinkage,
2718 M.getDataLayout().getProgramAddressSpace(), FunctionName, &M);
2719 F->setMetadata(
2720 LLVMContext::MD_guid,
2721 MDTuple::get(M.getContext(), {FuncMD->getOperand(2).get()}));
2722 if (ExportSummary) {
2725 ->getValue()
2726 ->getUniqueInteger()
2727 .getZExtValue();
2728 if (auto VI = ExportSummary->getValueInfo(GUID))
2729 F->setDSOLocal(
2730 VI.isDSOLocal(ExportSummary->withDSOLocalPropagation()));
2731 }
2732 }
2733 // If the function is available_externally, remove its definition so
2734 // that it is handled the same way as a declaration. Later we will try
2735 // to create an alias using this function's linkage, which will fail if
2736 // the linkage is available_externally. This will also result in us
2737 // following the code path below to replace the type metadata.
2738 if (F->hasAvailableExternallyLinkage()) {
2739 // Maintain !guid metadata.
2740 auto *OrigGUIDMD = F->getMetadata(LLVMContext::MD_guid);
2741 F->setLinkage(GlobalValue::ExternalLinkage);
2742 F->deleteBody();
2743 F->setComdat(nullptr);
2744 F->clearMetadata();
2745 F->setMetadata(LLVMContext::MD_guid, OrigGUIDMD);
2746 }
2747
2748 // Update the linkage for extern_weak declarations when a definition
2749 // exists.
2750 if (Linkage == CfiFunctionLinkage::Definition &&
2751 F->hasExternalWeakLinkage())
2752 F->setLinkage(GlobalValue::ExternalLinkage);
2753
2754 // If the function in the full LTO module is a declaration, replace its
2755 // type metadata with the type metadata we found in cfi.functions. That
2756 // metadata is presumed to be more accurate than the metadata attached
2757 // to the declaration.
2758 if (F->isDeclaration()) {
2759 if (Linkage == CfiFunctionLinkage::WeakDeclaration)
2761
2762 F->eraseMetadata(LLVMContext::MD_type);
2763 for (unsigned I = 3; I < FuncMD->getNumOperands(); ++I)
2764 F->addMetadata(LLVMContext::MD_type,
2765 *cast<MDNode>(FuncMD->getOperand(I).get()));
2766 }
2767 uint8_t Encoded = cast<ConstantAsMetadata>(FuncMD->getOperand(1))
2768 ->getValue()
2769 ->getUniqueInteger()
2770 .getZExtValue();
2771 // TODO: Implement for Full LTO.
2772 FunctionSummaryHotness[F] = decodeCfiFunctionHotness(Encoded);
2773 }
2774 }
2775 }
2776
2777 struct AliasToCreate {
2778 Function *Alias;
2779 std::string TargetName;
2780 };
2781 std::vector<AliasToCreate> AliasesToCreate;
2782
2783 // Parse alias data to replace stand-in function declarations for aliases
2784 // with an alias to the intended target.
2785 if (ExportSummary) {
2786 if (NamedMDNode *AliasesMD = M.getNamedMetadata("aliases")) {
2787 for (auto *AliasMD : AliasesMD->operands()) {
2789 for (MDString *MDS : make_isa_range<MDString>(AliasMD->operands())) {
2790 StringRef AliasName = MDS->getString();
2791 if (!ExportedFunctions.count(AliasName))
2792 continue;
2793 auto *AliasF = M.getFunction(AliasName);
2794 if (AliasF)
2795 Aliases.push_back(AliasF);
2796 }
2797
2798 if (Aliases.empty())
2799 continue;
2800
2801 for (unsigned I = 1; I != Aliases.size(); ++I) {
2802 auto *AliasF = Aliases[I];
2803 ExportedFunctions.erase(AliasF->getName());
2804 AliasesToCreate.push_back(
2805 {AliasF, std::string(Aliases[0]->getName())});
2806 }
2807 }
2808 }
2809 }
2810
2811 DenseMap<GlobalObject *, GlobalTypeMember *> GlobalTypeMembers;
2812 for (GlobalObject &GO : M.global_objects()) {
2814 continue;
2815
2816 Types.clear();
2817 GO.getMetadata(LLVMContext::MD_type, Types);
2818
2819 bool IsJumpTableCanonical = false;
2820 bool IsExported = false;
2821 if (Function *F = dyn_cast<Function>(&GO)) {
2822 IsJumpTableCanonical = isJumpTableCanonical(F);
2823 if (auto It = ExportedFunctions.find(F->getName());
2824 It != ExportedFunctions.end()) {
2825 IsJumpTableCanonical |=
2826 It->second.Linkage == CfiFunctionLinkage::Definition;
2827 IsExported = true;
2828 // TODO: The logic here checks only that the function is address taken,
2829 // not that the address takers are live. This can be updated to check
2830 // their liveness and emit fewer jumptable entries once monolithic LTO
2831 // builds also emit summaries.
2832 } else if (!F->hasAddressTaken()) {
2833 if (!CrossDsoCfi || !IsJumpTableCanonical || F->hasLocalLinkage())
2834 continue;
2835 }
2836
2837 // TODO: Pre-fill for full LTO.
2838 // if (!ExportSummary)
2839 // FunctionSummaryHotness[F] = getHotness(*F, PSI, BFIGetter);
2840 }
2841
2842 auto *GTM = GlobalTypeMember::create(Alloc, &GO, IsJumpTableCanonical,
2843 IsExported, Types);
2844 GlobalTypeMembers[&GO] = GTM;
2845 for (MDNode *Type : Types) {
2846 verifyTypeMDNode(&GO, Type);
2847 auto &Info = TypeIdInfo[Type->getOperand(1)];
2848 Info.UniqueId = ++CurUniqueId;
2849 Info.RefGlobals.push_back(GTM);
2850 }
2851 }
2852
2853 auto AddTypeIdUse = [&](Metadata *TypeId) -> TypeIdUserInfo & {
2854 // Add the call site to the list of call sites for this type identifier. We
2855 // also use TypeIdUsers to keep track of whether we have seen this type
2856 // identifier before. If we have, we don't need to re-add the referenced
2857 // globals to the equivalence class.
2858 auto Ins = TypeIdUsers.insert({TypeId, {}});
2859 if (Ins.second) {
2860 // Add the type identifier to the equivalence class.
2861 auto &GCI = GlobalClasses.insert(TypeId);
2862 GlobalClassesTy::member_iterator CurSet = GlobalClasses.findLeader(GCI);
2863
2864 // Add the referenced globals to the type identifier's equivalence class.
2865 for (GlobalTypeMember *GTM : TypeIdInfo[TypeId].RefGlobals)
2866 CurSet = GlobalClasses.unionSets(
2867 CurSet, GlobalClasses.findLeader(GlobalClasses.insert(GTM)));
2868 }
2869
2870 return Ins.first->second;
2871 };
2872
2873 if (TypeTestFunc) {
2874 for (const Use &U : TypeTestFunc->uses()) {
2875 auto CI = cast<CallInst>(U.getUser());
2876 // If this type test is only used by llvm.assume instructions, it
2877 // was used for whole program devirtualization, and is being kept
2878 // for use by other optimization passes. We do not need or want to
2879 // lower it here. We also don't want to rewrite any associated globals
2880 // unnecessarily. These will be removed by a subsequent LTT invocation
2881 // with the DropTypeTests flag set.
2882 bool OnlyAssumeUses = !CI->use_empty();
2883 for (const Use &CIU : CI->uses()) {
2884 if (isa<AssumeInst>(CIU.getUser()))
2885 continue;
2886 OnlyAssumeUses = false;
2887 break;
2888 }
2889 if (OnlyAssumeUses)
2890 continue;
2891
2892 auto TypeIdMDVal = dyn_cast<MetadataAsValue>(CI->getArgOperand(1));
2893 if (!TypeIdMDVal)
2894 report_fatal_error("Second argument of llvm.type.test must be metadata");
2895 auto TypeId = TypeIdMDVal->getMetadata();
2896 AddTypeIdUse(TypeId).CallSites.push_back(CI);
2897 }
2898 }
2899
2900 if (ICallBranchFunnelFunc) {
2901 for (const Use &U : ICallBranchFunnelFunc->uses()) {
2902 if (Arch != Triple::x86_64)
2904 "llvm.icall.branch.funnel not supported on this target");
2905
2906 auto CI = cast<CallInst>(U.getUser());
2907
2908 std::vector<GlobalTypeMember *> Targets;
2909 if (CI->arg_size() % 2 != 1)
2910 report_fatal_error("number of arguments should be odd");
2911
2912 GlobalClassesTy::member_iterator CurSet;
2913 for (unsigned I = 1; I != CI->arg_size(); I += 2) {
2914 int64_t Offset;
2916 CI->getOperand(I), Offset, M.getDataLayout()));
2917 if (!Base)
2919 "Expected branch funnel operand to be global value");
2920
2921 auto It = GlobalTypeMembers.find(Base);
2922 if (It == GlobalTypeMembers.end())
2923 reportFatalUsageError("Expected branch funnel operand to be a "
2924 "defined global value with type metadata");
2925 GlobalTypeMember *GTM = It->second;
2926 Targets.push_back(GTM);
2927 GlobalClassesTy::member_iterator NewSet =
2928 GlobalClasses.findLeader(GlobalClasses.insert(GTM));
2929 if (I == 1)
2930 CurSet = NewSet;
2931 else
2932 CurSet = GlobalClasses.unionSets(CurSet, NewSet);
2933 }
2934
2935 GlobalClasses.unionSets(
2936 CurSet, GlobalClasses.findLeader(
2937 GlobalClasses.insert(ICallBranchFunnel::create(
2938 Alloc, CI, Targets, ++CurUniqueId))));
2939 }
2940 }
2941
2942 if (ExportSummary) {
2943 DenseMap<GlobalValue::GUID, TinyPtrVector<Metadata *>> MetadataByGUID;
2944 for (auto &P : TypeIdInfo) {
2945 if (auto *TypeId = dyn_cast<MDString>(P.first))
2947 TypeId->getString())]
2948 .push_back(TypeId);
2949 }
2950
2951 for (auto &P : *ExportSummary) {
2952 for (auto &S : P.second.getSummaryList()) {
2953 if (!ExportSummary->isGlobalValueLive(S.get()))
2954 continue;
2955 if (auto *FS = dyn_cast<FunctionSummary>(S->getBaseObject()))
2956 for (GlobalValue::GUID G : FS->type_tests())
2957 for (Metadata *MD : MetadataByGUID[G])
2958 AddTypeIdUse(MD).IsExported = true;
2959 }
2960 }
2961 }
2962
2963 if (GlobalClasses.empty())
2964 return false;
2965
2966 {
2967 ScopedSaveAliaseesAndUsed S(M);
2968 // For each disjoint set we found...
2969 for (const auto &C : GlobalClasses) {
2970 if (!C->isLeader())
2971 continue;
2972
2973 ++NumTypeIdDisjointSets;
2974 // Build the list of type identifiers in this disjoint set.
2975 std::vector<Metadata *> TypeIds;
2976 std::vector<GlobalTypeMember *> Globals;
2977 std::vector<ICallBranchFunnel *> ICallBranchFunnels;
2978 for (auto M : GlobalClasses.members(*C)) {
2979 if (isa<Metadata *>(M))
2980 TypeIds.push_back(cast<Metadata *>(M));
2981 else if (isa<GlobalTypeMember *>(M))
2982 Globals.push_back(cast<GlobalTypeMember *>(M));
2983 else
2984 ICallBranchFunnels.push_back(cast<ICallBranchFunnel *>(M));
2985 }
2986
2987 // Order type identifiers by unique ID for determinism. This ordering is
2988 // stable as there is a one-to-one mapping between metadata and unique
2989 // IDs.
2990 llvm::sort(TypeIds, [&](Metadata *M1, Metadata *M2) {
2991 return TypeIdInfo[M1].UniqueId < TypeIdInfo[M2].UniqueId;
2992 });
2993
2994 // Same for the branch funnels.
2995 llvm::sort(ICallBranchFunnels,
2996 [&](ICallBranchFunnel *F1, ICallBranchFunnel *F2) {
2997 return F1->UniqueId < F2->UniqueId;
2998 });
2999
3000 // Build bitsets for this disjoint set.
3001 buildBitSetsFromDisjointSet(TypeIds, Globals, ICallBranchFunnels);
3002 }
3003 }
3004
3005 allocateByteArrays();
3006
3007 for (auto A : AliasesToCreate) {
3008 auto *Target = M.getNamedValue(A.TargetName);
3009 if (!isa<GlobalAlias>(Target))
3010 continue;
3011 auto *AliasGA = GlobalAlias::create("", Target);
3012 AliasGA->setVisibility(A.Alias->getVisibility());
3013 AliasGA->setLinkage(A.Alias->getLinkage());
3014 AliasGA->setDSOLocal(A.Alias->isDSOLocal());
3015 AliasGA->takeName(A.Alias);
3016 A.Alias->replaceAllUsesWith(AliasGA);
3017 A.Alias->eraseFromParent();
3018 }
3019
3020 // Emit .symver directives for exported functions, if they exist.
3021 if (ExportSummary) {
3022 if (NamedMDNode *SymversMD = M.getNamedMetadata("symvers")) {
3023 for (auto *Symver : SymversMD->operands()) {
3024 assert(Symver->getNumOperands() >= 2);
3025 StringRef SymbolName =
3026 cast<MDString>(Symver->getOperand(0))->getString();
3027 StringRef Alias = cast<MDString>(Symver->getOperand(1))->getString();
3028
3029 if (!ExportedFunctions.count(SymbolName))
3030 continue;
3031
3032 M.appendModuleInlineAsm(
3033 (llvm::Twine(".symver ") + SymbolName + ", " + Alias).str());
3034 }
3035 }
3036 }
3037
3038 return true;
3039}
3040
3043 bool Changed;
3044 if (UseCommandLine)
3045 Changed = LowerTypeTestsModule::runForTesting(M, AM);
3046 else
3047 Changed = LowerTypeTestsModule(M, AM, ExportSummary, ImportSummary).lower();
3048 if (!Changed)
3049 return PreservedAnalyses::all();
3050 return PreservedAnalyses::none();
3051}
3052
3054 raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {
3055 static_cast<PassInfoMixin<DropTypeTestsPass> *>(this)->printPipeline(
3056 OS, MapClassName2PassName);
3057 OS << '<';
3058 switch (Kind) {
3059 case DropTestKind::Assume:
3060 OS << "assume";
3061 break;
3062 case DropTestKind::All:
3063 OS << "all";
3064 break;
3065 }
3066 OS << '>';
3067}
3068
3073
3076 bool Changed = false;
3077 // Figure out whether inlining has exposed a constant address to a lowered
3078 // type test, and remove the test if so and the address is known to pass the
3079 // test. Unfortunately this pass ends up needing to reverse engineer what
3080 // LowerTypeTests did; this is currently inherent to the design of ThinLTO
3081 // importing where LowerTypeTests needs to run at the start.
3082 //
3083 // We look for things like:
3084 //
3085 // sub (i64 ptrtoint (ptr @_Z2fpv to i64), i64 ptrtoint (ptr
3086 // @__typeid__ZTSFvvE_global_addr to i64))
3087 //
3088 // which gets replaced with 0 if _Z2fpv (more specifically _Z2fpv.cfi, the
3089 // function referred to by the jump table) is a member of the type _ZTSFvv, as
3090 // well as things like
3091 //
3092 // icmp eq ptr @_Z2fpv, @__typeid__ZTSFvvE_global_addr
3093 //
3094 // which gets replaced with true if _Z2fpv is a member.
3095 for (auto &GV : M.globals()) {
3096 if (!GV.getName().starts_with("__typeid_") ||
3097 !GV.getName().ends_with("_global_addr"))
3098 continue;
3099 // __typeid_foo_global_addr -> foo
3100 auto *MD = MDString::get(M.getContext(),
3101 GV.getName().substr(9, GV.getName().size() - 21));
3102 auto MaySimplifyPtr = [&](Value *Ptr) {
3103 if (auto *GV = dyn_cast<GlobalValue>(Ptr))
3104 if (auto *CFIGV = M.getNamedValue((GV->getName() + ".cfi").str()))
3105 Ptr = CFIGV;
3106 return isKnownTypeIdMember(MD, M.getDataLayout(), Ptr, 0);
3107 };
3108 auto MaySimplifyInt = [&](Value *Op) {
3109 auto *PtrAsInt = dyn_cast<ConstantExpr>(Op);
3110 if (!PtrAsInt || PtrAsInt->getOpcode() != Instruction::PtrToInt)
3111 return false;
3112 return MaySimplifyPtr(PtrAsInt->getOperand(0));
3113 };
3114 for (User *U : make_early_inc_range(GV.users())) {
3115 if (auto *CI = dyn_cast<ICmpInst>(U)) {
3116 if (CI->getPredicate() == CmpInst::ICMP_EQ &&
3117 MaySimplifyPtr(CI->getOperand(0))) {
3118 // This is an equality comparison (TypeTestResolution::Single case in
3119 // lowerTypeTestCall). In this case we just replace the comparison
3120 // with true.
3121 CI->replaceAllUsesWith(ConstantInt::getTrue(M.getContext()));
3122 CI->eraseFromParent();
3123 Changed = true;
3124 continue;
3125 }
3126 }
3127 auto *CE = dyn_cast<ConstantExpr>(U);
3128 if (!CE || CE->getOpcode() != Instruction::PtrToInt)
3129 continue;
3130 for (Use &U : make_early_inc_range(CE->uses())) {
3131 auto *CE = dyn_cast<ConstantExpr>(U.getUser());
3132 if (U.getOperandNo() == 0 && CE &&
3133 CE->getOpcode() == Instruction::Sub &&
3134 MaySimplifyInt(CE->getOperand(1))) {
3135 // This is a computation of PtrOffset as generated by
3136 // LowerTypeTestsModule::lowerTypeTestCall above. If
3137 // isKnownTypeIdMember passes we just pretend it evaluated to 0. This
3138 // should cause later passes to remove the range and alignment checks.
3139 // The bitset checks won't be removed but those are uncommon.
3140 CE->replaceAllUsesWith(ConstantInt::get(CE->getType(), 0));
3141 Changed = true;
3142 }
3143 auto *CI = dyn_cast<ICmpInst>(U.getUser());
3144 if (U.getOperandNo() == 1 && CI &&
3145 CI->getPredicate() == CmpInst::ICMP_EQ &&
3146 MaySimplifyInt(CI->getOperand(0))) {
3147 // This is an equality comparison. Unlike in the case above it
3148 // remained as an integer compare.
3149 CI->replaceAllUsesWith(ConstantInt::getTrue(M.getContext()));
3150 CI->eraseFromParent();
3151 Changed = true;
3152 }
3153 }
3154 }
3155 }
3156
3157 if (!Changed)
3158 return PreservedAnalyses::all();
3162 PA.preserve<LoopAnalysis>();
3163 return PA;
3164}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the StringMap class.
uint64_t uint64_t
AMDGPU Register Bank Select
This file implements a class to represent arbitrary precision integral constant values and operations...
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
This file defines the BumpPtrAllocator interface.
This file contains the simple types necessary to represent the attributes associated with functions a...
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
This file contains the declarations for the subclasses of Constant, which represent the different fla...
DXIL Finalize Linkage
dxil translate DXIL Translate Metadata
This file defines the DenseMap class.
Generic implementation of equivalence classes through the use Tarjan's efficient union-find algorithm...
This file provides a collection of function (or more generally, callable) type erasure utilities supp...
#define DEBUG_TYPE
Hexagon Common GEP
Module.h This file contains the declarations for the Module class.
This header defines various interfaces for pass management in LLVM.
This defines the Use class.
static const unsigned kARMJumpTableEntrySize
static cl::opt< bool > ReorderCfiJumpTablesProfiles("reorder-cfi-jump-tables-profiles", cl::init(true), cl::Hidden, cl::desc("Reorder CFI jump tables using profile information"))
static const unsigned kLOONGARCH64JumpTableEntrySize
static cl::opt< std::string > ClReadSummary("lowertypetests-read-summary", cl::desc("Read summary from given textual assembly or YAML " "file before running pass"), cl::Hidden)
static bool isKnownTypeIdMember(Metadata *TypeId, const DataLayout &DL, Value *V, uint64_t COffset)
static const unsigned kX86IBTJumpTableEntrySize
static SmallVector< DILocation * > createJumpTableDebugInfo(Function *F, ArrayRef< GlobalTypeMember * > Functions)
static ConstantInt * extractNumericTypeId(MDNode &MD)
Extracts a numeric type identifier from an MDNode containing type metadata.
static const unsigned kRISCVJumpTableEntrySize
static auto buildBitSets(ArrayRef< Metadata * > TypeIds, const DenseMap< GlobalTypeMember *, uint64_t > &GlobalLayout)
static void dropTypeTests(Module &M, Function &TypeTestFunc, bool ShouldDropAll)
static Value * createMaskedBitTest(IRBuilder<> &B, Value *Bits, Value *BitOffset)
Build a test that bit BitOffset mod sizeof(Bits)*8 is set in Bits.
static bool isThumbFunction(Function *F, Triple::ArchType ModuleArch)
static const unsigned kX86JumpTableEntrySize
static void createCfiSymversMetadata(Module &DestM, const Module &SrcM)
static cl::opt< bool > AvoidReuse("lowertypetests-avoid-reuse", cl::desc("Try to avoid reuse of byte array addresses using aliases"), cl::Hidden, cl::init(true))
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 const unsigned kARMBTIJumpTableEntrySize
static cl::opt< bool > EnableJumpTableDebugInfo("lowertypetests-jump-table-debug-info", cl::init(true), cl::Hidden, cl::desc("Enable debug info generation for jump tables"))
static CfiFunctionLinkage decodeCfiFunctionLinkage(uint8_t Encoded)
static void createCfiFunctionsMetadata(Module &DestM, ArrayRef< GlobalValue * > CfiFunctions, ProfileSummaryInfo &PSI, function_ref< const BlockFrequencyInfo &(Function &)> BFIGetter)
static cl::opt< std::string > ClWriteSummary("lowertypetests-write-summary", cl::desc("Write summary to given YAML file after running pass"), cl::Hidden)
static BitSetInfo buildBitSet(ArrayRef< uint64_t > Offsets)
Build a bit set for list of offsets.
static const unsigned kARMv6MJumpTableEntrySize
static uint8_t encodeCfiFunctionLinkage(CfiFunctionLinkage Linkage, CfiFunctionHotness Hotness)
static CfiFunctionHotness decodeCfiFunctionHotness(uint8_t Encoded)
static const unsigned kHexagonJumpTableEntrySize
static void createCfiAliasesMetadata(Module &DestM, const Module &SrcM)
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
#define G(x, y, z)
Definition MD5.cpp:55
Machine Check Debug Module
This file implements a map that provides insertion order iteration.
This file contains the declarations for metadata subclasses.
#define T
ModuleSummaryIndex.h This file contains the declarations the classes that hold the module index and s...
#define P(N)
FunctionAnalysisManager FAM
This file defines the PointerUnion class, which is a discriminated union of pointer types.
This file contains the declarations for profiling metadata utility functions.
static StringRef getName(Value *V)
This file contains some templates that are useful if you are working with the STL at all.
This file implements a set that has insertion order iteration characteristics.
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:171
#define LLVM_DEBUG(...)
Definition Debug.h:119
This pass exposes codegen information to IR-level passes.
This header defines support for implementing classes that have some trailing object (or arrays of obj...
static bool isDirectCall(const MCInst &Inst)
Class for arbitrary precision integers.
Definition APInt.h:78
uint64_t getZExtValue() const
Get zero extended value.
Definition APInt.h:1560
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
size_t size() const
Get the array size.
Definition ArrayRef.h:141
bool empty() const
Check if the array is empty.
Definition ArrayRef.h:136
static LLVM_ABI ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
Functions, function parameters, and return types can have attributes to indicate how they should be t...
Definition Attributes.h:106
LLVM_ABI StringRef getValueAsString() const
Return the attribute's value as a string.
bool isValid() const
Return true if the attribute is any kind of attribute.
Definition Attributes.h:262
LLVM_ABI BasicBlock * splitBasicBlock(iterator I, const Twine &BBName="")
Split the basic block into two basic blocks at the specified instruction.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Definition BasicBlock.h:206
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
Definition BasicBlock.h:237
BlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate IR basic block frequen...
Value * getArgOperand(unsigned i) const
unsigned arg_size() const
void addSymbolWithThinLTOGUID(StringRef Name, GlobalValue::GUID GUID)
Add the function name and the GUID that ThinLTO uses for it.
bool contains(StringRef Name) const
@ ICMP_NE
not equal
Definition InstrTypes.h:762
static CondBrInst * Create(Value *Cond, BasicBlock *IfTrue, BasicBlock *IfFalse, InsertPosition InsertBefore=nullptr)
static LLVM_ABI ConstantAggregateZero * get(Type *Ty)
ConstantArray - Constant Array Declarations.
Definition Constants.h:590
static ConstantAsMetadata * get(Constant *C)
Definition Metadata.h:548
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:878
static LLVM_ABI Constant * getIntToPtr(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static LLVM_ABI Constant * getPointerCast(Constant *C, Type *Ty)
Create a BitCast, AddrSpaceCast, or a PtrToInt cast constant expression.
static LLVM_SUPPRESS_DEPRECATED_DECLARATIONS_POP Constant * getInBoundsPtrAdd(Constant *Ptr, Constant *Offset)
Create a getelementptr inbounds i8, ptr, offset constant expression.
Definition Constants.h:1550
static Constant * getPtrAdd(Constant *Ptr, Constant *Offset, GEPNoWrapFlags NW=GEPNoWrapFlags::none(), std::optional< ConstantRange > InRange=std::nullopt, Type *OnlyIfReduced=nullptr)
Create a getelementptr i8, ptr, offset constant expression.
Definition Constants.h:1518
static LLVM_ABI Constant * getPtrToInt(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static LLVM_SUPPRESS_DEPRECATED_DECLARATIONS_PUSH 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:1477
This is the shared class of boolean and integer constants.
Definition Constants.h:87
static LLVM_ABI ConstantInt * getTrue(LLVMContext &Context)
static LLVM_ABI ConstantInt * getFalse(LLVMContext &Context)
static LLVM_ABI ConstantPointerNull * get(PointerType *T)
Static factory methods - Return objects of the specified value.
static Constant * getAnon(ArrayRef< Constant * > V, bool Packed=false)
Return an anonymous struct that has the specified elements.
Definition Constants.h:643
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
LLVM_ABI void finalize()
Construct any deferred debug info descriptors.
Definition DIBuilder.cpp:73
LLVM_ABI DISubroutineType * createSubroutineType(DITypeArray ParameterTypes, DINode::DIFlags Flags=DINode::FlagZero, unsigned CC=0)
Create subroutine type.
LLVM_ABI DISubprogram * createFunction(DIScope *Scope, StringRef Name, StringRef LinkageName, DIFile *File, unsigned LineNo, DISubroutineType *Ty, unsigned ScopeLine, DINode::DIFlags Flags=DINode::FlagZero, DISubprogram::DISPFlags SPFlags=DISubprogram::SPFlagZero, DITemplateParameterArray TParams=nullptr, DISubprogram *Decl=nullptr, DITypeArray ThrownTypes=nullptr, DINodeArray Annotations=nullptr, StringRef TargetFuncName="", bool UseKeyInstructions=false)
Create a new descriptor for the specified subprogram.
LLVM_ABI DICompileUnit * createCompileUnit(DISourceLanguageName Lang, DIFile *File, StringRef Producer, bool isOptimized, StringRef Flags, unsigned RV, StringRef SplitName=StringRef(), DICompileUnit::DebugEmissionKind Kind=DICompileUnit::DebugEmissionKind::FullDebug, uint64_t DWOId=0, bool SplitDebugInlining=true, bool DebugInfoForProfiling=false, DICompileUnit::DebugNameTableKind NameTableKind=DICompileUnit::DebugNameTableKind::Default, bool RangesBaseAddress=false, StringRef SysRoot={}, StringRef SDK={})
A CompileUnit provides an anchor for all debugging information generated during this instance of comp...
LLVM_ABI DIFile * createFile(StringRef Filename, StringRef Directory, std::optional< DIFile::ChecksumInfo< StringRef > > Checksum=std::nullopt, std::optional< StringRef > Source=std::nullopt)
Create a file descriptor to hold debugging information for a file.
Wrapper structure that holds source language identity metadata that includes language name,...
Subprogram description. Uses SubclassData1.
Type array for a subprogram.
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
bool empty() const
Definition DenseMap.h:716
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:766
iterator end()
Definition DenseMap.h:686
ValueT lookup(const_arg_type_t< KeyT > Val) const
Return the entry for the specified key, or a default constructed value if no such entry exists.
Definition DenseMap.h:793
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition DenseMap.h:827
Analysis pass which computes a DominatorTree.
Definition Dominators.h:241
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
LLVM_ABI void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
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:169
const BasicBlock & getEntryBlock() const
Definition Function.h:794
void eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing module and deletes it.
Definition Function.cpp:451
static GEPNoWrapFlags inBounds()
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:692
LLVM_ABI void setMetadata(unsigned KindID, MDNode *Node)
Set a particular kind of metadata attachment.
bool hasMetadata() const
Return true if this GlobalObject has any metadata attached to it.
LLVM_ABI void setComdat(Comdat *C)
Definition Globals.cpp:287
LLVM_ABI void setSection(StringRef S)
Change the section for this global.
Definition Globals.cpp:348
const Comdat * getComdat() const
LLVM_ABI bool eraseMetadata(unsigned KindID)
Erase all metadata attachments with the given kind.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this GlobalObject.
bool hasSection() const
Check if this global has a custom object file section.
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:80
bool isDSOLocal() const
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
VisibilityTypes getVisibility() const
static bool isLocalLinkage(LinkageTypes Linkage)
LinkageTypes getLinkage() const
uint64_t GUID
Declare a type to represent a global unique identifier for a global value.
bool isDeclarationForLinker() const
void setDSOLocal(bool Local)
PointerType * getType() const
Global values are always pointers.
VisibilityTypes
An enumeration for the kinds of visibility of global values.
Definition GlobalValue.h:67
@ HiddenVisibility
The GV is hidden.
Definition GlobalValue.h:69
void setVisibility(VisibilityTypes V)
LinkageTypes
An enumeration for the kinds of linkage for global values.
Definition GlobalValue.h:52
@ 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
@ ExternalWeakLinkage
ExternalWeak linkage description.
Definition GlobalValue.h:62
Type * getValueType() const
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
LLVM_ABI void setInitializer(Constant *InitVal)
setInitializer - Sets the initializer for this global variable, removing any existing initializer if ...
Definition Globals.cpp:613
bool hasInitializer() const
Definitions have initializers, declarations don't.
MaybeAlign getAlign() const
Returns the alignment of the given variable.
void setConstant(bool Val)
LLVM_ABI void setCodeModel(CodeModel::Model CM)
Change the code model for this global.
Definition Globals.cpp:660
LLVM_ABI void eraseFromParent()
eraseFromParent - This method unlinks 'this' from the containing module and deletes it.
Definition Globals.cpp:609
LLVM_ABI CallInst * CreateIntrinsicWithoutFolding(Intrinsic::ID ID, ArrayRef< Type * > OverloadTypes, ArrayRef< Value * > Args, FMFSource FMFSource={}, const Twine &Name="", ArrayRef< OperandBundleDef > OpBundles={})
Create a call to intrinsic ID with Args, mangled using OverloadTypes.
Value * CreateInsertValue(Value *Agg, Value *Val, ArrayRef< unsigned > Idxs, const Twine &Name="")
Definition IRBuilder.h:2723
Value * CreatePtrAdd(Value *Ptr, Value *Offset, const Twine &Name="", GEPNoWrapFlags NW=GEPNoWrapFlags::none())
Definition IRBuilder.h:2092
LoadInst * CreateLoad(Type *Ty, Value *Ptr, const char *Name)
Provided to resolve 'CreateLoad(Ty, Ptr, "...")' correctly, instead of converting the string to 'bool...
Definition IRBuilder.h:1907
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2909
static LLVM_ABI InlineAsm * get(FunctionType *Ty, StringRef AsmString, StringRef Constraints, bool hasSideEffects, bool isAlignStack=false, AsmDialect asmDialect=AD_ATT, bool canThrow=false)
InlineAsm::get - Return the specified uniqued inline asm string.
Definition InlineAsm.cpp:43
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
iterator_range< user_iterator > users()
LLVM_ABI void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
user_iterator user_begin()
Analysis pass that exposes the LoopInfo for a function.
Definition LoopInfo.h:594
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
Metadata node.
Definition Metadata.h:1081
const MDOperand & getOperand(unsigned I) const
Definition Metadata.h:1437
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition Metadata.h:1579
unsigned getNumOperands() const
Return number of MDNode operands.
Definition Metadata.h:1443
Metadata * get() const
Definition Metadata.h:931
static LLVM_ABI MDString * get(LLVMContext &Context, StringRef Str)
Definition Metadata.cpp:597
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition Metadata.h:1525
This class implements a map that also provides access to all stored values in a deterministic order.
Definition MapVector.h:38
bool empty() const
Definition MapVector.h:79
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition MapVector.h:126
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,...
Root of the metadata hierarchy.
Definition Metadata.h:64
TypeIdSummary & getOrInsertTypeIdSummary(StringRef TypeId)
Return an existing or new TypeIdSummary entry for TypeId.
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 ...
CfiFunctionIndex & cfiFunctionDecls()
CfiFunctionIndex & cfiFunctionDefs()
static LLVM_ABI void CollectAsmSymvers(const Module &M, function_ref< void(StringRef, StringRef)> AsmSymver)
Parse inline ASM and collect the symvers directives that are defined in the current module.
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
LLVMContext & getContext() const
Get the global data context.
Definition Module.h:332
Function * getFunction(StringRef Name) const
Look up the specified function in the module symbol table.
Definition Module.cpp:235
iterator_range< alias_iterator > aliases()
Definition Module.h:853
NamedMDNode * getOrInsertNamedMetadata(StringRef Name)
Return the named MDNode in the module with the specified name.
Definition Module.cpp:308
A tuple of MDNodes.
Definition Metadata.h:1797
iterator_range< op_iterator > operands()
Definition Metadata.h:1893
LLVM_ABI void addOperand(MDNode *M)
static PointerType * getUnqual(LLVMContext &C)
This constructs an opaque pointer to an object in the default address space (address space zero).
unsigned getAddressSpace() const
Return the address space of the Pointer type.
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
Analysis pass which computes a PostDominatorTree.
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
PreservedAnalyses & preserve()
Mark an analysis as preserved.
Definition Analysis.h:132
Analysis providing profile information.
bool isFunctionColdInCallGraph(const FuncT *F, BFIT &BFI) const
Returns true if F contains only cold code.
LLVM_ABI bool isFunctionHotnessUnknown(const Function &F) const
Returns true if the hotness of F is unknown.
bool isFunctionHotInCallGraph(const FuncT *F, BFIT &BFI) const
Returns true if F contains hot code.
LLVM_ABI bool hasPartialSampleProfile() const
Returns true if module M has partial-profile sample profile.
static ReturnInst * Create(LLVMContext &C, Value *retVal=nullptr, InsertPosition InsertBefore=nullptr)
LLVM_ABI void print(const char *ProgName, raw_ostream &S, bool ShowColors=true, bool ShowKindLabel=true, bool ShowLocation=true) const
A vector that has set insertion semantics.
Definition SetVector.h:57
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition SetVector.h:157
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
reference emplace_back(ArgTypes &&... Args)
void reserve(size_type N)
iterator erase(const_iterator CI)
void resize(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition StringRef.h:736
bool consume_back(StringRef Suffix)
Returns true if this StringRef has the given suffix and removes that suffix.
Definition StringRef.h:691
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition StringRef.h:597
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition StringRef.h:258
constexpr size_t size() const
Get the string size.
Definition StringRef.h:144
bool ends_with(StringRef Suffix) const
Check if this string ends with the given Suffix.
Definition StringRef.h:270
Type * getElementType(unsigned N) const
Analysis pass providing the TargetTransformInfo.
See the file comment for details on the usage of the TrailingObjects type.
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
@ loongarch64
Definition Triple.h:66
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
Definition Type.cpp:300
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
Definition Type.cpp:272
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
Definition Type.cpp:297
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
op_range operands()
Definition User.h:267
Value * getOperand(unsigned i) const
Definition User.h:207
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
bool hasOneUse() const
Return true if there is exactly one use of this value.
Definition Value.h:441
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition Value.cpp:549
iterator_range< user_iterator > users()
Definition Value.h:428
use_iterator use_begin()
Definition Value.h:366
bool use_empty() const
Definition Value.h:348
LLVM_ABI bool replaceUsesWithIf(Value *New, llvm::function_ref< bool(Use &U)> ShouldReplace)
Go through the uses list for this definition and make each use point to "V" if the callback ShouldRep...
Definition Value.cpp:557
iterator_range< use_iterator > uses()
Definition Value.h:382
bool hasName() const
Definition Value.h:263
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:315
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
Definition Value.cpp:396
std::pair< iterator, bool > insert(const ValueT &V)
Definition DenseSet.h:209
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
Definition DenseSet.h:182
void insert_range(Range &&R)
Definition DenseSet.h:235
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:187
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:123
NodeTy * getNextNode()
Get the next node, or nullptr for the list tail.
Definition ilist_node.h:348
This class implements a layout algorithm for globals referenced by bit sets that tries to keep member...
LLVM_ABI const std::vector< uint64_t > & build()
Flatten fragments into a single layout and return it.
LLVM_ABI void addFragment(const std::set< uint64_t > &F)
Add F to the layout while trying to keep its indices contiguous.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
CallInst * Call
Changed
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char SymbolName[]
Key for Kernel::Metadata::mSymbolName.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:83
LLVM_ABI Function * getDeclarationIfExists(const Module *M, ID id)
Look up the Function declaration of the intrinsic id in the Module M and return it if it exists.
ValuesClass values(OptsTy... Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
initializer< Ty > init(const Ty &Val)
LLVM_ABI SetVector< uint64_t > findCfiTypeIds(const Module &M)
Finds all 64-bit numeric type identifiers in M used for cross-DSO CFI.
LLVM_ABI bool cleanUpTypeCheckedLoad(Module &M, Function &CheckedLoadFn, bool IsRelative)
Lower @llvm.type.checked.load[.relative] calls to the guarded load with the check assumed true,...
LLVM_ABI void createCfiMetadata(Module &DestM, const Module &SrcM, ArrayRef< GlobalValue * > CfiFunctions, ProfileSummaryInfo &PSI, function_ref< const BlockFrequencyInfo &(Function &)> BFIGetter)
Creates cfi.functions, aliases, and symvers named metadata in DestM for CFI functions in CfiFunctions...
LLVM_ABI bool isJumpTableCanonical(Function *F)
LLVM_ABI bool hasTypeMetadata(const GlobalObject &GO)
Returns whether a global or its associated global has attached type metadata.
LLVM_ABI SetVector< GlobalValue * > findCfiFunctions(Module &M)
Finds all functions and aliases in M that may need CFI jump table entries.
std::enable_if_t< detail::IsValidPointer< X, Y >::value, X * > extract_or_null(Y &&MD)
Extract a Value from Metadata, allowing null.
Definition Metadata.h:694
SmallVector< unsigned char, 0 > ByteArray
Definition PropertySet.h:25
NodeAddr< PhiNode * > Phi
Definition RDFGraph.h:390
NodeAddr< UseNode * > Use
Definition RDFGraph.h:385
@ OF_TextWithCRLF
The file should be opened in text mode and use a carriage linefeed '\r '.
Definition FileSystem.h:802
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI void ReplaceInstWithInst(BasicBlock *BB, BasicBlock::iterator &BI, Instruction *I)
Replace the instruction specified by BI with the instruction specified by I.
@ Offset
Definition DWP.cpp:577
bool operator<(int64_t V1, const APSInt &V2)
Definition APSInt.h:360
void stable_sort(R &&Range)
Definition STLExtras.h:2132
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1755
detail::zip_longest_range< T, U, Args... > zip_longest(T &&t, U &&u, Args &&... args)
Iterate over two or more iterators at the same time.
Definition STLExtras.h:997
@ Unknown
Not known to have no common set bits.
LLVM_ABI void setExplicitlyUnknownBranchWeightsIfProfiled(Instruction &I, StringRef PassName, const Function *F=nullptr)
Like setExplicitlyUnknownBranchWeights(...), but only sets unknown branch weights in the new instruct...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
@ Load
The value being inserted comes from a load (InsertElement only).
@ Export
Export information to summary.
Definition IPO.h:40
@ None
Do nothing.
Definition IPO.h:38
@ Import
Import information from summary.
Definition IPO.h:39
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition STLExtras.h:2224
Value * GetPointerBaseWithConstantOffset(Value *Ptr, int64_t &Offset, const DataLayout &DL, bool AllowNonInbounds=true)
Analyze the specified pointer to see if it can be expressed as a base pointer plus a constant offset.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition STLExtras.h:649
InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy
Provide the FunctionAnalysisManager to Module proxy.
@ O1
Optimize quickly without destroying debuggability.
@ O2
Optimize for fast execution as much as possible without triggering significant incremental compile ti...
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
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:204
unsigned M1(unsigned Val)
Definition VE.h:377
auto make_isa_range(RangeT &&Range)
Return a range over Range containing only elements for which isa<T> holds, casting each of them to T.
Definition STLExtras.h:567
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
LLVM_ABI bool convertUsersOfConstantsToInstructions(ArrayRef< Constant * > Consts, Function *RestrictToFunc=nullptr, bool RemoveDeadConstants=true, bool IncludeSelf=false)
Replace constant expressions users of the given constants with instructions.
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1652
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
IRBuilder(LLVMContext &, FolderTy, InserterTy) -> IRBuilder< FolderTy, InserterTy >
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:149
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
LLVM_ABI raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
@ Ref
The access may reference the value stored in memory.
Definition ModRef.h:32
@ Other
Any other memory.
Definition ModRef.h:68
TargetTransformInfo TTI
LLVM_ABI void appendToCompilerUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.compiler.used list.
IntPtrTy
Definition InstrProf.h:82
DWARFExpression::Operation Op
Expected< T > errorOrToExpected(ErrorOr< T > &&EO)
Convert an ErrorOr<T> to an Expected<T>.
Definition Error.h:1261
ArrayRef(const T &OneElt) -> ArrayRef< T >
OutputIt copy(R &&Range, OutputIt Out)
Definition STLExtras.h:1901
constexpr unsigned BitWidth
LLVM_ABI void appendToGlobalCtors(Module &M, Function *F, int Priority, Constant *Data=nullptr)
Append F to the list of global ctors of module M with the given Priority.
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
Definition STLExtras.h:2208
LLVM_ABI Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
Definition Error.cpp:107
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 ...
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
Definition Allocator.h:391
LLVM_ABI void appendToUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.used list.
LLVM_ABI std::unique_ptr< ModuleSummaryIndex > parseSummaryIndexAssembly(MemoryBufferRef F, SMDiagnostic &Err)
Parse LLVM Assembly for summary index from a MemoryBuffer.
Definition Parser.cpp:168
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Definition MIRParser.h:39
constexpr uint64_t NextPowerOf2(uint64_t A)
Returns the next power of two (in 64-bits) that is strictly greater than A.
Definition MathExtras.h:368
LLVM_ABI GlobalVariable * collectUsedGlobalVariables(const Module &M, SmallVectorImpl< GlobalValue * > &Vec, bool CompilerUsed)
Given "llvm.used" or "llvm.compiler.used" as a global name, collect the initializer elements of that ...
Definition Module.cpp:951
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
Definition Error.cpp:177
TypeTestResolution TTRes
Kind
Specifies which kind of type check we should emit for this byte array.
@ Unknown
Unknown (analysis not performed, don't lower)
@ Single
Single element (last example in "Short Inline Bit Vectors")
@ Inline
Inlined bit vector ("Short Inline Bit Vectors")
@ Unsat
Unsatisfiable type (i.e. no global has this type metadata)
@ AllOnes
All-ones bit vector ("Eliminating Bit Vector Checks for All-Ones Bit Vectors")
@ ByteArray
Test a byte array (first example)
unsigned SizeM1BitWidth
Range of size-1 expressed as a bit width.
enum llvm::TypeTestResolution::Kind TheKind
SmallVector< uint64_t, 16 > Offsets
LLVM_ABI bool containsGlobalOffset(uint64_t Offset) const
LLVM_ABI void print(raw_ostream &OS) const
This class is used to build a byte array containing overlapping bit sets.
uint64_t BitAllocs[BitsPerByte]
The number of bytes allocated so far for each of the bits.
std::vector< uint8_t > Bytes
The byte array built so far.
LLVM_ABI void allocate(const std::set< uint64_t > &Bits, uint64_t BitSize, uint64_t &AllocByteOffset, uint8_t &AllocMask)
Allocate BitSize bits in the byte array where Bits contains the bits to set.