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
379–382
387
388

When does this happen?

402

Avoid isa + cast : use dyn_cast instead.

410

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
388

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
370

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?

388

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

406

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
370

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.

388

Yeah, it was confusing for me too :)

406

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
370

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
370

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
418
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