[Mesa-dev] [PATCH 26/30] i965/ir: Move idom tree calculation and related logic into analysis object.

Francisco Jerez currojerez at riseup.net
Mon Mar 14 03:47:30 UTC 2016


This only does half of the work.  The actual representation of the
idom tree is left untouched, but the computation algorithm is moved
into a separate analysis result class wrapped in a BRW_ANALYSIS
object, along with the intersect() and dump_domtree() auxiliary
functions in order to keep things tidy.
---
 src/mesa/drivers/dri/i965/brw_cfg.cpp              | 44 ++++++++++------------
 src/mesa/drivers/dri/i965/brw_cfg.h                | 38 ++++++++++++++++---
 .../drivers/dri/i965/brw_fs_combine_constants.cpp  |  4 +-
 src/mesa/drivers/dri/i965/brw_shader.cpp           |  3 +-
 src/mesa/drivers/dri/i965/brw_shader.h             |  2 +
 5 files changed, 59 insertions(+), 32 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_cfg.cpp b/src/mesa/drivers/dri/i965/brw_cfg.cpp
index 4fcee72..f586dd0 100644
--- a/src/mesa/drivers/dri/i965/brw_cfg.cpp
+++ b/src/mesa/drivers/dri/i965/brw_cfg.cpp
@@ -34,6 +34,8 @@
  * blocks with successor/predecessor edges connecting them.
  */
 
+using namespace brw;
+
 static bblock_t *
 pop_stack(exec_list *list)
 {
@@ -158,7 +160,6 @@ cfg_t::cfg_t(exec_list *instructions)
    block_list.make_empty();
    blocks = NULL;
    num_blocks = 0;
-   idom_dirty = true;
 
    bblock_t *cur = NULL;
    int ip = 0;
@@ -384,7 +385,6 @@ cfg_t::remove_block(bblock_t *block)
 
    this->blocks[this->num_blocks - 1]->num = this->num_blocks - 2;
    this->num_blocks--;
-   idom_dirty = true;
 }
 
 bblock_t *
@@ -423,8 +423,7 @@ cfg_t::make_block_array()
 void
 cfg_t::dump(backend_shader *s)
 {
-   if (idom_dirty)
-      calculate_idom();
+   const idom_tree *idom = (s ? &s->idom_analysis.require() : NULL);
 
    foreach_block (block, this) {
       if (block->idom)
@@ -456,19 +455,18 @@ cfg_t::dump(backend_shader *s)
  * (less than 1000 nodes) that this algorithm is significantly faster than
  * others like Lengauer-Tarjan.
  */
-void
-cfg_t::calculate_idom()
+idom_tree::idom_tree(const backend_shader *s)
 {
-   foreach_block(block, this) {
+   foreach_block(block, s->cfg) {
       block->idom = NULL;
    }
-   blocks[0]->idom = blocks[0];
+   s->cfg->blocks[0]->idom = s->cfg->blocks[0];
 
    bool changed;
    do {
       changed = false;
 
-      foreach_block(block, this) {
+      foreach_block(block, s->cfg) {
          if (block->num == 0)
             continue;
 
@@ -489,12 +487,10 @@ cfg_t::calculate_idom()
          }
       }
    } while (changed);
-
-   idom_dirty = false;
 }
 
 bblock_t *
-cfg_t::intersect(bblock_t *b1, bblock_t *b2)
+idom_tree::intersect(bblock_t *b1, bblock_t *b2) const
 {
    /* Note, the comparisons here are the opposite of what the paper says
     * because we index blocks from beginning -> end (i.e. reverse post-order)
@@ -511,26 +507,26 @@ cfg_t::intersect(bblock_t *b1, bblock_t *b2)
 }
 
 void
-cfg_t::dump_cfg()
+idom_tree::dump(const backend_shader *s) const
 {
-   printf("digraph CFG {\n");
-   for (int b = 0; b < num_blocks; b++) {
-      bblock_t *block = this->blocks[b];
-
-      foreach_list_typed_safe (bblock_link, child, link, &block->children) {
-         printf("\t%d -> %d\n", b, child->block->num);
+   printf("digraph DominanceTree {\n");
+   foreach_block(block, s->cfg) {
+      if (block->idom) {
+         printf("\t%d -> %d\n", block->idom->num, block->num);
       }
    }
    printf("}\n");
 }
 
 void
-cfg_t::dump_domtree()
+cfg_t::dump_cfg()
 {
-   printf("digraph DominanceTree {\n");
-   foreach_block(block, this) {
-      if (block->idom) {
-         printf("\t%d -> %d\n", block->idom->num, block->num);
+   printf("digraph CFG {\n");
+   for (int b = 0; b < num_blocks; b++) {
+      bblock_t *block = this->blocks[b];
+
+      foreach_list_typed_safe (bblock_link, child, link, &block->children) {
+         printf("\t%d -> %d\n", b, child->block->num);
       }
    }
    printf("}\n");
diff --git a/src/mesa/drivers/dri/i965/brw_cfg.h b/src/mesa/drivers/dri/i965/brw_cfg.h
index 0813798..1c9207c 100644
--- a/src/mesa/drivers/dri/i965/brw_cfg.h
+++ b/src/mesa/drivers/dri/i965/brw_cfg.h
@@ -29,6 +29,9 @@
 #define BRW_CFG_H
 
 #include "brw_ir.h"
+#ifdef __cplusplus
+#include "brw_ir_analysis.h"
+#endif
 
 struct bblock_t;
 
@@ -272,12 +275,9 @@ 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_shader *s);
    void dump_cfg();
-   void dump_domtree();
 #endif
    void *mem_ctx;
 
@@ -286,8 +286,6 @@ struct cfg_t {
    struct bblock_t **blocks;
    int num_blocks;
 
-   bool idom_dirty;
-
    unsigned cycle_count;
 };
 
@@ -344,4 +342,34 @@ struct cfg_t {
         !__scan_inst->is_head_sentinel();                      \
         __scan_inst = (__type *)__scan_inst->prev)
 
+#ifdef __cplusplus
+namespace brw {
+   /**
+    * Immediate dominator tree analysis of a shader.
+    */
+   struct idom_tree {
+      idom_tree(const backend_shader *s);
+
+      bool
+      validate(const backend_shader *) const
+      {
+         /* FINISHME */
+         return true;
+      }
+
+      analysis_dependency_class
+      dependency_class() const
+      {
+         return DEPENDENCY_BLOCKS;
+      }
+
+      bblock_t *
+      intersect(bblock_t *b1, bblock_t *b2) const;
+
+      void
+      dump(const backend_shader *s) const;
+   };
+}
+#endif
+
 #endif /* BRW_CFG_H */
diff --git a/src/mesa/drivers/dri/i965/brw_fs_combine_constants.cpp b/src/mesa/drivers/dri/i965/brw_fs_combine_constants.cpp
index d556935..c771aca 100644
--- a/src/mesa/drivers/dri/i965/brw_fs_combine_constants.cpp
+++ b/src/mesa/drivers/dri/i965/brw_fs_combine_constants.cpp
@@ -202,7 +202,7 @@ fs_visitor::opt_combine_constants()
    table.len = 0;
    table.imm = ralloc_array(const_ctx, struct imm, table.size);
 
-   cfg->calculate_idom();
+   const brw::idom_tree &idom = idom_analysis.require();
    unsigned ip = -1;
 
    /* Make a pass through all instructions and count the number of times each
@@ -224,7 +224,7 @@ fs_visitor::opt_combine_constants()
          struct imm *imm = find_imm(&table, val);
 
          if (imm) {
-            bblock_t *intersection = cfg_t::intersect(block, imm->block);
+            bblock_t *intersection = idom.intersect(block, imm->block);
             if (intersection != imm->block)
                imm->inst = NULL;
             imm->block = intersection;
diff --git a/src/mesa/drivers/dri/i965/brw_shader.cpp b/src/mesa/drivers/dri/i965/brw_shader.cpp
index 4d701d9..24fe8f2 100644
--- a/src/mesa/drivers/dri/i965/brw_shader.cpp
+++ b/src/mesa/drivers/dri/i965/brw_shader.cpp
@@ -593,7 +593,7 @@ backend_shader::backend_shader(const struct brw_compiler *compiler,
      nir(shader),
      stage_prog_data(stage_prog_data),
      mem_ctx(mem_ctx),
-     cfg(NULL),
+     cfg(NULL), idom_analysis(this),
      stage(shader->stage)
 {
    debug_enabled = INTEL_DEBUG & intel_debug_flag_for_shader_stage(stage);
@@ -1049,6 +1049,7 @@ backend_shader::calculate_cfg()
 void
 backend_shader::invalidate_analysis(brw::analysis_dependency_class c)
 {
+   idom_analysis.invalidate(c);
 }
 
 /**
diff --git a/src/mesa/drivers/dri/i965/brw_shader.h b/src/mesa/drivers/dri/i965/brw_shader.h
index a244f48..769dca4 100644
--- a/src/mesa/drivers/dri/i965/brw_shader.h
+++ b/src/mesa/drivers/dri/i965/brw_shader.h
@@ -68,6 +68,8 @@ public:
    exec_list instructions;
 
    cfg_t *cfg;
+   BRW_ANALYSIS(idom_analysis, brw::idom_tree,
+                const backend_shader *) idom_analysis;
 
    gl_shader_stage stage;
    bool debug_enabled;
-- 
2.7.0



More information about the mesa-dev mailing list