1111//
1212// ===----------------------------------------------------------------------===//
1313
14+ #include " BPFAsmPrinter.h"
1415#include " BPF.h"
1516#include " BPFInstrInfo.h"
1617#include " BPFMCInstLower.h"
1718#include " BTFDebug.h"
1819#include " MCTargetDesc/BPFInstPrinter.h"
1920#include " TargetInfo/BPFTargetInfo.h"
21+ #include " llvm/BinaryFormat/ELF.h"
2022#include " llvm/CodeGen/AsmPrinter.h"
2123#include " llvm/CodeGen/MachineConstantPool.h"
2224#include " llvm/CodeGen/MachineInstr.h"
25+ #include " llvm/CodeGen/MachineJumpTableInfo.h"
2326#include " llvm/CodeGen/MachineModuleInfo.h"
27+ #include " llvm/CodeGen/TargetLowering.h"
2428#include " llvm/IR/Module.h"
2529#include " llvm/MC/MCAsmInfo.h"
30+ #include " llvm/MC/MCExpr.h"
2631#include " llvm/MC/MCInst.h"
2732#include " llvm/MC/MCStreamer.h"
2833#include " llvm/MC/MCSymbol.h"
34+ #include " llvm/MC/MCSymbolELF.h"
2935#include " llvm/MC/TargetRegistry.h"
3036#include " llvm/Support/Compiler.h"
3137#include " llvm/Support/raw_ostream.h"
38+ #include " llvm/Target/TargetLoweringObjectFile.h"
3239using namespace llvm ;
3340
3441#define DEBUG_TYPE " asm-printer"
3542
36- namespace {
37- class BPFAsmPrinter : public AsmPrinter {
38- public:
39- explicit BPFAsmPrinter (TargetMachine &TM,
40- std::unique_ptr<MCStreamer> Streamer)
41- : AsmPrinter(TM, std::move(Streamer), ID), BTF(nullptr ) {}
42-
43- StringRef getPassName () const override { return " BPF Assembly Printer" ; }
44- bool doInitialization (Module &M) override ;
45- void printOperand (const MachineInstr *MI, int OpNum, raw_ostream &O);
46- bool PrintAsmOperand (const MachineInstr *MI, unsigned OpNo,
47- const char *ExtraCode, raw_ostream &O) override ;
48- bool PrintAsmMemoryOperand (const MachineInstr *MI, unsigned OpNum,
49- const char *ExtraCode, raw_ostream &O) override ;
50-
51- void emitInstruction (const MachineInstr *MI) override ;
52-
53- static char ID;
54-
55- private:
56- BTFDebug *BTF;
57- };
58- } // namespace
59-
6043bool BPFAsmPrinter::doInitialization (Module &M) {
6144 AsmPrinter::doInitialization (M);
6245
@@ -69,6 +52,45 @@ bool BPFAsmPrinter::doInitialization(Module &M) {
6952 return false ;
7053}
7154
55+ const BPFTargetMachine &BPFAsmPrinter::getBTM () const {
56+ return static_cast <const BPFTargetMachine &>(TM);
57+ }
58+
59+ bool BPFAsmPrinter::doFinalization (Module &M) {
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 ;
73+ ConstantArray *CA = dyn_cast<ConstantArray>(CV);
74+ if (!CA)
75+ continue ;
76+
77+ for (unsigned i = 1 , e = CA->getNumOperands (); i != e; ++i) {
78+ if (!dyn_cast<BlockAddress>(CA->getOperand (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+
91+ return AsmPrinter::doFinalization (M);
92+ }
93+
7294void BPFAsmPrinter::printOperand (const MachineInstr *MI, int OpNum,
7395 raw_ostream &O) {
7496 const MachineOperand &MO = MI->getOperand (OpNum);
@@ -150,6 +172,50 @@ void BPFAsmPrinter::emitInstruction(const MachineInstr *MI) {
150172 EmitToStreamer (*OutStreamer, TmpInst);
151173}
152174
175+ MCSymbol *BPFAsmPrinter::getJTPublicSymbol (unsigned JTI) {
176+ SmallString<60 > Name;
177+ raw_svector_ostream (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+
187+ void BPFAsmPrinter::emitJumpTableInfo () {
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+
196+ const TargetLoweringObjectFile &TLOF = getObjFileLowering ();
197+ const Function &F = MF->getFunction ();
198+ MCSection *JTS = TLOF.getSectionForJumpTable (F, TM);
199+ assert (MJTI->getEntryKind () == MachineJumpTableInfo::EK_BlockAddress);
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+
153219char BPFAsmPrinter::ID = 0 ;
154220
155221INITIALIZE_PASS (BPFAsmPrinter, " bpf-asm-printer" , " BPF Assembly Printer" , false ,
0 commit comments