nir: add type information to load uniform/input and store output intrinsics
[mesa.git] / src / compiler / nir / nir_repair_ssa.c
index 3ab4f0f6db74b1c97555a1580c933f1c1e631580..f182818374d79750a93ae34331251953d31046c2 100644 (file)
@@ -70,13 +70,22 @@ repair_ssa_def(nir_ssa_def *def, void *void_state)
    struct repair_ssa_state *state = void_state;
 
    bool is_valid = true;
-   nir_foreach_use(def, src) {
+   nir_foreach_use(src, def) {
       if (!nir_block_dominates(def->parent_instr->block, get_src_block(src))) {
          is_valid = false;
          break;
       }
    }
 
+   nir_foreach_if_use(src, def) {
+      nir_block *block_before_if =
+         nir_cf_node_as_block(nir_cf_node_prev(&src->parent_if->cf_node));
+      if (!nir_block_dominates(def->parent_instr->block, block_before_if)) {
+         is_valid = false;
+         break;
+      }
+   }
+
    if (is_valid)
       return true;
 
@@ -85,11 +94,12 @@ repair_ssa_def(nir_ssa_def *def, void *void_state)
    BITSET_SET(state->def_set, def->parent_instr->block->index);
 
    struct nir_phi_builder_value *val =
-      nir_phi_builder_add_value(pb, def->num_components, state->def_set);
+      nir_phi_builder_add_value(pb, def->num_components, def->bit_size,
+                                state->def_set);
 
    nir_phi_builder_value_set_block_def(val, def->parent_instr->block, def);
 
-   nir_foreach_use_safe(def, src) {
+   nir_foreach_use_safe(src, def) {
       nir_block *src_block = get_src_block(src);
       if (!nir_block_dominates(def->parent_instr->block, src_block)) {
          nir_instr_rewrite_src(src->parent_instr, src, nir_src_for_ssa(
@@ -97,14 +107,13 @@ repair_ssa_def(nir_ssa_def *def, void *void_state)
       }
    }
 
-   return true;
-}
-
-static bool
-repair_ssa_block(nir_block *block, void *state)
-{
-   nir_foreach_instr_safe(block, instr) {
-      nir_foreach_ssa_def(instr, repair_ssa_def, state);
+   nir_foreach_if_use_safe(src, def) {
+      nir_block *block_before_if =
+         nir_cf_node_as_block(nir_cf_node_prev(&src->parent_if->cf_node));
+      if (!nir_block_dominates(def->parent_instr->block, block_before_if)) {
+         nir_if_rewrite_condition(src->parent_if, nir_src_for_ssa(
+            nir_phi_builder_value_get_block_def(val, block_before_if)));
+      }
    }
 
    return true;
@@ -122,7 +131,11 @@ nir_repair_ssa_impl(nir_function_impl *impl)
    nir_metadata_require(impl, nir_metadata_block_index |
                               nir_metadata_dominance);
 
-   nir_foreach_block(impl, repair_ssa_block, &state);
+   nir_foreach_block(block, impl) {
+      nir_foreach_instr_safe(instr, block) {
+         nir_foreach_ssa_def(instr, repair_ssa_def, &state);
+      }
+   }
 
    if (state.progress)
       nir_metadata_preserve(impl, nir_metadata_block_index |
@@ -148,7 +161,7 @@ nir_repair_ssa(nir_shader *shader)
 {
    bool progress = false;
 
-   nir_foreach_function(shader, function) {
+   nir_foreach_function(function, shader) {
       if (function->impl)
          progress = nir_repair_ssa_impl(function->impl) || progress;
    }