86#include "llvm/IR/IntrinsicsBPF.h"
96#define DEBUG_TYPE "bpf-abstract-member-access"
106 M, Intrinsic::bpf_passthrough, {Input->
getType(), Input->
getType()});
119class BPFAbstractMemberAccess final {
132 typedef std::stack<std::pair<CallInst *, CallInfo>> CallInfoStack;
136 BPFPreserveArrayAI = 1,
137 BPFPreserveUnionAI = 2,
138 BPFPreserveStructAI = 3,
139 BPFPreserveFieldInfoAI = 4,
146 static std::map<std::string, GlobalVariable *> GEPGlobals;
148 std::map<CallInst *, std::pair<CallInst *, CallInfo>> AIChain;
152 std::map<CallInst *, CallInfo> BaseAICalls;
154 std::map<DICompositeType *, DIDerivedType *> AnonRecords;
159 void ResetMetadata(
struct CallInfo &CInfo);
173 bool removePreserveAccessIndexIntrinsic(
Function &
F);
174 void replaceWithGEP(std::vector<CallInst *> &CallList,
176 bool HasPreserveFieldInfoCall(CallInfoStack &CallStack);
184 std::string &AccessKey,
MDNode *&BaseMeta);
186 std::string &AccessKey,
bool &IsInt32Ret);
191std::map<std::string, GlobalVariable *> BPFAbstractMemberAccess::GEPGlobals;
194bool BPFAbstractMemberAccess::run(
Function &
F) {
195 LLVM_DEBUG(
dbgs() <<
"********** Abstract Member Accesses **********\n");
202 if (
M->debug_compile_units().empty())
211 if (SP && SP->isDefinition()) {
212 for (
DIType *Ty: SP->getType()->getTypeArray())
213 CheckAnonRecordType(
nullptr, Ty);
214 for (
const DINode *DN : SP->getRetainedNodes()) {
215 if (
const auto *DV = dyn_cast<DILocalVariable>(DN))
216 CheckAnonRecordType(
nullptr, DV->getType());
220 DL = &
M->getDataLayout();
221 return doTransformation(
F);
224void BPFAbstractMemberAccess::ResetMetadata(
struct CallInfo &CInfo) {
225 if (
auto Ty = dyn_cast<DICompositeType>(CInfo.Metadata)) {
226 if (AnonRecords.find(Ty) != AnonRecords.end()) {
227 if (AnonRecords[Ty] !=
nullptr)
228 CInfo.Metadata = AnonRecords[Ty];
233void BPFAbstractMemberAccess::CheckCompositeType(
DIDerivedType *ParentTy,
236 ParentTy->
getTag() != dwarf::DW_TAG_typedef)
239 if (AnonRecords.find(CTy) == AnonRecords.end()) {
240 AnonRecords[CTy] = ParentTy;
248 if (CurrTy == ParentTy)
250 AnonRecords[CTy] =
nullptr;
253void BPFAbstractMemberAccess::CheckDerivedType(
DIDerivedType *ParentTy,
260 if (
Tag == dwarf::DW_TAG_pointer_type)
261 CheckAnonRecordType(
nullptr,
BaseType);
262 else if (
Tag == dwarf::DW_TAG_typedef)
265 CheckAnonRecordType(ParentTy,
BaseType);
268void BPFAbstractMemberAccess::CheckAnonRecordType(
DIDerivedType *ParentTy,
273 if (
auto *CTy = dyn_cast<DICompositeType>(Ty))
274 return CheckCompositeType(ParentTy, CTy);
275 else if (
auto *DTy = dyn_cast<DIDerivedType>(Ty))
276 return CheckDerivedType(ParentTy, DTy);
280 if (
Tag != dwarf::DW_TAG_typedef &&
Tag != dwarf::DW_TAG_const_type &&
281 Tag != dwarf::DW_TAG_volatile_type &&
282 Tag != dwarf::DW_TAG_restrict_type &&
283 Tag != dwarf::DW_TAG_member)
285 if (
Tag == dwarf::DW_TAG_typedef && !skipTypedef)
291 while (
auto *DTy = dyn_cast<DIDerivedType>(Ty)) {
294 Ty = DTy->getBaseType();
300 while (
auto *DTy = dyn_cast<DIDerivedType>(Ty)) {
303 Ty = DTy->getBaseType();
311 for (
uint32_t I = StartDim;
I < Elements.size(); ++
I) {
312 if (
auto *Element = dyn_cast_or_null<DINode>(Elements[
I]))
313 if (Element->getTag() == dwarf::DW_TAG_subrange_type) {
314 const DISubrange *SR = cast<DISubrange>(Element);
316 DimSize *= CI->getSExtValue();
325 return Call->getParamElementType(0);
329bool BPFAbstractMemberAccess::IsPreserveDIAccessIndexCall(
const CallInst *Call,
334 const auto *GV = dyn_cast<GlobalValue>(
Call->getCalledOperand());
337 if (GV->getName().startswith(
"llvm.preserve.array.access.index")) {
338 CInfo.Kind = BPFPreserveArrayAI;
339 CInfo.Metadata =
Call->getMetadata(LLVMContext::MD_preserve_access_index);
341 report_fatal_error(
"Missing metadata for llvm.preserve.array.access.index intrinsic");
342 CInfo.AccessIndex = getConstant(
Call->getArgOperand(2));
343 CInfo.Base =
Call->getArgOperand(0);
347 if (GV->getName().startswith(
"llvm.preserve.union.access.index")) {
348 CInfo.Kind = BPFPreserveUnionAI;
349 CInfo.Metadata =
Call->getMetadata(LLVMContext::MD_preserve_access_index);
351 report_fatal_error(
"Missing metadata for llvm.preserve.union.access.index intrinsic");
352 ResetMetadata(CInfo);
353 CInfo.AccessIndex = getConstant(
Call->getArgOperand(1));
354 CInfo.Base =
Call->getArgOperand(0);
357 if (GV->getName().startswith(
"llvm.preserve.struct.access.index")) {
358 CInfo.Kind = BPFPreserveStructAI;
359 CInfo.Metadata =
Call->getMetadata(LLVMContext::MD_preserve_access_index);
361 report_fatal_error(
"Missing metadata for llvm.preserve.struct.access.index intrinsic");
362 ResetMetadata(CInfo);
363 CInfo.AccessIndex = getConstant(
Call->getArgOperand(2));
364 CInfo.Base =
Call->getArgOperand(0);
368 if (GV->getName().startswith(
"llvm.bpf.preserve.field.info")) {
369 CInfo.Kind = BPFPreserveFieldInfoAI;
370 CInfo.Metadata =
nullptr;
372 uint64_t InfoKind = getConstant(
Call->getArgOperand(1));
375 CInfo.AccessIndex = InfoKind;
378 if (GV->getName().startswith(
"llvm.bpf.preserve.type.info")) {
379 CInfo.Kind = BPFPreserveFieldInfoAI;
380 CInfo.Metadata =
Call->getMetadata(LLVMContext::MD_preserve_access_index);
394 if (GV->getName().startswith(
"llvm.bpf.preserve.enum.value")) {
395 CInfo.Kind = BPFPreserveFieldInfoAI;
396 CInfo.Metadata =
Call->getMetadata(LLVMContext::MD_preserve_access_index);
412void BPFAbstractMemberAccess::replaceWithGEP(std::vector<CallInst *> &CallList,
415 for (
auto *Call : CallList) {
417 if (DimensionIndex > 0)
418 Dimension = getConstant(
Call->getArgOperand(DimensionIndex));
430 Call->eraseFromParent();
434bool BPFAbstractMemberAccess::removePreserveAccessIndexIntrinsic(
Function &
F) {
435 std::vector<CallInst *> PreserveArrayIndexCalls;
436 std::vector<CallInst *> PreserveUnionIndexCalls;
437 std::vector<CallInst *> PreserveStructIndexCalls;
442 auto *
Call = dyn_cast<CallInst>(&
I);
444 if (!IsPreserveDIAccessIndexCall(Call, CInfo))
448 if (CInfo.Kind == BPFPreserveArrayAI)
449 PreserveArrayIndexCalls.push_back(Call);
450 else if (CInfo.Kind == BPFPreserveUnionAI)
451 PreserveUnionIndexCalls.push_back(Call);
453 PreserveStructIndexCalls.push_back(Call);
466 replaceWithGEP(PreserveArrayIndexCalls, 1, 2);
467 replaceWithGEP(PreserveStructIndexCalls, 0, 1);
468 for (
auto *Call : PreserveUnionIndexCalls) {
469 Call->replaceAllUsesWith(
Call->getArgOperand(0));
470 Call->eraseFromParent();
479bool BPFAbstractMemberAccess::IsValidAIChain(
const MDNode *ParentType,
481 const MDNode *ChildType) {
490 if (isa<DIDerivedType>(CType))
494 if (
const auto *PtrTy = dyn_cast<DIDerivedType>(PType)) {
495 if (PtrTy->getTag() != dwarf::DW_TAG_pointer_type)
501 const auto *PTy = dyn_cast<DICompositeType>(PType);
502 const auto *CTy = dyn_cast<DICompositeType>(CType);
503 assert(PTy && CTy &&
"ParentType or ChildType is null or not composite");
506 assert(PTyTag == dwarf::DW_TAG_array_type ||
507 PTyTag == dwarf::DW_TAG_structure_type ||
508 PTyTag == dwarf::DW_TAG_union_type);
511 assert(CTyTag == dwarf::DW_TAG_array_type ||
512 CTyTag == dwarf::DW_TAG_structure_type ||
513 CTyTag == dwarf::DW_TAG_union_type);
516 if (PTyTag == dwarf::DW_TAG_array_type && PTyTag == CTyTag)
520 if (PTyTag == dwarf::DW_TAG_array_type)
521 Ty = PTy->getBaseType();
523 Ty = dyn_cast<DIType>(PTy->getElements()[ParentAI]);
528void BPFAbstractMemberAccess::traceAICall(
CallInst *Call,
535 if (
auto *BI = dyn_cast<BitCastInst>(Inst)) {
536 traceBitCast(BI, Call, ParentInfo);
537 }
else if (
auto *CI = dyn_cast<CallInst>(Inst)) {
540 if (IsPreserveDIAccessIndexCall(CI, ChildInfo) &&
541 IsValidAIChain(ParentInfo.Metadata, ParentInfo.AccessIndex,
542 ChildInfo.Metadata)) {
543 AIChain[CI] = std::make_pair(Call, ParentInfo);
544 traceAICall(CI, ChildInfo);
546 BaseAICalls[
Call] = ParentInfo;
548 }
else if (
auto *GI = dyn_cast<GetElementPtrInst>(Inst)) {
549 if (GI->hasAllZeroIndices())
550 traceGEP(GI, Call, ParentInfo);
552 BaseAICalls[
Call] = ParentInfo;
554 BaseAICalls[
Call] = ParentInfo;
559void BPFAbstractMemberAccess::traceBitCast(
BitCastInst *BitCast,
567 if (
auto *BI = dyn_cast<BitCastInst>(Inst)) {
568 traceBitCast(BI, Parent, ParentInfo);
569 }
else if (
auto *CI = dyn_cast<CallInst>(Inst)) {
571 if (IsPreserveDIAccessIndexCall(CI, ChildInfo) &&
572 IsValidAIChain(ParentInfo.Metadata, ParentInfo.AccessIndex,
573 ChildInfo.Metadata)) {
574 AIChain[CI] = std::make_pair(Parent, ParentInfo);
575 traceAICall(CI, ChildInfo);
577 BaseAICalls[Parent] = ParentInfo;
579 }
else if (
auto *GI = dyn_cast<GetElementPtrInst>(Inst)) {
580 if (GI->hasAllZeroIndices())
581 traceGEP(GI, Parent, ParentInfo);
583 BaseAICalls[Parent] = ParentInfo;
585 BaseAICalls[Parent] = ParentInfo;
597 if (
auto *BI = dyn_cast<BitCastInst>(Inst)) {
598 traceBitCast(BI, Parent, ParentInfo);
599 }
else if (
auto *CI = dyn_cast<CallInst>(Inst)) {
601 if (IsPreserveDIAccessIndexCall(CI, ChildInfo) &&
602 IsValidAIChain(ParentInfo.Metadata, ParentInfo.AccessIndex,
603 ChildInfo.Metadata)) {
604 AIChain[CI] = std::make_pair(Parent, ParentInfo);
605 traceAICall(CI, ChildInfo);
607 BaseAICalls[Parent] = ParentInfo;
609 }
else if (
auto *GI = dyn_cast<GetElementPtrInst>(Inst)) {
610 if (GI->hasAllZeroIndices())
611 traceGEP(GI, Parent, ParentInfo);
613 BaseAICalls[Parent] = ParentInfo;
615 BaseAICalls[Parent] = ParentInfo;
620void BPFAbstractMemberAccess::collectAICallChains(
Function &
F) {
627 auto *
Call = dyn_cast<CallInst>(&
I);
628 if (!IsPreserveDIAccessIndexCall(Call, CInfo) ||
629 AIChain.find(Call) != AIChain.end())
632 traceAICall(Call, CInfo);
636uint64_t BPFAbstractMemberAccess::getConstant(
const Value *IndexValue) {
637 const ConstantInt *CV = dyn_cast<ConstantInt>(IndexValue);
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 CInfo = AIChain[
Call].second;
854 while (CallStack.size()) {
855 auto StackElem = CallStack.top();
856 Call = StackElem.first;
857 CInfo = StackElem.second;
865 if (CInfo.Kind == BPFPreserveUnionAI ||
866 CInfo.Kind == BPFPreserveStructAI) {
870 TypeMeta = PossibleTypeDef;
875 assert(CInfo.Kind == BPFPreserveArrayAI);
881 uint64_t AccessIndex = CInfo.AccessIndex;
884 bool CheckElemType =
false;
885 if (
const auto *CTy = dyn_cast<DICompositeType>(Ty)) {
895 auto *DTy = cast<DIDerivedType>(Ty);
899 CTy = dyn_cast<DICompositeType>(
BaseTy);
901 CheckElemType =
true;
902 }
else if (CTy->
getTag() != dwarf::DW_TAG_array_type) {
903 FirstIndex += AccessIndex;
904 CheckElemType =
true;
911 auto *CTy = dyn_cast<DICompositeType>(
BaseTy);
913 if (HasPreserveFieldInfoCall(CallStack))
918 unsigned CTag = CTy->
getTag();
919 if (CTag == dwarf::DW_TAG_structure_type || CTag == dwarf::DW_TAG_union_type) {
922 if (HasPreserveFieldInfoCall(CallStack))
932 AccessKey += std::to_string(FirstIndex);
936 while (CallStack.size()) {
937 auto StackElem = CallStack.top();
938 CInfo = StackElem.second;
941 if (CInfo.Kind == BPFPreserveFieldInfoAI) {
942 InfoKind = CInfo.AccessIndex;
950 if (CallStack.size()) {
951 auto StackElem2 = CallStack.top();
952 CallInfo CInfo2 = StackElem2.second;
953 if (CInfo2.Kind == BPFPreserveFieldInfoAI) {
954 InfoKind = CInfo2.AccessIndex;
955 assert(CallStack.size() == 1);
960 uint64_t AccessIndex = CInfo.AccessIndex;
961 AccessKey +=
":" + std::to_string(AccessIndex);
966 PatchImm = GetFieldInfo(InfoKind, CTy, AccessIndex, PatchImm,
967 CInfo.RecordAlignment);
976 AccessKey =
"llvm." +
TypeName +
":" + std::to_string(InfoKind) +
":" +
977 std::to_string(PatchImm) +
"$" + AccessKey;
984 std::string &AccessKey,
990 std::string AccessStr(
"0");
997 PatchImm =
BaseTy->getSizeInBits() / 8;
1006 cast<GlobalVariable>(
Call->getArgOperand(1)->stripPointerCasts());
1018 const auto *CTy = cast<DICompositeType>(
BaseTy);
1019 assert(CTy->
getTag() == dwarf::DW_TAG_enumeration_type);
1022 const auto *
Enum = cast<DIEnumerator>(Element);
1023 if (
Enum->getName() == EnumeratorStr) {
1024 AccessStr = std::to_string(EnumIndex);
1032 PatchImm = std::stoll(std::string(EValueStr));
1038 AccessKey =
"llvm." + Ty->
getName().
str() +
":" +
1039 std::to_string(CInfo.AccessIndex) + std::string(
":") +
1040 std::to_string(PatchImm) + std::string(
"$") + AccessStr;
1047bool BPFAbstractMemberAccess::transformGEPChain(
CallInst *Call,
1049 std::string AccessKey;
1054 IsInt32Ret = CInfo.Kind == BPFPreserveFieldInfoAI;
1055 if (CInfo.Kind == BPFPreserveFieldInfoAI && CInfo.Metadata) {
1056 TypeMeta = computeAccessKey(Call, CInfo, AccessKey, IsInt32Ret);
1058 Base = computeBaseAndAccessKey(Call, CInfo, AccessKey, TypeMeta);
1066 if (GEPGlobals.find(AccessKey) == GEPGlobals.end()) {
1073 GV =
new GlobalVariable(*M, VarType,
false, GlobalVariable::ExternalLinkage,
1074 nullptr, AccessKey);
1076 GV->
setMetadata(LLVMContext::MD_preserve_access_index, TypeMeta);
1077 GEPGlobals[AccessKey] = GV;
1079 GV = GEPGlobals[AccessKey];
1082 if (CInfo.Kind == BPFPreserveFieldInfoAI) {
1092 Call->replaceAllUsesWith(PassThroughInst);
1093 Call->eraseFromParent();
1112 BCInst->insertBefore(Call);
1117 GEP->insertBefore(Call);
1121 BCInst2->insertBefore(Call);
1170 Call->replaceAllUsesWith(PassThroughInst);
1171 Call->eraseFromParent();
1176bool BPFAbstractMemberAccess::doTransformation(
Function &
F) {
1177 bool Transformed =
false;
1182 collectAICallChains(
F);
1184 for (
auto &
C : BaseAICalls)
1185 Transformed = transformGEPChain(
C.first,
C.second) || Transformed;
1187 return removePreserveAccessIndexIntrinsic(
F) || Transformed;
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
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.
const char LLVMTargetMachineRef TM
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 uint32_t SeqNum
llvm.bpf.passthrough builtin seq number
@ PRESERVE_TYPE_INFO_EXISTENCE
@ MAX_PRESERVE_TYPE_INFO_FLAG
@ PRESERVE_TYPE_INFO_MATCH
@ 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="", Instruction *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.
static Constant * get(Type *Ty, uint64_t V, bool IsSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
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 * CreateInBounds(Type *PointeeType, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
Create an "inbounds" getelementptr.
static GetElementPtrInst * Create(Type *PointeeType, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
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.
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.
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 PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
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.