How to deal with control-flow or data-flow dependency analysis?

Hello good guys :slight_smile: . I’m a newby for MLIR and I would like to analyze the dependency between the op inside the block of RegionBranchOpInterface ops ( scf.for, scf.if ) and the op defined outside the block. For example, the situation is as follows:

func.func @forward(%arg0: memref<16x32xf32>) {
    %c1 = arith.constant 1 : index
    %c16 = arith.constant 16 : index
    %c8 = arith.constant 8 : index
    %c0 = arith.constant 0 : index
    ...
    %event, %buffer = myDialect.alloc : !async.token, memref<16x32xf32>
    scf.for %arg1 = %c0 to %c16 step %c8 {
      ...
      %1 = myDialect.copy %buffer to %buffer_3 wait(%event_2 : !async.token) : memref<16x32xf32>, memref<16x32xf32>, !async.token
      ...
      %event_4, %buffer_5 = myDialect.alloc : !async.token, memref<16x16xf32, strided<[16, 1]>>
      %event_6, %buffer_7 = myDialect.alloc : !async.token, memref<16x32xf32>
      %3 = myDialect.copy %buffer to %buffer_7 wait(%event_6 : !async.token) : memref<16x32xf32>, memref<16x32xf32, !async.token>
      ...
      myDialect.free(%buffer_7) : memref<16x32xf32>
    }
    %0 = myDialect.copy %buffer to %arg0 : memref<16x32xf32>, memref<16x32xf32>, !async.token
    myDialect.free(%buffer) wait(%event : !async.token) : memref<16x32xf32>
    myDialect.wait_all(%0) : !async.token
    return
  }

myDialect ops have an operand called wait and must wait until async_token arrives. Here, what I want is to check the input buffer of the free op, check which event to wait for and insert async_token into the wait operand (dependency).

However, the op inside the scf.for block is using %buffer, and i am not sure how to check the dependency when trying to free %buffer outside the block. Can you help me or suggestions?

1 Like