MLIR 24.0.0git
ACCLegalizeSerial.cpp
Go to the documentation of this file.
1//===- ACCLegalizeSerial.cpp - Legalize ACC Serial region -----------------===//
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-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This pass converts acc.serial into acc.parallel with num_gangs(1)
10// num_workers(1) vector_length(1).
11//
12// This transformation simplifies processing of acc regions by unifying the
13// handling of serial and parallel constructs. Since an OpenACC serial region
14// executes sequentially (like a parallel region with a single gang, worker, and
15// vector), this conversion is semantically equivalent while enabling code reuse
16// in later compilation stages.
17//
18//===----------------------------------------------------------------------===//
19
22
26#include "mlir/IR/Builders.h"
28#include "mlir/IR/Location.h"
29#include "mlir/IR/MLIRContext.h"
31#include "mlir/IR/Region.h"
32#include "mlir/IR/Value.h"
33#include "mlir/Support/LLVM.h"
36#include "llvm/Support/Debug.h"
37
38namespace mlir {
39namespace acc {
40#define GEN_PASS_DEF_ACCLEGALIZESERIAL
41#include "mlir/Dialect/OpenACC/Transforms/Passes.h.inc"
42} // namespace acc
43} // namespace mlir
44
45#define DEBUG_TYPE "acc-legalize-serial"
46
47namespace {
48using namespace mlir;
49
50struct ACCSerialOpConversion : public OpRewritePattern<acc::SerialOp> {
51 using OpRewritePattern<acc::SerialOp>::OpRewritePattern;
52
53 LogicalResult matchAndRewrite(acc::SerialOp serialOp,
54 PatternRewriter &rewriter) const override {
55
56 const Location loc = serialOp.getLoc();
57
58 // Create a container holding the constant value of 1 for use as the
59 // num_gangs, num_workers, and vector_length attributes.
61 auto value = arith::ConstantIntOp::create(rewriter, loc, 1, 32);
62 numValues.push_back(value);
63
64 // Since num_gangs is specified as both attributes and values, create a
65 // segment attribute.
66 llvm::SmallVector<int32_t> numGangsSegments;
67 numGangsSegments.push_back(numValues.size());
68 auto gangSegmentsAttr = rewriter.getDenseI32ArrayAttr(numGangsSegments);
69
70 // Create a device_type attribute set to `none` which ensures that
71 // the parallel dimensions specification applies to the default clauses.
73 auto crtDeviceTypeAttr = mlir::acc::DeviceTypeAttr::get(
74 rewriter.getContext(), mlir::acc::DeviceType::None);
75 crtDeviceTypes.push_back(crtDeviceTypeAttr);
76 auto devTypeAttr =
77 mlir::ArrayAttr::get(rewriter.getContext(), crtDeviceTypes);
78
79 LLVM_DEBUG(llvm::dbgs() << "acc.serial OP: " << serialOp << "\n");
80
81 // Create a new acc.parallel op with the same operands - except include the
82 // num_gangs, num_workers, and vector_length attributes.
83 acc::ParallelOp parOp = acc::ParallelOp::create(
84 rewriter, loc, serialOp.getAsyncOperands(),
85 serialOp.getAsyncOperandsDeviceTypeAttr(), serialOp.getAsyncOnlyAttr(),
86 serialOp.getWaitOperands(), serialOp.getWaitOperandsSegmentsAttr(),
87 serialOp.getWaitOperandsDeviceTypeAttr(),
88 serialOp.getHasWaitDevnumAttr(), serialOp.getWaitOnlyAttr(), numValues,
89 gangSegmentsAttr, devTypeAttr, numValues, devTypeAttr, numValues,
90 devTypeAttr, serialOp.getIfCond(), serialOp.getSelfCond(),
91 serialOp.getSelfAttrAttr(), serialOp.getReductionOperands(),
92 serialOp.getPrivateOperands(), serialOp.getFirstprivateOperands(),
93 serialOp.getDataClauseOperands(), serialOp.getDefaultAttrAttr(),
94 serialOp.getCombinedAttr());
95
96 parOp.getRegion().takeBody(serialOp.getRegion());
97
98 LLVM_DEBUG(llvm::dbgs() << "acc.parallel OP: " << parOp << "\n");
99 rewriter.replaceOp(serialOp, parOp);
100
101 return success();
102 }
103};
104
105class ACCLegalizeSerial
106 : public mlir::acc::impl::ACCLegalizeSerialBase<ACCLegalizeSerial> {
107public:
108 using ACCLegalizeSerialBase<ACCLegalizeSerial>::ACCLegalizeSerialBase;
109
110 void getDependentDialects(DialectRegistry &registry) const override {
111 ACCLegalizeSerialBase<ACCLegalizeSerial>::getDependentDialects(registry);
113 }
114 void runOnOperation() override {
115 func::FuncOp funcOp = getOperation();
116 MLIRContext *context = funcOp.getContext();
117 RewritePatternSet patterns(context);
118 patterns.insert<ACCSerialOpConversion>(context);
119 (void)applyPatternsGreedily(funcOp, std::move(patterns));
120 }
121};
122} // namespace
return success()
DenseI32ArrayAttr getDenseI32ArrayAttr(ArrayRef< int32_t > values)
Definition Builders.cpp:171
MLIRContext * getContext() const
Definition Builders.h:56
The DialectRegistry maps a dialect namespace to a constructor for the matching dialect.
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition Location.h:76
MLIRContext is the top-level object for a collection of MLIR operations.
Definition MLIRContext.h:71
A special type of RewriterBase that coordinates the application of a rewrite pattern on the current I...
RewritePatternSet & insert(ConstructorArg &&arg, ConstructorArgs &&...args)
Add an instance of each of the pattern types 'Ts' to the pattern list with the given arguments.
virtual void replaceOp(Operation *op, ValueRange newValues)
Replace the results of the given (original) operation with the specified list of values (replacements...
static ConstantIntOp create(OpBuilder &builder, Location location, int64_t value, unsigned width)
Definition ArithOps.cpp:333
void registerAllExtensions(DialectRegistry &registry)
Register the standard OpenACC models for GPU, LLVM and MemRef IR.
Include the generated interface declarations.
LogicalResult applyPatternsGreedily(Region &region, const FrozenRewritePatternSet &patterns, GreedyRewriteConfig config=GreedyRewriteConfig(), bool *changed=nullptr)
Rewrite ops in the given region, which must be isolated from above, by repeatedly applying the highes...
OpRewritePattern is a wrapper around RewritePattern that allows for matching and rewriting against an...