[flang-commits] [flang] 9c0acc4 - [flang] Run algebraic simplification optimization pass.

Slava Zakharin via flang-commits flang-commits at lists.llvm.org
Thu Jul 21 11:55:20 PDT 2022


Author: Slava Zakharin
Date: 2022-07-21T11:43:39-07:00
New Revision: 9c0acc42e8d223de6d5c39ce2c26a83ad147b262

URL: https://github.com/llvm/llvm-project/commit/9c0acc42e8d223de6d5c39ce2c26a83ad147b262
DIFF: https://github.com/llvm/llvm-project/commit/9c0acc42e8d223de6d5c39ce2c26a83ad147b262.diff

LOG: [flang] Run algebraic simplification optimization pass.

Try 2 to merge 4fbd1d6c872e8228f23a6e13914222af40ca6461.

Flang algebraic simplification pass will run algebraic simplification
rewrite patterns for Math/Complex/etc. dialects. It is enabled
under opt-for-speed optimization levels (i.e. for O1/O2/O3; Os/Oz will not
enable it).

With this change the FIR/MLIR optimization pipeline becomes affected
by the -O* optimization level switches. Until now these switches
only affected the middle-end and back-end.

Differential Revision: https://reviews.llvm.org/D130035

Added: 
    flang/lib/Optimizer/Transforms/AlgebraicSimplification.cpp
    flang/test/Driver/bbc-mlir-pass-pipeline.f90

Modified: 
    flang/include/flang/Optimizer/Transforms/Passes.h
    flang/include/flang/Optimizer/Transforms/Passes.td
    flang/include/flang/Tools/CLOptions.inc
    flang/lib/Frontend/FrontendActions.cpp
    flang/lib/Optimizer/Transforms/CMakeLists.txt
    flang/lib/Optimizer/Transforms/PassDetail.h
    flang/test/Driver/mlir-pass-pipeline.f90
    flang/test/Fir/basic-program.fir
    flang/tools/bbc/CMakeLists.txt
    flang/tools/bbc/bbc.cpp
    flang/tools/tco/CMakeLists.txt
    flang/tools/tco/tco.cpp

Removed: 
    


################################################################################
diff  --git a/flang/include/flang/Optimizer/Transforms/Passes.h b/flang/include/flang/Optimizer/Transforms/Passes.h
index 38c071f76d3a9..f9c48b374fdcb 100644
--- a/flang/include/flang/Optimizer/Transforms/Passes.h
+++ b/flang/include/flang/Optimizer/Transforms/Passes.h
@@ -39,6 +39,7 @@ std::unique_ptr<mlir::Pass>
 createMemoryAllocationPass(bool dynOnHeap, std::size_t maxStackSize);
 std::unique_ptr<mlir::Pass> createAnnotateConstantOperandsPass();
 std::unique_ptr<mlir::Pass> createSimplifyRegionLitePass();
+std::unique_ptr<mlir::Pass> createAlgebraicSimplificationPass();
 
 // declarative passes
 #define GEN_PASS_REGISTRATION

diff  --git a/flang/include/flang/Optimizer/Transforms/Passes.td b/flang/include/flang/Optimizer/Transforms/Passes.td
index 8bfc55d01cf83..69684c6861c31 100644
--- a/flang/include/flang/Optimizer/Transforms/Passes.td
+++ b/flang/include/flang/Optimizer/Transforms/Passes.td
@@ -196,4 +196,17 @@ def SimplifyRegionLite : Pass<"simplify-region-lite", "mlir::ModuleOp"> {
   let constructor = "::fir::createSimplifyRegionLitePass()";
 }
 
+def AlgebraicSimplification : Pass<"flang-algebraic-simplification"> {
+  let summary = "";
+  let description = [{
+    Run algebraic simplifications for Math/Complex/etc. dialect operations.
+    This is a flang specific pass, because we may want to "tune"
+    the rewrite patterns specifically for Fortran (e.g. increase
+    the limit for constant exponent value that defines the cases
+    when pow(x, constant) is transformed into a set of multiplications, etc.).
+  }];
+  let dependentDialects = [ "mlir::math::MathDialect" ];
+  let constructor = "::fir::createAlgebraicSimplificationPass()";
+}
+
 #endif // FLANG_OPTIMIZER_TRANSFORMS_PASSES

diff  --git a/flang/include/flang/Tools/CLOptions.inc b/flang/include/flang/Tools/CLOptions.inc
index c432d7d9cb839..6d5ed9cbee871 100644
--- a/flang/include/flang/Tools/CLOptions.inc
+++ b/flang/include/flang/Tools/CLOptions.inc
@@ -15,6 +15,7 @@
 #include "mlir/Transforms/Passes.h"
 #include "flang/Optimizer/CodeGen/CodeGen.h"
 #include "flang/Optimizer/Transforms/Passes.h"
+#include "llvm/Passes/OptimizationLevel.h"
 #include "llvm/Support/CommandLine.h"
 
 #define DisableOption(DOName, DOOption, DODescription) \
@@ -50,6 +51,10 @@ static llvm::cl::opt<bool> ignoreMissingTypeDescriptors(
     llvm::cl::init(false), llvm::cl::Hidden);
 
 namespace {
+/// Default optimization level used to create Flang pass pipeline is O0.
+const static llvm::OptimizationLevel &defaultOptLevel{
+    llvm::OptimizationLevel::O0};
+
 /// Optimizer Passes
 DisableOption(CfgConversion, "cfg-conversion", "disable FIR to CFG pass");
 DisableOption(FirAvc, "avc", "array value copy analysis and transformation");
@@ -150,7 +155,8 @@ inline void addExternalNameConversionPass(mlir::PassManager &pm) {
 /// incremental conversion of FIR.
 ///
 /// \param pm - MLIR pass manager that will hold the pipeline definition
-inline void createDefaultFIROptimizerPassPipeline(mlir::PassManager &pm) {
+inline void createDefaultFIROptimizerPassPipeline(
+    mlir::PassManager &pm, llvm::OptimizationLevel optLevel = defaultOptLevel) {
   // simplify the IR
   mlir::GreedyRewriteConfig config;
   config.enableRegionSimplification = false;
@@ -159,6 +165,9 @@ inline void createDefaultFIROptimizerPassPipeline(mlir::PassManager &pm) {
   pm.addNestedPass<mlir::func::FuncOp>(fir::createCharacterConversionPass());
   pm.addPass(mlir::createCanonicalizerPass(config));
   pm.addPass(fir::createSimplifyRegionLitePass());
+  // Algebraic simplifications may increase code size.
+  if (optLevel.isOptimizingForSpeed())
+    pm.addPass(fir::createAlgebraicSimplificationPass());
   pm.addPass(mlir::createCSEPass());
   fir::addMemoryAllocationOpt(pm);
 
@@ -191,9 +200,12 @@ inline void createDefaultFIRCodeGenPassPipeline(mlir::PassManager &pm) {
 /// Create a pass pipeline for lowering from MLIR to LLVM IR
 ///
 /// \param pm - MLIR pass manager that will hold the pipeline definition
-inline void createMLIRToLLVMPassPipeline(mlir::PassManager &pm) {
+/// \param optLevel - optimization level used for creating FIR optimization
+///   passes pipeline
+inline void createMLIRToLLVMPassPipeline(
+    mlir::PassManager &pm, llvm::OptimizationLevel optLevel = defaultOptLevel) {
   // Add default optimizer pass pipeline.
-  fir::createDefaultFIROptimizerPassPipeline(pm);
+  fir::createDefaultFIROptimizerPassPipeline(pm, optLevel);
 
   // Add codegen pass pipeline.
   fir::createDefaultFIRCodeGenPassPipeline(pm);

diff  --git a/flang/lib/Frontend/FrontendActions.cpp b/flang/lib/Frontend/FrontendActions.cpp
index df1b509aad685..7591e1a866227 100644
--- a/flang/lib/Frontend/FrontendActions.cpp
+++ b/flang/lib/Frontend/FrontendActions.cpp
@@ -479,11 +479,29 @@ CodeGenAction::~CodeGenAction() = default;
 
 #include "flang/Tools/CLOptions.inc"
 
+static llvm::OptimizationLevel
+mapToLevel(const Fortran::frontend::CodeGenOptions &opts) {
+  switch (opts.OptimizationLevel) {
+  default:
+    llvm_unreachable("Invalid optimization level!");
+  case 0:
+    return llvm::OptimizationLevel::O0;
+  case 1:
+    return llvm::OptimizationLevel::O1;
+  case 2:
+    return llvm::OptimizationLevel::O2;
+  case 3:
+    return llvm::OptimizationLevel::O3;
+  }
+}
+
 // Lower the previously generated MLIR module into an LLVM IR module
 void CodeGenAction::generateLLVMIR() {
   assert(mlirModule && "The MLIR module has not been generated yet.");
 
   CompilerInstance &ci = this->getInstance();
+  auto opts = ci.getInvocation().getCodeGenOpts();
+  llvm::OptimizationLevel level = mapToLevel(opts);
 
   fir::support::loadDialects(*mlirCtx);
   fir::support::registerLLVMTranslation(*mlirCtx);
@@ -495,7 +513,7 @@ void CodeGenAction::generateLLVMIR() {
   pm.enableVerifier(/*verifyPasses=*/true);
 
   // Create the pass pipeline
-  fir::createMLIRToLLVMPassPipeline(pm);
+  fir::createMLIRToLLVMPassPipeline(pm, level);
   mlir::applyPassManagerCLOptions(pm);
 
   // run the pass manager
@@ -630,22 +648,6 @@ static void generateMachineCodeOrAssemblyImpl(clang::DiagnosticsEngine &diags,
   codeGenPasses.run(llvmModule);
 }
 
-static llvm::OptimizationLevel
-mapToLevel(const Fortran::frontend::CodeGenOptions &opts) {
-  switch (opts.OptimizationLevel) {
-  default:
-    llvm_unreachable("Invalid optimization level!");
-  case 0:
-    return llvm::OptimizationLevel::O0;
-  case 1:
-    return llvm::OptimizationLevel::O1;
-  case 2:
-    return llvm::OptimizationLevel::O2;
-  case 3:
-    return llvm::OptimizationLevel::O3;
-  }
-}
-
 void CodeGenAction::runOptimizationPipeline(llvm::raw_pwrite_stream &os) {
   auto opts = getInstance().getInvocation().getCodeGenOpts();
   llvm::OptimizationLevel level = mapToLevel(opts);

diff  --git a/flang/lib/Optimizer/Transforms/AlgebraicSimplification.cpp b/flang/lib/Optimizer/Transforms/AlgebraicSimplification.cpp
new file mode 100644
index 0000000000000..25a6a8d47f278
--- /dev/null
+++ b/flang/lib/Optimizer/Transforms/AlgebraicSimplification.cpp
@@ -0,0 +1,37 @@
+//===- AlgebraicSimplification.cpp - Simplify algebraic expressions -------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+// This file defines a pass that applies algebraic simplifications
+// to operations of Math/Complex/etc. dialects that are used by Flang.
+// It is done as a Flang specific pass, because we may want to tune
+// the parameters of the patterns for Fortran programs.
+//===----------------------------------------------------------------------===//
+
+#include "PassDetail.h"
+#include "flang/Optimizer/Transforms/Passes.h"
+#include "mlir/Dialect/Math/Transforms/Passes.h"
+#include "mlir/Transforms/GreedyPatternRewriteDriver.h"
+
+using namespace mlir;
+
+namespace {
+struct AlgebraicSimplification
+    : public fir::AlgebraicSimplificationBase<AlgebraicSimplification> {
+
+  void runOnOperation() override;
+};
+} // namespace
+
+void AlgebraicSimplification::runOnOperation() {
+  RewritePatternSet patterns(&getContext());
+  populateMathAlgebraicSimplificationPatterns(patterns);
+  (void)applyPatternsAndFoldGreedily(getOperation(), std::move(patterns));
+}
+
+std::unique_ptr<mlir::Pass> fir::createAlgebraicSimplificationPass() {
+  return std::make_unique<AlgebraicSimplification>();
+}

diff  --git a/flang/lib/Optimizer/Transforms/CMakeLists.txt b/flang/lib/Optimizer/Transforms/CMakeLists.txt
index 86547792cd698..2fd4aceb735a7 100644
--- a/flang/lib/Optimizer/Transforms/CMakeLists.txt
+++ b/flang/lib/Optimizer/Transforms/CMakeLists.txt
@@ -10,6 +10,7 @@ add_flang_library(FIRTransforms
   MemRefDataFlowOpt.cpp
   RewriteLoop.cpp
   SimplifyRegionLite.cpp
+  AlgebraicSimplification.cpp
 
   DEPENDS
   FIRBuilder
@@ -23,6 +24,7 @@ add_flang_library(FIRTransforms
   MLIRAffineUtils
   MLIRFuncDialect
   MLIRLLVMDialect
+  MLIRMathTransforms
   MLIROpenACCDialect
   MLIROpenMPDialect
   FIRSupport

diff  --git a/flang/lib/Optimizer/Transforms/PassDetail.h b/flang/lib/Optimizer/Transforms/PassDetail.h
index c81993d239c1f..e64951efbfa4e 100644
--- a/flang/lib/Optimizer/Transforms/PassDetail.h
+++ b/flang/lib/Optimizer/Transforms/PassDetail.h
@@ -12,6 +12,7 @@
 #include "mlir/Dialect/Affine/IR/AffineOps.h"
 #include "mlir/Dialect/Func/IR/FuncOps.h"
 #include "mlir/Dialect/LLVMIR/LLVMDialect.h"
+#include "mlir/Dialect/Math/IR/Math.h"
 #include "mlir/Dialect/OpenACC/OpenACC.h"
 #include "mlir/Dialect/OpenMP/OpenMPDialect.h"
 #include "mlir/Pass/Pass.h"

diff  --git a/flang/test/Driver/bbc-mlir-pass-pipeline.f90 b/flang/test/Driver/bbc-mlir-pass-pipeline.f90
new file mode 100644
index 0000000000000..42aecb3fe1a16
--- /dev/null
+++ b/flang/test/Driver/bbc-mlir-pass-pipeline.f90
@@ -0,0 +1,45 @@
+! Test the MLIR pass pipeline
+
+! RUN: bbc --mlir-pass-statistics --mlir-pass-statistics-display=pipeline %s 2>&1 | FileCheck %s
+end program
+
+! CHECK: Pass statistics report
+
+! CHECK: Fortran::lower::VerifierPass
+! CHECK-NEXT: CSE
+! Ideally, we need an output with only the pass names, but
+! there is currently no way to get that, so in order to
+! guarantee that the passes are in the expected order
+! (i.e. use -NEXT) we have to check the statistics output as well.
+! CHECK-NEXT:   (S) 0 num-cse'd - Number of operations CSE'd
+! CHECK-NEXT:   (S) 0 num-dce'd - Number of operations DCE'd
+
+! CHECK-NEXT: 'func.func' Pipeline
+! CHECK-NEXT:   ArrayValueCopy
+! CHECK-NEXT:   CharacterConversion
+
+! CHECK-NEXT: Canonicalizer
+! CHECK-NEXT: SimplifyRegionLite
+! CHECK-NEXT: AlgebraicSimplification
+! CHECK-NEXT: CSE
+! CHECK-NEXT:   (S) 0 num-cse'd - Number of operations CSE'd
+! CHECK-NEXT:   (S) 0 num-dce'd - Number of operations DCE'd
+
+! CHECK-NEXT: 'func.func' Pipeline
+! CHECK-NEXT:   MemoryAllocationOpt
+
+! CHECK-NEXT: Inliner
+! CHECK-NEXT: CSE
+! CHECK-NEXT:   (S) 0 num-cse'd - Number of operations CSE'd
+! CHECK-NEXT:   (S) 0 num-dce'd - Number of operations DCE'd
+
+! CHECK-NEXT: 'func.func' Pipeline
+! CHECK-NEXT:   CFGConversion
+
+! CHECK-NEXT: SCFToControlFlow
+! CHECK-NEXT: Canonicalizer
+! CHECK-NEXT: SimplifyRegionLite
+! CHECK-NEXT: CSE
+! CHECK-NEXT:   (S) 0 num-cse'd - Number of operations CSE'd
+! CHECK-NEXT:   (S) 0 num-dce'd - Number of operations DCE'd
+! CHECK-NOT: LLVMIRLoweringPass

diff  --git a/flang/test/Driver/mlir-pass-pipeline.f90 b/flang/test/Driver/mlir-pass-pipeline.f90
index c11afc02f9122..78104285db577 100644
--- a/flang/test/Driver/mlir-pass-pipeline.f90
+++ b/flang/test/Driver/mlir-pass-pipeline.f90
@@ -1,38 +1,61 @@
 ! Test the MLIR pass pipeline
 
-! RUN: %flang_fc1 -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline %s -o - 2>&1 | FileCheck %s
+! RUN: %flang_fc1 -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline -o /dev/null %s 2>&1 | FileCheck --check-prefixes=ALL %s
+! -O0 is the default:
+! RUN: %flang_fc1 -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline %s -O0 -o /dev/null 2>&1 | FileCheck --check-prefixes=ALL %s
+! RUN: %flang_fc1 -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline %s -O2 -o /dev/null 2>&1 | FileCheck --check-prefixes=ALL,O2 %s
 
 ! REQUIRES: asserts
 
 end program
 
-! CHECK: Pass statistics report
-
-! CHECK: CSE
-! CHECK-LABEL: 'func.func' Pipeline
-! CHECK: ArrayValueCopy
-! CHECK: CharacterConversion
-! CHECK: Canonicalizer
-! CHECK: SimplifyRegionLite
-! CHECK: CSE
-
-! CHECK-LABEL: 'func.func' Pipeline
-! CHECK: MemoryAllocationOpt
-! CHECK: Inliner
-! CHECK: CSE
-
-! CHECK-LABEL: 'func.func' Pipeline
-! CHECK: CFGConversion
-! CHECK: SCFToControlFlow
-! CHECK: Canonicalizer
-! CHECK: SimplifyRegionLite
-! CHECK: CSE
-! CHECK: BoxedProcedurePass
-
-! CHECK-LABEL: 'func.func' Pipeline
-! CHECK: AbstractResultOpt
-! CHECK: CodeGenRewrite
-! CHECK: TargetRewrite
-! CHECK: ExternalNameConversion
-! CHECK: FIRToLLVMLowering
-! CHECK-NOT: LLVMIRLoweringPass
+! ALL: Pass statistics report
+
+! ALL: Fortran::lower::VerifierPass
+! ALL-NEXT: CSE
+! Ideally, we need an output with only the pass names, but
+! there is currently no way to get that, so in order to
+! guarantee that the passes are in the expected order
+! (i.e. use -NEXT) we have to check the statistics output as well.
+! ALL-NEXT:   (S) 0 num-cse'd - Number of operations CSE'd
+! ALL-NEXT:   (S) 0 num-dce'd - Number of operations DCE'd
+
+! ALL-NEXT: 'func.func' Pipeline
+! ALL-NEXT:   ArrayValueCopy
+! ALL-NEXT:   CharacterConversion
+
+! ALL-NEXT: Canonicalizer
+! ALL-NEXT: SimplifyRegionLite
+!  O2-NEXT: AlgebraicSimplification
+! ALL-NEXT: CSE
+! ALL-NEXT:   (S) 0 num-cse'd - Number of operations CSE'd
+! ALL-NEXT:   (S) 0 num-dce'd - Number of operations DCE'd
+
+! ALL-NEXT: 'func.func' Pipeline
+! ALL-NEXT:   MemoryAllocationOpt
+
+! ALL-NEXT: Inliner
+! ALL-NEXT: CSE
+! ALL-NEXT:   (S) 0 num-cse'd - Number of operations CSE'd
+! ALL-NEXT:   (S) 0 num-dce'd - Number of operations DCE'd
+
+! ALL-NEXT: 'func.func' Pipeline
+! ALL-NEXT:   CFGConversion
+
+! ALL-NEXT: SCFToControlFlow
+! ALL-NEXT: Canonicalizer
+! ALL-NEXT: SimplifyRegionLite
+! ALL-NEXT: CSE
+! ALL-NEXT:   (S) 0 num-cse'd - Number of operations CSE'd
+! ALL-NEXT:   (S) 0 num-dce'd - Number of operations DCE'd
+! ALL-NEXT: BoxedProcedurePass
+
+! ALL-NEXT: 'func.func' Pipeline
+! ALL-NEXT:   AbstractResultOpt
+
+! ALL-NEXT: CodeGenRewrite
+! ALL-NEXT:   (S) 0 num-dce'd - Number of operations eliminated
+! ALL-NEXT: TargetRewrite
+! ALL-NEXT: ExternalNameConversion
+! ALL-NEXT: FIRToLLVMLowering
+! ALL-NOT: LLVMIRLoweringPass

diff  --git a/flang/test/Fir/basic-program.fir b/flang/test/Fir/basic-program.fir
index a187780b596cd..8d1aab12c9a0e 100644
--- a/flang/test/Fir/basic-program.fir
+++ b/flang/test/Fir/basic-program.fir
@@ -16,30 +16,45 @@ func.func @_QQmain() {
 
 // PASSES: Pass statistics report
 
-// PASSES: CSE
-// PASSES-LABEL: 'func.func' Pipeline
-// PASSES: ArrayValueCopy
-// PASSES: CharacterConversion
-// PASSES: Canonicalizer
-// PASSES: SimplifyRegionLite
-// PASSES: CSE
-
-// PASSES-LABEL: 'func.func' Pipeline
-// PASSES: MemoryAllocationOpt
-// PASSES: Inliner
-// PASSES: CSE
-
-// PASSES-LABEL: 'func.func' Pipeline
-// PASSES: CFGConversion
-// PASSES: SCFToControlFlow
-// PASSES: Canonicalizer
-// PASSES: SimplifyRegionLite
-// PASSES: CSE
-// PASSES: BoxedProcedurePass
-
-// PASSES-LABEL: 'func.func' Pipeline
-// PASSES: AbstractResultOpt
-// PASSES: CodeGenRewrite
-// PASSES: TargetRewrite
-// PASSES: FIRToLLVMLowering
-// PASSES: LLVMIRLoweringPass
+// PASSES:      CSE
+// PASSES-NEXT:   (S) 0 num-cse'd - Number of operations CSE'd
+// PASSES-NEXT:   (S) 0 num-dce'd - Number of operations DCE'd
+
+// PASSES-NEXT: 'func.func' Pipeline
+// PASSES-NEXT:   ArrayValueCopy
+// PASSES-NEXT:   CharacterConversion
+
+// PASSES-NEXT: Canonicalizer
+// PASSES-NEXT: SimplifyRegionLite
+// PASSES-NEXT: AlgebraicSimplification
+// PASSES-NEXT: CSE
+// PASSES-NEXT:   (S) 0 num-cse'd - Number of operations CSE'd
+// PASSES-NEXT:   (S) 0 num-dce'd - Number of operations DCE'd
+
+// PASSES-NEXT: 'func.func' Pipeline
+// PASSES-NEXT:   MemoryAllocationOpt
+
+// PASSES-NEXT: Inliner
+// PASSES-NEXT: CSE
+// PASSES-NEXT:   (S) 0 num-cse'd - Number of operations CSE'd
+// PASSES-NEXT:   (S) 0 num-dce'd - Number of operations DCE'd
+
+// PASSES-NEXT: 'func.func' Pipeline
+// PASSES-NEXT:   CFGConversion
+
+// PASSES-NEXT: SCFToControlFlow
+// PASSES-NEXT: Canonicalizer
+// PASSES-NEXT: SimplifyRegionLite
+// PASSES-NEXT: CSE
+// PASSES-NEXT:   (S) 0 num-cse'd - Number of operations CSE'd
+// PASSES-NEXT:   (S) 0 num-dce'd - Number of operations DCE'd
+// PASSES-NEXT: BoxedProcedurePass
+
+// PASSES-NEXT: 'func.func' Pipeline
+// PASSES-NEXT:   AbstractResultOpt
+
+// PASSES-NEXT: CodeGenRewrite
+// PASSES-NEXT:   (S) 0 num-dce'd - Number of operations eliminated
+// PASSES-NEXT: TargetRewrite
+// PASSES-NEXT: FIRToLLVMLowering
+// PASSES-NEXT: LLVMIRLoweringPass

diff  --git a/flang/tools/bbc/CMakeLists.txt b/flang/tools/bbc/CMakeLists.txt
index 72e0355e5e9ed..5830531dff78c 100644
--- a/flang/tools/bbc/CMakeLists.txt
+++ b/flang/tools/bbc/CMakeLists.txt
@@ -19,4 +19,5 @@ FortranParser
 FortranEvaluate
 FortranSemantics
 FortranLower
+LLVMPasses
 )

diff  --git a/flang/tools/bbc/bbc.cpp b/flang/tools/bbc/bbc.cpp
index cb8c78427a798..56ca8f79afee2 100644
--- a/flang/tools/bbc/bbc.cpp
+++ b/flang/tools/bbc/bbc.cpp
@@ -47,6 +47,7 @@
 #include "mlir/Pass/PassRegistry.h"
 #include "mlir/Transforms/GreedyPatternRewriteDriver.h"
 #include "mlir/Transforms/Passes.h"
+#include "llvm/Passes/OptimizationLevel.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/ErrorOr.h"
 #include "llvm/Support/FileSystem.h"
@@ -255,8 +256,8 @@ static mlir::LogicalResult convertFortranSourceToMLIR(
     // run the default canned pipeline
     pm.addPass(std::make_unique<Fortran::lower::VerifierPass>());
 
-    // Add default optimizer pass pipeline.
-    fir::createDefaultFIROptimizerPassPipeline(pm);
+    // Add O2 optimizer pass pipeline.
+    fir::createDefaultFIROptimizerPassPipeline(pm, llvm::OptimizationLevel::O2);
   }
 
   if (mlir::succeeded(pm.run(mlirModule))) {

diff  --git a/flang/tools/tco/CMakeLists.txt b/flang/tools/tco/CMakeLists.txt
index 2794dcd99cf50..329c3864f3fe5 100644
--- a/flang/tools/tco/CMakeLists.txt
+++ b/flang/tools/tco/CMakeLists.txt
@@ -21,4 +21,5 @@ target_link_libraries(tco PRIVATE
   MLIRParser
   MLIRSupport
   MLIRVectorToLLVM
+  LLVMPasses
 )

diff  --git a/flang/tools/tco/tco.cpp b/flang/tools/tco/tco.cpp
index 0c9e2f528a3fe..5fe0d8114742b 100644
--- a/flang/tools/tco/tco.cpp
+++ b/flang/tools/tco/tco.cpp
@@ -24,6 +24,7 @@
 #include "mlir/Pass/Pass.h"
 #include "mlir/Pass/PassManager.h"
 #include "mlir/Transforms/Passes.h"
+#include "llvm/Passes/OptimizationLevel.h"
 #include "llvm/Support/CommandLine.h"
 #include "llvm/Support/ErrorOr.h"
 #include "llvm/Support/FileSystem.h"
@@ -111,7 +112,8 @@ compileFIR(const mlir::PassPipelineCLParser &passPipeline) {
     if (mlir::failed(passPipeline.addToPipeline(pm, errorHandler)))
       return mlir::failure();
   } else {
-    fir::createMLIRToLLVMPassPipeline(pm);
+    // Run tco with O2 by default.
+    fir::createMLIRToLLVMPassPipeline(pm, llvm::OptimizationLevel::O2);
     fir::addLLVMDialectToLLVMPass(pm, out.os());
   }
 


        


More information about the flang-commits mailing list