From 0c049ea60a9f214911eef7901b94bd6343c04409 Mon Sep 17 00:00:00 2001 From: Alexis Engelke Date: Fri, 10 Mar 2023 15:20:30 +0100 Subject: [PATCH] [MC] Always encode instruction into SmallVector All users of MCCodeEmitter::encodeInstruction use a raw_svector_ostream to encode the instruction into a SmallVector. The raw_ostream however incurs some overhead for the actual encoding. This change allows an MCCodeEmitter to directly emit an instruction into a SmallVector without using a raw_ostream and therefore allow for performance improvments in encoding. A default path that uses existing raw_ostream implementations is provided. Reviewed By: MaskRay, Amir Differential Revision: https://reviews.llvm.org/D145791 --- bolt/include/bolt/Core/BinaryContext.h | 3 +-- bolt/lib/Core/BinaryContext.cpp | 3 +-- bolt/lib/Core/BinaryFunction.cpp | 3 +-- llvm/include/llvm/MC/MCCodeEmitter.h | 14 ++++++++++---- llvm/include/llvm/MCA/CodeEmitter.h | 5 +---- llvm/lib/MC/MCAsmStreamer.cpp | 3 +-- llvm/lib/MC/MCAssembler.cpp | 3 +-- llvm/lib/MC/MCCodeEmitter.cpp | 9 +++++++++ llvm/lib/MC/MCELFStreamer.cpp | 3 +-- llvm/lib/MC/MCMachOStreamer.cpp | 4 +--- llvm/lib/MC/MCObjectStreamer.cpp | 3 +-- llvm/lib/MC/MCSPIRVStreamer.cpp | 3 +-- llvm/lib/MC/MCWasmStreamer.cpp | 3 +-- llvm/lib/MC/MCWinCOFFStreamer.cpp | 3 +-- llvm/lib/MC/MCXCOFFStreamer.cpp | 3 +-- llvm/lib/MCA/CodeEmitter.cpp | 2 +- llvm/lib/Target/AMDGPU/AMDGPUMCInstLower.cpp | 6 ++---- llvm/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp | 3 +-- llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp | 3 +-- llvm/lib/Target/X86/X86MCInstLower.cpp | 6 ++---- llvm/tools/llvm-exegesis/lib/LlvmState.cpp | 4 +--- 21 files changed, 40 insertions(+), 49 deletions(-) diff --git a/bolt/include/bolt/Core/BinaryContext.h b/bolt/include/bolt/Core/BinaryContext.h index 26b8a64..7e2d4d6 100644 --- a/bolt/include/bolt/Core/BinaryContext.h +++ b/bolt/include/bolt/Core/BinaryContext.h @@ -1227,8 +1227,7 @@ public: Emitter = this->MCE.get(); SmallString<256> Code; SmallVector Fixups; - raw_svector_ostream VecOS(Code); - Emitter->encodeInstruction(Inst, VecOS, Fixups, *STI); + Emitter->encodeInstruction(Inst, Code, Fixups, *STI); return Code.size(); } diff --git a/bolt/lib/Core/BinaryContext.cpp b/bolt/lib/Core/BinaryContext.cpp index 09f59f7..6a9e35e 100644 --- a/bolt/lib/Core/BinaryContext.cpp +++ b/bolt/lib/Core/BinaryContext.cpp @@ -2289,9 +2289,8 @@ bool BinaryContext::validateInstructionEncoding( SmallString<256> Code; SmallVector Fixups; - raw_svector_ostream VecOS(Code); - MCE->encodeInstruction(Inst, VecOS, Fixups, *STI); + MCE->encodeInstruction(Inst, Code, Fixups, *STI); auto OutputSequence = ArrayRef((uint8_t *)Code.data(), Code.size()); if (InputSequence != OutputSequence) { if (opts::Verbosity > 1) { diff --git a/bolt/lib/Core/BinaryFunction.cpp b/bolt/lib/Core/BinaryFunction.cpp index 69ebd12..14a10be 100644 --- a/bolt/lib/Core/BinaryFunction.cpp +++ b/bolt/lib/Core/BinaryFunction.cpp @@ -1536,8 +1536,7 @@ bool BinaryFunction::scanExternalRefs() { // Emit the instruction using temp emitter and generate relocations. SmallString<256> Code; SmallVector Fixups; - raw_svector_ostream VecOS(Code); - Emitter.MCE->encodeInstruction(Instruction, VecOS, Fixups, *BC.STI); + Emitter.MCE->encodeInstruction(Instruction, Code, Fixups, *BC.STI); // Create relocation for every fixup. for (const MCFixup &Fixup : Fixups) { diff --git a/llvm/include/llvm/MC/MCCodeEmitter.h b/llvm/include/llvm/MC/MCCodeEmitter.h index 2794acc..9a36a51 100644 --- a/llvm/include/llvm/MC/MCCodeEmitter.h +++ b/llvm/include/llvm/MC/MCCodeEmitter.h @@ -22,6 +22,13 @@ class MCCodeEmitter { protected: // Can only create subclasses. MCCodeEmitter(); + /// EncodeInstruction - Encode the given \p Inst to bytes on the output stream + /// \p OS. Allows for an implementation of encodeInstruction that uses streams + /// instead of a SmallVector. + virtual void encodeInstruction(const MCInst &Inst, raw_ostream &OS, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const {} + public: MCCodeEmitter(const MCCodeEmitter &) = delete; MCCodeEmitter &operator=(const MCCodeEmitter &) = delete; @@ -36,11 +43,10 @@ public: /// \param OS output stream. virtual void emitPrefix(const MCInst &Inst, raw_ostream &OS, const MCSubtargetInfo &STI) const {} - /// EncodeInstruction - Encode the given \p Inst to bytes on the output - /// stream \p OS. - virtual void encodeInstruction(const MCInst &Inst, raw_ostream &OS, + /// EncodeInstruction - Encode the given \p Inst to bytes and append to \p CB. + virtual void encodeInstruction(const MCInst &Inst, SmallVectorImpl &CB, SmallVectorImpl &Fixups, - const MCSubtargetInfo &STI) const = 0; + const MCSubtargetInfo &STI) const; }; } // end namespace llvm diff --git a/llvm/include/llvm/MCA/CodeEmitter.h b/llvm/include/llvm/MCA/CodeEmitter.h index 502d812..431ceea 100644 --- a/llvm/include/llvm/MCA/CodeEmitter.h +++ b/llvm/include/llvm/MCA/CodeEmitter.h @@ -23,7 +23,6 @@ #include "llvm/MC/MCCodeEmitter.h" #include "llvm/MC/MCInst.h" #include "llvm/MC/MCSubtargetInfo.h" -#include "llvm/Support/raw_ostream.h" namespace llvm { namespace mca { @@ -38,7 +37,6 @@ class CodeEmitter { const MCCodeEmitter &MCE; SmallString<256> Code; - raw_svector_ostream VecOS; ArrayRef Sequence; // An EncodingInfo pair stores information. Base (i.e. first) @@ -53,8 +51,7 @@ class CodeEmitter { public: CodeEmitter(const MCSubtargetInfo &ST, const MCAsmBackend &AB, const MCCodeEmitter &CE, ArrayRef S) - : STI(ST), MAB(AB), MCE(CE), VecOS(Code), Sequence(S), - Encodings(S.size()) {} + : STI(ST), MAB(AB), MCE(CE), Sequence(S), Encodings(S.size()) {} StringRef getEncoding(unsigned MCID) { EncodingInfo EI = getOrCreateEncodingInfo(MCID); diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp index fa1ab27..c11d28b 100644 --- a/llvm/lib/MC/MCAsmStreamer.cpp +++ b/llvm/lib/MC/MCAsmStreamer.cpp @@ -2218,13 +2218,12 @@ void MCAsmStreamer::AddEncodingComment(const MCInst &Inst, raw_ostream &OS = getCommentOS(); SmallString<256> Code; SmallVector Fixups; - raw_svector_ostream VecOS(Code); // If we have no code emitter, don't emit code. if (!getAssembler().getEmitterPtr()) return; - getAssembler().getEmitter().encodeInstruction(Inst, VecOS, Fixups, STI); + getAssembler().getEmitter().encodeInstruction(Inst, Code, Fixups, STI); // If we are showing fixups, create symbolic markers in the encoded // representation. We do this by making a per-bit map to the fixup item index, diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp index a33d7ea..179fe23 100644 --- a/llvm/lib/MC/MCAssembler.cpp +++ b/llvm/lib/MC/MCAssembler.cpp @@ -996,8 +996,7 @@ bool MCAssembler::relaxInstruction(MCAsmLayout &Layout, // probably do so more efficiently in many cases. SmallVector Fixups; SmallString<256> Code; - raw_svector_ostream VecOS(Code); - getEmitter().encodeInstruction(Relaxed, VecOS, Fixups, *F.getSubtargetInfo()); + getEmitter().encodeInstruction(Relaxed, Code, Fixups, *F.getSubtargetInfo()); // Update the fragment. F.setInst(Relaxed); diff --git a/llvm/lib/MC/MCCodeEmitter.cpp b/llvm/lib/MC/MCCodeEmitter.cpp index 0d114f1..afbe31e 100644 --- a/llvm/lib/MC/MCCodeEmitter.cpp +++ b/llvm/lib/MC/MCCodeEmitter.cpp @@ -7,9 +7,18 @@ //===----------------------------------------------------------------------===// #include "llvm/MC/MCCodeEmitter.h" +#include "llvm/Support/raw_ostream.h" using namespace llvm; MCCodeEmitter::MCCodeEmitter() = default; MCCodeEmitter::~MCCodeEmitter() = default; + +void MCCodeEmitter::encodeInstruction(const MCInst &Inst, + SmallVectorImpl &CB, + SmallVectorImpl &Fixups, + const MCSubtargetInfo &STI) const { + raw_svector_ostream OS(CB); + encodeInstruction(Inst, OS, Fixups, STI); +} diff --git a/llvm/lib/MC/MCELFStreamer.cpp b/llvm/lib/MC/MCELFStreamer.cpp index 380576f..8dd002f 100644 --- a/llvm/lib/MC/MCELFStreamer.cpp +++ b/llvm/lib/MC/MCELFStreamer.cpp @@ -551,8 +551,7 @@ void MCELFStreamer::emitInstToData(const MCInst &Inst, MCAssembler &Assembler = getAssembler(); SmallVector Fixups; SmallString<256> Code; - raw_svector_ostream VecOS(Code); - Assembler.getEmitter().encodeInstruction(Inst, VecOS, Fixups, STI); + Assembler.getEmitter().encodeInstruction(Inst, Code, Fixups, STI); for (auto &Fixup : Fixups) fixSymbolsInTLSFixups(Fixup.getValue()); diff --git a/llvm/lib/MC/MCMachOStreamer.cpp b/llvm/lib/MC/MCMachOStreamer.cpp index 699742f..986c0c2c 100644 --- a/llvm/lib/MC/MCMachOStreamer.cpp +++ b/llvm/lib/MC/MCMachOStreamer.cpp @@ -31,7 +31,6 @@ #include "llvm/MC/TargetRegistry.h" #include "llvm/Support/Casting.h" #include "llvm/Support/ErrorHandling.h" -#include "llvm/Support/raw_ostream.h" #include #include @@ -486,8 +485,7 @@ void MCMachOStreamer::emitInstToData(const MCInst &Inst, SmallVector Fixups; SmallString<256> Code; - raw_svector_ostream VecOS(Code); - getAssembler().getEmitter().encodeInstruction(Inst, VecOS, Fixups, STI); + getAssembler().getEmitter().encodeInstruction(Inst, Code, Fixups, STI); // Add the fixups and data. for (MCFixup &Fixup : Fixups) { diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp index ac90325..d609194 100644 --- a/llvm/lib/MC/MCObjectStreamer.cpp +++ b/llvm/lib/MC/MCObjectStreamer.cpp @@ -471,8 +471,7 @@ void MCObjectStreamer::emitInstToFragment(const MCInst &Inst, insert(IF); SmallString<128> Code; - raw_svector_ostream VecOS(Code); - getAssembler().getEmitter().encodeInstruction(Inst, VecOS, IF->getFixups(), + getAssembler().getEmitter().encodeInstruction(Inst, Code, IF->getFixups(), STI); IF->getContents().append(Code.begin(), Code.end()); } diff --git a/llvm/lib/MC/MCSPIRVStreamer.cpp b/llvm/lib/MC/MCSPIRVStreamer.cpp index 863db7f..0bb73c7 100644 --- a/llvm/lib/MC/MCSPIRVStreamer.cpp +++ b/llvm/lib/MC/MCSPIRVStreamer.cpp @@ -21,8 +21,7 @@ void MCSPIRVStreamer::emitInstToData(const MCInst &Inst, MCAssembler &Assembler = getAssembler(); SmallVector Fixups; SmallString<256> Code; - raw_svector_ostream VecOS(Code); - Assembler.getEmitter().encodeInstruction(Inst, VecOS, Fixups, STI); + Assembler.getEmitter().encodeInstruction(Inst, Code, Fixups, STI); // Append the encoded instruction to the current data fragment (or create a // new such fragment if the current fragment is not a data fragment). diff --git a/llvm/lib/MC/MCWasmStreamer.cpp b/llvm/lib/MC/MCWasmStreamer.cpp index 823e98a8..fbab72f 100644 --- a/llvm/lib/MC/MCWasmStreamer.cpp +++ b/llvm/lib/MC/MCWasmStreamer.cpp @@ -196,8 +196,7 @@ void MCWasmStreamer::emitInstToData(const MCInst &Inst, MCAssembler &Assembler = getAssembler(); SmallVector Fixups; SmallString<256> Code; - raw_svector_ostream VecOS(Code); - Assembler.getEmitter().encodeInstruction(Inst, VecOS, Fixups, STI); + Assembler.getEmitter().encodeInstruction(Inst, Code, Fixups, STI); for (auto &Fixup : Fixups) fixSymbolsInTLSFixups(Fixup.getValue()); diff --git a/llvm/lib/MC/MCWinCOFFStreamer.cpp b/llvm/lib/MC/MCWinCOFFStreamer.cpp index dbbfcc5..c9a9681 100644 --- a/llvm/lib/MC/MCWinCOFFStreamer.cpp +++ b/llvm/lib/MC/MCWinCOFFStreamer.cpp @@ -53,8 +53,7 @@ void MCWinCOFFStreamer::emitInstToData(const MCInst &Inst, SmallVector Fixups; SmallString<256> Code; - raw_svector_ostream VecOS(Code); - getAssembler().getEmitter().encodeInstruction(Inst, VecOS, Fixups, STI); + getAssembler().getEmitter().encodeInstruction(Inst, Code, Fixups, STI); // Add the fixups and data. for (unsigned i = 0, e = Fixups.size(); i != e; ++i) { diff --git a/llvm/lib/MC/MCXCOFFStreamer.cpp b/llvm/lib/MC/MCXCOFFStreamer.cpp index d8ac07b..d996dcf 100644 --- a/llvm/lib/MC/MCXCOFFStreamer.cpp +++ b/llvm/lib/MC/MCXCOFFStreamer.cpp @@ -133,8 +133,7 @@ void MCXCOFFStreamer::emitInstToData(const MCInst &Inst, MCAssembler &Assembler = getAssembler(); SmallVector Fixups; SmallString<256> Code; - raw_svector_ostream VecOS(Code); - Assembler.getEmitter().encodeInstruction(Inst, VecOS, Fixups, STI); + Assembler.getEmitter().encodeInstruction(Inst, Code, Fixups, STI); // Add the fixups and data. MCDataFragment *DF = getOrCreateDataFragment(&STI); diff --git a/llvm/lib/MCA/CodeEmitter.cpp b/llvm/lib/MCA/CodeEmitter.cpp index 0ce17bd..b3936a9 100644 --- a/llvm/lib/MCA/CodeEmitter.cpp +++ b/llvm/lib/MCA/CodeEmitter.cpp @@ -27,7 +27,7 @@ CodeEmitter::EncodingInfo CodeEmitter::getOrCreateEncodingInfo(unsigned MCID) { MAB.relaxInstruction(Relaxed, STI); EI.first = Code.size(); - MCE.encodeInstruction(Relaxed, VecOS, Fixups, STI); + MCE.encodeInstruction(Relaxed, Code, Fixups, STI); EI.second = Code.size() - EI.first; return EI; } diff --git a/llvm/lib/Target/AMDGPU/AMDGPUMCInstLower.cpp b/llvm/lib/Target/AMDGPU/AMDGPUMCInstLower.cpp index da75f57..9ecad3b 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUMCInstLower.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUMCInstLower.cpp @@ -285,11 +285,10 @@ void AMDGPUAsmPrinter::emitInstruction(const MachineInstr *MI) { (!STI.hasOffset3fBug() || !MI->isBranch())) { SmallVector Fixups; SmallVector CodeBytes; - raw_svector_ostream CodeStream(CodeBytes); std::unique_ptr InstEmitter(createSIMCCodeEmitter( *STI.getInstrInfo(), OutContext)); - InstEmitter->encodeInstruction(TmpInst, CodeStream, Fixups, STI); + InstEmitter->encodeInstruction(TmpInst, CodeBytes, Fixups, STI); assert(CodeBytes.size() == STI.getInstrInfo()->getInstSizeInBytes(*MI)); } @@ -308,10 +307,9 @@ void AMDGPUAsmPrinter::emitInstruction(const MachineInstr *MI) { // Disassemble instruction/operands to hex representation. SmallVector Fixups; SmallVector CodeBytes; - raw_svector_ostream CodeStream(CodeBytes); DumpCodeInstEmitter->encodeInstruction( - TmpInst, CodeStream, Fixups, MF->getSubtarget()); + TmpInst, CodeBytes, Fixups, MF->getSubtarget()); HexLines.resize(HexLines.size() + 1); std::string &HexLine = HexLines.back(); raw_string_ostream HexStream(HexLine); diff --git a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp index 08ab3db..12c84ce 100644 --- a/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp +++ b/llvm/lib/Target/Hexagon/MCTargetDesc/HexagonAsmBackend.cpp @@ -51,8 +51,7 @@ class HexagonAsmBackend : public MCAsmBackend { MCInst &HMB) const { SmallVector Fixups; SmallString<256> Code; - raw_svector_ostream VecOS(Code); - E.encodeInstruction(HMB, VecOS, Fixups, *RF.getSubtargetInfo()); + E.encodeInstruction(HMB, Code, Fixups, *RF.getSubtargetInfo()); // Update the fragment. RF.setInst(HMB); diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp index b50a40e..839e003 100644 --- a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp +++ b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp @@ -844,8 +844,7 @@ bool X86AsmBackend::padInstructionViaRelaxation(MCRelaxableFragment &RF, SmallVector Fixups; SmallString<15> Code; - raw_svector_ostream VecOS(Code); - Emitter.encodeInstruction(Relaxed, VecOS, Fixups, *RF.getSubtargetInfo()); + Emitter.encodeInstruction(Relaxed, Code, Fixups, *RF.getSubtargetInfo()); const unsigned OldSize = RF.getContents().size(); const unsigned NewSize = Code.size(); assert(NewSize >= OldSize && "size decrease during relaxation?"); diff --git a/llvm/lib/Target/X86/X86MCInstLower.cpp b/llvm/lib/Target/X86/X86MCInstLower.cpp index 1b323d7..dbf64cc 100644 --- a/llvm/lib/Target/X86/X86MCInstLower.cpp +++ b/llvm/lib/Target/X86/X86MCInstLower.cpp @@ -108,8 +108,7 @@ void X86AsmPrinter::StackMapShadowTracker::count(MCInst &Inst, if (InShadow) { SmallString<256> Code; SmallVector Fixups; - raw_svector_ostream VecOS(Code); - CodeEmitter->encodeInstruction(Inst, VecOS, Fixups, STI); + CodeEmitter->encodeInstruction(Inst, Code, Fixups, STI); CurrentShadowSize += Code.size(); if (CurrentShadowSize >= RequiredShadowSize) InShadow = false; // The shadow is big enough. Stop counting. @@ -1446,8 +1445,7 @@ void X86AsmPrinter::LowerPATCHABLE_OP(const MachineInstr &MI, SmallString<256> Code; if (!EmptyInst) { SmallVector Fixups; - raw_svector_ostream VecOS(Code); - CodeEmitter->encodeInstruction(MCI, VecOS, Fixups, getSubtargetInfo()); + CodeEmitter->encodeInstruction(MCI, Code, Fixups, getSubtargetInfo()); } if (Code.size() < MinSize) { diff --git a/llvm/tools/llvm-exegesis/lib/LlvmState.cpp b/llvm/tools/llvm-exegesis/lib/LlvmState.cpp index 6c3d8ff..8aeea45 100644 --- a/llvm/tools/llvm-exegesis/lib/LlvmState.cpp +++ b/llvm/tools/llvm-exegesis/lib/LlvmState.cpp @@ -14,7 +14,6 @@ #include "llvm/MC/MCFixup.h" #include "llvm/MC/MCObjectFileInfo.h" #include "llvm/MC/TargetRegistry.h" -#include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" #include "llvm/TargetParser/Host.h" @@ -136,9 +135,8 @@ bool LLVMState::canAssemble(const MCInst &Inst) const { *TheTargetMachine->getMCInstrInfo(), Context)); assert(CodeEmitter && "unable to create code emitter"); SmallVector Tmp; - raw_svector_ostream OS(Tmp); SmallVector Fixups; - CodeEmitter->encodeInstruction(Inst, OS, Fixups, + CodeEmitter->encodeInstruction(Inst, Tmp, Fixups, *TheTargetMachine->getMCSubtargetInfo()); return Tmp.size() > 0; } -- 2.7.4