[PATCH 5/5] d3dcompiler: Track def-use chains for anonymous nodes.

Zebediah Figura z.figura12 at gmail.com
Tue Apr 14 19:39:58 CDT 2020


From: Zebediah Figura <zfigura at codeweavers.com>

This will be generally useful, and it's easier to make this change now while
relatively few things are touching source pointers.

Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
 dlls/d3dcompiler_43/d3dcompiler_private.h | 41 +++++++++++++-----
 dlls/d3dcompiler_43/hlsl.y                | 53 +++++++++++++----------
 dlls/d3dcompiler_43/utils.c               | 48 ++++++++++----------
 3 files changed, 84 insertions(+), 58 deletions(-)

diff --git a/dlls/d3dcompiler_43/d3dcompiler_private.h b/dlls/d3dcompiler_43/d3dcompiler_private.h
index 1aa232791ba..c235dff8e2f 100644
--- a/dlls/d3dcompiler_43/d3dcompiler_private.h
+++ b/dlls/d3dcompiler_43/d3dcompiler_private.h
@@ -662,6 +662,8 @@ struct hlsl_ir_node
     enum hlsl_ir_node_type type;
     struct hlsl_type *data_type;
 
+    struct list uses;
+
     struct source_location loc;
 
     /* Liveness ranges. "index" is the index of this instruction. Since this is
@@ -671,6 +673,12 @@ struct hlsl_ir_node
     unsigned int index, last_read;
 };
 
+struct hlsl_src
+{
+    struct hlsl_ir_node *node;
+    struct list entry;
+};
+
 #define HLSL_STORAGE_EXTERN          0x00000001
 #define HLSL_STORAGE_NOINTERPOLATION 0x00000002
 #define HLSL_MODIFIER_PRECISE        0x00000004
@@ -732,7 +740,7 @@ struct hlsl_ir_function_decl
 struct hlsl_ir_if
 {
     struct hlsl_ir_node node;
-    struct hlsl_ir_node *condition;
+    struct hlsl_src condition;
     struct list *then_instrs;
     struct list *else_instrs;
 };
@@ -816,7 +824,7 @@ struct hlsl_ir_expr
 {
     struct hlsl_ir_node node;
     enum hlsl_ir_expr_op op;
-    struct hlsl_ir_node *operands[3];
+    struct hlsl_src operands[3];
 };
 
 enum hlsl_ir_jump_type
@@ -831,13 +839,13 @@ struct hlsl_ir_jump
 {
     struct hlsl_ir_node node;
     enum hlsl_ir_jump_type type;
-    struct hlsl_ir_node *return_value;
+    struct hlsl_src return_value;
 };
 
 struct hlsl_ir_swizzle
 {
     struct hlsl_ir_node node;
-    struct hlsl_ir_node *val;
+    struct hlsl_src val;
     DWORD swizzle;
 };
 
@@ -856,12 +864,12 @@ struct hlsl_deref
         struct hlsl_ir_var *var;
         struct
         {
-            struct hlsl_ir_node *array;
-            struct hlsl_ir_node *index;
+            struct hlsl_src array;
+            struct hlsl_src index;
         } array;
         struct
         {
-            struct hlsl_ir_node *record;
+            struct hlsl_src record;
             struct hlsl_struct_field *field;
         } record;
     } v;
@@ -882,7 +890,7 @@ struct hlsl_lvalue
         struct
         {
             struct hlsl_lvalue *array;
-            struct hlsl_ir_node *index;
+            struct hlsl_src index;
         } array;
         struct
         {
@@ -896,7 +904,7 @@ struct hlsl_ir_assignment
 {
     struct hlsl_ir_node node;
     struct hlsl_lvalue lhs;
-    struct hlsl_ir_node *rhs;
+    struct hlsl_src rhs;
     unsigned char writemask;
 };
 
@@ -921,7 +929,7 @@ struct hlsl_ir_constant
 struct hlsl_ir_constructor
 {
     struct hlsl_ir_node node;
-    struct hlsl_ir_node *args[16];
+    struct hlsl_src args[16];
     unsigned int args_count;
 };
 
@@ -1102,6 +1110,19 @@ static inline void init_node(struct hlsl_ir_node *node, enum hlsl_ir_node_type t
     node->type = type;
     node->data_type = data_type;
     node->loc = loc;
+    list_init(&node->uses);
+}
+
+static inline void hlsl_src_from_node(struct hlsl_src *src, struct hlsl_ir_node *node)
+{
+    src->node = node;
+    list_add_tail(&node->uses, &src->entry);
+}
+
+static inline void hlsl_src_remove(struct hlsl_src *src)
+{
+    src->node = NULL;
+    list_remove(&src->entry);
 }
 
 BOOL add_declaration(struct hlsl_scope *scope, struct hlsl_ir_var *decl, BOOL local_var) DECLSPEC_HIDDEN;
diff --git a/dlls/d3dcompiler_43/hlsl.y b/dlls/d3dcompiler_43/hlsl.y
index c0ad6cda9e0..1b6e31e4964 100644
--- a/dlls/d3dcompiler_43/hlsl.y
+++ b/dlls/d3dcompiler_43/hlsl.y
@@ -278,7 +278,7 @@ static BOOL append_conditional_break(struct list *cond_list)
         return FALSE;
     }
     init_node(&iff->node, HLSL_IR_IF, NULL, condition->loc);
-    iff->condition = not;
+    hlsl_src_from_node(&iff->condition, not);
     list_add_tail(cond_list, &iff->node.entry);
 
     if (!(iff->then_instrs = d3dcompiler_alloc(sizeof(*iff->then_instrs))))
@@ -391,7 +391,7 @@ static struct hlsl_ir_swizzle *new_swizzle(DWORD s, unsigned int components,
         return NULL;
     init_node(&swizzle->node, HLSL_IR_SWIZZLE,
             new_hlsl_type(NULL, HLSL_CLASS_VECTOR, val->data_type->base_type, components, 1), *loc);
-    swizzle->val = val;
+    hlsl_src_from_node(&swizzle->val, val);
     swizzle->swizzle = s;
     return swizzle;
 }
@@ -482,6 +482,8 @@ static struct hlsl_ir_jump *new_return(struct hlsl_ir_node *value, struct source
 {
     struct hlsl_type *return_type = hlsl_ctx.cur_function->return_type;
     struct hlsl_ir_jump *jump = d3dcompiler_alloc(sizeof(*jump));
+    struct hlsl_ir_node *return_value;
+
     if (!jump)
     {
         ERR("Out of memory\n");
@@ -491,11 +493,12 @@ static struct hlsl_ir_jump *new_return(struct hlsl_ir_node *value, struct source
     jump->type = HLSL_IR_JUMP_RETURN;
     if (value)
     {
-        if (!(jump->return_value = implicit_conversion(value, return_type, &loc)))
+        if (!(return_value = implicit_conversion(value, return_type, &loc)))
         {
             d3dcompiler_free(jump);
             return NULL;
         }
+        hlsl_src_from_node(&jump->return_value, return_value);
     }
     else if (return_type->base_type != HLSL_TYPE_VOID)
     {
@@ -534,7 +537,7 @@ static struct hlsl_ir_deref *new_record_deref(struct hlsl_ir_node *record,
     }
     init_node(&deref->node, HLSL_IR_DEREF, field->type, loc);
     deref->src.type = HLSL_IR_DEREF_RECORD;
-    deref->src.v.record.record = record;
+    hlsl_src_from_node(&deref->src.v.record.record, record);
     deref->src.v.record.field = field;
     return deref;
 }
@@ -1992,16 +1995,18 @@ jump_statement:           KW_RETURN expr ';'
 selection_statement:      KW_IF '(' expr ')' if_body
                             {
                                 struct hlsl_ir_if *instr = d3dcompiler_alloc(sizeof(*instr));
+                                struct hlsl_ir_node *condition = node_from_list($3);
+
                                 if (!instr)
                                 {
                                     ERR("Out of memory\n");
                                     YYABORT;
                                 }
                                 init_node(&instr->node, HLSL_IR_IF, NULL, get_location(&@1));
-                                instr->condition = node_from_list($3);
+                                hlsl_src_from_node(&instr->condition, condition);
                                 instr->then_instrs = $5.then_instrs;
                                 instr->else_instrs = $5.else_instrs;
-                                if (instr->condition->data_type->dimx > 1 || instr->condition->data_type->dimy > 1)
+                                if (condition->data_type->dimx > 1 || condition->data_type->dimy > 1)
                                 {
                                     hlsl_report_message(instr->node.loc, HLSL_LEVEL_ERROR,
                                             "if condition requires a scalar");
@@ -2262,9 +2267,8 @@ postfix_expr:             primary_expr
                                 }
                                 init_node(&deref->node, HLSL_IR_DEREF, data_type, get_location(&@2));
                                 deref->src.type = HLSL_IR_DEREF_ARRAY;
-                                deref->src.v.array.array = node_from_list($1);
-                                deref->src.v.array.index = node_from_list($3);
-
+                                hlsl_src_from_node(&deref->src.v.array.array, node_from_list($1));
+                                hlsl_src_from_node(&deref->src.v.array.index, node_from_list($3));
                                 $$ = append_binop($1, $3, &deref->node);
                             }
                           /* "var_modifiers" doesn't make sense in this case, but it's needed
@@ -2272,6 +2276,7 @@ postfix_expr:             primary_expr
                         | var_modifiers type '(' initializer_expr_list ')'
                             {
                                 struct hlsl_ir_constructor *constructor;
+                                unsigned int i;
 
                                 TRACE("%s constructor.\n", debug_hlsl_type($2));
                                 if ($1)
@@ -2300,7 +2305,8 @@ postfix_expr:             primary_expr
                                 constructor = d3dcompiler_alloc(sizeof(*constructor));
                                 init_node(&constructor->node, HLSL_IR_CONSTRUCTOR, $2, get_location(&@3));
                                 constructor->args_count = $4.args_count;
-                                memcpy(constructor->args, $4.args, $4.args_count * sizeof(*$4.args));
+                                for (i = 0; i < $4.args_count; ++i)
+                                    hlsl_src_from_node(&constructor->args[i], $4.args[i]);
                                 d3dcompiler_free($4.args);
                                 $$ = append_unop($4.instrs, &constructor->node);
                             }
@@ -2699,7 +2705,7 @@ static void compute_liveness_recurse(struct list *instrs, unsigned int loop_firs
             var = hlsl_var_from_lvalue(&assignment->lhs);
             if (!var->first_write)
                 var->first_write = loop_first ? min(instr->index, loop_first) : instr->index;
-            assignment->rhs->last_read = instr->index;
+            assignment->rhs.node->last_read = instr->index;
             break;
         }
         case HLSL_IR_CONSTANT:
@@ -2709,7 +2715,7 @@ static void compute_liveness_recurse(struct list *instrs, unsigned int loop_firs
             struct hlsl_ir_constructor *constructor = constructor_from_node(instr);
             unsigned int i;
             for (i = 0; i < constructor->args_count; ++i)
-                constructor->args[i]->last_read = instr->index;
+                constructor->args[i].node->last_read = instr->index;
             break;
         }
         case HLSL_IR_DEREF:
@@ -2723,12 +2729,12 @@ static void compute_liveness_recurse(struct list *instrs, unsigned int loop_firs
                     break;
 
                 case HLSL_IR_DEREF_ARRAY:
-                    deref->src.v.array.array->last_read = instr->index;
-                    deref->src.v.array.index->last_read = instr->index;
+                    deref->src.v.array.array.node->last_read = instr->index;
+                    deref->src.v.array.index.node->last_read = instr->index;
                     break;
 
                 case HLSL_IR_DEREF_RECORD:
-                    deref->src.v.record.record->last_read = instr->index;
+                    deref->src.v.record.record.node->last_read = instr->index;
                     break;
             }
             break;
@@ -2736,11 +2742,10 @@ static void compute_liveness_recurse(struct list *instrs, unsigned int loop_firs
         case HLSL_IR_EXPR:
         {
             struct hlsl_ir_expr *expr = expr_from_node(instr);
-            expr->operands[0]->last_read = instr->index;
-            if (expr->operands[1])
-                expr->operands[1]->last_read = instr->index;
-            if (expr->operands[2])
-                expr->operands[2]->last_read = instr->index;
+            unsigned int i;
+
+            for (i = 0; i < ARRAY_SIZE(expr->operands) && expr->operands[i].node; ++i)
+                expr->operands[i].node->last_read = instr->index;
             break;
         }
         case HLSL_IR_IF:
@@ -2749,14 +2754,14 @@ static void compute_liveness_recurse(struct list *instrs, unsigned int loop_firs
             compute_liveness_recurse(iff->then_instrs, loop_first, loop_last);
             if (iff->else_instrs)
                 compute_liveness_recurse(iff->else_instrs, loop_first, loop_last);
-            iff->condition->last_read = instr->index;
+            iff->condition.node->last_read = instr->index;
             break;
         }
         case HLSL_IR_JUMP:
         {
             struct hlsl_ir_jump *jump = jump_from_node(instr);
-            if (jump->type == HLSL_IR_JUMP_RETURN && jump->return_value)
-                jump->return_value->last_read = instr->index;
+            if (jump->type == HLSL_IR_JUMP_RETURN && jump->return_value.node)
+                jump->return_value.node->last_read = instr->index;
             break;
         }
         case HLSL_IR_LOOP:
@@ -2769,7 +2774,7 @@ static void compute_liveness_recurse(struct list *instrs, unsigned int loop_firs
         case HLSL_IR_SWIZZLE:
         {
             struct hlsl_ir_swizzle *swizzle = swizzle_from_node(instr);
-            swizzle->val->last_read = instr->index;
+            swizzle->val.node->last_read = instr->index;
             break;
         }
         default:
diff --git a/dlls/d3dcompiler_43/utils.c b/dlls/d3dcompiler_43/utils.c
index 991306d5947..8537e193db4 100644
--- a/dlls/d3dcompiler_43/utils.c
+++ b/dlls/d3dcompiler_43/utils.c
@@ -1363,9 +1363,8 @@ struct hlsl_ir_expr *new_expr(enum hlsl_ir_expr_op op, struct hlsl_ir_node **ope
         return NULL;
     init_node(&expr->node, HLSL_IR_EXPR, type, *loc);
     expr->op = op;
-    expr->operands[0] = operands[0];
-    expr->operands[1] = operands[1];
-    expr->operands[2] = operands[2];
+    for (i = 0; i <= 2 && operands[i]; ++i)
+        hlsl_src_from_node(&expr->operands[i], operands[i]);
 
     return expr;
 }
@@ -1455,16 +1454,16 @@ static BOOL get_assignment_lhs(struct hlsl_lvalue *dst, struct hlsl_ir_node *nod
             return TRUE;
 
         case HLSL_IR_DEREF_ARRAY:
-            dst->v.array.index = deref->src.v.array.index;
+            hlsl_src_from_node(&dst->v.array.index, deref->src.v.array.index.node);
             if (!(dst->v.array.array = d3dcompiler_alloc(sizeof(*dst->v.array.array))))
                 return FALSE;
-            return get_assignment_lhs(dst->v.array.array, deref->src.v.array.array);
+            return get_assignment_lhs(dst->v.array.array, deref->src.v.array.array.node);
 
         case HLSL_IR_DEREF_RECORD:
             dst->v.record.field = deref->src.v.record.field;
             if (!(dst->v.record.record = d3dcompiler_alloc(sizeof(*dst->v.record.field))))
                 return FALSE;
-            return get_assignment_lhs(dst->v.record.record, deref->src.v.record.record);
+            return get_assignment_lhs(dst->v.record.record, deref->src.v.record.record.node);
 
         default:
             assert(0);
@@ -1501,11 +1500,12 @@ struct hlsl_ir_node *make_assignment(struct hlsl_ir_node *lhs, enum parse_assign
             if (lhs->data_type->type == HLSL_CLASS_MATRIX)
                 FIXME("Assignments with writemasks and matrices on lhs are not supported yet.\n");
 
-            lhs_inner = swizzle->val;
+            lhs_inner = swizzle->val.node;
+            hlsl_src_remove(&swizzle->val);
             list_remove(&lhs->entry);
 
             list_add_after(&rhs->entry, &lhs->entry);
-            swizzle->val = rhs;
+            hlsl_src_from_node(&swizzle->val, rhs);
             if (!(writemask = invert_swizzle(&swizzle->swizzle, writemask)))
             {
                 hlsl_report_message(lhs->loc, HLSL_LEVEL_ERROR, "invalid writemask");
@@ -1574,21 +1574,21 @@ struct hlsl_ir_node *make_assignment(struct hlsl_ir_node *lhs, enum parse_assign
         if (assign->lhs.type != HLSL_IR_DEREF_VAR)
         {
             FIXME("LHS expression not supported in compound assignments yet.\n");
-            assign->rhs = rhs;
+            hlsl_src_from_node(&assign->rhs, rhs);
         }
         else
         {
             TRACE("Adding an expression for the compound assignment.\n");
             expr = new_binary_expr(op, lhs, rhs, lhs->loc);
             list_add_after(&rhs->entry, &expr->entry);
-            assign->rhs = expr;
+            hlsl_src_from_node(&assign->rhs, expr);
         }
     }
     else
     {
         /* We could free the LHS derefs here, since we aren't using them
          * anymore, but it's easier just to leave that to a DCE pass. */
-        assign->rhs = rhs;
+        hlsl_src_from_node(&assign->rhs, rhs);
     }
 
     return &assign->node;
@@ -1895,7 +1895,7 @@ static void debug_dump_lvalue(const struct hlsl_lvalue *deref)
         case HLSL_IR_DEREF_ARRAY:
             debug_dump_lvalue(deref->v.array.array);
             wine_dbg_printf("[");
-            debug_dump_src(deref->v.array.index);
+            debug_dump_src(deref->v.array.index.node);
             wine_dbg_printf("]");
             break;
         case HLSL_IR_DEREF_RECORD:
@@ -1915,13 +1915,13 @@ static void debug_dump_deref(const struct hlsl_deref *deref)
             wine_dbg_printf(")");
             break;
         case HLSL_IR_DEREF_ARRAY:
-            debug_dump_src(deref->v.array.array);
+            debug_dump_src(deref->v.array.array.node);
             wine_dbg_printf("[");
-            debug_dump_src(deref->v.array.index);
+            debug_dump_src(deref->v.array.index.node);
             wine_dbg_printf("]");
             break;
         case HLSL_IR_DEREF_RECORD:
-            debug_dump_src(deref->v.record.record);
+            debug_dump_src(deref->v.record.record.node);
             wine_dbg_printf(".%s", debugstr_a(deref->v.record.field->name));
             break;
     }
@@ -2050,9 +2050,9 @@ static void debug_dump_ir_expr(const struct hlsl_ir_expr *expr)
     unsigned int i;
 
     wine_dbg_printf("%s (", debug_expr_op(expr));
-    for (i = 0; i < 3 && expr->operands[i]; ++i)
+    for (i = 0; i < 3 && expr->operands[i].node; ++i)
     {
-        debug_dump_src(expr->operands[i]);
+        debug_dump_src(expr->operands[i].node);
         wine_dbg_printf(" ");
     }
     wine_dbg_printf(")");
@@ -2065,7 +2065,7 @@ static void debug_dump_ir_constructor(const struct hlsl_ir_constructor *construc
     wine_dbg_printf("%s (", debug_hlsl_type(constructor->node.data_type));
     for (i = 0; i < constructor->args_count; ++i)
     {
-        debug_dump_src(constructor->args[i]);
+        debug_dump_src(constructor->args[i].node);
         wine_dbg_printf(" ");
     }
     wine_dbg_printf(")");
@@ -2097,7 +2097,7 @@ static void debug_dump_ir_assignment(const struct hlsl_ir_assignment *assign)
     if (assign->writemask != BWRITERSP_WRITEMASK_ALL)
         wine_dbg_printf("%s", debug_writemask(assign->writemask));
     wine_dbg_printf(" ");
-    debug_dump_src(assign->rhs);
+    debug_dump_src(assign->rhs.node);
     wine_dbg_printf(")");
 }
 
@@ -2105,9 +2105,9 @@ static void debug_dump_ir_swizzle(const struct hlsl_ir_swizzle *swizzle)
 {
     unsigned int i;
 
-    debug_dump_src(swizzle->val);
+    debug_dump_src(swizzle->val.node);
     wine_dbg_printf(".");
-    if (swizzle->val->data_type->dimy > 1)
+    if (swizzle->val.node->data_type->dimy > 1)
     {
         for (i = 0; i < swizzle->node.data_type->dimx; ++i)
             wine_dbg_printf("_m%u%u", (swizzle->swizzle >> i * 8) & 0xf, (swizzle->swizzle >> (i * 8 + 4)) & 0xf);
@@ -2136,8 +2136,8 @@ static void debug_dump_ir_jump(const struct hlsl_ir_jump *jump)
             break;
         case HLSL_IR_JUMP_RETURN:
             wine_dbg_printf("return ");
-            if (jump->return_value)
-                debug_dump_src(jump->return_value);
+            if (jump->return_value.node)
+                debug_dump_src(jump->return_value.node);
             wine_dbg_printf(";");
             break;
     }
@@ -2146,7 +2146,7 @@ static void debug_dump_ir_jump(const struct hlsl_ir_jump *jump)
 static void debug_dump_ir_if(const struct hlsl_ir_if *if_node)
 {
     wine_dbg_printf("if (");
-    debug_dump_src(if_node->condition);
+    debug_dump_src(if_node->condition.node);
     wine_dbg_printf(")\n{\n");
     debug_dump_instr_list(if_node->then_instrs);
     wine_dbg_printf("}\n");
-- 
2.26.0




More information about the wine-devel mailing list