[PATCH vkd3d v3 4/6] vkd3d-shader/hlsl: Perform a copy propagation pass.

Zebediah Figura (she/her) zfigura at codeweavers.com
Thu Nov 11 22:32:27 CST 2021


Looking really good, at least from visual examination; the only thing I 
have left for the moment is nitpicking the trace formats...

On 11/11/21 05:06, Giovanni Mascellani wrote:
> +static void copy_propagation_invalidate_whole_variable(struct copy_propagation_variable *variable)
> +{
> +    TRACE("invalidate variable %s\n", variable->var->name);

Nitpick, but can you please make this trace consistent with vkd3d style?

> +    memset(variable->values, 0, sizeof(*variable->values) * variable->var->data_type->reg_size);
> +}
> +
> +static void copy_propagation_set_value(struct copy_propagation_variable *variable, unsigned int offset,
> +        unsigned char writemask, struct hlsl_ir_node *node)
> +{
> +    unsigned int i;
> +
> +    for (i = 0; i < 4; ++i)
> +    {
> +        if (writemask & (1u << i))
> +        {
> +            TRACE("variable %s[%d] is written by %p[%d]\n", variable->var->name, offset + i, node, i);

And this one.

> +            variable->values[offset + i].node = node;
> +            variable->values[offset + i].component = i;
> +        }
> +    }
> +}
> +
> +static struct hlsl_ir_node *copy_propagation_find_replacement(struct copy_propagation_variable *variable,
> +        unsigned int offset, unsigned int count, unsigned int *swizzle)
> +{
> +    struct hlsl_ir_node *node = NULL;
> +    unsigned int i;
> +
> +    assert(offset + count <= variable->var->data_type->reg_size);
> +
> +    *swizzle = 0;
> +
> +    for (i = 0; i < count; ++i)
> +    {
> +        if (!node)
> +            node = variable->values[offset + i].node;
> +        else if (node != variable->values[offset + i].node)
> +            return NULL;
> +        *swizzle |= variable->values[offset + i].component << (2 * i);
> +    }
> +
> +    return node;
> +}
> +
> +static bool copy_propagation_analyze_load(struct hlsl_ctx *ctx, struct hlsl_ir_load *load,
> +        struct copy_propagation_state *state)
> +{
> +    struct hlsl_ir_node *node = &load->node, *new_node;
> +    struct copy_propagation_variable *variable;
> +    struct hlsl_type *type = node->data_type;
> +    unsigned int offset, swizzle;
> +    struct hlsl_deref *src = &load->src;
> +    struct hlsl_ir_var *var = src->var;
> +    struct hlsl_ir_swizzle *swizzle_node;
> +
> +    if (type->type != HLSL_CLASS_SCALAR && type->type != HLSL_CLASS_VECTOR)
> +        return false;
> +
> +    if (!hlsl_offset_from_deref(src, &offset))
> +        return false;
> +
> +    variable = copy_propagation_get_variable(state, var);
> +    if (!variable)
> +        return false;
> +
> +    new_node = copy_propagation_find_replacement(variable, offset, type->dimx, &swizzle);
> +
> +    TRACE("load from %s[%d-%d] reconstructed to %p[%u %u %u %u]\n", var->name, offset, offset + type->dimx,
> +            new_node, swizzle % 4, (swizzle >> 2) % 4, (swizzle >> 4) % 4, (swizzle >> 6) % 4);

And this one. Also, do we want to dump the latter part as a swizzle, à 
la dump_ir_swizzle(), and the former with debug_hlsl_writemask()? I'd 
think so, although then again I haven't made use of the trace.



More information about the wine-devel mailing list