Except for the minor stale comment and assuming you checked that we don't call nir_create_local_reg() anymore,
Reviewed-by: Connor Abbott <cwabbo...@gmail.com> On Tue, Dec 16, 2014 at 1:11 AM, Jason Ekstrand <ja...@jlekstrand.net> wrote: > With this commit, the GLSL IR -> NIR pass generates NIR in more-or-less SSA > form. It's SSA in the sense that it doesn't have any registers, but it > isn't really useful SSA because it still has a pile of load/store > intrinsics that we will need to get rid of. > --- > src/glsl/nir/glsl_to_nir.cpp | 246 > ++++++++++++++++++++----------------------- > 1 file changed, 117 insertions(+), 129 deletions(-) > > diff --git a/src/glsl/nir/glsl_to_nir.cpp b/src/glsl/nir/glsl_to_nir.cpp > index 6870bd2..f85b50e 100644 > --- a/src/glsl/nir/glsl_to_nir.cpp > +++ b/src/glsl/nir/glsl_to_nir.cpp > @@ -618,15 +618,13 @@ nir_visitor::visit(ir_call *ir) > assert(0); > } > > - nir_register *reg = nir_local_reg_create(impl); > - reg->num_components = 1; > - > nir_intrinsic_instr *instr = nir_intrinsic_instr_create(shader, op); > ir_dereference *param = > (ir_dereference *) ir->actual_parameters.get_head(); > param->accept(this); > instr->variables[0] = this->deref_head; > - instr->dest.reg.reg = reg; > + instr->dest.is_ssa = true; > + nir_ssa_def_init(&instr->instr, &instr->dest.ssa, 1, NULL); > > nir_instr_insert_after_cf_list(this->cf_node_list, &instr->instr); > > @@ -635,7 +633,8 @@ nir_visitor::visit(ir_call *ir) > > ir->return_deref->accept(this); > store_instr->variables[0] = this->deref_head; > - store_instr->src[0].reg.reg = reg; > + store_instr->src[0].is_ssa = true; > + store_instr->src[0].ssa = &instr->dest.ssa; > > nir_instr_insert_after_cf_list(this->cf_node_list, > &store_instr->instr); > > @@ -665,121 +664,124 @@ nir_visitor::visit(ir_call *ir) > void > nir_visitor::visit(ir_assignment *ir) > { > - if (ir->write_mask != (1 << ir->lhs->type->vector_elements) - 1 && > - ir->write_mask != 0) { > + unsigned num_components = ir->lhs->type->vector_elements; > + > + if ((ir->rhs->as_dereference() || ir->rhs->as_constant()) && > + (ir->write_mask == (1 << num_components) - 1 || ir->write_mask == > 0)) { > + /* We're doing a plane-as-can-be copy, so emit a copy_var */ > plain-as-can-be > + nir_intrinsic_instr *copy = > + nir_intrinsic_instr_create(this->shader, nir_intrinsic_copy_var); > + > + ir->lhs->accept(this); > + copy->variables[0] = this->deref_head; > + > + ir->rhs->accept(this); > + copy->variables[1] = this->deref_head; > + > + > + if (ir->condition) { > + nir_if *if_stmt = nir_if_create(this->shader); > + if_stmt->condition = evaluate_rvalue(ir->condition); > + nir_cf_node_insert_end(this->cf_node_list, &if_stmt->cf_node); > + nir_instr_insert_after_cf_list(&if_stmt->then_list, > ©->instr); > + } else { > + nir_instr_insert_after_cf_list(this->cf_node_list, ©->instr); > + } > + return; > + } > + > + assert(ir->rhs->type->is_scalar() || ir->rhs->type->is_vector()); > + > + ir->lhs->accept(this); > + nir_deref_var *lhs_deref = this->deref_head; > + nir_src src = evaluate_rvalue(ir->rhs); > + > + if (ir->write_mask != (1 << num_components) - 1 && ir->write_mask != > 0) { > /* > * We have no good way to update only part of a variable, so just > load > - * the LHS into a register, do a writemasked move, and then store it > + * the LHS and do a vec operation to combine the old with the new, > and > + * then store it > * back into the LHS. Copy propagation should get rid of the mess. > */ > > - ir->lhs->accept(this); > - nir_deref_var *lhs_deref = this->deref_head; > - nir_register *reg = nir_local_reg_create(this->impl); > - reg->num_components = ir->lhs->type->vector_elements; > - > - nir_intrinsic_op op; > + nir_intrinsic_op load_op; > switch (ir->lhs->type->vector_elements) { > - case 1: op = nir_intrinsic_load_var_vec1; break; > - case 2: op = nir_intrinsic_load_var_vec2; break; > - case 3: op = nir_intrinsic_load_var_vec3; break; > - case 4: op = nir_intrinsic_load_var_vec4; break; > - default: assert(0); break; > + case 1: load_op = nir_intrinsic_load_var_vec1; break; > + case 2: load_op = nir_intrinsic_load_var_vec2; break; > + case 3: load_op = nir_intrinsic_load_var_vec3; break; > + case 4: load_op = nir_intrinsic_load_var_vec4; break; > + default: unreachable("Invalid number of components"); break; > } > > - nir_intrinsic_instr *load = > nir_intrinsic_instr_create(this->shader, op); > - load->dest.reg.reg = reg; > + nir_intrinsic_instr *load = nir_intrinsic_instr_create(this->shader, > + load_op); > + load->dest.is_ssa = true; > + nir_ssa_def_init(&load->instr, &load->dest.ssa, > + num_components, NULL); > load->variables[0] = lhs_deref; > nir_instr_insert_after_cf_list(this->cf_node_list, &load->instr); > > - nir_alu_instr *move = > - nir_alu_instr_create(this->shader, > - supports_ints ? nir_op_fmov : nir_op_imov); > - move->dest.dest.reg.reg = reg; > - move->dest.write_mask = ir->write_mask; > - move->src[0].src = evaluate_rvalue(ir->rhs); > - > - /* > - * GLSL IR will give us the input to the write-masked assignment in > a > - * single packed vector, whereas we expect each input component to > be in > - * the same channel as the writemask. So, for example, if the > writemask > - * is xzw, then we have to swizzle x -> x, y -> z, and z -> w. > + nir_op vec_op; > + switch (ir->lhs->type->vector_elements) { > + case 1: vec_op = nir_op_imov; break; > + case 2: vec_op = nir_op_vec2; break; > + case 3: vec_op = nir_op_vec3; break; > + case 4: vec_op = nir_op_vec4; break; > + default: unreachable("Invalid number of components"); break; > + } > + nir_alu_instr *vec = nir_alu_instr_create(this->shader, vec_op); > + vec->dest.dest.is_ssa = true; > + nir_ssa_def_init(&vec->instr, &vec->dest.dest.ssa, > + num_components, NULL); > + vec->dest.write_mask = (1 << num_components) - 1; > + > + /* GLSL IR will give us the input to the write-masked assignment > + * in a single packed vector, whereas we expect each input > + * component to be in the same channel as the writemask. So, for > + * example, if the writemask is xzw, then we have to swizzle x -> > + * x, y -> z, and z -> w. > */ > This comment is stale now, since we have to do the unpacking for a different reason (we're interleaving the old and the new vectors). > - > unsigned component = 0; > - for (unsigned i = 0; i < 4; i++) { > - if ((ir->write_mask >> i) & 1) { > - move->src[0].swizzle[i] = component++; > + for (unsigned i = 0; i < ir->lhs->type->vector_elements; i++) { > + if (ir->write_mask & (1 << i)) { > + vec->src[i].src = src; > + vec->src[i].swizzle[0] = component++; > } else { > - move->src[0].swizzle[i] = 0; > + vec->src[i].src.is_ssa = true; > + vec->src[i].src.ssa = &load->dest.ssa; > + vec->src[i].swizzle[0] = i; > } > } > > - if (ir->condition != NULL) { > - move->has_predicate = true; > - move->predicate = evaluate_rvalue(ir->condition); > - } > - > - nir_instr_insert_after_cf_list(this->cf_node_list, &move->instr); > + nir_instr_insert_after_cf_list(this->cf_node_list, &vec->instr); > > - switch (ir->lhs->type->vector_elements) { > - case 1: op = nir_intrinsic_store_var_vec1; break; > - case 2: op = nir_intrinsic_store_var_vec2; break; > - case 3: op = nir_intrinsic_store_var_vec3; break; > - case 4: op = nir_intrinsic_store_var_vec4; break; > - default: assert(0); break; > - } > - > - nir_intrinsic_instr *store = > nir_intrinsic_instr_create(this->shader, op); > - nir_deref *store_deref = nir_copy_deref(this->shader, > &lhs_deref->deref); > - store->variables[0] = nir_deref_as_var(store_deref); > - store->src[0].reg.reg = reg; > - nir_instr_insert_after_cf_list(this->cf_node_list, &store->instr); > - return; > - } > - > - if (ir->rhs->as_dereference() || ir->rhs->as_constant()) { > - /* we're copying structs or arrays, so emit a copy_var */ > - nir_intrinsic_instr *copy = > - nir_intrinsic_instr_create(this->shader, nir_intrinsic_copy_var); > - > - ir->lhs->accept(this); > - copy->variables[0] = this->deref_head; > - > - ir->rhs->accept(this); > - copy->variables[1] = this->deref_head; > - > - if (ir->condition != NULL) { > - copy->has_predicate = true; > - copy->predicate = evaluate_rvalue(ir->condition); > - } > - nir_instr_insert_after_cf_list(this->cf_node_list, ©->instr); > - return; > + src.is_ssa = true; > + src.ssa = &vec->dest.dest.ssa; > } > > - assert(ir->rhs->type->is_scalar() || ir->rhs->type->is_vector()); > - > - nir_intrinsic_op op; > + nir_intrinsic_op store_op; > switch (ir->lhs->type->vector_elements) { > - case 1: op = nir_intrinsic_store_var_vec1; break; > - case 2: op = nir_intrinsic_store_var_vec2; break; > - case 3: op = nir_intrinsic_store_var_vec3; break; > - case 4: op = nir_intrinsic_store_var_vec4; break; > - default: assert(0); break; > + case 1: store_op = nir_intrinsic_store_var_vec1; break; > + case 2: store_op = nir_intrinsic_store_var_vec2; break; > + case 3: store_op = nir_intrinsic_store_var_vec3; break; > + case 4: store_op = nir_intrinsic_store_var_vec4; break; > + default: unreachable("Invalid number of components"); break; > } > > - nir_intrinsic_instr *store = nir_intrinsic_instr_create(this->shader, > op); > - > - ir->lhs->accept(this); > - store->variables[0] = this->deref_head; > - store->src[0] = evaluate_rvalue(ir->rhs); > - > - if (ir->condition != NULL) { > - store->has_predicate = true; > - store->predicate = evaluate_rvalue(ir->condition); > + nir_intrinsic_instr *store = nir_intrinsic_instr_create(this->shader, > + store_op); > + nir_deref *store_deref = nir_copy_deref(this->shader, > &lhs_deref->deref); > + store->variables[0] = nir_deref_as_var(store_deref); > + store->src[0] = src; > + > + if (ir->condition) { > + nir_if *if_stmt = nir_if_create(this->shader); > + if_stmt->condition = evaluate_rvalue(ir->condition); > + nir_cf_node_insert_end(this->cf_node_list, &if_stmt->cf_node); > + nir_instr_insert_after_cf_list(&if_stmt->then_list, &store->instr); > + } else { > + nir_instr_insert_after_cf_list(this->cf_node_list, &store->instr); > } > - > - nir_instr_insert_after_cf_list(this->cf_node_list, &store->instr); > } > > /* > @@ -829,8 +831,8 @@ nir_visitor::add_instr(nir_instr *instr, unsigned > num_components) > { > nir_dest *dest = get_instr_dest(instr); > > - dest->reg.reg = nir_local_reg_create(this->impl); > - dest->reg.reg->num_components = num_components; > + dest->is_ssa = true; > + nir_ssa_def_init(instr, &dest->ssa, num_components, NULL); > > nir_instr_insert_after_cf_list(this->cf_node_list, instr); > this->result = instr; > @@ -846,43 +848,27 @@ nir_visitor::evaluate_rvalue(ir_rvalue* ir) > * must emit a variable load. > */ > > - nir_intrinsic_op op; > + nir_intrinsic_op load_op; > switch (ir->type->vector_elements) { > - case 1: > - op = nir_intrinsic_load_var_vec1; > - break; > - case 2: > - op = nir_intrinsic_load_var_vec2; > - break; > - case 3: > - op = nir_intrinsic_load_var_vec3; > - break; > - case 4: > - op = nir_intrinsic_load_var_vec4; > - break; > + case 1: load_op = nir_intrinsic_load_var_vec1; break; > + case 2: load_op = nir_intrinsic_load_var_vec2; break; > + case 3: load_op = nir_intrinsic_load_var_vec3; break; > + case 4: load_op = nir_intrinsic_load_var_vec4; break; > + default: unreachable("Invalid number of components"); > } > > nir_intrinsic_instr *load_instr = > - nir_intrinsic_instr_create(this->shader, op); > + nir_intrinsic_instr_create(this->shader, load_op); > load_instr->variables[0] = this->deref_head; > add_instr(&load_instr->instr, ir->type->vector_elements); > } > > - /* > - * instr doesn't have a destination right now, give it one and then > set up > - * the source so that it points to it. > - * > - * TODO: once we support SSA plumb through a use_ssa boolean and use > SSA > - * here instead of creating a register. > - */ > nir_dest *dest = get_instr_dest(this->result); > - assert(dest->reg.reg); > - nir_src src; > > - src.is_ssa = false; > - src.reg.base_offset = 0; > - src.reg.indirect = NULL; > - src.reg.reg = dest->reg.reg; > + assert(dest->is_ssa); > + nir_src src; > + src.is_ssa = true; > + src.ssa = &dest->ssa; > > return src; > } > @@ -964,13 +950,15 @@ nir_visitor::visit(ir_expression *ir) > nir_load_const_instr *const_zero = > nir_load_const_instr_create(shader); > const_zero->num_components = 1; > const_zero->value.u[0] = 0; > - const_zero->dest.reg.reg = nir_local_reg_create(this->impl); > - const_zero->dest.reg.reg->num_components = 1; > + const_zero->dest.is_ssa = true; > + nir_ssa_def_init(&const_zero->instr, &const_zero->dest.ssa, 1, > NULL); > nir_instr_insert_after_cf_list(this->cf_node_list, > &const_zero->instr); > > nir_alu_instr *compare = nir_alu_instr_create(shader, > nir_op_ine); > - compare->src[0].src.reg.reg = load->dest.reg.reg; > - compare->src[1].src.reg.reg = const_zero->dest.reg.reg; > + compare->src[0].src.is_ssa = true; > + compare->src[0].src.ssa = &load->dest.ssa; > + compare->src[1].src.is_ssa = true; > + compare->src[1].src.ssa = &const_zero->dest.ssa; > for (unsigned i = 0; i < ir->type->vector_elements; i++) > compare->src[1].swizzle[i] = 0; > compare->dest.write_mask = (1 << ir->type->vector_elements) - 1; > -- > 2.2.0 > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/mesa-dev >
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev