86#include "llvm/IR/IntrinsicsBPF.h"
97#define DEBUG_TYPE "bpf-abstract-member-access"
107 M, Intrinsic::bpf_passthrough, {
Input->getType(),
Input->getType()});
120class BPFAbstractMemberAccess final {
124 bool run(Function &
F);
128 uint32_t AccessIndex;
129 MaybeAlign RecordAlignment;
133 typedef std::stack<std::pair<CallInst *, CallInfo>> CallInfoStack;
137 BPFPreserveArrayAI = 1,
138 BPFPreserveUnionAI = 2,
139 BPFPreserveStructAI = 3,
140 BPFPreserveFieldInfoAI = 4,
144 const DataLayout *DL =
nullptr;
147 static std::map<std::string, GlobalVariable *> GEPGlobals;
149 std::map<CallInst *, std::pair<CallInst *, CallInfo>> AIChain;
153 std::map<CallInst *, CallInfo> BaseAICalls;
155 std::map<DICompositeType *, DIDerivedType *> AnonRecords;
157 void CheckAnonRecordType(DIDerivedType *ParentTy, DIType *Ty);
158 void CheckCompositeType(DIDerivedType *ParentTy, DICompositeType *CTy);
159 void CheckDerivedType(DIDerivedType *ParentTy, DIDerivedType *DTy);
160 void ResetMetadata(
struct CallInfo &CInfo);
162 bool doTransformation(Function &
F);
164 void traceAICall(CallInst *
Call, CallInfo &ParentInfo);
165 void traceBitCast(BitCastInst *BitCast, CallInst *Parent,
166 CallInfo &ParentInfo);
167 void traceGEP(GetElementPtrInst *
GEP, CallInst *Parent,
168 CallInfo &ParentInfo);
169 void collectAICallChains(Function &
F);
171 bool IsPreserveDIAccessIndexCall(
const CallInst *
Call, CallInfo &Cinfo);
172 bool IsValidAIChain(
const MDNode *ParentMeta, uint32_t ParentAI,
173 const MDNode *ChildMeta);
174 bool removePreserveAccessIndexIntrinsic(Function &
F);
175 bool HasPreserveFieldInfoCall(CallInfoStack &CallStack);
176 void GetStorageBitRange(DIDerivedType *MemberTy, Align RecordAlignment,
177 uint32_t &StartBitOffset, uint32_t &EndBitOffset);
178 uint32_t GetFieldInfo(uint32_t InfoKind, DICompositeType *CTy,
179 uint32_t AccessIndex, uint32_t PatchImm,
180 MaybeAlign RecordAlignment);
182 Value *computeBaseAndAccessKey(CallInst *
Call, CallInfo &CInfo,
183 std::string &AccessKey, MDNode *&BaseMeta);
184 MDNode *computeAccessKey(CallInst *
Call, CallInfo &CInfo,
185 std::string &AccessKey,
bool &IsInt32Ret);
186 bool transformGEPChain(CallInst *
Call, CallInfo &CInfo);
189std::map<std::string, GlobalVariable *> BPFAbstractMemberAccess::GEPGlobals;
192bool BPFAbstractMemberAccess::run(
Function &
F) {
193 LLVM_DEBUG(
dbgs() <<
"********** Abstract Member Accesses **********\n");
208 DISubprogram *
SP =
F.getSubprogram();
209 if (SP &&
SP->isDefinition()) {
210 for (DIType *Ty:
SP->getType()->getTypeArray())
211 CheckAnonRecordType(
nullptr, Ty);
212 for (
const DINode *DN :
SP->getRetainedNodes()) {
214 CheckAnonRecordType(
nullptr, DV->getType());
219 return doTransformation(
F);
222void BPFAbstractMemberAccess::ResetMetadata(
struct CallInfo &CInfo) {
224 auto It = AnonRecords.find(Ty);
225 if (It != AnonRecords.end() && It->second !=
nullptr)
226 CInfo.Metadata = It->second;
230void BPFAbstractMemberAccess::CheckCompositeType(DIDerivedType *ParentTy,
231 DICompositeType *CTy) {
233 ParentTy->
getTag() != dwarf::DW_TAG_typedef)
236 auto [It,
Inserted] = AnonRecords.try_emplace(CTy, ParentTy);
240 if (!Inserted && It->second != ParentTy)
241 It->second =
nullptr;
244void BPFAbstractMemberAccess::CheckDerivedType(DIDerivedType *ParentTy,
245 DIDerivedType *DTy) {
246 DIType *
BaseType = DTy->getBaseType();
251 if (
Tag == dwarf::DW_TAG_pointer_type)
252 CheckAnonRecordType(
nullptr,
BaseType);
253 else if (
Tag == dwarf::DW_TAG_typedef)
256 CheckAnonRecordType(ParentTy,
BaseType);
259void BPFAbstractMemberAccess::CheckAnonRecordType(DIDerivedType *ParentTy,
265 return CheckCompositeType(ParentTy, CTy);
267 return CheckDerivedType(ParentTy, DTy);
271 if (Tag != dwarf::DW_TAG_typedef && Tag != dwarf::DW_TAG_const_type &&
272 Tag != dwarf::DW_TAG_volatile_type &&
273 Tag != dwarf::DW_TAG_restrict_type &&
274 Tag != dwarf::DW_TAG_member)
276 if (Tag == dwarf::DW_TAG_typedef && !skipTypedef)
285 Ty = DTy->getBaseType();
294 Ty = DTy->getBaseType();
302 for (
uint32_t I = StartDim;
I < Elements.size(); ++
I) {
304 if (Element->getTag() == dwarf::DW_TAG_subrange_type) {
307 DimSize *= CI->getSExtValue();
316 return Call->getParamElementType(0);
326bool BPFAbstractMemberAccess::IsPreserveDIAccessIndexCall(
const CallInst *
Call,
334 if (GV->getName().starts_with(
"llvm.preserve.array.access.index")) {
335 CInfo.Kind = BPFPreserveArrayAI;
336 CInfo.Metadata =
Call->
getMetadata(LLVMContext::MD_preserve_access_index);
338 report_fatal_error(
"Missing metadata for llvm.preserve.array.access.index intrinsic");
344 if (GV->getName().starts_with(
"llvm.preserve.union.access.index")) {
345 CInfo.Kind = BPFPreserveUnionAI;
346 CInfo.Metadata =
Call->
getMetadata(LLVMContext::MD_preserve_access_index);
348 report_fatal_error(
"Missing metadata for llvm.preserve.union.access.index intrinsic");
349 ResetMetadata(CInfo);
354 if (GV->getName().starts_with(
"llvm.preserve.struct.access.index")) {
355 CInfo.Kind = BPFPreserveStructAI;
356 CInfo.Metadata =
Call->
getMetadata(LLVMContext::MD_preserve_access_index);
358 report_fatal_error(
"Missing metadata for llvm.preserve.struct.access.index intrinsic");
359 ResetMetadata(CInfo);
365 if (GV->getName().starts_with(
"llvm.bpf.preserve.field.info")) {
366 CInfo.Kind = BPFPreserveFieldInfoAI;
367 CInfo.Metadata =
nullptr;
372 CInfo.AccessIndex = InfoKind;
375 if (GV->getName().starts_with(
"llvm.bpf.preserve.type.info")) {
376 CInfo.Kind = BPFPreserveFieldInfoAI;
377 CInfo.Metadata =
Call->
getMetadata(LLVMContext::MD_preserve_access_index);
391 if (GV->getName().starts_with(
"llvm.bpf.preserve.enum.value")) {
392 CInfo.Kind = BPFPreserveFieldInfoAI;
393 CInfo.Metadata =
Call->
getMetadata(LLVMContext::MD_preserve_access_index);
412 if (DimensionIndex > 0)
421 Call->getArgOperand(0), IdxList,
422 "",
Call->getIterator());
424 Call->eraseFromParent();
436 Call->replaceAllUsesWith(
Call->getArgOperand(0));
437 Call->eraseFromParent();
440bool BPFAbstractMemberAccess::removePreserveAccessIndexIntrinsic(
Function &
F) {
441 std::vector<CallInst *> PreserveArrayIndexCalls;
442 std::vector<CallInst *> PreserveUnionIndexCalls;
443 std::vector<CallInst *> PreserveStructIndexCalls;
450 if (!IsPreserveDIAccessIndexCall(
Call, CInfo))
454 if (CInfo.Kind == BPFPreserveArrayAI)
455 PreserveArrayIndexCalls.push_back(
Call);
456 else if (CInfo.Kind == BPFPreserveUnionAI)
457 PreserveUnionIndexCalls.push_back(
Call);
459 PreserveStructIndexCalls.push_back(
Call);
485bool BPFAbstractMemberAccess::IsValidAIChain(
const MDNode *ParentType,
487 const MDNode *ChildType) {
501 if (PtrTy->getTag() != dwarf::DW_TAG_pointer_type)
509 assert(PTy && CTy &&
"ParentType or ChildType is null or not composite");
511 uint32_t PTyTag = PTy->getTag();
512 assert(PTyTag == dwarf::DW_TAG_array_type ||
513 PTyTag == dwarf::DW_TAG_structure_type ||
514 PTyTag == dwarf::DW_TAG_union_type);
516 uint32_t CTyTag = CTy->
getTag();
517 assert(CTyTag == dwarf::DW_TAG_array_type ||
518 CTyTag == dwarf::DW_TAG_structure_type ||
519 CTyTag == dwarf::DW_TAG_union_type);
522 if (PTyTag == dwarf::DW_TAG_array_type && PTyTag == CTyTag)
526 if (PTyTag == dwarf::DW_TAG_array_type)
527 Ty = PTy->getBaseType();
534void BPFAbstractMemberAccess::traceAICall(CallInst *
Call,
535 CallInfo &ParentInfo) {
542 traceBitCast(BI,
Call, ParentInfo);
546 if (IsPreserveDIAccessIndexCall(CI, ChildInfo) &&
547 IsValidAIChain(ParentInfo.Metadata, ParentInfo.AccessIndex,
548 ChildInfo.Metadata)) {
549 AIChain[CI] = std::make_pair(
Call, ParentInfo);
550 traceAICall(CI, ChildInfo);
552 BaseAICalls[
Call] = ParentInfo;
555 if (GI->hasAllZeroIndices())
556 traceGEP(GI,
Call, ParentInfo);
558 BaseAICalls[
Call] = ParentInfo;
560 BaseAICalls[
Call] = ParentInfo;
565void BPFAbstractMemberAccess::traceBitCast(BitCastInst *BitCast,
567 CallInfo &ParentInfo) {
568 for (User *U : BitCast->
users()) {
574 traceBitCast(BI, Parent, ParentInfo);
577 if (IsPreserveDIAccessIndexCall(CI, ChildInfo) &&
578 IsValidAIChain(ParentInfo.Metadata, ParentInfo.AccessIndex,
579 ChildInfo.Metadata)) {
580 AIChain[CI] = std::make_pair(Parent, ParentInfo);
581 traceAICall(CI, ChildInfo);
583 BaseAICalls[Parent] = ParentInfo;
586 if (GI->hasAllZeroIndices())
587 traceGEP(GI, Parent, ParentInfo);
589 BaseAICalls[Parent] = ParentInfo;
591 BaseAICalls[Parent] = ParentInfo;
596void BPFAbstractMemberAccess::traceGEP(GetElementPtrInst *
GEP, CallInst *Parent,
597 CallInfo &ParentInfo) {
598 for (User *U :
GEP->users()) {
604 traceBitCast(BI, Parent, ParentInfo);
607 if (IsPreserveDIAccessIndexCall(CI, ChildInfo) &&
608 IsValidAIChain(ParentInfo.Metadata, ParentInfo.AccessIndex,
609 ChildInfo.Metadata)) {
610 AIChain[CI] = std::make_pair(Parent, ParentInfo);
611 traceAICall(CI, ChildInfo);
613 BaseAICalls[Parent] = ParentInfo;
616 if (GI->hasAllZeroIndices())
617 traceGEP(GI, Parent, ParentInfo);
619 BaseAICalls[Parent] = ParentInfo;
621 BaseAICalls[Parent] = ParentInfo;
626void BPFAbstractMemberAccess::collectAICallChains(Function &
F) {
634 if (!IsPreserveDIAccessIndexCall(
Call, CInfo) ||
635 AIChain.find(
Call) != AIChain.end())
638 traceAICall(
Call, CInfo);
643void BPFAbstractMemberAccess::GetStorageBitRange(DIDerivedType *MemberTy,
644 Align RecordAlignment,
645 uint32_t &StartBitOffset,
646 uint32_t &EndBitOffset) {
650 if (RecordAlignment > 8) {
653 if (MemberBitOffset / 64 != (MemberBitOffset + MemberBitSize) / 64)
655 "requiring too big alignment");
656 RecordAlignment =
Align(8);
659 uint32_t AlignBits = RecordAlignment.
value() * 8;
660 if (MemberBitSize > AlignBits)
662 "bitfield size greater than record alignment");
664 StartBitOffset = MemberBitOffset & ~(AlignBits - 1);
665 if ((StartBitOffset + AlignBits) < (MemberBitOffset + MemberBitSize))
667 "cross alignment boundary");
668 EndBitOffset = StartBitOffset + AlignBits;
671uint32_t BPFAbstractMemberAccess::GetFieldInfo(uint32_t InfoKind,
672 DICompositeType *CTy,
673 uint32_t AccessIndex,
675 MaybeAlign RecordAlignment) {
681 if (
Tag == dwarf::DW_TAG_array_type) {
684 (EltTy->getSizeInBits() >> 3);
685 }
else if (
Tag == dwarf::DW_TAG_structure_type) {
690 unsigned SBitOffset, NextSBitOffset;
691 GetStorageBitRange(MemberTy, *RecordAlignment, SBitOffset,
693 PatchImm += SBitOffset >> 3;
700 if (
Tag == dwarf::DW_TAG_array_type) {
702 return calcArraySize(CTy, 1) * (EltTy->getSizeInBits() >> 3);
707 return SizeInBits >> 3;
709 unsigned SBitOffset, NextSBitOffset;
710 GetStorageBitRange(MemberTy, *RecordAlignment, SBitOffset,
712 SizeInBits = NextSBitOffset - SBitOffset;
713 if (SizeInBits & (SizeInBits - 1))
715 return SizeInBits >> 3;
720 const DIType *BaseTy;
721 if (
Tag == dwarf::DW_TAG_array_type) {
736 if (!CompTy || CompTy->getTag() != dwarf::DW_TAG_enumeration_type)
741 uint32_t Encoding = BTy->getEncoding();
742 return (Encoding == dwarf::DW_ATE_signed || Encoding == dwarf::DW_ATE_signed_char);
751 DIDerivedType *MemberTy =
nullptr;
752 bool IsBitField =
false;
755 if (
Tag == dwarf::DW_TAG_array_type) {
767 return 64 - SizeInBits;
770 unsigned SBitOffset, NextSBitOffset;
771 GetStorageBitRange(MemberTy, *RecordAlignment, SBitOffset, NextSBitOffset);
772 if (NextSBitOffset - SBitOffset > 64)
777 return SBitOffset + 64 - OffsetInBits - SizeInBits;
779 return OffsetInBits + 64 - NextSBitOffset;
783 DIDerivedType *MemberTy =
nullptr;
784 bool IsBitField =
false;
786 if (
Tag == dwarf::DW_TAG_array_type) {
798 return 64 - SizeInBits;
801 unsigned SBitOffset, NextSBitOffset;
802 GetStorageBitRange(MemberTy, *RecordAlignment, SBitOffset, NextSBitOffset);
803 if (NextSBitOffset - SBitOffset > 64)
806 return 64 - SizeInBits;
812bool BPFAbstractMemberAccess::HasPreserveFieldInfoCall(CallInfoStack &CallStack) {
814 while (CallStack.size()) {
815 auto StackElem = CallStack.top();
816 if (StackElem.second.Kind == BPFPreserveFieldInfoAI)
826Value *BPFAbstractMemberAccess::computeBaseAndAccessKey(CallInst *
Call,
828 std::string &AccessKey,
832 CallInfoStack CallStack;
836 CallStack.push(std::make_pair(
Call, CInfo));
837 auto &Chain = AIChain[
Call];
838 CInfo = Chain.second;
852 uint32_t FirstIndex = 0;
853 uint32_t PatchImm = 0;
855 while (CallStack.size()) {
856 auto StackElem = CallStack.top();
857 Call = StackElem.first;
858 CInfo = StackElem.second;
866 if (CInfo.Kind == BPFPreserveUnionAI ||
867 CInfo.Kind == BPFPreserveStructAI) {
871 TypeMeta = PossibleTypeDef;
876 assert(CInfo.Kind == BPFPreserveArrayAI);
882 uint64_t AccessIndex = CInfo.AccessIndex;
884 DIType *BaseTy =
nullptr;
885 bool CheckElemType =
false;
902 CheckElemType =
true;
903 }
else if (CTy->
getTag() != dwarf::DW_TAG_array_type) {
904 FirstIndex += AccessIndex;
905 CheckElemType =
true;
914 if (HasPreserveFieldInfoCall(CallStack))
919 unsigned CTag = CTy->
getTag();
920 if (CTag == dwarf::DW_TAG_structure_type || CTag == dwarf::DW_TAG_union_type) {
923 if (HasPreserveFieldInfoCall(CallStack))
933 AccessKey += std::to_string(FirstIndex);
937 while (CallStack.size()) {
938 auto StackElem = CallStack.top();
939 CInfo = StackElem.second;
942 if (CInfo.Kind == BPFPreserveFieldInfoAI) {
943 InfoKind = CInfo.AccessIndex;
951 if (CallStack.size()) {
952 auto StackElem2 = CallStack.top();
953 CallInfo CInfo2 = StackElem2.second;
954 if (CInfo2.Kind == BPFPreserveFieldInfoAI) {
955 InfoKind = CInfo2.AccessIndex;
956 assert(CallStack.size() == 1);
961 uint64_t AccessIndex = CInfo.AccessIndex;
962 AccessKey +=
":" + std::to_string(AccessIndex);
964 MDNode *MDN = CInfo.Metadata;
967 PatchImm = GetFieldInfo(InfoKind, CTy, AccessIndex, PatchImm,
968 CInfo.RecordAlignment);
977 AccessKey =
"llvm." +
TypeName +
":" + std::to_string(InfoKind) +
":" +
978 std::to_string(PatchImm) +
"$" + AccessKey;
983MDNode *BPFAbstractMemberAccess::computeAccessKey(CallInst *
Call,
985 std::string &AccessKey,
991 std::string AccessStr(
"0");
1006 const GlobalVariable *GV =
1011 StringRef ValueStr =
DA->getAsString();
1015 StringRef EnumeratorStr = ValueStr.
substr(0, Separator);
1020 assert(CTy->
getTag() == dwarf::DW_TAG_enumeration_type);
1024 if (
Enum->getName() == EnumeratorStr) {
1025 AccessStr = std::to_string(EnumIndex);
1032 StringRef EValueStr = ValueStr.
substr(Separator + 1);
1033 PatchImm = std::stoll(std::string(EValueStr));
1039 AccessKey =
"llvm." + Ty->
getName().
str() +
":" +
1040 std::to_string(CInfo.AccessIndex) + std::string(
":") +
1041 std::to_string(PatchImm) + std::string(
"$") + AccessStr;
1048bool BPFAbstractMemberAccess::transformGEPChain(CallInst *
Call,
1050 std::string AccessKey;
1055 IsInt32Ret = CInfo.Kind == BPFPreserveFieldInfoAI;
1056 if (CInfo.Kind == BPFPreserveFieldInfoAI && CInfo.Metadata) {
1057 TypeMeta = computeAccessKey(
Call, CInfo, AccessKey, IsInt32Ret);
1059 Base = computeBaseAndAccessKey(
Call, CInfo, AccessKey, TypeMeta);
1067 if (GEPGlobals.find(AccessKey) == GEPGlobals.end()) {
1068 IntegerType *VarType;
1070 VarType = Type::getInt32Ty(BB->
getContext());
1072 VarType = Type::getInt64Ty(BB->
getContext());
1074 GV =
new GlobalVariable(*M, VarType,
false, GlobalVariable::ExternalLinkage,
1075 nullptr, AccessKey);
1077 GV->
setMetadata(LLVMContext::MD_preserve_access_index, TypeMeta);
1078 GEPGlobals[AccessKey] = GV;
1080 GV = GEPGlobals[AccessKey];
1083 if (CInfo.Kind == BPFPreserveFieldInfoAI) {
1087 LDInst =
new LoadInst(Type::getInt32Ty(BB->
getContext()), GV,
"",
1090 LDInst =
new LoadInst(Type::getInt64Ty(BB->
getContext()), GV,
"",
1109 auto *LDInst =
new LoadInst(Type::getInt64Ty(BB->
getContext()), GV,
"",
1167bool BPFAbstractMemberAccess::doTransformation(Function &
F) {
1168 bool Transformed =
false;
1173 collectAICallChains(
F);
1175 for (
auto &
C : BaseAICalls)
1176 Transformed = transformGEPChain(
C.first,
C.second) || Transformed;
1178 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.
StringRef - Represent a constant reference to a string, i.e.
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.
uint64_t value() const
This is a hole in the type system and should not be abused.