1*61046927SAndroid Build Coastguard Worker /*
2*61046927SAndroid Build Coastguard Worker * Copyright © 2014 Intel Corporation
3*61046927SAndroid Build Coastguard Worker *
4*61046927SAndroid Build Coastguard Worker * Permission is hereby granted, free of charge, to any person obtaining a
5*61046927SAndroid Build Coastguard Worker * copy of this software and associated documentation files (the "Software"),
6*61046927SAndroid Build Coastguard Worker * to deal in the Software without restriction, including without limitation
7*61046927SAndroid Build Coastguard Worker * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8*61046927SAndroid Build Coastguard Worker * and/or sell copies of the Software, and to permit persons to whom the
9*61046927SAndroid Build Coastguard Worker * Software is furnished to do so, subject to the following conditions:
10*61046927SAndroid Build Coastguard Worker *
11*61046927SAndroid Build Coastguard Worker * The above copyright notice and this permission notice (including the next
12*61046927SAndroid Build Coastguard Worker * paragraph) shall be included in all copies or substantial portions of the
13*61046927SAndroid Build Coastguard Worker * Software.
14*61046927SAndroid Build Coastguard Worker *
15*61046927SAndroid Build Coastguard Worker * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16*61046927SAndroid Build Coastguard Worker * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17*61046927SAndroid Build Coastguard Worker * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18*61046927SAndroid Build Coastguard Worker * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19*61046927SAndroid Build Coastguard Worker * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20*61046927SAndroid Build Coastguard Worker * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21*61046927SAndroid Build Coastguard Worker * IN THE SOFTWARE.
22*61046927SAndroid Build Coastguard Worker */
23*61046927SAndroid Build Coastguard Worker
24*61046927SAndroid Build Coastguard Worker #include "nir.h"
25*61046927SAndroid Build Coastguard Worker #include "nir_vla.h"
26*61046927SAndroid Build Coastguard Worker #include "nir_worklist.h"
27*61046927SAndroid Build Coastguard Worker
28*61046927SAndroid Build Coastguard Worker /*
29*61046927SAndroid Build Coastguard Worker * Basic liveness analysis. This works only in SSA form.
30*61046927SAndroid Build Coastguard Worker *
31*61046927SAndroid Build Coastguard Worker * This liveness pass treats phi nodes as being melded to the space between
32*61046927SAndroid Build Coastguard Worker * blocks so that the destinations of a phi are in the livein of the block
33*61046927SAndroid Build Coastguard Worker * in which it resides and the sources are in the liveout of the
34*61046927SAndroid Build Coastguard Worker * corresponding block. By formulating the liveness information in this
35*61046927SAndroid Build Coastguard Worker * way, we ensure that the definition of any variable dominates its entire
36*61046927SAndroid Build Coastguard Worker * live range. This is true because the only way that the definition of an
37*61046927SAndroid Build Coastguard Worker * SSA value may not dominate a use is if the use is in a phi node and the
38*61046927SAndroid Build Coastguard Worker * uses in phi no are in the live-out of the corresponding predecessor
39*61046927SAndroid Build Coastguard Worker * block but not in the live-in of the block containing the phi node.
40*61046927SAndroid Build Coastguard Worker */
41*61046927SAndroid Build Coastguard Worker
42*61046927SAndroid Build Coastguard Worker struct live_defs_state {
43*61046927SAndroid Build Coastguard Worker unsigned bitset_words;
44*61046927SAndroid Build Coastguard Worker
45*61046927SAndroid Build Coastguard Worker /* Used in propagate_across_edge() */
46*61046927SAndroid Build Coastguard Worker BITSET_WORD *tmp_live;
47*61046927SAndroid Build Coastguard Worker
48*61046927SAndroid Build Coastguard Worker nir_block_worklist worklist;
49*61046927SAndroid Build Coastguard Worker };
50*61046927SAndroid Build Coastguard Worker
51*61046927SAndroid Build Coastguard Worker /* Initialize the liveness data to zero and add the given block to the
52*61046927SAndroid Build Coastguard Worker * worklist.
53*61046927SAndroid Build Coastguard Worker */
54*61046927SAndroid Build Coastguard Worker static void
init_liveness_block(nir_block * block,struct live_defs_state * state)55*61046927SAndroid Build Coastguard Worker init_liveness_block(nir_block *block,
56*61046927SAndroid Build Coastguard Worker struct live_defs_state *state)
57*61046927SAndroid Build Coastguard Worker {
58*61046927SAndroid Build Coastguard Worker block->live_in = reralloc(block, block->live_in, BITSET_WORD,
59*61046927SAndroid Build Coastguard Worker state->bitset_words);
60*61046927SAndroid Build Coastguard Worker memset(block->live_in, 0, state->bitset_words * sizeof(BITSET_WORD));
61*61046927SAndroid Build Coastguard Worker
62*61046927SAndroid Build Coastguard Worker block->live_out = reralloc(block, block->live_out, BITSET_WORD,
63*61046927SAndroid Build Coastguard Worker state->bitset_words);
64*61046927SAndroid Build Coastguard Worker memset(block->live_out, 0, state->bitset_words * sizeof(BITSET_WORD));
65*61046927SAndroid Build Coastguard Worker
66*61046927SAndroid Build Coastguard Worker nir_block_worklist_push_head(&state->worklist, block);
67*61046927SAndroid Build Coastguard Worker }
68*61046927SAndroid Build Coastguard Worker
69*61046927SAndroid Build Coastguard Worker static bool
set_src_live(nir_src * src,void * void_live)70*61046927SAndroid Build Coastguard Worker set_src_live(nir_src *src, void *void_live)
71*61046927SAndroid Build Coastguard Worker {
72*61046927SAndroid Build Coastguard Worker BITSET_WORD *live = void_live;
73*61046927SAndroid Build Coastguard Worker
74*61046927SAndroid Build Coastguard Worker if (nir_src_is_undef(*src))
75*61046927SAndroid Build Coastguard Worker return true; /* undefined variables are never live */
76*61046927SAndroid Build Coastguard Worker
77*61046927SAndroid Build Coastguard Worker BITSET_SET(live, src->ssa->index);
78*61046927SAndroid Build Coastguard Worker
79*61046927SAndroid Build Coastguard Worker return true;
80*61046927SAndroid Build Coastguard Worker }
81*61046927SAndroid Build Coastguard Worker
82*61046927SAndroid Build Coastguard Worker static bool
set_ssa_def_dead(nir_def * def,void * void_live)83*61046927SAndroid Build Coastguard Worker set_ssa_def_dead(nir_def *def, void *void_live)
84*61046927SAndroid Build Coastguard Worker {
85*61046927SAndroid Build Coastguard Worker BITSET_WORD *live = void_live;
86*61046927SAndroid Build Coastguard Worker
87*61046927SAndroid Build Coastguard Worker BITSET_CLEAR(live, def->index);
88*61046927SAndroid Build Coastguard Worker
89*61046927SAndroid Build Coastguard Worker return true;
90*61046927SAndroid Build Coastguard Worker }
91*61046927SAndroid Build Coastguard Worker
92*61046927SAndroid Build Coastguard Worker /** Propagates the live in of succ across the edge to the live out of pred
93*61046927SAndroid Build Coastguard Worker *
94*61046927SAndroid Build Coastguard Worker * Phi nodes exist "between" blocks and all the phi nodes at the start of a
95*61046927SAndroid Build Coastguard Worker * block act "in parallel". When we propagate from the live_in of one
96*61046927SAndroid Build Coastguard Worker * block to the live out of the other, we have to kill any writes from phis
97*61046927SAndroid Build Coastguard Worker * and make live any sources.
98*61046927SAndroid Build Coastguard Worker *
99*61046927SAndroid Build Coastguard Worker * Returns true if updating live out of pred added anything
100*61046927SAndroid Build Coastguard Worker */
101*61046927SAndroid Build Coastguard Worker static bool
propagate_across_edge(nir_block * pred,nir_block * succ,struct live_defs_state * state)102*61046927SAndroid Build Coastguard Worker propagate_across_edge(nir_block *pred, nir_block *succ,
103*61046927SAndroid Build Coastguard Worker struct live_defs_state *state)
104*61046927SAndroid Build Coastguard Worker {
105*61046927SAndroid Build Coastguard Worker BITSET_WORD *live = state->tmp_live;
106*61046927SAndroid Build Coastguard Worker memcpy(live, succ->live_in, state->bitset_words * sizeof *live);
107*61046927SAndroid Build Coastguard Worker
108*61046927SAndroid Build Coastguard Worker nir_foreach_phi(phi, succ) {
109*61046927SAndroid Build Coastguard Worker set_ssa_def_dead(&phi->def, live);
110*61046927SAndroid Build Coastguard Worker }
111*61046927SAndroid Build Coastguard Worker
112*61046927SAndroid Build Coastguard Worker nir_foreach_phi(phi, succ) {
113*61046927SAndroid Build Coastguard Worker nir_foreach_phi_src(src, phi) {
114*61046927SAndroid Build Coastguard Worker if (src->pred == pred) {
115*61046927SAndroid Build Coastguard Worker set_src_live(&src->src, live);
116*61046927SAndroid Build Coastguard Worker break;
117*61046927SAndroid Build Coastguard Worker }
118*61046927SAndroid Build Coastguard Worker }
119*61046927SAndroid Build Coastguard Worker }
120*61046927SAndroid Build Coastguard Worker
121*61046927SAndroid Build Coastguard Worker BITSET_WORD progress = 0;
122*61046927SAndroid Build Coastguard Worker for (unsigned i = 0; i < state->bitset_words; ++i) {
123*61046927SAndroid Build Coastguard Worker progress |= live[i] & ~pred->live_out[i];
124*61046927SAndroid Build Coastguard Worker pred->live_out[i] |= live[i];
125*61046927SAndroid Build Coastguard Worker }
126*61046927SAndroid Build Coastguard Worker return progress != 0;
127*61046927SAndroid Build Coastguard Worker }
128*61046927SAndroid Build Coastguard Worker
129*61046927SAndroid Build Coastguard Worker void
nir_live_defs_impl(nir_function_impl * impl)130*61046927SAndroid Build Coastguard Worker nir_live_defs_impl(nir_function_impl *impl)
131*61046927SAndroid Build Coastguard Worker {
132*61046927SAndroid Build Coastguard Worker struct live_defs_state state = {
133*61046927SAndroid Build Coastguard Worker .bitset_words = BITSET_WORDS(impl->ssa_alloc),
134*61046927SAndroid Build Coastguard Worker };
135*61046927SAndroid Build Coastguard Worker state.tmp_live = rzalloc_array(impl, BITSET_WORD, state.bitset_words),
136*61046927SAndroid Build Coastguard Worker
137*61046927SAndroid Build Coastguard Worker /* Number the instructions so we can do cheap interference tests using the
138*61046927SAndroid Build Coastguard Worker * instruction index.
139*61046927SAndroid Build Coastguard Worker */
140*61046927SAndroid Build Coastguard Worker nir_metadata_require(impl, nir_metadata_instr_index);
141*61046927SAndroid Build Coastguard Worker
142*61046927SAndroid Build Coastguard Worker nir_block_worklist_init(&state.worklist, impl->num_blocks, NULL);
143*61046927SAndroid Build Coastguard Worker
144*61046927SAndroid Build Coastguard Worker /* Allocate live_in and live_out sets and add all of the blocks to the
145*61046927SAndroid Build Coastguard Worker * worklist.
146*61046927SAndroid Build Coastguard Worker */
147*61046927SAndroid Build Coastguard Worker nir_foreach_block(block, impl) {
148*61046927SAndroid Build Coastguard Worker init_liveness_block(block, &state);
149*61046927SAndroid Build Coastguard Worker }
150*61046927SAndroid Build Coastguard Worker
151*61046927SAndroid Build Coastguard Worker /* We're now ready to work through the worklist and update the liveness
152*61046927SAndroid Build Coastguard Worker * sets of each of the blocks. By the time we get to this point, every
153*61046927SAndroid Build Coastguard Worker * block in the function implementation has been pushed onto the
154*61046927SAndroid Build Coastguard Worker * worklist in reverse order. As long as we keep the worklist
155*61046927SAndroid Build Coastguard Worker * up-to-date as we go, everything will get covered.
156*61046927SAndroid Build Coastguard Worker */
157*61046927SAndroid Build Coastguard Worker while (!nir_block_worklist_is_empty(&state.worklist)) {
158*61046927SAndroid Build Coastguard Worker /* We pop them off in the reverse order we pushed them on. This way
159*61046927SAndroid Build Coastguard Worker * the first walk of the instructions is backwards so we only walk
160*61046927SAndroid Build Coastguard Worker * once in the case of no control flow.
161*61046927SAndroid Build Coastguard Worker */
162*61046927SAndroid Build Coastguard Worker nir_block *block = nir_block_worklist_pop_head(&state.worklist);
163*61046927SAndroid Build Coastguard Worker
164*61046927SAndroid Build Coastguard Worker memcpy(block->live_in, block->live_out,
165*61046927SAndroid Build Coastguard Worker state.bitset_words * sizeof(BITSET_WORD));
166*61046927SAndroid Build Coastguard Worker
167*61046927SAndroid Build Coastguard Worker nir_if *following_if = nir_block_get_following_if(block);
168*61046927SAndroid Build Coastguard Worker if (following_if)
169*61046927SAndroid Build Coastguard Worker set_src_live(&following_if->condition, block->live_in);
170*61046927SAndroid Build Coastguard Worker
171*61046927SAndroid Build Coastguard Worker nir_foreach_instr_reverse(instr, block) {
172*61046927SAndroid Build Coastguard Worker /* Phi nodes are handled seperately so we want to skip them. Since
173*61046927SAndroid Build Coastguard Worker * we are going backwards and they are at the beginning, we can just
174*61046927SAndroid Build Coastguard Worker * break as soon as we see one.
175*61046927SAndroid Build Coastguard Worker */
176*61046927SAndroid Build Coastguard Worker if (instr->type == nir_instr_type_phi)
177*61046927SAndroid Build Coastguard Worker break;
178*61046927SAndroid Build Coastguard Worker
179*61046927SAndroid Build Coastguard Worker nir_foreach_def(instr, set_ssa_def_dead, block->live_in);
180*61046927SAndroid Build Coastguard Worker nir_foreach_src(instr, set_src_live, block->live_in);
181*61046927SAndroid Build Coastguard Worker }
182*61046927SAndroid Build Coastguard Worker
183*61046927SAndroid Build Coastguard Worker /* Walk over all of the predecessors of the current block updating
184*61046927SAndroid Build Coastguard Worker * their live in with the live out of this one. If anything has
185*61046927SAndroid Build Coastguard Worker * changed, add the predecessor to the work list so that we ensure
186*61046927SAndroid Build Coastguard Worker * that the new information is used.
187*61046927SAndroid Build Coastguard Worker */
188*61046927SAndroid Build Coastguard Worker set_foreach(block->predecessors, entry) {
189*61046927SAndroid Build Coastguard Worker nir_block *pred = (nir_block *)entry->key;
190*61046927SAndroid Build Coastguard Worker if (propagate_across_edge(pred, block, &state))
191*61046927SAndroid Build Coastguard Worker nir_block_worklist_push_tail(&state.worklist, pred);
192*61046927SAndroid Build Coastguard Worker }
193*61046927SAndroid Build Coastguard Worker }
194*61046927SAndroid Build Coastguard Worker
195*61046927SAndroid Build Coastguard Worker ralloc_free(state.tmp_live);
196*61046927SAndroid Build Coastguard Worker nir_block_worklist_fini(&state.worklist);
197*61046927SAndroid Build Coastguard Worker }
198*61046927SAndroid Build Coastguard Worker
199*61046927SAndroid Build Coastguard Worker /** Return the live set at a cursor
200*61046927SAndroid Build Coastguard Worker *
201*61046927SAndroid Build Coastguard Worker * Note: The bitset returned may be the live_in or live_out from the block in
202*61046927SAndroid Build Coastguard Worker * which the instruction lives. Do not ralloc_free() it directly;
203*61046927SAndroid Build Coastguard Worker * instead, provide a mem_ctx and free that.
204*61046927SAndroid Build Coastguard Worker */
205*61046927SAndroid Build Coastguard Worker const BITSET_WORD *
nir_get_live_defs(nir_cursor cursor,void * mem_ctx)206*61046927SAndroid Build Coastguard Worker nir_get_live_defs(nir_cursor cursor, void *mem_ctx)
207*61046927SAndroid Build Coastguard Worker {
208*61046927SAndroid Build Coastguard Worker nir_block *block = nir_cursor_current_block(cursor);
209*61046927SAndroid Build Coastguard Worker nir_function_impl *impl = nir_cf_node_get_function(&block->cf_node);
210*61046927SAndroid Build Coastguard Worker assert(impl->valid_metadata & nir_metadata_live_defs);
211*61046927SAndroid Build Coastguard Worker
212*61046927SAndroid Build Coastguard Worker switch (cursor.option) {
213*61046927SAndroid Build Coastguard Worker case nir_cursor_before_block:
214*61046927SAndroid Build Coastguard Worker return cursor.block->live_in;
215*61046927SAndroid Build Coastguard Worker
216*61046927SAndroid Build Coastguard Worker case nir_cursor_after_block:
217*61046927SAndroid Build Coastguard Worker return cursor.block->live_out;
218*61046927SAndroid Build Coastguard Worker
219*61046927SAndroid Build Coastguard Worker case nir_cursor_before_instr:
220*61046927SAndroid Build Coastguard Worker if (cursor.instr == nir_block_first_instr(cursor.instr->block))
221*61046927SAndroid Build Coastguard Worker return cursor.instr->block->live_in;
222*61046927SAndroid Build Coastguard Worker break;
223*61046927SAndroid Build Coastguard Worker
224*61046927SAndroid Build Coastguard Worker case nir_cursor_after_instr:
225*61046927SAndroid Build Coastguard Worker if (cursor.instr == nir_block_last_instr(cursor.instr->block))
226*61046927SAndroid Build Coastguard Worker return cursor.instr->block->live_out;
227*61046927SAndroid Build Coastguard Worker break;
228*61046927SAndroid Build Coastguard Worker }
229*61046927SAndroid Build Coastguard Worker
230*61046927SAndroid Build Coastguard Worker /* If we got here, we're an instruction cursor mid-block */
231*61046927SAndroid Build Coastguard Worker const unsigned bitset_words = BITSET_WORDS(impl->ssa_alloc);
232*61046927SAndroid Build Coastguard Worker BITSET_WORD *live = ralloc_array(mem_ctx, BITSET_WORD, bitset_words);
233*61046927SAndroid Build Coastguard Worker memcpy(live, block->live_out, bitset_words * sizeof(BITSET_WORD));
234*61046927SAndroid Build Coastguard Worker
235*61046927SAndroid Build Coastguard Worker nir_foreach_instr_reverse(instr, block) {
236*61046927SAndroid Build Coastguard Worker if (cursor.option == nir_cursor_after_instr && instr == cursor.instr)
237*61046927SAndroid Build Coastguard Worker break;
238*61046927SAndroid Build Coastguard Worker
239*61046927SAndroid Build Coastguard Worker /* If someone asked for liveness in the middle of a bunch of phis,
240*61046927SAndroid Build Coastguard Worker * that's an error. Since we are going backwards and they are at the
241*61046927SAndroid Build Coastguard Worker * beginning, we can just blow up as soon as we see one.
242*61046927SAndroid Build Coastguard Worker */
243*61046927SAndroid Build Coastguard Worker assert(instr->type != nir_instr_type_phi);
244*61046927SAndroid Build Coastguard Worker if (instr->type == nir_instr_type_phi)
245*61046927SAndroid Build Coastguard Worker break;
246*61046927SAndroid Build Coastguard Worker
247*61046927SAndroid Build Coastguard Worker nir_foreach_def(instr, set_ssa_def_dead, live);
248*61046927SAndroid Build Coastguard Worker nir_foreach_src(instr, set_src_live, live);
249*61046927SAndroid Build Coastguard Worker
250*61046927SAndroid Build Coastguard Worker if (cursor.option == nir_cursor_before_instr && instr == cursor.instr)
251*61046927SAndroid Build Coastguard Worker break;
252*61046927SAndroid Build Coastguard Worker }
253*61046927SAndroid Build Coastguard Worker
254*61046927SAndroid Build Coastguard Worker return live;
255*61046927SAndroid Build Coastguard Worker }
256*61046927SAndroid Build Coastguard Worker
257*61046927SAndroid Build Coastguard Worker static bool
src_does_not_use_def(nir_src * src,void * def)258*61046927SAndroid Build Coastguard Worker src_does_not_use_def(nir_src *src, void *def)
259*61046927SAndroid Build Coastguard Worker {
260*61046927SAndroid Build Coastguard Worker return src->ssa != (nir_def *)def;
261*61046927SAndroid Build Coastguard Worker }
262*61046927SAndroid Build Coastguard Worker
263*61046927SAndroid Build Coastguard Worker static bool
search_for_use_after_instr(nir_instr * start,nir_def * def)264*61046927SAndroid Build Coastguard Worker search_for_use_after_instr(nir_instr *start, nir_def *def)
265*61046927SAndroid Build Coastguard Worker {
266*61046927SAndroid Build Coastguard Worker /* Only look for a use strictly after the given instruction */
267*61046927SAndroid Build Coastguard Worker struct exec_node *node = start->node.next;
268*61046927SAndroid Build Coastguard Worker while (!exec_node_is_tail_sentinel(node)) {
269*61046927SAndroid Build Coastguard Worker nir_instr *instr = exec_node_data(nir_instr, node, node);
270*61046927SAndroid Build Coastguard Worker if (!nir_foreach_src(instr, src_does_not_use_def, def))
271*61046927SAndroid Build Coastguard Worker return true;
272*61046927SAndroid Build Coastguard Worker node = node->next;
273*61046927SAndroid Build Coastguard Worker }
274*61046927SAndroid Build Coastguard Worker
275*61046927SAndroid Build Coastguard Worker /* If uses are considered to be in the block immediately preceding the if
276*61046927SAndroid Build Coastguard Worker * so we need to also check the following if condition, if any.
277*61046927SAndroid Build Coastguard Worker */
278*61046927SAndroid Build Coastguard Worker nir_if *following_if = nir_block_get_following_if(start->block);
279*61046927SAndroid Build Coastguard Worker if (following_if && following_if->condition.ssa == def)
280*61046927SAndroid Build Coastguard Worker return true;
281*61046927SAndroid Build Coastguard Worker
282*61046927SAndroid Build Coastguard Worker return false;
283*61046927SAndroid Build Coastguard Worker }
284*61046927SAndroid Build Coastguard Worker
285*61046927SAndroid Build Coastguard Worker /* Returns true if def is live at instr assuming that def comes before
286*61046927SAndroid Build Coastguard Worker * instr in a pre DFS search of the dominance tree.
287*61046927SAndroid Build Coastguard Worker */
288*61046927SAndroid Build Coastguard Worker static bool
nir_def_is_live_at(nir_def * def,nir_instr * instr)289*61046927SAndroid Build Coastguard Worker nir_def_is_live_at(nir_def *def, nir_instr *instr)
290*61046927SAndroid Build Coastguard Worker {
291*61046927SAndroid Build Coastguard Worker if (BITSET_TEST(instr->block->live_out, def->index)) {
292*61046927SAndroid Build Coastguard Worker /* Since def dominates instr, if def is in the liveout of the block,
293*61046927SAndroid Build Coastguard Worker * it's live at instr
294*61046927SAndroid Build Coastguard Worker */
295*61046927SAndroid Build Coastguard Worker return true;
296*61046927SAndroid Build Coastguard Worker } else {
297*61046927SAndroid Build Coastguard Worker if (BITSET_TEST(instr->block->live_in, def->index) ||
298*61046927SAndroid Build Coastguard Worker def->parent_instr->block == instr->block) {
299*61046927SAndroid Build Coastguard Worker /* In this case it is either live coming into instr's block or it
300*61046927SAndroid Build Coastguard Worker * is defined in the same block. In this case, we simply need to
301*61046927SAndroid Build Coastguard Worker * see if it is used after instr.
302*61046927SAndroid Build Coastguard Worker */
303*61046927SAndroid Build Coastguard Worker return search_for_use_after_instr(instr, def);
304*61046927SAndroid Build Coastguard Worker } else {
305*61046927SAndroid Build Coastguard Worker return false;
306*61046927SAndroid Build Coastguard Worker }
307*61046927SAndroid Build Coastguard Worker }
308*61046927SAndroid Build Coastguard Worker }
309*61046927SAndroid Build Coastguard Worker
310*61046927SAndroid Build Coastguard Worker bool
nir_defs_interfere(nir_def * a,nir_def * b)311*61046927SAndroid Build Coastguard Worker nir_defs_interfere(nir_def *a, nir_def *b)
312*61046927SAndroid Build Coastguard Worker {
313*61046927SAndroid Build Coastguard Worker if (a->parent_instr == b->parent_instr) {
314*61046927SAndroid Build Coastguard Worker /* Two variables defined at the same time interfere assuming at
315*61046927SAndroid Build Coastguard Worker * least one isn't dead.
316*61046927SAndroid Build Coastguard Worker */
317*61046927SAndroid Build Coastguard Worker return true;
318*61046927SAndroid Build Coastguard Worker } else if (a->parent_instr->type == nir_instr_type_undef ||
319*61046927SAndroid Build Coastguard Worker b->parent_instr->type == nir_instr_type_undef) {
320*61046927SAndroid Build Coastguard Worker /* If either variable is an ssa_undef, then there's no interference */
321*61046927SAndroid Build Coastguard Worker return false;
322*61046927SAndroid Build Coastguard Worker } else if (a->parent_instr->index < b->parent_instr->index) {
323*61046927SAndroid Build Coastguard Worker return nir_def_is_live_at(a, b->parent_instr);
324*61046927SAndroid Build Coastguard Worker } else {
325*61046927SAndroid Build Coastguard Worker return nir_def_is_live_at(b, a->parent_instr);
326*61046927SAndroid Build Coastguard Worker }
327*61046927SAndroid Build Coastguard Worker }
328