85#include "llvm/IR/IntrinsicsBPF.h"
95#define DEBUG_TYPE "bpf-abstract-member-access"
105 M, Intrinsic::bpf_passthrough, {Input->
getType(), Input->
getType()});
118class BPFAbstractMemberAccess final {
131 typedef std::stack<std::pair<CallInst *, CallInfo>> CallInfoStack;
135 BPFPreserveArrayAI = 1,
136 BPFPreserveUnionAI = 2,
137 BPFPreserveStructAI = 3,
138 BPFPreserveFieldInfoAI = 4,
145 static std::map<std::string, GlobalVariable *> GEPGlobals;
147 std::map<CallInst *, std::pair<CallInst *, CallInfo>> AIChain;
151 std::map<CallInst *, CallInfo> BaseAICalls;
153 std::map<DICompositeType *, DIDerivedType *> AnonRecords;
158 void ResetMetadata(
struct CallInfo &CInfo);
172 bool removePreserveAccessIndexIntrinsic(
Function &
F);
173 void replaceWithGEP(std::vector<CallInst *> &CallList,
175 bool HasPreserveFieldInfoCall(CallInfoStack &CallStack);
183 std::string &AccessKey,
MDNode *&BaseMeta);
185 std::string &AccessKey,
bool &IsInt32Ret);
190std::map<std::string, GlobalVariable *> BPFAbstractMemberAccess::GEPGlobals;
192class BPFAbstractMemberAccessLegacyPass final :
public FunctionPass {
196 return BPFAbstractMemberAccess(TM).run(
F);
212char BPFAbstractMemberAccessLegacyPass::ID = 0;
214 "BPF Abstract Member Access",
false,
false)
217 return new BPFAbstractMemberAccessLegacyPass(
TM);
220bool BPFAbstractMemberAccess::run(
Function &
F) {
221 LLVM_DEBUG(
dbgs() <<
"********** Abstract Member Accesses **********\n");
228 if (
M->debug_compile_units().empty())
237 if (SP && SP->isDefinition()) {
238 for (
DIType *Ty: SP->getType()->getTypeArray())
239 CheckAnonRecordType(
nullptr, Ty);
240 for (
const DINode *DN : SP->getRetainedNodes()) {
241 if (
const auto *DV = dyn_cast<DILocalVariable>(DN))
242 CheckAnonRecordType(
nullptr, DV->getType());
246 DL = &
M->getDataLayout();
247 return doTransformation(
F);
250void BPFAbstractMemberAccess::ResetMetadata(
struct CallInfo &CInfo) {
251 if (
auto Ty = dyn_cast<DICompositeType>(CInfo.Metadata)) {
252 if (AnonRecords.find(Ty) != AnonRecords.end()) {
253 if (AnonRecords[Ty] !=
nullptr)
254 CInfo.Metadata = AnonRecords[Ty];
259void BPFAbstractMemberAccess::CheckCompositeType(
DIDerivedType *ParentTy,
262 ParentTy->
getTag() != dwarf::DW_TAG_typedef)
265 if (AnonRecords.find(CTy) == AnonRecords.end()) {
266 AnonRecords[CTy] = ParentTy;
274 if (CurrTy == ParentTy)
276 AnonRecords[CTy] =
nullptr;
279void BPFAbstractMemberAccess::CheckDerivedType(
DIDerivedType *ParentTy,
286 if (
Tag == dwarf::DW_TAG_pointer_type)
287 CheckAnonRecordType(
nullptr,
BaseType);
288 else if (
Tag == dwarf::DW_TAG_typedef)
291 CheckAnonRecordType(ParentTy,
BaseType);
294void BPFAbstractMemberAccess::CheckAnonRecordType(
DIDerivedType *ParentTy,
299 if (
auto *CTy = dyn_cast<DICompositeType>(Ty))
300 return CheckCompositeType(ParentTy, CTy);
301 else if (
auto *DTy = dyn_cast<DIDerivedType>(Ty))
302 return CheckDerivedType(ParentTy, DTy);
306 if (
Tag != dwarf::DW_TAG_typedef &&
Tag != dwarf::DW_TAG_const_type &&
307 Tag != dwarf::DW_TAG_volatile_type &&
308 Tag != dwarf::DW_TAG_restrict_type &&
309 Tag != dwarf::DW_TAG_member)
311 if (
Tag == dwarf::DW_TAG_typedef && !skipTypedef)
317 while (
auto *DTy = dyn_cast<DIDerivedType>(Ty)) {
320 Ty = DTy->getBaseType();
326 while (
auto *DTy = dyn_cast<DIDerivedType>(Ty)) {
329 Ty = DTy->getBaseType();
337 for (
uint32_t I = StartDim;
I < Elements.size(); ++
I) {
338 if (
auto *Element = dyn_cast_or_null<DINode>(Elements[
I]))
339 if (Element->getTag() == dwarf::DW_TAG_subrange_type) {
340 const DISubrange *SR = cast<DISubrange>(Element);
342 DimSize *= CI->getSExtValue();
351 return Call->getParamElementType(0);
355bool BPFAbstractMemberAccess::IsPreserveDIAccessIndexCall(
const CallInst *Call,
360 const auto *GV = dyn_cast<GlobalValue>(
Call->getCalledOperand());
363 if (GV->getName().startswith(
"llvm.preserve.array.access.index")) {
364 CInfo.Kind = BPFPreserveArrayAI;
365 CInfo.Metadata =
Call->getMetadata(LLVMContext::MD_preserve_access_index);
367 report_fatal_error(
"Missing metadata for llvm.preserve.array.access.index intrinsic");
368 CInfo.AccessIndex = getConstant(
Call->getArgOperand(2));
369 CInfo.Base =
Call->getArgOperand(0);
373 if (GV->getName().startswith(
"llvm.preserve.union.access.index")) {
374 CInfo.Kind = BPFPreserveUnionAI;
375 CInfo.Metadata =
Call->getMetadata(LLVMContext::MD_preserve_access_index);
377 report_fatal_error(
"Missing metadata for llvm.preserve.union.access.index intrinsic");
378 ResetMetadata(CInfo);
379 CInfo.AccessIndex = getConstant(
Call->getArgOperand(1));
380 CInfo.Base =
Call->getArgOperand(0);
383 if (GV->getName().startswith(
"llvm.preserve.struct.access.index")) {
384 CInfo.Kind = BPFPreserveStructAI;
385 CInfo.Metadata =
Call->getMetadata(LLVMContext::MD_preserve_access_index);
387 report_fatal_error(
"Missing metadata for llvm.preserve.struct.access.index intrinsic");
388 ResetMetadata(CInfo);
389 CInfo.AccessIndex = getConstant(
Call->getArgOperand(2));
390 CInfo.Base =
Call->getArgOperand(0);
394 if (GV->getName().startswith(
"llvm.bpf.preserve.field.info")) {
395 CInfo.Kind = BPFPreserveFieldInfoAI;
396 CInfo.Metadata =
nullptr;
398 uint64_t InfoKind = getConstant(
Call->getArgOperand(1));
401 CInfo.AccessIndex = InfoKind;
404 if (GV->getName().startswith(
"llvm.bpf.preserve.type.info")) {
405 CInfo.Kind = BPFPreserveFieldInfoAI;
406 CInfo.Metadata =
Call->getMetadata(LLVMContext::MD_preserve_access_index);
420 if (GV->getName().startswith(
"llvm.bpf.preserve.enum.value")) {
421 CInfo.Kind = BPFPreserveFieldInfoAI;
422 CInfo.Metadata =
Call->getMetadata(LLVMContext::MD_preserve_access_index);
438void BPFAbstractMemberAccess::replaceWithGEP(std::vector<CallInst *> &CallList,
441 for (
auto *Call : CallList) {
443 if (DimensionIndex > 0)
444 Dimension = getConstant(
Call->getArgOperand(DimensionIndex));
456 Call->eraseFromParent();
460bool BPFAbstractMemberAccess::removePreserveAccessIndexIntrinsic(
Function &
F) {
461 std::vector<CallInst *> PreserveArrayIndexCalls;
462 std::vector<CallInst *> PreserveUnionIndexCalls;
463 std::vector<CallInst *> PreserveStructIndexCalls;
468 auto *
Call = dyn_cast<CallInst>(&
I);
470 if (!IsPreserveDIAccessIndexCall(Call, CInfo))
474 if (CInfo.Kind == BPFPreserveArrayAI)
475 PreserveArrayIndexCalls.push_back(Call);
476 else if (CInfo.Kind == BPFPreserveUnionAI)
477 PreserveUnionIndexCalls.push_back(Call);
479 PreserveStructIndexCalls.push_back(Call);
492 replaceWithGEP(PreserveArrayIndexCalls, 1, 2);
493 replaceWithGEP(PreserveStructIndexCalls, 0, 1);
494 for (
auto *Call : PreserveUnionIndexCalls) {
495 Call->replaceAllUsesWith(
Call->getArgOperand(0));
496 Call->eraseFromParent();
505bool BPFAbstractMemberAccess::IsValidAIChain(
const MDNode *ParentType,
507 const MDNode *ChildType) {
516 if (isa<DIDerivedType>(CType))
520 if (
const auto *PtrTy = dyn_cast<DIDerivedType>(PType)) {
521 if (PtrTy->getTag() != dwarf::DW_TAG_pointer_type)
527 const auto *PTy = dyn_cast<DICompositeType>(PType);
528 const auto *CTy = dyn_cast<DICompositeType>(CType);
529 assert(PTy && CTy &&
"ParentType or ChildType is null or not composite");
532 assert(PTyTag == dwarf::DW_TAG_array_type ||
533 PTyTag == dwarf::DW_TAG_structure_type ||
534 PTyTag == dwarf::DW_TAG_union_type);
537 assert(CTyTag == dwarf::DW_TAG_array_type ||
538 CTyTag == dwarf::DW_TAG_structure_type ||
539 CTyTag == dwarf::DW_TAG_union_type);
542 if (PTyTag == dwarf::DW_TAG_array_type && PTyTag == CTyTag)
546 if (PTyTag == dwarf::DW_TAG_array_type)
547 Ty = PTy->getBaseType();
549 Ty = dyn_cast<DIType>(PTy->getElements()[ParentAI]);
554void BPFAbstractMemberAccess::traceAICall(
CallInst *Call,
561 if (
auto *BI = dyn_cast<BitCastInst>(Inst)) {
562 traceBitCast(BI, Call, ParentInfo);
563 }
else if (
auto *CI = dyn_cast<CallInst>(Inst)) {
566 if (IsPreserveDIAccessIndexCall(CI, ChildInfo) &&
567 IsValidAIChain(ParentInfo.Metadata, ParentInfo.AccessIndex,
568 ChildInfo.Metadata)) {
569 AIChain[CI] = std::make_pair(Call, ParentInfo);
570 traceAICall(CI, ChildInfo);
572 BaseAICalls[
Call] = ParentInfo;
574 }
else if (
auto *GI = dyn_cast<GetElementPtrInst>(Inst)) {
575 if (GI->hasAllZeroIndices())
576 traceGEP(GI, Call, ParentInfo);
578 BaseAICalls[
Call] = ParentInfo;
580 BaseAICalls[
Call] = ParentInfo;
585void BPFAbstractMemberAccess::traceBitCast(
BitCastInst *BitCast,
593 if (
auto *BI = dyn_cast<BitCastInst>(Inst)) {
594 traceBitCast(BI, Parent, ParentInfo);
595 }
else if (
auto *CI = dyn_cast<CallInst>(Inst)) {
597 if (IsPreserveDIAccessIndexCall(CI, ChildInfo) &&
598 IsValidAIChain(ParentInfo.Metadata, ParentInfo.AccessIndex,
599 ChildInfo.Metadata)) {
600 AIChain[CI] = std::make_pair(Parent, ParentInfo);
601 traceAICall(CI, ChildInfo);
603 BaseAICalls[Parent] = ParentInfo;
605 }
else if (
auto *GI = dyn_cast<GetElementPtrInst>(Inst)) {
606 if (GI->hasAllZeroIndices())
607 traceGEP(GI, Parent, ParentInfo);
609 BaseAICalls[Parent] = ParentInfo;
611 BaseAICalls[Parent] = ParentInfo;
623 if (
auto *BI = dyn_cast<BitCastInst>(Inst)) {
624 traceBitCast(BI, Parent, ParentInfo);
625 }
else if (
auto *CI = dyn_cast<CallInst>(Inst)) {
627 if (IsPreserveDIAccessIndexCall(CI, ChildInfo) &&
628 IsValidAIChain(ParentInfo.Metadata, ParentInfo.AccessIndex,
629 ChildInfo.Metadata)) {
630 AIChain[CI] = std::make_pair(Parent, ParentInfo);
631 traceAICall(CI, ChildInfo);
633 BaseAICalls[Parent] = ParentInfo;
635 }
else if (
auto *GI = dyn_cast<GetElementPtrInst>(Inst)) {
636 if (GI->hasAllZeroIndices())
637 traceGEP(GI, Parent, ParentInfo);
639 BaseAICalls[Parent] = ParentInfo;
641 BaseAICalls[Parent] = ParentInfo;
646void BPFAbstractMemberAccess::collectAICallChains(
Function &
F) {
653 auto *
Call = dyn_cast<CallInst>(&
I);
654 if (!IsPreserveDIAccessIndexCall(Call, CInfo) ||
655 AIChain.find(Call) != AIChain.end())
658 traceAICall(Call, CInfo);
662uint64_t BPFAbstractMemberAccess::getConstant(
const Value *IndexValue) {
663 const ConstantInt *CV = dyn_cast<ConstantInt>(IndexValue);
669void BPFAbstractMemberAccess::GetStorageBitRange(
DIDerivedType *MemberTy,
670 Align RecordAlignment,
676 if (RecordAlignment > 8) {
679 if (MemberBitOffset / 64 != (MemberBitOffset + MemberBitSize) / 64)
681 "requiring too big alignment");
682 RecordAlignment =
Align(8);
686 if (MemberBitSize > AlignBits)
688 "bitfield size greater than record alignment");
690 StartBitOffset = MemberBitOffset & ~(AlignBits - 1);
691 if ((StartBitOffset + AlignBits) < (MemberBitOffset + MemberBitSize))
693 "cross alignment boundary");
694 EndBitOffset = StartBitOffset + AlignBits;
707 if (
Tag == dwarf::DW_TAG_array_type) {
710 (EltTy->getSizeInBits() >> 3);
711 }
else if (
Tag == dwarf::DW_TAG_structure_type) {
712 auto *MemberTy = cast<DIDerivedType>(CTy->
getElements()[AccessIndex]);
716 unsigned SBitOffset, NextSBitOffset;
717 GetStorageBitRange(MemberTy, *RecordAlignment, SBitOffset,
719 PatchImm += SBitOffset >> 3;
726 if (
Tag == dwarf::DW_TAG_array_type) {
728 return calcArraySize(CTy, 1) * (EltTy->getSizeInBits() >> 3);
730 auto *MemberTy = cast<DIDerivedType>(CTy->
getElements()[AccessIndex]);
733 return SizeInBits >> 3;
735 unsigned SBitOffset, NextSBitOffset;
736 GetStorageBitRange(MemberTy, *RecordAlignment, SBitOffset,
738 SizeInBits = NextSBitOffset - SBitOffset;
739 if (SizeInBits & (SizeInBits - 1))
741 return SizeInBits >> 3;
747 if (
Tag == dwarf::DW_TAG_array_type) {
753 auto *MemberTy = cast<DIDerivedType>(CTy->
getElements()[AccessIndex]);
758 const auto *BTy = dyn_cast<DIBasicType>(
BaseTy);
760 const auto *CompTy = dyn_cast<DICompositeType>(
BaseTy);
762 if (!CompTy || CompTy->getTag() != dwarf::DW_TAG_enumeration_type)
765 BTy = dyn_cast<DIBasicType>(
BaseTy);
767 uint32_t Encoding = BTy->getEncoding();
768 return (Encoding == dwarf::DW_ATE_signed || Encoding == dwarf::DW_ATE_signed_char);
778 bool IsBitField =
false;
781 if (
Tag == dwarf::DW_TAG_array_type) {
785 MemberTy = cast<DIDerivedType>(CTy->
getElements()[AccessIndex]);
793 return 64 - SizeInBits;
796 unsigned SBitOffset, NextSBitOffset;
797 GetStorageBitRange(MemberTy, *RecordAlignment, SBitOffset, NextSBitOffset);
798 if (NextSBitOffset - SBitOffset > 64)
803 return SBitOffset + 64 - OffsetInBits - SizeInBits;
805 return OffsetInBits + 64 - NextSBitOffset;
810 bool IsBitField =
false;
812 if (
Tag == dwarf::DW_TAG_array_type) {
816 MemberTy = cast<DIDerivedType>(CTy->
getElements()[AccessIndex]);
824 return 64 - SizeInBits;
827 unsigned SBitOffset, NextSBitOffset;
828 GetStorageBitRange(MemberTy, *RecordAlignment, SBitOffset, NextSBitOffset);
829 if (NextSBitOffset - SBitOffset > 64)
832 return 64 - SizeInBits;
838bool BPFAbstractMemberAccess::HasPreserveFieldInfoCall(CallInfoStack &CallStack) {
840 while (CallStack.size()) {
841 auto StackElem = CallStack.top();
842 if (StackElem.second.Kind == BPFPreserveFieldInfoAI)
852Value *BPFAbstractMemberAccess::computeBaseAndAccessKey(
CallInst *Call,
854 std::string &AccessKey,
858 CallInfoStack CallStack;
862 CallStack.push(std::make_pair(Call, CInfo));
863 CInfo = AIChain[
Call].second;
880 while (CallStack.size()) {
881 auto StackElem = CallStack.top();
882 Call = StackElem.first;
883 CInfo = StackElem.second;
891 if (CInfo.Kind == BPFPreserveUnionAI ||
892 CInfo.Kind == BPFPreserveStructAI) {
896 TypeMeta = PossibleTypeDef;
901 assert(CInfo.Kind == BPFPreserveArrayAI);
907 uint64_t AccessIndex = CInfo.AccessIndex;
910 bool CheckElemType =
false;
911 if (
const auto *CTy = dyn_cast<DICompositeType>(Ty)) {
921 auto *DTy = cast<DIDerivedType>(Ty);
925 CTy = dyn_cast<DICompositeType>(
BaseTy);
927 CheckElemType =
true;
928 }
else if (CTy->
getTag() != dwarf::DW_TAG_array_type) {
929 FirstIndex += AccessIndex;
930 CheckElemType =
true;
937 auto *CTy = dyn_cast<DICompositeType>(
BaseTy);
939 if (HasPreserveFieldInfoCall(CallStack))
944 unsigned CTag = CTy->
getTag();
945 if (CTag == dwarf::DW_TAG_structure_type || CTag == dwarf::DW_TAG_union_type) {
948 if (HasPreserveFieldInfoCall(CallStack))
958 AccessKey += std::to_string(FirstIndex);
962 while (CallStack.size()) {
963 auto StackElem = CallStack.top();
964 CInfo = StackElem.second;
967 if (CInfo.Kind == BPFPreserveFieldInfoAI) {
968 InfoKind = CInfo.AccessIndex;
976 if (CallStack.size()) {
977 auto StackElem2 = CallStack.top();
978 CallInfo CInfo2 = StackElem2.second;
979 if (CInfo2.Kind == BPFPreserveFieldInfoAI) {
980 InfoKind = CInfo2.AccessIndex;
981 assert(CallStack.size() == 1);
986 uint64_t AccessIndex = CInfo.AccessIndex;
987 AccessKey +=
":" + std::to_string(AccessIndex);
992 PatchImm = GetFieldInfo(InfoKind, CTy, AccessIndex, PatchImm,
993 CInfo.RecordAlignment);
1002 AccessKey =
"llvm." +
TypeName +
":" + std::to_string(InfoKind) +
":" +
1003 std::to_string(PatchImm) +
"$" + AccessKey;
1010 std::string &AccessKey,
1016 std::string AccessStr(
"0");
1023 PatchImm =
BaseTy->getSizeInBits() / 8;
1032 cast<GlobalVariable>(
Call->getArgOperand(1)->stripPointerCasts());
1044 const auto *CTy = cast<DICompositeType>(
BaseTy);
1045 assert(CTy->
getTag() == dwarf::DW_TAG_enumeration_type);
1048 const auto *
Enum = cast<DIEnumerator>(Element);
1049 if (
Enum->getName() == EnumeratorStr) {
1050 AccessStr = std::to_string(EnumIndex);
1058 PatchImm = std::stoll(std::string(EValueStr));
1064 AccessKey =
"llvm." + Ty->
getName().
str() +
":" +
1065 std::to_string(CInfo.AccessIndex) + std::string(
":") +
1066 std::to_string(PatchImm) + std::string(
"$") + AccessStr;
1073bool BPFAbstractMemberAccess::transformGEPChain(
CallInst *Call,
1075 std::string AccessKey;
1080 IsInt32Ret = CInfo.Kind == BPFPreserveFieldInfoAI;
1081 if (CInfo.Kind == BPFPreserveFieldInfoAI && CInfo.Metadata) {
1082 TypeMeta = computeAccessKey(Call, CInfo, AccessKey, IsInt32Ret);
1084 Base = computeBaseAndAccessKey(Call, CInfo, AccessKey, TypeMeta);
1092 if (GEPGlobals.find(AccessKey) == GEPGlobals.end()) {
1099 GV =
new GlobalVariable(*M, VarType,
false, GlobalVariable::ExternalLinkage,
1100 nullptr, AccessKey);
1102 GV->
setMetadata(LLVMContext::MD_preserve_access_index, TypeMeta);
1103 GEPGlobals[AccessKey] = GV;
1105 GV = GEPGlobals[AccessKey];
1108 if (CInfo.Kind == BPFPreserveFieldInfoAI) {
1118 Call->replaceAllUsesWith(PassThroughInst);
1119 Call->eraseFromParent();
1138 BCInst->insertBefore(Call);
1143 GEP->insertBefore(Call);
1147 BCInst2->insertBefore(Call);
1196 Call->replaceAllUsesWith(PassThroughInst);
1197 Call->eraseFromParent();
1202bool BPFAbstractMemberAccess::doTransformation(
Function &
F) {
1203 bool Transformed =
false;
1208 collectAICallChains(
F);
1210 for (
auto &
C : BaseAICalls)
1211 Transformed = transformGEPChain(
C.first,
C.second) || Transformed;
1213 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 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.
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
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
uint64_t getOffsetInBits() const
StringRef getName() const
uint64_t getSizeInBits() const
A parsed version of the target data layout string in and methods for querying it.
FunctionPass class - This class is used to implement most global optimizations.
virtual bool runOnFunction(Function &F)=0
runOnFunction - Virtual method overriden by subclasses to do the per-function processing of the pass.
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.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ 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.
FunctionPass * createBPFAbstractMemberAccess(BPFTargetMachine *TM)
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.