mirror of OpenBSD xenocara tree github.com/openbsd/xenocara
openbsd
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at jcs 181 lines 5.3 kB view raw
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) { \ 40 ralloc_steal(mem_ctx, obj); \ 41 } 42 43static void sweep_cf_node(nir_shader *nir, nir_cf_node *cf_node); 44 45static void 46sweep_block(nir_shader *nir, nir_block *block) 47{ 48 ralloc_steal(nir, block); 49 50 nir_foreach_instr(instr, block) { 51 gc_mark_live(nir->gctx, instr); 52 53 switch (instr->type) { 54 case nir_instr_type_tex: 55 gc_mark_live(nir->gctx, nir_instr_as_tex(instr)->src); 56 break; 57 case nir_instr_type_phi: 58 nir_foreach_phi_src(src, nir_instr_as_phi(instr)) 59 gc_mark_live(nir->gctx, src); 60 break; 61 case nir_instr_type_intrinsic: 62 ralloc_steal(nir, (void*)nir_instr_as_intrinsic(instr)->name); 63 break; 64 default: 65 break; 66 } 67 } 68} 69 70static void 71sweep_if(nir_shader *nir, nir_if *iff) 72{ 73 ralloc_steal(nir, iff); 74 75 foreach_list_typed(nir_cf_node, cf_node, node, &iff->then_list) { 76 sweep_cf_node(nir, cf_node); 77 } 78 79 foreach_list_typed(nir_cf_node, cf_node, node, &iff->else_list) { 80 sweep_cf_node(nir, cf_node); 81 } 82} 83 84static void 85sweep_loop(nir_shader *nir, nir_loop *loop) 86{ 87 assert(!nir_loop_has_continue_construct(loop)); 88 ralloc_steal(nir, loop); 89 90 foreach_list_typed(nir_cf_node, cf_node, node, &loop->body) { 91 sweep_cf_node(nir, cf_node); 92 } 93} 94 95static void 96sweep_cf_node(nir_shader *nir, nir_cf_node *cf_node) 97{ 98 switch (cf_node->type) { 99 case nir_cf_node_block: 100 sweep_block(nir, nir_cf_node_as_block(cf_node)); 101 break; 102 case nir_cf_node_if: 103 sweep_if(nir, nir_cf_node_as_if(cf_node)); 104 break; 105 case nir_cf_node_loop: 106 sweep_loop(nir, nir_cf_node_as_loop(cf_node)); 107 break; 108 default: 109 unreachable("Invalid CF node type"); 110 } 111} 112 113static void 114sweep_impl(nir_shader *nir, nir_function_impl *impl) 115{ 116 ralloc_steal(nir, impl); 117 118 steal_list(nir, nir_variable, &impl->locals); 119 120 foreach_list_typed(nir_cf_node, cf_node, node, &impl->body) { 121 sweep_cf_node(nir, cf_node); 122 } 123 124 sweep_block(nir, impl->end_block); 125 126 /* Wipe out all the metadata, if any. */ 127 nir_metadata_preserve(impl, nir_metadata_none); 128} 129 130static void 131sweep_function(nir_shader *nir, nir_function *f) 132{ 133 ralloc_steal(nir, f); 134 ralloc_steal(nir, f->params); 135 136 for (unsigned i = 0; i < f->num_params; i++) 137 ralloc_steal(nir, (char *)f->params[i].name); 138 139 if (f->impl) 140 sweep_impl(nir, f->impl); 141} 142 143void 144nir_sweep(nir_shader *nir) 145{ 146 void *rubbish = ralloc_context(NULL); 147 148 struct list_head instr_gc_list; 149 list_inithead(&instr_gc_list); 150 151 /* First, move ownership of all the memory to a temporary context; assume dead. */ 152 ralloc_adopt(rubbish, nir); 153 154 /* Start sweeping */ 155 gc_sweep_start(nir->gctx); 156 157 ralloc_steal(nir, nir->gctx); 158 ralloc_steal(nir, (char *)nir->info.name); 159 if (nir->info.label) 160 ralloc_steal(nir, (char *)nir->info.label); 161 162 /* Variables are not dead. Steal them back. */ 163 steal_list(nir, nir_variable, &nir->variables); 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 ralloc_steal(nir, nir->constant_data); 171 ralloc_steal(nir, nir->xfb_info); 172 ralloc_steal(nir, nir->printf_info); 173 for (int i = 0; i < nir->printf_info_count; i++) { 174 ralloc_steal(nir, nir->printf_info[i].arg_sizes); 175 ralloc_steal(nir, nir->printf_info[i].strings); 176 } 177 178 /* Free everything we didn't steal back. */ 179 gc_sweep_end(nir->gctx); 180 ralloc_free(rubbish); 181}