23#include "llvm/ADT/StringExtras.h"
24#include "llvm/Support/Debug.h"
28#define GEN_PASS_DEF_ACCEMITREMARKSLOOP
29#include "mlir/Dialect/OpenACC/Transforms/Passes.h.inc"
33#define DEBUG_TYPE "acc-emit-remarks-loop"
40computeRegionInSpecializedAccRoutine(acc::ComputeRegionOp computeRegion) {
41 if (
auto func = computeRegion->getParentOfType<FunctionOpInterface>())
46static bool shouldEmitLoopRemarks(acc::ComputeRegionOp computeRegion) {
47 StringRef origin = computeRegion.getOrigin();
48 if (origin == acc::KernelsOp::getOperationName() ||
49 origin == acc::ParallelOp::getOperationName() ||
50 origin == acc::SerialOp::getOperationName())
53 return computeRegionInSpecializedAccRoutine(computeRegion);
56static std::string getACCParLevelName(acc::GPUParallelDimAttr parDim,
58 acc::ComputeRegionOp computeRegion) {
60 if (policy.
isSeq(parDim))
61 accName =
"sequential";
66 else if (policy.
isGang(parDim))
71 if (!policy.
isSeq(parDim) &&
72 !computeRegionInSpecializedAccRoutine(computeRegion)) {
73 if (std::optional<uint64_t> constant =
74 computeRegion.getKnownConstantLaunchArg(parDim))
75 accName +=
"(" + std::to_string(*constant) +
")";
80static std::string getGPUParDimName(acc::GPUParallelDimAttr parDim,
81 llvm::StringRef separator) {
82 auto formatDim = [&](llvm::StringRef prefix,
char axis) {
83 return (prefix + separator).str() + axis;
86 if (parDim.isThreadX())
87 return formatDim(
"threadidx",
'x');
88 if (parDim.isThreadY())
89 return formatDim(
"threadidx",
'y');
90 if (parDim.isThreadZ())
91 return formatDim(
"threadidx",
'z');
92 if (parDim.isBlockX())
93 return formatDim(
"blockidx",
'x');
94 if (parDim.isBlockY())
95 return formatDim(
"blockidx",
'y');
96 if (parDim.isBlockZ())
97 return formatDim(
"blockidx",
'z');
101static void emitLoopMappingRemark(acc::ComputeRegionOp computeRegion,
102 LoopLikeOpInterface loopOp,
105 llvm::StringRef gpuDimSeparator) {
106 acc::GPUParallelDimsAttr parDimsAttr =
107 loopOp->getAttrOfType<acc::GPUParallelDimsAttr>(
108 acc::GPUParallelDimsAttr::name);
113 parDims = parDimsAttr.getArray();
114 }
else if (isa<scf::ForOp>(loopOp.getOperation())) {
115 seqParDims.push_back(acc::GPUParallelDimAttr::seqDim(loopOp->getContext()));
116 parDims = seqParDims;
127 for (acc::GPUParallelDimAttr parDim : parDims) {
128 accMsgs.push_back(getACCParLevelName(parDim, policy, computeRegion));
129 if (std::string gpuName = getGPUParDimName(parDim, gpuDimSeparator);
131 gpuMsgs.push_back(std::move(gpuName));
134 std::string msg =
"!$acc loop " + llvm::join(accMsgs,
", ");
138 msg +=
" collapse(" + std::to_string(collapseCount) +
")";
140 if (!gpuMsgs.empty())
141 msg +=
" ! " + llvm::join(gpuMsgs,
" ");
147class ACCEmitRemarksLoop
150 using ACCEmitRemarksLoopBase<ACCEmitRemarksLoop>::ACCEmitRemarksLoopBase;
152 void runOnOperation()
override {
153 func::FuncOp
func = getOperation();
156 if (gpuDimSeparator.empty())
157 gpuDimSeparator =
".";
159 func.walk([&](acc::ComputeRegionOp computeRegion) {
160 if (!shouldEmitLoopRemarks(computeRegion))
163 computeRegion.getRegion().walk([&](LoopLikeOpInterface loopOp) {
164 emitLoopMappingRemark(computeRegion, loopOp, accSupport, policy,
virtual bool isWorker(ParDimAttrT attr) const =0
Check if the attribute represents worker parallelism.
virtual bool isSeq(ParDimAttrT attr) const =0
Check if the attribute represents sequential execution.
virtual bool isVector(ParDimAttrT attr) const =0
Check if the attribute represents vector parallelism.
virtual bool isGang(ParDimAttrT attr) const =0
Check if the attribute represents gang parallelism (any gang dimension).
Default policy that provides the standard GPU mapping: gang(dim:1) -> BlockX (gridDim....
remark::detail::InFlightRemark emitRemark(Operation *op, std::function< std::string()> messageFn, llvm::StringRef category="openacc")
Emit an OpenACC remark with lazy message generation.
uint64_t getCollapseCount(Operation *op)
Number of original loops collapsed into op, or 1 when op carries no collapse_count attribute.
bool isSpecializedAccRoutine(mlir::Operation *op)
Used to check whether this is a specialized accelerator version of acc routine function.
ACCParMappingPolicy< mlir::acc::GPUParallelDimAttr > ACCToGPUMappingPolicy
Type alias for the GPU-specific mapping policy.
Include the generated interface declarations.