Glad to hear from you Uday!
I’m exploring different dependence graph abstractions to answer fundamentally this question – For an operation that is writing into memory via memref, who is the “immediate/next” operation that is going to read from that memref (an example is in the bottom)? These operations are in a lower-level abstraction compared to Affine and hence not able to leverage MemRefDependenceGraph used for LoopFusion. (Also, MemRefDependenceGraph is yet to perform the loop-depth wise dependence analysis).
However, I thought of constructing all the dependencies (including transitive) by considering for every pair of load/stores and filter the transitive ones from the entire set. But, I’m realizing that this is becoming tricky especially in presence of loop nests and also not efficient w.r.t to compilation time overhead.
The other possibility is to walk through the block of the given operation, then traverse upwards to see if there are any blocks/for/if nodes and keep tracking of the closest ones – I felt this is very ad-hoc and complex. I also slowly started to realize that Program Dependence Graphs may not be straightforward to answer this question – Maybe multi-dimensional timestamps from the polyhedral model?
S1; // Store
Who is the immediate/next statement that is going to read memref after being written by S4? The answer is either S3 or S5, but not S2.