43 using namespace lowertypetests;
47 #define DEBUG_TYPE "lowertypetests"
49 STATISTIC(ByteArraySizeBits,
"Byte array size in bits");
50 STATISTIC(ByteArraySizeBytes,
"Byte array size in bytes");
51 STATISTIC(NumByteArraysCreated,
"Number of byte arrays created");
52 STATISTIC(NumTypeTestCallsLowered,
"Number of type test calls lowered");
53 STATISTIC(NumTypeIdDisjointSets,
"Number of disjoint sets of type identifiers");
56 "lowertypetests-avoid-reuse",
57 cl::desc(
"Try to avoid reuse of byte array addresses using aliases"),
61 "lowertypetests-summary-action",
62 cl::desc(
"What to do with the summary when running this pass"),
65 "Import typeid resolutions from summary and globals"),
67 "Export typeid resolutions to summary and globals")),
71 "lowertypetests-read-summary",
72 cl::desc(
"Read summary from given YAML file before running pass"),
76 "lowertypetests-write-summary",
77 cl::desc(
"Write summary to given YAML file after running pass"),
91 return Bits.count(BitOffset);
104 for (uint64_t
B :
Bits)
134 for (uint64_t
Offset : Offsets) {
145 std::vector<uint64_t> &Fragment =
Fragments.back();
146 uint64_t FragmentIndex =
Fragments.size() - 1;
148 for (
auto ObjIndex : F) {
150 if (OldFragmentIndex == 0) {
153 Fragment.push_back(ObjIndex);
160 std::vector<uint64_t> &OldFragment =
Fragments[OldFragmentIndex];
161 Fragment.insert(Fragment.end(), OldFragment.begin(), OldFragment.end());
167 for (uint64_t ObjIndex : Fragment)
172 uint64_t BitSize, uint64_t &AllocByteOffset,
173 uint8_t &AllocMask) {
183 unsigned ReqSize = AllocByteOffset + BitSize;
185 if (
Bytes.size() < ReqSize)
186 Bytes.resize(ReqSize);
189 AllocMask = 1 <<
Bit;
190 for (uint64_t
B : Bits)
191 Bytes[AllocByteOffset +
B] |= AllocMask;
196 struct ByteArrayInfo {
197 std::set<uint64_t>
Bits;
208 class GlobalTypeMember final :
TrailingObjects<GlobalTypeMember, MDNode *> {
213 size_t numTrailingObjects(OverloadToken<MDNode *>)
const {
return NTypes; }
218 auto *GTM =
static_cast<GlobalTypeMember *
>(Alloc.
Allocate(
219 totalSizeToAlloc<MDNode *>(Types.
size()),
alignof(GlobalTypeMember)));
221 GTM->NTypes = Types.
size();
222 std::uninitialized_copy(Types.
begin(), Types.
end(),
223 GTM->getTrailingObjects<
MDNode *>());
230 return makeArrayRef(getTrailingObjects<MDNode *>(), NTypes);
234 class LowerTypeTestsModule {
240 bool LinkerSubsectionsViaSymbols;
251 IntegerType *IntPtrTy = M.getDataLayout().getIntPtrType(M.getContext(), 0);
254 uint64_t IndirectIndex = 1;
263 struct TypeIdLowering {
278 unsigned SizeM1BitWidth;
290 std::vector<ByteArrayInfo> ByteArrayInfos;
292 Function *WeakInitializerFn =
nullptr;
297 ByteArrayInfo *createByteArray(
BitSetInfo &BSI);
298 void allocateByteArrays();
301 void lowerTypeTestCalls(
305 const TypeIdLowering &TIL);
308 unsigned getJumpTableEntrySize();
309 Type *getJumpTableEntryType();
324 void findGlobalVariableUsersOf(
Constant *
C,
336 static bool runForTesting(
Module &M);
342 bool UseCommandLine =
false;
356 bool runOnModule(
Module &M)
override {
360 return LowerTypeTestsModule::runForTesting(M);
361 return LowerTypeTestsModule(M, Action, Summary).lower();
367 INITIALIZE_PASS(LowerTypeTests,
"lowertypetests",
"Lower type metadata",
false,
369 char LowerTypeTests::
ID = 0;
373 return new LowerTypeTests(Action, Summary);
385 for (
auto &GlobalAndOffset : GlobalLayout) {
386 for (
MDNode *
Type : GlobalAndOffset.first->types()) {
387 if (
Type->getOperand(1) != TypeId)
391 cast<ConstantAsMetadata>(
Type->getOperand(0))->getValue())
393 BSB.
addOffset(GlobalAndOffset.second + Offset);
404 auto BitsType = cast<IntegerType>(Bits->
getType());
405 unsigned BitWidth = BitsType->getBitWidth();
415 ByteArrayInfo *LowerTypeTestsModule::createByteArray(
BitSetInfo &BSI) {
424 ByteArrayInfos.emplace_back();
425 ByteArrayInfo *BAI = &ByteArrayInfos.back();
427 BAI->Bits = BSI.
Bits;
429 BAI->ByteArray = ByteArrayGlobal;
430 BAI->MaskGlobal = MaskGlobal;
434 void LowerTypeTestsModule::allocateByteArrays() {
435 std::stable_sort(ByteArrayInfos.begin(), ByteArrayInfos.end(),
436 [](
const ByteArrayInfo &BAI1,
const ByteArrayInfo &BAI2) {
437 return BAI1.BitSize > BAI2.BitSize;
440 std::vector<uint64_t> ByteArrayOffsets(ByteArrayInfos.size());
443 for (
unsigned I = 0;
I != ByteArrayInfos.size(); ++
I) {
444 ByteArrayInfo *BAI = &ByteArrayInfos[
I];
447 BAB.allocate(BAI->Bits, BAI->BitSize, ByteArrayOffsets[
I], Mask);
449 BAI->MaskGlobal->replaceAllUsesWith(
451 BAI->MaskGlobal->eraseFromParent();
459 for (
unsigned I = 0; I != ByteArrayInfos.size(); ++
I) {
460 ByteArrayInfo *BAI = &ByteArrayInfos[
I];
465 ByteArrayConst->
getType(), ByteArray, Idxs);
470 if (LinkerSubsectionsViaSymbols) {
471 BAI->ByteArray->replaceAllUsesWith(GEP);
475 BAI->ByteArray->replaceAllUsesWith(Alias);
477 BAI->ByteArray->eraseFromParent();
480 ByteArraySizeBits = BAB.BitAllocs[0] + BAB.BitAllocs[1] + BAB.BitAllocs[2] +
481 BAB.BitAllocs[3] + BAB.BitAllocs[4] + BAB.BitAllocs[5] +
482 BAB.BitAllocs[6] + BAB.BitAllocs[7];
483 ByteArraySizeBytes = BAB.Bytes.size();
489 const TypeIdLowering &TIL,
496 Constant *ByteArray = TIL.TheByteArray;
497 if (!LinkerSubsectionsViaSymbols &&
AvoidReuse) {
502 "bits_use", ByteArray, &M);
515 Value *V, uint64_t COffset) {
516 if (
auto GV = dyn_cast<GlobalObject>(V)) {
520 if (
Type->getOperand(1) != TypeId)
524 cast<ConstantAsMetadata>(
Type->getOperand(0))->getValue())
526 if (COffset == Offset)
532 if (
auto GEP = dyn_cast<GEPOperator>(V)) {
534 bool Result = GEP->accumulateConstantOffset(DL, APOffset);
537 COffset += APOffset.getZExtValue();
541 if (
auto Op = dyn_cast<Operator>(V)) {
542 if (
Op->getOpcode() == Instruction::BitCast)
556 const TypeIdLowering &TIL) {
601 return OffsetInRange;
608 Value *
Bit = createBitSetTest(ThenB, TIL, BitOffset);
622 void LowerTypeTestsModule::buildBitSetsFromGlobalVariables(
628 std::vector<Constant *> GlobalInits;
630 for (GlobalTypeMember *
G : Globals) {
636 uint64_t Padding =
NextPowerOf2(InitSize - 1) - InitSize;
641 Padding =
alignTo(InitSize, 128) - InitSize;
643 GlobalInits.push_back(
646 if (!GlobalInits.empty())
647 GlobalInits.pop_back();
649 auto *CombinedGlobal =
658 for (
unsigned I = 0; I != Globals.size(); ++
I)
660 GlobalLayout[Globals[I]] = CombinedGlobalLayout->getElementOffset(I * 2);
662 lowerTypeTestCalls(TypeIds, CombinedGlobal, GlobalLayout);
667 for (
unsigned I = 0; I != Globals.size(); ++
I) {
674 NewInit->
getType(), CombinedGlobal, CombinedGlobalIdxs);
675 if (LinkerSubsectionsViaSymbols) {
681 CombinedGlobalElemPtr, &M);
683 GAlias->takeName(GV);
690 void LowerTypeTestsModule::lowerTypeTestCalls(
698 BitSetInfo BSI = buildBitSet(TypeId, GlobalLayout);
700 if (
auto MDS = dyn_cast<MDString>(TypeId))
701 dbgs() << MDS->getString() <<
": ";
703 dbgs() <<
"<unnamed>: ";
714 TIL.SizeM1BitWidth = (BSI.
BitSize <= 128) ? 7 : 32;
717 }
else if (BSI.
BitSize <= 64) {
719 TIL.SizeM1BitWidth = (BSI.
BitSize <= 32) ? 5 : 6;
721 uint64_t InlineBits = 0;
722 for (
auto Bit : BSI.
Bits)
723 InlineBits |= uint64_t(1) <<
Bit;
731 TIL.SizeM1BitWidth = (BSI.
BitSize <= 128) ? 7 : 32;
734 ++NumByteArraysCreated;
735 ByteArrayInfo *BAI = createByteArray(BSI);
736 TIL.TheByteArray = BAI->ByteArray;
737 TIL.BitMask = BAI->MaskGlobal;
741 for (
CallInst *CI : TypeTestCallSites[TypeId]) {
742 ++NumTypeTestCallsLowered;
743 Value *Lowered = lowerTypeTestCall(TypeId, CI, TIL);
756 if (isa<GlobalVariable>(GO) && GO->
hasSection())
758 "A member of a type identifier may not have an explicit section");
762 "A global var member of a type identifier must be a definition");
775 unsigned LowerTypeTestsModule::getJumpTableEntrySize() {
792 void LowerTypeTestsModule::createJumpTableEntry(
795 unsigned ArgIndex = AsmArgs.
size();
798 AsmOS <<
"jmp ${" << ArgIndex <<
":c}@plt\n";
799 AsmOS <<
"int3\nint3\nint3\n";
801 AsmOS <<
"b $" << ArgIndex <<
"\n";
803 AsmOS <<
"b.w $" << ArgIndex <<
"\n";
808 ConstraintOS << (ArgIndex > 0 ?
",s" :
"s");
812 Type *LowerTypeTestsModule::getJumpTableEntryType() {
818 void LowerTypeTestsModule::buildBitSetsFromFunctions(
822 buildBitSetsFromFunctionsNative(TypeIds, Functions);
824 buildBitSetsFromFunctionsWASM(TypeIds, Functions);
829 void LowerTypeTestsModule::moveInitializerToModuleConstructor(
831 if (WeakInitializerFn ==
nullptr) {
839 WeakInitializerFn->setSection(
841 ?
"__TEXT,__StaticInit,regular,pure_instructions"
848 IRBuilder<> IRB(WeakInitializerFn->getEntryBlock().getTerminator());
854 void LowerTypeTestsModule::findGlobalVariableUsersOf(
856 for (
auto *U : C->
users()){
857 if (
auto *GV = dyn_cast<GlobalVariable>(U))
859 else if (
auto *C2 = dyn_cast<Constant>(U))
860 findGlobalVariableUsersOf(C2, Out);
865 void LowerTypeTestsModule::replaceWeakDeclarationWithJumpTablePtr(
870 findGlobalVariableUsersOf(F, GlobalVarUsers);
871 for (
auto GV : GlobalVarUsers)
872 moveInitializerToModuleConstructor(GV);
889 void LowerTypeTestsModule::createJumpTable(
891 std::string AsmStr, ConstraintStr;
896 for (
unsigned I = 0; I != Functions.
size(); ++
I)
897 createJumpTableEntry(AsmOS, ConstraintOS, AsmArgs,
898 cast<Function>(Functions[I]->getGlobal()));
904 ?
"__TEXT,__text,regular,pure_instructions"
924 for (
const auto &Arg : AsmArgs)
928 AsmOS.str(), ConstraintOS.str(),
931 IRB.CreateCall(JumpTableAsm, AsmArgs);
932 IRB.CreateUnreachable();
937 void LowerTypeTestsModule::buildBitSetsFromFunctionsNative(
1020 unsigned EntrySize = getJumpTableEntrySize();
1021 for (
unsigned I = 0; I != Functions.
size(); ++
I)
1022 GlobalLayout[Functions[I]] = I * EntrySize;
1033 lowerTypeTestCalls(TypeIds, JumpTable, GlobalLayout);
1037 for (
unsigned I = 0; I != Functions.
size(); ++
I) {
1038 Function *F = cast<Function>(Functions[
I]->getGlobal());
1042 JumpTableType, JumpTable,
1049 replaceWeakDeclarationWithJumpTablePtr(F, CombinedGlobalElemPtr);
1057 CombinedGlobalElemPtr, &M);
1059 FAlias->takeName(F);
1060 if (FAlias->hasName())
1061 F->
setName(FAlias->getName() +
".cfi");
1068 createJumpTable(JumpTableFn, Functions);
1077 void LowerTypeTestsModule::buildBitSetsFromFunctionsWASM(
1084 for (GlobalTypeMember *GTM : Functions) {
1085 Function *F = cast<Function>(GTM->getGlobal());
1098 GlobalLayout[GTM] = IndirectIndex++;
1107 void LowerTypeTestsModule::buildBitSetsFromDisjointSet(
1110 for (
unsigned I = 0; I != TypeIds.
size(); ++
I)
1111 TypeIdIndices[TypeIds[I]] = I;
1115 std::vector<std::set<uint64_t>> TypeMembers(TypeIds.
size());
1116 unsigned GlobalIndex = 0;
1117 for (GlobalTypeMember *GTM : Globals) {
1118 for (
MDNode *Type : GTM->types()) {
1120 unsigned TypeIdIndex = TypeIdIndices[Type->
getOperand(1)];
1121 TypeMembers[TypeIdIndex].
insert(GlobalIndex);
1129 TypeMembers.begin(), TypeMembers.end(),
1130 [](
const std::set<uint64_t> &O1,
const std::set<uint64_t> &O2) {
1131 return O1.size() < O2.size();
1138 for (
auto &&MemSet : TypeMembers)
1142 if (Globals.empty() || isa<GlobalVariable>(Globals[0]->getGlobal())) {
1144 std::vector<GlobalTypeMember *> OrderedGVs(Globals.size());
1145 auto OGI = OrderedGVs.begin();
1146 for (
auto &&F : GLB.Fragments) {
1147 for (
auto &&Offset : F) {
1151 "variables and functions");
1152 *OGI++ = Globals[
Offset];
1156 buildBitSetsFromGlobalVariables(TypeIds, OrderedGVs);
1159 std::vector<GlobalTypeMember *> OrderedFns(Globals.size());
1160 auto OFI = OrderedFns.begin();
1161 for (
auto &&F : GLB.Fragments) {
1162 for (
auto &&Offset : F) {
1166 "variables and functions");
1167 *OFI++ = Globals[
Offset];
1171 buildBitSetsFromFunctions(TypeIds, OrderedFns);
1178 : M(M), Action(Action), Summary(Summary) {
1181 (void)this->Summary;
1184 LinkerSubsectionsViaSymbols = TargetTriple.
isMacOSX();
1185 Arch = TargetTriple.getArch();
1186 OS = TargetTriple.getOS();
1187 ObjectFormat = TargetTriple.getObjectFormat();
1190 bool LowerTypeTestsModule::runForTesting(
Module &M) {
1198 auto ReadSummaryFile =
1206 bool Changed = LowerTypeTestsModule(M,
ClSummaryAction, &Summary).lower();
1222 bool LowerTypeTestsModule::lower() {
1225 if (!TypeTestFunc || TypeTestFunc->
use_empty())
1233 GlobalClassesTy GlobalClasses;
1245 std::vector<GlobalTypeMember *> RefGlobals;
1256 auto *GTM = GlobalTypeMember::create(Alloc, &GO, Types);
1257 for (
MDNode *Type : Types) {
1258 verifyTypeMDNode(&GO, Type);
1259 auto &Info = TypeIdInfo[cast<MDNode>(
Type)->getOperand(1)];
1261 Info.RefGlobals.push_back(GTM);
1265 for (
const Use &U : TypeTestFunc->
uses()) {
1266 auto CI = cast<CallInst>(U.getUser());
1271 auto BitSet = BitSetMDVal->getMetadata();
1277 std::pair<DenseMap<Metadata *, std::vector<CallInst *>>::iterator,
bool>
1278 Ins = TypeTestCallSites.insert(
1279 std::make_pair(BitSet, std::vector<CallInst *>()));
1280 Ins.first->second.push_back(CI);
1285 GlobalClassesTy::iterator GCI = GlobalClasses.insert(BitSet);
1286 GlobalClassesTy::member_iterator CurSet = GlobalClasses.findLeader(GCI);
1289 for (GlobalTypeMember *GTM : TypeIdInfo[BitSet].RefGlobals)
1290 CurSet = GlobalClasses.unionSets(
1291 CurSet, GlobalClasses.findLeader(GlobalClasses.insert(GTM)));
1294 if (GlobalClasses.empty())
1299 std::vector<std::pair<GlobalClassesTy::iterator, unsigned>> Sets;
1300 for (GlobalClassesTy::iterator I = GlobalClasses.begin(),
1301 E = GlobalClasses.end();
1305 ++NumTypeIdDisjointSets;
1307 unsigned MaxIndex = 0;
1308 for (GlobalClassesTy::member_iterator
MI = GlobalClasses.member_begin(I);
1309 MI != GlobalClasses.member_end(); ++
MI) {
1311 MaxIndex = std::max(MaxIndex, TypeIdInfo[
MI->get<
Metadata *>()].Index);
1313 Sets.emplace_back(I, MaxIndex);
1315 std::sort(Sets.begin(), Sets.end(),
1316 [](
const std::pair<GlobalClassesTy::iterator, unsigned> &S1,
1317 const std::pair<GlobalClassesTy::iterator, unsigned> &S2) {
1318 return S1.second < S2.second;
1322 for (
const auto &S : Sets) {
1324 std::vector<Metadata *> TypeIds;
1325 std::vector<GlobalTypeMember *> Globals;
1326 for (GlobalClassesTy::member_iterator
MI =
1327 GlobalClasses.member_begin(S.first);
1328 MI != GlobalClasses.member_end(); ++
MI) {
1332 Globals.push_back(
MI->get<GlobalTypeMember *>());
1337 std::sort(TypeIds.begin(), TypeIds.end(), [&](
Metadata *M1,
Metadata *M2) {
1338 return TypeIdInfo[M1].Index < TypeIdInfo[M2].Index;
1342 buildBitSetsFromDisjointSet(TypeIds, Globals);
1345 allocateByteArrays();
void setVisibility(VisibilityTypes V)
This class implements a layout algorithm for globals referenced by bit sets that tries to keep member...
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
void push_back(const T &Elt)
A parsed version of the target data layout string in and methods for querying it. ...
LinkageTypes getLinkage() const
static ConstantInt * getFalse(LLVMContext &Context)
iterator_range< use_iterator > uses()
This class is used to build a byte array containing overlapping bit sets.
static IntegerType * getInt1Ty(LLVMContext &C)
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
VisibilityTypes getVisibility() const
Value * CreateICmpNE(Value *LHS, Value *RHS, const Twine &Name="")
void print(raw_ostream &OS) const
Value * CreateZExtOrTrunc(Value *V, Type *DestTy, const Twine &Name="")
Create a ZExt or Trunc from the integer value V to DestTy.
STATISTIC(NumFunctions,"Total number of functions")
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
A Module instance is used to store all the information related to an LLVM module. ...
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 Constant * getAnon(ArrayRef< Constant * > V, bool Packed=false)
Return an anonymous struct that has the specified elements.
Unsatisfiable type (i.e. no global has this type metadata)
unsigned getNumOperands() const
Return number of MDNode operands.
static ConstantAggregateZero * get(Type *Ty)
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.
Helper for check-and-exit error handling.
Type * getValueType() const
This class represents a function call, abstracting a target machine's calling convention.
static Constant * getGetElementPtr(Type *Ty, Constant *C, ArrayRef< Constant * > IdxList, bool InBounds=false, Optional< unsigned > InRangeIndex=None, Type *OnlyIfReducedTy=nullptr)
Getelementptr form.
static Constant * getIntToPtr(Constant *C, Type *Ty, bool OnlyIfReduced=false)
Like Internal, but omit from symbol table.
void addOffset(uint64_t Offset)
uint64_t alignTo(uint64_t Value, uint64_t Align, uint64_t Skew=0)
Returns the next integer (mod 2**64) that is greater than or equal to Value and is a multiple of Alig...
unsigned getAddressSpace() const
Return the address space of the Pointer type.
static IntegerType * getInt64Ty(LLVMContext &C)
static Constant * getSub(Constant *C1, Constant *C2, bool HasNUW=false, bool HasNSW=false)
Kind
Specifies which kind of type check we should emit for this byte array.
Value * CreateICmpULE(Value *LHS, Value *RHS, const Twine &Name="")
void reserve(size_type N)
void setAlignment(unsigned Align)
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
std::vector< uint8_t > Bytes
The byte array built so far.
const std::string & getTargetTriple() const
Get the target triple which is a string describing the target host.
std::vector< uint64_t > FragmentMap
Mapping from object index to fragment index.
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
iterator_range< global_object_iterator > global_objects()
static ReturnInst * Create(LLVMContext &C, Value *retVal=nullptr, Instruction *InsertBefore=nullptr)
static bool isKnownTypeIdMember(Metadata *TypeId, const DataLayout &DL, Value *V, uint64_t COffset)
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
bool isMacOSX() const
isMacOSX - Is this a Mac OS X triple.
Used to lazily calculate structure layout information for a target machine, based on the DataLayout s...
void initializeLowerTypeTestsPass(PassRegistry &)
const StructLayout * getStructLayout(StructType *Ty) const
Returns a StructLayout object, indicating the alignment of the struct, its size, and the offsets of i...
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
void setInitializer(Constant *InitVal)
setInitializer - Sets the initializer for this global variable, removing any existing initializer if ...
static Constant * get(LLVMContext &Context, ArrayRef< uint8_t > Elts)
get() constructors - Return a constant with array type with an element count and element type matchin...
Class to represent struct types.
A Use represents the edge between a Value definition and its users.
static const unsigned kX86JumpTableEntrySize
The returned value is undefined.
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
static StringRef getName(Value *V)
void setName(const Twine &Name)
Change the name of the value.
void eraseFromParent() override
eraseFromParent - This method unlinks 'this' from the containing module and deletes it...
LLVM_NODISCARD bool empty() const
static Constant * getZExt(Constant *C, Type *Ty, bool OnlyIfReduced=false)
bool insert(const value_type &X)
Insert a new element into the SetVector.
unsigned getAlignment() const
Class to represent array types.
static Constant * getSelect(Constant *C, Constant *V1, Constant *V2, Type *OnlyIfReducedTy=nullptr)
Select constant expr.
static FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Value * CreateSub(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Class to hold module path string table and global value map, and encapsulate methods for operating on...
size_t size() const
size - Get the array size.
void SetInsertPoint(BasicBlock *TheBB)
This specifies that created instructions should be appended to the end of the specified block...
Class to represent pointers.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
Value * CreateOr(Value *LHS, Value *RHS, const Twine &Name="")
Function * getFunction(StringRef Name) const
Look up the specified function in the module symbol table.
static bool isWeakForLinker(LinkageTypes Linkage)
Whether the definition of this global may be replaced at link time.
static Constant * getBitCast(Constant *C, Type *Ty, bool OnlyIfReduced=false)
bool hasSection() const
Check if this global has a custom object file section.
ValuesClass values(OptsTy...Options)
Helper to build a ValuesClass by forwarding a variable number of arguments as an initializer list to ...
ExternalWeak linkage description.
LoadInst * CreateLoad(Value *Ptr, const char *Name)
initializer< Ty > init(const Ty &Val)
static Constant * getInBoundsGetElementPtr(Type *Ty, Constant *C, ArrayRef< Constant * > IdxList)
Create an "inbounds" getelementptr.
Subclasses of this class are all able to terminate a basic block.
A set of analyses that are preserved following a run of a transformation pass.
static ConstantPointerNull * get(PointerType *T)
Static factory methods - Return objects of the specified value.
std::size_t countTrailingZeros(T Val, ZeroBehavior ZB=ZB_Width)
Count number of 0's from the least significant bit to the most stopping at the first 1...
LLVM Basic Block Representation.
The instances of the Type class are immutable: once they are created, they are never changed...
Allocate memory in an ever growing pool, as if by bump-pointer.
This is an important base class in LLVM.
Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
LowerTypeTestsSummaryAction
What to do with the summary when running the LowerTypeTests pass.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
LLVM_ATTRIBUTE_RETURNS_NONNULL LLVM_ATTRIBUTE_RETURNS_NOALIAS void * Allocate(size_t Size, size_t Alignment)
Allocate space at the specified alignment.
EquivalenceClasses - This represents a collection of equivalence classes and supports three efficient...
Expected< T > errorOrToExpected(ErrorOr< T > &&EO)
Convert an ErrorOr<T> to an Expected<T>.
static Type * getVoidTy(LLVMContext &C)
Single element (last example in "Short Inline Bit Vectors")
See the file comment for details on the usage of the TrailingObjects type.
uint64_t BitAllocs[BitsPerByte]
The number of bytes allocated so far for each of the bits.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
Value * CreateICmpEQ(Value *LHS, Value *RHS, const Twine &Name="")
static Constant * getICmp(unsigned short pred, Constant *LHS, Constant *RHS, bool OnlyIfReduced=false)
get* - Return some common constants without having to specify the full Instruction::OPCODE identifier...
Class to represent integer types.
bool empty() const
empty - Check if the array is empty.
SmallVector< uint64_t, 16 > Offsets
void setConstant(bool Val)
bool isThreadLocal() const
If the value is "Thread Local", its value isn't shared by the threads.
The Output class is used to generate a yaml document from in-memory structs and vectors.
uint64_t NextPowerOf2(uint64_t A)
NextPowerOf2 - Returns the next power of two (in 64-bits) that is strictly greater than A...
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
Triple - Helper class for working with autoconf configuration names.
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
PHINode * CreatePHI(Type *Ty, unsigned NumReservedValues, const Twine &Name="")
static Constant * getPointerCast(Constant *C, Type *Ty)
Create a BitCast, AddrSpaceCast, or a PtrToInt cast constant expression.
const MDOperand & getOperand(unsigned I) const
A SetVector that performs no allocations if smaller than a certain size.
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the generic address space (address sp...
This is the shared class of boolean and integer constants.
Import typeid resolutions from summary and globals.
uint64_t getTypeAllocSize(Type *Ty) const
Returns the offset in bytes between successive objects of the specified type, including alignment pad...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Module.h This file contains the declarations for the Module class.
Type * getType() const
All values are typed, get the type of this value.
TerminatorInst * SplitBlockAndInsertIfThen(Value *Cond, Instruction *SplitBefore, bool Unreachable, MDNode *BranchWeights=nullptr, DominatorTree *DT=nullptr, LoopInfo *LI=nullptr)
Split the containing block at the specified instruction - everything before SplitBefore stays in the ...
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
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.
static ConstantInt * getTrue(LLVMContext &Context)
void setLinkage(LinkageTypes LT)
static GCRegistry::Add< ShadowStackGC > C("shadow-stack","Very portable GC for uncooperative code generators")
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Value * getArgOperand(unsigned i) const
getArgOperand/setArgOperand - Return/set the i-th call argument.
Value * CreateGEP(Value *Ptr, ArrayRef< Value * > IdxList, const Twine &Name="")
Target - Wrapper for Target specific information.
Class for arbitrary precision integers.
iterator_range< user_iterator > users()
Value * CreateShl(Value *LHS, Value *RHS, const Twine &Name="", bool HasNUW=false, bool HasNSW=false)
The file should be opened in text mode on platforms that make this distinction.
void eraseFromParent() override
eraseFromParent - This method unlinks 'this' from the containing module and deletes it...
MDNode * getMetadata(unsigned KindID) const
Get the current metadata attachments for the given kind, if any.
void setMetadata(unsigned KindID, MDNode *MD)
Set a particular kind of metadata attachment.
#define clEnumValN(ENUMVAL, FLAGNAME, DESC)
static MDTuple * get(LLVMContext &Context, ArrayRef< Metadata * > MDs)
Test a byte array (first example)
PointerType * getType() const
Global values are always pointers.
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
ModulePass * createLowerTypeTestsPass(LowerTypeTestsSummaryAction Action, ModuleSummaryIndex *Index)
This pass lowers type metadata and the llvm.type.test intrinsic to bitsets.
bool hasAddressTaken(const User **=nullptr) const
hasAddressTaken - returns true if there are any uses of this function other than direct calls or invo...
A raw_ostream that writes to a file descriptor.
static IntegerType * getInt32Ty(LLVMContext &C)
All-ones bit vector ("Eliminating Bit Vector Checks for All-Ones Bit Vectors") ...
static Constant * getPtrToInt(Constant *C, Type *Ty, bool OnlyIfReduced=false)
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
ModulePass class - This class is used to implement unstructured interprocedural optimizations and ana...
unsigned getPointerSizeInBits(unsigned AS=0) const
Layout pointer size, in bits FIXME: The defaults need to be removed once all of the backends/clients ...
static ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
Rename collisions when linking (static functions).
static InlineAsm * get(FunctionType *Ty, StringRef AsmString, StringRef Constraints, bool hasSideEffects, bool isAlignStack=false, AsmDialect asmDialect=AD_ATT)
InlineAsm::get - Return the specified uniqued inline asm string.
Inlined bit vector ("Short Inline Bit Vectors")
Value * CreateAnd(Value *LHS, Value *RHS, const Twine &Name="")
Value * CreatePtrToInt(Value *V, Type *DestTy, const Twine &Name="")
static cl::opt< std::string > ClReadSummary("lowertypetests-read-summary", cl::desc("Read summary from given YAML file before running pass"), cl::Hidden)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static Value * createMaskedBitTest(IRBuilder<> &B, Value *Bits, Value *BitOffset)
Build a test that bit BitOffset mod sizeof(Bits)*8 is set in Bits.
void addFragment(const std::set< uint64_t > &F)
Add F to the layout while trying to keep its indices contiguous.
A raw_ostream that writes to an std::string.
LLVM Value Representation.
static cl::opt< SummaryAction > ClSummaryAction("lowertypetests-summary-action", cl::desc("What to do with the summary when running this pass"), cl::values(clEnumValN(SummaryAction::None,"none","Do nothing"), clEnumValN(SummaryAction::Import,"import","Import typeid resolutions from summary and globals"), clEnumValN(SummaryAction::Export,"export","Export typeid resolutions to summary and globals")), cl::Hidden)
This header defines support for implementing classes that have some trailing object (or arrays of obj...
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
Value * CreateLShr(Value *LHS, Value *RHS, const Twine &Name="", bool isExact=false)
This class implements an extremely fast bulk output stream that can only output to a stream...
static const unsigned kARMJumpTableEntrySize
void addFnAttr(Attribute::AttrKind Kind)
Add function attributes to this function.
A container for analyses that lazily runs them and caches their results.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, const Twine &N="", Module *M=nullptr)
std::set< uint64_t > Bits
static cl::opt< std::string > ClWriteSummary("lowertypetests-write-summary", cl::desc("Write summary to given YAML file after running pass"), cl::Hidden)
Export typeid resolutions to summary and globals.
std::vector< std::vector< uint64_t > > Fragments
The computed layout.
bool isDeclarationForLinker() const
static IntegerType * getInt8Ty(LLVMContext &C)
void setSection(StringRef S)
Change the section for this global.
const BasicBlock * getParent() const
static 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...
bool containsGlobalOffset(uint64_t Offset) const
LLVMContext & getContext() const
Get the global data context.