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