i965/fs: Make emit_spill/unspill static functions taking builder as argument.
[mesa.git] / src / mesa / drivers / dri / i965 / brw_cfg.h
index 388d29e87231e4529df9383d6acb622fc22790c2..5b770aa7af121c6f08308c13aa169d9b21d9cd22 100644 (file)
@@ -60,7 +60,7 @@ 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;
@@ -81,6 +81,7 @@ struct bblock_t {
 
    struct exec_node link;
    struct cfg_t *cfg;
+   struct bblock_t *idom;
 
    int start_ip;
    int end_ip;
@@ -90,13 +91,7 @@ struct bblock_t {
    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 *
@@ -126,24 +121,36 @@ bblock_end_const(const struct bblock_t *block)
 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;
 }
 
@@ -277,8 +284,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;
 
@@ -286,6 +297,10 @@ struct cfg_t {
    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
@@ -305,9 +320,15 @@ 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)
 
+#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)
 
@@ -322,12 +343,15 @@ 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_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)