From 9f31dd663d9f1e8a9c24e7f745db1ba19bc222f6 Mon Sep 17 00:00:00 2001 From: Hanchen Ye Date: Fri, 8 Jan 2021 01:13:41 -0600 Subject: [PATCH] [AffineStoreForward] factor out applyAffineStoreForward() method; [SimplifyMemrefAccess] factor out applySimplifyMemrefAccess() method --- include/Transforms/Passes.h | 4 ++ lib/Transforms/AffineStoreForward.cpp | 75 ++++++++++++++++--------- lib/Transforms/SimplifyMemrefAccess.cpp | 11 ++-- 3 files changed, 59 insertions(+), 31 deletions(-) diff --git a/include/Transforms/Passes.h b/include/Transforms/Passes.h index 60c6463..710b314 100644 --- a/include/Transforms/Passes.h +++ b/include/Transforms/Passes.h @@ -33,6 +33,10 @@ bool applyLoopPipelining(AffineForOp loop, OpBuilder &builder); bool applyArrayPartition(FuncOp func, OpBuilder &builder); +bool applyAffineStoreForward(FuncOp func, OpBuilder &builder); + +bool applySimplifyMemrefAccess(FuncOp func); + //===----------------------------------------------------------------------===// // Optimization Pass Entries //===----------------------------------------------------------------------===// diff --git a/lib/Transforms/AffineStoreForward.cpp b/lib/Transforms/AffineStoreForward.cpp index e1c9306..322f135 100644 --- a/lib/Transforms/AffineStoreForward.cpp +++ b/lib/Transforms/AffineStoreForward.cpp @@ -19,6 +19,23 @@ using namespace scalehls; // The difference between this pass and built-in memref-dataflow-opt is this // pass support to forward the StoreOps that are conditionally executed. +namespace { +struct AffineStoreForward : public AffineStoreForwardBase { + void runOnOperation() override { + // Only supports single block functions at the moment. + FuncOp func = getOperation(); + auto builder = OpBuilder(func); + + if (!llvm::hasSingleElement(func)) { + markAllAnalysesPreserved(); + return; + } + + applyAffineStoreForward(func, builder); + } +}; +} // namespace + namespace { // The store to load forwarding relies on three conditions: // @@ -52,29 +69,30 @@ namespace { // currently only eliminates the stores only if no other loads/uses (other // than dealloc) remain. // -struct AffineStoreForward : public AffineStoreForwardBase { - void runOnOperation() override; +class AffineStoreForwardImpl { +public: + explicit AffineStoreForwardImpl(SmallPtrSet &memrefsToErase, + DominanceInfo *domInfo, + PostDominanceInfo *postDomInfo, + OpBuilder &builder) + : memrefsToErase(memrefsToErase), domInfo(domInfo), + postDomInfo(postDomInfo), builder(builder) {} void forwardStoreToLoad(AffineReadOpInterface loadOp); // A list of memref's that are potentially dead / could be eliminated. - SmallPtrSet memrefsToErase; + SmallPtrSet &memrefsToErase; DominanceInfo *domInfo = nullptr; PostDominanceInfo *postDomInfo = nullptr; + + OpBuilder &builder; }; - -} // end anonymous namespace - -/// 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 scalehls::createAffineStoreForwardPass() { - return std::make_unique(); -} +} // namespace // This is a straightforward implementation not optimized for speed. Optimize // if needed. -void AffineStoreForward::forwardStoreToLoad(AffineReadOpInterface loadOp) { +void AffineStoreForwardImpl::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. @@ -188,7 +206,6 @@ void AffineStoreForward::forwardStoreToLoad(AffineReadOpInterface loadOp) { return; // Create a new if operation before the loadOp. - OpBuilder builder(loadOp); builder.setInsertionPointAfter(loadOp); auto newIfOp = builder.create( loadOp.getLoc(), loadOp.getValue().getType(), ifOp.getIntegerSet(), @@ -214,21 +231,21 @@ void AffineStoreForward::forwardStoreToLoad(AffineReadOpInterface loadOp) { memrefsToErase.insert(loadOp.getMemRef()); } -void AffineStoreForward::runOnOperation() { - // Only supports single block functions at the moment. - FuncOp f = getOperation(); - if (!llvm::hasSingleElement(f)) { - markAllAnalysesPreserved(); - return; - } - - domInfo = &getAnalysis(); - postDomInfo = &getAnalysis(); - +bool scalehls::applyAffineStoreForward(FuncOp func, OpBuilder &builder) { + SmallPtrSet memrefsToErase; memrefsToErase.clear(); + auto domInfo = DominanceInfo(func); + auto postDomInfo = PostDominanceInfo(func); + + // Instantiate the pass implementation. + auto implement = + AffineStoreForwardImpl(memrefsToErase, &domInfo, &postDomInfo, builder); + // Walk all load's and perform store to load forwarding. - f.walk([&](AffineReadOpInterface loadOp) { forwardStoreToLoad(loadOp); }); + func.walk([&](AffineReadOpInterface loadOp) { + implement.forwardStoreToLoad(loadOp); + }); // Check if the store fwd'ed memrefs are now left with only stores and can // thus be completely deleted. Note: the canonicalize pass should be able @@ -250,4 +267,12 @@ void AffineStoreForward::runOnOperation() { user->erase(); defOp->erase(); } + + return true; +} + +/// 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 scalehls::createAffineStoreForwardPass() { + return std::make_unique(); } diff --git a/lib/Transforms/SimplifyMemrefAccess.cpp b/lib/Transforms/SimplifyMemrefAccess.cpp index 3fe0b37..2048eb2 100644 --- a/lib/Transforms/SimplifyMemrefAccess.cpp +++ b/lib/Transforms/SimplifyMemrefAccess.cpp @@ -15,14 +15,11 @@ using namespace scalehls; namespace { struct SimplifyMemrefAccess : public SimplifyMemrefAccessBase { - void runOnOperation() override; + void runOnOperation() override { applySimplifyMemrefAccess(getOperation()); } }; +} // namespace -} // end anonymous namespace - -void SimplifyMemrefAccess::runOnOperation() { - auto func = getOperation(); - +bool scalehls::applySimplifyMemrefAccess(FuncOp func) { // Collect all load and store operations in the function block. MemAccessesMap map; getMemAccessesMap(func.front(), map); @@ -115,6 +112,8 @@ void SimplifyMemrefAccess::runOnOperation() { opIndex++; } } + + return true; } std::unique_ptr scalehls::createSimplifyMemrefAccessPass() {