LLVM 24.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"
80#include "llvm/ADT/MapVector.h"
81#include "llvm/ADT/STLExtras.h"
87#include "llvm/IR/Instruction.h"
89#include "llvm/IR/IntrinsicsBPF.h"
90#include "llvm/IR/Module.h"
91#include "llvm/IR/PassManager.h"
92#include "llvm/IR/Type.h"
93#include "llvm/IR/User.h"
94#include "llvm/IR/Value.h"
95#include "llvm/IR/ValueHandle.h"
96#include "llvm/Pass.h"
98#include <stack>
99
100#define DEBUG_TYPE "bpf-abstract-member-access"
101
102namespace llvm {
104
107 Instruction *Before) {
109 M, Intrinsic::bpf_passthrough, {Input->getType(), Input->getType()});
110 Constant *SeqNumVal = ConstantInt::get(Type::getInt32Ty(BB->getContext()),
112
113 auto *NewInst = CallInst::Create(Fn, {SeqNumVal, Input});
114 NewInst->insertBefore(Before->getIterator());
115 return NewInst;
116}
117} // namespace llvm
118
119using namespace llvm;
120
121namespace {
122class BPFAbstractMemberAccess final {
123public:
124 BPFAbstractMemberAccess(BPFTargetMachine *TM) : TM(TM) {}
125
126 bool run(Function &F);
127
128 struct CallInfo {
129 uint32_t Kind;
130 uint32_t AccessIndex;
131 MaybeAlign RecordAlignment;
132 MDNode *Metadata;
133 WeakTrackingVH Base;
134 };
135 typedef std::stack<std::pair<CallInst *, CallInfo>> CallInfoStack;
136
137private:
138 enum : uint32_t {
139 BPFPreserveArrayAI = 1,
140 BPFPreserveUnionAI = 2,
141 BPFPreserveStructAI = 3,
142 BPFPreserveFieldInfoAI = 4,
143 };
144
145 TargetMachine *TM;
146 const DataLayout *DL = nullptr;
147 Module *M = nullptr;
148
149 static std::map<std::string, GlobalVariable *> GEPGlobals;
150 // A map to link preserve_*_access_index intrinsic calls.
151 std::map<CallInst *, std::pair<CallInst *, CallInfo>> AIChain;
152 // A map to hold all the base preserve_*_access_index intrinsic calls.
153 // The base call is not an input of any other preserve_*
154 // intrinsics.
155 // Iterated below, so the order can't come from the addresses.
156 SmallMapVector<CallInst *, CallInfo, 4> BaseAICalls;
157 // A map to hold <AnonRecord, TypeDef> relationships
158 std::map<DICompositeType *, DIDerivedType *> AnonRecords;
159
160 void CheckAnonRecordType(DIDerivedType *ParentTy, DIType *Ty);
161 void CheckCompositeType(DIDerivedType *ParentTy, DICompositeType *CTy);
162 void CheckDerivedType(DIDerivedType *ParentTy, DIDerivedType *DTy);
163 void ResetMetadata(struct CallInfo &CInfo);
164
165 bool doTransformation(Function &F);
166
167 void traceAICall(CallInst *Call, CallInfo &ParentInfo);
168 void traceBitCast(BitCastInst *BitCast, CallInst *Parent,
169 CallInfo &ParentInfo);
170 void traceGEP(GetElementPtrInst *GEP, CallInst *Parent,
171 CallInfo &ParentInfo);
172 void collectAICallChains(Function &F);
173
174 bool IsPreserveDIAccessIndexCall(const CallInst *Call, CallInfo &Cinfo);
175 bool IsValidAIChain(const MDNode *ParentMeta, uint32_t ParentAI,
176 const MDNode *ChildMeta);
177 bool removePreserveAccessIndexIntrinsic(Function &F);
178 bool HasPreserveFieldInfoCall(CallInfoStack &CallStack);
179 void GetStorageBitRange(DIDerivedType *MemberTy, Align RecordAlignment,
180 uint32_t &StartBitOffset, uint32_t &EndBitOffset);
181 uint32_t GetFieldInfo(uint32_t InfoKind, DICompositeType *CTy,
182 uint32_t AccessIndex, uint32_t PatchImm,
183 MaybeAlign RecordAlignment);
184
185 Value *computeBaseAndAccessKey(CallInst *Call, CallInfo &CInfo,
186 std::string &AccessKey, MDNode *&BaseMeta);
187 struct EnumAccess {
188 size_t Index;
189 StringRef Value;
190 };
191 static EnumAccess computeEnumAccess(const CallInst *Call, const DIType *Ty);
192 MDNode *computeAccessKey(CallInst *Call, const CallInfo &CInfo,
193 std::string &AccessKey);
194 bool transformGEPChain(CallInst *Call, CallInfo &CInfo);
195};
196
197std::map<std::string, GlobalVariable *> BPFAbstractMemberAccess::GEPGlobals;
198} // End anonymous namespace
199
200bool BPFAbstractMemberAccess::run(Function &F) {
201 LLVM_DEBUG(dbgs() << "********** Abstract Member Accesses **********\n");
202
203 M = F.getParent();
204 if (!M)
205 return false;
206
207 // Bail out if no debug info.
208 if (M->debug_compile_units().empty())
209 return false;
210
211 // For each argument/return/local_variable type, trace the type
212 // pattern like '[derived_type]* [composite_type]' to check
213 // and remember (anon record -> typedef) relations where the
214 // anon record is defined as
215 // typedef [const/volatile/restrict]* [anon record]
216 DISubprogram *SP = F.getSubprogram();
217 if (SP && SP->isDefinition()) {
218 for (DIType *Ty: SP->getType()->getTypeArray())
219 CheckAnonRecordType(nullptr, Ty);
220 for (const MDNode *DN : SP->getRetainedNodes()) {
221 if (const auto *DV = dyn_cast<DILocalVariable>(DN))
222 CheckAnonRecordType(nullptr, DV->getType());
223 }
224 }
225
226 DL = &M->getDataLayout();
227 return doTransformation(F);
228}
229
230void BPFAbstractMemberAccess::ResetMetadata(struct CallInfo &CInfo) {
231 if (auto Ty = dyn_cast<DICompositeType>(CInfo.Metadata)) {
232 auto It = AnonRecords.find(Ty);
233 if (It != AnonRecords.end() && It->second != nullptr)
234 CInfo.Metadata = It->second;
235 }
236}
237
238void BPFAbstractMemberAccess::CheckCompositeType(DIDerivedType *ParentTy,
239 DICompositeType *CTy) {
240 if (!CTy->getName().empty() || !ParentTy ||
241 ParentTy->getTag() != dwarf::DW_TAG_typedef)
242 return;
243
244 auto [It, Inserted] = AnonRecords.try_emplace(CTy, ParentTy);
245 // Two or more typedef's may point to the same anon record.
246 // If this is the case, set the typedef DIType to be nullptr
247 // to indicate the duplication case.
248 if (!Inserted && It->second != ParentTy)
249 It->second = nullptr;
250}
251
252void BPFAbstractMemberAccess::CheckDerivedType(DIDerivedType *ParentTy,
253 DIDerivedType *DTy) {
254 DIType *BaseType = DTy->getBaseType();
255 if (!BaseType)
256 return;
257
258 unsigned Tag = DTy->getTag();
259 if (Tag == dwarf::DW_TAG_pointer_type)
260 CheckAnonRecordType(nullptr, BaseType);
261 else if (Tag == dwarf::DW_TAG_typedef)
262 CheckAnonRecordType(DTy, BaseType);
263 else
264 CheckAnonRecordType(ParentTy, BaseType);
265}
266
267void BPFAbstractMemberAccess::CheckAnonRecordType(DIDerivedType *ParentTy,
268 DIType *Ty) {
269 if (!Ty)
270 return;
271
272 if (auto *CTy = dyn_cast<DICompositeType>(Ty))
273 return CheckCompositeType(ParentTy, CTy);
274 else if (auto *DTy = dyn_cast<DIDerivedType>(Ty))
275 return CheckDerivedType(ParentTy, DTy);
276}
277
278static bool SkipDIDerivedTag(unsigned Tag, bool skipTypedef) {
279 if (Tag != dwarf::DW_TAG_typedef && Tag != dwarf::DW_TAG_const_type &&
280 Tag != dwarf::DW_TAG_volatile_type &&
281 Tag != dwarf::DW_TAG_restrict_type &&
282 Tag != dwarf::DW_TAG_member)
283 return false;
284 if (Tag == dwarf::DW_TAG_typedef && !skipTypedef)
285 return false;
286 return true;
287}
288
289static DIType * stripQualifiers(DIType *Ty, bool skipTypedef = true) {
290 while (auto *DTy = dyn_cast<DIDerivedType>(Ty)) {
291 if (!SkipDIDerivedTag(DTy->getTag(), skipTypedef))
292 break;
293 Ty = DTy->getBaseType();
294 }
295 return Ty;
296}
297
298static const DIType * stripQualifiers(const DIType *Ty) {
299 while (auto *DTy = dyn_cast<DIDerivedType>(Ty)) {
300 if (!SkipDIDerivedTag(DTy->getTag(), true))
301 break;
302 Ty = DTy->getBaseType();
303 }
304 return Ty;
305}
306
307static uint32_t calcArraySize(const DICompositeType *CTy, uint32_t StartDim) {
308 DINodeArray Elements = CTy->getElements();
309 uint32_t DimSize = 1;
310 for (uint32_t I = StartDim; I < Elements.size(); ++I) {
311 if (auto *Element = dyn_cast_or_null<DINode>(Elements[I]))
312 if (Element->getTag() == dwarf::DW_TAG_subrange_type) {
313 const DISubrange *SR = cast<DISubrange>(Element);
314 auto *CI = dyn_cast<ConstantInt *>(SR->getCount());
315 DimSize *= CI->getSExtValue();
316 }
317 }
318
319 return DimSize;
320}
321
323 // Element type is stored in an elementtype() attribute on the first param.
324 return Call->getParamElementType(0);
325}
326
327static uint64_t getConstant(const Value *IndexValue) {
328 const ConstantInt *CV = dyn_cast<ConstantInt>(IndexValue);
329 assert(CV);
330 return CV->getValue().getZExtValue();
331}
332
333/// Check whether a call is a preserve_*_access_index intrinsic call or not.
334bool BPFAbstractMemberAccess::IsPreserveDIAccessIndexCall(const CallInst *Call,
335 CallInfo &CInfo) {
336 if (!Call)
337 return false;
338
339 const auto *GV = dyn_cast<GlobalValue>(Call->getCalledOperand());
340 if (!GV)
341 return false;
342 if (GV->getName().starts_with("llvm.preserve.array.access.index")) {
343 CInfo.Kind = BPFPreserveArrayAI;
344 CInfo.Metadata = Call->getMetadata(LLVMContext::MD_preserve_access_index);
345 if (!CInfo.Metadata)
346 report_fatal_error("Missing metadata for llvm.preserve.array.access.index intrinsic");
347 CInfo.AccessIndex = getConstant(Call->getArgOperand(2));
348 CInfo.Base = Call->getArgOperand(0);
349 CInfo.RecordAlignment = DL->getABITypeAlign(getBaseElementType(Call));
350 return true;
351 }
352 if (GV->getName().starts_with("llvm.preserve.union.access.index")) {
353 CInfo.Kind = BPFPreserveUnionAI;
354 CInfo.Metadata = Call->getMetadata(LLVMContext::MD_preserve_access_index);
355 if (!CInfo.Metadata)
356 report_fatal_error("Missing metadata for llvm.preserve.union.access.index intrinsic");
357 ResetMetadata(CInfo);
358 CInfo.AccessIndex = getConstant(Call->getArgOperand(1));
359 CInfo.Base = Call->getArgOperand(0);
360 return true;
361 }
362 if (GV->getName().starts_with("llvm.preserve.struct.access.index")) {
363 CInfo.Kind = BPFPreserveStructAI;
364 CInfo.Metadata = Call->getMetadata(LLVMContext::MD_preserve_access_index);
365 if (!CInfo.Metadata)
366 report_fatal_error("Missing metadata for llvm.preserve.struct.access.index intrinsic");
367 ResetMetadata(CInfo);
368 CInfo.AccessIndex = getConstant(Call->getArgOperand(2));
369 CInfo.Base = Call->getArgOperand(0);
370 CInfo.RecordAlignment = DL->getABITypeAlign(getBaseElementType(Call));
371 return true;
372 }
373 if (GV->getName().starts_with("llvm.bpf.preserve.field.info")) {
374 CInfo.Kind = BPFPreserveFieldInfoAI;
375 CInfo.Metadata = nullptr;
376 // Check validity of info_kind as clang did not check this.
378 if (InfoKind >= BTF::MAX_FIELD_RELOC_KIND)
379 report_fatal_error("Incorrect info_kind for llvm.bpf.preserve.field.info intrinsic");
380 CInfo.AccessIndex = InfoKind;
381 return true;
382 }
383 if (GV->getName().starts_with("llvm.bpf.preserve.type.info")) {
384 CInfo.Kind = BPFPreserveFieldInfoAI;
385 CInfo.Metadata = Call->getMetadata(LLVMContext::MD_preserve_access_index);
386 if (!CInfo.Metadata)
387 report_fatal_error("Missing metadata for llvm.preserve.type.info intrinsic");
390 report_fatal_error("Incorrect flag for llvm.bpf.preserve.type.info intrinsic");
392 CInfo.AccessIndex = BTF::TYPE_EXISTENCE;
394 CInfo.AccessIndex = BTF::TYPE_MATCH;
395 else
396 CInfo.AccessIndex = BTF::TYPE_SIZE;
397 return true;
398 }
399 if (GV->getName().starts_with("llvm.bpf.preserve.enum.value")) {
400 CInfo.Kind = BPFPreserveFieldInfoAI;
401 CInfo.Metadata = Call->getMetadata(LLVMContext::MD_preserve_access_index);
402 if (!CInfo.Metadata)
403 report_fatal_error("Missing metadata for llvm.preserve.enum.value intrinsic");
406 report_fatal_error("Incorrect flag for llvm.bpf.preserve.enum.value intrinsic");
408 CInfo.AccessIndex = BTF::ENUM_VALUE_EXISTENCE;
409 else
410 CInfo.AccessIndex = BTF::ENUM_VALUE;
411 return true;
412 }
413
414 return false;
415}
416
417static void replaceWithGEP(CallInst *Call, uint32_t DimensionIndex,
418 uint32_t GEPIndex) {
419 uint32_t Dimension = 1;
420 if (DimensionIndex > 0)
421 Dimension = getConstant(Call->getArgOperand(DimensionIndex));
422
423 Constant *Zero =
424 ConstantInt::get(Type::getInt32Ty(Call->getParent()->getContext()), 0);
425 SmallVector<Value *, 4> IdxList(Dimension, Zero);
426 IdxList.push_back(Call->getArgOperand(GEPIndex));
427
429 Call->getArgOperand(0), IdxList,
430 "", Call->getIterator());
431 Call->replaceAllUsesWith(GEP);
432 Call->eraseFromParent();
433}
434
438
442
444 Call->replaceAllUsesWith(Call->getArgOperand(0));
445 Call->eraseFromParent();
446}
447
448bool BPFAbstractMemberAccess::removePreserveAccessIndexIntrinsic(Function &F) {
449 std::vector<CallInst *> PreserveArrayIndexCalls;
450 std::vector<CallInst *> PreserveUnionIndexCalls;
451 std::vector<CallInst *> PreserveStructIndexCalls;
452 bool Found = false;
453
454 for (auto &BB : F)
455 for (auto &I : BB) {
456 auto *Call = dyn_cast<CallInst>(&I);
457 CallInfo CInfo;
458 if (!IsPreserveDIAccessIndexCall(Call, CInfo))
459 continue;
460
461 Found = true;
462 if (CInfo.Kind == BPFPreserveArrayAI)
463 PreserveArrayIndexCalls.push_back(Call);
464 else if (CInfo.Kind == BPFPreserveUnionAI)
465 PreserveUnionIndexCalls.push_back(Call);
466 else
467 PreserveStructIndexCalls.push_back(Call);
468 }
469
470 // do the following transformation:
471 // . addr = preserve_array_access_index(base, dimension, index)
472 // is transformed to
473 // addr = GEP(base, dimenion's zero's, index)
474 // . addr = preserve_union_access_index(base, di_index)
475 // is transformed to
476 // addr = base, i.e., all usages of "addr" are replaced by "base".
477 // . addr = preserve_struct_access_index(base, gep_index, di_index)
478 // is transformed to
479 // addr = GEP(base, 0, gep_index)
480 for (CallInst *Call : PreserveArrayIndexCalls)
482 for (CallInst *Call : PreserveStructIndexCalls)
484 for (CallInst *Call : PreserveUnionIndexCalls)
486
487 return Found;
488}
489
490/// Check whether the access index chain is valid. We check
491/// here because there may be type casts between two
492/// access indexes. We want to ensure memory access still valid.
493bool BPFAbstractMemberAccess::IsValidAIChain(const MDNode *ParentType,
494 uint32_t ParentAI,
495 const MDNode *ChildType) {
496 if (!ChildType)
497 return true; // preserve_field_info, no type comparison needed.
498
499 const DIType *PType = stripQualifiers(cast<DIType>(ParentType));
500 const DIType *CType = stripQualifiers(cast<DIType>(ChildType));
501
502 // Child is a derived/pointer type, which is due to type casting.
503 // Pointer type cannot be in the middle of chain.
504 if (isa<DIDerivedType>(CType))
505 return false;
506
507 // Parent is a pointer type.
508 if (const auto *PtrTy = dyn_cast<DIDerivedType>(PType)) {
509 if (PtrTy->getTag() != dwarf::DW_TAG_pointer_type)
510 return false;
511 return stripQualifiers(PtrTy->getBaseType()) == CType;
512 }
513
514 // Otherwise, struct/union/array types
515 const auto *PTy = dyn_cast<DICompositeType>(PType);
516 const auto *CTy = dyn_cast<DICompositeType>(CType);
517 assert(PTy && CTy && "ParentType or ChildType is null or not composite");
518
519 uint32_t PTyTag = PTy->getTag();
520 assert(PTyTag == dwarf::DW_TAG_array_type ||
521 PTyTag == dwarf::DW_TAG_structure_type ||
522 PTyTag == dwarf::DW_TAG_union_type);
523
524 uint32_t CTyTag = CTy->getTag();
525 assert(CTyTag == dwarf::DW_TAG_array_type ||
526 CTyTag == dwarf::DW_TAG_structure_type ||
527 CTyTag == dwarf::DW_TAG_union_type);
528
529 // Multi dimensional arrays, base element should be the same
530 if (PTyTag == dwarf::DW_TAG_array_type && PTyTag == CTyTag)
531 return PTy->getBaseType() == CTy->getBaseType();
532
533 DIType *Ty;
534 if (PTyTag == dwarf::DW_TAG_array_type)
535 Ty = PTy->getBaseType();
536 else
537 Ty = dyn_cast<DIType>(PTy->getElements()[ParentAI]);
538
540}
541
542void BPFAbstractMemberAccess::traceAICall(CallInst *Call,
543 CallInfo &ParentInfo) {
544 for (User *U : Call->users()) {
546 if (!Inst)
547 continue;
548
549 if (auto *BI = dyn_cast<BitCastInst>(Inst)) {
550 traceBitCast(BI, Call, ParentInfo);
551 } else if (auto *CI = dyn_cast<CallInst>(Inst)) {
552 CallInfo ChildInfo;
553
554 if (IsPreserveDIAccessIndexCall(CI, ChildInfo) &&
555 IsValidAIChain(ParentInfo.Metadata, ParentInfo.AccessIndex,
556 ChildInfo.Metadata)) {
557 AIChain[CI] = std::make_pair(Call, ParentInfo);
558 traceAICall(CI, ChildInfo);
559 } else {
560 BaseAICalls[Call] = ParentInfo;
561 }
562 } else if (auto *GI = dyn_cast<GetElementPtrInst>(Inst)) {
563 if (GI->hasAllZeroIndices())
564 traceGEP(GI, Call, ParentInfo);
565 else
566 BaseAICalls[Call] = ParentInfo;
567 } else {
568 BaseAICalls[Call] = ParentInfo;
569 }
570 }
571}
572
573void BPFAbstractMemberAccess::traceBitCast(BitCastInst *BitCast,
574 CallInst *Parent,
575 CallInfo &ParentInfo) {
576 for (User *U : BitCast->users()) {
578 if (!Inst)
579 continue;
580
581 if (auto *BI = dyn_cast<BitCastInst>(Inst)) {
582 traceBitCast(BI, Parent, ParentInfo);
583 } else if (auto *CI = dyn_cast<CallInst>(Inst)) {
584 CallInfo ChildInfo;
585 if (IsPreserveDIAccessIndexCall(CI, ChildInfo) &&
586 IsValidAIChain(ParentInfo.Metadata, ParentInfo.AccessIndex,
587 ChildInfo.Metadata)) {
588 AIChain[CI] = std::make_pair(Parent, ParentInfo);
589 traceAICall(CI, ChildInfo);
590 } else {
591 BaseAICalls[Parent] = ParentInfo;
592 }
593 } else if (auto *GI = dyn_cast<GetElementPtrInst>(Inst)) {
594 if (GI->hasAllZeroIndices())
595 traceGEP(GI, Parent, ParentInfo);
596 else
597 BaseAICalls[Parent] = ParentInfo;
598 } else {
599 BaseAICalls[Parent] = ParentInfo;
600 }
601 }
602}
603
604void BPFAbstractMemberAccess::traceGEP(GetElementPtrInst *GEP, CallInst *Parent,
605 CallInfo &ParentInfo) {
606 for (User *U : GEP->users()) {
608 if (!Inst)
609 continue;
610
611 if (auto *BI = dyn_cast<BitCastInst>(Inst)) {
612 traceBitCast(BI, Parent, ParentInfo);
613 } else if (auto *CI = dyn_cast<CallInst>(Inst)) {
614 CallInfo ChildInfo;
615 if (IsPreserveDIAccessIndexCall(CI, ChildInfo) &&
616 IsValidAIChain(ParentInfo.Metadata, ParentInfo.AccessIndex,
617 ChildInfo.Metadata)) {
618 AIChain[CI] = std::make_pair(Parent, ParentInfo);
619 traceAICall(CI, ChildInfo);
620 } else {
621 BaseAICalls[Parent] = ParentInfo;
622 }
623 } else if (auto *GI = dyn_cast<GetElementPtrInst>(Inst)) {
624 if (GI->hasAllZeroIndices())
625 traceGEP(GI, Parent, ParentInfo);
626 else
627 BaseAICalls[Parent] = ParentInfo;
628 } else {
629 BaseAICalls[Parent] = ParentInfo;
630 }
631 }
632}
633
634void BPFAbstractMemberAccess::collectAICallChains(Function &F) {
635 AIChain.clear();
636 BaseAICalls.clear();
637
638 for (auto &BB : F)
639 for (auto &I : BB) {
640 CallInfo CInfo;
641 auto *Call = dyn_cast<CallInst>(&I);
642 if (!IsPreserveDIAccessIndexCall(Call, CInfo) ||
643 AIChain.find(Call) != AIChain.end())
644 continue;
645
646 traceAICall(Call, CInfo);
647 }
648}
649
650/// Get the start and the end of storage offset for \p MemberTy.
651void BPFAbstractMemberAccess::GetStorageBitRange(DIDerivedType *MemberTy,
652 Align RecordAlignment,
653 uint32_t &StartBitOffset,
654 uint32_t &EndBitOffset) {
655 uint32_t MemberBitSize = MemberTy->getSizeInBits();
656 uint32_t MemberBitOffset = MemberTy->getOffsetInBits();
657
658 if (RecordAlignment > 8) {
659 // If the Bits are within an aligned 8-byte, set the RecordAlignment
660 // to 8, other report the fatal error.
661 if (MemberBitOffset / 64 != (MemberBitOffset + MemberBitSize) / 64)
662 report_fatal_error("Unsupported field expression for llvm.bpf.preserve.field.info, "
663 "requiring too big alignment");
664 RecordAlignment = Align(8);
665 }
666
667 uint32_t AlignBits = RecordAlignment.value() * 8;
668 if (MemberBitSize > AlignBits)
669 report_fatal_error("Unsupported field expression for llvm.bpf.preserve.field.info, "
670 "bitfield size greater than record alignment");
671
672 StartBitOffset = MemberBitOffset & ~(AlignBits - 1);
673 if ((StartBitOffset + AlignBits) < (MemberBitOffset + MemberBitSize))
674 report_fatal_error("Unsupported field expression for llvm.bpf.preserve.field.info, "
675 "cross alignment boundary");
676 EndBitOffset = StartBitOffset + AlignBits;
677}
678
679uint32_t BPFAbstractMemberAccess::GetFieldInfo(uint32_t InfoKind,
680 DICompositeType *CTy,
681 uint32_t AccessIndex,
682 uint32_t PatchImm,
683 MaybeAlign RecordAlignment) {
684 if (InfoKind == BTF::FIELD_EXISTENCE)
685 return 1;
686
687 uint32_t Tag = CTy->getTag();
688 if (InfoKind == BTF::FIELD_BYTE_OFFSET) {
689 if (Tag == dwarf::DW_TAG_array_type) {
690 auto *EltTy = stripQualifiers(CTy->getBaseType());
691 PatchImm += AccessIndex * calcArraySize(CTy, 1) *
692 (EltTy->getSizeInBits() >> 3);
693 } else if (Tag == dwarf::DW_TAG_structure_type) {
694 auto *MemberTy = cast<DIDerivedType>(CTy->getElements()[AccessIndex]);
695 if (!MemberTy->isBitField()) {
696 PatchImm += MemberTy->getOffsetInBits() >> 3;
697 } else {
698 unsigned SBitOffset, NextSBitOffset;
699 GetStorageBitRange(MemberTy, *RecordAlignment, SBitOffset,
700 NextSBitOffset);
701 PatchImm += SBitOffset >> 3;
702 }
703 }
704 return PatchImm;
705 }
706
707 if (InfoKind == BTF::FIELD_BYTE_SIZE) {
708 if (Tag == dwarf::DW_TAG_array_type) {
709 auto *EltTy = stripQualifiers(CTy->getBaseType());
710 return calcArraySize(CTy, 1) * (EltTy->getSizeInBits() >> 3);
711 } else {
712 auto *MemberTy = cast<DIDerivedType>(CTy->getElements()[AccessIndex]);
713 uint32_t SizeInBits = MemberTy->getSizeInBits();
714 if (!MemberTy->isBitField())
715 return SizeInBits >> 3;
716
717 unsigned SBitOffset, NextSBitOffset;
718 GetStorageBitRange(MemberTy, *RecordAlignment, SBitOffset,
719 NextSBitOffset);
720 SizeInBits = NextSBitOffset - SBitOffset;
721 if (SizeInBits & (SizeInBits - 1))
722 report_fatal_error("Unsupported field expression for llvm.bpf.preserve.field.info");
723 return SizeInBits >> 3;
724 }
725 }
726
727 if (InfoKind == BTF::FIELD_SIGNEDNESS) {
728 const DIType *BaseTy;
729 if (Tag == dwarf::DW_TAG_array_type) {
730 // Signedness only checked when final array elements are accessed.
731 if (CTy->getElements().size() != 1)
732 report_fatal_error("Invalid array expression for llvm.bpf.preserve.field.info");
733 BaseTy = stripQualifiers(CTy->getBaseType());
734 } else {
735 auto *MemberTy = cast<DIDerivedType>(CTy->getElements()[AccessIndex]);
736 BaseTy = stripQualifiers(MemberTy->getBaseType());
737 }
738
739 // Only basic types and enum types have signedness.
740 const auto *BTy = dyn_cast<DIBasicType>(BaseTy);
741 while (!BTy) {
742 const auto *CompTy = dyn_cast<DICompositeType>(BaseTy);
743 // Report an error if the field expression does not have signedness.
744 if (!CompTy || CompTy->getTag() != dwarf::DW_TAG_enumeration_type)
745 report_fatal_error("Invalid field expression for llvm.bpf.preserve.field.info");
746 BaseTy = stripQualifiers(CompTy->getBaseType());
747 BTy = dyn_cast<DIBasicType>(BaseTy);
748 }
749 uint32_t Encoding = BTy->getEncoding();
750 return (Encoding == dwarf::DW_ATE_signed || Encoding == dwarf::DW_ATE_signed_char);
751 }
752
753 if (InfoKind == BTF::FIELD_LSHIFT_U64) {
754 // The value is loaded into a value with FIELD_BYTE_SIZE size,
755 // and then zero or sign extended to U64.
756 // FIELD_LSHIFT_U64 and FIELD_RSHIFT_U64 are operations
757 // to extract the original value.
758 const Triple &Triple = TM->getTargetTriple();
759 DIDerivedType *MemberTy = nullptr;
760 bool IsBitField = false;
761 uint32_t SizeInBits;
762
763 if (Tag == dwarf::DW_TAG_array_type) {
764 auto *EltTy = stripQualifiers(CTy->getBaseType());
765 SizeInBits = calcArraySize(CTy, 1) * EltTy->getSizeInBits();
766 } else {
767 MemberTy = cast<DIDerivedType>(CTy->getElements()[AccessIndex]);
768 SizeInBits = MemberTy->getSizeInBits();
769 IsBitField = MemberTy->isBitField();
770 }
771
772 if (!IsBitField) {
773 if (SizeInBits > 64)
774 report_fatal_error("too big field size for llvm.bpf.preserve.field.info");
775 return 64 - SizeInBits;
776 }
777
778 unsigned SBitOffset, NextSBitOffset;
779 GetStorageBitRange(MemberTy, *RecordAlignment, SBitOffset, NextSBitOffset);
780 if (NextSBitOffset - SBitOffset > 64)
781 report_fatal_error("too big field size for llvm.bpf.preserve.field.info");
782
783 unsigned OffsetInBits = MemberTy->getOffsetInBits();
784 if (Triple.getArch() == Triple::bpfel)
785 return SBitOffset + 64 - OffsetInBits - SizeInBits;
786 else
787 return OffsetInBits + 64 - NextSBitOffset;
788 }
789
790 if (InfoKind == BTF::FIELD_RSHIFT_U64) {
791 DIDerivedType *MemberTy = nullptr;
792 bool IsBitField = false;
793 uint32_t SizeInBits;
794 if (Tag == dwarf::DW_TAG_array_type) {
795 auto *EltTy = stripQualifiers(CTy->getBaseType());
796 SizeInBits = calcArraySize(CTy, 1) * EltTy->getSizeInBits();
797 } else {
798 MemberTy = cast<DIDerivedType>(CTy->getElements()[AccessIndex]);
799 SizeInBits = MemberTy->getSizeInBits();
800 IsBitField = MemberTy->isBitField();
801 }
802
803 if (!IsBitField) {
804 if (SizeInBits > 64)
805 report_fatal_error("too big field size for llvm.bpf.preserve.field.info");
806 return 64 - SizeInBits;
807 }
808
809 unsigned SBitOffset, NextSBitOffset;
810 GetStorageBitRange(MemberTy, *RecordAlignment, SBitOffset, NextSBitOffset);
811 if (NextSBitOffset - SBitOffset > 64)
812 report_fatal_error("too big field size for llvm.bpf.preserve.field.info");
813
814 return 64 - SizeInBits;
815 }
816
817 llvm_unreachable("Unknown llvm.bpf.preserve.field.info info kind");
818}
819
820bool BPFAbstractMemberAccess::HasPreserveFieldInfoCall(CallInfoStack &CallStack) {
821 // This is called in error return path, no need to maintain CallStack.
822 while (CallStack.size()) {
823 auto StackElem = CallStack.top();
824 if (StackElem.second.Kind == BPFPreserveFieldInfoAI)
825 return true;
826 CallStack.pop();
827 }
828 return false;
829}
830
831/// Compute the base of the whole preserve_* intrinsics chains, i.e., the base
832/// pointer of the first preserve_*_access_index call, and construct the access
833/// string, which will be the name of a global variable.
834Value *BPFAbstractMemberAccess::computeBaseAndAccessKey(CallInst *Call,
835 CallInfo &CInfo,
836 std::string &AccessKey,
837 MDNode *&TypeMeta) {
838 Value *Base = nullptr;
839 std::string TypeName;
840 CallInfoStack CallStack;
841
842 // Put the access chain into a stack with the top as the head of the chain.
843 while (Call) {
844 CallStack.push(std::make_pair(Call, CInfo));
845 auto &Chain = AIChain[Call];
846 CInfo = Chain.second;
847 Call = Chain.first;
848 }
849
850 // The access offset from the base of the head of chain is also
851 // calculated here as all debuginfo types are available.
852
853 // Get type name and calculate the first index.
854 // We only want to get type name from typedef, structure or union.
855 // If user wants a relocation like
856 // int *p; ... __builtin_preserve_access_index(&p[4]) ...
857 // or
858 // int a[10][20]; ... __builtin_preserve_access_index(&a[2][3]) ...
859 // we will skip them.
860 uint32_t FirstIndex = 0;
861 uint32_t PatchImm = 0; // AccessOffset or the requested field info
863 while (CallStack.size()) {
864 auto StackElem = CallStack.top();
865 Call = StackElem.first;
866 CInfo = StackElem.second;
867
868 if (!Base)
869 Base = CInfo.Base;
870
871 DIType *PossibleTypeDef = stripQualifiers(cast<DIType>(CInfo.Metadata),
872 false);
873 DIType *Ty = stripQualifiers(PossibleTypeDef);
874 if (CInfo.Kind == BPFPreserveUnionAI ||
875 CInfo.Kind == BPFPreserveStructAI) {
876 // struct or union type. If the typedef is in the metadata, always
877 // use the typedef.
878 TypeName = std::string(PossibleTypeDef->getName());
879 TypeMeta = PossibleTypeDef;
880 PatchImm += FirstIndex * (Ty->getSizeInBits() >> 3);
881 break;
882 }
883
884 assert(CInfo.Kind == BPFPreserveArrayAI);
885
886 // Array entries will always be consumed for accumulative initial index.
887 CallStack.pop();
888
889 // BPFPreserveArrayAI
890 uint64_t AccessIndex = CInfo.AccessIndex;
891
892 DIType *BaseTy = nullptr;
893 bool CheckElemType = false;
894 if (const auto *CTy = dyn_cast<DICompositeType>(Ty)) {
895 // array type
896 assert(CTy->getTag() == dwarf::DW_TAG_array_type);
897
898
899 FirstIndex += AccessIndex * calcArraySize(CTy, 1);
900 BaseTy = stripQualifiers(CTy->getBaseType());
901 CheckElemType = CTy->getElements().size() == 1;
902 } else {
903 // pointer type
904 auto *DTy = cast<DIDerivedType>(Ty);
905 assert(DTy->getTag() == dwarf::DW_TAG_pointer_type);
906
907 BaseTy = stripQualifiers(DTy->getBaseType());
908 CTy = dyn_cast<DICompositeType>(BaseTy);
909 if (!CTy) {
910 CheckElemType = true;
911 } else if (CTy->getTag() != dwarf::DW_TAG_array_type) {
912 FirstIndex += AccessIndex;
913 CheckElemType = true;
914 } else {
915 FirstIndex += AccessIndex * calcArraySize(CTy, 0);
916 }
917 }
918
919 if (CheckElemType) {
920 auto *CTy = dyn_cast<DICompositeType>(BaseTy);
921 if (!CTy) {
922 if (HasPreserveFieldInfoCall(CallStack))
923 report_fatal_error("Invalid field access for llvm.preserve.field.info intrinsic");
924 return nullptr;
925 }
926
927 unsigned CTag = CTy->getTag();
928 if (CTag == dwarf::DW_TAG_structure_type || CTag == dwarf::DW_TAG_union_type) {
929 TypeName = std::string(CTy->getName());
930 } else {
931 if (HasPreserveFieldInfoCall(CallStack))
932 report_fatal_error("Invalid field access for llvm.preserve.field.info intrinsic");
933 return nullptr;
934 }
935 TypeMeta = CTy;
936 PatchImm += FirstIndex * (CTy->getSizeInBits() >> 3);
937 break;
938 }
939 }
940 assert(TypeName.size());
941 AccessKey += std::to_string(FirstIndex);
942
943 // Traverse the rest of access chain to complete offset calculation
944 // and access key construction.
945 while (CallStack.size()) {
946 auto StackElem = CallStack.top();
947 CInfo = StackElem.second;
948 CallStack.pop();
949
950 if (CInfo.Kind == BPFPreserveFieldInfoAI) {
951 InfoKind = CInfo.AccessIndex;
952 if (InfoKind == BTF::FIELD_EXISTENCE)
953 PatchImm = 1;
954 break;
955 }
956
957 // If the next Call (the top of the stack) is a BPFPreserveFieldInfoAI,
958 // the action will be extracting field info.
959 if (CallStack.size()) {
960 auto StackElem2 = CallStack.top();
961 CallInfo CInfo2 = StackElem2.second;
962 if (CInfo2.Kind == BPFPreserveFieldInfoAI) {
963 InfoKind = CInfo2.AccessIndex;
964 assert(CallStack.size() == 1);
965 }
966 }
967
968 // Access Index
969 uint64_t AccessIndex = CInfo.AccessIndex;
970 MDNode *MDN = CInfo.Metadata;
971 // At this stage, it cannot be pointer type.
973
974 uint64_t BTFIndex = AccessIndex;
975 if (CTy->getTag() == dwarf::DW_TAG_structure_type) {
976 DINodeArray Elements = CTy->getElements();
977 uint64_t Offset = getBTFRecordElementOffset(Elements[AccessIndex]);
978 // Find this element's position in the stable offset order without
979 // sorting the whole record for every CO-RE access.
980 BTFIndex = 0;
981 for (unsigned I = 0; I < Elements.size(); ++I) {
982 uint64_t ElementOffset = getBTFRecordElementOffset(Elements[I]);
983 if (ElementOffset < Offset ||
984 (ElementOffset == Offset && I < AccessIndex))
985 ++BTFIndex;
986 }
987 }
988 AccessKey += ":" + std::to_string(BTFIndex);
989
990 PatchImm = GetFieldInfo(InfoKind, CTy, AccessIndex, PatchImm,
991 CInfo.RecordAlignment);
992 }
993
994 // Access key is the
995 // "llvm." + type name + ":" + reloc type + ":" + patched imm + "$" +
996 // access string,
997 // uniquely identifying one relocation.
998 // The prefix "llvm." indicates this is a temporary global, which should
999 // not be emitted to ELF file.
1000 AccessKey = "llvm." + TypeName + ":" + std::to_string(InfoKind) + ":" +
1001 std::to_string(PatchImm) + "$" + AccessKey;
1002
1003 return Base;
1004}
1005
1006BPFAbstractMemberAccess::EnumAccess
1007BPFAbstractMemberAccess::computeEnumAccess(const CallInst *Call,
1008 const DIType *Ty) {
1009 // The argument can be a global or a GEP into a global.
1010 const auto *GV =
1012 assert(GV->hasInitializer());
1013 const auto *DA = cast<ConstantDataArray>(GV->getInitializer());
1014 assert(DA->isString());
1015 StringRef ValueStr = DA->getAsString();
1016 size_t Separator = ValueStr.find(':');
1017 StringRef Enumerator = ValueStr.substr(0, Separator);
1018 StringRef Value = ValueStr.substr(Separator + 1);
1019
1020 const auto *CTy = cast<DICompositeType>(stripQualifiers(Ty));
1021 assert(CTy->getTag() == dwarf::DW_TAG_enumeration_type);
1022 for (auto [Index, Element] : enumerate(CTy->getElements()))
1023 if (cast<DIEnumerator>(Element)->getName() == Enumerator)
1024 return {Index, Value};
1025 return {0, Value};
1026}
1027
1028MDNode *BPFAbstractMemberAccess::computeAccessKey(CallInst *Call,
1029 const CallInfo &CInfo,
1030 std::string &AccessKey) {
1031 DIType *Ty = stripQualifiers(cast<DIType>(CInfo.Metadata), false);
1032 assert(!Ty->getName().empty());
1033
1034 int64_t PatchImm = 1;
1035 size_t AccessIndex = 0;
1036 switch (CInfo.AccessIndex) {
1038 case BTF::TYPE_MATCH:
1039 break;
1040 case BTF::TYPE_SIZE:
1041 // typedef debuginfo type has size 0, get the eventual base type.
1042 PatchImm = stripQualifiers(Ty)->getSizeInBits() / 8;
1043 break;
1045 AccessIndex = computeEnumAccess(Call, Ty).Index;
1046 break;
1047 case BTF::ENUM_VALUE: {
1048 auto [Index, Value] = computeEnumAccess(Call, Ty);
1049 PatchImm = std::stoll(Value.str());
1050 AccessIndex = Index;
1051 break;
1052 }
1053 default:
1054 llvm_unreachable("Unexpected BPF type relocation kind");
1055 }
1056
1057 AccessKey = "llvm." + Ty->getName().str() + ":" +
1058 std::to_string(CInfo.AccessIndex) + std::string(":") +
1059 std::to_string(PatchImm) + std::string("$") +
1060 std::to_string(AccessIndex);
1061
1062 return Ty;
1063}
1064
1065/// Call/Kind is the base preserve_*_access_index() call. Attempts to do
1066/// transformation to a chain of relocable GEPs.
1067bool BPFAbstractMemberAccess::transformGEPChain(CallInst *Call,
1068 CallInfo &CInfo) {
1069 std::string AccessKey;
1070 MDNode *TypeMeta;
1071 Value *Base = nullptr;
1072
1073 if (CInfo.Kind == BPFPreserveFieldInfoAI && CInfo.Metadata) {
1074 TypeMeta = computeAccessKey(Call, CInfo, AccessKey);
1075 } else {
1076 Base = computeBaseAndAccessKey(Call, CInfo, AccessKey, TypeMeta);
1077 if (!Base)
1078 return false;
1079 }
1080
1081 BasicBlock *BB = Call->getParent();
1082 GlobalVariable *GV;
1083 bool IsInt32Ret = Call->getType()->isIntegerTy(32);
1084
1085 if (GEPGlobals.find(AccessKey) == GEPGlobals.end()) {
1086 IntegerType *VarType;
1087 if (IsInt32Ret)
1088 VarType = Type::getInt32Ty(BB->getContext()); // 32bit return value
1089 else
1090 VarType = Type::getInt64Ty(BB->getContext()); // 64bit ptr or enum value
1091
1092 GV = new GlobalVariable(*M, VarType, false, GlobalVariable::ExternalLinkage,
1093 nullptr, AccessKey);
1095 GV->setMetadata(LLVMContext::MD_preserve_access_index, TypeMeta);
1096 GEPGlobals[AccessKey] = GV;
1097 } else {
1098 GV = GEPGlobals[AccessKey];
1099 }
1100
1101 if (CInfo.Kind == BPFPreserveFieldInfoAI) {
1102 // Load the global variable which represents the returned field info.
1103 LoadInst *LDInst;
1104 if (IsInt32Ret)
1105 LDInst = new LoadInst(Type::getInt32Ty(BB->getContext()), GV, "",
1106 Call->getIterator());
1107 else
1108 LDInst = new LoadInst(Type::getInt64Ty(BB->getContext()), GV, "",
1109 Call->getIterator());
1110
1111 Instruction *PassThroughInst =
1113 Call->replaceAllUsesWith(PassThroughInst);
1115 return true;
1116 }
1117
1118 // For any original GEP Call and Base %2 like
1119 // %4 = bitcast %struct.net_device** %dev1 to i64*
1120 // it is transformed to:
1121 // %6 = load llvm.sk_buff:0:50$0:0:0:2:0
1122 // %8 = getelementptr i8, i8* %2, %6
1123 // using %8 instead of %4
1124 // The original Call inst is removed.
1125
1126 // Load the global variable.
1127 auto *LDInst = new LoadInst(Type::getInt64Ty(BB->getContext()), GV, "",
1128 Call->getIterator());
1129
1130 // Generate a GetElementPtr
1131 auto *GEP = GetElementPtrInst::Create(Type::getInt8Ty(BB->getContext()), Base,
1132 LDInst);
1133 GEP->insertBefore(Call->getIterator());
1134
1135 // For the following code,
1136 // Block0:
1137 // ...
1138 // if (...) goto Block1 else ...
1139 // Block1:
1140 // %6 = load llvm.sk_buff:0:50$0:0:0:2:0
1141 // %8 = getelementptr i8, i8* %2, %6
1142 // ...
1143 // goto CommonExit
1144 // Block2:
1145 // ...
1146 // if (...) goto Block3 else ...
1147 // Block3:
1148 // %6 = load llvm.bpf_map:0:40$0:0:0:2:0
1149 // %8 = getelementptr i8, i8* %2, %6
1150 // ...
1151 // goto CommonExit
1152 // CommonExit
1153 // SimplifyCFG may generate:
1154 // Block0:
1155 // ...
1156 // if (...) goto Block_Common else ...
1157 // Block2:
1158 // ...
1159 // if (...) goto Block_Common else ...
1160 // Block_Common:
1161 // PHI = [llvm.sk_buff:0:50$0:0:0:2:0, llvm.bpf_map:0:40$0:0:0:2:0]
1162 // %6 = load PHI
1163 // %8 = getelementptr i8, i8* %2, %6
1164 // ...
1165 // goto CommonExit
1166 // For the above code, we cannot perform proper relocation since
1167 // "load PHI" has two possible relocations.
1168 //
1169 // To prevent above tail merging, we use __builtin_bpf_passthrough()
1170 // where one of its parameters is a seq_num. Since two
1171 // __builtin_bpf_passthrough() funcs will always have different seq_num,
1172 // tail merging cannot happen. The __builtin_bpf_passthrough() will be
1173 // removed in the beginning of Target IR passes.
1174 //
1175 // This approach is also used in other places when global var
1176 // representing a relocation is used.
1177 Instruction *PassThroughInst =
1179 Call->replaceAllUsesWith(PassThroughInst);
1181
1182 return true;
1183}
1184
1185bool BPFAbstractMemberAccess::doTransformation(Function &F) {
1186 bool Transformed = false;
1187
1188 // Collect PreserveDIAccessIndex Intrinsic call chains.
1189 // The call chains will be used to generate the access
1190 // patterns similar to GEP.
1191 collectAICallChains(F);
1192
1193 for (auto &C : BaseAICalls)
1194 Transformed = transformGEPChain(C.first, C.second) || Transformed;
1195
1196 return removePreserveAccessIndexIntrinsic(F) || Transformed;
1197}
1198
1199PreservedAnalyses
1201 return BPFAbstractMemberAccess(TM).run(F) ? PreservedAnalyses::none()
1203}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
uint64_t uint64_t
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.
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
This file contains constants used for implementing Dwarf debug support.
Hexagon Common GEP
Module.h This file contains the declarations for the Module class.
This header defines various interfaces for pass management in LLVM.
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
This file implements a map that provides insertion order iteration.
static StringRef getName(Value *V)
This file contains some templates that are useful if you are working with the STL at all.
BaseType
A given derived pointer can have multiple base pointers through phi/selects.
This file defines the SmallVector class.
#define LLVM_DEBUG(...)
Definition Debug.h:119
The Input class is used to parse a yaml document into in-memory structs and vectors.
uint64_t getZExtValue() const
Get zero extended value.
Definition APInt.h:1560
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
static void removeArrayAccessCall(CallInst *Call)
static uint32_t SeqNum
llvm.bpf.passthrough builtin seq number
Definition BPFCORE.h:66
static void removeStructAccessCall(CallInst *Call)
static void removeUnionAccessCall(CallInst *Call)
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.
Definition BPFCORE.h:61
LLVM Basic Block Representation.
Definition BasicBlock.h:62
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.
Definition Constants.h:87
const APInt & getValue() const
Return the constant as an APInt value reference.
Definition Constants.h:159
This is an important base class in LLVM.
Definition Constant.h:43
DINodeArray getElements() const
DIType * getBaseType() const
LLVM_ABI dwarf::Tag getTag() const
Array subrange.
LLVM_ABI BoundType getCount() const
Base class for types.
bool isBitField() 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.
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.
iterator_range< user_iterator > users()
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:68
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...
Definition Module.h:981
const DataLayout & getDataLayout() const
Get the data layout for the module's target platform.
Definition Module.h:325
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition Analysis.h:115
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
std::string str() const
Get the contents as an std::string.
Definition StringRef.h:222
constexpr StringRef substr(size_t Start, size_t N=npos) const
Return a reference to the substring from [Start, Start + N).
Definition StringRef.h:597
constexpr bool empty() const
Check if the string is empty.
Definition StringRef.h:141
size_t find(char C, size_t From=0) const
Search for the first character C in the string.
Definition StringRef.h:290
const Triple & getTargetTriple() const
ArchType getArch() const
Get the parsed architecture type of this triple.
Definition Triple.h:515
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
Definition Type.cpp:299
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition Type.h:252
LLVM Value Representation.
Definition Value.h:75
Type * getType() const
All values are typed, get the type of this value.
Definition Value.h:257
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition Value.cpp:549
LLVM_ABI const Value * stripPointerCasts() const
Strip off pointer casts, all-zero GEPs and address space casts.
Definition Value.cpp:708
const ParentTy * getParent() const
Definition ilist_node.h:34
self_iterator getIterator()
Definition ilist_node.h:123
CallInst * Call
#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.
InfoKind
Entry kind values for the .amdgpu.info section.
@ FIELD_RSHIFT_U64
Definition BTF.h:287
@ ENUM_VALUE
Definition BTF.h:293
@ FIELD_SIGNEDNESS
Definition BTF.h:285
@ FIELD_BYTE_OFFSET
Definition BTF.h:282
@ FIELD_BYTE_SIZE
Definition BTF.h:283
@ ENUM_VALUE_EXISTENCE
Definition BTF.h:292
@ MAX_FIELD_RELOC_KIND
Definition BTF.h:295
@ TYPE_EXISTENCE
Definition BTF.h:290
@ FIELD_LSHIFT_U64
Definition BTF.h:286
@ TYPE_MATCH
Definition BTF.h:294
@ TYPE_SIZE
Definition BTF.h:291
@ FIELD_EXISTENCE
Definition BTF.h:284
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:83
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > OverloadTys={})
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.
constexpr MCPhysReg SP
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
friend class Instruction
Iterator for Instructions in a `BasicBlock.
Definition BasicBlock.h:73
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
auto enumerate(FirstRange &&First, RestRanges &&...Rest)
Given two or more input ranges, returns a new range whose values are tuples (A, B,...
Definition STLExtras.h:2570
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
Definition InstrProf.h:143
auto dyn_cast_or_null(const Y &Val)
Definition Casting.h:753
uint64_t getBTFRecordElementOffset(const DINode *Element)
Return the bit offset used to order an element of a BTF structure record.
Definition BPFCORE.h:25
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
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...
Definition Casting.h:547
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
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.
Definition Alignment.h:82