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