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/STLExtras.h"
23#include "llvm/ADT/SetVector.h"
25#include "llvm/ADT/Statistic.h"
26#include "llvm/ADT/StringRef.h"
35#include "llvm/IR/Attributes.h"
36#include "llvm/IR/BasicBlock.h"
37#include "llvm/IR/Constant.h"
38#include "llvm/IR/Constants.h"
39#include "llvm/IR/DIBuilder.h"
40#include "llvm/IR/DataLayout.h"
42#include "llvm/IR/Function.h"
43#include "llvm/IR/GlobalAlias.h"
45#include "llvm/IR/GlobalValue.h"
47#include "llvm/IR/IRBuilder.h"
48#include "llvm/IR/InlineAsm.h"
49#include "llvm/IR/Instruction.h"
52#include "llvm/IR/Intrinsics.h"
53#include "llvm/IR/LLVMContext.h"
54#include "llvm/IR/MDBuilder.h"
55#include "llvm/IR/Metadata.h"
56#include "llvm/IR/Module.h"
59#include "llvm/IR/Operator.h"
60#include "llvm/IR/PassManager.h"
63#include "llvm/IR/Type.h"
64#include "llvm/IR/Use.h"
65#include "llvm/IR/User.h"
66#include "llvm/IR/Value.h"
70#include "llvm/Support/Debug.h"
71#include "llvm/Support/Error.h"
81#include "llvm/Transforms/IPO.h"
84#include <algorithm>
85#include <cassert>
86#include <cstdint>
87#include <set>
88#include <string>
89#include <system_error>
90#include <utility>
91#include <vector>
92
93using namespace llvm;
94using namespace lowertypetests;
95
96#define DEBUG_TYPE "lowertypetests"
97
98STATISTIC(ByteArraySizeBits, "Byte array size in bits");
99STATISTIC(ByteArraySizeBytes, "Byte array size in bytes");
100STATISTIC(NumByteArraysCreated, "Number of byte arrays created");
101STATISTIC(NumTypeTestCallsLowered, "Number of type test calls lowered");
102STATISTIC(NumTypeIdDisjointSets, "Number of disjoint sets of type identifiers");
103
105 "lowertypetests-avoid-reuse",
106 cl::desc("Try to avoid reuse of byte array addresses using aliases"),
107 cl::Hidden, cl::init(true));
108
110 "lowertypetests-summary-action",
111 cl::desc("What to do with the summary when running this pass"),
112 cl::values(clEnumValN(PassSummaryAction::None, "none", "Do nothing"),
114 "Import typeid resolutions from summary and globals"),
116 "Export typeid resolutions to summary and globals")),
117 cl::Hidden);
118
120 ClReadSummary("lowertypetests-read-summary",
121 cl::desc("Read summary from given textual assembly or YAML "
122 "file before running pass"),
123 cl::Hidden);
124
126 "lowertypetests-write-summary",
127 cl::desc("Write summary to given YAML file after running pass"),
128 cl::Hidden);
129
130// FIXME: Remove in clang 24.
132 "lowertypetests-jump-table-debug-info", cl::init(true), cl::Hidden,
133 cl::desc("Enable debug info generation for jump tables"));
134
136 if (Offset < ByteOffset)
137 return false;
138
139 if ((Offset - ByteOffset) % (uint64_t(1) << AlignLog2) != 0)
140 return false;
141
142 uint64_t BitOffset = (Offset - ByteOffset) >> AlignLog2;
143 if (BitOffset >= BitSize)
144 return false;
145
146 return Bits.count(BitSize - 1 - BitOffset);
147}
148
150 OS << "offset " << ByteOffset << " size " << BitSize << " align "
151 << (1 << AlignLog2);
152
153 if (isAllOnes()) {
154 OS << " all-ones\n";
155 return;
156 }
157
158 OS << " { ";
159 for (uint64_t B : Bits)
160 OS << B << ' ';
161 OS << "}\n";
162}
163
165 if (Min > Max)
166 Min = 0;
167
168 // Normalize each offset against the minimum observed offset, and compute
169 // the bitwise OR of each of the offsets. The number of trailing zeros
170 // in the mask gives us the log2 of the alignment of all offsets, which
171 // allows us to compress the bitset by only storing one bit per aligned
172 // address.
173 uint64_t Mask = 0;
174 for (uint64_t &Offset : Offsets) {
175 Offset -= Min;
176 Mask |= Offset;
177 }
178
179 BitSetInfo BSI;
180 BSI.ByteOffset = Min;
181
182 BSI.AlignLog2 = 0;
183 if (Mask != 0)
184 BSI.AlignLog2 = llvm::countr_zero(Mask);
185
186 // Build the compressed bitset while normalizing the offsets against the
187 // computed alignment.
188 BSI.BitSize = ((Max - Min) >> BSI.AlignLog2) + 1;
189 for (uint64_t Offset : Offsets) {
190 Offset >>= BSI.AlignLog2;
191 // We invert the order of bits when adding them to the bitset. This is
192 // because the offset that we test against is computed by subtracting the
193 // address that we are testing from the global's address, which means that
194 // the offset increases as the tested address decreases.
195 BSI.Bits.insert(BSI.BitSize - 1 - Offset);
196 }
197
198 return BSI;
199}
200
201void GlobalLayoutBuilder::addFragment(const std::set<uint64_t> &F) {
202 assert(Fragments.front().empty() && "Cannot add fragments after build()");
203
204 // Create a new fragment to hold the layout for F.
205 Fragments.emplace_back();
206 std::vector<uint64_t> &Fragment = Fragments.back();
207 uint64_t FragmentIndex = Fragments.size() - 1;
208
209 std::vector<std::vector<uint64_t>> SubFragments;
210 for (auto ObjIndex : F) {
211 uint64_t OldFragmentIndex = FragmentMap[ObjIndex];
212 if (OldFragmentIndex == 0) {
213 // We haven't seen this object index before, so just add it to the current
214 // fragment.
215 SubFragments.push_back({ObjIndex});
216 } else if (!Fragments[OldFragmentIndex].empty()) {
217 // This index belongs to an existing fragment. Copy the elements of the
218 // old fragment into this one and clear the old fragment. We don't update
219 // the fragment map just yet, this ensures that any further references to
220 // indices from the old fragment in this fragment do not insert any more
221 // indices.
222 SubFragments.push_back(std::move(Fragments[OldFragmentIndex]));
223 }
224 }
225
226 if (Less) {
227 llvm::stable_sort(SubFragments, [&](const std::vector<uint64_t> &A,
228 const std::vector<uint64_t> &B) {
229 return Less(A.back(), B.back());
230 });
231 }
232
233 for (auto &SF : SubFragments)
234 llvm::append_range(Fragment, std::move(SF));
235
236 // Update the fragment map to point our object indices to this fragment.
237 for (uint64_t ObjIndex : Fragment)
238 FragmentMap[ObjIndex] = FragmentIndex;
239}
240
241const std::vector<uint64_t> &GlobalLayoutBuilder::build() {
242 if (Less) {
243 // If multiple root fragments remain (e.g. disjoint signatures with no
244 // generalized type), order them so the one containing the hottest function
245 // is placed last.
246 llvm::erase_if(Fragments,
247 [](const std::vector<uint64_t> &F) { return F.empty(); });
248 llvm::stable_sort(Fragments, [&](const std::vector<uint64_t> &FA,
249 const std::vector<uint64_t> &FB) {
250 return Less(FA.back(), FB.back());
251 });
252 }
253
254 std::vector<uint64_t> Layout;
255 Layout.reserve(FragmentMap.size());
256 for (auto &&F : Fragments)
257 llvm::append_range(Layout, F);
258 Fragments.clear();
259 Fragments.push_back(std::move(Layout));
260 return Fragments.front();
261}
262
263void ByteArrayBuilder::allocate(const std::set<uint64_t> &Bits,
264 uint64_t BitSize, uint64_t &AllocByteOffset,
265 uint8_t &AllocMask) {
266 // Find the smallest current allocation.
267 unsigned Bit = 0;
268 for (unsigned I = 1; I != BitsPerByte; ++I)
269 if (BitAllocs[I] < BitAllocs[Bit])
270 Bit = I;
271
272 AllocByteOffset = BitAllocs[Bit];
273
274 // Add our size to it.
275 unsigned ReqSize = AllocByteOffset + BitSize;
276 BitAllocs[Bit] = ReqSize;
277 if (Bytes.size() < ReqSize)
278 Bytes.resize(ReqSize);
279
280 // Set our bits.
281 AllocMask = 1 << Bit;
282 for (uint64_t B : Bits)
283 Bytes[AllocByteOffset + B] |= AllocMask;
284}
285
287 if (F->isDeclarationForLinker())
288 return false;
290 F->getParent()->getModuleFlag("CFI Canonical Jump Tables"));
291 if (!CI || !CI->isZero())
292 return true;
293 return F->hasFnAttribute("cfi-canonical-jump-table");
294}
295
296namespace {
297
298struct ByteArrayInfo {
299 std::set<uint64_t> Bits;
300 uint64_t BitSize;
301 GlobalVariable *ByteArray;
302 GlobalVariable *MaskGlobal;
303 uint8_t *MaskPtr = nullptr;
304};
305
306/// A POD-like structure that we use to store a global reference together with
307/// its metadata types. In this pass we frequently need to query the set of
308/// metadata types referenced by a global, which at the IR level is an expensive
309/// operation involving a map lookup; this data structure helps to reduce the
310/// number of times we need to do this lookup.
311class GlobalTypeMember final : TrailingObjects<GlobalTypeMember, MDNode *> {
312 friend TrailingObjects;
313
314 GlobalObject *GO;
315 size_t NTypes;
316
317 // For functions: true if the jump table is canonical. This essentially means
318 // whether the canonical address (i.e. the symbol table entry) of the function
319 // is provided by the local jump table. This is normally the same as whether
320 // the function is defined locally, but if canonical jump tables are disabled
321 // by the user then the jump table never provides a canonical definition.
322 bool IsJumpTableCanonical;
323
324 // For functions: true if this function is either defined or used in a thinlto
325 // module and its jumptable entry needs to be exported to thinlto backends.
326 bool IsExported;
327
328public:
329 static GlobalTypeMember *create(BumpPtrAllocator &Alloc, GlobalObject *GO,
330 bool IsJumpTableCanonical, bool IsExported,
331 ArrayRef<MDNode *> Types) {
332 auto *GTM = static_cast<GlobalTypeMember *>(Alloc.Allocate(
333 totalSizeToAlloc<MDNode *>(Types.size()), alignof(GlobalTypeMember)));
334 GTM->GO = GO;
335 GTM->NTypes = Types.size();
336 GTM->IsJumpTableCanonical = IsJumpTableCanonical;
337 GTM->IsExported = IsExported;
338 llvm::copy(Types, GTM->getTrailingObjects());
339 return GTM;
340 }
341
342 GlobalObject *getGlobal() const {
343 return GO;
344 }
345
346 bool isJumpTableCanonical() const {
347 return IsJumpTableCanonical;
348 }
349
350 bool isExported() const {
351 return IsExported;
352 }
353
354 ArrayRef<MDNode *> types() const { return getTrailingObjects(NTypes); }
355};
356
357struct ICallBranchFunnel final
358 : TrailingObjects<ICallBranchFunnel, GlobalTypeMember *> {
359 static ICallBranchFunnel *create(BumpPtrAllocator &Alloc, CallInst *CI,
361 unsigned UniqueId) {
362 auto *Call = static_cast<ICallBranchFunnel *>(
363 Alloc.Allocate(totalSizeToAlloc<GlobalTypeMember *>(Targets.size()),
364 alignof(ICallBranchFunnel)));
365 Call->CI = CI;
366 Call->UniqueId = UniqueId;
367 Call->NTargets = Targets.size();
368 llvm::copy(Targets, Call->getTrailingObjects());
369 return Call;
370 }
371
372 CallInst *CI;
373 ArrayRef<GlobalTypeMember *> targets() const {
374 return getTrailingObjects(NTargets);
375 }
376
377 unsigned UniqueId;
378
379private:
380 size_t NTargets;
381};
382
383struct ScopedSaveAliaseesAndUsed {
384 Module &M;
386 std::vector<std::pair<GlobalAlias *, Function *>> FunctionAliases;
387 std::vector<std::pair<GlobalIFunc *, Function *>> ResolverIFuncs;
388
389 // This function only removes functions from llvm.used and llvm.compiler.used.
390 // We cannot remove global variables because they need to follow RAUW, as
391 // they may be deleted by buildBitSetsFromGlobalVariables.
392 void collectAndEraseUsedFunctions(Module &M,
393 SmallVectorImpl<GlobalValue *> &Vec,
394 bool CompilerUsed) {
395 auto *GV = collectUsedGlobalVariables(M, Vec, CompilerUsed);
396 if (!GV)
397 return;
398 // There's no API to only remove certain array elements from
399 // llvm.used/llvm.compiler.used, so we remove all of them and add back only
400 // the non-functions.
401 GV->eraseFromParent();
402 auto NonFuncBegin =
403 std::stable_partition(Vec.begin(), Vec.end(), [](GlobalValue *GV) {
404 return isa<Function>(GV);
405 });
406 if (CompilerUsed)
407 appendToCompilerUsed(M, {NonFuncBegin, Vec.end()});
408 else
409 appendToUsed(M, {NonFuncBegin, Vec.end()});
410 Vec.resize(NonFuncBegin - Vec.begin());
411 }
412
413 ScopedSaveAliaseesAndUsed(Module &M) : M(M) {
414 // The users of this class want to replace all function references except
415 // for aliases and llvm.used/llvm.compiler.used with references to a jump
416 // table. We avoid replacing aliases in order to avoid introducing a double
417 // indirection (or an alias pointing to a declaration in ThinLTO mode), and
418 // we avoid replacing llvm.used/llvm.compiler.used because these global
419 // variables describe properties of the global, not the jump table (besides,
420 // offseted references to the jump table in llvm.used are invalid).
421 // Unfortunately, LLVM doesn't have a "RAUW except for these (possibly
422 // indirect) users", so what we do is save the list of globals referenced by
423 // llvm.used/llvm.compiler.used and aliases, erase the used lists, let RAUW
424 // replace the aliasees and then set them back to their original values at
425 // the end.
426 collectAndEraseUsedFunctions(M, Used, false);
427 collectAndEraseUsedFunctions(M, CompilerUsed, true);
428
429 for (auto &GA : M.aliases()) {
430 // FIXME: This should look past all aliases not just interposable ones,
431 // see discussion on D65118.
432 if (auto *F = dyn_cast<Function>(GA.getAliasee()->stripPointerCasts()))
433 FunctionAliases.push_back({&GA, F});
434 }
435
436 for (auto &GI : M.ifuncs())
437 if (auto *F = dyn_cast<Function>(GI.getResolver()->stripPointerCasts()))
438 ResolverIFuncs.push_back({&GI, F});
439 }
440
441 ~ScopedSaveAliaseesAndUsed() {
442 appendToUsed(M, Used);
443 appendToCompilerUsed(M, CompilerUsed);
444
445 for (auto P : FunctionAliases)
446 P.first->setAliasee(P.second);
447
448 for (auto P : ResolverIFuncs) {
449 // This does not preserve pointer casts that may have been stripped by the
450 // constructor, but the resolver's type is different from that of the
451 // ifunc anyway.
452 P.first->setResolver(P.second);
453 }
454 }
455};
456
457class LowerTypeTestsModule {
458 Module &M;
459
460 ModuleSummaryIndex *ExportSummary;
461 const ModuleSummaryIndex *ImportSummary;
462
463 Triple::ArchType Arch;
465 Triple::ObjectFormatType ObjectFormat;
466
467 // Determines which kind of Thumb jump table we generate. If arch is
468 // either 'arm' or 'thumb' we need to find this out, because
469 // selectJumpTableArmEncoding may decide to use Thumb in either case.
470 bool CanUseArmJumpTable = false, CanUseThumbBWJumpTable = false;
471
472 // Cache variable used by hasBranchTargetEnforcement().
473 int HasBranchTargetEnforcement = -1;
474
475 IntegerType *Int1Ty = Type::getInt1Ty(M.getContext());
476 IntegerType *Int8Ty = Type::getInt8Ty(M.getContext());
477 PointerType *PtrTy = PointerType::getUnqual(M.getContext());
478 ArrayType *Int8Arr0Ty = ArrayType::get(Type::getInt8Ty(M.getContext()), 0);
479 IntegerType *Int32Ty = Type::getInt32Ty(M.getContext());
480 IntegerType *Int64Ty = Type::getInt64Ty(M.getContext());
481 IntegerType *IntPtrTy = M.getDataLayout().getIntPtrType(M.getContext(), 0);
482
483 // Indirect function call index assignment counter for WebAssembly
484 uint64_t IndirectIndex = 1;
485
486 // Mapping from type identifiers to the call sites that test them, as well as
487 // whether the type identifier needs to be exported to ThinLTO backends as
488 // part of the regular LTO phase of the ThinLTO pipeline (see exportTypeId).
489 struct TypeIdUserInfo {
490 std::vector<CallInst *> CallSites;
491 bool IsExported = false;
492 };
493 DenseMap<Metadata *, TypeIdUserInfo> TypeIdUsers;
494
495 /// This structure describes how to lower type tests for a particular type
496 /// identifier. It is either built directly from the global analysis (during
497 /// regular LTO or the regular LTO phase of ThinLTO), or indirectly using type
498 /// identifier summaries and external symbol references (in ThinLTO backends).
499 struct TypeIdLowering {
501
502 /// All except Unsat: the address of the last element within the combined
503 /// global.
504 Constant *OffsetedGlobal;
505
506 /// ByteArray, Inline, AllOnes: log2 of the required global alignment
507 /// relative to the start address.
508 Constant *AlignLog2;
509
510 /// ByteArray, Inline, AllOnes: one less than the size of the memory region
511 /// covering members of this type identifier as a multiple of 2^AlignLog2.
512 Constant *SizeM1;
513
514 /// ByteArray: the byte array to test the address against.
515 Constant *TheByteArray;
516
517 /// ByteArray: the bit mask to apply to bytes loaded from the byte array.
518 Constant *BitMask;
519
520 /// Inline: the bit mask to test the address against.
521 Constant *InlineBits;
522 };
523
524 std::vector<ByteArrayInfo> ByteArrayInfos;
525
526 Function *WeakInitializerFn = nullptr;
527
528 GlobalVariable *GlobalAnnotation;
529 DenseSet<Value *> FunctionAnnotations;
530
531 // Cross-DSO CFI emits jumptable entries for exported functions as well as
532 // address taken functions in case they are address taken in other modules.
533 bool CrossDsoCfi = M.getModuleFlag("Cross-DSO CFI") != nullptr;
534
535 bool shouldExportConstantsAsAbsoluteSymbols();
536 uint8_t *exportTypeId(StringRef TypeId, const TypeIdLowering &TIL);
537 TypeIdLowering importTypeId(StringRef TypeId);
538 void importTypeTest(CallInst *CI);
539 void importFunction(Function *F, bool isJumpTableCanonical);
540
541 ByteArrayInfo *createByteArray(const BitSetInfo &BSI);
542 void allocateByteArrays();
543 Value *createBitSetTest(IRBuilder<> &B, const TypeIdLowering &TIL,
544 Value *BitOffset);
545 void lowerTypeTestCalls(
546 ArrayRef<Metadata *> TypeIds, Constant *CombinedGlobalAddr,
547 const DenseMap<GlobalTypeMember *, uint64_t> &GlobalLayout);
548 Value *lowerTypeTestCall(Metadata *TypeId, CallInst *CI,
549 const TypeIdLowering &TIL);
550
551 void buildBitSetsFromGlobalVariables(ArrayRef<Metadata *> TypeIds,
554 selectJumpTableArmEncoding(ArrayRef<GlobalTypeMember *> Functions);
555 bool hasBranchTargetEnforcement();
556 unsigned getJumpTableEntrySize(Triple::ArchType JumpTableArch);
557 InlineAsm *createJumpTableEntryAsm(Triple::ArchType JumpTableArch);
558 void verifyTypeMDNode(GlobalObject *GO, MDNode *Type);
559 void buildBitSetsFromFunctions(ArrayRef<Metadata *> TypeIds,
561 void buildBitSetsFromFunctionsNative(ArrayRef<Metadata *> TypeIds,
563 void buildBitSetsFromFunctionsWASM(ArrayRef<Metadata *> TypeIds,
565 void
566 buildBitSetsFromDisjointSet(ArrayRef<Metadata *> TypeIds,
568 ArrayRef<ICallBranchFunnel *> ICallBranchFunnels);
569
570 void replaceWeakDeclarationWithJumpTablePtr(Function *F, Constant *JT,
571 bool IsJumpTableCanonical);
572 void moveInitializerToModuleConstructor(GlobalVariable *GV);
573 void findGlobalVariableUsersOf(Constant *C,
574 SmallSetVector<GlobalVariable *, 8> &Out);
575
576 void createJumpTable(Function *F, ArrayRef<GlobalTypeMember *> Functions,
577 Triple::ArchType JumpTableArch);
578
579 /// replaceCfiUses - Go through the uses list for this definition and make
580 /// each use point to "New" instead of "Old" when the use is outside the
581 /// block. 'Old's use list is expected to have at least one element. Unlike
582 /// replaceAllUsesWith this function skips blockaddr and direct call uses.
583 void replaceCfiUses(Function *Old, Value *New, bool IsJumpTableCanonical);
584
585 /// replaceDirectCalls - Go through the uses list for this definition and
586 /// replace each use, which is a direct function call.
587 void replaceDirectCalls(Value *Old, Value *New);
588
589 bool isFunctionAnnotation(Value *V) const {
590 return FunctionAnnotations.contains(V);
591 }
592
593 void maybeReplaceComdat(Function *F, StringRef OriginalName);
594
595public:
596 LowerTypeTestsModule(Module &M, ModuleAnalysisManager &AM,
597 ModuleSummaryIndex *ExportSummary,
598 const ModuleSummaryIndex *ImportSummary);
599
600 bool lower();
601
602 // Lower the module using the action and summary passed as command line
603 // arguments. For testing purposes only.
604 static bool runForTesting(Module &M, ModuleAnalysisManager &AM);
605};
606} // end anonymous namespace
607
608/// Build a bit set for list of offsets.
610 // Compute the byte offset of each address associated with this type
611 // identifier.
612 return BitSetBuilder(Offsets).build();
613}
614
615/// Build a test that bit BitOffset mod sizeof(Bits)*8 is set in
616/// Bits. This pattern matches to the bt instruction on x86.
618 Value *BitOffset) {
619 auto BitsType = cast<IntegerType>(Bits->getType());
620 unsigned BitWidth = BitsType->getBitWidth();
621
622 BitOffset = B.CreateZExtOrTrunc(BitOffset, BitsType);
623 Value *BitIndex =
624 B.CreateAnd(BitOffset, ConstantInt::get(BitsType, BitWidth - 1));
625 Value *BitMask = B.CreateShl(ConstantInt::get(BitsType, 1), BitIndex);
626 Value *MaskedBits = B.CreateAnd(Bits, BitMask);
627 return B.CreateICmpNE(MaskedBits, ConstantInt::get(BitsType, 0));
628}
629
630ByteArrayInfo *LowerTypeTestsModule::createByteArray(const BitSetInfo &BSI) {
631 // Create globals to stand in for byte arrays and masks. These never actually
632 // get initialized, we RAUW and erase them later in allocateByteArrays() once
633 // we know the offset and mask to use.
634 auto ByteArrayGlobal = new GlobalVariable(
635 M, Int8Ty, /*isConstant=*/true, GlobalValue::PrivateLinkage, nullptr);
636 auto MaskGlobal = new GlobalVariable(M, Int8Ty, /*isConstant=*/true,
638
639 ByteArrayInfos.emplace_back();
640 ByteArrayInfo *BAI = &ByteArrayInfos.back();
641
642 BAI->Bits = BSI.Bits;
643 BAI->BitSize = BSI.BitSize;
644 BAI->ByteArray = ByteArrayGlobal;
645 BAI->MaskGlobal = MaskGlobal;
646 return BAI;
647}
648
649void LowerTypeTestsModule::allocateByteArrays() {
650 llvm::stable_sort(ByteArrayInfos,
651 [](const ByteArrayInfo &BAI1, const ByteArrayInfo &BAI2) {
652 return BAI1.BitSize > BAI2.BitSize;
653 });
654
655 std::vector<uint64_t> ByteArrayOffsets(ByteArrayInfos.size());
656
658 for (unsigned I = 0; I != ByteArrayInfos.size(); ++I) {
659 ByteArrayInfo *BAI = &ByteArrayInfos[I];
660
661 uint8_t Mask;
662 BAB.allocate(BAI->Bits, BAI->BitSize, ByteArrayOffsets[I], Mask);
663
664 BAI->MaskGlobal->replaceAllUsesWith(
665 ConstantExpr::getIntToPtr(ConstantInt::get(Int8Ty, Mask), PtrTy));
666 BAI->MaskGlobal->eraseFromParent();
667 if (BAI->MaskPtr)
668 *BAI->MaskPtr = Mask;
669 }
670
671 Constant *ByteArrayConst = ConstantDataArray::get(M.getContext(), BAB.Bytes);
672 auto ByteArray =
673 new GlobalVariable(M, ByteArrayConst->getType(), /*isConstant=*/true,
674 GlobalValue::PrivateLinkage, ByteArrayConst);
675
676 for (unsigned I = 0; I != ByteArrayInfos.size(); ++I) {
677 ByteArrayInfo *BAI = &ByteArrayInfos[I];
679 ByteArray, ConstantInt::get(IntPtrTy, ByteArrayOffsets[I]));
680
681 // Create an alias instead of RAUW'ing the gep directly. On x86 this ensures
682 // that the pc-relative displacement is folded into the lea instead of the
683 // test instruction getting another displacement.
684 GlobalAlias *Alias = GlobalAlias::create(
685 Int8Ty, 0, GlobalValue::PrivateLinkage, "bits", GEP, &M);
686 BAI->ByteArray->replaceAllUsesWith(Alias);
687 BAI->ByteArray->eraseFromParent();
688 }
689
690 ByteArraySizeBits = BAB.BitAllocs[0] + BAB.BitAllocs[1] + BAB.BitAllocs[2] +
691 BAB.BitAllocs[3] + BAB.BitAllocs[4] + BAB.BitAllocs[5] +
692 BAB.BitAllocs[6] + BAB.BitAllocs[7];
693 ByteArraySizeBytes = BAB.Bytes.size();
694}
695
696/// Build a test that bit BitOffset is set in the type identifier that was
697/// lowered to TIL, which must be either an Inline or a ByteArray.
698Value *LowerTypeTestsModule::createBitSetTest(IRBuilder<> &B,
699 const TypeIdLowering &TIL,
700 Value *BitOffset) {
701 if (TIL.TheKind == TypeTestResolution::Inline) {
702 // If the bit set is sufficiently small, we can avoid a load by bit testing
703 // a constant.
704 return createMaskedBitTest(B, TIL.InlineBits, BitOffset);
705 } else {
706 Constant *ByteArray = TIL.TheByteArray;
707 if (AvoidReuse && !ImportSummary) {
708 // Each use of the byte array uses a different alias. This makes the
709 // backend less likely to reuse previously computed byte array addresses,
710 // improving the security of the CFI mechanism based on this pass.
711 // This won't work when importing because TheByteArray is external.
713 "bits_use", ByteArray, &M);
714 }
715
716 Value *ByteAddr = B.CreateGEP(Int8Ty, ByteArray, BitOffset);
717 Value *Byte = B.CreateLoad(Int8Ty, ByteAddr);
718
719 Value *ByteAndMask =
720 B.CreateAnd(Byte, ConstantExpr::getPtrToInt(TIL.BitMask, Int8Ty));
721 return B.CreateICmpNE(ByteAndMask, ConstantInt::get(Int8Ty, 0));
722 }
723}
724
725static bool isKnownTypeIdMember(Metadata *TypeId, const DataLayout &DL,
726 Value *V, uint64_t COffset) {
727 if (auto GV = dyn_cast<GlobalObject>(V)) {
729 GV->getMetadata(LLVMContext::MD_type, Types);
730 for (MDNode *Type : Types) {
731 if (Type->getOperand(1) != TypeId)
732 continue;
735 cast<ConstantAsMetadata>(Type->getOperand(0))->getValue())
736 ->getZExtValue();
737 if (COffset == Offset)
738 return true;
739 }
740 return false;
741 }
742
743 if (auto GEP = dyn_cast<GEPOperator>(V)) {
744 APInt APOffset(DL.getIndexSizeInBits(0), 0);
745 bool Result = GEP->accumulateConstantOffset(DL, APOffset);
746 if (!Result)
747 return false;
748 COffset += APOffset.getZExtValue();
749 return isKnownTypeIdMember(TypeId, DL, GEP->getPointerOperand(), COffset);
750 }
751
752 if (auto Op = dyn_cast<Operator>(V)) {
753 if (Op->getOpcode() == Instruction::BitCast)
754 return isKnownTypeIdMember(TypeId, DL, Op->getOperand(0), COffset);
755
756 if (Op->getOpcode() == Instruction::Select)
757 return isKnownTypeIdMember(TypeId, DL, Op->getOperand(1), COffset) &&
758 isKnownTypeIdMember(TypeId, DL, Op->getOperand(2), COffset);
759 }
760
761 return false;
762}
763
764/// Lower a llvm.type.test call to its implementation. Returns the value to
765/// replace the call with.
766Value *LowerTypeTestsModule::lowerTypeTestCall(Metadata *TypeId, CallInst *CI,
767 const TypeIdLowering &TIL) {
768 // Delay lowering if the resolution is currently unknown.
769 if (TIL.TheKind == TypeTestResolution::Unknown)
770 return nullptr;
771 if (TIL.TheKind == TypeTestResolution::Unsat)
772 return ConstantInt::getFalse(M.getContext());
773
774 Value *Ptr = CI->getArgOperand(0);
775 const DataLayout &DL = M.getDataLayout();
776 if (isKnownTypeIdMember(TypeId, DL, Ptr, 0))
777 return ConstantInt::getTrue(M.getContext());
778
779 BasicBlock *InitialBB = CI->getParent();
780
781 IRBuilder<> B(CI);
782
783 Value *PtrAsInt = B.CreatePtrToInt(Ptr, IntPtrTy);
784
785 Constant *OffsetedGlobalAsInt =
786 ConstantExpr::getPtrToInt(TIL.OffsetedGlobal, IntPtrTy);
787 if (TIL.TheKind == TypeTestResolution::Single)
788 return B.CreateICmpEQ(PtrAsInt, OffsetedGlobalAsInt);
789
790 // Here we compute `last element - address`. The reason why we do this instead
791 // of computing `address - first element` is that it leads to a slightly
792 // shorter instruction sequence on x86. Because it doesn't matter how we do
793 // the subtraction on other architectures, we do so unconditionally.
794 Value *PtrOffset = B.CreateSub(OffsetedGlobalAsInt, PtrAsInt);
795
796 // We need to check that the offset both falls within our range and is
797 // suitably aligned. We can check both properties at the same time by
798 // performing a right rotate by log2(alignment) followed by an integer
799 // comparison against the bitset size. The rotate will move the lower
800 // order bits that need to be zero into the higher order bits of the
801 // result, causing the comparison to fail if they are nonzero. The rotate
802 // also conveniently gives us a bit offset to use during the load from
803 // the bitset.
804 Value *BitOffset = B.CreateIntrinsic(IntPtrTy, Intrinsic::fshr,
805 {PtrOffset, PtrOffset, TIL.AlignLog2});
806
807 Value *OffsetInRange = B.CreateICmpULE(BitOffset, TIL.SizeM1);
808
809 // If the bit set is all ones, testing against it is unnecessary.
810 if (TIL.TheKind == TypeTestResolution::AllOnes)
811 return OffsetInRange;
812
813 // See if the intrinsic is used in the following common pattern:
814 // br(llvm.type.test(...), thenbb, elsebb)
815 // where nothing happens between the type test and the br.
816 // If so, create slightly simpler IR.
817 if (CI->hasOneUse())
818 if (auto *Br = dyn_cast<CondBrInst>(*CI->user_begin()))
819 if (CI->getNextNode() == Br) {
820 BasicBlock *Then = InitialBB->splitBasicBlock(CI->getIterator());
821 BasicBlock *Else = Br->getSuccessor(1);
822 CondBrInst *NewBr = CondBrInst::Create(OffsetInRange, Then, Else);
823 NewBr->setMetadata(LLVMContext::MD_prof,
824 Br->getMetadata(LLVMContext::MD_prof));
825 ReplaceInstWithInst(InitialBB->getTerminator(), NewBr);
826
827 // Update phis in Else resulting from InitialBB being split
828 for (auto &Phi : Else->phis())
829 Phi.addIncoming(Phi.getIncomingValueForBlock(Then), InitialBB);
830
831 IRBuilder<> ThenB(CI);
832 return createBitSetTest(ThenB, TIL, BitOffset);
833 }
834
835 MDBuilder MDB(M.getContext());
836 IRBuilder<> ThenB(SplitBlockAndInsertIfThen(OffsetInRange, CI, false,
837 MDB.createLikelyBranchWeights()));
838
839 // Now that we know that the offset is in range and aligned, load the
840 // appropriate bit from the bitset.
841 Value *Bit = createBitSetTest(ThenB, TIL, BitOffset);
842
843 // The value we want is 0 if we came directly from the initial block
844 // (having failed the range or alignment checks), or the loaded bit if
845 // we came from the block in which we loaded it.
846 B.SetInsertPoint(CI);
847 PHINode *P = B.CreatePHI(Int1Ty, 2);
848 P->addIncoming(ConstantInt::get(Int1Ty, 0), InitialBB);
849 P->addIncoming(Bit, ThenB.GetInsertBlock());
850 return P;
851}
852
853/// Given a disjoint set of type identifiers and globals, lay out the globals,
854/// build the bit sets and lower the llvm.type.test calls.
855void LowerTypeTestsModule::buildBitSetsFromGlobalVariables(
857 // Build a new global with the combined contents of the referenced globals.
858 // This global is a struct whose even-indexed elements contain the original
859 // contents of the referenced globals and whose odd-indexed elements contain
860 // any padding required to align the next element to the next power of 2 plus
861 // any additional padding required to meet its alignment requirements.
862 std::vector<Constant *> GlobalInits;
863 const DataLayout &DL = M.getDataLayout();
864 DenseMap<GlobalTypeMember *, uint64_t> GlobalLayout;
865 Align MaxAlign;
866 uint64_t CurOffset = 0;
867 uint64_t DesiredPadding = 0;
868 for (GlobalTypeMember *G : Globals) {
869 auto *GV = cast<GlobalVariable>(G->getGlobal());
871 DL.getValueOrABITypeAlignment(GV->getAlign(), GV->getValueType());
872 MaxAlign = std::max(MaxAlign, Alignment);
873 uint64_t GVOffset = alignTo(CurOffset + DesiredPadding, Alignment);
874 GlobalLayout[G] = GVOffset;
875 if (GVOffset != 0) {
876 uint64_t Padding = GVOffset - CurOffset;
877 GlobalInits.push_back(
879 }
880
881 GlobalInits.push_back(GV->getInitializer());
882 uint64_t InitSize = GV->getGlobalSize(DL);
883 CurOffset = GVOffset + InitSize;
884
885 // Compute the amount of padding that we'd like for the next element.
886 DesiredPadding = NextPowerOf2(InitSize - 1) - InitSize;
887
888 // Experiments of different caps with Chromium on both x64 and ARM64
889 // have shown that the 32-byte cap generates the smallest binary on
890 // both platforms while different caps yield similar performance.
891 // (see https://lists.llvm.org/pipermail/llvm-dev/2018-July/124694.html)
892 if (DesiredPadding > 32)
893 DesiredPadding = alignTo(InitSize, 32) - InitSize;
894 }
895
896 Constant *NewInit = ConstantStruct::getAnon(M.getContext(), GlobalInits);
897 auto *CombinedGlobal =
898 new GlobalVariable(M, NewInit->getType(), /*isConstant=*/true,
900 CombinedGlobal->setAlignment(MaxAlign);
901
902 StructType *NewTy = cast<StructType>(NewInit->getType());
903 lowerTypeTestCalls(TypeIds, CombinedGlobal, GlobalLayout);
904
905 // Build aliases pointing to offsets into the combined global for each
906 // global from which we built the combined global, and replace references
907 // to the original globals with references to the aliases.
908 for (unsigned I = 0; I != Globals.size(); ++I) {
909 GlobalVariable *GV = cast<GlobalVariable>(Globals[I]->getGlobal());
910
911 // Multiply by 2 to account for padding elements.
912 Constant *CombinedGlobalIdxs[] = {ConstantInt::get(Int32Ty, 0),
913 ConstantInt::get(Int32Ty, I * 2)};
914 Constant *CombinedGlobalElemPtr = ConstantExpr::getInBoundsGetElementPtr(
915 NewInit->getType(), CombinedGlobal, CombinedGlobalIdxs);
916 assert(GV->getType()->getAddressSpace() == 0);
917 GlobalAlias *GAlias =
918 GlobalAlias::create(NewTy->getElementType(I * 2), 0, GV->getLinkage(),
919 "", CombinedGlobalElemPtr, &M);
920 GAlias->setVisibility(GV->getVisibility());
921 GAlias->takeName(GV);
922 GV->replaceAllUsesWith(GAlias);
923 GV->eraseFromParent();
924 }
925}
926
927bool LowerTypeTestsModule::shouldExportConstantsAsAbsoluteSymbols() {
928 return (Arch == Triple::x86 || Arch == Triple::x86_64) &&
929 ObjectFormat == Triple::ELF;
930}
931
932/// Export the given type identifier so that ThinLTO backends may import it.
933/// Type identifiers are exported by adding coarse-grained information about how
934/// to test the type identifier to the summary, and creating symbols in the
935/// object file (aliases and absolute symbols) containing fine-grained
936/// information about the type identifier.
937///
938/// Returns a pointer to the location in which to store the bitmask, if
939/// applicable.
940uint8_t *LowerTypeTestsModule::exportTypeId(StringRef TypeId,
941 const TypeIdLowering &TIL) {
942 TypeTestResolution &TTRes =
943 ExportSummary->getOrInsertTypeIdSummary(TypeId).TTRes;
944 TTRes.TheKind = TIL.TheKind;
945
946 auto ExportGlobal = [&](StringRef Name, Constant *C) {
947 GlobalAlias *GA =
949 "__typeid_" + TypeId + "_" + Name, C, &M);
951 };
952
953 auto ExportConstant = [&](StringRef Name, uint64_t &Storage, Constant *C) {
954 if (shouldExportConstantsAsAbsoluteSymbols())
955 ExportGlobal(Name, ConstantExpr::getIntToPtr(C, PtrTy));
956 else
957 Storage = cast<ConstantInt>(C)->getZExtValue();
958 };
959
960 if (TIL.TheKind != TypeTestResolution::Unsat)
961 ExportGlobal("global_addr", TIL.OffsetedGlobal);
962
963 if (TIL.TheKind == TypeTestResolution::ByteArray ||
964 TIL.TheKind == TypeTestResolution::Inline ||
965 TIL.TheKind == TypeTestResolution::AllOnes) {
966 ExportConstant("align", TTRes.AlignLog2, TIL.AlignLog2);
967 ExportConstant("size_m1", TTRes.SizeM1, TIL.SizeM1);
968
969 uint64_t BitSize = cast<ConstantInt>(TIL.SizeM1)->getZExtValue() + 1;
970 if (TIL.TheKind == TypeTestResolution::Inline)
971 TTRes.SizeM1BitWidth = (BitSize <= 32) ? 5 : 6;
972 else
973 TTRes.SizeM1BitWidth = (BitSize <= 128) ? 7 : 32;
974 }
975
976 if (TIL.TheKind == TypeTestResolution::ByteArray) {
977 ExportGlobal("byte_array", TIL.TheByteArray);
978 if (shouldExportConstantsAsAbsoluteSymbols())
979 ExportGlobal("bit_mask", TIL.BitMask);
980 else
981 return &TTRes.BitMask;
982 }
983
984 if (TIL.TheKind == TypeTestResolution::Inline)
985 ExportConstant("inline_bits", TTRes.InlineBits, TIL.InlineBits);
986
987 return nullptr;
988}
989
990LowerTypeTestsModule::TypeIdLowering
991LowerTypeTestsModule::importTypeId(StringRef TypeId) {
992 const TypeIdSummary *TidSummary = ImportSummary->getTypeIdSummary(TypeId);
993 if (!TidSummary)
994 return {}; // Unsat: no globals match this type id.
995 const TypeTestResolution &TTRes = TidSummary->TTRes;
996
997 TypeIdLowering TIL;
998 TIL.TheKind = TTRes.TheKind;
999
1000 auto ImportGlobal = [&](StringRef Name) {
1001 // Give the global a type of length 0 so that it is not assumed not to alias
1002 // with any other global.
1003 GlobalVariable *GV = M.getOrInsertGlobal(
1004 ("__typeid_" + TypeId + "_" + Name).str(), Int8Arr0Ty);
1006 return GV;
1007 };
1008
1009 auto ImportConstant = [&](StringRef Name, uint64_t Const, unsigned AbsWidth,
1010 Type *Ty) {
1011 if (!shouldExportConstantsAsAbsoluteSymbols()) {
1012 Constant *C =
1013 ConstantInt::get(isa<IntegerType>(Ty) ? Ty : Int64Ty, Const);
1014 if (!isa<IntegerType>(Ty))
1016 return C;
1017 }
1018
1019 Constant *C = ImportGlobal(Name);
1020 auto *GV = cast<GlobalVariable>(C->stripPointerCasts());
1021 if (isa<IntegerType>(Ty))
1023 if (GV->getMetadata(LLVMContext::MD_absolute_symbol))
1024 return C;
1025
1026 auto SetAbsRange = [&](uint64_t Min, uint64_t Max) {
1027 auto *MinC = ConstantAsMetadata::get(ConstantInt::get(IntPtrTy, Min));
1028 auto *MaxC = ConstantAsMetadata::get(ConstantInt::get(IntPtrTy, Max));
1029 GV->setMetadata(LLVMContext::MD_absolute_symbol,
1030 MDNode::get(M.getContext(), {MinC, MaxC}));
1031 };
1032 if (AbsWidth == IntPtrTy->getBitWidth()) {
1033 uint64_t AllOnes = IntPtrTy->getBitMask();
1034 SetAbsRange(AllOnes, AllOnes); // Full set.
1035 } else {
1036 SetAbsRange(0, 1ull << AbsWidth);
1037 }
1038 return C;
1039 };
1040
1041 if (TIL.TheKind != TypeTestResolution::Unsat) {
1042 auto *GV = ImportGlobal("global_addr");
1043 // This is either a vtable (in .data.rel.ro) or a jump table (in .text).
1044 // Either way it's expected to be in the low 2 GiB, so set the small code
1045 // model.
1046 //
1047 // For .data.rel.ro, we currently place all such sections in the low 2 GiB
1048 // [1], and for .text the sections are expected to be in the low 2 GiB under
1049 // the small and medium code models [2] and this pass only supports those
1050 // code models (e.g. jump tables use jmp instead of movabs/jmp).
1051 //
1052 // [1]https://github.com/llvm/llvm-project/pull/137742
1053 // [2]https://maskray.me/blog/2023-05-14-relocation-overflow-and-code-models
1055 TIL.OffsetedGlobal = GV;
1056 }
1057
1058 if (TIL.TheKind == TypeTestResolution::ByteArray ||
1059 TIL.TheKind == TypeTestResolution::Inline ||
1060 TIL.TheKind == TypeTestResolution::AllOnes) {
1061 TIL.AlignLog2 = ImportConstant("align", TTRes.AlignLog2, 8, IntPtrTy);
1062 TIL.SizeM1 =
1063 ImportConstant("size_m1", TTRes.SizeM1, TTRes.SizeM1BitWidth, IntPtrTy);
1064 }
1065
1066 if (TIL.TheKind == TypeTestResolution::ByteArray) {
1067 TIL.TheByteArray = ImportGlobal("byte_array");
1068 TIL.BitMask = ImportConstant("bit_mask", TTRes.BitMask, 8, PtrTy);
1069 }
1070
1071 if (TIL.TheKind == TypeTestResolution::Inline)
1072 TIL.InlineBits = ImportConstant(
1073 "inline_bits", TTRes.InlineBits, 1 << TTRes.SizeM1BitWidth,
1074 TTRes.SizeM1BitWidth <= 5 ? Int32Ty : Int64Ty);
1075
1076 return TIL;
1077}
1078
1079void LowerTypeTestsModule::importTypeTest(CallInst *CI) {
1080 auto TypeIdMDVal = dyn_cast<MetadataAsValue>(CI->getArgOperand(1));
1081 if (!TypeIdMDVal)
1082 report_fatal_error("Second argument of llvm.type.test must be metadata");
1083
1084 auto TypeIdStr = dyn_cast<MDString>(TypeIdMDVal->getMetadata());
1085 // If this is a local unpromoted type, which doesn't have a metadata string,
1086 // treat as Unknown and delay lowering, so that we can still utilize it for
1087 // later optimizations.
1088 if (!TypeIdStr)
1089 return;
1090
1091 TypeIdLowering TIL = importTypeId(TypeIdStr->getString());
1092 Value *Lowered = lowerTypeTestCall(TypeIdStr, CI, TIL);
1093 if (Lowered) {
1094 CI->replaceAllUsesWith(Lowered);
1095 CI->eraseFromParent();
1096 }
1097}
1098
1099void LowerTypeTestsModule::maybeReplaceComdat(Function *F,
1100 StringRef OriginalName) {
1101 // For COFF we should also rename the comdat if this function also
1102 // happens to be the key function. Even if the comdat name changes, this
1103 // should still be fine since comdat and symbol resolution happens
1104 // before LTO, so all symbols which would prevail have been selected.
1105 if (F->hasComdat() && ObjectFormat == Triple::COFF &&
1106 F->getComdat()->getName() == OriginalName) {
1107 Comdat *OldComdat = F->getComdat();
1108 Comdat *NewComdat = M.getOrInsertComdat(F->getName());
1109 for (GlobalObject &GO : M.global_objects()) {
1110 if (GO.getComdat() == OldComdat)
1111 GO.setComdat(NewComdat);
1112 }
1113 }
1114}
1115
1116// ThinLTO backend: the function F has a jump table entry; update this module
1117// accordingly. isJumpTableCanonical describes the type of the jump table entry.
1118void LowerTypeTestsModule::importFunction(Function *F,
1119 bool isJumpTableCanonical) {
1120 assert(F->getType()->getAddressSpace() == 0);
1121
1122 GlobalValue::VisibilityTypes Visibility = F->getVisibility();
1123 std::string Name = std::string(F->getName());
1124
1125 if (F->isDeclarationForLinker() && isJumpTableCanonical) {
1126 // Non-dso_local functions may be overriden at run time,
1127 // don't short curcuit them
1128 if (!F->isDSOLocal())
1129 return;
1130 if (F->isDeclaration()) {
1131 // Direct calls do not need the type check, so let them skip the jump
1132 // table and call the real function directly.
1133 Function *RealF = Function::Create(F->getFunctionType(),
1135 F->getAddressSpace(),
1136 Name + ".cfi", &M);
1138 replaceDirectCalls(F, RealF);
1139 return;
1140 }
1141 // Otherwise F is an available_externally definition imported from
1142 // another module. Handle it like a local definition below: the body is
1143 // renamed to Name.cfi and stays the target of direct calls, so it remains
1144 // inlinable, while address-taken uses are redirected to the jump table
1145 // entry. If the body is not inlined and is dropped later, the reference
1146 // to Name.cfi resolves to the real function at link time, exactly as for
1147 // a declaration.
1148 }
1149
1150 Function *FDecl;
1151 if (!isJumpTableCanonical) {
1152 // Either a declaration of an external function or a reference to a locally
1153 // defined jump table.
1154 FDecl = Function::Create(F->getFunctionType(), GlobalValue::ExternalLinkage,
1155 F->getAddressSpace(), Name + ".cfi_jt", &M);
1157 } else {
1158 F->setName(Name + ".cfi");
1159 maybeReplaceComdat(F, Name);
1160 FDecl = Function::Create(F->getFunctionType(), GlobalValue::ExternalLinkage,
1161 F->getAddressSpace(), Name, &M);
1162 FDecl->setVisibility(Visibility);
1163 FDecl->setDSOLocal(F->isDSOLocal());
1164 Visibility = GlobalValue::HiddenVisibility;
1165
1166 // Update aliases pointing to this function to also include the ".cfi" suffix,
1167 // We expect the jump table entry to either point to the real function or an
1168 // alias. Redirect all other users to the jump table entry.
1169 for (auto &U : F->uses()) {
1170 if (auto *A = dyn_cast<GlobalAlias>(U.getUser())) {
1171 std::string AliasName = A->getName().str() + ".cfi";
1172 Function *AliasDecl = Function::Create(
1173 F->getFunctionType(), GlobalValue::ExternalLinkage,
1174 F->getAddressSpace(), "", &M);
1175 AliasDecl->takeName(A);
1176 A->replaceAllUsesWith(AliasDecl);
1177 A->setName(AliasName);
1178 AliasDecl->setDSOLocal(A->isDSOLocal());
1179 }
1180 }
1181 }
1182
1183 if (F->hasExternalWeakLinkage())
1184 replaceWeakDeclarationWithJumpTablePtr(F, FDecl, isJumpTableCanonical);
1185 else
1186 replaceCfiUses(F, FDecl, isJumpTableCanonical);
1187
1188 // Set visibility late because it's used in replaceCfiUses() to determine
1189 // whether uses need to be replaced.
1190 F->setVisibility(Visibility);
1191}
1192
1193static auto
1195 const DenseMap<GlobalTypeMember *, uint64_t> &GlobalLayout) {
1197 // Pre-populate the map with interesting type identifiers.
1198 for (Metadata *TypeId : TypeIds)
1199 OffsetsByTypeID[TypeId];
1200 for (const auto &[Mem, MemOff] : GlobalLayout) {
1201 for (MDNode *Type : Mem->types()) {
1202 auto It = OffsetsByTypeID.find(Type->getOperand(1));
1203 if (It == OffsetsByTypeID.end())
1204 continue;
1207 cast<ConstantAsMetadata>(Type->getOperand(0))->getValue())
1208 ->getZExtValue();
1209 It->second.push_back(MemOff + Offset);
1210 }
1211 }
1212
1214 BitSets.reserve(TypeIds.size());
1215 for (Metadata *TypeId : TypeIds) {
1216 BitSets.emplace_back(TypeId, buildBitSet(OffsetsByTypeID[TypeId]));
1217 LLVM_DEBUG({
1218 if (auto MDS = dyn_cast<MDString>(TypeId))
1219 dbgs() << MDS->getString() << ": ";
1220 else
1221 dbgs() << "<unnamed>: ";
1222 BitSets.back().second.print(dbgs());
1223 });
1224 }
1225
1226 return BitSets;
1227}
1228
1229void LowerTypeTestsModule::lowerTypeTestCalls(
1230 ArrayRef<Metadata *> TypeIds, Constant *CombinedGlobalAddr,
1231 const DenseMap<GlobalTypeMember *, uint64_t> &GlobalLayout) {
1232 // For each type identifier in this disjoint set...
1233 for (const auto &[TypeId, BSI] : buildBitSets(TypeIds, GlobalLayout)) {
1234 ByteArrayInfo *BAI = nullptr;
1235 TypeIdLowering TIL;
1236
1237 uint64_t GlobalOffset =
1238 BSI.ByteOffset + ((BSI.BitSize - 1) << BSI.AlignLog2);
1239 TIL.OffsetedGlobal = ConstantExpr::getPtrAdd(
1240 CombinedGlobalAddr, ConstantInt::get(IntPtrTy, GlobalOffset)),
1241 TIL.AlignLog2 = ConstantInt::get(IntPtrTy, BSI.AlignLog2);
1242 TIL.SizeM1 = ConstantInt::get(IntPtrTy, BSI.BitSize - 1);
1243 if (BSI.isAllOnes()) {
1244 TIL.TheKind = (BSI.BitSize == 1) ? TypeTestResolution::Single
1245 : TypeTestResolution::AllOnes;
1246 } else if (BSI.BitSize <= IntPtrTy->getBitWidth()) {
1247 TIL.TheKind = TypeTestResolution::Inline;
1248 uint64_t InlineBits = 0;
1249 for (auto Bit : BSI.Bits)
1250 InlineBits |= uint64_t(1) << Bit;
1251 if (InlineBits == 0)
1252 TIL.TheKind = TypeTestResolution::Unsat;
1253 else
1254 TIL.InlineBits = ConstantInt::get(
1255 (BSI.BitSize <= 32) ? Int32Ty : Int64Ty, InlineBits);
1256 } else {
1257 TIL.TheKind = TypeTestResolution::ByteArray;
1258 ++NumByteArraysCreated;
1259 BAI = createByteArray(BSI);
1260 TIL.TheByteArray = BAI->ByteArray;
1261 TIL.BitMask = BAI->MaskGlobal;
1262 }
1263
1264 TypeIdUserInfo &TIUI = TypeIdUsers[TypeId];
1265
1266 if (TIUI.IsExported) {
1267 uint8_t *MaskPtr = exportTypeId(cast<MDString>(TypeId)->getString(), TIL);
1268 if (BAI)
1269 BAI->MaskPtr = MaskPtr;
1270 }
1271
1272 // Lower each call to llvm.type.test for this type identifier.
1273 for (CallInst *CI : TIUI.CallSites) {
1274 ++NumTypeTestCallsLowered;
1275 Value *Lowered = lowerTypeTestCall(TypeId, CI, TIL);
1276 if (Lowered) {
1277 CI->replaceAllUsesWith(Lowered);
1278 CI->eraseFromParent();
1279 }
1280 }
1281 }
1282}
1283
1284void LowerTypeTestsModule::verifyTypeMDNode(GlobalObject *GO, MDNode *Type) {
1285 if (Type->getNumOperands() != 2)
1286 report_fatal_error("All operands of type metadata must have 2 elements");
1287
1288 if (GO->isThreadLocal())
1289 report_fatal_error("Bit set element may not be thread-local");
1290 if (isa<GlobalVariable>(GO) && GO->hasSection())
1292 "A member of a type identifier may not have an explicit section");
1293
1294 // FIXME: We previously checked that global var member of a type identifier
1295 // must be a definition, but the IR linker may leave type metadata on
1296 // declarations. We should restore this check after fixing PR31759.
1297
1298 auto OffsetConstMD = dyn_cast<ConstantAsMetadata>(Type->getOperand(0));
1299 if (!OffsetConstMD)
1300 report_fatal_error("Type offset must be a constant");
1301 auto OffsetInt = dyn_cast<ConstantInt>(OffsetConstMD->getValue());
1302 if (!OffsetInt)
1303 report_fatal_error("Type offset must be an integer constant");
1304}
1305
1306static const unsigned kX86JumpTableEntrySize = 8;
1307static const unsigned kX86IBTJumpTableEntrySize = 16;
1308static const unsigned kARMJumpTableEntrySize = 4;
1309static const unsigned kARMBTIJumpTableEntrySize = 8;
1310static const unsigned kARMv6MJumpTableEntrySize = 16;
1311static const unsigned kRISCVJumpTableEntrySize = 8;
1312static const unsigned kLOONGARCH64JumpTableEntrySize = 8;
1313static const unsigned kHexagonJumpTableEntrySize = 4;
1314
1315bool LowerTypeTestsModule::hasBranchTargetEnforcement() {
1316 if (HasBranchTargetEnforcement == -1) {
1317 // First time this query has been called. Find out the answer by checking
1318 // the module flags.
1319 if (const auto *BTE = mdconst::extract_or_null<ConstantInt>(
1320 M.getModuleFlag("branch-target-enforcement")))
1321 HasBranchTargetEnforcement = !BTE->isZero();
1322 else
1323 HasBranchTargetEnforcement = 0;
1324 }
1325 return HasBranchTargetEnforcement;
1326}
1327
1328unsigned
1329LowerTypeTestsModule::getJumpTableEntrySize(Triple::ArchType JumpTableArch) {
1330 switch (JumpTableArch) {
1331 case Triple::x86:
1332 case Triple::x86_64:
1333 if (const auto *MD = mdconst::extract_or_null<ConstantInt>(
1334 M.getModuleFlag("cf-protection-branch")))
1335 if (MD->getZExtValue())
1338 case Triple::arm:
1340 case Triple::thumb:
1341 if (CanUseThumbBWJumpTable) {
1342 if (hasBranchTargetEnforcement())
1345 } else {
1347 }
1348 case Triple::aarch64:
1349 if (hasBranchTargetEnforcement())
1352 case Triple::riscv32:
1353 case Triple::riscv64:
1357 case Triple::hexagon:
1359 default:
1360 report_fatal_error("Unsupported architecture for jump tables");
1361 }
1362}
1363
1364// Create an inline asm constant representing a jump table entry for the target.
1365// This consists of an instruction sequence containing a relative branch to
1366// Dest.
1367InlineAsm *
1368LowerTypeTestsModule::createJumpTableEntryAsm(Triple::ArchType JumpTableArch) {
1369 std::string Asm;
1370 raw_string_ostream AsmOS(Asm);
1371
1372 if (JumpTableArch == Triple::x86 || JumpTableArch == Triple::x86_64) {
1373 bool Endbr = false;
1374 if (const auto *MD = mdconst::extract_or_null<ConstantInt>(
1375 M.getModuleFlag("cf-protection-branch")))
1376 Endbr = !MD->isZero();
1377 if (Endbr)
1378 AsmOS << (JumpTableArch == Triple::x86 ? "endbr32\n" : "endbr64\n");
1379 AsmOS << "jmp ${0:c}@plt\n";
1380 if (Endbr)
1381 AsmOS << ".balign 16, 0xcc\n";
1382 else
1383 AsmOS << "int3\nint3\nint3\n";
1384 } else if (JumpTableArch == Triple::arm) {
1385 AsmOS << "b $0\n";
1386 } else if (JumpTableArch == Triple::aarch64) {
1387 if (hasBranchTargetEnforcement())
1388 AsmOS << "bti c\n";
1389 AsmOS << "b $0\n";
1390 } else if (JumpTableArch == Triple::thumb) {
1391 if (!CanUseThumbBWJumpTable) {
1392 // In Armv6-M, this sequence will generate a branch without corrupting
1393 // any registers. We use two stack words; in the second, we construct the
1394 // address we'll pop into pc, and the first is used to save and restore
1395 // r0 which we use as a temporary register.
1396 //
1397 // To support position-independent use cases, the offset of the target
1398 // function is stored as a relative offset (which will expand into an
1399 // R_ARM_REL32 relocation in ELF, and presumably the equivalent in other
1400 // object file types), and added to pc after we load it. (The alternative
1401 // B.W is automatically pc-relative.)
1402 //
1403 // There are five 16-bit Thumb instructions here, so the .balign 4 adds a
1404 // sixth halfword of padding, and then the offset consumes a further 4
1405 // bytes, for a total of 16, which is very convenient since entries in
1406 // this jump table need to have power-of-two size.
1407 AsmOS << "push {r0,r1}\n"
1408 << "ldr r0, 1f\n"
1409 << "0: add r0, r0, pc\n"
1410 << "str r0, [sp, #4]\n"
1411 << "pop {r0,pc}\n"
1412 << ".balign 4\n"
1413 << "1: .word $0 - (0b + 4)\n";
1414 } else {
1415 if (hasBranchTargetEnforcement())
1416 AsmOS << "bti\n";
1417 AsmOS << "b.w $0\n";
1418 }
1419 } else if (JumpTableArch == Triple::riscv32 ||
1420 JumpTableArch == Triple::riscv64) {
1421 AsmOS << "tail $0@plt\n";
1422 } else if (JumpTableArch == Triple::loongarch64) {
1423 AsmOS << "pcalau12i $$t0, %pc_hi20($0)\n"
1424 << "jirl $$r0, $$t0, %pc_lo12($0)\n";
1425 } else if (JumpTableArch == Triple::hexagon) {
1426 AsmOS << "jump $0\n";
1427 } else {
1428 report_fatal_error("Unsupported architecture for jump tables");
1429 }
1430
1431 return InlineAsm::get(
1432 FunctionType::get(Type::getVoidTy(M.getContext()), PtrTy, false),
1433 AsmOS.str(), "s",
1434 /*hasSideEffects=*/true);
1435}
1436
1437/// Given a disjoint set of type identifiers and functions, build the bit sets
1438/// and lower the llvm.type.test calls, architecture dependently.
1439void LowerTypeTestsModule::buildBitSetsFromFunctions(
1441 if (Arch == Triple::x86 || Arch == Triple::x86_64 || Arch == Triple::arm ||
1442 Arch == Triple::thumb || Arch == Triple::aarch64 ||
1443 Arch == Triple::riscv32 || Arch == Triple::riscv64 ||
1444 Arch == Triple::loongarch64 || Arch == Triple::hexagon)
1445 buildBitSetsFromFunctionsNative(TypeIds, Functions);
1446 else if (Arch == Triple::wasm32 || Arch == Triple::wasm64)
1447 buildBitSetsFromFunctionsWASM(TypeIds, Functions);
1448 else
1449 report_fatal_error("Unsupported architecture for jump tables");
1450}
1451
1452void LowerTypeTestsModule::moveInitializerToModuleConstructor(
1453 GlobalVariable *GV) {
1454 if (WeakInitializerFn == nullptr) {
1455 WeakInitializerFn = Function::Create(
1456 FunctionType::get(Type::getVoidTy(M.getContext()),
1457 /* IsVarArg */ false),
1459 M.getDataLayout().getProgramAddressSpace(),
1460 "__cfi_global_var_init", &M);
1461 BasicBlock *BB =
1462 BasicBlock::Create(M.getContext(), "entry", WeakInitializerFn);
1463 ReturnInst::Create(M.getContext(), BB);
1464 WeakInitializerFn->setSection(
1465 ObjectFormat == Triple::MachO
1466 ? "__TEXT,__StaticInit,regular,pure_instructions"
1467 : ".text.startup");
1468 // This code is equivalent to relocation application, and should run at the
1469 // earliest possible time (i.e. with the highest priority).
1470 appendToGlobalCtors(M, WeakInitializerFn, /* Priority */ 0);
1471 }
1472
1473 IRBuilder<> IRB(WeakInitializerFn->getEntryBlock().getTerminator());
1474 GV->setConstant(false);
1475 IRB.CreateAlignedStore(GV->getInitializer(), GV, GV->getAlign());
1477}
1478
1479void LowerTypeTestsModule::findGlobalVariableUsersOf(
1480 Constant *C, SmallSetVector<GlobalVariable *, 8> &Out) {
1481 for (auto *U : C->users()){
1482 if (auto *GV = dyn_cast<GlobalVariable>(U))
1483 Out.insert(GV);
1484 else if (auto *C2 = dyn_cast<Constant>(U))
1485 findGlobalVariableUsersOf(C2, Out);
1486 }
1487}
1488
1489// Replace all uses of F with (F ? JT : 0).
1490void LowerTypeTestsModule::replaceWeakDeclarationWithJumpTablePtr(
1491 Function *F, Constant *JT, bool IsJumpTableCanonical) {
1492 // The target expression can not appear in a constant initializer on most
1493 // (all?) targets. Switch to a runtime initializer.
1494 SmallSetVector<GlobalVariable *, 8> GlobalVarUsers;
1495 findGlobalVariableUsersOf(F, GlobalVarUsers);
1496 for (auto *GV : GlobalVarUsers) {
1497 if (GV == GlobalAnnotation)
1498 continue;
1499 moveInitializerToModuleConstructor(GV);
1500 }
1501
1502 // Can not RAUW F with an expression that uses F. Replace with a temporary
1503 // placeholder first.
1504 Function *PlaceholderFn =
1506 F->getAddressSpace(), "", &M);
1507 replaceCfiUses(F, PlaceholderFn, IsJumpTableCanonical);
1508
1510 // Don't use range based loop, because use list will be modified.
1511 while (!PlaceholderFn->use_empty()) {
1512 Use &U = *PlaceholderFn->use_begin();
1513 auto *InsertPt = dyn_cast<Instruction>(U.getUser());
1514 assert(InsertPt && "Non-instruction users should have been eliminated");
1515 auto *PN = dyn_cast<PHINode>(InsertPt);
1516 if (PN)
1517 InsertPt = PN->getIncomingBlock(U)->getTerminator();
1518 IRBuilder Builder(InsertPt);
1519 Value *ICmp = Builder.CreateICmp(CmpInst::ICMP_NE, F,
1520 Constant::getNullValue(F->getType()));
1521 Value *Select = Builder.CreateSelect(ICmp, JT,
1522 Constant::getNullValue(F->getType()));
1523
1524 if (auto *SI = dyn_cast<SelectInst>(Select))
1526 // For phi nodes, we need to update the incoming value for all operands
1527 // with the same predecessor.
1528 if (PN)
1529 PN->setIncomingValueForBlock(InsertPt->getParent(), Select);
1530 else
1531 U.set(Select);
1532 }
1533 PlaceholderFn->eraseFromParent();
1534}
1535
1536static bool isThumbFunction(Function *F, Triple::ArchType ModuleArch) {
1537 Attribute TFAttr = F->getFnAttribute("target-features");
1538 if (TFAttr.isValid()) {
1540 TFAttr.getValueAsString().split(Features, ',');
1541 for (StringRef Feature : Features) {
1542 if (Feature == "-thumb-mode")
1543 return false;
1544 else if (Feature == "+thumb-mode")
1545 return true;
1546 }
1547 }
1548
1549 return ModuleArch == Triple::thumb;
1550}
1551
1552// Each jump table must be either ARM or Thumb as a whole for the bit-test math
1553// to work. Pick one that matches the majority of members to minimize interop
1554// veneers inserted by the linker.
1555Triple::ArchType LowerTypeTestsModule::selectJumpTableArmEncoding(
1556 ArrayRef<GlobalTypeMember *> Functions) {
1557 if (Arch != Triple::arm && Arch != Triple::thumb)
1558 return Arch;
1559
1560 if (!CanUseThumbBWJumpTable && CanUseArmJumpTable) {
1561 // In architectures that provide Arm and Thumb-1 but not Thumb-2,
1562 // we should always prefer the Arm jump table format, because the
1563 // Thumb-1 one is larger and slower.
1564 return Triple::arm;
1565 }
1566
1567 // Otherwise, go with majority vote.
1568 unsigned ArmCount = 0, ThumbCount = 0;
1569 for (const auto GTM : Functions) {
1570 if (!GTM->isJumpTableCanonical()) {
1571 // PLT stubs are always ARM.
1572 // FIXME: This is the wrong heuristic for non-canonical jump tables.
1573 ++ArmCount;
1574 continue;
1575 }
1576
1577 Function *F = cast<Function>(GTM->getGlobal());
1578 ++(isThumbFunction(F, Arch) ? ThumbCount : ArmCount);
1579 }
1580
1581 return ArmCount > ThumbCount ? Triple::arm : Triple::thumb;
1582}
1583
1584// Create location for each function entry which should look like this:
1585// frame #0: c::c() (.cfi_jt) at sanitizer/ubsan_interface.h:0:0
1586// frame #1: __ubsan_check_cfi_icall_jt at sanitizer/ubsan_interface.h:0
1589 Module &M = *F->getParent();
1590 DICompileUnit *CU = nullptr;
1591 auto CUs = M.debug_compile_units();
1592 if (!CUs.empty())
1593 CU = *CUs.begin();
1594
1595 DIBuilder DIB(M, /*AllowUnresolved=*/true, CU);
1596 DIFile *File = DIB.createFile("ubsan_interface.h", "sanitizer");
1597 if (!CU) {
1598 // Synthetic module (like ld-temp.o), it frequently lacks a DICompileUnit
1599 // even if the rest of the program has debug info.
1600 CU = DIB.createCompileUnit(
1601 DISourceLanguageName(dwarf::DW_LANG_C), File, "llvm", true, "", 0, "",
1603 }
1604
1605 DISubroutineType *DIFnTy = DIB.createSubroutineType(nullptr);
1606
1607 DISubprogram *UbsanSP = DIB.createFunction(
1608 CU, "__ubsan_check_cfi_icall_jt", {}, File, 0, DIFnTy, 0,
1609 DINode::FlagArtificial, DISubprogram::SPFlagDefinition);
1610
1611 F->setSubprogram(UbsanSP);
1612
1613 DILocation *UbsanLoc = DILocation::get(M.getContext(), 0, 0, UbsanSP);
1614
1615 SmallVector<DILocation *> Locations;
1616 Locations.reserve(Functions.size());
1617
1618 for (auto *Func : Functions) {
1619 StringRef FuncName = Func->getGlobal()->getName();
1620 FuncName.consume_back(".cfi");
1621 DISubprogram *JumpSP = DIB.createFunction(
1622 CU, (FuncName + ".cfi_jt").str(), {}, File, 0, DIFnTy, 0,
1623 DINode::FlagArtificial, DISubprogram::SPFlagDefinition);
1624
1625 DILocation *EntryLoc =
1626 DILocation::get(M.getContext(), 0, 0, JumpSP, UbsanLoc);
1627
1628 Locations.push_back(EntryLoc);
1629 }
1630
1631 DIB.finalize();
1632
1633 return Locations;
1634}
1635
1636void LowerTypeTestsModule::createJumpTable(
1638 Triple::ArchType JumpTableArch) {
1639 unsigned JumpTableEntrySize = getJumpTableEntrySize(JumpTableArch);
1640 // Give the jumptable section this type in order to enable jumptable
1641 // relaxation. Only do this if cross-DSO CFI is disabled because jumptable
1642 // relaxation violates cross-DSO CFI's restrictions on the ordering of the
1643 // jumptable relative to other sections.
1644 if (!CrossDsoCfi)
1645 F->setMetadata(LLVMContext::MD_elf_section_properties,
1646 MDNode::get(F->getContext(),
1648 ConstantAsMetadata::get(ConstantInt::get(
1649 Int64Ty, ELF::SHT_LLVM_CFI_JUMP_TABLE)),
1650 ConstantAsMetadata::get(ConstantInt::get(
1651 Int64Ty, JumpTableEntrySize))}));
1652
1653 BasicBlock *BB = BasicBlock::Create(M.getContext(), "entry", F);
1654 IRBuilder<> IRB(BB);
1655
1657 if (M.getDwarfVersion() != 0 && EnableJumpTableDebugInfo)
1658 Locations = createJumpTableDebugInfo(F, Functions);
1659
1660 InlineAsm *JumpTableAsm = createJumpTableEntryAsm(JumpTableArch);
1661
1662 // Check if all entries have the NoUnwind attribute.
1663 // If all entries have it, we can safely mark the
1664 // cfi.jumptable as NoUnwind, otherwise, direct calls
1665 // to the jump table will not handle exceptions properly
1666 bool areAllEntriesNounwind = true;
1667 assert(Locations.empty() || Functions.size() == Locations.size());
1668 for (auto [GTM, Loc] : zip_longest(Functions, Locations)) {
1669 if (Loc.has_value())
1670 IRB.SetCurrentDebugLocation(*Loc);
1671 if (!cast<Function>((*GTM)->getGlobal())
1672 ->hasFnAttribute(Attribute::NoUnwind)) {
1673 areAllEntriesNounwind = false;
1674 }
1675 IRB.CreateCall(JumpTableAsm, (*GTM)->getGlobal());
1676 }
1677 IRB.CreateUnreachable();
1678
1679 // Align the whole table by entry size.
1680 F->setPreferredAlignment(Align(JumpTableEntrySize));
1681 F->addFnAttr(Attribute::Naked);
1682 if (JumpTableArch == Triple::arm)
1683 F->addFnAttr("target-features", "-thumb-mode");
1684 if (JumpTableArch == Triple::thumb) {
1685 if (hasBranchTargetEnforcement()) {
1686 // If we're generating a Thumb jump table with BTI, add a target-features
1687 // setting to ensure BTI can be assembled.
1688 F->addFnAttr("target-features", "+thumb-mode,+pacbti");
1689 } else {
1690 F->addFnAttr("target-features", "+thumb-mode");
1691 if (CanUseThumbBWJumpTable) {
1692 // Thumb jump table assembly needs Thumb2. The following attribute is
1693 // added by Clang for -march=armv7.
1694 F->addFnAttr("target-cpu", "cortex-a8");
1695 }
1696 }
1697 }
1698 // When -mbranch-protection= is used, the inline asm adds a BTI. Suppress BTI
1699 // for the function to avoid double BTI. This is a no-op without
1700 // -mbranch-protection=.
1701 if (JumpTableArch == Triple::aarch64 || JumpTableArch == Triple::thumb) {
1702 if (F->hasFnAttribute("branch-target-enforcement"))
1703 F->removeFnAttr("branch-target-enforcement");
1704 if (F->hasFnAttribute("sign-return-address"))
1705 F->removeFnAttr("sign-return-address");
1706 }
1707 if (JumpTableArch == Triple::riscv32 || JumpTableArch == Triple::riscv64) {
1708 // Make sure the jump table assembly is not modified by the assembler or
1709 // the linker.
1710 F->addFnAttr("target-features", "-c,-relax");
1711 }
1712 // When -fcf-protection= is used, the inline asm adds an ENDBR. Suppress ENDBR
1713 // for the function to avoid double ENDBR. This is a no-op without
1714 // -fcf-protection=.
1715 if (JumpTableArch == Triple::x86 || JumpTableArch == Triple::x86_64)
1716 F->addFnAttr(Attribute::NoCfCheck);
1717
1718 // Make sure we don't emit .eh_frame for this function if it isn't needed.
1719 if (areAllEntriesNounwind)
1720 F->addFnAttr(Attribute::NoUnwind);
1721
1722 // Make sure we do not inline any calls to the cfi.jumptable.
1723 F->addFnAttr(Attribute::NoInline);
1724}
1725
1726/// Given a disjoint set of type identifiers and functions, build a jump table
1727/// for the functions, build the bit sets and lower the llvm.type.test calls.
1728void LowerTypeTestsModule::buildBitSetsFromFunctionsNative(
1730 // Unlike the global bitset builder, the function bitset builder cannot
1731 // re-arrange functions in a particular order and base its calculations on the
1732 // layout of the functions' entry points, as we have no idea how large a
1733 // particular function will end up being (the size could even depend on what
1734 // this pass does!) Instead, we build a jump table, which is a block of code
1735 // consisting of one branch instruction for each of the functions in the bit
1736 // set that branches to the target function, and redirect any taken function
1737 // addresses to the corresponding jump table entry. In the object file's
1738 // symbol table, the symbols for the target functions also refer to the jump
1739 // table entries, so that addresses taken outside the module will pass any
1740 // verification done inside the module.
1741 //
1742 // In more concrete terms, suppose we have three functions f, g, h which are
1743 // of the same type, and a function foo that returns their addresses:
1744 //
1745 // f:
1746 // mov 0, %eax
1747 // ret
1748 //
1749 // g:
1750 // mov 1, %eax
1751 // ret
1752 //
1753 // h:
1754 // mov 2, %eax
1755 // ret
1756 //
1757 // foo:
1758 // mov f, %eax
1759 // mov g, %edx
1760 // mov h, %ecx
1761 // ret
1762 //
1763 // We output the jump table as module-level inline asm string. The end result
1764 // will (conceptually) look like this:
1765 //
1766 // f = .cfi.jumptable
1767 // g = .cfi.jumptable + 4
1768 // h = .cfi.jumptable + 8
1769 // .cfi.jumptable:
1770 // jmp f.cfi ; 5 bytes
1771 // int3 ; 1 byte
1772 // int3 ; 1 byte
1773 // int3 ; 1 byte
1774 // jmp g.cfi ; 5 bytes
1775 // int3 ; 1 byte
1776 // int3 ; 1 byte
1777 // int3 ; 1 byte
1778 // jmp h.cfi ; 5 bytes
1779 // int3 ; 1 byte
1780 // int3 ; 1 byte
1781 // int3 ; 1 byte
1782 //
1783 // f.cfi:
1784 // mov 0, %eax
1785 // ret
1786 //
1787 // g.cfi:
1788 // mov 1, %eax
1789 // ret
1790 //
1791 // h.cfi:
1792 // mov 2, %eax
1793 // ret
1794 //
1795 // foo:
1796 // mov f, %eax
1797 // mov g, %edx
1798 // mov h, %ecx
1799 // ret
1800 //
1801 // Because the addresses of f, g, h are evenly spaced at a power of 2, in the
1802 // normal case the check can be carried out using the same kind of simple
1803 // arithmetic that we normally use for globals.
1804
1805 // FIXME: find a better way to represent the jumptable in the IR.
1806 assert(!Functions.empty());
1807
1808 // Decide on the jump table encoding, so that we know how big the
1809 // entries will be.
1810 Triple::ArchType JumpTableArch = selectJumpTableArmEncoding(Functions);
1811
1812 // Build a simple layout based on the regular layout of jump tables.
1813 DenseMap<GlobalTypeMember *, uint64_t> GlobalLayout;
1814 unsigned EntrySize = getJumpTableEntrySize(JumpTableArch);
1815 for (unsigned I = 0; I != Functions.size(); ++I)
1816 GlobalLayout[Functions[I]] = I * EntrySize;
1817
1818 Function *JumpTableFn =
1820 /* IsVarArg */ false),
1822 M.getDataLayout().getProgramAddressSpace(),
1823 ".cfi.jumptable", &M);
1824 ArrayType *JumpTableEntryType = ArrayType::get(Int8Ty, EntrySize);
1826 ArrayType::get(JumpTableEntryType, Functions.size());
1828 JumpTableFn, PointerType::getUnqual(M.getContext()));
1829
1830 lowerTypeTestCalls(TypeIds, JumpTable, GlobalLayout);
1831
1832 // Build aliases pointing to offsets into the jump table, and replace
1833 // references to the original functions with references to the aliases.
1834 for (unsigned I = 0; I != Functions.size(); ++I) {
1835 Function *F = cast<Function>(Functions[I]->getGlobal());
1836 bool IsJumpTableCanonical = Functions[I]->isJumpTableCanonical();
1837
1838 Constant *CombinedGlobalElemPtr = ConstantExpr::getInBoundsGetElementPtr(
1839 JumpTableType, JumpTable,
1840 ArrayRef<Constant *>{ConstantInt::get(IntPtrTy, 0),
1841 ConstantInt::get(IntPtrTy, I)});
1842
1843 const bool IsExported = Functions[I]->isExported();
1844 if (!IsJumpTableCanonical) {
1847 GlobalAlias *JtAlias = GlobalAlias::create(JumpTableEntryType, 0, LT,
1848 F->getName() + ".cfi_jt",
1849 CombinedGlobalElemPtr, &M);
1850 if (IsExported)
1852 else
1853 appendToUsed(M, {JtAlias});
1854 }
1855
1856 if (IsExported) {
1857 GlobalValue::GUID GUID = F->getGUID();
1858 if (IsJumpTableCanonical)
1859 ExportSummary->cfiFunctionDefs().addSymbolWithThinLTOGUID(F->getName(),
1860 GUID);
1861 else
1862 ExportSummary->cfiFunctionDecls().addSymbolWithThinLTOGUID(F->getName(),
1863 GUID);
1864 }
1865
1866 if (!IsJumpTableCanonical) {
1867 if (F->hasExternalWeakLinkage())
1868 replaceWeakDeclarationWithJumpTablePtr(F, CombinedGlobalElemPtr,
1869 IsJumpTableCanonical);
1870 else
1871 replaceCfiUses(F, CombinedGlobalElemPtr, IsJumpTableCanonical);
1872 } else {
1873 assert(F->getType()->getAddressSpace() == 0);
1874
1875 GlobalAlias *FAlias =
1876 GlobalAlias::create(JumpTableEntryType, 0, F->getLinkage(), "",
1877 CombinedGlobalElemPtr, &M);
1878 FAlias->setVisibility(F->getVisibility());
1879 FAlias->setDSOLocal(F->isDSOLocal());
1880 FAlias->takeName(F);
1881 if (FAlias->hasName()) {
1882 F->setName(FAlias->getName() + ".cfi");
1883 maybeReplaceComdat(F, FAlias->getName());
1884 }
1885 replaceCfiUses(F, FAlias, IsJumpTableCanonical);
1886 if (!F->hasLocalLinkage())
1887 F->setVisibility(GlobalVariable::HiddenVisibility);
1888 }
1889 }
1890
1891 createJumpTable(JumpTableFn, Functions, JumpTableArch);
1892}
1893
1894/// Assign a dummy layout using an incrementing counter, tag each function
1895/// with its index represented as metadata, and lower each type test to an
1896/// integer range comparison. During generation of the indirect function call
1897/// table in the backend, it will assign the given indexes.
1898/// Note: Dynamic linking is not supported, as the WebAssembly ABI has not yet
1899/// been finalized.
1900void LowerTypeTestsModule::buildBitSetsFromFunctionsWASM(
1902 assert(!Functions.empty());
1903
1904 // Build consecutive monotonic integer ranges for each call target set
1905 DenseMap<GlobalTypeMember *, uint64_t> GlobalLayout;
1906
1907 for (GlobalTypeMember *GTM : Functions) {
1908 Function *F = cast<Function>(GTM->getGlobal());
1909
1910 // Skip functions that are not address taken, to avoid bloating the table
1911 if (!F->hasAddressTaken())
1912 continue;
1913
1914 // Store metadata with the index for each function
1915 MDNode *MD = MDNode::get(F->getContext(),
1917 ConstantInt::get(Int64Ty, IndirectIndex))));
1918 F->setMetadata("wasm.index", MD);
1919
1920 // Assign the counter value
1921 GlobalLayout[GTM] = IndirectIndex++;
1922 }
1923
1924 // The indirect function table index space starts at zero, so pass a NULL
1925 // pointer as the subtracted "jump table" offset.
1926 lowerTypeTestCalls(TypeIds, ConstantPointerNull::get(PtrTy),
1927 GlobalLayout);
1928}
1929
1930void LowerTypeTestsModule::buildBitSetsFromDisjointSet(
1932 ArrayRef<ICallBranchFunnel *> ICallBranchFunnels) {
1933 DenseMap<Metadata *, uint64_t> TypeIdIndices;
1934 for (unsigned I = 0; I != TypeIds.size(); ++I)
1935 TypeIdIndices[TypeIds[I]] = I;
1936
1937 // For each type identifier, build a set of indices that refer to members of
1938 // the type identifier.
1939 std::vector<std::set<uint64_t>> TypeMembers(TypeIds.size());
1940 unsigned GlobalIndex = 0;
1941 DenseMap<GlobalTypeMember *, uint64_t> GlobalIndices;
1942 for (GlobalTypeMember *GTM : Globals) {
1943 for (MDNode *Type : GTM->types()) {
1944 // Type = { offset, type identifier }
1945 auto I = TypeIdIndices.find(Type->getOperand(1));
1946 if (I != TypeIdIndices.end())
1947 TypeMembers[I->second].insert(GlobalIndex);
1948 }
1949 GlobalIndices[GTM] = GlobalIndex;
1950 GlobalIndex++;
1951 }
1952
1953 for (ICallBranchFunnel *JT : ICallBranchFunnels) {
1954 TypeMembers.emplace_back();
1955 std::set<uint64_t> &TMSet = TypeMembers.back();
1956 for (GlobalTypeMember *T : JT->targets())
1957 TMSet.insert(GlobalIndices[T]);
1958 }
1959
1960 // Order the sets of indices by size. The GlobalLayoutBuilder works best
1961 // when given small index sets first.
1962 llvm::stable_sort(TypeMembers, [](const std::set<uint64_t> &O1,
1963 const std::set<uint64_t> &O2) {
1964 return O1.size() < O2.size();
1965 });
1966
1967 // Create a GlobalLayoutBuilder and provide it with index sets as layout
1968 // fragments. The GlobalLayoutBuilder tries to lay out members of fragments as
1969 // close together as possible.
1970 GlobalLayoutBuilder GLB(Globals.size());
1971 for (auto &&MemSet : TypeMembers)
1972 GLB.addFragment(MemSet);
1973
1974 // Build a vector of globals with the computed layout.
1975 bool IsGlobalSet =
1976 Globals.empty() || isa<GlobalVariable>(Globals[0]->getGlobal());
1977 std::vector<GlobalTypeMember *> OrderedGTMs(Globals.size());
1978 auto OGTMI = OrderedGTMs.begin();
1979 for (uint64_t Offset : GLB.build()) {
1980 if (IsGlobalSet != isa<GlobalVariable>(Globals[Offset]->getGlobal()))
1981 report_fatal_error("Type identifier may not contain both global "
1982 "variables and functions");
1983 *OGTMI++ = Globals[Offset];
1984 }
1985
1986 // Build the bitsets from this disjoint set.
1987 if (IsGlobalSet)
1988 buildBitSetsFromGlobalVariables(TypeIds, OrderedGTMs);
1989 else
1990 buildBitSetsFromFunctions(TypeIds, OrderedGTMs);
1991}
1992
1993/// Lower all type tests in this module.
1994LowerTypeTestsModule::LowerTypeTestsModule(
1995 Module &M, ModuleAnalysisManager &AM, ModuleSummaryIndex *ExportSummary,
1996 const ModuleSummaryIndex *ImportSummary)
1997 : M(M), ExportSummary(ExportSummary), ImportSummary(ImportSummary) {
1998 assert(!(ExportSummary && ImportSummary));
1999 Triple TargetTriple(M.getTargetTriple());
2000 Arch = TargetTriple.getArch();
2001 if (Arch == Triple::arm)
2002 CanUseArmJumpTable = true;
2003 if (Arch == Triple::arm || Arch == Triple::thumb) {
2004 auto &FAM =
2006 for (Function &F : M) {
2007 // Skip declarations since we should not query the TTI for them.
2008 if (F.isDeclaration())
2009 continue;
2010 auto &TTI = FAM.getResult<TargetIRAnalysis>(F);
2011 if (TTI.hasArmWideBranch(false))
2012 CanUseArmJumpTable = true;
2013 if (TTI.hasArmWideBranch(true))
2014 CanUseThumbBWJumpTable = true;
2015 }
2016 }
2017 OS = TargetTriple.getOS();
2018 ObjectFormat = TargetTriple.getObjectFormat();
2019
2020 // Function annotation describes or applies to function itself, and
2021 // shouldn't be associated with jump table thunk generated for CFI.
2022 GlobalAnnotation = M.getGlobalVariable("llvm.global.annotations");
2023 if (GlobalAnnotation && GlobalAnnotation->hasInitializer()) {
2024 const ConstantArray *CA =
2025 cast<ConstantArray>(GlobalAnnotation->getInitializer());
2026 FunctionAnnotations.insert_range(CA->operands());
2027 }
2028}
2029
2030bool LowerTypeTestsModule::runForTesting(Module &M, ModuleAnalysisManager &AM) {
2031 std::unique_ptr<ModuleSummaryIndex> Summary;
2032
2033 // Handle the command-line summary arguments. This code is for testing
2034 // purposes only, so we handle errors directly.
2035 if (!ClReadSummary.empty()) {
2036 ExitOnError ExitOnErr("-lowertypetests-read-summary: " + ClReadSummary +
2037 ": ");
2038 auto ReadSummaryFile = ExitOnErr(errorOrToExpected(
2039 MemoryBuffer::getFile(ClReadSummary, /*IsText=*/true)));
2040 // TODO: Convert the rest of tests (some YAML features are missing from
2041 // textual summary assembly) and remove YAML from this file.
2042 if (ReadSummaryFile->getBuffer().starts_with("---")) {
2043 Summary = std::make_unique<ModuleSummaryIndex>(/*HaveGVs=*/false);
2044 yaml::Input In(ReadSummaryFile->getBuffer());
2045 In >> *Summary;
2046 ExitOnErr(errorCodeToError(In.error()));
2047 } else {
2048 SMDiagnostic Err;
2049 Summary =
2050 parseSummaryIndexAssembly(ReadSummaryFile->getMemBufferRef(), Err);
2051 if (!Summary) {
2052 Err.print(ClReadSummary.c_str(), errs());
2053 report_fatal_error("Failed to parse summary index assembly");
2054 }
2055 }
2056 } else {
2057 Summary = std::make_unique<ModuleSummaryIndex>(/*HaveGVs=*/false);
2058 }
2059
2060 bool Changed =
2061 LowerTypeTestsModule(
2062 M, AM,
2063 ClSummaryAction == PassSummaryAction::Export ? Summary.get()
2064 : nullptr,
2065 ClSummaryAction == PassSummaryAction::Import ? Summary.get()
2066 : nullptr)
2067 .lower();
2068
2069 if (!ClWriteSummary.empty()) {
2070 ExitOnError ExitOnErr("-lowertypetests-write-summary: " + ClWriteSummary +
2071 ": ");
2072 std::error_code EC;
2073 raw_fd_ostream OS(ClWriteSummary, EC, sys::fs::OF_TextWithCRLF);
2074 ExitOnErr(errorCodeToError(EC));
2075
2076 yaml::Output Out(OS);
2077 Out << *Summary;
2078 }
2079
2080 return Changed;
2081}
2082
2083static bool isDirectCall(Use& U) {
2084 auto *Usr = dyn_cast<CallInst>(U.getUser());
2085 return Usr && Usr->isCallee(&U);
2086}
2087
2088void LowerTypeTestsModule::replaceCfiUses(Function *Old, Value *New,
2089 bool IsJumpTableCanonical) {
2090 SmallSetVector<Constant *, 4> Constants;
2091 for (Use &U : llvm::make_early_inc_range(Old->uses())) {
2092 // Skip no_cfi values, which refer to the function body instead of the jump
2093 // table.
2094 if (isa<NoCFIValue>(U.getUser()))
2095 continue;
2096
2097 // Skip direct calls to externally defined or dso_local functions.
2098 if (isDirectCall(U) && (Old->isDSOLocal() || !IsJumpTableCanonical))
2099 continue;
2100
2101 // Skip function annotation.
2102 if (isFunctionAnnotation(U.getUser()))
2103 continue;
2104
2105 // Must handle Constants specially, we cannot call replaceUsesOfWith on a
2106 // constant because they are uniqued.
2107 if (auto *C = dyn_cast<Constant>(U.getUser())) {
2108 if (!isa<GlobalValue>(C)) {
2109 // Save unique users to avoid processing operand replacement
2110 // more than once.
2111 Constants.insert(C);
2112 continue;
2113 }
2114 }
2115
2116 U.set(New);
2117 }
2118
2119 // Process operand replacement of saved constants.
2120 for (auto *C : Constants)
2121 C->handleOperandChange(Old, New);
2122}
2123
2124void LowerTypeTestsModule::replaceDirectCalls(Value *Old, Value *New) {
2126}
2127
2128static void dropTypeTests(Module &M, Function &TypeTestFunc,
2129 bool ShouldDropAll) {
2130 for (Use &U : llvm::make_early_inc_range(TypeTestFunc.uses())) {
2131 auto *CI = cast<CallInst>(U.getUser());
2132 // Find and erase llvm.assume intrinsics for this llvm.type.test call.
2133 for (Use &CIU : llvm::make_early_inc_range(CI->uses()))
2134 if (auto *Assume = dyn_cast<AssumeInst>(CIU.getUser()))
2135 Assume->eraseFromParent();
2136 // If the assume was merged with another assume, we might have a use on a
2137 // phi or select (which will feed the assume). Simply replace the use on
2138 // the phi/select with "true" and leave the merged assume.
2139 //
2140 // If ShouldDropAll is set, then we we need to update any remaining uses,
2141 // regardless of the instruction type.
2142 if (!CI->use_empty()) {
2143 assert(ShouldDropAll || all_of(CI->users(), [](User *U) -> bool {
2144 return isa<PHINode>(U) || isa<SelectInst>(U);
2145 }));
2146 CI->replaceAllUsesWith(ConstantInt::getTrue(M.getContext()));
2147 }
2148 CI->eraseFromParent();
2149 }
2150}
2151
2152static bool dropTypeTests(Module &M, bool ShouldDropAll) {
2153 Function *TypeTestFunc =
2154 Intrinsic::getDeclarationIfExists(&M, Intrinsic::type_test);
2155 if (TypeTestFunc)
2156 dropTypeTests(M, *TypeTestFunc, ShouldDropAll);
2157 // Normally we'd have already removed all @llvm.public.type.test calls,
2158 // except for in the case where we originally were performing ThinLTO but
2159 // decided not to in the backend.
2160 Function *PublicTypeTestFunc =
2161 Intrinsic::getDeclarationIfExists(&M, Intrinsic::public_type_test);
2162 if (PublicTypeTestFunc)
2163 dropTypeTests(M, *PublicTypeTestFunc, ShouldDropAll);
2164 if (TypeTestFunc || PublicTypeTestFunc) {
2165 // We have deleted the type intrinsics, so we no longer have enough
2166 // information to reason about the liveness of virtual function pointers
2167 // in GlobalDCE.
2168 for (GlobalVariable &GV : M.globals())
2169 GV.eraseMetadata(LLVMContext::MD_vcall_visibility);
2170 return true;
2171 }
2172 return false;
2173}
2174
2175bool LowerTypeTestsModule::lower() {
2176 Function *TypeTestFunc =
2177 Intrinsic::getDeclarationIfExists(&M, Intrinsic::type_test);
2178
2179 // If only some of the modules were split, we cannot correctly perform
2180 // this transformation. We already checked for the presense of type tests
2181 // with partially split modules during the thin link, and would have emitted
2182 // an error if any were found, so here we can simply return.
2183 if ((ExportSummary && ExportSummary->partiallySplitLTOUnits()) ||
2184 (ImportSummary && ImportSummary->partiallySplitLTOUnits()))
2185 return false;
2186
2187 Function *ICallBranchFunnelFunc =
2188 Intrinsic::getDeclarationIfExists(&M, Intrinsic::icall_branch_funnel);
2189 if ((!TypeTestFunc || TypeTestFunc->use_empty()) &&
2190 (!ICallBranchFunnelFunc || ICallBranchFunnelFunc->use_empty()) &&
2191 !ExportSummary && !ImportSummary)
2192 return false;
2193
2194 if (ImportSummary) {
2195 if (TypeTestFunc)
2196 for (Use &U : llvm::make_early_inc_range(TypeTestFunc->uses()))
2197 importTypeTest(cast<CallInst>(U.getUser()));
2198
2199 if (ICallBranchFunnelFunc && !ICallBranchFunnelFunc->use_empty())
2201 "unexpected call to llvm.icall.branch.funnel during import phase");
2202
2205 for (auto &F : M) {
2206 // CFI functions are either external, or promoted. A local function may
2207 // have the same name, but it's not the one we are looking for.
2208 if (F.hasLocalLinkage())
2209 continue;
2210 if (ImportSummary->cfiFunctionDefs().contains(F.getName()))
2211 Defs.push_back(&F);
2212 else if (ImportSummary->cfiFunctionDecls().contains(F.getName()))
2213 Decls.push_back(&F);
2214 }
2215
2216 {
2217 ScopedSaveAliaseesAndUsed S(M);
2218 for (auto *F : Defs)
2219 importFunction(F, /*isJumpTableCanonical*/ true);
2220 for (auto *F : Decls)
2221 importFunction(F, /*isJumpTableCanonical*/ false);
2222 }
2223
2224 return true;
2225 }
2226
2227 // Equivalence class set containing type identifiers and the globals that
2228 // reference them. This is used to partition the set of type identifiers in
2229 // the module into disjoint sets.
2230 using GlobalClassesTy = EquivalenceClasses<
2231 PointerUnion<GlobalTypeMember *, Metadata *, ICallBranchFunnel *>>;
2232 GlobalClassesTy GlobalClasses;
2233
2234 // Verify the type metadata and build a few data structures to let us
2235 // efficiently enumerate the type identifiers associated with a global:
2236 // a list of GlobalTypeMembers (a GlobalObject stored alongside a vector
2237 // of associated type metadata) and a mapping from type identifiers to their
2238 // list of GlobalTypeMembers and last observed index in the list of globals.
2239 // The indices will be used later to deterministically order the list of type
2240 // identifiers.
2242 struct TIInfo {
2243 unsigned UniqueId;
2244 std::vector<GlobalTypeMember *> RefGlobals;
2245 };
2246 DenseMap<Metadata *, TIInfo> TypeIdInfo;
2247 unsigned CurUniqueId = 0;
2249
2250 struct ExportedFunctionInfo {
2252 MDNode *FuncMD; // {name, linkage, type[, type...]}
2253 };
2254 MapVector<StringRef, ExportedFunctionInfo> ExportedFunctions;
2255 if (ExportSummary) {
2256 NamedMDNode *CfiFunctionsMD = M.getNamedMetadata("cfi.functions");
2257 if (CfiFunctionsMD) {
2258 // A set of all functions that are address taken by a live global object.
2259 DenseSet<GlobalValue::GUID> AddressTaken;
2260 for (auto &I : *ExportSummary)
2261 for (auto &GVS : I.second.getSummaryList())
2262 if (GVS->isLive())
2263 for (const auto &Ref : GVS->refs()) {
2264 AddressTaken.insert(Ref.getGUID());
2265 for (auto &RefGVS : Ref.getSummaryList())
2266 if (auto Alias = dyn_cast<AliasSummary>(RefGVS.get()))
2267 AddressTaken.insert(Alias->getAliaseeGUID());
2268 }
2270 if (AddressTaken.count(GUID))
2271 return true;
2272 auto VI = ExportSummary->getValueInfo(GUID);
2273 if (!VI)
2274 return false;
2275 for (auto &I : VI.getSummaryList())
2276 if (auto Alias = dyn_cast<AliasSummary>(I.get()))
2277 if (AddressTaken.count(Alias->getAliaseeGUID()))
2278 return true;
2279 return false;
2280 };
2281 for (auto *FuncMD : CfiFunctionsMD->operands()) {
2282 assert(FuncMD->getNumOperands() >= 2);
2283 StringRef FunctionName =
2284 cast<MDString>(FuncMD->getOperand(0))->getString();
2286 cast<ConstantAsMetadata>(FuncMD->getOperand(1))
2287 ->getValue()
2288 ->getUniqueInteger()
2289 .getZExtValue());
2290 const GlobalValue::GUID GUID =
2291 cast<ConstantAsMetadata>(FuncMD->getOperand(2))
2292 ->getValue()
2293 ->getUniqueInteger()
2294 .getZExtValue();
2295 // Do not emit jumptable entries for functions that are not-live and
2296 // have no live references (and are not exported with cross-DSO CFI.)
2297 if (!ExportSummary->isGUIDLive(GUID))
2298 continue;
2299 if (!IsAddressTaken(GUID)) {
2300 if (!CrossDsoCfi || Linkage != CFL_Definition)
2301 continue;
2302
2303 bool Exported = false;
2304 if (auto VI = ExportSummary->getValueInfo(GUID))
2305 for (const auto &GVS : VI.getSummaryList())
2306 if (GVS->isLive() && !GlobalValue::isLocalLinkage(GVS->linkage()))
2307 Exported = true;
2308
2309 if (!Exported)
2310 continue;
2311 }
2312 auto P = ExportedFunctions.insert({FunctionName, {Linkage, FuncMD}});
2313 if (!P.second && P.first->second.Linkage != CFL_Definition)
2314 P.first->second = {Linkage, FuncMD};
2315 }
2316
2317 for (const auto &P : ExportedFunctions) {
2318 StringRef FunctionName = P.first;
2319 CfiFunctionLinkage Linkage = P.second.Linkage;
2320 MDNode *FuncMD = P.second.FuncMD;
2321 Function *F = M.getFunction(FunctionName);
2322 if (F && F->hasLocalLinkage()) {
2323 // Locally defined function that happens to have the same name as a
2324 // function defined in a ThinLTO module. Rename it to move it out of
2325 // the way of the external reference that we're about to create.
2326 // Note that setName will find a unique name for the function, so even
2327 // if there is an existing function with the suffix there won't be a
2328 // name collision.
2329 F->setName(F->getName() + ".1");
2330 F = nullptr;
2331 }
2332
2333 if (!F) {
2335 FunctionType::get(Type::getVoidTy(M.getContext()), false),
2336 GlobalVariable::ExternalLinkage,
2337 M.getDataLayout().getProgramAddressSpace(), FunctionName, &M);
2338 F->setMetadata(
2339 LLVMContext::MD_guid,
2340 MDTuple::get(M.getContext(), {FuncMD->getOperand(2).get()}));
2341 if (ExportSummary) {
2344 ->getValue()
2345 ->getUniqueInteger()
2346 .getZExtValue();
2347 if (auto VI = ExportSummary->getValueInfo(GUID))
2348 F->setDSOLocal(
2349 VI.isDSOLocal(ExportSummary->withDSOLocalPropagation()));
2350 }
2351 }
2352 // If the function is available_externally, remove its definition so
2353 // that it is handled the same way as a declaration. Later we will try
2354 // to create an alias using this function's linkage, which will fail if
2355 // the linkage is available_externally. This will also result in us
2356 // following the code path below to replace the type metadata.
2357 if (F->hasAvailableExternallyLinkage()) {
2358 // Maintain !guid metadata.
2359 auto *OrigGUIDMD = F->getMetadata(LLVMContext::MD_guid);
2360 F->setLinkage(GlobalValue::ExternalLinkage);
2361 F->deleteBody();
2362 F->setComdat(nullptr);
2363 F->clearMetadata();
2364 F->setMetadata(LLVMContext::MD_guid, OrigGUIDMD);
2365 }
2366
2367 // Update the linkage for extern_weak declarations when a definition
2368 // exists.
2369 if (Linkage == CFL_Definition && F->hasExternalWeakLinkage())
2370 F->setLinkage(GlobalValue::ExternalLinkage);
2371
2372 // If the function in the full LTO module is a declaration, replace its
2373 // type metadata with the type metadata we found in cfi.functions. That
2374 // metadata is presumed to be more accurate than the metadata attached
2375 // to the declaration.
2376 if (F->isDeclaration()) {
2379
2380 F->eraseMetadata(LLVMContext::MD_type);
2381 for (unsigned I = 3; I < FuncMD->getNumOperands(); ++I)
2382 F->addMetadata(LLVMContext::MD_type,
2383 *cast<MDNode>(FuncMD->getOperand(I).get()));
2384 }
2385 }
2386 }
2387 }
2388
2389 struct AliasToCreate {
2390 Function *Alias;
2391 std::string TargetName;
2392 };
2393 std::vector<AliasToCreate> AliasesToCreate;
2394
2395 // Parse alias data to replace stand-in function declarations for aliases
2396 // with an alias to the intended target.
2397 if (ExportSummary) {
2398 if (NamedMDNode *AliasesMD = M.getNamedMetadata("aliases")) {
2399 for (auto *AliasMD : AliasesMD->operands()) {
2401 for (Metadata *MD : AliasMD->operands()) {
2402 auto *MDS = dyn_cast<MDString>(MD);
2403 if (!MDS)
2404 continue;
2405 StringRef AliasName = MDS->getString();
2406 if (!ExportedFunctions.count(AliasName))
2407 continue;
2408 auto *AliasF = M.getFunction(AliasName);
2409 if (AliasF)
2410 Aliases.push_back(AliasF);
2411 }
2412
2413 if (Aliases.empty())
2414 continue;
2415
2416 for (unsigned I = 1; I != Aliases.size(); ++I) {
2417 auto *AliasF = Aliases[I];
2418 ExportedFunctions.erase(AliasF->getName());
2419 AliasesToCreate.push_back(
2420 {AliasF, std::string(Aliases[0]->getName())});
2421 }
2422 }
2423 }
2424 }
2425
2426 DenseMap<GlobalObject *, GlobalTypeMember *> GlobalTypeMembers;
2427 for (GlobalObject &GO : M.global_objects()) {
2429 continue;
2430
2431 Types.clear();
2432 GO.getMetadata(LLVMContext::MD_type, Types);
2433
2434 bool IsJumpTableCanonical = false;
2435 bool IsExported = false;
2436 if (Function *F = dyn_cast<Function>(&GO)) {
2437 IsJumpTableCanonical = isJumpTableCanonical(F);
2438 if (auto It = ExportedFunctions.find(F->getName());
2439 It != ExportedFunctions.end()) {
2440 IsJumpTableCanonical |= It->second.Linkage == CFL_Definition;
2441 IsExported = true;
2442 // TODO: The logic here checks only that the function is address taken,
2443 // not that the address takers are live. This can be updated to check
2444 // their liveness and emit fewer jumptable entries once monolithic LTO
2445 // builds also emit summaries.
2446 } else if (!F->hasAddressTaken()) {
2447 if (!CrossDsoCfi || !IsJumpTableCanonical || F->hasLocalLinkage())
2448 continue;
2449 }
2450 }
2451
2452 auto *GTM = GlobalTypeMember::create(Alloc, &GO, IsJumpTableCanonical,
2453 IsExported, Types);
2454 GlobalTypeMembers[&GO] = GTM;
2455 for (MDNode *Type : Types) {
2456 verifyTypeMDNode(&GO, Type);
2457 auto &Info = TypeIdInfo[Type->getOperand(1)];
2458 Info.UniqueId = ++CurUniqueId;
2459 Info.RefGlobals.push_back(GTM);
2460 }
2461 }
2462
2463 auto AddTypeIdUse = [&](Metadata *TypeId) -> TypeIdUserInfo & {
2464 // Add the call site to the list of call sites for this type identifier. We
2465 // also use TypeIdUsers to keep track of whether we have seen this type
2466 // identifier before. If we have, we don't need to re-add the referenced
2467 // globals to the equivalence class.
2468 auto Ins = TypeIdUsers.insert({TypeId, {}});
2469 if (Ins.second) {
2470 // Add the type identifier to the equivalence class.
2471 auto &GCI = GlobalClasses.insert(TypeId);
2472 GlobalClassesTy::member_iterator CurSet = GlobalClasses.findLeader(GCI);
2473
2474 // Add the referenced globals to the type identifier's equivalence class.
2475 for (GlobalTypeMember *GTM : TypeIdInfo[TypeId].RefGlobals)
2476 CurSet = GlobalClasses.unionSets(
2477 CurSet, GlobalClasses.findLeader(GlobalClasses.insert(GTM)));
2478 }
2479
2480 return Ins.first->second;
2481 };
2482
2483 if (TypeTestFunc) {
2484 for (const Use &U : TypeTestFunc->uses()) {
2485 auto CI = cast<CallInst>(U.getUser());
2486 // If this type test is only used by llvm.assume instructions, it
2487 // was used for whole program devirtualization, and is being kept
2488 // for use by other optimization passes. We do not need or want to
2489 // lower it here. We also don't want to rewrite any associated globals
2490 // unnecessarily. These will be removed by a subsequent LTT invocation
2491 // with the DropTypeTests flag set.
2492 bool OnlyAssumeUses = !CI->use_empty();
2493 for (const Use &CIU : CI->uses()) {
2494 if (isa<AssumeInst>(CIU.getUser()))
2495 continue;
2496 OnlyAssumeUses = false;
2497 break;
2498 }
2499 if (OnlyAssumeUses)
2500 continue;
2501
2502 auto TypeIdMDVal = dyn_cast<MetadataAsValue>(CI->getArgOperand(1));
2503 if (!TypeIdMDVal)
2504 report_fatal_error("Second argument of llvm.type.test must be metadata");
2505 auto TypeId = TypeIdMDVal->getMetadata();
2506 AddTypeIdUse(TypeId).CallSites.push_back(CI);
2507 }
2508 }
2509
2510 if (ICallBranchFunnelFunc) {
2511 for (const Use &U : ICallBranchFunnelFunc->uses()) {
2512 if (Arch != Triple::x86_64)
2514 "llvm.icall.branch.funnel not supported on this target");
2515
2516 auto CI = cast<CallInst>(U.getUser());
2517
2518 std::vector<GlobalTypeMember *> Targets;
2519 if (CI->arg_size() % 2 != 1)
2520 report_fatal_error("number of arguments should be odd");
2521
2522 GlobalClassesTy::member_iterator CurSet;
2523 for (unsigned I = 1; I != CI->arg_size(); I += 2) {
2524 int64_t Offset;
2526 CI->getOperand(I), Offset, M.getDataLayout()));
2527 if (!Base)
2529 "Expected branch funnel operand to be global value");
2530
2531 auto It = GlobalTypeMembers.find(Base);
2532 if (It == GlobalTypeMembers.end())
2533 reportFatalUsageError("Expected branch funnel operand to be a "
2534 "defined global value with type metadata");
2535 GlobalTypeMember *GTM = It->second;
2536 Targets.push_back(GTM);
2537 GlobalClassesTy::member_iterator NewSet =
2538 GlobalClasses.findLeader(GlobalClasses.insert(GTM));
2539 if (I == 1)
2540 CurSet = NewSet;
2541 else
2542 CurSet = GlobalClasses.unionSets(CurSet, NewSet);
2543 }
2544
2545 GlobalClasses.unionSets(
2546 CurSet, GlobalClasses.findLeader(
2547 GlobalClasses.insert(ICallBranchFunnel::create(
2548 Alloc, CI, Targets, ++CurUniqueId))));
2549 }
2550 }
2551
2552 if (ExportSummary) {
2553 DenseMap<GlobalValue::GUID, TinyPtrVector<Metadata *>> MetadataByGUID;
2554 for (auto &P : TypeIdInfo) {
2555 if (auto *TypeId = dyn_cast<MDString>(P.first))
2557 TypeId->getString())]
2558 .push_back(TypeId);
2559 }
2560
2561 for (auto &P : *ExportSummary) {
2562 for (auto &S : P.second.getSummaryList()) {
2563 if (!ExportSummary->isGlobalValueLive(S.get()))
2564 continue;
2565 if (auto *FS = dyn_cast<FunctionSummary>(S->getBaseObject()))
2566 for (GlobalValue::GUID G : FS->type_tests())
2567 for (Metadata *MD : MetadataByGUID[G])
2568 AddTypeIdUse(MD).IsExported = true;
2569 }
2570 }
2571 }
2572
2573 if (GlobalClasses.empty())
2574 return false;
2575
2576 {
2577 ScopedSaveAliaseesAndUsed S(M);
2578 // For each disjoint set we found...
2579 for (const auto &C : GlobalClasses) {
2580 if (!C->isLeader())
2581 continue;
2582
2583 ++NumTypeIdDisjointSets;
2584 // Build the list of type identifiers in this disjoint set.
2585 std::vector<Metadata *> TypeIds;
2586 std::vector<GlobalTypeMember *> Globals;
2587 std::vector<ICallBranchFunnel *> ICallBranchFunnels;
2588 for (auto M : GlobalClasses.members(*C)) {
2589 if (isa<Metadata *>(M))
2590 TypeIds.push_back(cast<Metadata *>(M));
2591 else if (isa<GlobalTypeMember *>(M))
2592 Globals.push_back(cast<GlobalTypeMember *>(M));
2593 else
2594 ICallBranchFunnels.push_back(cast<ICallBranchFunnel *>(M));
2595 }
2596
2597 // Order type identifiers by unique ID for determinism. This ordering is
2598 // stable as there is a one-to-one mapping between metadata and unique
2599 // IDs.
2600 llvm::sort(TypeIds, [&](Metadata *M1, Metadata *M2) {
2601 return TypeIdInfo[M1].UniqueId < TypeIdInfo[M2].UniqueId;
2602 });
2603
2604 // Same for the branch funnels.
2605 llvm::sort(ICallBranchFunnels,
2606 [&](ICallBranchFunnel *F1, ICallBranchFunnel *F2) {
2607 return F1->UniqueId < F2->UniqueId;
2608 });
2609
2610 // Build bitsets for this disjoint set.
2611 buildBitSetsFromDisjointSet(TypeIds, Globals, ICallBranchFunnels);
2612 }
2613 }
2614
2615 allocateByteArrays();
2616
2617 for (auto A : AliasesToCreate) {
2618 auto *Target = M.getNamedValue(A.TargetName);
2619 if (!isa<GlobalAlias>(Target))
2620 continue;
2621 auto *AliasGA = GlobalAlias::create("", Target);
2622 AliasGA->setVisibility(A.Alias->getVisibility());
2623 AliasGA->setLinkage(A.Alias->getLinkage());
2624 AliasGA->setDSOLocal(A.Alias->isDSOLocal());
2625 AliasGA->takeName(A.Alias);
2626 A.Alias->replaceAllUsesWith(AliasGA);
2627 A.Alias->eraseFromParent();
2628 }
2629
2630 // Emit .symver directives for exported functions, if they exist.
2631 if (ExportSummary) {
2632 if (NamedMDNode *SymversMD = M.getNamedMetadata("symvers")) {
2633 for (auto *Symver : SymversMD->operands()) {
2634 assert(Symver->getNumOperands() >= 2);
2635 StringRef SymbolName =
2636 cast<MDString>(Symver->getOperand(0))->getString();
2637 StringRef Alias = cast<MDString>(Symver->getOperand(1))->getString();
2638
2639 if (!ExportedFunctions.count(SymbolName))
2640 continue;
2641
2642 M.appendModuleInlineAsm(
2643 (llvm::Twine(".symver ") + SymbolName + ", " + Alias).str());
2644 }
2645 }
2646 }
2647
2648 return true;
2649}
2650
2653 bool Changed;
2654 if (UseCommandLine)
2655 Changed = LowerTypeTestsModule::runForTesting(M, AM);
2656 else
2657 Changed = LowerTypeTestsModule(M, AM, ExportSummary, ImportSummary).lower();
2658 if (!Changed)
2659 return PreservedAnalyses::all();
2660 return PreservedAnalyses::none();
2661}
2662
2664 raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {
2665 static_cast<PassInfoMixin<DropTypeTestsPass> *>(this)->printPipeline(
2666 OS, MapClassName2PassName);
2667 OS << '<';
2668 switch (Kind) {
2669 case DropTestKind::Assume:
2670 OS << "assume";
2671 break;
2672 case DropTestKind::All:
2673 OS << "all";
2674 break;
2675 }
2676 OS << '>';
2677}
2678
2683
2686 bool Changed = false;
2687 // Figure out whether inlining has exposed a constant address to a lowered
2688 // type test, and remove the test if so and the address is known to pass the
2689 // test. Unfortunately this pass ends up needing to reverse engineer what
2690 // LowerTypeTests did; this is currently inherent to the design of ThinLTO
2691 // importing where LowerTypeTests needs to run at the start.
2692 //
2693 // We look for things like:
2694 //
2695 // sub (i64 ptrtoint (ptr @_Z2fpv to i64), i64 ptrtoint (ptr
2696 // @__typeid__ZTSFvvE_global_addr to i64))
2697 //
2698 // which gets replaced with 0 if _Z2fpv (more specifically _Z2fpv.cfi, the
2699 // function referred to by the jump table) is a member of the type _ZTSFvv, as
2700 // well as things like
2701 //
2702 // icmp eq ptr @_Z2fpv, @__typeid__ZTSFvvE_global_addr
2703 //
2704 // which gets replaced with true if _Z2fpv is a member.
2705 for (auto &GV : M.globals()) {
2706 if (!GV.getName().starts_with("__typeid_") ||
2707 !GV.getName().ends_with("_global_addr"))
2708 continue;
2709 // __typeid_foo_global_addr -> foo
2710 auto *MD = MDString::get(M.getContext(),
2711 GV.getName().substr(9, GV.getName().size() - 21));
2712 auto MaySimplifyPtr = [&](Value *Ptr) {
2713 if (auto *GV = dyn_cast<GlobalValue>(Ptr))
2714 if (auto *CFIGV = M.getNamedValue((GV->getName() + ".cfi").str()))
2715 Ptr = CFIGV;
2716 return isKnownTypeIdMember(MD, M.getDataLayout(), Ptr, 0);
2717 };
2718 auto MaySimplifyInt = [&](Value *Op) {
2719 auto *PtrAsInt = dyn_cast<ConstantExpr>(Op);
2720 if (!PtrAsInt || PtrAsInt->getOpcode() != Instruction::PtrToInt)
2721 return false;
2722 return MaySimplifyPtr(PtrAsInt->getOperand(0));
2723 };
2724 for (User *U : make_early_inc_range(GV.users())) {
2725 if (auto *CI = dyn_cast<ICmpInst>(U)) {
2726 if (CI->getPredicate() == CmpInst::ICMP_EQ &&
2727 MaySimplifyPtr(CI->getOperand(0))) {
2728 // This is an equality comparison (TypeTestResolution::Single case in
2729 // lowerTypeTestCall). In this case we just replace the comparison
2730 // with true.
2731 CI->replaceAllUsesWith(ConstantInt::getTrue(M.getContext()));
2732 CI->eraseFromParent();
2733 Changed = true;
2734 continue;
2735 }
2736 }
2737 auto *CE = dyn_cast<ConstantExpr>(U);
2738 if (!CE || CE->getOpcode() != Instruction::PtrToInt)
2739 continue;
2740 for (Use &U : make_early_inc_range(CE->uses())) {
2741 auto *CE = dyn_cast<ConstantExpr>(U.getUser());
2742 if (U.getOperandNo() == 0 && CE &&
2743 CE->getOpcode() == Instruction::Sub &&
2744 MaySimplifyInt(CE->getOperand(1))) {
2745 // This is a computation of PtrOffset as generated by
2746 // LowerTypeTestsModule::lowerTypeTestCall above. If
2747 // isKnownTypeIdMember passes we just pretend it evaluated to 0. This
2748 // should cause later passes to remove the range and alignment checks.
2749 // The bitset checks won't be removed but those are uncommon.
2750 CE->replaceAllUsesWith(ConstantInt::get(CE->getType(), 0));
2751 Changed = true;
2752 }
2753 auto *CI = dyn_cast<ICmpInst>(U.getUser());
2754 if (U.getOperandNo() == 1 && CI &&
2755 CI->getPredicate() == CmpInst::ICMP_EQ &&
2756 MaySimplifyInt(CI->getOperand(0))) {
2757 // This is an equality comparison. Unlike in the case above it
2758 // remained as an integer compare.
2759 CI->replaceAllUsesWith(ConstantInt::getTrue(M.getContext()));
2760 CI->eraseFromParent();
2761 Changed = true;
2762 }
2763 }
2764 }
2765 }
2766
2767 if (!Changed)
2768 return PreservedAnalyses::all();
2772 PA.preserve<LoopAnalysis>();
2773 return PA;
2774}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
unsigned 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...
#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 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 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 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 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 bool isDirectCall(Use &U)
static const unsigned kARMv6MJumpTableEntrySize
static const unsigned kHexagonJumpTableEntrySize
#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 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...
Class for arbitrary precision integers.
Definition APInt.h:78
uint64_t getZExtValue() const
Get zero extended value.
Definition APInt.h:1561
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:263
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
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:537
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 Constant * getInBoundsGetElementPtr(Type *Ty, Constant *C, ArrayRef< Constant * > IdxList)
Create an "inbounds" getelementptr.
Definition Constants.h:1507
static LLVM_ABI Constant * getPointerCast(Constant *C, Type *Ty)
Create a BitCast, AddrSpaceCast, or a PtrToInt cast constant expression.
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:1497
static LLVM_ABI Constant * getPtrToInt(Constant *C, Type *Ty, bool OnlyIfReduced=false)
static Constant * getInBoundsPtrAdd(Constant *Ptr, Constant *Offset)
Create a getelementptr inbounds i8, ptr, offset constant expression.
Definition Constants.h:1524
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
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:223
iterator end()
Definition DenseMap.h:141
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition DenseMap.h:284
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 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.
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
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Definition IRBuilder.h:2910
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.
LLVM_ABI void setMetadata(unsigned KindID, MDNode *Node)
Set the metadata of the specified kind to the specified node.
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:1069
const MDOperand & getOperand(unsigned I) const
Definition Metadata.h:1426
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition Metadata.h:1567
unsigned getNumOperands() const
Return number of MDNode operands.
Definition Metadata.h:1432
Metadata * get() const
Definition Metadata.h:920
static LLVM_ABI MDString * get(LLVMContext &Context, StringRef Str)
Definition Metadata.cpp:615
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Definition Metadata.h:1513
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()
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
iterator_range< op_iterator > operands()
Definition Metadata.h:1851
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.
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
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
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 Type * getVoidTy(LLVMContext &C)
Definition Type.cpp:282
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:255
user_iterator user_begin()
Definition Value.h:402
bool hasOneUse() const
Return true if there is exactly one use of this value.
Definition Value.h:439
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition Value.cpp:553
iterator_range< user_iterator > users()
Definition Value.h:426
use_iterator use_begin()
Definition Value.h:364
bool use_empty() const
Definition Value.h:346
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:561
iterator_range< use_iterator > uses()
Definition Value.h:380
bool hasName() const
Definition Value.h:261
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
Definition Value.cpp:319
LLVM_ABI void takeName(Value *V)
Transfer the name from V to this value.
Definition Value.cpp:400
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:81
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 bool isJumpTableCanonical(Function *F)
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:683
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:804
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
void stable_sort(R &&Range)
Definition STLExtras.h:2116
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:1739
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:981
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
@ 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:2208
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:633
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...
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
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:1636
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
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:144
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
TargetTransformInfo TTI
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
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:1885
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:2192
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:390
LLVM_ABI void appendToUsed(Module &M, ArrayRef< GlobalValue * > Values)
Adds global values to the llvm.used list.
CfiFunctionLinkage
The type of CFI jumptable needed for a function.
@ CFL_WeakDeclaration
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:932
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.