This is an archive of the discontinued LLVM Phabricator instance.

[MLIR][SPIRVToLLVM] Conversion pattern for loop op
ClosedPublic

Authored by georgemitenkov on Jul 21 2020, 9:11 AM.

Details

Summary

This patch introduces a conversion of spv.loop to LLVM dialect.
Similarly to spv.selection, op's control attributes are not mapped to LLVM
yet and therefore the conversion fails if the loop control is not None. Also,
all blocks within the loop should be reachable in order for conversion to
succeed.

Diff Detail

Event Timeline

georgemitenkov created this revision.Jul 21 2020, 9:11 AM
mravishankar requested changes to this revision.Jul 31 2020, 11:09 PM

Nice!

mlir/lib/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVM.cpp
736

This seems out of place here. Better to add it as a canonicalization or folding pattern for spirv::LoopOp

745

Block *currentBlock = loopOp.getBlock() ?

Also the convention of auto is to use it only when its clear from the context what the type is or if it is too verbose.

747

auto position = Block::iterator(loopOp) ?

Note that here auto is OK.

Btw, if you are changing the insertion point just the get the Operation after loop, you can just say loopOp->getNextNode()

This revision now requires changes to proceed.Jul 31 2020, 11:09 PM
rriddle added inline comments.Aug 1 2020, 12:37 AM
mlir/lib/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVM.cpp
736

Please do not use .size(), it is O(N). Use loopOp.body().empty() instead.

georgemitenkov marked 4 inline comments as done.

Addressed comments

georgemitenkov added inline comments.Aug 3 2020, 2:22 AM
mlir/lib/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVM.cpp
745

Not sure loopOp.getBlock() works in this case? I think you meant rewriter.getBlock() to get the current block of the builder

THanks for the update. Minor edit comments here. Sorry didnt post these earlierl

mlir/lib/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVM.cpp
722

I think some more comments about the loop structure in LLVM dialect would be helpful here.

745

Right. I meant rewriter.getBlock() . Thanks for interpreting it correctly!

mlir/test/Conversion/SPIRVToLLVM/control-flow-ops-to-llvm.mlir
88

Instead of splitting the CHECK: across the entire IR snippet, its better and more readable to write it as a sequence of CHECK instructions. Also do not hard code basic block IDs. For example, the below could be written as

     CHECK:   llvm.br ^[[BB1:.*]]
     CHECK: ^[[BB1]]:
     CHECK:   %[[COND:.*]] = ...
CHECK-NEXT:   llvm.cond_br %[[COND]], ^[[BB2:.*]], ^[[BB4:.*]]
     CHECK: ^[{BB2]]:
     CHECK:   llvm.br ^[[BB3:.*]]
     CHECK: ^[[BB3]]:
     CHECK:   llvm.br ^[{BB1]]
     CHECK: ^[[BB4]]
     CHECK:   llvm.br ^[[BB5:.*]]
     CHECK: ^[[BB5]]:
CHECK-NEXT:   llvm.return
mravishankar requested changes to this revision.Aug 3 2020, 11:41 PM
This revision now requires changes to proceed.Aug 3 2020, 11:41 PM
georgemitenkov marked 2 inline comments as done.

Addressed comments:

  • Put check statements in one block
  • Added a diagram of the loop structure in LLVM
georgemitenkov added inline comments.Aug 4 2020, 2:09 AM
mlir/lib/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVM.cpp
722

Would the diagram be sufficient, or do you think more details should be added?

mravishankar accepted this revision.Aug 4 2020, 10:10 AM
mravishankar added inline comments.
mlir/lib/Conversion/SPIRVToLLVM/ConvertSPIRVToLLVM.cpp
723

Wow! THis is super nice! Thanks

This revision is now accepted and ready to land.Aug 4 2020, 10:10 AM
This revision was automatically updated to reflect the committed changes.