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/Value.h"
25#include "llvm/Pass.h"
27
28#define DEBUG_TYPE "bpf-preserve-di-type"
29
30namespace llvm {
32} // namespace llvm
33
34using namespace llvm;
35
36namespace {
37
38static 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().starts_with("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 }
89 DIType *Ty = cast<DIType>(MD);
90 while (auto *DTy = dyn_cast<DIDerivedType>(Ty)) {
91 unsigned Tag = DTy->getTag();
92 if (Tag != dwarf::DW_TAG_const_type && Tag != dwarf::DW_TAG_volatile_type)
93 break;
94 Ty = DTy->getBaseType();
95 }
96
97 if (Reloc == BTF::BTF_TYPE_ID_REMOTE) {
98 if (Ty->getName().empty()) {
99 if (isa<DISubroutineType>(Ty))
101 "SubroutineType not supported for BTF_TYPE_ID_REMOTE reloc");
102 else
103 report_fatal_error("Empty type name for BTF_TYPE_ID_REMOTE reloc");
104 }
105 }
106 MD = Ty;
107
108 BasicBlock *BB = Call->getParent();
109 IntegerType *VarType = Type::getInt64Ty(BB->getContext());
110 std::string GVName =
111 BaseName + std::to_string(Count) + "$" + std::to_string(Reloc);
113 *M, VarType, false, GlobalVariable::ExternalLinkage, nullptr, GVName);
115 GV->setMetadata(LLVMContext::MD_preserve_access_index, MD);
116
117 // Load the global variable which represents the type info.
118 auto *LDInst = new LoadInst(Type::getInt64Ty(BB->getContext()), GV, "",
119 Call->getIterator());
120 Instruction *PassThroughInst =
121 BPFCoreSharedInfo::insertPassThrough(M, BB, LDInst, Call);
122 Call->replaceAllUsesWith(PassThroughInst);
123 Call->eraseFromParent();
124 Count++;
125 }
126
127 return true;
128}
129} // End anonymous namespace
130
133 return BPFPreserveDITypeImpl(F) ? PreservedAnalyses::none()
135}
This file contains the layout of .BTF and .BTF.ext ELF sections.
#define LLVM_DEBUG(...)
Definition: Debug.h:106
This file contains constants used for implementing Dwarf debug support.
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:55
#define I(x, y, z)
Definition: MD5.cpp:58
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:83
Base class for types.
StringRef getName() const
void setMetadata(unsigned KindID, MDNode *Node)
Set a particular kind of metadata attachment.
Definition: Metadata.cpp:1531
void addAttribute(Attribute::AttrKind Kind)
Add attribute to this global.
Class to represent integer types.
Definition: DerivedTypes.h:42
An instruction for reading from memory.
Definition: Instructions.h:176
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:51
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:147
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