MLIR
17.0.0git
|
#include "mlir/Dialect/Affine/Passes.h"
#include "mlir/Dialect/Affine/Analysis/AffineStructures.h"
#include "mlir/Dialect/Affine/Analysis/LoopAnalysis.h"
#include "mlir/Dialect/Affine/Analysis/Utils.h"
#include "mlir/Dialect/Affine/IR/AffineOps.h"
#include "mlir/Dialect/Affine/LoopFusionUtils.h"
#include "mlir/Dialect/Affine/LoopUtils.h"
#include "mlir/Dialect/Affine/Utils.h"
#include "mlir/Dialect/MemRef/IR/MemRef.h"
#include "mlir/IR/AffineExpr.h"
#include "mlir/IR/AffineMap.h"
#include "mlir/IR/Builders.h"
#include "mlir/Transforms/Passes.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include <iomanip>
#include <optional>
#include <sstream>
#include "mlir/Dialect/Affine/Passes.h.inc"
Go to the source code of this file.
Namespaces | |
mlir | |
This header declares functions that assist transformations in the MemRef dialect. | |
mlir::affine | |
Macros | |
#define | GEN_PASS_DEF_AFFINELOOPFUSION |
#define | DEBUG_TYPE "affine-loop-fusion" |
Functions | |
static bool | canRemoveSrcNodeAfterFusion (unsigned srcId, unsigned dstId, const ComputationSliceState &fusionSlice, Operation *fusedLoopInsPoint, const DenseSet< Value > &escapingMemRefs, MemRefDependenceGraph *mdg) |
Returns true if node 'srcId' can be removed after fusing it with node 'dstId'. More... | |
static void | getProducerCandidates (unsigned dstId, MemRefDependenceGraph *mdg, SmallVectorImpl< unsigned > &srcIdCandidates) |
Returns in 'srcIdCandidates' the producer fusion candidates for consumer 'dstId'. More... | |
static void | gatherProducerConsumerMemrefs (unsigned srcId, unsigned dstId, MemRefDependenceGraph *mdg, DenseSet< Value > &producerConsumerMemrefs) |
Returns in 'producerConsumerMemrefs' the memrefs involved in a producer-consumer dependence between 'srcId' and 'dstId'. More... | |
static bool | isEscapingMemref (Value memref, Block *block) |
A memref escapes in the context of the fusion pass if either: More... | |
static void | gatherEscapingMemrefs (unsigned id, MemRefDependenceGraph *mdg, DenseSet< Value > &escapingMemRefs) |
Returns in 'escapingMemRefs' the memrefs from affine store ops in node 'id' that escape the block or are accessed in a non-affine way. More... | |
static void | sinkSequentialLoops (MemRefDependenceGraph::Node *node) |
static Value | createPrivateMemRef (AffineForOp forOp, Operation *srcStoreOpInst, unsigned dstLoopDepth, std::optional< unsigned > fastMemorySpace, uint64_t localBufSizeThreshold) |
static bool | hasNonAffineUsersOnThePath (unsigned srcId, unsigned dstId, Value memref, MemRefDependenceGraph *mdg) |
Walking from node 'srcId' to node 'dstId' (exclusive of 'srcId' and 'dstId'), if there is any non-affine operation accessing 'memref', return true. More... | |
static bool | hasNonAffineUsersOnThePath (unsigned srcId, unsigned dstId, MemRefDependenceGraph *mdg) |
Check whether a memref value in node 'srcId' has a non-affine that is between node 'srcId' and node 'dstId' (exclusive of 'srcNode' and 'dstNode'). More... | |
static bool | isFusionProfitable (Operation *srcOpInst, Operation *srcStoreOpInst, AffineForOp dstForOp, ArrayRef< ComputationSliceState > depthSliceUnions, unsigned maxLegalFusionDepth, unsigned *dstLoopDepth, double computeToleranceThreshold) |
#define DEBUG_TYPE "affine-loop-fusion" |
Definition at line 45 of file LoopFusion.cpp.
#define GEN_PASS_DEF_AFFINELOOPFUSION |
Definition at line 40 of file LoopFusion.cpp.
|
static |
Returns true if node 'srcId' can be removed after fusing it with node 'dstId'.
The node can be removed if any of the following conditions are met:
Definition at line 83 of file LoopFusion.cpp.
References mlir::Operation::getBlock(), mlir::affine::MemRefDependenceGraph::getNode(), mlir::Operation::isBeforeInBlock(), mlir::affine::ComputationSliceState::isMaximal(), mlir::affine::MemRefDependenceGraph::Node::op, and mlir::affine::MemRefDependenceGraph::outEdges.
|
static |
Definition at line 370 of file LoopFusion.cpp.
References mlir::affine::MemRefRegion::compute(), mlir::OpBuilder::create(), mlir::floorDiv(), mlir::AffineMap::get(), mlir::get(), mlir::Builder::getAffineConstantExpr(), mlir::Builder::getAffineDimExpr(), mlir::affine::MemRefRegion::getConstantBoundingSizeAndShape(), mlir::affine::MemRefRegion::getConstraints(), mlir::Operation::getLoc(), mlir::affine::getMemRefIntOrFloatEltSizeInBytes(), mlir::presburger::IntegerRelation::getNumCols(), mlir::presburger::IntegerRelation::getNumVars(), mlir::Operation::getParentRegion(), mlir::FlatLinearValueConstraints::getValues(), mlir::affine::replaceAllMemRefUsesWith(), mlir::simplifyAffineExpr(), and mlir::succeeded().
|
static |
Returns in 'escapingMemRefs' the memrefs from affine store ops in node 'id' that escape the block or are accessed in a non-affine way.
Definition at line 221 of file LoopFusion.cpp.
References mlir::affine::MemRefDependenceGraph::block, mlir::affine::MemRefDependenceGraph::getNode(), and isEscapingMemref().
|
static |
Returns in 'producerConsumerMemrefs' the memrefs involved in a producer-consumer dependence between 'srcId' and 'dstId'.
Definition at line 178 of file LoopFusion.cpp.
References mlir::affine::gatherProducerConsumerMemrefs(), and mlir::affine::MemRefDependenceGraph::getNode().
|
static |
Returns in 'srcIdCandidates' the producer fusion candidates for consumer 'dstId'.
Candidates are sorted by node id order. This order corresponds to the program order when the 'mdg' is created. However, program order is not guaranteed and must not be required by the client. Program order won't be held if the 'mdg' is reused from a previous fusion step or if the node creation order changes in the future to support more advance cases.
Definition at line 142 of file LoopFusion.cpp.
References mlir::affine::MemRefDependenceGraph::getNode(), and mlir::affine::MemRefDependenceGraph::inEdges.
|
static |
Check whether a memref value in node 'srcId' has a non-affine that is between node 'srcId' and node 'dstId' (exclusive of 'srcNode' and 'dstNode').
Definition at line 508 of file LoopFusion.cpp.
References mlir::affine::MemRefDependenceGraph::getNode(), mlir::affine::MemRefDependenceGraph::Node::op, and mlir::Operation::walk().
|
static |
Walking from node 'srcId' to node 'dstId' (exclusive of 'srcId' and 'dstId'), if there is any non-affine operation accessing 'memref', return true.
Otherwise, return false.
Definition at line 474 of file LoopFusion.cpp.
References mlir::affine::MemRefDependenceGraph::getNode(), mlir::Value::getUsers(), and mlir::affine::MemRefDependenceGraph::nodes.
A memref escapes in the context of the fusion pass if either:
Definition at line 194 of file LoopFusion.cpp.
References mlir::Value::getDefiningOp(), and mlir::Value::getUsers().
Referenced by gatherEscapingMemrefs().
|
static |
Definition at line 568 of file LoopFusion.cpp.
References mlir::affine::MemRefRegion::compute(), mlir::failed(), mlir::affine::getAffineForIVs(), mlir::affine::getComputeCost(), mlir::affine::getFusionComputeCost(), mlir::Operation::getLoc(), mlir::affine::getLoopNestStats(), mlir::affine::getMemoryFootprintBytes(), mlir::affine::MemRefRegion::getRegionSize(), mlir::affine::ComputationSliceState::isEmpty(), and max().
|
static |
Definition at line 359 of file LoopFusion.cpp.
References mlir::affine::MemRefDependenceGraph::Node::op, and mlir::affine::sinkSequentialLoops().