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.
56 sel_chan(unsigned id
= 0) : id(id
) {}
57 sel_chan(unsigned sel
, unsigned chan
) : id(((sel
<< 2) | chan
) + 1) {}
59 unsigned sel() const { return sel(id
); }
60 unsigned chan() const {return chan(id
); }
61 operator unsigned() const {return id
;}
63 static unsigned sel(unsigned idx
) { return (idx
-1) >> 2; }
64 static unsigned chan(unsigned idx
) { return (idx
-1) & 3; }
66 sel_chan(unsigned bank
, unsigned index
,
67 unsigned chan
, alu_kcache_index_mode index_mode
)
68 : id(sel_chan((bank
<< 12) | index
| ((unsigned)index_mode
<< 28), chan
).id
) {}
69 unsigned kcache_index_mode() const { return sel() >> 28; }
70 unsigned kcache_sel() const { return sel() & 0x0fffffffu
; }
71 unsigned kcache_bank() const { return kcache_sel() >> 12; }
74 inline sb_ostream
& operator <<(sb_ostream
& o
, sel_chan r
) {
75 static const char * ch
= "xyzw";
76 o
<< r
.sel() << "." << ch
[r
.chan()];
80 typedef std::vector
<value
*> vvec
;
84 static const unsigned SB_POOL_ALIGN
= 8;
85 static const unsigned SB_POOL_DEFAULT_BLOCK_SIZE
= (1 << 16);
87 typedef std::vector
<void*> block_vector
;
94 sb_pool(unsigned block_size
= SB_POOL_DEFAULT_BLOCK_SIZE
)
95 : block_size(block_size
), blocks(), total_size() {}
97 virtual ~sb_pool() { free_all(); }
99 void* allocate(unsigned sz
);
105 template <typename V
, typename Comp
= std::less
<V
> >
107 typedef std::vector
<V
> data_vector
;
111 typedef typename
data_vector::iterator iterator
;
112 typedef typename
data_vector::const_iterator const_iterator
;
117 iterator
begin() { return vec
.begin(); }
118 iterator
end() { return vec
.end(); }
119 const_iterator
begin() const { return vec
.begin(); }
120 const_iterator
end() const { return vec
.end(); }
122 void add_set(const sb_set
& s
) {
124 t
.reserve(vec
.size() + s
.vec
.size());
125 std::set_union(vec
.begin(), vec
.end(), s
.vec
.begin(), s
.vec
.end(),
126 std::inserter(t
, t
.begin()), Comp());
130 iterator
lower_bound(const V
& v
) {
131 return std::lower_bound(vec
.begin(), vec
.end(), v
, Comp());
134 std::pair
<iterator
, bool> insert(const V
& v
) {
135 iterator P
= lower_bound(v
);
136 if (P
!= vec
.end() && is_equal(*P
, v
))
137 return std::make_pair(P
, false);
138 return std::make_pair(vec
.insert(P
, v
), true);
141 unsigned erase(const V
& v
) {
142 iterator P
= lower_bound(v
);
143 if (P
== vec
.end() || !is_equal(*P
, v
))
149 void clear() { vec
.clear(); }
151 bool empty() { return vec
.empty(); }
153 bool is_equal(const V
& v1
, const V
& v2
) {
154 return !Comp()(v1
, v2
) && !Comp()(v2
, v1
);
157 iterator
find(const V
& v
) {
158 iterator P
= lower_bound(v
);
159 return (P
!= vec
.end() && is_equal(*P
, v
)) ? P
: vec
.end();
162 unsigned size() { return vec
.size(); }
163 void erase(iterator I
) { vec
.erase(I
); }
166 template <typename K
, typename V
, typename KComp
= std::less
<K
> >
168 typedef std::pair
<K
, V
> datatype
;
171 bool operator()(const datatype
&v1
, const datatype
&v2
) {
172 return KComp()(v1
.first
, v2
.first
);
176 typedef sb_set
<datatype
, Comp
> dataset
;
184 typedef typename
dataset::iterator iterator
;
186 iterator
begin() { return set
.begin(); }
187 iterator
end() { return set
.end(); }
189 void clear() { set
.clear(); }
191 V
& operator[](const K
& key
) {
192 datatype P
= std::make_pair(key
, V());
193 iterator F
= set
.find(P
);
194 if (F
== set
.end()) {
195 return (*(set
.insert(P
).first
)).second
;
201 std::pair
<iterator
, bool> insert(const datatype
& d
) {
202 return set
.insert(d
);
205 iterator
find(const K
& key
) {
206 return set
.find(std::make_pair(key
, V()));
209 unsigned erase(const K
& key
) {
210 return set
.erase(std::make_pair(key
, V()));
213 void erase(iterator I
) {
219 typedef uint32_t basetype
;
220 static const unsigned bt_bits
= sizeof(basetype
) << 3;
221 std::vector
<basetype
> data
;
226 sb_bitset() : data(), bit_size() {}
228 bool get(unsigned id
);
229 void set(unsigned id
, bool bit
= true);
230 bool set_chk(unsigned id
, bool bit
= true);
233 void resize(unsigned size
);
235 unsigned size() { return bit_size
; }
237 unsigned find_bit(unsigned start
= 0);
239 void swap(sb_bitset
& bs2
);
241 bool operator==(const sb_bitset
&bs2
);
242 bool operator!=(const sb_bitset
&bs2
) { return !(*this == bs2
); }
244 sb_bitset
& operator|=(const sb_bitset
&bs2
) {
245 if (bit_size
< bs2
.bit_size
) {
246 resize(bs2
.bit_size
);
249 for (unsigned i
= 0, c
= std::min(data
.size(), bs2
.data
.size()); i
< c
;
251 data
[i
] |= bs2
.data
[i
];
256 sb_bitset
& operator&=(const sb_bitset
&bs2
);
257 sb_bitset
& mask(const sb_bitset
&bs2
);
259 friend sb_bitset
operator|(const sb_bitset
&b1
, const sb_bitset
&b2
) {
284 class sb_value_pool
: protected sb_pool
{
285 unsigned aligned_elt_size
;
288 sb_value_pool(unsigned elt_size
, unsigned block_elts
= 256)
289 : sb_pool(block_elts
* (aligned_elt_size
= ((elt_size
+
290 SB_POOL_ALIGN
- 1) & ~(SB_POOL_ALIGN
- 1)))) {}
292 virtual ~sb_value_pool() { delete_all(); }
294 value
* create(value_kind k
, sel_chan regid
, unsigned ver
);
296 value
* operator[](unsigned id
) {
297 unsigned offset
= id
* aligned_elt_size
;
299 if (offset
< block_size
) {
302 block_id
= offset
/ block_size
;
303 offset
= offset
% block_size
;
305 return (value
*)((char*)blocks
[block_id
] + offset
);
308 unsigned size() { return total_size
/ aligned_elt_size
; }
323 sb_value_set() : bs() {}
330 iterator(shader
&sh
, sb_value_set
*s
, unsigned nb
= 0);
333 iterator
& operator++() {
334 if (nb
+ 1 < s
->bs
.size())
335 nb
= s
->bs
.find_bit(nb
+ 1);
340 bool operator !=(const iterator
&i
) {
341 return s
!= i
.s
|| nb
!= i
.nb
;
343 bool operator ==(const iterator
&i
) { return !(*this != i
); }
344 value
* operator *() {
351 iterator
begin(shader
&sh
) {
352 return iterator(sh
, this, bs
.size() ? bs
.find_bit(0) : 0);
354 iterator
end(shader
&sh
) { return iterator(sh
, this, bs
.size()); }
356 bool add_set_checked(sb_value_set
& s2
);
358 void add_set(sb_value_set
& s2
) {
359 if (bs
.size() < s2
.bs
.size())
360 bs
.resize(s2
.bs
.size());
364 void remove_set(sb_value_set
& s2
);
366 bool add_vec(vvec
&vv
);
368 bool add_val(value
*v
);
369 bool contains(value
*v
);
371 bool remove_val(value
*v
);
373 bool remove_vec(vvec
&vv
);
380 typedef sb_value_set val_set
;
383 sel_chan base_gpr
; // original gpr
384 sel_chan gpr
; // assigned by regalloc
387 gpr_array(sel_chan base_gpr
, unsigned array_size
) : base_gpr(base_gpr
),
388 array_size(array_size
) {}
390 unsigned hash() { return (base_gpr
<< 10) * array_size
; }
392 val_set interferences
;
399 typedef std::vector
<gpr_array
*> regarray_vec
;
402 VLF_UNDEF
= (1 << 0),
403 VLF_READONLY
= (1 << 1),
406 VLF_PIN_REG
= (1 << 3),
407 VLF_PIN_CHAN
= (1 << 4),
409 // opposite to alu clause local value - goes through alu clause boundary
410 // (can't use temp gpr, can't recolor in the alu scheduler, etc)
411 VLF_GLOBAL
= (1 << 5),
412 VLF_FIXED
= (1 << 6),
415 VLF_PREALLOC
= (1 << 8)
418 inline value_flags
operator |(value_flags l
, value_flags r
) {
419 return (value_flags
)((unsigned)l
|(unsigned)r
);
421 inline value_flags
operator &(value_flags l
, value_flags r
) {
422 return (value_flags
)((unsigned)l
&(unsigned)r
);
424 inline value_flags
operator ~(value_flags l
) {
425 return (value_flags
)(~(unsigned)l
);
427 inline value_flags
& operator |=(value_flags
&l
, value_flags r
) {
431 inline value_flags
& operator &=(value_flags
&l
, value_flags r
) {
438 sb_ostream
& operator << (sb_ostream
&o
, value
&v
);
440 typedef uint32_t value_hash
;
458 use_info(node
*n
, use_kind kind
, int arg
, use_info
* next
)
459 : next(next
), op(n
), kind(kind
), arg(arg
) {}
462 enum constraint_kind
{
475 value(unsigned sh_id
, value_kind k
, sel_chan select
, unsigned ver
= 0)
478 version(ver
), select(select
), pin_gpr(select
), gpr(),
479 gvn_source(), ghash(),
480 def(), adef(), uses(), constraint(), chunk(),
481 literal_value(), uid(sh_id
) {}
483 ~value() { delete_uses(); }
485 friend class sb_value_pool
;
507 ra_constraint
*constraint
;
510 literal literal_value
;
512 bool is_const() { return kind
== VLK_CONST
|| kind
== VLK_UNDEF
; }
515 return is_special_reg() && select
== sel_chan(SV_AR_INDEX
, 0);
517 bool is_geometry_emit() {
518 return is_special_reg() && select
== sel_chan(SV_GEOMETRY_EMIT
, 0);
522 assert(!(def
&& adef
));
523 return def
? def
: adef
;
528 while (v
->gvn_source
&& v
!= v
->gvn_source
)
529 // FIXME we really shouldn't have such chains
534 bool is_float_0_or_1() {
536 return v
->is_const() && (v
->literal_value
== literal(0)
537 || v
->literal_value
== literal(1.0f
));
540 bool is_undef() { return gvalue()->kind
== VLK_UNDEF
; }
543 return (kind
== VLK_REG
|| kind
== VLK_TEMP
);
547 return array
&& is_any_gpr();
550 // scalar gpr, as opposed to element of gpr array
552 return !array
&& is_any_gpr();
555 bool is_special_reg() { return kind
== VLK_SPECIAL_REG
; }
556 bool is_any_reg() { return is_any_gpr() || is_special_reg(); }
557 bool is_kcache() { return kind
== VLK_KCACHE
; }
558 bool is_rel() { return kind
== VLK_REL_REG
; }
559 bool is_readonly() { return flags
& VLF_READONLY
; }
561 bool is_chan_pinned() { return flags
& VLF_PIN_CHAN
; }
562 bool is_reg_pinned() { return flags
& VLF_PIN_REG
; }
573 bool is_dead() { return flags
& VLF_DEAD
; }
575 literal
& get_const_value() {
577 assert(v
->is_const());
578 return v
->literal_value
;
581 // true if needs to be encoded as literal in alu
584 && literal_value
!= literal(0)
585 && literal_value
!= literal(1)
586 && literal_value
!= literal(-1)
587 && literal_value
!= literal(0.5)
588 && literal_value
!= literal(1.0);
591 void add_use(node
*n
, use_kind kind
, int arg
);
594 value_hash
rel_hash();
596 void assign_source(value
*v
) {
597 assert(!gvn_source
|| gvn_source
== this);
598 gvn_source
= v
->gvalue();
601 bool v_equal(value
*v
) { return gvalue() == v
->gvalue(); }
603 unsigned use_count();
606 sel_chan
get_final_gpr() {
607 if (array
&& array
->gpr
) {
608 int reg_offset
= select
.sel() - array
->base_gpr
.sel();
609 if (rel
&& rel
->is_const())
610 reg_offset
+= rel
->get_const_value().i
;
611 return array
->gpr
+ (reg_offset
<< 2);
617 unsigned get_final_chan() {
620 return array
->gpr
.chan();
627 val_set interferences
;
634 typedef std::vector
<value
*> vt_item
;
635 typedef std::vector
<vt_item
> vt_table
;
649 value_table(expr_handler
&ex
, unsigned size_bits
= 10)
650 : ex(ex
), size_bits(size_bits
), size(1u << size_bits
),
651 size_mask(size
- 1), hashtable(size
), cnt() {}
655 void add_value(value
* v
);
657 bool expr_equal(value
* l
, value
* r
);
659 unsigned count() { return cnt
; }
661 void get_values(vvec
& v
);
694 NST_LOOP_PHI_CONTAINER
,
702 NF_REG_CONSTRAINT
= (1 << 1),
703 NF_CHAN_CONSTRAINT
= (1 << 2),
704 NF_ALU_4SLOT
= (1 << 3),
705 NF_CONTAINER
= (1 << 4),
707 NF_COPY_MOV
= (1 << 5),
709 NF_DONT_KILL
= (1 << 6),
710 NF_DONT_HOIST
= (1 << 7),
711 NF_DONT_MOVE
= (1 << 8),
713 // for KILLxx - we want to schedule them as early as possible
714 NF_SCHEDULE_EARLY
= (1 << 9),
716 // for ALU_PUSH_BEFORE - when set, replace with PUSH + ALU
717 NF_ALU_STACK_WORKAROUND
= (1 << 10)
720 inline node_flags
operator |(node_flags l
, node_flags r
) {
721 return (node_flags
)((unsigned)l
|(unsigned)r
);
723 inline node_flags
& operator |=(node_flags
&l
, node_flags r
) {
728 inline node_flags
& operator &=(node_flags
&l
, node_flags r
) {
729 l
= (node_flags
)((unsigned)l
& (unsigned)r
);
733 inline node_flags
operator ~(node_flags r
) {
734 return (node_flags
)~(unsigned)r
;
739 unsigned alu_kill_count
;
740 unsigned alu_copy_mov_count
;
742 unsigned fetch_count
;
743 unsigned region_count
;
746 unsigned loop_phi_count
;
747 unsigned depart_count
;
748 unsigned repeat_count
;
751 node_stats() : alu_count(), alu_kill_count(), alu_copy_mov_count(),
752 cf_count(), fetch_count(), region_count(),
753 loop_count(), phi_count(), loop_phi_count(), depart_count(),
754 repeat_count(), if_count() {}
763 class container_node
;
769 node(node_type nt
, node_subtype nst
, node_flags flags
= NF_EMPTY
)
770 : prev(), next(), parent(),
771 type(nt
), subtype(nst
), flags(flags
),
772 pred(), dst(), src() {}
778 container_node
*parent
;
781 node_subtype subtype
;
789 virtual bool is_valid() { return true; }
790 virtual bool accept(vpass
&p
, bool enter
);
792 void insert_before(node
*n
);
793 void insert_after(node
*n
);
794 void replace_with(node
*n
);
797 virtual value_hash
hash();
798 value_hash
hash_src();
800 virtual bool fold_dispatch(expr_handler
*ex
);
802 bool is_container() { return flags
& NF_CONTAINER
; }
804 bool is_alu_packed() { return subtype
== NST_ALU_PACKED_INST
; }
805 bool is_alu_inst() { return subtype
== NST_ALU_INST
; }
806 bool is_alu_group() { return subtype
== NST_ALU_GROUP
; }
807 bool is_alu_clause() { return subtype
== NST_ALU_CLAUSE
; }
809 bool is_fetch_clause() {
810 return subtype
== NST_TEX_CLAUSE
|| subtype
== NST_VTX_CLAUSE
;
813 bool is_copy() { return subtype
== NST_COPY
; }
814 bool is_copy_mov() { return flags
& NF_COPY_MOV
; }
815 bool is_any_alu() { return is_alu_inst() || is_alu_packed() || is_copy(); }
817 bool is_fetch_inst() { return subtype
== NST_FETCH_INST
; }
818 bool is_cf_inst() { return subtype
== NST_CF_INST
; }
820 bool is_region() { return type
== NT_REGION
; }
821 bool is_depart() { return type
== NT_DEPART
; }
822 bool is_repeat() { return type
== NT_REPEAT
; }
823 bool is_if() { return type
== NT_IF
; }
824 bool is_bb() { return subtype
== NST_BB
; }
826 bool is_phi() { return subtype
== NST_PHI
; }
828 bool is_dead() { return flags
& NF_DEAD
; }
830 bool is_cf_op(unsigned op
);
831 bool is_alu_op(unsigned op
);
832 bool is_fetch_op(unsigned op
);
834 unsigned cf_op_flags();
835 unsigned alu_op_flags();
836 unsigned alu_op_slot_flags();
837 unsigned fetch_op_flags();
842 bool vec_uses_ar(vvec
&vv
) {
843 for (vvec::iterator I
= vv
.begin(), E
= vv
.end(); I
!= E
; ++I
) {
845 if (v
&& v
->rel
&& !v
->rel
->is_const())
852 return vec_uses_ar(dst
) || vec_uses_ar(src
);
856 region_node
* get_parent_region();
861 class container_node
: public node
{
864 container_node(node_type nt
= NT_LIST
, node_subtype nst
= NST_LIST
,
865 node_flags flags
= NF_EMPTY
)
866 : node(nt
, nst
, flags
| NF_CONTAINER
), first(), last(),
867 live_after(), live_before() {}
878 iterator(node
*pp
= NULL
) : p(pp
) {}
879 iterator
& operator ++() { p
= p
->next
; return *this;}
880 iterator
& operator --() { p
= p
->prev
; return *this;}
881 node
* operator *() { return p
; }
882 node
* operator ->() { return p
; }
883 const iterator
advance(int n
) {
884 if (!n
) return *this;
886 if (n
> 0) while (n
--) ++I
;
887 else while (n
++) --I
;
890 const iterator
operator +(int n
) { return advance(n
); }
891 const iterator
operator -(int n
) { return advance(-n
); }
892 bool operator !=(const iterator
&i
) { return p
!= i
.p
; }
893 bool operator ==(const iterator
&i
) { return p
== i
.p
; }
899 riterator(node
*p
= NULL
) : i(p
) {}
900 riterator
& operator ++() { --i
; return *this;}
901 riterator
& operator --() { ++i
; return *this;}
902 node
* operator *() { return *i
; }
903 node
* operator ->() { return *i
; }
904 bool operator !=(const riterator
&r
) { return i
!= r
.i
; }
905 bool operator ==(const riterator
&r
) { return i
== r
.i
; }
908 iterator
begin() { return first
; }
909 iterator
end() { return NULL
; }
910 riterator
rbegin() { return last
; }
911 riterator
rend() { return NULL
; }
913 bool empty() { assert(first
!= NULL
|| first
== last
); return !first
; }
916 // used with node containers that represent shceduling queues
917 // ignores copies and takes into account alu_packed_node items
918 unsigned real_alu_count();
920 void push_back(node
*n
);
921 void push_front(node
*n
);
923 void insert_node_before(node
*s
, node
*n
);
924 void insert_node_after(node
*s
, node
*n
);
926 void append_from(container_node
*c
);
928 // remove range [b..e) from some container and assign to this container
929 void move(iterator b
, iterator e
);
932 void expand(container_node
*n
);
933 void remove_node(node
*n
);
935 node
*cut(iterator b
, iterator e
);
937 void clear() { first
= last
= NULL
; }
939 virtual bool is_valid() { return true; }
940 virtual bool accept(vpass
&p
, bool enter
);
941 virtual bool fold_dispatch(expr_handler
*ex
);
943 node
* front() { return first
; }
944 node
* back() { return last
; }
946 void collect_stats(node_stats
&s
);
953 typedef container_node::iterator node_iterator
;
954 typedef container_node::riterator node_riterator
;
956 class alu_group_node
: public container_node
{
958 alu_group_node() : container_node(NT_LIST
, NST_ALU_GROUP
), literals() {}
961 std::vector
<literal
> literals
;
963 virtual bool is_valid() { return subtype
== NST_ALU_GROUP
; }
964 virtual bool accept(vpass
&p
, bool enter
);
967 unsigned literal_chan(literal l
) {
968 std::vector
<literal
>::iterator F
=
969 std::find(literals
.begin(), literals
.end(), l
);
970 assert(F
!= literals
.end());
971 return F
- literals
.begin();
977 class cf_node
: public container_node
{
979 cf_node() : container_node(NT_OP
, NST_CF_INST
), jump_target(),
980 jump_after_target() { memset(&bc
, 0, sizeof(bc_cf
)); };
984 cf_node
*jump_target
;
985 bool jump_after_target
;
987 virtual bool is_valid() { return subtype
== NST_CF_INST
; }
988 virtual bool accept(vpass
&p
, bool enter
);
989 virtual bool fold_dispatch(expr_handler
*ex
);
991 void jump(cf_node
*c
) { jump_target
= c
; jump_after_target
= false; }
992 void jump_after(cf_node
*c
) { jump_target
= c
; jump_after_target
= true; }
997 class alu_node
: public node
{
999 alu_node() : node(NT_OP
, NST_ALU_INST
) { memset(&bc
, 0, sizeof(bc_alu
)); };
1003 virtual bool is_valid() { return subtype
== NST_ALU_INST
; }
1004 virtual bool accept(vpass
&p
, bool enter
);
1005 virtual bool fold_dispatch(expr_handler
*ex
);
1007 unsigned forced_bank_swizzle() {
1008 return ((bc
.op_ptr
->flags
& AF_INTERP
) && (bc
.slot_flags
== AF_4V
)) ?
1012 // return param index + 1 if instruction references interpolation param,
1014 unsigned interp_param();
1016 alu_group_node
*get_alu_group_node();
1018 friend class shader
;
1021 // for multi-slot instrs - DOT/INTERP/... (maybe useful for 64bit pairs later)
1022 class alu_packed_node
: public container_node
{
1024 alu_packed_node() : container_node(NT_OP
, NST_ALU_PACKED_INST
) {}
1027 const alu_op_info
* op_ptr() {
1028 return static_cast<alu_node
*>(first
)->bc
.op_ptr
;
1030 unsigned op() { return static_cast<alu_node
*>(first
)->bc
.op
; }
1031 void init_args(bool repl
);
1033 virtual bool is_valid() { return subtype
== NST_ALU_PACKED_INST
; }
1034 virtual bool accept(vpass
&p
, bool enter
);
1035 virtual bool fold_dispatch(expr_handler
*ex
);
1037 unsigned get_slot_mask();
1038 void update_packed_items(sb_context
&ctx
);
1040 friend class shader
;
1043 class fetch_node
: public node
{
1045 fetch_node() : node(NT_OP
, NST_FETCH_INST
) { memset(&bc
, 0, sizeof(bc_fetch
)); };
1049 virtual bool is_valid() { return subtype
== NST_FETCH_INST
; }
1050 virtual bool accept(vpass
&p
, bool enter
);
1051 virtual bool fold_dispatch(expr_handler
*ex
);
1053 bool uses_grad() { return bc
.op_ptr
->flags
& FF_USEGRAD
; }
1055 friend class shader
;
1060 class repeat_node
: public container_node
{
1062 repeat_node(region_node
*target
, unsigned id
)
1063 : container_node(NT_REPEAT
, NST_LIST
), target(target
), rep_id(id
) {}
1065 region_node
*target
;
1068 virtual bool accept(vpass
&p
, bool enter
);
1070 friend class shader
;
1073 class depart_node
: public container_node
{
1075 depart_node(region_node
*target
, unsigned id
)
1076 : container_node(NT_DEPART
, NST_LIST
), target(target
), dep_id(id
) {}
1078 region_node
*target
;
1081 virtual bool accept(vpass
&p
, bool enter
);
1083 friend class shader
;
1086 class if_node
: public container_node
{
1088 if_node() : container_node(NT_IF
, NST_LIST
), cond() {};
1090 value
*cond
; // glued to pseudo output (dst[2]) of the PRED_SETxxx
1092 virtual bool accept(vpass
&p
, bool enter
);
1094 friend class shader
;
1097 typedef std::vector
<depart_node
*> depart_vec
;
1098 typedef std::vector
<repeat_node
*> repeat_vec
;
1100 class region_node
: public container_node
{
1102 region_node(unsigned id
) : container_node(NT_REGION
, NST_LIST
), region_id(id
),
1103 loop_phi(), phi(), vars_defined(), departs(), repeats(), src_loop()
1108 container_node
*loop_phi
;
1109 container_node
*phi
;
1111 val_set vars_defined
;
1116 // true if region was created for loop in the parser, sometimes repeat_node
1117 // may be optimized away so we need to remember this information
1120 virtual bool accept(vpass
&p
, bool enter
);
1122 unsigned dep_count() { return departs
.size(); }
1123 unsigned rep_count() { return repeats
.size() + 1; }
1125 bool is_loop() { return src_loop
|| !repeats
.empty(); }
1127 container_node
* get_entry_code_location() {
1129 while (p
&& (p
->is_depart() || p
->is_repeat()))
1130 p
= static_cast<container_node
*>(p
)->first
;
1132 container_node
*c
= static_cast<container_node
*>(p
);
1139 void expand_depart(depart_node
*d
);
1140 void expand_repeat(repeat_node
*r
);
1142 friend class shader
;
1145 class bb_node
: public container_node
{
1147 bb_node(unsigned id
, unsigned loop_level
)
1148 : container_node(NT_LIST
, NST_BB
), id(id
), loop_level(loop_level
) {}
1151 unsigned loop_level
;
1153 virtual bool accept(vpass
&p
, bool enter
);
1155 friend class shader
;
1159 typedef std::vector
<region_node
*> regions_vec
;
1160 typedef std::vector
<bb_node
*> bbs_vec
;
1161 typedef std::list
<node
*> sched_queue
;
1162 typedef sched_queue::iterator sq_iterator
;
1163 typedef std::vector
<node
*> node_vec
;
1164 typedef std::list
<node
*> node_list
;
1165 typedef std::set
<node
*> node_set
;
1169 } // namespace r600_sb
1171 #endif /* R600_SB_IR_H_ */