nir: Make "divergent" a property of an SSA value
v2: fix usage in ACO (by Daniel Schürmann) Reviewed-by: Rhys Perry <pendingchaos02@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/4062>
This commit is contained in:
committed by
Marge Bot
parent
db94a2d03d
commit
ca2d53f451
@@ -711,9 +711,8 @@ void emit_comparison(isel_context *ctx, nir_alu_instr *instr, Temp dst,
|
||||
{
|
||||
aco_opcode s_op = instr->src[0].src.ssa->bit_size == 64 ? s64_op : instr->src[0].src.ssa->bit_size == 32 ? s32_op : aco_opcode::num_opcodes;
|
||||
aco_opcode v_op = instr->src[0].src.ssa->bit_size == 64 ? v64_op : instr->src[0].src.ssa->bit_size == 32 ? v32_op : v16_op;
|
||||
bool divergent_vals = ctx->divergent_vals[instr->dest.dest.ssa.index];
|
||||
bool use_valu = s_op == aco_opcode::num_opcodes ||
|
||||
divergent_vals ||
|
||||
nir_dest_is_divergent(instr->dest.dest) ||
|
||||
ctx->allocated[instr->src[0].src.ssa->index].type() == RegType::vgpr ||
|
||||
ctx->allocated[instr->src[1].src.ssa->index].type() == RegType::vgpr;
|
||||
aco_opcode op = use_valu ? v_op : s_op;
|
||||
@@ -779,7 +778,7 @@ void emit_bcsel(isel_context *ctx, nir_alu_instr *instr, Temp dst)
|
||||
assert(els.regClass() == bld.lm);
|
||||
}
|
||||
|
||||
if (!ctx->divergent_vals[instr->src[0].src.ssa->index]) { /* uniform condition and values in sgpr */
|
||||
if (!nir_src_is_divergent(instr->src[0].src)) { /* uniform condition and values in sgpr */
|
||||
if (dst.regClass() == s1 || dst.regClass() == s2) {
|
||||
assert((then.regClass() == s1 || then.regClass() == s2) && els.regClass() == then.regClass());
|
||||
assert(dst.size() == then.size());
|
||||
@@ -5010,7 +5009,7 @@ void visit_load_resource(isel_context *ctx, nir_intrinsic_instr *instr)
|
||||
{
|
||||
Builder bld(ctx->program, ctx->block);
|
||||
Temp index = get_ssa_temp(ctx, instr->src[0].ssa);
|
||||
if (!ctx->divergent_vals[instr->dest.ssa.index])
|
||||
if (!nir_dest_is_divergent(instr->dest))
|
||||
index = bld.as_uniform(index);
|
||||
unsigned desc_set = nir_intrinsic_desc_set(instr);
|
||||
unsigned binding = nir_intrinsic_binding(instr);
|
||||
@@ -6086,7 +6085,7 @@ void visit_store_ssbo(isel_context *ctx, nir_intrinsic_instr *instr)
|
||||
Temp rsrc = convert_pointer_to_64_bit(ctx, get_ssa_temp(ctx, instr->src[1].ssa));
|
||||
rsrc = bld.smem(aco_opcode::s_load_dwordx4, bld.def(s4), rsrc, Operand(0u));
|
||||
|
||||
bool smem = !ctx->divergent_vals[instr->src[2].ssa->index] &&
|
||||
bool smem = !nir_src_is_divergent(instr->src[2]) &&
|
||||
ctx->options->chip_class >= GFX8 &&
|
||||
elem_size_bytes >= 4;
|
||||
if (smem)
|
||||
@@ -7477,11 +7476,11 @@ void visit_intrinsic(isel_context *ctx, nir_intrinsic_instr *instr)
|
||||
case nir_intrinsic_shuffle:
|
||||
case nir_intrinsic_read_invocation: {
|
||||
Temp src = get_ssa_temp(ctx, instr->src[0].ssa);
|
||||
if (!ctx->divergent_vals[instr->src[0].ssa->index]) {
|
||||
if (!nir_src_is_divergent(instr->src[0])) {
|
||||
emit_uniform_subgroup(ctx, instr, src);
|
||||
} else {
|
||||
Temp tid = get_ssa_temp(ctx, instr->src[1].ssa);
|
||||
if (instr->intrinsic == nir_intrinsic_read_invocation || !ctx->divergent_vals[instr->src[1].ssa->index])
|
||||
if (instr->intrinsic == nir_intrinsic_read_invocation || !nir_src_is_divergent(instr->src[1]))
|
||||
tid = bld.as_uniform(tid);
|
||||
Temp dst = get_ssa_temp(ctx, &instr->dest.ssa);
|
||||
if (src.regClass() == v1) {
|
||||
@@ -7587,7 +7586,7 @@ void visit_intrinsic(isel_context *ctx, nir_intrinsic_instr *instr)
|
||||
nir_intrinsic_cluster_size(instr) : 0;
|
||||
cluster_size = util_next_power_of_two(MIN2(cluster_size ? cluster_size : ctx->program->wave_size, ctx->program->wave_size));
|
||||
|
||||
if (!ctx->divergent_vals[instr->src[0].ssa->index] && (op == nir_op_ior || op == nir_op_iand)) {
|
||||
if (!nir_src_is_divergent(instr->src[0]) && (op == nir_op_ior || op == nir_op_iand)) {
|
||||
emit_uniform_subgroup(ctx, instr, src);
|
||||
} else if (instr->dest.ssa.bit_size == 1) {
|
||||
if (op == nir_op_imul || op == nir_op_umin || op == nir_op_imin)
|
||||
@@ -7670,7 +7669,7 @@ void visit_intrinsic(isel_context *ctx, nir_intrinsic_instr *instr)
|
||||
}
|
||||
case nir_intrinsic_quad_broadcast: {
|
||||
Temp src = get_ssa_temp(ctx, instr->src[0].ssa);
|
||||
if (!ctx->divergent_vals[instr->dest.ssa.index]) {
|
||||
if (!nir_dest_is_divergent(instr->dest)) {
|
||||
emit_uniform_subgroup(ctx, instr, src);
|
||||
} else {
|
||||
Temp dst = get_ssa_temp(ctx, &instr->dest.ssa);
|
||||
@@ -7717,7 +7716,7 @@ void visit_intrinsic(isel_context *ctx, nir_intrinsic_instr *instr)
|
||||
case nir_intrinsic_quad_swap_diagonal:
|
||||
case nir_intrinsic_quad_swizzle_amd: {
|
||||
Temp src = get_ssa_temp(ctx, instr->src[0].ssa);
|
||||
if (!ctx->divergent_vals[instr->dest.ssa.index]) {
|
||||
if (!nir_dest_is_divergent(instr->dest)) {
|
||||
emit_uniform_subgroup(ctx, instr, src);
|
||||
break;
|
||||
}
|
||||
@@ -7779,7 +7778,7 @@ void visit_intrinsic(isel_context *ctx, nir_intrinsic_instr *instr)
|
||||
}
|
||||
case nir_intrinsic_masked_swizzle_amd: {
|
||||
Temp src = get_ssa_temp(ctx, instr->src[0].ssa);
|
||||
if (!ctx->divergent_vals[instr->dest.ssa.index]) {
|
||||
if (!nir_dest_is_divergent(instr->dest)) {
|
||||
emit_uniform_subgroup(ctx, instr, src);
|
||||
break;
|
||||
}
|
||||
@@ -8774,7 +8773,7 @@ void visit_phi(isel_context *ctx, nir_phi_instr *instr)
|
||||
Temp dst = get_ssa_temp(ctx, &instr->dest.ssa);
|
||||
assert(instr->dest.ssa.bit_size != 1 || dst.regClass() == ctx->program->lane_mask);
|
||||
|
||||
bool logical = !dst.is_linear() || ctx->divergent_vals[instr->dest.ssa.index];
|
||||
bool logical = !dst.is_linear() || nir_dest_is_divergent(instr->dest);
|
||||
logical |= ctx->block->kind & block_kind_merge;
|
||||
aco_opcode opcode = logical ? aco_opcode::p_phi : aco_opcode::p_linear_phi;
|
||||
|
||||
@@ -9468,7 +9467,7 @@ static bool visit_if(isel_context *ctx, nir_if *if_stmt)
|
||||
aco_ptr<Pseudo_branch_instruction> branch;
|
||||
if_context ic;
|
||||
|
||||
if (!ctx->divergent_vals[if_stmt->condition.ssa->index]) { /* uniform condition */
|
||||
if (!nir_src_is_divergent(if_stmt->condition)) { /* uniform condition */
|
||||
/**
|
||||
* Uniform conditionals are represented in the following way*) :
|
||||
*
|
||||
@@ -10683,8 +10682,6 @@ void select_program(Program *program,
|
||||
if (ngg_no_gs && !ngg_early_prim_export(&ctx))
|
||||
ngg_emit_nogs_output(&ctx);
|
||||
|
||||
ralloc_free(ctx.divergent_vals);
|
||||
|
||||
if (i == 0 && ctx.stage == vertex_tess_control_hs && ctx.tcs_in_out_eq) {
|
||||
/* Outputs of the previous stage are inputs to the next stage */
|
||||
ctx.inputs = ctx.outputs;
|
||||
|
||||
@@ -57,7 +57,6 @@ struct isel_context {
|
||||
nir_shader *shader;
|
||||
uint32_t constant_data_offset;
|
||||
Block *block;
|
||||
bool *divergent_vals;
|
||||
std::unique_ptr<Temp[]> allocated;
|
||||
std::unordered_map<unsigned, std::array<Temp,NIR_MAX_VEC_COMPONENTS>> allocated_vec;
|
||||
Stage stage; /* Stage */
|
||||
@@ -152,7 +151,7 @@ unsigned get_interp_input(nir_intrinsic_op intrin, enum glsl_interp_mode interp)
|
||||
* block instead. This is so that we can use any SGPR live-out of the side
|
||||
* without the branch without creating a linear phi in the invert or merge block. */
|
||||
bool
|
||||
sanitize_if(nir_function_impl *impl, bool *divergent, nir_if *nif)
|
||||
sanitize_if(nir_function_impl *impl, nir_if *nif)
|
||||
{
|
||||
//TODO: skip this if the condition is uniform and there are no divergent breaks/continues?
|
||||
|
||||
@@ -197,7 +196,7 @@ sanitize_if(nir_function_impl *impl, bool *divergent, nir_if *nif)
|
||||
}
|
||||
|
||||
bool
|
||||
sanitize_cf_list(nir_function_impl *impl, bool *divergent, struct exec_list *cf_list)
|
||||
sanitize_cf_list(nir_function_impl *impl, struct exec_list *cf_list)
|
||||
{
|
||||
bool progress = false;
|
||||
foreach_list_typed(nir_cf_node, cf_node, node, cf_list) {
|
||||
@@ -206,14 +205,14 @@ sanitize_cf_list(nir_function_impl *impl, bool *divergent, struct exec_list *cf_
|
||||
break;
|
||||
case nir_cf_node_if: {
|
||||
nir_if *nif = nir_cf_node_as_if(cf_node);
|
||||
progress |= sanitize_cf_list(impl, divergent, &nif->then_list);
|
||||
progress |= sanitize_cf_list(impl, divergent, &nif->else_list);
|
||||
progress |= sanitize_if(impl, divergent, nif);
|
||||
progress |= sanitize_cf_list(impl, &nif->then_list);
|
||||
progress |= sanitize_cf_list(impl, &nif->else_list);
|
||||
progress |= sanitize_if(impl, nif);
|
||||
break;
|
||||
}
|
||||
case nir_cf_node_loop: {
|
||||
nir_loop *loop = nir_cf_node_as_loop(cf_node);
|
||||
progress |= sanitize_cf_list(impl, divergent, &loop->body);
|
||||
progress |= sanitize_cf_list(impl, &loop->body);
|
||||
break;
|
||||
}
|
||||
case nir_cf_node_function:
|
||||
@@ -238,11 +237,11 @@ void init_context(isel_context *ctx, nir_shader *shader)
|
||||
unsigned lane_mask_size = ctx->program->lane_mask.size();
|
||||
|
||||
ctx->shader = shader;
|
||||
ctx->divergent_vals = nir_divergence_analysis(shader, nir_divergence_view_index_uniform);
|
||||
nir_divergence_analysis(shader, nir_divergence_view_index_uniform);
|
||||
|
||||
/* sanitize control flow */
|
||||
nir_metadata_require(impl, nir_metadata_dominance);
|
||||
sanitize_cf_list(impl, ctx->divergent_vals, &impl->body);
|
||||
sanitize_cf_list(impl, &impl->body);
|
||||
nir_metadata_preserve(impl, (nir_metadata)~nir_metadata_block_index);
|
||||
|
||||
/* we'll need this for isel */
|
||||
@@ -332,10 +331,10 @@ void init_context(isel_context *ctx, nir_shader *shader)
|
||||
case nir_op_b2f16:
|
||||
case nir_op_b2f32:
|
||||
case nir_op_mov:
|
||||
type = ctx->divergent_vals[alu_instr->dest.dest.ssa.index] ? RegType::vgpr : RegType::sgpr;
|
||||
type = nir_dest_is_divergent(alu_instr->dest.dest) ? RegType::vgpr : RegType::sgpr;
|
||||
break;
|
||||
case nir_op_bcsel:
|
||||
type = ctx->divergent_vals[alu_instr->dest.dest.ssa.index] ? RegType::vgpr : RegType::sgpr;
|
||||
type = nir_dest_is_divergent(alu_instr->dest.dest) ? RegType::vgpr : RegType::sgpr;
|
||||
/* fallthrough */
|
||||
default:
|
||||
for (unsigned i = 0; i < nir_op_infos[alu_instr->op].num_inputs; i++) {
|
||||
@@ -465,7 +464,7 @@ void init_context(isel_context *ctx, nir_shader *shader)
|
||||
case nir_intrinsic_load_global:
|
||||
case nir_intrinsic_vulkan_resource_index:
|
||||
case nir_intrinsic_load_shared:
|
||||
type = ctx->divergent_vals[intrinsic->dest.ssa.index] ? RegType::vgpr : RegType::sgpr;
|
||||
type = nir_dest_is_divergent(intrinsic->dest) ? RegType::vgpr : RegType::sgpr;
|
||||
break;
|
||||
case nir_intrinsic_load_view_index:
|
||||
type = ctx->stage == fragment_fs ? RegType::vgpr : RegType::sgpr;
|
||||
@@ -524,9 +523,10 @@ void init_context(isel_context *ctx, nir_shader *shader)
|
||||
|
||||
if (tex->dest.ssa.bit_size == 64)
|
||||
size *= 2;
|
||||
if (tex->op == nir_texop_texture_samples)
|
||||
assert(!ctx->divergent_vals[tex->dest.ssa.index]);
|
||||
if (ctx->divergent_vals[tex->dest.ssa.index])
|
||||
if (tex->op == nir_texop_texture_samples) {
|
||||
assert(!tex->dest.ssa.divergent);
|
||||
}
|
||||
if (nir_dest_is_divergent(tex->dest))
|
||||
allocated[tex->dest.ssa.index] = Temp(0, RegClass(RegType::vgpr, size));
|
||||
else
|
||||
allocated[tex->dest.ssa.index] = Temp(0, RegClass(RegType::sgpr, size));
|
||||
@@ -558,7 +558,7 @@ void init_context(isel_context *ctx, nir_shader *shader)
|
||||
break;
|
||||
}
|
||||
|
||||
if (ctx->divergent_vals[phi->dest.ssa.index]) {
|
||||
if (nir_dest_is_divergent(phi->dest)) {
|
||||
type = RegType::vgpr;
|
||||
} else {
|
||||
type = RegType::sgpr;
|
||||
|
||||
Reference in New Issue
Block a user