[PATCH vkd3d v8 4/4] vkd3d-shader/hlsl: Recostruct constant loads in copy propagation.

Giovanni Mascellani gmascellani at codeweavers.com
Sat Nov 20 08:38:00 CST 2021


Signed-off-by: Giovanni Mascellani <gmascellani at codeweavers.com>
---
 libs/vkd3d-shader/hlsl_codegen.c | 74 +++++++++++++++++++++++++++-----
 1 file changed, 64 insertions(+), 10 deletions(-)

diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c
index 367e854b..e0c93714 100644
--- a/libs/vkd3d-shader/hlsl_codegen.c
+++ b/libs/vkd3d-shader/hlsl_codegen.c
@@ -434,6 +434,48 @@ static struct hlsl_ir_node *copy_propagation_compute_replacement(struct copy_pro
     return node;
 }
 
+static struct hlsl_ir_node *copy_propagation_compute_constant(struct hlsl_ctx *ctx,
+        struct copy_propagation_var_def *variable, 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;
+    unsigned int i;
+
+    assert(offset + count <= variable->var->data_type->reg_size);
+
+    for (i = 0; i < count; ++i)
+    {
+        struct hlsl_ir_node *store_node = variable->values[offset + i].node;
+        enum hlsl_base_type store_type;
+
+        if (!store_node)
+            return NULL;
+        if (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;
+    }
+
+    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)
+    {
+        struct hlsl_ir_node *store_node = variable->values[offset + i].node;
+
+        constant->value[i] = hlsl_ir_constant(store_node)->value[variable->values[offset + i].component];
+    }
+
+    return &constant->node;
+}
+
 static bool copy_propagation_analyze_load(struct hlsl_ctx *ctx, struct hlsl_ir_load *load,
         struct copy_propagation_state *state)
 {
@@ -455,21 +497,33 @@ static bool copy_propagation_analyze_load(struct hlsl_ctx *ctx, struct hlsl_ir_l
     if (!variable)
         return false;
 
-    new_node = copy_propagation_compute_replacement(variable, offset, type->dimx, &swizzle);
+    if ((new_node = copy_propagation_compute_replacement(variable, offset, type->dimx, &swizzle)))
+    {
+        TRACE("Load from %s[%d-%d] reconstructed as instruction %p%s.\n",
+                var->name, offset, offset + type->dimx, new_node, debug_hlsl_swizzle(swizzle, 4));
 
-    TRACE("Load from %s[%d-%d] reconstructed 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);
 
-    if (!new_node)
-        return false;
+        replace_node(node, &swizzle_node->node);
 
-    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);
+        return true;
+    }
 
-    replace_node(node, &swizzle_node->node);
+    if ((new_node = copy_propagation_compute_constant(ctx, variable, offset, type->dimx, &load->node.loc)))
+    {
+        TRACE("Load from %s[%d-%d] reconstructed as constant value.\n",
+                var->name, offset, offset + type->dimx);
 
-    return true;
+        list_add_before(&node->entry, &new_node->entry);
+
+        replace_node(node, new_node);
+
+        return true;
+    }
+
+    return false;
 }
 
 static void copy_propagation_record_store(struct hlsl_ctx *ctx, struct hlsl_ir_store *store,
-- 
2.33.1




More information about the wine-devel mailing list