[llvm] [MC, X86] emitInstruction: remove virtual function calls due to Intel JCC Erratum (PR #96835)

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Wed Jun 26 17:31:58 PDT 2024


https://github.com/MaskRay created https://github.com/llvm/llvm-project/pull/96835

https://reviews.llvm.org/D70157 (for Intel Jump Conditional Code
Erratum) introduced two virtual function calls in the generic
MCObjectStreamer::emitInstruction, which added some overhead.

Define X86ELFStreamer and move the emitInstruction{Begin,End} hooks to
X86AsmBackend. For now, keep X86AsmBackend and X86ELFStreamer and in the
same file to avoid virtual function calls.


>From c4143d438f3cecf2fc4d6d76e46ea1a93f7c5af4 Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Wed, 26 Jun 2024 17:31:49 -0700
Subject: [PATCH] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20initia?=
 =?UTF-8?q?l=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Created using spr 1.3.5-bogner
---
 llvm/include/llvm/MC/MCAsmBackend.h           |  7 ----
 llvm/lib/MC/MCObjectStreamer.cpp              |  2 --
 .../Target/X86/MCTargetDesc/X86AsmBackend.cpp | 36 +++++++++++++++++--
 .../Target/X86/MCTargetDesc/X86ELFStreamer.h  | 22 ++++++++++++
 .../X86/MCTargetDesc/X86MCTargetDesc.cpp      |  2 ++
 5 files changed, 57 insertions(+), 12 deletions(-)
 create mode 100644 llvm/lib/Target/X86/MCTargetDesc/X86ELFStreamer.h

diff --git a/llvm/include/llvm/MC/MCAsmBackend.h b/llvm/include/llvm/MC/MCAsmBackend.h
index 01a64fb425a94..1f36b7e98274f 100644
--- a/llvm/include/llvm/MC/MCAsmBackend.h
+++ b/llvm/include/llvm/MC/MCAsmBackend.h
@@ -62,13 +62,6 @@ class MCAsmBackend {
   /// tricky way for optimization.
   virtual bool allowEnhancedRelaxation() const { return false; }
 
-  /// Give the target a chance to manipulate state related to instruction
-  /// alignment (e.g. padding for optimization), instruction relaxablility, etc.
-  /// before and after actually emitting the instruction.
-  virtual void emitInstructionBegin(MCObjectStreamer &OS, const MCInst &Inst,
-                                    const MCSubtargetInfo &STI) {}
-  virtual void emitInstructionEnd(MCObjectStreamer &OS, const MCInst &Inst) {}
-
   /// lifetime management
   virtual void reset() {}
 
diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp
index 5dc73c5b7887a..fec1ccee6ff84 100644
--- a/llvm/lib/MC/MCObjectStreamer.cpp
+++ b/llvm/lib/MC/MCObjectStreamer.cpp
@@ -330,9 +330,7 @@ void MCObjectStreamer::emitInstruction(const MCInst &Inst,
                                                 "' cannot have instructions");
     return;
   }
-  getAssembler().getBackend().emitInstructionBegin(*this, Inst, STI);
   emitInstructionImpl(Inst, STI);
-  getAssembler().getBackend().emitInstructionEnd(*this, Inst);
 }
 
 void MCObjectStreamer::emitInstructionImpl(const MCInst &Inst,
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
index c2188d206b5f6..fa3674830b728 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
@@ -7,8 +7,9 @@
 //===----------------------------------------------------------------------===//
 
 #include "MCTargetDesc/X86BaseInfo.h"
-#include "MCTargetDesc/X86FixupKinds.h"
+#include "MCTargetDesc/X86ELFStreamer.h"
 #include "MCTargetDesc/X86EncodingOptimization.h"
+#include "MCTargetDesc/X86FixupKinds.h"
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/BinaryFormat/ELF.h"
 #include "llvm/BinaryFormat/MachO.h"
@@ -162,8 +163,8 @@ class X86AsmBackend : public MCAsmBackend {
   bool allowAutoPadding() const override;
   bool allowEnhancedRelaxation() const override;
   void emitInstructionBegin(MCObjectStreamer &OS, const MCInst &Inst,
-                            const MCSubtargetInfo &STI) override;
-  void emitInstructionEnd(MCObjectStreamer &OS, const MCInst &Inst) override;
+                            const MCSubtargetInfo &STI);
+  void emitInstructionEnd(MCObjectStreamer &OS, const MCInst &Inst);
 
   unsigned getNumFixupKinds() const override {
     return X86::NumTargetFixupKinds;
@@ -1546,3 +1547,32 @@ MCAsmBackend *llvm::createX86_64AsmBackend(const Target &T,
     return new ELFX86_X32AsmBackend(T, OSABI, STI);
   return new ELFX86_64AsmBackend(T, OSABI, STI);
 }
+
+namespace {
+class X86ELFStreamer : public MCELFStreamer {
+public:
+  X86ELFStreamer(MCContext &Context, std::unique_ptr<MCAsmBackend> TAB,
+                 std::unique_ptr<MCObjectWriter> OW,
+                 std::unique_ptr<MCCodeEmitter> Emitter)
+      : MCELFStreamer(Context, std::move(TAB), std::move(OW),
+                      std::move(Emitter)) {}
+
+  void emitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI) override;
+};
+} // end anonymous namespace
+
+void X86ELFStreamer::emitInstruction(const MCInst &Inst,
+                                     const MCSubtargetInfo &STI) {
+  auto &Backend = static_cast<X86AsmBackend &>(getAssembler().getBackend());
+  Backend.emitInstructionBegin(*this, Inst, STI);
+  MCObjectStreamer::emitInstruction(Inst, STI);
+  Backend.emitInstructionEnd(*this, Inst);
+}
+
+MCStreamer *llvm::createX86ELFStreamer(const Triple &T, MCContext &Context,
+                                       std::unique_ptr<MCAsmBackend> &&MAB,
+                                       std::unique_ptr<MCObjectWriter> &&MOW,
+                                       std::unique_ptr<MCCodeEmitter> &&MCE) {
+  return new X86ELFStreamer(Context, std::move(MAB), std::move(MOW),
+                            std::move(MCE));
+}
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86ELFStreamer.h b/llvm/lib/Target/X86/MCTargetDesc/X86ELFStreamer.h
new file mode 100644
index 0000000000000..e57c45d97b37a
--- /dev/null
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86ELFStreamer.h
@@ -0,0 +1,22 @@
+//===-- X86ELFStreamer.h - ELF Streamer for X86 -----------------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIB_TARGET_X86_MCTARGETDESC_X86ELFSTREAMER_H
+#define LLVM_LIB_TARGET_X86_MCTARGETDESC_X86ELFSTREAMER_H
+
+#include "llvm/MC/MCELFStreamer.h"
+
+namespace llvm {
+
+MCStreamer *createX86ELFStreamer(const Triple &T, MCContext &Context,
+                                 std::unique_ptr<MCAsmBackend> &&MAB,
+                                 std::unique_ptr<MCObjectWriter> &&MOW,
+                                 std::unique_ptr<MCCodeEmitter> &&MCE);
+}
+
+#endif
diff --git a/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp b/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp
index ed4d0a45bd8f2..d862e7427489c 100644
--- a/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp
+++ b/llvm/lib/Target/X86/MCTargetDesc/X86MCTargetDesc.cpp
@@ -14,6 +14,7 @@
 #include "TargetInfo/X86TargetInfo.h"
 #include "X86ATTInstPrinter.h"
 #include "X86BaseInfo.h"
+#include "X86ELFStreamer.h"
 #include "X86IntelInstPrinter.h"
 #include "X86MCAsmInfo.h"
 #include "X86TargetStreamer.h"
@@ -741,6 +742,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeX86TargetMC() {
     // Register the null streamer.
     TargetRegistry::RegisterNullTargetStreamer(*T, createX86NullTargetStreamer);
 
+    TargetRegistry::RegisterELFStreamer(*T, createX86ELFStreamer);
     TargetRegistry::RegisterCOFFStreamer(*T, createX86WinCOFFStreamer);
 
     // Register the MCInstPrinter.



More information about the llvm-commits mailing list