nir/inline_functions: Switch to inlining everything
authorJason Ekstrand <jason.ekstrand@intel.com>
Wed, 30 Dec 2015 00:57:01 +0000 (16:57 -0800)
committerJason Ekstrand <jason.ekstrand@intel.com>
Wed, 30 Dec 2015 00:58:00 +0000 (16:58 -0800)
src/glsl/nir/nir.h
src/glsl/nir/nir_inline_functions.c

index 714edc1541c8f2ac78fddf0884fa69daedb38e58..b413b38220e26486b91bd607689e20fd5abb86a9 100644 (file)
@@ -2027,7 +2027,6 @@ bool nir_split_var_copies(nir_shader *shader);
 bool nir_lower_returns_impl(nir_function_impl *impl);
 bool nir_lower_returns(nir_shader *shader);
 
-bool nir_inline_functions_impl(nir_function_impl *impl);
 bool nir_inline_functions(nir_shader *shader);
 
 void nir_lower_var_copy_instr(nir_intrinsic_instr *copy, void *mem_ctx);
index e7e17ca76009cca86769da0b02799375bee96864..3cf832790531dd97ffdd2e21dad31f3abb5a365b 100644 (file)
 #include "nir_control_flow.h"
 
 struct inline_functions_state {
-   nir_function_impl *impl;
+   struct set *inlined;
    nir_builder builder;
    bool progress;
 };
 
+static bool inline_function_impl(nir_function_impl *impl, struct set *inlined);
+
 static bool
 inline_functions_block(nir_block *block, void *void_state)
 {
@@ -54,11 +56,13 @@ inline_functions_block(nir_block *block, void *void_state)
       nir_call_instr *call = nir_instr_as_call(instr);
       assert(call->callee->impl);
 
+      inline_function_impl(call->callee->impl, state->inlined);
+
       nir_function_impl *callee_copy =
          nir_function_impl_clone(call->callee->impl);
 
-      exec_list_append(&state->impl->locals, &callee_copy->locals);
-      exec_list_append(&state->impl->registers, &callee_copy->registers);
+      exec_list_append(&b->impl->locals, &callee_copy->locals);
+      exec_list_append(&b->impl->registers, &callee_copy->registers);
 
       b->cursor = nir_before_instr(&call->instr);
 
@@ -104,22 +108,29 @@ inline_functions_block(nir_block *block, void *void_state)
    return true;
 }
 
-bool
-nir_inline_functions_impl(nir_function_impl *impl)
+static bool
+inline_function_impl(nir_function_impl *impl, struct set *inlined)
 {
+   if (_mesa_set_search(inlined, impl))
+      return false; /* Already inlined */
+
    struct inline_functions_state state;
 
+   state.inlined = inlined;
    state.progress = false;
-   state.impl = impl;
    nir_builder_init(&state.builder, impl);
 
    nir_foreach_block(impl, inline_functions_block, &state);
 
-   /* SSA and register indices are completely messed up now */
-   nir_index_ssa_defs(impl);
-   nir_index_local_regs(impl);
+   if (state.progress) {
+      /* SSA and register indices are completely messed up now */
+      nir_index_ssa_defs(impl);
+      nir_index_local_regs(impl);
+
+      nir_metadata_preserve(impl, nir_metadata_none);
+   }
 
-   nir_metadata_preserve(impl, nir_metadata_none);
+   _mesa_set_add(inlined, impl);
 
    return state.progress;
 }
@@ -127,12 +138,16 @@ nir_inline_functions_impl(nir_function_impl *impl)
 bool
 nir_inline_functions(nir_shader *shader)
 {
+   struct set *inlined = _mesa_set_create(NULL, _mesa_hash_pointer,
+                                          _mesa_key_pointer_equal);
    bool progress = false;
 
    nir_foreach_function(shader, function) {
       if (function->impl)
-         progress = nir_inline_functions_impl(function->impl) || progress;
+         progress = inline_function_impl(function->impl, inlined) || progress;
    }
 
+   _mesa_set_destroy(inlined, NULL);
+
    return progress;
 }