[clang] [llvm] [LoongArch] Add options for annotate tablejump (PR #102411)

via cfe-commits cfe-commits at lists.llvm.org
Tue Oct 15 06:02:41 PDT 2024


https://github.com/wangleiat updated https://github.com/llvm/llvm-project/pull/102411

>From 7bcf5ebc9444e7cb98746ef0d182cbd4b60196e2 Mon Sep 17 00:00:00 2001
From: wanglei <wanglei at loongson.cn>
Date: Thu, 8 Aug 2024 09:41:25 +0800
Subject: [PATCH 1/2] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20in?=
 =?UTF-8?q?itial=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Created using spr 1.3.5-bogner
---
 clang/include/clang/Driver/Options.td         |   4 +
 clang/lib/Driver/ToolChains/Clang.cpp         |   8 ++
 .../Target/LoongArch/LoongArchAsmPrinter.cpp  |  49 +++++++++
 .../Target/LoongArch/LoongArchAsmPrinter.h    |   1 +
 .../LoongArch/LoongArchExpandPseudoInsts.cpp  |  17 +++
 .../CodeGen/LoongArch/annotate-tablejump.ll   | 102 ++++++++++++++++++
 6 files changed, 181 insertions(+)
 create mode 100644 llvm/test/CodeGen/LoongArch/annotate-tablejump.ll

diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 51ec29f1dc3212..18ad7f5868e48f 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -5319,6 +5319,10 @@ def mno_lasx : Flag<["-"], "mno-lasx">, Group<m_loongarch_Features_Group>,
 def msimd_EQ : Joined<["-"], "msimd=">, Group<m_loongarch_Features_Group>,
   Flags<[TargetSpecific]>,
   HelpText<"Select the SIMD extension(s) to be enabled in LoongArch either 'none', 'lsx', 'lasx'.">;
+def mannotate_tablejump : Flag<["-"], "mannotate-tablejump">, Group<m_loongarch_Features_Group>,
+  HelpText<"Enable annotate table jump instruction to correlate it with the jump table.">;
+def mno_annotate_tablejump : Flag<["-"], "mno-annotate-tablejump">, Group<m_loongarch_Features_Group>,
+  HelpText<"Disable annotate table jump instruction to correlate it with the jump table.">;
 def mnop_mcount : Flag<["-"], "mnop-mcount">, HelpText<"Generate mcount/__fentry__ calls as nops. To activate they need to be patched in.">,
   Visibility<[ClangOption, CC1Option]>, Group<m_Group>,
   MarshallingInfoFlag<CodeGenOpts<"MNopMCount">>;
diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 2054c8fe928e2e..342c083b01101e 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -1876,6 +1876,14 @@ void Clang::AddLoongArchTargetArgs(const ArgList &Args,
     CmdArgs.push_back("-tune-cpu");
     CmdArgs.push_back(Args.MakeArgString(TuneCPU));
   }
+
+  if (Arg *A = Args.getLastArg(options::OPT_mannotate_tablejump,
+                               options::OPT_mno_annotate_tablejump)) {
+    if (A->getOption().matches(options::OPT_mannotate_tablejump)) {
+      CmdArgs.push_back("-mllvm");
+      CmdArgs.push_back("-loongarch-annotate-tablejump");
+    }
+  }
 }
 
 void Clang::AddMIPSTargetArgs(const ArgList &Args,
diff --git a/llvm/lib/Target/LoongArch/LoongArchAsmPrinter.cpp b/llvm/lib/Target/LoongArch/LoongArchAsmPrinter.cpp
index f478870217ec60..b4c5be194bff52 100644
--- a/llvm/lib/Target/LoongArch/LoongArchAsmPrinter.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchAsmPrinter.cpp
@@ -15,16 +15,26 @@
 #include "LoongArch.h"
 #include "LoongArchTargetMachine.h"
 #include "MCTargetDesc/LoongArchInstPrinter.h"
+#include "MCTargetDesc/LoongArchMCTargetDesc.h"
 #include "TargetInfo/LoongArchTargetInfo.h"
 #include "llvm/CodeGen/AsmPrinter.h"
+#include "llvm/CodeGen/MachineJumpTableInfo.h"
+#include "llvm/CodeGen/MachineModuleInfoImpls.h"
 #include "llvm/MC/MCContext.h"
 #include "llvm/MC/MCInstBuilder.h"
+#include "llvm/MC/MCSectionELF.h"
 #include "llvm/MC/TargetRegistry.h"
 
 using namespace llvm;
 
 #define DEBUG_TYPE "loongarch-asm-printer"
 
+cl::opt<bool> LArchAnnotateTableJump(
+    "loongarch-annotate-tablejump", cl::Hidden,
+    cl::desc(
+        "Annotate table jump instruction to correlate it with the jump table."),
+    cl::init(false));
+
 // Simple pseudo-instructions have their lowering (with expansion to real
 // instructions) auto-generated.
 #include "LoongArchGenMCPseudoLowering.inc"
@@ -189,6 +199,45 @@ void LoongArchAsmPrinter::emitSled(const MachineInstr &MI, SledKind Kind) {
   recordSled(BeginOfSled, MI, Kind, 2);
 }
 
+void LoongArchAsmPrinter::emitJumpTableInfo() {
+  AsmPrinter::emitJumpTableInfo();
+
+  if (!LArchAnnotateTableJump)
+    return;
+
+  assert(TM.getTargetTriple().isOSBinFormatELF());
+
+  const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
+  if (!MJTI)
+    return;
+
+  const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
+  if (JT.empty())
+    return;
+
+  OutStreamer->switchSection(MMI->getContext().getELFSection(
+      ".discard.tablejump_annotate", ELF::SHT_PROGBITS, 0));
+
+  unsigned Size = getDataLayout().getPointerSize();
+
+  for (unsigned JTI = 0, e = JT.size(); JTI != e; ++JTI) {
+    const std::vector<MachineBasicBlock *> &JTBBs = JT[JTI].MBBs;
+    if (JTBBs.empty())
+      continue;
+    for (auto *Pred : JTBBs[0]->predecessors()) {
+      for (auto &MI : Pred->instrs()) {
+        if (MI.getOpcode() != LoongArch::PseudoBRIND || !MI.getPreInstrSymbol())
+          continue;
+        OutStreamer->emitValue(
+            MCSymbolRefExpr::create(MI.getPreInstrSymbol(), OutContext), Size);
+        MCSymbol *JTISymbol = GetJTISymbol(JTI);
+        OutStreamer->emitValue(MCSymbolRefExpr::create(JTISymbol, OutContext),
+                               Size);
+      }
+    }
+  }
+}
+
 bool LoongArchAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
   AsmPrinter::runOnMachineFunction(MF);
   // Emit the XRay table for this function.
diff --git a/llvm/lib/Target/LoongArch/LoongArchAsmPrinter.h b/llvm/lib/Target/LoongArch/LoongArchAsmPrinter.h
index 9da90886627ec9..b5239ab37e147f 100644
--- a/llvm/lib/Target/LoongArch/LoongArchAsmPrinter.h
+++ b/llvm/lib/Target/LoongArch/LoongArchAsmPrinter.h
@@ -53,6 +53,7 @@ class LLVM_LIBRARY_VISIBILITY LoongArchAsmPrinter : public AsmPrinter {
   bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp) const {
     return lowerLoongArchMachineOperandToMCOperand(MO, MCOp, *this);
   }
+  void emitJumpTableInfo() override;
 };
 
 } // end namespace llvm
diff --git a/llvm/lib/Target/LoongArch/LoongArchExpandPseudoInsts.cpp b/llvm/lib/Target/LoongArch/LoongArchExpandPseudoInsts.cpp
index 33b93e42bb5c47..c72f9157525f4f 100644
--- a/llvm/lib/Target/LoongArch/LoongArchExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchExpandPseudoInsts.cpp
@@ -27,6 +27,8 @@
 
 using namespace llvm;
 
+extern cl::opt<bool> LArchAnnotateTableJump;
+
 #define LOONGARCH_PRERA_EXPAND_PSEUDO_NAME                                     \
   "LoongArch Pre-RA pseudo instruction expansion pass"
 #define LOONGARCH_EXPAND_PSEUDO_NAME                                           \
@@ -167,6 +169,21 @@ bool LoongArchPreRAExpandPseudo::expandMI(
   case LoongArch::PseudoTAIL_MEDIUM:
   case LoongArch::PseudoTAIL_LARGE:
     return expandFunctionCALL(MBB, MBBI, NextMBBI, /*IsTailCall=*/true);
+  case LoongArch::PseudoBRIND:
+    // If the PseudoBRIND is used to table jump, then emit a label to annotate
+    // the `jr` instruction.
+    if (!LArchAnnotateTableJump)
+      return false;
+    for (auto &MI : MBB.instrs()) {
+      for (auto MO : MI.operands()) {
+        if (!MO.isJTI())
+          continue;
+        MachineFunction *MF = MBB.getParent();
+        MBBI->setPreInstrSymbol(
+            *MF, MF->getContext().createNamedTempSymbol("jrtb_"));
+        return false;
+      }
+    }
   }
   return false;
 }
diff --git a/llvm/test/CodeGen/LoongArch/annotate-tablejump.ll b/llvm/test/CodeGen/LoongArch/annotate-tablejump.ll
new file mode 100644
index 00000000000000..ddea8c80b0ea48
--- /dev/null
+++ b/llvm/test/CodeGen/LoongArch/annotate-tablejump.ll
@@ -0,0 +1,102 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
+; RUN: llc --mtriple=loongarch32 -mattr=+d \
+; RUN:   --min-jump-table-entries=4 < %s \
+; RUN:   --loongarch-annotate-tablejump \
+; RUN:   | FileCheck %s --check-prefix=LA32-JT
+; RUN: llc --mtriple=loongarch64 -mattr=+d \
+; RUN:   --min-jump-table-entries=4 < %s \
+; RUN:   --loongarch-annotate-tablejump \
+; RUN:   | FileCheck %s --check-prefix=LA64-JT
+
+define void @switch_4_arms(i32 %in, ptr %out) nounwind {
+; LA32-JT-LABEL: switch_4_arms:
+; LA32-JT:       # %bb.0: # %entry
+; LA32-JT-NEXT:    addi.w $a0, $a0, -1
+; LA32-JT-NEXT:    ori $a2, $zero, 3
+; LA32-JT-NEXT:    bltu $a2, $a0, .LBB0_7
+; LA32-JT-NEXT:  # %bb.1: # %entry
+; LA32-JT-NEXT:    pcalau12i $a2, %pc_hi20(.LJTI0_0)
+; LA32-JT-NEXT:    addi.w $a2, $a2, %pc_lo12(.LJTI0_0)
+; LA32-JT-NEXT:    alsl.w $a0, $a0, $a2, 2
+; LA32-JT-NEXT:    ld.w $a0, $a0, 0
+; LA32-JT-NEXT:  .Ljrtb_0:
+; LA32-JT-NEXT:    jr $a0
+; LA32-JT-NEXT:  .LBB0_2: # %bb1
+; LA32-JT-NEXT:    ori $a0, $zero, 4
+; LA32-JT-NEXT:    b .LBB0_6
+; LA32-JT-NEXT:  .LBB0_3: # %bb3
+; LA32-JT-NEXT:    ori $a0, $zero, 2
+; LA32-JT-NEXT:    b .LBB0_6
+; LA32-JT-NEXT:  .LBB0_4: # %bb4
+; LA32-JT-NEXT:    ori $a0, $zero, 1
+; LA32-JT-NEXT:    b .LBB0_6
+; LA32-JT-NEXT:  .LBB0_5: # %bb2
+; LA32-JT-NEXT:    ori $a0, $zero, 3
+; LA32-JT-NEXT:  .LBB0_6: # %exit
+; LA32-JT-NEXT:    st.w $a0, $a1, 0
+; LA32-JT-NEXT:  .LBB0_7: # %exit
+; LA32-JT-NEXT:    ret
+;
+; LA64-JT-LABEL: switch_4_arms:
+; LA64-JT:       # %bb.0: # %entry
+; LA64-JT-NEXT:    addi.w $a0, $a0, 0
+; LA64-JT-NEXT:    addi.d $a0, $a0, -1
+; LA64-JT-NEXT:    ori $a2, $zero, 3
+; LA64-JT-NEXT:    bltu $a2, $a0, .LBB0_7
+; LA64-JT-NEXT:  # %bb.1: # %entry
+; LA64-JT-NEXT:    slli.d $a0, $a0, 3
+; LA64-JT-NEXT:    pcalau12i $a2, %pc_hi20(.LJTI0_0)
+; LA64-JT-NEXT:    addi.d $a2, $a2, %pc_lo12(.LJTI0_0)
+; LA64-JT-NEXT:    ldx.d $a0, $a0, $a2
+; LA64-JT-NEXT:  .Ljrtb_0:
+; LA64-JT-NEXT:    jr $a0
+; LA64-JT-NEXT:  .LBB0_2: # %bb1
+; LA64-JT-NEXT:    ori $a0, $zero, 4
+; LA64-JT-NEXT:    b .LBB0_6
+; LA64-JT-NEXT:  .LBB0_3: # %bb3
+; LA64-JT-NEXT:    ori $a0, $zero, 2
+; LA64-JT-NEXT:    b .LBB0_6
+; LA64-JT-NEXT:  .LBB0_4: # %bb4
+; LA64-JT-NEXT:    ori $a0, $zero, 1
+; LA64-JT-NEXT:    b .LBB0_6
+; LA64-JT-NEXT:  .LBB0_5: # %bb2
+; LA64-JT-NEXT:    ori $a0, $zero, 3
+; LA64-JT-NEXT:  .LBB0_6: # %exit
+; LA64-JT-NEXT:    st.w $a0, $a1, 0
+; LA64-JT-NEXT:  .LBB0_7: # %exit
+; LA64-JT-NEXT:    ret
+entry:
+  switch i32 %in, label %exit [
+    i32 1, label %bb1
+    i32 2, label %bb2
+    i32 3, label %bb3
+    i32 4, label %bb4
+  ]
+bb1:
+  store i32 4, ptr %out
+  br label %exit
+bb2:
+  store i32 3, ptr %out
+  br label %exit
+bb3:
+  store i32 2, ptr %out
+  br label %exit
+bb4:
+  store i32 1, ptr %out
+  br label %exit
+exit:
+  ret void
+}
+
+; UTC_ARGS: --disable
+
+; LA32-JT-LABEL: .LJTI0_0:
+; LA32-JT:       .section .discard.tablejump_annotate,"", at progbits
+; LA32-JT-NEXT:  .word .Ljrtb_0
+; LA32-JT-NEXT:  .word .LJTI0_0
+
+; UTC_ARGS: --disable
+; LA64-JT-LABEL: .LJTI0_0:
+; LA64-JT:       .section .discard.tablejump_annotate,"", at progbits
+; LA64-JT-NEXT:  .dword .Ljrtb_0
+; LA64-JT-NEXT:  .dword .LJTI0_0

>From 6861ff958bbcb9d30ca6fca8203739cb00dabf03 Mon Sep 17 00:00:00 2001
From: wanglei <wanglei at loongson.cn>
Date: Tue, 15 Oct 2024 21:02:30 +0800
Subject: [PATCH 2/2] Address heiher's comments

Created using spr 1.3.5-bogner
---
 llvm/lib/Target/LoongArch/LoongArchAsmPrinter.cpp    | 12 ++++--------
 .../Target/LoongArch/LoongArchExpandPseudoInsts.cpp  | 12 ++++++------
 .../Target/LoongArch/LoongArchMachineFunctionInfo.h  | 10 ++++++----
 3 files changed, 16 insertions(+), 18 deletions(-)

diff --git a/llvm/lib/Target/LoongArch/LoongArchAsmPrinter.cpp b/llvm/lib/Target/LoongArch/LoongArchAsmPrinter.cpp
index e51720bb6b2e1c..28a8662da8c624 100644
--- a/llvm/lib/Target/LoongArch/LoongArchAsmPrinter.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchAsmPrinter.cpp
@@ -273,14 +273,10 @@ void LoongArchAsmPrinter::emitJumpTableInfo() {
         MCSymbolRefExpr::create(LAFI->getJumpInfoJrMI(Idx)->getPreInstrSymbol(),
                                 OutContext),
         Size);
-    for (auto MO : LAFI->getJumpInfoJTIMI(Idx)->operands()) {
-      if (!MO.isJTI())
-        continue;
-      OutStreamer->emitValue(
-          MCSymbolRefExpr::create(GetJTISymbol(MO.getIndex()), OutContext),
-          Size);
-      break;
-    }
+    OutStreamer->emitValue(
+        MCSymbolRefExpr::create(
+            GetJTISymbol(LAFI->getJumpInfoJTIMO(Idx)->getIndex()), OutContext),
+        Size);
   }
 }
 
diff --git a/llvm/lib/Target/LoongArch/LoongArchExpandPseudoInsts.cpp b/llvm/lib/Target/LoongArch/LoongArchExpandPseudoInsts.cpp
index 2ceec8b0089a50..4a10f2e282d133 100644
--- a/llvm/lib/Target/LoongArch/LoongArchExpandPseudoInsts.cpp
+++ b/llvm/lib/Target/LoongArch/LoongArchExpandPseudoInsts.cpp
@@ -617,14 +617,14 @@ void LoongArchPreRAExpandPseudo::annotateTableJump(
   MachineFunction *MF = MBB.getParent();
   MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
 
-  bool IsFinded = false;
+  bool IsFound = false;
 
   std::function<void(MachineInstr *, int)> FindJTIMI = [&](MachineInstr *MInst,
                                                            int FindDepth) {
     if (FindDepth < 0)
       return;
     for (auto &MO : MInst->all_uses()) {
-      if (IsFinded)
+      if (IsFound)
         return;
       Register Reg = MO.getReg();
       if (!Reg.isVirtual())
@@ -633,12 +633,12 @@ void LoongArchPreRAExpandPseudo::annotateTableJump(
       if (!DefMI)
         continue;
       for (unsigned Idx = 0; Idx < DefMI->getNumOperands(); ++Idx) {
-        if (DefMI->getOperand(Idx).isJTI()) {
+        MachineOperand &MO = DefMI->getOperand(Idx);
+        if (MO.isJTI()) {
           MBBI->setPreInstrSymbol(
               *MF, MF->getContext().createNamedTempSymbol("jrtb_"));
-          MF->getInfo<LoongArchMachineFunctionInfo>()->setJumpInfo(&*MBBI,
-                                                                   DefMI);
-          IsFinded = true;
+          MF->getInfo<LoongArchMachineFunctionInfo>()->setJumpInfo(&*MBBI, &MO);
+          IsFound = true;
           return;
         }
       }
diff --git a/llvm/lib/Target/LoongArch/LoongArchMachineFunctionInfo.h b/llvm/lib/Target/LoongArch/LoongArchMachineFunctionInfo.h
index 252c057f4bbc05..d9a5bfb78fe45d 100644
--- a/llvm/lib/Target/LoongArch/LoongArchMachineFunctionInfo.h
+++ b/llvm/lib/Target/LoongArch/LoongArchMachineFunctionInfo.h
@@ -40,7 +40,7 @@ class LoongArchMachineFunctionInfo : public MachineFunctionInfo {
   SmallVector<Register, 8> SExt32Registers;
 
   /// TODO: comments, fix name?
-  SmallVector<std::pair<MachineInstr *, MachineInstr *>, 4> JumpInfos;
+  SmallVector<std::pair<MachineInstr *, MachineOperand *>, 4> JumpInfos;
 
 public:
   LoongArchMachineFunctionInfo(const Function &F,
@@ -74,12 +74,14 @@ class LoongArchMachineFunctionInfo : public MachineFunctionInfo {
   bool isSExt32Register(Register Reg) const {
     return is_contained(SExt32Registers, Reg);
   }
-  void setJumpInfo(MachineInstr *JrMI, MachineInstr *JTIMI) {
-    JumpInfos.push_back(std::make_pair(JrMI, JTIMI));
+  void setJumpInfo(MachineInstr *JrMI, MachineOperand *JTIMO) {
+    JumpInfos.push_back(std::make_pair(JrMI, JTIMO));
   }
   unsigned getJumpInfoSize() { return JumpInfos.size(); }
   MachineInstr *getJumpInfoJrMI(unsigned Idx) { return JumpInfos[Idx].first; }
-  MachineInstr *getJumpInfoJTIMI(unsigned Idx) { return JumpInfos[Idx].second; }
+  MachineOperand *getJumpInfoJTIMO(unsigned Idx) {
+    return JumpInfos[Idx].second;
+  }
 };
 
 } // end namespace llvm



More information about the cfe-commits mailing list