2 * Copyright 2013 Vadim Girlin <vadimgirlin@gmail.com>
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * on the rights to use, copy, modify, merge, publish, distribute, sub
8 * license, and/or sell copies of the Software, and to permit persons to whom
9 * the Software is furnished to do so, subject to the following conditions:
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
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
20 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
21 * USE OR OTHER DEALINGS IN THE SOFTWARE.
27 #include "sb_shader.h"
33 bool r600_sb::psi_ops::visit(alu_node
& n
, bool enter
) {
39 bool psi_ops::visit(node
& n
, bool enter
) {
41 assert(n
.subtype
== NST_PSI
);
45 // TODO eliminate predication until there is full support in all passes
46 // unpredicate instructions and replace psi-nodes with conditional moves
52 value
* get_pred_val(node
&n
) {
53 value
*pred_val
= NULL
;
55 for (vvec::iterator I
= n
.src
.begin(), E
= n
.src
.end(); I
!= E
; I
+= 3) {
61 assert(pred
== pred_val
);
68 // for now we'll never inline psi's with different predicate values,
69 // so psi node may only contain the refs to one predicate value.
70 bool psi_ops::try_inline(node
& n
) {
71 assert(n
.subtype
== NST_PSI
);
76 assert(sz
&& (sz
% 3 == 0));
78 value
*pred_val
= get_pred_val(n
);
84 for (int i
= sz
- 1; i
>= 0; i
-= 3) {
87 ns
.erase(ns
.begin(), ns
.begin() + i
+ 1);
92 value
* predsel
= ns
[i
-1];
93 int ps
= !predsel
? 3 : predsel
== sh
.get_pred_sel(0) ? 1 : 2;
97 if (val
->def
->subtype
== NST_PSI
&& ps
== 3) {
98 if (get_pred_val(*val
->def
) != pred_val
)
101 vvec
&ds
= val
->def
->src
;
103 ns
.insert(ns
.begin() + i
+ 1, ds
.begin(), ds
.end());
104 ns
.erase(ns
.begin() + i
- 2, ns
.begin() + i
+ 1);
109 if ((ps_mask
& ps
) == ps
) {
110 // this predicate select is subsumed by already handled ops
111 ns
.erase(ns
.begin() + i
- 2, ns
.begin() + i
+ 1);
120 bool psi_ops::try_reduce(node
& n
) {
121 assert(n
.subtype
== NST_PSI
);
122 assert(n
.src
.size() % 3 == 0);
129 void psi_ops::unpredicate(node
*n
) {
131 if (!n
->is_alu_inst())
134 alu_node
*a
= static_cast<alu_node
*>(n
);
138 bool psi_ops::eliminate(node
& n
) {
139 assert(n
.subtype
== NST_PSI
);
140 assert(n
.src
.size() == 6);
144 value
*s1
= n
.src
[2];
145 value
*s2
= n
.src
[5];
147 value
*pred
= n
.src
[3];
149 bool psel
= n
.src
[4] == sh
.get_pred_sel(0);
151 value
*sel
= get_select_value_for_em(sh
, pred
);
153 if (s1
->is_undef()) {
154 if (s2
->is_undef()) {
157 n
.insert_after(sh
.create_mov(d
, s2
));
159 } else if (s2
->is_undef()) {
160 n
.insert_after(sh
.create_mov(d
, s1
));
162 alu_node
*a
= sh
.create_alu();
163 a
->bc
.set_op(ALU_OP3_CNDE_INT
);
166 a
->src
.push_back(sel
);
169 a
->src
.push_back(s1
);
170 a
->src
.push_back(s2
);
172 a
->src
.push_back(s2
);
173 a
->src
.push_back(s1
);
181 if (s1
->is_any_gpr() && !s1
->is_undef() && s1
->def
)
182 unpredicate(s1
->def
);
183 if (s2
->is_any_gpr() && !s2
->is_undef() && s2
->def
)
184 unpredicate(s2
->def
);
189 } // namespace r600_sb