86#include "llvm/IR/IntrinsicsBPF.h"
97#define DEBUG_TYPE "bpf-abstract-member-access"
106 M, Intrinsic::bpf_passthrough, {
Input->getType(),
Input->getType()});
119class BPFAbstractMemberAccess final {
123 bool run(Function &
F);
127 uint32_t AccessIndex;
128 MaybeAlign RecordAlignment;
132 typedef std::stack<std::pair<CallInst *, CallInfo>> CallInfoStack;
136 BPFPreserveArrayAI = 1,
137 BPFPreserveUnionAI = 2,
138 BPFPreserveStructAI = 3,
139 BPFPreserveFieldInfoAI = 4,
143 const DataLayout *DL =
nullptr;
146 static std::map<std::string, GlobalVariable *> GEPGlobals;
148 std::map<CallInst *, std::pair<CallInst *, CallInfo>> AIChain;
152 std::map<CallInst *, CallInfo> BaseAICalls;
154 std::map<DICompositeType *, DIDerivedType *> AnonRecords;
156 void CheckAnonRecordType(DIDerivedType *ParentTy, DIType *Ty);
157 void CheckCompositeType(DIDerivedType *ParentTy, DICompositeType *CTy);
158 void CheckDerivedType(DIDerivedType *ParentTy, DIDerivedType *DTy);
159 void ResetMetadata(
struct CallInfo &CInfo);
161 bool doTransformation(Function &
F);
163 void traceAICall(CallInst *
Call, CallInfo &ParentInfo);
164 void traceBitCast(BitCastInst *BitCast, CallInst *Parent,
165 CallInfo &ParentInfo);
166 void traceGEP(GetElementPtrInst *
GEP, CallInst *Parent,
167 CallInfo &ParentInfo);
168 void collectAICallChains(Function &
F);
170 bool IsPreserveDIAccessIndexCall(
const CallInst *
Call, CallInfo &Cinfo);
171 bool IsValidAIChain(
const MDNode *ParentMeta, uint32_t ParentAI,
172 const MDNode *ChildMeta);
173 bool removePreserveAccessIndexIntrinsic(Function &
F);
174 bool HasPreserveFieldInfoCall(CallInfoStack &CallStack);
175 void GetStorageBitRange(DIDerivedType *MemberTy, Align RecordAlignment,
176 uint32_t &StartBitOffset, uint32_t &EndBitOffset);
177 uint32_t GetFieldInfo(uint32_t InfoKind, DICompositeType *CTy,
178 uint32_t AccessIndex, uint32_t PatchImm,
179 MaybeAlign RecordAlignment);
181 Value *computeBaseAndAccessKey(CallInst *
Call, CallInfo &CInfo,
182 std::string &AccessKey, MDNode *&BaseMeta);
183 MDNode *computeAccessKey(CallInst *
Call, CallInfo &CInfo,
184 std::string &AccessKey,
bool &IsInt32Ret);
185 bool transformGEPChain(CallInst *
Call, CallInfo &CInfo);
188std::map<std::string, GlobalVariable *> BPFAbstractMemberAccess::GEPGlobals;
191bool BPFAbstractMemberAccess::run(
Function &
F) {
192 LLVM_DEBUG(
dbgs() <<
"********** Abstract Member Accesses **********\n");
207 DISubprogram *
SP =
F.getSubprogram();
208 if (SP &&
SP->isDefinition()) {
209 for (DIType *Ty:
SP->getType()->getTypeArray())
210 CheckAnonRecordType(
nullptr, Ty);
211 for (
const DINode *DN :
SP->getRetainedNodes()) {
213 CheckAnonRecordType(
nullptr, DV->getType());
218 return doTransformation(
F);
221void BPFAbstractMemberAccess::ResetMetadata(
struct CallInfo &CInfo) {
223 auto It = AnonRecords.find(Ty);
224 if (It != AnonRecords.end() && It->second !=
nullptr)
225 CInfo.Metadata = It->second;
229void BPFAbstractMemberAccess::CheckCompositeType(DIDerivedType *ParentTy,
230 DICompositeType *CTy) {
232 ParentTy->
getTag() != dwarf::DW_TAG_typedef)
235 auto [It,
Inserted] = AnonRecords.try_emplace(CTy, ParentTy);
239 if (!Inserted && It->second != ParentTy)
240 It->second =
nullptr;
243void BPFAbstractMemberAccess::CheckDerivedType(DIDerivedType *ParentTy,
244 DIDerivedType *DTy) {
245 DIType *
BaseType = DTy->getBaseType();
250 if (
Tag == dwarf::DW_TAG_pointer_type)
251 CheckAnonRecordType(
nullptr,
BaseType);
252 else if (
Tag == dwarf::DW_TAG_typedef)
255 CheckAnonRecordType(ParentTy,
BaseType);
258void BPFAbstractMemberAccess::CheckAnonRecordType(DIDerivedType *ParentTy,
264 return CheckCompositeType(ParentTy, CTy);
266 return CheckDerivedType(ParentTy, DTy);
270 if (Tag != dwarf::DW_TAG_typedef && Tag != dwarf::DW_TAG_const_type &&
271 Tag != dwarf::DW_TAG_volatile_type &&
272 Tag != dwarf::DW_TAG_restrict_type &&
273 Tag != dwarf::DW_TAG_member)
275 if (Tag == dwarf::DW_TAG_typedef && !skipTypedef)
284 Ty = DTy->getBaseType();
293 Ty = DTy->getBaseType();
301 for (
uint32_t I = StartDim;
I < Elements.size(); ++
I) {
303 if (Element->getTag() == dwarf::DW_TAG_subrange_type) {
306 DimSize *= CI->getSExtValue();
315 return Call->getParamElementType(0);
325bool BPFAbstractMemberAccess::IsPreserveDIAccessIndexCall(
const CallInst *
Call,
333 if (GV->getName().starts_with(
"llvm.preserve.array.access.index")) {
334 CInfo.Kind = BPFPreserveArrayAI;
335 CInfo.Metadata =
Call->
getMetadata(LLVMContext::MD_preserve_access_index);
337 report_fatal_error(
"Missing metadata for llvm.preserve.array.access.index intrinsic");
343 if (GV->getName().starts_with(
"llvm.preserve.union.access.index")) {
344 CInfo.Kind = BPFPreserveUnionAI;
345 CInfo.Metadata =
Call->
getMetadata(LLVMContext::MD_preserve_access_index);
347 report_fatal_error(
"Missing metadata for llvm.preserve.union.access.index intrinsic");
348 ResetMetadata(CInfo);
353 if (GV->getName().starts_with(
"llvm.preserve.struct.access.index")) {
354 CInfo.Kind = BPFPreserveStructAI;
355 CInfo.Metadata =
Call->
getMetadata(LLVMContext::MD_preserve_access_index);
357 report_fatal_error(
"Missing metadata for llvm.preserve.struct.access.index intrinsic");
358 ResetMetadata(CInfo);
364 if (GV->getName().starts_with(
"llvm.bpf.preserve.field.info")) {
365 CInfo.Kind = BPFPreserveFieldInfoAI;
366 CInfo.Metadata =
nullptr;
371 CInfo.AccessIndex = InfoKind;
374 if (GV->getName().starts_with(
"llvm.bpf.preserve.type.info")) {
375 CInfo.Kind = BPFPreserveFieldInfoAI;
376 CInfo.Metadata =
Call->
getMetadata(LLVMContext::MD_preserve_access_index);
390 if (GV->getName().starts_with(
"llvm.bpf.preserve.enum.value")) {
391 CInfo.Kind = BPFPreserveFieldInfoAI;
392 CInfo.Metadata =
Call->
getMetadata(LLVMContext::MD_preserve_access_index);
411 if (DimensionIndex > 0)
420 Call->getArgOperand(0), IdxList,
421 "",
Call->getIterator());
423 Call->eraseFromParent();
435 Call->replaceAllUsesWith(
Call->getArgOperand(0));
436 Call->eraseFromParent();
439bool BPFAbstractMemberAccess::removePreserveAccessIndexIntrinsic(
Function &
F) {
440 std::vector<CallInst *> PreserveArrayIndexCalls;
441 std::vector<CallInst *> PreserveUnionIndexCalls;
442 std::vector<CallInst *> PreserveStructIndexCalls;
449 if (!IsPreserveDIAccessIndexCall(
Call, CInfo))
453 if (CInfo.Kind == BPFPreserveArrayAI)
454 PreserveArrayIndexCalls.push_back(
Call);
455 else if (CInfo.Kind == BPFPreserveUnionAI)
456 PreserveUnionIndexCalls.push_back(
Call);
458 PreserveStructIndexCalls.push_back(
Call);
484bool BPFAbstractMemberAccess::IsValidAIChain(
const MDNode *ParentType,
486 const MDNode *ChildType) {
500 if (PtrTy->getTag() != dwarf::DW_TAG_pointer_type)
508 assert(PTy && CTy &&
"ParentType or ChildType is null or not composite");
510 uint32_t PTyTag = PTy->getTag();
511 assert(PTyTag == dwarf::DW_TAG_array_type ||
512 PTyTag == dwarf::DW_TAG_structure_type ||
513 PTyTag == dwarf::DW_TAG_union_type);
515 uint32_t CTyTag = CTy->
getTag();
516 assert(CTyTag == dwarf::DW_TAG_array_type ||
517 CTyTag == dwarf::DW_TAG_structure_type ||
518 CTyTag == dwarf::DW_TAG_union_type);
521 if (PTyTag == dwarf::DW_TAG_array_type && PTyTag == CTyTag)
525 if (PTyTag == dwarf::DW_TAG_array_type)
526 Ty = PTy->getBaseType();
533void BPFAbstractMemberAccess::traceAICall(CallInst *
Call,
534 CallInfo &ParentInfo) {
541 traceBitCast(BI,
Call, ParentInfo);
545 if (IsPreserveDIAccessIndexCall(CI, ChildInfo) &&
546 IsValidAIChain(ParentInfo.Metadata, ParentInfo.AccessIndex,
547 ChildInfo.Metadata)) {
548 AIChain[CI] = std::make_pair(
Call, ParentInfo);
549 traceAICall(CI, ChildInfo);
551 BaseAICalls[
Call] = ParentInfo;
554 if (GI->hasAllZeroIndices())
555 traceGEP(GI,
Call, ParentInfo);
557 BaseAICalls[
Call] = ParentInfo;
559 BaseAICalls[
Call] = ParentInfo;
564void BPFAbstractMemberAccess::traceBitCast(BitCastInst *BitCast,
566 CallInfo &ParentInfo) {
567 for (User *U : BitCast->
users()) {
573 traceBitCast(BI, Parent, ParentInfo);
576 if (IsPreserveDIAccessIndexCall(CI, ChildInfo) &&
577 IsValidAIChain(ParentInfo.Metadata, ParentInfo.AccessIndex,
578 ChildInfo.Metadata)) {
579 AIChain[CI] = std::make_pair(Parent, ParentInfo);
580 traceAICall(CI, ChildInfo);
582 BaseAICalls[Parent] = ParentInfo;
585 if (GI->hasAllZeroIndices())
586 traceGEP(GI, Parent, ParentInfo);
588 BaseAICalls[Parent] = ParentInfo;
590 BaseAICalls[Parent] = ParentInfo;
595void BPFAbstractMemberAccess::traceGEP(GetElementPtrInst *
GEP, CallInst *Parent,
596 CallInfo &ParentInfo) {
597 for (User *U :
GEP->users()) {
603 traceBitCast(BI, Parent, ParentInfo);
606 if (IsPreserveDIAccessIndexCall(CI, ChildInfo) &&
607 IsValidAIChain(ParentInfo.Metadata, ParentInfo.AccessIndex,
608 ChildInfo.Metadata)) {
609 AIChain[CI] = std::make_pair(Parent, ParentInfo);
610 traceAICall(CI, ChildInfo);
612 BaseAICalls[Parent] = ParentInfo;
615 if (GI->hasAllZeroIndices())
616 traceGEP(GI, Parent, ParentInfo);
618 BaseAICalls[Parent] = ParentInfo;
620 BaseAICalls[Parent] = ParentInfo;
625void BPFAbstractMemberAccess::collectAICallChains(Function &
F) {
633 if (!IsPreserveDIAccessIndexCall(
Call, CInfo) ||
634 AIChain.find(
Call) != AIChain.end())
637 traceAICall(
Call, CInfo);
642void BPFAbstractMemberAccess::GetStorageBitRange(DIDerivedType *MemberTy,
643 Align RecordAlignment,
644 uint32_t &StartBitOffset,
645 uint32_t &EndBitOffset) {
649 if (RecordAlignment > 8) {
652 if (MemberBitOffset / 64 != (MemberBitOffset + MemberBitSize) / 64)
654 "requiring too big alignment");
655 RecordAlignment =
Align(8);
658 uint32_t AlignBits = RecordAlignment.
value() * 8;
659 if (MemberBitSize > AlignBits)
661 "bitfield size greater than record alignment");
663 StartBitOffset = MemberBitOffset & ~(AlignBits - 1);
664 if ((StartBitOffset + AlignBits) < (MemberBitOffset + MemberBitSize))
666 "cross alignment boundary");
667 EndBitOffset = StartBitOffset + AlignBits;
670uint32_t BPFAbstractMemberAccess::GetFieldInfo(uint32_t InfoKind,
671 DICompositeType *CTy,
672 uint32_t AccessIndex,
674 MaybeAlign RecordAlignment) {
680 if (
Tag == dwarf::DW_TAG_array_type) {
683 (EltTy->getSizeInBits() >> 3);
684 }
else if (
Tag == dwarf::DW_TAG_structure_type) {
689 unsigned SBitOffset, NextSBitOffset;
690 GetStorageBitRange(MemberTy, *RecordAlignment, SBitOffset,
692 PatchImm += SBitOffset >> 3;
699 if (
Tag == dwarf::DW_TAG_array_type) {
701 return calcArraySize(CTy, 1) * (EltTy->getSizeInBits() >> 3);
706 return SizeInBits >> 3;
708 unsigned SBitOffset, NextSBitOffset;
709 GetStorageBitRange(MemberTy, *RecordAlignment, SBitOffset,
711 SizeInBits = NextSBitOffset - SBitOffset;
712 if (SizeInBits & (SizeInBits - 1))
714 return SizeInBits >> 3;
719 const DIType *BaseTy;
720 if (
Tag == dwarf::DW_TAG_array_type) {
735 if (!CompTy || CompTy->getTag() != dwarf::DW_TAG_enumeration_type)
740 uint32_t Encoding = BTy->getEncoding();
741 return (Encoding == dwarf::DW_ATE_signed || Encoding == dwarf::DW_ATE_signed_char);
750 DIDerivedType *MemberTy =
nullptr;
751 bool IsBitField =
false;
754 if (
Tag == dwarf::DW_TAG_array_type) {
766 return 64 - SizeInBits;
769 unsigned SBitOffset, NextSBitOffset;
770 GetStorageBitRange(MemberTy, *RecordAlignment, SBitOffset, NextSBitOffset);
771 if (NextSBitOffset - SBitOffset > 64)
776 return SBitOffset + 64 - OffsetInBits - SizeInBits;
778 return OffsetInBits + 64 - NextSBitOffset;
782 DIDerivedType *MemberTy =
nullptr;
783 bool IsBitField =
false;
785 if (
Tag == dwarf::DW_TAG_array_type) {
797 return 64 - SizeInBits;
800 unsigned SBitOffset, NextSBitOffset;
801 GetStorageBitRange(MemberTy, *RecordAlignment, SBitOffset, NextSBitOffset);
802 if (NextSBitOffset - SBitOffset > 64)
805 return 64 - SizeInBits;
811bool BPFAbstractMemberAccess::HasPreserveFieldInfoCall(CallInfoStack &CallStack) {
813 while (CallStack.size()) {
814 auto StackElem = CallStack.top();
815 if (StackElem.second.Kind == BPFPreserveFieldInfoAI)
825Value *BPFAbstractMemberAccess::computeBaseAndAccessKey(CallInst *
Call,
827 std::string &AccessKey,
831 CallInfoStack CallStack;
835 CallStack.push(std::make_pair(
Call, CInfo));
836 auto &Chain = AIChain[
Call];
837 CInfo = Chain.second;
851 uint32_t FirstIndex = 0;
852 uint32_t PatchImm = 0;
854 while (CallStack.size()) {
855 auto StackElem = CallStack.top();
856 Call = StackElem.first;
857 CInfo = StackElem.second;
865 if (CInfo.Kind == BPFPreserveUnionAI ||
866 CInfo.Kind == BPFPreserveStructAI) {
870 TypeMeta = PossibleTypeDef;
875 assert(CInfo.Kind == BPFPreserveArrayAI);
881 uint64_t AccessIndex = CInfo.AccessIndex;
883 DIType *BaseTy =
nullptr;
884 bool CheckElemType =
false;
901 CheckElemType =
true;
902 }
else if (CTy->
getTag() != dwarf::DW_TAG_array_type) {
903 FirstIndex += AccessIndex;
904 CheckElemType =
true;
913 if (HasPreserveFieldInfoCall(CallStack))
918 unsigned CTag = CTy->
getTag();
919 if (CTag == dwarf::DW_TAG_structure_type || CTag == dwarf::DW_TAG_union_type) {
922 if (HasPreserveFieldInfoCall(CallStack))
932 AccessKey += std::to_string(FirstIndex);
936 while (CallStack.size()) {
937 auto StackElem = CallStack.top();
938 CInfo = StackElem.second;
941 if (CInfo.Kind == BPFPreserveFieldInfoAI) {
942 InfoKind = CInfo.AccessIndex;
950 if (CallStack.size()) {
951 auto StackElem2 = CallStack.top();
952 CallInfo CInfo2 = StackElem2.second;
953 if (CInfo2.Kind == BPFPreserveFieldInfoAI) {
954 InfoKind = CInfo2.AccessIndex;
955 assert(CallStack.size() == 1);
960 uint64_t AccessIndex = CInfo.AccessIndex;
961 AccessKey +=
":" + std::to_string(AccessIndex);
963 MDNode *MDN = CInfo.Metadata;
966 PatchImm = GetFieldInfo(InfoKind, CTy, AccessIndex, PatchImm,
967 CInfo.RecordAlignment);
976 AccessKey =
"llvm." +
TypeName +
":" + std::to_string(InfoKind) +
":" +
977 std::to_string(PatchImm) +
"$" + AccessKey;
982MDNode *BPFAbstractMemberAccess::computeAccessKey(CallInst *
Call,
984 std::string &AccessKey,
990 std::string AccessStr(
"0");
1005 const GlobalVariable *GV =
1010 StringRef ValueStr =
DA->getAsString();
1014 StringRef EnumeratorStr = ValueStr.
substr(0, Separator);
1019 assert(CTy->
getTag() == dwarf::DW_TAG_enumeration_type);
1023 if (
Enum->getName() == EnumeratorStr) {
1024 AccessStr = std::to_string(EnumIndex);
1031 StringRef EValueStr = ValueStr.
substr(Separator + 1);
1032 PatchImm = std::stoll(std::string(EValueStr));
1038 AccessKey =
"llvm." + Ty->
getName().
str() +
":" +
1039 std::to_string(CInfo.AccessIndex) + std::string(
":") +
1040 std::to_string(PatchImm) + std::string(
"$") + AccessStr;
1047bool BPFAbstractMemberAccess::transformGEPChain(CallInst *
Call,
1049 std::string AccessKey;
1054 IsInt32Ret = CInfo.Kind == BPFPreserveFieldInfoAI;
1055 if (CInfo.Kind == BPFPreserveFieldInfoAI && CInfo.Metadata) {
1056 TypeMeta = computeAccessKey(
Call, CInfo, AccessKey, IsInt32Ret);
1058 Base = computeBaseAndAccessKey(
Call, CInfo, AccessKey, TypeMeta);
1066 if (GEPGlobals.find(AccessKey) == GEPGlobals.end()) {
1067 IntegerType *VarType;
1069 VarType = Type::getInt32Ty(BB->
getContext());
1071 VarType = Type::getInt64Ty(BB->
getContext());
1073 GV =
new GlobalVariable(*M, VarType,
false, GlobalVariable::ExternalLinkage,
1074 nullptr, AccessKey);
1076 GV->
setMetadata(LLVMContext::MD_preserve_access_index, TypeMeta);
1077 GEPGlobals[AccessKey] = GV;
1079 GV = GEPGlobals[AccessKey];
1082 if (CInfo.Kind == BPFPreserveFieldInfoAI) {
1086 LDInst =
new LoadInst(Type::getInt32Ty(BB->
getContext()), GV,
"",
1089 LDInst =
new LoadInst(Type::getInt64Ty(BB->
getContext()), GV,
"",
1108 auto *LDInst =
new LoadInst(Type::getInt64Ty(BB->
getContext()), GV,
"",
1166bool BPFAbstractMemberAccess::doTransformation(Function &
F) {
1167 bool Transformed =
false;
1172 collectAICallChains(
F);
1174 for (
auto &
C : BaseAICalls)
1175 Transformed = transformGEPChain(
C.first,
C.second) || Transformed;
1177 return removePreserveAccessIndexIntrinsic(
F) || Transformed;
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static void replaceWithGEP(CallInst *Call, uint32_t DimensionIndex, uint32_t GEPIndex)
static uint64_t getConstant(const Value *IndexValue)
static Type * getBaseElementType(const CallInst *Call)
static uint32_t calcArraySize(const DICompositeType *CTy, uint32_t StartDim)
static bool SkipDIDerivedTag(unsigned Tag, bool skipTypedef)
static DIType * stripQualifiers(DIType *Ty, bool skipTypedef=true)
This file contains the layout of .BTF and .BTF.ext ELF sections.
This file contains constants used for implementing Dwarf debug support.
Module.h This file contains the declarations for the Module class.
This header defines various interfaces for pass management in LLVM.
Machine Check Debug Module
BaseType
A given derived pointer can have multiple base pointers through phi/selects.
uint64_t getZExtValue() const
Get zero extended value.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
static void removeArrayAccessCall(CallInst *Call)
static uint32_t SeqNum
llvm.bpf.passthrough builtin seq number
static void removeStructAccessCall(CallInst *Call)
@ PRESERVE_TYPE_INFO_EXISTENCE
@ MAX_PRESERVE_TYPE_INFO_FLAG
@ PRESERVE_TYPE_INFO_MATCH
static void removeUnionAccessCall(CallInst *Call)
@ PRESERVE_ENUM_VALUE_EXISTENCE
@ MAX_PRESERVE_ENUM_VALUE_FLAG
static Instruction * insertPassThrough(Module *M, BasicBlock *BB, Instruction *Input, Instruction *Before)
Insert a bpf passthrough builtin function.
static constexpr StringRef AmaAttr
The attribute attached to globals representing a field access.
LLVM Basic Block Representation.
LLVM_ABI LLVMContext & getContext() const
Get the context in which this basic block lives.
Value * getCalledOperand() const
Value * getArgOperand(unsigned i) const
This class represents a function call, abstracting a target machine's calling convention.
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
This is the shared class of boolean and integer constants.
const APInt & getValue() const
Return the constant as an APInt value reference.
This is an important base class in LLVM.
DINodeArray getElements() const
DIType * getBaseType() const
LLVM_ABI dwarf::Tag getTag() const
LLVM_ABI BoundType getCount() const
uint64_t getOffsetInBits() const
StringRef getName() const
uint64_t getSizeInBits() const
static GetElementPtrInst * Create(Type *PointeeType, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
static GetElementPtrInst * CreateInBounds(Type *PointeeType, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
Create an "inbounds" getelementptr.
LLVM_ABI void setMetadata(unsigned KindID, MDNode *Node)
Set a particular kind of metadata attachment.
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
bool hasInitializer() const
Definitions have initializers, declarations don't.
void addAttribute(Attribute::AttrKind Kind)
Add attribute to this global.
LLVM_ABI void insertBefore(InstListType::iterator InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified position.
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
A Module instance is used to store all the information related to an LLVM module.
iterator_range< debug_compile_units_iterator > debug_compile_units() const
Return an iterator for all DICompileUnits listed in this Module's llvm.dbg.cu named metadata node and...
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
std::string str() const
str - Get the contents as an std::string.
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
constexpr bool empty() const
empty - Check if the string is empty.
size_t find_first_of(char C, size_t From=0) const
Find the first character in the string that is C, or npos if not found.
const Triple & getTargetTriple() const
ArchType getArch() const
Get the parsed architecture type of this triple.
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
LLVM Value Representation.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
iterator_range< user_iterator > users()
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
const ParentTy * getParent() const
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr char TypeName[]
Key for Kernel::Arg::Metadata::mTypeName.
@ C
The default llvm calling convention, compatible with C.
@ BasicBlock
Various leaf nodes.
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > Tys={})
Look up the Function declaration of the intrinsic id in the Module M.
Flag
These should be considered private to the implementation of the MCInstrDesc class.
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
FunctionAddr VTableAddr Value
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
auto dyn_cast_or_null(const Y &Val)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
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...
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.