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.
55 sel_chan(unsigned id
= 0) : id(id
) {}
56 sel_chan(unsigned sel
, unsigned chan
) : id(((sel
<< 2) | chan
) + 1) {}
58 unsigned sel() const { return sel(id
); }
59 unsigned chan() const {return chan(id
); }
60 operator unsigned() const {return id
;}
62 static unsigned sel(unsigned idx
) { return (idx
-1) >> 2; }
63 static unsigned chan(unsigned idx
) { return (idx
-1) & 3; }
66 inline sb_ostream
& operator <<(sb_ostream
& o
, sel_chan r
) {
67 static const char * ch
= "xyzw";
68 o
<< r
.sel() << "." << ch
[r
.chan()];
72 typedef std::vector
<value
*> vvec
;
76 static const unsigned SB_POOL_ALIGN
= 8;
77 static const unsigned SB_POOL_DEFAULT_BLOCK_SIZE
= (1 << 16);
79 typedef std::vector
<void*> block_vector
;
86 sb_pool(unsigned block_size
= SB_POOL_DEFAULT_BLOCK_SIZE
)
87 : block_size(block_size
), blocks(), total_size() {}
89 virtual ~sb_pool() { free_all(); }
91 void* allocate(unsigned sz
);
97 template <typename V
, typename Comp
= std::less
<V
> >
99 typedef std::vector
<V
> data_vector
;
103 typedef typename
data_vector::iterator iterator
;
104 typedef typename
data_vector::const_iterator const_iterator
;
109 iterator
begin() { return vec
.begin(); }
110 iterator
end() { return vec
.end(); }
111 const_iterator
begin() const { return vec
.begin(); }
112 const_iterator
end() const { return vec
.end(); }
114 void add_set(const sb_set
& s
) {
116 t
.reserve(vec
.size() + s
.vec
.size());
117 std::set_union(vec
.begin(), vec
.end(), s
.vec
.begin(), s
.vec
.end(),
118 std::inserter(t
, t
.begin()), Comp());
122 iterator
lower_bound(const V
& v
) {
123 return std::lower_bound(vec
.begin(), vec
.end(), v
, Comp());
126 std::pair
<iterator
, bool> insert(const V
& v
) {
127 iterator P
= lower_bound(v
);
128 if (P
!= vec
.end() && is_equal(*P
, v
))
129 return std::make_pair(P
, false);
130 return std::make_pair(vec
.insert(P
, v
), true);
133 unsigned erase(const V
& v
) {
134 iterator P
= lower_bound(v
);
135 if (P
== vec
.end() || !is_equal(*P
, v
))
141 void clear() { vec
.clear(); }
143 bool empty() { return vec
.empty(); }
145 bool is_equal(const V
& v1
, const V
& v2
) {
146 return !Comp()(v1
, v2
) && !Comp()(v2
, v1
);
149 iterator
find(const V
& v
) {
150 iterator P
= lower_bound(v
);
151 return (P
!= vec
.end() && is_equal(*P
, v
)) ? P
: vec
.end();
154 unsigned size() { return vec
.size(); }
155 void erase(iterator I
) { vec
.erase(I
); }
158 template <typename K
, typename V
, typename KComp
= std::less
<K
> >
160 typedef std::pair
<K
, V
> datatype
;
163 bool operator()(const datatype
&v1
, const datatype
&v2
) {
164 return KComp()(v1
.first
, v2
.first
);
168 typedef sb_set
<datatype
, Comp
> dataset
;
176 typedef typename
dataset::iterator iterator
;
178 iterator
begin() { return set
.begin(); }
179 iterator
end() { return set
.end(); }
181 void clear() { set
.clear(); }
183 V
& operator[](const K
& key
) {
184 datatype P
= std::make_pair(key
, V());
185 iterator F
= set
.find(P
);
186 if (F
== set
.end()) {
187 return (*(set
.insert(P
).first
)).second
;
193 std::pair
<iterator
, bool> insert(const datatype
& d
) {
194 return set
.insert(d
);
197 iterator
find(const K
& key
) {
198 return set
.find(std::make_pair(key
, V()));
201 unsigned erase(const K
& key
) {
202 return set
.erase(std::make_pair(key
, V()));
205 void erase(iterator I
) {
211 typedef uint32_t basetype
;
212 static const unsigned bt_bits
= sizeof(basetype
) << 3;
213 std::vector
<basetype
> data
;
218 sb_bitset() : data(), bit_size() {}
220 bool get(unsigned id
);
221 void set(unsigned id
, bool bit
= true);
222 bool set_chk(unsigned id
, bool bit
= true);
225 void resize(unsigned size
);
227 unsigned size() { return bit_size
; }
229 unsigned find_bit(unsigned start
= 0);
231 void swap(sb_bitset
& bs2
);
233 bool operator==(const sb_bitset
&bs2
);
234 bool operator!=(const sb_bitset
&bs2
) { return !(*this == bs2
); }
236 sb_bitset
& operator|=(const sb_bitset
&bs2
) {
237 if (bit_size
< bs2
.bit_size
) {
238 resize(bs2
.bit_size
);
241 for (unsigned i
= 0, c
= std::min(data
.size(), bs2
.data
.size()); i
< c
;
243 data
[i
] |= bs2
.data
[i
];
248 sb_bitset
& operator&=(const sb_bitset
&bs2
);
249 sb_bitset
& mask(const sb_bitset
&bs2
);
251 friend sb_bitset
operator|(const sb_bitset
&b1
, const sb_bitset
&b2
) {
276 class sb_value_pool
: protected sb_pool
{
277 unsigned aligned_elt_size
;
280 sb_value_pool(unsigned elt_size
, unsigned block_elts
= 256)
281 : sb_pool(block_elts
* (aligned_elt_size
= ((elt_size
+
282 SB_POOL_ALIGN
- 1) & ~(SB_POOL_ALIGN
- 1)))) {}
284 virtual ~sb_value_pool() { delete_all(); }
286 value
* create(value_kind k
, sel_chan regid
, unsigned ver
);
288 value
* operator[](unsigned id
) {
289 unsigned offset
= id
* aligned_elt_size
;
291 if (offset
< block_size
) {
294 block_id
= offset
/ block_size
;
295 offset
= offset
% block_size
;
297 return (value
*)((char*)blocks
[block_id
] + offset
);
300 unsigned size() { return total_size
/ aligned_elt_size
; }
315 sb_value_set() : bs() {}
322 iterator(shader
&sh
, sb_value_set
*s
, unsigned nb
= 0);
325 iterator
& operator++() {
326 if (nb
+ 1 < s
->bs
.size())
327 nb
= s
->bs
.find_bit(nb
+ 1);
332 bool operator !=(const iterator
&i
) {
333 return s
!= i
.s
|| nb
!= i
.nb
;
335 bool operator ==(const iterator
&i
) { return !(*this != i
); }
336 value
* operator *() {
343 iterator
begin(shader
&sh
) {
344 return iterator(sh
, this, bs
.size() ? bs
.find_bit(0) : 0);
346 iterator
end(shader
&sh
) { return iterator(sh
, this, bs
.size()); }
348 bool add_set_checked(sb_value_set
& s2
);
350 void add_set(sb_value_set
& s2
) {
351 if (bs
.size() < s2
.bs
.size())
352 bs
.resize(s2
.bs
.size());
356 void remove_set(sb_value_set
& s2
);
358 bool add_vec(vvec
&vv
);
360 bool add_val(value
*v
);
361 bool contains(value
*v
);
363 bool remove_val(value
*v
);
365 bool remove_vec(vvec
&vv
);
372 typedef sb_value_set val_set
;
375 sel_chan base_gpr
; // original gpr
376 sel_chan gpr
; // assigned by regalloc
379 gpr_array(sel_chan base_gpr
, unsigned array_size
) : base_gpr(base_gpr
),
380 array_size(array_size
) {}
382 unsigned hash() { return (base_gpr
<< 10) * array_size
; }
384 val_set interferences
;
391 typedef std::vector
<gpr_array
*> regarray_vec
;
394 VLF_UNDEF
= (1 << 0),
395 VLF_READONLY
= (1 << 1),
398 VLF_PIN_REG
= (1 << 3),
399 VLF_PIN_CHAN
= (1 << 4),
401 // opposite to alu clause local value - goes through alu clause boundary
402 // (can't use temp gpr, can't recolor in the alu scheduler, etc)
403 VLF_GLOBAL
= (1 << 5),
404 VLF_FIXED
= (1 << 6),
407 VLF_PREALLOC
= (1 << 8)
410 inline value_flags
operator |(value_flags l
, value_flags r
) {
411 return (value_flags
)((unsigned)l
|(unsigned)r
);
413 inline value_flags
operator &(value_flags l
, value_flags r
) {
414 return (value_flags
)((unsigned)l
&(unsigned)r
);
416 inline value_flags
operator ~(value_flags l
) {
417 return (value_flags
)(~(unsigned)l
);
419 inline value_flags
& operator |=(value_flags
&l
, value_flags r
) {
423 inline value_flags
& operator &=(value_flags
&l
, value_flags r
) {
430 sb_ostream
& operator << (sb_ostream
&o
, value
&v
);
432 typedef uint32_t value_hash
;
450 use_info(node
*n
, use_kind kind
, int arg
, use_info
* next
)
451 : next(next
), op(n
), kind(kind
), arg(arg
) {}
454 enum constraint_kind
{
467 value(unsigned sh_id
, value_kind k
, sel_chan select
, unsigned ver
= 0)
470 version(ver
), select(select
), pin_gpr(select
), gpr(),
471 gvn_source(), ghash(),
472 def(), adef(), uses(), constraint(), chunk(),
473 literal_value(), uid(sh_id
) {}
475 ~value() { delete_uses(); }
477 friend class sb_value_pool
;
499 ra_constraint
*constraint
;
502 literal literal_value
;
504 bool is_const() { return kind
== VLK_CONST
|| kind
== VLK_UNDEF
; }
507 return is_special_reg() && select
== sel_chan(SV_AR_INDEX
, 0);
511 assert(!(def
&& adef
));
512 return def
? def
: adef
;
517 while (v
->gvn_source
&& v
!= v
->gvn_source
)
518 // FIXME we really shouldn't have such chains
523 bool is_float_0_or_1() {
525 return v
->is_const() && (v
->literal_value
== literal(0)
526 || v
->literal_value
== literal(1.0f
));
529 bool is_undef() { return gvalue()->kind
== VLK_UNDEF
; }
532 return (kind
== VLK_REG
|| kind
== VLK_TEMP
);
536 return array
&& is_any_gpr();
539 // scalar gpr, as opposed to element of gpr array
541 return !array
&& is_any_gpr();
544 bool is_special_reg() { return kind
== VLK_SPECIAL_REG
; }
545 bool is_any_reg() { return is_any_gpr() || is_special_reg(); }
546 bool is_kcache() { return kind
== VLK_KCACHE
; }
547 bool is_rel() { return kind
== VLK_REL_REG
; }
548 bool is_readonly() { return flags
& VLF_READONLY
; }
550 bool is_chan_pinned() { return flags
& VLF_PIN_CHAN
; }
551 bool is_reg_pinned() { return flags
& VLF_PIN_REG
; }
562 bool is_dead() { return flags
& VLF_DEAD
; }
564 literal
& get_const_value() {
566 assert(v
->is_const());
567 return v
->literal_value
;
570 // true if needs to be encoded as literal in alu
573 && literal_value
!= literal(0)
574 && literal_value
!= literal(1)
575 && literal_value
!= literal(-1)
576 && literal_value
!= literal(0.5)
577 && literal_value
!= literal(1.0);
580 void add_use(node
*n
, use_kind kind
, int arg
);
583 value_hash
rel_hash();
585 void assign_source(value
*v
) {
586 assert(!gvn_source
|| gvn_source
== this);
587 gvn_source
= v
->gvalue();
590 bool v_equal(value
*v
) { return gvalue() == v
->gvalue(); }
592 unsigned use_count();
595 sel_chan
get_final_gpr() {
596 if (array
&& array
->gpr
) {
597 int reg_offset
= select
.sel() - array
->base_gpr
.sel();
598 if (rel
&& rel
->is_const())
599 reg_offset
+= rel
->get_const_value().i
;
600 return array
->gpr
+ (reg_offset
<< 2);
606 unsigned get_final_chan() {
609 return array
->gpr
.chan();
616 val_set interferences
;
623 typedef std::vector
<value
*> vt_item
;
624 typedef std::vector
<vt_item
> vt_table
;
638 value_table(expr_handler
&ex
, unsigned size_bits
= 10)
639 : ex(ex
), size_bits(size_bits
), size(1u << size_bits
),
640 size_mask(size
- 1), hashtable(size
), cnt() {}
644 void add_value(value
* v
);
646 bool expr_equal(value
* l
, value
* r
);
648 unsigned count() { return cnt
; }
650 void get_values(vvec
& v
);
683 NST_LOOP_PHI_CONTAINER
,
691 NF_REG_CONSTRAINT
= (1 << 1),
692 NF_CHAN_CONSTRAINT
= (1 << 2),
693 NF_ALU_4SLOT
= (1 << 3),
694 NF_CONTAINER
= (1 << 4),
696 NF_COPY_MOV
= (1 << 5),
698 NF_DONT_KILL
= (1 << 6),
699 NF_DONT_HOIST
= (1 << 7),
700 NF_DONT_MOVE
= (1 << 8),
702 // for KILLxx - we want to schedule them as early as possible
703 NF_SCHEDULE_EARLY
= (1 << 9),
705 // for ALU_PUSH_BEFORE - when set, replace with PUSH + ALU
706 NF_ALU_STACK_WORKAROUND
= (1 << 10)
709 inline node_flags
operator |(node_flags l
, node_flags r
) {
710 return (node_flags
)((unsigned)l
|(unsigned)r
);
712 inline node_flags
& operator |=(node_flags
&l
, node_flags r
) {
717 inline node_flags
& operator &=(node_flags
&l
, node_flags r
) {
718 l
= (node_flags
)((unsigned)l
& (unsigned)r
);
722 inline node_flags
operator ~(node_flags r
) {
723 return (node_flags
)~(unsigned)r
;
728 unsigned alu_kill_count
;
729 unsigned alu_copy_mov_count
;
731 unsigned fetch_count
;
732 unsigned region_count
;
735 unsigned loop_phi_count
;
736 unsigned depart_count
;
737 unsigned repeat_count
;
740 node_stats() : alu_count(), alu_kill_count(), alu_copy_mov_count(),
741 cf_count(), fetch_count(), region_count(),
742 loop_count(), phi_count(), loop_phi_count(), depart_count(),
743 repeat_count(), if_count() {}
752 class container_node
;
758 node(node_type nt
, node_subtype nst
, node_flags flags
= NF_EMPTY
)
759 : prev(), next(), parent(),
760 type(nt
), subtype(nst
), flags(flags
),
761 pred(), dst(), src() {}
767 container_node
*parent
;
770 node_subtype subtype
;
778 virtual bool is_valid() { return true; }
779 virtual bool accept(vpass
&p
, bool enter
);
781 void insert_before(node
*n
);
782 void insert_after(node
*n
);
783 void replace_with(node
*n
);
786 virtual value_hash
hash();
787 value_hash
hash_src();
789 virtual bool fold_dispatch(expr_handler
*ex
);
791 bool is_container() { return flags
& NF_CONTAINER
; }
793 bool is_alu_packed() { return subtype
== NST_ALU_PACKED_INST
; }
794 bool is_alu_inst() { return subtype
== NST_ALU_INST
; }
795 bool is_alu_group() { return subtype
== NST_ALU_GROUP
; }
796 bool is_alu_clause() { return subtype
== NST_ALU_CLAUSE
; }
798 bool is_fetch_clause() {
799 return subtype
== NST_TEX_CLAUSE
|| subtype
== NST_VTX_CLAUSE
;
802 bool is_copy() { return subtype
== NST_COPY
; }
803 bool is_copy_mov() { return flags
& NF_COPY_MOV
; }
804 bool is_any_alu() { return is_alu_inst() || is_alu_packed() || is_copy(); }
806 bool is_fetch_inst() { return subtype
== NST_FETCH_INST
; }
807 bool is_cf_inst() { return subtype
== NST_CF_INST
; }
809 bool is_region() { return type
== NT_REGION
; }
810 bool is_depart() { return type
== NT_DEPART
; }
811 bool is_repeat() { return type
== NT_REPEAT
; }
812 bool is_if() { return type
== NT_IF
; }
813 bool is_bb() { return subtype
== NST_BB
; }
815 bool is_phi() { return subtype
== NST_PHI
; }
817 bool is_dead() { return flags
& NF_DEAD
; }
819 bool is_cf_op(unsigned op
);
820 bool is_alu_op(unsigned op
);
821 bool is_fetch_op(unsigned op
);
823 unsigned cf_op_flags();
824 unsigned alu_op_flags();
825 unsigned alu_op_slot_flags();
826 unsigned fetch_op_flags();
831 bool vec_uses_ar(vvec
&vv
) {
832 for (vvec::iterator I
= vv
.begin(), E
= vv
.end(); I
!= E
; ++I
) {
834 if (v
&& v
->rel
&& !v
->rel
->is_const())
841 return vec_uses_ar(dst
) || vec_uses_ar(src
);
845 region_node
* get_parent_region();
850 class container_node
: public node
{
853 container_node(node_type nt
= NT_LIST
, node_subtype nst
= NST_LIST
,
854 node_flags flags
= NF_EMPTY
)
855 : node(nt
, nst
, flags
| NF_CONTAINER
), first(), last(),
856 live_after(), live_before() {}
867 iterator(node
*pp
= NULL
) : p(pp
) {}
868 iterator
& operator ++() { p
= p
->next
; return *this;}
869 iterator
& operator --() { p
= p
->prev
; return *this;}
870 node
* operator *() { return p
; }
871 node
* operator ->() { return p
; }
872 const iterator
advance(int n
) {
873 if (!n
) return *this;
875 if (n
> 0) while (n
--) ++I
;
876 else while (n
++) --I
;
879 const iterator
operator +(int n
) { return advance(n
); }
880 const iterator
operator -(int n
) { return advance(-n
); }
881 bool operator !=(const iterator
&i
) { return p
!= i
.p
; }
882 bool operator ==(const iterator
&i
) { return p
== i
.p
; }
888 riterator(node
*p
= NULL
) : i(p
) {}
889 riterator
& operator ++() { --i
; return *this;}
890 riterator
& operator --() { ++i
; return *this;}
891 node
* operator *() { return *i
; }
892 node
* operator ->() { return *i
; }
893 bool operator !=(const riterator
&r
) { return i
!= r
.i
; }
894 bool operator ==(const riterator
&r
) { return i
== r
.i
; }
897 iterator
begin() { return first
; }
898 iterator
end() { return NULL
; }
899 riterator
rbegin() { return last
; }
900 riterator
rend() { return NULL
; }
902 bool empty() { assert(first
!= NULL
|| first
== last
); return !first
; }
905 // used with node containers that represent shceduling queues
906 // ignores copies and takes into account alu_packed_node items
907 unsigned real_alu_count();
909 void push_back(node
*n
);
910 void push_front(node
*n
);
912 void insert_node_before(node
*s
, node
*n
);
913 void insert_node_after(node
*s
, node
*n
);
915 void append_from(container_node
*c
);
917 // remove range [b..e) from some container and assign to this container
918 void move(iterator b
, iterator e
);
921 void expand(container_node
*n
);
922 void remove_node(node
*n
);
924 node
*cut(iterator b
, iterator e
);
926 void clear() { first
= last
= NULL
; }
928 virtual bool is_valid() { return true; }
929 virtual bool accept(vpass
&p
, bool enter
);
930 virtual bool fold_dispatch(expr_handler
*ex
);
932 node
* front() { return first
; }
933 node
* back() { return last
; }
935 void collect_stats(node_stats
&s
);
942 typedef container_node::iterator node_iterator
;
943 typedef container_node::riterator node_riterator
;
945 class alu_group_node
: public container_node
{
947 alu_group_node() : container_node(NT_LIST
, NST_ALU_GROUP
), literals() {}
950 std::vector
<literal
> literals
;
952 virtual bool is_valid() { return subtype
== NST_ALU_GROUP
; }
953 virtual bool accept(vpass
&p
, bool enter
);
956 unsigned literal_chan(literal l
) {
957 std::vector
<literal
>::iterator F
=
958 std::find(literals
.begin(), literals
.end(), l
);
959 assert(F
!= literals
.end());
960 return F
- literals
.begin();
966 class cf_node
: public container_node
{
968 cf_node() : container_node(NT_OP
, NST_CF_INST
), jump_target(),
969 jump_after_target() { memset(&bc
, 0, sizeof(bc_cf
)); };
973 cf_node
*jump_target
;
974 bool jump_after_target
;
976 virtual bool is_valid() { return subtype
== NST_CF_INST
; }
977 virtual bool accept(vpass
&p
, bool enter
);
978 virtual bool fold_dispatch(expr_handler
*ex
);
980 void jump(cf_node
*c
) { jump_target
= c
; jump_after_target
= false; }
981 void jump_after(cf_node
*c
) { jump_target
= c
; jump_after_target
= true; }
986 class alu_node
: public node
{
988 alu_node() : node(NT_OP
, NST_ALU_INST
) { memset(&bc
, 0, sizeof(bc_alu
)); };
992 virtual bool is_valid() { return subtype
== NST_ALU_INST
; }
993 virtual bool accept(vpass
&p
, bool enter
);
994 virtual bool fold_dispatch(expr_handler
*ex
);
996 unsigned forced_bank_swizzle() {
997 return ((bc
.op_ptr
->flags
& AF_INTERP
) && (bc
.slot_flags
== AF_4V
)) ?
1001 // return param index + 1 if instruction references interpolation param,
1003 unsigned interp_param();
1005 alu_group_node
*get_alu_group_node();
1007 friend class shader
;
1010 // for multi-slot instrs - DOT/INTERP/... (maybe useful for 64bit pairs later)
1011 class alu_packed_node
: public container_node
{
1013 alu_packed_node() : container_node(NT_OP
, NST_ALU_PACKED_INST
) {}
1016 const alu_op_info
* op_ptr() {
1017 return static_cast<alu_node
*>(first
)->bc
.op_ptr
;
1019 unsigned op() { return static_cast<alu_node
*>(first
)->bc
.op
; }
1020 void init_args(bool repl
);
1022 virtual bool is_valid() { return subtype
== NST_ALU_PACKED_INST
; }
1023 virtual bool accept(vpass
&p
, bool enter
);
1024 virtual bool fold_dispatch(expr_handler
*ex
);
1026 unsigned get_slot_mask();
1027 void update_packed_items(sb_context
&ctx
);
1029 friend class shader
;
1032 class fetch_node
: public node
{
1034 fetch_node() : node(NT_OP
, NST_FETCH_INST
) { memset(&bc
, 0, sizeof(bc_fetch
)); };
1038 virtual bool is_valid() { return subtype
== NST_FETCH_INST
; }
1039 virtual bool accept(vpass
&p
, bool enter
);
1040 virtual bool fold_dispatch(expr_handler
*ex
);
1042 bool uses_grad() { return bc
.op_ptr
->flags
& FF_USEGRAD
; }
1044 friend class shader
;
1049 class repeat_node
: public container_node
{
1051 repeat_node(region_node
*target
, unsigned id
)
1052 : container_node(NT_REPEAT
, NST_LIST
), target(target
), rep_id(id
) {}
1054 region_node
*target
;
1057 virtual bool accept(vpass
&p
, bool enter
);
1059 friend class shader
;
1062 class depart_node
: public container_node
{
1064 depart_node(region_node
*target
, unsigned id
)
1065 : container_node(NT_DEPART
, NST_LIST
), target(target
), dep_id(id
) {}
1067 region_node
*target
;
1070 virtual bool accept(vpass
&p
, bool enter
);
1072 friend class shader
;
1075 class if_node
: public container_node
{
1077 if_node() : container_node(NT_IF
, NST_LIST
), cond() {};
1079 value
*cond
; // glued to pseudo output (dst[2]) of the PRED_SETxxx
1081 virtual bool accept(vpass
&p
, bool enter
);
1083 friend class shader
;
1086 typedef std::vector
<depart_node
*> depart_vec
;
1087 typedef std::vector
<repeat_node
*> repeat_vec
;
1089 class region_node
: public container_node
{
1091 region_node(unsigned id
) : container_node(NT_REGION
, NST_LIST
), region_id(id
),
1092 loop_phi(), phi(), vars_defined(), departs(), repeats(), src_loop()
1097 container_node
*loop_phi
;
1098 container_node
*phi
;
1100 val_set vars_defined
;
1105 // true if region was created for loop in the parser, sometimes repeat_node
1106 // may be optimized away so we need to remember this information
1109 virtual bool accept(vpass
&p
, bool enter
);
1111 unsigned dep_count() { return departs
.size(); }
1112 unsigned rep_count() { return repeats
.size() + 1; }
1114 bool is_loop() { return src_loop
|| !repeats
.empty(); }
1116 container_node
* get_entry_code_location() {
1118 while (p
&& (p
->is_depart() || p
->is_repeat()))
1119 p
= static_cast<container_node
*>(p
)->first
;
1121 container_node
*c
= static_cast<container_node
*>(p
);
1128 void expand_depart(depart_node
*d
);
1129 void expand_repeat(repeat_node
*r
);
1131 friend class shader
;
1134 class bb_node
: public container_node
{
1136 bb_node(unsigned id
, unsigned loop_level
)
1137 : container_node(NT_LIST
, NST_BB
), id(id
), loop_level(loop_level
) {}
1140 unsigned loop_level
;
1142 virtual bool accept(vpass
&p
, bool enter
);
1144 friend class shader
;
1148 typedef std::vector
<region_node
*> regions_vec
;
1149 typedef std::vector
<bb_node
*> bbs_vec
;
1150 typedef std::list
<node
*> sched_queue
;
1151 typedef sched_queue::iterator sq_iterator
;
1152 typedef std::vector
<node
*> node_vec
;
1153 typedef std::list
<node
*> node_list
;
1154 typedef std::set
<node
*> node_set
;
1158 } // namespace r600_sb
1160 #endif /* R600_SB_IR_H_ */