LLVM 20.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"
19#include "llvm/IR/Instruction.h"
21#include "llvm/IR/Module.h"
22#include "llvm/IR/PassManager.h"
23#include "llvm/IR/Type.h"
24#include "llvm/IR/User.h"
25#include "llvm/IR/Value.h"
26#include "llvm/Pass.h"
28
29#define DEBUG_TYPE "bpf-preserve-di-type"
30
31namespace llvm {
33} // namespace llvm
34
35using namespace llvm;
36
37namespace {
38
39static bool BPFPreserveDITypeImpl(Function &F) {
40 LLVM_DEBUG(dbgs() << "********** preserve debuginfo type **********\n");
41
42 Module *M = F.getParent();
43
44 // Bail out if no debug info.
45 if (M->debug_compile_units().empty())
46 return false;
47
48 std::vector<CallInst *> PreserveDITypeCalls;
49
50 for (auto &BB : F) {
51 for (auto &I : BB) {
52 auto *Call = dyn_cast<CallInst>(&I);
53 if (!Call)
54 continue;
55
56 const auto *GV = dyn_cast<GlobalValue>(Call->getCalledOperand());
57 if (!GV)
58 continue;
59
60 if (GV->getName().starts_with("llvm.bpf.btf.type.id")) {
61 if (!Call->getMetadata(LLVMContext::MD_preserve_access_index))
63 "Missing metadata for llvm.bpf.btf.type.id intrinsic");
64 PreserveDITypeCalls.push_back(Call);
65 }
66 }
67 }
68
69 if (PreserveDITypeCalls.empty())
70 return false;
71
72 std::string BaseName = "llvm.btf_type_id.";
73 static int Count = 0;
74 for (auto *Call : PreserveDITypeCalls) {
75 const ConstantInt *Flag = dyn_cast<ConstantInt>(Call->getArgOperand(1));
76 assert(Flag);
77 uint64_t FlagValue = Flag->getValue().getZExtValue();
78
80 report_fatal_error("Incorrect flag for llvm.bpf.btf.type.id intrinsic");
81
82 MDNode *MD = Call->getMetadata(LLVMContext::MD_preserve_access_index);
83
84 uint32_t Reloc;
87 } else {
89 }
90 DIType *Ty = cast<DIType>(MD);
91 while (auto *DTy = dyn_cast<DIDerivedType>(Ty)) {
92 unsigned Tag = DTy->getTag();
93 if (Tag != dwarf::DW_TAG_const_type && Tag != dwarf::DW_TAG_volatile_type)
94 break;
95 Ty = DTy->getBaseType();
96 }
97
98 if (Reloc == BTF::BTF_TYPE_ID_REMOTE) {
99 if (Ty->getName().empty()) {
100 if (isa<DISubroutineType>(Ty))
102 "SubroutineType not supported for BTF_TYPE_ID_REMOTE reloc");
103 else
104 report_fatal_error("Empty type name for BTF_TYPE_ID_REMOTE reloc");
105 }
106 }
107 MD = Ty;
108
109 BasicBlock *BB = Call->getParent();
110 IntegerType *VarType = Type::getInt64Ty(BB->getContext());
111 std::string GVName =
112 BaseName + std::to_string(Count) + "$" + std::to_string(Reloc);
114 *M, VarType, false, GlobalVariable::ExternalLinkage, nullptr, GVName);
116 GV->setMetadata(LLVMContext::MD_preserve_access_index, MD);
117
118 // Load the global variable which represents the type info.
119 auto *LDInst = new LoadInst(Type::getInt64Ty(BB->getContext()), GV, "",
120 Call->getIterator());
121 Instruction *PassThroughInst =
122 BPFCoreSharedInfo::insertPassThrough(M, BB, LDInst, Call);
123 Call->replaceAllUsesWith(PassThroughInst);
124 Call->eraseFromParent();
125 Count++;
126 }
127
128 return true;
129}
130} // End anonymous namespace
131
134 return BPFPreserveDITypeImpl(F) ? PreservedAnalyses::none()
136}
This file contains the layout of .BTF and .BTF.ext ELF sections.
#define LLVM_DEBUG(X)
Definition: Debug.h:101
This file contains constants used for implementing Dwarf debug support.
#define F(x, y, z)
Definition: MD5.cpp:55
#define I(x, y, z)
Definition: MD5.cpp:58
Module.h This file contains the declarations for the Module class.
This header defines various interfaces for pass management in LLVM.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:253
static constexpr StringRef TypeIdAttr
The attribute attached to globals representing a type id.
Definition: BPFCORE.h:48
static Instruction * insertPassThrough(Module *M, BasicBlock *BB, Instruction *Input, Instruction *Before)
Insert a bpf passthrough builtin function.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
LLVM Basic Block Representation.
Definition: BasicBlock.h:61
LLVMContext & getContext() const
Get the context in which this basic block lives.
Definition: BasicBlock.cpp:168
This is the shared class of boolean and integer constants.
Definition: Constants.h:81
Base class for types.
StringRef getName() const
void setMetadata(unsigned KindID, MDNode *Node)
Set a particular kind of metadata attachment.
Definition: Metadata.cpp:1494
void addAttribute(Attribute::AttrKind Kind)
Add attribute to this global.
Class to represent integer types.
Definition: DerivedTypes.h:40
An instruction for reading from memory.
Definition: Instructions.h:174
Metadata node.
Definition: Metadata.h:1069
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
A set of analyses that are preserved following a run of a transformation pass.
Definition: Analysis.h:111
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition: Analysis.h:114
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: Analysis.h:117
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:134
static IntegerType * getInt64Ty(LLVMContext &C)
@ BTF_TYPE_ID_REMOTE
Definition: BTF.h:289
@ BTF_TYPE_ID_LOCAL
Definition: BTF.h:288
Flag
These should be considered private to the implementation of the MCInstrDesc class.
Definition: MCInstrDesc.h:148
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition: Error.cpp:167