Revert "[flang] Run algebraic simplification optimization pass."

This reverts commit 4fbd1d6c87.
This commit is contained in:
Slava Zakharin 2022-07-20 16:56:28 -07:00
parent aabc4b13e8
commit 7434375666
12 changed files with 74 additions and 228 deletions

View File

@ -39,7 +39,6 @@ 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

View File

@ -196,17 +196,4 @@ 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

View File

@ -15,7 +15,6 @@
#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) \
@ -51,10 +50,6 @@ 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");
@ -155,8 +150,7 @@ 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, llvm::OptimizationLevel optLevel = defaultOptLevel) {
inline void createDefaultFIROptimizerPassPipeline(mlir::PassManager &pm) {
// simplify the IR
mlir::GreedyRewriteConfig config;
config.enableRegionSimplification = false;
@ -165,9 +159,6 @@ inline void createDefaultFIROptimizerPassPipeline(
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);
@ -200,12 +191,9 @@ 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
/// \param optLevel - optimization level used for creating FIR optimization
/// passes pipeline
inline void createMLIRToLLVMPassPipeline(
mlir::PassManager &pm, llvm::OptimizationLevel optLevel = defaultOptLevel) {
inline void createMLIRToLLVMPassPipeline(mlir::PassManager &pm) {
// Add default optimizer pass pipeline.
fir::createDefaultFIROptimizerPassPipeline(pm, optLevel);
fir::createDefaultFIROptimizerPassPipeline(pm);
// Add codegen pass pipeline.
fir::createDefaultFIRCodeGenPassPipeline(pm);

View File

@ -479,29 +479,11 @@ 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);
@ -513,7 +495,7 @@ void CodeGenAction::generateLLVMIR() {
pm.enableVerifier(/*verifyPasses=*/true);
// Create the pass pipeline
fir::createMLIRToLLVMPassPipeline(pm, level);
fir::createMLIRToLLVMPassPipeline(pm);
mlir::applyPassManagerCLOptions(pm);
// run the pass manager
@ -648,6 +630,22 @@ 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);

View File

@ -1,37 +0,0 @@
//===- 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>();
}

View File

@ -10,7 +10,6 @@ add_flang_library(FIRTransforms
MemRefDataFlowOpt.cpp
RewriteLoop.cpp
SimplifyRegionLite.cpp
AlgebraicSimplification.cpp
DEPENDS
FIRBuilder
@ -24,7 +23,6 @@ add_flang_library(FIRTransforms
MLIRAffineUtils
MLIRFuncDialect
MLIRLLVMDialect
MLIRMathTransforms
MLIROpenACCDialect
MLIROpenMPDialect
FIRSupport

View File

@ -12,7 +12,6 @@
#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"

View File

@ -1,45 +0,0 @@
! 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

View File

@ -1,58 +1,35 @@
! Test the MLIR pass pipeline
! 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
! RUN: %flang_fc1 -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline %s -o - 2>&1 | FileCheck %s
end program
! ALL: Pass statistics report
! CHECK: 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
! CHECK: CSE
! CHECK-LABEL: 'func.func' Pipeline
! CHECK: ArrayValueCopy
! CHECK: CharacterConversion
! CHECK: Canonicalizer
! CHECK: SimplifyRegionLite
! CHECK: CSE
! ALL-NEXT: 'func.func' Pipeline
! ALL-NEXT: ArrayValueCopy
! ALL-NEXT: CharacterConversion
! CHECK-LABEL: 'func.func' Pipeline
! CHECK: MemoryAllocationOpt
! CHECK: Inliner
! CHECK: CSE
! 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
! CHECK-LABEL: 'func.func' Pipeline
! CHECK: CFGConversion
! CHECK: SCFToControlFlow
! CHECK: Canonicalizer
! CHECK: SimplifyRegionLite
! CHECK: CSE
! CHECK: BoxedProcedurePass
! 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
! CHECK-LABEL: 'func.func' Pipeline
! CHECK: AbstractResultOpt
! CHECK: CodeGenRewrite
! CHECK: TargetRewrite
! CHECK: ExternalNameConversion
! CHECK: FIRToLLVMLowering
! CHECK-NOT: LLVMIRLoweringPass

View File

@ -14,45 +14,30 @@ func.func @_QQmain() {
// PASSES: Pass statistics report
// 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: CSE
// PASSES-LABEL: 'func.func' Pipeline
// PASSES: ArrayValueCopy
// PASSES: CharacterConversion
// PASSES: Canonicalizer
// PASSES: SimplifyRegionLite
// PASSES: CSE
// PASSES-NEXT: 'func.func' Pipeline
// PASSES-NEXT: ArrayValueCopy
// PASSES-NEXT: CharacterConversion
// PASSES-LABEL: 'func.func' Pipeline
// PASSES: MemoryAllocationOpt
// PASSES: Inliner
// PASSES: CSE
// 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-LABEL: 'func.func' Pipeline
// PASSES: CFGConversion
// PASSES: SCFToControlFlow
// PASSES: Canonicalizer
// PASSES: SimplifyRegionLite
// PASSES: CSE
// PASSES: BoxedProcedurePass
// 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
// PASSES-LABEL: 'func.func' Pipeline
// PASSES: AbstractResultOpt
// PASSES: CodeGenRewrite
// PASSES: TargetRewrite
// PASSES: FIRToLLVMLowering
// PASSES: LLVMIRLoweringPass

View File

@ -47,7 +47,6 @@
#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"
@ -256,8 +255,8 @@ static mlir::LogicalResult convertFortranSourceToMLIR(
// run the default canned pipeline
pm.addPass(std::make_unique<Fortran::lower::VerifierPass>());
// Add O2 optimizer pass pipeline.
fir::createDefaultFIROptimizerPassPipeline(pm, llvm::OptimizationLevel::O2);
// Add default optimizer pass pipeline.
fir::createDefaultFIROptimizerPassPipeline(pm);
}
if (mlir::succeeded(pm.run(mlirModule))) {

View File

@ -24,7 +24,6 @@
#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"
@ -112,8 +111,7 @@ compileFIR(const mlir::PassPipelineCLParser &passPipeline) {
if (mlir::failed(passPipeline.addToPipeline(pm, errorHandler)))
return mlir::failure();
} else {
// Run tco with O2 by default.
fir::createMLIRToLLVMPassPipeline(pm, llvm::OptimizationLevel::O2);
fir::createMLIRToLLVMPassPipeline(pm);
fir::addLLVMDialectToLLVMPass(pm, out.os());
}