[llvm] Add LVN Pass (PR #66833)

Aleksei Romanov via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 19 15:12:57 PDT 2023


https://github.com/al-romanov created https://github.com/llvm/llvm-project/pull/66833

None

>From 58aa6813fcdbdfcd7e3246d0d3d0441ecdb3e4cb Mon Sep 17 00:00:00 2001
From: Aleksei Romanov <raa_2001 at mail.ru>
Date: Wed, 20 Sep 2023 01:10:02 +0300
Subject: [PATCH 1/2] [LVN] Add tests on LVN Pass (NFC)

---
 llvm/test/Transforms/LVN/simple_test.ll | 9 +++++++++
 1 file changed, 9 insertions(+)
 create mode 100644 llvm/test/Transforms/LVN/simple_test.ll

diff --git a/llvm/test/Transforms/LVN/simple_test.ll b/llvm/test/Transforms/LVN/simple_test.ll
new file mode 100644
index 000000000000000..79b7a2d4e408f44
--- /dev/null
+++ b/llvm/test/Transforms/LVN/simple_test.ll
@@ -0,0 +1,9 @@
+define dso_local i32 @f(i32 noundef %a, i32 noundef %b, i32 noundef %c) {
+entry:
+  %add = add i32 %a, %b
+  %mul = mul i32 %b, %c
+  %add1 = add i32 %a, %b
+  %mul2 = mul i32 %add, %mul
+  %add3 = add i32 %mul2, %add1
+  ret i32 %add3
+}

>From dde94170e94635540368460e697a8b445eccf2af Mon Sep 17 00:00:00 2001
From: Aleksei Romanov <raa_2001 at mail.ru>
Date: Wed, 20 Sep 2023 01:11:20 +0300
Subject: [PATCH 2/2] [LVN] Add simple LVN Pass

---
 llvm/include/llvm/Transforms/Scalar/LVN.h | 19 ++++++++++++
 llvm/lib/Passes/PassBuilder.cpp           |  1 +
 llvm/lib/Passes/PassRegistry.def          |  1 +
 llvm/lib/Transforms/Scalar/CMakeLists.txt |  1 +
 llvm/lib/Transforms/Scalar/LVN.cpp        | 38 +++++++++++++++++++++++
 5 files changed, 60 insertions(+)
 create mode 100644 llvm/include/llvm/Transforms/Scalar/LVN.h
 create mode 100644 llvm/lib/Transforms/Scalar/LVN.cpp

diff --git a/llvm/include/llvm/Transforms/Scalar/LVN.h b/llvm/include/llvm/Transforms/Scalar/LVN.h
new file mode 100644
index 000000000000000..f20b66c1d98f774
--- /dev/null
+++ b/llvm/include/llvm/Transforms/Scalar/LVN.h
@@ -0,0 +1,19 @@
+#ifndef LLVM_TRANSFORMS_SCALAR_LVN_H
+#define LLVM_TRANSFORMS_SCALAR_LVN_H
+
+#include "llvm/IR/PassManager.h"
+#include "llvm/Pass.h"
+
+namespace llvm {
+
+class LVNPass : public PassInfoMixin<LVNPass> {
+public:
+  PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+
+private:
+  void runImpl(BasicBlock &BB);
+};
+
+} // end namespace llvm
+
+#endif // LLVM_TRANSFORMS_SCALAR_LVN_H
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index 5c7f26109930c9d..dc99c9408a20cda 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -201,6 +201,7 @@
 #include "llvm/Transforms/Scalar/LowerGuardIntrinsic.h"
 #include "llvm/Transforms/Scalar/LowerMatrixIntrinsics.h"
 #include "llvm/Transforms/Scalar/LowerWidenableCondition.h"
+#include "llvm/Transforms/Scalar/LVN.h"
 #include "llvm/Transforms/Scalar/MakeGuardsExplicit.h"
 #include "llvm/Transforms/Scalar/MemCpyOptimizer.h"
 #include "llvm/Transforms/Scalar/MergeICmps.h"
diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def
index b9aa015d02dd95d..1729eb6120db72a 100644
--- a/llvm/lib/Passes/PassRegistry.def
+++ b/llvm/lib/Passes/PassRegistry.def
@@ -358,6 +358,7 @@ FUNCTION_PASS("loop-simplify", LoopSimplifyPass())
 FUNCTION_PASS("loop-sink", LoopSinkPass())
 FUNCTION_PASS("lowerinvoke", LowerInvokePass())
 FUNCTION_PASS("lowerswitch", LowerSwitchPass())
+FUNCTION_PASS("lvn", LVNPass())
 FUNCTION_PASS("mem2reg", PromotePass())
 FUNCTION_PASS("memcpyopt", MemCpyOptPass())
 FUNCTION_PASS("mergeicmps", MergeICmpsPass())
diff --git a/llvm/lib/Transforms/Scalar/CMakeLists.txt b/llvm/lib/Transforms/Scalar/CMakeLists.txt
index eb008c15903a744..1f39809420e4c7b 100644
--- a/llvm/lib/Transforms/Scalar/CMakeLists.txt
+++ b/llvm/lib/Transforms/Scalar/CMakeLists.txt
@@ -52,6 +52,7 @@ add_llvm_component_library(LLVMScalarOpts
   LowerGuardIntrinsic.cpp
   LowerMatrixIntrinsics.cpp
   LowerWidenableCondition.cpp
+  LVN.cpp
   MakeGuardsExplicit.cpp
   MemCpyOptimizer.cpp
   MergeICmps.cpp
diff --git a/llvm/lib/Transforms/Scalar/LVN.cpp b/llvm/lib/Transforms/Scalar/LVN.cpp
new file mode 100644
index 000000000000000..e5c0deb21dda7c2
--- /dev/null
+++ b/llvm/lib/Transforms/Scalar/LVN.cpp
@@ -0,0 +1,38 @@
+#include "llvm/Transforms/Scalar/LVN.h"
+
+#include <map>
+#include <tuple>
+#include <unordered_map>
+
+#include "llvm/IR/InstrTypes.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace llvm;
+
+PreservedAnalyses LVNPass::run(Function &F, FunctionAnalysisManager &AM) {
+  for (auto &BB : F) {
+    runImpl(BB);
+  }
+  return PreservedAnalyses::all();
+}
+
+void LVNPass::runImpl(BasicBlock &BB) {
+  std::map<std::tuple<Instruction::BinaryOps, Value *, Value *>, Value *>
+      InstrToValue;
+  for (auto &I : BB) {
+    BinaryOperator *BO = dyn_cast<BinaryOperator>(&I);
+    if (!BO) {
+      continue;
+    }
+    Value *RHS = BO->getOperand(0);
+    Value *LHS = BO->getOperand(1);
+    auto InstrTuple = std::make_tuple(BO->getOpcode(), RHS, LHS);
+    Value *BOValue = static_cast<Value *>(BO);
+    auto FoundInstrIt = InstrToValue.find(InstrTuple);
+    if (FoundInstrIt == InstrToValue.end()) {
+      InstrToValue.insert({InstrTuple, BOValue});
+    } else {
+      BO->replaceAllUsesWith(FoundInstrIt->second);
+    }
+  }
+}



More information about the llvm-commits mailing list