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 {
133 typedef std::stack<std::pair<CallInst *, CallInfo>> CallInfoStack;
137 BPFPreserveArrayAI = 1,
138 BPFPreserveUnionAI = 2,
139 BPFPreserveStructAI = 3,
140 BPFPreserveFieldInfoAI = 4,
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;
160 void ResetMetadata(
struct CallInfo &CInfo);
174 bool removePreserveAccessIndexIntrinsic(
Function &
F);
175 bool HasPreserveFieldInfoCall(CallInfoStack &CallStack);
183 std::string &AccessKey,
MDNode *&BaseMeta);
185 std::string &AccessKey,
bool &IsInt32Ret);
189std::map<std::string, GlobalVariable *> BPFAbstractMemberAccess::GEPGlobals;
192bool BPFAbstractMemberAccess::run(
Function &
F) {
193 LLVM_DEBUG(
dbgs() <<
"********** Abstract Member Accesses **********\n");
200 if (
M->debug_compile_units().empty())
209 if (SP &&
SP->isDefinition()) {
210 for (
DIType *Ty:
SP->getType()->getTypeArray())
211 CheckAnonRecordType(
nullptr, Ty);
212 for (
const DINode *DN :
SP->getRetainedNodes()) {
213 if (
const auto *DV = dyn_cast<DILocalVariable>(DN))
214 CheckAnonRecordType(
nullptr, DV->getType());
218 DL = &
M->getDataLayout();
219 return doTransformation(
F);
222void BPFAbstractMemberAccess::ResetMetadata(
struct CallInfo &CInfo) {
223 if (
auto Ty = dyn_cast<DICompositeType>(CInfo.Metadata)) {
224 auto It = AnonRecords.find(Ty);
225 if (It != AnonRecords.end() && It->second !=
nullptr)
226 CInfo.Metadata = It->second;
230void BPFAbstractMemberAccess::CheckCompositeType(
DIDerivedType *ParentTy,
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,
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,
264 if (
auto *CTy = dyn_cast<DICompositeType>(Ty))
265 return CheckCompositeType(ParentTy, CTy);
266 else if (
auto *DTy = dyn_cast<DIDerivedType>(Ty))
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)
282 while (
auto *DTy = dyn_cast<DIDerivedType>(Ty)) {
285 Ty = DTy->getBaseType();
291 while (
auto *DTy = dyn_cast<DIDerivedType>(Ty)) {
294 Ty = DTy->getBaseType();
302 for (
uint32_t I = StartDim;
I < Elements.size(); ++
I) {
303 if (
auto *Element = dyn_cast_or_null<DINode>(Elements[
I]))
304 if (Element->getTag() == dwarf::DW_TAG_subrange_type) {
305 const DISubrange *SR = cast<DISubrange>(Element);
306 auto *CI = dyn_cast<ConstantInt *>(SR->
getCount());
307 DimSize *= CI->getSExtValue();
316 return Call->getParamElementType(0);
320 const ConstantInt *CV = dyn_cast<ConstantInt>(IndexValue);
326bool BPFAbstractMemberAccess::IsPreserveDIAccessIndexCall(
const CallInst *Call,
331 const auto *GV = dyn_cast<GlobalValue>(
Call->getCalledOperand());
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");
340 CInfo.Base =
Call->getArgOperand(0);
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);
351 CInfo.Base =
Call->getArgOperand(0);
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);
361 CInfo.Base =
Call->getArgOperand(0);
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)
413 Dimension =
getConstant(Call->getArgOperand(DimensionIndex));
418 IdxList.
push_back(Call->getArgOperand(GEPIndex));
421 Call->getArgOperand(0), IdxList,
422 "", Call->getIterator());
423 Call->replaceAllUsesWith(
GEP);
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;
448 auto *Call = dyn_cast<CallInst>(&
I);
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);
472 for (
CallInst *Call : PreserveArrayIndexCalls)
474 for (
CallInst *Call : PreserveStructIndexCalls)
476 for (
CallInst *Call : PreserveUnionIndexCalls)
485bool BPFAbstractMemberAccess::IsValidAIChain(
const MDNode *ParentType,
487 const MDNode *ChildType) {
496 if (isa<DIDerivedType>(CType))
500 if (
const auto *PtrTy = dyn_cast<DIDerivedType>(PType)) {
501 if (PtrTy->getTag() != dwarf::DW_TAG_pointer_type)
507 const auto *PTy = dyn_cast<DICompositeType>(PType);
508 const auto *CTy = dyn_cast<DICompositeType>(CType);
509 assert(PTy && CTy &&
"ParentType or ChildType is null or not composite");
512 assert(PTyTag == dwarf::DW_TAG_array_type ||
513 PTyTag == dwarf::DW_TAG_structure_type ||
514 PTyTag == dwarf::DW_TAG_union_type);
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();
529 Ty = dyn_cast<DIType>(PTy->getElements()[ParentAI]);
534void BPFAbstractMemberAccess::traceAICall(
CallInst *Call,
541 if (
auto *BI = dyn_cast<BitCastInst>(Inst)) {
542 traceBitCast(BI, Call, ParentInfo);
543 }
else if (
auto *CI = dyn_cast<CallInst>(Inst)) {
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;
554 }
else if (
auto *GI = dyn_cast<GetElementPtrInst>(Inst)) {
555 if (GI->hasAllZeroIndices())
556 traceGEP(GI, Call, ParentInfo);
558 BaseAICalls[
Call] = ParentInfo;
560 BaseAICalls[
Call] = ParentInfo;
565void BPFAbstractMemberAccess::traceBitCast(
BitCastInst *BitCast,
573 if (
auto *BI = dyn_cast<BitCastInst>(Inst)) {
574 traceBitCast(BI, Parent, ParentInfo);
575 }
else if (
auto *CI = dyn_cast<CallInst>(Inst)) {
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;
585 }
else if (
auto *GI = dyn_cast<GetElementPtrInst>(Inst)) {
586 if (GI->hasAllZeroIndices())
587 traceGEP(GI, Parent, ParentInfo);
589 BaseAICalls[Parent] = ParentInfo;
591 BaseAICalls[Parent] = ParentInfo;
603 if (
auto *BI = dyn_cast<BitCastInst>(Inst)) {
604 traceBitCast(BI, Parent, ParentInfo);
605 }
else if (
auto *CI = dyn_cast<CallInst>(Inst)) {
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;
615 }
else if (
auto *GI = dyn_cast<GetElementPtrInst>(Inst)) {
616 if (GI->hasAllZeroIndices())
617 traceGEP(GI, Parent, ParentInfo);
619 BaseAICalls[Parent] = ParentInfo;
621 BaseAICalls[Parent] = ParentInfo;
626void BPFAbstractMemberAccess::collectAICallChains(
Function &
F) {
633 auto *
Call = dyn_cast<CallInst>(&
I);
634 if (!IsPreserveDIAccessIndexCall(Call, CInfo) ||
635 AIChain.find(Call) != AIChain.end())
638 traceAICall(Call, CInfo);
644 Align RecordAlignment,
650 if (RecordAlignment > 8) {
653 if (MemberBitOffset / 64 != (MemberBitOffset + MemberBitSize) / 64)
655 "requiring too big alignment");
656 RecordAlignment =
Align(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;
681 if (
Tag == dwarf::DW_TAG_array_type) {
684 (EltTy->getSizeInBits() >> 3);
685 }
else if (
Tag == dwarf::DW_TAG_structure_type) {
688 PatchImm +=
MemberTy->getOffsetInBits() >> 3;
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;
721 if (
Tag == dwarf::DW_TAG_array_type) {
732 const auto *BTy = dyn_cast<DIBasicType>(
BaseTy);
734 const auto *CompTy = dyn_cast<DICompositeType>(
BaseTy);
736 if (!CompTy || CompTy->getTag() != dwarf::DW_TAG_enumeration_type)
739 BTy = dyn_cast<DIBasicType>(
BaseTy);
741 uint32_t Encoding = BTy->getEncoding();
742 return (Encoding == dwarf::DW_ATE_signed || Encoding == dwarf::DW_ATE_signed_char);
752 bool IsBitField =
false;
755 if (
Tag == dwarf::DW_TAG_array_type) {
760 SizeInBits =
MemberTy->getSizeInBits();
761 IsBitField =
MemberTy->isBitField();
767 return 64 - SizeInBits;
770 unsigned SBitOffset, NextSBitOffset;
771 GetStorageBitRange(
MemberTy, *RecordAlignment, SBitOffset, NextSBitOffset);
772 if (NextSBitOffset - SBitOffset > 64)
775 unsigned OffsetInBits =
MemberTy->getOffsetInBits();
777 return SBitOffset + 64 - OffsetInBits - SizeInBits;
779 return OffsetInBits + 64 - NextSBitOffset;
784 bool IsBitField =
false;
786 if (
Tag == dwarf::DW_TAG_array_type) {
791 SizeInBits =
MemberTy->getSizeInBits();
792 IsBitField =
MemberTy->isBitField();
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;
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;
885 bool CheckElemType =
false;
886 if (
const auto *CTy = dyn_cast<DICompositeType>(Ty)) {
896 auto *DTy = cast<DIDerivedType>(Ty);
900 CTy = dyn_cast<DICompositeType>(
BaseTy);
902 CheckElemType =
true;
903 }
else if (CTy->
getTag() != dwarf::DW_TAG_array_type) {
904 FirstIndex += AccessIndex;
905 CheckElemType =
true;
912 auto *CTy = dyn_cast<DICompositeType>(
BaseTy);
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);
967 PatchImm = GetFieldInfo(InfoKind, CTy, AccessIndex, PatchImm,
968 CInfo.RecordAlignment);
977 AccessKey =
"llvm." +
TypeName +
":" + std::to_string(InfoKind) +
":" +
978 std::to_string(PatchImm) +
"$" + AccessKey;
985 std::string &AccessKey,
991 std::string AccessStr(
"0");
998 PatchImm =
BaseTy->getSizeInBits() / 8;
1007 cast<GlobalVariable>(
Call->getArgOperand(1)->stripPointerCasts());
1019 const auto *CTy = cast<DICompositeType>(
BaseTy);
1020 assert(CTy->
getTag() == dwarf::DW_TAG_enumeration_type);
1023 const auto *
Enum = cast<DIEnumerator>(Element);
1024 if (
Enum->getName() == EnumeratorStr) {
1025 AccessStr = std::to_string(EnumIndex);
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()) {
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) {
1088 Call->getIterator());
1091 Call->getIterator());
1095 Call->replaceAllUsesWith(PassThroughInst);
1096 Call->eraseFromParent();
1110 Call->getIterator());
1115 GEP->insertBefore(
Call->getIterator());
1161 Call->replaceAllUsesWith(PassThroughInst);
1162 Call->eraseFromParent();
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.
uint64_t getZExtValue() const
Get zero extended value.
A container for analyses that lazily runs them and caches their results.
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.
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)
An array constant whose element type is a simple 1/2/4/8-byte integer or float/double,...
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
Tagged DWARF-like metadata node.
LLVM_ABI dwarf::Tag getTag() const
Subprogram description. Uses SubclassData1.
LLVM_ABI BoundType getCount() const
StringRef getName() const
uint64_t getSizeInBits() const
A parsed version of the target data layout string in and methods for querying it.
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.
LLVM_ABI void setMetadata(unsigned KindID, MDNode *Node)
Set a particular kind of metadata attachment.
@ ExternalLinkage
Externally visible function.
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.
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.
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.
Primary interface to the complete machine description for the target machine.
Triple - Helper class for working with autoconf configuration names.
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 * getInt8Ty(LLVMContext &C)
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
iterator_range< user_iterator > users()
Value handle that is nullable, but tries to track the Value.
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char TypeName[]
Key for Kernel::Arg::Metadata::mTypeName.
@ C
The default llvm calling convention, compatible with C.
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.
This is an optimization pass for GlobalISel generic memory operations.
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)
This struct is a compact representation of a valid (non-zero power of two) alignment.
uint64_t value() const
This is a hole in the type system and should not be abused.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.