This allow lowering to support scf.for and scf.if with results. As right now spv region operations don't have return value the results are demoted to Function memory. We create one allocation per result right before the region and store the yield values in it. Then we can load back the value from allocation to be able to use the result.
Details
Diff Detail
Event Timeline
Cool, thanks!
mlir/lib/Conversion/GPUToSPIRV/ConvertGPUToSPIRV.cpp | ||
---|---|---|
45 ↗ | (On Diff #272208) | This comment needs to be updated. It would be nice to give a high-level description of what we are doing here regarding yield handling. |
58 ↗ | (On Diff #272208) | llvm::to_vector<4>(operands) will work here? |
142 ↗ | (On Diff #272208) | s/IfOp/scf ops/ |
143 ↗ | (On Diff #272208) | There is no spv.if. :) |
143 ↗ | (On Diff #272208) | s/doesn't have result/doesn't yield value/ |
144 ↗ | (On Diff #272208) | s/ForOp/scf op/ |
146 ↗ | (On Diff #272208) | s/Replace/replace/ |
160 ↗ | (On Diff #272208) | I think you can directly pass in spirv::StorageClass::Function here. We should have a build method for that. |
mlir/test/Conversion/GPUToSPIRV/if.mlir | ||
134 | Let's add a TODO here to mention this is missing proper VariablePointer capability. |
I realized my previous patch breaks seriazliation/deserialization since those require merge block to only have merge op in it. I rebased my change on top of D82914 and use the scf context to keep track of the VariableOp created during lowering of the control flow region. This allows adding store when lowering yield operation instead and solve the problem with merge block.
Sorry for the mess this cause in the review process.
mlir/include/mlir/Conversion/SCFToSPIRV/SCFToSPIRV.h | ||
---|---|---|
35–36 | Can you please comment on what this class is, and its intended purpose? | |
mlir/lib/Conversion/SCFToSPIRV/SCFToSPIRV.cpp | ||
23 | Please document what this is and what it is used for. | |
25 | nit: Move these out of the mlir namespace and into the global namespace for the file. | |
42 | nit: /// | |
84 | nit: Please use /// for top-level comments. | |
89 | Static methods should not be within namespaces. Please split this out of the anonymous namespace. Anonymous namespaces should not be used for functions. | |
94 | nit: Please spell out auto here. | |
97 | nit: Please spell out auto here. | |
106 | nit: Please add a parameter comment here, /*...=*/nullptr | |
143 | nit: Spell out auto here. | |
153–156 | nit: Please cache the end iterator of for loops, and drop the int part of unsigned int. for (unsigned i = 1, e = ...; i != e; ++i) | |
258 | nit: Drop trivial braces, and cache the end iterator. |
Nice! Thanks for this! I just have a few more nits. Please address River's comments.
mlir/include/mlir/Conversion/SCFToSPIRV/SCFToSPIRV.h | ||
---|---|---|
35–36 | +1 | |
mlir/lib/Conversion/GPUToSPIRV/ConvertGPUToSPIRV.cpp | ||
58 ↗ | (On Diff #272208) | Oh sorry misread. :) |
mlir/lib/Conversion/SCFToSPIRV/SCFToSPIRV.cpp | ||
84 | "Replaces SCF op outputs with SPIR-V variable loads." | |
87 | s/srf/SCF/ | |
252 | If the region returns values, store ... |
mlir/lib/Conversion/GPUToSPIRV/ConvertGPUToSPIRV.cpp | ||
---|---|---|
160 ↗ | (On Diff #272208) | I think we have a build methods that is: static void build(::mlir::OpBuilder &odsBuilder, ::mlir::OperationState &odsState, ::mlir::Type pointer, ::mlir::spirv::StorageClass storage_class, /*optional*/::mlir::Value initializer); |
Can you please comment on what this class is, and its intended purpose?