[mlir][Affine][NFC] Wrap dialect in "affine" namespace

This cleanup aligns the affine dialect with all the other dialects.

Differential Revision: https://reviews.llvm.org/D148687
This commit is contained in:
Matthias Springer 2023-04-20 11:02:05 +09:00
parent fbc63e5658
commit 4c48f016ef
153 changed files with 918 additions and 734 deletions

View File

@ -27,7 +27,7 @@
namespace fir::support {
#define FLANG_NONCODEGEN_DIALECT_LIST \
mlir::AffineDialect, FIROpsDialect, hlfir::hlfirDialect, \
mlir::affine::AffineDialect, FIROpsDialect, hlfir::hlfirDialect, \
mlir::acc::OpenACCDialect, mlir::omp::OpenMPDialect, \
mlir::scf::SCFDialect, mlir::arith::ArithDialect, \
mlir::cf::ControlFlowDialect, mlir::func::FuncDialect, \
@ -63,25 +63,25 @@ inline void loadDialects(mlir::MLIRContext &context) {
inline void registerMLIRPassesForFortranTools() {
mlir::registerCanonicalizerPass();
mlir::registerCSEPass();
mlir::registerAffineLoopFusionPass();
mlir::affine::registerAffineLoopFusionPass();
mlir::registerLoopInvariantCodeMotionPass();
mlir::registerLoopCoalescingPass();
mlir::affine::registerLoopCoalescingPass();
mlir::registerStripDebugInfoPass();
mlir::registerPrintOpStatsPass();
mlir::registerInlinerPass();
mlir::registerSCCPPass();
mlir::registerAffineScalarReplacementPass();
mlir::affine::registerAffineScalarReplacementPass();
mlir::registerSymbolDCEPass();
mlir::registerLocationSnapshotPass();
mlir::registerAffinePipelineDataTransferPass();
mlir::affine::registerAffinePipelineDataTransferPass();
mlir::registerAffineVectorizePass();
mlir::registerAffineLoopUnrollPass();
mlir::registerAffineLoopUnrollAndJamPass();
mlir::registerSimplifyAffineStructuresPass();
mlir::registerAffineLoopInvariantCodeMotionPass();
mlir::registerAffineLoopTilingPass();
mlir::registerAffineDataCopyGenerationPass();
mlir::affine::registerAffineVectorizePass();
mlir::affine::registerAffineLoopUnrollPass();
mlir::affine::registerAffineLoopUnrollAndJamPass();
mlir::affine::registerSimplifyAffineStructuresPass();
mlir::affine::registerAffineLoopInvariantCodeMotionPass();
mlir::affine::registerAffineLoopTilingPass();
mlir::affine::registerAffineDataCopyGenerationPass();
mlir::registerConvertAffineToStandardPass();
}

View File

@ -64,7 +64,8 @@ def AffineDialectPromotion : Pass<"promote-to-affine", "::mlir::func::FuncOp"> {
}];
let constructor = "::fir::createPromoteToAffinePass()";
let dependentDialects = [
"fir::FIROpsDialect", "mlir::func::FuncDialect", "mlir::AffineDialect"
"fir::FIROpsDialect", "mlir::func::FuncDialect",
"mlir::affine::AffineDialect"
];
}
@ -78,7 +79,8 @@ def AffineDialectDemotion : Pass<"demote-affine", "::mlir::func::FuncOp"> {
}];
let constructor = "::fir::createAffineDemotionPass()";
let dependentDialects = [
"fir::FIROpsDialect", "mlir::func::FuncDialect", "mlir::AffineDialect"
"fir::FIROpsDialect", "mlir::func::FuncDialect",
"mlir::affine::AffineDialect"
];
}

View File

@ -46,16 +46,17 @@ using namespace mlir;
namespace {
class AffineLoadConversion : public OpConversionPattern<mlir::AffineLoadOp> {
class AffineLoadConversion
: public OpConversionPattern<mlir::affine::AffineLoadOp> {
public:
using OpConversionPattern<mlir::AffineLoadOp>::OpConversionPattern;
using OpConversionPattern<mlir::affine::AffineLoadOp>::OpConversionPattern;
LogicalResult
matchAndRewrite(mlir::AffineLoadOp op, OpAdaptor adaptor,
matchAndRewrite(mlir::affine::AffineLoadOp op, OpAdaptor adaptor,
ConversionPatternRewriter &rewriter) const override {
SmallVector<Value> indices(adaptor.getIndices());
auto maybeExpandedMap =
expandAffineMap(rewriter, op.getLoc(), op.getAffineMap(), indices);
auto maybeExpandedMap = affine::expandAffineMap(rewriter, op.getLoc(),
op.getAffineMap(), indices);
if (!maybeExpandedMap)
return failure();
@ -68,16 +69,17 @@ public:
}
};
class AffineStoreConversion : public OpConversionPattern<mlir::AffineStoreOp> {
class AffineStoreConversion
: public OpConversionPattern<mlir::affine::AffineStoreOp> {
public:
using OpConversionPattern<mlir::AffineStoreOp>::OpConversionPattern;
using OpConversionPattern<mlir::affine::AffineStoreOp>::OpConversionPattern;
LogicalResult
matchAndRewrite(mlir::AffineStoreOp op, OpAdaptor adaptor,
matchAndRewrite(mlir::affine::AffineStoreOp op, OpAdaptor adaptor,
ConversionPatternRewriter &rewriter) const override {
SmallVector<Value> indices(op.getIndices());
auto maybeExpandedMap =
expandAffineMap(rewriter, op.getLoc(), op.getAffineMap(), indices);
auto maybeExpandedMap = affine::expandAffineMap(rewriter, op.getLoc(),
op.getAffineMap(), indices);
if (!maybeExpandedMap)
return failure();

View File

@ -227,7 +227,7 @@ private:
if (auto blockArg = value.dyn_cast<mlir::BlockArgument>()) {
affineArgs.push_back(value);
if (isa<fir::DoLoopOp>(blockArg.getOwner()->getParentOp()) ||
isa<mlir::AffineForOp>(blockArg.getOwner()->getParentOp()))
isa<mlir::affine::AffineForOp>(blockArg.getOwner()->getParentOp()))
return {mlir::getAffineDimExpr(dimCount++, value.getContext())};
return {mlir::getAffineSymbolExpr(symCount++, value.getContext())};
}
@ -397,7 +397,7 @@ static void populateIndexArgs(fir::ArrayCoorOp acoOp,
}
/// Returns affine.apply and fir.convert from array_coor and gendims
static std::pair<mlir::AffineApplyOp, fir::ConvertOp>
static std::pair<affine::AffineApplyOp, fir::ConvertOp>
createAffineOps(mlir::Value arrayRef, mlir::PatternRewriter &rewriter) {
auto acoOp = arrayRef.getDefiningOp<ArrayCoorOp>();
auto affineMap =
@ -407,8 +407,8 @@ createAffineOps(mlir::Value arrayRef, mlir::PatternRewriter &rewriter) {
populateIndexArgs(acoOp, indexArgs, rewriter);
auto affineApply = rewriter.create<mlir::AffineApplyOp>(acoOp.getLoc(),
affineMap, indexArgs);
auto affineApply = rewriter.create<affine::AffineApplyOp>(
acoOp.getLoc(), affineMap, indexArgs);
auto arrayElementType = coordinateArrayElement(acoOp);
auto newType =
mlir::MemRefType::get({mlir::ShapedType::kDynamic}, arrayElementType);
@ -420,7 +420,7 @@ createAffineOps(mlir::Value arrayRef, mlir::PatternRewriter &rewriter) {
static void rewriteLoad(fir::LoadOp loadOp, mlir::PatternRewriter &rewriter) {
rewriter.setInsertionPoint(loadOp);
auto affineOps = createAffineOps(loadOp.getMemref(), rewriter);
rewriter.replaceOpWithNewOp<mlir::AffineLoadOp>(
rewriter.replaceOpWithNewOp<affine::AffineLoadOp>(
loadOp, affineOps.second.getResult(), affineOps.first.getResult());
}
@ -428,9 +428,9 @@ static void rewriteStore(fir::StoreOp storeOp,
mlir::PatternRewriter &rewriter) {
rewriter.setInsertionPoint(storeOp);
auto affineOps = createAffineOps(storeOp.getMemref(), rewriter);
rewriter.replaceOpWithNewOp<mlir::AffineStoreOp>(storeOp, storeOp.getValue(),
affineOps.second.getResult(),
affineOps.first.getResult());
rewriter.replaceOpWithNewOp<affine::AffineStoreOp>(
storeOp, storeOp.getValue(), affineOps.second.getResult(),
affineOps.first.getResult());
}
static void rewriteMemoryOps(Block *block, mlir::PatternRewriter &rewriter) {
@ -483,7 +483,7 @@ public:
}
private:
std::pair<mlir::AffineForOp, mlir::Value>
std::pair<affine::AffineForOp, mlir::Value>
createAffineFor(fir::DoLoopOp op, mlir::PatternRewriter &rewriter) const {
if (auto constantStep = constantIntegerLike(op.getStep()))
if (*constantStep > 0)
@ -492,10 +492,10 @@ private:
}
// when step for the loop is positive compile time constant
std::pair<mlir::AffineForOp, mlir::Value>
std::pair<affine::AffineForOp, mlir::Value>
positiveConstantStep(fir::DoLoopOp op, int64_t step,
mlir::PatternRewriter &rewriter) const {
auto affineFor = rewriter.create<mlir::AffineForOp>(
auto affineFor = rewriter.create<affine::AffineForOp>(
op.getLoc(), ValueRange(op.getLowerBound()),
mlir::AffineMap::get(0, 1,
mlir::getAffineSymbolExpr(0, op.getContext())),
@ -506,14 +506,14 @@ private:
return std::make_pair(affineFor, affineFor.getInductionVar());
}
std::pair<mlir::AffineForOp, mlir::Value>
std::pair<affine::AffineForOp, mlir::Value>
genericBounds(fir::DoLoopOp op, mlir::PatternRewriter &rewriter) const {
auto lowerBound = mlir::getAffineSymbolExpr(0, op.getContext());
auto upperBound = mlir::getAffineSymbolExpr(1, op.getContext());
auto step = mlir::getAffineSymbolExpr(2, op.getContext());
mlir::AffineMap upperBoundMap = mlir::AffineMap::get(
0, 3, (upperBound - lowerBound + step).floorDiv(step));
auto genericUpperBound = rewriter.create<mlir::AffineApplyOp>(
auto genericUpperBound = rewriter.create<affine::AffineApplyOp>(
op.getLoc(), upperBoundMap,
ValueRange({op.getLowerBound(), op.getUpperBound(), op.getStep()}));
auto actualIndexMap = mlir::AffineMap::get(
@ -521,7 +521,7 @@ private:
(lowerBound + mlir::getAffineDimExpr(0, op.getContext())) *
mlir::getAffineSymbolExpr(1, op.getContext()));
auto affineFor = rewriter.create<mlir::AffineForOp>(
auto affineFor = rewriter.create<affine::AffineForOp>(
op.getLoc(), ValueRange(),
AffineMap::getConstantMap(0, op.getContext()),
genericUpperBound.getResult(),
@ -529,7 +529,7 @@ private:
1 + mlir::getAffineSymbolExpr(0, op.getContext())),
1);
rewriter.setInsertionPointToStart(affineFor.getBody());
auto actualIndex = rewriter.create<mlir::AffineApplyOp>(
auto actualIndex = rewriter.create<affine::AffineApplyOp>(
op.getLoc(), actualIndexMap,
ValueRange(
{affineFor.getInductionVar(), op.getLowerBound(), op.getStep()}));
@ -558,7 +558,7 @@ public:
<< "AffineIfConversion: couldn't calculate affine condition\n";);
return failure();
}
auto affineIf = rewriter.create<mlir::AffineIfOp>(
auto affineIf = rewriter.create<affine::AffineIfOp>(
op.getLoc(), affineCondition.getIntegerSet(),
affineCondition.getAffineArgs(), !op.getElseRegion().empty());
rewriter.startRootUpdate(affineIf);
@ -596,7 +596,7 @@ public:
patterns.insert<AffineIfConversion>(context, functionAnalysis);
patterns.insert<AffineLoopConversion>(context, functionAnalysis);
mlir::ConversionTarget target = *context;
target.addLegalDialect<mlir::AffineDialect, FIROpsDialect,
target.addLegalDialect<mlir::affine::AffineDialect, FIROpsDialect,
mlir::scf::SCFDialect, mlir::arith::ArithDialect,
mlir::func::FuncDialect>();
target.addDynamicallyLegalOp<IfOp>([&functionAnalysis](fir::IfOp op) {

View File

@ -110,7 +110,7 @@ public:
mlir::RewritePatternSet patterns(context);
patterns.insert<CharacterConvertConversion>(context);
mlir::ConversionTarget target(*context);
target.addLegalDialect<mlir::AffineDialect, fir::FIROpsDialect,
target.addLegalDialect<mlir::affine::AffineDialect, fir::FIROpsDialect,
mlir::arith::ArithDialect,
mlir::func::FuncDialect>();

View File

@ -316,8 +316,9 @@ public:
patterns.insert<CfgLoopConv, CfgIfConv, CfgIterWhileConv>(
context, forceLoopToExecuteOnce);
mlir::ConversionTarget target(*context);
target.addLegalDialect<mlir::AffineDialect, mlir::cf::ControlFlowDialect,
FIROpsDialect, mlir::func::FuncDialect>();
target.addLegalDialect<mlir::affine::AffineDialect,
mlir::cf::ControlFlowDialect, FIROpsDialect,
mlir::func::FuncDialect>();
// apply the patterns
target.addIllegalOp<ResultOp, DoLoopOp, IfOp, IterWhileOp>();

View File

@ -238,8 +238,9 @@ public:
patterns.insert<SelectTypeConv>(context, moduleMutex);
patterns.insert<DispatchOpConv>(context, bindingTables);
mlir::ConversionTarget target(*context);
target.addLegalDialect<mlir::AffineDialect, mlir::cf::ControlFlowDialect,
FIROpsDialect, mlir::func::FuncDialect>();
target.addLegalDialect<mlir::affine::AffineDialect,
mlir::cf::ControlFlowDialect, FIROpsDialect,
mlir::func::FuncDialect>();
// apply the patterns
target.addIllegalOp<SelectTypeOp>();

View File

@ -98,7 +98,8 @@ struct MyTarget : public ConversionTarget {
/// Mark all operations within Affine dialect have dynamic legality
/// constraints.
addDynamicallyLegalDialect<AffineDialect>([](Operation *op) { ... });
addDynamicallyLegalDialect<affine::AffineDialect>(
[](Operation *op) { ... });
/// Mark `func.return` as dynamically legal, but provide a specific legality
/// callback.

View File

@ -64,7 +64,7 @@ void ToyToAffineLoweringPass::runOnOperation() {
// We define the specific operations, or dialects, that are legal targets for
// this lowering. In our case, we are lowering to a combination of the
// `Affine`, `Arith`, `Func`, and `MemRef` dialects.
target.addLegalDialect<AffineDialect, arith::ArithDialect,
target.addLegalDialect<affine::AffineDialect, arith::ArithDialect,
func::FuncDialect, memref::MemRefDialect>();
// We also define the Toy dialect as Illegal so that the conversion will fail

View File

@ -75,14 +75,15 @@ static void lowerOpToLoops(Operation *op, ValueRange operands,
// loop induction variables.
SmallVector<int64_t, 4> lowerBounds(tensorType.getRank(), /*Value=*/0);
SmallVector<int64_t, 4> steps(tensorType.getRank(), /*Value=*/1);
buildAffineLoopNest(
affine::buildAffineLoopNest(
rewriter, loc, lowerBounds, tensorType.getShape(), steps,
[&](OpBuilder &nestedBuilder, Location loc, ValueRange ivs) {
// Call the processing function with the rewriter, the memref operands,
// and the loop induction variables. This function will return the value
// to store at the current index.
Value valueToStore = processIteration(nestedBuilder, operands, ivs);
nestedBuilder.create<AffineStoreOp>(loc, valueToStore, alloc, ivs);
nestedBuilder.create<affine::AffineStoreOp>(loc, valueToStore, alloc,
ivs);
});
// Replace this operation with the generated alloc.
@ -113,9 +114,9 @@ struct BinaryOpLowering : public ConversionPattern {
// Generate loads for the element of 'lhs' and 'rhs' at the
// inner loop.
auto loadedLhs = builder.create<AffineLoadOp>(
auto loadedLhs = builder.create<affine::AffineLoadOp>(
loc, binaryAdaptor.getLhs(), loopIvs);
auto loadedRhs = builder.create<AffineLoadOp>(
auto loadedRhs = builder.create<affine::AffineLoadOp>(
loc, binaryAdaptor.getRhs(), loopIvs);
// Create the binary operation performed on the loaded
@ -174,7 +175,7 @@ struct ConstantOpLowering : public OpRewritePattern<toy::ConstantOp> {
// The last dimension is the base case of the recursion, at this point
// we store the element at the given index.
if (dimension == valueShape.size()) {
rewriter.create<AffineStoreOp>(
rewriter.create<affine::AffineStoreOp>(
loc, rewriter.create<arith::ConstantOp>(loc, *valueIt++), alloc,
llvm::ArrayRef(indices));
return;
@ -291,8 +292,8 @@ struct TransposeOpLowering : public ConversionPattern {
// Transpose the elements by generating a load from the
// reverse indices.
SmallVector<Value, 2> reverseIvs(llvm::reverse(loopIvs));
return builder.create<AffineLoadOp>(loc, input,
reverseIvs);
return builder.create<affine::AffineLoadOp>(loc, input,
reverseIvs);
});
return success();
}
@ -313,7 +314,8 @@ struct ToyToAffineLoweringPass
MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(ToyToAffineLoweringPass)
void getDependentDialects(DialectRegistry &registry) const override {
registry.insert<AffineDialect, func::FuncDialect, memref::MemRefDialect>();
registry.insert<affine::AffineDialect, func::FuncDialect,
memref::MemRefDialect>();
}
void runOnOperation() final;
};
@ -327,8 +329,9 @@ void ToyToAffineLoweringPass::runOnOperation() {
// We define the specific operations, or dialects, that are legal targets for
// this lowering. In our case, we are lowering to a combination of the
// `Affine`, `Arith`, `Func`, and `MemRef` dialects.
target.addLegalDialect<AffineDialect, BuiltinDialect, arith::ArithDialect,
func::FuncDialect, memref::MemRefDialect>();
target.addLegalDialect<affine::AffineDialect, BuiltinDialect,
arith::ArithDialect, func::FuncDialect,
memref::MemRefDialect>();
// We also define the Toy dialect as Illegal so that the conversion will fail
// if any of these operations are *not* converted. Given that we actually want

View File

@ -148,8 +148,8 @@ int dumpMLIR() {
// Add optimizations if enabled.
if (enableOpt) {
optPM.addPass(mlir::createLoopFusionPass());
optPM.addPass(mlir::createAffineScalarReplacementPass());
optPM.addPass(mlir::affine::createLoopFusionPass());
optPM.addPass(mlir::affine::createAffineScalarReplacementPass());
}
}

View File

@ -75,14 +75,15 @@ static void lowerOpToLoops(Operation *op, ValueRange operands,
// loop induction variables.
SmallVector<int64_t, 4> lowerBounds(tensorType.getRank(), /*Value=*/0);
SmallVector<int64_t, 4> steps(tensorType.getRank(), /*Value=*/1);
buildAffineLoopNest(
affine::buildAffineLoopNest(
rewriter, loc, lowerBounds, tensorType.getShape(), steps,
[&](OpBuilder &nestedBuilder, Location loc, ValueRange ivs) {
// Call the processing function with the rewriter, the memref operands,
// and the loop induction variables. This function will return the value
// to store at the current index.
Value valueToStore = processIteration(nestedBuilder, operands, ivs);
nestedBuilder.create<AffineStoreOp>(loc, valueToStore, alloc, ivs);
nestedBuilder.create<affine::AffineStoreOp>(loc, valueToStore, alloc,
ivs);
});
// Replace this operation with the generated alloc.
@ -113,9 +114,9 @@ struct BinaryOpLowering : public ConversionPattern {
// Generate loads for the element of 'lhs' and 'rhs' at the
// inner loop.
auto loadedLhs = builder.create<AffineLoadOp>(
auto loadedLhs = builder.create<affine::AffineLoadOp>(
loc, binaryAdaptor.getLhs(), loopIvs);
auto loadedRhs = builder.create<AffineLoadOp>(
auto loadedRhs = builder.create<affine::AffineLoadOp>(
loc, binaryAdaptor.getRhs(), loopIvs);
// Create the binary operation performed on the loaded
@ -174,7 +175,7 @@ struct ConstantOpLowering : public OpRewritePattern<toy::ConstantOp> {
// The last dimension is the base case of the recursion, at this point
// we store the element at the given index.
if (dimension == valueShape.size()) {
rewriter.create<AffineStoreOp>(
rewriter.create<affine::AffineStoreOp>(
loc, rewriter.create<arith::ConstantOp>(loc, *valueIt++), alloc,
llvm::ArrayRef(indices));
return;
@ -291,8 +292,8 @@ struct TransposeOpLowering : public ConversionPattern {
// Transpose the elements by generating a load from the
// reverse indices.
SmallVector<Value, 2> reverseIvs(llvm::reverse(loopIvs));
return builder.create<AffineLoadOp>(loc, input,
reverseIvs);
return builder.create<affine::AffineLoadOp>(loc, input,
reverseIvs);
});
return success();
}
@ -313,7 +314,8 @@ struct ToyToAffineLoweringPass
MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(ToyToAffineLoweringPass)
void getDependentDialects(DialectRegistry &registry) const override {
registry.insert<AffineDialect, func::FuncDialect, memref::MemRefDialect>();
registry.insert<affine::AffineDialect, func::FuncDialect,
memref::MemRefDialect>();
}
void runOnOperation() final;
};
@ -327,8 +329,9 @@ void ToyToAffineLoweringPass::runOnOperation() {
// We define the specific operations, or dialects, that are legal targets for
// this lowering. In our case, we are lowering to a combination of the
// `Affine`, `Arith`, `Func`, and `MemRef` dialects.
target.addLegalDialect<AffineDialect, BuiltinDialect, arith::ArithDialect,
func::FuncDialect, memref::MemRefDialect>();
target.addLegalDialect<affine::AffineDialect, BuiltinDialect,
arith::ArithDialect, func::FuncDialect,
memref::MemRefDialect>();
// We also define the Toy dialect as Illegal so that the conversion will fail
// if any of these operations are *not* converted. Given that we actually want

View File

@ -166,8 +166,8 @@ int loadAndProcessMLIR(mlir::MLIRContext &context,
// Add optimizations if enabled.
if (enableOpt) {
optPM.addPass(mlir::createLoopFusionPass());
optPM.addPass(mlir::createAffineScalarReplacementPass());
optPM.addPass(mlir::affine::createLoopFusionPass());
optPM.addPass(mlir::affine::createAffineScalarReplacementPass());
}
}

View File

@ -75,14 +75,15 @@ static void lowerOpToLoops(Operation *op, ValueRange operands,
// loop induction variables.
SmallVector<int64_t, 4> lowerBounds(tensorType.getRank(), /*Value=*/0);
SmallVector<int64_t, 4> steps(tensorType.getRank(), /*Value=*/1);
buildAffineLoopNest(
affine::buildAffineLoopNest(
rewriter, loc, lowerBounds, tensorType.getShape(), steps,
[&](OpBuilder &nestedBuilder, Location loc, ValueRange ivs) {
// Call the processing function with the rewriter, the memref operands,
// and the loop induction variables. This function will return the value
// to store at the current index.
Value valueToStore = processIteration(nestedBuilder, operands, ivs);
nestedBuilder.create<AffineStoreOp>(loc, valueToStore, alloc, ivs);
nestedBuilder.create<affine::AffineStoreOp>(loc, valueToStore, alloc,
ivs);
});
// Replace this operation with the generated alloc.
@ -113,9 +114,9 @@ struct BinaryOpLowering : public ConversionPattern {
// Generate loads for the element of 'lhs' and 'rhs' at the
// inner loop.
auto loadedLhs = builder.create<AffineLoadOp>(
auto loadedLhs = builder.create<affine::AffineLoadOp>(
loc, binaryAdaptor.getLhs(), loopIvs);
auto loadedRhs = builder.create<AffineLoadOp>(
auto loadedRhs = builder.create<affine::AffineLoadOp>(
loc, binaryAdaptor.getRhs(), loopIvs);
// Create the binary operation performed on the loaded
@ -174,7 +175,7 @@ struct ConstantOpLowering : public OpRewritePattern<toy::ConstantOp> {
// The last dimension is the base case of the recursion, at this point
// we store the element at the given index.
if (dimension == valueShape.size()) {
rewriter.create<AffineStoreOp>(
rewriter.create<affine::AffineStoreOp>(
loc, rewriter.create<arith::ConstantOp>(loc, *valueIt++), alloc,
llvm::ArrayRef(indices));
return;
@ -291,8 +292,8 @@ struct TransposeOpLowering : public ConversionPattern {
// Transpose the elements by generating a load from the
// reverse indices.
SmallVector<Value, 2> reverseIvs(llvm::reverse(loopIvs));
return builder.create<AffineLoadOp>(loc, input,
reverseIvs);
return builder.create<affine::AffineLoadOp>(loc, input,
reverseIvs);
});
return success();
}
@ -313,7 +314,8 @@ struct ToyToAffineLoweringPass
MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(ToyToAffineLoweringPass)
void getDependentDialects(DialectRegistry &registry) const override {
registry.insert<AffineDialect, func::FuncDialect, memref::MemRefDialect>();
registry.insert<affine::AffineDialect, func::FuncDialect,
memref::MemRefDialect>();
}
void runOnOperation() final;
};
@ -327,8 +329,9 @@ void ToyToAffineLoweringPass::runOnOperation() {
// We define the specific operations, or dialects, that are legal targets for
// this lowering. In our case, we are lowering to a combination of the
// `Affine`, `Arith`, `Func`, and `MemRef` dialects.
target.addLegalDialect<AffineDialect, BuiltinDialect, arith::ArithDialect,
func::FuncDialect, memref::MemRefDialect>();
target.addLegalDialect<affine::AffineDialect, BuiltinDialect,
arith::ArithDialect, func::FuncDialect,
memref::MemRefDialect>();
// We also define the Toy dialect as Illegal so that the conversion will fail
// if any of these operations are *not* converted. Given that we actually want

View File

@ -167,8 +167,8 @@ int loadAndProcessMLIR(mlir::MLIRContext &context,
// Add optimizations if enabled.
if (enableOpt) {
optPM.addPass(mlir::createLoopFusionPass());
optPM.addPass(mlir::createAffineScalarReplacementPass());
optPM.addPass(mlir::affine::createLoopFusionPass());
optPM.addPass(mlir::affine::createAffineScalarReplacementPass());
}
}

View File

@ -12,16 +12,18 @@
#include "mlir/Support/LLVM.h"
namespace mlir {
class AffineForOp;
class Location;
struct LogicalResult;
class OpBuilder;
class Pass;
class RewritePattern;
class RewritePatternSet;
class Value;
class ValueRange;
class RewritePatternSet;
namespace affine {
class AffineForOp;
} // namespace affine
#define GEN_PASS_DECL_CONVERTAFFINETOSTANDARD
#include "mlir/Conversion/Passes.h.inc"
@ -37,11 +39,11 @@ void populateAffineToVectorConversionPatterns(RewritePatternSet &patterns);
/// Emit code that computes the lower bound of the given affine loop using
/// standard arithmetic operations.
Value lowerAffineLowerBound(AffineForOp op, OpBuilder &builder);
Value lowerAffineLowerBound(affine::AffineForOp op, OpBuilder &builder);
/// Emit code that computes the upper bound of the given affine loop using
/// standard arithmetic operations.
Value lowerAffineUpperBound(AffineForOp op, OpBuilder &builder);
Value lowerAffineUpperBound(affine::AffineForOp op, OpBuilder &builder);
/// Lowers affine control flow operations (ForStmt, IfStmt and AffineApplyOp)
/// to equivalent lower-level constructs (flow of basic blocks and arithmetic

View File

@ -856,7 +856,7 @@ def ConvertAffineForToGPU
def ConvertParallelLoopToGpu : Pass<"convert-parallel-loops-to-gpu"> {
let summary = "Convert mapped scf.parallel ops to gpu launch operations";
let constructor = "mlir::createParallelLoopToGpuPass()";
let dependentDialects = ["AffineDialect", "gpu::GPUDialect"];
let dependentDialects = ["affine::AffineDialect", "gpu::GPUDialect"];
}
//===----------------------------------------------------------------------===//
@ -1033,7 +1033,7 @@ def ConvertVectorToGPU : Pass<"convert-vector-to-gpu"> {
"dialect";
let constructor = "mlir::createConvertVectorToGPUPass()";
let dependentDialects = [
"memref::MemRefDialect", "gpu::GPUDialect", "AffineDialect",
"memref::MemRefDialect", "gpu::GPUDialect", "affine::AffineDialect",
"vector::VectorDialect", "nvgpu::NVGPUDialect"
];
@ -1052,7 +1052,7 @@ def ConvertVectorToSCF : Pass<"convert-vector-to-scf"> {
"dialect";
let constructor = "mlir::createConvertVectorToSCFPass()";
let dependentDialects = [
"AffineDialect",
"affine::AffineDialect",
"memref::MemRefDialect",
"scf::SCFDialect",
"tensor::TensorDialect"

View File

@ -11,7 +11,6 @@
#include "mlir/Support/LLVM.h"
namespace mlir {
class AffineForOp;
class ConversionTarget;
struct LogicalResult;
class MLIRContext;
@ -19,6 +18,10 @@ class Value;
class Operation;
class RewritePatternSet;
namespace affine {
class AffineForOp;
} // namespace affine
namespace scf {
class ForOp;
} // namespace scf
@ -37,7 +40,7 @@ class ForOp;
// TODO: Consider removing this in favor of affine.for -> affine.parallel
// detection followed by an affine.parallel -> scf.parallel -> gpu.launch
// conversion
LogicalResult convertAffineLoopNestToGPULaunch(AffineForOp forOp,
LogicalResult convertAffineLoopNestToGPULaunch(affine::AffineForOp forOp,
unsigned numBlockDims,
unsigned numThreadDims);

View File

@ -21,13 +21,14 @@
#include <optional>
namespace mlir {
class Operation;
namespace affine {
class AffineApplyOp;
class AffineForOp;
class AffineValueMap;
class FlatAffineRelation;
class FlatAffineValueConstraints;
class Operation;
/// A description of a (parallelizable) reduction in an affine loop.
struct LoopReduction {
@ -191,6 +192,7 @@ void getDependenceComponents(
AffineForOp forOp, unsigned maxLoopDepth,
std::vector<SmallVector<DependenceComponent, 2>> *depCompsVec);
} // namespace affine
} // namespace mlir
#endif // MLIR_DIALECT_AFFINE_ANALYSIS_AFFINEANALYSIS_H

View File

@ -22,23 +22,24 @@
#include <optional>
namespace mlir {
class AffineCondition;
class AffineForOp;
class AffineIfOp;
class AffineParallelOp;
class AffineMap;
class AffineValueMap;
class IntegerSet;
class MLIRContext;
class Value;
class MemRefType;
class MLIRContext;
struct MutableAffineMap;
class Value;
namespace presburger {
class MultiAffineFunction;
} // namespace presburger
namespace affine {
class AffineCondition;
class AffineForOp;
class AffineIfOp;
class AffineParallelOp;
class AffineValueMap;
/// FlatAffineValueConstraints is an extension of FlatLinearValueConstraints
/// with helper functions for Affine dialect ops.
class FlatAffineValueConstraints : public FlatLinearValueConstraints {
@ -254,6 +255,7 @@ LogicalResult getRelationFromMap(AffineMap &map, FlatAffineRelation &rel);
LogicalResult getRelationFromMap(const AffineValueMap &map,
FlatAffineRelation &rel);
} // namespace affine
} // namespace mlir
#endif // MLIR_DIALECT_AFFINE_ANALYSIS_AFFINESTRUCTURES_H

View File

@ -18,16 +18,17 @@
#include <optional>
namespace mlir {
class AffineExpr;
class AffineForOp;
class AffineMap;
class BlockArgument;
class MemRefType;
class NestedPattern;
class Operation;
class Value;
namespace affine {
class AffineForOp;
class NestedPattern;
/// Returns the trip count of the loop as an affine map with its corresponding
/// operands if the latter is expressible as an affine expression, and nullptr
/// otherwise. This method always succeeds as long as the lower bound is not a
@ -83,6 +84,7 @@ bool isVectorizableLoopBody(AffineForOp loop, int *memRefDim,
// the support.
bool isOpwiseShiftValid(AffineForOp forOp, ArrayRef<uint64_t> shifts);
} // namespace affine
} // namespace mlir
#endif // MLIR_DIALECT_AFFINE_ANALYSIS_LOOPANALYSIS_H

View File

@ -14,10 +14,11 @@
#include "llvm/Support/Allocator.h"
namespace mlir {
class NestedPattern;
class Operation;
namespace affine {
class NestedPattern;
/// An NestedPattern captures nested patterns in the IR.
/// It is used in conjunction with a scoped NestedPatternContext which is an
/// llvm::BumpPtrAllocator that handles memory allocations efficiently and
@ -191,6 +192,7 @@ bool isReductionLoop(Operation &op);
bool isLoadOrStore(Operation &op);
} // namespace matcher
} // namespace affine
} // namespace mlir
#endif // MLIR_DIALECT_AFFINE_ANALYSIS_NESTEDMATCHER_H

View File

@ -22,15 +22,16 @@
#include <optional>
namespace mlir {
class AffineForOp;
class AffineValueMap;
class Block;
class Location;
struct MemRefAccess;
class Operation;
class Value;
namespace affine {
class AffineForOp;
class AffineValueMap;
struct MemRefAccess;
// LoopNestStateCollector walks loop nests and collects load and store
// operations, and whether or not a region holding op other than ForOp and IfOp
// was encountered in the loop nest.
@ -576,6 +577,7 @@ FailureOr<AffineValueMap>
simplifyConstrainedMinMaxOp(Operation *op,
FlatAffineValueConstraints constraints);
} // namespace affine
} // namespace mlir
#endif // MLIR_DIALECT_AFFINE_ANALYSIS_UTILS_H

View File

@ -17,8 +17,6 @@
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/OpDefinition.h"
namespace mlir {
#include "mlir/Dialect/Affine/IR/AffineMemoryOpInterfaces.h.inc"
} // namespace mlir
#endif // MLIR_DIALECT_AFFINE_IR_AFFINEMEMORYOPINTERFACES_H

View File

@ -20,62 +20,59 @@ def AffineReadOpInterface : OpInterface<"AffineReadOpInterface"> {
Interface to query characteristics of read-like ops with affine
restrictions.
}];
let cppNamespace = "::mlir::affine";
let methods = [
InterfaceMethod<
/*desc=*/"Returns the memref operand to read from.",
/*retTy=*/"Value",
/*retTy=*/"::mlir::Value",
/*methodName=*/"getMemRef",
/*args=*/(ins),
/*methodBody*/[{}],
/*defaultImplementation=*/ [{
ConcreteOp op = cast<ConcreteOp>(this->getOperation());
return op.getOperand(op.getMemRefOperandIndex());
return $_op.getOperand($_op.getMemRefOperandIndex());
}]
>,
InterfaceMethod<
/*desc=*/"Returns the type of the memref operand.",
/*retTy=*/"MemRefType",
/*retTy=*/"::mlir::MemRefType",
/*methodName=*/"getMemRefType",
/*args=*/(ins),
/*methodBody=*/[{}],
/*defaultImplementation=*/[{
ConcreteOp op = cast<ConcreteOp>(this->getOperation());
return op.getMemRef().getType().template cast<MemRefType>();
return $_op.getMemRef().getType().template cast<::mlir::MemRefType>();
}]
>,
InterfaceMethod<
/*desc=*/"Returns affine map operands.",
/*retTy=*/"Operation::operand_range",
/*retTy=*/"::mlir::Operation::operand_range",
/*methodName=*/"getMapOperands",
/*args=*/(ins),
/*methodBody=*/[{}],
/*defaultImplementation=*/[{
ConcreteOp op = cast<ConcreteOp>(this->getOperation());
return llvm::drop_begin(op.getOperands(), 1);
return llvm::drop_begin($_op.getOperands(), 1);
}]
>,
InterfaceMethod<
/*desc=*/[{
Returns the affine map used to index the memref for this operation.
}],
/*retTy=*/"AffineMap",
/*retTy=*/"::mlir::AffineMap",
/*methodName=*/"getAffineMap",
/*args=*/(ins),
/*methodBody=*/[{}],
/*defaultImplementation=*/[{
ConcreteOp op = cast<ConcreteOp>(this->getOperation());
return op.getAffineMapAttr().getValue();
return $_op.getAffineMapAttr().getValue();
}]
>,
InterfaceMethod<
/*desc=*/"Returns the value read by this operation.",
/*retTy=*/"Value",
/*retTy=*/"::mlir::Value",
/*methodName=*/"getValue",
/*args=*/(ins),
/*methodBody=*/[{}],
/*defaultImplementation=*/[{
return cast<ConcreteOp>(this->getOperation());
return $_op;
}]
>,
];
@ -86,63 +83,59 @@ def AffineWriteOpInterface : OpInterface<"AffineWriteOpInterface"> {
Interface to query characteristics of write-like ops with affine
restrictions.
}];
let cppNamespace = "::mlir::affine";
let methods = [
InterfaceMethod<
/*desc=*/"Returns the memref operand to write to.",
/*retTy=*/"Value",
/*retTy=*/"::mlir::Value",
/*methodName=*/"getMemRef",
/*args=*/(ins),
/*methodBody=*/[{}],
/*defaultImplementation=*/[{
ConcreteOp op = cast<ConcreteOp>(this->getOperation());
return op.getOperand(op.getMemRefOperandIndex());
return $_op.getOperand($_op.getMemRefOperandIndex());
}]
>,
InterfaceMethod<
/*desc=*/"Returns the type of the memref operand.",
/*retTy=*/"MemRefType",
/*retTy=*/"::mlir::MemRefType",
/*methodName=*/"getMemRefType",
/*args=*/(ins),
/*methodBody=*/[{}],
/*defaultImplementation=*/[{
ConcreteOp op = cast<ConcreteOp>(this->getOperation());
return op.getMemRef().getType().template cast<MemRefType>();
return $_op.getMemRef().getType().template cast<::mlir::MemRefType>();
}]
>,
InterfaceMethod<
/*desc=*/"Returns affine map operands.",
/*retTy=*/"Operation::operand_range",
/*retTy=*/"::mlir::Operation::operand_range",
/*methodName=*/"getMapOperands",
/*args=*/(ins),
/*methodBody=*/[{}],
/*defaultImplementation=*/[{
ConcreteOp op = cast<ConcreteOp>(this->getOperation());
return llvm::drop_begin(op.getOperands(), 2);
return llvm::drop_begin($_op.getOperands(), 2);
}]
>,
InterfaceMethod<
/*desc=*/[{
Returns the affine map used to index the memref for this operation.
}],
/*retTy=*/"AffineMap",
/*retTy=*/"::mlir::AffineMap",
/*methodName=*/"getAffineMap",
/*args=*/(ins),
/*methodName=*/[{}],
/*defaultImplementation=*/[{
ConcreteOp op = cast<ConcreteOp>(this->getOperation());
return op.getAffineMapAttr().getValue();
return $_op.getAffineMapAttr().getValue();
}]
>,
InterfaceMethod<
/*desc=*/"Returns the value to store.",
/*retTy=*/"Value",
/*retTy=*/"::mlir::Value",
/*methodName=*/"getValueToStore",
/*args=*/(ins),
/*methodBody=*/[{}],
/*defaultImplementation=*/[{
ConcreteOp op = cast<ConcreteOp>(this->getOperation());
return op.getOperand(op.getStoredValOperandIndex());
return $_op.getOperand($_op.getStoredValOperandIndex());
}]
>,
];
@ -155,20 +148,21 @@ def AffineMapAccessInterface : OpInterface<"AffineMapAccessInterface"> {
memref operand. The memref argument given to this interface much match
one of those memref operands.
}];
let cppNamespace = "::mlir::affine";
let methods = [
InterfaceMethod<
/*desc=*/"Returns the AffineMapAttr associated with 'memref'.",
/*retTy=*/"NamedAttribute",
/*retTy=*/"::mlir::NamedAttribute",
/*methodName=*/"getAffineMapAttrForMemRef",
/*args=*/(ins "Value":$memref),
/*args=*/(ins "::mlir::Value":$memref),
/*methodBody=*/[{}],
/*defaultImplementation=*/[{
ConcreteOp op = cast<ConcreteOp>(this->getOperation());
assert(memref == op.getMemRef() &&
assert(memref == $_op.getMemRef() &&
"Expected memref argument to match memref operand");
return {StringAttr::get(op.getContext(), op.getMapAttrStrName()),
op.getAffineMapAttr()};
return {::mlir::StringAttr::get(
$_op.getContext(), $_op.getMapAttrStrName()),
$_op.getAffineMapAttr()};
}]
>,
];

View File

@ -22,13 +22,12 @@
#include "mlir/Interfaces/LoopLikeInterface.h"
namespace mlir {
namespace affine {
class AffineApplyOp;
class AffineBound;
class AffineValueMap;
/// TODO: These should be renamed if they are on the mlir namespace.
/// Ideally, they should go in a mlir::affine:: namespace.
/// A utility function to check if a value is defined at the top level of an
/// op with trait `AffineScope` or is a region argument for such an op. A value
/// of index type defined at the top level is always a valid symbol for all its
@ -438,13 +437,18 @@ SmallVector<Value, 4> applyMapToValues(OpBuilder &b, Location loc,
/// argument.
void fullyComposeAffineMapAndOperands(AffineMap *map,
SmallVectorImpl<Value> *operands);
} // namespace affine
} // namespace mlir
#include "mlir/Dialect/Affine/IR/AffineOpsDialect.h.inc"
#define GET_OP_CLASSES
#include "mlir/Dialect/Affine/IR/AffineOps.h.inc"
namespace mlir {
namespace affine {
/// Returns true if the provided value is the induction variable of an
/// AffineForOp.
bool isAffineForInductionVar(Value val);
@ -537,6 +541,7 @@ private:
friend class AffineForOp;
};
} // namespace affine
} // namespace mlir
#endif

View File

@ -21,7 +21,7 @@ include "mlir/Interfaces/SideEffectInterfaces.td"
def Affine_Dialect : Dialect {
let name = "affine";
let cppNamespace = "mlir";
let cppNamespace = "::mlir::affine";
let hasConstantMaterializer = 1;
let dependentDialects = ["arith::ArithDialect"];
}

View File

@ -18,6 +18,7 @@
#include "mlir/IR/Value.h"
namespace mlir {
namespace affine {
/// An AffineValueMap is an affine map plus its ML value operands and
/// results for analysis purposes. The structure is still a tree form that is
@ -89,6 +90,7 @@ private:
SmallVector<Value, 4> results;
};
} // namespace affine
} // namespace mlir
#endif // MLIR_DIALECT_AFFINE_IR_AFFINEVALUEMAP_H

View File

@ -21,9 +21,11 @@
#include "llvm/ADT/SmallVector.h"
namespace mlir {
class Operation;
namespace affine {
class AffineForOp;
struct ComputationSliceState;
class Operation;
// TODO: Extend this module to include utility functions for querying fusion
// cost/storage reduction, and for performing the loop fusion transformation.
@ -165,6 +167,8 @@ bool getFusionComputeCost(AffineForOp srcForOp, LoopNestStats &srcStats,
void gatherProducerConsumerMemrefs(ArrayRef<Operation *> srcOps,
ArrayRef<Operation *> dstOps,
DenseSet<Value> &producerConsumerMemrefs);
} // namespace affine
} // namespace mlir
#endif // MLIR_DIALECT_AFFINE_LOOPFUSIONUTILS_H

View File

@ -22,10 +22,8 @@
#include <optional>
namespace mlir {
class AffineForOp;
class AffineMap;
class LoopLikeOpInterface;
struct MemRefRegion;
class OpBuilder;
class Value;
class ValueRange;
@ -39,6 +37,10 @@ class ForOp;
class ParallelOp;
} // namespace scf
namespace affine {
class AffineForOp;
struct MemRefRegion;
/// Unrolls this for operation completely if the trip count is known to be
/// constant. Returns failure otherwise.
LogicalResult loopUnrollFull(AffineForOp forOp);
@ -345,6 +347,7 @@ LogicalResult coalescePerfectlyNestedLoops(LoopOpTy op) {
return result;
}
} // namespace affine
} // namespace mlir
#endif // MLIR_DIALECT_AFFINE_LOOPUTILS_H

View File

@ -23,6 +23,7 @@ namespace func {
class FuncOp;
} // namespace func
namespace affine {
class AffineForOp;
/// Fusion mode to attempt. The default mode `Greedy` does both
@ -123,6 +124,7 @@ std::unique_ptr<Pass> createAffineExpandIndexOpsPass();
#define GEN_PASS_REGISTRATION
#include "mlir/Dialect/Affine/Passes.h.inc"
} // namespace affine
} // namespace mlir
#endif // MLIR_DIALECT_AFFINE_PASSES_H

View File

@ -17,7 +17,7 @@ include "mlir/Pass/PassBase.td"
def AffineDataCopyGeneration : Pass<"affine-data-copy-generate", "func::FuncOp"> {
let summary = "Generate explicit copying for affine memory operations";
let constructor = "mlir::createAffineDataCopyGenerationPass()";
let constructor = "mlir::affine::createAffineDataCopyGenerationPass()";
let dependentDialects = ["memref::MemRefDialect"];
let options = [
Option<"fastMemoryCapacity", "fast-mem-capacity", "uint64_t",
@ -152,7 +152,7 @@ def AffineLoopFusion : Pass<"affine-loop-fusion"> {
}
```
}];
let constructor = "mlir::createLoopFusionPass()";
let constructor = "mlir::affine::createLoopFusionPass()";
let options = [
Option<"computeToleranceThreshold", "fusion-compute-tolerance", "double",
/*default=*/"0.30f", "Fractional increase in additional computation "
@ -166,12 +166,12 @@ def AffineLoopFusion : Pass<"affine-loop-fusion"> {
Option<"maximalFusion", "fusion-maximal", "bool", /*default=*/"false",
"Enables maximal loop fusion">,
Option<"affineFusionMode", "mode", "enum FusionMode",
"mlir::FusionMode::Greedy", "fusion mode to attempt",
"llvm::cl::values(clEnumValN(mlir::FusionMode::Greedy,"
"mlir::affine::FusionMode::Greedy", "fusion mode to attempt",
"llvm::cl::values(clEnumValN(mlir::affine::FusionMode::Greedy,"
" \"greedy\", \"Perform greedy (both producer-consumer and sibling) fusion\"), "
"clEnumValN( mlir::FusionMode::ProducerConsumer, "
"clEnumValN( mlir::affine::FusionMode::ProducerConsumer, "
"\"producer\", \"Perform only producer-consumer fusion\"), "
"clEnumValN( mlir::FusionMode::Sibling, "
"clEnumValN( mlir::affine::FusionMode::Sibling, "
"\"sibling\", \"Perform only sibling fusion\"))">,
];
let dependentDialects = ["memref::MemRefDialect"];
@ -180,12 +180,12 @@ def AffineLoopFusion : Pass<"affine-loop-fusion"> {
def AffineLoopInvariantCodeMotion
: Pass<"affine-loop-invariant-code-motion", "func::FuncOp"> {
let summary = "Hoist loop invariant instructions outside of affine loops";
let constructor = "mlir::createAffineLoopInvariantCodeMotionPass()";
let constructor = "mlir::affine::createAffineLoopInvariantCodeMotionPass()";
}
def AffineLoopTiling : Pass<"affine-loop-tile", "func::FuncOp"> {
let summary = "Tile affine loop nests";
let constructor = "mlir::createLoopTilingPass()";
let constructor = "mlir::affine::createLoopTilingPass()";
let options = [
Option<"cacheSizeInKiB", "cache-size", "uint64_t", /*default=*/"512",
"Set size of cache to tile for in KiB (default: 512)">,
@ -201,7 +201,7 @@ def AffineLoopTiling : Pass<"affine-loop-tile", "func::FuncOp"> {
def AffineLoopUnroll : Pass<"affine-loop-unroll", "func::FuncOp"> {
let summary = "Unroll affine loops";
let constructor = "mlir::createLoopUnrollPass()";
let constructor = "mlir::affine::createLoopUnrollPass()";
let options = [
Option<"unrollFactor", "unroll-factor", "unsigned", /*default=*/"4",
"Use this unroll factor for all loops being unrolled">,
@ -221,7 +221,7 @@ def AffineLoopUnroll : Pass<"affine-loop-unroll", "func::FuncOp"> {
def AffineLoopUnrollAndJam : Pass<"affine-loop-unroll-jam", "func::FuncOp"> {
let summary = "Unroll and jam affine loops";
let constructor = "mlir::createLoopUnrollAndJamPass()";
let constructor = "mlir::affine::createLoopUnrollAndJamPass()";
let options = [
Option<"unrollJamFactor", "unroll-jam-factor", "unsigned",
/*default=*/"4",
@ -295,7 +295,7 @@ def AffinePipelineDataTransfer
}
```
}];
let constructor = "mlir::createPipelineDataTransferPass()";
let constructor = "mlir::affine::createPipelineDataTransferPass()";
}
def AffineScalarReplacement : Pass<"affine-scalrep", "func::FuncOp"> {
@ -341,7 +341,7 @@ def AffineScalarReplacement : Pass<"affine-scalrep", "func::FuncOp"> {
}
```
}];
let constructor = "mlir::createAffineScalarReplacementPass()";
let constructor = "mlir::affine::createAffineScalarReplacementPass()";
}
def AffineVectorize : Pass<"affine-super-vectorize", "func::FuncOp"> {
@ -369,7 +369,7 @@ def AffineVectorize : Pass<"affine-super-vectorize", "func::FuncOp"> {
def AffineParallelize : Pass<"affine-parallelize", "func::FuncOp"> {
let summary = "Convert affine.for ops into 1-D affine.parallel";
let constructor = "mlir::createAffineParallelizePass()";
let constructor = "mlir::affine::createAffineParallelizePass()";
let options = [
Option<"maxNested", "max-nested", "unsigned", /*default=*/"-1u",
"Maximum number of nested parallel loops to produce. "
@ -382,7 +382,7 @@ def AffineParallelize : Pass<"affine-parallelize", "func::FuncOp"> {
def AffineLoopNormalize : Pass<"affine-loop-normalize", "func::FuncOp"> {
let summary = "Apply normalization transformations to affine loop-like ops";
let constructor = "mlir::createAffineLoopNormalizePass()";
let constructor = "mlir::affine::createAffineLoopNormalizePass()";
let options = [
Option<"promoteSingleIter", "promote-single-iter", "bool",
/*default=*/"true", "Promote single iteration loops">,
@ -392,19 +392,19 @@ def AffineLoopNormalize : Pass<"affine-loop-normalize", "func::FuncOp"> {
def LoopCoalescing : Pass<"affine-loop-coalescing", "func::FuncOp"> {
let summary = "Coalesce nested loops with independent bounds into a single "
"loop";
let constructor = "mlir::createLoopCoalescingPass()";
let constructor = "mlir::affine::createLoopCoalescingPass()";
let dependentDialects = ["arith::ArithDialect"];
}
def SimplifyAffineStructures : Pass<"affine-simplify-structures", "func::FuncOp"> {
let summary = "Simplify affine expressions in maps/sets and normalize "
"memrefs";
let constructor = "mlir::createSimplifyAffineStructuresPass()";
let constructor = "mlir::affine::createSimplifyAffineStructuresPass()";
}
def AffineExpandIndexOps : Pass<"affine-expand-index-ops"> {
let summary = "Lower affine operations operating on indices into more fundamental operations";
let constructor = "mlir::createAffineExpandIndexOpsPass()";
let constructor = "mlir::affine::createAffineExpandIndexOpsPass()";
}
#endif // MLIR_DIALECT_AFFINE_PASSES

View File

@ -15,12 +15,11 @@
#include "mlir/IR/OpImplementation.h"
namespace mlir {
class AffineForOp;
namespace func {
class FuncOp;
} // namespace func
namespace affine {
class ForOp;
class AffineForOp;
} // namespace affine
} // namespace mlir

View File

@ -18,7 +18,6 @@
#include "mlir/Support/LogicalResult.h"
namespace mlir {
class AffineApplyOp;
class Location;
class OpBuilder;
class OpFoldResult;
@ -30,6 +29,9 @@ namespace presburger {
enum class BoundType;
} // namespace presburger
namespace affine {
class AffineApplyOp;
/// Populate patterns that expand affine index operations into more fundamental
/// operations (not necessarily restricted to Affine dialect).
void populateAffineExpandIndexOpsPatterns(RewritePatternSet &patterns);
@ -83,6 +85,7 @@ FailureOr<OpFoldResult> reifyShapedValueDimBound(
ValueBoundsConstraintSet::StopConditionFn stopCondition = nullptr,
bool closedUB = false);
} // namespace affine
} // namespace mlir
#endif // MLIR_DIALECT_AFFINE_TRANSFORMS_TRANSFORMS_H

View File

@ -18,10 +18,6 @@
#include <optional>
namespace mlir {
class AffineForOp;
class AffineIfOp;
class AffineParallelOp;
class DominanceInfo;
class Operation;
class PostDominanceInfo;
@ -36,6 +32,11 @@ class AllocOp;
struct LogicalResult;
namespace affine {
class AffineForOp;
class AffineIfOp;
class AffineParallelOp;
using ReductionLoopMap = DenseMap<Operation *, SmallVector<LoopReduction, 2>>;
/// Replaces a parallel affine.for op with a 1-d affine.parallel op. `forOp`'s
@ -384,6 +385,7 @@ private:
Location loc;
};
} // namespace affine
} // namespace mlir
#endif // MLIR_DIALECT_AFFINE_UTILS_H

View File

@ -16,6 +16,8 @@
namespace mlir {
class RewriterBase;
namespace affine {
/// Fills the `combinedOffsets`, `combinedSizes` and `combinedStrides` to use
/// when combining a producer slice **into** a consumer slice.
///
@ -99,6 +101,7 @@ void resolveSizesIntoOpWithSizes(
const llvm::SmallBitVector &rankReducedSourceDims,
SmallVectorImpl<OpFoldResult> &resolvedSizes);
} // namespace affine
} // namespace mlir
#endif // MLIR_DIALECT_AFFINE_VIEWLIKEINTERFACEUTILS_H

View File

@ -26,7 +26,7 @@ def Bufferization_Dialect : Dialect {
deallocation](/docs/BufferDeallocationInternals/).
}];
let dependentDialects = [
"AffineDialect", "memref::MemRefDialect", "tensor::TensorDialect"
"affine::AffineDialect", "memref::MemRefDialect", "tensor::TensorDialect"
];
let extraClassDeclaration = [{

View File

@ -37,7 +37,7 @@ def Linalg_Dialect : Dialect {
let cppNamespace = "::mlir::linalg";
let dependentDialects = [
"arith::ArithDialect",
"AffineDialect",
"affine::AffineDialect",
"math::MathDialect",
"memref::MemRefDialect",
"tensor::TensorDialect",

View File

@ -37,7 +37,7 @@ def LinalgFoldUnitExtentDims : Pass<"linalg-fold-unit-extent-dims", ""> {
"Generate rank-reducing slices instead of reassociative reshapes">
];
let dependentDialects = [
"linalg::LinalgDialect", "AffineDialect", "memref::MemRefDialect"
"linalg::LinalgDialect", "affine::AffineDialect", "memref::MemRefDialect"
];
}
@ -45,7 +45,7 @@ def LinalgElementwiseOpFusion : Pass<"linalg-fuse-elementwise-ops"> {
let summary = "Fuse elementwise operations on tensors";
let constructor = "mlir::createLinalgElementwiseOpFusionPass()";
let dependentDialects = [
"AffineDialect", "linalg::LinalgDialect", "memref::MemRefDialect"
"affine::AffineDialect", "linalg::LinalgDialect", "memref::MemRefDialect"
];
}
@ -68,7 +68,7 @@ def LinalgLowerToAffineLoops : Pass<"convert-linalg-to-affine-loops", "func::Fun
"loops";
let constructor = "mlir::createConvertLinalgToAffineLoopsPass()";
let dependentDialects = [
"AffineDialect", "linalg::LinalgDialect", "memref::MemRefDialect"];
"affine::AffineDialect", "linalg::LinalgDialect", "memref::MemRefDialect"];
}
def LinalgLowerToLoops : Pass<"convert-linalg-to-loops", "func::FuncOp"> {
@ -77,7 +77,7 @@ def LinalgLowerToLoops : Pass<"convert-linalg-to-loops", "func::FuncOp"> {
let dependentDialects = [
"linalg::LinalgDialect",
"scf::SCFDialect",
"AffineDialect"
"affine::AffineDialect"
];
}
@ -87,7 +87,7 @@ def LinalgLowerToParallelLoops
"loops";
let constructor = "mlir::createConvertLinalgToParallelLoopsPass()";
let dependentDialects = [
"AffineDialect",
"affine::AffineDialect",
"linalg::LinalgDialect",
"memref::MemRefDialect",
"scf::SCFDialect"
@ -98,7 +98,7 @@ def LinalgBufferize : Pass<"linalg-bufferize", "func::FuncOp"> {
let summary = "Bufferize the linalg dialect";
let constructor = "mlir::createLinalgBufferizePass()";
let dependentDialects = [
"AffineDialect",
"affine::AffineDialect",
"bufferization::BufferizationDialect",
"linalg::LinalgDialect",
"memref::MemRefDialect",

View File

@ -18,10 +18,13 @@
namespace mlir {
class AffineExpr;
class AffineForOp;
class AffineMap;
class PatternRewriter;
namespace affine {
class AffineForOp;
} // namespace affine
namespace tensor {
class ExtractSliceOp;
} // namespace tensor

View File

@ -24,7 +24,7 @@ def FoldMemRefAliasOps : Pass<"fold-memref-alias-ops"> {
}];
let constructor = "mlir::memref::createFoldMemRefAliasOpsPass()";
let dependentDialects = [
"AffineDialect", "memref::MemRefDialect", "vector::VectorDialect"
"affine::AffineDialect", "memref::MemRefDialect", "vector::VectorDialect"
];
}
@ -156,7 +156,7 @@ def NormalizeMemRefs : Pass<"normalize-memrefs", "ModuleOp"> {
```
}];
let constructor = "mlir::memref::createNormalizeMemRefsPass()";
let dependentDialects = ["AffineDialect"];
let dependentDialects = ["affine::AffineDialect"];
}
def ResolveRankedShapeTypeResultDims :
@ -184,7 +184,7 @@ def ResolveShapedTypeResultDims : Pass<"resolve-shaped-type-result-dims"> {
}];
let constructor = "mlir::memref::createResolveShapedTypeResultDimsPass()";
let dependentDialects = [
"AffineDialect", "memref::MemRefDialect", "tensor::TensorDialect"
"affine::AffineDialect", "memref::MemRefDialect", "tensor::TensorDialect"
];
}
@ -199,7 +199,7 @@ def ExpandStridedMetadata : Pass<"expand-strided-metadata"> {
}];
let constructor = "mlir::memref::createExpandStridedMetadataPass()";
let dependentDialects = [
"AffineDialect", "memref::MemRefDialect"
"affine::AffineDialect", "memref::MemRefDialect"
];
}
#endif // MLIR_DIALECT_MEMREF_TRANSFORMS_PASSES

View File

@ -24,7 +24,7 @@ def SCFForLoopCanonicalization
: Pass<"scf-for-loop-canonicalization"> {
let summary = "Canonicalize operations within scf.for loop bodies";
let constructor = "mlir::createSCFForLoopCanonicalizationPass()";
let dependentDialects = ["AffineDialect", "tensor::TensorDialect",
let dependentDialects = ["affine::AffineDialect", "tensor::TensorDialect",
"memref::MemRefDialect"];
}
@ -37,7 +37,7 @@ def SCFForLoopPeeling : Pass<"scf-for-loop-peeling"> {
"Do not peel loops inside of the last, partial iteration of another "
"already peeled loop.">
];
let dependentDialects = ["AffineDialect"];
let dependentDialects = ["affine::AffineDialect"];
}
def SCFForLoopSpecialization : Pass<"scf-for-loop-specialization"> {
@ -109,7 +109,7 @@ def SCFParallelLoopTiling : Pass<"scf-parallel-loop-tiling"> {
"Perform tiling with fixed upper bound with inbound check "
"inside the internal loops">
];
let dependentDialects = ["AffineDialect"];
let dependentDialects = ["affine::AffineDialect"];
}
def SCFForLoopRangeFolding : Pass<"scf-for-loop-range-folding"> {

View File

@ -18,9 +18,7 @@
#include "mlir/Support/LogicalResult.h"
namespace mlir {
class AffineApplyOp;
class AffineMap;
class FlatAffineValueConstraints;
struct LogicalResult;
class Operation;
class OpFoldResult;
@ -28,6 +26,10 @@ class RewriterBase;
class Value;
class ValueRange;
namespace affine {
class FlatAffineValueConstraints;
} // namespace affine
namespace scf {
class IfOp;
@ -45,7 +47,7 @@ LogicalResult matchForLikeLoop(Value iv, OpFoldResult &lb, OpFoldResult &ub,
/// Populate the given constraint set with induction variable constraints of a
/// "for" loop with the given range and step.
LogicalResult addLoopRangeConstraints(FlatAffineValueConstraints &cstr,
LogicalResult addLoopRangeConstraints(affine::FlatAffineValueConstraints &cstr,
Value iv, OpFoldResult lb,
OpFoldResult ub, OpFoldResult step);

View File

@ -70,7 +70,7 @@ def SparsificationPass : Pass<"sparsification", "ModuleOp"> {
}];
let constructor = "mlir::createSparsificationPass()";
let dependentDialects = [
"AffineDialect",
"affine::AffineDialect",
"arith::ArithDialect",
"bufferization::BufferizationDialect",
"LLVM::LLVMDialect",

View File

@ -48,7 +48,7 @@ def Tensor_Dialect : Dialect {
let hasCanonicalizer = 1;
let hasConstantMaterializer = 1;
let dependentDialects = [
"AffineDialect",
"affine::AffineDialect",
"arith::ArithDialect",
"complex::ComplexDialect",
];

View File

@ -23,7 +23,7 @@ def FoldTensorSubsetOps : Pass<"fold-tensor-subset-ops"> {
}];
let constructor = "mlir::tensor::createFoldTensorSubsetOpsPass()";
let dependentDialects = [
"AffineDialect", "tensor::TensorDialect", "vector::VectorDialect"
"affine::AffineDialect", "tensor::TensorDialect", "vector::VectorDialect"
];
}

View File

@ -18,8 +18,6 @@
namespace mlir {
// Forward declarations.
class AffineApplyOp;
class AffineForOp;
class AffineMap;
class Block;
class Location;
@ -30,6 +28,11 @@ class Value;
class VectorType;
class VectorTransferOpInterface;
namespace affine {
class AffineApplyOp;
class AffineForOp;
} // namespace affine
namespace vector {
/// Helper function that creates a memref::DimOp or tensor::DimOp depending on
/// the type of `source`.

View File

@ -86,7 +86,7 @@ namespace mlir {
inline void registerAllDialects(DialectRegistry &registry) {
// clang-format off
registry.insert<acc::OpenACCDialect,
AffineDialect,
affine::AffineDialect,
arith::ArithDialect,
amdgpu::AMDGPUDialect,
amx::AMXDialect,

View File

@ -55,7 +55,7 @@ inline void registerAllPasses() {
registerConversionPasses();
// Dialect passes
registerAffinePasses();
affine::registerAffinePasses();
registerAsyncPasses();
arith::registerArithPasses();
bufferization::registerBufferizationPasses();

View File

@ -30,6 +30,7 @@ namespace mlir {
} // namespace mlir
using namespace mlir;
using namespace mlir::affine;
using namespace mlir::vector;
/// Given a range of values, emit the code that reduces them with "min" or "max"

View File

@ -141,8 +141,9 @@ struct ConvertLinalgToStandardPass
void ConvertLinalgToStandardPass::runOnOperation() {
auto module = getOperation();
ConversionTarget target(getContext());
target.addLegalDialect<AffineDialect, arith::ArithDialect, func::FuncDialect,
memref::MemRefDialect, scf::SCFDialect>();
target.addLegalDialect<affine::AffineDialect, arith::ArithDialect,
func::FuncDialect, memref::MemRefDialect,
scf::SCFDialect>();
target.addLegalOp<ModuleOp, func::FuncOp, func::ReturnOp>();
RewritePatternSet patterns(&getContext());
populateLinalgToStandardConversionPatterns(patterns);

View File

@ -36,6 +36,7 @@
#define DEBUG_TYPE "loops-to-gpu"
using namespace mlir;
using namespace mlir::affine;
using namespace mlir::scf;
// Name of internal attribute to mark visited operations during conversion.

View File

@ -42,7 +42,7 @@ struct ForLoopMapper : public impl::ConvertAffineForToGPUBase<ForLoopMapper> {
void runOnOperation() override {
for (Operation &op : llvm::make_early_inc_range(
getOperation().getFunctionBody().getOps())) {
if (auto forOp = dyn_cast<AffineForOp>(&op)) {
if (auto forOp = dyn_cast<affine::AffineForOp>(&op)) {
if (failed(convertAffineLoopNestToGPULaunch(forOp, numBlockDims,
numThreadDims)))
signalPassFailure();

View File

@ -66,7 +66,7 @@ static void getXferIndices(RewriterBase &rewriter, TransferOpType xferOp,
SmallVector<Value, 3> dims(dimValues.begin(), dimValues.end());
dims.push_back(prevIdx);
AffineExpr d0 = rewriter.getAffineDimExpr(offsetMap.getNumDims());
indices[dim.getPosition()] = makeComposedAffineApply(
indices[dim.getPosition()] = affine::makeComposedAffineApply(
rewriter, loc, d0 + offsetMap.getResult(offsetsIdx++), dims);
continue;
}

View File

@ -102,7 +102,8 @@ static void getXferIndices(OpBuilder &b, OpTy xferOp, Value iv,
AffineExpr d0, d1;
bindDims(xferOp.getContext(), d0, d1);
Value offset = adaptor.getIndices()[*dim];
indices[*dim] = makeComposedAffineApply(b, loc, d0 + d1, {offset, iv});
indices[*dim] =
affine::makeComposedAffineApply(b, loc, d0 + d1, {offset, iv});
}
}
@ -178,7 +179,8 @@ static Value generateInBoundsCheck(
AffineExpr d0, d1;
bindDims(xferOp.getContext(), d0, d1);
Value base = xferOp.getIndices()[*dim];
Value memrefIdx = makeComposedAffineApply(b, loc, d0 + d1, {base, iv});
Value memrefIdx =
affine::makeComposedAffineApply(b, loc, d0 + d1, {base, iv});
cond = lb.create<arith::CmpIOp>(arith::CmpIPredicate::sgt, memrefDim,
memrefIdx);
}
@ -1111,7 +1113,8 @@ get1dMemrefIndices(OpBuilder &b, OpTy xferOp, Value iv,
AffineExpr d0, d1;
bindDims(xferOp.getContext(), d0, d1);
Value offset = memrefIndices[dim];
memrefIndices[dim] = makeComposedAffineApply(b, loc, d0 + d1, {offset, iv});
memrefIndices[dim] =
affine::makeComposedAffineApply(b, loc, d0 + d1, {offset, iv});
return dim;
}

View File

@ -31,6 +31,7 @@
#define DEBUG_TYPE "affine-analysis"
using namespace mlir;
using namespace affine;
using namespace presburger;
/// Get the value that is being reduced by `pos`-th reduction in the loop if
@ -78,7 +79,7 @@ static Value getSupportedReduction(AffineForOp forOp, unsigned pos,
}
/// Populate `supportedReductions` with descriptors of the supported reductions.
void mlir::getSupportedReductions(
void mlir::affine::getSupportedReductions(
AffineForOp forOp, SmallVectorImpl<LoopReduction> &supportedReductions) {
unsigned numIterArgs = forOp.getNumIterOperands();
if (numIterArgs == 0)
@ -94,8 +95,8 @@ void mlir::getSupportedReductions(
/// Returns true if `forOp' is a parallel loop. If `parallelReductions` is
/// provided, populates it with descriptors of the parallelizable reductions and
/// treats them as not preventing parallelization.
bool mlir::isLoopParallel(AffineForOp forOp,
SmallVectorImpl<LoopReduction> *parallelReductions) {
bool mlir::affine::isLoopParallel(
AffineForOp forOp, SmallVectorImpl<LoopReduction> *parallelReductions) {
unsigned numIterArgs = forOp.getNumIterOperands();
// Loop is not parallel if it has SSA loop-carried dependences and reduction
@ -132,7 +133,7 @@ static bool isLocallyDefined(Value v, Operation *enclosingOp) {
return viewOp && isLocallyDefined(viewOp.getViewSource(), enclosingOp);
}
bool mlir::isLoopMemoryParallel(AffineForOp forOp) {
bool mlir::affine::isLoopMemoryParallel(AffineForOp forOp) {
// Any memref-typed iteration arguments are treated as serializing.
if (llvm::any_of(forOp.getResultTypes(),
[](Type type) { return type.isa<BaseMemRefType>(); }))
@ -186,7 +187,7 @@ bool mlir::isLoopMemoryParallel(AffineForOp forOp) {
/// and ending at operands which are not defined by AffineApplyOps.
// TODO: Add a method to AffineApplyOp which forward substitutes the
// AffineApplyOp into any user AffineApplyOps.
void mlir::getReachableAffineApplyOps(
void mlir::affine::getReachableAffineApplyOps(
ArrayRef<Value> operands, SmallVectorImpl<Operation *> &affineApplyOps) {
struct State {
// The ssa value for this node in the DFS traversal.
@ -236,8 +237,8 @@ void mlir::getReachableAffineApplyOps(
// FlatAffineValueConstraints. (For eg., by using iv - lb % step = 0 and/or by
// introducing a method in FlatAffineValueConstraints
// setExprStride(ArrayRef<int64_t> expr, int64_t stride)
LogicalResult mlir::getIndexSet(MutableArrayRef<Operation *> ops,
FlatAffineValueConstraints *domain) {
LogicalResult mlir::affine::getIndexSet(MutableArrayRef<Operation *> ops,
FlatAffineValueConstraints *domain) {
SmallVector<Value, 4> indices;
SmallVector<Operation *, 8> loopOps;
size_t numDims = 0;
@ -594,7 +595,7 @@ void MemRefAccess::getAccessMap(AffineValueMap *accessMap) const {
//
//
// TODO: Support AffineExprs mod/floordiv/ceildiv.
DependenceResult mlir::checkMemrefAccessDependence(
DependenceResult mlir::affine::checkMemrefAccessDependence(
const MemRefAccess &srcAccess, const MemRefAccess &dstAccess,
unsigned loopDepth, FlatAffineValueConstraints *dependenceConstraints,
SmallVector<DependenceComponent, 2> *dependenceComponents, bool allowRAR) {
@ -671,7 +672,7 @@ DependenceResult mlir::checkMemrefAccessDependence(
/// Gathers dependence components for dependences between all ops in loop nest
/// rooted at 'forOp' at loop depths in range [1, maxLoopDepth].
void mlir::getDependenceComponents(
void mlir::affine::getDependenceComponents(
AffineForOp forOp, unsigned maxLoopDepth,
std::vector<SmallVector<DependenceComponent, 2>> *depCompsVec) {
// Collect all load and store ops in loop nest rooted at 'forOp'.

View File

@ -31,6 +31,7 @@
#define DEBUG_TYPE "affine-structures"
using namespace mlir;
using namespace affine;
using namespace presburger;
@ -489,8 +490,8 @@ void FlatAffineRelation::removeVarRange(VarKind kind, unsigned varStart,
numRangeDims -= intersectRangeLHS - intersectRangeRHS;
}
LogicalResult mlir::getRelationFromMap(AffineMap &map,
FlatAffineRelation &rel) {
LogicalResult mlir::affine::getRelationFromMap(AffineMap &map,
FlatAffineRelation &rel) {
// Get flattened affine expressions.
std::vector<SmallVector<int64_t, 8>> flatExprs;
FlatAffineValueConstraints localVarCst;
@ -525,8 +526,8 @@ LogicalResult mlir::getRelationFromMap(AffineMap &map,
return success();
}
LogicalResult mlir::getRelationFromMap(const AffineValueMap &map,
FlatAffineRelation &rel) {
LogicalResult mlir::affine::getRelationFromMap(const AffineValueMap &map,
FlatAffineRelation &rel) {
AffineMap affineMap = map.getAffineMap();
if (failed(getRelationFromMap(affineMap, rel)))

View File

@ -28,13 +28,14 @@
#include <type_traits>
using namespace mlir;
using namespace mlir::affine;
/// Returns the trip count of the loop as an affine expression if the latter is
/// expressible as an affine expression, and nullptr otherwise. The trip count
/// expression is simplified before returning. This method only utilizes map
/// composition to construct lower and upper bounds before computing the trip
/// count expressions.
void mlir::getTripCountMapAndOperands(
void mlir::affine::getTripCountMapAndOperands(
AffineForOp forOp, AffineMap *tripCountMap,
SmallVectorImpl<Value> *tripCountOperands) {
MLIRContext *context = forOp.getContext();
@ -83,7 +84,7 @@ void mlir::getTripCountMapAndOperands(
/// otherwise. This method uses affine expression analysis (in turn using
/// getTripCount) and is able to determine constant trip count in non-trivial
/// cases.
std::optional<uint64_t> mlir::getConstantTripCount(AffineForOp forOp) {
std::optional<uint64_t> mlir::affine::getConstantTripCount(AffineForOp forOp) {
SmallVector<Value, 4> operands;
AffineMap map;
getTripCountMapAndOperands(forOp, &map, &operands);
@ -109,7 +110,7 @@ std::optional<uint64_t> mlir::getConstantTripCount(AffineForOp forOp) {
/// Returns the greatest known integral divisor of the trip count. Affine
/// expression analysis is used (indirectly through getTripCount), and
/// this method is thus able to determine non-trivial divisors.
uint64_t mlir::getLargestDivisorOfTripCount(AffineForOp forOp) {
uint64_t mlir::affine::getLargestDivisorOfTripCount(AffineForOp forOp) {
SmallVector<Value, 4> operands;
AffineMap map;
getTripCountMapAndOperands(forOp, &map, &operands);
@ -183,7 +184,8 @@ static bool isAccessIndexInvariant(Value iv, Value index) {
return !composeOp.getAffineValueMap().isFunctionOf(0, iv);
}
DenseSet<Value> mlir::getInvariantAccesses(Value iv, ArrayRef<Value> indices) {
DenseSet<Value> mlir::affine::getInvariantAccesses(Value iv,
ArrayRef<Value> indices) {
DenseSet<Value> res;
for (auto val : indices) {
if (isAccessIndexInvariant(iv, val)) {
@ -335,8 +337,8 @@ isVectorizableLoopBodyWithOpCond(AffineForOp loop,
return true;
}
bool mlir::isVectorizableLoopBody(AffineForOp loop, int *memRefDim,
NestedPattern &vectorTransferMatcher) {
bool mlir::affine::isVectorizableLoopBody(
AffineForOp loop, int *memRefDim, NestedPattern &vectorTransferMatcher) {
*memRefDim = -1;
VectorizableOpFun fun([memRefDim](AffineForOp loop, Operation &op) {
auto load = dyn_cast<AffineLoadOp>(op);
@ -358,8 +360,8 @@ bool mlir::isVectorizableLoopBody(AffineForOp loop, int *memRefDim,
return isVectorizableLoopBodyWithOpCond(loop, fun, vectorTransferMatcher);
}
bool mlir::isVectorizableLoopBody(AffineForOp loop,
NestedPattern &vectorTransferMatcher) {
bool mlir::affine::isVectorizableLoopBody(
AffineForOp loop, NestedPattern &vectorTransferMatcher) {
return isVectorizableLoopBodyWithOpCond(loop, nullptr, vectorTransferMatcher);
}
@ -368,7 +370,8 @@ bool mlir::isVectorizableLoopBody(AffineForOp loop,
/// 'def' and all its uses have the same shift factor.
// TODO: extend this to check for memory-based dependence violation when we have
// the support.
bool mlir::isOpwiseShiftValid(AffineForOp forOp, ArrayRef<uint64_t> shifts) {
bool mlir::affine::isOpwiseShiftValid(AffineForOp forOp,
ArrayRef<uint64_t> shifts) {
auto *forBody = forOp.getBody();
assert(shifts.size() == forBody->getOperations().size());

View File

@ -17,6 +17,7 @@
#include "llvm/Support/raw_ostream.h"
using namespace mlir;
using namespace mlir::affine;
llvm::BumpPtrAllocator *&NestedMatch::allocator() {
thread_local llvm::BumpPtrAllocator *allocator = nullptr;
@ -130,6 +131,7 @@ static bool isAffineForOp(Operation &op) { return isa<AffineForOp>(op); }
static bool isAffineIfOp(Operation &op) { return isa<AffineIfOp>(op); }
namespace mlir {
namespace affine {
namespace matcher {
NestedPattern Op(FilterFunctionType filter) {
@ -176,4 +178,5 @@ bool isLoadOrStore(Operation &op) {
}
} // namespace matcher
} // namespace affine
} // namespace mlir

View File

@ -28,6 +28,7 @@
#define DEBUG_TYPE "analysis-utils"
using namespace mlir;
using namespace affine;
using namespace presburger;
using llvm::SmallDenseMap;
@ -501,7 +502,8 @@ void MemRefDependenceGraph::print(raw_ostream &os) const {
}
}
void mlir::getAffineForIVs(Operation &op, SmallVectorImpl<AffineForOp> *loops) {
void mlir::affine::getAffineForIVs(Operation &op,
SmallVectorImpl<AffineForOp> *loops) {
auto *currOp = op.getParentOp();
AffineForOp currAffineForOp;
// Traverse up the hierarchy collecting all 'affine.for' operation while
@ -514,8 +516,8 @@ void mlir::getAffineForIVs(Operation &op, SmallVectorImpl<AffineForOp> *loops) {
std::reverse(loops->begin(), loops->end());
}
void mlir::getEnclosingAffineOps(Operation &op,
SmallVectorImpl<Operation *> *ops) {
void mlir::affine::getEnclosingAffineOps(Operation &op,
SmallVectorImpl<Operation *> *ops) {
ops->clear();
Operation *currOp = op.getParentOp();
@ -1063,7 +1065,7 @@ LogicalResult MemRefRegion::compute(Operation *op, unsigned loopDepth,
}
std::optional<int64_t>
mlir::getMemRefIntOrFloatEltSizeInBytes(MemRefType memRefType) {
mlir::affine::getMemRefIntOrFloatEltSizeInBytes(MemRefType memRefType) {
auto elementType = memRefType.getElementType();
unsigned sizeInBits;
@ -1113,7 +1115,7 @@ std::optional<int64_t> MemRefRegion::getRegionSize() {
/// into account size of the vector as well.
// TODO: improve/complete this when we have target data.
std::optional<uint64_t>
mlir::getIntOrFloatMemRefSizeInBytes(MemRefType memRefType) {
mlir::affine::getIntOrFloatMemRefSizeInBytes(MemRefType memRefType) {
if (!memRefType.hasStaticShape())
return std::nullopt;
auto elementType = memRefType.getElementType();
@ -1130,8 +1132,8 @@ mlir::getIntOrFloatMemRefSizeInBytes(MemRefType memRefType) {
}
template <typename LoadOrStoreOp>
LogicalResult mlir::boundCheckLoadOrStoreOp(LoadOrStoreOp loadOrStoreOp,
bool emitError) {
LogicalResult mlir::affine::boundCheckLoadOrStoreOp(LoadOrStoreOp loadOrStoreOp,
bool emitError) {
static_assert(llvm::is_one_of<LoadOrStoreOp, AffineReadOpInterface,
AffineWriteOpInterface>::value,
"argument should be either a AffineReadOpInterface or a "
@ -1186,9 +1188,11 @@ LogicalResult mlir::boundCheckLoadOrStoreOp(LoadOrStoreOp loadOrStoreOp,
// Explicitly instantiate the template so that the compiler knows we need them!
template LogicalResult
mlir::boundCheckLoadOrStoreOp(AffineReadOpInterface loadOp, bool emitError);
mlir::affine::boundCheckLoadOrStoreOp(AffineReadOpInterface loadOp,
bool emitError);
template LogicalResult
mlir::boundCheckLoadOrStoreOp(AffineWriteOpInterface storeOp, bool emitError);
mlir::affine::boundCheckLoadOrStoreOp(AffineWriteOpInterface storeOp,
bool emitError);
// Returns in 'positions' the Block positions of 'op' in each ancestor
// Block from the Block containing operation, stopping at 'limitBlock'.
@ -1250,7 +1254,7 @@ static LogicalResult addMissingLoopIVBounds(SmallPtrSet<Value, 8> &ivs,
/// Returns the innermost common loop depth for the set of operations in 'ops'.
// TODO: Move this to LoopUtils.
unsigned mlir::getInnermostCommonLoopDepth(
unsigned mlir::affine::getInnermostCommonLoopDepth(
ArrayRef<Operation *> ops, SmallVectorImpl<AffineForOp> *surroundingLoops) {
unsigned numOps = ops.size();
assert(numOps > 0 && "Expected at least one operation");
@ -1282,10 +1286,10 @@ unsigned mlir::getInnermostCommonLoopDepth(
/// then verifies if it is valid. Returns 'SliceComputationResult::Success' if
/// union was computed correctly, an appropriate failure otherwise.
SliceComputationResult
mlir::computeSliceUnion(ArrayRef<Operation *> opsA, ArrayRef<Operation *> opsB,
unsigned loopDepth, unsigned numCommonLoops,
bool isBackwardSlice,
ComputationSliceState *sliceUnion) {
mlir::affine::computeSliceUnion(ArrayRef<Operation *> opsA,
ArrayRef<Operation *> opsB, unsigned loopDepth,
unsigned numCommonLoops, bool isBackwardSlice,
ComputationSliceState *sliceUnion) {
// Compute the union of slice bounds between all pairs in 'opsA' and
// 'opsB' in 'sliceUnionCst'.
FlatAffineValueConstraints sliceUnionCst;
@ -1322,8 +1326,9 @@ mlir::computeSliceUnion(ArrayRef<Operation *> opsA, ArrayRef<Operation *> opsB,
// Compute slice bounds for 'srcAccess' and 'dstAccess'.
ComputationSliceState tmpSliceState;
mlir::getComputationSliceState(i, j, &dependenceConstraints, loopDepth,
isBackwardSlice, &tmpSliceState);
mlir::affine::getComputationSliceState(i, j, &dependenceConstraints,
loopDepth, isBackwardSlice,
&tmpSliceState);
if (sliceUnionCst.getNumDimAndSymbolVars() == 0) {
// Initialize 'sliceUnionCst' with the bounds computed in previous step.
@ -1465,7 +1470,7 @@ static std::optional<uint64_t> getConstDifference(AffineMap lbMap,
// nest surrounding represented by slice loop bounds in 'slice'. Returns true
// on success, false otherwise (if a non-constant trip count was encountered).
// TODO: Make this work with non-unit step loops.
bool mlir::buildSliceTripCountMap(
bool mlir::affine::buildSliceTripCountMap(
const ComputationSliceState &slice,
llvm::SmallDenseMap<Operation *, uint64_t, 8> *tripCountMap) {
unsigned numSrcLoopIVs = slice.ivs.size();
@ -1503,7 +1508,7 @@ bool mlir::buildSliceTripCountMap(
}
// Return the number of iterations in the given slice.
uint64_t mlir::getSliceIterationCount(
uint64_t mlir::affine::getSliceIterationCount(
const llvm::SmallDenseMap<Operation *, uint64_t, 8> &sliceTripCountMap) {
uint64_t iterCount = 1;
for (const auto &count : sliceTripCountMap) {
@ -1517,7 +1522,7 @@ const char *const kSliceFusionBarrierAttrName = "slice_fusion_barrier";
// 'dependenceConstraints' at depth greater than 'loopDepth', and computes slice
// bounds in 'sliceState' which represent the one loop nest's IVs in terms of
// the other loop nest's IVs, symbols and constants (using 'isBackwardsSlice').
void mlir::getComputationSliceState(
void mlir::affine::getComputationSliceState(
Operation *depSourceOp, Operation *depSinkOp,
FlatAffineValueConstraints *dependenceConstraints, unsigned loopDepth,
bool isBackwardSlice, ComputationSliceState *sliceState) {
@ -1631,10 +1636,9 @@ void mlir::getComputationSliceState(
// entire destination index set. Subtract out the dependent destination
// iterations from destination index set and check for emptiness --- this is one
// solution.
AffineForOp
mlir::insertBackwardComputationSlice(Operation *srcOpInst, Operation *dstOpInst,
unsigned dstLoopDepth,
ComputationSliceState *sliceState) {
AffineForOp mlir::affine::insertBackwardComputationSlice(
Operation *srcOpInst, Operation *dstOpInst, unsigned dstLoopDepth,
ComputationSliceState *sliceState) {
// Get loop nest surrounding src operation.
SmallVector<AffineForOp, 4> srcLoopIVs;
getAffineForIVs(*srcOpInst, &srcLoopIVs);
@ -1713,7 +1717,7 @@ bool MemRefAccess::isStore() const {
/// Returns the nesting depth of this statement, i.e., the number of loops
/// surrounding this statement.
unsigned mlir::getNestingDepth(Operation *op) {
unsigned mlir::affine::getNestingDepth(Operation *op) {
Operation *currOp = op;
unsigned depth = 0;
while ((currOp = currOp->getParentOp())) {
@ -1741,7 +1745,7 @@ bool MemRefAccess::operator==(const MemRefAccess &rhs) const {
[](AffineExpr e) { return e == 0; });
}
void mlir::getAffineIVs(Operation &op, SmallVectorImpl<Value> &ivs) {
void mlir::affine::getAffineIVs(Operation &op, SmallVectorImpl<Value> &ivs) {
auto *currOp = op.getParentOp();
AffineForOp currAffineForOp;
// Traverse up the hierarchy collecting all 'affine.for' and affine.parallel
@ -1758,7 +1762,8 @@ void mlir::getAffineIVs(Operation &op, SmallVectorImpl<Value> &ivs) {
/// Returns the number of surrounding loops common to 'loopsA' and 'loopsB',
/// where each lists loops from outer-most to inner-most in loop nest.
unsigned mlir::getNumCommonSurroundingLoops(Operation &a, Operation &b) {
unsigned mlir::affine::getNumCommonSurroundingLoops(Operation &a,
Operation &b) {
SmallVector<Value, 4> loopsA, loopsB;
getAffineIVs(a, loopsA);
getAffineIVs(b, loopsB);
@ -1817,8 +1822,8 @@ static std::optional<int64_t> getMemoryFootprintBytes(Block &block,
return totalSizeInBytes;
}
std::optional<int64_t> mlir::getMemoryFootprintBytes(AffineForOp forOp,
int memorySpace) {
std::optional<int64_t> mlir::affine::getMemoryFootprintBytes(AffineForOp forOp,
int memorySpace) {
auto *forInst = forOp.getOperation();
return ::getMemoryFootprintBytes(
*forInst->getBlock(), Block::iterator(forInst),
@ -1826,7 +1831,7 @@ std::optional<int64_t> mlir::getMemoryFootprintBytes(AffineForOp forOp,
}
/// Returns whether a loop is parallel and contains a reduction loop.
bool mlir::isLoopParallelAndContainsReduction(AffineForOp forOp) {
bool mlir::affine::isLoopParallelAndContainsReduction(AffineForOp forOp) {
SmallVector<LoopReduction> reductions;
if (!isLoopParallel(forOp, &reductions))
return false;
@ -1835,8 +1840,8 @@ bool mlir::isLoopParallelAndContainsReduction(AffineForOp forOp) {
/// Returns in 'sequentialLoops' all sequential loops in loop nest rooted
/// at 'forOp'.
void mlir::getSequentialLoops(AffineForOp forOp,
llvm::SmallDenseSet<Value, 8> *sequentialLoops) {
void mlir::affine::getSequentialLoops(
AffineForOp forOp, llvm::SmallDenseSet<Value, 8> *sequentialLoops) {
forOp->walk([&](Operation *op) {
if (auto innerFor = dyn_cast<AffineForOp>(op))
if (!isLoopParallel(innerFor))
@ -1844,7 +1849,7 @@ void mlir::getSequentialLoops(AffineForOp forOp,
});
}
IntegerSet mlir::simplifyIntegerSet(IntegerSet set) {
IntegerSet mlir::affine::simplifyIntegerSet(IntegerSet set) {
FlatAffineValueConstraints fac(set);
if (fac.isEmpty())
return IntegerSet::getEmptySet(set.getNumDims(), set.getNumSymbols(),
@ -1930,9 +1935,8 @@ static AffineMap addConstToResults(AffineMap map, int64_t val) {
// ... | 0 | 0 | -1 | ... | ... | = 0
// 0 | 0 | 1 | -1 | 0 | -1 | >= 0
//
FailureOr<AffineValueMap>
mlir::simplifyConstrainedMinMaxOp(Operation *op,
FlatAffineValueConstraints constraints) {
FailureOr<AffineValueMap> mlir::affine::simplifyConstrainedMinMaxOp(
Operation *op, FlatAffineValueConstraints constraints) {
bool isMin = isa<AffineMinOp>(op);
assert((isMin || isa<AffineMaxOp>(op)) && "expect AffineMin/MaxOp");
MLIRContext *ctx = op->getContext();
@ -2032,6 +2036,6 @@ mlir::simplifyConstrainedMinMaxOp(Operation *op,
newMap.getNumDims(), newMap.getNumSymbols());
}
}
mlir::canonicalizeMapAndOperands(&newMap, &newOperands);
affine::canonicalizeMapAndOperands(&newMap, &newOperands);
return AffineValueMap(newMap, newOperands);
}

View File

@ -9,6 +9,7 @@
#include "mlir/Dialect/Affine/IR/AffineMemoryOpInterfaces.h"
using namespace mlir;
using namespace mlir::affine;
//===----------------------------------------------------------------------===//
// Affine Memory Op Interfaces

View File

@ -26,6 +26,7 @@
#include <optional>
using namespace mlir;
using namespace mlir::affine;
#define DEBUG_TYPE "affine-ops"
@ -35,7 +36,7 @@ using namespace mlir;
/// `region` or is an argument of `region`. A value of index type defined at the
/// top level of a `AffineScope` region is always a valid symbol for all
/// uses in that region.
bool mlir::isTopLevelValue(Value value, Region *region) {
bool mlir::affine::isTopLevelValue(Value value, Region *region) {
if (auto arg = value.dyn_cast<BlockArgument>())
return arg.getParentRegion() == region;
return value.getDefiningOp()->getParentRegion() == region;
@ -231,7 +232,7 @@ Operation *AffineDialect::materializeConstant(OpBuilder &builder,
/// op with trait `AffineScope`. If the value is defined in an unlinked region,
/// conservatively assume it is not top-level. A value of index type defined at
/// the top level is always a valid symbol.
bool mlir::isTopLevelValue(Value value) {
bool mlir::affine::isTopLevelValue(Value value) {
if (auto arg = value.dyn_cast<BlockArgument>()) {
// The block owning the argument may be unlinked, e.g. when the surrounding
// region has not yet been attached to an Op, at which point the parent Op
@ -246,7 +247,7 @@ bool mlir::isTopLevelValue(Value value) {
/// Returns the closest region enclosing `op` that is held by an operation with
/// trait `AffineScope`; `nullptr` if there is no such region.
Region *mlir::getAffineScope(Operation *op) {
Region *mlir::affine::getAffineScope(Operation *op) {
auto *curOp = op;
while (auto *parentOp = curOp->getParentOp()) {
if (parentOp->hasTrait<OpTrait::AffineScope>())
@ -261,7 +262,7 @@ Region *mlir::getAffineScope(Operation *op) {
// *) It is valid as a symbol.
// *) It is an induction variable.
// *) It is the result of affine apply operation with dimension id arguments.
bool mlir::isValidDim(Value value) {
bool mlir::affine::isValidDim(Value value) {
// The value must be an index type.
if (!value.getType().isIndex())
return false;
@ -281,7 +282,7 @@ bool mlir::isValidDim(Value value) {
// *) It is valid as a symbol.
// *) It is an induction variable.
// *) It is the result of an affine apply operation with dimension id operands.
bool mlir::isValidDim(Value value, Region *region) {
bool mlir::affine::isValidDim(Value value, Region *region) {
// The value must be an index type.
if (!value.getType().isIndex())
return false;
@ -358,7 +359,7 @@ static bool isDimOpValidSymbol(ShapedDimOpInterface dimOp, Region *region) {
// *) It is the result of an affine.apply operation with symbol operands.
// *) It is a result of the dim op on a memref whose corresponding size is a
// valid symbol.
bool mlir::isValidSymbol(Value value) {
bool mlir::affine::isValidSymbol(Value value) {
if (!value)
return false;
@ -387,7 +388,7 @@ bool mlir::isValidSymbol(Value value) {
/// If `region` is null, conservatively assume the symbol definition scope does
/// not exist and only accept the values that would be symbols regardless of
/// the surrounding region structure, i.e. the first three cases above.
bool mlir::isValidSymbol(Value value, Region *region) {
bool mlir::affine::isValidSymbol(Value value, Region *region) {
// The value must be an index type.
if (!value.getType().isIndex())
return false;
@ -447,9 +448,8 @@ static void printDimAndSymbolList(Operation::operand_iterator begin,
}
/// Parses dimension and symbol list and returns true if parsing failed.
ParseResult mlir::parseDimAndSymbolList(OpAsmParser &parser,
SmallVectorImpl<Value> &operands,
unsigned &numDims) {
ParseResult mlir::affine::parseDimAndSymbolList(
OpAsmParser &parser, SmallVectorImpl<Value> &operands, unsigned &numDims) {
SmallVector<OpAsmParser::UnresolvedOperand, 8> opInfos;
if (parser.parseOperandList(opInfos, OpAsmParser::Delimiter::Paren))
return failure();
@ -541,7 +541,7 @@ LogicalResult AffineApplyOp::verify() {
// its operands are valid dimension ids.
bool AffineApplyOp::isValidDim() {
return llvm::all_of(getOperands(),
[](Value op) { return mlir::isValidDim(op); });
[](Value op) { return affine::isValidDim(op); });
}
// The result of the affine apply operation can be used as a dimension id if all
@ -556,14 +556,14 @@ bool AffineApplyOp::isValidDim(Region *region) {
// operands are symbols.
bool AffineApplyOp::isValidSymbol() {
return llvm::all_of(getOperands(),
[](Value op) { return mlir::isValidSymbol(op); });
[](Value op) { return affine::isValidSymbol(op); });
}
// The result of the affine apply operation can be used as a symbol in `region`
// if all its operands are symbols in `region`.
bool AffineApplyOp::isValidSymbol(Region *region) {
return llvm::all_of(getOperands(), [&](Value operand) {
return mlir::isValidSymbol(operand, region);
return affine::isValidSymbol(operand, region);
});
}
@ -1071,8 +1071,8 @@ static void composeAffineMapAndOperands(AffineMap *map,
*map = simplifyAffineMap(*map);
}
void mlir::fullyComposeAffineMapAndOperands(AffineMap *map,
SmallVectorImpl<Value> *operands) {
void mlir::affine::fullyComposeAffineMapAndOperands(
AffineMap *map, SmallVectorImpl<Value> *operands) {
while (llvm::any_of(*operands, [](Value v) {
return isa_and_nonnull<AffineApplyOp>(v.getDefiningOp());
})) {
@ -1168,9 +1168,9 @@ createOrFold(OpBuilder &b, Location loc, ValueRange operands,
return op->getResult(0);
}
AffineApplyOp mlir::makeComposedAffineApply(OpBuilder &b, Location loc,
AffineMap map,
ValueRange operands) {
AffineApplyOp mlir::affine::makeComposedAffineApply(OpBuilder &b, Location loc,
AffineMap map,
ValueRange operands) {
AffineMap normalizedMap = map;
SmallVector<Value, 8> normalizedOperands(operands.begin(), operands.end());
composeAffineMapAndOperands(&normalizedMap, &normalizedOperands);
@ -1178,8 +1178,9 @@ AffineApplyOp mlir::makeComposedAffineApply(OpBuilder &b, Location loc,
return b.create<AffineApplyOp>(loc, normalizedMap, normalizedOperands);
}
AffineApplyOp mlir::makeComposedAffineApply(OpBuilder &b, Location loc,
AffineExpr e, ValueRange values) {
AffineApplyOp mlir::affine::makeComposedAffineApply(OpBuilder &b, Location loc,
AffineExpr e,
ValueRange values) {
return makeComposedAffineApply(
b, loc, AffineMap::inferFromExprList(ArrayRef<AffineExpr>{e}).front(),
values);
@ -1216,8 +1217,9 @@ static void composeMultiResultAffineMap(AffineMap &map,
}
OpFoldResult
mlir::makeComposedFoldedAffineApply(OpBuilder &b, Location loc, AffineMap map,
ArrayRef<OpFoldResult> operands) {
mlir::affine::makeComposedFoldedAffineApply(OpBuilder &b, Location loc,
AffineMap map,
ArrayRef<OpFoldResult> operands) {
assert(map.getNumResults() == 1 && "building affine.apply with !=1 result");
SmallVector<Operation *> constants;
@ -1234,14 +1236,16 @@ mlir::makeComposedFoldedAffineApply(OpBuilder &b, Location loc, AffineMap map,
}
OpFoldResult
mlir::makeComposedFoldedAffineApply(OpBuilder &b, Location loc, AffineExpr expr,
ArrayRef<OpFoldResult> operands) {
mlir::affine::makeComposedFoldedAffineApply(OpBuilder &b, Location loc,
AffineExpr expr,
ArrayRef<OpFoldResult> operands) {
return makeComposedFoldedAffineApply(
b, loc, AffineMap::inferFromExprList(ArrayRef<AffineExpr>{expr}).front(),
operands);
}
SmallVector<OpFoldResult> mlir::makeComposedFoldedMultiResultAffineApply(
SmallVector<OpFoldResult>
mlir::affine::makeComposedFoldedMultiResultAffineApply(
OpBuilder &b, Location loc, AffineMap map,
ArrayRef<OpFoldResult> operands) {
return llvm::to_vector(llvm::map_range(
@ -1251,8 +1255,8 @@ SmallVector<OpFoldResult> mlir::makeComposedFoldedMultiResultAffineApply(
}));
}
Value mlir::makeComposedAffineMin(OpBuilder &b, Location loc, AffineMap map,
ValueRange operands) {
Value mlir::affine::makeComposedAffineMin(OpBuilder &b, Location loc,
AffineMap map, ValueRange operands) {
SmallVector<Value> allOperands = llvm::to_vector(operands);
composeMultiResultAffineMap(map, allOperands);
return b.createOrFold<AffineMinOp>(loc, b.getIndexType(), map, allOperands);
@ -1277,14 +1281,16 @@ static OpFoldResult makeComposedFoldedMinMax(OpBuilder &b, Location loc,
}
OpFoldResult
mlir::makeComposedFoldedAffineMin(OpBuilder &b, Location loc, AffineMap map,
ArrayRef<OpFoldResult> operands) {
mlir::affine::makeComposedFoldedAffineMin(OpBuilder &b, Location loc,
AffineMap map,
ArrayRef<OpFoldResult> operands) {
return makeComposedFoldedMinMax<AffineMinOp>(b, loc, map, operands);
}
OpFoldResult
mlir::makeComposedFoldedAffineMax(OpBuilder &b, Location loc, AffineMap map,
ArrayRef<OpFoldResult> operands) {
mlir::affine::makeComposedFoldedAffineMax(OpBuilder &b, Location loc,
AffineMap map,
ArrayRef<OpFoldResult> operands) {
return makeComposedFoldedMinMax<AffineMaxOp>(b, loc, map, operands);
}
@ -1299,8 +1305,9 @@ static Value createFoldedComposedAffineApply(OpBuilder &b, Location loc,
return b.createOrFold<AffineApplyOp>(loc, map, operands);
}
SmallVector<Value, 4> mlir::applyMapToValues(OpBuilder &b, Location loc,
AffineMap map, ValueRange values) {
SmallVector<Value, 4> mlir::affine::applyMapToValues(OpBuilder &b, Location loc,
AffineMap map,
ValueRange values) {
SmallVector<Value, 4> res;
res.reserve(map.getNumResults());
unsigned numDims = map.getNumDims(), numSym = map.getNumSymbols();
@ -1436,13 +1443,13 @@ static void canonicalizeMapOrSetAndOperands(MapOrSet *mapOrSet,
*operands = resultOperands;
}
void mlir::canonicalizeMapAndOperands(AffineMap *map,
SmallVectorImpl<Value> *operands) {
void mlir::affine::canonicalizeMapAndOperands(
AffineMap *map, SmallVectorImpl<Value> *operands) {
canonicalizeMapOrSetAndOperands<AffineMap>(map, operands);
}
void mlir::canonicalizeSetAndOperands(IntegerSet *set,
SmallVectorImpl<Value> *operands) {
void mlir::affine::canonicalizeSetAndOperands(
IntegerSet *set, SmallVectorImpl<Value> *operands) {
canonicalizeMapOrSetAndOperands<IntegerSet>(set, operands);
}
@ -2518,19 +2525,19 @@ Speculation::Speculatability AffineForOp::getSpeculatability() {
/// Returns true if the provided value is the induction variable of a
/// AffineForOp.
bool mlir::isAffineForInductionVar(Value val) {
bool mlir::affine::isAffineForInductionVar(Value val) {
return getForInductionVarOwner(val) != AffineForOp();
}
bool mlir::isAffineParallelInductionVar(Value val) {
bool mlir::affine::isAffineParallelInductionVar(Value val) {
return getAffineParallelInductionVarOwner(val) != nullptr;
}
bool mlir::isAffineInductionVar(Value val) {
bool mlir::affine::isAffineInductionVar(Value val) {
return isAffineForInductionVar(val) || isAffineParallelInductionVar(val);
}
AffineForOp mlir::getForInductionVarOwner(Value val) {
AffineForOp mlir::affine::getForInductionVarOwner(Value val) {
auto ivArg = val.dyn_cast<BlockArgument>();
if (!ivArg || !ivArg.getOwner())
return AffineForOp();
@ -2541,7 +2548,7 @@ AffineForOp mlir::getForInductionVarOwner(Value val) {
return AffineForOp();
}
AffineParallelOp mlir::getAffineParallelInductionVarOwner(Value val) {
AffineParallelOp mlir::affine::getAffineParallelInductionVarOwner(Value val) {
auto ivArg = val.dyn_cast<BlockArgument>();
if (!ivArg || !ivArg.getOwner())
return nullptr;
@ -2554,15 +2561,15 @@ AffineParallelOp mlir::getAffineParallelInductionVarOwner(Value val) {
/// Extracts the induction variables from a list of AffineForOps and returns
/// them.
void mlir::extractForInductionVars(ArrayRef<AffineForOp> forInsts,
SmallVectorImpl<Value> *ivs) {
void mlir::affine::extractForInductionVars(ArrayRef<AffineForOp> forInsts,
SmallVectorImpl<Value> *ivs) {
ivs->reserve(forInsts.size());
for (auto forInst : forInsts)
ivs->push_back(forInst.getInductionVar());
}
void mlir::extractInductionVars(ArrayRef<mlir::Operation *> affineOps,
SmallVectorImpl<mlir::Value> &ivs) {
void mlir::affine::extractInductionVars(ArrayRef<mlir::Operation *> affineOps,
SmallVectorImpl<mlir::Value> &ivs) {
ivs.reserve(affineOps.size());
for (Operation *op : affineOps) {
// Add constraints from forOp's bounds.
@ -2640,7 +2647,7 @@ buildAffineLoopFromValues(OpBuilder &builder, Location loc, Value lb, Value ub,
/*iterArgs=*/std::nullopt, bodyBuilderFn);
}
void mlir::buildAffineLoopNest(
void mlir::affine::buildAffineLoopNest(
OpBuilder &builder, Location loc, ArrayRef<int64_t> lbs,
ArrayRef<int64_t> ubs, ArrayRef<int64_t> steps,
function_ref<void(OpBuilder &, Location, ValueRange)> bodyBuilderFn) {
@ -2648,7 +2655,7 @@ void mlir::buildAffineLoopNest(
buildAffineLoopFromConstants);
}
void mlir::buildAffineLoopNest(
void mlir::affine::buildAffineLoopNest(
OpBuilder &builder, Location loc, ValueRange lbs, ValueRange ubs,
ArrayRef<int64_t> steps,
function_ref<void(OpBuilder &, Location, ValueRange)> bodyBuilderFn) {
@ -2656,11 +2663,12 @@ void mlir::buildAffineLoopNest(
buildAffineLoopFromValues);
}
AffineForOp mlir::replaceForOpWithNewYields(OpBuilder &b, AffineForOp loop,
ValueRange newIterOperands,
ValueRange newYieldedValues,
ValueRange newIterArgs,
bool replaceLoopResults) {
AffineForOp mlir::affine::replaceForOpWithNewYields(OpBuilder &b,
AffineForOp loop,
ValueRange newIterOperands,
ValueRange newYieldedValues,
ValueRange newIterArgs,
bool replaceLoopResults) {
assert(newIterOperands.size() == newYieldedValues.size() &&
"newIterOperands must be of the same size as newYieldedValues");
// Create a new loop before the existing one, with the extra operands.

View File

@ -10,6 +10,7 @@
#include "mlir/Dialect/Affine/IR/AffineOps.h"
using namespace mlir;
using namespace mlir::affine;
AffineValueMap::AffineValueMap(AffineMap map, ValueRange operands,
ValueRange results)

View File

@ -12,6 +12,7 @@
#include "mlir/Interfaces/ValueBoundsOpInterface.h"
using namespace mlir;
using namespace mlir::affine;
namespace mlir {
namespace {

View File

@ -19,6 +19,7 @@
#include "mlir/Transforms/GreedyPatternRewriteDriver.h"
using namespace mlir;
using namespace mlir::affine;
using namespace mlir::transform;
//===----------------------------------------------------------------------===//

View File

@ -35,13 +35,16 @@
#include <optional>
namespace mlir {
namespace affine {
#define GEN_PASS_DEF_AFFINEDATACOPYGENERATION
#include "mlir/Dialect/Affine/Passes.h.inc"
} // namespace affine
} // namespace mlir
#define DEBUG_TYPE "affine-data-copy-generate"
using namespace mlir;
using namespace mlir::affine;
namespace {
@ -57,7 +60,8 @@ namespace {
// TODO: We currently can't generate copies correctly when stores
// are strided. Check for strided stores.
struct AffineDataCopyGeneration
: public impl::AffineDataCopyGenerationBase<AffineDataCopyGeneration> {
: public affine::impl::AffineDataCopyGenerationBase<
AffineDataCopyGeneration> {
AffineDataCopyGeneration() = default;
explicit AffineDataCopyGeneration(unsigned slowMemorySpace,
unsigned fastMemorySpace,
@ -85,17 +89,15 @@ struct AffineDataCopyGeneration
/// by the latter. Only load op's handled for now.
/// TODO: extend this to store op's.
std::unique_ptr<OperationPass<func::FuncOp>>
mlir::createAffineDataCopyGenerationPass(unsigned slowMemorySpace,
unsigned fastMemorySpace,
unsigned tagMemorySpace,
int minDmaTransferSize,
uint64_t fastMemCapacityBytes) {
mlir::affine::createAffineDataCopyGenerationPass(
unsigned slowMemorySpace, unsigned fastMemorySpace, unsigned tagMemorySpace,
int minDmaTransferSize, uint64_t fastMemCapacityBytes) {
return std::make_unique<AffineDataCopyGeneration>(
slowMemorySpace, fastMemorySpace, tagMemorySpace, minDmaTransferSize,
fastMemCapacityBytes);
}
std::unique_ptr<OperationPass<func::FuncOp>>
mlir::createAffineDataCopyGenerationPass() {
mlir::affine::createAffineDataCopyGenerationPass() {
return std::make_unique<AffineDataCopyGeneration>();
}

View File

@ -18,11 +18,14 @@
#include "mlir/Transforms/GreedyPatternRewriteDriver.h"
namespace mlir {
namespace affine {
#define GEN_PASS_DEF_AFFINEEXPANDINDEXOPS
#include "mlir/Dialect/Affine/Passes.h.inc"
} // namespace affine
} // namespace mlir
using namespace mlir;
using namespace mlir::affine;
namespace {
/// Lowers `affine.delinearize_index` into a sequence of division and remainder
@ -43,7 +46,7 @@ struct LowerDelinearizeIndexOps
};
class ExpandAffineIndexOpsPass
: public impl::AffineExpandIndexOpsBase<ExpandAffineIndexOpsPass> {
: public affine::impl::AffineExpandIndexOpsBase<ExpandAffineIndexOpsPass> {
public:
ExpandAffineIndexOpsPass() = default;
@ -59,10 +62,11 @@ public:
} // namespace
void mlir::populateAffineExpandIndexOpsPatterns(RewritePatternSet &patterns) {
void mlir::affine::populateAffineExpandIndexOpsPatterns(
RewritePatternSet &patterns) {
patterns.insert<LowerDelinearizeIndexOps>(patterns.getContext());
}
std::unique_ptr<Pass> mlir::createAffineExpandIndexOpsPass() {
std::unique_ptr<Pass> mlir::affine::createAffineExpandIndexOpsPass() {
return std::make_unique<ExpandAffineIndexOpsPass>();
}

View File

@ -34,13 +34,16 @@
#include "llvm/Support/raw_ostream.h"
namespace mlir {
namespace affine {
#define GEN_PASS_DEF_AFFINELOOPINVARIANTCODEMOTION
#include "mlir/Dialect/Affine/Passes.h.inc"
} // namespace affine
} // namespace mlir
#define DEBUG_TYPE "licm"
using namespace mlir;
using namespace mlir::affine;
namespace {
@ -50,7 +53,8 @@ namespace {
/// TODO: This code should be removed once the new LICM pass can handle its
/// uses.
struct LoopInvariantCodeMotion
: public impl::AffineLoopInvariantCodeMotionBase<LoopInvariantCodeMotion> {
: public affine::impl::AffineLoopInvariantCodeMotionBase<
LoopInvariantCodeMotion> {
void runOnOperation() override;
void runOnAffineForOp(AffineForOp forOp);
};
@ -71,9 +75,9 @@ areAllOpsInTheBlockListInvariant(Region &blockList, Value indVar,
SmallPtrSetImpl<Operation *> &opsToHoist);
// Returns true if the individual op is loop invariant.
bool isOpLoopInvariant(Operation &op, Value indVar, ValueRange iterArgs,
SmallPtrSetImpl<Operation *> &opsWithUsers,
SmallPtrSetImpl<Operation *> &opsToHoist) {
static bool isOpLoopInvariant(Operation &op, Value indVar, ValueRange iterArgs,
SmallPtrSetImpl<Operation *> &opsWithUsers,
SmallPtrSetImpl<Operation *> &opsToHoist) {
LLVM_DEBUG(llvm::dbgs() << "iterating on op: " << op;);
if (auto ifOp = dyn_cast<AffineIfOp>(op)) {
@ -167,10 +171,11 @@ bool isOpLoopInvariant(Operation &op, Value indVar, ValueRange iterArgs,
}
// Checks if all ops in a region (i.e. list of blocks) are loop invariant.
bool areAllOpsInTheBlockListInvariant(
Region &blockList, Value indVar, ValueRange iterArgs,
SmallPtrSetImpl<Operation *> &opsWithUsers,
SmallPtrSetImpl<Operation *> &opsToHoist) {
static bool
areAllOpsInTheBlockListInvariant(Region &blockList, Value indVar,
ValueRange iterArgs,
SmallPtrSetImpl<Operation *> &opsWithUsers,
SmallPtrSetImpl<Operation *> &opsToHoist) {
for (auto &b : blockList) {
for (auto &op : b) {
@ -183,10 +188,10 @@ bool areAllOpsInTheBlockListInvariant(
}
// Returns true if the affine.if op can be hoisted.
bool checkInvarianceOfNestedIfOps(AffineIfOp ifOp, Value indVar,
ValueRange iterArgs,
SmallPtrSetImpl<Operation *> &opsWithUsers,
SmallPtrSetImpl<Operation *> &opsToHoist) {
static bool
checkInvarianceOfNestedIfOps(AffineIfOp ifOp, Value indVar, ValueRange iterArgs,
SmallPtrSetImpl<Operation *> &opsWithUsers,
SmallPtrSetImpl<Operation *> &opsToHoist) {
if (!areAllOpsInTheBlockListInvariant(ifOp.getThenRegion(), indVar, iterArgs,
opsWithUsers, opsToHoist))
return false;
@ -243,6 +248,6 @@ void LoopInvariantCodeMotion::runOnOperation() {
}
std::unique_ptr<OperationPass<func::FuncOp>>
mlir::createAffineLoopInvariantCodeMotionPass() {
mlir::affine::createAffineLoopInvariantCodeMotionPass() {
return std::make_unique<LoopInvariantCodeMotion>();
}

View File

@ -17,11 +17,14 @@
#include "mlir/Dialect/Func/IR/FuncOps.h"
namespace mlir {
namespace affine {
#define GEN_PASS_DEF_AFFINELOOPNORMALIZE
#include "mlir/Dialect/Affine/Passes.h.inc"
} // namespace affine
} // namespace mlir
using namespace mlir;
using namespace mlir::affine;
namespace {
@ -29,7 +32,7 @@ namespace {
/// As currently implemented, this pass cannot fail, but it might skip over ops
/// that are already in a normalized form.
struct AffineLoopNormalizePass
: public impl::AffineLoopNormalizeBase<AffineLoopNormalizePass> {
: public affine::impl::AffineLoopNormalizeBase<AffineLoopNormalizePass> {
explicit AffineLoopNormalizePass(bool promoteSingleIter) {
this->promoteSingleIter = promoteSingleIter;
}
@ -47,6 +50,6 @@ struct AffineLoopNormalizePass
} // namespace
std::unique_ptr<OperationPass<func::FuncOp>>
mlir::createAffineLoopNormalizePass(bool promoteSingleIter) {
mlir::affine::createAffineLoopNormalizePass(bool promoteSingleIter) {
return std::make_unique<AffineLoopNormalizePass>(promoteSingleIter);
}

View File

@ -27,18 +27,21 @@
#include <deque>
namespace mlir {
namespace affine {
#define GEN_PASS_DEF_AFFINEPARALLELIZE
#include "mlir/Dialect/Affine/Passes.h.inc"
} // namespace affine
} // namespace mlir
#define DEBUG_TYPE "affine-parallel"
using namespace mlir;
using namespace mlir::affine;
namespace {
/// Convert all parallel affine.for op into 1-D affine.parallel op.
struct AffineParallelize
: public impl::AffineParallelizeBase<AffineParallelize> {
: public affine::impl::AffineParallelizeBase<AffineParallelize> {
void runOnOperation() override;
};
@ -89,6 +92,6 @@ void AffineParallelize::runOnOperation() {
}
std::unique_ptr<OperationPass<func::FuncOp>>
mlir::createAffineParallelizePass() {
mlir::affine::createAffineParallelizePass() {
return std::make_unique<AffineParallelize>();
}

View File

@ -23,24 +23,28 @@
#include <algorithm>
namespace mlir {
namespace affine {
#define GEN_PASS_DEF_AFFINESCALARREPLACEMENT
#include "mlir/Dialect/Affine/Passes.h.inc"
} // namespace affine
} // namespace mlir
#define DEBUG_TYPE "affine-scalrep"
using namespace mlir;
using namespace mlir::affine;
namespace {
struct AffineScalarReplacement
: public impl::AffineScalarReplacementBase<AffineScalarReplacement> {
: public affine::impl::AffineScalarReplacementBase<
AffineScalarReplacement> {
void runOnOperation() override;
};
} // namespace
std::unique_ptr<OperationPass<func::FuncOp>>
mlir::createAffineScalarReplacementPass() {
mlir::affine::createAffineScalarReplacementPass() {
return std::make_unique<AffineScalarReplacement>();
}

View File

@ -18,6 +18,7 @@
#include "llvm/Support/Debug.h"
using namespace mlir;
using namespace mlir::affine;
#define DEBUG_TYPE "decompose-affine-ops"
#define DBGS() (llvm::dbgs() << "[" DEBUG_TYPE "]: ")
@ -38,8 +39,8 @@ static int64_t numEnclosingInvariantLoops(OpOperand &operand) {
return count;
}
void mlir::reorderOperandsByHoistability(RewriterBase &rewriter,
AffineApplyOp op) {
void mlir::affine::reorderOperandsByHoistability(RewriterBase &rewriter,
AffineApplyOp op) {
SmallVector<int64_t> numInvariant = llvm::to_vector(
llvm::map_range(op->getOpOperands(), [&](OpOperand &operand) {
return numEnclosingInvariantLoops(operand);
@ -92,8 +93,8 @@ static AffineApplyOp createSubApply(RewriterBase &rewriter,
rhsOperands);
}
FailureOr<AffineApplyOp> mlir::decompose(RewriterBase &rewriter,
AffineApplyOp op) {
FailureOr<AffineApplyOp> mlir::affine::decompose(RewriterBase &rewriter,
AffineApplyOp op) {
// 1. Preconditions: only handle dimensionless AffineApplyOp maps with a
// top-level binary expression that we can reassociate (i.e. add or mul).
AffineMap m = op.getAffineMap();

View File

@ -19,18 +19,21 @@
#include "llvm/Support/Debug.h"
namespace mlir {
namespace affine {
#define GEN_PASS_DEF_LOOPCOALESCING
#include "mlir/Dialect/Affine/Passes.h.inc"
} // namespace affine
} // namespace mlir
#define PASS_NAME "loop-coalescing"
#define DEBUG_TYPE PASS_NAME
using namespace mlir;
using namespace mlir::affine;
namespace {
struct LoopCoalescingPass
: public impl::LoopCoalescingBase<LoopCoalescingPass> {
: public affine::impl::LoopCoalescingBase<LoopCoalescingPass> {
void runOnOperation() override {
func::FuncOp func = getOperation();
@ -45,6 +48,7 @@ struct LoopCoalescingPass
} // namespace
std::unique_ptr<OperationPass<func::FuncOp>> mlir::createLoopCoalescingPass() {
std::unique_ptr<OperationPass<func::FuncOp>>
mlir::affine::createLoopCoalescingPass() {
return std::make_unique<LoopCoalescingPass>();
}

View File

@ -36,13 +36,16 @@
#include <sstream>
namespace mlir {
namespace affine {
#define GEN_PASS_DEF_AFFINELOOPFUSION
#include "mlir/Dialect/Affine/Passes.h.inc"
} // namespace affine
} // namespace mlir
#define DEBUG_TYPE "affine-loop-fusion"
using namespace mlir;
using namespace mlir::affine;
namespace {
/// Loop fusion pass. This pass currently supports a greedy fusion policy,
@ -54,7 +57,7 @@ namespace {
// TODO: Extend this pass to check for fusion preventing dependences,
// and add support for more general loop fusion algorithms.
struct LoopFusion : public impl::AffineLoopFusionBase<LoopFusion> {
struct LoopFusion : public affine::impl::AffineLoopFusionBase<LoopFusion> {
LoopFusion() = default;
LoopFusion(unsigned fastMemorySpace, uint64_t localBufSizeThresholdBytes,
bool maximalFusion, enum FusionMode affineFusionMode) {
@ -1039,7 +1042,7 @@ public:
depthSliceUnions.resize(dstLoopDepthTest);
FusionStrategy strategy(FusionStrategy::ProducerConsumer);
for (unsigned i = 1; i <= dstLoopDepthTest; ++i) {
FusionResult result = mlir::canFuseLoops(
FusionResult result = affine::canFuseLoops(
srcAffineForOp, dstAffineForOp,
/*dstLoopDepth=*/i, &depthSliceUnions[i - 1], strategy);
@ -1259,7 +1262,7 @@ public:
unsigned maxLegalFusionDepth = 0;
FusionStrategy strategy(memref);
for (unsigned i = 1; i <= dstLoopDepthTest; ++i) {
FusionResult result = mlir::canFuseLoops(
FusionResult result = affine::canFuseLoops(
sibAffineForOp, dstAffineForOp,
/*dstLoopDepth=*/i, &depthSliceUnions[i - 1], strategy);
@ -1291,9 +1294,9 @@ public:
// further inside `fuseLoops`.
bool isInnermostInsertion = (bestDstLoopDepth == dstLoopDepthTest);
// Fuse computation slice of 'sibLoopNest' into 'dstLoopNest'.
mlir::fuseLoops(sibAffineForOp, dstAffineForOp,
depthSliceUnions[bestDstLoopDepth - 1],
isInnermostInsertion);
affine::fuseLoops(sibAffineForOp, dstAffineForOp,
depthSliceUnions[bestDstLoopDepth - 1],
isInnermostInsertion);
auto dstForInst = cast<AffineForOp>(dstNode->op);
// Update operation position of fused loop nest (if needed).
@ -1501,10 +1504,9 @@ void LoopFusion::runOnOperation() {
runOnBlock(&block);
}
std::unique_ptr<Pass>
mlir::createLoopFusionPass(unsigned fastMemorySpace,
uint64_t localBufSizeThreshold, bool maximalFusion,
enum FusionMode affineFusionMode) {
std::unique_ptr<Pass> mlir::affine::createLoopFusionPass(
unsigned fastMemorySpace, uint64_t localBufSizeThreshold,
bool maximalFusion, enum FusionMode affineFusionMode) {
return std::make_unique<LoopFusion>(fastMemorySpace, localBufSizeThreshold,
maximalFusion, affineFusionMode);
}

View File

@ -28,18 +28,21 @@
#include <optional>
namespace mlir {
namespace affine {
#define GEN_PASS_DEF_AFFINELOOPTILING
#include "mlir/Dialect/Affine/Passes.h.inc"
} // namespace affine
} // namespace mlir
using namespace mlir;
using namespace mlir::affine;
#define DEBUG_TYPE "affine-loop-tile"
namespace {
/// A pass to perform loop tiling on all suitable loop nests of a Function.
struct LoopTiling : public impl::AffineLoopTilingBase<LoopTiling> {
struct LoopTiling : public affine::impl::AffineLoopTilingBase<LoopTiling> {
LoopTiling() = default;
explicit LoopTiling(uint64_t cacheSizeBytes, bool avoidMaxMinBounds = true)
: avoidMaxMinBounds(avoidMaxMinBounds) {
@ -62,10 +65,11 @@ struct LoopTiling : public impl::AffineLoopTilingBase<LoopTiling> {
/// Creates a pass to perform loop tiling on all suitable loop nests of a
/// Function.
std::unique_ptr<OperationPass<func::FuncOp>>
mlir::createLoopTilingPass(uint64_t cacheSizeBytes) {
mlir::affine::createLoopTilingPass(uint64_t cacheSizeBytes) {
return std::make_unique<LoopTiling>(cacheSizeBytes);
}
std::unique_ptr<OperationPass<func::FuncOp>> mlir::createLoopTilingPass() {
std::unique_ptr<OperationPass<func::FuncOp>>
mlir::affine::createLoopTilingPass() {
return std::make_unique<LoopTiling>();
}
@ -97,7 +101,7 @@ static void adjustToDivisorsOfTripCounts(ArrayRef<AffineForOp> band,
/// hyper-rectangles, which are scheduled in the lexicographically increasing
/// order on the vector of loop indices. This function will return failure when
/// any dependence component is negative along any of `origLoops`.
static bool checkTilingLegality(MutableArrayRef<mlir::AffineForOp> origLoops) {
static bool checkTilingLegality(MutableArrayRef<AffineForOp> origLoops) {
assert(!origLoops.empty() && "no original loops provided");
// We first find out all dependences we intend to check.

View File

@ -25,13 +25,16 @@
#include <optional>
namespace mlir {
namespace affine {
#define GEN_PASS_DEF_AFFINELOOPUNROLL
#include "mlir/Dialect/Affine/Passes.h.inc"
} // namespace affine
} // namespace mlir
#define DEBUG_TYPE "affine-loop-unroll"
using namespace mlir;
using namespace mlir::affine;
namespace {
@ -42,7 +45,7 @@ namespace {
/// full unroll threshold was specified, in which case, fully unrolls all loops
/// with trip count less than the specified threshold. The latter is for testing
/// purposes, especially for testing outer loop unrolling.
struct LoopUnroll : public impl::AffineLoopUnrollBase<LoopUnroll> {
struct LoopUnroll : public affine::impl::AffineLoopUnrollBase<LoopUnroll> {
// Callback to obtain unroll factors; if this has a callable target, takes
// precedence over command-line argument or passed argument.
const std::function<unsigned(AffineForOp)> getUnrollFactor;
@ -142,7 +145,7 @@ LogicalResult LoopUnroll::runOnAffineForOp(AffineForOp forOp) {
cleanUpUnroll);
}
std::unique_ptr<OperationPass<func::FuncOp>> mlir::createLoopUnrollPass(
std::unique_ptr<OperationPass<func::FuncOp>> mlir::affine::createLoopUnrollPass(
int unrollFactor, bool unrollUpToFactor, bool unrollFull,
const std::function<unsigned(AffineForOp)> &getUnrollFactor) {
return std::make_unique<LoopUnroll>(

View File

@ -49,19 +49,22 @@
#include <optional>
namespace mlir {
namespace affine {
#define GEN_PASS_DEF_AFFINELOOPUNROLLANDJAM
#include "mlir/Dialect/Affine/Passes.h.inc"
} // namespace affine
} // namespace mlir
#define DEBUG_TYPE "affine-loop-unroll-jam"
using namespace mlir;
using namespace mlir::affine;
namespace {
/// Loop unroll jam pass. Currently, this just unroll jams the first
/// outer loop in a Function.
struct LoopUnrollAndJam
: public impl::AffineLoopUnrollAndJamBase<LoopUnrollAndJam> {
: public affine::impl::AffineLoopUnrollAndJamBase<LoopUnrollAndJam> {
explicit LoopUnrollAndJam(
std::optional<unsigned> unrollJamFactor = std::nullopt) {
if (unrollJamFactor)
@ -73,7 +76,7 @@ struct LoopUnrollAndJam
} // namespace
std::unique_ptr<OperationPass<func::FuncOp>>
mlir::createLoopUnrollAndJamPass(int unrollJamFactor) {
mlir::affine::createLoopUnrollAndJamPass(int unrollJamFactor) {
return std::make_unique<LoopUnrollAndJam>(
unrollJamFactor == -1 ? std::nullopt
: std::optional<unsigned>(unrollJamFactor));

View File

@ -27,17 +27,21 @@
#include "llvm/Support/Debug.h"
namespace mlir {
namespace affine {
#define GEN_PASS_DEF_AFFINEPIPELINEDATATRANSFER
#include "mlir/Dialect/Affine/Passes.h.inc"
} // namespace affine
} // namespace mlir
#define DEBUG_TYPE "affine-pipeline-data-transfer"
using namespace mlir;
using namespace mlir::affine;
namespace {
struct PipelineDataTransfer
: public impl::AffinePipelineDataTransferBase<PipelineDataTransfer> {
: public affine::impl::AffinePipelineDataTransferBase<
PipelineDataTransfer> {
void runOnOperation() override;
void runOnAffineForOp(AffineForOp forOp);
@ -49,7 +53,7 @@ struct PipelineDataTransfer
/// Creates a pass to pipeline explicit movement of data across levels of the
/// memory hierarchy.
std::unique_ptr<OperationPass<func::FuncOp>>
mlir::createPipelineDataTransferPass() {
mlir::affine::createPipelineDataTransferPass() {
return std::make_unique<PipelineDataTransfer>();
}
@ -328,7 +332,7 @@ void PipelineDataTransfer::runOnAffineForOp(AffineForOp forOp) {
instShiftMap[dmaStartOp] = 0;
// Set shifts for DMA start op's affine operand computation slices to 0.
SmallVector<AffineApplyOp, 4> sliceOps;
mlir::createAffineComputationSlice(dmaStartOp, &sliceOps);
affine::createAffineComputationSlice(dmaStartOp, &sliceOps);
if (!sliceOps.empty()) {
for (auto sliceOp : sliceOps) {
instShiftMap[sliceOp.getOperation()] = 0;

View File

@ -14,6 +14,7 @@
#include "mlir/Interfaces/ValueBoundsOpInterface.h"
using namespace mlir;
using namespace mlir::affine;
static FailureOr<OpFoldResult>
reifyValueBound(OpBuilder &b, Location loc, presburger::BoundType type,
@ -54,7 +55,7 @@ reifyValueBound(OpBuilder &b, Location loc, presburger::BoundType type,
}
// Simplify and return bound.
mlir::canonicalizeMapAndOperands(&boundMap, &operands);
affine::canonicalizeMapAndOperands(&boundMap, &operands);
// Check for special cases where no affine.apply op is needed.
if (boundMap.isSingleConstant()) {
// Bound is a constant: return an IntegerAttr.
@ -69,10 +70,10 @@ reifyValueBound(OpBuilder &b, Location loc, presburger::BoundType type,
operands[expr.getPosition() + boundMap.getNumDims()]);
// General case: build affine.apply op.
return static_cast<OpFoldResult>(
b.create<AffineApplyOp>(loc, boundMap, operands).getResult());
b.create<affine::AffineApplyOp>(loc, boundMap, operands).getResult());
}
FailureOr<OpFoldResult> mlir::reifyShapedValueDimBound(
FailureOr<OpFoldResult> mlir::affine::reifyShapedValueDimBound(
OpBuilder &b, Location loc, presburger::BoundType type, Value value,
int64_t dim, ValueBoundsConstraintSet::StopConditionFn stopCondition,
bool closedUB) {
@ -89,7 +90,7 @@ FailureOr<OpFoldResult> mlir::reifyShapedValueDimBound(
closedUB);
}
FailureOr<OpFoldResult> mlir::reifyIndexValueBound(
FailureOr<OpFoldResult> mlir::affine::reifyIndexValueBound(
OpBuilder &b, Location loc, presburger::BoundType type, Value value,
ValueBoundsConstraintSet::StopConditionFn stopCondition, bool closedUB) {
auto reifyToOperands = [&](Value v, std::optional<int64_t> d) {

View File

@ -20,13 +20,16 @@
#include "mlir/Transforms/GreedyPatternRewriteDriver.h"
namespace mlir {
namespace affine {
#define GEN_PASS_DEF_SIMPLIFYAFFINESTRUCTURES
#include "mlir/Dialect/Affine/Passes.h.inc"
} // namespace affine
} // namespace mlir
#define DEBUG_TYPE "simplify-affine-structure"
using namespace mlir;
using namespace mlir::affine;
namespace {
@ -35,7 +38,8 @@ namespace {
/// all memrefs with non-trivial layout maps are converted to ones with trivial
/// identity layout ones.
struct SimplifyAffineStructures
: public impl::SimplifyAffineStructuresBase<SimplifyAffineStructures> {
: public affine::impl::SimplifyAffineStructuresBase<
SimplifyAffineStructures> {
void runOnOperation() override;
/// Utility to simplify an affine attribute and update its entry in the parent
@ -78,7 +82,7 @@ struct SimplifyAffineStructures
} // namespace
std::unique_ptr<OperationPass<func::FuncOp>>
mlir::createSimplifyAffineStructuresPass() {
mlir::affine::createSimplifyAffineStructuresPass() {
return std::make_unique<SimplifyAffineStructures>();
}

View File

@ -31,11 +31,14 @@
#include <optional>
namespace mlir {
namespace affine {
#define GEN_PASS_DEF_AFFINEVECTORIZE
#include "mlir/Dialect/Affine/Passes.h.inc"
} // namespace affine
} // namespace mlir
using namespace mlir;
using namespace affine;
using namespace vector;
///
@ -585,7 +588,7 @@ isVectorizableLoopPtrFactory(const DenseSet<Operation *> &parallelLoops,
static std::optional<NestedPattern>
makePattern(const DenseSet<Operation *> &parallelLoops, int vectorRank,
ArrayRef<int64_t> fastestVaryingPattern) {
using matcher::For;
using affine::matcher::For;
int64_t d0 = fastestVaryingPattern.empty() ? -1 : fastestVaryingPattern[0];
int64_t d1 = fastestVaryingPattern.size() < 2 ? -1 : fastestVaryingPattern[1];
int64_t d2 = fastestVaryingPattern.size() < 3 ? -1 : fastestVaryingPattern[2];
@ -606,7 +609,7 @@ makePattern(const DenseSet<Operation *> &parallelLoops, int vectorRank,
}
static NestedPattern &vectorTransferPattern() {
static auto pattern = matcher::Op([](Operation &op) {
static auto pattern = affine::matcher::Op([](Operation &op) {
return isa<vector::TransferReadOp, vector::TransferWriteOp>(op);
});
return pattern;
@ -616,7 +619,7 @@ namespace {
/// Base state for the vectorize pass.
/// Command line arguments are preempted by non-empty pass arguments.
struct Vectorize : public impl::AffineVectorizeBase<Vectorize> {
struct Vectorize : public affine::impl::AffineVectorizeBase<Vectorize> {
using Base::Base;
void runOnOperation() override;
@ -1796,7 +1799,6 @@ verifyLoopNesting(const std::vector<SmallVector<AffineForOp, 2>> &loops) {
return success();
}
namespace mlir {
/// External utility to vectorize affine loops in 'loops' using the n-D
/// vectorization factors in 'vectorSizes'. By default, each vectorization
@ -1806,10 +1808,10 @@ namespace mlir {
/// If `reductionLoops` is not empty, the given reduction loops may be
/// vectorized along the reduction dimension.
/// TODO: Vectorizing reductions is supported only for 1-D vectorization.
void vectorizeAffineLoops(Operation *parentOp, DenseSet<Operation *> &loops,
ArrayRef<int64_t> vectorSizes,
ArrayRef<int64_t> fastestVaryingPattern,
const ReductionLoopMap &reductionLoops) {
void mlir::affine::vectorizeAffineLoops(
Operation *parentOp, DenseSet<Operation *> &loops,
ArrayRef<int64_t> vectorSizes, ArrayRef<int64_t> fastestVaryingPattern,
const ReductionLoopMap &reductionLoops) {
// Thread-safe RAII local context, BumpPtrAllocator freed on exit.
NestedPatternContext mlContext;
vectorizeLoops(parentOp, loops, vectorSizes, fastestVaryingPattern,
@ -1851,14 +1853,12 @@ void vectorizeAffineLoops(Operation *parentOp, DenseSet<Operation *> &loops,
/// loops = {{%i2}}, to vectorize only the first innermost loop;
/// loops = {{%i3}}, to vectorize only the second innermost loop;
/// loops = {{%i1}}, to vectorize only the middle loop.
LogicalResult
vectorizeAffineLoopNest(std::vector<SmallVector<AffineForOp, 2>> &loops,
const VectorizationStrategy &strategy) {
LogicalResult mlir::affine::vectorizeAffineLoopNest(
std::vector<SmallVector<AffineForOp, 2>> &loops,
const VectorizationStrategy &strategy) {
// Thread-safe RAII local context, BumpPtrAllocator freed on exit.
NestedPatternContext mlContext;
if (failed(verifyLoopNesting(loops)))
return failure();
return vectorizeLoopNest(loops, strategy);
}
} // namespace mlir

View File

@ -26,6 +26,7 @@
#define DEBUG_TYPE "loop-fusion-utils"
using namespace mlir;
using namespace mlir::affine;
// Gathers all load and store memref accesses in 'opA' into 'values', where
// 'values[memref] == true' for each store operation.
@ -245,10 +246,11 @@ static unsigned getMaxLoopDepth(ArrayRef<Operation *> srcOps,
// TODO: This pass performs some computation that is the same for all the depths
// (e.g., getMaxLoopDepth). Implement a version of this utility that processes
// all the depths at once or only the legal maximal depth for maximal fusion.
FusionResult mlir::canFuseLoops(AffineForOp srcForOp, AffineForOp dstForOp,
unsigned dstLoopDepth,
ComputationSliceState *srcSlice,
FusionStrategy fusionStrategy) {
FusionResult mlir::affine::canFuseLoops(AffineForOp srcForOp,
AffineForOp dstForOp,
unsigned dstLoopDepth,
ComputationSliceState *srcSlice,
FusionStrategy fusionStrategy) {
// Return 'failure' if 'dstLoopDepth == 0'.
if (dstLoopDepth == 0) {
LLVM_DEBUG(llvm::dbgs() << "Cannot fuse loop nests at depth 0\n");
@ -303,7 +305,7 @@ FusionResult mlir::canFuseLoops(AffineForOp srcForOp, AffineForOp dstForOp,
// Calculate the number of common loops surrounding 'srcForOp' and 'dstForOp'.
unsigned numCommonLoops =
mlir::getNumCommonSurroundingLoops(*srcForOp, *dstForOp);
affine::getNumCommonSurroundingLoops(*srcForOp, *dstForOp);
// Filter out ops in 'opsA' to compute the slice union based on the
// assumptions made by the fusion strategy.
@ -335,9 +337,9 @@ FusionResult mlir::canFuseLoops(AffineForOp srcForOp, AffineForOp dstForOp,
// Compute union of computation slices computed between all pairs of ops
// from 'forOpA' and 'forOpB'.
SliceComputationResult sliceComputationResult =
mlir::computeSliceUnion(strategyOpsA, opsB, dstLoopDepth, numCommonLoops,
isSrcForOpBeforeDstForOp, srcSlice);
SliceComputationResult sliceComputationResult = affine::computeSliceUnion(
strategyOpsA, opsB, dstLoopDepth, numCommonLoops,
isSrcForOpBeforeDstForOp, srcSlice);
if (sliceComputationResult.value == SliceComputationResult::GenericFailure) {
LLVM_DEBUG(llvm::dbgs() << "computeSliceUnion failed\n");
return FusionResult::FailPrecondition;
@ -353,8 +355,8 @@ FusionResult mlir::canFuseLoops(AffineForOp srcForOp, AffineForOp dstForOp,
/// Patch the loop body of a forOp that is a single iteration reduction loop
/// into its containing block.
LogicalResult promoteSingleIterReductionLoop(AffineForOp forOp,
bool siblingFusionUser) {
static LogicalResult promoteSingleIterReductionLoop(AffineForOp forOp,
bool siblingFusionUser) {
// Check if the reduction loop is a single iteration loop.
std::optional<uint64_t> tripCount = getConstantTripCount(forOp);
if (!tripCount || *tripCount != 1)
@ -416,9 +418,9 @@ LogicalResult promoteSingleIterReductionLoop(AffineForOp forOp,
/// Fuses 'srcForOp' into 'dstForOp' with destination loop block insertion point
/// and source slice loop bounds specified in 'srcSlice'.
void mlir::fuseLoops(AffineForOp srcForOp, AffineForOp dstForOp,
const ComputationSliceState &srcSlice,
bool isInnermostSiblingInsertion) {
void mlir::affine::fuseLoops(AffineForOp srcForOp, AffineForOp dstForOp,
const ComputationSliceState &srcSlice,
bool isInnermostSiblingInsertion) {
// Clone 'srcForOp' into 'dstForOp' at 'srcSlice->insertPoint'.
OpBuilder b(srcSlice.insertPoint->getBlock(), srcSlice.insertPoint);
IRMapping mapper;
@ -465,7 +467,8 @@ void mlir::fuseLoops(AffineForOp srcForOp, AffineForOp dstForOp,
/// Collect loop nest statistics (eg. loop trip count and operation count)
/// in 'stats' for loop nest rooted at 'forOp'. Returns true on success,
/// returns false otherwise.
bool mlir::getLoopNestStats(AffineForOp forOpRoot, LoopNestStats *stats) {
bool mlir::affine::getLoopNestStats(AffineForOp forOpRoot,
LoopNestStats *stats) {
auto walkResult = forOpRoot.walk([&](AffineForOp forOp) {
auto *childForOp = forOp.getOperation();
auto *parentForOp = forOp->getParentOp();
@ -553,7 +556,7 @@ static int64_t getComputeCostHelper(
/// Currently, the total cost is computed by counting the total operation
/// instance count (i.e. total number of operations in the loop body * loop
/// trip count) for the entire loop nest.
int64_t mlir::getComputeCost(AffineForOp forOp, LoopNestStats &stats) {
int64_t mlir::affine::getComputeCost(AffineForOp forOp, LoopNestStats &stats) {
return getComputeCostHelper(forOp, stats,
/*tripCountOverrideMap=*/nullptr,
/*computeCostMap=*/nullptr);
@ -564,10 +567,12 @@ int64_t mlir::getComputeCost(AffineForOp forOp, LoopNestStats &stats) {
/// the total cost is computed by counting the total operation instance count
/// (i.e. total number of operations in the loop body * loop trip count) for
/// the entire loop nest.
bool mlir::getFusionComputeCost(AffineForOp srcForOp, LoopNestStats &srcStats,
AffineForOp dstForOp, LoopNestStats &dstStats,
const ComputationSliceState &slice,
int64_t *computeCost) {
bool mlir::affine::getFusionComputeCost(AffineForOp srcForOp,
LoopNestStats &srcStats,
AffineForOp dstForOp,
LoopNestStats &dstStats,
const ComputationSliceState &slice,
int64_t *computeCost) {
llvm::SmallDenseMap<Operation *, uint64_t, 8> sliceTripCountMap;
DenseMap<Operation *, int64_t> computeCostMap;
@ -634,7 +639,7 @@ bool mlir::getFusionComputeCost(AffineForOp srcForOp, LoopNestStats &srcStats,
/// Returns in 'producerConsumerMemrefs' the memrefs involved in a
/// producer-consumer dependence between write ops in 'srcOps' and read ops in
/// 'dstOps'.
void mlir::gatherProducerConsumerMemrefs(
void mlir::affine::gatherProducerConsumerMemrefs(
ArrayRef<Operation *> srcOps, ArrayRef<Operation *> dstOps,
DenseSet<Value> &producerConsumerMemrefs) {
// Gather memrefs from stores in 'srcOps'.

View File

@ -34,6 +34,7 @@
#define DEBUG_TYPE "loop-utils"
using namespace mlir;
using namespace affine;
using namespace presburger;
using llvm::SmallMapVector;
@ -128,7 +129,7 @@ static void replaceIterArgsAndYieldResults(AffineForOp forOp) {
/// Promotes the loop body of a forOp to its containing block if the forOp
/// was known to have a single iteration.
// TODO: extend this for arbitrary affine bounds.
LogicalResult mlir::promoteIfSingleIteration(AffineForOp forOp) {
LogicalResult mlir::affine::promoteIfSingleIteration(AffineForOp forOp) {
std::optional<uint64_t> tripCount = getConstantTripCount(forOp);
if (!tripCount || *tripCount != 1)
return failure();
@ -232,9 +233,9 @@ static AffineForOp generateShiftedLoop(
// asserts preservation of SSA dominance. A check for that as well as that for
// memory-based dependence preservation check rests with the users of this
// method.
LogicalResult mlir::affineForOpBodySkew(AffineForOp forOp,
ArrayRef<uint64_t> shifts,
bool unrollPrologueEpilogue) {
LogicalResult mlir::affine::affineForOpBodySkew(AffineForOp forOp,
ArrayRef<uint64_t> shifts,
bool unrollPrologueEpilogue) {
assert(forOp.getBody()->getOperations().size() == shifts.size() &&
"too few/many shifts");
if (forOp.getBody()->begin() == std::prev(forOp.getBody()->end()))
@ -363,7 +364,8 @@ LogicalResult mlir::affineForOpBodySkew(AffineForOp forOp,
}
/// Checks whether a loop nest is hyper-rectangular or not.
LogicalResult checkIfHyperRectangular(MutableArrayRef<AffineForOp> input) {
static LogicalResult
checkIfHyperRectangular(MutableArrayRef<AffineForOp> input) {
FlatAffineValueConstraints cst;
SmallVector<Operation *, 8> ops(input.begin(), input.end());
// 0-d or 1-d is trivially hyper-rectangular.
@ -384,8 +386,8 @@ LogicalResult checkIfHyperRectangular(MutableArrayRef<AffineForOp> input) {
/// Check if the input nest is supported for tiling and whether tiling would be
/// legal or not.
template <typename t>
LogicalResult performPreTilingChecks(MutableArrayRef<AffineForOp> input,
ArrayRef<t> tileSizes) {
static LogicalResult performPreTilingChecks(MutableArrayRef<AffineForOp> input,
ArrayRef<t> tileSizes) {
assert(input.size() == tileSizes.size() && "Too few/many tile sizes");
if (llvm::any_of(input,
@ -418,15 +420,15 @@ static void moveLoopBodyImpl(AffineForOp src, AffineForOp dest,
/// Move the loop body of AffineForOp 'src' from 'src' to the start of dest
/// body.
void moveLoopBody(AffineForOp src, AffineForOp dest) {
static void moveLoopBody(AffineForOp src, AffineForOp dest) {
moveLoopBodyImpl(src, dest, dest.getBody()->begin());
}
/// Constructs tiled loop nest, without setting the loop bounds and move the
/// body of the original loop nest to the tiled loop nest.
void constructTiledLoopNest(MutableArrayRef<AffineForOp> origLoops,
AffineForOp rootAffineForOp, unsigned width,
MutableArrayRef<AffineForOp> tiledLoops) {
static void constructTiledLoopNest(MutableArrayRef<AffineForOp> origLoops,
AffineForOp rootAffineForOp, unsigned width,
MutableArrayRef<AffineForOp> tiledLoops) {
Location loc = rootAffineForOp.getLoc();
// The outermost among the loops as we add more..
@ -773,9 +775,9 @@ constructTiledIndexSetHyperRect(MutableArrayRef<AffineForOp> origLoops,
}
LogicalResult
mlir::tilePerfectlyNested(MutableArrayRef<AffineForOp> input,
ArrayRef<unsigned> tileSizes,
SmallVectorImpl<AffineForOp> *tiledNest) {
mlir::affine::tilePerfectlyNested(MutableArrayRef<AffineForOp> input,
ArrayRef<unsigned> tileSizes,
SmallVectorImpl<AffineForOp> *tiledNest) {
if (input.empty())
return success();
@ -816,10 +818,9 @@ mlir::tilePerfectlyNested(MutableArrayRef<AffineForOp> input,
/// loops and intra-tile loops, using SSA values as tiling parameters. A band
/// is a contiguous set of loops.
// TODO: handle non hyper-rectangular spaces.
LogicalResult
mlir::tilePerfectlyNestedParametric(MutableArrayRef<AffineForOp> input,
ArrayRef<Value> tileSizes,
SmallVectorImpl<AffineForOp> *tiledNest) {
LogicalResult mlir::affine::tilePerfectlyNestedParametric(
MutableArrayRef<AffineForOp> input, ArrayRef<Value> tileSizes,
SmallVectorImpl<AffineForOp> *tiledNest) {
if (input.empty())
return success();
@ -859,8 +860,8 @@ mlir::tilePerfectlyNestedParametric(MutableArrayRef<AffineForOp> input,
/// (the first op being another AffineFor, and the second op - a terminator).
/// A loop is perfectly nested iff: the first op in the loop's body is another
/// AffineForOp, and the second op is a terminator).
void mlir::getPerfectlyNestedLoops(SmallVectorImpl<AffineForOp> &nestedLoops,
AffineForOp root) {
void mlir::affine::getPerfectlyNestedLoops(
SmallVectorImpl<AffineForOp> &nestedLoops, AffineForOp root) {
for (unsigned i = 0; i < std::numeric_limits<unsigned>::max(); ++i) {
nestedLoops.push_back(root);
Block &body = root.getRegion().front();
@ -876,8 +877,8 @@ void mlir::getPerfectlyNestedLoops(SmallVectorImpl<AffineForOp> &nestedLoops,
/// Identify valid and profitable bands of loops to tile. This is currently just
/// a temporary placeholder to test the mechanics of tiled code generation.
/// Returns all maximal outermost perfect loop nests to tile.
void mlir::getTileableBands(func::FuncOp f,
std::vector<SmallVector<AffineForOp, 6>> *bands) {
void mlir::affine::getTileableBands(
func::FuncOp f, std::vector<SmallVector<AffineForOp, 6>> *bands) {
// Get maximal perfect nest of 'affine.for' insts starting from root
// (inclusive).
for (AffineForOp forOp : f.getOps<AffineForOp>()) {
@ -888,7 +889,7 @@ void mlir::getTileableBands(func::FuncOp f,
}
/// Unrolls this loop completely.
LogicalResult mlir::loopUnrollFull(AffineForOp forOp) {
LogicalResult mlir::affine::loopUnrollFull(AffineForOp forOp) {
std::optional<uint64_t> mayBeConstantTripCount = getConstantTripCount(forOp);
if (mayBeConstantTripCount.has_value()) {
uint64_t tripCount = *mayBeConstantTripCount;
@ -903,8 +904,8 @@ LogicalResult mlir::loopUnrollFull(AffineForOp forOp) {
/// Unrolls this loop by the specified factor or by the trip count (if constant)
/// whichever is lower.
LogicalResult mlir::loopUnrollUpToFactor(AffineForOp forOp,
uint64_t unrollFactor) {
LogicalResult mlir::affine::loopUnrollUpToFactor(AffineForOp forOp,
uint64_t unrollFactor) {
std::optional<uint64_t> mayBeConstantTripCount = getConstantTripCount(forOp);
if (mayBeConstantTripCount.has_value() &&
*mayBeConstantTripCount < unrollFactor)
@ -1011,7 +1012,7 @@ static LogicalResult generateCleanupLoopForUnroll(AffineForOp forOp,
/// Unrolls this loop by the specified factor. Returns success if the loop
/// is successfully unrolled.
LogicalResult mlir::loopUnrollByFactor(
LogicalResult mlir::affine::loopUnrollByFactor(
AffineForOp forOp, uint64_t unrollFactor,
function_ref<void(unsigned, Operation *, OpBuilder)> annotateFn,
bool cleanUpUnroll) {
@ -1078,8 +1079,8 @@ LogicalResult mlir::loopUnrollByFactor(
return success();
}
LogicalResult mlir::loopUnrollJamUpToFactor(AffineForOp forOp,
uint64_t unrollJamFactor) {
LogicalResult mlir::affine::loopUnrollJamUpToFactor(AffineForOp forOp,
uint64_t unrollJamFactor) {
std::optional<uint64_t> mayBeConstantTripCount = getConstantTripCount(forOp);
if (mayBeConstantTripCount.has_value() &&
*mayBeConstantTripCount < unrollJamFactor)
@ -1129,8 +1130,8 @@ struct JamBlockGatherer {
};
/// Unrolls and jams this loop by the specified factor.
LogicalResult mlir::loopUnrollJamByFactor(AffineForOp forOp,
uint64_t unrollJamFactor) {
LogicalResult mlir::affine::loopUnrollJamByFactor(AffineForOp forOp,
uint64_t unrollJamFactor) {
assert(unrollJamFactor > 0 && "unroll jam factor should be positive");
std::optional<uint64_t> mayBeConstantTripCount = getConstantTripCount(forOp);
@ -1212,7 +1213,7 @@ LogicalResult mlir::loopUnrollJamByFactor(AffineForOp forOp,
}
// Create a new loop with additional iterOperands, iter_args and yield
// operands. This new loop will take the loop body of the original loop.
AffineForOp newForOp = mlir::replaceForOpWithNewYields(
AffineForOp newForOp = affine::replaceForOpWithNewYields(
builder, oldForOp, dupIterOperands, dupYieldOperands, dupIterArgs);
newLoopsWithIterArgs.push_back(newForOp);
// `forOp` has been replaced with a new loop.
@ -1323,7 +1324,7 @@ LogicalResult mlir::loopUnrollJamByFactor(AffineForOp forOp,
/// Performs loop interchange on 'forOpA' and 'forOpB', where 'forOpB' is
/// nested within 'forOpA' as the only non-terminator operation in its block.
void mlir::interchangeLoops(AffineForOp forOpA, AffineForOp forOpB) {
void mlir::affine::interchangeLoops(AffineForOp forOpA, AffineForOp forOpB) {
assert(&*forOpA.getBody()->begin() == forOpB.getOperation());
auto &forOpABody = forOpA.getBody()->getOperations();
auto &forOpBBody = forOpB.getBody()->getOperations();
@ -1380,8 +1381,8 @@ static bool checkLoopInterchangeDependences(
/// Checks if the loop interchange permutation 'loopPermMap' of the perfectly
/// nested sequence of loops in 'loops' would violate dependences.
bool mlir::isValidLoopInterchangePermutation(ArrayRef<AffineForOp> loops,
ArrayRef<unsigned> loopPermMap) {
bool mlir::affine::isValidLoopInterchangePermutation(
ArrayRef<AffineForOp> loops, ArrayRef<unsigned> loopPermMap) {
// Gather dependence components for dependences between all ops in loop nest
// rooted at 'loops[0]', at loop depths in range [1, maxLoopDepth].
assert(loopPermMap.size() == loops.size());
@ -1394,7 +1395,7 @@ bool mlir::isValidLoopInterchangePermutation(ArrayRef<AffineForOp> loops,
/// Returns true if `loops` is a perfectly nested loop nest, where loops appear
/// in it from outermost to innermost.
bool LLVM_ATTRIBUTE_UNUSED
mlir::isPerfectlyNested(ArrayRef<AffineForOp> loops) {
mlir::affine::isPerfectlyNested(ArrayRef<AffineForOp> loops) {
assert(!loops.empty() && "no loops provided");
// We already know that the block can't be empty.
@ -1416,8 +1417,8 @@ mlir::isPerfectlyNested(ArrayRef<AffineForOp> loops) {
// input[i] should move from position i -> permMap[i]. Returns the position in
// `input` that becomes the new outermost loop.
unsigned mlir::permuteLoops(MutableArrayRef<AffineForOp> input,
ArrayRef<unsigned> permMap) {
unsigned mlir::affine::permuteLoops(MutableArrayRef<AffineForOp> input,
ArrayRef<unsigned> permMap) {
assert(input.size() == permMap.size() && "invalid permutation map size");
// Check whether the permutation spec is valid. This is a small vector - we'll
// just sort and check if it's iota.
@ -1486,7 +1487,7 @@ unsigned mlir::permuteLoops(MutableArrayRef<AffineForOp> input,
// Sinks all sequential loops to the innermost levels (while preserving
// relative order among them) and moves all parallel loops to the
// outermost (while again preserving relative order among them).
AffineForOp mlir::sinkSequentialLoops(AffineForOp forOp) {
AffineForOp mlir::affine::sinkSequentialLoops(AffineForOp forOp) {
SmallVector<AffineForOp, 4> loops;
getPerfectlyNestedLoops(loops, forOp);
if (loops.size() < 2)
@ -1621,8 +1622,8 @@ static AffineForOp stripmineSink(AffineForOp forOp, SizeType factor,
}
SmallVector<SmallVector<AffineForOp, 8>, 8>
mlir::tile(ArrayRef<AffineForOp> forOps, ArrayRef<uint64_t> sizes,
ArrayRef<AffineForOp> targets) {
mlir::affine::tile(ArrayRef<AffineForOp> forOps, ArrayRef<uint64_t> sizes,
ArrayRef<AffineForOp> targets) {
SmallVector<SmallVector<AffineForOp, 8>, 8> res;
SmallVector<AffineForOp, 8> currentTargets(targets.begin(), targets.end());
for (auto it : llvm::zip(forOps, sizes)) {
@ -1633,9 +1634,9 @@ mlir::tile(ArrayRef<AffineForOp> forOps, ArrayRef<uint64_t> sizes,
return res;
}
SmallVector<AffineForOp, 8> mlir::tile(ArrayRef<AffineForOp> forOps,
ArrayRef<uint64_t> sizes,
AffineForOp target) {
SmallVector<AffineForOp, 8> mlir::affine::tile(ArrayRef<AffineForOp> forOps,
ArrayRef<uint64_t> sizes,
AffineForOp target) {
SmallVector<AffineForOp, 8> res;
for (auto loops : tile(forOps, sizes, ArrayRef<AffineForOp>(target))) {
assert(loops.size() == 1);
@ -1644,7 +1645,7 @@ SmallVector<AffineForOp, 8> mlir::tile(ArrayRef<AffineForOp> forOps,
return res;
}
LogicalResult mlir::coalesceLoops(MutableArrayRef<AffineForOp> loops) {
LogicalResult mlir::affine::coalesceLoops(MutableArrayRef<AffineForOp> loops) {
if (loops.size() < 2)
return success();
@ -1758,8 +1759,9 @@ LogicalResult mlir::coalesceLoops(MutableArrayRef<AffineForOp> loops) {
return success();
}
void mlir::mapLoopToProcessorIds(scf::ForOp forOp, ArrayRef<Value> processorId,
ArrayRef<Value> numProcessors) {
void mlir::affine::mapLoopToProcessorIds(scf::ForOp forOp,
ArrayRef<Value> processorId,
ArrayRef<Value> numProcessors) {
assert(processorId.size() == numProcessors.size());
if (processorId.empty())
return;
@ -2300,11 +2302,11 @@ static bool getFullMemRefAsRegion(Operation *op, unsigned numParamLoopIVs,
return true;
}
LogicalResult mlir::affineDataCopyGenerate(Block::iterator begin,
Block::iterator end,
const AffineCopyOptions &copyOptions,
std::optional<Value> filterMemRef,
DenseSet<Operation *> &copyNests) {
LogicalResult
mlir::affine::affineDataCopyGenerate(Block::iterator begin, Block::iterator end,
const AffineCopyOptions &copyOptions,
std::optional<Value> filterMemRef,
DenseSet<Operation *> &copyNests) {
if (begin == end)
return success();
@ -2490,16 +2492,15 @@ LogicalResult mlir::affineDataCopyGenerate(Block::iterator begin,
// A convenience version of affineDataCopyGenerate for all ops in the body of
// an AffineForOp.
LogicalResult mlir::affineDataCopyGenerate(AffineForOp forOp,
const AffineCopyOptions &copyOptions,
std::optional<Value> filterMemRef,
DenseSet<Operation *> &copyNests) {
LogicalResult mlir::affine::affineDataCopyGenerate(
AffineForOp forOp, const AffineCopyOptions &copyOptions,
std::optional<Value> filterMemRef, DenseSet<Operation *> &copyNests) {
return affineDataCopyGenerate(forOp.getBody()->begin(),
std::prev(forOp.getBody()->end()), copyOptions,
filterMemRef, copyNests);
}
LogicalResult mlir::generateCopyForMemRegion(
LogicalResult mlir::affine::generateCopyForMemRegion(
const MemRefRegion &memrefRegion, Operation *analyzedOp,
const AffineCopyOptions &copyOptions, CopyGenerateResult &result) {
Block *block = analyzedOp->getBlock();
@ -2543,8 +2544,8 @@ gatherLoopsInBlock(Block *block, unsigned currLoopDepth,
}
/// Gathers all AffineForOps in 'func.func' grouped by loop depth.
void mlir::gatherLoops(func::FuncOp func,
std::vector<SmallVector<AffineForOp, 2>> &depthToLoops) {
void mlir::affine::gatherLoops(
func::FuncOp func, std::vector<SmallVector<AffineForOp, 2>> &depthToLoops) {
for (auto &block : func)
gatherLoopsInBlock(&block, /*currLoopDepth=*/0, depthToLoops);
@ -2559,7 +2560,7 @@ void mlir::gatherLoops(func::FuncOp func,
// affine.applys, fold to constant if all result dimensions of the map are
// constant (canonicalizeMapAndOperands below already does this for single
// result bound maps), and use simplifyMap to perform algebraic simplification.
AffineForOp mlir::createCanonicalizedAffineForOp(
AffineForOp mlir::affine::createCanonicalizedAffineForOp(
OpBuilder b, Location loc, ValueRange lbOperands, AffineMap lbMap,
ValueRange ubOperands, AffineMap ubMap, int64_t step) {
SmallVector<Value, 4> lowerOperands(lbOperands);
@ -2716,8 +2717,8 @@ createFullTiles(MutableArrayRef<AffineForOp> inputNest,
}
LogicalResult
mlir::separateFullTiles(MutableArrayRef<AffineForOp> inputNest,
SmallVectorImpl<AffineForOp> *fullTileNest) {
mlir::affine::separateFullTiles(MutableArrayRef<AffineForOp> inputNest,
SmallVectorImpl<AffineForOp> *fullTileNest) {
if (inputNest.empty())
return success();

View File

@ -30,6 +30,7 @@
#define DEBUG_TYPE "affine-utils"
using namespace mlir;
using namespace affine;
using namespace presburger;
namespace {
@ -209,17 +210,18 @@ private:
/// Create a sequence of operations that implement the `expr` applied to the
/// given dimension and symbol values.
mlir::Value mlir::expandAffineExpr(OpBuilder &builder, Location loc,
AffineExpr expr, ValueRange dimValues,
ValueRange symbolValues) {
mlir::Value mlir::affine::expandAffineExpr(OpBuilder &builder, Location loc,
AffineExpr expr,
ValueRange dimValues,
ValueRange symbolValues) {
return AffineApplyExpander(builder, dimValues, symbolValues, loc).visit(expr);
}
/// Create a sequence of operations that implement the `affineMap` applied to
/// the given `operands` (as it it were an AffineApplyOp).
std::optional<SmallVector<Value, 8>>
mlir::expandAffineMap(OpBuilder &builder, Location loc, AffineMap affineMap,
ValueRange operands) {
mlir::affine::expandAffineMap(OpBuilder &builder, Location loc,
AffineMap affineMap, ValueRange operands) {
auto numDims = affineMap.getNumDims();
auto expanded = llvm::to_vector<8>(
llvm::map_range(affineMap.getResults(),
@ -341,8 +343,8 @@ static AffineIfOp hoistAffineIfOp(AffineIfOp ifOp, Operation *hoistOverOp) {
}
LogicalResult
mlir::affineParallelize(AffineForOp forOp,
ArrayRef<LoopReduction> parallelReductions) {
mlir::affine::affineParallelize(AffineForOp forOp,
ArrayRef<LoopReduction> parallelReductions) {
// Fail early if there are iter arguments that are not reductions.
unsigned numReductions = parallelReductions.size();
if (numReductions != forOp.getNumIterOperands())
@ -400,7 +402,7 @@ mlir::affineParallelize(AffineForOp forOp,
}
// Returns success if any hoisting happened.
LogicalResult mlir::hoistAffineIfOp(AffineIfOp ifOp, bool *folded) {
LogicalResult mlir::affine::hoistAffineIfOp(AffineIfOp ifOp, bool *folded) {
// Bail out early if the ifOp returns a result. TODO: Consider how to
// properly support this case.
if (ifOp.getNumResults() != 0)
@ -454,8 +456,9 @@ LogicalResult mlir::hoistAffineIfOp(AffineIfOp ifOp, bool *folded) {
}
// Return the min expr after replacing the given dim.
AffineExpr mlir::substWithMin(AffineExpr e, AffineExpr dim, AffineExpr min,
AffineExpr max, bool positivePath) {
AffineExpr mlir::affine::substWithMin(AffineExpr e, AffineExpr dim,
AffineExpr min, AffineExpr max,
bool positivePath) {
if (e == dim)
return positivePath ? min : max;
if (auto bin = e.dyn_cast<AffineBinaryOpExpr>()) {
@ -480,7 +483,7 @@ AffineExpr mlir::substWithMin(AffineExpr e, AffineExpr dim, AffineExpr min,
return e;
}
void mlir::normalizeAffineParallel(AffineParallelOp op) {
void mlir::affine::normalizeAffineParallel(AffineParallelOp op) {
// Loops with min/max in bounds are not normalized at the moment.
if (op.hasMinMaxBounds())
return;
@ -544,7 +547,8 @@ void mlir::normalizeAffineParallel(AffineParallelOp op) {
ubExprs, op.getContext());
op.setUpperBounds(ranges.getOperands(), newUpperMap);
}
LogicalResult mlir::normalizeAffineFor(AffineForOp op, bool promoteSingleIter) {
LogicalResult mlir::affine::normalizeAffineFor(AffineForOp op,
bool promoteSingleIter) {
if (promoteSingleIter && succeeded(promoteIfSingleIteration(op)))
return success();
@ -701,7 +705,7 @@ static bool mayHaveEffect(Operation *srcMemOp, Operation *destMemOp,
}
template <typename EffectType, typename T>
bool mlir::hasNoInterveningEffect(Operation *start, T memOp) {
bool mlir::affine::hasNoInterveningEffect(Operation *start, T memOp) {
auto isLocallyAllocated = [](Value memref) {
auto *defOp = memref.getDefiningOp();
return defOp && hasSingleEffect<MemoryEffects::Allocate>(defOp, memref);
@ -894,7 +898,7 @@ static LogicalResult forwardStoreToLoad(
// 4. Ensure there is no intermediate operation which could replace the
// value in memory.
if (!mlir::hasNoInterveningEffect<MemoryEffects::Write>(storeOp, loadOp))
if (!affine::hasNoInterveningEffect<MemoryEffects::Write>(storeOp, loadOp))
continue;
// We now have a candidate for forwarding.
@ -921,9 +925,10 @@ static LogicalResult forwardStoreToLoad(
return success();
}
template bool mlir::hasNoInterveningEffect<mlir::MemoryEffects::Read,
mlir::AffineReadOpInterface>(
mlir::Operation *, mlir::AffineReadOpInterface);
template bool
mlir::affine::hasNoInterveningEffect<mlir::MemoryEffects::Read,
affine::AffineReadOpInterface>(
mlir::Operation *, affine::AffineReadOpInterface);
// This attempts to find stores which have no impact on the final result.
// A writing op writeA will be eliminated if there exists an op writeB if
@ -961,7 +966,7 @@ static void findUnusedStore(AffineWriteOpInterface writeA,
// There cannot be an operation which reads from memory between
// the two writes.
if (!mlir::hasNoInterveningEffect<MemoryEffects::Read>(writeA, writeB))
if (!affine::hasNoInterveningEffect<MemoryEffects::Read>(writeA, writeB))
continue;
opsToErase.push_back(writeA);
@ -997,7 +1002,7 @@ static void loadCSE(AffineReadOpInterface loadA,
continue;
// 3. There is no write between loadA and loadB.
if (!mlir::hasNoInterveningEffect<MemoryEffects::Write>(
if (!affine::hasNoInterveningEffect<MemoryEffects::Write>(
loadB.getOperation(), loadA))
continue;
@ -1055,8 +1060,8 @@ static void loadCSE(AffineReadOpInterface loadA,
// currently only eliminates the stores only if no other loads/uses (other
// than dealloc) remain.
//
void mlir::affineScalarReplace(func::FuncOp f, DominanceInfo &domInfo,
PostDominanceInfo &postDomInfo) {
void mlir::affine::affineScalarReplace(func::FuncOp f, DominanceInfo &domInfo,
PostDominanceInfo &postDomInfo) {
// Load op's whose results were replaced by those forwarded from stores.
SmallVector<Operation *, 8> opsToErase;
@ -1109,13 +1114,11 @@ void mlir::affineScalarReplace(func::FuncOp f, DominanceInfo &domInfo,
}
// Perform the replacement in `op`.
LogicalResult mlir::replaceAllMemRefUsesWith(Value oldMemRef, Value newMemRef,
Operation *op,
ArrayRef<Value> extraIndices,
AffineMap indexRemap,
ArrayRef<Value> extraOperands,
ArrayRef<Value> symbolOperands,
bool allowNonDereferencingOps) {
LogicalResult mlir::affine::replaceAllMemRefUsesWith(
Value oldMemRef, Value newMemRef, Operation *op,
ArrayRef<Value> extraIndices, AffineMap indexRemap,
ArrayRef<Value> extraOperands, ArrayRef<Value> symbolOperands,
bool allowNonDereferencingOps) {
unsigned newMemRefRank = newMemRef.getType().cast<MemRefType>().getRank();
(void)newMemRefRank; // unused in opt mode
unsigned oldMemRefRank = oldMemRef.getType().cast<MemRefType>().getRank();
@ -1285,7 +1288,7 @@ LogicalResult mlir::replaceAllMemRefUsesWith(Value oldMemRef, Value newMemRef,
return success();
}
LogicalResult mlir::replaceAllMemRefUsesWith(
LogicalResult mlir::affine::replaceAllMemRefUsesWith(
Value oldMemRef, Value newMemRef, ArrayRef<Value> extraIndices,
AffineMap indexRemap, ArrayRef<Value> extraOperands,
ArrayRef<Value> symbolOperands, Operation *domOpFilter,
@ -1401,7 +1404,7 @@ LogicalResult mlir::replaceAllMemRefUsesWith(
/// all the affine.apply op's supplying operands to this opInst did not have any
/// uses besides this opInst; otherwise returns the list of affine.apply
/// operations created in output argument `sliceOps`.
void mlir::createAffineComputationSlice(
void mlir::affine::createAffineComputationSlice(
Operation *opInst, SmallVectorImpl<AffineApplyOp> *sliceOps) {
// Collect all operands that are results of affine apply ops.
SmallVector<Value, 4> subOperands;
@ -1709,7 +1712,7 @@ static void createNewDynamicSizes(MemRefType oldMemRefType,
}
// TODO: Currently works for static memrefs with a single layout map.
LogicalResult mlir::normalizeMemRef(memref::AllocOp *allocOp) {
LogicalResult mlir::affine::normalizeMemRef(memref::AllocOp *allocOp) {
MemRefType memrefType = allocOp->getType();
OpBuilder b(*allocOp);
@ -1767,8 +1770,8 @@ LogicalResult mlir::normalizeMemRef(memref::AllocOp *allocOp) {
return success();
}
MemRefType mlir::normalizeMemRefType(MemRefType memrefType,
unsigned numSymbolicOperands) {
MemRefType mlir::affine::normalizeMemRefType(MemRefType memrefType,
unsigned numSymbolicOperands) {
unsigned rank = memrefType.getRank();
if (rank == 0)
return memrefType;
@ -1848,13 +1851,15 @@ MemRefType mlir::normalizeMemRefType(MemRefType memrefType,
return newMemRefType;
}
DivModValue mlir::getDivMod(OpBuilder &b, Location loc, Value lhs, Value rhs) {
DivModValue mlir::affine::getDivMod(OpBuilder &b, Location loc, Value lhs,
Value rhs) {
DivModValue result;
AffineExpr d0, d1;
bindDims(b.getContext(), d0, d1);
result.quotient =
makeComposedAffineApply(b, loc, d0.floorDiv(d1), {lhs, rhs});
result.remainder = makeComposedAffineApply(b, loc, d0 % d1, {lhs, rhs});
affine::makeComposedAffineApply(b, loc, d0.floorDiv(d1), {lhs, rhs});
result.remainder =
affine::makeComposedAffineApply(b, loc, d0 % d1, {lhs, rhs});
return result;
}
@ -1871,9 +1876,9 @@ static FailureOr<OpFoldResult> getIndexProduct(OpBuilder &b, Location loc,
return result;
}
FailureOr<SmallVector<Value>> mlir::delinearizeIndex(OpBuilder &b, Location loc,
Value linearIndex,
ArrayRef<Value> basis) {
FailureOr<SmallVector<Value>>
mlir::affine::delinearizeIndex(OpBuilder &b, Location loc, Value linearIndex,
ArrayRef<Value> basis) {
unsigned numDims = basis.size();
SmallVector<Value> divisors;

View File

@ -12,8 +12,9 @@
#include "mlir/IR/PatternMatch.h"
using namespace mlir;
using namespace affine;
LogicalResult mlir::mergeOffsetsSizesAndStrides(
LogicalResult mlir::affine::mergeOffsetsSizesAndStrides(
OpBuilder &builder, Location loc, ArrayRef<OpFoldResult> producerOffsets,
ArrayRef<OpFoldResult> producerSizes,
ArrayRef<OpFoldResult> producerStrides,
@ -58,7 +59,7 @@ LogicalResult mlir::mergeOffsetsSizesAndStrides(
return success();
}
LogicalResult mlir::mergeOffsetsSizesAndStrides(
LogicalResult mlir::affine::mergeOffsetsSizesAndStrides(
OpBuilder &builder, Location loc, OffsetSizeAndStrideOpInterface producer,
OffsetSizeAndStrideOpInterface consumer,
const llvm::SmallBitVector &droppedProducerDims,
@ -77,7 +78,7 @@ LogicalResult mlir::mergeOffsetsSizesAndStrides(
combinedOffsets, combinedSizes, combinedStrides);
}
void mlir::resolveIndicesIntoOpWithOffsetsAndStrides(
void mlir::affine::resolveIndicesIntoOpWithOffsetsAndStrides(
RewriterBase &rewriter, Location loc,
ArrayRef<OpFoldResult> mixedSourceOffsets,
ArrayRef<OpFoldResult> mixedSourceStrides,
@ -109,7 +110,7 @@ void mlir::resolveIndicesIntoOpWithOffsetsAndStrides(
}
}
void mlir::resolveSizesIntoOpWithSizes(
void mlir::affine::resolveSizesIntoOpWithSizes(
ArrayRef<OpFoldResult> sourceSizes, ArrayRef<OpFoldResult> destSizes,
const llvm::SmallBitVector &rankReducedSourceDims,
SmallVectorImpl<OpFoldResult> &resolvedSizes) {

View File

@ -61,7 +61,7 @@ static Value buildLinearThreadId(RewriterBase &rewriter, Location loc,
rewriter.create<ThreadIdOp>(loc, indexType, Dimension::z).getResult()};
threadsAndWorkGroups.push_back(blockDimsOfr[0]);
threadsAndWorkGroups.push_back(blockDimsOfr[1]);
OpFoldResult ofr = makeComposedFoldedAffineApply(
OpFoldResult ofr = affine::makeComposedFoldedAffineApply(
rewriter, loc, tx + ty * BDX + tz * BDX * BDY, threadsAndWorkGroups);
return getValueOrCreateConstantIndexOp(rewriter, loc, ofr);
}
@ -137,7 +137,7 @@ struct GpuWarpIdBuilder : public GpuIdBuilder {
// `forallMappingSizes`.
Value linearId = buildLinearThreadId(rewriter, loc, this->blockDimsOfr);
AffineExpr d0 = getAffineDimExpr(0, rewriter.getContext());
OpFoldResult warpIdOfr = makeComposedFoldedAffineApply(
OpFoldResult warpIdOfr = affine::makeComposedFoldedAffineApply(
rewriter, loc, d0.floorDiv(kWarpSize), {linearId});
Value warpId = getValueOrCreateConstantIndexOp(rewriter, loc, warpIdOfr);
// Sizes in [x, y, z] -> [z, y x] order to properly compute strides in
@ -149,7 +149,8 @@ struct GpuWarpIdBuilder : public GpuIdBuilder {
SmallVector<Value> ids;
// Reverse back to be in [x, y, z] order.
for (AffineExpr e : llvm::reverse(delinearizingExprs))
ids.push_back(makeComposedAffineApply(rewriter, loc, e, warpId));
ids.push_back(
affine::makeComposedAffineApply(rewriter, loc, e, warpId));
// clang-format off
LDBG("----linearId: " << linearId);
@ -204,7 +205,8 @@ struct GpuLinearIdBuilder : public GpuIdBuilder {
SmallVector<Value> ids;
// Reverse back to be in [x, y, z] order.
for (AffineExpr e : llvm::reverse(delinearizingExprs))
ids.push_back(makeComposedAffineApply(rewriter, loc, e, linearId));
ids.push_back(
affine::makeComposedAffineApply(rewriter, loc, e, linearId));
// clang-format off
LLVM_DEBUG(llvm::interleaveComma(reverseBasisSizes,

View File

@ -81,8 +81,8 @@ static void insertCopyLoops(ImplicitLocOpBuilder &b, Value from, Value to) {
GPUDialect::getNumWorkgroupDimensions())))) {
Value v = en.value();
auto loop = cast<scf::ForOp>(v.getParentRegion()->getParentOp());
mapLoopToProcessorIds(loop, {threadIds[en.index()]},
{blockDims[en.index()]});
affine::mapLoopToProcessorIds(loop, {threadIds[en.index()]},
{blockDims[en.index()]});
}
}

View File

@ -636,7 +636,7 @@ LinalgOp::reifyResultShapes(OpBuilder &b,
Location loc = getOperation()->getLoc();
IRRewriter rewriter(b);
SmallVector<OpFoldResult> allResultDimValues =
makeComposedFoldedMultiResultAffineApply(
affine::makeComposedFoldedMultiResultAffineApply(
rewriter, loc, resultShapesFromInputShapesMap,
createFlatListOfOperandDims(b, loc));
int64_t pos = 0;

View File

@ -580,7 +580,7 @@ struct FoldInsertPadIntoFill : public OpRewritePattern<tensor::InsertSliceOp> {
// plus low padding sizes.
SmallVector<OpFoldResult, 4> newOffsets;
for (const auto &p : llvm::zip(lowPads, oldOffsets)) {
newOffsets.push_back(makeComposedFoldedAffineApply(
newOffsets.push_back(affine::makeComposedFoldedAffineApply(
rewriter, loc, addMap, {std::get<0>(p), std::get<1>(p)}));
}

View File

@ -1169,8 +1169,8 @@ DiagnosedSilenceableFailure transform::MultiTileSizesOp::applyToOne(
AffineExpr s0 = builder.getAffineSymbolExpr(0);
AffineExpr s1 = builder.getAffineSymbolExpr(1);
Operation *splitPoint =
makeComposedAffineApply(builder, target.getLoc(), s0 * s1,
{spec->lowTileSize, spec->lowTripCount});
affine::makeComposedAffineApply(builder, target.getLoc(), s0 * s1,
{spec->lowTileSize, spec->lowTripCount});
Operation *lowTileSize = spec->lowTileSize.getDefiningOp();
Operation *highTileSize = spec->highTileSize.getDefiningOp();
assert(lowTileSize && highTileSize && splitPoint &&
@ -1420,7 +1420,7 @@ packMatmulGreedily(RewriterBase &rewriter, LinalgOp linalgOp,
AffineExpr d0, s0;
bindDims(rewriter.getContext(), d0);
bindSymbols(rewriter.getContext(), s0);
adjustedPackedSizes.push_back(makeComposedFoldedAffineApply(
adjustedPackedSizes.push_back(affine::makeComposedFoldedAffineApply(
rewriter, genericOp->getLoc(), d0.ceilDiv(s0) * s0,
{loopRanges[adjustedPackedSizes.size()].size,
rewriter.getIndexAttr(paddedSizesNextMultipleOf[i])}));
@ -1983,8 +1983,8 @@ transform::ScalarizeOp::applyToOne(LinalgOp target,
TrackingListener listener(state, *this);
IRRewriter rewriter(getContext(), &listener);
SmallVector<OpFoldResult> shapeSizes =
makeComposedFoldedMultiResultAffineApply(rewriter, loc, map,
allShapeSizes);
affine::makeComposedFoldedMultiResultAffineApply(rewriter, loc, map,
allShapeSizes);
// If the shape size is dynamic, tile by 1.
// Otherwise, do not tile (i.e. tile size 0).
for (OpFoldResult shapeSize : shapeSizes) {
@ -3351,7 +3351,7 @@ public:
void init() {
declareDependentDialect<pdl::PDLDialect>();
declareDependentDialect<LinalgDialect>();
declareGeneratedDialect<AffineDialect>();
declareGeneratedDialect<affine::AffineDialect>();
declareGeneratedDialect<arith::ArithDialect>();
declareGeneratedDialect<scf::SCFDialect>();
declareGeneratedDialect<vector::VectorDialect>();

View File

@ -96,7 +96,7 @@ struct BubbleUpExtractSliceOpPattern
linalgOp, "failed to get loops map from shape sizes");
}
SmallVector<OpFoldResult> sizeBounds =
makeComposedFoldedMultiResultAffineApply(
affine::makeComposedFoldedMultiResultAffineApply(
rewriter, linalgLoc, shapeSizesToLoopsMap, allShapeSizes);
// The offsets and sizes from the slice operation only give you the tile

View File

@ -55,7 +55,7 @@ static SmallVector<Value> unrollIndex(OpBuilder &b, Location loc, Value index,
for (int64_t f : factors)
basis.push_back(b.create<arith::ConstantOp>(loc, b.getIndexAttr(f)));
FailureOr<SmallVector<Value>> multiIndex =
delinearizeIndex(b, loc, index, basis);
affine::delinearizeIndex(b, loc, index, basis);
assert(!failed(multiIndex) && "Failed to linearize img2col index");
return *multiIndex;
}
@ -68,7 +68,8 @@ static Value getConvolvedIndex(OpBuilder &b, Location loc, Value oIndex,
AffineExpr oExpr, fExpr;
bindSymbols(b.getContext(), oExpr, fExpr);
AffineMap convMap = AffineMap::get(0, 2, stride * oExpr + fExpr);
return makeComposedAffineApply(b, loc, convMap, ValueRange{oIndex, fIndex});
return affine::makeComposedAffineApply(b, loc, convMap,
ValueRange{oIndex, fIndex});
}
FailureOr<std::pair<Operation *, Operation *>>

View File

@ -111,8 +111,8 @@ static SmallVector<OpFoldResult> getGenericOpLoopRange(OpBuilder &b,
cast<LinalgOp>(op.getOperation()).createFlatListOfOperandDims(b, loc);
AffineMap map = op.getShapesToLoopsMap();
IRRewriter rewriter(b);
return makeComposedFoldedMultiResultAffineApply(rewriter, loc, map,
allShapesSizes);
return affine::makeComposedFoldedMultiResultAffineApply(rewriter, loc, map,
allShapesSizes);
}
/// Helper method to permute the list of `values` based on the `map`.

View File

@ -179,7 +179,7 @@ static void generateFusedElementwiseOpRegion(
});
for (IndexOp indexOp :
llvm::make_early_inc_range(producerBlock.getOps<IndexOp>())) {
Value newIndex = rewriter.create<mlir::AffineApplyOp>(
Value newIndex = rewriter.create<affine::AffineApplyOp>(
producer.getLoc(),
consumerToProducerLoopsMap.getSubMap(indexOp.getDim()), fusedIndices);
mapper.map(indexOp.getResult(), newIndex);
@ -719,7 +719,7 @@ static void updateExpandedGenericOpRegion(PatternRewriter &rewriter,
assert(!ShapedType::isDynamic(std::get<0>(it)));
AffineExpr idx, acc;
bindDims(rewriter.getContext(), idx, acc);
newIndex = rewriter.create<AffineApplyOp>(
newIndex = rewriter.create<affine::AffineApplyOp>(
indexOp.getLoc(), idx + acc * std::get<0>(it),
ValueRange{std::get<1>(it), newIndex});
}
@ -1871,7 +1871,7 @@ struct LinalgElementwiseOpFusionPass
populateFoldReshapeOpsByExpansionPatterns(patterns, defaultControlFn);
// General canonicalization patterns.
AffineApplyOp::getCanonicalizationPatterns(patterns, context);
affine::AffineApplyOp::getCanonicalizationPatterns(patterns, context);
GenericOp::getCanonicalizationPatterns(patterns, context);
tensor::ExpandShapeOp::getCanonicalizationPatterns(patterns, context);
tensor::CollapseShapeOp::getCanonicalizationPatterns(patterns, context);

View File

@ -462,7 +462,7 @@ HoistPaddingAnalysis::getHoistedPackedTensorSizes(RewriterBase &rewriter,
// of the enclosing loops.
for (auto forOp : packingLoops) {
// Compute an upper bound `ubVal` for the upper bound of `forOp`.
FailureOr<OpFoldResult> loopUb = reifyIndexValueBound(
FailureOr<OpFoldResult> loopUb = affine::reifyIndexValueBound(
rewriter, loc, presburger::BoundType::UB, forOp.getUpperBound(),
/*stopCondition=*/
[&](Value v, std::optional<int64_t> d) {
@ -472,7 +472,8 @@ HoistPaddingAnalysis::getHoistedPackedTensorSizes(RewriterBase &rewriter,
Operation *op = v.getDefiningOp();
if (!op)
return true;
return !isa<AffineMinOp, AffineMaxOp, AffineApplyOp>(op);
return !isa<affine::AffineMinOp, affine::AffineMaxOp,
affine::AffineApplyOp>(op);
},
/*closedUB=*/true);
assert(succeeded(loopUb) && "could not get upper bound");
@ -485,7 +486,7 @@ HoistPaddingAnalysis::getHoistedPackedTensorSizes(RewriterBase &rewriter,
AffineExpr lb, ub, step;
bindDims(rewriter.getContext(), lb, ub);
bindSymbols(rewriter.getContext(), step);
Value res = rewriter.createOrFold<AffineApplyOp>(
Value res = rewriter.createOrFold<affine::AffineApplyOp>(
loc, (ub - lb).ceilDiv(step),
ValueRange{forOp.getLowerBound(), ubVal,
cast<scf::ForOp>(forOp).getStep()});
@ -519,7 +520,7 @@ static Value buildLoopIterationCount(RewriterBase &rewriter, scf::ForOp outer,
Value ivVal = forOp.getInductionVar(), lbVal = forOp.getLowerBound(),
stepVal = forOp.getStep();
auto loc = forOp->getLoc();
return rewriter.createOrFold<AffineApplyOp>(
return rewriter.createOrFold<affine::AffineApplyOp>(
loc, (iv - lb).ceilDiv(step), ValueRange{ivVal, lbVal, stepVal});
}

View File

@ -94,7 +94,7 @@ void mlir::linalg::hoistRedundantVectorTransfers(func::FuncOp func) {
auto loop = dyn_cast<LoopLikeOpInterface>(transferRead->getParentOp());
LLVM_DEBUG(DBGS() << "Parent op: " << *transferRead->getParentOp()
<< "\n");
if (!isa_and_nonnull<scf::ForOp, AffineForOp>(loop))
if (!isa_and_nonnull<scf::ForOp, affine::AffineForOp>(loop))
return WalkResult::advance();
LLVM_DEBUG(DBGS() << "Candidate read: " << *transferRead.getOperation()
@ -200,7 +200,7 @@ void mlir::linalg::hoistRedundantVectorTransfers(func::FuncOp func) {
// the walk.
return WalkResult::interrupt();
})
.Case<AffineForOp>([&](AffineForOp affineForOp) {
.Case<affine::AffineForOp>([&](affine::AffineForOp affineForOp) {
auto newForOp = replaceForOpWithNewYields(
b, affineForOp, transferRead.getVector(),
SmallVector<Value>{transferWrite.getVector()},

View File

@ -96,7 +96,7 @@ mlir::linalg::interchangeGenericOp(RewriterBase &rewriter, GenericOp genericOp,
std::back_inserter(allIndices), [&](uint64_t dim) {
return rewriter.create<IndexOp>(indexOp->getLoc(), dim);
});
rewriter.replaceOpWithNewOp<AffineApplyOp>(
rewriter.replaceOpWithNewOp<affine::AffineApplyOp>(
indexOp, permutationMap.getSubMap(indexOp.getDim()), allIndices);
}
}

View File

@ -49,8 +49,8 @@ static SmallVector<Value> makeCanonicalAffineApplies(OpBuilder &b, Location loc,
for (auto e : map.getResults()) {
auto exprMap = AffineMap::get(dims, map.getNumSymbols(), e);
SmallVector<Value> operands(vals.begin(), vals.end());
canonicalizeMapAndOperands(&exprMap, &operands);
res.push_back(b.create<AffineApplyOp>(loc, exprMap, operands));
affine::canonicalizeMapAndOperands(&exprMap, &operands);
res.push_back(b.create<affine::AffineApplyOp>(loc, exprMap, operands));
}
return res;
}
@ -189,7 +189,7 @@ static void replaceIndexOpsByInductionVariables(RewriterBase &rewriter,
.Case([&](scf::ForOp forOp) {
allIvs.push_back(forOp.getInductionVar());
})
.Case([&](AffineForOp affineForOp) {
.Case([&](affine::AffineForOp affineForOp) {
allIvs.push_back(affineForOp.getInductionVar());
})
.Default([&](Operation *op) { assert(false && "unexpected op"); });
@ -208,10 +208,12 @@ static void replaceIndexOpsByInductionVariables(RewriterBase &rewriter,
template <typename LoopTy>
static FailureOr<LinalgLoops> linalgOpToLoopsImpl(RewriterBase &rewriter,
LinalgOp linalgOp) {
using LoadOpTy = std::conditional_t<std::is_same<LoopTy, AffineForOp>::value,
AffineLoadOp, memref::LoadOp>;
using StoreOpTy = std::conditional_t<std::is_same<LoopTy, AffineForOp>::value,
AffineStoreOp, memref::StoreOp>;
using LoadOpTy =
std::conditional_t<std::is_same<LoopTy, affine::AffineForOp>::value,
affine::AffineLoadOp, memref::LoadOp>;
using StoreOpTy =
std::conditional_t<std::is_same<LoopTy, affine::AffineForOp>::value,
affine::AffineStoreOp, memref::StoreOp>;
// The flattened loopToOperandRangesMaps is expected to be an invertible
// permutation map (which is asserted in the inverse calculation).
@ -284,11 +286,11 @@ public:
/// other cases, it is replaced by its unique operand.
struct FoldAffineOp : public RewritePattern {
FoldAffineOp(MLIRContext *context)
: RewritePattern(AffineApplyOp::getOperationName(), 0, context) {}
: RewritePattern(affine::AffineApplyOp::getOperationName(), 0, context) {}
LogicalResult matchAndRewrite(Operation *op,
PatternRewriter &rewriter) const override {
AffineApplyOp affineApplyOp = cast<AffineApplyOp>(op);
auto affineApplyOp = cast<affine::AffineApplyOp>(op);
auto map = affineApplyOp.getAffineMap();
if (map.getNumResults() != 1 || map.getNumInputs() > 1)
return failure();
@ -316,7 +318,7 @@ static void lowerLinalgToLoopsImpl(func::FuncOp funcOp) {
patterns.add<LinalgRewritePattern<LoopType>>(context);
memref::DimOp::getCanonicalizationPatterns(patterns, context);
tensor::DimOp::getCanonicalizationPatterns(patterns, context);
AffineApplyOp::getCanonicalizationPatterns(patterns, context);
affine::AffineApplyOp::getCanonicalizationPatterns(patterns, context);
patterns.add<FoldAffineOp>(context);
// Just apply the patterns greedily.
(void)applyPatternsAndFoldGreedily(funcOp, std::move(patterns));
@ -328,7 +330,7 @@ struct LowerToAffineLoops
registry.insert<memref::MemRefDialect>();
}
void runOnOperation() override {
lowerLinalgToLoopsImpl<AffineForOp>(getOperation());
lowerLinalgToLoopsImpl<affine::AffineForOp>(getOperation());
}
};
@ -368,7 +370,7 @@ mlir::createConvertLinalgToAffineLoopsPass() {
/// Emits a loop nest of `affine.for` with the proper body for `linalgOp`.
FailureOr<LinalgLoops>
mlir::linalg::linalgOpToAffineLoops(RewriterBase &rewriter, LinalgOp linalgOp) {
return linalgOpToLoopsImpl<AffineForOp>(rewriter, linalgOp);
return linalgOpToLoopsImpl<affine::AffineForOp>(rewriter, linalgOp);
}
/// Emits a loop nest of `scf.for` with the proper body for `linalgOp`.

View File

@ -81,14 +81,14 @@ linalg::splitOp(RewriterBase &rewriter, TilingInterface op, unsigned dimension,
// Adjust the split point so that it doesn't overflow the size.
AffineExpr d0, d1, d2;
bindDims(rewriter.getContext(), d0, d1, d2);
OpFoldResult minSplitPoint = makeComposedFoldedAffineMin(
OpFoldResult minSplitPoint = affine::makeComposedFoldedAffineMin(
rewriter, op.getLoc(),
AffineMap::inferFromExprList(ArrayRef<AffineExpr>{d0, d1 + d2}).front(),
{splitPoint, offsets[dimension], sizes[dimension]});
// Compute the size of the second part. Return early if the second part would
// have an empty iteration space.
OpFoldResult remainingSize = makeComposedFoldedAffineApply(
OpFoldResult remainingSize = affine::makeComposedFoldedAffineApply(
rewriter, op.getLoc(), d0 + d1 - d2,
{iterationSpace[dimension].offset, iterationSpace[dimension].size,
minSplitPoint});
@ -121,7 +121,7 @@ linalg::splitOp(RewriterBase &rewriter, TilingInterface op, unsigned dimension,
});
// Create the second part.
OpFoldResult totalOffset = makeComposedFoldedAffineApply(
OpFoldResult totalOffset = affine::makeComposedFoldedAffineApply(
rewriter, op.getLoc(), d0 + d1, {offsets[dimension], minSplitPoint});
SmallVector<Value> secondResults;
TilingInterface secondPart =

View File

@ -39,6 +39,7 @@ namespace mlir {
} // namespace mlir
using namespace mlir;
using namespace mlir::affine;
using namespace mlir::linalg;
using namespace mlir::scf;
@ -178,7 +179,7 @@ mlir::linalg::computeMultiTileSizes(OpBuilder &builder, LinalgOp op,
AffineExpr s1 = b.getAffineSymbolExpr(1);
AffineExpr s2 = b.getAffineSymbolExpr(2);
auto apply = [&](AffineExpr expr, ValueRange values) -> Value {
return makeComposedAffineApply(b, b.getLoc(), expr, values);
return affine::makeComposedAffineApply(b, b.getLoc(), expr, values);
};
Value a = apply(s0.floorDiv(s1), {tripCount, divisorValue});
Value t = apply((s0 + s1 - 1).floorDiv(s1), {targetSizeValue, divisorValue});
@ -228,7 +229,7 @@ static bool canOmitTileOffsetInBoundsCheck(OpFoldResult tileSize,
/// Build an `affine_max` of all the `vals`.
static OpFoldResult buildMax(OpBuilder &b, Location loc,
ArrayRef<OpFoldResult> vals) {
return makeComposedFoldedAffineMax(
return affine::makeComposedFoldedAffineMax(
b, loc, AffineMap::getMultiDimIdentityMap(vals.size(), loc.getContext()),
vals);
}
@ -236,7 +237,7 @@ static OpFoldResult buildMax(OpBuilder &b, Location loc,
/// Build an `affine_min` of all the `vals`.
static OpFoldResult buildMin(OpBuilder &b, Location loc,
ArrayRef<OpFoldResult> vals) {
return makeComposedFoldedAffineMin(
return affine::makeComposedFoldedAffineMin(
b, loc, AffineMap::getMultiDimIdentityMap(vals.size(), loc.getContext()),
vals);
}
@ -968,10 +969,10 @@ mlir::linalg::getLinalgTilingCanonicalizationPatterns(MLIRContext *ctx) {
void mlir::linalg::populateLinalgTilingCanonicalizationPatterns(
RewritePatternSet &patterns) {
auto *ctx = patterns.getContext();
AffineApplyOp::getCanonicalizationPatterns(patterns, ctx);
AffineForOp::getCanonicalizationPatterns(patterns, ctx);
AffineMinOp::getCanonicalizationPatterns(patterns, ctx);
AffineMaxOp::getCanonicalizationPatterns(patterns, ctx);
affine::AffineApplyOp::getCanonicalizationPatterns(patterns, ctx);
affine::AffineForOp::getCanonicalizationPatterns(patterns, ctx);
affine::AffineMinOp::getCanonicalizationPatterns(patterns, ctx);
affine::AffineMaxOp::getCanonicalizationPatterns(patterns, ctx);
arith::ConstantIndexOp::getCanonicalizationPatterns(patterns, ctx);
memref::SubViewOp::getCanonicalizationPatterns(patterns, ctx);

Some files were not shown because too many files have changed in this diff Show More