*/
#include "nir.h"
+#include "nir_builder.h"
#include "nir_vla.h"
/*
*/
struct from_ssa_state {
- void *mem_ctx;
+ nir_builder builder;
void *dead_ctx;
bool phi_webs_only;
struct hash_table *merge_node_table;
nir_instr *instr;
- nir_function_impl *impl;
};
/* Returns true if a dominates b */
* Each SSA definition is associated with a merge_node and the association
* is represented by a combination of a hash table and the "def" parameter
* in the merge_node structure. The merge_set stores a linked list of
- * merge_node's in dominence order of the ssa definitions. (Since the
+ * merge_nodes in dominence order of the ssa definitions. (Since the
* liveness analysis pass indexes the SSA values in dominence order for us,
* this is an easy thing to keep up.) It is assumed that no pair of the
* nodes in a given set interfere. Merging two sets or checking for
last_phi_instr = instr;
}
- /* If we don't have any phi's, then there's nothing for us to do. */
+ /* If we don't have any phis, then there's nothing for us to do. */
if (last_phi_instr == NULL)
return true;
* matter which node's definition we use.
*/
if (node->set->reg == NULL)
- node->set->reg = create_reg_for_ssa_def(def, state->impl);
+ node->set->reg = create_reg_for_ssa_def(def, state->builder.impl);
reg = node->set->reg;
} else {
if (def->parent_instr->type == nir_instr_type_load_const)
return true;
- reg = create_reg_for_ssa_def(def, state->impl);
+ reg = create_reg_for_ssa_def(def, state->builder.impl);
}
nir_ssa_def_rewrite_uses(def, nir_src_for_reg(reg));
}
static void
-emit_copy(nir_parallel_copy_instr *pcopy, nir_src src, nir_src dest_src,
- void *mem_ctx)
+emit_copy(nir_builder *b, nir_src src, nir_src dest_src)
{
assert(!dest_src.is_ssa &&
dest_src.reg.indirect == NULL &&
else
assert(src.reg.reg->num_components >= dest_src.reg.reg->num_components);
- nir_alu_instr *mov = nir_alu_instr_create(mem_ctx, nir_op_imov);
+ nir_alu_instr *mov = nir_alu_instr_create(b->shader, nir_op_imov);
nir_src_copy(&mov->src[0].src, &src, mov);
mov->dest.dest = nir_dest_for_reg(dest_src.reg.reg);
mov->dest.write_mask = (1 << dest_src.reg.reg->num_components) - 1;
- nir_instr_insert_before(&pcopy->instr, &mov->instr);
+ nir_builder_instr_insert(b, &mov->instr);
}
-/* Resolves a single parallel copy operation into a sequence of mov's
+/* Resolves a single parallel copy operation into a sequence of movs
*
* This is based on Algorithm 1 from "Revisiting Out-of-SSA Translation for
* Correctness, Code Quality, and Efficiency" by Boissinot et. al..
NIR_VLA(int, to_do, num_copies * 2);
int to_do_idx = -1;
+ state->builder.cursor = nir_before_instr(&pcopy->instr);
+
/* Now we set everything up:
* - All values get assigned a temporary index
* - Current locations are set from sources
while (ready_idx >= 0) {
int b = ready[ready_idx--];
int a = pred[b];
- emit_copy(pcopy, values[loc[a]], values[b], state->mem_ctx);
+ emit_copy(&state->builder, values[loc[a]], values[b]);
/* If any other copies want a they can find it at b */
loc[a] = b;
* backend can coalesce the (possibly multiple) temporaries.
*/
assert(num_vals < num_copies * 2);
- nir_register *reg = nir_local_reg_create(state->impl);
+ nir_register *reg = nir_local_reg_create(state->builder.impl);
reg->name = "copy_temp";
reg->num_array_elems = 0;
if (values[b].is_ssa)
values[num_vals].is_ssa = false;
values[num_vals].reg.reg = reg;
- emit_copy(pcopy, values[b], values[num_vals], state->mem_ctx);
+ emit_copy(&state->builder, values[b], values[num_vals]);
loc[b] = num_vals;
ready[++ready_idx] = b;
num_vals++;
{
struct from_ssa_state state;
- state.mem_ctx = ralloc_parent(impl);
+ nir_builder_init(&state.builder, impl);
state.dead_ctx = ralloc_context(NULL);
- state.impl = impl;
state.phi_webs_only = phi_webs_only;
state.merge_node_table = _mesa_hash_table_create(NULL, _mesa_hash_pointer,
_mesa_key_pointer_equal);
nir_instr_insert(nir_after_block_before_jump(block), &mov->instr);
}
-/** Lower all of the phi nodes in a block to imov's to and from a register
+/** Lower all of the phi nodes in a block to imovs to and from a register
*
* This provides a very quick-and-dirty out-of-SSA pass that you can run on a
- * single block to convert all of it's phis to a register and some imov's.
+ * single block to convert all of its phis to a register and some imovs.
* The code that is generated, while not optimal for actual codegen in a
* back-end, is easy to generate, correct, and will turn into the same set of
* phis after you call regs_to_ssa and do some copy propagation.
} else {
nir_foreach_dest(instr, dest_replace_ssa_with_reg, &state);
}
- nir_foreach_dest(instr, dest_replace_ssa_with_reg, &state);
}
return state.progress;