[PATCH vkd3d v2 1/3] vkd3d-shader/hlsl: Handle branches in copy propagation.
Zebediah Figura (she/her)
zfigura at codeweavers.com
Thu Jan 20 20:19:40 CST 2022
On 1/20/22 05:23, Giovanni Mascellani wrote:
> @@ -307,15 +316,23 @@ static void copy_propagation_var_def_destroy(struct rb_entry *entry, void *conte
> vkd3d_free(var_def);
> }
>
> -static struct copy_propagation_var_def *copy_propagation_get_var_def(struct copy_propagation_state *state,
> - struct hlsl_ir_var *var)
> +static struct copy_propagation_value *copy_propagation_get_value(struct copy_propagation_state *state,
> + struct hlsl_ir_var *var, unsigned component)
> {
> - struct rb_entry *entry = rb_get(&state->var_defs, var);
> + for (; state; state = state->parent)
> + {
> + struct rb_entry *entry = rb_get(&state->var_defs, var);
> + if (entry)
> + {
> + struct copy_propagation_var_def *var_def = RB_ENTRY_VALUE(entry, struct copy_propagation_var_def, entry);
> + assert(component < var_def->var->data_type->reg_size);
>
> - if (entry)
> - return RB_ENTRY_VALUE(entry, struct copy_propagation_var_def, entry);
> - else
> - return NULL;
> + if (var_def->values[component].state != VALUE_STATE_NOT_WRITTEN)
Why not just check for VALUE_STATE_STATICALLY_WRITTEN?
> + return &var_def->values[component];
> + }
> + }
> +
> + return NULL;
> }
>
> static struct copy_propagation_var_def *copy_propagation_create_var_def(struct hlsl_ctx *ctx,
> @@ -339,10 +356,35 @@ static struct copy_propagation_var_def *copy_propagation_create_var_def(struct h
> return var_def;
> }
>
> +static void copy_propagation_invalidate_variable(struct copy_propagation_var_def *var_def,
> + unsigned offset, unsigned char writemask)
> +{
> + unsigned i;
> +
> + TRACE("Invalidate variable %s[%u]%s.\n", var_def->var->name, offset, debug_hlsl_writemask(writemask));
> +
> + for (i = 0; i < 4; ++i)
> + {
> + if (writemask & (1u << i))
> + {
> + memset(&var_def->values[offset + i], 0, sizeof(var_def->values[offset + i]));
This memset() doesn't seem necessary anymore.
> + var_def->values[offset + i].state = VALUE_STATE_DYNAMICALLY_WRITTEN;
> + }
> + }
> +}
> +
> static void copy_propagation_invalidate_whole_variable(struct copy_propagation_var_def *var_def)
> {
> + unsigned i;
> +
> TRACE("Invalidate variable %s.\n", var_def->var->name);
> +
> memset(var_def->values, 0, sizeof(*var_def->values) * var_def->var->data_type->reg_size);
Note that you don't need this memset() anymore either.
> +
> + for (i = 0; i < var_def->var->data_type->reg_size; ++i)
> + {
> + var_def->values[i].state = VALUE_STATE_DYNAMICALLY_WRITTEN;
> + }
> }
>
...
> +static void copy_propagation_invalidate_from_block(struct hlsl_ctx *ctx, struct copy_propagation_state *state,
> + struct hlsl_block *block)
> +{
> + struct hlsl_ir_node *instr;
> +
> + LIST_FOR_EACH_ENTRY(instr, &block->instrs, struct hlsl_ir_node, entry)
> + {
> + switch (instr->type)
> + {
> + case HLSL_IR_STORE:
> + {
> + struct hlsl_ir_store *store = hlsl_ir_store(instr);
> + struct copy_propagation_var_def *var_def;
> + struct hlsl_deref *lhs = &store->lhs;
> + struct hlsl_ir_var *var = lhs->var;
> + unsigned int offset;
> +
> + if (!(var_def = copy_propagation_create_var_def(ctx, state, var)))
> + continue;
> +
> + if (hlsl_offset_from_deref(lhs, &offset))
> + copy_propagation_invalidate_variable(var_def, offset, store->writemask);
> + else
> + copy_propagation_invalidate_whole_variable(var_def);
> +
> + break;
> + }
> +
> + case HLSL_IR_IF:
> + {
> + struct hlsl_ir_if *iff = hlsl_ir_if(instr);
> +
> + copy_propagation_invalidate_from_block(ctx, state, &iff->then_instrs);
> + copy_propagation_invalidate_from_block(ctx, state, &iff->else_instrs);
> +
> + break;
> + }
> +
> + case HLSL_IR_LOOP:
> + {
> + struct hlsl_ir_loop *loop = hlsl_ir_loop(instr);
> +
> + copy_propagation_invalidate_from_block(ctx, state, &loop->body);
> +
> + break;
> + }
> +
> + default:
> + break;
> + }
> + }
> +}
As an alternative, you could iterate over the whole state, marking the
parent as "dynamically written" wherever the child state is written.
More information about the wine-devel
mailing list