nir: Move nir_lower_mediump_outputs from ir3
[mesa.git] / src / compiler / nir / nir_liveness.c
index 05f79d7bc617a76b45fd02701616c67f2115a75b..16dbeb4a22302a231ba3d662a1b61ec9544b69c3 100644 (file)
@@ -46,6 +46,9 @@ struct live_ssa_defs_state {
    unsigned num_ssa_defs;
    unsigned bitset_words;
 
+   /* Used in propagate_across_edge() */
+   BITSET_WORD *tmp_live;
+
    nir_block_worklist worklist;
 };
 
@@ -62,23 +65,13 @@ index_ssa_def(nir_ssa_def *def, void *void_state)
    return true;
 }
 
-static bool
-index_ssa_definitions_block(nir_block *block, void *state)
-{
-   nir_foreach_instr(block, instr)
-      nir_foreach_ssa_def(instr, index_ssa_def, state);
-
-   return true;
-}
-
 /* Initialize the liveness data to zero and add the given block to the
  * worklist.
  */
 static bool
-init_liveness_block(nir_block *block, void *void_state)
+init_liveness_block(nir_block *block,
+                    struct live_ssa_defs_state *state)
 {
-   struct live_ssa_defs_state *state = void_state;
-
    block->live_in = reralloc(block, block->live_in, BITSET_WORD,
                              state->bitset_words);
    memset(block->live_in, 0, state->bitset_words * sizeof(BITSET_WORD));
@@ -131,10 +124,10 @@ static bool
 propagate_across_edge(nir_block *pred, nir_block *succ,
                       struct live_ssa_defs_state *state)
 {
-   NIR_VLA(BITSET_WORD, live, state->bitset_words);
+   BITSET_WORD *live = state->tmp_live;
    memcpy(live, succ->live_in, state->bitset_words * sizeof *live);
 
-   nir_foreach_instr(succ, instr) {
+   nir_foreach_instr(instr, succ) {
       if (instr->type != nir_instr_type_phi)
          break;
       nir_phi_instr *phi = nir_instr_as_phi(instr);
@@ -143,12 +136,12 @@ propagate_across_edge(nir_block *pred, nir_block *succ,
       set_ssa_def_dead(&phi->dest.ssa, live);
    }
 
-   nir_foreach_instr(succ, instr) {
+   nir_foreach_instr(instr, succ) {
       if (instr->type != nir_instr_type_phi)
          break;
       nir_phi_instr *phi = nir_instr_as_phi(instr);
 
-      nir_foreach_phi_src(phi, src) {
+      nir_foreach_phi_src(src, phi) {
          if (src->pred == pred) {
             set_src_live(&src->src, live);
             break;
@@ -174,7 +167,10 @@ nir_live_ssa_defs_impl(nir_function_impl *impl)
     * can be compacted into a single bit.
     */
    state.num_ssa_defs = 1;
-   nir_foreach_block(impl, index_ssa_definitions_block, &state);
+   nir_foreach_block(block, impl) {
+      nir_foreach_instr(instr, block)
+         nir_foreach_ssa_def(instr, index_ssa_def, &state);
+   }
 
    nir_block_worklist_init(&state.worklist, impl->num_blocks, NULL);
 
@@ -183,7 +179,11 @@ nir_live_ssa_defs_impl(nir_function_impl *impl)
     * blocks to the worklist.
     */
    state.bitset_words = BITSET_WORDS(state.num_ssa_defs);
-   nir_foreach_block(impl, init_liveness_block, &state);
+   state.tmp_live = rzalloc_array(impl, BITSET_WORD, state.bitset_words);
+   nir_foreach_block(block, impl) {
+      init_liveness_block(block, &state);
+   }
+
 
    /* We're now ready to work through the worklist and update the liveness
     * sets of each of the blocks.  By the time we get to this point, every
@@ -205,7 +205,7 @@ nir_live_ssa_defs_impl(nir_function_impl *impl)
       if (following_if)
          set_src_live(&following_if->condition, block->live_in);
 
-      nir_foreach_instr_reverse(block, instr) {
+      nir_foreach_instr_reverse(instr, block) {
          /* Phi nodes are handled seperately so we want to skip them.  Since
           * we are going backwards and they are at the beginning, we can just
           * break as soon as we see one.
@@ -222,7 +222,6 @@ nir_live_ssa_defs_impl(nir_function_impl *impl)
        * changed, add the predecessor to the work list so that we ensure
        * that the new information is used.
        */
-      struct set_entry *entry;
       set_foreach(block->predecessors, entry) {
          nir_block *pred = (nir_block *)entry->key;
          if (propagate_across_edge(pred, block, &state))
@@ -230,6 +229,7 @@ nir_live_ssa_defs_impl(nir_function_impl *impl)
       }
    }
 
+   ralloc_free(state.tmp_live);
    nir_block_worklist_fini(&state.worklist);
 }