[flang-commits] [flang] [flang][CodeGen] Run PreCGRewrite on omp reduction declare ops (PR #84954)
Tom Eccles via flang-commits
flang-commits at lists.llvm.org
Wed Mar 20 02:49:43 PDT 2024
https://github.com/tblah updated https://github.com/llvm/llvm-project/pull/84954
>From 85b46f6f5ec1c87c0043930130536cc83ea07333 Mon Sep 17 00:00:00 2001
From: Tom Eccles <tom.eccles at arm.com>
Date: Thu, 15 Feb 2024 12:12:29 +0000
Subject: [PATCH 1/8] [flang] run CFG conversion on omp reduction declare ops
Most FIR passes only look for FIR operations inside of functions (either
because they run only on func.func or they run on the module but iterate
over functions internally). But there can also be FIR operations inside
of fir.global, some OpenMP and OpenACC container operations.
This has worked so far for fir.global and OpenMP reductions because they
only contained very simple FIR code which doesn't need most passes to be
lowered into LLVM IR. I am not sure how OpenACC works.
In the long run, I hope to see a more systematic approach to making sure
that every pass runs on all of these container operations. I will write
an RFC for this soon.
In the meantime, this pass duplicates the CFG conversion pass to also
run on omp reduction operations. This is similar to how the
AbstractResult pass is already duplicated for fir.global operations.
Co-authored-by: Mats Petersson <mats.petersson at arm.com>
---
.../flang/Optimizer/Transforms/Passes.h | 7 +++--
.../flang/Optimizer/Transforms/Passes.td | 12 ++++++--
flang/include/flang/Tools/CLOptions.inc | 4 ++-
.../Transforms/ControlFlowConverter.cpp | 30 ++++++++++++++-----
flang/test/Driver/bbc-mlir-pass-pipeline.f90 | 5 +++-
.../test/Driver/mlir-debug-pass-pipeline.f90 | 16 +++++-----
flang/test/Driver/mlir-pass-pipeline.f90 | 16 ++++++----
flang/test/Fir/array-value-copy-2.fir | 4 +--
flang/test/Fir/basic-program.fir | 5 +++-
.../Fir/convert-to-llvm-openmp-and-fir.fir | 2 +-
flang/test/Fir/loop01.fir | 2 +-
flang/test/Fir/loop02.fir | 4 +--
flang/test/Lower/OpenMP/FIR/flush.f90 | 2 +-
flang/test/Lower/OpenMP/FIR/master.f90 | 2 +-
.../Lower/OpenMP/FIR/parallel-sections.f90 | 2 +-
15 files changed, 76 insertions(+), 37 deletions(-)
diff --git a/flang/include/flang/Optimizer/Transforms/Passes.h b/flang/include/flang/Optimizer/Transforms/Passes.h
index e1d22c8c986da7..adf747ebdb400b 100644
--- a/flang/include/flang/Optimizer/Transforms/Passes.h
+++ b/flang/include/flang/Optimizer/Transforms/Passes.h
@@ -11,6 +11,7 @@
#include "flang/Optimizer/Dialect/FIROps.h"
#include "mlir/Dialect/LLVMIR/LLVMAttrs.h"
+#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
#include "mlir/Pass/Pass.h"
#include "mlir/Pass/PassRegistry.h"
#include <memory>
@@ -37,7 +38,8 @@ namespace fir {
#define GEN_PASS_DECL_ANNOTATECONSTANTOPERANDS
#define GEN_PASS_DECL_ARRAYVALUECOPY
#define GEN_PASS_DECL_CHARACTERCONVERSION
-#define GEN_PASS_DECL_CFGCONVERSION
+#define GEN_PASS_DECL_CFGCONVERSIONONFUNC
+#define GEN_PASS_DECL_CFGCONVERSIONONREDUCTION
#define GEN_PASS_DECL_EXTERNALNAMECONVERSION
#define GEN_PASS_DECL_MEMREFDATAFLOWOPT
#define GEN_PASS_DECL_SIMPLIFYINTRINSICS
@@ -53,7 +55,8 @@ std::unique_ptr<mlir::Pass> createAbstractResultOnGlobalOptPass();
std::unique_ptr<mlir::Pass> createAffineDemotionPass();
std::unique_ptr<mlir::Pass>
createArrayValueCopyPass(fir::ArrayValueCopyOptions options = {});
-std::unique_ptr<mlir::Pass> createFirToCfgPass();
+std::unique_ptr<mlir::Pass> createFirToCfgOnFuncPass();
+std::unique_ptr<mlir::Pass> createFirToCfgOnReductionPass();
std::unique_ptr<mlir::Pass> createCharacterConversionPass();
std::unique_ptr<mlir::Pass> createExternalNameConversionPass();
std::unique_ptr<mlir::Pass>
diff --git a/flang/include/flang/Optimizer/Transforms/Passes.td b/flang/include/flang/Optimizer/Transforms/Passes.td
index 5fb576fd876254..e6ea92d814400f 100644
--- a/flang/include/flang/Optimizer/Transforms/Passes.td
+++ b/flang/include/flang/Optimizer/Transforms/Passes.td
@@ -145,7 +145,8 @@ def CharacterConversion : Pass<"character-conversion"> {
];
}
-def CFGConversion : Pass<"cfg-conversion", "::mlir::func::FuncOp"> {
+class CFGConversionBase<string optExt, string operation>
+ : Pass<"cfg-conversion-on-" # optExt # "-opt", operation> {
let summary = "Convert FIR structured control flow ops to CFG ops.";
let description = [{
Transform the `fir.do_loop`, `fir.if`, `fir.iterate_while` and
@@ -154,7 +155,6 @@ def CFGConversion : Pass<"cfg-conversion", "::mlir::func::FuncOp"> {
This pass is required before code gen to the LLVM IR dialect.
}];
- let constructor = "::fir::createFirToCfgPass()";
let dependentDialects = [
"fir::FIROpsDialect", "mlir::func::FuncDialect"
];
@@ -165,6 +165,14 @@ def CFGConversion : Pass<"cfg-conversion", "::mlir::func::FuncOp"> {
];
}
+def CFGConversionOnFunc : CFGConversionBase<"func", "mlir::func::FuncOp"> {
+ let constructor = "::fir::createFirToCfgOnFuncPass()";
+}
+
+def CFGConversionOnReduction : CFGConversionBase<"reduce", "mlir::omp::ReductionDeclareOp"> {
+ let constructor = "::fir::createFirToCfgOnReductionPass()";
+}
+
def ExternalNameConversion : Pass<"external-name-interop", "mlir::ModuleOp"> {
let summary = "Convert name for external interoperability";
let description = [{
diff --git a/flang/include/flang/Tools/CLOptions.inc b/flang/include/flang/Tools/CLOptions.inc
index 68e504d0ccb512..21b36dba9ac704 100644
--- a/flang/include/flang/Tools/CLOptions.inc
+++ b/flang/include/flang/Tools/CLOptions.inc
@@ -123,7 +123,9 @@ static void addCanonicalizerPassWithoutRegionSimplification(
inline void addCfgConversionPass(mlir::PassManager &pm) {
addNestedPassConditionally<mlir::func::FuncOp>(
- pm, disableCfgConversion, fir::createFirToCfgPass);
+ pm, disableCfgConversion, fir::createFirToCfgOnFuncPass);
+ addNestedPassConditionally<mlir::omp::ReductionDeclareOp>(
+ pm, disableCfgConversion, fir::createFirToCfgOnReductionPass);
}
inline void addAVC(
diff --git a/flang/lib/Optimizer/Transforms/ControlFlowConverter.cpp b/flang/lib/Optimizer/Transforms/ControlFlowConverter.cpp
index 0944b184ca0d4e..f972f59749bea1 100644
--- a/flang/lib/Optimizer/Transforms/ControlFlowConverter.cpp
+++ b/flang/lib/Optimizer/Transforms/ControlFlowConverter.cpp
@@ -24,7 +24,8 @@
#include "llvm/Support/CommandLine.h"
namespace fir {
-#define GEN_PASS_DEF_CFGCONVERSION
+#define GEN_PASS_DEF_CFGCONVERSIONONFUNC
+#define GEN_PASS_DEF_CFGCONVERSIONONREDUCTION
#include "flang/Optimizer/Transforms/Passes.h.inc"
} // namespace fir
@@ -308,13 +309,14 @@ class CfgIterWhileConv : public mlir::OpRewritePattern<fir::IterWhileOp> {
};
/// Convert FIR structured control flow ops to CFG ops.
-class CfgConversion : public fir::impl::CFGConversionBase<CfgConversion> {
+template <typename Pass, template <typename> class PassBase>
+class CfgConversionTemplate : public PassBase<Pass> {
public:
void runOnOperation() override {
- auto *context = &getContext();
+ auto *context = &this->getContext();
mlir::RewritePatternSet patterns(context);
patterns.insert<CfgLoopConv, CfgIfConv, CfgIterWhileConv>(
- context, forceLoopToExecuteOnce);
+ context, this->forceLoopToExecuteOnce);
mlir::ConversionTarget target(*context);
target.addLegalDialect<mlir::affine::AffineDialect,
mlir::cf::ControlFlowDialect, FIROpsDialect,
@@ -323,19 +325,31 @@ class CfgConversion : public fir::impl::CFGConversionBase<CfgConversion> {
// apply the patterns
target.addIllegalOp<ResultOp, DoLoopOp, IfOp, IterWhileOp>();
target.markUnknownOpDynamicallyLegal([](Operation *) { return true; });
- if (mlir::failed(mlir::applyPartialConversion(getOperation(), target,
+ if (mlir::failed(mlir::applyPartialConversion(this->getOperation(), target,
std::move(patterns)))) {
mlir::emitError(mlir::UnknownLoc::get(context),
"error in converting to CFG\n");
- signalPassFailure();
+ this->signalPassFailure();
}
}
};
+
+class CfgConversionOnFunc
+ : public CfgConversionTemplate<CfgConversionOnFunc,
+ ::fir::impl::CFGConversionOnFuncBase> {};
+
+class CfgConversionOnReduction
+ : public CfgConversionTemplate<CfgConversionOnReduction,
+ ::fir::impl::CFGConversionOnReductionBase> {
+};
} // namespace
/// Convert FIR's structured control flow ops to CFG ops. This
/// conversion enables the `createLowerToCFGPass` to transform these to CFG
/// form.
-std::unique_ptr<mlir::Pass> fir::createFirToCfgPass() {
- return std::make_unique<CfgConversion>();
+std::unique_ptr<mlir::Pass> fir::createFirToCfgOnFuncPass() {
+ return std::make_unique<CfgConversionOnFunc>();
+}
+std::unique_ptr<mlir::Pass> fir::createFirToCfgOnReductionPass() {
+ return std::make_unique<CfgConversionOnReduction>();
}
diff --git a/flang/test/Driver/bbc-mlir-pass-pipeline.f90 b/flang/test/Driver/bbc-mlir-pass-pipeline.f90
index 243a620a9fd003..b25edf3599175e 100644
--- a/flang/test/Driver/bbc-mlir-pass-pipeline.f90
+++ b/flang/test/Driver/bbc-mlir-pass-pipeline.f90
@@ -38,9 +38,12 @@
! 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: Pipeline Collection : ['func.func', 'omp.reduction.declare']
! CHECK-NEXT: 'func.func' Pipeline
! CHECK-NEXT: PolymorphicOpConversion
-! CHECK-NEXT: CFGConversion
+! CHECK-NEXT: CFGConversionOnFunc
+! CHECK-NEXT: 'omp.reduction.declare' Pipeline
+! CHECK-NEXT: CFGConversionOnReduction
! CHECK-NEXT: SCFToControlFlow
! CHECK-NEXT: Canonicalizer
diff --git a/flang/test/Driver/mlir-debug-pass-pipeline.f90 b/flang/test/Driver/mlir-debug-pass-pipeline.f90
index 45b1717d7187db..a865b170c3d417 100644
--- a/flang/test/Driver/mlir-debug-pass-pipeline.f90
+++ b/flang/test/Driver/mlir-debug-pass-pipeline.f90
@@ -58,10 +58,12 @@
! 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: PolymorphicOpConversion
-! ALL-NEXT: CFGConversion
-
+! ALL-NEXT: Pipeline Collection : ['func.func', 'omp.reduction.declare']
+! ALL-NEXT: 'func.func' Pipeline
+! ALL-NEXT: PolymorphicOpConversion
+! ALL-NEXT: CFGConversionOnFunc
+! ALL-NEXT: 'omp.reduction.declare' Pipeline
+! ALL-NEXT: CFGConversionOnReduction
! ALL-NEXT: SCFToControlFlow
! ALL-NEXT: Canonicalizer
! ALL-NEXT: SimplifyRegionLite
@@ -72,9 +74,9 @@
! ALL-NEXT: Pipeline Collection : ['fir.global', 'func.func']
! ALL-NEXT: 'fir.global' Pipeline
-! ALL-NEXT: AbstractResultOnGlobalOpt
-! ALL-NEXT: 'func.func' Pipeline
-! ALL-NEXT: AbstractResultOnFuncOpt
+! ALL-NEXT: AbstractResultOnGlobalOpt
+! ALL-NEXT: 'func.func' Pipeline
+! ALL-NEXT: AbstractResultOnFuncOpt
! ALL-NEXT: CodeGenRewrite
! ALL-NEXT: (S) 0 num-dce'd - Number of operations eliminated
diff --git a/flang/test/Driver/mlir-pass-pipeline.f90 b/flang/test/Driver/mlir-pass-pipeline.f90
index 3d8c42f123e2eb..ee3f41a15ca481 100644
--- a/flang/test/Driver/mlir-pass-pipeline.f90
+++ b/flang/test/Driver/mlir-pass-pipeline.f90
@@ -1,8 +1,8 @@
! 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
+! RUN: %flang_fc1 -S -mmlir --mlir-pass-statistics -mmlir --mlir-pass-statistics-display=pipeline -o /dev/null %s 2>&1 | FileCheck --check-prefixes=ALL,NOTO2 %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 -O0 -o /dev/null 2>&1 | FileCheck --check-prefixes=ALL,NOTO2 %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
@@ -49,11 +49,15 @@
! 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: PolymorphicOpConversion
+! O2-NEXT: 'func.func' Pipeline
+! O2-NEXT: PolymorphicOpConversion
! O2-NEXT: AddAliasTags
-! O2-NEXT: 'func.func' Pipeline
-! ALL-NEXT: CFGConversion
+! ALL-NEXT: Pipeline Collection : ['func.func', 'omp.reduction.declare']
+! ALL-NEXT: 'func.func' Pipeline
+! NOTO2-NEXT: PolymorphicOpConversion
+! ALL-NEXT: CFGConversionOnFunc
+! ALL-NEXT: 'omp.reduction.declare' Pipeline
+! ALL-NEXT: CFGConversionOnReduction
! ALL-NEXT: SCFToControlFlow
! ALL-NEXT: Canonicalizer
diff --git a/flang/test/Fir/array-value-copy-2.fir b/flang/test/Fir/array-value-copy-2.fir
index 21b340af10c6b8..cb8d6ca2b05540 100644
--- a/flang/test/Fir/array-value-copy-2.fir
+++ b/flang/test/Fir/array-value-copy-2.fir
@@ -1,5 +1,5 @@
-// RUN: fir-opt --array-value-copy --cfg-conversion %s | FileCheck %s
-// RUN: fir-opt --array-value-copy="optimize-conflicts=true" --cfg-conversion %s | FileCheck %s
+// RUN: fir-opt --array-value-copy --cfg-conversion-on-func-opt %s | FileCheck %s
+// RUN: fir-opt --array-value-copy="optimize-conflicts=true" --cfg-conversion-on-func-opt %s | FileCheck %s
// CHECK-LABEL: func @_QPslice1(
// CHECK-NOT: fir.allocmem
diff --git a/flang/test/Fir/basic-program.fir b/flang/test/Fir/basic-program.fir
index d8a9e74c318ce1..516946bd4fb46a 100644
--- a/flang/test/Fir/basic-program.fir
+++ b/flang/test/Fir/basic-program.fir
@@ -60,8 +60,11 @@ func.func @_QQmain() {
// PASSES-NEXT: AddAliasTags
+// PASSES-NEXT: Pipeline Collection : ['func.func', 'omp.reduction.declare']
// PASSES-NEXT: 'func.func' Pipeline
-// PASSES-NEXT: CFGConversion
+// PASSES-NEXT: CFGConversionOnFunc
+// PASSES-NEXT: 'omp.reduction.declare' Pipeline
+// PASSES-NEXT: CFGConversionOnReduction
// PASSES-NEXT: SCFToControlFlow
// PASSES-NEXT: Canonicalizer
diff --git a/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir b/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir
index a1fc614334dbce..8d9bdca4bf5446 100644
--- a/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir
+++ b/flang/test/Fir/convert-to-llvm-openmp-and-fir.fir
@@ -1,4 +1,4 @@
-// RUN: fir-opt --split-input-file --cfg-conversion --fir-to-llvm-ir="target=aarch64-unknown-linux-gnu" %s | FileCheck %s
+// RUN: fir-opt --split-input-file --cfg-conversion-on-func-opt --fir-to-llvm-ir="target=aarch64-unknown-linux-gnu" %s | FileCheck %s
func.func @_QPsb1(%arg0: !fir.ref<i32> {fir.bindc_name = "n"}, %arg1: !fir.ref<!fir.array<?xi32>> {fir.bindc_name = "arr"}) {
%c1_i64 = arith.constant 1 : i64
diff --git a/flang/test/Fir/loop01.fir b/flang/test/Fir/loop01.fir
index 72ca1c3989e453..c849797b969eba 100644
--- a/flang/test/Fir/loop01.fir
+++ b/flang/test/Fir/loop01.fir
@@ -1,4 +1,4 @@
-// RUN: fir-opt --split-input-file --cfg-conversion %s | FileCheck %s
+// RUN: fir-opt --split-input-file --cfg-conversion-on-func-opt %s | FileCheck %s
func.func @x(%lb : index, %ub : index, %step : index, %b : i1, %addr : !fir.ref<index>) {
fir.do_loop %iv = %lb to %ub step %step unordered {
diff --git a/flang/test/Fir/loop02.fir b/flang/test/Fir/loop02.fir
index 50948e0e7aa6b5..8918666f0b3460 100644
--- a/flang/test/Fir/loop02.fir
+++ b/flang/test/Fir/loop02.fir
@@ -1,5 +1,5 @@
-// RUN: fir-opt --cfg-conversion="always-execute-loop-body=true" %s | FileCheck %s
-// RUN: fir-opt --cfg-conversion %s | FileCheck %s --check-prefix=NOOPT
+// RUN: fir-opt --cfg-conversion-on-func-opt="always-execute-loop-body=true" %s | FileCheck %s
+// RUN: fir-opt --cfg-conversion-on-func-opt %s | FileCheck %s --check-prefix=NOOPT
func.func @x(%addr : !fir.ref<index>) {
%bound = arith.constant 452 : index
diff --git a/flang/test/Lower/OpenMP/FIR/flush.f90 b/flang/test/Lower/OpenMP/FIR/flush.f90
index 2c281632b85cb0..2868367fbdba64 100644
--- a/flang/test/Lower/OpenMP/FIR/flush.f90
+++ b/flang/test/Lower/OpenMP/FIR/flush.f90
@@ -1,7 +1,7 @@
! This test checks lowering of OpenMP Flush Directive.
!RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -fopenmp %s -o - | FileCheck %s --check-prefixes="FIRDialect,OMPDialect"
-!RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -fopenmp %s -o - | fir-opt --cfg-conversion | fir-opt --fir-to-llvm-ir | FileCheck %s --check-prefixes="LLVMIRDialect,OMPDialect"
+!RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -fopenmp %s -o - | fir-opt --cfg-conversion-on-func-opt | fir-opt --fir-to-llvm-ir | FileCheck %s --check-prefixes="LLVMIRDialect,OMPDialect"
subroutine flush_standalone(a, b, c)
integer, intent(inout) :: a, b, c
diff --git a/flang/test/Lower/OpenMP/FIR/master.f90 b/flang/test/Lower/OpenMP/FIR/master.f90
index dd9910da2f4190..3bac582c7725a8 100644
--- a/flang/test/Lower/OpenMP/FIR/master.f90
+++ b/flang/test/Lower/OpenMP/FIR/master.f90
@@ -1,5 +1,5 @@
!RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -fopenmp %s -o - | FileCheck %s --check-prefixes="FIRDialect,OMPDialect"
-!RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -fopenmp %s -o - | fir-opt --cfg-conversion | fir-opt --fir-to-llvm-ir | FileCheck %s --check-prefixes="OMPDialect"
+!RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -fopenmp %s -o - | fir-opt --cfg-conversion-on-func-opt | fir-opt --fir-to-llvm-ir | FileCheck %s --check-prefixes="OMPDialect"
!===============================================================================
! parallel construct with function call which has master construct internally
diff --git a/flang/test/Lower/OpenMP/FIR/parallel-sections.f90 b/flang/test/Lower/OpenMP/FIR/parallel-sections.f90
index 33fda178323f2b..78d73f038f0793 100644
--- a/flang/test/Lower/OpenMP/FIR/parallel-sections.f90
+++ b/flang/test/Lower/OpenMP/FIR/parallel-sections.f90
@@ -1,5 +1,5 @@
!RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -fopenmp %s -o - | FileCheck %s --check-prefixes="FIRDialect,OMPDialect"
-!RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -fopenmp %s -o - | fir-opt --cfg-conversion | fir-opt --fir-to-llvm-ir | FileCheck %s --check-prefixes="OMPDialect,LLVMDialect"
+!RUN: %flang_fc1 -emit-fir -flang-deprecated-no-hlfir -fopenmp %s -o - | fir-opt --cfg-conversion-on-func-opt | fir-opt --fir-to-llvm-ir | FileCheck %s --check-prefixes="OMPDialect,LLVMDialect"
!===============================================================================
! Parallel sections construct
>From cdad77c9af6b277c3c2daa7876e60d52c7acf8fb Mon Sep 17 00:00:00 2001
From: Tom Eccles <tom.eccles at arm.com>
Date: Thu, 14 Mar 2024 08:40:54 +0000
Subject: [PATCH 2/8] Expose cfg conversions to other passes
---
flang/include/flang/Optimizer/Transforms/Passes.h | 3 +++
.../lib/Optimizer/Transforms/ControlFlowConverter.cpp | 10 ++++++++--
2 files changed, 11 insertions(+), 2 deletions(-)
diff --git a/flang/include/flang/Optimizer/Transforms/Passes.h b/flang/include/flang/Optimizer/Transforms/Passes.h
index adf747ebdb400b..a60d39c8df08d8 100644
--- a/flang/include/flang/Optimizer/Transforms/Passes.h
+++ b/flang/include/flang/Optimizer/Transforms/Passes.h
@@ -99,6 +99,9 @@ createFunctionAttrPass(FunctionAttrTypes &functionAttr, bool noInfsFPMath,
bool noNaNsFPMath, bool approxFuncFPMath,
bool noSignedZerosFPMath, bool unsafeFPMath);
+void populateCfgConversionRewrites(mlir::RewritePatternSet &patterns,
+ bool forceLoopToExecuteOnce = false);
+
// declarative passes
#define GEN_PASS_REGISTRATION
#include "flang/Optimizer/Transforms/Passes.h.inc"
diff --git a/flang/lib/Optimizer/Transforms/ControlFlowConverter.cpp b/flang/lib/Optimizer/Transforms/ControlFlowConverter.cpp
index f972f59749bea1..45609a99995d0a 100644
--- a/flang/lib/Optimizer/Transforms/ControlFlowConverter.cpp
+++ b/flang/lib/Optimizer/Transforms/ControlFlowConverter.cpp
@@ -315,8 +315,7 @@ class CfgConversionTemplate : public PassBase<Pass> {
void runOnOperation() override {
auto *context = &this->getContext();
mlir::RewritePatternSet patterns(context);
- patterns.insert<CfgLoopConv, CfgIfConv, CfgIterWhileConv>(
- context, this->forceLoopToExecuteOnce);
+ fir::populateCfgConversionRewrites(patterns, this->forceLoopToExecuteOnce);
mlir::ConversionTarget target(*context);
target.addLegalDialect<mlir::affine::AffineDialect,
mlir::cf::ControlFlowDialect, FIROpsDialect,
@@ -344,6 +343,13 @@ class CfgConversionOnReduction
};
} // namespace
+/// Expose conversion rewriters to other passes
+void fir::populateCfgConversionRewrites(mlir::RewritePatternSet &patterns,
+ bool forceLoopToExecuteOnce) {
+ patterns.insert<CfgLoopConv, CfgIfConv, CfgIterWhileConv>(
+ patterns.getContext(), forceLoopToExecuteOnce);
+}
+
/// Convert FIR's structured control flow ops to CFG ops. This
/// conversion enables the `createLowerToCFGPass` to transform these to CFG
/// form.
>From 888ed3805caf8899112e34e7c3ec283644b71ff6 Mon Sep 17 00:00:00 2001
From: Tom Eccles <tom.eccles at arm.com>
Date: Wed, 20 Mar 2024 09:45:47 +0000
Subject: [PATCH 3/8] Add test
---
.../omp-reduction-cfg-conversion.fir | 57 +++++++++++++++++++
1 file changed, 57 insertions(+)
create mode 100644 flang/test/Transforms/omp-reduction-cfg-conversion.fir
diff --git a/flang/test/Transforms/omp-reduction-cfg-conversion.fir b/flang/test/Transforms/omp-reduction-cfg-conversion.fir
new file mode 100644
index 00000000000000..c27bba2f7b0764
--- /dev/null
+++ b/flang/test/Transforms/omp-reduction-cfg-conversion.fir
@@ -0,0 +1,57 @@
+// RUN: fir-opt --cfg-conversion-on-reduce-opt %s | FileCheck %s
+
+omp.reduction.declare @add_reduction_i_32_box_3_byref : !fir.ref<!fir.box<!fir.array<3xi32>>> init {
+^bb0(%arg0: !fir.ref<!fir.box<!fir.array<3xi32>>>):
+ %c4_i32 = arith.constant 4 : i32
+ %c0_i32 = arith.constant 0 : i32
+ %c3 = arith.constant 3 : index
+ %0 = fir.alloca !fir.box<!fir.array<3xi32>>
+ %1 = fir.alloca !fir.array<3xi32> {bindc_name = "omp.reduction.array.init"}
+ %2 = fir.shape %c3 : (index) -> !fir.shape<1>
+ %3 = fir.declare %1(%2) {uniq_name = "omp.reduction.array.init"} : (!fir.ref<!fir.array<3xi32>>, !fir.shape<1>) -> !fir.ref<!fir.array<3xi32>>
+ %4 = fir.embox %3(%2) : (!fir.ref<!fir.array<3xi32>>, !fir.shape<1>) -> !fir.box<!fir.array<3xi32>>
+ %5 = fir.alloca i32
+ fir.store %c0_i32 to %5 : !fir.ref<i32>
+ %6 = fir.embox %5 : (!fir.ref<i32>) -> !fir.box<i32>
+ fir.store %4 to %0 : !fir.ref<!fir.box<!fir.array<3xi32>>>
+ %7 = fir.address_of(@_QQclX9a9fdf8c5fd329fbbf2b0c08e2ca9a1e) : !fir.ref<!fir.char<1,40>>
+ %8 = fir.convert %0 : (!fir.ref<!fir.box<!fir.array<3xi32>>>) -> !fir.ref<!fir.box<none>>
+ %9 = fir.convert %6 : (!fir.box<i32>) -> !fir.box<none>
+ %10 = fir.convert %7 : (!fir.ref<!fir.char<1,40>>) -> !fir.ref<i8>
+ %11 = fir.call @_FortranAAssign(%8, %9, %10, %c4_i32) : (!fir.ref<!fir.box<none>>, !fir.box<none>, !fir.ref<i8>, i32) -> none
+ %12 = fir.alloca !fir.box<!fir.array<3xi32>>
+ fir.store %4 to %12 : !fir.ref<!fir.box<!fir.array<3xi32>>>
+ omp.yield(%12 : !fir.ref<!fir.box<!fir.array<3xi32>>>)
+} combiner {
+^bb0(%arg0: !fir.ref<!fir.box<!fir.array<3xi32>>>, %arg1: !fir.ref<!fir.box<!fir.array<3xi32>>>):
+ %c1 = arith.constant 1 : index
+ %c0 = arith.constant 0 : index
+ %0 = fir.load %arg0 : !fir.ref<!fir.box<!fir.array<3xi32>>>
+ %1 = fir.load %arg1 : !fir.ref<!fir.box<!fir.array<3xi32>>>
+ %2:3 = fir.box_dims %0, %c0 : (!fir.box<!fir.array<3xi32>>, index) -> (index, index, index)
+ %3 = fir.shape_shift %2#0, %2#1 : (index, index) -> !fir.shapeshift<1>
+ fir.do_loop %arg2 = %c1 to %2#1 step %c1 unordered {
+ %4 = fir.array_coor %0(%3) %arg2 : (!fir.box<!fir.array<3xi32>>, !fir.shapeshift<1>, index) -> !fir.ref<i32>
+ %5 = fir.array_coor %1(%3) %arg2 : (!fir.box<!fir.array<3xi32>>, !fir.shapeshift<1>, index) -> !fir.ref<i32>
+ %6 = fir.load %4 : !fir.ref<i32>
+ %7 = fir.load %5 : !fir.ref<i32>
+ %8 = arith.addi %6, %7 : i32
+ fir.store %8 to %4 : !fir.ref<i32>
+ }
+ omp.yield(%arg0 : !fir.ref<!fir.box<!fir.array<3xi32>>>)
+}
+
+// ensure cfg conversion has run on the do loop
+// CHECK: combiner {
+// CHECK-NOT: fir.do_loop
+// CHECK: ^bb0({{.*}}):
+// ...
+// CHECK: cf.br ^bb1
+// CHECK: ^bb1({{.*}}):
+// ...
+// CHECK: cf.cond_br %{{.*}} ^bb2, ^bb3
+// CHECK: ^bb2:
+// ...
+// CHECK: cf.br ^bb1
+// CHECK: ^bb3:
+
>From 8dea29a80044d44ca2ef7472fe7760995c3bf869 Mon Sep 17 00:00:00 2001
From: Tom Eccles <tom.eccles at arm.com>
Date: Fri, 1 Mar 2024 16:59:09 +0000
Subject: [PATCH 4/8] [flang][CodeGen] Run PreCGRewrite on omp reduction
declare ops
OpenMP reduction declare operations can contain FIR code which needs to
be lowered to LLVM. With array reductions, these regions can contain
more complicated operations which need PreCGRewriting. A similar extra
case was already needed for fir::GlobalOp.
---
flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp b/flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp
index 9d48a2f08aba03..04a3a693658474 100644
--- a/flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp
+++ b/flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp
@@ -22,6 +22,7 @@
#include "mlir/Transforms/RegionUtils.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Debug.h"
+#include <mlir/Dialect/OpenMP/OpenMPDialect.h>
namespace fir {
#define GEN_PASS_DEF_CODEGENREWRITE
@@ -318,6 +319,10 @@ class CodeGenRewrite : public fir::impl::CodeGenRewriteBase<CodeGenRewrite> {
runOn(func, func.getBody());
for (auto global : mod.getOps<fir::GlobalOp>())
runOn(global, global.getRegion());
+ for (auto omp : mod.getOps<mlir::omp::ReductionDeclareOp>()) {
+ runOn(omp, omp.getInitializerRegion());
+ runOn(omp, omp.getReductionRegion());
+ }
}
};
>From 13cd25877a5b2c8b387f2411b50aa7f36357fda5 Mon Sep 17 00:00:00 2001
From: Tom Eccles <tom.eccles at arm.com>
Date: Thu, 14 Mar 2024 07:54:12 +0000
Subject: [PATCH 5/8] Fix include
---
flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp b/flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp
index 04a3a693658474..433e4b87aa4a55 100644
--- a/flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp
+++ b/flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp
@@ -18,11 +18,11 @@
#include "flang/Optimizer/Dialect/FIROps.h"
#include "flang/Optimizer/Dialect/FIRType.h"
#include "flang/Optimizer/Dialect/Support/FIRContext.h"
+#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
#include "mlir/Transforms/DialectConversion.h"
#include "mlir/Transforms/RegionUtils.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Support/Debug.h"
-#include <mlir/Dialect/OpenMP/OpenMPDialect.h>
namespace fir {
#define GEN_PASS_DEF_CODEGENREWRITE
>From 8a432d5028ff2f368398fba519dcc8c12b851e49 Mon Sep 17 00:00:00 2001
From: Tom Eccles <tom.eccles at arm.com>
Date: Thu, 14 Mar 2024 08:02:40 +0000
Subject: [PATCH 6/8] Run PreCGRewrite on all regions in the module
---
flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp | 13 +++----------
1 file changed, 3 insertions(+), 10 deletions(-)
diff --git a/flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp b/flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp
index 433e4b87aa4a55..074f165a87257b 100644
--- a/flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp
+++ b/flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp
@@ -284,7 +284,7 @@ class DeclareOpConversion : public mlir::OpRewritePattern<fir::DeclareOp> {
class CodeGenRewrite : public fir::impl::CodeGenRewriteBase<CodeGenRewrite> {
public:
- void runOn(mlir::Operation *op, mlir::Region ®ion) {
+ void runOn(mlir::Operation *op) {
auto &context = getContext();
mlir::ConversionTarget target(context);
target.addLegalDialect<mlir::arith::ArithDialect, fir::FIROpsDialect,
@@ -314,15 +314,8 @@ class CodeGenRewrite : public fir::impl::CodeGenRewriteBase<CodeGenRewrite> {
void runOnOperation() override final {
// Call runOn on all top level regions that may contain emboxOp/arrayCoorOp.
- auto mod = getOperation();
- for (auto func : mod.getOps<mlir::func::FuncOp>())
- runOn(func, func.getBody());
- for (auto global : mod.getOps<fir::GlobalOp>())
- runOn(global, global.getRegion());
- for (auto omp : mod.getOps<mlir::omp::ReductionDeclareOp>()) {
- runOn(omp, omp.getInitializerRegion());
- runOn(omp, omp.getReductionRegion());
- }
+ mlir::ModuleOp mod = getOperation();
+ runOn(mod);
}
};
>From 717f22f2c5c602c50a1a0b21479ec837a2accbbd Mon Sep 17 00:00:00 2001
From: Tom Eccles <tom.eccles at arm.com>
Date: Thu, 14 Mar 2024 14:03:13 +0000
Subject: [PATCH 7/8] Remove unessecary include
---
flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp | 1 -
1 file changed, 1 deletion(-)
diff --git a/flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp b/flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp
index 074f165a87257b..6e43cdcd8d1fdf 100644
--- a/flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp
+++ b/flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp
@@ -18,7 +18,6 @@
#include "flang/Optimizer/Dialect/FIROps.h"
#include "flang/Optimizer/Dialect/FIRType.h"
#include "flang/Optimizer/Dialect/Support/FIRContext.h"
-#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
#include "mlir/Transforms/DialectConversion.h"
#include "mlir/Transforms/RegionUtils.h"
#include "llvm/ADT/STLExtras.h"
>From 83ad738ffd37464328520b4a94ce0f01ce10351a Mon Sep 17 00:00:00 2001
From: Tom Eccles <tom.eccles at arm.com>
Date: Fri, 15 Mar 2024 11:28:30 +0000
Subject: [PATCH 8/8] Remove runOn
---
flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp | 14 +++++---------
1 file changed, 5 insertions(+), 9 deletions(-)
diff --git a/flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp b/flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp
index 6e43cdcd8d1fdf..665bf09b8fc33b 100644
--- a/flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp
+++ b/flang/lib/Optimizer/CodeGen/PreCGRewrite.cpp
@@ -283,7 +283,9 @@ class DeclareOpConversion : public mlir::OpRewritePattern<fir::DeclareOp> {
class CodeGenRewrite : public fir::impl::CodeGenRewriteBase<CodeGenRewrite> {
public:
- void runOn(mlir::Operation *op) {
+ void runOnOperation() override final {
+ mlir::ModuleOp mod = getOperation();
+
auto &context = getContext();
mlir::ConversionTarget target(context);
target.addLegalDialect<mlir::arith::ArithDialect, fir::FIROpsDialect,
@@ -300,7 +302,7 @@ class CodeGenRewrite : public fir::impl::CodeGenRewriteBase<CodeGenRewrite> {
mlir::RewritePatternSet patterns(&context);
fir::populatePreCGRewritePatterns(patterns);
if (mlir::failed(
- mlir::applyPartialConversion(op, target, std::move(patterns)))) {
+ mlir::applyPartialConversion(mod, target, std::move(patterns)))) {
mlir::emitError(mlir::UnknownLoc::get(&context),
"error in running the pre-codegen conversions");
signalPassFailure();
@@ -308,13 +310,7 @@ class CodeGenRewrite : public fir::impl::CodeGenRewriteBase<CodeGenRewrite> {
}
// Erase any residual (fir.shape, fir.slice...).
mlir::IRRewriter rewriter(&context);
- (void)mlir::runRegionDCE(rewriter, op->getRegions());
- }
-
- void runOnOperation() override final {
- // Call runOn on all top level regions that may contain emboxOp/arrayCoorOp.
- mlir::ModuleOp mod = getOperation();
- runOn(mod);
+ (void)mlir::runRegionDCE(rewriter, mod->getRegions());
}
};
More information about the flang-commits
mailing list