Module: Mesa
Branch: master
Commit: 6bd876dcaa4403b30eedd5ebe66bfadcef1f1a0c
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=6bd876dcaa4403b30eedd5ebe66bfadcef1f1a0c

Author: Jason Ekstrand <[email protected]>
Date:   Thu Oct 19 10:11:22 2017 -0700

spirv: Only emit functions which are actually used

Instead of emitting absolutely everything, just emit the few functions
that are actually referenced in some way by the entrypoint.  This should
save us quite a bit of time when handed large shader modules containing
many entrypoints.

Reviewed-by: Kenneth Graunke <[email protected]>
Reviewed-by: Kristian H. Kristensen <[email protected]>

---

 src/compiler/spirv/spirv_to_nir.c | 29 +++++++++++++++++++++--------
 src/compiler/spirv/vtn_cfg.c      |  2 ++
 src/compiler/spirv/vtn_private.h  |  3 +++
 3 files changed, 26 insertions(+), 8 deletions(-)

diff --git a/src/compiler/spirv/spirv_to_nir.c 
b/src/compiler/spirv/spirv_to_nir.c
index c58cf5cbfd..2c4f5b0c93 100644
--- a/src/compiler/spirv/spirv_to_nir.c
+++ b/src/compiler/spirv/spirv_to_nir.c
@@ -1394,8 +1394,11 @@ vtn_handle_function_call(struct vtn_builder *b, SpvOp 
opcode,
                          const uint32_t *w, unsigned count)
 {
    struct vtn_type *res_type = vtn_value(b, w[1], vtn_value_type_type)->type;
-   struct nir_function *callee =
-      vtn_value(b, w[3], vtn_value_type_function)->func->impl->function;
+   struct vtn_function *vtn_callee =
+      vtn_value(b, w[3], vtn_value_type_function)->func;
+   struct nir_function *callee = vtn_callee->impl->function;
+
+   vtn_callee->referenced = true;
 
    nir_call_instr *call = nir_call_instr_create(b->nb.shader, callee);
    for (unsigned i = 0; i < call->num_params; i++) {
@@ -3366,12 +3369,22 @@ spirv_to_nir(const uint32_t *words, size_t word_count,
 
    vtn_build_cfg(b, words, word_end);
 
-   foreach_list_typed(struct vtn_function, func, node, &b->functions) {
-      b->const_table = _mesa_hash_table_create(b, _mesa_hash_pointer,
-                                               _mesa_key_pointer_equal);
-
-      vtn_function_emit(b, func, vtn_handle_body_instruction);
-   }
+   assert(b->entry_point->value_type == vtn_value_type_function);
+   b->entry_point->func->referenced = true;
+
+   bool progress;
+   do {
+      progress = false;
+      foreach_list_typed(struct vtn_function, func, node, &b->functions) {
+         if (func->referenced && !func->emitted) {
+            b->const_table = _mesa_hash_table_create(b, _mesa_hash_pointer,
+                                                     _mesa_key_pointer_equal);
+
+            vtn_function_emit(b, func, vtn_handle_body_instruction);
+            progress = true;
+         }
+      }
+   } while (progress);
 
    assert(b->entry_point->value_type == vtn_value_type_function);
    nir_function *entry_point = b->entry_point->func->impl->function;
diff --git a/src/compiler/spirv/vtn_cfg.c b/src/compiler/spirv/vtn_cfg.c
index 13f0221771..70bbccb7cd 100644
--- a/src/compiler/spirv/vtn_cfg.c
+++ b/src/compiler/spirv/vtn_cfg.c
@@ -783,4 +783,6 @@ vtn_function_emit(struct vtn_builder *b, struct 
vtn_function *func,
     */
    if (b->has_loop_continue)
       nir_repair_ssa_impl(func->impl);
+
+   func->emitted = true;
 }
diff --git a/src/compiler/spirv/vtn_private.h b/src/compiler/spirv/vtn_private.h
index 173a7b3d7c..751f5011b7 100644
--- a/src/compiler/spirv/vtn_private.h
+++ b/src/compiler/spirv/vtn_private.h
@@ -159,6 +159,9 @@ struct vtn_block {
 struct vtn_function {
    struct exec_node node;
 
+   bool referenced;
+   bool emitted;
+
    nir_function_impl *impl;
    struct vtn_block *start_block;
 

_______________________________________________
mesa-commit mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-commit

Reply via email to