1 /*
2  * Copyright © 2017 Gert Wollny
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
21  * DEALINGS IN THE SOFTWARE.
22  */
23 
24 #include "st_glsl_to_tgsi_temprename.h"
25 #include "st_glsl_to_tgsi_array_merge.h"
26 #include "tgsi/tgsi_info.h"
27 #include "tgsi/tgsi_strings.h"
28 #include "program/prog_instruction.h"
29 #include "util/bitscan.h"
30 #include <limits>
31 #include <cstdlib>
32 
33 /* std::sort is significantly faster than qsort */
34 #define USE_STL_SORT
35 #ifdef USE_STL_SORT
36 #include <algorithm>
37 #endif
38 
39 #ifndef NDEBUG
40 #include <iostream>
41 #include <iomanip>
42 #include "program/prog_print.h"
43 #include "util/debug.h"
44 using std::cerr;
45 using std::setw;
46 using std::ostream;
47 #endif
48 
49 /* If <windows.h> is included this is defined and clashes with
50  * std::numeric_limits<>::max()
51  */
52 #ifdef max
53 #undef max
54 #endif
55 
56 using std::numeric_limits;
57 
58 /* Without c++11 define the nullptr for forward-compatibility
59  * and better readibility */
60 #if __cplusplus < 201103L
61 #define nullptr 0
62 #endif
63 
64 #ifndef NDEBUG
65 /* Prepare to make it possible to specify log file */
66 static std::ostream& debug_log = cerr;
67 
68 /* Helper function to check whether we want to seen debugging output */
is_debug_enabled()69 static inline bool is_debug_enabled ()
70 {
71    static int debug_enabled = -1;
72    if (debug_enabled < 0)
73       debug_enabled = env_var_as_boolean("GLSL_TO_TGSI_RENAME_DEBUG", false);
74    return debug_enabled > 0;
75 }
76 #define RENAME_DEBUG(X) if (is_debug_enabled()) do { X; } while (false);
77 #else
78 #define RENAME_DEBUG(X)
79 #endif
80 
81 namespace {
82 
83 enum prog_scope_type {
84    outer_scope,           /* Outer program scope */
85    loop_body,             /* Inside a loop */
86    if_branch,             /* Inside if branch */
87    else_branch,           /* Inside else branch */
88    switch_body,           /* Inside switch statmenet */
89    switch_case_branch,    /* Inside switch case statmenet */
90    switch_default_branch, /* Inside switch default statmenet */
91    undefined_scope
92 };
93 
94 class prog_scope {
95 public:
96    prog_scope(prog_scope *parent, prog_scope_type type, int id,
97               int depth, int begin);
98 
99    prog_scope_type type() const;
100    prog_scope *parent() const;
101    int nesting_depth() const;
102    int id() const;
103    int end() const;
104    int begin() const;
105    int loop_break_line() const;
106 
107    const prog_scope *in_else_scope() const;
108    const prog_scope *in_ifelse_scope() const;
109    const prog_scope *in_parent_ifelse_scope() const;
110    const prog_scope *innermost_loop() const;
111    const prog_scope *outermost_loop() const;
112    const prog_scope *enclosing_conditional() const;
113 
114    bool is_loop() const;
115    bool is_in_loop() const;
116    bool is_switchcase_scope_in_loop() const;
117    bool is_conditional() const;
118    bool is_child_of(const prog_scope *scope) const;
119    bool is_child_of_ifelse_id_sibling(const prog_scope *scope) const;
120 
121    bool break_is_for_switchcase() const;
122    bool contains_range_of(const prog_scope& other) const;
123 
124    void set_end(int end);
125    void set_loop_break_line(int line);
126 
127 private:
128    prog_scope_type scope_type;
129    int scope_id;
130    int scope_nesting_depth;
131    int scope_begin;
132    int scope_end;
133    int break_loop_line;
134    prog_scope *parent_scope;
135 };
136 
137 /* Some storage class to encapsulate the prog_scope (de-)allocations */
138 class prog_scope_storage {
139 public:
140    prog_scope_storage(void *mem_ctx, int n);
141    ~prog_scope_storage();
142    prog_scope * create(prog_scope *p, prog_scope_type type, int id,
143                        int lvl, int s_begin);
144 private:
145    void *mem_ctx;
146    int current_slot;
147    prog_scope *storage;
148 };
149 
150 /* Class to track the access to a component of a temporary register. */
151 
152 class temp_comp_access {
153 public:
154    temp_comp_access();
155 
156    void record_read(int line, prog_scope *scope);
157    void record_write(int line, prog_scope *scope);
158    register_live_range get_required_live_range();
159 private:
160    void propagate_live_range_to_dominant_write_scope();
161    bool conditional_ifelse_write_in_loop() const;
162 
163    void record_ifelse_write(const prog_scope& scope);
164    void record_if_write(const prog_scope& scope);
165    void record_else_write(const prog_scope& scope);
166 
167    prog_scope *last_read_scope;
168    prog_scope *first_read_scope;
169    prog_scope *first_write_scope;
170 
171    int first_write;
172    int last_read;
173    int last_write;
174    int first_read;
175 
176    /* This member variable tracks the current resolution of conditional writing
177     * to this temporary in IF/ELSE clauses.
178     *
179     * The initial value "conditionality_untouched" indicates that this
180     * temporary has not yet been written to within an if clause.
181     *
182     * A positive (other than "conditionality_untouched") number refers to the
183     * last loop id for which the write was resolved as unconditional. With each
184     * new loop this value will be overwitten by "conditionality_unresolved"
185     * on entering the first IF clause writing this temporary.
186     *
187     * The value "conditionality_unresolved" indicates that no resolution has
188     * been achieved so far. If the variable is set to this value at the end of
189     * the processing of the whole shader it also indicates a conditional write.
190     *
191     * The value "write_is_conditional" marks that the variable is written
192     * conditionally (i.e. not in all relevant IF/ELSE code path pairs) in at
193     * least one loop.
194     */
195    int conditionality_in_loop_id;
196 
197    /* Helper constants to make the tracking code more readable. */
198    static const int write_is_conditional = -1;
199    static const int conditionality_unresolved = 0;
200    static const int conditionality_untouched;
201    static const int write_is_unconditional;
202 
203    /* A bit field tracking the nexting levels of if-else clauses where the
204     * temporary has (so far) been written to in the if branch, but not in the
205     * else branch.
206     */
207    unsigned int if_scope_write_flags;
208 
209    int next_ifelse_nesting_depth;
210    static const int supported_ifelse_nesting_depth = 32;
211 
212    /* Tracks the last if scope in which the temporary was written to
213     * without a write in the correspondig else branch. Is also used
214     * to track read-before-write in the according scope.
215     */
216    const prog_scope *current_unpaired_if_write_scope;
217 
218    /* Flag to resolve read-before-write in the else scope. */
219    bool was_written_in_current_else_scope;
220 };
221 
222 const int
223 temp_comp_access::conditionality_untouched = numeric_limits<int>::max();
224 
225 const int
226 temp_comp_access::write_is_unconditional = numeric_limits<int>::max() - 1;
227 
228 /* Class to track the access to all components of a temporary register. */
229 class temp_access {
230 public:
231    temp_access();
232    void record_read(int line, prog_scope *scope, int swizzle);
233    void record_write(int line, prog_scope *scope, int writemask);
234    register_live_range get_required_live_range();
235 private:
236    void update_access_mask(int mask);
237 
238    temp_comp_access comp[4];
239    int access_mask;
240    bool needs_component_tracking;
241 };
242 
243 /* Class to track array access.
244  * Compared to the temporary tracking this is very simplified, mainly because
245  * with the likely indirect access one can not really establish access
246  * patterns for individual elements. Instead the life range evaluation is
247  * always for the whole array, handles only loops and the fact whether a
248  * value was accessed conditionally in a loop.
249  */
250 class array_access {
251 public:
252    array_access();
253    void record_access(int line, prog_scope *scope, int swizzle);
254    void get_required_live_range(array_live_range &lr);
255 private:
256    int first_access;
257    int last_access;
258    prog_scope *first_access_scope;
259    prog_scope *last_access_scope;
260    unsigned accumulated_swizzle:4;
261    int conditional_access_in_loop:1;
262 };
263 
prog_scope_storage(void * mc,int n)264 prog_scope_storage::prog_scope_storage(void *mc, int n):
265    mem_ctx(mc),
266    current_slot(0)
267 {
268    storage = ralloc_array(mem_ctx, prog_scope, n);
269 }
270 
~prog_scope_storage()271 prog_scope_storage::~prog_scope_storage()
272 {
273    ralloc_free(storage);
274 }
275 
276 prog_scope*
create(prog_scope * p,prog_scope_type type,int id,int lvl,int s_begin)277 prog_scope_storage::create(prog_scope *p, prog_scope_type type, int id,
278                            int lvl, int s_begin)
279 {
280    storage[current_slot] = prog_scope(p, type, id, lvl, s_begin);
281    return &storage[current_slot++];
282 }
283 
prog_scope(prog_scope * parent,prog_scope_type type,int id,int depth,int scope_begin)284 prog_scope::prog_scope(prog_scope *parent, prog_scope_type type, int id,
285                        int depth, int scope_begin):
286    scope_type(type),
287    scope_id(id),
288    scope_nesting_depth(depth),
289    scope_begin(scope_begin),
290    scope_end(-1),
291    break_loop_line(numeric_limits<int>::max()),
292    parent_scope(parent)
293 {
294 }
295 
type() const296 prog_scope_type prog_scope::type() const
297 {
298    return scope_type;
299 }
300 
parent() const301 prog_scope *prog_scope::parent() const
302 {
303    return parent_scope;
304 }
305 
nesting_depth() const306 int prog_scope::nesting_depth() const
307 {
308    return scope_nesting_depth;
309 }
310 
is_loop() const311 bool prog_scope::is_loop() const
312 {
313    return (scope_type == loop_body);
314 }
315 
is_in_loop() const316 bool prog_scope::is_in_loop() const
317 {
318    if (scope_type == loop_body)
319       return true;
320 
321    if (parent_scope)
322       return parent_scope->is_in_loop();
323 
324    return false;
325 }
326 
innermost_loop() const327 const prog_scope *prog_scope::innermost_loop() const
328 {
329    if (scope_type == loop_body)
330       return this;
331 
332    if (parent_scope)
333       return parent_scope->innermost_loop();
334 
335    return nullptr;
336 }
337 
outermost_loop() const338 const prog_scope *prog_scope::outermost_loop() const
339 {
340    const prog_scope *loop = nullptr;
341    const prog_scope *p = this;
342 
343    do {
344       if (p->type() == loop_body)
345          loop = p;
346       p = p->parent();
347    } while (p);
348 
349    return loop;
350 }
351 
is_child_of_ifelse_id_sibling(const prog_scope * scope) const352 bool prog_scope::is_child_of_ifelse_id_sibling(const prog_scope *scope) const
353 {
354    const prog_scope *my_parent = in_parent_ifelse_scope();
355    while (my_parent) {
356       /* is a direct child? */
357       if (my_parent == scope)
358          return false;
359       /* is a child of the conditions sibling? */
360       if (my_parent->id() == scope->id())
361          return true;
362       my_parent = my_parent->in_parent_ifelse_scope();
363    }
364    return false;
365 }
366 
is_child_of(const prog_scope * scope) const367 bool prog_scope::is_child_of(const prog_scope *scope) const
368 {
369    const prog_scope *my_parent = parent();
370    while (my_parent) {
371       if (my_parent == scope)
372          return true;
373       my_parent = my_parent->parent();
374    }
375    return false;
376 }
377 
enclosing_conditional() const378 const prog_scope *prog_scope::enclosing_conditional() const
379 {
380    if (is_conditional())
381       return this;
382 
383    if (parent_scope)
384       return parent_scope->enclosing_conditional();
385 
386    return nullptr;
387 }
388 
contains_range_of(const prog_scope & other) const389 bool prog_scope::contains_range_of(const prog_scope& other) const
390 {
391    return (begin() <= other.begin()) && (end() >= other.end());
392 }
393 
is_conditional() const394 bool prog_scope::is_conditional() const
395 {
396    return scope_type == if_branch ||
397          scope_type == else_branch ||
398          scope_type == switch_case_branch ||
399          scope_type == switch_default_branch;
400 }
401 
in_else_scope() const402 const prog_scope *prog_scope::in_else_scope() const
403 {
404    if (scope_type == else_branch)
405       return this;
406 
407    if (parent_scope)
408       return parent_scope->in_else_scope();
409 
410    return nullptr;
411 }
412 
in_parent_ifelse_scope() const413 const prog_scope *prog_scope::in_parent_ifelse_scope() const
414 {
415         if (parent_scope)
416                 return parent_scope->in_ifelse_scope();
417         else
418                 return nullptr;
419 }
420 
in_ifelse_scope() const421 const prog_scope *prog_scope::in_ifelse_scope() const
422 {
423    if (scope_type == if_branch ||
424        scope_type == else_branch)
425       return this;
426 
427    if (parent_scope)
428       return parent_scope->in_ifelse_scope();
429 
430    return nullptr;
431 }
432 
is_switchcase_scope_in_loop() const433 bool prog_scope::is_switchcase_scope_in_loop() const
434 {
435    return (scope_type == switch_case_branch ||
436            scope_type == switch_default_branch) &&
437          is_in_loop();
438 }
439 
break_is_for_switchcase() const440 bool prog_scope::break_is_for_switchcase() const
441 {
442    if (scope_type == loop_body)
443       return false;
444 
445    if (scope_type == switch_case_branch ||
446        scope_type == switch_default_branch ||
447        scope_type == switch_body)
448       return true;
449 
450    if (parent_scope)
451       return parent_scope->break_is_for_switchcase();
452 
453    return false;
454 }
455 
id() const456 int prog_scope::id() const
457 {
458    return scope_id;
459 }
460 
begin() const461 int prog_scope::begin() const
462 {
463    return scope_begin;
464 }
465 
end() const466 int prog_scope::end() const
467 {
468    return scope_end;
469 }
470 
set_end(int end)471 void prog_scope::set_end(int end)
472 {
473    if (scope_end == -1)
474       scope_end = end;
475 }
476 
set_loop_break_line(int line)477 void prog_scope::set_loop_break_line(int line)
478 {
479    if (scope_type == loop_body) {
480       break_loop_line = MIN2(break_loop_line, line);
481    } else {
482       if (parent_scope)
483          parent()->set_loop_break_line(line);
484    }
485 }
486 
loop_break_line() const487 int prog_scope::loop_break_line() const
488 {
489    return break_loop_line;
490 }
491 
temp_access()492 temp_access::temp_access():
493    access_mask(0),
494    needs_component_tracking(false)
495 {
496 }
497 
update_access_mask(int mask)498 void temp_access::update_access_mask(int mask)
499 {
500    if (access_mask && access_mask != mask)
501       needs_component_tracking = true;
502    access_mask |= mask;
503 }
504 
record_write(int line,prog_scope * scope,int writemask)505 void temp_access::record_write(int line, prog_scope *scope, int writemask)
506 {
507    update_access_mask(writemask);
508 
509    if (writemask & WRITEMASK_X)
510       comp[0].record_write(line, scope);
511    if (writemask & WRITEMASK_Y)
512       comp[1].record_write(line, scope);
513    if (writemask & WRITEMASK_Z)
514       comp[2].record_write(line, scope);
515    if (writemask & WRITEMASK_W)
516       comp[3].record_write(line, scope);
517 }
518 
record_read(int line,prog_scope * scope,int readmask)519 void temp_access::record_read(int line, prog_scope *scope, int readmask)
520 {
521    update_access_mask(readmask);
522 
523    if (readmask & WRITEMASK_X)
524       comp[0].record_read(line, scope);
525    if (readmask & WRITEMASK_Y)
526       comp[1].record_read(line, scope);
527    if (readmask & WRITEMASK_Z)
528       comp[2].record_read(line, scope);
529    if (readmask & WRITEMASK_W)
530       comp[3].record_read(line, scope);
531 }
532 
array_access()533 array_access::array_access():
534    first_access(-1),
535    last_access(-1),
536    first_access_scope(nullptr),
537    last_access_scope(nullptr),
538    accumulated_swizzle(0),
539    conditional_access_in_loop(false)
540 {
541 }
542 
record_access(int line,prog_scope * scope,int swizzle)543 void array_access::record_access(int line, prog_scope *scope, int swizzle)
544 {
545    if (!first_access_scope) {
546       first_access = line;
547       first_access_scope = scope;
548    }
549    last_access_scope = scope;
550    last_access = line;
551    accumulated_swizzle |= swizzle;
552    if (scope->in_ifelse_scope() && scope->innermost_loop())
553       conditional_access_in_loop = true;
554 }
555 
get_required_live_range(array_live_range & lr)556 void array_access::get_required_live_range(array_live_range& lr)
557 {
558    RENAME_DEBUG(debug_log << "first_access_scope=" << first_access_scope << "\n");
559    RENAME_DEBUG(debug_log << "last_access_scope=" << last_access_scope << "\n");
560 
561    if (first_access_scope == last_access_scope) {
562       lr.set_live_range(first_access, last_access);
563       lr.set_access_mask(accumulated_swizzle);
564       return;
565    }
566 
567    const prog_scope *shared_scope = first_access_scope;
568    const prog_scope *other_scope = last_access_scope;
569 
570    assert(shared_scope);
571    RENAME_DEBUG(debug_log << "shared_scope=" << shared_scope << "\n");
572 
573    if (conditional_access_in_loop) {
574       const prog_scope *help = shared_scope->outermost_loop();
575       if (help) {
576 	 shared_scope = help;
577       } else {
578 	 help = other_scope->outermost_loop();
579 	 if (help)
580 	    other_scope = help;
581       }
582       if (first_access > shared_scope->begin())
583 	 first_access = shared_scope->begin();
584       if (last_access < shared_scope->end())
585 	 last_access = shared_scope->end();
586    }
587 
588    /* See if any of the two is the parent of the other. */
589    if (other_scope->contains_range_of(*shared_scope)) {
590       shared_scope = other_scope;
591    } else while (!shared_scope->contains_range_of(*other_scope)) {
592       assert(shared_scope->parent());
593       if (shared_scope->type() == loop_body) {
594 	 if (last_access < shared_scope->end())
595 	     last_access = shared_scope->end();
596       }
597       shared_scope = shared_scope->parent();
598    }
599 
600    while (shared_scope != other_scope) {
601       if (other_scope->type() == loop_body) {
602 	 if (last_access < other_scope->end())
603 	     last_access = other_scope->end();
604       }
605       other_scope = other_scope->parent();
606    }
607 
608    lr.set_live_range(first_access, last_access);
609    lr.set_access_mask(accumulated_swizzle);
610 }
611 
612 
make_live_range(int b,int e)613 inline static register_live_range make_live_range(int b, int e)
614 {
615    register_live_range lt;
616    lt.begin = b;
617    lt.end = e;
618    return lt;
619 }
620 
get_required_live_range()621 register_live_range temp_access::get_required_live_range()
622 {
623    register_live_range result = make_live_range(-1, -1);
624 
625    unsigned mask = access_mask;
626    while (mask) {
627       unsigned chan = u_bit_scan(&mask);
628       register_live_range lt = comp[chan].get_required_live_range();
629 
630       if (lt.begin >= 0) {
631          if ((result.begin < 0) || (result.begin > lt.begin))
632             result.begin = lt.begin;
633       }
634 
635       if (lt.end > result.end)
636          result.end = lt.end;
637 
638       if (!needs_component_tracking)
639          break;
640    }
641    return result;
642 }
643 
temp_comp_access()644 temp_comp_access::temp_comp_access():
645    last_read_scope(nullptr),
646    first_read_scope(nullptr),
647    first_write_scope(nullptr),
648    first_write(-1),
649    last_read(-1),
650    last_write(-1),
651    first_read(numeric_limits<int>::max()),
652    conditionality_in_loop_id(conditionality_untouched),
653    if_scope_write_flags(0),
654    next_ifelse_nesting_depth(0),
655    current_unpaired_if_write_scope(nullptr),
656    was_written_in_current_else_scope(false)
657 {
658 }
659 
record_read(int line,prog_scope * scope)660 void temp_comp_access::record_read(int line, prog_scope *scope)
661 {
662    last_read_scope = scope;
663    last_read = line;
664 
665    if (first_read > line) {
666       first_read = line;
667       first_read_scope = scope;
668    }
669 
670    /* If the conditionality of the first write is already resolved then
671     * no further checks are required.
672     */
673    if (conditionality_in_loop_id == write_is_unconditional ||
674        conditionality_in_loop_id == write_is_conditional)
675       return;
676 
677    /* Check whether we are in a condition within a loop */
678    const prog_scope *ifelse_scope = scope->in_ifelse_scope();
679    const prog_scope *enclosing_loop;
680    if (ifelse_scope && (enclosing_loop = ifelse_scope->innermost_loop())) {
681 
682       /* If we have either not yet written to this register nor writes are
683        * resolved as unconditional in the enclosing loop then check whether
684        * we read before write in an IF/ELSE branch.
685        */
686       if ((conditionality_in_loop_id != write_is_conditional) &&
687           (conditionality_in_loop_id != enclosing_loop->id())) {
688 
689          if (current_unpaired_if_write_scope)  {
690 
691             /* Has been written in this or a parent scope? - this makes the temporary
692              * unconditionally set at this point.
693              */
694             if (scope->is_child_of(current_unpaired_if_write_scope))
695                return;
696 
697             /* Has been written in the same scope before it was read? */
698             if (ifelse_scope->type() == if_branch) {
699                if (current_unpaired_if_write_scope->id() == scope->id())
700                   return;
701             } else {
702                if (was_written_in_current_else_scope)
703                   return;
704             }
705          }
706 
707          /* The temporary was read (conditionally) before it is written, hence
708           * it should survive a loop. This can be signaled like if it were
709           * conditionally written.
710           */
711          conditionality_in_loop_id = write_is_conditional;
712       }
713    }
714 }
715 
record_write(int line,prog_scope * scope)716 void temp_comp_access::record_write(int line, prog_scope *scope)
717 {
718    last_write = line;
719 
720    if (first_write < 0) {
721       first_write = line;
722       first_write_scope = scope;
723 
724       /* If the first write we encounter is not in a conditional branch, or
725        * the conditional write is not within a loop, then this is to be
726        * considered an unconditional dominant write.
727        */
728       const prog_scope *conditional = scope->enclosing_conditional();
729       if (!conditional || !conditional->innermost_loop()) {
730          conditionality_in_loop_id = write_is_unconditional;
731       }
732    }
733 
734    /* The conditionality of the first write is already resolved. */
735    if (conditionality_in_loop_id == write_is_unconditional ||
736        conditionality_in_loop_id == write_is_conditional)
737       return;
738 
739    /* If the nesting depth is larger than the supported level,
740     * then we assume conditional writes.
741     */
742    if (next_ifelse_nesting_depth >= supported_ifelse_nesting_depth) {
743       conditionality_in_loop_id = write_is_conditional;
744       return;
745    }
746 
747    /* If we are in an IF/ELSE scope within a loop and the loop has not
748     * been resolved already, then record this write.
749     */
750    const prog_scope *ifelse_scope = scope->in_ifelse_scope();
751    if (ifelse_scope && ifelse_scope->innermost_loop() &&
752        ifelse_scope->innermost_loop()->id()  != conditionality_in_loop_id)
753       record_ifelse_write(*ifelse_scope);
754 }
755 
record_ifelse_write(const prog_scope & scope)756 void temp_comp_access::record_ifelse_write(const prog_scope& scope)
757 {
758    if (scope.type() == if_branch) {
759       /* The first write in an IF branch within a loop implies unresolved
760        * conditionality (if it was untouched or unconditional before).
761        */
762       conditionality_in_loop_id = conditionality_unresolved;
763       was_written_in_current_else_scope = false;
764       record_if_write(scope);
765    } else {
766       was_written_in_current_else_scope = true;
767       record_else_write(scope);
768    }
769 }
770 
record_if_write(const prog_scope & scope)771 void temp_comp_access::record_if_write(const prog_scope& scope)
772 {
773    /* Don't record write if this IF scope if it ...
774     * - is not the first write in this IF scope,
775     * - has already been written in a parent IF scope.
776     * In both cases this write is a secondary write that doesn't contribute
777     * to resolve conditionality.
778     *
779     * Record the write if it
780     * - is the first one (obviously),
781     * - happens in an IF branch that is a child of the ELSE branch of the
782     *   last active IF/ELSE pair. In this case recording this write is used to
783     *   established whether the write is (un-)conditional in the scope enclosing
784     *   this outer IF/ELSE pair.
785     */
786    if (!current_unpaired_if_write_scope ||
787        (current_unpaired_if_write_scope->id() != scope.id() &&
788         scope.is_child_of_ifelse_id_sibling(current_unpaired_if_write_scope)))  {
789       if_scope_write_flags |= 1 << next_ifelse_nesting_depth;
790       current_unpaired_if_write_scope = &scope;
791       next_ifelse_nesting_depth++;
792    }
793 }
794 
record_else_write(const prog_scope & scope)795 void temp_comp_access::record_else_write(const prog_scope& scope)
796 {
797    int mask = 1 << (next_ifelse_nesting_depth - 1);
798 
799    /* If the temporary was written in an IF branch on the same scope level
800     * and this branch is the sibling of this ELSE branch, then we have a
801     * pair of writes that makes write access to this temporary unconditional
802     * in the enclosing scope.
803     */
804 
805    if ((if_scope_write_flags & mask) &&
806        (scope.id() == current_unpaired_if_write_scope->id())) {
807           --next_ifelse_nesting_depth;
808          if_scope_write_flags &= ~mask;
809 
810          /* The following code deals with propagating unconditionality from
811           * inner levels of nested IF/ELSE to the outer levels like in
812           *
813           * 1: var t;
814           * 2: if (a) {        <- start scope A
815           * 3:    if (b)
816           * 4:         t = ...
817           * 5:    else
818           * 6:         t = ...
819           * 7: } else {        <- start scope B
820           * 8:    if (c)
821           * 9:         t = ...
822           * A:    else         <- start scope C
823           * B:         t = ...
824           * C: }
825           *
826           */
827 
828          const prog_scope *parent_ifelse = scope.parent()->in_ifelse_scope();
829 
830          if (1 << (next_ifelse_nesting_depth - 1) & if_scope_write_flags) {
831             /* We are at the end of scope C and already recorded a write
832              * within an IF scope (A), the sibling of the parent ELSE scope B,
833              * and it is not yet resolved. Mark that as the last relevant
834              * IF scope. Below the write will be resolved for the A/B
835              * scope pair.
836              */
837             current_unpaired_if_write_scope = parent_ifelse;
838          } else {
839             current_unpaired_if_write_scope = nullptr;
840          }
841 	 /* Promote the first write scope to the enclosing scope because
842 	  * the current IF/ELSE pair is now irrelevant for the analysis.
843 	  * This is also required to evaluate the minimum life time for t in
844 	  * {
845 	  *    var t;
846 	  *    if (a)
847 	  *      t = ...
848 	  *    else
849 	  *      t = ...
850 	  *    x = t;
851 	  *    ...
852 	  * }
853 	  */
854 	 first_write_scope = scope.parent();
855 
856          /* If some parent is IF/ELSE and in a loop then propagate the
857           * write to that scope. Otherwise the write is unconditional
858           * because it happens in both corresponding IF/ELSE branches
859           * in this loop, and hence, record the loop id to signal the
860           * resolution.
861           */
862          if (parent_ifelse && parent_ifelse->is_in_loop()) {
863             record_ifelse_write(*parent_ifelse);
864          } else {
865             conditionality_in_loop_id = scope.innermost_loop()->id();
866          }
867    } else {
868      /* The temporary was not written in the IF branch corresponding
869       * to this ELSE branch, hence the write is conditional.
870       */
871       conditionality_in_loop_id = write_is_conditional;
872    }
873 }
874 
conditional_ifelse_write_in_loop() const875 bool temp_comp_access::conditional_ifelse_write_in_loop() const
876 {
877    return conditionality_in_loop_id <= conditionality_unresolved;
878 }
879 
propagate_live_range_to_dominant_write_scope()880 void temp_comp_access::propagate_live_range_to_dominant_write_scope()
881 {
882    first_write = first_write_scope->begin();
883    int lr = first_write_scope->end();
884 
885    if (last_read < lr)
886       last_read = lr;
887 }
888 
get_required_live_range()889 register_live_range temp_comp_access::get_required_live_range()
890 {
891    bool keep_for_full_loop = false;
892 
893    /* This register component is not used at all, or only read,
894     * mark it as unused and ignore it when renaming.
895     * glsl_to_tgsi_visitor::renumber_registers will take care of
896     * eliminating registers that are not written to.
897     */
898    if (last_write < 0)
899       return make_live_range(-1, -1);
900 
901    assert(first_write_scope);
902 
903    /* Only written to, just make sure the register component is not
904     * reused in the range it is used to write to
905     */
906    if (!last_read_scope)
907       return make_live_range(first_write, last_write + 1);
908 
909    const prog_scope *enclosing_scope_first_read = first_read_scope;
910    const prog_scope *enclosing_scope_first_write = first_write_scope;
911 
912    /* We read before writing in a loop
913     * hence the value must survive the loops
914     */
915    if ((first_read <= first_write) &&
916        first_read_scope->is_in_loop()) {
917       keep_for_full_loop = true;
918       enclosing_scope_first_read = first_read_scope->outermost_loop();
919    }
920 
921    /* A conditional write within a (nested) loop must survive the outermost
922     * loop if the last read was not within the same scope.
923     */
924    const prog_scope *conditional = enclosing_scope_first_write->enclosing_conditional();
925    if (conditional && !conditional->contains_range_of(*last_read_scope) &&
926        (conditional->is_switchcase_scope_in_loop() ||
927         conditional_ifelse_write_in_loop())) {
928          keep_for_full_loop = true;
929          enclosing_scope_first_write = conditional->outermost_loop();
930    }
931 
932    /* Evaluate the scope that is shared by all: required first write scope,
933     * required first read before write scope, and last read scope.
934     */
935    const prog_scope *enclosing_scope = enclosing_scope_first_read;
936    if (enclosing_scope_first_write->contains_range_of(*enclosing_scope))
937       enclosing_scope = enclosing_scope_first_write;
938 
939    if (last_read_scope->contains_range_of(*enclosing_scope))
940       enclosing_scope = last_read_scope;
941 
942    while (!enclosing_scope->contains_range_of(*enclosing_scope_first_write) ||
943           !enclosing_scope->contains_range_of(*last_read_scope)) {
944       enclosing_scope = enclosing_scope->parent();
945       assert(enclosing_scope);
946    }
947 
948    /* Propagate the last read scope to the target scope */
949    while (enclosing_scope->nesting_depth() < last_read_scope->nesting_depth()) {
950       /* If the read is in a loop and we have to move up the scope we need to
951        * extend the live range to the end of this current loop because at this
952        * point we don't know whether the component was written before
953        * un-conditionally in the same loop.
954        */
955       if (last_read_scope->is_loop())
956          last_read = last_read_scope->end();
957 
958       last_read_scope = last_read_scope->parent();
959    }
960 
961    /* If the variable has to be kept for the whole loop, and we
962     * are currently in a loop, then propagate the live range.
963     */
964    if (keep_for_full_loop && first_write_scope->is_loop())
965       propagate_live_range_to_dominant_write_scope();
966 
967    /* Propagate the first_dominant_write scope to the target scope */
968    while (enclosing_scope->nesting_depth() < first_write_scope->nesting_depth()) {
969       /* Propagate live_range if there was a break in a loop and the write was
970        * after the break inside that loop. Note, that this is only needed if
971        * we move up in the scopes.
972        */
973       if (first_write_scope->loop_break_line() < first_write) {
974          keep_for_full_loop = true;
975 	 propagate_live_range_to_dominant_write_scope();
976       }
977 
978       first_write_scope = first_write_scope->parent();
979 
980       /* Propagte live_range if we are now in a loop */
981       if (keep_for_full_loop && first_write_scope->is_loop())
982 	  propagate_live_range_to_dominant_write_scope();
983    }
984 
985    /* The last write past the last read is dead code, but we have to
986     * ensure that the component is not reused too early, hence extend the
987     * live_range past the last write.
988     */
989    if (last_write >= last_read)
990       last_read = last_write + 1;
991 
992    /* Here we are at the same scope, all is resolved */
993    return make_live_range(first_write, last_read);
994 }
995 
996 /* Helper class for sorting and searching the registers based
997  * on live ranges. */
998 class register_merge_record {
999 public:
1000    int begin;
1001    int end;
1002    int reg;
1003    bool erase;
1004 
operator <(const register_merge_record & rhs) const1005    bool operator < (const register_merge_record& rhs) const {
1006       return begin < rhs.begin;
1007    }
1008 };
1009 
1010 class access_recorder {
1011 public:
1012    access_recorder(int _ntemps, int _narrays);
1013    ~access_recorder();
1014 
1015    void record_read(const st_src_reg& src, int line, prog_scope *scope);
1016    void record_write(const st_dst_reg& src, int line, prog_scope *scope,
1017 		     bool no_reswizzle);
1018 
1019    void get_required_live_ranges(register_live_range *register_live_ranges,
1020 				 array_live_range *array_live_ranges);
1021 private:
1022 
1023    int ntemps;
1024    int narrays;
1025    temp_access *temp_acc;
1026    array_access *array_acc;
1027 };
1028 
access_recorder(int _ntemps,int _narrays)1029 access_recorder::access_recorder(int _ntemps, int _narrays):
1030    ntemps(_ntemps),
1031    narrays(_narrays)
1032 {
1033    temp_acc = new temp_access[ntemps];
1034    array_acc = new array_access[narrays];
1035 }
1036 
~access_recorder()1037 access_recorder::~access_recorder()
1038 {
1039    delete[] array_acc;
1040    delete[] temp_acc;
1041 }
1042 
record_read(const st_src_reg & src,int line,prog_scope * scope)1043 void access_recorder::record_read(const st_src_reg& src, int line,
1044                                   prog_scope *scope)
1045 {
1046    int readmask = 0;
1047    for (int idx = 0; idx < 4; ++idx) {
1048       int swz = GET_SWZ(src.swizzle, idx);
1049       readmask |= (1 << swz) & 0xF;
1050    }
1051 
1052    if (src.file == PROGRAM_TEMPORARY)
1053       temp_acc[src.index].record_read(line, scope, readmask);
1054 
1055    if (src.file == PROGRAM_ARRAY) {
1056       assert(src.array_id <= narrays);
1057       array_acc[src.array_id - 1].record_access(line, scope, readmask);
1058    }
1059 
1060    if (src.reladdr)
1061       record_read(*src.reladdr, line, scope);
1062    if (src.reladdr2)
1063       record_read(*src.reladdr2, line, scope);
1064 }
1065 
record_write(const st_dst_reg & dst,int line,prog_scope * scope,bool can_reswizzle)1066 void access_recorder::record_write(const st_dst_reg& dst, int line,
1067 				   prog_scope *scope, bool can_reswizzle)
1068 {
1069    if (dst.file == PROGRAM_TEMPORARY)
1070       temp_acc[dst.index].record_write(line, scope, dst.writemask);
1071 
1072    if (dst.file == PROGRAM_ARRAY) {
1073       assert(dst.array_id <= narrays);
1074 
1075       /* If the array is written as dst of a multi-dst operation, we must not
1076        * reswizzle the access, because we would have to reswizzle also the
1077        * other dst. For now just fill the mask to make interleaving impossible.
1078        */
1079       array_acc[dst.array_id - 1].record_access(line, scope,
1080 						can_reswizzle ? dst.writemask: 0xF);
1081    }
1082 
1083    if (dst.reladdr)
1084       record_read(*dst.reladdr, line, scope);
1085    if (dst.reladdr2)
1086       record_read(*dst.reladdr2, line, scope);
1087 }
1088 
get_required_live_ranges(struct register_live_range * register_live_ranges,class array_live_range * array_live_ranges)1089 void access_recorder::get_required_live_ranges(struct register_live_range *register_live_ranges,
1090 					       class array_live_range *array_live_ranges)
1091 {
1092    RENAME_DEBUG(debug_log << "== register live ranges ==========\n");
1093    for(int i = 0; i < ntemps; ++i) {
1094       RENAME_DEBUG(debug_log << setw(4) << i);
1095       register_live_ranges[i] = temp_acc[i].get_required_live_range();
1096       RENAME_DEBUG(debug_log << ": [" << register_live_ranges[i].begin << ", "
1097 		   << register_live_ranges[i].end << "]\n");
1098    }
1099    RENAME_DEBUG(debug_log << "==================================\n\n");
1100 
1101    RENAME_DEBUG(debug_log << "== array live ranges ==========\n");
1102    for(int i = 0; i < narrays; ++i) {
1103       RENAME_DEBUG(debug_log<< setw(4) << i);
1104       array_acc[i].get_required_live_range(array_live_ranges[i]);
1105       RENAME_DEBUG(debug_log << ": [" <<array_live_ranges[i].begin() << ", "
1106 			<< array_live_ranges[i].end() << "]\n");
1107    }
1108    RENAME_DEBUG(debug_log << "==================================\n\n");
1109 }
1110 
1111 }
1112 
1113 #ifndef NDEBUG
1114 /* Function used for debugging. */
1115 static void dump_instruction(ostream& os, int line, prog_scope *scope,
1116                              const glsl_to_tgsi_instruction& inst);
1117 #endif
1118 
1119 /* Scan the program and estimate the required register live ranges.
1120  * The arraylive_ranges must be pre-allocated
1121  */
1122 bool
get_temp_registers_required_live_ranges(void * mem_ctx,exec_list * instructions,int ntemps,struct register_live_range * register_live_ranges,int narrays,class array_live_range * array_live_ranges)1123 get_temp_registers_required_live_ranges(void *mem_ctx, exec_list *instructions,
1124 		  int ntemps, struct register_live_range *register_live_ranges,
1125 		  int narrays, class array_live_range *array_live_ranges)
1126 {
1127    int line = 0;
1128    int loop_id = 1;
1129    int if_id = 1;
1130    int switch_id = 0;
1131    bool is_at_end = false;
1132    int n_scopes = 1;
1133 
1134    /* Count scopes to allocate the needed space without the need for
1135     * re-allocation
1136     */
1137    foreach_in_list(glsl_to_tgsi_instruction, inst, instructions) {
1138       if (inst->op == TGSI_OPCODE_BGNLOOP ||
1139           inst->op == TGSI_OPCODE_SWITCH ||
1140           inst->op == TGSI_OPCODE_CASE ||
1141           inst->op == TGSI_OPCODE_IF ||
1142           inst->op == TGSI_OPCODE_UIF ||
1143           inst->op == TGSI_OPCODE_ELSE ||
1144           inst->op == TGSI_OPCODE_DEFAULT)
1145          ++n_scopes;
1146    }
1147 
1148    prog_scope_storage scopes(mem_ctx, n_scopes);
1149 
1150    access_recorder access(ntemps, narrays);
1151 
1152    prog_scope *cur_scope = scopes.create(nullptr, outer_scope, 0, 0, line);
1153 
1154    RENAME_DEBUG(debug_log << "========= Begin shader ============\n");
1155 
1156    foreach_in_list(glsl_to_tgsi_instruction, inst, instructions) {
1157       if (is_at_end) {
1158          assert(!"GLSL_TO_TGSI: shader has instructions past end marker");
1159          break;
1160       }
1161 
1162       RENAME_DEBUG(dump_instruction(debug_log, line, cur_scope, *inst));
1163 
1164       switch (inst->op) {
1165       case TGSI_OPCODE_BGNLOOP: {
1166          cur_scope = scopes.create(cur_scope, loop_body, loop_id++,
1167                                    cur_scope->nesting_depth() + 1, line);
1168          break;
1169       }
1170       case TGSI_OPCODE_ENDLOOP: {
1171          cur_scope->set_end(line);
1172          cur_scope = cur_scope->parent();
1173          assert(cur_scope);
1174          break;
1175       }
1176       case TGSI_OPCODE_IF:
1177       case TGSI_OPCODE_UIF: {
1178          assert(num_inst_src_regs(inst) == 1);
1179          access.record_read(inst->src[0], line, cur_scope);
1180          cur_scope = scopes.create(cur_scope, if_branch, if_id++,
1181                                    cur_scope->nesting_depth() + 1, line + 1);
1182          break;
1183       }
1184       case TGSI_OPCODE_ELSE: {
1185          assert(cur_scope->type() == if_branch);
1186          cur_scope->set_end(line - 1);
1187          cur_scope = scopes.create(cur_scope->parent(), else_branch,
1188                                    cur_scope->id(), cur_scope->nesting_depth(),
1189                                    line + 1);
1190          break;
1191       }
1192       case TGSI_OPCODE_END: {
1193          cur_scope->set_end(line);
1194          is_at_end = true;
1195          break;
1196       }
1197       case TGSI_OPCODE_ENDIF: {
1198          cur_scope->set_end(line - 1);
1199          cur_scope = cur_scope->parent();
1200          assert(cur_scope);
1201          break;
1202       }
1203       case TGSI_OPCODE_SWITCH: {
1204          assert(num_inst_src_regs(inst) == 1);
1205          prog_scope *scope = scopes.create(cur_scope, switch_body, switch_id++,
1206                                            cur_scope->nesting_depth() + 1, line);
1207          /* We record the read only for the SWITCH statement itself, like it
1208           * is used by the only consumer of TGSI_OPCODE_SWITCH in tgsi_exec.c.
1209           */
1210          access.record_read(inst->src[0], line, cur_scope);
1211          cur_scope = scope;
1212          break;
1213       }
1214       case TGSI_OPCODE_ENDSWITCH: {
1215          cur_scope->set_end(line - 1);
1216          /* Remove the case level, it might not have been
1217           * closed with a break.
1218           */
1219          if (cur_scope->type() != switch_body)
1220             cur_scope = cur_scope->parent();
1221 
1222          cur_scope = cur_scope->parent();
1223          assert(cur_scope);
1224          break;
1225       }
1226       case TGSI_OPCODE_CASE: {
1227          /* Take care of tracking the registers. */
1228          prog_scope *switch_scope = cur_scope->type() == switch_body ?
1229                                        cur_scope : cur_scope->parent();
1230 
1231          assert(num_inst_src_regs(inst) == 1);
1232          access.record_read(inst->src[0], line, switch_scope);
1233 
1234          FALLTHROUGH; /* To allocate the scope. */
1235       }
1236       case TGSI_OPCODE_DEFAULT: {
1237          prog_scope_type t = inst->op == TGSI_OPCODE_CASE ? switch_case_branch
1238                                                        : switch_default_branch;
1239          prog_scope *switch_scope = (cur_scope->type() == switch_body) ?
1240             cur_scope : cur_scope->parent();
1241          assert(switch_scope->type() == switch_body);
1242          prog_scope *scope = scopes.create(switch_scope, t,
1243                                            switch_scope->id(),
1244                                            switch_scope->nesting_depth() + 1,
1245                                            line);
1246          /* Previous case falls through, so scope was not yet closed. */
1247          if ((cur_scope != switch_scope) && (cur_scope->end() == -1))
1248             cur_scope->set_end(line - 1);
1249          cur_scope = scope;
1250          break;
1251       }
1252       case TGSI_OPCODE_BRK: {
1253          if (cur_scope->break_is_for_switchcase()) {
1254             cur_scope->set_end(line - 1);
1255          } else {
1256             cur_scope->set_loop_break_line(line);
1257          }
1258          break;
1259       }
1260       case TGSI_OPCODE_CAL:
1261       case TGSI_OPCODE_RET:
1262          /* These opcodes are not supported and if a subroutine would
1263 	  * be called in a shader, then the live_range tracking would have
1264           * to follow that call to see which registers are used there.
1265           * Since this is not done, we have to bail out here and signal
1266           * that no register merge will take place.
1267           */
1268          return false;
1269       default: {
1270          for (unsigned j = 0; j < num_inst_src_regs(inst); j++) {
1271             access.record_read(inst->src[j], line, cur_scope);
1272          }
1273          for (unsigned j = 0; j < inst->tex_offset_num_offset; j++) {
1274             access.record_read(inst->tex_offsets[j], line, cur_scope);
1275          }
1276 	 unsigned ndst = num_inst_dst_regs(inst);
1277 	 for (unsigned j = 0; j < ndst; j++) {
1278 	    access.record_write(inst->dst[j], line, cur_scope, ndst == 1);
1279          }
1280 	 access.record_read(inst->resource, line, cur_scope);
1281       }
1282       }
1283       ++line;
1284    }
1285 
1286    RENAME_DEBUG(debug_log << "==================================\n\n");
1287 
1288    /* Make sure last scope is closed, even though no
1289     * TGSI_OPCODE_END was given.
1290     */
1291    if (cur_scope->end() < 0)
1292       cur_scope->set_end(line - 1);
1293 
1294    access.get_required_live_ranges(register_live_ranges, array_live_ranges);
1295    return true;
1296 }
1297 
1298 /* Find the next register between [start, end) that has a live range starting
1299  * at or after bound by using a binary search.
1300  * start points at the beginning of the search range,
1301  * end points at the element past the end of the search range, and
1302  * the array comprising [start, end) must be sorted in ascending order.
1303  */
1304 static register_merge_record*
find_next_rename(register_merge_record * start,register_merge_record * end,int bound)1305 find_next_rename(register_merge_record* start, register_merge_record* end, int bound)
1306 {
1307    int delta = (end - start);
1308 
1309    while (delta > 0) {
1310       int half = delta >> 1;
1311       register_merge_record* middle = start + half;
1312 
1313       if (bound <= middle->begin) {
1314          delta = half;
1315       } else {
1316          start = middle;
1317          ++start;
1318          delta -= half + 1;
1319       }
1320    }
1321 
1322    return start;
1323 }
1324 
1325 #ifndef USE_STL_SORT
register_merge_record_compare(const void * a,const void * b)1326 static int register_merge_record_compare (const void *a, const void *b) {
1327    const register_merge_record *aa = static_cast<const register_merge_record*>(a);
1328    const register_merge_record *bb = static_cast<const register_merge_record*>(b);
1329    return aa->begin < bb->begin ? -1 : (aa->begin > bb->begin ? 1 : 0);
1330 }
1331 #endif
1332 
1333 /* This functions evaluates the register merges by using a binary
1334  * search to find suitable merge candidates. */
get_temp_registers_remapping(void * mem_ctx,int ntemps,const struct register_live_range * live_ranges,struct rename_reg_pair * result)1335 void get_temp_registers_remapping(void *mem_ctx, int ntemps,
1336 				  const struct register_live_range *live_ranges,
1337 				  struct rename_reg_pair *result)
1338 {
1339    register_merge_record *reg_access = ralloc_array(mem_ctx, register_merge_record, ntemps);
1340 
1341    int used_temps = 0;
1342    for (int i = 0; i < ntemps; ++i) {
1343       if (live_ranges[i].begin >= 0) {
1344 	 reg_access[used_temps].begin =live_ranges[i].begin;
1345 	 reg_access[used_temps].end =live_ranges[i].end;
1346          reg_access[used_temps].reg = i;
1347          reg_access[used_temps].erase = false;
1348          ++used_temps;
1349       }
1350    }
1351 
1352 #ifdef USE_STL_SORT
1353    std::sort(reg_access, reg_access + used_temps);
1354 #else
1355    std::qsort(reg_access, used_temps, sizeof(register_merge_record),
1356 	      register_merge_record_compare);
1357 #endif
1358 
1359    register_merge_record *trgt = reg_access;
1360    register_merge_record *reg_access_end = reg_access + used_temps;
1361    register_merge_record *first_erase = reg_access_end;
1362    register_merge_record *search_start = trgt + 1;
1363 
1364    while (trgt != reg_access_end) {
1365       register_merge_record *src = find_next_rename(search_start, reg_access_end,
1366                                             trgt->end);
1367       if (src != reg_access_end) {
1368          result[src->reg].new_reg = trgt->reg;
1369          result[src->reg].valid = true;
1370          trgt->end = src->end;
1371 
1372          /* Since we only search forward, don't remove the renamed
1373           * register just now, only mark it. */
1374          src->erase = true;
1375 
1376          if (first_erase == reg_access_end)
1377             first_erase = src;
1378 
1379          search_start = src + 1;
1380       } else {
1381          /* Moving to the next target register it is time to remove
1382           * the already merged registers from the search range */
1383          if (first_erase != reg_access_end) {
1384 	    register_merge_record *outp = first_erase;
1385 	    register_merge_record *inp = first_erase + 1;
1386 
1387             while (inp != reg_access_end) {
1388                if (!inp->erase)
1389                   *outp++ = *inp;
1390                ++inp;
1391             }
1392 
1393             reg_access_end = outp;
1394             first_erase = reg_access_end;
1395          }
1396          ++trgt;
1397          search_start = trgt + 1;
1398       }
1399    }
1400    ralloc_free(reg_access);
1401 }
1402 
1403 /* Code below used for debugging */
1404 #ifndef NDEBUG
1405 static
dump_instruction(ostream & os,int line,prog_scope * scope,const glsl_to_tgsi_instruction & inst)1406 void dump_instruction(ostream& os, int line, prog_scope *scope,
1407                       const glsl_to_tgsi_instruction& inst)
1408 {
1409    const struct tgsi_opcode_info *info = inst.info;
1410    int indent = scope->nesting_depth();
1411    if ((scope->type() == switch_case_branch ||
1412         scope->type() == switch_default_branch) &&
1413        (info->opcode == TGSI_OPCODE_CASE ||
1414         info->opcode == TGSI_OPCODE_DEFAULT))
1415       --indent;
1416 
1417    if (info->opcode == TGSI_OPCODE_ENDIF ||
1418        info->opcode == TGSI_OPCODE_ELSE ||
1419        info->opcode == TGSI_OPCODE_ENDLOOP ||
1420        info->opcode == TGSI_OPCODE_ENDSWITCH)
1421       --indent;
1422 
1423    os << setw(4) << line << ": ";
1424    os << setw(indent * 4) << " ";
1425    os << inst << "\n";
1426 }
1427 #endif
1428