1b8e80941Smrg/* 2b8e80941Smrg * Copyright © 2014 Intel Corporation 3b8e80941Smrg * 4b8e80941Smrg * Permission is hereby granted, free of charge, to any person obtaining a 5b8e80941Smrg * copy of this software and associated documentation files (the "Software"), 6b8e80941Smrg * to deal in the Software without restriction, including without limitation 7b8e80941Smrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8b8e80941Smrg * and/or sell copies of the Software, and to permit persons to whom the 9b8e80941Smrg * Software is furnished to do so, subject to the following conditions: 10b8e80941Smrg * 11b8e80941Smrg * The above copyright notice and this permission notice (including the next 12b8e80941Smrg * paragraph) shall be included in all copies or substantial portions of the 13b8e80941Smrg * Software. 14b8e80941Smrg * 15b8e80941Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16b8e80941Smrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17b8e80941Smrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18b8e80941Smrg * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19b8e80941Smrg * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20b8e80941Smrg * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21b8e80941Smrg * IN THE SOFTWARE. 22b8e80941Smrg * 23b8e80941Smrg * Authors: 24b8e80941Smrg * Connor Abbott (cwabbott0@gmail.com) 25b8e80941Smrg * 26b8e80941Smrg */ 27b8e80941Smrg 28b8e80941Smrg#include "nir.h" 29b8e80941Smrg#include "nir_worklist.h" 30b8e80941Smrg 31b8e80941Smrg/* SSA-based mark-and-sweep dead code elimination */ 32b8e80941Smrg 33b8e80941Smrgstatic void 34b8e80941Smrgmark_and_push(nir_instr_worklist *wl, nir_instr *instr) 35b8e80941Smrg{ 36b8e80941Smrg nir_instr_worklist_push_tail(wl, instr); 37b8e80941Smrg instr->pass_flags = 1; 38b8e80941Smrg} 39b8e80941Smrg 40b8e80941Smrgstatic bool 41b8e80941Smrgmark_live_cb(nir_src *src, void *_state) 42b8e80941Smrg{ 43b8e80941Smrg nir_instr_worklist *worklist = (nir_instr_worklist *) _state; 44b8e80941Smrg 45b8e80941Smrg if (src->is_ssa && !src->ssa->parent_instr->pass_flags) 46b8e80941Smrg mark_and_push(worklist, src->ssa->parent_instr); 47b8e80941Smrg 48b8e80941Smrg return true; 49b8e80941Smrg} 50b8e80941Smrg 51b8e80941Smrgstatic void 52b8e80941Smrginit_instr(nir_instr *instr, nir_instr_worklist *worklist) 53b8e80941Smrg{ 54b8e80941Smrg nir_alu_instr *alu_instr; 55b8e80941Smrg nir_deref_instr *deref_instr; 56b8e80941Smrg nir_intrinsic_instr *intrin_instr; 57b8e80941Smrg nir_tex_instr *tex_instr; 58b8e80941Smrg 59b8e80941Smrg /* We use the pass_flags to store the live/dead information. In DCE, we 60b8e80941Smrg * just treat it as a zero/non-zero boolean for whether or not the 61b8e80941Smrg * instruction is live. 62b8e80941Smrg */ 63b8e80941Smrg instr->pass_flags = 0; 64b8e80941Smrg 65b8e80941Smrg switch (instr->type) { 66b8e80941Smrg case nir_instr_type_call: 67b8e80941Smrg case nir_instr_type_jump: 68b8e80941Smrg mark_and_push(worklist, instr); 69b8e80941Smrg break; 70b8e80941Smrg 71b8e80941Smrg case nir_instr_type_alu: 72b8e80941Smrg alu_instr = nir_instr_as_alu(instr); 73b8e80941Smrg if (!alu_instr->dest.dest.is_ssa) 74b8e80941Smrg mark_and_push(worklist, instr); 75b8e80941Smrg break; 76b8e80941Smrg 77b8e80941Smrg case nir_instr_type_deref: 78b8e80941Smrg deref_instr = nir_instr_as_deref(instr); 79b8e80941Smrg if (!deref_instr->dest.is_ssa) 80b8e80941Smrg mark_and_push(worklist, instr); 81b8e80941Smrg break; 82b8e80941Smrg 83b8e80941Smrg case nir_instr_type_intrinsic: 84b8e80941Smrg intrin_instr = nir_instr_as_intrinsic(instr); 85b8e80941Smrg if (nir_intrinsic_infos[intrin_instr->intrinsic].flags & 86b8e80941Smrg NIR_INTRINSIC_CAN_ELIMINATE) { 87b8e80941Smrg if (nir_intrinsic_infos[intrin_instr->intrinsic].has_dest && 88b8e80941Smrg !intrin_instr->dest.is_ssa) { 89b8e80941Smrg mark_and_push(worklist, instr); 90b8e80941Smrg } 91b8e80941Smrg } else { 92b8e80941Smrg mark_and_push(worklist, instr); 93b8e80941Smrg } 94b8e80941Smrg break; 95b8e80941Smrg 96b8e80941Smrg case nir_instr_type_tex: 97b8e80941Smrg tex_instr = nir_instr_as_tex(instr); 98b8e80941Smrg if (!tex_instr->dest.is_ssa) 99b8e80941Smrg mark_and_push(worklist, instr); 100b8e80941Smrg break; 101b8e80941Smrg 102b8e80941Smrg default: 103b8e80941Smrg break; 104b8e80941Smrg } 105b8e80941Smrg} 106b8e80941Smrg 107b8e80941Smrgstatic bool 108b8e80941Smrginit_block(nir_block *block, nir_instr_worklist *worklist) 109b8e80941Smrg{ 110b8e80941Smrg nir_foreach_instr(instr, block) 111b8e80941Smrg init_instr(instr, worklist); 112b8e80941Smrg 113b8e80941Smrg nir_if *following_if = nir_block_get_following_if(block); 114b8e80941Smrg if (following_if) { 115b8e80941Smrg if (following_if->condition.is_ssa && 116b8e80941Smrg !following_if->condition.ssa->parent_instr->pass_flags) 117b8e80941Smrg mark_and_push(worklist, following_if->condition.ssa->parent_instr); 118b8e80941Smrg } 119b8e80941Smrg 120b8e80941Smrg return true; 121b8e80941Smrg} 122b8e80941Smrg 123b8e80941Smrgstatic bool 124b8e80941Smrgnir_opt_dce_impl(nir_function_impl *impl) 125b8e80941Smrg{ 126b8e80941Smrg nir_instr_worklist *worklist = nir_instr_worklist_create(); 127b8e80941Smrg 128b8e80941Smrg nir_foreach_block(block, impl) { 129b8e80941Smrg init_block(block, worklist); 130b8e80941Smrg } 131b8e80941Smrg 132b8e80941Smrg nir_foreach_instr_in_worklist(instr, worklist) 133b8e80941Smrg nir_foreach_src(instr, mark_live_cb, worklist); 134b8e80941Smrg 135b8e80941Smrg nir_instr_worklist_destroy(worklist); 136b8e80941Smrg 137b8e80941Smrg bool progress = false; 138b8e80941Smrg 139b8e80941Smrg nir_foreach_block(block, impl) { 140b8e80941Smrg nir_foreach_instr_safe(instr, block) { 141b8e80941Smrg if (!instr->pass_flags) { 142b8e80941Smrg nir_instr_remove(instr); 143b8e80941Smrg progress = true; 144b8e80941Smrg } 145b8e80941Smrg } 146b8e80941Smrg } 147b8e80941Smrg 148b8e80941Smrg if (progress) { 149b8e80941Smrg nir_metadata_preserve(impl, nir_metadata_block_index | 150b8e80941Smrg nir_metadata_dominance); 151b8e80941Smrg } else { 152b8e80941Smrg#ifndef NDEBUG 153b8e80941Smrg impl->valid_metadata &= ~nir_metadata_not_properly_reset; 154b8e80941Smrg#endif 155b8e80941Smrg } 156b8e80941Smrg 157b8e80941Smrg return progress; 158b8e80941Smrg} 159b8e80941Smrg 160b8e80941Smrgbool 161b8e80941Smrgnir_opt_dce(nir_shader *shader) 162b8e80941Smrg{ 163b8e80941Smrg bool progress = false; 164b8e80941Smrg nir_foreach_function(function, shader) { 165b8e80941Smrg if (function->impl && nir_opt_dce_impl(function->impl)) 166b8e80941Smrg progress = true; 167b8e80941Smrg } 168b8e80941Smrg 169b8e80941Smrg return progress; 170b8e80941Smrg} 171