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().startswith(
"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().startswith(
"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().startswith(
"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().startswith(
"llvm.bpf.preserve.field.info")) {
373 CInfo.Kind = BPFPreserveFieldInfoAI;
374 CInfo.Metadata =
nullptr;
379 CInfo.AccessIndex = InfoKind;
382 if (GV->getName().startswith(
"llvm.bpf.preserve.type.info")) {
383 CInfo.Kind = BPFPreserveFieldInfoAI;
384 CInfo.Metadata =
Call->getMetadata(LLVMContext::MD_preserve_access_index);
398 if (GV->getName().startswith(
"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));
431 Call->replaceAllUsesWith(
GEP);
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;
456 auto *Call = dyn_cast<CallInst>(&
I);
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);
480 for (
CallInst *Call : PreserveArrayIndexCalls)
482 for (
CallInst *Call : PreserveStructIndexCalls)
484 for (
CallInst *Call : PreserveUnionIndexCalls)
493bool BPFAbstractMemberAccess::IsValidAIChain(
const MDNode *ParentType,
495 const MDNode *ChildType) {
504 if (isa<DIDerivedType>(CType))
508 if (
const auto *PtrTy = dyn_cast<DIDerivedType>(PType)) {
509 if (PtrTy->getTag() != dwarf::DW_TAG_pointer_type)
515 const auto *PTy = dyn_cast<DICompositeType>(PType);
516 const auto *CTy = dyn_cast<DICompositeType>(CType);
517 assert(PTy && CTy &&
"ParentType or ChildType is null or not composite");
520 assert(PTyTag == dwarf::DW_TAG_array_type ||
521 PTyTag == dwarf::DW_TAG_structure_type ||
522 PTyTag == dwarf::DW_TAG_union_type);
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();
537 Ty = dyn_cast<DIType>(PTy->getElements()[ParentAI]);
542void BPFAbstractMemberAccess::traceAICall(
CallInst *Call,
549 if (
auto *BI = dyn_cast<BitCastInst>(Inst)) {
550 traceBitCast(BI, Call, ParentInfo);
551 }
else if (
auto *CI = dyn_cast<CallInst>(Inst)) {
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;
562 }
else if (
auto *GI = dyn_cast<GetElementPtrInst>(Inst)) {
563 if (GI->hasAllZeroIndices())
564 traceGEP(GI, Call, ParentInfo);
566 BaseAICalls[
Call] = ParentInfo;
568 BaseAICalls[
Call] = ParentInfo;
573void BPFAbstractMemberAccess::traceBitCast(
BitCastInst *BitCast,
581 if (
auto *BI = dyn_cast<BitCastInst>(Inst)) {
582 traceBitCast(BI, Parent, ParentInfo);
583 }
else if (
auto *CI = dyn_cast<CallInst>(Inst)) {
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;
593 }
else if (
auto *GI = dyn_cast<GetElementPtrInst>(Inst)) {
594 if (GI->hasAllZeroIndices())
595 traceGEP(GI, Parent, ParentInfo);
597 BaseAICalls[Parent] = ParentInfo;
599 BaseAICalls[Parent] = ParentInfo;
611 if (
auto *BI = dyn_cast<BitCastInst>(Inst)) {
612 traceBitCast(BI, Parent, ParentInfo);
613 }
else if (
auto *CI = dyn_cast<CallInst>(Inst)) {
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;
623 }
else if (
auto *GI = dyn_cast<GetElementPtrInst>(Inst)) {
624 if (GI->hasAllZeroIndices())
625 traceGEP(GI, Parent, ParentInfo);
627 BaseAICalls[Parent] = ParentInfo;
629 BaseAICalls[Parent] = ParentInfo;
634void BPFAbstractMemberAccess::collectAICallChains(
Function &
F) {
641 auto *
Call = dyn_cast<CallInst>(&
I);
642 if (!IsPreserveDIAccessIndexCall(Call, CInfo) ||
643 AIChain.find(Call) != AIChain.end())
646 traceAICall(Call, CInfo);
652 Align RecordAlignment,
658 if (RecordAlignment > 8) {
661 if (MemberBitOffset / 64 != (MemberBitOffset + MemberBitSize) / 64)
663 "requiring too big alignment");
664 RecordAlignment =
Align(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;
689 if (
Tag == dwarf::DW_TAG_array_type) {
692 (EltTy->getSizeInBits() >> 3);
693 }
else if (
Tag == dwarf::DW_TAG_structure_type) {
696 PatchImm +=
MemberTy->getOffsetInBits() >> 3;
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;
729 if (
Tag == dwarf::DW_TAG_array_type) {
740 const auto *BTy = dyn_cast<DIBasicType>(
BaseTy);
742 const auto *CompTy = dyn_cast<DICompositeType>(
BaseTy);
744 if (!CompTy || CompTy->getTag() != dwarf::DW_TAG_enumeration_type)
747 BTy = dyn_cast<DIBasicType>(
BaseTy);
749 uint32_t Encoding = BTy->getEncoding();
750 return (Encoding == dwarf::DW_ATE_signed || Encoding == dwarf::DW_ATE_signed_char);
760 bool IsBitField =
false;
763 if (
Tag == dwarf::DW_TAG_array_type) {
768 SizeInBits =
MemberTy->getSizeInBits();
769 IsBitField =
MemberTy->isBitField();
775 return 64 - SizeInBits;
778 unsigned SBitOffset, NextSBitOffset;
779 GetStorageBitRange(
MemberTy, *RecordAlignment, SBitOffset, NextSBitOffset);
780 if (NextSBitOffset - SBitOffset > 64)
783 unsigned OffsetInBits =
MemberTy->getOffsetInBits();
785 return SBitOffset + 64 - OffsetInBits - SizeInBits;
787 return OffsetInBits + 64 - NextSBitOffset;
792 bool IsBitField =
false;
794 if (
Tag == dwarf::DW_TAG_array_type) {
799 SizeInBits =
MemberTy->getSizeInBits();
800 IsBitField =
MemberTy->isBitField();
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 CInfo = AIChain[
Call].second;
862 while (CallStack.size()) {
863 auto StackElem = CallStack.top();
864 Call = StackElem.first;
865 CInfo = StackElem.second;
873 if (CInfo.Kind == BPFPreserveUnionAI ||
874 CInfo.Kind == BPFPreserveStructAI) {
878 TypeMeta = PossibleTypeDef;
883 assert(CInfo.Kind == BPFPreserveArrayAI);
889 uint64_t AccessIndex = CInfo.AccessIndex;
892 bool CheckElemType =
false;
893 if (
const auto *CTy = dyn_cast<DICompositeType>(Ty)) {
903 auto *DTy = cast<DIDerivedType>(Ty);
907 CTy = dyn_cast<DICompositeType>(
BaseTy);
909 CheckElemType =
true;
910 }
else if (CTy->
getTag() != dwarf::DW_TAG_array_type) {
911 FirstIndex += AccessIndex;
912 CheckElemType =
true;
919 auto *CTy = dyn_cast<DICompositeType>(
BaseTy);
921 if (HasPreserveFieldInfoCall(CallStack))
926 unsigned CTag = CTy->
getTag();
927 if (CTag == dwarf::DW_TAG_structure_type || CTag == dwarf::DW_TAG_union_type) {
930 if (HasPreserveFieldInfoCall(CallStack))
940 AccessKey += std::to_string(FirstIndex);
944 while (CallStack.size()) {
945 auto StackElem = CallStack.top();
946 CInfo = StackElem.second;
949 if (CInfo.Kind == BPFPreserveFieldInfoAI) {
950 InfoKind = CInfo.AccessIndex;
958 if (CallStack.size()) {
959 auto StackElem2 = CallStack.top();
960 CallInfo CInfo2 = StackElem2.second;
961 if (CInfo2.Kind == BPFPreserveFieldInfoAI) {
962 InfoKind = CInfo2.AccessIndex;
963 assert(CallStack.size() == 1);
968 uint64_t AccessIndex = CInfo.AccessIndex;
969 AccessKey +=
":" + std::to_string(AccessIndex);
974 PatchImm = GetFieldInfo(InfoKind, CTy, AccessIndex, PatchImm,
975 CInfo.RecordAlignment);
984 AccessKey =
"llvm." +
TypeName +
":" + std::to_string(InfoKind) +
":" +
985 std::to_string(PatchImm) +
"$" + AccessKey;
992 std::string &AccessKey,
998 std::string AccessStr(
"0");
1005 PatchImm =
BaseTy->getSizeInBits() / 8;
1014 cast<GlobalVariable>(
Call->getArgOperand(1)->stripPointerCasts());
1026 const auto *CTy = cast<DICompositeType>(
BaseTy);
1027 assert(CTy->
getTag() == dwarf::DW_TAG_enumeration_type);
1030 const auto *
Enum = cast<DIEnumerator>(Element);
1031 if (
Enum->getName() == EnumeratorStr) {
1032 AccessStr = std::to_string(EnumIndex);
1040 PatchImm = std::stoll(std::string(EValueStr));
1046 AccessKey =
"llvm." + Ty->
getName().
str() +
":" +
1047 std::to_string(CInfo.AccessIndex) + std::string(
":") +
1048 std::to_string(PatchImm) + std::string(
"$") + AccessStr;
1055bool BPFAbstractMemberAccess::transformGEPChain(
CallInst *Call,
1057 std::string AccessKey;
1062 IsInt32Ret = CInfo.Kind == BPFPreserveFieldInfoAI;
1063 if (CInfo.Kind == BPFPreserveFieldInfoAI && CInfo.Metadata) {
1064 TypeMeta = computeAccessKey(Call, CInfo, AccessKey, IsInt32Ret);
1066 Base = computeBaseAndAccessKey(Call, CInfo, AccessKey, TypeMeta);
1074 if (GEPGlobals.find(AccessKey) == GEPGlobals.end()) {
1082 nullptr, AccessKey);
1084 GV->
setMetadata(LLVMContext::MD_preserve_access_index, TypeMeta);
1085 GEPGlobals[AccessKey] = GV;
1087 GV = GEPGlobals[AccessKey];
1090 if (CInfo.Kind == BPFPreserveFieldInfoAI) {
1100 Call->replaceAllUsesWith(PassThroughInst);
1101 Call->eraseFromParent();
1121 BCInst->insertBefore(Call);
1126 GEP->insertBefore(Call);
1130 BCInst2->insertBefore(Call);
1179 Call->replaceAllUsesWith(PassThroughInst);
1180 Call->eraseFromParent();
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;
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.
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 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="", 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.
@ 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.