forked from OSchip/llvm-project
[MLIR][NFC] Rename MemRefDataFlow -> AffineScalarReplacement
NFC. Rename MemRefDataFlow -> AffineScalarReplacement and move to AffineTransforms library. Pass command line rename: -memref-dataflow-opt -> affine-scalrep. Update outdated pass documentation. Rationale: https://llvm.discourse.group/t/move-and-rename-memref-dataflow-opt-lib-transforms-lib-affine-dialect-transforms/3640 Differential Revision: https://reviews.llvm.org/D104190
This commit is contained in:
parent
8e93aa304b
commit
88e4aae57d
|
@ -15,6 +15,7 @@
|
|||
#include "toy/Parser.h"
|
||||
#include "toy/Passes.h"
|
||||
|
||||
#include "mlir/Dialect/Affine/Passes.h"
|
||||
#include "mlir/IR/AsmState.h"
|
||||
#include "mlir/IR/BuiltinOps.h"
|
||||
#include "mlir/IR/MLIRContext.h"
|
||||
|
@ -146,7 +147,7 @@ int dumpMLIR() {
|
|||
// Add optimizations if enabled.
|
||||
if (enableOpt) {
|
||||
optPM.addPass(mlir::createLoopFusionPass());
|
||||
optPM.addPass(mlir::createMemRefDataFlowOptPass());
|
||||
optPM.addPass(mlir::createAffineScalarReplacementPass());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "toy/Parser.h"
|
||||
#include "toy/Passes.h"
|
||||
|
||||
#include "mlir/Dialect/Affine/Passes.h"
|
||||
#include "mlir/ExecutionEngine/ExecutionEngine.h"
|
||||
#include "mlir/ExecutionEngine/OptUtils.h"
|
||||
#include "mlir/IR/AsmState.h"
|
||||
|
@ -161,7 +162,7 @@ int loadAndProcessMLIR(mlir::MLIRContext &context,
|
|||
// Add optimizations if enabled.
|
||||
if (enableOpt) {
|
||||
optPM.addPass(mlir::createLoopFusionPass());
|
||||
optPM.addPass(mlir::createMemRefDataFlowOptPass());
|
||||
optPM.addPass(mlir::createAffineScalarReplacementPass());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "toy/Parser.h"
|
||||
#include "toy/Passes.h"
|
||||
|
||||
#include "mlir/Dialect/Affine/Passes.h"
|
||||
#include "mlir/ExecutionEngine/ExecutionEngine.h"
|
||||
#include "mlir/ExecutionEngine/OptUtils.h"
|
||||
#include "mlir/IR/AsmState.h"
|
||||
|
@ -162,7 +163,7 @@ int loadAndProcessMLIR(mlir::MLIRContext &context,
|
|||
// Add optimizations if enabled.
|
||||
if (enableOpt) {
|
||||
optPM.addPass(mlir::createLoopFusionPass());
|
||||
optPM.addPass(mlir::createMemRefDataFlowOptPass());
|
||||
optPM.addPass(mlir::createAffineScalarReplacementPass());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -48,6 +48,11 @@ std::unique_ptr<OperationPass<FuncOp>> createAffineDataCopyGenerationPass(
|
|||
/// Overload relying on pass options for initialization.
|
||||
std::unique_ptr<OperationPass<FuncOp>> createAffineDataCopyGenerationPass();
|
||||
|
||||
/// Creates a pass to replace affine memref accesses by scalars using store to
|
||||
/// load forwarding and redundant load elimination; consequently also eliminate
|
||||
/// dead allocs.
|
||||
std::unique_ptr<OperationPass<FuncOp>> createAffineScalarReplacementPass();
|
||||
|
||||
/// Creates a pass to perform tiling on loop nests.
|
||||
std::unique_ptr<OperationPass<FuncOp>>
|
||||
createLoopTilingPass(uint64_t cacheSizeBytes);
|
||||
|
|
|
@ -94,6 +94,52 @@ def AffineLoopUnrollAndJam : FunctionPass<"affine-loop-unroll-jam"> {
|
|||
];
|
||||
}
|
||||
|
||||
def AffineScalarReplacement : FunctionPass<"affine-scalrep"> {
|
||||
let summary = "Replace affine memref acceses by scalars by forwarding stores "
|
||||
"to loads and eliminating redundant loads";
|
||||
let description = [{
|
||||
This pass performs store to load forwarding and redundant load elimination
|
||||
for affine memref accesses and potentially eliminates the entire memref
|
||||
if all its accesses are forwarded.
|
||||
|
||||
Input
|
||||
|
||||
```mlir
|
||||
func @store_load_affine_apply() -> memref<10x10xf32> {
|
||||
%cf7 = constant 7.0 : f32
|
||||
%m = alloc() : memref<10x10xf32>
|
||||
affine.for %i0 = 0 to 10 {
|
||||
affine.for %i1 = 0 to 10 {
|
||||
affine.store %cf7, %m[%i0, %i1] : memref<10x10xf32>
|
||||
%v0 = affine.load %m[%i0, %i1] : memref<10x10xf32>
|
||||
%v1 = addf %v0, %v0 : f32
|
||||
}
|
||||
}
|
||||
return %m : memref<10x10xf32>
|
||||
}
|
||||
```
|
||||
|
||||
Output
|
||||
|
||||
```mlir
|
||||
module {
|
||||
func @store_load_affine_apply() -> memref<10x10xf32> {
|
||||
%cst = constant 7.000000e+00 : f32
|
||||
%0 = alloc() : memref<10x10xf32>
|
||||
affine.for %arg0 = 0 to 10 {
|
||||
affine.for %arg1 = 0 to 10 {
|
||||
affine.store %cst, %0[%arg0, %arg1] : memref<10x10xf32>
|
||||
%1 = addf %cst, %cst : f32
|
||||
}
|
||||
}
|
||||
return %0 : memref<10x10xf32>
|
||||
}
|
||||
}
|
||||
```
|
||||
}];
|
||||
let constructor = "mlir::createAffineScalarReplacementPass()";
|
||||
}
|
||||
|
||||
def AffineVectorize : FunctionPass<"affine-super-vectorize"> {
|
||||
let summary = "Vectorize to a target independent n-D vector abstraction";
|
||||
let constructor = "mlir::createSuperVectorizePass()";
|
||||
|
|
|
@ -96,10 +96,6 @@ std::unique_ptr<OperationPass<FuncOp>> createLoopCoalescingPass();
|
|||
/// variables into another ParallelLoop over less than N induction variables.
|
||||
std::unique_ptr<Pass> createParallelLoopCollapsingPass();
|
||||
|
||||
/// Creates a pass to perform optimizations relying on memref dataflow such as
|
||||
/// store to load forwarding, elimination of dead stores, and dead allocs.
|
||||
std::unique_ptr<OperationPass<FuncOp>> createMemRefDataFlowOptPass();
|
||||
|
||||
/// Creates a pass to strip debug information from a function.
|
||||
std::unique_ptr<Pass> createStripDebugInfoPass();
|
||||
|
||||
|
|
|
@ -480,51 +480,6 @@ def LoopInvariantCodeMotion : Pass<"loop-invariant-code-motion"> {
|
|||
let constructor = "mlir::createLoopInvariantCodeMotionPass()";
|
||||
}
|
||||
|
||||
def MemRefDataFlowOpt : FunctionPass<"memref-dataflow-opt"> {
|
||||
let summary = "Perform store/load forwarding for memrefs";
|
||||
let description = [{
|
||||
This pass performs store to load forwarding for memref's to eliminate memory
|
||||
accesses and potentially the entire memref if all its accesses are
|
||||
forwarded.
|
||||
|
||||
Input
|
||||
|
||||
```mlir
|
||||
func @store_load_affine_apply() -> memref<10x10xf32> {
|
||||
%cf7 = constant 7.0 : f32
|
||||
%m = alloc() : memref<10x10xf32>
|
||||
affine.for %i0 = 0 to 10 {
|
||||
affine.for %i1 = 0 to 10 {
|
||||
affine.store %cf7, %m[%i0, %i1] : memref<10x10xf32>
|
||||
%v0 = affine.load %m[%i0, %i1] : memref<10x10xf32>
|
||||
%v1 = addf %v0, %v0 : f32
|
||||
}
|
||||
}
|
||||
return %m : memref<10x10xf32>
|
||||
}
|
||||
```
|
||||
|
||||
Output
|
||||
|
||||
```mlir
|
||||
module {
|
||||
func @store_load_affine_apply() -> memref<10x10xf32> {
|
||||
%cst = constant 7.000000e+00 : f32
|
||||
%0 = alloc() : memref<10x10xf32>
|
||||
affine.for %arg0 = 0 to 10 {
|
||||
affine.for %arg1 = 0 to 10 {
|
||||
affine.store %cst, %0[%arg0, %arg1] : memref<10x10xf32>
|
||||
%1 = addf %cst, %cst : f32
|
||||
}
|
||||
}
|
||||
return %0 : memref<10x10xf32>
|
||||
}
|
||||
}
|
||||
```
|
||||
}];
|
||||
let constructor = "mlir::createMemRefDataFlowOptPass()";
|
||||
}
|
||||
|
||||
def NormalizeMemRefs : Pass<"normalize-memrefs", "ModuleOp"> {
|
||||
let summary = "Normalize memrefs";
|
||||
let description = [{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//===- MemRefDataFlowOpt.cpp - MemRef DataFlow Optimization pass ------ -*-===//
|
||||
//===- AffineScalarReplacement.cpp - Affine scalar replacement pass -------===//
|
||||
//
|
||||
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||
// See https://llvm.org/LICENSE.txt for license information.
|
||||
|
@ -6,8 +6,8 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file implements a pass to forward memref stores to loads, thereby
|
||||
// potentially getting rid of intermediate memref's entirely. It also removes
|
||||
// This file implements a pass to forward affine memref stores to loads, thereby
|
||||
// potentially getting rid of intermediate memrefs entirely. It also removes
|
||||
// redundant loads.
|
||||
// TODO: In the future, similar techniques could be used to eliminate
|
||||
// dead memref store's and perform more complex forwarding when support for
|
||||
|
@ -18,11 +18,11 @@
|
|||
#include "mlir/Analysis/AffineAnalysis.h"
|
||||
#include "mlir/Analysis/Utils.h"
|
||||
#include "mlir/Dialect/Affine/IR/AffineOps.h"
|
||||
#include "mlir/Dialect/Affine/Passes.h"
|
||||
#include "mlir/Dialect/MemRef/IR/MemRef.h"
|
||||
#include "mlir/Dialect/StandardOps/IR/Ops.h"
|
||||
#include "mlir/IR/Dominance.h"
|
||||
#include "mlir/Support/LogicalResult.h"
|
||||
#include "mlir/Transforms/Passes.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include <algorithm>
|
||||
|
||||
|
@ -66,7 +66,8 @@ namespace {
|
|||
// currently only eliminates the stores only if no other loads/uses (other
|
||||
// than dealloc) remain.
|
||||
//
|
||||
struct MemRefDataFlowOpt : public MemRefDataFlowOptBase<MemRefDataFlowOpt> {
|
||||
struct AffineScalarReplacement
|
||||
: public AffineScalarReplacementBase<AffineScalarReplacement> {
|
||||
void runOnFunction() override;
|
||||
|
||||
LogicalResult forwardStoreToLoad(AffineReadOpInterface loadOp);
|
||||
|
@ -86,8 +87,9 @@ struct MemRefDataFlowOpt : public MemRefDataFlowOptBase<MemRefDataFlowOpt> {
|
|||
|
||||
/// Creates a pass to perform optimizations relying on memref dataflow such as
|
||||
/// store to load forwarding, elimination of dead stores, and dead allocs.
|
||||
std::unique_ptr<OperationPass<FuncOp>> mlir::createMemRefDataFlowOptPass() {
|
||||
return std::make_unique<MemRefDataFlowOpt>();
|
||||
std::unique_ptr<OperationPass<FuncOp>>
|
||||
mlir::createAffineScalarReplacementPass() {
|
||||
return std::make_unique<AffineScalarReplacement>();
|
||||
}
|
||||
|
||||
// Check if the store may be reaching the load.
|
||||
|
@ -115,7 +117,7 @@ static bool storeMayReachLoad(Operation *storeOp, Operation *loadOp,
|
|||
// This is a straightforward implementation not optimized for speed. Optimize
|
||||
// if needed.
|
||||
LogicalResult
|
||||
MemRefDataFlowOpt::forwardStoreToLoad(AffineReadOpInterface loadOp) {
|
||||
AffineScalarReplacement::forwardStoreToLoad(AffineReadOpInterface loadOp) {
|
||||
// First pass over the use list to get the minimum number of surrounding
|
||||
// loops common between the load op and the store op, with min taken across
|
||||
// all store ops.
|
||||
|
@ -206,7 +208,7 @@ MemRefDataFlowOpt::forwardStoreToLoad(AffineReadOpInterface loadOp) {
|
|||
// 1) loadA and loadB have mathematically equivalent affine access functions.
|
||||
// 2) loadB dominates loadA.
|
||||
// 3) loadB postdominates all the store op's that have a dependence into loadA.
|
||||
void MemRefDataFlowOpt::loadCSE(AffineReadOpInterface loadOp) {
|
||||
void AffineScalarReplacement::loadCSE(AffineReadOpInterface loadOp) {
|
||||
// The list of load op candidates for forwarding that satisfy conditions
|
||||
// (1) and (2) above - they will be filtered later when checking (3).
|
||||
SmallVector<Operation *, 8> fwdingCandidates;
|
||||
|
@ -283,7 +285,7 @@ void MemRefDataFlowOpt::loadCSE(AffineReadOpInterface loadOp) {
|
|||
loadOpsToErase.push_back(loadOp);
|
||||
}
|
||||
|
||||
void MemRefDataFlowOpt::runOnFunction() {
|
||||
void AffineScalarReplacement::runOnFunction() {
|
||||
// Only supports single block functions at the moment.
|
||||
FuncOp f = getFunction();
|
||||
if (!llvm::hasSingleElement(f)) {
|
|
@ -3,6 +3,7 @@ add_mlir_dialect_library(MLIRAffineTransforms
|
|||
AffineLoopInvariantCodeMotion.cpp
|
||||
AffineLoopNormalize.cpp
|
||||
AffineParallelize.cpp
|
||||
AffineScalarReplacement.cpp
|
||||
LoopTiling.cpp
|
||||
LoopUnroll.cpp
|
||||
LoopUnrollAndJam.cpp
|
||||
|
|
|
@ -13,7 +13,6 @@ add_mlir_library(MLIRTransforms
|
|||
LoopCoalescing.cpp
|
||||
LoopFusion.cpp
|
||||
LoopInvariantCodeMotion.cpp
|
||||
MemRefDataFlowOpt.cpp
|
||||
NormalizeMemRefs.cpp
|
||||
OpStats.cpp
|
||||
ParallelLoopCollapsing.cpp
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// RUN: mlir-opt -allow-unregistered-dialect %s -memref-dataflow-opt | FileCheck %s
|
||||
// RUN: mlir-opt -allow-unregistered-dialect %s -affine-scalrep | FileCheck %s
|
||||
|
||||
// CHECK-DAG: [[$MAP0:#map[0-9]+]] = affine_map<(d0, d1) -> (d1 + 1)>
|
||||
// CHECK-DAG: [[$MAP1:#map[0-9]+]] = affine_map<(d0, d1) -> (d0)>
|
Loading…
Reference in New Issue