brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.9 KiB · 5aa1273 Raw
85 lines · cpp
1//===- LowerNontemporal.cpp -------------------------------------------===//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// Add nontemporal attributes to load and stores of variables marked as10// nontemporal.11//12//===----------------------------------------------------------------------===//13 14#include "flang/Optimizer/Dialect/FIRCG/CGOps.h"15#include "flang/Optimizer/Dialect/FIROpsSupport.h"16#include "flang/Optimizer/OpenMP/Passes.h"17#include "mlir/Dialect/OpenMP/OpenMPDialect.h"18#include "llvm/ADT/TypeSwitch.h"19 20using namespace mlir;21 22namespace flangomp {23#define GEN_PASS_DEF_LOWERNONTEMPORALPASS24#include "flang/Optimizer/OpenMP/Passes.h.inc"25} // namespace flangomp26 27namespace {28class LowerNontemporalPass29    : public flangomp::impl::LowerNontemporalPassBase<LowerNontemporalPass> {30  void addNonTemporalAttr(omp::SimdOp simdOp) {31    if (simdOp.getNontemporalVars().empty())32      return;33 34    std::function<mlir::Value(mlir::Value)> getBaseOperand =35        [&](mlir::Value operand) -> mlir::Value {36      auto *defOp = operand.getDefiningOp();37      while (defOp) {38        llvm::TypeSwitch<Operation *>(defOp)39            .Case<fir::ArrayCoorOp, fir::cg::XArrayCoorOp, fir::LoadOp>(40                [&](auto op) {41                  operand = op.getMemref();42                  defOp = operand.getDefiningOp();43                })44            .Case<fir::BoxAddrOp>([&](auto op) {45              operand = op.getVal();46              defOp = operand.getDefiningOp();47            })48            .Default([&](auto op) { defOp = nullptr; });49      }50      return operand;51    };52 53    // walk through the operations and mark the load and store as nontemporal54    simdOp->walk([&](Operation *op) {55      mlir::Value operand = nullptr;56 57      if (auto loadOp = llvm::dyn_cast<fir::LoadOp>(op))58        operand = loadOp.getMemref();59      else if (auto storeOp = llvm::dyn_cast<fir::StoreOp>(op))60        operand = storeOp.getMemref();61 62      // Skip load and store operations involving boxes (allocatable or pointer63      // types).64      if (operand && !(fir::isAllocatableType(operand.getType()) ||65                       fir::isPointerType((operand.getType())))) {66        operand = getBaseOperand(operand);67 68        // TODO : Handling of nontemporal clause inside atomic construct69        if (llvm::is_contained(simdOp.getNontemporalVars(), operand)) {70          if (auto loadOp = llvm::dyn_cast<fir::LoadOp>(op))71            loadOp.setNontemporal(true);72          else if (auto storeOp = llvm::dyn_cast<fir::StoreOp>(op))73            storeOp.setNontemporal(true);74        }75      }76    });77  }78 79  void runOnOperation() override {80    Operation *op = getOperation();81    op->walk([&](omp::SimdOp simdOp) { addNonTemporalAttr(simdOp); });82  }83};84} // namespace85