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 for (
unsigned I = 0;
I < Dimension; ++
I)
420 IdxList.
push_back(Call->getArgOperand(GEPIndex));
423 Call->getArgOperand(0), IdxList,
424 "", Call->getIterator());
425 Call->replaceAllUsesWith(
GEP);
426 Call->eraseFromParent();
438 Call->replaceAllUsesWith(Call->getArgOperand(0));
439 Call->eraseFromParent();
442bool BPFAbstractMemberAccess::removePreserveAccessIndexIntrinsic(
Function &
F) {
443 std::vector<CallInst *> PreserveArrayIndexCalls;
444 std::vector<CallInst *> PreserveUnionIndexCalls;
445 std::vector<CallInst *> PreserveStructIndexCalls;
450 auto *Call = dyn_cast<CallInst>(&
I);
452 if (!IsPreserveDIAccessIndexCall(Call, CInfo))
456 if (CInfo.Kind == BPFPreserveArrayAI)
457 PreserveArrayIndexCalls.push_back(Call);
458 else if (CInfo.Kind == BPFPreserveUnionAI)
459 PreserveUnionIndexCalls.push_back(Call);
461 PreserveStructIndexCalls.push_back(Call);
474 for (
CallInst *Call : PreserveArrayIndexCalls)
476 for (
CallInst *Call : PreserveStructIndexCalls)
478 for (
CallInst *Call : PreserveUnionIndexCalls)
487bool BPFAbstractMemberAccess::IsValidAIChain(
const MDNode *ParentType,
489 const MDNode *ChildType) {
498 if (isa<DIDerivedType>(CType))
502 if (
const auto *PtrTy = dyn_cast<DIDerivedType>(PType)) {
503 if (PtrTy->getTag() != dwarf::DW_TAG_pointer_type)
509 const auto *PTy = dyn_cast<DICompositeType>(PType);
510 const auto *CTy = dyn_cast<DICompositeType>(CType);
511 assert(PTy && CTy &&
"ParentType or ChildType is null or not composite");
514 assert(PTyTag == dwarf::DW_TAG_array_type ||
515 PTyTag == dwarf::DW_TAG_structure_type ||
516 PTyTag == dwarf::DW_TAG_union_type);
519 assert(CTyTag == dwarf::DW_TAG_array_type ||
520 CTyTag == dwarf::DW_TAG_structure_type ||
521 CTyTag == dwarf::DW_TAG_union_type);
524 if (PTyTag == dwarf::DW_TAG_array_type && PTyTag == CTyTag)
528 if (PTyTag == dwarf::DW_TAG_array_type)
529 Ty = PTy->getBaseType();
531 Ty = dyn_cast<DIType>(PTy->getElements()[ParentAI]);
536void BPFAbstractMemberAccess::traceAICall(
CallInst *Call,
543 if (
auto *BI = dyn_cast<BitCastInst>(Inst)) {
544 traceBitCast(BI, Call, ParentInfo);
545 }
else if (
auto *CI = dyn_cast<CallInst>(Inst)) {
548 if (IsPreserveDIAccessIndexCall(CI, ChildInfo) &&
549 IsValidAIChain(ParentInfo.Metadata, ParentInfo.AccessIndex,
550 ChildInfo.Metadata)) {
551 AIChain[CI] = std::make_pair(Call, ParentInfo);
552 traceAICall(CI, ChildInfo);
554 BaseAICalls[
Call] = ParentInfo;
556 }
else if (
auto *GI = dyn_cast<GetElementPtrInst>(Inst)) {
557 if (GI->hasAllZeroIndices())
558 traceGEP(GI, Call, ParentInfo);
560 BaseAICalls[
Call] = ParentInfo;
562 BaseAICalls[
Call] = ParentInfo;
567void BPFAbstractMemberAccess::traceBitCast(
BitCastInst *BitCast,
575 if (
auto *BI = dyn_cast<BitCastInst>(Inst)) {
576 traceBitCast(BI, Parent, ParentInfo);
577 }
else if (
auto *CI = dyn_cast<CallInst>(Inst)) {
579 if (IsPreserveDIAccessIndexCall(CI, ChildInfo) &&
580 IsValidAIChain(ParentInfo.Metadata, ParentInfo.AccessIndex,
581 ChildInfo.Metadata)) {
582 AIChain[CI] = std::make_pair(Parent, ParentInfo);
583 traceAICall(CI, ChildInfo);
585 BaseAICalls[Parent] = ParentInfo;
587 }
else if (
auto *GI = dyn_cast<GetElementPtrInst>(Inst)) {
588 if (GI->hasAllZeroIndices())
589 traceGEP(GI, Parent, ParentInfo);
591 BaseAICalls[Parent] = ParentInfo;
593 BaseAICalls[Parent] = ParentInfo;
605 if (
auto *BI = dyn_cast<BitCastInst>(Inst)) {
606 traceBitCast(BI, Parent, ParentInfo);
607 }
else if (
auto *CI = dyn_cast<CallInst>(Inst)) {
609 if (IsPreserveDIAccessIndexCall(CI, ChildInfo) &&
610 IsValidAIChain(ParentInfo.Metadata, ParentInfo.AccessIndex,
611 ChildInfo.Metadata)) {
612 AIChain[CI] = std::make_pair(Parent, ParentInfo);
613 traceAICall(CI, ChildInfo);
615 BaseAICalls[Parent] = ParentInfo;
617 }
else if (
auto *GI = dyn_cast<GetElementPtrInst>(Inst)) {
618 if (GI->hasAllZeroIndices())
619 traceGEP(GI, Parent, ParentInfo);
621 BaseAICalls[Parent] = ParentInfo;
623 BaseAICalls[Parent] = ParentInfo;
628void BPFAbstractMemberAccess::collectAICallChains(
Function &
F) {
635 auto *
Call = dyn_cast<CallInst>(&
I);
636 if (!IsPreserveDIAccessIndexCall(Call, CInfo) ||
637 AIChain.find(Call) != AIChain.end())
640 traceAICall(Call, CInfo);
646 Align RecordAlignment,
652 if (RecordAlignment > 8) {
655 if (MemberBitOffset / 64 != (MemberBitOffset + MemberBitSize) / 64)
657 "requiring too big alignment");
658 RecordAlignment =
Align(8);
662 if (MemberBitSize > AlignBits)
664 "bitfield size greater than record alignment");
666 StartBitOffset = MemberBitOffset & ~(AlignBits - 1);
667 if ((StartBitOffset + AlignBits) < (MemberBitOffset + MemberBitSize))
669 "cross alignment boundary");
670 EndBitOffset = StartBitOffset + AlignBits;
683 if (
Tag == dwarf::DW_TAG_array_type) {
686 (EltTy->getSizeInBits() >> 3);
687 }
else if (
Tag == dwarf::DW_TAG_structure_type) {
690 PatchImm +=
MemberTy->getOffsetInBits() >> 3;
692 unsigned SBitOffset, NextSBitOffset;
693 GetStorageBitRange(
MemberTy, *RecordAlignment, SBitOffset,
695 PatchImm += SBitOffset >> 3;
702 if (
Tag == dwarf::DW_TAG_array_type) {
704 return calcArraySize(CTy, 1) * (EltTy->getSizeInBits() >> 3);
709 return SizeInBits >> 3;
711 unsigned SBitOffset, NextSBitOffset;
712 GetStorageBitRange(
MemberTy, *RecordAlignment, SBitOffset,
714 SizeInBits = NextSBitOffset - SBitOffset;
715 if (SizeInBits & (SizeInBits - 1))
717 return SizeInBits >> 3;
723 if (
Tag == dwarf::DW_TAG_array_type) {
734 const auto *BTy = dyn_cast<DIBasicType>(
BaseTy);
736 const auto *CompTy = dyn_cast<DICompositeType>(
BaseTy);
738 if (!CompTy || CompTy->getTag() != dwarf::DW_TAG_enumeration_type)
741 BTy = dyn_cast<DIBasicType>(
BaseTy);
743 uint32_t Encoding = BTy->getEncoding();
744 return (Encoding == dwarf::DW_ATE_signed || Encoding == dwarf::DW_ATE_signed_char);
754 bool IsBitField =
false;
757 if (
Tag == dwarf::DW_TAG_array_type) {
762 SizeInBits =
MemberTy->getSizeInBits();
763 IsBitField =
MemberTy->isBitField();
769 return 64 - SizeInBits;
772 unsigned SBitOffset, NextSBitOffset;
773 GetStorageBitRange(
MemberTy, *RecordAlignment, SBitOffset, NextSBitOffset);
774 if (NextSBitOffset - SBitOffset > 64)
777 unsigned OffsetInBits =
MemberTy->getOffsetInBits();
779 return SBitOffset + 64 - OffsetInBits - SizeInBits;
781 return OffsetInBits + 64 - NextSBitOffset;
786 bool IsBitField =
false;
788 if (
Tag == dwarf::DW_TAG_array_type) {
793 SizeInBits =
MemberTy->getSizeInBits();
794 IsBitField =
MemberTy->isBitField();
800 return 64 - SizeInBits;
803 unsigned SBitOffset, NextSBitOffset;
804 GetStorageBitRange(
MemberTy, *RecordAlignment, SBitOffset, NextSBitOffset);
805 if (NextSBitOffset - SBitOffset > 64)
808 return 64 - SizeInBits;
814bool BPFAbstractMemberAccess::HasPreserveFieldInfoCall(CallInfoStack &CallStack) {
816 while (CallStack.size()) {
817 auto StackElem = CallStack.top();
818 if (StackElem.second.Kind == BPFPreserveFieldInfoAI)
828Value *BPFAbstractMemberAccess::computeBaseAndAccessKey(
CallInst *Call,
830 std::string &AccessKey,
834 CallInfoStack CallStack;
838 CallStack.push(std::make_pair(Call, CInfo));
839 CInfo = AIChain[
Call].second;
856 while (CallStack.size()) {
857 auto StackElem = CallStack.top();
858 Call = StackElem.first;
859 CInfo = StackElem.second;
867 if (CInfo.Kind == BPFPreserveUnionAI ||
868 CInfo.Kind == BPFPreserveStructAI) {
872 TypeMeta = PossibleTypeDef;
877 assert(CInfo.Kind == BPFPreserveArrayAI);
883 uint64_t AccessIndex = CInfo.AccessIndex;
886 bool CheckElemType =
false;
887 if (
const auto *CTy = dyn_cast<DICompositeType>(Ty)) {
897 auto *DTy = cast<DIDerivedType>(Ty);
901 CTy = dyn_cast<DICompositeType>(
BaseTy);
903 CheckElemType =
true;
904 }
else if (CTy->
getTag() != dwarf::DW_TAG_array_type) {
905 FirstIndex += AccessIndex;
906 CheckElemType =
true;
913 auto *CTy = dyn_cast<DICompositeType>(
BaseTy);
915 if (HasPreserveFieldInfoCall(CallStack))
920 unsigned CTag = CTy->
getTag();
921 if (CTag == dwarf::DW_TAG_structure_type || CTag == dwarf::DW_TAG_union_type) {
924 if (HasPreserveFieldInfoCall(CallStack))
934 AccessKey += std::to_string(FirstIndex);
938 while (CallStack.size()) {
939 auto StackElem = CallStack.top();
940 CInfo = StackElem.second;
943 if (CInfo.Kind == BPFPreserveFieldInfoAI) {
944 InfoKind = CInfo.AccessIndex;
952 if (CallStack.size()) {
953 auto StackElem2 = CallStack.top();
954 CallInfo CInfo2 = StackElem2.second;
955 if (CInfo2.Kind == BPFPreserveFieldInfoAI) {
956 InfoKind = CInfo2.AccessIndex;
957 assert(CallStack.size() == 1);
962 uint64_t AccessIndex = CInfo.AccessIndex;
963 AccessKey +=
":" + std::to_string(AccessIndex);
968 PatchImm = GetFieldInfo(InfoKind, CTy, AccessIndex, PatchImm,
969 CInfo.RecordAlignment);
978 AccessKey =
"llvm." +
TypeName +
":" + std::to_string(InfoKind) +
":" +
979 std::to_string(PatchImm) +
"$" + AccessKey;
986 std::string &AccessKey,
992 std::string AccessStr(
"0");
999 PatchImm =
BaseTy->getSizeInBits() / 8;
1008 cast<GlobalVariable>(
Call->getArgOperand(1)->stripPointerCasts());
1020 const auto *CTy = cast<DICompositeType>(
BaseTy);
1021 assert(CTy->
getTag() == dwarf::DW_TAG_enumeration_type);
1024 const auto *
Enum = cast<DIEnumerator>(Element);
1025 if (
Enum->getName() == EnumeratorStr) {
1026 AccessStr = std::to_string(EnumIndex);
1034 PatchImm = std::stoll(std::string(EValueStr));
1040 AccessKey =
"llvm." + Ty->
getName().
str() +
":" +
1041 std::to_string(CInfo.AccessIndex) + std::string(
":") +
1042 std::to_string(PatchImm) + std::string(
"$") + AccessStr;
1049bool BPFAbstractMemberAccess::transformGEPChain(
CallInst *Call,
1051 std::string AccessKey;
1056 IsInt32Ret = CInfo.Kind == BPFPreserveFieldInfoAI;
1057 if (CInfo.Kind == BPFPreserveFieldInfoAI && CInfo.Metadata) {
1058 TypeMeta = computeAccessKey(Call, CInfo, AccessKey, IsInt32Ret);
1060 Base = computeBaseAndAccessKey(Call, CInfo, AccessKey, TypeMeta);
1068 if (GEPGlobals.find(AccessKey) == GEPGlobals.end()) {
1076 nullptr, AccessKey);
1078 GV->
setMetadata(LLVMContext::MD_preserve_access_index, TypeMeta);
1079 GEPGlobals[AccessKey] = GV;
1081 GV = GEPGlobals[AccessKey];
1084 if (CInfo.Kind == BPFPreserveFieldInfoAI) {
1089 Call->getIterator());
1092 Call->getIterator());
1096 Call->replaceAllUsesWith(PassThroughInst);
1097 Call->eraseFromParent();
1113 Call->getIterator());
1118 BCInst->insertBefore(Call);
1123 GEP->insertBefore(Call);
1127 BCInst2->insertBefore(Call);
1176 Call->replaceAllUsesWith(PassThroughInst);
1177 Call->eraseFromParent();
1182bool BPFAbstractMemberAccess::doTransformation(
Function &
F) {
1183 bool Transformed =
false;
1188 collectAICallChains(
F);
1190 for (
auto &
C : BaseAICalls)
1191 Transformed = transformGEPChain(
C.first,
C.second) || Transformed;
1193 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 * 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.
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.