16 #include "../PassDetail.h" 44 arith::CmpIPredicate predicate,
46 assert(!llvm::empty(values) &&
"empty min/max chain");
48 auto valueIt = values.begin();
50 for (; valueIt != values.end(); ++valueIt) {
51 auto cmpOp = builder.
create<arith::CmpIOp>(loc, predicate,
value, *valueIt);
52 value = builder.
create<arith::SelectOp>(loc, cmpOp.getResult(),
value,
84 op.getUpperBoundOperands());
92 op.getLowerBoundOperands());
135 if (isa<scf::ParallelOp>(op->getParentOp())) {
156 auto scfForOp = rewriter.
create<scf::ForOp>(loc, lowerBound, upperBound,
157 step, op.getIterOperands());
160 scfForOp.getRegion().end());
161 rewriter.
replaceOp(op, scfForOp.getResults());
181 lowerBoundTuple.reserve(op.getNumDims());
182 upperBoundTuple.reserve(op.getNumDims());
183 for (
unsigned i = 0, e = op.getNumDims(); i < e; ++i) {
185 op.getLowerBoundsOperands());
188 lowerBoundTuple.push_back(lower);
191 op.getUpperBoundsOperands());
194 upperBoundTuple.push_back(upper);
196 steps.reserve(op.getSteps().size());
197 for (int64_t step : op.getSteps())
201 Operation *affineParOpTerminator = op.getBody()->getTerminator();
202 scf::ParallelOp parOp;
203 if (op.getResults().empty()) {
205 parOp = rewriter.
create<scf::ParallelOp>(loc, lowerBoundTuple,
206 upperBoundTuple, steps,
210 parOp.getRegion().end());
211 rewriter.
replaceOp(op, parOp.getResults());
218 for (
auto pair : llvm::zip(reductions, op.getResultTypes())) {
222 Type resultType = std::get<1>(pair);
224 arith::symbolizeAtomicRMWKind(
225 static_cast<uint64_t>(reduction.
cast<IntegerAttr>().getInt()));
226 assert(reductionOp &&
"Reduction operation cannot be of None Type");
227 arith::AtomicRMWKind reductionOpValue = *reductionOp;
228 identityVals.push_back(
231 parOp = rewriter.
create<scf::ParallelOp>(
232 loc, lowerBoundTuple, upperBoundTuple, steps, identityVals,
238 parOp.getRegion().end());
239 assert(reductions.size() == affineParOpTerminator->
getNumOperands() &&
240 "Unequal number of reductions and operands.");
241 for (
unsigned i = 0, end = reductions.size(); i < end; i++) {
244 arith::symbolizeAtomicRMWKind(
245 reductions[i].cast<IntegerAttr>().getInt());
246 assert(reductionOp &&
"Reduction Operation cannot be of None Type");
247 arith::AtomicRMWKind reductionOpValue = *reductionOp;
249 auto reduceOp = rewriter.
create<scf::ReduceOp>(
253 reductionOpValue, rewriter, loc,
254 reduceOp.getReductionOperator().front().getArgument(0),
255 reduceOp.getReductionOperator().front().getArgument(1));
256 rewriter.
create<scf::ReduceReturnOp>(loc, reductionResult);
258 rewriter.
replaceOp(op, parOp.getResults());
269 auto loc = op.getLoc();
272 auto integerSet = op.getIntegerSet();
275 auto operandsRef = llvm::makeArrayRef(operands);
278 Value cond =
nullptr;
279 for (
unsigned i = 0, e = integerSet.getNumConstraints(); i < e; ++i) {
280 AffineExpr constraintExpr = integerSet.getConstraint(i);
281 bool isEquality = integerSet.isEq(i);
284 auto numDims = integerSet.getNumDims();
286 operandsRef.take_front(numDims),
287 operandsRef.drop_front(numDims));
291 isEquality ? arith::CmpIPredicate::eq : arith::CmpIPredicate::sge;
293 rewriter.
create<arith::CmpIOp>(loc, pred, affResult, zeroConstant);
295 ? rewriter.
create<arith::AndIOp>(loc, cond, cmpVal).getResult()
302 bool hasElseRegion = !op.getElseRegion().empty();
303 auto ifOp = rewriter.
create<scf::IfOp>(loc, op.getResultTypes(), cond,
306 &ifOp.getThenRegion().back());
307 rewriter.
eraseBlock(&ifOp.getThenRegion().back());
310 &ifOp.getElseRegion().back());
311 rewriter.
eraseBlock(&ifOp.getElseRegion().back());
315 rewriter.
replaceOp(op, ifOp.getResults());
328 auto maybeExpandedMap =
330 llvm::to_vector<8>(op.getOperands()));
331 if (!maybeExpandedMap)
333 rewriter.
replaceOp(op, *maybeExpandedMap);
349 auto resultOperands =
372 auto resultOperands =
379 op, op.getMemref(), *resultOperands, op.getIsWrite(),
380 op.getLocalityHint(), op.getIsDataCache());
396 auto maybeExpandedMap =
398 if (!maybeExpandedMap)
403 op, op.getValueToStore(), op.getMemRef(), *maybeExpandedMap);
419 auto operandsRef = llvm::makeArrayRef(operands);
425 if (!maybeExpandedSrcMap)
431 if (!maybeExpandedDstMap)
437 if (!maybeExpandedTagMap)
442 op, op.
getSrcMemRef(), *maybeExpandedSrcMap, op.getDstMemRef(),
443 *maybeExpandedDstMap, op.getNumElements(), op.getTagMemRef(),
444 *maybeExpandedTagMap, op.getStride(), op.getNumElementsPerStride());
460 auto maybeExpandedTagMap =
462 if (!maybeExpandedTagMap)
467 op, op.
getTagMemRef(), *maybeExpandedTagMap, op.getNumElements());
475 class AffineVectorLoadLowering :
public OpRewritePattern<AffineVectorLoadOp> {
483 auto resultOperands =
490 op, op.getVectorType(), op.getMemRef(), *resultOperands);
498 class AffineVectorStoreLowering :
public OpRewritePattern<AffineVectorStoreOp> {
506 auto maybeExpandedMap =
508 if (!maybeExpandedMap)
512 op, op.getValueToStore(), op.getMemRef(), *maybeExpandedMap);
523 AffineDmaStartLowering,
524 AffineDmaWaitLowering,
528 AffineParallelLowering,
529 AffinePrefetchLowering,
533 AffineYieldOpLowering>(patterns.
getContext());
541 AffineVectorLoadLowering,
542 AffineVectorStoreLowering>(patterns.
getContext());
547 class LowerAffinePass :
public ConvertAffineToStandardBase<LowerAffinePass> {
548 void runOnOperation()
override {
553 target.
addLegalDialect<arith::ArithmeticDialect, memref::MemRefDialect,
554 scf::SCFDialect, VectorDialect>();
556 std::move(patterns))))
565 return std::make_unique<LowerAffinePass>();
TODO: Remove this file when SCCP and integer range analysis have been ported to the new framework...
Optional< SmallVector< Value, 8 > > expandAffineMap(OpBuilder &builder, Location loc, AffineMap affineMap, ValueRange operands)
Create a sequence of operations that implement the affineMap applied to the given operands (as it it ...
A special type of RewriterBase that coordinates the application of a rewrite pattern on the current I...
Operation is a basic unit of execution within MLIR.
LogicalResult applyPartialConversion(ArrayRef< Operation *> ops, ConversionTarget &target, const FrozenRewritePatternSet &patterns, DenseSet< Operation *> *unconvertedOps=nullptr)
Below we define several entry points for operation conversion.
void populateAffineToStdConversionPatterns(RewritePatternSet &patterns)
Collect a set of patterns to convert from the Affine dialect to the Standard dialect, in particular convert structured affine control flow into CFG branch-based control flow.
Specialization of arith.constant op that returns an integer value.
void setInsertionPoint(Block *block, Block::iterator insertPoint)
Set the insertion point to the specified location.
Value getOperand(unsigned idx)
bool failed(LogicalResult result)
Utility function that returns true if the provided LogicalResult corresponds to a failure value...
unsigned getNumOperands()
virtual void inlineRegionBefore(Region ®ion, Region &parent, Region::iterator before)
Move the blocks that belong to "region" before the given position in another region "parent"...
static constexpr const bool value
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Value getTagMemRef()
Returns the Tag MemRef associated with the DMA operation being waited on.
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
Operation * create(const OperationState &state)
Creates an operation given the fields represented as an OperationState.
This class represents an efficient way to signal success or failure.
LogicalResult failure(bool isFailure=true)
Utility function to generate a LogicalResult.
virtual void replaceOp(Operation *op, ValueRange newValues)
This method replaces the results of the operation with the specified list of values.
operand_range getTagIndices()
Returns the tag memref index for this DMA operation.
unsigned getSrcMemRefOperandIndex()
Returns the operand index of the source memref.
Attributes are known-constant values of operations.
Value getReductionOp(AtomicRMWKind op, OpBuilder &builder, Location loc, Value lhs, Value rhs)
Returns the value obtained by applying the reduction operation kind associated with a binary AtomicRM...
Base type for affine expression.
std::unique_ptr< Pass > createLowerAffinePass()
Lowers affine control flow operations (ForStmt, IfStmt and AffineApplyOp) to equivalent lower-level c...
Value lowerAffineLowerBound(AffineForOp op, OpBuilder &builder)
Emit code that computes the lower bound of the given affine loop using standard arithmetic operations...
static Value lowerAffineMapMax(OpBuilder &builder, Location loc, AffineMap map, ValueRange operands)
Emit instructions that correspond to computing the maximum value among the values of a (potentially) ...
A multi-dimensional affine map Affine map's are immutable like Type's, and they are uniqued...
AffineDmaWaitOp blocks until the completion of a DMA operation associated with the tag element 'tag[i...
Value getIdentityValue(AtomicRMWKind op, Type resultType, OpBuilder &builder, Location loc)
Returns the identity value associated with an AtomicRMWKind op.
Value getSrcMemRef()
Returns the source MemRefType for this DMA operation.
void addLegalDialect(StringRef name, Names... names)
Register the operations of the given dialects as legal.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
static Value lowerAffineMapMin(OpBuilder &builder, Location loc, AffineMap map, ValueRange operands)
Emit instructions that correspond to computing the minimum value among the values of a (potentially) ...
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
static Value buildMinMaxReductionSeq(Location loc, arith::CmpIPredicate predicate, ValueRange values, OpBuilder &builder)
Given a range of values, emit the code that reduces them with "min" or "max" depending on the provide...
AffineMap getTagMap()
Returns the affine map used to access the tag memref.
OpRewritePattern is a wrapper around RewritePattern that allows for matching and rewriting against an...
AffineMap getTagMap()
Returns the affine map used to access the tag memref.
AffineMap getSrcMap()
Returns the affine map used to access the source memref.
Location getLoc()
The source location the operation was defined or derived from.
RewritePatternSet & add(ConstructorArg &&arg, ConstructorArgs &&... args)
Add an instance of each of the pattern types 'Ts' to the pattern list with the given arguments...
OpTy replaceOpWithNewOp(Operation *op, Args &&...args)
Replaces the result op with a new op that is created without verification.
Specialization of arith.constant op that returns an integer of index type.
AffineMap getDstMap()
Returns the affine map used to access the destination memref.
unsigned getTagMemRefOperandIndex()
Returns the operand index of the tag memref.
AffineDmaStartOp starts a non-blocking DMA operation that transfers data from a source memref to a de...
void setInsertionPointToEnd(Block *block)
Sets the insertion point to the end of the specified block.
std::enable_if_t<!std::is_convertible< CallbackT, Twine >::value, LogicalResult > notifyMatchFailure(Location loc, CallbackT &&reasonCallback)
Used to notify the rewriter that the IR failed to be rewritten because of a match failure...
This class describes a specific conversion target.
Value expandAffineExpr(OpBuilder &builder, Location loc, AffineExpr expr, ValueRange dimValues, ValueRange symbolValues)
Emit code that computes the given affine expression using standard arithmetic operations applied to t...
This class helps build Operations.
Value lowerAffineUpperBound(AffineForOp op, OpBuilder &builder)
Emit code that computes the upper bound of the given affine loop using standard arithmetic operations...
This class provides an abstraction over the different types of ranges over Values.
void populateAffineToVectorConversionPatterns(RewritePatternSet &patterns)
Collect a set of patterns to convert vector-related Affine ops to the Vector dialect.
MLIRContext * getContext() const
unsigned getDstMemRefOperandIndex()
Returns the operand index of the destination memref.
virtual void eraseBlock(Block *block)
This method erases all operations in a block.