LLVM 23.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
30using namespace llvm;
31
32namespace {
33
34static bool BPFPreserveDITypeImpl(Function &F) {
35 LLVM_DEBUG(dbgs() << "********** preserve debuginfo type **********\n");
36
37 Module *M = F.getParent();
38
39 // Bail out if no debug info.
40 if (M->debug_compile_units().empty())
41 return false;
42
43 std::vector<CallInst *> PreserveDITypeCalls;
44
45 for (auto &BB : F) {
46 for (auto &I : BB) {
47 auto *Call = dyn_cast<CallInst>(&I);
48 if (!Call)
49 continue;
50
51 const auto *GV = dyn_cast<GlobalValue>(Call->getCalledOperand());
52 if (!GV)
53 continue;
54
55 if (GV->getName().starts_with("llvm.bpf.btf.type.id")) {
56 if (!Call->getMetadata(LLVMContext::MD_preserve_access_index))
58 "Missing metadata for llvm.bpf.btf.type.id intrinsic");
59 PreserveDITypeCalls.push_back(Call);
60 }
61 }
62 }
63
64 if (PreserveDITypeCalls.empty())
65 return false;
66
67 std::string BaseName = "llvm.btf_type_id.";
68 static int Count = 0;
69 for (auto *Call : PreserveDITypeCalls) {
70 const ConstantInt *Flag = dyn_cast<ConstantInt>(Call->getArgOperand(1));
71 assert(Flag);
72 uint64_t FlagValue = Flag->getValue().getZExtValue();
73
75 report_fatal_error("Incorrect flag for llvm.bpf.btf.type.id intrinsic");
76
77 MDNode *MD = Call->getMetadata(LLVMContext::MD_preserve_access_index);
78
82 } else {
84 }
85 DIType *Ty = cast<DIType>(MD);
86 while (auto *DTy = dyn_cast<DIDerivedType>(Ty)) {
87 unsigned Tag = DTy->getTag();
88 if (Tag != dwarf::DW_TAG_const_type && Tag != dwarf::DW_TAG_volatile_type)
89 break;
90 Ty = DTy->getBaseType();
91 }
92
93 MD = Ty;
94
95 BasicBlock *BB = Call->getParent();
96 IntegerType *VarType = Type::getInt64Ty(BB->getContext());
97 std::string GVName =
98 BaseName + std::to_string(Count) + "$" + std::to_string(Reloc);
100 *M, VarType, false, GlobalVariable::ExternalLinkage, nullptr, GVName);
102 GV->setMetadata(LLVMContext::MD_preserve_access_index, MD);
103
104 // Load the global variable which represents the type info.
105 auto *LDInst = new LoadInst(Type::getInt64Ty(BB->getContext()), GV, "",
106 Call->getIterator());
107 Instruction *PassThroughInst =
109 Call->replaceAllUsesWith(PassThroughInst);
110 Call->eraseFromParent();
111 Count++;
112 }
113
114 return true;
115}
116} // End anonymous namespace
117
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file contains the layout of .BTF and .BTF.ext ELF sections.
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:54
#define I(x, y, z)
Definition MD5.cpp:57
#define LLVM_DEBUG(...)
Definition Debug.h:114
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:62
LLVM_ABI LLVMContext & getContext() const
Get the context in which this basic block lives.
This is the shared class of boolean and integer constants.
Definition Constants.h:87
Base class for types.
LLVM_ABI void setMetadata(unsigned KindID, MDNode *Node)
Set a particular kind of metadata attachment.
@ ExternalLinkage
Externally visible function.
Definition GlobalValue.h:53
void addAttribute(Attribute::AttrKind Kind)
Add attribute to this global.
Class to represent integer types.
An instruction for reading from memory.
Metadata node.
Definition Metadata.h:1080
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:67
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
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
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
Definition Type.cpp:297
CallInst * Call
@ BTF_TYPE_ID_REMOTE
Definition BTF.h:289
@ BTF_TYPE_ID_LOCAL
Definition BTF.h:288
This is an optimization pass for GlobalISel generic memory operations.
Definition Types.h:26
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:207
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
Definition Error.cpp:163
FunctionAddr VTableAddr Count
Definition InstrProf.h:139
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.