LLVM  14.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"
16 #include "llvm/IR/GlobalVariable.h"
17 #include "llvm/IR/Instruction.h"
18 #include "llvm/IR/Instructions.h"
19 #include "llvm/IR/Module.h"
20 #include "llvm/IR/PassManager.h"
21 #include "llvm/IR/Type.h"
22 #include "llvm/IR/User.h"
23 #include "llvm/IR/Value.h"
24 #include "llvm/Pass.h"
26 
27 #define DEBUG_TYPE "bpf-preserve-di-type"
28 
29 namespace llvm {
31 } // namespace llvm
32 
33 using namespace llvm;
34 
35 namespace {
36 
37 static bool BPFPreserveDITypeImpl(Function &F) {
38  LLVM_DEBUG(dbgs() << "********** preserve debuginfo type **********\n");
39 
40  Module *M = F.getParent();
41 
42  // Bail out if no debug info.
43  if (M->debug_compile_units().empty())
44  return false;
45 
46  std::vector<CallInst *> PreserveDITypeCalls;
47 
48  for (auto &BB : F) {
49  for (auto &I : BB) {
50  auto *Call = dyn_cast<CallInst>(&I);
51  if (!Call)
52  continue;
53 
54  const auto *GV = dyn_cast<GlobalValue>(Call->getCalledOperand());
55  if (!GV)
56  continue;
57 
58  if (GV->getName().startswith("llvm.bpf.btf.type.id")) {
59  if (!Call->getMetadata(LLVMContext::MD_preserve_access_index))
61  "Missing metadata for llvm.bpf.btf.type.id intrinsic");
62  PreserveDITypeCalls.push_back(Call);
63  }
64  }
65  }
66 
67  if (PreserveDITypeCalls.empty())
68  return false;
69 
70  std::string BaseName = "llvm.btf_type_id.";
71  static int Count = 0;
72  for (auto Call : PreserveDITypeCalls) {
73  const ConstantInt *Flag = dyn_cast<ConstantInt>(Call->getArgOperand(1));
74  assert(Flag);
75  uint64_t FlagValue = Flag->getValue().getZExtValue();
76 
78  report_fatal_error("Incorrect flag for llvm.bpf.btf.type.id intrinsic");
79 
80  MDNode *MD = Call->getMetadata(LLVMContext::MD_preserve_access_index);
81 
82  uint32_t Reloc;
85  } else {
87  DIType *Ty = cast<DIType>(MD);
88  while (auto *DTy = dyn_cast<DIDerivedType>(Ty)) {
89  unsigned Tag = DTy->getTag();
90  if (Tag != dwarf::DW_TAG_const_type &&
91  Tag != dwarf::DW_TAG_volatile_type)
92  break;
93  Ty = DTy->getBaseType();
94  }
95 
96  if (Ty->getName().empty())
97  report_fatal_error("Empty type name for BTF_TYPE_ID_REMOTE reloc");
98  MD = Ty;
99  }
100 
101  BasicBlock *BB = Call->getParent();
102  IntegerType *VarType = Type::getInt64Ty(BB->getContext());
103  std::string GVName = BaseName + std::to_string(Count) + "$" +
104  std::to_string(Reloc);
105  GlobalVariable *GV = new GlobalVariable(
106  *M, VarType, false, GlobalVariable::ExternalLinkage, NULL, GVName);
108  GV->setMetadata(LLVMContext::MD_preserve_access_index, MD);
109 
110  // Load the global variable which represents the type info.
111  auto *LDInst =
112  new LoadInst(Type::getInt64Ty(BB->getContext()), GV, "", Call);
113  Instruction *PassThroughInst =
114  BPFCoreSharedInfo::insertPassThrough(M, BB, LDInst, Call);
115  Call->replaceAllUsesWith(PassThroughInst);
116  Call->eraseFromParent();
117  Count++;
118  }
119 
120  return true;
121 }
122 
123 class BPFPreserveDIType final : public FunctionPass {
124  bool runOnFunction(Function &F) override;
125 
126 public:
127  static char ID;
128  BPFPreserveDIType() : FunctionPass(ID) {}
129 };
130 } // End anonymous namespace
131 
132 char BPFPreserveDIType::ID = 0;
133 INITIALIZE_PASS(BPFPreserveDIType, DEBUG_TYPE, "BPF Preserve Debuginfo Type",
134  false, false)
135 
137  return new BPFPreserveDIType();
138 }
139 
141  return BPFPreserveDITypeImpl(F);
142 }
143 
146  return BPFPreserveDITypeImpl(F) ? PreservedAnalyses::none()
148 }
llvm::PreservedAnalyses
A set of analyses that are preserved following a run of a transformation pass.
Definition: PassManager.h:155
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AllocatorList.h:23
llvm::DIType
Base class for types.
Definition: DebugInfoMetadata.h:665
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::StringRef::empty
LLVM_NODISCARD bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:152
DebugInfoMetadata.h
llvm::BPFPreserveDITypePass::run
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
Definition: BPFPreserveDIType.cpp:144
llvm::Function
Definition: Function.h:62
Pass.h
llvm::BPFCoreSharedInfo::BTF_TYPE_ID_LOCAL
@ BTF_TYPE_ID_LOCAL
Definition: BPFCORE.h:29
llvm::GlobalVariable
Definition: GlobalVariable.h:40
llvm::PreservedAnalyses::none
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition: PassManager.h:158
llvm::createBPFPreserveDIType
FunctionPass * createBPFPreserveDIType()
Module.h
BPF.h
llvm::dwarf::Tag
Tag
Definition: Dwarf.h:104
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
F
#define F(x, y, z)
Definition: MD5.cpp:56
llvm::BasicBlock
LLVM Basic Block Representation.
Definition: BasicBlock.h:58
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:711
llvm::IntegerType
Class to represent integer types.
Definition: DerivedTypes.h:40
llvm::Instruction
Definition: Instruction.h:45
llvm::GlobalVariable::addAttribute
void addAttribute(Attribute::AttrKind Kind)
Add attribute to this global.
Definition: GlobalVariable.h:188
llvm::MCID::Flag
Flag
These should be considered private to the implementation of the MCInstrDesc class.
Definition: MCInstrDesc.h:146
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::MCID::Call
@ Call
Definition: MCInstrDesc.h:153
Type.h
llvm::BPFCoreSharedInfo::BTF_TYPE_ID_REMOTE
@ BTF_TYPE_ID_REMOTE
Definition: BPFCORE.h:30
DEBUG_TYPE
#define DEBUG_TYPE
Definition: BPFPreserveDIType.cpp:27
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:100
I
#define I(x, y, z)
Definition: MD5.cpp:59
llvm::BPFCoreSharedInfo::MAX_BTF_TYPE_ID_FLAG
@ MAX_BTF_TYPE_ID_FLAG
Definition: BPFCORE.h:43
INITIALIZE_PASS
INITIALIZE_PASS(BPFPreserveDIType, DEBUG_TYPE, "BPF Preserve Debuginfo Type", false, false) FunctionPass *llvm
Definition: BPFPreserveDIType.cpp:133
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:63
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:67
llvm::MDNode
Metadata node.
Definition: Metadata.h:906
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:57
uint32_t
llvm::LoadInst
An instruction for reading from memory.
Definition: Instructions.h:175
runOnFunction
static bool runOnFunction(Function &F, bool PostInlining)
Definition: EntryExitInstrumenter.cpp:69
llvm::Type::getInt64Ty
static IntegerType * getInt64Ty(LLVMContext &C)
Definition: Type.cpp:242
llvm::PreservedAnalyses::all
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: PassManager.h:161
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:1234
Instructions.h
User.h
llvm::to_string
std::string to_string(const T &Value)
Definition: ScopedPrinter.h:63
llvm::AnalysisManager
A container for analyses that lazily runs them and caches their results.
Definition: InstructionSimplify.h:44
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:298
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:40
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:38