89#include "llvm/IR/IntrinsicsBPF.h"
100#define DEBUG_TYPE "bpf-abstract-member-access"
109 M, Intrinsic::bpf_passthrough, {
Input->getType(),
Input->getType()});
122class BPFAbstractMemberAccess final {
130 uint32_t AccessIndex;
131 MaybeAlign RecordAlignment;
135 typedef std::stack<std::pair<CallInst *, CallInfo>> CallInfoStack;
139 BPFPreserveArrayAI = 1,
140 BPFPreserveUnionAI = 2,
141 BPFPreserveStructAI = 3,
142 BPFPreserveFieldInfoAI = 4,
146 const DataLayout *DL =
nullptr;
149 static std::map<std::string, GlobalVariable *> GEPGlobals;
151 std::map<CallInst *, std::pair<CallInst *, CallInfo>> AIChain;
156 SmallMapVector<CallInst *, CallInfo, 4> BaseAICalls;
158 std::map<DICompositeType *, DIDerivedType *> AnonRecords;
160 void CheckAnonRecordType(DIDerivedType *ParentTy, DIType *Ty);
161 void CheckCompositeType(DIDerivedType *ParentTy, DICompositeType *CTy);
162 void CheckDerivedType(DIDerivedType *ParentTy, DIDerivedType *DTy);
163 void ResetMetadata(
struct CallInfo &CInfo);
167 void traceAICall(CallInst *
Call, CallInfo &ParentInfo);
168 void traceBitCast(BitCastInst *BitCast, CallInst *Parent,
169 CallInfo &ParentInfo);
170 void traceGEP(GetElementPtrInst *
GEP, CallInst *Parent,
171 CallInfo &ParentInfo);
174 bool IsPreserveDIAccessIndexCall(
const CallInst *
Call, CallInfo &Cinfo);
175 bool IsValidAIChain(
const MDNode *ParentMeta, uint32_t ParentAI,
176 const MDNode *ChildMeta);
177 bool removePreserveAccessIndexIntrinsic(
Function &
F);
178 bool HasPreserveFieldInfoCall(CallInfoStack &CallStack);
179 void GetStorageBitRange(DIDerivedType *MemberTy, Align RecordAlignment,
180 uint32_t &StartBitOffset, uint32_t &EndBitOffset);
181 uint32_t GetFieldInfo(uint32_t InfoKind, DICompositeType *CTy,
182 uint32_t AccessIndex, uint32_t PatchImm,
183 MaybeAlign RecordAlignment);
185 Value *computeBaseAndAccessKey(CallInst *
Call, CallInfo &CInfo,
186 std::string &AccessKey, MDNode *&BaseMeta);
191 static EnumAccess computeEnumAccess(
const CallInst *
Call,
const DIType *Ty);
192 MDNode *computeAccessKey(CallInst *
Call,
const CallInfo &CInfo,
193 std::string &AccessKey);
194 bool transformGEPChain(CallInst *
Call, CallInfo &CInfo);
197std::map<std::string, GlobalVariable *> BPFAbstractMemberAccess::GEPGlobals;
200bool BPFAbstractMemberAccess::run(
Function &
F) {
201 LLVM_DEBUG(
dbgs() <<
"********** Abstract Member Accesses **********\n");
216 DISubprogram *
SP =
F.getSubprogram();
217 if (SP &&
SP->isDefinition()) {
218 for (DIType *Ty:
SP->getType()->getTypeArray())
219 CheckAnonRecordType(
nullptr, Ty);
220 for (
const MDNode *DN :
SP->getRetainedNodes()) {
222 CheckAnonRecordType(
nullptr, DV->getType());
227 return doTransformation(
F);
230void BPFAbstractMemberAccess::ResetMetadata(
struct CallInfo &CInfo) {
232 auto It = AnonRecords.find(Ty);
233 if (It != AnonRecords.end() && It->second !=
nullptr)
234 CInfo.Metadata = It->second;
238void BPFAbstractMemberAccess::CheckCompositeType(DIDerivedType *ParentTy,
239 DICompositeType *CTy) {
241 ParentTy->
getTag() != dwarf::DW_TAG_typedef)
244 auto [It,
Inserted] = AnonRecords.try_emplace(CTy, ParentTy);
248 if (!Inserted && It->second != ParentTy)
249 It->second =
nullptr;
252void BPFAbstractMemberAccess::CheckDerivedType(DIDerivedType *ParentTy,
253 DIDerivedType *DTy) {
254 DIType *
BaseType = DTy->getBaseType();
259 if (
Tag == dwarf::DW_TAG_pointer_type)
260 CheckAnonRecordType(
nullptr,
BaseType);
261 else if (
Tag == dwarf::DW_TAG_typedef)
264 CheckAnonRecordType(ParentTy,
BaseType);
267void BPFAbstractMemberAccess::CheckAnonRecordType(DIDerivedType *ParentTy,
273 return CheckCompositeType(ParentTy, CTy);
275 return CheckDerivedType(ParentTy, DTy);
279 if (Tag != dwarf::DW_TAG_typedef && Tag != dwarf::DW_TAG_const_type &&
280 Tag != dwarf::DW_TAG_volatile_type &&
281 Tag != dwarf::DW_TAG_restrict_type &&
282 Tag != dwarf::DW_TAG_member)
284 if (Tag == dwarf::DW_TAG_typedef && !skipTypedef)
293 Ty = DTy->getBaseType();
302 Ty = DTy->getBaseType();
310 for (
uint32_t I = StartDim;
I < Elements.size(); ++
I) {
312 if (Element->getTag() == dwarf::DW_TAG_subrange_type) {
315 DimSize *= CI->getSExtValue();
324 return Call->getParamElementType(0);
334bool BPFAbstractMemberAccess::IsPreserveDIAccessIndexCall(
const CallInst *
Call,
342 if (GV->getName().starts_with(
"llvm.preserve.array.access.index")) {
343 CInfo.Kind = BPFPreserveArrayAI;
344 CInfo.Metadata =
Call->
getMetadata(LLVMContext::MD_preserve_access_index);
346 report_fatal_error(
"Missing metadata for llvm.preserve.array.access.index intrinsic");
352 if (GV->getName().starts_with(
"llvm.preserve.union.access.index")) {
353 CInfo.Kind = BPFPreserveUnionAI;
354 CInfo.Metadata =
Call->
getMetadata(LLVMContext::MD_preserve_access_index);
356 report_fatal_error(
"Missing metadata for llvm.preserve.union.access.index intrinsic");
357 ResetMetadata(CInfo);
362 if (GV->getName().starts_with(
"llvm.preserve.struct.access.index")) {
363 CInfo.Kind = BPFPreserveStructAI;
364 CInfo.Metadata =
Call->
getMetadata(LLVMContext::MD_preserve_access_index);
366 report_fatal_error(
"Missing metadata for llvm.preserve.struct.access.index intrinsic");
367 ResetMetadata(CInfo);
373 if (GV->getName().starts_with(
"llvm.bpf.preserve.field.info")) {
374 CInfo.Kind = BPFPreserveFieldInfoAI;
375 CInfo.Metadata =
nullptr;
383 if (GV->getName().starts_with(
"llvm.bpf.preserve.type.info")) {
384 CInfo.Kind = BPFPreserveFieldInfoAI;
385 CInfo.Metadata =
Call->
getMetadata(LLVMContext::MD_preserve_access_index);
399 if (GV->getName().starts_with(
"llvm.bpf.preserve.enum.value")) {
400 CInfo.Kind = BPFPreserveFieldInfoAI;
401 CInfo.Metadata =
Call->
getMetadata(LLVMContext::MD_preserve_access_index);
420 if (DimensionIndex > 0)
429 Call->getArgOperand(0), IdxList,
430 "",
Call->getIterator());
432 Call->eraseFromParent();
444 Call->replaceAllUsesWith(
Call->getArgOperand(0));
445 Call->eraseFromParent();
448bool BPFAbstractMemberAccess::removePreserveAccessIndexIntrinsic(
Function &
F) {
449 std::vector<CallInst *> PreserveArrayIndexCalls;
450 std::vector<CallInst *> PreserveUnionIndexCalls;
451 std::vector<CallInst *> PreserveStructIndexCalls;
458 if (!IsPreserveDIAccessIndexCall(
Call, CInfo))
462 if (CInfo.Kind == BPFPreserveArrayAI)
463 PreserveArrayIndexCalls.push_back(
Call);
464 else if (CInfo.Kind == BPFPreserveUnionAI)
465 PreserveUnionIndexCalls.push_back(
Call);
467 PreserveStructIndexCalls.push_back(
Call);
493bool BPFAbstractMemberAccess::IsValidAIChain(
const MDNode *ParentType,
495 const MDNode *ChildType) {
509 if (PtrTy->getTag() != dwarf::DW_TAG_pointer_type)
517 assert(PTy && CTy &&
"ParentType or ChildType is null or not composite");
519 uint32_t PTyTag = PTy->getTag();
520 assert(PTyTag == dwarf::DW_TAG_array_type ||
521 PTyTag == dwarf::DW_TAG_structure_type ||
522 PTyTag == dwarf::DW_TAG_union_type);
524 uint32_t CTyTag = CTy->
getTag();
525 assert(CTyTag == dwarf::DW_TAG_array_type ||
526 CTyTag == dwarf::DW_TAG_structure_type ||
527 CTyTag == dwarf::DW_TAG_union_type);
530 if (PTyTag == dwarf::DW_TAG_array_type && PTyTag == CTyTag)
534 if (PTyTag == dwarf::DW_TAG_array_type)
535 Ty = PTy->getBaseType();
542void BPFAbstractMemberAccess::traceAICall(CallInst *
Call,
543 CallInfo &ParentInfo) {
550 traceBitCast(BI,
Call, ParentInfo);
554 if (IsPreserveDIAccessIndexCall(CI, ChildInfo) &&
555 IsValidAIChain(ParentInfo.Metadata, ParentInfo.AccessIndex,
556 ChildInfo.Metadata)) {
557 AIChain[CI] = std::make_pair(
Call, ParentInfo);
558 traceAICall(CI, ChildInfo);
560 BaseAICalls[
Call] = ParentInfo;
563 if (GI->hasAllZeroIndices())
564 traceGEP(GI,
Call, ParentInfo);
566 BaseAICalls[
Call] = ParentInfo;
568 BaseAICalls[
Call] = ParentInfo;
573void BPFAbstractMemberAccess::traceBitCast(BitCastInst *BitCast,
575 CallInfo &ParentInfo) {
576 for (User *U : BitCast->
users()) {
582 traceBitCast(BI, Parent, ParentInfo);
585 if (IsPreserveDIAccessIndexCall(CI, ChildInfo) &&
586 IsValidAIChain(ParentInfo.Metadata, ParentInfo.AccessIndex,
587 ChildInfo.Metadata)) {
588 AIChain[CI] = std::make_pair(Parent, ParentInfo);
589 traceAICall(CI, ChildInfo);
591 BaseAICalls[Parent] = ParentInfo;
594 if (GI->hasAllZeroIndices())
595 traceGEP(GI, Parent, ParentInfo);
597 BaseAICalls[Parent] = ParentInfo;
599 BaseAICalls[Parent] = ParentInfo;
604void BPFAbstractMemberAccess::traceGEP(GetElementPtrInst *
GEP, CallInst *Parent,
605 CallInfo &ParentInfo) {
606 for (User *U :
GEP->users()) {
612 traceBitCast(BI, Parent, ParentInfo);
615 if (IsPreserveDIAccessIndexCall(CI, ChildInfo) &&
616 IsValidAIChain(ParentInfo.Metadata, ParentInfo.AccessIndex,
617 ChildInfo.Metadata)) {
618 AIChain[CI] = std::make_pair(Parent, ParentInfo);
619 traceAICall(CI, ChildInfo);
621 BaseAICalls[Parent] = ParentInfo;
624 if (GI->hasAllZeroIndices())
625 traceGEP(GI, Parent, ParentInfo);
627 BaseAICalls[Parent] = ParentInfo;
629 BaseAICalls[Parent] = ParentInfo;
634void BPFAbstractMemberAccess::collectAICallChains(
Function &
F) {
642 if (!IsPreserveDIAccessIndexCall(
Call, CInfo) ||
643 AIChain.find(
Call) != AIChain.end())
646 traceAICall(
Call, CInfo);
651void BPFAbstractMemberAccess::GetStorageBitRange(DIDerivedType *MemberTy,
652 Align RecordAlignment,
653 uint32_t &StartBitOffset,
654 uint32_t &EndBitOffset) {
658 if (RecordAlignment > 8) {
661 if (MemberBitOffset / 64 != (MemberBitOffset + MemberBitSize) / 64)
663 "requiring too big alignment");
664 RecordAlignment =
Align(8);
667 uint32_t AlignBits = RecordAlignment.
value() * 8;
668 if (MemberBitSize > AlignBits)
670 "bitfield size greater than record alignment");
672 StartBitOffset = MemberBitOffset & ~(AlignBits - 1);
673 if ((StartBitOffset + AlignBits) < (MemberBitOffset + MemberBitSize))
675 "cross alignment boundary");
676 EndBitOffset = StartBitOffset + AlignBits;
679uint32_t BPFAbstractMemberAccess::GetFieldInfo(uint32_t InfoKind,
680 DICompositeType *CTy,
681 uint32_t AccessIndex,
683 MaybeAlign RecordAlignment) {
689 if (
Tag == dwarf::DW_TAG_array_type) {
692 (EltTy->getSizeInBits() >> 3);
693 }
else if (
Tag == dwarf::DW_TAG_structure_type) {
698 unsigned SBitOffset, NextSBitOffset;
699 GetStorageBitRange(MemberTy, *RecordAlignment, SBitOffset,
701 PatchImm += SBitOffset >> 3;
708 if (
Tag == dwarf::DW_TAG_array_type) {
710 return calcArraySize(CTy, 1) * (EltTy->getSizeInBits() >> 3);
715 return SizeInBits >> 3;
717 unsigned SBitOffset, NextSBitOffset;
718 GetStorageBitRange(MemberTy, *RecordAlignment, SBitOffset,
720 SizeInBits = NextSBitOffset - SBitOffset;
721 if (SizeInBits & (SizeInBits - 1))
723 return SizeInBits >> 3;
728 const DIType *BaseTy;
729 if (
Tag == dwarf::DW_TAG_array_type) {
744 if (!CompTy || CompTy->getTag() != dwarf::DW_TAG_enumeration_type)
749 uint32_t Encoding = BTy->getEncoding();
750 return (Encoding == dwarf::DW_ATE_signed || Encoding == dwarf::DW_ATE_signed_char);
759 DIDerivedType *MemberTy =
nullptr;
760 bool IsBitField =
false;
763 if (
Tag == dwarf::DW_TAG_array_type) {
775 return 64 - SizeInBits;
778 unsigned SBitOffset, NextSBitOffset;
779 GetStorageBitRange(MemberTy, *RecordAlignment, SBitOffset, NextSBitOffset);
780 if (NextSBitOffset - SBitOffset > 64)
785 return SBitOffset + 64 - OffsetInBits - SizeInBits;
787 return OffsetInBits + 64 - NextSBitOffset;
791 DIDerivedType *MemberTy =
nullptr;
792 bool IsBitField =
false;
794 if (
Tag == dwarf::DW_TAG_array_type) {
806 return 64 - SizeInBits;
809 unsigned SBitOffset, NextSBitOffset;
810 GetStorageBitRange(MemberTy, *RecordAlignment, SBitOffset, NextSBitOffset);
811 if (NextSBitOffset - SBitOffset > 64)
814 return 64 - SizeInBits;
820bool BPFAbstractMemberAccess::HasPreserveFieldInfoCall(CallInfoStack &CallStack) {
822 while (CallStack.size()) {
823 auto StackElem = CallStack.top();
824 if (StackElem.second.Kind == BPFPreserveFieldInfoAI)
834Value *BPFAbstractMemberAccess::computeBaseAndAccessKey(CallInst *
Call,
836 std::string &AccessKey,
840 CallInfoStack CallStack;
844 CallStack.push(std::make_pair(
Call, CInfo));
845 auto &Chain = AIChain[
Call];
846 CInfo = Chain.second;
860 uint32_t FirstIndex = 0;
861 uint32_t PatchImm = 0;
863 while (CallStack.size()) {
864 auto StackElem = CallStack.top();
865 Call = StackElem.first;
866 CInfo = StackElem.second;
874 if (CInfo.Kind == BPFPreserveUnionAI ||
875 CInfo.Kind == BPFPreserveStructAI) {
879 TypeMeta = PossibleTypeDef;
884 assert(CInfo.Kind == BPFPreserveArrayAI);
890 uint64_t AccessIndex = CInfo.AccessIndex;
892 DIType *BaseTy =
nullptr;
893 bool CheckElemType =
false;
910 CheckElemType =
true;
911 }
else if (CTy->
getTag() != dwarf::DW_TAG_array_type) {
912 FirstIndex += AccessIndex;
913 CheckElemType =
true;
922 if (HasPreserveFieldInfoCall(CallStack))
927 unsigned CTag = CTy->
getTag();
928 if (CTag == dwarf::DW_TAG_structure_type || CTag == dwarf::DW_TAG_union_type) {
931 if (HasPreserveFieldInfoCall(CallStack))
941 AccessKey += std::to_string(FirstIndex);
945 while (CallStack.size()) {
946 auto StackElem = CallStack.top();
947 CInfo = StackElem.second;
950 if (CInfo.Kind == BPFPreserveFieldInfoAI) {
959 if (CallStack.size()) {
960 auto StackElem2 = CallStack.top();
961 CallInfo CInfo2 = StackElem2.second;
962 if (CInfo2.Kind == BPFPreserveFieldInfoAI) {
964 assert(CallStack.size() == 1);
969 uint64_t AccessIndex = CInfo.AccessIndex;
970 MDNode *MDN = CInfo.Metadata;
975 if (CTy->
getTag() == dwarf::DW_TAG_structure_type) {
983 if (ElementOffset <
Offset ||
984 (ElementOffset ==
Offset &&
I < AccessIndex))
988 AccessKey +=
":" + std::to_string(BTFIndex);
990 PatchImm = GetFieldInfo(InfoKind, CTy, AccessIndex, PatchImm,
991 CInfo.RecordAlignment);
1000 AccessKey =
"llvm." +
TypeName +
":" + std::to_string(InfoKind) +
":" +
1001 std::to_string(PatchImm) +
"$" + AccessKey;
1006BPFAbstractMemberAccess::EnumAccess
1007BPFAbstractMemberAccess::computeEnumAccess(
const CallInst *
Call,
1012 assert(GV->hasInitializer());
1015 StringRef ValueStr =
DA->getAsString();
1016 size_t Separator = ValueStr.
find(
':');
1021 assert(CTy->
getTag() == dwarf::DW_TAG_enumeration_type);
1028MDNode *BPFAbstractMemberAccess::computeAccessKey(CallInst *
Call,
1029 const CallInfo &CInfo,
1030 std::string &AccessKey) {
1034 int64_t PatchImm = 1;
1035 size_t AccessIndex = 0;
1036 switch (CInfo.AccessIndex) {
1045 AccessIndex = computeEnumAccess(
Call, Ty).Index;
1049 PatchImm = std::stoll(
Value.str());
1050 AccessIndex =
Index;
1057 AccessKey =
"llvm." + Ty->
getName().
str() +
":" +
1058 std::to_string(CInfo.AccessIndex) + std::string(
":") +
1059 std::to_string(PatchImm) + std::string(
"$") +
1060 std::to_string(AccessIndex);
1067bool BPFAbstractMemberAccess::transformGEPChain(CallInst *
Call,
1069 std::string AccessKey;
1073 if (CInfo.Kind == BPFPreserveFieldInfoAI && CInfo.Metadata) {
1074 TypeMeta = computeAccessKey(
Call, CInfo, AccessKey);
1076 Base = computeBaseAndAccessKey(
Call, CInfo, AccessKey, TypeMeta);
1085 if (GEPGlobals.find(AccessKey) == GEPGlobals.end()) {
1086 IntegerType *VarType;
1088 VarType = Type::getInt32Ty(BB->
getContext());
1090 VarType = Type::getInt64Ty(BB->
getContext());
1092 GV =
new GlobalVariable(*M, VarType,
false, GlobalVariable::ExternalLinkage,
1093 nullptr, AccessKey);
1095 GV->
setMetadata(LLVMContext::MD_preserve_access_index, TypeMeta);
1096 GEPGlobals[AccessKey] = GV;
1098 GV = GEPGlobals[AccessKey];
1101 if (CInfo.Kind == BPFPreserveFieldInfoAI) {
1105 LDInst =
new LoadInst(Type::getInt32Ty(BB->
getContext()), GV,
"",
1108 LDInst =
new LoadInst(Type::getInt64Ty(BB->
getContext()), GV,
"",
1127 auto *LDInst =
new LoadInst(Type::getInt64Ty(BB->
getContext()), GV,
"",
1185bool BPFAbstractMemberAccess::doTransformation(
Function &
F) {
1186 bool Transformed =
false;
1191 collectAICallChains(
F);
1193 for (
auto &
C : BaseAICalls)
1194 Transformed = transformGEPChain(
C.first,
C.second) || Transformed;
1196 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.
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
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.
This file implements a map that provides insertion order iteration.
static StringRef getName(Value *V)
BaseType
A given derived pointer can have multiple base pointers through phi/selects.
This file defines the SmallVector class.
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.
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.
iterator_range< user_iterator > users()
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
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
Check if the string is empty.
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
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)
bool isIntegerTy() const
True if this is an instance of IntegerType.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
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.
InfoKind
Entry kind values for the .amdgpu.info section.
@ BasicBlock
Various leaf nodes.
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > OverloadTys={})
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.
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
auto dyn_cast_or_null(const Y &Val)
uint64_t getBTFRecordElementOffset(const DINode *Element)
Return the bit offset used to order an element of a BTF structure record.
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.