st/mesa: factor ucp-lowering logic into helper
[mesa.git] / src / mesa / state_tracker / st_glsl_to_tgsi_temprename.cpp
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 */
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
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
271 prog_scope_storage::~prog_scope_storage()
272 {
273 ralloc_free(storage);
274 }
275
276 prog_scope*
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
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
296 prog_scope_type prog_scope::type() const
297 {
298 return scope_type;
299 }
300
301 prog_scope *prog_scope::parent() const
302 {
303 return parent_scope;
304 }
305
306 int prog_scope::nesting_depth() const
307 {
308 return scope_nesting_depth;
309 }
310
311 bool prog_scope::is_loop() const
312 {
313 return (scope_type == loop_body);
314 }
315
316 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
327 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
338 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
352 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
367 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
378 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
389 bool prog_scope::contains_range_of(const prog_scope& other) const
390 {
391 return (begin() <= other.begin()) && (end() >= other.end());
392 }
393
394 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
402 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
413 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
421 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
433 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
440 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
456 int prog_scope::id() const
457 {
458 return scope_id;
459 }
460
461 int prog_scope::begin() const
462 {
463 return scope_begin;
464 }
465
466 int prog_scope::end() const
467 {
468 return scope_end;
469 }
470
471 void prog_scope::set_end(int end)
472 {
473 if (scope_end == -1)
474 scope_end = end;
475 }
476
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
487 int prog_scope::loop_break_line() const
488 {
489 return break_loop_line;
490 }
491
492 temp_access::temp_access():
493 access_mask(0),
494 needs_component_tracking(false)
495 {
496 }
497
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
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
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
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
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
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
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
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
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
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
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
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
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
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
875 bool temp_comp_access::conditional_ifelse_write_in_loop() const
876 {
877 return conditionality_in_loop_id <= conditionality_unresolved;
878 }
879
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
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
1005 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
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
1037 access_recorder::~access_recorder()
1038 {
1039 delete[] array_acc;
1040 delete[] temp_acc;
1041 }
1042
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
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
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
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 /* Fall through 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*
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
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. */
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
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