for (unsigned i = 0; i < num_srcs; i++)
alu_src_init(&instr->src[i]);
- instr->has_predicate = false;
- src_init(&instr->predicate);
-
return instr;
}
instr->num_components = 0;
instr->array_elems = 0;
- instr->has_predicate = false;
- src_init(&instr->predicate);
-
return instr;
}
for (unsigned i = 0; i < num_srcs; i++)
src_init(&instr->src[i]);
- instr->has_predicate = false;
- src_init(&instr->predicate);
-
return instr;
}
instr->params = ralloc_array(mem_ctx, nir_deref_var *, instr->num_params);
instr->return_deref = NULL;
- instr->has_predicate = false;
- src_init(&instr->predicate);
-
return instr;
}
for (unsigned i = 0; i < 4; i++)
src_init(&instr->src[i]);
- instr->has_predicate = false;
- src_init(&instr->predicate);
-
instr->sampler_index = 0;
instr->sampler_array_size = 0;
instr->sampler = NULL;
if (!visit_src(&instr->src[i].src, cb, state))
return false;
- if (instr->has_predicate)
- if (!visit_src(&instr->predicate, cb, state))
- return false;
-
return true;
}
if (!visit_src(&instr->src[i], cb, state))
return false;
- if (instr->has_predicate)
- if (!visit_src(&instr->predicate, cb, state))
- return false;
-
if (instr->sampler != NULL)
if (!visit_deref_src(instr->sampler, cb, state))
return false;
if (!visit_deref_src(instr->variables[i], cb, state))
return false;
- if (instr->has_predicate)
- if (!visit_src(&instr->predicate, cb, state))
- return false;
-
return true;
}
static bool
visit_call_src(nir_call_instr *instr, nir_foreach_src_cb cb, void *state)
{
- if (instr->has_predicate)
- if (!visit_src(&instr->predicate, cb, state))
- return false;
-
return true;
}
visit_load_const_src(nir_load_const_instr *instr, nir_foreach_src_cb cb,
void *state)
{
- if (instr->has_predicate)
- if (!visit_src(&instr->predicate, cb, state))
- return false;
-
return true;
}
typedef struct nir_alu_instr {
nir_instr instr;
nir_op op;
- bool has_predicate;
- nir_src predicate;
nir_alu_dest dest;
nir_alu_src src[];
} nir_alu_instr;
nir_deref_var **params;
nir_deref_var *return_deref;
- bool has_predicate;
- nir_src predicate;
-
struct nir_function_overload *callee;
} nir_call_instr;
nir_deref_var *variables[2];
- bool has_predicate;
- nir_src predicate;
-
nir_src src[];
} nir_intrinsic_instr;
typedef struct {
nir_instr instr;
- bool has_predicate;
- nir_src predicate;
-
enum glsl_sampler_dim sampler_dim;
nir_alu_type dest_type;
*/
unsigned array_elems;
- bool has_predicate;
- nir_src predicate;
-
nir_dest dest;
} nir_load_const_instr;
store->src[0].is_ssa = true;
store->src[0].ssa = &load->dest.ssa;
- if (copy_instr->has_predicate) {
- store->has_predicate = true;
- store->predicate = nir_src_copy(copy_instr->predicate, state->mem_ctx);
- }
-
nir_instr_insert_before(©_instr->instr, &store->instr);
register_store_instr(store, false, state);
}
assert(intrin->src[0].is_ssa);
- nir_alu_instr *mov;
- if (intrin->has_predicate) {
- mov = nir_alu_instr_create(state->mem_ctx, nir_op_bcsel);
- mov->src[0].src = nir_src_copy(intrin->predicate,
- state->mem_ctx);
- /* Splat the condition to all channels */
- memset(mov->src[0].swizzle, 0, sizeof mov->src[0].swizzle);
-
- mov->src[1].src.is_ssa = true;
- mov->src[1].src.ssa = intrin->src[0].ssa;
- for (unsigned i = intrin->num_components; i < 4; i++)
- mov->src[1].swizzle[i] = 0;
-
- mov->src[2].src.is_ssa = true;
- mov->src[2].src.ssa = get_ssa_def_for_block(node, block, state);
- for (unsigned i = intrin->num_components; i < 4; i++)
- mov->src[2].swizzle[i] = 0;
-
- } else {
- mov = nir_alu_instr_create(state->mem_ctx, nir_op_imov);
-
- mov->src[0].src.is_ssa = true;
- mov->src[0].src.ssa = intrin->src[0].ssa;
- for (unsigned i = intrin->num_components; i < 4; i++)
- mov->src[0].swizzle[i] = 0;
- }
+ nir_alu_instr *mov = nir_alu_instr_create(state->mem_ctx,
+ nir_op_imov);
+ mov->src[0].src.is_ssa = true;
+ mov->src[0].src.ssa = intrin->src[0].ssa;
+ for (unsigned i = intrin->num_components; i < 4; i++)
+ mov->src[0].swizzle[i] = 0;
mov->dest.write_mask = (1 << intrin->num_components) - 1;
mov->dest.dest.is_ssa = true;
while (copy_prop_alu_src(alu_instr, i))
progress = true;
- if (alu_instr->has_predicate)
- while (copy_prop_src(&alu_instr->predicate, instr, NULL))
- progress = true;
-
if (!alu_instr->dest.dest.is_ssa && alu_instr->dest.dest.reg.indirect)
while (copy_prop_src(alu_instr->dest.dest.reg.indirect, instr, NULL))
progress = true;
if (alu1->op != alu2->op)
return false;
- if (alu1->has_predicate != alu2->has_predicate)
- return false;
-
- if (alu1->has_predicate &&
- !nir_srcs_equal(alu1->predicate, alu2->predicate))
- return false;
-
/* TODO: We can probably acutally do something more inteligent such
* as allowing different numbers and taking a maximum or something
* here */
static void
print_alu_instr(nir_alu_instr *instr, FILE *fp)
{
- if (instr->has_predicate) {
- fprintf(fp, "(");
- print_src(&instr->predicate, fp);
- fprintf(fp, ") ");
- }
-
print_alu_dest(&instr->dest, fp);
fprintf(fp, " = %s", nir_op_infos[instr->op].name);
{
unsigned num_srcs = nir_intrinsic_infos[instr->intrinsic].num_srcs;
- if (instr->has_predicate) {
- fprintf(fp, "(");
- print_src(&instr->predicate, fp);
- fprintf(fp, ") ");
- }
-
if (nir_intrinsic_infos[instr->intrinsic].has_dest) {
print_dest(&instr->dest, fp);
fprintf(fp, " = ");
static void
print_tex_instr(nir_tex_instr *instr, print_var_state *state, FILE *fp)
{
- if (instr->has_predicate) {
- fprintf(fp, "(");
- print_src(&instr->predicate, fp);
- fprintf(fp, ") ");
- }
-
print_dest(&instr->dest, fp);
fprintf(fp, " = ");
static void
print_call_instr(nir_call_instr *instr, print_var_state *state, FILE *fp)
{
- if (instr->has_predicate) {
- fprintf(fp, "(");
- print_src(&instr->predicate, fp);
- fprintf(fp, ") ");
- }
-
fprintf(fp, "call %s ", instr->callee->function->name);
for (unsigned i = 0; i < instr->num_params; i++) {
static void
print_load_const_instr(nir_load_const_instr *instr, unsigned tabs, FILE *fp)
{
- if (instr->has_predicate) {
- fprintf(fp, "(");
- print_src(&instr->predicate, fp);
- fprintf(fp, ") ");
- }
-
print_dest(&instr->dest, fp);
fprintf(fp, " = load_const ");
nir_intrinsic_instr *new_copy =
nir_intrinsic_instr_create(state->mem_ctx, nir_intrinsic_copy_var);
- if (old_copy->has_predicate) {
- new_copy->has_predicate = true;
- new_copy->predicate = nir_src_copy(old_copy->predicate,
- state->mem_ctx);
- }
-
/* We need to make copies because a) this deref chain actually
* belongs to the copy instruction and b) the deref chains may
* have some of the same links due to the way we constructed them
/* map from SSA value -> original register */
struct hash_table *ssa_map;
-
- /* predicate for this instruction */
- nir_src *predicate;
} rewrite_state;
static nir_ssa_def *get_ssa_src(nir_register *reg, rewrite_state *state)
if (state->states[index].stack == NULL)
return true;
- nir_alu_instr *csel = NULL;
- if (state->predicate) {
- /*
- * To capture the information that we may or may not overwrite this
- * register due to the predicate, we need to emit a conditional select
- * that takes the old version of the register and the new version.
- * This is basically a watered-down version of the Psi-SSA
- * representation, without any of the optimizations.
- *
- * TODO: do we actually need full-blown Psi-SSA?
- */
- csel = nir_alu_instr_create(state->mem_ctx, nir_op_bcsel);
- csel->dest.dest.reg.reg = dest->reg.reg;
- csel->dest.write_mask = (1 << dest->reg.reg->num_components) - 1;
- csel->src[0].src = nir_src_copy(*state->predicate, state->mem_ctx);
- /* Splat the condition to all channels */
- memset(csel->src[0].swizzle, 0, sizeof csel->src[0].swizzle);
- csel->src[2].src.is_ssa = true;
- csel->src[2].src.ssa = get_ssa_src(dest->reg.reg, state);
- }
-
dest->is_ssa = true;
char *name = NULL;
_mesa_hash_table_insert(state->ssa_map, &dest->ssa, reg);
- if (state->predicate) {
- csel->src[1].src.is_ssa = true;
- csel->src[1].src.ssa = &dest->ssa;
-
- nir_instr *old_parent_instr = state->parent_instr;
- nir_src *old_predicate = state->predicate;
- state->parent_instr = &csel->instr;
- state->predicate = NULL;
- rewrite_def_forwards(&csel->dest.dest, state);
- state->parent_instr = old_parent_instr;
- state->predicate = old_predicate;
-
- nir_instr_insert_after(state->parent_instr, &csel->instr);
- }
-
return true;
}
rewrite_alu_instr_forward(nir_alu_instr *instr, rewrite_state *state)
{
state->parent_instr = &instr->instr;
- state->predicate = instr->has_predicate ? &instr->predicate : NULL;
nir_foreach_src(&instr->instr, rewrite_use, state);
}
}
- vec->has_predicate = instr->has_predicate;
- if (instr->has_predicate)
- vec->predicate = nir_src_copy(instr->predicate, state->mem_ctx);
-
nir_instr_insert_after(&instr->instr, &vec->instr);
state->parent_instr = &vec->instr;
- state->predicate = vec->has_predicate ? &vec->predicate : NULL;
rewrite_def_forwards(&vec->dest.dest, state);
} else {
rewrite_def_forwards(&instr->dest.dest, state);
rewrite_phi_instr(nir_phi_instr *instr, rewrite_state *state)
{
state->parent_instr = &instr->instr;
- state->predicate = NULL;
rewrite_def_forwards(&instr->dest, state);
}
-static nir_src *
-get_instr_predicate(nir_instr *instr)
-{
- nir_alu_instr *alu_instr;
- nir_load_const_instr *load_const_instr;
- nir_intrinsic_instr *intrinsic_instr;
- nir_tex_instr *tex_instr;
-
- switch (instr->type) {
- case nir_instr_type_alu:
- alu_instr = nir_instr_as_alu(instr);
- if (alu_instr->has_predicate)
- return &alu_instr->predicate;
- else
- return NULL;
-
- case nir_instr_type_load_const:
- load_const_instr = nir_instr_as_load_const(instr);
- if (load_const_instr->has_predicate)
- return &load_const_instr->predicate;
- else
- return NULL;
-
- case nir_instr_type_intrinsic:
- intrinsic_instr = nir_instr_as_intrinsic(instr);
- if (intrinsic_instr->has_predicate)
- return &intrinsic_instr->predicate;
- else
- return NULL;
-
- case nir_instr_type_tex:
- tex_instr = nir_instr_as_tex(instr);
- if (tex_instr->has_predicate)
- return &tex_instr->predicate;
- else
- return NULL;
-
- default:
- break;
- }
-
- return NULL;
-}
-
static void
rewrite_instr_forward(nir_instr *instr, rewrite_state *state)
{
}
state->parent_instr = instr;
- state->predicate = get_instr_predicate(instr);
nir_foreach_src(instr, rewrite_use, state);
nir_foreach_dest(instr, rewrite_def_forwards, state);
* called after phi nodes are inserted so we can count phi node
* definitions too.
*/
- unsigned stack_size = 0;
- struct set_entry *entry;
- set_foreach(reg->defs, entry) {
- nir_instr *def = (nir_instr *) entry->key;
-
- stack_size++;
-
- /*
- * predicates generate an additional predicate destination that
- * gets pushed on the stack
- *
- * Note: ALU instructions generate an additional instruction too,
- * but as of now only the additional instruction is pushed onto
- * the stack, and not the original instruction because it doesn't
- * need to be (actually, we could do the same with predicates,
- * but it was easier to just use the existing codepath).
- */
-
- if (def->type == nir_instr_type_intrinsic) {
- nir_intrinsic_instr *intrinsic_instr =
- nir_instr_as_intrinsic(def);
- if (nir_intrinsic_infos[intrinsic_instr->intrinsic].has_dest &&
- intrinsic_instr->has_predicate)
- stack_size++;
- } else {
- if (get_instr_predicate(def) != NULL)
- stack_size++;
- }
- }
+ unsigned stack_size = reg->defs->entries;
state->states[reg->index].stack = ralloc_array(state->states,
nir_ssa_def *,
for (unsigned i = 0; i < nir_op_infos[instr->op].num_inputs; i++) {
validate_alu_src(instr, i, state);
}
-
- if (instr->has_predicate)
- validate_src(&instr->predicate, state);
}
static void
default:
break;
}
-
- if (instr->has_predicate)
- validate_src(&instr->predicate, state);
}
static void
}
validate_deref_var(instr->return_deref, state);
-
- if (instr->has_predicate)
- validate_src(&instr->predicate, state);
}
static void
assert(instr->dest.reg.base_offset + instr->array_elems <=
instr->dest.reg.reg->num_array_elems);
}
-
- if (instr->has_predicate)
- validate_src(&instr->predicate, state);
}
static void
struct brw_wm_prog_key *fs_key = (struct brw_wm_prog_key *) this->key;
fs_reg op[3];
- fs_reg dest = get_nir_dest(instr->dest.dest);
- dest.type = brw_type_for_nir_type(nir_op_infos[instr->op].output_type);
-
- fs_reg result;
- if (instr->has_predicate) {
- result = fs_reg(GRF, virtual_grf_alloc(4));
- result.type = dest.type;
- } else {
- result = dest;
- }
-
+ fs_reg result = get_nir_dest(instr->dest.dest);
+ result.type = brw_type_for_nir_type(nir_op_infos[instr->op].output_type);
for (unsigned i = 0; i < nir_op_infos[instr->op].num_inputs; i++)
op[i] = get_nir_alu_src(instr, i);
default:
unreachable("unhandled instruction");
}
-
- /* emit a predicated move if there was predication */
- if (instr->has_predicate) {
- fs_inst *inst = emit(MOV(reg_null_d,
- retype(get_nir_src(instr->predicate),
- BRW_REGISTER_TYPE_UD)));
- inst->conditional_mod = BRW_CONDITIONAL_NZ;
- inst = MOV(dest, result);
- inst->predicate = BRW_PREDICATE_NORMAL;
- emit_percomp(inst, instr->dest.write_mask);
- }
}
fs_reg
fs_reg dest;
if (nir_intrinsic_infos[instr->intrinsic].has_dest)
dest = get_nir_dest(instr->dest);
- if (instr->has_predicate) {
- fs_inst *inst = emit(MOV(reg_null_d,
- retype(get_nir_src(instr->predicate),
- BRW_REGISTER_TYPE_UD)));
- inst->conditional_mod = BRW_CONDITIONAL_NZ;
- }
bool has_indirect = false;
fs_reg reg = fs_reg(retype(brw_vec8_grf(payload.sample_mask_in_reg, 0),
BRW_REGISTER_TYPE_D));
dest.type = reg.type;
- fs_inst *inst = MOV(dest, reg);
- if (instr->has_predicate)
- inst->predicate = BRW_PREDICATE_NORMAL;
- emit(inst);
+ emit(MOV(dest, reg));
break;
}
src.type = dest.type;
index++;
- fs_inst *inst = MOV(dest, src);
- if (instr->has_predicate)
- inst->predicate = BRW_PREDICATE_NORMAL;
- emit(inst);
+ emit(MOV(dest, src));
dest.reg_offset++;
}
}
fs_reg(2)));
unsigned vec4_offset = instr->const_index[0] / 4;
- for (int i = 0; i < instr->num_components; i++) {
- exec_list list = VARYING_PULL_CONSTANT_LOAD(offset(dest, i),
- surf_index, base_offset,
- vec4_offset + i);
-
- fs_inst *last_inst = (fs_inst *) list.get_tail();
- if (instr->has_predicate)
- last_inst->predicate = BRW_PREDICATE_NORMAL;
- emit(list);
- }
+ for (int i = 0; i < instr->num_components; i++)
+ emit(VARYING_PULL_CONSTANT_LOAD(offset(dest, i), surf_index,
+ base_offset, vec4_offset + i));
} else {
fs_reg packed_consts = fs_reg(this, glsl_type::float_type);
packed_consts.type = dest.type;
*/
assert(packed_consts.subreg_offset < 32);
- fs_inst *inst = MOV(dest, packed_consts);
- if (instr->has_predicate)
- inst->predicate = BRW_PREDICATE_NORMAL;
- emit(inst);
-
+ emit(MOV(dest, packed_consts));
dest.reg_offset++;
}
}
src.type = dest.type;
index++;
- fs_inst *inst = MOV(dest, src);
- if (instr->has_predicate)
- inst->predicate = BRW_PREDICATE_NORMAL;
- emit(inst);
+ emit(MOV(dest, src));
dest.reg_offset++;
}
}
fs_reg src = interp_reg(instr->variables[0]->var->data.location, j);
src.type = dest.type;
- fs_inst *inst = emit(FS_OPCODE_LINTERP, dest, dst_x, dst_y, src);
- if (instr->has_predicate)
- inst->predicate = BRW_PREDICATE_NORMAL;
+ emit(FS_OPCODE_LINTERP, dest, dst_x, dst_y, src);
dest.reg_offset++;
}
break;
src.reladdr = new(mem_ctx) fs_reg(get_nir_src(instr->src[1]));
new_dest.type = src.type;
index++;
- fs_inst *inst = MOV(new_dest, src);
- if (instr->has_predicate)
- inst->predicate = BRW_PREDICATE_NORMAL;
- emit(inst);
+ emit(MOV(new_dest, src));
src.reg_offset++;
}
}