This is an archive of the discontinued LLVM Phabricator instance.

[MLIR] Add a foldTrait() mechanism to allow traits to define folding and test it with an Involution trait
ClosedPublic

Authored by ahmedsabie on Oct 4 2020, 9:55 PM.

Details

Summary

This change allows folds to be done on a newly introduced involution trait rather than having to manually rewrite this optimization for every instance of an involution

Diff Detail

Event Timeline

ahmedsabie created this revision.Oct 4 2020, 9:55 PM
Herald added a project: Restricted Project. · View Herald Transcript
ahmedsabie requested review of this revision.Oct 4 2020, 9:55 PM
rriddle requested changes to this revision.Oct 4 2020, 10:08 PM

Can you split this commit into two? You seem to be adding core infra that isnt documented in your commit title or description, and is arguably more important than adding an involution trait.

This revision now requires changes to proceed.Oct 4 2020, 10:08 PM

This is great!

@rriddle what about renaming the revision Add a foldTrait() mechanism to allow traits to define folding and test it with an Involution trait"? I agree that the involution is completely secondary here.

ahmedsabie updated this revision to Diff 296203.Oct 5 2020, 9:35 AM

update commit message to be more descriptive of the infrastructure change

ahmedsabie retitled this revision from [MLIR] Introduce involution based folding to [MLIR] Add a foldTrait() mechanism to allow traits to define folding and test it with an Involution trait.Oct 5 2020, 9:36 AM

I agree with Mehdi on keeping it as one PR but updating the name since making a separate PR with just the trait folding would require writing code for its test that's almost the same as what's required for involution anyways

andyly added inline comments.Oct 5 2020, 10:09 AM
mlir/test/lib/Dialect/Test/TestTraits.cpp
11–13

Should these imports be removed?

stephenneuendorffer added inline comments.
mlir/include/mlir/IR/OpBase.td
1726

I think you mean op op X == X ?

jpienaar added inline comments.
mlir/include/mlir/IR/OpBase.td
1737

These two shouldn't be needed as users don't need to write them, they are redundant with arguments and results specification and automatically inserted.

mlir/include/mlir/IR/OpDefinition.h
1438
mlir/test/lib/Dialect/Test/TestOps.td
801

ODS automatically inserts OneResult and OneOperand, so these need not be manually specified here. (same below)

(see OpEmitter::genTraits)

rriddle requested changes to this revision.Oct 5 2020, 1:41 PM

Keeping them together is fine if you are using involution as a driving test case given that it is rather simple.

mlir/docs/Traits.md
69

The format of trait folding hooks should be the same as the general form for operations, unless you want to use template meta-programming to allow a trait to define either. This form here looks specific to a certain type of operation, i.e. single result operations, which does not encompass all operation types.

mlir/include/mlir/IR/OpDefinition.h
1030

Are involution operations allowed to be folded if they are side effecting?

mlir/test/lib/Dialect/Test/TestOps.td
801

Please wrap .td files at 80 characters, just like other source files.

mlir/test/lib/Dialect/Test/TestTraits.cpp
2

This should be 80 characters long, the title here is also off.

11

Please remove commented out code.

15

This file doesn't use dialect conversion or anything from FoldUtils, these shouldn't be necessary.

36

nit: Drop the newline here.

mlir/test/mlir-tblgen/trait.mlir
23

Please use a consistent format for the check lines, either all before or all after. (More preference to before than after).

This revision now requires changes to proceed.Oct 5 2020, 1:41 PM
ahmedsabie updated this revision to Diff 296528.EditedOct 6 2020, 12:53 PM

Added no side effect requirement to involution, changed fold to two different signatures to be consistent with existing fold functionality, and fixed issues addressed by comments

ahmedsabie marked 13 inline comments as done.Oct 6 2020, 12:57 PM
ahmedsabie added inline comments.
mlir/include/mlir/IR/OpDefinition.h
1030

good catch, I added the requirement of no side effects being present

mehdi_amini added inline comments.Oct 6 2020, 1:22 PM
mlir/lib/IR/Operation.cpp
737

Nit: remove braces

mlir/test/lib/Dialect/Test/TestOps.td
806

Do we need to provide this "hasFolder"?
This seems like an unneeded limitation to me right now, can you elaborate if you're just adding it here for the fallback?
(and so could you add a test with an op without defining hasFolder = 1?)

The limitation on side-effect is a bit unfortunate: I suspect we'd want lmhlo involution operation on buffers. But we can leave this for future work.

rriddle added a comment.EditedOct 6 2020, 3:54 PM

What do you think of adding detection for in-place folds and continuing to fold in such cases? If an operation is folded in-place, we don't necessarily have to stop the folding process prematurely.

mlir/docs/Traits.md
62

The *must* here is too strong, the second form should still be valid even if the operation isn't single result. Otherwise that limits how general a trait can be, e.g. what if we extend involution to more than just single operand/result? At that point the trait would provide a general folding implementation using the second form.

76

nit: Otherwise,

84

The OpFoldResult should be LogicalResult here.

mlir/include/mlir/IR/OpDefinition.h
450

Can you call into the general form here as a default implementation? That would allow for traits to implement the general form if they want.

1366

Is it possible for these to be made private?

mlir/test/lib/Dialect/Test/TestTraits.cpp
22

nit: Please capitalize the start of comments, and end with proper punctuation.

ahmedsabie updated this revision to Diff 296818.Oct 7 2020, 3:23 PM
ahmedsabie marked an inline comment as done.

Allow traits to continue folding if an inplace fold occured

ahmedsabie added inline comments.Oct 7 2020, 3:24 PM
mlir/test/lib/Dialect/Test/TestOps.td
806

No it just emphasizes that when op folding fails the trait folding takes over. I added a separate test to clearly highlight this is not needed

rriddle accepted this revision.Oct 8 2020, 11:32 AM

Thanks, LGTM after resolving the remaining comments.

mlir/include/mlir/IR/OpDefinition.h
343

Please fix the naming violations here and above.

344

Can you inline the variable definition into the if here and below?

452

nit: Drop the newline here.

455

nit: Drop else after return.

457

nit: Add a message to the assert.

1443

Please fix the naming style issues here and below.

mlir/lib/IR/Operation.cpp
685

nit: Drop the newline here.

mlir/tools/mlir-opt/mlir-opt.cpp
140

nit: Please use a registerTest* naming scheme for this method.

This revision is now accepted and ready to land.Oct 8 2020, 11:32 AM
andyly accepted this revision.Oct 8 2020, 1:09 PM
ahmedsabie updated this revision to Diff 297063.Oct 8 2020, 2:53 PM

Fix last few minor comments

I don't have push access so if you get a chance to push my code and its good please do, thanks!

This revision was landed with ongoing or failed builds.Oct 8 2020, 8:26 PM
This revision was automatically updated to reflect the committed changes.

Pushed a revert in 16580d791f3b ; can you try to build after configuring cmake with -DBUILD_SHARED_LIBS=ON ?

Pushed a revert in 16580d791f3b ; can you try to build after configuring cmake with -DBUILD_SHARED_LIBS=ON ?

It seems there's an issue with using MemoryEffectOpInterface::getEffects in Operation.cpp where I get an undefined reference to this call. I tried adding MLIRSideEffectInterfaces under LINK_LIBS for IR/CMakeLists but I get a cyclic dependency is only allowed among static libraries error. Is there something else I can try or is there a way to check an op has no side effects with using getEffects?

Pushed a revert in 16580d791f3b ; can you try to build after configuring cmake with -DBUILD_SHARED_LIBS=ON ?

It seems there's an issue with using MemoryEffectOpInterface::getEffects in Operation.cpp where I get an undefined reference to this call. I tried adding MLIRSideEffectInterfaces under LINK_LIBS for IR/CMakeLists but I get a cyclic dependency is only allowed among static libraries error. Is there something else I can try or is there a way to check an op has no side effects with using getEffects?

For now I would drop the check on non-side effecting and add a FIXME to add it back later. The actual fix, IMO, is to either:

a) Add a new Traits/ directory and start moving traits there.
b) Rename the Interfaces/ directory to something more general, and start moving traits there.

We should be funneling all of the traits into IR because it isn't scalable, and it also prevents depending on other libraries(such as in this instance). I don't have a big preference on whether we should do a) or b) in the long run.