1 /* 2 * Copyright 2013 Vadim Girlin <vadimgirlin (at) gmail.com> 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 * on the rights to use, copy, modify, merge, publish, distribute, sub 8 * license, and/or sell copies of the Software, and to permit persons to whom 9 * the 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 NON-INFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 21 * USE OR OTHER DEALINGS IN THE SOFTWARE. 22 * 23 * Authors: 24 * Vadim Girlin 25 */ 26 27 #include "sb_shader.h" 28 #include "sb_pass.h" 29 30 namespace r600_sb { 31 32 int def_use::run() { 33 run_on(sh.root, true); 34 run_on(sh.root, false); 35 return 0; 36 } 37 38 void def_use::process_phi(container_node *c, bool defs, bool uses) { 39 40 for (node_iterator I = c->begin(), E = c->end(); I != E; ++I) { 41 node *n = *I; 42 if (uses) 43 process_uses(n); 44 if (defs) 45 process_defs(n, n->dst, false); 46 } 47 } 48 49 void def_use::run_on(node* n, bool defs) { 50 51 bool is_region = (n->type == NT_REGION); 52 bool is_op = (n->type == NT_OP || n->type == NT_IF); 53 54 if (is_op) { 55 56 if (0) { 57 sblog << "def_use processing op "; 58 dump::dump_op(n); 59 sblog << "\n"; 60 } 61 62 if (defs) 63 process_defs(n, n->dst, false); 64 else 65 process_uses(n); 66 } else if (is_region & defs) { 67 region_node *r = static_cast<region_node*>(n); 68 if (r->loop_phi) 69 process_phi(r->loop_phi, true, false); 70 } 71 72 if (n->is_container() && n->subtype != NST_ALU_PACKED_INST) { 73 container_node *c = static_cast<container_node*>(n); 74 for (node_iterator I = c->begin(), E = c->end(); I != E; ++I) { 75 run_on(*I, defs); 76 } 77 } 78 79 if (is_region) { 80 region_node *r = static_cast<region_node*>(n); 81 if (r->phi) 82 process_phi(r->phi, defs, !defs); 83 if (r->loop_phi && !defs) 84 process_phi(r->loop_phi, false, true); 85 } 86 } 87 88 void def_use::process_defs(node *n, vvec &vv, bool arr_def) { 89 90 for (vvec::iterator I = vv.begin(), E = vv.end(); I != E; ++I) { 91 value *v = *I; 92 if (!v) 93 continue; 94 95 if (arr_def) 96 v->adef = n; 97 else 98 v->def = n; 99 100 v->delete_uses(); 101 102 if (v->is_rel()) { 103 process_defs(n, v->mdef, true); 104 } 105 } 106 } 107 108 void def_use::process_uses(node* n) { 109 unsigned k = 0; 110 111 for (vvec::iterator I = n->src.begin(), E = n->src.end(); I != E; 112 ++I, ++k) { 113 value *v = *I; 114 if (!v || v->is_readonly()) 115 continue; 116 117 if (v->is_rel()) { 118 if (!v->rel->is_readonly()) 119 v->rel->add_use(n, UK_SRC_REL, k); 120 121 unsigned k2 = 0; 122 for (vvec::iterator I = v->muse.begin(), E = v->muse.end(); 123 I != E; ++I, ++k2) { 124 value *v = *I; 125 if (!v) 126 continue; 127 128 v->add_use(n, UK_MAYUSE, k2); 129 } 130 } else 131 v->add_use(n, UK_SRC, k); 132 } 133 134 k = 0; 135 for (vvec::iterator I = n->dst.begin(), E = n->dst.end(); I != E; 136 ++I, ++k) { 137 value *v = *I; 138 if (!v || !v->is_rel()) 139 continue; 140 141 if (!v->rel->is_readonly()) 142 v->rel->add_use(n, UK_DST_REL, k); 143 unsigned k2 = 0; 144 for (vvec::iterator I = v->muse.begin(), E = v->muse.end(); 145 I != E; ++I, ++k2) { 146 value *v = *I; 147 if (!v) 148 continue; 149 150 v->add_use(n, UK_MAYDEF, k2); 151 } 152 } 153 154 if (n->pred) 155 n->pred->add_use(n, UK_PRED, 0); 156 157 if (n->type == NT_IF) { 158 if_node *i = static_cast<if_node*>(n); 159 if (i->cond) 160 i->cond->add_use(i, UK_COND, 0); 161 } 162 } 163 164 } // namespace r600_sb 165