//===- SCFToOpenMP.cpp - Structured Control Flow to OpenMP conversion -----===// // // 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 implements a pass to convert scf.parallel operations into OpenMP // parallel loops. // //===----------------------------------------------------------------------===// #include "mlir/Conversion/SCFToOpenMP/SCFToOpenMP.h" #include "mlir/Analysis/SliceAnalysis.h" #include "mlir/Dialect/Affine/Analysis/LoopAnalysis.h" #include "mlir/Dialect/Arith/IR/Arith.h" #include "mlir/Dialect/LLVMIR/LLVMDialect.h" #include "mlir/Dialect/MemRef/IR/MemRef.h" #include "mlir/Dialect/OpenMP/OpenMPDialect.h" #include "mlir/Dialect/SCF/IR/SCF.h" #include "mlir/IR/ImplicitLocOpBuilder.h" #include "mlir/IR/SymbolTable.h" #include "mlir/Pass/Pass.h" #include "mlir/Transforms/DialectConversion.h" namespace mlir { #define GEN_PASS_DEF_CONVERTSCFTOOPENMPPASS #include "mlir/Conversion/Passes.h.inc" } // namespace mlir usingnamespacemlir; /// Matches a block containing a "simple" reduction. The expected shape of the /// block is as follows. /// /// ^bb(%arg0, %arg1): /// %0 = OpTy(%arg0, %arg1) /// scf.reduce.return %0 template <typename... OpTy> static bool matchSimpleReduction(Block &block) { … } /// Matches a block containing a select-based min/max reduction. The types of /// select and compare operations are provided as template arguments. The /// comparison predicates suitable for min and max are provided as function /// arguments. If a reduction is matched, `ifMin` will be set if the reduction /// compute the minimum and unset if it computes the maximum, otherwise it /// remains unmodified. The expected shape of the block is as follows. /// /// ^bb(%arg0, %arg1): /// %0 = CompareOpTy(<one-of-predicates>, %arg0, %arg1) /// %1 = SelectOpTy(%0, %arg0, %arg1) // %arg0, %arg1 may be swapped here. /// scf.reduce.return %1 template < typename CompareOpTy, typename SelectOpTy, typename Predicate = decltype(std::declval<CompareOpTy>().getPredicate())> static bool matchSelectReduction(Block &block, ArrayRef<Predicate> lessThanPredicates, ArrayRef<Predicate> greaterThanPredicates, bool &isMin) { … } /// Returns the float semantics for the given float type. static const llvm::fltSemantics &fltSemanticsForType(FloatType type) { … } /// Returns an attribute with the minimum (if `min` is set) or the maximum value /// (otherwise) for the given float type. static Attribute minMaxValueForFloat(Type type, bool min) { … } /// Returns an attribute with the signed integer minimum (if `min` is set) or /// the maximum value (otherwise) for the given integer type, regardless of its /// signedness semantics (only the width is considered). static Attribute minMaxValueForSignedInt(Type type, bool min) { … } /// Returns an attribute with the unsigned integer minimum (if `min` is set) or /// the maximum value (otherwise) for the given integer type, regardless of its /// signedness semantics (only the width is considered). static Attribute minMaxValueForUnsignedInt(Type type, bool min) { … } /// Creates an OpenMP reduction declaration and inserts it into the provided /// symbol table. The declaration has a constant initializer with the neutral /// value `initValue`, and the `reductionIndex`-th reduction combiner carried /// over from `reduce`. static omp::DeclareReductionOp createDecl(PatternRewriter &builder, SymbolTable &symbolTable, scf::ReduceOp reduce, int64_t reductionIndex, Attribute initValue) { … } /// Adds an atomic reduction combiner to the given OpenMP reduction declaration /// using llvm.atomicrmw of the given kind. static omp::DeclareReductionOp addAtomicRMW(OpBuilder &builder, LLVM::AtomicBinOp atomicKind, omp::DeclareReductionOp decl, scf::ReduceOp reduce, int64_t reductionIndex) { … } /// Creates an OpenMP reduction declaration that corresponds to the given SCF /// reduction and returns it. Recognizes common reductions in order to identify /// the neutral value, necessary for the OpenMP declaration. If the reduction /// cannot be recognized, returns null. static omp::DeclareReductionOp declareReduction(PatternRewriter &builder, scf::ReduceOp reduce, int64_t reductionIndex) { … } namespace { struct ParallelOpLowering : public OpRewritePattern<scf::ParallelOp> { … }; /// Applies the conversion patterns in the given function. static LogicalResult applyPatterns(ModuleOp module, unsigned numThreads) { … } /// A pass converting SCF operations to OpenMP operations. struct SCFToOpenMPPass : public impl::ConvertSCFToOpenMPPassBase<SCFToOpenMPPass> { … }; } // namespace