//===- MarkDeclareTarget.cpp ----------------------------------------------===//
//
// 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
//
//===----------------------------------------------------------------------===//
//
// Mark functions called from explicit target code as implicitly declare target.
//
//===----------------------------------------------------------------------===//

#include "mlir/Dialect/OpenMP/OpenMPDialect.h"
#include "mlir/IR/Operation.h"
#include "mlir/IR/SymbolTable.h"
#include "mlir/Interfaces/FunctionInterfaces.h"
#include "mlir/Pass/Pass.h"
#include "mlir/Support/LLVM.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/TypeSwitch.h"

namespace mlir {
namespace omp {

#define GEN_PASS_DEF_MARKDECLARETARGETPASS
#include "mlir/Dialect/OpenMP/Transforms/Passes.h.inc"

} // namespace omp
} // namespace mlir

using namespace mlir;
namespace {

class MarkDeclareTargetPass
    : public omp::impl::MarkDeclareTargetPassBase<MarkDeclareTargetPass> {

  struct ParentInfo {
    omp::DeclareTargetDeviceType devTy;
    omp::DeclareTargetCaptureClause capClause;
    bool automap;
  };

  void processSymbolRef(SymbolRefAttr symRef, ParentInfo parentInfo,
                        llvm::SmallPtrSet<Operation *, 16> visited) {
    Operation *symOp = getOperation().lookupSymbol(symRef);
    if (!symOp)
      return;
    auto current = llvm::dyn_cast<omp::DeclareTargetInterface>(symOp);
    if (!current)
      return;

    if (current.isDeclareTarget()) {
      auto currentDt = current.getDeclareTargetDeviceType();

      // Found the same function twice, with different device_types,
      // mark as Any as it belongs to both
      if (currentDt != parentInfo.devTy &&
          currentDt != omp::DeclareTargetDeviceType::any) {
        current.setDeclareTarget(omp::DeclareTargetDeviceType::any,
                                 current.getDeclareTargetCaptureClause(),
                                 current.getDeclareTargetAutomap());
      }
    } else {
      current.setDeclareTarget(parentInfo.devTy, parentInfo.capClause,
                               parentInfo.automap);
    }

    markNestedFuncs(parentInfo, symOp, visited);
  }

  void processReductionRefs(std::optional<mlir::ArrayAttr> symRefs,
                            ParentInfo parentInfo,
                            llvm::SmallPtrSet<Operation *, 16> visited) {
    if (!symRefs)
      return;

    for (auto symRef : symRefs->getAsRange<mlir::SymbolRefAttr>()) {
      if (auto declareReductionOp =
              getOperation().lookupSymbol<omp::DeclareReductionOp>(symRef)) {
        markNestedFuncs(parentInfo, declareReductionOp, visited);
      }
    }
  }

  void processReductionClauses(Operation *op, ParentInfo parentInfo,
                               llvm::SmallPtrSet<Operation *, 16> visited) {
    llvm::TypeSwitch<Operation &>(*op)
        .Case([&](omp::LoopOp op) {
          processReductionRefs(op.getReductionSyms(), parentInfo, visited);
        })
        .Case([&](omp::ParallelOp op) {
          processReductionRefs(op.getReductionSyms(), parentInfo, visited);
        })
        .Case([&](omp::SectionsOp op) {
          processReductionRefs(op.getReductionSyms(), parentInfo, visited);
        })
        .Case([&](omp::SimdOp op) {
          processReductionRefs(op.getReductionSyms(), parentInfo, visited);
        })
        .Case([&](omp::TargetOp op) {
          processReductionRefs(op.getInReductionSyms(), parentInfo, visited);
        })
        .Case([&](omp::TaskgroupOp op) {
          processReductionRefs(op.getTaskReductionSyms(), parentInfo, visited);
        })
        .Case([&](omp::TaskloopContextOp op) {
          processReductionRefs(op.getReductionSyms(), parentInfo, visited);
          processReductionRefs(op.getInReductionSyms(), parentInfo, visited);
        })
        .Case([&](omp::TaskOp op) {
          processReductionRefs(op.getInReductionSyms(), parentInfo, visited);
        })
        .Case([&](omp::TeamsOp op) {
          processReductionRefs(op.getReductionSyms(), parentInfo, visited);
        })
        .Case([&](omp::WsloopOp op) {
          processReductionRefs(op.getReductionSyms(), parentInfo, visited);
        })
        .Default([](Operation &) {});
  }

  void markNestedFuncs(ParentInfo parentInfo, Operation *currOp,
                       llvm::SmallPtrSet<Operation *, 16> visited) {
    if (visited.contains(currOp))
      return;
    visited.insert(currOp);

    currOp->walk([&, this](Operation *op) {
      if (auto callOp = llvm::dyn_cast<CallOpInterface>(op)) {
        if (auto symRef = llvm::dyn_cast_if_present<mlir::SymbolRefAttr>(
                callOp.getCallableForCallee())) {
          processSymbolRef(symRef, parentInfo, visited);
        }
      }
      processReductionClauses(op, parentInfo, visited);
    });
  }

  // This pass executes on mlir::ModuleOp's marking functions contained within
  // as implicitly declare target if they are called from within an explicitly
  // marked declare target function or a target region (TargetOp)
  void runOnOperation() override {
    for (auto funcOp : getOperation().getOps<FunctionOpInterface>()) {
      auto declareTargetOp =
          llvm::dyn_cast<omp::DeclareTargetInterface>(funcOp.getOperation());
      if (!declareTargetOp || !declareTargetOp.isDeclareTarget())
        continue;
      llvm::SmallPtrSet<Operation *, 16> visited;
      ParentInfo parentInfo{declareTargetOp.getDeclareTargetDeviceType(),
                            declareTargetOp.getDeclareTargetCaptureClause(),
                            declareTargetOp.getDeclareTargetAutomap()};
      markNestedFuncs(parentInfo, funcOp, visited);
    }

    // TODO: Extend to work with reverse-offloading, this shouldn't
    // require too much effort, just need to check the device clause
    // when it's lowering has been implemented and change the
    // DeclareTargetDeviceType argument from nohost to host depending on
    // the contents of the device clause
    getOperation()->walk([&](omp::TargetOp tarOp) {
      llvm::SmallPtrSet<Operation *, 16> visited;
      ParentInfo parentInfo = {
          /*devTy=*/omp::DeclareTargetDeviceType::nohost,
          /*capClause=*/omp::DeclareTargetCaptureClause::to,
          /*automap=*/false,
      };
      markNestedFuncs(parentInfo, tarOp, visited);
    });
  }
};
} // namespace
