nir_sweep.c revision 01e04c3f
11.6Srillig/* 21.1Sroy * Copyright © 2015 Intel Corporation 31.1Sroy * 41.1Sroy * Permission is hereby granted, free of charge, to any person obtaining a 51.1Sroy * copy of this software and associated documentation files (the "Software"), 61.1Sroy * to deal in the Software without restriction, including without limitation 71.1Sroy * the rights to use, copy, modify, merge, publish, distribute, sublicense, 81.1Sroy * and/or sell copies of the Software, and to permit persons to whom the 91.1Sroy * Software is furnished to do so, subject to the following conditions: 101.1Sroy * 111.1Sroy * The above copyright notice and this permission notice (including the next 121.1Sroy * paragraph) shall be included in all copies or substantial portions of the 131.1Sroy * Software. 141.1Sroy * 151.1Sroy * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 161.1Sroy * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 171.1Sroy * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 181.1Sroy * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 191.1Sroy * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 201.1Sroy * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 211.1Sroy * IN THE SOFTWARE. 221.1Sroy */ 231.1Sroy 241.1Sroy#include "nir.h" 251.1Sroy 261.1Sroy/** 271.1Sroy * \file nir_sweep.c 281.1Sroy * 291.1Sroy * The nir_sweep() pass performs a mark and sweep pass over a nir_shader's associated 301.1Sroy * memory - anything still connected to the program will be kept, and any dead memory 311.1Sroy * we dropped on the floor will be freed. 321.1Sroy * 331.1Sroy * The expectation is that drivers should call this when finished compiling the shader 341.1Sroy * (after any optimization, lowering, and so on). However, it's also fine to call it 351.1Sroy * earlier, and even many times, trading CPU cycles for memory savings. 361.6Srillig */ 371.1Sroy 381.1Sroy#define steal_list(mem_ctx, type, list) \ 391.1Sroy foreach_list_typed(type, obj, node, list) { ralloc_steal(mem_ctx, obj); } 401.1Sroy 411.1Sroystatic void sweep_cf_node(nir_shader *nir, nir_cf_node *cf_node); 421.1Sroy 431.1Sroystatic bool 441.1Sroysweep_src_indirect(nir_src *src, void *nir) 451.6Srillig{ 461.1Sroy if (!src->is_ssa && src->reg.indirect) 471.1Sroy ralloc_steal(nir, src->reg.indirect); 481.1Sroy 491.3Sroy return true; 501.1Sroy} 511.1Sroy 521.1Sroystatic bool 531.1Sroysweep_dest_indirect(nir_dest *dest, void *nir) 541.1Sroy{ 551.1Sroy if (!dest->is_ssa && dest->reg.indirect) 561.1Sroy ralloc_steal(nir, dest->reg.indirect); 571.1Sroy 581.1Sroy return true; 591.1Sroy} 601.1Sroy 611.1Sroystatic void 621.1Sroysweep_block(nir_shader *nir, nir_block *block) 631.1Sroy{ 641.1Sroy ralloc_steal(nir, block); 651.1Sroy 661.1Sroy nir_foreach_instr(instr, block) { 671.1Sroy ralloc_steal(nir, instr); 681.1Sroy 691.1Sroy nir_foreach_src(instr, sweep_src_indirect, nir); 701.1Sroy nir_foreach_dest(instr, sweep_dest_indirect, nir); 711.4Sjoerg } 721.1Sroy} 731.1Sroy 741.1Sroystatic void 751.1Sroysweep_if(nir_shader *nir, nir_if *iff) 761.1Sroy{ 771.1Sroy ralloc_steal(nir, iff); 781.1Sroy 791.1Sroy foreach_list_typed(nir_cf_node, cf_node, node, &iff->then_list) { 801.1Sroy sweep_cf_node(nir, cf_node); 811.1Sroy } 821.1Sroy 831.1Sroy foreach_list_typed(nir_cf_node, cf_node, node, &iff->else_list) { 841.1Sroy sweep_cf_node(nir, cf_node); 851.3Sroy } 861.3Sroy} 871.2Slukem 881.6Srilligstatic void 891.2Slukemsweep_loop(nir_shader *nir, nir_loop *loop) 901.1Sroy{ 911.1Sroy ralloc_steal(nir, loop); 921.2Slukem 931.2Slukem foreach_list_typed(nir_cf_node, cf_node, node, &loop->body) { 941.1Sroy sweep_cf_node(nir, cf_node); 951.1Sroy } 961.1Sroy} 971.1Sroy 981.1Sroystatic void 991.1Sroysweep_cf_node(nir_shader *nir, nir_cf_node *cf_node) 1001.1Sroy{ 1011.1Sroy switch (cf_node->type) { 1021.6Srillig case nir_cf_node_block: 1031.6Srillig sweep_block(nir, nir_cf_node_as_block(cf_node)); 1041.6Srillig break; 1051.1Sroy case nir_cf_node_if: 1061.1Sroy sweep_if(nir, nir_cf_node_as_if(cf_node)); 1071.6Srillig break; 1081.1Sroy case nir_cf_node_loop: 1091.1Sroy sweep_loop(nir, nir_cf_node_as_loop(cf_node)); 1101.1Sroy break; 1111.1Sroy default: 1121.1Sroy unreachable("Invalid CF node type"); 1131.1Sroy } 1141.1Sroy} 1151.1Sroy 1161.1Sroystatic void 1171.1Sroysweep_impl(nir_shader *nir, nir_function_impl *impl) 1181.1Sroy{ 1191.5Smrg ralloc_steal(nir, impl); 1201.1Sroy 1211.1Sroy steal_list(nir, nir_variable, &impl->locals); 1221.1Sroy steal_list(nir, nir_register, &impl->registers); 1231.1Sroy 1241.1Sroy foreach_list_typed(nir_cf_node, cf_node, node, &impl->body) { 1251.1Sroy sweep_cf_node(nir, cf_node); 1261.1Sroy } 1271.1Sroy 1281.1Sroy sweep_block(nir, impl->end_block); 1291.6Srillig 1301.1Sroy /* Wipe out all the metadata, if any. */ 1311.1Sroy nir_metadata_preserve(impl, nir_metadata_none); 1321.6Srillig} 1331.1Sroy 1341.1Sroystatic void 1351.1Sroysweep_function(nir_shader *nir, nir_function *f) 1361.1Sroy{ 1371.1Sroy ralloc_steal(nir, f); 1381.2Slukem ralloc_steal(nir, f->params); 1391.1Sroy 1401.1Sroy if (f->impl) 1411.1Sroy sweep_impl(nir, f->impl); 1421.1Sroy} 1431.1Sroy 1441.1Sroyvoid 1451.1Sroynir_sweep(nir_shader *nir) 1461.1Sroy{ 1471.1Sroy void *rubbish = ralloc_context(NULL); 1481.1Sroy 1491.1Sroy /* First, move ownership of all the memory to a temporary context; assume dead. */ 1501.1Sroy ralloc_adopt(rubbish, nir); 1511.1Sroy 1521.1Sroy ralloc_steal(nir, (char *)nir->info.name); 1531.1Sroy if (nir->info.label) 1541.1Sroy ralloc_steal(nir, (char *)nir->info.label); 1551.1Sroy 1561.1Sroy /* Variables and registers are not dead. Steal them back. */ 1571.1Sroy steal_list(nir, nir_variable, &nir->uniforms); 1581.1Sroy steal_list(nir, nir_variable, &nir->inputs); 1591.1Sroy steal_list(nir, nir_variable, &nir->outputs); 1601.1Sroy steal_list(nir, nir_variable, &nir->shared); 1611.6Srillig steal_list(nir, nir_variable, &nir->globals); 1621.6Srillig steal_list(nir, nir_variable, &nir->system_values); 1631.1Sroy steal_list(nir, nir_register, &nir->registers); 1641.6Srillig 1651.1Sroy /* Recurse into functions, stealing their contents back. */ 1661.1Sroy foreach_list_typed(nir_function, func, node, &nir->functions) { 1671.1Sroy sweep_function(nir, func); 1681.1Sroy } 1691.1Sroy 1701.1Sroy ralloc_steal(nir, nir->constant_data); 1711.1Sroy 1721.1Sroy /* Free everything we didn't steal back. */ 1731.1Sroy ralloc_free(rubbish); 1741.1Sroy} 1751.1Sroy