Implement the missing lowering from std.dim to the LLVM dialect in case of a
dynamic dimension.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
mlir/test/Conversion/StandardToLLVM/convert-dynamic-memref-ops.mlir | ||
---|---|---|
416 | please, capture !llvm<"{ float*, float*, i64, [3 x i64], [3 x i64] }"> as [[DESCR_TY]] and use everywhere below. |
mlir/test/Conversion/StandardToLLVM/convert-dynamic-memref-ops.mlir | ||
---|---|---|
427 | Does this work when translated to LLVM proper? (You can check with mlir-translate). I think the argument to a GEP needs to be a pointer but in this case it is a value. |
Have you checked that bare-pointer calling convention also works?
mlir/lib/Conversion/StandardToLLVM/StandardToLLVM.cpp | ||
---|---|---|
574 | Value is a descriptor (LLVM struct type), you need to extractvalue from it before doing GEP. | |
mlir/test/Conversion/StandardToLLVM/convert-dynamic-memref-ops.mlir | ||
411 | Nit: I think "dynamic-memref-ops" was intended for ops working on dynamic memrefs, i.e. those with dynamic dimensions. This is not the case here. | |
416 | Cool trick! |
Fix getelementptr issue.
mlir/lib/Conversion/StandardToLLVM/StandardToLLVM.cpp | ||
---|---|---|
574 | I see. Unfortunately not even the sizes in the MemRefDescriptor are a pointer here :/ | |
mlir/test/Conversion/StandardToLLVM/convert-dynamic-memref-ops.mlir | ||
427 | The new version does. It copies everything to stack-allocated memory. Is this what you meant earlier today? I checked this manually with mlir-translate. Should that be reflected in this test, i.e. should I add the corresponding //RUN: ... statement? |
In the long run we need a better way to do this so that we only materialize the descriptor once if needed. Until then, this will work (with some nits).
We can land this without restoring the stack for now.
mlir/lib/Conversion/StandardToLLVM/StandardToLLVM.cpp | ||
---|---|---|
580 | Does LLVM allow to store the entire array at once? I think store supports writing array-typed values. One concern with this implementation is that it could fill up the stack quickly. Assume this gets called in a loop, then each iteration would put a new copy on the stack. We could use @llvm.stackrestore to limit the lifetime of the alloca'd memory. Not sure what that does to LLVMs optimizations, though. @ftynse Should stackrestore be an operation in the llvm dialect? Seems handy to have it there. |
In D81834#2092607, @ftynse wrote:
Have you checked that bare-pointer calling convention also works?How can I do that?
mlir-opt -convert-std-to-llvmir="use-bare-ptr-memref-call-conv=1". There are also some tests for this flag.
Approving now, we can revise to the stacksave/stackrestore version in a separate commit. (It can be handy for dynamically-ranked memrefs as well).
mlir/lib/Conversion/StandardToLLVM/StandardToLLVM.cpp | ||
---|---|---|
580 | At some point, we were storing the entire descriptor on stack, and it did lead to stack explosion when called in a loop. I spent quite some time cleaning that up and now I am wary of alloca'ed memory for memrefs. I don't see another option here though. The common trick I've seen is to put stack allocations in the entry block of the function. One cannot branch to that block so there will be no loops. And since this memory is only used in the immediately succeeding instructions and then discarded, we don't need any lifetime analysis to do the trick. This does not play well with pattern-based rewrites though...
Sure, it's an intrinsic, so it should be really easy to add. |
@ftynse, the new test case fails with bare-pointer calling convention because its argument is a dynamically shaped memref.
All the other tests with a dynamically shaped memref fail in the same way.
I tried the new test case with a statically shaped memref and it all works just fine.
Should I move the test case to another file, make the argument statically shaped, and test with bare-pointer calling convention?
mlir/lib/Conversion/StandardToLLVM/StandardToLLVM.cpp | ||
---|---|---|
580 | @herhut, can you check if this is what you had in mind? |
Should I move the test case to another file, make the argument statically shaped, and test with bare-pointer calling convention?
No, just asking to double check. Thanks!
Value is a descriptor (LLVM struct type), you need to extractvalue from it before doing GEP.