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 {
 
  124  bool run(Function &
F);
 
  128    uint32_t AccessIndex;
 
  129    MaybeAlign RecordAlignment;
 
  133  typedef std::stack<std::pair<CallInst *, CallInfo>> CallInfoStack;
 
  137    BPFPreserveArrayAI = 1,
 
  138    BPFPreserveUnionAI = 2,
 
  139    BPFPreserveStructAI = 3,
 
  140    BPFPreserveFieldInfoAI = 4,
 
  144  const DataLayout *DL = 
nullptr;
 
  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;
 
  157  void CheckAnonRecordType(DIDerivedType *ParentTy, DIType *Ty);
 
  158  void CheckCompositeType(DIDerivedType *ParentTy, DICompositeType *CTy);
 
  159  void CheckDerivedType(DIDerivedType *ParentTy, DIDerivedType *DTy);
 
  160  void ResetMetadata(
struct CallInfo &CInfo);
 
  162  bool doTransformation(Function &
F);
 
  164  void traceAICall(CallInst *
Call, CallInfo &ParentInfo);
 
  165  void traceBitCast(BitCastInst *BitCast, CallInst *Parent,
 
  166                    CallInfo &ParentInfo);
 
  167  void traceGEP(GetElementPtrInst *
GEP, CallInst *Parent,
 
  168                CallInfo &ParentInfo);
 
  169  void collectAICallChains(Function &
F);
 
  171  bool IsPreserveDIAccessIndexCall(
const CallInst *
Call, CallInfo &Cinfo);
 
  172  bool IsValidAIChain(
const MDNode *ParentMeta, uint32_t ParentAI,
 
  173                      const MDNode *ChildMeta);
 
  174  bool removePreserveAccessIndexIntrinsic(Function &
F);
 
  175  bool HasPreserveFieldInfoCall(CallInfoStack &CallStack);
 
  176  void GetStorageBitRange(DIDerivedType *MemberTy, Align RecordAlignment,
 
  177                          uint32_t &StartBitOffset, uint32_t &EndBitOffset);
 
  178  uint32_t GetFieldInfo(uint32_t InfoKind, DICompositeType *CTy,
 
  179                        uint32_t AccessIndex, uint32_t PatchImm,
 
  180                        MaybeAlign RecordAlignment);
 
  182  Value *computeBaseAndAccessKey(CallInst *
Call, CallInfo &CInfo,
 
  183                                 std::string &AccessKey, MDNode *&BaseMeta);
 
  184  MDNode *computeAccessKey(CallInst *
Call, CallInfo &CInfo,
 
  185                           std::string &AccessKey, 
bool &IsInt32Ret);
 
  186  bool transformGEPChain(CallInst *
Call, CallInfo &CInfo);
 
  189std::map<std::string, GlobalVariable *> BPFAbstractMemberAccess::GEPGlobals;
 
  192bool BPFAbstractMemberAccess::run(
Function &
F) {
 
  193  LLVM_DEBUG(
dbgs() << 
"********** Abstract Member Accesses **********\n");
 
  208  DISubprogram *
SP = 
F.getSubprogram();
 
  209  if (SP && 
SP->isDefinition()) {
 
  210    for (DIType *Ty: 
SP->getType()->getTypeArray())
 
  211      CheckAnonRecordType(
nullptr, Ty);
 
  212    for (
const DINode *DN : 
SP->getRetainedNodes()) {
 
  214        CheckAnonRecordType(
nullptr, DV->getType());
 
  219  return doTransformation(
F);
 
  222void BPFAbstractMemberAccess::ResetMetadata(
struct CallInfo &CInfo) {
 
  224    auto It = AnonRecords.find(Ty);
 
  225    if (It != AnonRecords.end() && It->second != 
nullptr)
 
  226      CInfo.Metadata = It->second;
 
  230void BPFAbstractMemberAccess::CheckCompositeType(DIDerivedType *ParentTy,
 
  231                                                 DICompositeType *CTy) {
 
  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,
 
  245                                               DIDerivedType *DTy) {
 
  246  DIType *
BaseType = DTy->getBaseType();
 
  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,
 
  265    return CheckCompositeType(ParentTy, CTy);
 
  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)
 
 
  285    Ty = DTy->getBaseType();
 
 
  294    Ty = DTy->getBaseType();
 
 
  302  for (
uint32_t I = StartDim; 
I < Elements.size(); ++
I) {
 
  304      if (Element->getTag() == dwarf::DW_TAG_subrange_type) {
 
  307        DimSize *= CI->getSExtValue();
 
 
  316  return Call->getParamElementType(0);
 
 
  326bool BPFAbstractMemberAccess::IsPreserveDIAccessIndexCall(
const CallInst *
Call,
 
  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");
 
  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);
 
  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);
 
  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)
 
  421                                                Call->getArgOperand(0), IdxList,
 
  422                                                "", 
Call->getIterator());
 
  424  Call->eraseFromParent();
 
 
  436  Call->replaceAllUsesWith(
Call->getArgOperand(0));
 
  437  Call->eraseFromParent();
 
 
  440bool BPFAbstractMemberAccess::removePreserveAccessIndexIntrinsic(
Function &
F) {
 
  441  std::vector<CallInst *> PreserveArrayIndexCalls;
 
  442  std::vector<CallInst *> PreserveUnionIndexCalls;
 
  443  std::vector<CallInst *> PreserveStructIndexCalls;
 
  450      if (!IsPreserveDIAccessIndexCall(
Call, CInfo))
 
  454      if (CInfo.Kind == BPFPreserveArrayAI)
 
  455        PreserveArrayIndexCalls.push_back(
Call);
 
  456      else if (CInfo.Kind == BPFPreserveUnionAI)
 
  457        PreserveUnionIndexCalls.push_back(
Call);
 
  459        PreserveStructIndexCalls.push_back(
Call);
 
  485bool BPFAbstractMemberAccess::IsValidAIChain(
const MDNode *ParentType,
 
  487                                             const MDNode *ChildType) {
 
  501    if (PtrTy->getTag() != dwarf::DW_TAG_pointer_type)
 
  509  assert(PTy && CTy && 
"ParentType or ChildType is null or not composite");
 
  511  uint32_t PTyTag = PTy->getTag();
 
  512  assert(PTyTag == dwarf::DW_TAG_array_type ||
 
  513         PTyTag == dwarf::DW_TAG_structure_type ||
 
  514         PTyTag == dwarf::DW_TAG_union_type);
 
  516  uint32_t CTyTag = CTy->
getTag();
 
  517  assert(CTyTag == dwarf::DW_TAG_array_type ||
 
  518         CTyTag == dwarf::DW_TAG_structure_type ||
 
  519         CTyTag == dwarf::DW_TAG_union_type);
 
  522  if (PTyTag == dwarf::DW_TAG_array_type && PTyTag == CTyTag)
 
  526  if (PTyTag == dwarf::DW_TAG_array_type)
 
  527    Ty = PTy->getBaseType();
 
  534void BPFAbstractMemberAccess::traceAICall(CallInst *
Call,
 
  535                                          CallInfo &ParentInfo) {
 
  542      traceBitCast(BI, 
Call, ParentInfo);
 
  546      if (IsPreserveDIAccessIndexCall(CI, ChildInfo) &&
 
  547          IsValidAIChain(ParentInfo.Metadata, ParentInfo.AccessIndex,
 
  548                         ChildInfo.Metadata)) {
 
  549        AIChain[CI] = std::make_pair(
Call, ParentInfo);
 
  550        traceAICall(CI, ChildInfo);
 
  552        BaseAICalls[
Call] = ParentInfo;
 
  555      if (GI->hasAllZeroIndices())
 
  556        traceGEP(GI, 
Call, ParentInfo);
 
  558        BaseAICalls[
Call] = ParentInfo;
 
  560      BaseAICalls[
Call] = ParentInfo;
 
  565void BPFAbstractMemberAccess::traceBitCast(BitCastInst *BitCast,
 
  567                                           CallInfo &ParentInfo) {
 
  568  for (User *U : BitCast->
users()) {
 
  574      traceBitCast(BI, Parent, ParentInfo);
 
  577      if (IsPreserveDIAccessIndexCall(CI, ChildInfo) &&
 
  578          IsValidAIChain(ParentInfo.Metadata, ParentInfo.AccessIndex,
 
  579                         ChildInfo.Metadata)) {
 
  580        AIChain[CI] = std::make_pair(Parent, ParentInfo);
 
  581        traceAICall(CI, ChildInfo);
 
  583        BaseAICalls[Parent] = ParentInfo;
 
  586      if (GI->hasAllZeroIndices())
 
  587        traceGEP(GI, Parent, ParentInfo);
 
  589        BaseAICalls[Parent] = ParentInfo;
 
  591      BaseAICalls[Parent] = ParentInfo;
 
  596void BPFAbstractMemberAccess::traceGEP(GetElementPtrInst *
GEP, CallInst *Parent,
 
  597                                       CallInfo &ParentInfo) {
 
  598  for (User *U : 
GEP->users()) {
 
  604      traceBitCast(BI, Parent, ParentInfo);
 
  607      if (IsPreserveDIAccessIndexCall(CI, ChildInfo) &&
 
  608          IsValidAIChain(ParentInfo.Metadata, ParentInfo.AccessIndex,
 
  609                         ChildInfo.Metadata)) {
 
  610        AIChain[CI] = std::make_pair(Parent, ParentInfo);
 
  611        traceAICall(CI, ChildInfo);
 
  613        BaseAICalls[Parent] = ParentInfo;
 
  616      if (GI->hasAllZeroIndices())
 
  617        traceGEP(GI, Parent, ParentInfo);
 
  619        BaseAICalls[Parent] = ParentInfo;
 
  621      BaseAICalls[Parent] = ParentInfo;
 
  626void BPFAbstractMemberAccess::collectAICallChains(Function &
F) {
 
  634      if (!IsPreserveDIAccessIndexCall(
Call, CInfo) ||
 
  635          AIChain.find(
Call) != AIChain.end())
 
  638      traceAICall(
Call, CInfo);
 
  643void BPFAbstractMemberAccess::GetStorageBitRange(DIDerivedType *MemberTy,
 
  644                                                 Align RecordAlignment,
 
  645                                                 uint32_t &StartBitOffset,
 
  646                                                 uint32_t &EndBitOffset) {
 
  650  if (RecordAlignment > 8) {
 
  653    if (MemberBitOffset / 64 != (MemberBitOffset + MemberBitSize) / 64)
 
  655                         "requiring too big alignment");
 
  656    RecordAlignment = 
Align(8);
 
  659  uint32_t AlignBits = RecordAlignment.
value() * 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;
 
  671uint32_t BPFAbstractMemberAccess::GetFieldInfo(uint32_t InfoKind,
 
  672                                               DICompositeType *CTy,
 
  673                                               uint32_t AccessIndex,
 
  675                                               MaybeAlign RecordAlignment) {
 
  681    if (
Tag == dwarf::DW_TAG_array_type) {
 
  684                  (EltTy->getSizeInBits() >> 3);
 
  685    } 
else if (
Tag == dwarf::DW_TAG_structure_type) {
 
  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;
 
  720    const DIType *BaseTy;
 
  721    if (
Tag == dwarf::DW_TAG_array_type) {
 
  736      if (!CompTy || CompTy->getTag() != dwarf::DW_TAG_enumeration_type)
 
  741    uint32_t Encoding = BTy->getEncoding();
 
  742    return (Encoding == dwarf::DW_ATE_signed || Encoding == dwarf::DW_ATE_signed_char);
 
  751    DIDerivedType *MemberTy = 
nullptr;
 
  752    bool IsBitField = 
false;
 
  755    if (
Tag == dwarf::DW_TAG_array_type) {
 
  767      return 64 - SizeInBits;
 
  770    unsigned SBitOffset, NextSBitOffset;
 
  771    GetStorageBitRange(MemberTy, *RecordAlignment, SBitOffset, NextSBitOffset);
 
  772    if (NextSBitOffset - SBitOffset > 64)
 
  777      return SBitOffset + 64 - OffsetInBits - SizeInBits;
 
  779      return OffsetInBits + 64 - NextSBitOffset;
 
  783    DIDerivedType *MemberTy = 
nullptr;
 
  784    bool IsBitField = 
false;
 
  786    if (
Tag == dwarf::DW_TAG_array_type) {
 
  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    auto &Chain = AIChain[
Call];
 
  838    CInfo = Chain.second;
 
  852  uint32_t FirstIndex = 0;
 
  853  uint32_t PatchImm = 0; 
 
  855  while (CallStack.size()) {
 
  856    auto StackElem = CallStack.top();
 
  857    Call = StackElem.first;
 
  858    CInfo = StackElem.second;
 
  866    if (CInfo.Kind == BPFPreserveUnionAI ||
 
  867        CInfo.Kind == BPFPreserveStructAI) {
 
  871      TypeMeta = PossibleTypeDef;
 
  876    assert(CInfo.Kind == BPFPreserveArrayAI);
 
  882    uint64_t AccessIndex = CInfo.AccessIndex;
 
  884    DIType *BaseTy = 
nullptr;
 
  885    bool CheckElemType = 
false;
 
  902        CheckElemType = 
true;
 
  903      } 
else if (CTy->
getTag() != dwarf::DW_TAG_array_type) {
 
  904        FirstIndex += AccessIndex;
 
  905        CheckElemType = 
true;
 
  914        if (HasPreserveFieldInfoCall(CallStack))
 
  919      unsigned CTag = CTy->
getTag();
 
  920      if (CTag == dwarf::DW_TAG_structure_type || CTag == dwarf::DW_TAG_union_type) {
 
  923        if (HasPreserveFieldInfoCall(CallStack))
 
  933  AccessKey += std::to_string(FirstIndex);
 
  937  while (CallStack.size()) {
 
  938    auto StackElem = CallStack.top();
 
  939    CInfo = StackElem.second;
 
  942    if (CInfo.Kind == BPFPreserveFieldInfoAI) {
 
  943      InfoKind = CInfo.AccessIndex;
 
  951    if (CallStack.size()) {
 
  952      auto StackElem2 = CallStack.top();
 
  953      CallInfo CInfo2 = StackElem2.second;
 
  954      if (CInfo2.Kind == BPFPreserveFieldInfoAI) {
 
  955        InfoKind = CInfo2.AccessIndex;
 
  956        assert(CallStack.size() == 1);
 
  961    uint64_t AccessIndex = CInfo.AccessIndex;
 
  962    AccessKey += 
":" + std::to_string(AccessIndex);
 
  964    MDNode *MDN = CInfo.Metadata;
 
  967    PatchImm = GetFieldInfo(InfoKind, CTy, AccessIndex, PatchImm,
 
  968                            CInfo.RecordAlignment);
 
  977  AccessKey = 
"llvm." + 
TypeName + 
":" + std::to_string(InfoKind) + 
":" +
 
  978              std::to_string(PatchImm) + 
"$" + AccessKey;
 
  983MDNode *BPFAbstractMemberAccess::computeAccessKey(CallInst *
Call,
 
  985                                                  std::string &AccessKey,
 
  991  std::string AccessStr(
"0");
 
 1006    const GlobalVariable *GV =
 
 1011    StringRef ValueStr = 
DA->getAsString();
 
 1015    StringRef EnumeratorStr = ValueStr.
substr(0, Separator);
 
 1020    assert(CTy->
getTag() == dwarf::DW_TAG_enumeration_type);
 
 1024      if (
Enum->getName() == EnumeratorStr) {
 
 1025        AccessStr = std::to_string(EnumIndex);
 
 1032      StringRef EValueStr = ValueStr.
substr(Separator + 1);
 
 1033      PatchImm = std::stoll(std::string(EValueStr));
 
 1039  AccessKey = 
"llvm." + Ty->
getName().
str() + 
":" +
 
 1040              std::to_string(CInfo.AccessIndex) + std::string(
":") +
 
 1041              std::to_string(PatchImm) + std::string(
"$") + AccessStr;
 
 1048bool BPFAbstractMemberAccess::transformGEPChain(CallInst *
Call,
 
 1050  std::string AccessKey;
 
 1055  IsInt32Ret = CInfo.Kind == BPFPreserveFieldInfoAI;
 
 1056  if (CInfo.Kind == BPFPreserveFieldInfoAI && CInfo.Metadata) {
 
 1057    TypeMeta = computeAccessKey(
Call, CInfo, AccessKey, IsInt32Ret);
 
 1059    Base = computeBaseAndAccessKey(
Call, CInfo, AccessKey, TypeMeta);
 
 1067  if (GEPGlobals.find(AccessKey) == GEPGlobals.end()) {
 
 1068    IntegerType *VarType;
 
 1070      VarType = Type::getInt32Ty(BB->
getContext()); 
 
 1072      VarType = Type::getInt64Ty(BB->
getContext()); 
 
 1074    GV = 
new GlobalVariable(*M, VarType, 
false, GlobalVariable::ExternalLinkage,
 
 1075                            nullptr, AccessKey);
 
 1077    GV->
setMetadata(LLVMContext::MD_preserve_access_index, TypeMeta);
 
 1078    GEPGlobals[AccessKey] = GV;
 
 1080    GV = GEPGlobals[AccessKey];
 
 1083  if (CInfo.Kind == BPFPreserveFieldInfoAI) {
 
 1087      LDInst = 
new LoadInst(Type::getInt32Ty(BB->
getContext()), GV, 
"",
 
 1090      LDInst = 
new LoadInst(Type::getInt64Ty(BB->
getContext()), GV, 
"",
 
 1109  auto *LDInst = 
new LoadInst(Type::getInt64Ty(BB->
getContext()), GV, 
"",
 
 1167bool BPFAbstractMemberAccess::doTransformation(Function &
F) {
 
 1168  bool Transformed = 
false;
 
 1173  collectAICallChains(
F);
 
 1175  for (
auto &
C : BaseAICalls)
 
 1176    Transformed = transformGEPChain(
C.first, 
C.second) || Transformed;
 
 1178  return removePreserveAccessIndexIntrinsic(
F) || Transformed;
 
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
 
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.
 
Machine Check Debug Module
 
BaseType
A given derived pointer can have multiple base pointers through phi/selects.
 
uint64_t getZExtValue() const
Get zero extended value.
 
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.
 
LLVM_ABI LLVMContext & getContext() const
Get the context in which this basic block lives.
 
Value * getCalledOperand() const
 
Value * getArgOperand(unsigned i) const
 
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)
 
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
 
LLVM_ABI dwarf::Tag getTag() const
 
LLVM_ABI BoundType getCount() const
 
uint64_t getOffsetInBits() const
 
StringRef getName() const
 
uint64_t getSizeInBits() const
 
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.
 
LLVM_ABI 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.
 
LLVM_ABI void insertBefore(InstListType::iterator InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified position.
 
LLVM_ABI InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
 
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
 
A Module instance is used to store all the information related to an LLVM module.
 
iterator_range< debug_compile_units_iterator > debug_compile_units() const
Return an iterator for all DICompileUnits listed in this Module's llvm.dbg.cu named metadata node and...
 
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
 
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.
 
const Triple & getTargetTriple() const
 
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 LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
 
LLVM Value Representation.
 
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
 
iterator_range< user_iterator > users()
 
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
 
const ParentTy * getParent() const
 
self_iterator getIterator()
 
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
 
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
 
constexpr char TypeName[]
Key for Kernel::Arg::Metadata::mTypeName.
 
@ C
The default llvm calling convention, compatible with C.
 
@ BasicBlock
Various leaf nodes.
 
LLVM_ABI 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.
 
friend class Instruction
Iterator for Instructions in a `BasicBlock.
 
This is an optimization pass for GlobalISel generic memory operations.
 
FunctionAddr VTableAddr Value
 
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
 
auto dyn_cast_or_null(const Y &Val)
 
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
 
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
 
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
 
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
 
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
 
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.