[PATCH v4 1/5] d3dcompiler: Return an instruction list instead of a single instruction from nodes representing expressions.

Zebediah Figura z.figura12 at gmail.com
Tue Feb 11 22:54:17 CST 2020


From: Zebediah Figura <zfigura at codeweavers.com>

Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
---
 dlls/d3dcompiler_43/d3dcompiler_private.h |   6 +
 dlls/d3dcompiler_43/hlsl.y                | 326 +++++++++++-----------
 dlls/d3dcompiler_43/utils.c               |  46 +--
 3 files changed, 183 insertions(+), 195 deletions(-)

diff --git a/dlls/d3dcompiler_43/d3dcompiler_private.h b/dlls/d3dcompiler_43/d3dcompiler_private.h
index 5fc3161f5f0..9c58830ffe2 100644
--- a/dlls/d3dcompiler_43/d3dcompiler_private.h
+++ b/dlls/d3dcompiler_43/d3dcompiler_private.h
@@ -984,6 +984,7 @@ struct parse_initializer
 {
     struct hlsl_ir_node **args;
     unsigned int args_count;
+    struct list *instrs;
 };
 
 struct parse_variable_def
@@ -1120,6 +1121,11 @@ static inline struct hlsl_ir_loop *loop_from_node(const struct hlsl_ir_node *nod
     return CONTAINING_RECORD(node, struct hlsl_ir_loop, node);
 }
 
+static inline struct hlsl_ir_node *node_from_list(struct list *list)
+{
+    return LIST_ENTRY(list_tail(list), struct hlsl_ir_node, entry);
+}
+
 BOOL add_declaration(struct hlsl_scope *scope, struct hlsl_ir_var *decl, BOOL local_var) DECLSPEC_HIDDEN;
 struct hlsl_ir_var *get_variable(struct hlsl_scope *scope, const char *name) DECLSPEC_HIDDEN;
 void free_declaration(struct hlsl_ir_var *decl) DECLSPEC_HIDDEN;
diff --git a/dlls/d3dcompiler_43/hlsl.y b/dlls/d3dcompiler_43/hlsl.y
index d81d6afa9cc..87a5273d2d8 100644
--- a/dlls/d3dcompiler_43/hlsl.y
+++ b/dlls/d3dcompiler_43/hlsl.y
@@ -255,56 +255,49 @@ static void declare_predefined_types(struct hlsl_scope *scope)
     add_type_to_scope(scope, type);
 }
 
-static struct hlsl_ir_if *loop_condition(struct list *cond_list)
+static BOOL append_conditional_break(struct list *cond_list)
 {
-    struct hlsl_ir_node *cond, *not_cond;
-    struct hlsl_ir_if *out_cond;
+    struct hlsl_ir_node *condition, *not;
     struct hlsl_ir_jump *jump;
-    unsigned int count = list_count(cond_list);
+    struct hlsl_ir_if *iff;
 
-    if (!count)
-        return NULL;
-    if (count != 1)
-        ERR("Got multiple expressions in a for condition.\n");
+    /* E.g. "for (i = 0; ; ++i)". */
+    if (!list_count(cond_list))
+        return TRUE;
 
-    cond = LIST_ENTRY(list_head(cond_list), struct hlsl_ir_node, entry);
-    out_cond = d3dcompiler_alloc(sizeof(*out_cond));
-    if (!out_cond)
+    condition = node_from_list(cond_list);
+    if (!(not = new_unary_expr(HLSL_IR_UNOP_LOGIC_NOT, condition, condition->loc)))
     {
         ERR("Out of memory.\n");
-        return NULL;
+        return FALSE;
     }
-    out_cond->node.type = HLSL_IR_IF;
-    if (!(not_cond = new_unary_expr(HLSL_IR_UNOP_LOGIC_NOT, cond, cond->loc)))
+    list_add_tail(cond_list, &not->entry);
+
+    if (!(iff = d3dcompiler_alloc(sizeof(*iff))))
     {
         ERR("Out of memory.\n");
-        d3dcompiler_free(out_cond);
-        return NULL;
+        return FALSE;
     }
-    out_cond->condition = not_cond;
-    jump = d3dcompiler_alloc(sizeof(*jump));
-    if (!jump)
+    iff->node.type = HLSL_IR_IF;
+    iff->condition = not;
+    list_add_tail(cond_list, &iff->node.entry);
+
+    if (!(iff->then_instrs = d3dcompiler_alloc(sizeof(*iff->then_instrs))))
     {
         ERR("Out of memory.\n");
-        d3dcompiler_free(out_cond);
-        d3dcompiler_free(not_cond);
-        return NULL;
+        return FALSE;
     }
-    jump->node.type = HLSL_IR_JUMP;
-    jump->type = HLSL_IR_JUMP_BREAK;
-    out_cond->then_instrs = d3dcompiler_alloc(sizeof(*out_cond->then_instrs));
-    if (!out_cond->then_instrs)
+    list_init(iff->then_instrs);
+
+    if (!(jump = d3dcompiler_alloc(sizeof(*jump))))
     {
         ERR("Out of memory.\n");
-        d3dcompiler_free(out_cond);
-        d3dcompiler_free(not_cond);
-        d3dcompiler_free(jump);
-        return NULL;
+        return FALSE;
     }
-    list_init(out_cond->then_instrs);
-    list_add_head(out_cond->then_instrs, &jump->node.entry);
-
-    return out_cond;
+    jump->node.type = HLSL_IR_JUMP;
+    jump->type = HLSL_IR_JUMP_BREAK;
+    list_add_head(iff->then_instrs, &jump->node.entry);
+    return TRUE;
 }
 
 enum loop_type
@@ -315,7 +308,7 @@ enum loop_type
 };
 
 static struct list *create_loop(enum loop_type type, struct list *init, struct list *cond,
-        struct hlsl_ir_node *iter, struct list *body, struct source_location *loc)
+        struct list *iter, struct list *body, struct source_location *loc)
 {
     struct list *list = NULL;
     struct hlsl_ir_loop *loop = NULL;
@@ -340,20 +333,19 @@ static struct list *create_loop(enum loop_type type, struct list *init, struct l
         goto oom;
     list_init(loop->body);
 
-    cond_jump = loop_condition(cond);
-    if (!cond_jump)
+    if (!append_conditional_break(cond))
         goto oom;
 
     if (type != LOOP_DO_WHILE)
-        list_add_tail(loop->body, &cond_jump->node.entry);
+        list_move_tail(loop->body, cond);
 
     list_move_tail(loop->body, body);
 
     if (iter)
-        list_add_tail(loop->body, &iter->entry);
+        list_move_tail(loop->body, iter);
 
     if (type == LOOP_DO_WHILE)
-        list_add_tail(loop->body, &cond_jump->node.entry);
+        list_move_tail(loop->body, cond);
 
     d3dcompiler_free(init);
     d3dcompiler_free(cond);
@@ -369,7 +361,7 @@ oom:
     d3dcompiler_free(list);
     free_instr_list(init);
     free_instr_list(cond);
-    free_instr(iter);
+    free_instr_list(iter);
     free_instr_list(body);
     return NULL;
 }
@@ -388,9 +380,7 @@ static unsigned int initializer_size(const struct parse_initializer *initializer
 
 static void free_parse_initializer(struct parse_initializer *initializer)
 {
-    unsigned int i;
-    for (i = 0; i < initializer->args_count; ++i)
-        free_instr(initializer->args[i]);
+    free_instr_list(initializer->instrs);
     d3dcompiler_free(initializer->args);
 }
 
@@ -508,6 +498,9 @@ static void struct_var_initializer(struct list *list, struct hlsl_ir_var *var,
         return;
     }
 
+    list_move_tail(list, initializer->instrs);
+    d3dcompiler_free(initializer->instrs);
+
     LIST_FOR_EACH_ENTRY(field, type->e.elements, struct hlsl_struct_field, entry)
     {
         struct hlsl_ir_node *node = initializer->args[i];
@@ -526,6 +519,7 @@ static void struct_var_initializer(struct list *list, struct hlsl_ir_var *var,
                 break;
             }
             deref->node.loc = node->loc;
+            list_add_tail(list, &deref->node.entry);
             assignment = make_assignment(&deref->node, ASSIGN_OP_ASSIGN, BWRITERSP_WRITEMASK_ALL, node);
             list_add_tail(list, &assignment->entry);
         }
@@ -533,9 +527,6 @@ static void struct_var_initializer(struct list *list, struct hlsl_ir_var *var,
             FIXME("Initializing with \"mismatched\" fields is not supported yet.\n");
     }
 
-    /* Free initializer elements in excess. */
-    for (; i < initializer->args_count; ++i)
-        free_instr(initializer->args[i]);
     d3dcompiler_free(initializer->args);
 }
 
@@ -609,6 +600,7 @@ static struct list *declare_vars(struct hlsl_type *basic_type, DWORD modifiers,
         if (v->initializer.args_count)
         {
             unsigned int size = initializer_size(&v->initializer);
+            struct hlsl_ir_deref *deref;
 
             TRACE("Variable with initializer.\n");
             if (type->type <= HLSL_CLASS_LAST_NUMERIC
@@ -661,7 +653,10 @@ static struct list *declare_vars(struct hlsl_type *basic_type, DWORD modifiers,
                 continue;
             }
 
-            assignment = make_assignment(&new_var_deref(var)->node, ASSIGN_OP_ASSIGN,
+            deref = new_var_deref(var);
+            list_add_tail(statements_list, &deref->node.entry);
+            list_add_tail(statements_list, &v->initializer.args[0]->entry);
+            assignment = make_assignment(&deref->node, ASSIGN_OP_ASSIGN,
                     BWRITERSP_WRITEMASK_ALL, v->initializer.args[0]);
             d3dcompiler_free(v->initializer.args);
             list_add_tail(statements_list, &assignment->entry);
@@ -880,6 +875,35 @@ static const struct hlsl_ir_function_decl *get_overloaded_func(struct wine_rb_tr
     return NULL;
 }
 
+static struct list *append_unop(struct list *list, struct hlsl_ir_node *node)
+{
+    list_add_tail(list, &node->entry);
+    return list;
+}
+
+static struct list *append_binop(struct list *first, struct list *second, struct hlsl_ir_node *node)
+{
+    list_move_tail(first, second);
+    d3dcompiler_free(second);
+    list_add_tail(first, &node->entry);
+    return first;
+}
+
+static struct list *make_list(struct hlsl_ir_node *node)
+{
+    struct list *list;
+
+    if (!(list = d3dcompiler_alloc(sizeof(*list))))
+    {
+        ERR("Out of memory.\n");
+        free_instr(node);
+        return NULL;
+    }
+    list_init(list);
+    list_add_tail(list, &node->entry);
+    return list;
+}
+
 %}
 
 %locations
@@ -1024,12 +1048,12 @@ static const struct hlsl_ir_function_decl *get_overloaded_func(struct wine_rb_tr
 %type <variable_def> type_spec
 %type <initializer> complex_initializer
 %type <initializer> initializer_expr_list
-%type <instr> initializer_expr
+%type <list> initializer_expr
 %type <modifiers> var_modifiers
 %type <list> field
 %type <list> parameters
 %type <list> param_list
-%type <instr> expr
+%type <list> expr
 %type <intval> array
 %type <list> statement
 %type <list> statement_list
@@ -1048,21 +1072,21 @@ static const struct hlsl_ir_function_decl *get_overloaded_func(struct wine_rb_tr
 %type <list> variables_def
 %type <list> variables_def_optional
 %type <if_body> if_body
-%type <instr> primary_expr
-%type <instr> postfix_expr
-%type <instr> unary_expr
-%type <instr> mul_expr
-%type <instr> add_expr
-%type <instr> shift_expr
-%type <instr> relational_expr
-%type <instr> equality_expr
-%type <instr> bitand_expr
-%type <instr> bitxor_expr
-%type <instr> bitor_expr
-%type <instr> logicand_expr
-%type <instr> logicor_expr
-%type <instr> conditional_expr
-%type <instr> assignment_expr
+%type <list> primary_expr
+%type <list> postfix_expr
+%type <list> unary_expr
+%type <list> mul_expr
+%type <list> add_expr
+%type <list> shift_expr
+%type <list> relational_expr
+%type <list> equality_expr
+%type <list> bitand_expr
+%type <list> bitxor_expr
+%type <list> bitor_expr
+%type <list> logicand_expr
+%type <list> logicor_expr
+%type <list> conditional_expr
+%type <list> assignment_expr
 %type <list> expr_statement
 %type <unary_op> unary_op
 %type <assign_op> assign_op
@@ -1615,7 +1639,7 @@ array:                    /* Empty */
                             {
                                 FIXME("Array.\n");
                                 $$ = 0;
-                                free_instr($2);
+                                free_instr_list($2);
                             }
 
 var_modifiers:            /* Empty */
@@ -1672,7 +1696,8 @@ complex_initializer:      initializer_expr
                                 $$.args_count = 1;
                                 if (!($$.args = d3dcompiler_alloc(sizeof(*$$.args))))
                                     YYABORT;
-                                $$.args[0] = $1;
+                                $$.args[0] = node_from_list($1);
+                                $$.instrs = $1;
                             }
                         | '{' initializer_expr_list '}'
                             {
@@ -1693,14 +1718,17 @@ initializer_expr_list:    initializer_expr
                                 $$.args_count = 1;
                                 if (!($$.args = d3dcompiler_alloc(sizeof(*$$.args))))
                                     YYABORT;
-                                $$.args[0] = $1;
+                                $$.args[0] = node_from_list($1);
+                                $$.instrs = $1;
                             }
                         | initializer_expr_list ',' initializer_expr
                             {
                                 $$ = $1;
                                 if (!($$.args = d3dcompiler_realloc($$.args, ($$.args_count + 1) * sizeof(*$$.args))))
                                     YYABORT;
-                                $$.args[$$.args_count++] = $3;
+                                $$.args[$$.args_count++] = node_from_list($3);
+                                list_move_tail($$.instrs, $3);
+                                d3dcompiler_free($3);
                             }
 
 boolean:                  KW_TRUE
@@ -1742,15 +1770,14 @@ jump_statement:           KW_RETURN expr ';'
                                 jump->node.type = HLSL_IR_JUMP;
                                 set_location(&jump->node.loc, &@1);
                                 jump->type = HLSL_IR_JUMP_RETURN;
-                                jump->node.data_type = $2->data_type;
-                                jump->return_value = $2;
+                                jump->node.data_type = node_from_list($2)->data_type;
+                                jump->return_value = node_from_list($2);
 
                                 FIXME("Check for valued return on void function.\n");
                                 FIXME("Implicit conversion to the return type if needed, "
 				        "error out if conversion not possible.\n");
 
-                                $$ = d3dcompiler_alloc(sizeof(*$$));
-                                list_init($$);
+                                $$ = $2;
                                 list_add_tail($$, &jump->node.entry);
                             }
 
@@ -1764,18 +1791,17 @@ selection_statement:      KW_IF '(' expr ')' if_body
                                 }
                                 instr->node.type = HLSL_IR_IF;
                                 set_location(&instr->node.loc, &@1);
-                                instr->condition = $3;
+                                instr->condition = node_from_list($3);
                                 instr->then_instrs = $5.then_instrs;
                                 instr->else_instrs = $5.else_instrs;
-                                if ($3->data_type->dimx > 1 || $3->data_type->dimy > 1)
+                                if (instr->condition->data_type->dimx > 1 || instr->condition->data_type->dimy > 1)
                                 {
                                     hlsl_report_message(instr->node.loc.file, instr->node.loc.line,
                                             instr->node.loc.col, HLSL_LEVEL_ERROR,
                                             "if condition requires a scalar");
                                 }
-                                $$ = d3dcompiler_alloc(sizeof(*$$));
-                                list_init($$);
-                                list_add_head($$, &instr->node.entry);
+                                $$ = $3;
+                                list_add_tail($$, &instr->node.entry);
                             }
 
 if_body:                  statement
@@ -1792,32 +1818,14 @@ if_body:                  statement
 loop_statement:           KW_WHILE '(' expr ')' statement
                             {
                                 struct source_location loc;
-                                struct list *cond = d3dcompiler_alloc(sizeof(*cond));
-
-                                if (!cond)
-                                {
-                                    ERR("Out of memory.\n");
-                                    YYABORT;
-                                }
-                                list_init(cond);
-                                list_add_head(cond, &$3->entry);
                                 set_location(&loc, &@1);
-                                $$ = create_loop(LOOP_WHILE, NULL, cond, NULL, $5, &loc);
+                                $$ = create_loop(LOOP_WHILE, NULL, $3, NULL, $5, &loc);
                             }
                         | KW_DO statement KW_WHILE '(' expr ')' ';'
                             {
                                 struct source_location loc;
-                                struct list *cond = d3dcompiler_alloc(sizeof(*cond));
-
-                                if (!cond)
-                                {
-                                    ERR("Out of memory.\n");
-                                    YYABORT;
-                                }
-                                list_init(cond);
-                                list_add_head(cond, &$5->entry);
                                 set_location(&loc, &@1);
-                                $$ = create_loop(LOOP_DO_WHILE, NULL, cond, NULL, $2, &loc);
+                                $$ = create_loop(LOOP_DO_WHILE, NULL, $5, NULL, $2, &loc);
                             }
                         | KW_FOR '(' scope_start expr_statement expr_statement expr ')' statement
                             {
@@ -1846,10 +1854,7 @@ expr_statement:           ';'
                             }
                         | expr ';'
                             {
-                                $$ = d3dcompiler_alloc(sizeof(*$$));
-                                list_init($$);
-                                if ($1)
-                                    list_add_head($$, &$1->entry);
+                                $$ = $1;
                             }
 
 primary_expr:             C_FLOAT
@@ -1864,7 +1869,8 @@ primary_expr:             C_FLOAT
                                 set_location(&c->node.loc, &yylloc);
                                 c->node.data_type = new_hlsl_type(d3dcompiler_strdup("float"), HLSL_CLASS_SCALAR, HLSL_TYPE_FLOAT, 1, 1);
                                 c->v.value.f[0] = $1;
-                                $$ = &c->node;
+                                if (!($$ = make_list(&c->node)))
+                                    YYABORT;
                             }
                         | C_INTEGER
                             {
@@ -1878,7 +1884,8 @@ primary_expr:             C_FLOAT
                                 set_location(&c->node.loc, &yylloc);
                                 c->node.data_type = new_hlsl_type(d3dcompiler_strdup("int"), HLSL_CLASS_SCALAR, HLSL_TYPE_INT, 1, 1);
                                 c->v.value.i[0] = $1;
-                                $$ = &c->node;
+                                if (!($$ = make_list(&c->node)))
+                                    YYABORT;
                             }
                         | boolean
                             {
@@ -1892,7 +1899,8 @@ primary_expr:             C_FLOAT
                                 set_location(&c->node.loc, &yylloc);
                                 c->node.data_type = new_hlsl_type(d3dcompiler_strdup("bool"), HLSL_CLASS_SCALAR, HLSL_TYPE_BOOL, 1, 1);
                                 c->v.value.b[0] = $1;
-                                $$ = &c->node;
+                                if (!($$ = make_list(&c->node)))
+                                    YYABORT;
                             }
                         | VAR_IDENTIFIER
                             {
@@ -1908,8 +1916,9 @@ primary_expr:             C_FLOAT
                                 }
                                 if ((deref = new_var_deref(var)))
                                 {
-                                    $$ = &deref->node;
-                                    set_location(&$$->loc, &@1);
+                                    set_location(&deref->node.loc, &@1);
+                                    if (!($$ = make_list(&deref->node)))
+                                        YYABORT;
                                 }
                                 else
                                     $$ = NULL;
@@ -1926,43 +1935,48 @@ postfix_expr:             primary_expr
                         | postfix_expr OP_INC
                             {
                                 struct source_location loc;
+                                struct hlsl_ir_node *inc;
 
                                 set_location(&loc, &@2);
-                                if ($1->data_type->modifiers & HLSL_MODIFIER_CONST)
+                                if (node_from_list($1)->data_type->modifiers & HLSL_MODIFIER_CONST)
                                 {
                                     hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
                                             "modifying a const expression");
                                     YYABORT;
                                 }
-                                $$ = new_unary_expr(HLSL_IR_UNOP_POSTINC, $1, loc);
+                                inc = new_unary_expr(HLSL_IR_UNOP_POSTINC, node_from_list($1), loc);
                                 /* Post increment/decrement expressions are considered const */
-                                $$->data_type = clone_hlsl_type($$->data_type);
-                                $$->data_type->modifiers |= HLSL_MODIFIER_CONST;
+                                inc->data_type = clone_hlsl_type(inc->data_type);
+                                inc->data_type->modifiers |= HLSL_MODIFIER_CONST;
+                                $$ = append_unop($1, inc);
                             }
                         | postfix_expr OP_DEC
                             {
                                 struct source_location loc;
+                                struct hlsl_ir_node *inc;
 
                                 set_location(&loc, &@2);
-                                if ($1->data_type->modifiers & HLSL_MODIFIER_CONST)
+                                if (node_from_list($1)->data_type->modifiers & HLSL_MODIFIER_CONST)
                                 {
                                     hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
                                             "modifying a const expression");
                                     YYABORT;
                                 }
-                                $$ = new_unary_expr(HLSL_IR_UNOP_POSTDEC, $1, loc);
+                                inc = new_unary_expr(HLSL_IR_UNOP_POSTDEC, node_from_list($1), loc);
                                 /* Post increment/decrement expressions are considered const */
-                                $$->data_type = clone_hlsl_type($$->data_type);
-                                $$->data_type->modifiers |= HLSL_MODIFIER_CONST;
+                                inc->data_type = clone_hlsl_type(inc->data_type);
+                                inc->data_type->modifiers |= HLSL_MODIFIER_CONST;
+                                $$ = append_unop($1, inc);
                             }
                         | postfix_expr '.' any_identifier
                             {
+                                struct hlsl_ir_node *node = node_from_list($1);
                                 struct source_location loc;
 
                                 set_location(&loc, &@2);
-                                if ($1->data_type->type == HLSL_CLASS_STRUCT)
+                                if (node->data_type->type == HLSL_CLASS_STRUCT)
                                 {
-                                    struct hlsl_type *type = $1->data_type;
+                                    struct hlsl_type *type = node->data_type;
                                     struct hlsl_struct_field *field;
 
                                     $$ = NULL;
@@ -1970,7 +1984,7 @@ postfix_expr:             primary_expr
                                     {
                                         if (!strcmp($3, field->name))
                                         {
-                                            struct hlsl_ir_deref *deref = new_record_deref($1, field);
+                                            struct hlsl_ir_deref *deref = new_record_deref(node, field);
 
                                             if (!deref)
                                             {
@@ -1978,7 +1992,7 @@ postfix_expr:             primary_expr
                                                 YYABORT;
                                             }
                                             deref->node.loc = loc;
-                                            $$ = &deref->node;
+                                            $$ = append_unop($1, &deref->node);
                                             break;
                                         }
                                     }
@@ -1989,18 +2003,18 @@ postfix_expr:             primary_expr
                                         YYABORT;
                                     }
                                 }
-                                else if ($1->data_type->type <= HLSL_CLASS_LAST_NUMERIC)
+                                else if (node->data_type->type <= HLSL_CLASS_LAST_NUMERIC)
                                 {
                                     struct hlsl_ir_swizzle *swizzle;
 
-                                    swizzle = get_swizzle($1, $3, &loc);
+                                    swizzle = get_swizzle(node, $3, &loc);
                                     if (!swizzle)
                                     {
                                         hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
                                                 "invalid swizzle %s", debugstr_a($3));
                                         YYABORT;
                                     }
-                                    $$ = &swizzle->node;
+                                    $$ = append_unop($1, &swizzle->node);
                                 }
                                 else
                                 {
@@ -2015,7 +2029,7 @@ postfix_expr:             primary_expr
                                  * subcomponent access.
                                  * We store it as an array dereference in any case. */
                                 struct hlsl_ir_deref *deref = d3dcompiler_alloc(sizeof(*deref));
-                                struct hlsl_type *expr_type = $1->data_type;
+                                struct hlsl_type *expr_type = node_from_list($1)->data_type;
                                 struct source_location loc;
 
                                 TRACE("Array dereference from type %s\n", debug_hlsl_type(expr_type));
@@ -2048,24 +2062,24 @@ postfix_expr:             primary_expr
                                         hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
                                                 "expression is not array-indexable");
                                     d3dcompiler_free(deref);
-                                    free_instr($1);
-                                    free_instr($3);
+                                    free_instr_list($1);
+                                    free_instr_list($3);
                                     YYABORT;
                                 }
-                                if ($3->data_type->type != HLSL_CLASS_SCALAR)
+                                if (node_from_list($3)->data_type->type != HLSL_CLASS_SCALAR)
                                 {
                                     hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
                                             "array index is not scalar");
                                     d3dcompiler_free(deref);
-                                    free_instr($1);
-                                    free_instr($3);
+                                    free_instr_list($1);
+                                    free_instr_list($3);
                                     YYABORT;
                                 }
                                 deref->type = HLSL_IR_DEREF_ARRAY;
-                                deref->v.array.array = $1;
-                                deref->v.array.index = $3;
+                                deref->v.array.array = node_from_list($1);
+                                deref->v.array.index = node_from_list($3);
 
-                                $$ = &deref->node;
+                                $$ = append_binop($1, $3, &deref->node);
                             }
                           /* "var_modifiers" doesn't make sense in this case, but it's needed
                              in the grammar to avoid shift/reduce conflicts. */
@@ -2104,7 +2118,7 @@ postfix_expr:             primary_expr
                                 constructor->args_count = $4.args_count;
                                 memcpy(constructor->args, $4.args, $4.args_count * sizeof(*$4.args));
                                 d3dcompiler_free($4.args);
-                                $$ = &constructor->node;
+                                $$ = append_unop($4.instrs, &constructor->node);
                             }
 
 unary_expr:               postfix_expr
@@ -2116,26 +2130,26 @@ unary_expr:               postfix_expr
                                 struct source_location loc;
 
                                 set_location(&loc, &@1);
-                                if ($2->data_type->modifiers & HLSL_MODIFIER_CONST)
+                                if (node_from_list($2)->data_type->modifiers & HLSL_MODIFIER_CONST)
                                 {
                                     hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
                                             "modifying a const expression");
                                     YYABORT;
                                 }
-                                $$ = new_unary_expr(HLSL_IR_UNOP_PREINC, $2, loc);
+                                $$ = append_unop($2, new_unary_expr(HLSL_IR_UNOP_PREINC, node_from_list($2), loc));
                             }
                         | OP_DEC unary_expr
                             {
                                 struct source_location loc;
 
                                 set_location(&loc, &@1);
-                                if ($2->data_type->modifiers & HLSL_MODIFIER_CONST)
+                                if (node_from_list($2)->data_type->modifiers & HLSL_MODIFIER_CONST)
                                 {
                                     hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
                                             "modifying a const expression");
                                     YYABORT;
                                 }
-                                $$ = new_unary_expr(HLSL_IR_UNOP_PREDEC, $2, loc);
+                                $$ = append_unop($2, new_unary_expr(HLSL_IR_UNOP_PREDEC, node_from_list($2), loc));
                             }
                         | unary_op unary_expr
                             {
@@ -2150,14 +2164,13 @@ unary_expr:               postfix_expr
                                 else
                                 {
                                     set_location(&loc, &@1);
-                                    $$ = new_unary_expr(ops[$1], $2, loc);
+                                    $$ = append_unop($2, new_unary_expr(ops[$1], node_from_list($2), loc));
                                 }
                             }
                           /* var_modifiers just to avoid shift/reduce conflicts */
                         | '(' var_modifiers type array ')' unary_expr
                             {
-                                struct hlsl_ir_expr *expr;
-                                struct hlsl_type *src_type = $6->data_type;
+                                struct hlsl_type *src_type = node_from_list($6)->data_type;
                                 struct hlsl_type *dst_type;
                                 struct source_location loc;
 
@@ -2182,8 +2195,7 @@ unary_expr:               postfix_expr
                                     YYABORT;
                                 }
 
-                                expr = new_cast($6, dst_type, &loc);
-                                $$ = expr ? &expr->node : NULL;
+                                $$ = append_unop($6, &new_cast(node_from_list($6), dst_type, &loc)->node);
                             }
 
 unary_op:                 '+'
@@ -2212,21 +2224,21 @@ mul_expr:                 unary_expr
                                 struct source_location loc;
 
                                 set_location(&loc, &@2);
-                                $$ = new_binary_expr(HLSL_IR_BINOP_MUL, $1, $3, loc);
+                                $$ = append_binop($1, $3, new_binary_expr(HLSL_IR_BINOP_MUL, node_from_list($1), node_from_list($3), loc));
                             }
                         | mul_expr '/' unary_expr
                             {
                                 struct source_location loc;
 
                                 set_location(&loc, &@2);
-                                $$ = new_binary_expr(HLSL_IR_BINOP_DIV, $1, $3, loc);
+                                $$ = append_binop($1, $3, new_binary_expr(HLSL_IR_BINOP_DIV, node_from_list($1), node_from_list($3), loc));
                             }
                         | mul_expr '%' unary_expr
                             {
                                 struct source_location loc;
 
                                 set_location(&loc, &@2);
-                                $$ = new_binary_expr(HLSL_IR_BINOP_MOD, $1, $3, loc);
+                                $$ = append_binop($1, $3, new_binary_expr(HLSL_IR_BINOP_MOD, node_from_list($1), node_from_list($3), loc));
                             }
 
 add_expr:                 mul_expr
@@ -2238,14 +2250,14 @@ add_expr:                 mul_expr
                                 struct source_location loc;
 
                                 set_location(&loc, &@2);
-                                $$ = new_binary_expr(HLSL_IR_BINOP_ADD, $1, $3, loc);
+                                $$ = append_binop($1, $3, new_binary_expr(HLSL_IR_BINOP_ADD, node_from_list($1), node_from_list($3), loc));
                             }
                         | add_expr '-' mul_expr
                             {
                                 struct source_location loc;
 
                                 set_location(&loc, &@2);
-                                $$ = new_binary_expr(HLSL_IR_BINOP_SUB, $1, $3, loc);
+                                $$ = append_binop($1, $3, new_binary_expr(HLSL_IR_BINOP_SUB, node_from_list($1), node_from_list($3), loc));
                             }
 
 shift_expr:               add_expr
@@ -2270,28 +2282,28 @@ relational_expr:          shift_expr
                                 struct source_location loc;
 
                                 set_location(&loc, &@2);
-                                $$ = new_binary_expr(HLSL_IR_BINOP_LESS, $1, $3, loc);
+                                $$ = append_binop($1, $3, new_binary_expr(HLSL_IR_BINOP_LESS, node_from_list($1), node_from_list($3), loc));
                             }
                         | relational_expr '>' shift_expr
                             {
                                 struct source_location loc;
 
                                 set_location(&loc, &@2);
-                                $$ = new_binary_expr(HLSL_IR_BINOP_GREATER, $1, $3, loc);
+                                $$ = append_binop($1, $3, new_binary_expr(HLSL_IR_BINOP_GREATER, node_from_list($1), node_from_list($3), loc));
                             }
                         | relational_expr OP_LE shift_expr
                             {
                                 struct source_location loc;
 
                                 set_location(&loc, &@2);
-                                $$ = new_binary_expr(HLSL_IR_BINOP_LEQUAL, $1, $3, loc);
+                                $$ = append_binop($1, $3, new_binary_expr(HLSL_IR_BINOP_LEQUAL, node_from_list($1), node_from_list($3), loc));
                             }
                         | relational_expr OP_GE shift_expr
                             {
                                 struct source_location loc;
 
                                 set_location(&loc, &@2);
-                                $$ = new_binary_expr(HLSL_IR_BINOP_GEQUAL, $1, $3, loc);
+                                $$ = append_binop($1, $3, new_binary_expr(HLSL_IR_BINOP_GEQUAL, node_from_list($1), node_from_list($3), loc));
                             }
 
 equality_expr:            relational_expr
@@ -2303,14 +2315,14 @@ equality_expr:            relational_expr
                                 struct source_location loc;
 
                                 set_location(&loc, &@2);
-                                $$ = new_binary_expr(HLSL_IR_BINOP_EQUAL, $1, $3, loc);
+                                $$ = append_binop($1, $3, new_binary_expr(HLSL_IR_BINOP_EQUAL, node_from_list($1), node_from_list($3), loc));
                             }
                         | equality_expr OP_NE relational_expr
                             {
                                 struct source_location loc;
 
                                 set_location(&loc, &@2);
-                                $$ = new_binary_expr(HLSL_IR_BINOP_NEQUAL, $1, $3, loc);
+                                $$ = append_binop($1, $3, new_binary_expr(HLSL_IR_BINOP_NEQUAL, node_from_list($1), node_from_list($3), loc));
                             }
 
 bitand_expr:              equality_expr
@@ -2374,18 +2386,20 @@ assignment_expr:          conditional_expr
                         | unary_expr assign_op assignment_expr
                             {
                                 struct source_location loc;
+                                struct hlsl_ir_node *instr;
 
                                 set_location(&loc, &@2);
-                                if ($1->data_type->modifiers & HLSL_MODIFIER_CONST)
+                                if (node_from_list($1)->data_type->modifiers & HLSL_MODIFIER_CONST)
                                 {
                                     hlsl_report_message(loc.file, loc.line, loc.col, HLSL_LEVEL_ERROR,
                                             "l-value is const");
                                     YYABORT;
                                 }
-                                $$ = make_assignment($1, $2, BWRITERSP_WRITEMASK_ALL, $3);
-                                if (!$$)
+                                if (!(instr = make_assignment(node_from_list($1), $2,
+                                        BWRITERSP_WRITEMASK_ALL, node_from_list($3))))
                                     YYABORT;
-                                $$->loc = loc;
+                                instr->loc = loc;
+                                $$ = append_binop($3, $1, instr);
                             }
 
 assign_op:                '='
diff --git a/dlls/d3dcompiler_43/utils.c b/dlls/d3dcompiler_43/utils.c
index 0cae62b60fc..3f5a57ffa40 100644
--- a/dlls/d3dcompiler_43/utils.c
+++ b/dlls/d3dcompiler_43/utils.c
@@ -1278,10 +1278,14 @@ static struct hlsl_type *expr_common_type(struct hlsl_type *t1, struct hlsl_type
 static struct hlsl_ir_node *implicit_conversion(struct hlsl_ir_node *node, struct hlsl_type *type,
         struct source_location *loc)
 {
+    struct hlsl_ir_expr *cast;
+
     if (compare_hlsl_types(node->data_type, type))
         return node;
     TRACE("Implicit conversion of expression to %s\n", debug_hlsl_type(type));
-    return &new_cast(node, type, loc)->node;
+    if ((cast = new_cast(node, type, loc)))
+        list_add_after(&node->entry, &cast->node.entry);
+    return &cast->node;
 }
 
 struct hlsl_ir_expr *new_expr(enum hlsl_ir_expr_op op, struct hlsl_ir_node **operands,
@@ -1468,8 +1472,6 @@ struct hlsl_ir_node *make_assignment(struct hlsl_ir_node *left, enum parse_assig
             hlsl_report_message(rhs->loc.file, rhs->loc.line, rhs->loc.col, HLSL_LEVEL_ERROR,
                     "can't implicitly convert %s to %s",
                     debug_hlsl_type(rhs->data_type), debug_hlsl_type(type));
-            free_instr(lhs);
-            free_instr(rhs);
             d3dcompiler_free(assign);
             return NULL;
         }
@@ -1481,8 +1483,6 @@ struct hlsl_ir_node *make_assignment(struct hlsl_ir_node *left, enum parse_assig
         if (!converted_rhs)
         {
             ERR("Couldn't implicitly convert expression to %s.\n", debug_hlsl_type(type));
-            free_instr(lhs);
-            free_instr(rhs);
             d3dcompiler_free(assign);
             return NULL;
         }
@@ -1502,11 +1502,9 @@ struct hlsl_ir_node *make_assignment(struct hlsl_ir_node *left, enum parse_assig
         }
         else
         {
-            struct hlsl_ir_deref *lhs_deref = deref_from_node(lhs), *new_deref;
-
             TRACE("Adding an expression for the compound assignment.\n");
-            new_deref = new_var_deref(lhs_deref->v.var);
-            expr = new_binary_expr(op, &new_deref->node, rhs, left->loc);
+            expr = new_binary_expr(op, lhs, rhs, lhs->loc);
+            list_add_after(&rhs->entry, &expr->entry);
             assign->rhs = expr;
         }
     }
@@ -2173,60 +2171,32 @@ static void free_ir_constant(struct hlsl_ir_constant *constant)
 
 static void free_ir_deref(struct hlsl_ir_deref *deref)
 {
-    switch (deref->type)
-    {
-        case HLSL_IR_DEREF_VAR:
-            /* Variables are shared among nodes in the tree. */
-            break;
-        case HLSL_IR_DEREF_ARRAY:
-            free_instr(deref->v.array.array);
-            free_instr(deref->v.array.index);
-            break;
-        case HLSL_IR_DEREF_RECORD:
-            free_instr(deref->v.record.record);
-            break;
-    }
     d3dcompiler_free(deref);
 }
 
 static void free_ir_swizzle(struct hlsl_ir_swizzle *swizzle)
 {
-    free_instr(swizzle->val);
     d3dcompiler_free(swizzle);
 }
 
 static void free_ir_constructor(struct hlsl_ir_constructor *constructor)
 {
-    unsigned int i;
-    for (i = 0; i < constructor->args_count; ++i)
-        free_instr(constructor->args[i]);
     d3dcompiler_free(constructor);
 }
 
 static void free_ir_expr(struct hlsl_ir_expr *expr)
 {
-    unsigned int i;
-
-    for (i = 0; i < 3; ++i)
-    {
-        if (!expr->operands[i])
-            break;
-        free_instr(expr->operands[i]);
-    }
     free_instr_list(expr->subexpressions);
     d3dcompiler_free(expr);
 }
 
 static void free_ir_assignment(struct hlsl_ir_assignment *assignment)
 {
-    free_instr(assignment->lhs);
-    free_instr(assignment->rhs);
     d3dcompiler_free(assignment);
 }
 
 static void free_ir_if(struct hlsl_ir_if *if_node)
 {
-    free_instr(if_node->condition);
     free_instr_list(if_node->then_instrs);
     free_instr_list(if_node->else_instrs);
     d3dcompiler_free(if_node);
@@ -2234,8 +2204,6 @@ static void free_ir_if(struct hlsl_ir_if *if_node)
 
 static void free_ir_jump(struct hlsl_ir_jump *jump)
 {
-    if (jump->type == HLSL_IR_JUMP_RETURN)
-        free_instr(jump->return_value);
     d3dcompiler_free(jump);
 }
 
-- 
2.25.0




More information about the wine-devel mailing list