bool is_successor_of(const bblock_t *block) const;
bool can_combine_with(const bblock_t *that) const;
void combine_with(bblock_t *that);
- void dump(backend_visitor *v) const;
+ void dump(backend_shader *s) const;
backend_instruction *start();
const backend_instruction *start() const;
struct exec_node link;
struct cfg_t *cfg;
+ struct bblock_t *idom;
int start_ip;
int end_ip;
struct exec_list children;
int num;
- /* If the current basic block ends in an IF or ELSE instruction, these will
- * point to the basic blocks containing the other associated instruction.
- *
- * Otherwise they are NULL.
- */
- struct bblock_t *if_block;
- struct bblock_t *else_block;
+ unsigned cycle_count;
};
static inline struct backend_instruction *
static inline struct bblock_t *
bblock_next(struct bblock_t *block)
{
+ if (exec_node_is_tail_sentinel(block->link.next))
+ return NULL;
+
return (struct bblock_t *)block->link.next;
}
static inline const struct bblock_t *
bblock_next_const(const struct bblock_t *block)
{
+ if (exec_node_is_tail_sentinel(block->link.next))
+ return NULL;
+
return (const struct bblock_t *)block->link.next;
}
static inline struct bblock_t *
bblock_prev(struct bblock_t *block)
{
+ if (exec_node_is_head_sentinel(block->link.prev))
+ return NULL;
+
return (struct bblock_t *)block->link.prev;
}
static inline const struct bblock_t *
bblock_prev_const(const struct bblock_t *block)
{
+ if (exec_node_is_head_sentinel(block->link.prev))
+ return NULL;
+
return (const struct bblock_t *)block->link.prev;
}
bblock_t *new_block();
void set_next_block(bblock_t **cur, bblock_t *block, int ip);
void make_block_array();
+ void calculate_idom();
+ static bblock_t *intersect(bblock_t *b1, bblock_t *b2);
- void dump(backend_visitor *v) const;
+ void dump(backend_shader *s);
+ void dump_cfg();
+ void dump_domtree();
#endif
void *mem_ctx;
struct exec_list block_list;
struct bblock_t **blocks;
int num_blocks;
+
+ bool idom_dirty;
+
+ unsigned cycle_count;
};
/* Note that this is implemented with a double for loop -- break will
#define foreach_block(__block, __cfg) \
foreach_list_typed (bblock_t, __block, link, &(__cfg)->block_list)
+#define foreach_block_reverse(__block, __cfg) \
+ foreach_list_typed_reverse (bblock_t, __block, link, &(__cfg)->block_list)
+
#define foreach_block_safe(__block, __cfg) \
foreach_list_typed_safe (bblock_t, __block, link, &(__cfg)->block_list)
+#define foreach_block_reverse_safe(__block, __cfg) \
+ foreach_list_typed_reverse_safe (bblock_t, __block, link, &(__cfg)->block_list)
+
#define foreach_inst_in_block(__type, __inst, __block) \
foreach_in_list(__type, __inst, &(__block)->instructions)
#define foreach_inst_in_block_reverse(__type, __inst, __block) \
foreach_in_list_reverse(__type, __inst, &(__block)->instructions)
-#define foreach_inst_in_block_starting_from(__type, __scan_inst, __inst, __block) \
+#define foreach_inst_in_block_reverse_safe(__type, __inst, __block) \
+ foreach_in_list_reverse_safe(__type, __inst, &(__block)->instructions)
+
+#define foreach_inst_in_block_starting_from(__type, __scan_inst, __inst) \
for (__type *__scan_inst = (__type *)__inst->next; \
!__scan_inst->is_tail_sentinel(); \
__scan_inst = (__type *)__scan_inst->next)
-#define foreach_inst_in_block_reverse_starting_from(__type, __scan_inst, __inst, __block) \
+#define foreach_inst_in_block_reverse_starting_from(__type, __scan_inst, __inst) \
for (__type *__scan_inst = (__type *)__inst->prev; \
!__scan_inst->is_head_sentinel(); \
__scan_inst = (__type *)__scan_inst->prev)