本笔记目的是自建一个 Pass 流水来实现想要的优化功能,可以直接参考 patch:

diff --git a/llvm/lib/Passes/PassBuilderPipelines.cpp b/llvm/lib/Passes/PassBuilderPipelines.cpp
index 546a5eb1ec28..e68b497a23ab 100644
--- a/llvm/lib/Passes/PassBuilderPipelines.cpp
+++ b/llvm/lib/Passes/PassBuilderPipelines.cpp
@@ -305,6 +305,11 @@ static cl::opt<std::string> InstrumentColdFuncOnlyPath(
              "with --pgo-instrument-cold-function-only)"),
     cl::Hidden);
 
+static cl::opt<bool> BuildCustomPipeline(
+    "custom-pipeline", cl::init(false), cl::Hidden,
+    cl::desc(
+        "Enable pass to customize pipeline"));
+
 extern cl::opt<std::string> UseCtxProfile;
 extern cl::opt<bool> PGOInstrumentColdFunctionOnly;
 
@@ -2189,6 +2194,12 @@ PassBuilder::buildLTODefaultPipeline(OptimizationLevel Level,
   return MPM;
 }
 
+FunctionPassManager buildCustomFuncPipeline() {
+  FunctionPassManager FPM;
+  FPM.addPass(EarlyCSEPass(true /* Enable mem-ssa. */));
+  return FPM;
+}
+
 ModulePassManager
 PassBuilder::buildO0DefaultPipeline(OptimizationLevel Level,
                                     ThinOrFullLTOPhase Phase) {
@@ -2196,7 +2207,11 @@ PassBuilder::buildO0DefaultPipeline(OptimizationLevel Level,
          "buildO0DefaultPipeline should only be used with O0");
 
   ModulePassManager MPM;
-
+  if (BuildCustomPipeline) {
+    FunctionPassManager FPM = buildCustomFuncPipeline();
+    MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
+    return MPM;
+  }
   // Perform pseudo probe instrumentation in O0 mode. This is for the
   // consistency between different build modes. For example, a LTO build can be
   // mixed with an O0 prelink and an O2 postlink. Loading a sample profile in

我这里仅仅启用了一个 early-cse Pass 以供验证,当使用:
opt -O0 source_1.ll -custom-pipeline -debug-only=early-cse

是能看到 EarlyCSE 的执行日志的。