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