LLVM  16.0.0git
BPFPreserveDIType.cpp
Go to the documentation of this file.
1 //===----------- BPFPreserveDIType.cpp - Preserve DebugInfo Types ---------===//
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 // Preserve Debuginfo types encoded in __builtin_btf_type_id() metadata.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "BPF.h"
14 #include "BPFCORE.h"
17 #include "llvm/IR/GlobalVariable.h"
18 #include "llvm/IR/Instruction.h"
19 #include "llvm/IR/Instructions.h"
20 #include "llvm/IR/Module.h"
21 #include "llvm/IR/PassManager.h"
22 #include "llvm/IR/Type.h"
23 #include "llvm/IR/User.h"
24 #include "llvm/IR/Value.h"
25 #include "llvm/Pass.h"
27 
28 #define DEBUG_TYPE "bpf-preserve-di-type"
29 
30 namespace llvm {
32 } // namespace llvm
33 
34 using namespace llvm;
35 
36 namespace {
37 
38 static bool BPFPreserveDITypeImpl(Function &F) {
39  LLVM_DEBUG(dbgs() << "********** preserve debuginfo type **********\n");
40 
41  Module *M = F.getParent();
42 
43  // Bail out if no debug info.
44  if (M->debug_compile_units().empty())
45  return false;
46 
47  std::vector<CallInst *> PreserveDITypeCalls;
48 
49  for (auto &BB : F) {
50  for (auto &I : BB) {
51  auto *Call = dyn_cast<CallInst>(&I);
52  if (!Call)
53  continue;
54 
55  const auto *GV = dyn_cast<GlobalValue>(Call->getCalledOperand());
56  if (!GV)
57  continue;
58 
59  if (GV->getName().startswith("llvm.bpf.btf.type.id")) {
60  if (!Call->getMetadata(LLVMContext::MD_preserve_access_index))
62  "Missing metadata for llvm.bpf.btf.type.id intrinsic");
63  PreserveDITypeCalls.push_back(Call);
64  }
65  }
66  }
67 
68  if (PreserveDITypeCalls.empty())
69  return false;
70 
71  std::string BaseName = "llvm.btf_type_id.";
72  static int Count = 0;
73  for (auto *Call : PreserveDITypeCalls) {
74  const ConstantInt *Flag = dyn_cast<ConstantInt>(Call->getArgOperand(1));
75  assert(Flag);
76  uint64_t FlagValue = Flag->getValue().getZExtValue();
77 
79  report_fatal_error("Incorrect flag for llvm.bpf.btf.type.id intrinsic");
80 
81  MDNode *MD = Call->getMetadata(LLVMContext::MD_preserve_access_index);
82 
83  uint32_t Reloc;
86  } else {
88  DIType *Ty = cast<DIType>(MD);
89  while (auto *DTy = dyn_cast<DIDerivedType>(Ty)) {
90  unsigned Tag = DTy->getTag();
91  if (Tag != dwarf::DW_TAG_const_type &&
92  Tag != dwarf::DW_TAG_volatile_type)
93  break;
94  Ty = DTy->getBaseType();
95  }
96 
97  if (Ty->getName().empty()) {
98  if (isa<DISubroutineType>(Ty))
100  "SubroutineType not supported for BTF_TYPE_ID_REMOTE reloc");
101  else
102  report_fatal_error("Empty type name for BTF_TYPE_ID_REMOTE reloc");
103  }
104  MD = Ty;
105  }
106 
107  BasicBlock *BB = Call->getParent();
108  IntegerType *VarType = Type::getInt64Ty(BB->getContext());
109  std::string GVName =
110  BaseName + std::to_string(Count) + "$" + std::to_string(Reloc);
111  GlobalVariable *GV = new GlobalVariable(
112  *M, VarType, false, GlobalVariable::ExternalLinkage, nullptr, GVName);
114  GV->setMetadata(LLVMContext::MD_preserve_access_index, MD);
115 
116  // Load the global variable which represents the type info.
117  auto *LDInst =
118  new LoadInst(Type::getInt64Ty(BB->getContext()), GV, "", Call);
119  Instruction *PassThroughInst =
120  BPFCoreSharedInfo::insertPassThrough(M, BB, LDInst, Call);
121  Call->replaceAllUsesWith(PassThroughInst);
122  Call->eraseFromParent();
123  Count++;
124  }
125 
126  return true;
127 }
128 
129 class BPFPreserveDIType final : public FunctionPass {
130  bool runOnFunction(Function &F) override;
131 
132 public:
133  static char ID;
134  BPFPreserveDIType() : FunctionPass(ID) {}
135 };
136 } // End anonymous namespace
137 
138 char BPFPreserveDIType::ID = 0;
139 INITIALIZE_PASS(BPFPreserveDIType, DEBUG_TYPE, "BPF Preserve Debuginfo Type",
140  false, false)
141 
143  return new BPFPreserveDIType();
144 }
145 
147  return BPFPreserveDITypeImpl(F);
148 }
149 
152  return BPFPreserveDITypeImpl(F) ? PreservedAnalyses::none()
154 }
llvm::PreservedAnalyses
A set of analyses that are preserved following a run of a transformation pass.
Definition: PassManager.h:152
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
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
DebugInfoMetadata.h
llvm::BPFPreserveDITypePass::run
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Definition: BPFPreserveDIType.cpp:150
llvm::Function
Definition: Function.h:60
Pass.h
llvm::BPFCoreSharedInfo::BTF_TYPE_ID_LOCAL
@ BTF_TYPE_ID_LOCAL
Definition: BPFCORE.h:29
llvm::GlobalVariable
Definition: GlobalVariable.h:39
llvm::PreservedAnalyses::none
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition: PassManager.h:155
llvm::createBPFPreserveDIType
FunctionPass * createBPFPreserveDIType()
Module.h
BPF.h
llvm::dwarf::Tag
Tag
Definition: Dwarf.h:105
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
F
#define F(x, y, z)
Definition: MD5.cpp:55
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
Instruction.h
llvm::ConstantInt
This is the shared class of boolean and integer constants.
Definition: Constants.h:79
llvm::DIType::getName
StringRef getName() const
Definition: DebugInfoMetadata.h:704
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:145
llvm::MCID::Call
@ Call
Definition: MCInstrDesc.h:155
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
Type.h
llvm::BPFCoreSharedInfo::BTF_TYPE_ID_REMOTE
@ BTF_TYPE_ID_REMOTE
Definition: BPFCORE.h:30
llvm::StringRef::empty
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:134
DEBUG_TYPE
#define DEBUG_TYPE
Definition: BPFPreserveDIType.cpp:28
uint64_t
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::BPFCoreSharedInfo::MAX_BTF_TYPE_ID_FLAG
@ MAX_BTF_TYPE_ID_FLAG
Definition: BPFCORE.h:44
INITIALIZE_PASS
INITIALIZE_PASS(BPFPreserveDIType, DEBUG_TYPE, "BPF Preserve Debuginfo Type", false, false) FunctionPass *llvm
Definition: BPFPreserveDIType.cpp:139
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::BPFCoreSharedInfo::TypeIdAttr
static constexpr StringRef TypeIdAttr
The attribute attached to globals representing a type id.
Definition: BPFCORE.h:65
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:944
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
Dwarf.h
uint32_t
llvm::LoadInst
An instruction for reading from memory.
Definition: Instructions.h:174
runOnFunction
static bool runOnFunction(Function &F, bool PostInlining)
Definition: EntryExitInstrumenter.cpp:69
llvm::Type::getInt64Ty
static IntegerType * getInt64Ty(LLVMContext &C)
Definition: Type.cpp:240
llvm::PreservedAnalyses::all
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: PassManager.h:158
GlobalVariable.h
BPFCORE.h
PassManager.h
llvm::GlobalValue::ExternalLinkage
@ ExternalLinkage
Externally visible function.
Definition: GlobalValue.h:48
llvm::GlobalObject::setMetadata
void setMetadata(unsigned KindID, MDNode *Node)
Set a particular kind of metadata attachment.
Definition: Metadata.cpp:1326
Instructions.h
User.h
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
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:308
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
BasicBlockUtils.h
Value.h
llvm::BPFCoreSharedInfo::BTF_TYPE_ID_LOCAL_RELOC
@ BTF_TYPE_ID_LOCAL_RELOC
Definition: BPFCORE.h:41
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:38