This is an archive of the discontinued LLVM Phabricator instance.

[mlir] recursively convert builtin types to LLVM when possible
ClosedPublic

Authored by ftynse on Oct 26 2021, 8:25 AM.

Details

Summary

Given that LLVM dialect types may now optionally contain types from other
dialects, which itself is motivated by dialect interoperability and progressive
lowering, the conversion should no longer assume that the outermost LLVM
dialect type can be left as is. Instead, it should inspect the types it
contains and attempt to convert them to the LLVM dialect. Introduce this
capability for LLVM array, pointer and structure types. Only literal structures
are currently supported as handling identified structures requires the
converison infrastructure to have a mechanism for avoiding infite recursion in
case of recursive types.

Diff Detail

Event Timeline

ftynse created this revision.Oct 26 2021, 8:25 AM
ftynse requested review of this revision.Oct 26 2021, 8:25 AM
ftynse updated this revision to Diff 382341.Oct 26 2021, 8:28 AM

Now with a test.

rriddle added inline comments.Oct 26 2021, 1:39 PM
mlir/lib/Conversion/LLVMCommon/TypeConverter.cpp
45

Leftover debugging?

61–67

Is there a reason not to use convertTypes?

82–88

Same here.

@rriddle, since this grabbed your attention, any thoughts on how we should handle recursive types in the conversion? Would local stack somewhere in TypeConverter be enough?

ftynse updated this revision to Diff 382551.Oct 27 2021, 1:28 AM
ftynse marked 3 inline comments as done.

Address review.

ftynse added inline comments.Oct 27 2021, 11:28 AM
mlir/lib/Conversion/LLVMCommon/TypeConverter.cpp
61–67

I forgot it existed? :)

rriddle accepted this revision.Oct 27 2021, 2:57 PM

@rriddle, since this grabbed your attention, any thoughts on how we should handle recursive types in the conversion? Would local stack somewhere in TypeConverter be enough?

I think adding a set/stack to TypeConverter to track in-progress conversions is fine (we already have maps for cached conversions). The thing that isn't clear to me is how this is exposed to the user, i.e. how does the user detect when they are mid conversion? Do you have any ideas here?

This revision is now accepted and ready to land.Oct 27 2021, 2:57 PM

@rriddle, since this grabbed your attention, any thoughts on how we should handle recursive types in the conversion? Would local stack somewhere in TypeConverter be enough?

I think adding a set/stack to TypeConverter to track in-progress conversions is fine (we already have maps for cached conversions). The thing that isn't clear to me is how this is exposed to the user, i.e. how does the user detect when they are mid conversion? Do you have any ideas here?

We could pass the stack as an additional const reference argument to the user-supplied converter function + have a default wrapper that ignores the stack and calls user-supplied functions without this argument.

@rriddle, since this grabbed your attention, any thoughts on how we should handle recursive types in the conversion? Would local stack somewhere in TypeConverter be enough?

I think adding a set/stack to TypeConverter to track in-progress conversions is fine (we already have maps for cached conversions). The thing that isn't clear to me is how this is exposed to the user, i.e. how does the user detect when they are mid conversion? Do you have any ideas here?

We could pass the stack as an additional const reference argument to the user-supplied converter function + have a default wrapper that ignores the stack and calls user-supplied functions without this argument.

That could work. Would it be better to have a different callback for the recursive case? i.e. detect recursion and then call the other callback? I'm not sure the impact of that on performance though.

@rriddle, since this grabbed your attention, any thoughts on how we should handle recursive types in the conversion? Would local stack somewhere in TypeConverter be enough?

I think adding a set/stack to TypeConverter to track in-progress conversions is fine (we already have maps for cached conversions). The thing that isn't clear to me is how this is exposed to the user, i.e. how does the user detect when they are mid conversion? Do you have any ideas here?

We could pass the stack as an additional const reference argument to the user-supplied converter function + have a default wrapper that ignores the stack and calls user-supplied functions without this argument.

That could work. Would it be better to have a different callback for the recursive case? i.e. detect recursion and then call the other callback? I'm not sure the impact of that on performance though.

It is probably worth trying the two to check the performance implications.

Another alternative, which will only work if we require callbacks to be stateless, is to directly cache the result of each call and take it from cache instead of calling the callback when we hit the recursive case.