Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions flang/include/flang/Optimizer/Transforms/Passes.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ std::unique_ptr<mlir::Pass> createVScaleAttrPass();
std::unique_ptr<mlir::Pass>
createVScaleAttrPass(std::pair<unsigned, unsigned> vscaleAttr);

void populateFIRToSCFRewrites(mlir::RewritePatternSet &patterns,
bool parallelUnordered = false);

void populateCfgConversionRewrites(mlir::RewritePatternSet &patterns,
bool forceLoopToExecuteOnce = false,
bool setNSW = true);
Expand Down
4 changes: 4 additions & 0 deletions flang/include/flang/Optimizer/Transforms/Passes.td
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,10 @@ def FIRToSCFPass : Pass<"fir-to-scf"> {
let dependentDialects = [
"fir::FIROpsDialect", "mlir::scf::SCFDialect"
];
let options = [Option<"parallelUnordered", "parallel-unordered", "bool",
/*default=*/"false",
"Whether to convert `fir.do_loop` with the unordered "
"attribute to `scf.parallel`. Defaults to false.">];
}

def AnnotateConstantOperands : Pass<"annotate-constant"> {
Expand Down
20 changes: 17 additions & 3 deletions flang/lib/Optimizer/Transforms/FIRToSCF.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ class FIRToSCFPass : public fir::impl::FIRToSCFPassBase<FIRToSCFPass> {
struct DoLoopConversion : public mlir::OpRewritePattern<fir::DoLoopOp> {
using OpRewritePattern<fir::DoLoopOp>::OpRewritePattern;

DoLoopConversion(mlir::MLIRContext *context,
bool parallelUnorderedLoop = false,
mlir::PatternBenefit benefit = 1)
: OpRewritePattern<fir::DoLoopOp>(context, benefit),
parallelUnorderedLoop(parallelUnorderedLoop) {}

mlir::LogicalResult
matchAndRewrite(fir::DoLoopOp doLoopOp,
mlir::PatternRewriter &rewriter) const override {
Expand Down Expand Up @@ -57,7 +63,7 @@ struct DoLoopConversion : public mlir::OpRewritePattern<fir::DoLoopOp> {

// Create the scf.for or scf.parallel operation
mlir::Operation *scfLoopOp = nullptr;
if (isUnordered) {
if (isUnordered && parallelUnorderedLoop) {
scfLoopOp = mlir::scf::ParallelOp::create(rewriter, loc, {zero},
{tripCount}, {one}, iterArgs);
} else {
Expand Down Expand Up @@ -99,6 +105,9 @@ struct DoLoopConversion : public mlir::OpRewritePattern<fir::DoLoopOp> {
rewriter.replaceOp(doLoopOp, scfLoopOp);
return mlir::success();
}

private:
bool parallelUnorderedLoop;
};

struct IterWhileConversion : public mlir::OpRewritePattern<fir::IterWhileOp> {
Expand Down Expand Up @@ -210,10 +219,15 @@ struct IfConversion : public mlir::OpRewritePattern<fir::IfOp> {
};
} // namespace

void fir::populateFIRToSCFRewrites(mlir::RewritePatternSet &patterns,
bool parallelUnordered) {
patterns.add<IterWhileConversion, IfConversion>(patterns.getContext());
patterns.add<DoLoopConversion>(patterns.getContext(), parallelUnordered);
}

void FIRToSCFPass::runOnOperation() {
mlir::RewritePatternSet patterns(&getContext());
patterns.add<DoLoopConversion, IterWhileConversion, IfConversion>(
patterns.getContext());
fir::populateFIRToSCFRewrites(patterns, parallelUnordered);
walkAndApplyPatterns(getOperation(), std::move(patterns));
}

Expand Down
8 changes: 5 additions & 3 deletions flang/test/Fir/FirToSCF/do-loop.fir
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// RUN: fir-opt %s --fir-to-scf --split-input-file | FileCheck %s
// RUN: fir-opt %s --fir-to-scf --split-input-file | FileCheck %s --check-prefixes=CHECK,NO-PARALLEL
// RUN: fir-opt %s --fir-to-scf='parallel-unordered' --split-input-file | FileCheck %s --check-prefixes=CHECK,PARALLEL

// CHECK-LABEL: func.func @simple_loop(
// CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.array<100xi32>>) {
Expand Down Expand Up @@ -165,12 +166,13 @@ func.func @loop_with_final_value(%arg0: !fir.ref<!fir.array<100xi32>>, %arg1: !f
// CHECK: %[[DIVSI_0:.*]] = arith.divsi %[[ADDI_0]], %[[CONSTANT_0]] : index
// CHECK: %[[CONSTANT_3:.*]] = arith.constant 0 : index
// CHECK: %[[CONSTANT_4:.*]] = arith.constant 1 : index
// CHECK: scf.parallel (%[[VAL_0:.*]]) = (%[[CONSTANT_3]]) to (%[[DIVSI_0]]) step (%[[CONSTANT_4]]) {
// PARALLEL: scf.parallel (%[[VAL_0:.*]]) = (%[[CONSTANT_3]]) to (%[[DIVSI_0]]) step (%[[CONSTANT_4]]) {
// NO-PARALLEL: scf.for %[[VAL_0:.*]] = %[[CONSTANT_3]] to %[[DIVSI_0]] step %[[CONSTANT_4]] {
// CHECK: %[[MULI_0:.*]] = arith.muli %[[VAL_0]], %[[CONSTANT_0]] : index
// CHECK: %[[ADDI_1:.*]] = arith.addi %[[CONSTANT_0]], %[[MULI_0]] : index
// CHECK: %[[ARRAY_COOR_0:.*]] = fir.array_coor %[[ARG0]](%[[SHAPE_0]]) %[[ADDI_1]] : (!fir.ref<!fir.array<100xi32>>, !fir.shape<1>, index) -> !fir.ref<i32>
// CHECK: fir.store %[[CONSTANT_2]] to %[[ARRAY_COOR_0]] : !fir.ref<i32>
// CHECK: scf.reduce
// PARALLEL: scf.reduce
// CHECK: }
// CHECK: return
// CHECK: }
Expand Down