brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.7 KiB · f6aa865 Raw
198 lines · c
1//===-- Lower/OpenMP/DataSharingProcessor.h ---------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/10//11//===----------------------------------------------------------------------===//12#ifndef FORTRAN_LOWER_DATASHARINGPROCESSOR_H13#define FORTRAN_LOWER_DATASHARINGPROCESSOR_H14 15#include "flang/Lower/AbstractConverter.h"16#include "flang/Lower/OpenMP.h"17#include "flang/Lower/OpenMP/Clauses.h"18#include "flang/Optimizer/Builder/FIRBuilder.h"19#include "flang/Parser/parse-tree.h"20#include "flang/Semantics/symbol.h"21#include "mlir/Dialect/OpenMP/OpenMPDialect.h"22#include <variant>23 24namespace mlir {25namespace omp {26struct PrivateClauseOps;27} // namespace omp28} // namespace mlir29 30namespace Fortran {31namespace lower {32namespace omp {33 34class DataSharingProcessor {35private:36  /// A symbol visitor that keeps track of the currently active OpenMPConstruct37  /// at any point in time. This is used to track Symbol definition scopes in38  /// order to tell which OMP scope defined vs. references a certain Symbol.39  struct OMPConstructSymbolVisitor {40    OMPConstructSymbolVisitor(semantics::SemanticsContext &ctx)41        : version(ctx.langOptions().OpenMPVersion) {}42    template <typename T>43    bool Pre(const T &) {44      return true;45    }46    template <typename T>47    void Post(const T &) {}48 49    bool Pre(const parser::OpenMPConstruct &omp) {50      // Skip constructs that may not have privatizations.51      if (isOpenMPPrivatizingConstruct(omp, version))52        constructs.push_back(&omp);53      return true;54    }55 56    void Post(const parser::OpenMPConstruct &omp) {57      if (isOpenMPPrivatizingConstruct(omp, version))58        constructs.pop_back();59    }60 61    void Post(const parser::Name &name) {62      auto current = !constructs.empty() ? constructs.back() : ConstructPtr();63      symDefMap.try_emplace(name.symbol, current);64    }65 66    bool Pre(const parser::DeclarationConstruct &decl) {67      constructs.push_back(&decl);68      return true;69    }70 71    void Post(const parser::DeclarationConstruct &decl) {72      constructs.pop_back();73    }74 75    /// Given a \p symbol and an \p eval, returns true if eval is the OMP76    /// construct that defines symbol.77    bool isSymbolDefineBy(const semantics::Symbol *symbol,78                          lower::pft::Evaluation &eval) const;79 80    // Given a \p symbol, returns true if it is defined by a nested81    // `DeclarationConstruct`.82    bool83    isSymbolDefineByNestedDeclaration(const semantics::Symbol *symbol) const;84 85  private:86    using ConstructPtr = std::variant<const parser::OpenMPConstruct *,87                                      const parser::DeclarationConstruct *>;88    llvm::SmallVector<ConstructPtr> constructs;89    llvm::DenseMap<semantics::Symbol *, ConstructPtr> symDefMap;90 91    unsigned version;92  };93 94  mlir::OpBuilder::InsertPoint lastPrivIP;95  llvm::SmallVector<mlir::Value> loopIVs;96  // Symbols in private, firstprivate, and/or lastprivate clauses.97  llvm::SetVector<const semantics::Symbol *> explicitlyPrivatizedSymbols;98  llvm::SetVector<const semantics::Symbol *> defaultSymbols;99  llvm::SetVector<const semantics::Symbol *> implicitSymbols;100  llvm::SetVector<const semantics::Symbol *> preDeterminedSymbols;101  llvm::SetVector<const semantics::Symbol *> allPrivatizedSymbols;102 103  lower::AbstractConverter &converter;104  semantics::SemanticsContext &semaCtx;105  fir::FirOpBuilder &firOpBuilder;106  omp::List<omp::Clause> clauses;107  lower::pft::Evaluation &eval;108  bool shouldCollectPreDeterminedSymbols;109  bool useDelayedPrivatization;110  llvm::SmallPtrSet<const semantics::Symbol *, 16> mightHaveReadHostSym;111  lower::SymMap &symTable;112  bool isTargetPrivatization;113  OMPConstructSymbolVisitor visitor;114 115  bool needBarrier();116  void collectSymbols(semantics::Symbol::Flag flag,117                      llvm::SetVector<const semantics::Symbol *> &symbols);118  void collectSymbolsInNestedRegions(119      lower::pft::Evaluation &eval, semantics::Symbol::Flag flag,120      llvm::SetVector<const semantics::Symbol *> &symbolsInNestedRegions);121  void collectOmpObjectListSymbol(122      const omp::ObjectList &objects,123      llvm::SetVector<const semantics::Symbol *> &symbolSet);124  void collectSymbolsForPrivatization();125  void insertBarrier(mlir::omp::PrivateClauseOps *clauseOps);126  void collectDefaultSymbols();127  void collectImplicitSymbols();128  void collectPreDeterminedSymbols();129  void privatize(mlir::omp::PrivateClauseOps *clauseOps,130                 std::optional<llvm::omp::Directive> dir = std::nullopt);131  void copyLastPrivatize(mlir::Operation *op);132  void insertLastPrivateCompare(mlir::Operation *op);133  void cloneSymbol(const semantics::Symbol *sym);134  void135  copyFirstPrivateSymbol(const semantics::Symbol *sym,136                         mlir::OpBuilder::InsertPoint *copyAssignIP = nullptr);137  void copyLastPrivateSymbol(const semantics::Symbol *sym,138                             mlir::OpBuilder::InsertPoint *lastPrivIP);139  void insertDeallocs();140 141  static bool isOpenMPPrivatizingConstruct(const parser::OpenMPConstruct &omp,142                                           unsigned version);143  bool isOpenMPPrivatizingEvaluation(const pft::Evaluation &eval) const;144 145public:146  DataSharingProcessor(lower::AbstractConverter &converter,147                       semantics::SemanticsContext &semaCtx,148                       const List<Clause> &clauses,149                       lower::pft::Evaluation &eval,150                       bool shouldCollectPreDeterminedSymbols,151                       bool useDelayedPrivatization, lower::SymMap &symTable,152                       bool isTargetPrivatization = false);153 154  DataSharingProcessor(lower::AbstractConverter &converter,155                       semantics::SemanticsContext &semaCtx,156                       lower::pft::Evaluation &eval,157                       bool useDelayedPrivatization, lower::SymMap &symTable,158                       bool isTargetPrivatization = false);159 160  // Privatisation is split into two steps.161  // Step1 performs cloning of all privatisation clauses and copying for162  // firstprivates. Step1 is performed at the place where process/processStep1163  // is called. This is usually inside the Operation corresponding to the OpenMP164  // construct, for looping constructs this is just before the Operation. The165  // split into two steps was performed basically to be able to call166  // privatisation for looping constructs before the operation is created since167  // the bounds of the MLIR OpenMP operation can be privatised.168  // Step2 performs the copying for lastprivates and requires knowledge of the169  // MLIR operation to insert the last private update. Step2 adds170  // dealocation code as well.171  void processStep1(mlir::omp::PrivateClauseOps *clauseOps = nullptr,172                    std::optional<llvm::omp::Directive> dir = std::nullopt);173  void processStep2(mlir::Operation *op, bool isLoop);174 175  void pushLoopIV(mlir::Value iv) { loopIVs.push_back(iv); }176 177  const llvm::SetVector<const semantics::Symbol *> &178  getAllSymbolsToPrivatize() const {179    return allPrivatizedSymbols;180  }181 182  llvm::ArrayRef<const semantics::Symbol *> getDelayedPrivSymbols() const {183    return useDelayedPrivatization184               ? allPrivatizedSymbols.getArrayRef()185               : llvm::ArrayRef<const semantics::Symbol *>();186  }187 188  void privatizeSymbol(const semantics::Symbol *symToPrivatize,189                       mlir::omp::PrivateClauseOps *clauseOps,190                       std::optional<llvm::omp::Directive> dir = std::nullopt);191};192 193} // namespace omp194} // namespace lower195} // namespace Fortran196 197#endif // FORTRAN_LOWER_DATASHARINGPROCESSOR_H198