summaryrefslogtreecommitdiffstats
path: root/src/compiler/nir/nir_repair_ssa.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/nir/nir_repair_ssa.c')
-rw-r--r--src/compiler/nir/nir_repair_ssa.c79
1 files changed, 44 insertions, 35 deletions
diff --git a/src/compiler/nir/nir_repair_ssa.c b/src/compiler/nir/nir_repair_ssa.c
index 757afff490d..8eceadcebb0 100644
--- a/src/compiler/nir/nir_repair_ssa.c
+++ b/src/compiler/nir/nir_repair_ssa.c
@@ -103,48 +103,57 @@ repair_ssa_def(nir_ssa_def *def, void *void_state)
nir_foreach_use_safe(src, def) {
nir_block *src_block = get_src_block(src);
- if (nir_block_is_unreachable(src_block) ||
- !nir_block_dominates(def->parent_instr->block, src_block)) {
- nir_ssa_def *block_def =
- nir_phi_builder_value_get_block_def(val, src_block);
-
- /* If def was a deref and the use we're looking at is a deref that
- * isn't a cast, we need to wrap it in a cast so we don't loose any
- * deref information.
- */
- if (def->parent_instr->type == nir_instr_type_deref &&
- src->parent_instr->type == nir_instr_type_deref &&
- nir_instr_as_deref(src->parent_instr)->deref_type != nir_deref_type_cast) {
- nir_deref_instr *cast =
- nir_deref_instr_create(state->impl->function->shader,
- nir_deref_type_cast);
-
- nir_deref_instr *deref = nir_instr_as_deref(def->parent_instr);
- cast->mode = deref->mode;
- cast->type = deref->type;
- cast->parent = nir_src_for_ssa(block_def);
- cast->cast.ptr_stride = nir_deref_instr_ptr_as_array_stride(deref);
-
- nir_ssa_dest_init(&cast->instr, &cast->dest,
- def->num_components, def->bit_size, NULL);
- nir_instr_insert(nir_before_instr(src->parent_instr),
- &cast->instr);
- block_def = &cast->dest.ssa;
- }
-
- nir_instr_rewrite_src(src->parent_instr, src,
- nir_src_for_ssa(block_def));
+ if (src_block == def->parent_instr->block) {
+ assert(nir_phi_builder_value_get_block_def(val, src_block) == def);
+ continue;
}
+
+ nir_ssa_def *block_def =
+ nir_phi_builder_value_get_block_def(val, src_block);
+ if (block_def == def)
+ continue;
+
+ /* If def was a deref and the use we're looking at is a deref that
+ * isn't a cast, we need to wrap it in a cast so we don't loose any
+ * deref information.
+ */
+ if (def->parent_instr->type == nir_instr_type_deref &&
+ src->parent_instr->type == nir_instr_type_deref &&
+ nir_instr_as_deref(src->parent_instr)->deref_type != nir_deref_type_cast) {
+ nir_deref_instr *cast =
+ nir_deref_instr_create(state->impl->function->shader,
+ nir_deref_type_cast);
+
+ nir_deref_instr *deref = nir_instr_as_deref(def->parent_instr);
+ cast->mode = deref->mode;
+ cast->type = deref->type;
+ cast->parent = nir_src_for_ssa(block_def);
+ cast->cast.ptr_stride = nir_deref_instr_ptr_as_array_stride(deref);
+
+ nir_ssa_dest_init(&cast->instr, &cast->dest,
+ def->num_components, def->bit_size, NULL);
+ nir_instr_insert(nir_before_instr(src->parent_instr),
+ &cast->instr);
+ block_def = &cast->dest.ssa;
+ }
+
+ nir_instr_rewrite_src(src->parent_instr, src, nir_src_for_ssa(block_def));
}
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_is_unreachable(block_before_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)));
+ if (block_before_if == def->parent_instr->block) {
+ assert(nir_phi_builder_value_get_block_def(val, block_before_if) == def);
+ continue;
}
+
+ nir_ssa_def *block_def =
+ nir_phi_builder_value_get_block_def(val, block_before_if);
+ if (block_def == def)
+ continue;
+
+ nir_if_rewrite_condition(src->parent_if, nir_src_for_ssa(block_def));
}
return true;