91#include "llvm/IR/IntrinsicsBPF.h"
102#define DEBUG_TYPE "bpf-abstract-member-access"
111 auto [NameAndKind, PatchString] = Prefix.rsplit(
':');
116 PatchString.getAsInteger(10,
PatchImm))
126 M, Intrinsic::bpf_passthrough, {
Input->getType(),
Input->getType()});
139class BPFAbstractMemberAccess final {
147 uint32_t AccessIndex;
148 MaybeAlign RecordAlignment;
155 BPFPreserveArrayAI = 1,
156 BPFPreserveUnionAI = 2,
157 BPFPreserveStructAI = 3,
158 BPFPreserveFieldInfoAI = 4,
162 const DataLayout *
DL =
nullptr;
166 std::map<CallInst *, std::pair<CallInst *, CallInfo>> AIChain;
171 SmallMapVector<CallInst *, CallInfo, 4> BaseAICalls;
173 std::map<DICompositeType *, DIDerivedType *> AnonRecords;
175 void CheckAnonRecordType(DIDerivedType *ParentTy, DIType *Ty);
176 void CheckCompositeType(DIDerivedType *ParentTy, DICompositeType *CTy);
177 void CheckDerivedType(DIDerivedType *ParentTy, DIDerivedType *DTy);
178 void ResetMetadata(
struct CallInfo &CInfo);
182 void traceAICall(CallInst *
Call, CallInfo &ParentInfo);
183 void traceBitCast(BitCastInst *BitCast, CallInst *Parent,
184 CallInfo &ParentInfo);
185 void traceGEP(GetElementPtrInst *
GEP, CallInst *Parent,
186 CallInfo &ParentInfo);
189 bool IsPreserveDIAccessIndexCall(
const CallInst *
Call, CallInfo &Cinfo);
190 bool IsValidAIChain(
const MDNode *ParentMeta, uint32_t ParentAI,
191 const MDNode *ChildMeta);
192 bool removePreserveAccessIndexIntrinsic(
Function &
F);
193 void GetStorageBitRange(DIDerivedType *MemberTy, Align RecordAlignment,
194 uint32_t &StartBitOffset, uint32_t &EndBitOffset);
195 uint32_t GetFieldInfo(uint32_t InfoKind, DICompositeType *CTy,
196 uint32_t AccessIndex, uint32_t PatchImm,
197 MaybeAlign RecordAlignment);
203 static std::optional<AccessRoot>
204 consumeAccessRoot(SmallVectorImpl<CallInfo> &CallStack);
205 Value *computeFieldAccess(CallInst *
Call,
const CallInfo &Terminal,
206 std::string &RelocSuffix, DIType *&RootType);
211 static EnumAccess computeEnumAccess(
const CallInst *
Call,
const DIType *Ty);
212 DIType *computeTypeAccess(CallInst *
Call,
const CallInfo &CInfo,
213 std::string &RelocSuffix);
214 bool transformGEPChain(CallInst *
Call,
const CallInfo &CInfo);
219bool BPFAbstractMemberAccess::run(
Function &
F) {
220 LLVM_DEBUG(
dbgs() <<
"********** Abstract Member Accesses **********\n");
227 if (
M->debug_compile_units().empty())
236 if (SP &&
SP->isDefinition()) {
237 for (
DIType *Ty:
SP->getType()->getTypeArray())
238 CheckAnonRecordType(
nullptr, Ty);
239 for (
const MDNode *DN :
SP->getRetainedNodes()) {
241 CheckAnonRecordType(
nullptr, DV->getType());
245 DL = &
M->getDataLayout();
246 return doTransformation(
F);
249void BPFAbstractMemberAccess::ResetMetadata(
struct CallInfo &CInfo) {
251 auto It = AnonRecords.find(Ty);
252 if (It != AnonRecords.end() && It->second !=
nullptr)
253 CInfo.Metadata = It->second;
257void BPFAbstractMemberAccess::CheckCompositeType(
DIDerivedType *ParentTy,
260 ParentTy->
getTag() != dwarf::DW_TAG_typedef)
263 auto [It,
Inserted] = AnonRecords.try_emplace(CTy, ParentTy);
267 if (!Inserted && It->second != ParentTy)
268 It->second =
nullptr;
271void BPFAbstractMemberAccess::CheckDerivedType(
DIDerivedType *ParentTy,
278 if (
Tag == dwarf::DW_TAG_pointer_type)
279 CheckAnonRecordType(
nullptr,
BaseType);
280 else if (
Tag == dwarf::DW_TAG_typedef)
283 CheckAnonRecordType(ParentTy,
BaseType);
286void BPFAbstractMemberAccess::CheckAnonRecordType(
DIDerivedType *ParentTy,
292 return CheckCompositeType(ParentTy, CTy);
294 return CheckDerivedType(ParentTy, DTy);
298 if (Tag != dwarf::DW_TAG_typedef && Tag != dwarf::DW_TAG_const_type &&
299 Tag != dwarf::DW_TAG_volatile_type &&
300 Tag != dwarf::DW_TAG_restrict_type &&
301 Tag != dwarf::DW_TAG_member)
303 if (Tag == dwarf::DW_TAG_typedef && !skipTypedef)
312 Ty = DTy->getBaseType();
321 Ty = DTy->getBaseType();
329 for (
uint32_t I = StartDim;
I < Elements.size(); ++
I) {
331 if (Element->getTag() == dwarf::DW_TAG_subrange_type) {
334 DimSize *= CI->getSExtValue();
348 if (!Array || Array->getTag() != dwarf::DW_TAG_array_type)
351 Ty = Array->getBaseType();
357 return Call->getParamElementType(0);
367bool BPFAbstractMemberAccess::IsPreserveDIAccessIndexCall(
const CallInst *
Call,
375 if (GV->getName().starts_with(
"llvm.preserve.array.access.index")) {
376 CInfo.Kind = BPFPreserveArrayAI;
377 CInfo.Metadata =
Call->
getMetadata(LLVMContext::MD_preserve_access_index);
379 report_fatal_error(
"Missing metadata for llvm.preserve.array.access.index intrinsic");
385 if (GV->getName().starts_with(
"llvm.preserve.union.access.index")) {
386 CInfo.Kind = BPFPreserveUnionAI;
387 CInfo.Metadata =
Call->
getMetadata(LLVMContext::MD_preserve_access_index);
389 report_fatal_error(
"Missing metadata for llvm.preserve.union.access.index intrinsic");
390 ResetMetadata(CInfo);
395 if (GV->getName().starts_with(
"llvm.preserve.struct.access.index")) {
396 CInfo.Kind = BPFPreserveStructAI;
397 CInfo.Metadata =
Call->
getMetadata(LLVMContext::MD_preserve_access_index);
399 report_fatal_error(
"Missing metadata for llvm.preserve.struct.access.index intrinsic");
400 ResetMetadata(CInfo);
406 if (GV->getName().starts_with(
"llvm.bpf.preserve.field.info")) {
407 CInfo.Kind = BPFPreserveFieldInfoAI;
408 CInfo.Metadata =
nullptr;
416 if (GV->getName().starts_with(
"llvm.bpf.preserve.type.info")) {
417 CInfo.Kind = BPFPreserveFieldInfoAI;
418 CInfo.Metadata =
Call->
getMetadata(LLVMContext::MD_preserve_access_index);
432 if (GV->getName().starts_with(
"llvm.bpf.preserve.enum.value")) {
433 CInfo.Kind = BPFPreserveFieldInfoAI;
434 CInfo.Metadata =
Call->
getMetadata(LLVMContext::MD_preserve_access_index);
453 if (DimensionIndex > 0)
462 Call->getArgOperand(0), IdxList,
463 "",
Call->getIterator());
465 Call->eraseFromParent();
477 Call->replaceAllUsesWith(
Call->getArgOperand(0));
478 Call->eraseFromParent();
481bool BPFAbstractMemberAccess::removePreserveAccessIndexIntrinsic(
Function &
F) {
482 std::vector<CallInst *> PreserveArrayIndexCalls;
483 std::vector<CallInst *> PreserveUnionIndexCalls;
484 std::vector<CallInst *> PreserveStructIndexCalls;
485 std::vector<CallInst *> PreserveFieldInfoCalls;
492 if (!IsPreserveDIAccessIndexCall(
Call, CInfo))
496 if (CInfo.Kind == BPFPreserveArrayAI)
497 PreserveArrayIndexCalls.push_back(
Call);
498 else if (CInfo.Kind == BPFPreserveUnionAI)
499 PreserveUnionIndexCalls.push_back(
Call);
500 else if (CInfo.Kind == BPFPreserveFieldInfoAI)
501 PreserveFieldInfoCalls.push_back(
Call);
503 PreserveStructIndexCalls.push_back(
Call);
510 if (
Call->use_empty())
511 Call->eraseFromParent();
536bool BPFAbstractMemberAccess::IsValidAIChain(
const MDNode *ParentType,
538 const MDNode *ChildType) {
552 if (PtrTy->getTag() != dwarf::DW_TAG_pointer_type)
560 assert(PTy && CTy &&
"ParentType or ChildType is null or not composite");
562 uint32_t PTyTag = PTy->getTag();
563 assert(PTyTag == dwarf::DW_TAG_array_type ||
564 PTyTag == dwarf::DW_TAG_structure_type ||
565 PTyTag == dwarf::DW_TAG_union_type);
567 uint32_t CTyTag = CTy->
getTag();
568 assert(CTyTag == dwarf::DW_TAG_array_type ||
569 CTyTag == dwarf::DW_TAG_structure_type ||
570 CTyTag == dwarf::DW_TAG_union_type);
575 if (PTyTag == dwarf::DW_TAG_array_type && PTyTag == CTyTag &&
580 if (PTyTag == dwarf::DW_TAG_array_type)
581 Ty = PTy->getBaseType();
588void BPFAbstractMemberAccess::traceAICall(
CallInst *
Call,
596 traceBitCast(BI,
Call, ParentInfo);
600 if (IsPreserveDIAccessIndexCall(CI, ChildInfo) &&
601 IsValidAIChain(ParentInfo.Metadata, ParentInfo.AccessIndex,
602 ChildInfo.Metadata)) {
603 AIChain[CI] = std::make_pair(
Call, ParentInfo);
604 traceAICall(CI, ChildInfo);
606 BaseAICalls[
Call] = ParentInfo;
609 if (GI->hasAllZeroIndices())
610 traceGEP(GI,
Call, ParentInfo);
612 BaseAICalls[
Call] = ParentInfo;
614 BaseAICalls[
Call] = ParentInfo;
619void BPFAbstractMemberAccess::traceBitCast(
BitCastInst *BitCast,
628 traceBitCast(BI, Parent, ParentInfo);
631 if (IsPreserveDIAccessIndexCall(CI, ChildInfo) &&
632 IsValidAIChain(ParentInfo.Metadata, ParentInfo.AccessIndex,
633 ChildInfo.Metadata)) {
634 AIChain[CI] = std::make_pair(Parent, ParentInfo);
635 traceAICall(CI, ChildInfo);
637 BaseAICalls[Parent] = ParentInfo;
640 if (GI->hasAllZeroIndices())
641 traceGEP(GI, Parent, ParentInfo);
643 BaseAICalls[Parent] = ParentInfo;
645 BaseAICalls[Parent] = ParentInfo;
658 traceBitCast(BI, Parent, ParentInfo);
661 if (IsPreserveDIAccessIndexCall(CI, ChildInfo) &&
662 IsValidAIChain(ParentInfo.Metadata, ParentInfo.AccessIndex,
663 ChildInfo.Metadata)) {
664 AIChain[CI] = std::make_pair(Parent, ParentInfo);
665 traceAICall(CI, ChildInfo);
667 BaseAICalls[Parent] = ParentInfo;
670 if (GI->hasAllZeroIndices())
671 traceGEP(GI, Parent, ParentInfo);
673 BaseAICalls[Parent] = ParentInfo;
675 BaseAICalls[Parent] = ParentInfo;
680void BPFAbstractMemberAccess::collectAICallChains(
Function &
F) {
688 if (!IsPreserveDIAccessIndexCall(
Call, CInfo) ||
689 AIChain.find(
Call) != AIChain.end())
692 traceAICall(
Call, CInfo);
697void BPFAbstractMemberAccess::GetStorageBitRange(
DIDerivedType *MemberTy,
698 Align RecordAlignment,
699 uint32_t &StartBitOffset,
700 uint32_t &EndBitOffset) {
704 if (RecordAlignment > 8) {
707 if (MemberBitOffset / 64 != (MemberBitOffset + MemberBitSize) / 64)
709 "requiring too big alignment");
710 RecordAlignment =
Align(8);
713 uint32_t AlignBits = RecordAlignment.
value() * 8;
714 if (MemberBitSize > AlignBits)
716 "bitfield size greater than record alignment");
718 StartBitOffset = MemberBitOffset & ~(AlignBits - 1);
719 if ((StartBitOffset + AlignBits) < (MemberBitOffset + MemberBitSize))
721 "cross alignment boundary");
722 EndBitOffset = StartBitOffset + AlignBits;
725uint32_t BPFAbstractMemberAccess::GetFieldInfo(uint32_t InfoKind,
727 uint32_t AccessIndex,
735 if (
Tag == dwarf::DW_TAG_array_type) {
738 (EltTy->getSizeInBits() >> 3);
739 }
else if (
Tag == dwarf::DW_TAG_structure_type) {
744 unsigned SBitOffset, NextSBitOffset;
745 GetStorageBitRange(MemberTy, *RecordAlignment, SBitOffset,
747 PatchImm += SBitOffset >> 3;
754 if (
Tag == dwarf::DW_TAG_array_type) {
756 return calcArraySize(CTy, 1) * (EltTy->getSizeInBits() >> 3);
761 return SizeInBits >> 3;
763 unsigned SBitOffset, NextSBitOffset;
764 GetStorageBitRange(MemberTy, *RecordAlignment, SBitOffset,
766 SizeInBits = NextSBitOffset - SBitOffset;
767 if (SizeInBits & (SizeInBits - 1))
769 return SizeInBits >> 3;
775 if (
Tag == dwarf::DW_TAG_array_type) {
790 if (!CompTy || CompTy->getTag() != dwarf::DW_TAG_enumeration_type)
795 uint32_t Encoding = BTy->getEncoding();
796 return (Encoding == dwarf::DW_ATE_signed || Encoding == dwarf::DW_ATE_signed_char);
806 bool IsBitField =
false;
809 if (
Tag == dwarf::DW_TAG_array_type) {
821 return 64 - SizeInBits;
824 unsigned SBitOffset, NextSBitOffset;
825 GetStorageBitRange(MemberTy, *RecordAlignment, SBitOffset, NextSBitOffset);
826 if (NextSBitOffset - SBitOffset > 64)
831 return SBitOffset + 64 - OffsetInBits - SizeInBits;
833 return OffsetInBits + 64 - NextSBitOffset;
838 bool IsBitField =
false;
840 if (
Tag == dwarf::DW_TAG_array_type) {
852 return 64 - SizeInBits;
855 unsigned SBitOffset, NextSBitOffset;
856 GetStorageBitRange(MemberTy, *RecordAlignment, SBitOffset, NextSBitOffset);
857 if (NextSBitOffset - SBitOffset > 64)
860 return 64 - SizeInBits;
868std::optional<BPFAbstractMemberAccess::AccessRoot>
869BPFAbstractMemberAccess::consumeAccessRoot(
874 uint32_t FirstIndex = 0;
875 DIType *ElementTy =
nullptr;
876 while (!CallStack.
empty() && CallStack.
back().Kind == BPFPreserveArrayAI) {
881 case dwarf::DW_TAG_array_type: {
883 ElementTy =
Array->getBaseType();
887 case dwarf::DW_TAG_pointer_type:
894 FirstIndex += CInfo.AccessIndex * Stride;
901 assert(CInfo.Kind == BPFPreserveStructAI ||
902 CInfo.Kind == BPFPreserveUnionAI);
910 switch (
Record->getTag()) {
911 case dwarf::DW_TAG_structure_type:
912 case dwarf::DW_TAG_union_type:
924 const Twine &AccessString) {
925 return (
":" +
Twine(Kind) +
":" +
Twine(PatchImm) +
"$" + AccessString).str();
931 std::string &RelocSuffix,
935 const bool IsFieldInfo = Terminal.Kind == BPFPreserveFieldInfoAI;
939 for (
auto It = AIChain.find(
Call); It != AIChain.end();
940 It = AIChain.find(It->second.first))
944 const auto Root = consumeAccessRoot(CallStack);
948 "Invalid field access for llvm.preserve.field.info intrinsic");
953 assert(!Root->Type->getName().empty());
958 std::string AccessString = std::to_string(Root->Index);
963 while (!Fields.
empty()) {
968 uint64_t AccessIndex = CInfo.AccessIndex;
969 MDNode *MDN = CInfo.Metadata;
974 if (CTy->
getTag() == dwarf::DW_TAG_structure_type) {
982 if (ElementOffset <
Offset ||
983 (ElementOffset ==
Offset &&
I < AccessIndex))
987 AccessString +=
":" + std::to_string(BTFIndex);
991 const uint32_t FieldKind =
993 PatchImm = GetFieldInfo(FieldKind, CTy, AccessIndex, PatchImm,
994 CInfo.RecordAlignment);
1000 RootType = Root->Type;
1006BPFAbstractMemberAccess::EnumAccess
1007BPFAbstractMemberAccess::computeEnumAccess(
const CallInst *
Call,
1012 assert(GV->hasInitializer());
1016 size_t Separator = ValueStr.
find(
':');
1021 assert(CTy->
getTag() == dwarf::DW_TAG_enumeration_type);
1030 std::string &RelocSuffix) {
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;
1066 const std::string Prefix = (
"llvm." + Root->
getName()).str();
1067 std::string Name = (
Twine(Prefix) + RelocSuffix).str();
1068 for (
unsigned N = 1;
GlobalValue *Existing = M.getNamedValue(Name); ++
N) {
1070 if (GV && GV->isDeclaration() && GV->hasExternalLinkage() &&
1073 GV->getMetadata(LLVMContext::MD_preserve_access_index) == Root)
1077 Name = (
Twine(Prefix) +
"." +
Twine(
N) + RelocSuffix).str();
1083 GV->setMetadata(LLVMContext::MD_preserve_access_index, Root);
1089bool BPFAbstractMemberAccess::transformGEPChain(
CallInst *
Call,
1091 std::string RelocSuffix;
1095 const bool IsFieldInfo = CInfo.Kind == BPFPreserveFieldInfoAI;
1096 if (IsFieldInfo && CInfo.Metadata) {
1097 Root = computeTypeAccess(
Call, CInfo, RelocSuffix);
1099 Base = computeFieldAccess(
Call, CInfo, RelocSuffix, Root);
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 GlobalVariable * getOrCreateAmaGlobal(Module &M, DIType *Root, IntegerType *ValueType, StringRef RelocSuffix)
static void replaceWithGEP(CallInst *Call, uint32_t DimensionIndex, uint32_t GEPIndex)
static uint64_t getConstant(const Value *IndexValue)
static std::string formatAmaSuffix(uint32_t Kind, int64_t PatchImm, const Twine &AccessString)
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)
static uint32_t calcElementCount(DIType *&Ty)
Return the number of innermost elements in Ty, looking through array element types such as Row in typ...
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.
Machine Check Debug Module
This file implements a map that provides insertion order iteration.
static StringRef getName(Value *V)
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
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.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
const T & back() const
Get the last element.
ArrayRef< T > drop_back(size_t N=1) const
Drop the last N elements of the array.
bool empty() const
Check if the array is empty.
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.
This class represents a no-op cast from one type to another.
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
Subprogram description. Uses SubclassData1.
LLVM_ABI BoundType getCount() const
uint64_t getOffsetInBits() const
StringRef getName() const
uint64_t getSizeInBits() const
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
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.
@ ExternalLinkage
Externally visible function.
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()
Class to represent integer types.
An instruction for reading from memory.
A Module instance is used to store all the information related to an LLVM module.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
StringRef getName() const
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
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.
std::pair< StringRef, StringRef > rsplit(StringRef Separator) const
Split into two substrings around the last occurrence of a separator string.
Triple - Helper class for working with autoconf configuration names.
ArchType getArch() const
Get the parsed architecture type of this triple.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
static LLVM_ABI IntegerType * getInt8Ty(LLVMContext &C)
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.
LLVMContext & getContext() const
All values hold a context through their type.
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.
InfoKind
Entry kind values for the .amdgpu.info section.
PatchableRelocKind
CO-RE relocation kind codes used in .BTF.ext section.
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.
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.
LLVM_ABI void reportFatalInternalError(Error Err)
Report a fatal error that indicates a bug in LLVM.
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...
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
PointerUnion< const Value *, const PseudoSourceValue * > ValueType
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
This struct is a compact representation of a valid (non-zero power of two) alignment.
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.
BTF::PatchableRelocKind Kind
static AmaRelocation decode(StringRef Name)
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.