LLVM 22.0.0git
BPFAsmPrinter.cpp
Go to the documentation of this file.
1//===-- BPFAsmPrinter.cpp - BPF LLVM assembly writer ----------------------===//
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// This file contains a printer that converts from our internal representation
10// of machine-dependent LLVM code to the BPF assembly language.
11//
12//===----------------------------------------------------------------------===//
13
14#include "BPFAsmPrinter.h"
15#include "BPF.h"
16#include "BPFInstrInfo.h"
17#include "BPFMCInstLower.h"
18#include "BTFDebug.h"
28#include "llvm/IR/Module.h"
29#include "llvm/MC/MCAsmInfo.h"
30#include "llvm/MC/MCExpr.h"
31#include "llvm/MC/MCInst.h"
32#include "llvm/MC/MCStreamer.h"
33#include "llvm/MC/MCSymbol.h"
34#include "llvm/MC/MCSymbolELF.h"
39using namespace llvm;
40
41#define DEBUG_TYPE "asm-printer"
42
45
46 // Only emit BTF when debuginfo available.
47 if (MAI->doesSupportDebugInformation() && !M.debug_compile_units().empty()) {
48 BTF = new BTFDebug(this);
49 Handlers.push_back(std::unique_ptr<BTFDebug>(BTF));
50 }
51
52 return false;
53}
54
55const BPFTargetMachine &BPFAsmPrinter::getBTM() const {
56 return static_cast<const BPFTargetMachine &>(TM);
57}
58
60 // Remove unused globals which are previously used for jump table.
61 const BPFSubtarget *Subtarget = getBTM().getSubtargetImpl();
62 if (Subtarget->hasGotox()) {
63 std::vector<GlobalVariable *> Targets;
64 for (GlobalVariable &Global : M.globals()) {
65 if (Global.getLinkage() != GlobalValue::PrivateLinkage)
66 continue;
67 if (!Global.isConstant() || !Global.hasInitializer())
68 continue;
69
70 Constant *CV = dyn_cast<Constant>(Global.getInitializer());
71 if (!CV)
72 continue;
74 if (!CA)
75 continue;
76
77 for (unsigned i = 1, e = CA->getNumOperands(); i != e; ++i) {
79 continue;
80 }
81 Targets.push_back(&Global);
82 }
83
84 for (GlobalVariable *GV : Targets) {
85 GV->replaceAllUsesWith(PoisonValue::get(GV->getType()));
86 GV->dropAllReferences();
87 GV->eraseFromParent();
88 }
89 }
90
92}
93
95 raw_ostream &O) {
96 const MachineOperand &MO = MI->getOperand(OpNum);
97
98 switch (MO.getType()) {
101 break;
102
104 O << MO.getImm();
105 break;
106
108 O << *MO.getMBB()->getSymbol();
109 break;
110
112 O << *getSymbol(MO.getGlobal());
113 break;
114
117 O << BA->getName();
118 break;
119 }
120
123 break;
124
127 default:
128 llvm_unreachable("<unknown operand type>");
129 }
130}
131
133 const char *ExtraCode, raw_ostream &O) {
134 if (ExtraCode && ExtraCode[0])
135 return AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, O);
136
137 printOperand(MI, OpNo, O);
138 return false;
139}
140
142 unsigned OpNum, const char *ExtraCode,
143 raw_ostream &O) {
144 assert(OpNum + 1 < MI->getNumOperands() && "Insufficient operands");
145 const MachineOperand &BaseMO = MI->getOperand(OpNum);
146 const MachineOperand &OffsetMO = MI->getOperand(OpNum + 1);
147 assert(BaseMO.isReg() && "Unexpected base pointer for inline asm memory operand.");
148 assert(OffsetMO.isImm() && "Unexpected offset for inline asm memory operand.");
149 int Offset = OffsetMO.getImm();
150
151 if (ExtraCode)
152 return true; // Unknown modifier.
153
154 if (Offset < 0)
155 O << "(" << BPFInstPrinter::getRegisterName(BaseMO.getReg()) << " - " << -Offset << ")";
156 else
157 O << "(" << BPFInstPrinter::getRegisterName(BaseMO.getReg()) << " + " << Offset << ")";
158
159 return false;
160}
161
163 BPF_MC::verifyInstructionPredicates(MI->getOpcode(),
164 getSubtargetInfo().getFeatureBits());
165
166 MCInst TmpInst;
167
168 if (!BTF || !BTF->InstLower(MI, TmpInst)) {
169 BPFMCInstLower MCInstLowering(OutContext, *this);
170 MCInstLowering.Lower(MI, TmpInst);
171 }
172 EmitToStreamer(*OutStreamer, TmpInst);
173}
174
176 SmallString<60> Name;
178 << "BPF.JT." << MF->getFunctionNumber() << '.' << JTI;
179 MCSymbol *S = OutContext.getOrCreateSymbol(Name);
180 if (auto *ES = static_cast<MCSymbolELF *>(S)) {
181 ES->setBinding(ELF::STB_GLOBAL);
182 ES->setType(ELF::STT_OBJECT);
183 }
184 return S;
185}
186
188 const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
189 if (!MJTI)
190 return;
191
192 const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
193 if (JT.empty())
194 return;
195
197 const Function &F = MF->getFunction();
198 MCSection *JTS = TLOF.getSectionForJumpTable(F, TM);
200 unsigned EntrySize = MJTI->getEntrySize(getDataLayout());
201 OutStreamer->switchSection(JTS);
202 for (unsigned JTI = 0; JTI < JT.size(); JTI++) {
203 ArrayRef<MachineBasicBlock *> JTBBs = JT[JTI].MBBs;
204 if (JTBBs.empty())
205 continue;
206
207 MCSymbol *JTStart = getJTPublicSymbol(JTI);
208 OutStreamer->emitLabel(JTStart);
209 for (const MachineBasicBlock *MBB : JTBBs) {
210 const MCExpr *LHS = MCSymbolRefExpr::create(MBB->getSymbol(), OutContext);
211 OutStreamer->emitValue(LHS, EntrySize);
212 }
213 const MCExpr *JTSize =
214 MCConstantExpr::create(JTBBs.size() * EntrySize, OutContext);
215 OutStreamer->emitELFSize(JTStart, JTSize);
216 }
217}
218
219char BPFAsmPrinter::ID = 0;
220
221INITIALIZE_PASS(BPFAsmPrinter, "bpf-asm-printer", "BPF Assembly Printer", false,
222 false)
223
224// Force static initialization.
226LLVMInitializeBPFAsmPrinter() {
230}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock & MBB
This file contains support for writing BTF debug info.
#define LLVM_ABI
Definition Compiler.h:213
#define LLVM_EXTERNAL_VISIBILITY
Definition Compiler.h:132
IRTranslator LLVM IR MI
Module.h This file contains the declarations for the Module class.
#define F(x, y, z)
Definition MD5.cpp:55
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition PassSupport.h:56
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
This file describes how to lower LLVM code to machine code.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:41
size_t size() const
size - Get the array size.
Definition ArrayRef.h:147
bool empty() const
empty - Check if the array is empty.
Definition ArrayRef.h:142
const TargetLoweringObjectFile & getObjFileLowering() const
Return information about object file lowering.
MCSymbol * getSymbol(const GlobalValue *GV) const
void EmitToStreamer(MCStreamer &S, const MCInst &Inst)
TargetMachine & TM
Target machine description.
Definition AsmPrinter.h:93
const MCAsmInfo * MAI
Target Asm Printer information.
Definition AsmPrinter.h:96
SmallVector< std::unique_ptr< AsmPrinterHandler >, 2 > Handlers
Definition AsmPrinter.h:245
MachineFunction * MF
The current machine function.
Definition AsmPrinter.h:108
bool doInitialization(Module &M) override
Set up the AsmPrinter when we are working on a new module.
MCContext & OutContext
This is the context for the output file that we are streaming.
Definition AsmPrinter.h:100
bool doFinalization(Module &M) override
Shut down the asmprinter.
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
Definition AsmPrinter.h:105
MCSymbol * GetBlockAddressSymbol(const BlockAddress *BA) const
Return the MCSymbol used to satisfy BlockAddress uses of the specified basic block.
const DataLayout & getDataLayout() const
Return information about data layout.
MCSymbol * GetExternalSymbolSymbol(const Twine &Sym) const
Return the MCSymbol for the specified ExternalSymbol.
const MCSubtargetInfo & getSubtargetInfo() const
Return information about subtarget.
virtual bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &OS)
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant.
MCSymbol * getJTPublicSymbol(unsigned JTI)
void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O)
bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum, const char *ExtraCode, raw_ostream &O) override
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant as...
bool doFinalization(Module &M) override
Shut down the asmprinter.
bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo, const char *ExtraCode, raw_ostream &O) override
Print the specified operand of MI, an INLINEASM instruction, using the specified assembler variant.
bool doInitialization(Module &M) override
Set up the AsmPrinter when we are working on a new module.
virtual void emitJumpTableInfo() override
Print assembly representations of the jump tables used by the current function to the current output ...
void emitInstruction(const MachineInstr *MI) override
Targets should implement this to emit instructions.
static const char * getRegisterName(MCRegister Reg)
void Lower(const MachineInstr *MI, MCInst &OutMI) const
bool hasGotox() const
Collect and emit BTF information.
Definition BTFDebug.h:289
ConstantArray - Constant Array Declarations.
Definition Constants.h:433
This is an important base class in LLVM.
Definition Constant.h:43
@ PrivateLinkage
Like Internal, but omit from symbol table.
Definition GlobalValue.h:61
static LLVM_ABI const MCConstantExpr * create(int64_t Value, MCContext &Ctx, bool PrintInHex=false, unsigned SizeInBytes=0)
Definition MCExpr.cpp:212
Base class for the full range of assembler expressions which are needed for parsing.
Definition MCExpr.h:34
Instances of this class represent a single low-level machine instruction.
Definition MCInst.h:188
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Definition MCSection.h:521
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx, SMLoc Loc=SMLoc())
Definition MCExpr.h:214
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition MCSymbol.h:42
StringRef getName() const
getName - Get the symbol name.
Definition MCSymbol.h:188
LLVM_ABI MCSymbol * getSymbol() const
Return the MCSymbol for this basic block.
Representation of each machine instruction.
LLVM_ABI unsigned getEntrySize(const DataLayout &TD) const
getEntrySize - Return the size of each entry in the jump table.
@ EK_BlockAddress
EK_BlockAddress - Each entry is a plain address of block, e.g.: .word LBB123.
const std::vector< MachineJumpTableEntry > & getJumpTables() const
MachineOperand class - Representation of each machine instruction operand.
const GlobalValue * getGlobal() const
int64_t getImm() const
bool isReg() const
isReg - Tests if this is a MO_Register operand.
MachineBasicBlock * getMBB() const
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
const BlockAddress * getBlockAddress() const
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
const char * getSymbolName() const
Register getReg() const
getReg - Returns the register number.
@ MO_Immediate
Immediate operand.
@ MO_ConstantPoolIndex
Address of indexed Constant in Constant Pool.
@ MO_GlobalAddress
Address of a global value.
@ MO_BlockAddress
Address of a basic block.
@ MO_MachineBasicBlock
MachineBasicBlock reference.
@ MO_Register
Register operand.
@ MO_ExternalSymbol
Name of external global symbol.
@ MO_JumpTableIndex
Address of indexed Jump Table for switch.
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:67
static LLVM_ABI PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition SmallString.h:26
virtual MCSection * getSectionForJumpTable(const Function &F, const TargetMachine &TM) const
Value * getOperand(unsigned i) const
Definition User.h:232
unsigned getNumOperands() const
Definition User.h:254
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
A raw_ostream that writes to an SmallVector or SmallString.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ STT_OBJECT
Definition ELF.h:1412
@ STB_GLOBAL
Definition ELF.h:1400
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:477
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:649
Target & getTheBPFleTarget()
Target & getTheBPFbeTarget()
Target & getTheBPFTarget()
@ Global
Append to llvm.global_dtors.
RegisterAsmPrinter - Helper template for registering a target specific assembly printer,...