[Mlir-commits] [mlir] [MLIR][Affine] Extend/generalize MDG to properly add edges between non-affine ops (PR #125451)
Uday Bondhugula
llvmlistbot at llvm.org
Tue Feb 4 05:05:56 PST 2025
================
@@ -106,8 +159,88 @@ void Node::getLoadAndStoreMemrefSet(
}
}
-// Initializes the data dependence graph by walking operations in `block`.
-// Assigns each node in the graph a node id based on program order in 'f'.
+/// Returns the values that this op has a memref effect of type `EffectTys` on,
+/// not considering recursive effects.
+template <typename... EffectTys>
+static void getEffectedValues(Operation *op, SmallVectorImpl<Value> &values) {
+ auto memOp = dyn_cast<MemoryEffectOpInterface>(op);
+ if (!memOp) {
+ if (op->hasTrait<OpTrait::HasRecursiveMemoryEffects>())
+ // No effects.
+ return;
+ // Memref operands have to be considered as being affected.
+ for (Value operand : op->getOperands()) {
+ if (isa<MemRefType>(operand.getType()))
+ values.push_back(operand);
+ }
+ return;
+ }
+ SmallVector<SideEffects::EffectInstance<MemoryEffects::Effect>, 4> effects;
+ memOp.getEffects(effects);
+ for (auto &effect : effects) {
+ Value effectVal = effect.getValue();
+ if (isa<EffectTys...>(effect.getEffect()) && effectVal &&
+ isa<MemRefType>(effectVal.getType()))
+ values.push_back(effectVal);
+ };
+}
+
+/// Add `op` to MDG creating a new node and adding its memory accesses (affine
+/// or non-affine to memrefAccesses (memref -> list of nodes with accesses) map.
+Node *addNodeToMDG(Operation *nodeOp, MemRefDependenceGraph &mdg,
+ DenseMap<Value, SetVector<unsigned>> &memrefAccesses) {
+ auto &nodes = mdg.nodes;
+ // Create graph node 'id' to represent top-level 'forOp' and record
+ // all loads and store accesses it contains.
+ LoopNestStateCollector collector;
+ collector.collect(nodeOp);
+ unsigned newNodeId = mdg.nextNodeId++;
+ Node &node = nodes.insert({newNodeId, Node(newNodeId, nodeOp)}).first->second;
+ for (Operation *op : collector.loadOpInsts) {
+ node.loads.push_back(op);
+ auto memref = cast<AffineReadOpInterface>(op).getMemRef();
+ memrefAccesses[memref].insert(node.id);
+ }
+ for (Operation *opInst : collector.storeOpInsts) {
+ node.stores.push_back(opInst);
+ auto memref = cast<AffineWriteOpInterface>(opInst).getMemRef();
+ memrefAccesses[memref].insert(node.id);
+ }
+ for (Operation *op : collector.memrefLoads) {
+ SmallVector<Value> effectedValues;
+ getEffectedValues<MemoryEffects::Read>(op, effectedValues);
----------------
bondhugula wrote:
We handle all write and free effect ops further below and they aren't exclusive to this, i.e., ops that have multiple effects will appear in multiple lists of `collector`. Ops with alloc effect are handled in the case for ops with more than zero results, and SSA dependences from the results are taken care of. Other than these four effects, there's nothing else left.
https://github.com/llvm/llvm-project/pull/125451
More information about the Mlir-commits
mailing list