[llvm] machinebackend pass test (PR #122487)

Kun Liu via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 10 18:05:54 PST 2025


https://github.com/Ryan-hub-bit updated https://github.com/llvm/llvm-project/pull/122487

>From 9e95cde15ce30630e7118fe046b6dff2d7adf7d9 Mon Sep 17 00:00:00 2001
From: Liu <kliu14 at tulane.edu>
Date: Fri, 10 Jan 2025 10:21:22 -0600
Subject: [PATCH 1/3] machinebackend pass test

---
 llvm/lib/Target/X86/X86MatchJumptablePass.cpp | 44 +++++++++++++++++++
 llvm/lib/Target/X86/X86MatchJumptablePass.h   |  0
 2 files changed, 44 insertions(+)
 create mode 100644 llvm/lib/Target/X86/X86MatchJumptablePass.cpp
 create mode 100644 llvm/lib/Target/X86/X86MatchJumptablePass.h

diff --git a/llvm/lib/Target/X86/X86MatchJumptablePass.cpp b/llvm/lib/Target/X86/X86MatchJumptablePass.cpp
new file mode 100644
index 00000000000000..bfb6b1b7f89f18
--- /dev/null
+++ b/llvm/lib/Target/X86/X86MatchJumptablePass.cpp
@@ -0,0 +1,44 @@
+#include "X86.h"
+#include "llvm/CodeGen/MachineFunctionPass.h"
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/CodeGen/MachineRegisterInfo.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Support/raw_ostream.h"
+
+
+using namespace llvm;
+
+namespace {
+  class X86MatchJumptablePass : public MachineFunctionPass {
+  public:
+    static char ID;
+
+    X86MatchJumptablePass() : MachineFunctionPass(ID) {}
+
+    bool runOnMachineFunction(MachineFunction &MF) override {
+      LLVM_DEBUG(dbgs() << "Running X86MyBackendPass on function: "
+                        << MF.getName() << "\n");
+
+      // Example: Iterate through instructions
+      for (auto &MBB : MF) {
+        for (auto &MI : MBB) {
+          // Process instructions here
+          LLVM_DEBUG(dbgs() << "Instruction: " << MI << "\n");
+        }
+      }
+
+      return false; // Return true if the pass modifies the function
+    }
+
+    StringRef getPassName() const override {
+      return "X86 My Backend Pass";
+    }
+  };
+}
+
+char X86MatchJumptablePass::ID = 0;
+
+// Register the pass
+FunctionPass *llvm::createX86MatchJumptablePass() {
+  return new X86MatchJumptablePass();
+}
diff --git a/llvm/lib/Target/X86/X86MatchJumptablePass.h b/llvm/lib/Target/X86/X86MatchJumptablePass.h
new file mode 100644
index 00000000000000..e69de29bb2d1d6

>From 27bee8dbc8fa03e331302e799429b7450c2b1166 Mon Sep 17 00:00:00 2001
From: ryan <liu864579887 at gmail.com>
Date: Fri, 10 Jan 2025 17:01:39 -0600
Subject: [PATCH 2/3] good

---
 .../llvm/Transforms/IPO/JumpTableFinder.h     | 62 +++++++++++++++++++
 llvm/lib/Target/X86/CMakeLists.txt            |  1 +
 llvm/lib/Target/X86/X86MatchJumptablePass.cpp | 15 +++--
 llvm/lib/Target/X86/X86MatchJumptablePass.h   | 14 +++++
 llvm/lib/Target/X86/X86TargetMachine.cpp      |  3 +-
 5 files changed, 90 insertions(+), 5 deletions(-)
 create mode 100644 llvm/include/llvm/Transforms/IPO/JumpTableFinder.h

diff --git a/llvm/include/llvm/Transforms/IPO/JumpTableFinder.h b/llvm/include/llvm/Transforms/IPO/JumpTableFinder.h
new file mode 100644
index 00000000000000..9d2fb3b405f8c8
--- /dev/null
+++ b/llvm/include/llvm/Transforms/IPO/JumpTableFinder.h
@@ -0,0 +1,62 @@
+// #ifndef LLVM_ANALYSIS_JUMPTABLEFINDERPASS_H
+// #define LLVM_ANALYSIS_JUMPTABLEFINDERPASS_H
+
+// #include "llvm/IR/PassManager.h"
+// #include "llvm/IR/Module.h"
+// #include "llvm/Support/raw_ostream.h"
+// #include <set>
+
+// namespace llvm {
+
+// class JumptableFinderPass : public PassInfoMixin<JumptableFinderPass> {
+// public:
+//     /// Main entry point for the pass. Analyzes the module to find and analyze jump tables.
+//     PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
+//     /// Implementation of the jump table finder.
+//     void jumptableFinderImpl(Module &M);
+
+//     /// Analyze a SwitchInst for potential jump table patterns.
+//     void findJumpTableFromSwitch(SwitchInst *SI);
+
+//     /// Analyze a GetElementPtrInst for jump table patterns.
+//     void analyzeJumpTable(GetElementPtrInst *GEP);
+
+//     /// Analyze the index computation of a jump table.
+//     void analyzeIndex(Value *Index);
+
+//     /// Find all potential targets for a jump table.
+//     void findTargets(GetElementPtrInst *GEP, std::set<BasicBlock*> &Targets);
+
+//     /// Check the density of a SwitchInst's cases to determine if it forms a jump table.
+//     bool checkDensity(SwitchInst *SI);
+
+//     /// Check if a GetElementPtrInst leads to an indirect branch.
+//     bool leadsToIndirectBranch(GetElementPtrInst *GEP);
+// };
+
+// } // namespace llvm
+
+// #endif // LLVM_ANALYSIS_JUMPTABLEFINDERPASS_H
+
+#ifndef LLVM_TRANSFORMS_IPO_JUMPTABLEFINDER_H
+#define LLVM_TRANSFORMS_IPO_JUMPTABLEFINDER_H
+
+#include "llvm/IR/Module.h"
+#include "llvm/IR/PassManager.h" // For PassInfoMixin and PreservedAnalyses
+#include "llvm/IR/Function.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/Support/raw_ostream.h"
+#include <set>
+
+namespace llvm {
+
+class JumptableFinderPass : public PassInfoMixin<JumptableFinderPass> {
+public:
+    // Entry point for the pass
+    PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
+};
+
+} // namespace llvm
+
+#endif // LLVM_TRANSFORMS_IPO_JUMPTABLEFINDER_H
diff --git a/llvm/lib/Target/X86/CMakeLists.txt b/llvm/lib/Target/X86/CMakeLists.txt
index 9553a8619feb51..4be4576a6a9057 100644
--- a/llvm/lib/Target/X86/CMakeLists.txt
+++ b/llvm/lib/Target/X86/CMakeLists.txt
@@ -23,6 +23,7 @@ tablegen(LLVM X86GenFoldTables.inc -gen-x86-fold-tables -asmwriternum=1)
 add_public_tablegen_target(X86CommonTableGen)
 
 set(sources
+X86MatchJumptablePass.cpp
   X86ArgumentStackSlotRebase.cpp
   X86AsmPrinter.cpp
   X86AvoidTrailingCall.cpp
diff --git a/llvm/lib/Target/X86/X86MatchJumptablePass.cpp b/llvm/lib/Target/X86/X86MatchJumptablePass.cpp
index bfb6b1b7f89f18..c3683dacbdf8fe 100644
--- a/llvm/lib/Target/X86/X86MatchJumptablePass.cpp
+++ b/llvm/lib/Target/X86/X86MatchJumptablePass.cpp
@@ -4,7 +4,9 @@
 #include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/Support/Debug.h"
 #include "llvm/Support/raw_ostream.h"
+#include "X86MatchJumptablePass.h"
 
+#define DEBUG_TYPE "x86-my-pass"
 
 using namespace llvm;
 
@@ -38,7 +40,12 @@ namespace {
 
 char X86MatchJumptablePass::ID = 0;
 
-// Register the pass
-FunctionPass *llvm::createX86MatchJumptablePass() {
-  return new X86MatchJumptablePass();
-}
+// Ensure the function is in the llvm namespace
+namespace llvm {
+  
+  // Define the pass
+  FunctionPass *createX86MatchJumptablePass() {
+    return new X86MatchJumptablePass();
+  }
+
+} // end llvm namespace
diff --git a/llvm/lib/Target/X86/X86MatchJumptablePass.h b/llvm/lib/Target/X86/X86MatchJumptablePass.h
index e69de29bb2d1d6..67233bf729aec6 100644
--- a/llvm/lib/Target/X86/X86MatchJumptablePass.h
+++ b/llvm/lib/Target/X86/X86MatchJumptablePass.h
@@ -0,0 +1,14 @@
+#ifndef LLVM_LIB_TARGET_X86_X86MATCHJUMPTABLEPASS_H
+#define LLVM_LIB_TARGET_X86_X86MATCHJUMPTABLEPASS_H
+
+
+#pragma once
+#include "llvm/CodeGen/MachineFunctionPass.h"
+
+namespace llvm {
+
+  FunctionPass *createX86MatchJumptablePass();
+
+} // end namespace llvm
+
+#endif // LLVM_LIB_TARGET_X86_X86MATCHJUMPTABLEPASS_H
\ No newline at end of file
diff --git a/llvm/lib/Target/X86/X86TargetMachine.cpp b/llvm/lib/Target/X86/X86TargetMachine.cpp
index 20dfdd27b33df6..b9c13fda07dfc7 100644
--- a/llvm/lib/Target/X86/X86TargetMachine.cpp
+++ b/llvm/lib/Target/X86/X86TargetMachine.cpp
@@ -12,6 +12,7 @@
 
 #include "X86TargetMachine.h"
 #include "MCTargetDesc/X86MCTargetDesc.h"
+#include "X86MatchJumptablePass.h"  // Include the header with the function declaration
 #include "TargetInfo/X86TargetInfo.h"
 #include "X86.h"
 #include "X86MachineFunctionInfo.h"
@@ -464,7 +465,7 @@ MachineFunctionInfo *X86TargetMachine::createMachineFunctionInfo(
 
 void X86PassConfig::addIRPasses() {
   addPass(createAtomicExpandLegacyPass());
-
+  addPass(llvm::createX86MatchJumptablePass());
   // We add both pass anyway and when these two passes run, we skip the pass
   // based on the option level and option attribute.
   addPass(createX86LowerAMXIntrinsicsPass());

>From 0dc2ceac51b6c4182a8816b215146b3b7a68c1bd Mon Sep 17 00:00:00 2001
From: Liu <kliu14 at tulane.edu>
Date: Fri, 10 Jan 2025 20:05:42 -0600
Subject: [PATCH 3/3] jumptable

---
 llvm/lib/Target/X86/CMakeLists.txt            |   2 +-
 llvm/lib/Target/X86/X86MatchJumptablePass.cpp | 102 +++++++++++++++---
 llvm/lib/Target/X86/X86MatchJumptablePass.h   |  10 +-
 llvm/lib/Target/X86/X86TargetMachine.cpp      |   5 +-
 4 files changed, 99 insertions(+), 20 deletions(-)

diff --git a/llvm/lib/Target/X86/CMakeLists.txt b/llvm/lib/Target/X86/CMakeLists.txt
index 4be4576a6a9057..f5dcf13e47ed25 100644
--- a/llvm/lib/Target/X86/CMakeLists.txt
+++ b/llvm/lib/Target/X86/CMakeLists.txt
@@ -23,7 +23,7 @@ tablegen(LLVM X86GenFoldTables.inc -gen-x86-fold-tables -asmwriternum=1)
 add_public_tablegen_target(X86CommonTableGen)
 
 set(sources
-X86MatchJumptablePass.cpp
+  X86MatchJumptablePass.cpp
   X86ArgumentStackSlotRebase.cpp
   X86AsmPrinter.cpp
   X86AvoidTrailingCall.cpp
diff --git a/llvm/lib/Target/X86/X86MatchJumptablePass.cpp b/llvm/lib/Target/X86/X86MatchJumptablePass.cpp
index c3683dacbdf8fe..d8263af59a855d 100644
--- a/llvm/lib/Target/X86/X86MatchJumptablePass.cpp
+++ b/llvm/lib/Target/X86/X86MatchJumptablePass.cpp
@@ -6,7 +6,7 @@
 #include "llvm/Support/raw_ostream.h"
 #include "X86MatchJumptablePass.h"
 
-#define DEBUG_TYPE "x86-my-pass"
+#define DEBUG_TYPE "match-jump-table"
 
 using namespace llvm;
 
@@ -18,23 +18,97 @@ namespace {
     X86MatchJumptablePass() : MachineFunctionPass(ID) {}
 
     bool runOnMachineFunction(MachineFunction &MF) override {
-      LLVM_DEBUG(dbgs() << "Running X86MyBackendPass on function: "
-                        << MF.getName() << "\n");
-
-      // Example: Iterate through instructions
-      for (auto &MBB : MF) {
-        for (auto &MI : MBB) {
-          // Process instructions here
-          LLVM_DEBUG(dbgs() << "Instruction: " << MI << "\n");
+    LLVM_DEBUG(dbgs() << "Analyzing jump tables in function: " << MF.getName() << "\n");
+
+    // Get jump table information
+    MachineJumpTableInfo *JumpTableInfo = MF.getJumpTableInfo();
+    if (!JumpTableInfo) {
+      LLVM_DEBUG(dbgs() << "No jump tables in this function.\n");
+      return false;
+    }
+    // Assuming JumpTableInfo is available
+    for (unsigned JTIndex = 0; JTIndex < JumpTableInfo->getJumpTables().size(); ++JTIndex) {
+  const MachineJumpTableEntry &JTEntry = JumpTableInfo->getJumpTables()[JTIndex];
+  
+  LLVM_DEBUG(dbgs() << "Jump Table #" << JTIndex << " Base Address: " << JTEntry.BaseAddress << "\n");
+
+  // Iterate through the entries (target basic blocks) in this jump table
+  for (auto *MBB : JTEntry.MBBs) {
+    LLVM_DEBUG(dbgs() << "  Target BasicBlock: " << MBB->getName() << " Address: " << MBB->getAddress() << "\n");
+     }
+    
+
+      // Trace potential indirect jumps related to this jump table
+      traceIndirectJumps(MF, JTIndex, JumpTableInfo);
+    }
+    return false;
+
+}
+
+  void traceIndirectJumps(MachineFunction &MF, unsigned JTIndex, MachineJumpTableInfo *JumpTableInfo) {
+    const MachineJumpTableEntry &JTEntry = JumpTableInfo->getJumpTables()[JTIndex];
+
+    for (auto &MBB : MF) {
+      for (auto &MI : MBB) {
+        if (MI.isIndirectBranch()) {
+          LLVM_DEBUG(dbgs() << "Found indirect jump: " << MI << "\n");
+
+          // Analyze data flow to check if this jump is related to the jump table
+          if (isJumpTableRelated(MI, JTEntry, MF)) {
+            LLVM_DEBUG(dbgs() << "This indirect jump is related to Jump Table #" << JTIndex << "\n");
+          }
         }
       }
+    }
+  }
+
+  bool isJumpTableRelated(MachineInstr &MI, const MachineJumpTableEntry &JTEntry, MachineFunction &MF) {
+  for (unsigned OpIdx = 0; OpIdx < MI.getNumOperands(); ++OpIdx) {
+    const MachineOperand &Op = MI.getOperand(OpIdx);
 
-      return false; // Return true if the pass modifies the function
+    if (Op.isReg()) {
+      Register Reg = Op.getReg();
+      MachineRegisterInfo &MRI = MF.getRegInfo();
+      // Check if any of the definitions of the register are related to a jump table load
+      for (MachineInstr &DefMI : MRI.def_instructions(Reg)) {
+        if (isJumpTableLoad(DefMI, JTEntry)) {
+          return true;
+        }
+      }
+    } else if (Op.isImm()) {
+      // Check if the immediate operand might be an offset/index into the jump table
+      int64_t ImmValue = Op.getImm();
+      
+      // For example, if the jump table has 10 entries, check if the immediate is between 0 and 9
+      if (ImmValue >= 0 && ImmValue < JTEntry.MBBs.size()) {
+        // This immediate value could be an index into the jump table
+        LLVM_DEBUG(dbgs() << "Immediate operand is a possible jump table index: " << ImmValue << "\n");
+        return true;
+      }
     }
+  }
+  return false;
+}
 
-    StringRef getPassName() const override {
-      return "X86 My Backend Pass";
+bool isJumpTableLoad(MachineInstr &MI, const MachineJumpTableEntry &JTEntry) {
+    if (MI.mayLoad()) {
+        for (unsigned i = 0; i < MI.getNumOperands(); ++i) {
+            const MachineOperand &Op = MI.getOperand(i);
+            if (Op.isGlobal() && Op.getGlobal() == JTEntry.BaseAddress) {
+                return true;
+            }
+        }
     }
+    return false;
+}
+
+  StringRef getPassName() const override {
+    return "Match Jump Table Pass";
+  }
+
+    // StringRef getPassName() const override {
+    //   return "X86 My Backend Pass";
+    // }
   };
 }
 
@@ -49,3 +123,7 @@ namespace llvm {
   }
 
 } // end llvm namespace
+
+static RegisterPass<X86MatchJumptablePass> X("match-jump-table", "Match Jump Table Pass", false, false);
+
+
diff --git a/llvm/lib/Target/X86/X86MatchJumptablePass.h b/llvm/lib/Target/X86/X86MatchJumptablePass.h
index 67233bf729aec6..ac6fc315b025ad 100644
--- a/llvm/lib/Target/X86/X86MatchJumptablePass.h
+++ b/llvm/lib/Target/X86/X86MatchJumptablePass.h
@@ -1,14 +1,14 @@
 #ifndef LLVM_LIB_TARGET_X86_X86MATCHJUMPTABLEPASS_H
 #define LLVM_LIB_TARGET_X86_X86MATCHJUMPTABLEPASS_H
 
-
-#pragma once
 #include "llvm/CodeGen/MachineFunctionPass.h"
 
 namespace llvm {
 
-  FunctionPass *createX86MatchJumptablePass();
+/// \brief Creates the X86MatchJumptablePass.
+/// This pass analyzes and processes jump tables in X86 backend code generation.
+FunctionPass *createX86MatchJumptablePass();
 
-} // end namespace llvm
+} // namespace llvm
 
-#endif // LLVM_LIB_TARGET_X86_X86MATCHJUMPTABLEPASS_H
\ No newline at end of file
+#endif // LLVM_LIB_TARGET_X86_X86MATCHJUMPTABLEPASS_H
diff --git a/llvm/lib/Target/X86/X86TargetMachine.cpp b/llvm/lib/Target/X86/X86TargetMachine.cpp
index b9c13fda07dfc7..7faeeb2af64e8e 100644
--- a/llvm/lib/Target/X86/X86TargetMachine.cpp
+++ b/llvm/lib/Target/X86/X86TargetMachine.cpp
@@ -11,8 +11,8 @@
 //===----------------------------------------------------------------------===//
 
 #include "X86TargetMachine.h"
+#include "X86MatchJumptablePass.h"
 #include "MCTargetDesc/X86MCTargetDesc.h"
-#include "X86MatchJumptablePass.h"  // Include the header with the function declaration
 #include "TargetInfo/X86TargetInfo.h"
 #include "X86.h"
 #include "X86MachineFunctionInfo.h"
@@ -465,7 +465,7 @@ MachineFunctionInfo *X86TargetMachine::createMachineFunctionInfo(
 
 void X86PassConfig::addIRPasses() {
   addPass(createAtomicExpandLegacyPass());
-  addPass(llvm::createX86MatchJumptablePass());
+
   // We add both pass anyway and when these two passes run, we skip the pass
   // based on the option level and option attribute.
   addPass(createX86LowerAMXIntrinsicsPass());
@@ -597,6 +597,7 @@ void X86PassConfig::addPreEmitPass() {
     addPass(createBreakFalseDeps());
   }
 
+  addPass(createX86MatchJumptablePass());
   addPass(createX86IndirectBranchTrackingPass());
 
   addPass(createX86IssueVZeroUpperPass());



More information about the llvm-commits mailing list