00aee66f25b82288e8991899864812b632eca6d9
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.
30 #define VT_DUMP(q) do { q } while (0)
37 #include "sb_shader.h"
42 static const char * chans
= "xyzw01?_";
44 sb_ostream
& operator << (sb_ostream
&o
, value
&v
) {
46 bool dead
= v
.flags
& VLF_DEAD
;
52 case VLK_SPECIAL_REG
: {
53 switch (v
.select
.sel()) {
54 case SV_AR_INDEX
: o
<< "AR"; break;
55 case SV_ALU_PRED
: o
<< "PR"; break;
56 case SV_EXEC_MASK
: o
<< "EM"; break;
57 case SV_VALID_MASK
: o
<< "VM"; break;
58 default: o
<< "???specialreg"; break;
64 o
<< "R" << v
.select
.sel() << "."
65 << chans
[v
.select
.chan()];
69 o
<< "C" << v
.select
.sel() << "." << chans
[v
.select
.chan()];
73 o
<< v
.literal_value
.f
<< "|";
74 o
.print_zw_hex(v
.literal_value
.u
, 8);
77 o
<< "Param" << (v
.select
.sel() - ALU_SRC_PARAM_OFFSET
)
78 << chans
[v
.select
.chan()];
81 o
<< "t" << v
.select
.sel() - shader::temp_regid_offset
;
97 o
<< v
.kind
<< "?????";
102 o
<< "." << v
.version
;
123 o
<< "@R" << g
.sel() << "." << chans
[g
.chan()];
129 void value_table::add_value(value
* v
) {
136 sblog
<< "gvn add_value ";
140 value_hash hash
= v
->hash();
141 vt_item
& vti
= hashtable
[hash
& size_mask
];
145 if (v
->def
&& ex
.try_fold(v
)) {
147 sblog
<< " folded: ";
148 dump::dump_val(v
->gvn_source
);
155 for (vt_item::iterator I
= vti
.begin(), E
= vti
.end(); I
!= E
; ++I
, ++n
) {
161 if (expr_equal(c
, v
)) {
162 v
->gvn_source
= c
->gvn_source
;
165 sblog
<< " found : equal to ";
166 dump::dump_val(v
->gvn_source
);
175 sblog
<< " added new\n";
179 value_hash
value::hash() {
187 ghash
= ((uintptr_t)this) | 1;
192 value_hash
value::rel_hash() {
193 value_hash h
= rel
? rel
->hash() : 0;
199 bool value_table::expr_equal(value
* l
, value
* r
) {
200 return ex
.equal(l
, r
);
203 void value_table::get_values(vvec
& v
) {
206 vvec::iterator T
= v
.begin();
208 for(vt_table::iterator I
= hashtable
.begin(), E
= hashtable
.end();
210 T
= std::copy(I
->begin(), I
->end(), T
);
214 void value::add_use(node
* n
, use_kind kind
, int arg
) {
217 dump::dump_val(this);
220 sblog
<< " kind " << kind
<< " arg " << arg
<< "\n";
222 uses
= new use_info(n
, kind
, arg
, uses
);
225 unsigned value::use_count() {
235 bool value::is_global() {
237 return chunk
->is_global();
238 return flags
& VLF_GLOBAL
;
241 void value::set_global() {
248 void value::set_prealloc() {
250 flags
|= VLF_PREALLOC
;
252 chunk
->set_prealloc();
255 bool value::is_fixed() {
256 if (array
&& array
->gpr
)
259 return chunk
->is_fixed();
260 return flags
& VLF_FIXED
;
269 bool value::is_prealloc() {
271 return chunk
->is_prealloc();
272 return flags
& VLF_PREALLOC
;
275 void value::delete_uses() {
276 use_info
*u
, *c
= uses
;
285 void ra_constraint::update_values() {
286 for (vvec::iterator I
= values
.begin(), E
= values
.end(); I
!= E
; ++I
) {
287 assert(!(*I
)->constraint
);
288 (*I
)->constraint
= this;
292 void* sb_pool::allocate(unsigned sz
) {
293 sz
= (sz
+ SB_POOL_ALIGN
- 1) & ~(SB_POOL_ALIGN
- 1);
294 assert (sz
< (block_size
>> 6) && "too big allocation size for sb_pool");
296 unsigned offset
= total_size
% block_size
;
297 unsigned capacity
= block_size
* blocks
.size();
299 if (total_size
+ sz
> capacity
) {
300 total_size
= capacity
;
301 void * nb
= malloc(block_size
);
302 blocks
.push_back(nb
);
307 return ((char*)blocks
.back() + offset
);
310 void sb_pool::free_all() {
311 for (block_vector::iterator I
= blocks
.begin(), E
= blocks
.end(); I
!= E
;
317 value
* sb_value_pool::create(value_kind k
, sel_chan regid
,
319 void* np
= allocate(aligned_elt_size
);
320 value
*v
= new (np
) value(size(), k
, regid
, ver
);
324 void sb_value_pool::delete_all() {
325 unsigned bcnt
= blocks
.size();
326 unsigned toffset
= 0;
327 for (unsigned b
= 0; b
< bcnt
; ++b
) {
328 char *bstart
= (char*)blocks
[b
];
329 for (unsigned offset
= 0; offset
< block_size
;
330 offset
+= aligned_elt_size
) {
331 ((value
*)(bstart
+ offset
))->~value();
332 toffset
+= aligned_elt_size
;
333 if (toffset
>= total_size
)
339 bool sb_bitset::get(unsigned id
) {
340 assert(id
< bit_size
);
341 unsigned w
= id
/ bt_bits
;
342 unsigned b
= id
% bt_bits
;
343 return (data
[w
] >> b
) & 1;
346 void sb_bitset::set(unsigned id
, bool bit
) {
347 assert(id
< bit_size
);
348 unsigned w
= id
/ bt_bits
;
349 unsigned b
= id
% bt_bits
;
350 if (w
>= data
.size())
356 data
[w
] &= ~(1 << b
);
359 inline bool sb_bitset::set_chk(unsigned id
, bool bit
) {
360 assert(id
< bit_size
);
361 unsigned w
= id
/ bt_bits
;
362 unsigned b
= id
% bt_bits
;
363 basetype d
= data
[w
];
364 basetype dn
= (d
& ~(1 << b
)) | (bit
<< b
);
366 data
[w
] = r
? dn
: data
[w
];
370 void sb_bitset::clear() {
371 std::fill(data
.begin(), data
.end(), 0);
374 void sb_bitset::resize(unsigned size
) {
375 unsigned cur_data_size
= data
.size();
376 unsigned new_data_size
= (size
+ bt_bits
- 1) / bt_bits
;
379 if (new_data_size
!= cur_data_size
)
380 data
.resize(new_data_size
);
382 // make sure that new bits in the existing word are cleared
383 if (cur_data_size
&& size
> bit_size
&& bit_size
% bt_bits
) {
384 basetype clear_mask
= (~(basetype
)0u) << (bit_size
% bt_bits
);
385 data
[cur_data_size
- 1] &= ~clear_mask
;
391 unsigned sb_bitset::find_bit(unsigned start
) {
392 assert(start
< bit_size
);
393 unsigned w
= start
/ bt_bits
;
394 unsigned b
= start
% bt_bits
;
395 unsigned sz
= data
.size();
398 basetype d
= data
[w
] >> b
;
400 unsigned pos
= __builtin_ctz(d
) + b
+ w
* bt_bits
;
411 sb_value_set::iterator::iterator(shader
& sh
, sb_value_set
* s
, unsigned nb
)
412 : vp(sh
.get_value_pool()), s(s
), nb(nb
) {}
414 bool sb_value_set::add_set_checked(sb_value_set
& s2
) {
415 if (bs
.size() < s2
.bs
.size())
416 bs
.resize(s2
.bs
.size());
417 sb_bitset nbs
= bs
| s2
.bs
;
425 void r600_sb::sb_value_set::remove_set(sb_value_set
& s2
) {
429 bool sb_value_set::add_val(value
* v
) {
431 if (bs
.size() < v
->uid
)
432 bs
.resize(v
->uid
+ 32);
434 return bs
.set_chk(v
->uid
- 1, 1);
437 bool sb_value_set::remove_vec(vvec
& vv
) {
438 bool modified
= false;
439 for (vvec::iterator I
= vv
.begin(), E
= vv
.end(); I
!= E
; ++I
) {
441 modified
|= remove_val(*I
);
446 void sb_value_set::clear() {
450 bool sb_value_set::remove_val(value
* v
) {
452 if (bs
.size() < v
->uid
)
454 return bs
.set_chk(v
->uid
- 1, 0);
457 bool r600_sb::sb_value_set::add_vec(vvec
& vv
) {
458 bool modified
= false;
459 for (vvec::iterator I
= vv
.begin(), E
= vv
.end(); I
!= E
; ++I
) {
462 modified
|= add_val(v
);
467 bool r600_sb::sb_value_set::contains(value
* v
) {
468 unsigned b
= v
->uid
- 1;
470 return bs
.get(v
->uid
- 1);
475 bool sb_value_set::empty() {
476 return bs
.size() == 0 || bs
.find_bit(0) == bs
.size();
479 void sb_bitset::swap(sb_bitset
& bs2
) {
480 std::swap(data
, bs2
.data
);
481 std::swap(bit_size
, bs2
.bit_size
);
484 bool sb_bitset::operator ==(const sb_bitset
& bs2
) {
485 if (bit_size
!= bs2
.bit_size
)
488 for (unsigned i
= 0, c
= data
.size(); i
< c
; ++i
) {
489 if (data
[i
] != bs2
.data
[i
])
495 sb_bitset
& sb_bitset::operator &=(const sb_bitset
& bs2
) {
496 if (bit_size
> bs2
.bit_size
) {
497 resize(bs2
.bit_size
);
500 for (unsigned i
= 0, c
= std::min(data
.size(), bs2
.data
.size()); i
< c
;
502 data
[i
] &= bs2
.data
[i
];
507 sb_bitset
& sb_bitset::mask(const sb_bitset
& bs2
) {
508 if (bit_size
< bs2
.bit_size
) {
509 resize(bs2
.bit_size
);
512 for (unsigned i
= 0, c
= data
.size(); i
< c
;
514 data
[i
] &= ~bs2
.data
[i
];
519 bool ra_constraint::check() {
520 assert(kind
== CK_SAME_REG
);
524 for (vvec::iterator I
= values
.begin(), E
= values
.end(); I
!= E
; ++I
) {
533 reg
= v
->gpr
.sel() + 1;
534 else if (reg
!= v
->gpr
.sel() + 1)
537 if (v
->is_chan_pinned()) {
538 if (v
->pin_gpr
.chan() != v
->gpr
.chan())
545 bool gpr_array::is_dead() {
549 } // namespace r600_sb