LLVM  15.0.0git
BPFAbstractMemberAccess.cpp
Go to the documentation of this file.
1 //===------ BPFAbstractMemberAccess.cpp - Abstracting Member Accesses -----===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This pass abstracted struct/union member accesses in order to support
10 // compile-once run-everywhere (CO-RE). The CO-RE intends to compile the program
11 // which can run on different kernels. In particular, if bpf program tries to
12 // access a particular kernel data structure member, the details of the
13 // intermediate member access will be remembered so bpf loader can do
14 // necessary adjustment right before program loading.
15 //
16 // For example,
17 //
18 // struct s {
19 // int a;
20 // int b;
21 // };
22 // struct t {
23 // struct s c;
24 // int d;
25 // };
26 // struct t e;
27 //
28 // For the member access e.c.b, the compiler will generate code
29 // &e + 4
30 //
31 // The compile-once run-everywhere instead generates the following code
32 // r = 4
33 // &e + r
34 // The "4" in "r = 4" can be changed based on a particular kernel version.
35 // For example, on a particular kernel version, if struct s is changed to
36 //
37 // struct s {
38 // int new_field;
39 // int a;
40 // int b;
41 // }
42 //
43 // By repeating the member access on the host, the bpf loader can
44 // adjust "r = 4" as "r = 8".
45 //
46 // This feature relies on the following three intrinsic calls:
47 // addr = preserve_array_access_index(base, dimension, index)
48 // addr = preserve_union_access_index(base, di_index)
49 // !llvm.preserve.access.index <union_ditype>
50 // addr = preserve_struct_access_index(base, gep_index, di_index)
51 // !llvm.preserve.access.index <struct_ditype>
52 //
53 // Bitfield member access needs special attention. User cannot take the
54 // address of a bitfield acceess. To facilitate kernel verifier
55 // for easy bitfield code optimization, a new clang intrinsic is introduced:
56 // uint32_t __builtin_preserve_field_info(member_access, info_kind)
57 // In IR, a chain with two (or more) intrinsic calls will be generated:
58 // ...
59 // addr = preserve_struct_access_index(base, 1, 1) !struct s
60 // uint32_t result = bpf_preserve_field_info(addr, info_kind)
61 //
62 // Suppose the info_kind is FIELD_SIGNEDNESS,
63 // The above two IR intrinsics will be replaced with
64 // a relocatable insn:
65 // signness = /* signness of member_access */
66 // and signness can be changed by bpf loader based on the
67 // types on the host.
68 //
69 // User can also test whether a field exists or not with
70 // uint32_t result = bpf_preserve_field_info(member_access, FIELD_EXISTENCE)
71 // The field will be always available (result = 1) during initial
72 // compilation, but bpf loader can patch with the correct value
73 // on the target host where the member_access may or may not be available
74 //
75 //===----------------------------------------------------------------------===//
76 
77 #include "BPF.h"
78 #include "BPFCORE.h"
79 #include "BPFTargetMachine.h"
82 #include "llvm/IR/GlobalVariable.h"
83 #include "llvm/IR/Instruction.h"
84 #include "llvm/IR/Instructions.h"
85 #include "llvm/IR/IntrinsicsBPF.h"
86 #include "llvm/IR/Module.h"
87 #include "llvm/IR/PassManager.h"
88 #include "llvm/IR/Type.h"
89 #include "llvm/IR/User.h"
90 #include "llvm/IR/Value.h"
91 #include "llvm/Pass.h"
93 #include <stack>
94 
95 #define DEBUG_TYPE "bpf-abstract-member-access"
96 
97 namespace llvm {
100 
102  Instruction *Input,
103  Instruction *Before) {
105  M, Intrinsic::bpf_passthrough, {Input->getType(), Input->getType()});
106  Constant *SeqNumVal = ConstantInt::get(Type::getInt32Ty(BB->getContext()),
108 
109  auto *NewInst = CallInst::Create(Fn, {SeqNumVal, Input});
110  BB->getInstList().insert(Before->getIterator(), NewInst);
111  return NewInst;
112 }
113 } // namespace llvm
114 
115 using namespace llvm;
116 
117 namespace {
118 class BPFAbstractMemberAccess final {
119 public:
120  BPFAbstractMemberAccess(BPFTargetMachine *TM) : TM(TM) {}
121 
122  bool run(Function &F);
123 
124  struct CallInfo {
125  uint32_t Kind;
126  uint32_t AccessIndex;
127  MaybeAlign RecordAlignment;
128  MDNode *Metadata;
129  Value *Base;
130  };
131  typedef std::stack<std::pair<CallInst *, CallInfo>> CallInfoStack;
132 
133 private:
134  enum : uint32_t {
135  BPFPreserveArrayAI = 1,
136  BPFPreserveUnionAI = 2,
137  BPFPreserveStructAI = 3,
138  BPFPreserveFieldInfoAI = 4,
139  };
140 
141  TargetMachine *TM;
142  const DataLayout *DL = nullptr;
143  Module *M = nullptr;
144 
145  static std::map<std::string, GlobalVariable *> GEPGlobals;
146  // A map to link preserve_*_access_index intrinsic calls.
147  std::map<CallInst *, std::pair<CallInst *, CallInfo>> AIChain;
148  // A map to hold all the base preserve_*_access_index intrinsic calls.
149  // The base call is not an input of any other preserve_*
150  // intrinsics.
151  std::map<CallInst *, CallInfo> BaseAICalls;
152 
153  bool doTransformation(Function &F);
154 
155  void traceAICall(CallInst *Call, CallInfo &ParentInfo);
156  void traceBitCast(BitCastInst *BitCast, CallInst *Parent,
157  CallInfo &ParentInfo);
158  void traceGEP(GetElementPtrInst *GEP, CallInst *Parent,
159  CallInfo &ParentInfo);
160  void collectAICallChains(Function &F);
161 
162  bool IsPreserveDIAccessIndexCall(const CallInst *Call, CallInfo &Cinfo);
163  bool IsValidAIChain(const MDNode *ParentMeta, uint32_t ParentAI,
164  const MDNode *ChildMeta);
165  bool removePreserveAccessIndexIntrinsic(Function &F);
166  void replaceWithGEP(std::vector<CallInst *> &CallList,
167  uint32_t NumOfZerosIndex, uint32_t DIIndex);
168  bool HasPreserveFieldInfoCall(CallInfoStack &CallStack);
169  void GetStorageBitRange(DIDerivedType *MemberTy, Align RecordAlignment,
170  uint32_t &StartBitOffset, uint32_t &EndBitOffset);
171  uint32_t GetFieldInfo(uint32_t InfoKind, DICompositeType *CTy,
172  uint32_t AccessIndex, uint32_t PatchImm,
173  MaybeAlign RecordAlignment);
174 
175  Value *computeBaseAndAccessKey(CallInst *Call, CallInfo &CInfo,
176  std::string &AccessKey, MDNode *&BaseMeta);
177  MDNode *computeAccessKey(CallInst *Call, CallInfo &CInfo,
178  std::string &AccessKey, bool &IsInt32Ret);
179  uint64_t getConstant(const Value *IndexValue);
180  bool transformGEPChain(CallInst *Call, CallInfo &CInfo);
181 };
182 
183 std::map<std::string, GlobalVariable *> BPFAbstractMemberAccess::GEPGlobals;
184 
185 class BPFAbstractMemberAccessLegacyPass final : public FunctionPass {
187 
188  bool runOnFunction(Function &F) override {
189  return BPFAbstractMemberAccess(TM).run(F);
190  }
191 
192 public:
193  static char ID;
194 
195  // Add optional BPFTargetMachine parameter so that BPF backend can add the
196  // phase with target machine to find out the endianness. The default
197  // constructor (without parameters) is used by the pass manager for managing
198  // purposes.
199  BPFAbstractMemberAccessLegacyPass(BPFTargetMachine *TM = nullptr)
200  : FunctionPass(ID), TM(TM) {}
201 };
202 
203 } // End anonymous namespace
204 
206 INITIALIZE_PASS(BPFAbstractMemberAccessLegacyPass, DEBUG_TYPE,
207  "BPF Abstract Member Access", false, false)
208 
210  return new BPFAbstractMemberAccessLegacyPass(TM);
211 }
212 
214  LLVM_DEBUG(dbgs() << "********** Abstract Member Accesses **********\n");
215 
216  M = F.getParent();
217  if (!M)
218  return false;
219 
220  // Bail out if no debug info.
221  if (M->debug_compile_units().empty())
222  return false;
223 
224  DL = &M->getDataLayout();
225  return doTransformation(F);
226 }
227 
228 static bool SkipDIDerivedTag(unsigned Tag, bool skipTypedef) {
229  if (Tag != dwarf::DW_TAG_typedef && Tag != dwarf::DW_TAG_const_type &&
230  Tag != dwarf::DW_TAG_volatile_type &&
231  Tag != dwarf::DW_TAG_restrict_type &&
232  Tag != dwarf::DW_TAG_member)
233  return false;
234  if (Tag == dwarf::DW_TAG_typedef && !skipTypedef)
235  return false;
236  return true;
237 }
238 
239 static DIType * stripQualifiers(DIType *Ty, bool skipTypedef = true) {
240  while (auto *DTy = dyn_cast<DIDerivedType>(Ty)) {
241  if (!SkipDIDerivedTag(DTy->getTag(), skipTypedef))
242  break;
243  Ty = DTy->getBaseType();
244  }
245  return Ty;
246 }
247 
248 static const DIType * stripQualifiers(const DIType *Ty) {
249  while (auto *DTy = dyn_cast<DIDerivedType>(Ty)) {
250  if (!SkipDIDerivedTag(DTy->getTag(), true))
251  break;
252  Ty = DTy->getBaseType();
253  }
254  return Ty;
255 }
256 
257 static uint32_t calcArraySize(const DICompositeType *CTy, uint32_t StartDim) {
258  DINodeArray Elements = CTy->getElements();
259  uint32_t DimSize = 1;
260  for (uint32_t I = StartDim; I < Elements.size(); ++I) {
261  if (auto *Element = dyn_cast_or_null<DINode>(Elements[I]))
262  if (Element->getTag() == dwarf::DW_TAG_subrange_type) {
263  const DISubrange *SR = cast<DISubrange>(Element);
264  auto *CI = SR->getCount().dyn_cast<ConstantInt *>();
265  DimSize *= CI->getSExtValue();
266  }
267  }
268 
269  return DimSize;
270 }
271 
272 static Type *getBaseElementType(const CallInst *Call) {
273  // Element type is stored in an elementtype() attribute on the first param.
274  return Call->getParamElementType(0);
275 }
276 
277 /// Check whether a call is a preserve_*_access_index intrinsic call or not.
278 bool BPFAbstractMemberAccess::IsPreserveDIAccessIndexCall(const CallInst *Call,
279  CallInfo &CInfo) {
280  if (!Call)
281  return false;
282 
283  const auto *GV = dyn_cast<GlobalValue>(Call->getCalledOperand());
284  if (!GV)
285  return false;
286  if (GV->getName().startswith("llvm.preserve.array.access.index")) {
287  CInfo.Kind = BPFPreserveArrayAI;
288  CInfo.Metadata = Call->getMetadata(LLVMContext::MD_preserve_access_index);
289  if (!CInfo.Metadata)
290  report_fatal_error("Missing metadata for llvm.preserve.array.access.index intrinsic");
291  CInfo.AccessIndex = getConstant(Call->getArgOperand(2));
292  CInfo.Base = Call->getArgOperand(0);
293  CInfo.RecordAlignment = DL->getABITypeAlign(getBaseElementType(Call));
294  return true;
295  }
296  if (GV->getName().startswith("llvm.preserve.union.access.index")) {
297  CInfo.Kind = BPFPreserveUnionAI;
298  CInfo.Metadata = Call->getMetadata(LLVMContext::MD_preserve_access_index);
299  if (!CInfo.Metadata)
300  report_fatal_error("Missing metadata for llvm.preserve.union.access.index intrinsic");
301  CInfo.AccessIndex = getConstant(Call->getArgOperand(1));
302  CInfo.Base = Call->getArgOperand(0);
303  return true;
304  }
305  if (GV->getName().startswith("llvm.preserve.struct.access.index")) {
306  CInfo.Kind = BPFPreserveStructAI;
307  CInfo.Metadata = Call->getMetadata(LLVMContext::MD_preserve_access_index);
308  if (!CInfo.Metadata)
309  report_fatal_error("Missing metadata for llvm.preserve.struct.access.index intrinsic");
310  CInfo.AccessIndex = getConstant(Call->getArgOperand(2));
311  CInfo.Base = Call->getArgOperand(0);
312  CInfo.RecordAlignment = DL->getABITypeAlign(getBaseElementType(Call));
313  return true;
314  }
315  if (GV->getName().startswith("llvm.bpf.preserve.field.info")) {
316  CInfo.Kind = BPFPreserveFieldInfoAI;
317  CInfo.Metadata = nullptr;
318  // Check validity of info_kind as clang did not check this.
319  uint64_t InfoKind = getConstant(Call->getArgOperand(1));
321  report_fatal_error("Incorrect info_kind for llvm.bpf.preserve.field.info intrinsic");
322  CInfo.AccessIndex = InfoKind;
323  return true;
324  }
325  if (GV->getName().startswith("llvm.bpf.preserve.type.info")) {
326  CInfo.Kind = BPFPreserveFieldInfoAI;
327  CInfo.Metadata = Call->getMetadata(LLVMContext::MD_preserve_access_index);
328  if (!CInfo.Metadata)
329  report_fatal_error("Missing metadata for llvm.preserve.type.info intrinsic");
330  uint64_t Flag = getConstant(Call->getArgOperand(1));
332  report_fatal_error("Incorrect flag for llvm.bpf.preserve.type.info intrinsic");
334  CInfo.AccessIndex = BPFCoreSharedInfo::TYPE_EXISTENCE;
335  else
336  CInfo.AccessIndex = BPFCoreSharedInfo::TYPE_SIZE;
337  return true;
338  }
339  if (GV->getName().startswith("llvm.bpf.preserve.enum.value")) {
340  CInfo.Kind = BPFPreserveFieldInfoAI;
341  CInfo.Metadata = Call->getMetadata(LLVMContext::MD_preserve_access_index);
342  if (!CInfo.Metadata)
343  report_fatal_error("Missing metadata for llvm.preserve.enum.value intrinsic");
344  uint64_t Flag = getConstant(Call->getArgOperand(2));
346  report_fatal_error("Incorrect flag for llvm.bpf.preserve.enum.value intrinsic");
348  CInfo.AccessIndex = BPFCoreSharedInfo::ENUM_VALUE_EXISTENCE;
349  else
350  CInfo.AccessIndex = BPFCoreSharedInfo::ENUM_VALUE;
351  return true;
352  }
353 
354  return false;
355 }
356 
357 void BPFAbstractMemberAccess::replaceWithGEP(std::vector<CallInst *> &CallList,
358  uint32_t DimensionIndex,
359  uint32_t GEPIndex) {
360  for (auto Call : CallList) {
361  uint32_t Dimension = 1;
362  if (DimensionIndex > 0)
363  Dimension = getConstant(Call->getArgOperand(DimensionIndex));
364 
365  Constant *Zero =
366  ConstantInt::get(Type::getInt32Ty(Call->getParent()->getContext()), 0);
367  SmallVector<Value *, 4> IdxList;
368  for (unsigned I = 0; I < Dimension; ++I)
369  IdxList.push_back(Zero);
370  IdxList.push_back(Call->getArgOperand(GEPIndex));
371 
373  getBaseElementType(Call), Call->getArgOperand(0), IdxList, "", Call);
374  Call->replaceAllUsesWith(GEP);
375  Call->eraseFromParent();
376  }
377 }
378 
379 bool BPFAbstractMemberAccess::removePreserveAccessIndexIntrinsic(Function &F) {
380  std::vector<CallInst *> PreserveArrayIndexCalls;
381  std::vector<CallInst *> PreserveUnionIndexCalls;
382  std::vector<CallInst *> PreserveStructIndexCalls;
383  bool Found = false;
384 
385  for (auto &BB : F)
386  for (auto &I : BB) {
387  auto *Call = dyn_cast<CallInst>(&I);
388  CallInfo CInfo;
389  if (!IsPreserveDIAccessIndexCall(Call, CInfo))
390  continue;
391 
392  Found = true;
393  if (CInfo.Kind == BPFPreserveArrayAI)
394  PreserveArrayIndexCalls.push_back(Call);
395  else if (CInfo.Kind == BPFPreserveUnionAI)
396  PreserveUnionIndexCalls.push_back(Call);
397  else
398  PreserveStructIndexCalls.push_back(Call);
399  }
400 
401  // do the following transformation:
402  // . addr = preserve_array_access_index(base, dimension, index)
403  // is transformed to
404  // addr = GEP(base, dimenion's zero's, index)
405  // . addr = preserve_union_access_index(base, di_index)
406  // is transformed to
407  // addr = base, i.e., all usages of "addr" are replaced by "base".
408  // . addr = preserve_struct_access_index(base, gep_index, di_index)
409  // is transformed to
410  // addr = GEP(base, 0, gep_index)
411  replaceWithGEP(PreserveArrayIndexCalls, 1, 2);
412  replaceWithGEP(PreserveStructIndexCalls, 0, 1);
413  for (auto Call : PreserveUnionIndexCalls) {
414  Call->replaceAllUsesWith(Call->getArgOperand(0));
415  Call->eraseFromParent();
416  }
417 
418  return Found;
419 }
420 
421 /// Check whether the access index chain is valid. We check
422 /// here because there may be type casts between two
423 /// access indexes. We want to ensure memory access still valid.
424 bool BPFAbstractMemberAccess::IsValidAIChain(const MDNode *ParentType,
425  uint32_t ParentAI,
426  const MDNode *ChildType) {
427  if (!ChildType)
428  return true; // preserve_field_info, no type comparison needed.
429 
430  const DIType *PType = stripQualifiers(cast<DIType>(ParentType));
431  const DIType *CType = stripQualifiers(cast<DIType>(ChildType));
432 
433  // Child is a derived/pointer type, which is due to type casting.
434  // Pointer type cannot be in the middle of chain.
435  if (isa<DIDerivedType>(CType))
436  return false;
437 
438  // Parent is a pointer type.
439  if (const auto *PtrTy = dyn_cast<DIDerivedType>(PType)) {
440  if (PtrTy->getTag() != dwarf::DW_TAG_pointer_type)
441  return false;
442  return stripQualifiers(PtrTy->getBaseType()) == CType;
443  }
444 
445  // Otherwise, struct/union/array types
446  const auto *PTy = dyn_cast<DICompositeType>(PType);
447  const auto *CTy = dyn_cast<DICompositeType>(CType);
448  assert(PTy && CTy && "ParentType or ChildType is null or not composite");
449 
450  uint32_t PTyTag = PTy->getTag();
451  assert(PTyTag == dwarf::DW_TAG_array_type ||
452  PTyTag == dwarf::DW_TAG_structure_type ||
453  PTyTag == dwarf::DW_TAG_union_type);
454 
455  uint32_t CTyTag = CTy->getTag();
456  assert(CTyTag == dwarf::DW_TAG_array_type ||
457  CTyTag == dwarf::DW_TAG_structure_type ||
458  CTyTag == dwarf::DW_TAG_union_type);
459 
460  // Multi dimensional arrays, base element should be the same
461  if (PTyTag == dwarf::DW_TAG_array_type && PTyTag == CTyTag)
462  return PTy->getBaseType() == CTy->getBaseType();
463 
464  DIType *Ty;
465  if (PTyTag == dwarf::DW_TAG_array_type)
466  Ty = PTy->getBaseType();
467  else
468  Ty = dyn_cast<DIType>(PTy->getElements()[ParentAI]);
469 
470  return dyn_cast<DICompositeType>(stripQualifiers(Ty)) == CTy;
471 }
472 
473 void BPFAbstractMemberAccess::traceAICall(CallInst *Call,
474  CallInfo &ParentInfo) {
475  for (User *U : Call->users()) {
476  Instruction *Inst = dyn_cast<Instruction>(U);
477  if (!Inst)
478  continue;
479 
480  if (auto *BI = dyn_cast<BitCastInst>(Inst)) {
481  traceBitCast(BI, Call, ParentInfo);
482  } else if (auto *CI = dyn_cast<CallInst>(Inst)) {
483  CallInfo ChildInfo;
484 
485  if (IsPreserveDIAccessIndexCall(CI, ChildInfo) &&
486  IsValidAIChain(ParentInfo.Metadata, ParentInfo.AccessIndex,
487  ChildInfo.Metadata)) {
488  AIChain[CI] = std::make_pair(Call, ParentInfo);
489  traceAICall(CI, ChildInfo);
490  } else {
491  BaseAICalls[Call] = ParentInfo;
492  }
493  } else if (auto *GI = dyn_cast<GetElementPtrInst>(Inst)) {
494  if (GI->hasAllZeroIndices())
495  traceGEP(GI, Call, ParentInfo);
496  else
497  BaseAICalls[Call] = ParentInfo;
498  } else {
499  BaseAICalls[Call] = ParentInfo;
500  }
501  }
502 }
503 
504 void BPFAbstractMemberAccess::traceBitCast(BitCastInst *BitCast,
505  CallInst *Parent,
506  CallInfo &ParentInfo) {
507  for (User *U : BitCast->users()) {
508  Instruction *Inst = dyn_cast<Instruction>(U);
509  if (!Inst)
510  continue;
511 
512  if (auto *BI = dyn_cast<BitCastInst>(Inst)) {
513  traceBitCast(BI, Parent, ParentInfo);
514  } else if (auto *CI = dyn_cast<CallInst>(Inst)) {
515  CallInfo ChildInfo;
516  if (IsPreserveDIAccessIndexCall(CI, ChildInfo) &&
517  IsValidAIChain(ParentInfo.Metadata, ParentInfo.AccessIndex,
518  ChildInfo.Metadata)) {
519  AIChain[CI] = std::make_pair(Parent, ParentInfo);
520  traceAICall(CI, ChildInfo);
521  } else {
522  BaseAICalls[Parent] = ParentInfo;
523  }
524  } else if (auto *GI = dyn_cast<GetElementPtrInst>(Inst)) {
525  if (GI->hasAllZeroIndices())
526  traceGEP(GI, Parent, ParentInfo);
527  else
528  BaseAICalls[Parent] = ParentInfo;
529  } else {
530  BaseAICalls[Parent] = ParentInfo;
531  }
532  }
533 }
534 
535 void BPFAbstractMemberAccess::traceGEP(GetElementPtrInst *GEP, CallInst *Parent,
536  CallInfo &ParentInfo) {
537  for (User *U : GEP->users()) {
538  Instruction *Inst = dyn_cast<Instruction>(U);
539  if (!Inst)
540  continue;
541 
542  if (auto *BI = dyn_cast<BitCastInst>(Inst)) {
543  traceBitCast(BI, Parent, ParentInfo);
544  } else if (auto *CI = dyn_cast<CallInst>(Inst)) {
545  CallInfo ChildInfo;
546  if (IsPreserveDIAccessIndexCall(CI, ChildInfo) &&
547  IsValidAIChain(ParentInfo.Metadata, ParentInfo.AccessIndex,
548  ChildInfo.Metadata)) {
549  AIChain[CI] = std::make_pair(Parent, ParentInfo);
550  traceAICall(CI, ChildInfo);
551  } else {
552  BaseAICalls[Parent] = ParentInfo;
553  }
554  } else if (auto *GI = dyn_cast<GetElementPtrInst>(Inst)) {
555  if (GI->hasAllZeroIndices())
556  traceGEP(GI, Parent, ParentInfo);
557  else
558  BaseAICalls[Parent] = ParentInfo;
559  } else {
560  BaseAICalls[Parent] = ParentInfo;
561  }
562  }
563 }
564 
565 void BPFAbstractMemberAccess::collectAICallChains(Function &F) {
566  AIChain.clear();
567  BaseAICalls.clear();
568 
569  for (auto &BB : F)
570  for (auto &I : BB) {
571  CallInfo CInfo;
572  auto *Call = dyn_cast<CallInst>(&I);
573  if (!IsPreserveDIAccessIndexCall(Call, CInfo) ||
574  AIChain.find(Call) != AIChain.end())
575  continue;
576 
577  traceAICall(Call, CInfo);
578  }
579 }
580 
581 uint64_t BPFAbstractMemberAccess::getConstant(const Value *IndexValue) {
582  const ConstantInt *CV = dyn_cast<ConstantInt>(IndexValue);
583  assert(CV);
584  return CV->getValue().getZExtValue();
585 }
586 
587 /// Get the start and the end of storage offset for \p MemberTy.
588 void BPFAbstractMemberAccess::GetStorageBitRange(DIDerivedType *MemberTy,
589  Align RecordAlignment,
590  uint32_t &StartBitOffset,
591  uint32_t &EndBitOffset) {
592  uint32_t MemberBitSize = MemberTy->getSizeInBits();
593  uint32_t MemberBitOffset = MemberTy->getOffsetInBits();
594 
595  if (RecordAlignment > 8) {
596  // If the Bits are within an aligned 8-byte, set the RecordAlignment
597  // to 8, other report the fatal error.
598  if (MemberBitOffset / 64 != (MemberBitOffset + MemberBitSize) / 64)
599  report_fatal_error("Unsupported field expression for llvm.bpf.preserve.field.info, "
600  "requiring too big alignment");
601  RecordAlignment = Align(8);
602  }
603 
604  uint32_t AlignBits = RecordAlignment.value() * 8;
605  if (MemberBitSize > AlignBits)
606  report_fatal_error("Unsupported field expression for llvm.bpf.preserve.field.info, "
607  "bitfield size greater than record alignment");
608 
609  StartBitOffset = MemberBitOffset & ~(AlignBits - 1);
610  if ((StartBitOffset + AlignBits) < (MemberBitOffset + MemberBitSize))
611  report_fatal_error("Unsupported field expression for llvm.bpf.preserve.field.info, "
612  "cross alignment boundary");
613  EndBitOffset = StartBitOffset + AlignBits;
614 }
615 
616 uint32_t BPFAbstractMemberAccess::GetFieldInfo(uint32_t InfoKind,
617  DICompositeType *CTy,
618  uint32_t AccessIndex,
619  uint32_t PatchImm,
620  MaybeAlign RecordAlignment) {
621  if (InfoKind == BPFCoreSharedInfo::FIELD_EXISTENCE)
622  return 1;
623 
624  uint32_t Tag = CTy->getTag();
625  if (InfoKind == BPFCoreSharedInfo::FIELD_BYTE_OFFSET) {
626  if (Tag == dwarf::DW_TAG_array_type) {
627  auto *EltTy = stripQualifiers(CTy->getBaseType());
628  PatchImm += AccessIndex * calcArraySize(CTy, 1) *
629  (EltTy->getSizeInBits() >> 3);
630  } else if (Tag == dwarf::DW_TAG_structure_type) {
631  auto *MemberTy = cast<DIDerivedType>(CTy->getElements()[AccessIndex]);
632  if (!MemberTy->isBitField()) {
633  PatchImm += MemberTy->getOffsetInBits() >> 3;
634  } else {
635  unsigned SBitOffset, NextSBitOffset;
636  GetStorageBitRange(MemberTy, *RecordAlignment, SBitOffset,
637  NextSBitOffset);
638  PatchImm += SBitOffset >> 3;
639  }
640  }
641  return PatchImm;
642  }
643 
644  if (InfoKind == BPFCoreSharedInfo::FIELD_BYTE_SIZE) {
645  if (Tag == dwarf::DW_TAG_array_type) {
646  auto *EltTy = stripQualifiers(CTy->getBaseType());
647  return calcArraySize(CTy, 1) * (EltTy->getSizeInBits() >> 3);
648  } else {
649  auto *MemberTy = cast<DIDerivedType>(CTy->getElements()[AccessIndex]);
650  uint32_t SizeInBits = MemberTy->getSizeInBits();
651  if (!MemberTy->isBitField())
652  return SizeInBits >> 3;
653 
654  unsigned SBitOffset, NextSBitOffset;
655  GetStorageBitRange(MemberTy, *RecordAlignment, SBitOffset,
656  NextSBitOffset);
657  SizeInBits = NextSBitOffset - SBitOffset;
658  if (SizeInBits & (SizeInBits - 1))
659  report_fatal_error("Unsupported field expression for llvm.bpf.preserve.field.info");
660  return SizeInBits >> 3;
661  }
662  }
663 
664  if (InfoKind == BPFCoreSharedInfo::FIELD_SIGNEDNESS) {
665  const DIType *BaseTy;
666  if (Tag == dwarf::DW_TAG_array_type) {
667  // Signedness only checked when final array elements are accessed.
668  if (CTy->getElements().size() != 1)
669  report_fatal_error("Invalid array expression for llvm.bpf.preserve.field.info");
670  BaseTy = stripQualifiers(CTy->getBaseType());
671  } else {
672  auto *MemberTy = cast<DIDerivedType>(CTy->getElements()[AccessIndex]);
673  BaseTy = stripQualifiers(MemberTy->getBaseType());
674  }
675 
676  // Only basic types and enum types have signedness.
677  const auto *BTy = dyn_cast<DIBasicType>(BaseTy);
678  while (!BTy) {
679  const auto *CompTy = dyn_cast<DICompositeType>(BaseTy);
680  // Report an error if the field expression does not have signedness.
681  if (!CompTy || CompTy->getTag() != dwarf::DW_TAG_enumeration_type)
682  report_fatal_error("Invalid field expression for llvm.bpf.preserve.field.info");
683  BaseTy = stripQualifiers(CompTy->getBaseType());
684  BTy = dyn_cast<DIBasicType>(BaseTy);
685  }
686  uint32_t Encoding = BTy->getEncoding();
687  return (Encoding == dwarf::DW_ATE_signed || Encoding == dwarf::DW_ATE_signed_char);
688  }
689 
690  if (InfoKind == BPFCoreSharedInfo::FIELD_LSHIFT_U64) {
691  // The value is loaded into a value with FIELD_BYTE_SIZE size,
692  // and then zero or sign extended to U64.
693  // FIELD_LSHIFT_U64 and FIELD_RSHIFT_U64 are operations
694  // to extract the original value.
695  const Triple &Triple = TM->getTargetTriple();
696  DIDerivedType *MemberTy = nullptr;
697  bool IsBitField = false;
698  uint32_t SizeInBits;
699 
700  if (Tag == dwarf::DW_TAG_array_type) {
701  auto *EltTy = stripQualifiers(CTy->getBaseType());
702  SizeInBits = calcArraySize(CTy, 1) * EltTy->getSizeInBits();
703  } else {
704  MemberTy = cast<DIDerivedType>(CTy->getElements()[AccessIndex]);
705  SizeInBits = MemberTy->getSizeInBits();
706  IsBitField = MemberTy->isBitField();
707  }
708 
709  if (!IsBitField) {
710  if (SizeInBits > 64)
711  report_fatal_error("too big field size for llvm.bpf.preserve.field.info");
712  return 64 - SizeInBits;
713  }
714 
715  unsigned SBitOffset, NextSBitOffset;
716  GetStorageBitRange(MemberTy, *RecordAlignment, SBitOffset, NextSBitOffset);
717  if (NextSBitOffset - SBitOffset > 64)
718  report_fatal_error("too big field size for llvm.bpf.preserve.field.info");
719 
720  unsigned OffsetInBits = MemberTy->getOffsetInBits();
721  if (Triple.getArch() == Triple::bpfel)
722  return SBitOffset + 64 - OffsetInBits - SizeInBits;
723  else
724  return OffsetInBits + 64 - NextSBitOffset;
725  }
726 
727  if (InfoKind == BPFCoreSharedInfo::FIELD_RSHIFT_U64) {
728  DIDerivedType *MemberTy = nullptr;
729  bool IsBitField = false;
730  uint32_t SizeInBits;
731  if (Tag == dwarf::DW_TAG_array_type) {
732  auto *EltTy = stripQualifiers(CTy->getBaseType());
733  SizeInBits = calcArraySize(CTy, 1) * EltTy->getSizeInBits();
734  } else {
735  MemberTy = cast<DIDerivedType>(CTy->getElements()[AccessIndex]);
736  SizeInBits = MemberTy->getSizeInBits();
737  IsBitField = MemberTy->isBitField();
738  }
739 
740  if (!IsBitField) {
741  if (SizeInBits > 64)
742  report_fatal_error("too big field size for llvm.bpf.preserve.field.info");
743  return 64 - SizeInBits;
744  }
745 
746  unsigned SBitOffset, NextSBitOffset;
747  GetStorageBitRange(MemberTy, *RecordAlignment, SBitOffset, NextSBitOffset);
748  if (NextSBitOffset - SBitOffset > 64)
749  report_fatal_error("too big field size for llvm.bpf.preserve.field.info");
750 
751  return 64 - SizeInBits;
752  }
753 
754  llvm_unreachable("Unknown llvm.bpf.preserve.field.info info kind");
755 }
756 
757 bool BPFAbstractMemberAccess::HasPreserveFieldInfoCall(CallInfoStack &CallStack) {
758  // This is called in error return path, no need to maintain CallStack.
759  while (CallStack.size()) {
760  auto StackElem = CallStack.top();
761  if (StackElem.second.Kind == BPFPreserveFieldInfoAI)
762  return true;
763  CallStack.pop();
764  }
765  return false;
766 }
767 
768 /// Compute the base of the whole preserve_* intrinsics chains, i.e., the base
769 /// pointer of the first preserve_*_access_index call, and construct the access
770 /// string, which will be the name of a global variable.
771 Value *BPFAbstractMemberAccess::computeBaseAndAccessKey(CallInst *Call,
772  CallInfo &CInfo,
773  std::string &AccessKey,
774  MDNode *&TypeMeta) {
775  Value *Base = nullptr;
776  std::string TypeName;
777  CallInfoStack CallStack;
778 
779  // Put the access chain into a stack with the top as the head of the chain.
780  while (Call) {
781  CallStack.push(std::make_pair(Call, CInfo));
782  CInfo = AIChain[Call].second;
783  Call = AIChain[Call].first;
784  }
785 
786  // The access offset from the base of the head of chain is also
787  // calculated here as all debuginfo types are available.
788 
789  // Get type name and calculate the first index.
790  // We only want to get type name from typedef, structure or union.
791  // If user wants a relocation like
792  // int *p; ... __builtin_preserve_access_index(&p[4]) ...
793  // or
794  // int a[10][20]; ... __builtin_preserve_access_index(&a[2][3]) ...
795  // we will skip them.
796  uint32_t FirstIndex = 0;
797  uint32_t PatchImm = 0; // AccessOffset or the requested field info
799  while (CallStack.size()) {
800  auto StackElem = CallStack.top();
801  Call = StackElem.first;
802  CInfo = StackElem.second;
803 
804  if (!Base)
805  Base = CInfo.Base;
806 
807  DIType *PossibleTypeDef = stripQualifiers(cast<DIType>(CInfo.Metadata),
808  false);
809  DIType *Ty = stripQualifiers(PossibleTypeDef);
810  if (CInfo.Kind == BPFPreserveUnionAI ||
811  CInfo.Kind == BPFPreserveStructAI) {
812  // struct or union type. If the typedef is in the metadata, always
813  // use the typedef.
814  TypeName = std::string(PossibleTypeDef->getName());
815  TypeMeta = PossibleTypeDef;
816  PatchImm += FirstIndex * (Ty->getSizeInBits() >> 3);
817  break;
818  }
819 
820  assert(CInfo.Kind == BPFPreserveArrayAI);
821 
822  // Array entries will always be consumed for accumulative initial index.
823  CallStack.pop();
824 
825  // BPFPreserveArrayAI
826  uint64_t AccessIndex = CInfo.AccessIndex;
827 
828  DIType *BaseTy = nullptr;
829  bool CheckElemType = false;
830  if (const auto *CTy = dyn_cast<DICompositeType>(Ty)) {
831  // array type
832  assert(CTy->getTag() == dwarf::DW_TAG_array_type);
833 
834 
835  FirstIndex += AccessIndex * calcArraySize(CTy, 1);
836  BaseTy = stripQualifiers(CTy->getBaseType());
837  CheckElemType = CTy->getElements().size() == 1;
838  } else {
839  // pointer type
840  auto *DTy = cast<DIDerivedType>(Ty);
841  assert(DTy->getTag() == dwarf::DW_TAG_pointer_type);
842 
843  BaseTy = stripQualifiers(DTy->getBaseType());
844  CTy = dyn_cast<DICompositeType>(BaseTy);
845  if (!CTy) {
846  CheckElemType = true;
847  } else if (CTy->getTag() != dwarf::DW_TAG_array_type) {
848  FirstIndex += AccessIndex;
849  CheckElemType = true;
850  } else {
851  FirstIndex += AccessIndex * calcArraySize(CTy, 0);
852  }
853  }
854 
855  if (CheckElemType) {
856  auto *CTy = dyn_cast<DICompositeType>(BaseTy);
857  if (!CTy) {
858  if (HasPreserveFieldInfoCall(CallStack))
859  report_fatal_error("Invalid field access for llvm.preserve.field.info intrinsic");
860  return nullptr;
861  }
862 
863  unsigned CTag = CTy->getTag();
864  if (CTag == dwarf::DW_TAG_structure_type || CTag == dwarf::DW_TAG_union_type) {
865  TypeName = std::string(CTy->getName());
866  } else {
867  if (HasPreserveFieldInfoCall(CallStack))
868  report_fatal_error("Invalid field access for llvm.preserve.field.info intrinsic");
869  return nullptr;
870  }
871  TypeMeta = CTy;
872  PatchImm += FirstIndex * (CTy->getSizeInBits() >> 3);
873  break;
874  }
875  }
876  assert(TypeName.size());
877  AccessKey += std::to_string(FirstIndex);
878 
879  // Traverse the rest of access chain to complete offset calculation
880  // and access key construction.
881  while (CallStack.size()) {
882  auto StackElem = CallStack.top();
883  CInfo = StackElem.second;
884  CallStack.pop();
885 
886  if (CInfo.Kind == BPFPreserveFieldInfoAI) {
887  InfoKind = CInfo.AccessIndex;
888  if (InfoKind == BPFCoreSharedInfo::FIELD_EXISTENCE)
889  PatchImm = 1;
890  break;
891  }
892 
893  // If the next Call (the top of the stack) is a BPFPreserveFieldInfoAI,
894  // the action will be extracting field info.
895  if (CallStack.size()) {
896  auto StackElem2 = CallStack.top();
897  CallInfo CInfo2 = StackElem2.second;
898  if (CInfo2.Kind == BPFPreserveFieldInfoAI) {
899  InfoKind = CInfo2.AccessIndex;
900  assert(CallStack.size() == 1);
901  }
902  }
903 
904  // Access Index
905  uint64_t AccessIndex = CInfo.AccessIndex;
906  AccessKey += ":" + std::to_string(AccessIndex);
907 
908  MDNode *MDN = CInfo.Metadata;
909  // At this stage, it cannot be pointer type.
910  auto *CTy = cast<DICompositeType>(stripQualifiers(cast<DIType>(MDN)));
911  PatchImm = GetFieldInfo(InfoKind, CTy, AccessIndex, PatchImm,
912  CInfo.RecordAlignment);
913  }
914 
915  // Access key is the
916  // "llvm." + type name + ":" + reloc type + ":" + patched imm + "$" +
917  // access string,
918  // uniquely identifying one relocation.
919  // The prefix "llvm." indicates this is a temporary global, which should
920  // not be emitted to ELF file.
921  AccessKey = "llvm." + TypeName + ":" + std::to_string(InfoKind) + ":" +
922  std::to_string(PatchImm) + "$" + AccessKey;
923 
924  return Base;
925 }
926 
927 MDNode *BPFAbstractMemberAccess::computeAccessKey(CallInst *Call,
928  CallInfo &CInfo,
929  std::string &AccessKey,
930  bool &IsInt32Ret) {
931  DIType *Ty = stripQualifiers(cast<DIType>(CInfo.Metadata), false);
932  assert(!Ty->getName().empty());
933 
934  int64_t PatchImm;
935  std::string AccessStr("0");
936  if (CInfo.AccessIndex == BPFCoreSharedInfo::TYPE_EXISTENCE) {
937  PatchImm = 1;
938  } else if (CInfo.AccessIndex == BPFCoreSharedInfo::TYPE_SIZE) {
939  // typedef debuginfo type has size 0, get the eventual base type.
940  DIType *BaseTy = stripQualifiers(Ty, true);
941  PatchImm = BaseTy->getSizeInBits() / 8;
942  } else {
943  // ENUM_VALUE_EXISTENCE and ENUM_VALUE
944  IsInt32Ret = false;
945 
946  // The argument could be a global variable or a getelementptr with base to
947  // a global variable depending on whether the clang option `opaque-options`
948  // is set or not.
949  const GlobalVariable *GV =
950  cast<GlobalVariable>(Call->getArgOperand(1)->stripPointerCasts());
951  assert(GV->hasInitializer());
952  const ConstantDataArray *DA = cast<ConstantDataArray>(GV->getInitializer());
953  assert(DA->isString());
954  StringRef ValueStr = DA->getAsString();
955 
956  // ValueStr format: <EnumeratorStr>:<Value>
957  size_t Separator = ValueStr.find_first_of(':');
958  StringRef EnumeratorStr = ValueStr.substr(0, Separator);
959 
960  // Find enumerator index in the debuginfo
961  DIType *BaseTy = stripQualifiers(Ty, true);
962  const auto *CTy = cast<DICompositeType>(BaseTy);
963  assert(CTy->getTag() == dwarf::DW_TAG_enumeration_type);
964  int EnumIndex = 0;
965  for (const auto Element : CTy->getElements()) {
966  const auto *Enum = cast<DIEnumerator>(Element);
967  if (Enum->getName() == EnumeratorStr) {
968  AccessStr = std::to_string(EnumIndex);
969  break;
970  }
971  EnumIndex++;
972  }
973 
974  if (CInfo.AccessIndex == BPFCoreSharedInfo::ENUM_VALUE) {
975  StringRef EValueStr = ValueStr.substr(Separator + 1);
976  PatchImm = std::stoll(std::string(EValueStr));
977  } else {
978  PatchImm = 1;
979  }
980  }
981 
982  AccessKey = "llvm." + Ty->getName().str() + ":" +
983  std::to_string(CInfo.AccessIndex) + std::string(":") +
984  std::to_string(PatchImm) + std::string("$") + AccessStr;
985 
986  return Ty;
987 }
988 
989 /// Call/Kind is the base preserve_*_access_index() call. Attempts to do
990 /// transformation to a chain of relocable GEPs.
991 bool BPFAbstractMemberAccess::transformGEPChain(CallInst *Call,
992  CallInfo &CInfo) {
993  std::string AccessKey;
994  MDNode *TypeMeta;
995  Value *Base = nullptr;
996  bool IsInt32Ret;
997 
998  IsInt32Ret = CInfo.Kind == BPFPreserveFieldInfoAI;
999  if (CInfo.Kind == BPFPreserveFieldInfoAI && CInfo.Metadata) {
1000  TypeMeta = computeAccessKey(Call, CInfo, AccessKey, IsInt32Ret);
1001  } else {
1002  Base = computeBaseAndAccessKey(Call, CInfo, AccessKey, TypeMeta);
1003  if (!Base)
1004  return false;
1005  }
1006 
1007  BasicBlock *BB = Call->getParent();
1008  GlobalVariable *GV;
1009 
1010  if (GEPGlobals.find(AccessKey) == GEPGlobals.end()) {
1011  IntegerType *VarType;
1012  if (IsInt32Ret)
1013  VarType = Type::getInt32Ty(BB->getContext()); // 32bit return value
1014  else
1015  VarType = Type::getInt64Ty(BB->getContext()); // 64bit ptr or enum value
1016 
1017  GV = new GlobalVariable(*M, VarType, false, GlobalVariable::ExternalLinkage,
1018  nullptr, AccessKey);
1020  GV->setMetadata(LLVMContext::MD_preserve_access_index, TypeMeta);
1021  GEPGlobals[AccessKey] = GV;
1022  } else {
1023  GV = GEPGlobals[AccessKey];
1024  }
1025 
1026  if (CInfo.Kind == BPFPreserveFieldInfoAI) {
1027  // Load the global variable which represents the returned field info.
1028  LoadInst *LDInst;
1029  if (IsInt32Ret)
1030  LDInst = new LoadInst(Type::getInt32Ty(BB->getContext()), GV, "", Call);
1031  else
1032  LDInst = new LoadInst(Type::getInt64Ty(BB->getContext()), GV, "", Call);
1033 
1034  Instruction *PassThroughInst =
1035  BPFCoreSharedInfo::insertPassThrough(M, BB, LDInst, Call);
1036  Call->replaceAllUsesWith(PassThroughInst);
1037  Call->eraseFromParent();
1038  return true;
1039  }
1040 
1041  // For any original GEP Call and Base %2 like
1042  // %4 = bitcast %struct.net_device** %dev1 to i64*
1043  // it is transformed to:
1044  // %6 = load llvm.sk_buff:0:50$0:0:0:2:0
1045  // %7 = bitcast %struct.sk_buff* %2 to i8*
1046  // %8 = getelementptr i8, i8* %7, %6
1047  // %9 = bitcast i8* %8 to i64*
1048  // using %9 instead of %4
1049  // The original Call inst is removed.
1050 
1051  // Load the global variable.
1052  auto *LDInst = new LoadInst(Type::getInt64Ty(BB->getContext()), GV, "", Call);
1053 
1054  // Generate a BitCast
1055  auto *BCInst = new BitCastInst(Base, Type::getInt8PtrTy(BB->getContext()));
1056  BB->getInstList().insert(Call->getIterator(), BCInst);
1057 
1058  // Generate a GetElementPtr
1059  auto *GEP = GetElementPtrInst::Create(Type::getInt8Ty(BB->getContext()),
1060  BCInst, LDInst);
1061  BB->getInstList().insert(Call->getIterator(), GEP);
1062 
1063  // Generate a BitCast
1064  auto *BCInst2 = new BitCastInst(GEP, Call->getType());
1065  BB->getInstList().insert(Call->getIterator(), BCInst2);
1066 
1067  // For the following code,
1068  // Block0:
1069  // ...
1070  // if (...) goto Block1 else ...
1071  // Block1:
1072  // %6 = load llvm.sk_buff:0:50$0:0:0:2:0
1073  // %7 = bitcast %struct.sk_buff* %2 to i8*
1074  // %8 = getelementptr i8, i8* %7, %6
1075  // ...
1076  // goto CommonExit
1077  // Block2:
1078  // ...
1079  // if (...) goto Block3 else ...
1080  // Block3:
1081  // %6 = load llvm.bpf_map:0:40$0:0:0:2:0
1082  // %7 = bitcast %struct.sk_buff* %2 to i8*
1083  // %8 = getelementptr i8, i8* %7, %6
1084  // ...
1085  // goto CommonExit
1086  // CommonExit
1087  // SimplifyCFG may generate:
1088  // Block0:
1089  // ...
1090  // if (...) goto Block_Common else ...
1091  // Block2:
1092  // ...
1093  // if (...) goto Block_Common else ...
1094  // Block_Common:
1095  // PHI = [llvm.sk_buff:0:50$0:0:0:2:0, llvm.bpf_map:0:40$0:0:0:2:0]
1096  // %6 = load PHI
1097  // %7 = bitcast %struct.sk_buff* %2 to i8*
1098  // %8 = getelementptr i8, i8* %7, %6
1099  // ...
1100  // goto CommonExit
1101  // For the above code, we cannot perform proper relocation since
1102  // "load PHI" has two possible relocations.
1103  //
1104  // To prevent above tail merging, we use __builtin_bpf_passthrough()
1105  // where one of its parameters is a seq_num. Since two
1106  // __builtin_bpf_passthrough() funcs will always have different seq_num,
1107  // tail merging cannot happen. The __builtin_bpf_passthrough() will be
1108  // removed in the beginning of Target IR passes.
1109  //
1110  // This approach is also used in other places when global var
1111  // representing a relocation is used.
1112  Instruction *PassThroughInst =
1113  BPFCoreSharedInfo::insertPassThrough(M, BB, BCInst2, Call);
1114  Call->replaceAllUsesWith(PassThroughInst);
1115  Call->eraseFromParent();
1116 
1117  return true;
1118 }
1119 
1120 bool BPFAbstractMemberAccess::doTransformation(Function &F) {
1121  bool Transformed = false;
1122 
1123  // Collect PreserveDIAccessIndex Intrinsic call chains.
1124  // The call chains will be used to generate the access
1125  // patterns similar to GEP.
1126  collectAICallChains(F);
1127 
1128  for (auto &C : BaseAICalls)
1129  Transformed = transformGEPChain(C.first, C.second) || Transformed;
1130 
1131  return removePreserveAccessIndexIntrinsic(F) || Transformed;
1132 }
1133 
1136  return BPFAbstractMemberAccess(TM).run(F) ? PreservedAnalyses::none()
1138 }
llvm::PreservedAnalyses
A set of analyses that are preserved following a run of a transformation pass.
Definition: PassManager.h:152
llvm::DICompositeType::getBaseType
DIType * getBaseType() const
Definition: DebugInfoMetadata.h:1175
llvm::BPFCoreSharedInfo::MAX_PRESERVE_ENUM_VALUE_FLAG
@ MAX_PRESERVE_ENUM_VALUE_FLAG
Definition: BPFCORE.h:57
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
llvm::DIType
Base class for types.
Definition: DebugInfoMetadata.h:658
M
We currently emits eax Perhaps this is what we really should generate is Is imull three or four cycles eax eax The current instruction priority is based on pattern complexity The former is more complex because it folds a load so the latter will not be emitted Perhaps we should use AddedComplexity to give LEA32r a higher priority We should always try to match LEA first since the LEA matching code does some estimate to determine whether the match is profitable if we care more about code then imull is better It s two bytes shorter than movl leal On a Pentium M
Definition: README.txt:252
llvm::DataLayout
A parsed version of the target data layout string in and methods for querying it.
Definition: DataLayout.h:113
llvm::Intrinsic::getDeclaration
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=None)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
Definition: Function.cpp:1418
llvm::Type::getInt8PtrTy
static PointerType * getInt8PtrTy(LLVMContext &C, unsigned AS=0)
Definition: Type.cpp:291
llvm::DIType::getSizeInBits
uint64_t getSizeInBits() const
Definition: DebugInfoMetadata.h:697
DebugInfoMetadata.h
llvm::Function
Definition: Function.h:60
Pass.h
llvm::BitCastInst
This class represents a no-op cast from one type to another.
Definition: Instructions.h:5212
llvm::ConstantInt::getValue
const APInt & getValue() const
Return the constant as an APInt value reference.
Definition: Constants.h:133
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1185
SkipDIDerivedTag
static bool SkipDIDerivedTag(unsigned Tag, bool skipTypedef)
Definition: BPFAbstractMemberAccess.cpp:228
llvm::GlobalVariable
Definition: GlobalVariable.h:39
llvm::Triple
Triple - Helper class for working with autoconf configuration names.
Definition: Triple.h:44
llvm::PreservedAnalyses::none
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition: PassManager.h:155
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
Module.h
llvm::BPFCoreSharedInfo::SeqNum
static uint32_t SeqNum
llvm.bpf.passthrough builtin seq number
Definition: BPFCORE.h:66
getBaseElementType
static Type * getBaseElementType(const CallInst *Call)
Definition: BPFAbstractMemberAccess.cpp:272
calcArraySize
static uint32_t calcArraySize(const DICompositeType *CTy, uint32_t StartDim)
Definition: BPFAbstractMemberAccess.cpp:257
BPF.h
llvm::dwarf::Tag
Tag
Definition: Dwarf.h:105
llvm::BPFCoreSharedInfo::TYPE_EXISTENCE
@ TYPE_EXISTENCE
Definition: BPFCORE.h:31
llvm::Type::getInt8Ty
static IntegerType * getInt8Ty(LLVMContext &C)
Definition: Type.cpp:237
llvm::Type::getInt32Ty
static IntegerType * getInt32Ty(LLVMContext &C)
Definition: Type.cpp:239
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
llvm::BPFCoreSharedInfo::FIELD_RSHIFT_U64
@ FIELD_RSHIFT_U64
Definition: BPFCORE.h:28
F
#define F(x, y, z)
Definition: MD5.cpp:55
llvm::GlobalVariable::hasInitializer
bool hasInitializer() const
Definitions have initializers, declarations don't.
Definition: GlobalVariable.h:91
llvm::BasicBlock
LLVM Basic Block Representation.
Definition: BasicBlock.h:55
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
llvm::StringRef::substr
LLVM_NODISCARD StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition: StringRef.h:615
llvm::CallInfo
Definition: GVNHoist.cpp:217
Instruction.h
llvm::ConstantInt
This is the shared class of boolean and integer constants.
Definition: Constants.h:79
llvm::DISubrange::getCount
BoundType getCount() const
Definition: DebugInfoMetadata.cpp:378
llvm::BPFCoreSharedInfo::MAX_PRESERVE_TYPE_INFO_FLAG
@ MAX_PRESERVE_TYPE_INFO_FLAG
Definition: BPFCORE.h:50
llvm::User
Definition: User.h:44
C
(vector float) vec_cmpeq(*A, *B) C
Definition: README_ALTIVEC.txt:86
llvm::CallInst::Create
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
Definition: Instructions.h:1504
llvm::BPFCoreSharedInfo::FIELD_EXISTENCE
@ FIELD_EXISTENCE
Definition: BPFCORE.h:25
llvm::DINode::getTag
dwarf::Tag getTag() const
Definition: DebugInfoMetadata.cpp:184
llvm::BPFCoreSharedInfo::FIELD_SIGNEDNESS
@ FIELD_SIGNEDNESS
Definition: BPFCORE.h:26
llvm::DIType::getName
StringRef getName() const
Definition: DebugInfoMetadata.h:704
llvm::DISubrange
Array subrange.
Definition: DebugInfoMetadata.h:300
llvm::M68kBeads::DA
@ DA
Definition: M68kBaseInfo.h:59
llvm::MaybeAlign
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Definition: Alignment.h:117
llvm::IntegerType
Class to represent integer types.
Definition: DerivedTypes.h:40
llvm::Instruction
Definition: Instruction.h:42
llvm::GlobalVariable::addAttribute
void addAttribute(Attribute::AttrKind Kind)
Add attribute to this global.
Definition: GlobalVariable.h:187
llvm::MCID::Flag
Flag
These should be considered private to the implementation of the MCInstrDesc class.
Definition: MCInstrDesc.h:147
llvm::report_fatal_error
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:143
llvm::APInt::getZExtValue
uint64_t getZExtValue() const
Get zero extended value.
Definition: APInt.h:1466
llvm::BPFAbstractMemberAccessPass::run
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Definition: BPFAbstractMemberAccess.cpp:1135
llvm::ConstantInt::get
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.
Definition: Constants.cpp:928
Align
uint64_t Align
Definition: ELFObjHandler.cpp:81
llvm::Align
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
llvm::MCID::Call
@ Call
Definition: MCInstrDesc.h:155
llvm::Metadata
Root of the metadata hierarchy.
Definition: Metadata.h:62
llvm::Triple::getArch
ArchType getArch() const
Get the parsed architecture type of this triple.
Definition: Triple.h:345
llvm::StringRef::str
LLVM_NODISCARD std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:249
llvm::lltok::Kind
Kind
Definition: LLToken.h:18
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
Type.h
llvm::dxil::PointerTypeAnalysis::run
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
Definition: PointerTypeAnalysis.cpp:101
llvm::BPFCoreSharedInfo::MAX_FIELD_RELOC_KIND
@ MAX_FIELD_RELOC_KIND
Definition: BPFCORE.h:36
llvm::GlobalVariable::getInitializer
const Constant * getInitializer() const
getInitializer - Return the initializer for this global variable.
Definition: GlobalVariable.h:135
llvm::Constant
This is an important base class in LLVM.
Definition: Constant.h:41
llvm::StringRef::empty
constexpr LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:153
llvm::DICompositeType::getElements
DINodeArray getElements() const
Definition: DebugInfoMetadata.h:1176
llvm::BPFCoreSharedInfo::ENUM_VALUE
@ ENUM_VALUE
Definition: BPFCORE.h:34
uint64_t
llvm::BPFCoreSharedInfo::FIELD_BYTE_OFFSET
@ FIELD_BYTE_OFFSET
Definition: BPFCORE.h:23
llvm::ConstantDataArray
An array constant whose element type is a simple 1/2/4/8-byte integer or float/double,...
Definition: Constants.h:679
llvm::BPFCoreSharedInfo::insertPassThrough
static Instruction * insertPassThrough(Module *M, BasicBlock *BB, Instruction *Input, Instruction *Before)
Insert a bpf passthrough builtin function.
Definition: BPFAbstractMemberAccess.cpp:101
I
#define I(x, y, z)
Definition: MD5.cpp:58
llvm::GetElementPtrInst
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
Definition: Instructions.h:916
llvm::GetElementPtrInst::CreateInBounds
static GetElementPtrInst * CreateInBounds(Type *PointeeType, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
Create an "inbounds" getelementptr.
Definition: Instructions.h:969
llvm::BPFCoreSharedInfo::PRESERVE_TYPE_INFO_EXISTENCE
@ PRESERVE_TYPE_INFO_EXISTENCE
Definition: BPFCORE.h:47
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::TargetMachine
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:77
DEBUG_TYPE
#define DEBUG_TYPE
Definition: BPFAbstractMemberAccess.cpp:95
llvm::pdb::PDB_SymType::Dimension
@ Dimension
llvm::Triple::bpfel
@ bpfel
Definition: Triple.h:56
llvm::DIType::isBitField
bool isBitField() const
Definition: DebugInfoMetadata.h:734
llvm::BPFCoreSharedInfo::TYPE_SIZE
@ TYPE_SIZE
Definition: BPFCORE.h:32
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
llvm::MDNode
Metadata node.
Definition: Metadata.h:937
llvm::BPFCoreSharedInfo::FIELD_BYTE_SIZE
@ FIELD_BYTE_SIZE
Definition: BPFCORE.h:24
llvm::GetElementPtrInst::Create
static GetElementPtrInst * Create(Type *PointeeType, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
Definition: Instructions.h:942
llvm::DICompositeType
Composite types.
Definition: DebugInfoMetadata.h:1042
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
Dwarf.h
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
llvm::createBPFAbstractMemberAccess
FunctionPass * createBPFAbstractMemberAccess(BPFTargetMachine *TM)
uint32_t
llvm::ilist_node_impl::getIterator
self_iterator getIterator()
Definition: ilist_node.h:82
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: AArch64SLSHardening.cpp:76
llvm::pdb::PDB_SymType::Enum
@ Enum
llvm::BPFCoreSharedInfo::PRESERVE_ENUM_VALUE_EXISTENCE
@ PRESERVE_ENUM_VALUE_EXISTENCE
Definition: BPFCORE.h:54
llvm::BPFCoreSharedInfo::ENUM_VALUE_EXISTENCE
@ ENUM_VALUE_EXISTENCE
Definition: BPFCORE.h:33
llvm::LoadInst
An instruction for reading from memory.
Definition: Instructions.h:173
llvm::BPFTargetMachine
Definition: BPFTargetMachine.h:20
runOnFunction
static bool runOnFunction(Function &F, bool PostInlining)
Definition: EntryExitInstrumenter.cpp:69
llvm::DIType::getOffsetInBits
uint64_t getOffsetInBits() const
Definition: DebugInfoMetadata.h:700
llvm::Type::getInt64Ty
static IntegerType * getInt64Ty(LLVMContext &C)
Definition: Type.cpp:240
llvm::AMDGPU::HSAMD::Kernel::Arg::Key::TypeName
constexpr char TypeName[]
Key for Kernel::Arg::Metadata::mTypeName.
Definition: AMDGPUMetadata.h:175
llvm::PreservedAnalyses::all
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: PassManager.h:158
llvm::Align::value
uint64_t value() const
This is a hole in the type system and should not be abused.
Definition: Alignment.h:85
stripQualifiers
static DIType * stripQualifiers(DIType *Ty, bool skipTypedef=true)
Definition: BPFAbstractMemberAccess.cpp:239
GlobalVariable.h
BPFCORE.h
PassManager.h
llvm::DIDerivedType
Derived types.
Definition: DebugInfoMetadata.h:924
llvm::GlobalValue::ExternalLinkage
@ ExternalLinkage
Externally visible function.
Definition: GlobalValue.h:48
llvm::BPFCoreSharedInfo::AmaAttr
static constexpr StringRef AmaAttr
The attribute attached to globals representing a field access.
Definition: BPFCORE.h:61
llvm::GlobalObject::setMetadata
void setMetadata(unsigned KindID, MDNode *Node)
Set a particular kind of metadata attachment.
Definition: Metadata.cpp:1264
Instructions.h
User.h
llvm::BPFCoreSharedInfo::FIELD_LSHIFT_U64
@ FIELD_LSHIFT_U64
Definition: BPFCORE.h:27
llvm::to_string
std::string to_string(const T &Value)
Definition: ScopedPrinter.h:85
llvm::AnalysisManager
A container for analyses that lazily runs them and caches their results.
Definition: InstructionSimplify.h:42
TM
const char LLVMTargetMachineRef TM
Definition: PassBuilderBindings.cpp:47
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:308
llvm::CallInst
This class represents a function call, abstracting a target machine's calling convention.
Definition: Instructions.h:1461
BB
Common register allocation spilling lr str ldr sxth r3 ldr mla r4 can lr mov lr str ldr sxth r3 mla r4 and then merge mul and lr str ldr sxth r3 mla r4 It also increase the likelihood the store may become dead bb27 Successors according to LLVM BB
Definition: README.txt:39
llvm::StringRef::find_first_of
LLVM_NODISCARD 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.
Definition: StringRef.h:414
GEP
Hexagon Common GEP
Definition: HexagonCommonGEP.cpp:171
INITIALIZE_PASS
INITIALIZE_PASS(BPFAbstractMemberAccessLegacyPass, DEBUG_TYPE, "BPF Abstract Member Access", false, false) FunctionPass *llvm
Definition: BPFAbstractMemberAccess.cpp:206
BasicBlockUtils.h
Value.h
llvm::Value
LLVM Value Representation.
Definition: Value.h:74
llvm::Value::users
iterator_range< user_iterator > users()
Definition: Value.h:421
llvm::sampleprof::Base
@ Base
Definition: Discriminator.h:58
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:38
BPFTargetMachine.h