Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2.  * Copyright © 2015 Intel Corporation
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a
  5.  * copy of this software and associated documentation files (the "Software"),
  6.  * to deal in the Software without restriction, including without limitation
  7.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8.  * and/or sell copies of the Software, and to permit persons to whom the
  9.  * Software is furnished to do so, subject to the following conditions:
  10.  *
  11.  * The above copyright notice and this permission notice (including the next
  12.  * paragraph) shall be included in all copies or substantial portions of the
  13.  * Software.
  14.  *
  15.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  18.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20.  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  21.  * IN THE SOFTWARE.
  22.  */
  23.  
  24. #include "nir.h"
  25.  
  26. /**
  27.  * \file nir_sweep.c
  28.  *
  29.  * The nir_sweep() pass performs a mark and sweep pass over a nir_shader's associated
  30.  * memory - anything still connected to the program will be kept, and any dead memory
  31.  * we dropped on the floor will be freed.
  32.  *
  33.  * The expectation is that drivers should call this when finished compiling the shader
  34.  * (after any optimization, lowering, and so on).  However, it's also fine to call it
  35.  * earlier, and even many times, trading CPU cycles for memory savings.
  36.  */
  37.  
  38. #define steal_list(mem_ctx, type, list) \
  39.    foreach_list_typed(type, obj, node, list) { ralloc_steal(mem_ctx, obj); }
  40.  
  41. static void sweep_cf_node(nir_shader *nir, nir_cf_node *cf_node);
  42.  
  43. static bool
  44. sweep_src_indirect(nir_src *src, void *nir)
  45. {
  46.    if (!src->is_ssa && src->reg.indirect)
  47.       ralloc_steal(nir, src->reg.indirect);
  48.  
  49.    return true;
  50. }
  51.  
  52. static bool
  53. sweep_dest_indirect(nir_dest *dest, void *nir)
  54. {
  55.    if (!dest->is_ssa && dest->reg.indirect)
  56.       ralloc_steal(nir, dest->reg.indirect);
  57.  
  58.    return true;
  59. }
  60.  
  61. static void
  62. sweep_block(nir_shader *nir, nir_block *block)
  63. {
  64.    ralloc_steal(nir, block);
  65.  
  66.    nir_foreach_instr(block, instr) {
  67.       ralloc_steal(nir, instr);
  68.  
  69.       nir_foreach_src(instr, sweep_src_indirect, nir);
  70.       nir_foreach_dest(instr, sweep_dest_indirect, nir);
  71.    }
  72. }
  73.  
  74. static void
  75. sweep_if(nir_shader *nir, nir_if *iff)
  76. {
  77.    ralloc_steal(nir, iff);
  78.  
  79.    foreach_list_typed(nir_cf_node, cf_node, node, &iff->then_list) {
  80.       sweep_cf_node(nir, cf_node);
  81.    }
  82.  
  83.    foreach_list_typed(nir_cf_node, cf_node, node, &iff->else_list) {
  84.       sweep_cf_node(nir, cf_node);
  85.    }
  86. }
  87.  
  88. static void
  89. sweep_loop(nir_shader *nir, nir_loop *loop)
  90. {
  91.    ralloc_steal(nir, loop);
  92.  
  93.    foreach_list_typed(nir_cf_node, cf_node, node, &loop->body) {
  94.       sweep_cf_node(nir, cf_node);
  95.    }
  96. }
  97.  
  98. static void
  99. sweep_cf_node(nir_shader *nir, nir_cf_node *cf_node)
  100. {
  101.    switch (cf_node->type) {
  102.    case nir_cf_node_block:
  103.       sweep_block(nir, nir_cf_node_as_block(cf_node));
  104.       break;
  105.    case nir_cf_node_if:
  106.       sweep_if(nir, nir_cf_node_as_if(cf_node));
  107.       break;
  108.    case nir_cf_node_loop:
  109.       sweep_loop(nir, nir_cf_node_as_loop(cf_node));
  110.       break;
  111.    default:
  112.       unreachable("Invalid CF node type");
  113.    }
  114. }
  115.  
  116. static void
  117. sweep_impl(nir_shader *nir, nir_function_impl *impl)
  118. {
  119.    ralloc_steal(nir, impl);
  120.  
  121.    ralloc_steal(nir, impl->params);
  122.    ralloc_steal(nir, impl->return_var);
  123.    steal_list(nir, nir_variable, &impl->locals);
  124.    steal_list(nir, nir_register, &impl->registers);
  125.  
  126.    foreach_list_typed(nir_cf_node, cf_node, node, &impl->body) {
  127.       sweep_cf_node(nir, cf_node);
  128.    }
  129.  
  130.    sweep_block(nir, impl->end_block);
  131.  
  132.    /* Wipe out all the metadata, if any. */
  133.    nir_metadata_preserve(impl, nir_metadata_none);
  134. }
  135.  
  136. static void
  137. sweep_function(nir_shader *nir, nir_function *f)
  138. {
  139.    ralloc_steal(nir, f);
  140.  
  141.    foreach_list_typed(nir_function_overload, overload, node, &f->overload_list) {
  142.       ralloc_steal(nir, overload);
  143.       ralloc_steal(nir, overload->params);
  144.       if (overload->impl)
  145.          sweep_impl(nir, overload->impl);
  146.    }
  147. }
  148.  
  149. void
  150. nir_sweep(nir_shader *nir)
  151. {
  152.    void *rubbish = ralloc_context(NULL);
  153.  
  154.    /* First, move ownership of all the memory to a temporary context; assume dead. */
  155.    ralloc_adopt(rubbish, nir);
  156.  
  157.    /* Variables and registers are not dead.  Steal them back. */
  158.    steal_list(nir, nir_variable, &nir->uniforms);
  159.    steal_list(nir, nir_variable, &nir->inputs);
  160.    steal_list(nir, nir_variable, &nir->outputs);
  161.    steal_list(nir, nir_variable, &nir->globals);
  162.    steal_list(nir, nir_variable, &nir->system_values);
  163.    steal_list(nir, nir_register, &nir->registers);
  164.  
  165.    /* Recurse into functions, stealing their contents back. */
  166.    foreach_list_typed(nir_function, func, node, &nir->functions) {
  167.       sweep_function(nir, func);
  168.    }
  169.  
  170.    /* Free everything we didn't steal back. */
  171.    ralloc_free(rubbish);
  172. }
  173.