This is an archive of the discontinued LLVM Phabricator instance.

[Flang][mlir] add a band-aid to support the creation of mutually recursive types when lowering to LLVM IR
ClosedPublic

Authored by schweitz on Jan 10 2020, 2:35 PM.

Details

Summary

This is a temporary implementation to support Flang. The LLVM-IR parser will need to be extended in some way to support recursive types. The exact approach here is still a work-in-progress.

Unfortunately, this won't pass roundtrip testing yet. Adding a comment to the test file as a reminder.

Diff Detail

Event Timeline

schweitz created this revision.Jan 10 2020, 2:35 PM
Herald added a project: Restricted Project. · View Herald Transcript
jdoerfert added inline comments.Jan 11 2020, 12:03 AM
mlir/test/Dialect/LLVMIR/roundtrip.mlir
222

A "FIXME/TODO" and an actual CHECK might be better here. The FIXME explains the problem and the CHECK makes sure we see changes to whatever we are doing.

ftynse added inline comments.Jan 14 2020, 2:47 AM
mlir/include/mlir/Dialect/LLVMIR/LLVMDialect.h
142

The convention for type constructors is getTypenameTy, and we already have getStructTy above.

149

You can use llvm::None as an empty ArrayRef

159

Nit: could you please add empty lines between implementations of different functions here and below to improve readability. Documentation comments are also welcome.

167

This looks like it would be better suited as an instance method. set also implies the argument is modified, which is not the case here...

mlir/test/Dialect/LLVMIR/roundtrip.mlir
222

+1

223

Could we have test for translating such types to LLVM? Normally, we should be able to parse the recursive type and see it after translation. Somewhere in test/Target/llvmir.mlir would be the right place.

schweitz marked 3 inline comments as done.Jan 14 2020, 11:06 AM
schweitz added inline comments.
mlir/include/mlir/Dialect/LLVMIR/LLVMDialect.h
142

This follows the LLVM convention with respect to struct types, which can be two phase. Create a named struct instance to get a reference to it. And secondly, set the fields of the struct. That departs from the operation of a get, which returns a finalized type instance.

149

ok

159

ok

167

That is what is happening here. In the case of a struct that has a field that points back to itself, the struct instance is instantiated and then the fields are set and use the struct instance.

mlir/test/Dialect/LLVMIR/roundtrip.mlir
222

Can someone provide a pointer to something like this? I'm having a hard time envisioning a test that tests for a TODO item.

jdoerfert added inline comments.Jan 14 2020, 11:31 AM
mlir/test/Dialect/LLVMIR/roundtrip.mlir
222
TODO: This should be llvm.func @recursive_type(!llvm<"%a = type { %a* }">)
CHECK: <here check what it is right now>
schweitz marked an inline comment as done.Jan 15 2020, 12:25 PM
schweitz added inline comments.
mlir/test/Dialect/LLVMIR/roundtrip.mlir
222

Running this test as mlir-opt %s | mlir-opt | FileCheck %s would result in the following output.

mlir/test/Dialect/LLVMIR/roundtrip.mlir:223:34: error: expected end of string
llvm.func @recursive_type(!llvm<"%a = type { %a* }">)
                                 ^
mlir/test/Dialect/LLVMIR/roundtrip.mlir:3:17: error: CHECK-LABEL: expected string not found in input
// CHECK-LABEL: func @ops(%arg0: !llvm.i32, %arg1: !llvm.float)
                ^
<stdin>:3:1: note: scanning from here
module {
^

That seems an undesirable option.

Another approach would be to add a separate test altogether, a test that expects the tool to error and terminate.

223

The title of this diff was meant to reflect the transitory nature of this patch. Parser work needs to be done to finish this. It is still undecided the exact nature of that parser work, as far as I understand.

This patch was being driven by merging the MLIR dependence into the F18/Flang project which was itself trying to be merged into the LLVM monorepo. It looks like all of these merges are on hold for now, so the urgency to have some sort of solution has been alleviated.

We still need real support for recursive-types in the LLVM-IR dialect of MLIR at some point (to support Fortran in our case).

jdoerfert added inline comments.Jan 15 2020, 12:30 PM
mlir/test/Dialect/LLVMIR/roundtrip.mlir
222

I'm confused. You have XXXCHECK check right now, why can't we make that into, or augment, a TODO with some information?

ftynse added inline comments.Jan 15 2020, 2:26 PM
mlir/include/mlir/Dialect/LLVMIR/LLVMDialect.h
142

Acknowledged.

mlir/test/Dialect/LLVMIR/roundtrip.mlir
222

The problem is that mlir-opt can not parse the IR that was printed. The solution to that is to avoid calling mlir-opt twice.

223

Even if it is a transient state, having a self-contained (i.e. not depending on f18) test is a way to demonstrate this state is useful for something and at least partially correct.

schweitz updated this revision to Diff 238564.Jan 16 2020, 12:01 PM
schweitz updated this revision to Diff 238568.Jan 16 2020, 12:04 PM
schweitz marked an inline comment as done.Jan 16 2020, 12:23 PM
schweitz marked an inline comment as done.Jan 16 2020, 12:27 PM
schweitz added inline comments.
mlir/test/Dialect/LLVMIR/roundtrip.mlir
223

It's problematic to build a functional test without a parser that can read the input. Since there is no way to read the recursive type from the IR file, we can't build it that way, nor can we output anything.

When driving this from C++ code, we can build a recursive type in memory and the pretty-printer *does* emit the LLVM type.

ftynse accepted this revision.Jan 17 2020, 8:54 AM
This revision is now accepted and ready to land.Jan 17 2020, 8:54 AM
ftynse retitled this revision from [Flang] add a band-aid to support the creation of mutually recursive types when lowering to LLVM IR to [Flang][mlir] add a band-aid to support the creation of mutually recursive types when lowering to LLVM IR.Jan 17 2020, 8:54 AM

I'll need someone to help with getting this committed to the mono repo. Thanks in advance.

This revision was automatically updated to reflect the committed changes.