X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fmesa%2Fdrivers%2Fdri%2Fi965%2Fbrw_cfg.h;h=a09491781e6015757594c2e2db93666ef9a3841a;hb=8a688bee83ced46eb4bff741f05d2da033c07ade;hp=a8b20af11ff597ec2f343767ce3ea164eb202a19;hpb=49374fab5d793ed426e01f7fef82c87442c14860;p=mesa.git diff --git a/src/mesa/drivers/dri/i965/brw_cfg.h b/src/mesa/drivers/dri/i965/brw_cfg.h index a8b20af11ff..a09491781e6 100644 --- a/src/mesa/drivers/dri/i965/brw_cfg.h +++ b/src/mesa/drivers/dri/i965/brw_cfg.h @@ -60,16 +60,28 @@ struct bblock_t { 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; backend_instruction *end(); const backend_instruction *end() const; + + bblock_t *next(); + const bblock_t *next() const; + bblock_t *prev(); + const bblock_t *prev() const; + + bool starts_with_control_flow() const; + bool ends_with_control_flow() const; + + backend_instruction *first_non_control_flow_inst(); + backend_instruction *last_non_control_flow_inst(); #endif struct exec_node link; struct cfg_t *cfg; + struct bblock_t *idom; int start_ip; int end_ip; @@ -78,14 +90,6 @@ struct bblock_t { struct exec_list parents; 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; }; static inline struct backend_instruction * @@ -112,6 +116,74 @@ bblock_end_const(const struct bblock_t *block) return (const struct backend_instruction *)exec_list_get_tail_const(&block->instructions); } +static inline struct bblock_t * +bblock_next(struct bblock_t *block) +{ + return (struct bblock_t *)block->link.next; +} + +static inline const struct bblock_t * +bblock_next_const(const struct bblock_t *block) +{ + return (const struct bblock_t *)block->link.next; +} + +static inline struct bblock_t * +bblock_prev(struct bblock_t *block) +{ + return (struct bblock_t *)block->link.prev; +} + +static inline const struct bblock_t * +bblock_prev_const(const struct bblock_t *block) +{ + return (const struct bblock_t *)block->link.prev; +} + +static inline bool +bblock_starts_with_control_flow(const struct bblock_t *block) +{ + enum opcode op = bblock_start_const(block)->opcode; + return op == BRW_OPCODE_DO || op == BRW_OPCODE_ENDIF; +} + +static inline bool +bblock_ends_with_control_flow(const struct bblock_t *block) +{ + enum opcode op = bblock_end_const(block)->opcode; + return op == BRW_OPCODE_IF || + op == BRW_OPCODE_ELSE || + op == BRW_OPCODE_WHILE || + op == BRW_OPCODE_BREAK || + op == BRW_OPCODE_CONTINUE; +} + +static inline struct backend_instruction * +bblock_first_non_control_flow_inst(struct bblock_t *block) +{ + struct backend_instruction *inst = bblock_start(block); + if (bblock_starts_with_control_flow(block)) +#ifdef __cplusplus + inst = (struct backend_instruction *)inst->next; +#else + inst = (struct backend_instruction *)inst->link.next; +#endif + return inst; +} + +static inline struct backend_instruction * +bblock_last_non_control_flow_inst(struct bblock_t *block) +{ + struct backend_instruction *inst = bblock_end(block); + if (bblock_ends_with_control_flow(block)) +#ifdef __cplusplus + inst = (struct backend_instruction *)inst->prev; +#else + inst = (struct backend_instruction *)inst->link.prev; +#endif + return inst; +} + #ifdef __cplusplus inline backend_instruction * bblock_t::start() @@ -136,6 +208,54 @@ bblock_t::end() const { return bblock_end_const(this); } + +inline bblock_t * +bblock_t::next() +{ + return bblock_next(this); +} + +inline const bblock_t * +bblock_t::next() const +{ + return bblock_next_const(this); +} + +inline bblock_t * +bblock_t::prev() +{ + return bblock_prev(this); +} + +inline const bblock_t * +bblock_t::prev() const +{ + return bblock_prev_const(this); +} + +inline bool +bblock_t::starts_with_control_flow() const +{ + return bblock_starts_with_control_flow(this); +} + +inline bool +bblock_t::ends_with_control_flow() const +{ + return bblock_ends_with_control_flow(this); +} + +inline backend_instruction * +bblock_t::first_non_control_flow_inst() +{ + return bblock_first_non_control_flow_inst(this); +} + +inline backend_instruction * +bblock_t::last_non_control_flow_inst() +{ + return bblock_last_non_control_flow_inst(this); +} #endif struct cfg_t { @@ -150,8 +270,12 @@ struct cfg_t { 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; @@ -159,6 +283,8 @@ struct cfg_t { struct exec_list block_list; struct bblock_t **blocks; int num_blocks; + + bool idom_dirty; }; /* Note that this is implemented with a double for loop -- break will @@ -178,6 +304,9 @@ struct cfg_t { #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) @@ -195,6 +324,9 @@ struct cfg_t { #define foreach_inst_in_block_reverse(__type, __inst, __block) \ foreach_in_list_reverse(__type, __inst, &(__block)->instructions) +#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, __block) \ for (__type *__scan_inst = (__type *)__inst->next; \ !__scan_inst->is_tail_sentinel(); \