[PATCH vkd3d v2 3/3] vkd3d-shader/hlsl: Propagate constant loads in copy propagation.
Giovanni Mascellani
gmascellani at codeweavers.com
Thu Jan 20 05:23:49 CST 2022
Signed-off-by: Giovanni Mascellani <gmascellani at codeweavers.com>
---
v2: Fixed for the new copy propagation architecture.
---
libs/vkd3d-shader/hlsl_codegen.c | 75 +++++++++++++++++++++++++++-----
1 file changed, 65 insertions(+), 10 deletions(-)
diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c
index 787191d2..76f88bc2 100644
--- a/libs/vkd3d-shader/hlsl_codegen.c
+++ b/libs/vkd3d-shader/hlsl_codegen.c
@@ -405,6 +405,52 @@ static void copy_propagation_set_value(struct copy_propagation_var_def *var_def,
}
}
+static struct hlsl_ir_node *copy_propagation_compute_constant(struct hlsl_ctx *ctx, struct copy_propagation_state *state,
+ struct hlsl_ir_var *var, unsigned int offset, unsigned int count,
+ const struct vkd3d_shader_location *loc)
+{
+ enum hlsl_base_type type = HLSL_TYPE_VOID;
+ struct hlsl_ir_constant *constant = NULL;
+ struct hlsl_ir_node *store_nodes[4];
+ unsigned store_components[4];
+ unsigned int i;
+
+ assert(offset + count <= var->data_type->reg_size);
+
+ for (i = 0; i < count; ++i)
+ {
+ struct copy_propagation_value *value = copy_propagation_get_value(state, var, offset + i);
+ struct hlsl_ir_node *store_node;
+ enum hlsl_base_type store_type;
+
+ if (!value || value->state != VALUE_STATE_STATICALLY_WRITTEN)
+ return NULL;
+
+ store_node = value->node;
+ if (!store_node || store_node->type != HLSL_IR_CONSTANT)
+ return NULL;
+
+ store_type = store_node->data_type->base_type;
+
+ if (type == HLSL_TYPE_VOID)
+ type = store_type;
+ else if (type != store_type)
+ return NULL;
+
+ store_nodes[i] = store_node;
+ store_components[i] = value->component;
+ }
+
+ if (!(constant = hlsl_new_uint_constant(ctx, 0, *loc)))
+ return NULL;
+ constant->node.data_type = hlsl_get_vector_type(ctx, type, count);
+
+ for (i = 0; i < count; ++i)
+ constant->value[i] = hlsl_ir_constant(store_nodes[i])->value[store_components[i]];
+
+ return &constant->node;
+}
+
static struct hlsl_ir_node *copy_propagation_compute_replacement(struct copy_propagation_state *state,
struct hlsl_ir_var *var, unsigned int offset, unsigned int count, unsigned int *swizzle)
{
@@ -448,19 +494,28 @@ static bool copy_propagation_analyze_load(struct hlsl_ctx *ctx, struct hlsl_ir_l
if (!hlsl_offset_from_deref(src, &offset))
return false;
- if (!(new_node = copy_propagation_compute_replacement(state, var, offset, type->dimx, &swizzle)))
+ if ((new_node = copy_propagation_compute_constant(ctx, state, var, offset, type->dimx, &load->node.loc)))
{
- TRACE("No single source for propagating load from %s[%u-%u].\n", var->name, offset, offset + type->dimx);
- return false;
+ TRACE("Load from %s[%d-%d] reconstructed as constant value.\n",
+ var->name, offset, offset + type->dimx);
+ list_add_before(&node->entry, &new_node->entry);
+ replace_node(node, new_node);
+ return true;
}
- TRACE("Load from %s[%u-%u] propagated as instruction %p%s.\n",
- var->name, offset, offset + type->dimx, new_node, debug_hlsl_swizzle(swizzle, 4));
- if (!(swizzle_node = hlsl_new_swizzle(ctx, swizzle, type->dimx, new_node, &node->loc)))
- return false;
- list_add_before(&node->entry, &swizzle_node->node.entry);
- replace_node(node, &swizzle_node->node);
- return true;
+ if ((new_node = copy_propagation_compute_replacement(state, var, offset, type->dimx, &swizzle)))
+ {
+ TRACE("Load from %s[%u-%u] propagated as instruction %p%s.\n",
+ var->name, offset, offset + type->dimx, new_node, debug_hlsl_swizzle(swizzle, 4));
+ if (!(swizzle_node = hlsl_new_swizzle(ctx, swizzle, type->dimx, new_node, &node->loc)))
+ return false;
+ list_add_before(&node->entry, &swizzle_node->node.entry);
+ replace_node(node, &swizzle_node->node);
+ return true;
+ }
+
+ TRACE("No single source for propagating load from %s[%u-%u].\n", var->name, offset, offset + type->dimx);
+ return false;
}
static void copy_propagation_record_store(struct hlsl_ctx *ctx, struct hlsl_ir_store *store,
--
2.34.1
More information about the wine-devel
mailing list