This is an archive of the discontinued LLVM Phabricator instance.

[mlir][conversion] NFC - Relax convert-cf-to-llvm and finalize-memref-to-llvm to also work on non-builtin module ops
Needs ReviewPublic

Authored by nicolasvasilache on Aug 2 2023, 12:39 AM.

Details

Summary

This is a prerequisite for unentangling LowerGpuOpsToNVVMOps which explicitly populates its conversion with
populateControlFlowToLLVMConversionPatterns and populateFinalizeMemRefToLLVMConversionPatterns.

However those patterns cannot be generally added to a pass anchored on a non-ModuleOp.

Instead, LowerGpuOpsToNVVMOps should stop including the world, in a future commit.

Diff Detail

Event Timeline

Herald added a reviewer: dcaballe. · View Herald Transcript
Herald added a project: Restricted Project. · View Herald Transcript
nicolasvasilache requested review of this revision.Aug 2 2023, 12:39 AM
Herald added a project: Restricted Project. · View Herald TranscriptAug 2 2023, 12:39 AM
ftynse added a comment.Aug 2 2023, 1:28 AM

Hmm, if some conversions need a symbol table, would it make sense to use that as a soft restriction rather than skipping the conversions entirely? Symbol table is not an interface (it's a trait and we don't have passes that run on traits), but it looks possible to check for the trait being early in runOnOperation and bail out?

springerm added inline comments.Aug 2 2023, 1:29 AM
mlir/include/mlir/Conversion/Passes.td
266

Can we make sure that the pass signals a failure in that case? (It probably already does, assuming that this is using a dialect conversion.)

@ftynse @springerm

The use case here is to allow partial conversions depending on the anchor op.
During GPU lowering, such passes would apply on GPUModuleOp to lower what they can; later after GPUModuleOp is lowered away into a GPUModuleOp the rest of the operations can be lowered.

Hmm, if some conversions need a symbol table, would it make sense to use that as a soft restriction rather than skipping the conversions entirely? Symbol table is not an interface (it's a trait and we don't have passes that run on traits), but it looks possible to check for the trait being early in runOnOperation and bail out?

I did start with this route but it is unclear to me that:

  1. any op with a symbol table is good enough to support external functions?
  2. we want the pass to fail/bail out
mlir/include/mlir/Conversion/Passes.td
266

I am unclear that we want to fail explicitly here: the current effect is that cf.assert is just ignored.
This is what happens already if one adds a nested pass that operates on a non-builtin module op: if the anchor op does not contain a module, this pass does not apply and no error is produced.

This revision was not accepted when it landed; it landed in state Needs Review.Aug 4 2023, 4:25 AM
This revision was automatically updated to reflect the committed changes.
ftynse added a comment.Aug 4 2023, 5:57 AM

Did this land accidentally?

@ftynse @springerm

The use case here is to allow partial conversions depending on the anchor op.
During GPU lowering, such passes would apply on GPUModuleOp to lower what they can; later after GPUModuleOp is lowered away into a GPUModuleOp the rest of the operations can be lowered.

Hmm, if some conversions need a symbol table, would it make sense to use that as a soft restriction rather than skipping the conversions entirely? Symbol table is not an interface (it's a trait and we don't have passes that run on traits), but it looks possible to check for the trait being early in runOnOperation and bail out?

I did start with this route but it is unclear to me that:

  1. any op with a symbol table is good enough to support external functions?

Symbol tables have no knowledge of external functions, or even functions altogether. They only reason about symbols. It's the function op that has can present itself as external (empty region) or not (non-empty region). Nothing prevents one from creating such ops, symbol table is only there for symbol name resolution and deduplication.

  1. we want the pass to fail/bail out

Passes can easily signal failures at any moment, this doesn't have to be a hardcoded precondition on the root operation...

void runOnOperation(Operation *op) {
  if (!op->hasTrait<OpTrait::SymbolTable>()) {
    op->emitError() << "pass can only run on ops with the SymbolTable trait";
    return signalPassFailure();
  }
  // do actual work here.
}
ftynse reopened this revision.Aug 4 2023, 6:31 AM

Did this land accidentally?

Ugh .. sorry yes .. it was stacked with another patch I landed.

Thanks for the revert(s)!