This is an archive of the discontinued LLVM Phabricator instance.

[mlir] Add a canonicalization pattern of casted AllocOp & AllocaOp
AcceptedPublic

Authored by mamrami on Jun 13 2023, 2:21 AM.

Details

Summary

In some cases the casted buffer could be allocated in the destination's type.
By rebuilding the allocating op with the matching type, the memref.cast is not needed.

Diff Detail

Event Timeline

mamrami created this revision.Jun 13 2023, 2:21 AM
Herald added a project: Restricted Project. · View Herald TranscriptJun 13 2023, 2:21 AM
mamrami requested review of this revision.Jun 13 2023, 2:21 AM
mamrami updated this revision to Diff 530884.Jun 13 2023, 6:16 AM

clang-format

mehdi_amini added inline comments.Jun 14 2023, 3:31 AM
mlir/lib/Dialect/MemRef/IR/MemRefOps.cpp
378–381
386
387

When does this happen?

401

Avoid isa + cast : use dyn_cast instead.

409

Can we do all of this in a single traversal of alloc->getUsers() instead of 3?

mlir/test/Dialect/MemRef/canonicalize.mlir
947

Is this useful to check?

949

Same here, I'm not sure this is necessary to check here. Checking the alloc and the NOT: cast seems like capturing the intent of the test I think.

961

Can you add negative tests? Basically we should have a case for each of the return failure() you have in the pattern I think.

mamrami updated this revision to Diff 548229.Aug 8 2023, 7:57 AM
mamrami marked 6 inline comments as done.

Address CR

mamrami marked 2 inline comments as done.Aug 8 2023, 7:59 AM
mamrami added inline comments.
mlir/lib/Dialect/MemRef/IR/MemRefOps.cpp
387

When castOp result is an UnrankedMemRefType, it cannot be casted to MemRefType.
I changed the code to make it more readable and clear.

mamrami marked an inline comment as done.Aug 8 2023, 8:00 AM

@mehdi_amini - Thanks for the detailed CR!!
And sorry for the delay..

mehdi_amini added inline comments.Aug 8 2023, 6:00 PM
mlir/lib/Dialect/MemRef/IR/MemRefOps.cpp
369

Is this valid for all operations in the memref dialect?

Also what about something like:

%alloc = memref.alloc(...)  : memref<?x?xf32>
%memref.copy %alloc, ...
if (%cond) {
  %casted = memref.cast %alloc : memref<?x?xf32> to memref<4x4xf32>
  ...
}

The control flow should prevent the folding, because the cast may not be reachable I think?

387

Ah! Forgot about unranked... It does not help that for Tensor the hierarchy is named with a different convention...

405

This logic seems overly complex because the interaction between isValidUser and this (they both check for CastOp for example`, and getting the result MemrefType of the cast use.

What does it look like if we inline isValidUser here instead?

mamrami marked an inline comment as done.Aug 9 2023, 8:53 AM
mamrami added inline comments.
mlir/lib/Dialect/MemRef/IR/MemRefOps.cpp
369

I believe you are right!
I think the cast and the alloc should be in the same block.
I'll add this if you agree it's a suffice requirement.

387

Yeah, it was confusing for me too :)

405

Done. Looks much better now

mamrami updated this revision to Diff 548638.Aug 9 2023, 8:55 AM
mamrami marked an inline comment as done.

Updates after CR

mehdi_amini added inline comments.Aug 9 2023, 10:30 PM
mlir/lib/Dialect/MemRef/IR/MemRefOps.cpp
369

I think post-dominate is the condition strictly speaking, but "same block" is a good start for now.

This comment was removed by mehdi_amini.
mamrami updated this revision to Diff 557179.Sep 21 2023, 8:05 AM

CR + rebase

mamrami added inline comments.Sep 21 2023, 8:08 AM
mlir/lib/Dialect/MemRef/IR/MemRefOps.cpp
369

Added a test with scf.if and blocked it.
Also blocked dynamic/unranked alloc that is casted to static, and added a test for dynamic alloc.

mehdi_amini accepted this revision.Sep 21 2023, 4:02 PM
mehdi_amini added inline comments.
mlir/lib/Dialect/MemRef/IR/MemRefOps.cpp
417
mlir/test/Dialect/MemRef/canonicalize.mlir
1041

Can you add // CHECK: memref.cast?
I'm afraid right now it is just deleted, so you may have to add a user of the cast.

This revision is now accepted and ready to land.Sep 21 2023, 4:02 PM