Index: flang/include/flang/Optimizer/CMakeLists.txt =================================================================== --- flang/include/flang/Optimizer/CMakeLists.txt +++ flang/include/flang/Optimizer/CMakeLists.txt @@ -1 +1,2 @@ add_subdirectory(Dialect) +add_subdirectory(Transforms) Index: flang/include/flang/Optimizer/Transforms/CMakeLists.txt =================================================================== --- /dev/null +++ flang/include/flang/Optimizer/Transforms/CMakeLists.txt @@ -0,0 +1,6 @@ + +set(LLVM_TARGET_DEFINITIONS Passes.td) +mlir_tablegen(Passes.h.inc -gen-pass-decls) +add_public_tablegen_target(FIROptTransformsPassIncGen) + +add_mlir_doc(Passes -gen-pass-doc OptimizerTransformPasses ./) Index: flang/include/flang/Optimizer/Transforms/Passes.h =================================================================== --- /dev/null +++ flang/include/flang/Optimizer/Transforms/Passes.h @@ -0,0 +1,58 @@ +//===-- Optimizer/Transforms/Passes.h ---------------------------*- C++ -*-===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#ifndef OPTIMIZER_TRANSFORMS_PASSES_H +#define OPTIMIZER_TRANSFORMS_PASSES_H + +#include "mlir/Pass/Pass.h" +#include "mlir/Pass/PassRegistry.h" +#include + +namespace mlir { +class BlockAndValueMapping; +class Operation; +class Pass; +class Region; +} // namespace mlir + +namespace fir { + +/// Convert fir.select_type to the standard dialect +std::unique_ptr createControlFlowLoweringPass(); + +/// Effects aware CSE pass +std::unique_ptr createCSEPass(); + +/// Convert FIR loop constructs to the Affine dialect +std::unique_ptr createPromoteToAffinePass(); + +/// Convert `fir.do_loop` and `fir.if` to a CFG. This +/// conversion enables the `createLowerToCFGPass` to transform these to CFG +/// form. +std::unique_ptr createFirToCfgPass(); + +/// A pass to convert the FIR dialect from "Mem-SSA" form to "Reg-SSA" +/// form. This pass is a port of LLVM's mem2reg pass, but modified for the FIR +/// dialect as well as the restructuring of MLIR's representation to present PHI +/// nodes as block arguments. +std::unique_ptr createMemToRegPass(); + +/// Support for inlining on FIR. +bool canLegallyInline(mlir::Operation *op, mlir::Region *reg, + mlir::BlockAndValueMapping &map); + +inline void registerOptTransformPasses() { +using mlir::Pass; +// declarative passes +#define GEN_PASS_REGISTRATION +#include "flang/Optimizer/Transforms/Passes.h.inc" +} + +} // namespace fir + +#endif // OPTIMIZER_TRANSFORMS_PASSES_H Index: flang/include/flang/Optimizer/Transforms/Passes.td =================================================================== --- /dev/null +++ flang/include/flang/Optimizer/Transforms/Passes.td @@ -0,0 +1,51 @@ +//===-- Passes.td - Transforms pass definition file --------*- tablegen -*-===// +// +// 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 contains definitions for passes within the Optimizer/Transforms/ +// directory. +// +//===----------------------------------------------------------------------===// + +#ifndef FLANG_OPTIMIZER_TRANSFORMS_PASSES +#define FLANG_OPTIMIZER_TRANSFORMS_PASSES + +include "mlir/Pass/PassBase.td" + +def AffineDialectPromotion : FunctionPass<"promote-to-affine"> { + let summary = "Promotes fir.loop and fir.where to affine.for and affine.if where possible"; + let description = [{ + TODO + }]; + let constructor = "fir::createPromoteToAffinePass()"; +} + +def BasicCSE : FunctionPass<"basic-cse"> { + let summary = "Basic common sub-expression elimination"; + let description = [{ + TODO + }]; + let constructor = "fir::createCSEPass()"; +} + +def ControlFlowLowering : FunctionPass<"lower-control-flow"> { + let summary = "Convert affine dialect, fir.select_type to standard dialect"; + let description = [{ + TODO + }]; + let constructor = "fir::createControlFlowLoweringPass()"; +} + +def CFGConversion : FunctionPass<"cfg-conversion"> { + let summary = "Convert FIR structured control flow ops to CFG ops."; + let description = [{ + TODO + }]; + let constructor = "fir::createFirToCfgPass()"; +} + +#endif // FLANG_OPTIMIZER_TRANSFORMS_PASSES Index: flang/lib/Optimizer/CMakeLists.txt =================================================================== --- flang/lib/Optimizer/CMakeLists.txt +++ flang/lib/Optimizer/CMakeLists.txt @@ -10,8 +10,11 @@ Support/InternalNames.cpp Support/KindMapping.cpp + Transforms/Inliner.cpp + DEPENDS FIROpsIncGen + FIROptTransformsPassIncGen ${dialect_libs} LINK_LIBS Index: flang/lib/Optimizer/Transforms/Inliner.cpp =================================================================== --- /dev/null +++ flang/lib/Optimizer/Transforms/Inliner.cpp @@ -0,0 +1,24 @@ +//===-- Inliner.cpp -------------------------------------------------------===// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "flang/Optimizer/Dialect/FIRDialect.h" +#include "flang/Optimizer/Dialect/FIROps.h" +#include "flang/Optimizer/Transforms/Passes.h" +#include "mlir/Transforms/Passes.h" +#include "llvm/Support/CommandLine.h" + +static llvm::cl::opt + aggressivelyInline("inline-all", + llvm::cl::desc("aggressively inline everything"), + llvm::cl::init(false)); + +/// Should we inline the callable `op` into region `reg`? +bool fir::canLegallyInline(mlir::Operation *op, mlir::Region *reg, + mlir::BlockAndValueMapping &map) { + return aggressivelyInline; +}