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 if (AnonRecords.find(Ty) != AnonRecords.end()) {
225 if (AnonRecords[Ty] !=
nullptr)
226 CInfo.Metadata = AnonRecords[Ty];
231void BPFAbstractMemberAccess::CheckCompositeType(
DIDerivedType *ParentTy,
234 ParentTy->
getTag() != dwarf::DW_TAG_typedef)
237 if (AnonRecords.find(CTy) == AnonRecords.end()) {
238 AnonRecords[CTy] = ParentTy;
246 if (CurrTy == ParentTy)
248 AnonRecords[CTy] =
nullptr;
251void BPFAbstractMemberAccess::CheckDerivedType(
DIDerivedType *ParentTy,
258 if (
Tag == dwarf::DW_TAG_pointer_type)
259 CheckAnonRecordType(
nullptr,
BaseType);
260 else if (
Tag == dwarf::DW_TAG_typedef)
263 CheckAnonRecordType(ParentTy,
BaseType);
266void BPFAbstractMemberAccess::CheckAnonRecordType(
DIDerivedType *ParentTy,
271 if (
auto *CTy = dyn_cast<DICompositeType>(Ty))
272 return CheckCompositeType(ParentTy, CTy);
273 else if (
auto *DTy = dyn_cast<DIDerivedType>(Ty))
274 return CheckDerivedType(ParentTy, DTy);
278 if (
Tag != dwarf::DW_TAG_typedef &&
Tag != dwarf::DW_TAG_const_type &&
279 Tag != dwarf::DW_TAG_volatile_type &&
280 Tag != dwarf::DW_TAG_restrict_type &&
281 Tag != dwarf::DW_TAG_member)
283 if (
Tag == dwarf::DW_TAG_typedef && !skipTypedef)
289 while (
auto *DTy = dyn_cast<DIDerivedType>(Ty)) {
292 Ty = DTy->getBaseType();
298 while (
auto *DTy = dyn_cast<DIDerivedType>(Ty)) {
301 Ty = DTy->getBaseType();
309 for (
uint32_t I = StartDim;
I < Elements.size(); ++
I) {
310 if (
auto *Element = dyn_cast_or_null<DINode>(Elements[
I]))
311 if (Element->getTag() == dwarf::DW_TAG_subrange_type) {
312 const DISubrange *SR = cast<DISubrange>(Element);
314 DimSize *= CI->getSExtValue();
323 return Call->getParamElementType(0);
327 const ConstantInt *CV = dyn_cast<ConstantInt>(IndexValue);
333bool BPFAbstractMemberAccess::IsPreserveDIAccessIndexCall(
const CallInst *Call,
338 const auto *GV = dyn_cast<GlobalValue>(
Call->getCalledOperand());
341 if (GV->getName().starts_with(
"llvm.preserve.array.access.index")) {
342 CInfo.Kind = BPFPreserveArrayAI;
343 CInfo.Metadata =
Call->getMetadata(LLVMContext::MD_preserve_access_index);
345 report_fatal_error(
"Missing metadata for llvm.preserve.array.access.index intrinsic");
347 CInfo.Base =
Call->getArgOperand(0);
351 if (GV->getName().starts_with(
"llvm.preserve.union.access.index")) {
352 CInfo.Kind = BPFPreserveUnionAI;
353 CInfo.Metadata =
Call->getMetadata(LLVMContext::MD_preserve_access_index);
355 report_fatal_error(
"Missing metadata for llvm.preserve.union.access.index intrinsic");
356 ResetMetadata(CInfo);
358 CInfo.Base =
Call->getArgOperand(0);
361 if (GV->getName().starts_with(
"llvm.preserve.struct.access.index")) {
362 CInfo.Kind = BPFPreserveStructAI;
363 CInfo.Metadata =
Call->getMetadata(LLVMContext::MD_preserve_access_index);
365 report_fatal_error(
"Missing metadata for llvm.preserve.struct.access.index intrinsic");
366 ResetMetadata(CInfo);
368 CInfo.Base =
Call->getArgOperand(0);
372 if (GV->getName().starts_with(
"llvm.bpf.preserve.field.info")) {
373 CInfo.Kind = BPFPreserveFieldInfoAI;
374 CInfo.Metadata =
nullptr;
379 CInfo.AccessIndex = InfoKind;
382 if (GV->getName().starts_with(
"llvm.bpf.preserve.type.info")) {
383 CInfo.Kind = BPFPreserveFieldInfoAI;
384 CInfo.Metadata =
Call->getMetadata(LLVMContext::MD_preserve_access_index);
398 if (GV->getName().starts_with(
"llvm.bpf.preserve.enum.value")) {
399 CInfo.Kind = BPFPreserveFieldInfoAI;
400 CInfo.Metadata =
Call->getMetadata(LLVMContext::MD_preserve_access_index);
419 if (DimensionIndex > 0)
420 Dimension =
getConstant(Call->getArgOperand(DimensionIndex));
425 for (
unsigned I = 0;
I < Dimension; ++
I)
427 IdxList.
push_back(Call->getArgOperand(GEPIndex));
430 Call->getArgOperand(0), IdxList,
431 "", Call->getIterator());
432 Call->replaceAllUsesWith(
GEP);
433 Call->eraseFromParent();
445 Call->replaceAllUsesWith(Call->getArgOperand(0));
446 Call->eraseFromParent();
449bool BPFAbstractMemberAccess::removePreserveAccessIndexIntrinsic(
Function &
F) {
450 std::vector<CallInst *> PreserveArrayIndexCalls;
451 std::vector<CallInst *> PreserveUnionIndexCalls;
452 std::vector<CallInst *> PreserveStructIndexCalls;
457 auto *Call = dyn_cast<CallInst>(&
I);
459 if (!IsPreserveDIAccessIndexCall(Call, CInfo))
463 if (CInfo.Kind == BPFPreserveArrayAI)
464 PreserveArrayIndexCalls.push_back(Call);
465 else if (CInfo.Kind == BPFPreserveUnionAI)
466 PreserveUnionIndexCalls.push_back(Call);
468 PreserveStructIndexCalls.push_back(Call);
481 for (
CallInst *Call : PreserveArrayIndexCalls)
483 for (
CallInst *Call : PreserveStructIndexCalls)
485 for (
CallInst *Call : PreserveUnionIndexCalls)
494bool BPFAbstractMemberAccess::IsValidAIChain(
const MDNode *ParentType,
496 const MDNode *ChildType) {
505 if (isa<DIDerivedType>(CType))
509 if (
const auto *PtrTy = dyn_cast<DIDerivedType>(PType)) {
510 if (PtrTy->getTag() != dwarf::DW_TAG_pointer_type)
516 const auto *PTy = dyn_cast<DICompositeType>(PType);
517 const auto *CTy = dyn_cast<DICompositeType>(CType);
518 assert(PTy && CTy &&
"ParentType or ChildType is null or not composite");
521 assert(PTyTag == dwarf::DW_TAG_array_type ||
522 PTyTag == dwarf::DW_TAG_structure_type ||
523 PTyTag == dwarf::DW_TAG_union_type);
526 assert(CTyTag == dwarf::DW_TAG_array_type ||
527 CTyTag == dwarf::DW_TAG_structure_type ||
528 CTyTag == dwarf::DW_TAG_union_type);
531 if (PTyTag == dwarf::DW_TAG_array_type && PTyTag == CTyTag)
535 if (PTyTag == dwarf::DW_TAG_array_type)
536 Ty = PTy->getBaseType();
538 Ty = dyn_cast<DIType>(PTy->getElements()[ParentAI]);
543void BPFAbstractMemberAccess::traceAICall(
CallInst *Call,
550 if (
auto *BI = dyn_cast<BitCastInst>(Inst)) {
551 traceBitCast(BI, Call, ParentInfo);
552 }
else if (
auto *CI = dyn_cast<CallInst>(Inst)) {
555 if (IsPreserveDIAccessIndexCall(CI, ChildInfo) &&
556 IsValidAIChain(ParentInfo.Metadata, ParentInfo.AccessIndex,
557 ChildInfo.Metadata)) {
558 AIChain[CI] = std::make_pair(Call, ParentInfo);
559 traceAICall(CI, ChildInfo);
561 BaseAICalls[
Call] = ParentInfo;
563 }
else if (
auto *GI = dyn_cast<GetElementPtrInst>(Inst)) {
564 if (GI->hasAllZeroIndices())
565 traceGEP(GI, Call, ParentInfo);
567 BaseAICalls[
Call] = ParentInfo;
569 BaseAICalls[
Call] = ParentInfo;
574void BPFAbstractMemberAccess::traceBitCast(
BitCastInst *BitCast,
582 if (
auto *BI = dyn_cast<BitCastInst>(Inst)) {
583 traceBitCast(BI, Parent, ParentInfo);
584 }
else if (
auto *CI = dyn_cast<CallInst>(Inst)) {
586 if (IsPreserveDIAccessIndexCall(CI, ChildInfo) &&
587 IsValidAIChain(ParentInfo.Metadata, ParentInfo.AccessIndex,
588 ChildInfo.Metadata)) {
589 AIChain[CI] = std::make_pair(Parent, ParentInfo);
590 traceAICall(CI, ChildInfo);
592 BaseAICalls[Parent] = ParentInfo;
594 }
else if (
auto *GI = dyn_cast<GetElementPtrInst>(Inst)) {
595 if (GI->hasAllZeroIndices())
596 traceGEP(GI, Parent, ParentInfo);
598 BaseAICalls[Parent] = ParentInfo;
600 BaseAICalls[Parent] = ParentInfo;
612 if (
auto *BI = dyn_cast<BitCastInst>(Inst)) {
613 traceBitCast(BI, Parent, ParentInfo);
614 }
else if (
auto *CI = dyn_cast<CallInst>(Inst)) {
616 if (IsPreserveDIAccessIndexCall(CI, ChildInfo) &&
617 IsValidAIChain(ParentInfo.Metadata, ParentInfo.AccessIndex,
618 ChildInfo.Metadata)) {
619 AIChain[CI] = std::make_pair(Parent, ParentInfo);
620 traceAICall(CI, ChildInfo);
622 BaseAICalls[Parent] = ParentInfo;
624 }
else if (
auto *GI = dyn_cast<GetElementPtrInst>(Inst)) {
625 if (GI->hasAllZeroIndices())
626 traceGEP(GI, Parent, ParentInfo);
628 BaseAICalls[Parent] = ParentInfo;
630 BaseAICalls[Parent] = ParentInfo;
635void BPFAbstractMemberAccess::collectAICallChains(
Function &
F) {
642 auto *
Call = dyn_cast<CallInst>(&
I);
643 if (!IsPreserveDIAccessIndexCall(Call, CInfo) ||
644 AIChain.find(Call) != AIChain.end())
647 traceAICall(Call, CInfo);
653 Align RecordAlignment,
659 if (RecordAlignment > 8) {
662 if (MemberBitOffset / 64 != (MemberBitOffset + MemberBitSize) / 64)
664 "requiring too big alignment");
665 RecordAlignment =
Align(8);
669 if (MemberBitSize > AlignBits)
671 "bitfield size greater than record alignment");
673 StartBitOffset = MemberBitOffset & ~(AlignBits - 1);
674 if ((StartBitOffset + AlignBits) < (MemberBitOffset + MemberBitSize))
676 "cross alignment boundary");
677 EndBitOffset = StartBitOffset + AlignBits;
690 if (
Tag == dwarf::DW_TAG_array_type) {
693 (EltTy->getSizeInBits() >> 3);
694 }
else if (
Tag == dwarf::DW_TAG_structure_type) {
697 PatchImm +=
MemberTy->getOffsetInBits() >> 3;
699 unsigned SBitOffset, NextSBitOffset;
700 GetStorageBitRange(
MemberTy, *RecordAlignment, SBitOffset,
702 PatchImm += SBitOffset >> 3;
709 if (
Tag == dwarf::DW_TAG_array_type) {
711 return calcArraySize(CTy, 1) * (EltTy->getSizeInBits() >> 3);
716 return SizeInBits >> 3;
718 unsigned SBitOffset, NextSBitOffset;
719 GetStorageBitRange(
MemberTy, *RecordAlignment, SBitOffset,
721 SizeInBits = NextSBitOffset - SBitOffset;
722 if (SizeInBits & (SizeInBits - 1))
724 return SizeInBits >> 3;
730 if (
Tag == dwarf::DW_TAG_array_type) {
741 const auto *BTy = dyn_cast<DIBasicType>(
BaseTy);
743 const auto *CompTy = dyn_cast<DICompositeType>(
BaseTy);
745 if (!CompTy || CompTy->getTag() != dwarf::DW_TAG_enumeration_type)
748 BTy = dyn_cast<DIBasicType>(
BaseTy);
750 uint32_t Encoding = BTy->getEncoding();
751 return (Encoding == dwarf::DW_ATE_signed || Encoding == dwarf::DW_ATE_signed_char);
761 bool IsBitField =
false;
764 if (
Tag == dwarf::DW_TAG_array_type) {
769 SizeInBits =
MemberTy->getSizeInBits();
770 IsBitField =
MemberTy->isBitField();
776 return 64 - SizeInBits;
779 unsigned SBitOffset, NextSBitOffset;
780 GetStorageBitRange(
MemberTy, *RecordAlignment, SBitOffset, NextSBitOffset);
781 if (NextSBitOffset - SBitOffset > 64)
784 unsigned OffsetInBits =
MemberTy->getOffsetInBits();
786 return SBitOffset + 64 - OffsetInBits - SizeInBits;
788 return OffsetInBits + 64 - NextSBitOffset;
793 bool IsBitField =
false;
795 if (
Tag == dwarf::DW_TAG_array_type) {
800 SizeInBits =
MemberTy->getSizeInBits();
801 IsBitField =
MemberTy->isBitField();
807 return 64 - SizeInBits;
810 unsigned SBitOffset, NextSBitOffset;
811 GetStorageBitRange(
MemberTy, *RecordAlignment, SBitOffset, NextSBitOffset);
812 if (NextSBitOffset - SBitOffset > 64)
815 return 64 - SizeInBits;
821bool BPFAbstractMemberAccess::HasPreserveFieldInfoCall(CallInfoStack &CallStack) {
823 while (CallStack.size()) {
824 auto StackElem = CallStack.top();
825 if (StackElem.second.Kind == BPFPreserveFieldInfoAI)
835Value *BPFAbstractMemberAccess::computeBaseAndAccessKey(
CallInst *Call,
837 std::string &AccessKey,
841 CallInfoStack CallStack;
845 CallStack.push(std::make_pair(Call, CInfo));
846 CInfo = AIChain[
Call].second;
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;
893 bool CheckElemType =
false;
894 if (
const auto *CTy = dyn_cast<DICompositeType>(Ty)) {
904 auto *DTy = cast<DIDerivedType>(Ty);
908 CTy = dyn_cast<DICompositeType>(
BaseTy);
910 CheckElemType =
true;
911 }
else if (CTy->
getTag() != dwarf::DW_TAG_array_type) {
912 FirstIndex += AccessIndex;
913 CheckElemType =
true;
920 auto *CTy = dyn_cast<DICompositeType>(
BaseTy);
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) {
951 InfoKind = CInfo.AccessIndex;
959 if (CallStack.size()) {
960 auto StackElem2 = CallStack.top();
961 CallInfo CInfo2 = StackElem2.second;
962 if (CInfo2.Kind == BPFPreserveFieldInfoAI) {
963 InfoKind = CInfo2.AccessIndex;
964 assert(CallStack.size() == 1);
969 uint64_t AccessIndex = CInfo.AccessIndex;
970 AccessKey +=
":" + std::to_string(AccessIndex);
975 PatchImm = GetFieldInfo(InfoKind, CTy, AccessIndex, PatchImm,
976 CInfo.RecordAlignment);
985 AccessKey =
"llvm." +
TypeName +
":" + std::to_string(InfoKind) +
":" +
986 std::to_string(PatchImm) +
"$" + AccessKey;
993 std::string &AccessKey,
999 std::string AccessStr(
"0");
1006 PatchImm =
BaseTy->getSizeInBits() / 8;
1015 cast<GlobalVariable>(
Call->getArgOperand(1)->stripPointerCasts());
1027 const auto *CTy = cast<DICompositeType>(
BaseTy);
1028 assert(CTy->
getTag() == dwarf::DW_TAG_enumeration_type);
1031 const auto *
Enum = cast<DIEnumerator>(Element);
1032 if (
Enum->getName() == EnumeratorStr) {
1033 AccessStr = std::to_string(EnumIndex);
1041 PatchImm = std::stoll(std::string(EValueStr));
1047 AccessKey =
"llvm." + Ty->
getName().
str() +
":" +
1048 std::to_string(CInfo.AccessIndex) + std::string(
":") +
1049 std::to_string(PatchImm) + std::string(
"$") + AccessStr;
1056bool BPFAbstractMemberAccess::transformGEPChain(
CallInst *Call,
1058 std::string AccessKey;
1063 IsInt32Ret = CInfo.Kind == BPFPreserveFieldInfoAI;
1064 if (CInfo.Kind == BPFPreserveFieldInfoAI && CInfo.Metadata) {
1065 TypeMeta = computeAccessKey(Call, CInfo, AccessKey, IsInt32Ret);
1067 Base = computeBaseAndAccessKey(Call, CInfo, AccessKey, TypeMeta);
1075 if (GEPGlobals.find(AccessKey) == GEPGlobals.end()) {
1083 nullptr, AccessKey);
1085 GV->
setMetadata(LLVMContext::MD_preserve_access_index, TypeMeta);
1086 GEPGlobals[AccessKey] = GV;
1088 GV = GEPGlobals[AccessKey];
1091 if (CInfo.Kind == BPFPreserveFieldInfoAI) {
1096 Call->getIterator());
1099 Call->getIterator());
1103 Call->replaceAllUsesWith(PassThroughInst);
1104 Call->eraseFromParent();
1120 Call->getIterator());
1125 BCInst->insertBefore(Call);
1130 GEP->insertBefore(Call);
1134 BCInst2->insertBefore(Call);
1183 Call->replaceAllUsesWith(PassThroughInst);
1184 Call->eraseFromParent();
1189bool BPFAbstractMemberAccess::doTransformation(
Function &
F) {
1190 bool Transformed =
false;
1195 collectAICallChains(
F);
1197 for (
auto &
C : BaseAICalls)
1198 Transformed = transformGEPChain(
C.first,
C.second) || Transformed;
1200 return removePreserveAccessIndexIntrinsic(
F) || Transformed;
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.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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.
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.
dwarf::Tag getTag() const
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.
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.
void insertBefore(Instruction *InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified instruction.
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.
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the default address space (address sp...
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 IntegerType * getInt8Ty(LLVMContext &C)
static IntegerType * getInt32Ty(LLVMContext &C)
static 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.
#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.
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=std::nullopt)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
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.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
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.