MLIR 24.0.0git
ACCSpecializePatterns.h
Go to the documentation of this file.
1//===- ACCSpecializePatterns.h - Common ACC Specialization Patterns ------===//
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 file contains common rewrite pattern templates used by both
10// ACCSpecializeForHost and ACCSpecializeForDevice passes.
11//
12// The patterns provide the following transformations:
13//
14// - ACCOpReplaceWithVarConversion<OpTy>: Replaces a data entry operation
15// with its var operand. Used for ops like acc.copyin, acc.create, etc.
16//
17// - ACCOpEraseConversion<OpTy>: Simply erases an operation. Used for
18// data exit ops like acc.copyout, acc.delete, and runtime ops.
19//
20// - ACCRegionUnwrapConversion<OpTy>: Inlines the region of an operation
21// and erases the wrapper. Used for structured data constructs
22// (acc.data, acc.host_data) and compute constructs (acc.parallel, etc.)
23//
24// - ACCDeclareEnterOpConversion: Erases acc.declare_enter and its
25// associated acc.declare_exit operation.
26//
27//===----------------------------------------------------------------------===//
28
29#ifndef MLIR_DIALECT_OPENACC_TRANSFORMS_ACCSPECIALIZEPATTERNS_H
30#define MLIR_DIALECT_OPENACC_TRANSFORMS_ACCSPECIALIZEPATTERNS_H
31
35
36namespace mlir {
37namespace acc {
38
39//===----------------------------------------------------------------------===//
40// Generic pattern templates for ACC specialization
41//===----------------------------------------------------------------------===//
42
43/// Pattern to replace an ACC op with its var operand.
44/// Used for data entry ops like acc.copyin, acc.create, acc.attach, etc.
45template <typename OpTy>
48
49public:
50 LogicalResult matchAndRewrite(OpTy op,
51 PatternRewriter &rewriter) const override {
52 // Defer if any user validates its operands as data entry ops (e.g.
53 // acc.data, acc.parallel, acc.declare_enter). Replacing the data entry
54 // op before these are processed would leave them with an invalid operand
55 // and fail IR verification.
56 for (Operation *user : op->getUsers()) {
57 if (isa<acc::DataOp, acc::HostDataOp, acc::KernelEnvironmentOp,
58 acc::ParallelOp, acc::SerialOp, acc::KernelsOp,
59 acc::DeclareEnterOp, acc::EnterDataOp>(user))
60 return failure();
61 }
62 // Replace this op with its var operand; it's possible the op has no uses
63 // if the op that had previously used it was already converted.
64 if (op->use_empty())
65 rewriter.eraseOp(op);
66 else
67 rewriter.replaceOp(op, op.getVar());
68 return success();
69 }
70};
71
72/// Pattern to simply erase an ACC op (for ops with no results).
73/// Used for data exit ops like acc.copyout, acc.delete, acc.detach, etc.
74template <typename OpTy>
77
78public:
79 LogicalResult matchAndRewrite(OpTy op,
80 PatternRewriter &rewriter) const override {
81 assert(op->getNumResults() == 0 && "expected op with no results");
82 rewriter.eraseOp(op);
83 return success();
84 }
85};
86
87/// Pattern to unwrap a region from an ACC op and erase the wrapper.
88/// Moves the region's contents to the parent block and removes the wrapper op.
89/// A multi-block region is wrapped in scf.execute_region instead, since its
90/// blocks cannot be moved into the parent block. Used for structured data
91/// constructs (acc.data, acc.host_data, acc.kernel_environment, acc.declare)
92/// and compute constructs (acc.parallel, acc.serial, acc.kernels).
93template <typename OpTy>
96
97public:
98 LogicalResult matchAndRewrite(OpTy op,
99 PatternRewriter &rewriter) const override {
100 Region &region = op.getRegion();
101 if (region.empty()) {
102 rewriter.eraseOp(op);
103 return success();
104 }
105 if (!region.hasOneBlock()) {
106 rewriter.setInsertionPoint(op);
107 IRMapping mapping;
108 wrapMultiBlockRegionWithSCFExecuteRegion(region, mapping, op.getLoc(),
109 rewriter);
110 rewriter.eraseOp(op);
111 return success();
112 }
113 Block *block = &region.front();
114 // Erase the terminator (acc.yield or acc.terminator) before unwrapping
115 rewriter.eraseOp(block->getTerminator());
116 rewriter.inlineBlockBefore(block, op);
117 rewriter.eraseOp(op);
118 return success();
119 }
120};
121
122/// Pattern to erase acc.declare_enter and its associated acc.declare_exit.
123/// The declare_enter produces a token that is consumed by declare_exit.
125 : public OpRewritePattern<acc::DeclareEnterOp> {
126 using OpRewritePattern<acc::DeclareEnterOp>::OpRewritePattern;
127
128public:
129 LogicalResult matchAndRewrite(acc::DeclareEnterOp op,
130 PatternRewriter &rewriter) const override {
131 // If the enter token is used by an exit, erase exit first.
132 if (!op->use_empty()) {
133 assert(op->hasOneUse() && "expected one use");
134 auto exitOp = dyn_cast<acc::DeclareExitOp>(*op->getUsers().begin());
135 assert(exitOp && "expected declare exit op");
136 rewriter.eraseOp(exitOp);
137 }
138 rewriter.eraseOp(op);
139 return success();
140 }
141};
142
143} // namespace acc
144} // namespace mlir
145
146#endif // MLIR_DIALECT_OPENACC_TRANSFORMS_ACCSPECIALIZEPATTERNS_H
return success()
Block represents an ordered list of Operations.
Definition Block.h:34
Operation * getTerminator()
Get the terminator operation of this block.
Definition Block.cpp:249
This is a utility class for mapping one set of IR entities to another.
Definition IRMapping.h:26
void setInsertionPoint(Block *block, Block::iterator insertPoint)
Set the insertion point to the specified location.
Definition Builders.h:401
Operation is the basic unit of execution within MLIR.
Definition Operation.h:87
A special type of RewriterBase that coordinates the application of a rewrite pattern on the current I...
This class contains a list of basic blocks and a link to the parent operation it is attached to.
Definition Region.h:26
Block & front()
Definition Region.h:65
bool empty()
Definition Region.h:60
bool hasOneBlock()
Return true if this region has exactly one block.
Definition Region.h:68
virtual void replaceOp(Operation *op, ValueRange newValues)
Replace the results of the given (original) operation with the specified list of values (replacements...
virtual void eraseOp(Operation *op)
This method erases an operation that is known to have no uses.
virtual void inlineBlockBefore(Block *source, Block *dest, Block::iterator before, ValueRange argValues={})
Inline the operations of block 'source' into block 'dest' before the given position.
Pattern to erase acc.declare_enter and its associated acc.declare_exit.
LogicalResult matchAndRewrite(acc::DeclareEnterOp op, PatternRewriter &rewriter) const override
Pattern to simply erase an ACC op (for ops with no results).
LogicalResult matchAndRewrite(OpTy op, PatternRewriter &rewriter) const override
Pattern to replace an ACC op with its var operand.
LogicalResult matchAndRewrite(OpTy op, PatternRewriter &rewriter) const override
Pattern to unwrap a region from an ACC op and erase the wrapper.
LogicalResult matchAndRewrite(OpTy op, PatternRewriter &rewriter) const override
scf::ExecuteRegionOp wrapMultiBlockRegionWithSCFExecuteRegion(Region &region, IRMapping &mapping, Location loc, RewriterBase &rewriter)
Wrap a multi-block region in an scf.execute_region.
Include the generated interface declarations.
OpRewritePattern(MLIRContext *context, PatternBenefit benefit=1, ArrayRef< StringRef > generatedNames={})