aboutsummaryrefslogtreecommitdiff
path: root/mlir/lib/Target/SPIRV
diff options
context:
space:
mode:
Diffstat (limited to 'mlir/lib/Target/SPIRV')
-rw-r--r--mlir/lib/Target/SPIRV/Serialization/Serializer.cpp18
1 files changed, 18 insertions, 0 deletions
diff --git a/mlir/lib/Target/SPIRV/Serialization/Serializer.cpp b/mlir/lib/Target/SPIRV/Serialization/Serializer.cpp
index b88fbaa..29ed5a4 100644
--- a/mlir/lib/Target/SPIRV/Serialization/Serializer.cpp
+++ b/mlir/lib/Target/SPIRV/Serialization/Serializer.cpp
@@ -89,6 +89,22 @@ static bool isZeroValue(Attribute attr) {
return false;
}
+/// Move all functions declaration before functions definitions. In SPIR-V
+/// "declarations" are functions without a body and "definitions" functions
+/// with a body. This is stronger than necessary. It should be sufficient to
+/// ensure any declarations precede their uses and not all definitions, however
+/// this allows to avoid analysing every function in the module this way.
+static void moveFuncDeclarationsToTop(spirv::ModuleOp moduleOp) {
+ Block::OpListType &ops = moduleOp.getBody()->getOperations();
+ if (ops.empty())
+ return;
+ Operation &firstOp = ops.front();
+ for (Operation &op : llvm::drop_begin(ops))
+ if (auto funcOp = dyn_cast<spirv::FuncOp>(op))
+ if (funcOp.getBody().empty())
+ funcOp->moveBefore(&firstOp);
+}
+
namespace mlir {
namespace spirv {
@@ -119,6 +135,8 @@ LogicalResult Serializer::serialize() {
processMemoryModel();
processDebugInfo();
+ moveFuncDeclarationsToTop(module);
+
// Iterate over the module body to serialize it. Assumptions are that there is
// only one basic block in the moduleOp
for (auto &op : *module.getBody()) {