Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- v4: don't add void to the scope
dlls/d3dcompiler_43/d3dcompiler_private.h | 8 ++ dlls/d3dcompiler_43/hlsl.y | 131 +++++++++++----------- 2 files changed, 75 insertions(+), 64 deletions(-)
diff --git a/dlls/d3dcompiler_43/d3dcompiler_private.h b/dlls/d3dcompiler_43/d3dcompiler_private.h index 6c2f234c4dd..8e96a4fbcac 100644 --- a/dlls/d3dcompiler_43/d3dcompiler_private.h +++ b/dlls/d3dcompiler_43/d3dcompiler_private.h @@ -595,6 +595,7 @@ enum hlsl_sampler_dim HLSL_SAMPLER_DIM_2D, HLSL_SAMPLER_DIM_3D, HLSL_SAMPLER_DIM_CUBE, + HLSL_SAMPLER_DIM_MAX = HLSL_SAMPLER_DIM_CUBE };
enum hlsl_matrix_majority @@ -983,6 +984,13 @@ struct hlsl_parse_ctx const struct hlsl_ir_function_decl *cur_function;
enum hlsl_matrix_majority matrix_majority; + + struct + { + struct hlsl_type *scalar[HLSL_TYPE_LAST_SCALAR + 1]; + struct hlsl_type *sampler[HLSL_SAMPLER_DIM_MAX + 1]; + struct hlsl_type *Void; + } builtin_types; };
extern struct hlsl_parse_ctx hlsl_ctx DECLSPEC_HIDDEN; diff --git a/dlls/d3dcompiler_43/hlsl.y b/dlls/d3dcompiler_43/hlsl.y index 058a627dc27..236fc8c1865 100644 --- a/dlls/d3dcompiler_43/hlsl.y +++ b/dlls/d3dcompiler_43/hlsl.y @@ -213,6 +213,15 @@ static void declare_predefined_types(struct hlsl_scope *scope) }; char name[10];
+ static const char *const sampler_names[] = + { + "sampler", + "sampler1D", + "sampler2D", + "sampler3D", + "samplerCUBE" + }; + for (bt = 0; bt <= HLSL_TYPE_LAST_SCALAR; ++bt) { for (y = 1; y <= 4; ++y) @@ -234,12 +243,22 @@ static void declare_predefined_types(struct hlsl_scope *scope) sprintf(name, "%s", names[bt]); type = new_hlsl_type(d3dcompiler_strdup(name), HLSL_CLASS_SCALAR, bt, x, y); add_type_to_scope(scope, type); + hlsl_ctx.builtin_types.scalar[bt] = type; } } } } }
+ for (bt = 0; bt <= HLSL_SAMPLER_DIM_MAX; ++bt) + { + type = new_hlsl_type(d3dcompiler_strdup(sampler_names[bt]), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1); + type->sampler_dim = bt; + hlsl_ctx.builtin_types.sampler[bt] = type; + } + + hlsl_ctx.builtin_types.Void = new_hlsl_type(d3dcompiler_strdup("void"), HLSL_CLASS_OBJECT, HLSL_TYPE_VOID, 1, 1); + /* DX8 effects predefined types */ type = new_hlsl_type(d3dcompiler_strdup("DWORD"), HLSL_CLASS_SCALAR, HLSL_TYPE_INT, 1, 1); add_type_to_scope(scope, type); @@ -548,15 +567,11 @@ static struct hlsl_ir_assignment *make_simple_assignment(struct hlsl_ir_var *lhs
static struct hlsl_ir_constant *new_uint_constant(unsigned int n, const struct source_location loc) { - struct hlsl_type *type; struct hlsl_ir_constant *c;
- if (!(type = new_hlsl_type(d3dcompiler_strdup("uint"), HLSL_CLASS_SCALAR, HLSL_TYPE_UINT, 1, 1))) - return NULL; - if (!(c = d3dcompiler_alloc(sizeof(*c)))) return NULL; - init_node(&c->node, HLSL_IR_CONSTANT, type, loc); + init_node(&c->node, HLSL_IR_CONSTANT, hlsl_ctx.builtin_types.scalar[HLSL_TYPE_UINT], loc); c->v.value.u[0] = n; return c; } @@ -1814,60 +1829,48 @@ type: base_type $$ = new_hlsl_type(NULL, HLSL_CLASS_MATRIX, $3->base_type, $5, $7); }
-base_type: KW_VOID - { - $$ = new_hlsl_type(d3dcompiler_strdup("void"), HLSL_CLASS_OBJECT, HLSL_TYPE_VOID, 1, 1); - } - | KW_SAMPLER - { - $$ = new_hlsl_type(d3dcompiler_strdup("sampler"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1); - $$->sampler_dim = HLSL_SAMPLER_DIM_GENERIC; - } - | KW_SAMPLER1D - { - $$ = new_hlsl_type(d3dcompiler_strdup("sampler1D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1); - $$->sampler_dim = HLSL_SAMPLER_DIM_1D; - } - | KW_SAMPLER2D - { - $$ = new_hlsl_type(d3dcompiler_strdup("sampler2D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1); - $$->sampler_dim = HLSL_SAMPLER_DIM_2D; - } - | KW_SAMPLER3D - { - $$ = new_hlsl_type(d3dcompiler_strdup("sampler3D"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1); - $$->sampler_dim = HLSL_SAMPLER_DIM_3D; - } - | KW_SAMPLERCUBE - { - $$ = new_hlsl_type(d3dcompiler_strdup("samplerCUBE"), HLSL_CLASS_OBJECT, HLSL_TYPE_SAMPLER, 1, 1); - $$->sampler_dim = HLSL_SAMPLER_DIM_CUBE; - } - | TYPE_IDENTIFIER - { - struct hlsl_type *type; +base_type:
- type = get_type(hlsl_ctx.cur_scope, $1, TRUE); - $$ = type; - d3dcompiler_free($1); - } - | KW_STRUCT TYPE_IDENTIFIER - { - struct hlsl_type *type; - - type = get_type(hlsl_ctx.cur_scope, $2, TRUE); - if (type->type != HLSL_CLASS_STRUCT) - { - hlsl_message("Line %u: redefining %s as a structure.\n", - hlsl_ctx.line_no, $2); - set_parse_status(&hlsl_ctx.status, PARSE_ERR); - } - else - { - $$ = type; - } - d3dcompiler_free($2); - } + KW_VOID + { + $$ = hlsl_ctx.builtin_types.Void; + } + | KW_SAMPLER + { + $$ = hlsl_ctx.builtin_types.sampler[HLSL_SAMPLER_DIM_GENERIC]; + } + | KW_SAMPLER1D + { + $$ = hlsl_ctx.builtin_types.sampler[HLSL_SAMPLER_DIM_1D]; + } + | KW_SAMPLER2D + { + $$ = hlsl_ctx.builtin_types.sampler[HLSL_SAMPLER_DIM_2D]; + } + | KW_SAMPLER3D + { + $$ = hlsl_ctx.builtin_types.sampler[HLSL_SAMPLER_DIM_3D]; + } + | KW_SAMPLERCUBE + { + $$ = hlsl_ctx.builtin_types.sampler[HLSL_SAMPLER_DIM_3D]; + } + | TYPE_IDENTIFIER + { + $$ = get_type(hlsl_ctx.cur_scope, $1, TRUE); + d3dcompiler_free($1); + } + | KW_STRUCT TYPE_IDENTIFIER + { + $$ = get_type(hlsl_ctx.cur_scope, $2, TRUE); + if ($$->type != HLSL_CLASS_STRUCT) + { + hlsl_message("Line %u: redefining %s as a structure.\n", + hlsl_ctx.line_no, $2); + set_parse_status(&hlsl_ctx.status, PARSE_ERR); + } + d3dcompiler_free($2); + }
declaration_statement: declaration | struct_declaration @@ -2207,8 +2210,8 @@ primary_expr: C_FLOAT ERR("Out of memory.\n"); YYABORT; } - init_node(&c->node, HLSL_IR_CONSTANT, new_hlsl_type(d3dcompiler_strdup("float"), - HLSL_CLASS_SCALAR, HLSL_TYPE_FLOAT, 1, 1), get_location(&@1)); + init_node(&c->node, HLSL_IR_CONSTANT, + hlsl_ctx.builtin_types.scalar[HLSL_TYPE_FLOAT], get_location(&@1)); c->v.value.f[0] = $1; if (!($$ = make_list(&c->node))) YYABORT; @@ -2221,8 +2224,8 @@ primary_expr: C_FLOAT ERR("Out of memory.\n"); YYABORT; } - init_node(&c->node, HLSL_IR_CONSTANT, new_hlsl_type(d3dcompiler_strdup("int"), - HLSL_CLASS_SCALAR, HLSL_TYPE_INT, 1, 1), get_location(&@1)); + init_node(&c->node, HLSL_IR_CONSTANT, + hlsl_ctx.builtin_types.scalar[HLSL_TYPE_INT], get_location(&@1)); c->v.value.i[0] = $1; if (!($$ = make_list(&c->node))) YYABORT; @@ -2235,8 +2238,8 @@ primary_expr: C_FLOAT ERR("Out of memory.\n"); YYABORT; } - init_node(&c->node, HLSL_IR_CONSTANT, new_hlsl_type(d3dcompiler_strdup("bool"), - HLSL_CLASS_SCALAR, HLSL_TYPE_BOOL, 1, 1), get_location(&@1)); + init_node(&c->node, HLSL_IR_CONSTANT, + hlsl_ctx.builtin_types.scalar[HLSL_TYPE_BOOL], get_location(&@1)); c->v.value.b[0] = $1; if (!($$ = make_list(&c->node))) YYABORT;
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/d3dcompiler_43/hlsl.y | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-)
diff --git a/dlls/d3dcompiler_43/hlsl.y b/dlls/d3dcompiler_43/hlsl.y index 236fc8c1865..f94e9a6462b 100644 --- a/dlls/d3dcompiler_43/hlsl.y +++ b/dlls/d3dcompiler_43/hlsl.y @@ -2323,14 +2323,9 @@ postfix_expr: primary_expr { if (!strcmp($3, field->name)) { - struct hlsl_ir_load *load = new_record_load(node, field, loc); - - if (!load) - { - ERR("Out of memory\n"); + if (!new_record_load(node, field, loc)) YYABORT; - } - $$ = append_unop($1, &load->node); + $$ = $1; break; } }
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
In particular so that we can remove the need for creating a load instruction, which besides being unnecessary was also never added to any instruction lists.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/d3dcompiler_43/hlsl.y | 43 +++++++++++++++++++++----------------- 1 file changed, 24 insertions(+), 19 deletions(-)
diff --git a/dlls/d3dcompiler_43/hlsl.y b/dlls/d3dcompiler_43/hlsl.y index f94e9a6462b..19e7dd7aeb5 100644 --- a/dlls/d3dcompiler_43/hlsl.y +++ b/dlls/d3dcompiler_43/hlsl.y @@ -549,22 +549,30 @@ static struct hlsl_ir_var *new_synthetic_var(const char *name, struct hlsl_type return var; }
-static struct hlsl_ir_assignment *make_simple_assignment(struct hlsl_ir_var *lhs, struct hlsl_ir_node *rhs) +static struct hlsl_ir_assignment *new_assignment(struct hlsl_ir_var *var, struct hlsl_ir_node *offset, + struct hlsl_ir_node *rhs, unsigned int writemask, struct source_location loc) { struct hlsl_ir_assignment *assign;
+ if (!writemask && type_is_single_reg(rhs->data_type)) + writemask = (1 << rhs->data_type->dimx) - 1; + if (!(assign = d3dcompiler_alloc(sizeof(*assign)))) return NULL;
- init_node(&assign->node, HLSL_IR_ASSIGNMENT, rhs->data_type, rhs->loc); - assign->lhs.var = lhs; + init_node(&assign->node, HLSL_IR_ASSIGNMENT, NULL, loc); + assign->lhs.var = var; + assign->lhs.offset = offset; assign->rhs = rhs; - if (type_is_single_reg(lhs->data_type)) - assign->writemask = (1 << lhs->data_type->dimx) - 1; - + assign->writemask = writemask; return assign; }
+static struct hlsl_ir_assignment *make_simple_assignment(struct hlsl_ir_var *lhs, struct hlsl_ir_node *rhs) +{ + return new_assignment(lhs, NULL, rhs, 0, rhs->loc); +} + static struct hlsl_ir_constant *new_uint_constant(unsigned int n, const struct source_location loc) { struct hlsl_ir_constant *c; @@ -693,8 +701,6 @@ static void struct_var_initializer(struct list *list, struct hlsl_ir_var *var, { struct hlsl_type *type = var->data_type; struct hlsl_struct_field *field; - struct hlsl_ir_node *assignment; - struct hlsl_ir_load *load; unsigned int i = 0;
if (initializer_size(initializer) != components_count_type(type)) @@ -710,22 +716,21 @@ static void struct_var_initializer(struct list *list, struct hlsl_ir_var *var, LIST_FOR_EACH_ENTRY(field, type->e.elements, struct hlsl_struct_field, entry) { struct hlsl_ir_node *node = initializer->args[i]; + struct hlsl_ir_assignment *assign; + struct hlsl_ir_constant *c;
if (i++ >= initializer->args_count) - { - d3dcompiler_free(initializer->args); - return; - } + break; + if (components_count_type(field->type) == components_count_type(node->data_type)) { - if (!(load = new_record_load(&new_var_load(var, var->loc)->node, field, node->loc))) - { - ERR("Out of memory.\n"); + if (!(c = new_uint_constant(field->reg_offset * 4, node->loc))) break; - } - list_add_tail(list, &load->node.entry); - assignment = make_assignment(&load->node, ASSIGN_OP_ASSIGN, node); - list_add_tail(list, &assignment->entry); + list_add_tail(list, &c->node.entry); + + if (!(assign = new_assignment(var, &c->node, node, 0, node->loc))) + break; + list_add_tail(list, &assign->node.entry); } else FIXME("Initializing with "mismatched" fields is not supported yet.\n");
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
On Tue, Jun 2, 2020 at 12:59 AM Zebediah Figura z.figura12@gmail.com wrote:
In particular so that we can remove the need for creating a load instruction, which besides being unnecessary was also never added to any instruction lists.
Well reviewed :/
I guess part of the issue is that some of the new_*() helpers add the instruction to the list and some don't. I'd say let's pick one and follow it through consistently (possibly by renaming the functions that do the opposite thing to not have the form "new_*").
On 6/3/20 11:04 AM, Matteo Bruni wrote:
On Tue, Jun 2, 2020 at 12:59 AM Zebediah Figura z.figura12@gmail.com wrote:
In particular so that we can remove the need for creating a load instruction, which besides being unnecessary was also never added to any instruction lists.
Well reviewed :/
I guess part of the issue is that some of the new_*() helpers add the instruction to the list and some don't. I'd say let's pick one and follow it through consistently (possibly by renaming the functions that do the opposite thing to not have the form "new_*").
Yeah, I noticed that too. I think renaming functions is a good way around this. Possibly "new_*" for functions that just allocate, and "add_*" for functions that add it to the list.
On Wed, Jun 3, 2020 at 6:18 PM Zebediah Figura zfigura@codeweavers.com wrote:
On 6/3/20 11:04 AM, Matteo Bruni wrote:
On Tue, Jun 2, 2020 at 12:59 AM Zebediah Figura z.figura12@gmail.com wrote:
In particular so that we can remove the need for creating a load instruction, which besides being unnecessary was also never added to any instruction lists.
Well reviewed :/
I guess part of the issue is that some of the new_*() helpers add the instruction to the list and some don't. I'd say let's pick one and follow it through consistently (possibly by renaming the functions that do the opposite thing to not have the form "new_*").
Yeah, I noticed that too. I think renaming functions is a good way around this. Possibly "new_*" for functions that just allocate, and "add_*" for functions that add it to the list.
Sounds good to me.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/d3dcompiler_43/d3dcompiler_private.h | 1 - dlls/d3dcompiler_43/hlsl.y | 19 +++++++++++++++---- dlls/d3dcompiler_43/utils.c | 16 ---------------- 3 files changed, 15 insertions(+), 21 deletions(-)
diff --git a/dlls/d3dcompiler_43/d3dcompiler_private.h b/dlls/d3dcompiler_43/d3dcompiler_private.h index 8e96a4fbcac..bc2e43cfff8 100644 --- a/dlls/d3dcompiler_43/d3dcompiler_private.h +++ b/dlls/d3dcompiler_43/d3dcompiler_private.h @@ -1096,7 +1096,6 @@ struct hlsl_ir_node *make_assignment(struct hlsl_ir_node *left, enum parse_assig struct hlsl_ir_node *right) DECLSPEC_HIDDEN; void push_scope(struct hlsl_parse_ctx *ctx) DECLSPEC_HIDDEN; BOOL pop_scope(struct hlsl_parse_ctx *ctx) DECLSPEC_HIDDEN; -struct hlsl_ir_function_decl *new_func_decl(struct hlsl_type *return_type, struct list *parameters) DECLSPEC_HIDDEN; void init_functions_tree(struct wine_rb_tree *funcs) DECLSPEC_HIDDEN; void add_function_decl(struct wine_rb_tree *funcs, char *name, struct hlsl_ir_function_decl *decl, BOOL intrinsic) DECLSPEC_HIDDEN; diff --git a/dlls/d3dcompiler_43/hlsl.y b/dlls/d3dcompiler_43/hlsl.y index 19e7dd7aeb5..bf0160e369a 100644 --- a/dlls/d3dcompiler_43/hlsl.y +++ b/dlls/d3dcompiler_43/hlsl.y @@ -1248,6 +1248,20 @@ static unsigned int evaluate_array_dimension(struct hlsl_ir_node *node) } }
+static struct hlsl_ir_function_decl *new_func_decl(struct hlsl_type *return_type, + struct list *parameters, const char *semantic, struct source_location loc) +{ + struct hlsl_ir_function_decl *decl; + + if (!(decl = d3dcompiler_alloc(sizeof(*decl)))) + return NULL; + decl->return_type = return_type; + decl->parameters = parameters; + decl->semantic = semantic; + decl->loc = loc; + return decl; +} + %}
%locations @@ -1648,15 +1662,12 @@ func_prototype: var_modifiers type var_identifier '(' parameters ')' c FIXME("Unexpected register reservation for a function.\n"); d3dcompiler_free($7.reg_reservation); } - $$.decl = new_func_decl($2, $5); - if (!$$.decl) + if (!($$.decl = new_func_decl($2, $5, $7.semantic, get_location(&@3)))) { ERR("Out of memory.\n"); YYABORT; } $$.name = $3; - $$.decl->semantic = $7.semantic; - $$.decl->loc = get_location(&@3); hlsl_ctx.cur_function = $$.decl; }
diff --git a/dlls/d3dcompiler_43/utils.c b/dlls/d3dcompiler_43/utils.c index 440ad491884..4fdda3513f7 100644 --- a/dlls/d3dcompiler_43/utils.c +++ b/dlls/d3dcompiler_43/utils.c @@ -1587,22 +1587,6 @@ BOOL pop_scope(struct hlsl_parse_ctx *ctx) return TRUE; }
-struct hlsl_ir_function_decl *new_func_decl(struct hlsl_type *return_type, struct list *parameters) -{ - struct hlsl_ir_function_decl *decl; - - decl = d3dcompiler_alloc(sizeof(*decl)); - if (!decl) - { - ERR("Out of memory.\n"); - return NULL; - } - decl->return_type = return_type; - decl->parameters = parameters; - - return decl; -} - static int compare_param_hlsl_types(const struct hlsl_type *t1, const struct hlsl_type *t2) { if (t1->type != t2->type)
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
As of 867fe22346, non-void types may have a base_type of HLSL_TYPE_VOID.
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/d3dcompiler_43/hlsl.y | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/dlls/d3dcompiler_43/hlsl.y b/dlls/d3dcompiler_43/hlsl.y index bf0160e369a..70ffa70fe10 100644 --- a/dlls/d3dcompiler_43/hlsl.y +++ b/dlls/d3dcompiler_43/hlsl.y @@ -278,6 +278,11 @@ static void declare_predefined_types(struct hlsl_scope *scope) add_type_to_scope(scope, type); }
+static BOOL type_is_void(const struct hlsl_type *type) +{ + return type->type == HLSL_CLASS_OBJECT && type->base_type == HLSL_TYPE_VOID; +} + static BOOL append_conditional_break(struct list *cond_list) { struct hlsl_ir_node *condition, *not; @@ -521,7 +526,7 @@ static struct hlsl_ir_jump *new_return(struct hlsl_ir_node *value, struct source return NULL; } } - else if (return_type->base_type != HLSL_TYPE_VOID) + else if (!type_is_void(return_type)) { hlsl_report_message(loc, HLSL_LEVEL_ERROR, "non-void function must return a value"); d3dcompiler_free(jump); @@ -1482,7 +1487,7 @@ hlsl_prog: /* empty */ } }
- if ($2.decl->return_type->base_type == HLSL_TYPE_VOID && $2.decl->semantic) + if (type_is_void($2.decl->return_type) && $2.decl->semantic) { hlsl_report_message($2.decl->loc, HLSL_LEVEL_ERROR, "void function with a semantic"); @@ -1651,7 +1656,7 @@ func_prototype: var_modifiers type var_identifier '(' parameters ')' c HLSL_LEVEL_ERROR, "redefinition of '%s'\n", $3); YYABORT; } - if ($2->base_type == HLSL_TYPE_VOID && $7.semantic) + if (type_is_void($2) && $7.semantic) { hlsl_report_message(get_location(&@7), HLSL_LEVEL_ERROR, "void function with a semantic");
Signed-off-by: Matteo Bruni mbruni@codeweavers.com
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/d3dcompiler_43/d3dcompiler_private.h | 2 +- dlls/d3dcompiler_43/hlsl.y | 92 +++++++++++++---------- dlls/d3dcompiler_43/utils.c | 5 +- 3 files changed, 55 insertions(+), 44 deletions(-)
diff --git a/dlls/d3dcompiler_43/d3dcompiler_private.h b/dlls/d3dcompiler_43/d3dcompiler_private.h index bc2e43cfff8..a61b84d6b54 100644 --- a/dlls/d3dcompiler_43/d3dcompiler_private.h +++ b/dlls/d3dcompiler_43/d3dcompiler_private.h @@ -722,6 +722,7 @@ struct hlsl_ir_function struct hlsl_ir_function_decl { struct hlsl_type *return_type; + struct hlsl_ir_var *return_var; struct source_location loc; struct wine_rb_entry entry; struct hlsl_ir_function *func; @@ -832,7 +833,6 @@ struct hlsl_ir_jump { struct hlsl_ir_node node; enum hlsl_ir_jump_type type; - struct hlsl_ir_node *return_value; };
struct hlsl_ir_swizzle diff --git a/dlls/d3dcompiler_43/hlsl.y b/dlls/d3dcompiler_43/hlsl.y index 70ffa70fe10..1797996ddbd 100644 --- a/dlls/d3dcompiler_43/hlsl.y +++ b/dlls/d3dcompiler_43/hlsl.y @@ -507,35 +507,6 @@ static struct hlsl_ir_swizzle *get_swizzle(struct hlsl_ir_node *value, const cha return NULL; }
-static struct hlsl_ir_jump *new_return(struct hlsl_ir_node *value, struct source_location loc) -{ - struct hlsl_type *return_type = hlsl_ctx.cur_function->return_type; - struct hlsl_ir_jump *jump = d3dcompiler_alloc(sizeof(*jump)); - if (!jump) - { - ERR("Out of memory\n"); - return NULL; - } - init_node(&jump->node, HLSL_IR_JUMP, NULL, loc); - jump->type = HLSL_IR_JUMP_RETURN; - if (value) - { - if (!(jump->return_value = implicit_conversion(value, return_type, &loc))) - { - d3dcompiler_free(jump); - return NULL; - } - } - else if (!type_is_void(return_type)) - { - hlsl_report_message(loc, HLSL_LEVEL_ERROR, "non-void function must return a value"); - d3dcompiler_free(jump); - return NULL; - } - - return jump; -} - static struct hlsl_ir_var *new_synthetic_var(const char *name, struct hlsl_type *type, const struct source_location loc) { @@ -578,6 +549,39 @@ static struct hlsl_ir_assignment *make_simple_assignment(struct hlsl_ir_var *lhs return new_assignment(lhs, NULL, rhs, 0, rhs->loc); }
+static struct hlsl_ir_jump *new_return(struct hlsl_ir_node *return_value, struct source_location loc) +{ + struct hlsl_type *return_type = hlsl_ctx.cur_function->return_type; + struct hlsl_ir_jump *jump; + + if (return_value) + { + struct hlsl_ir_assignment *assignment; + + if (!(return_value = implicit_conversion(return_value, return_type, &loc))) + return NULL; + + if (!(assignment = make_simple_assignment(hlsl_ctx.cur_function->return_var, return_value))) + return NULL; + list_add_after(&return_value->entry, &assignment->node.entry); + } + else if (!type_is_void(return_type)) + { + hlsl_report_message(loc, HLSL_LEVEL_ERROR, "non-void function must return a value"); + return NULL; + } + + if (!(jump = d3dcompiler_alloc(sizeof(*jump)))) + { + ERR("Out of memory\n"); + return NULL; + } + init_node(&jump->node, HLSL_IR_JUMP, NULL, loc); + jump->type = HLSL_IR_JUMP_RETURN; + + return jump; +} + static struct hlsl_ir_constant *new_uint_constant(unsigned int n, const struct source_location loc) { struct hlsl_ir_constant *c; @@ -1264,6 +1268,21 @@ static struct hlsl_ir_function_decl *new_func_decl(struct hlsl_type *return_type decl->parameters = parameters; decl->semantic = semantic; decl->loc = loc; + + if (!type_is_void(return_type)) + { + struct hlsl_ir_var *return_var; + char name[28]; + + sprintf(name, "<retval-%p>", decl); + if (!(return_var = new_synthetic_var(name, return_type, loc))) + { + d3dcompiler_free(decl); + return NULL; + } + decl->return_var = return_var; + } + return decl; }
@@ -2818,8 +2837,6 @@ static void compute_liveness_recurse(struct list *instrs, unsigned int loop_firs assignment->lhs.offset->last_read = instr->index; break; } - case HLSL_IR_CONSTANT: - break; case HLSL_IR_CONSTRUCTOR: { struct hlsl_ir_constructor *constructor = constructor_from_node(instr); @@ -2847,13 +2864,6 @@ static void compute_liveness_recurse(struct list *instrs, unsigned int loop_firs iff->condition->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; - break; - } case HLSL_IR_LOAD: { struct hlsl_ir_load *load = load_from_node(instr); @@ -2876,7 +2886,8 @@ static void compute_liveness_recurse(struct list *instrs, unsigned int loop_firs swizzle->val->last_read = instr->index; break; } - default: + case HLSL_IR_CONSTANT: + case HLSL_IR_JUMP: break; } } @@ -2899,6 +2910,9 @@ static void compute_liveness(struct hlsl_ir_function_decl *entry_func) var->last_read = UINT_MAX; }
+ if (entry_func->return_var) + entry_func->return_var->last_read = UINT_MAX; + compute_liveness_recurse(entry_func->body, 0, 0); }
diff --git a/dlls/d3dcompiler_43/utils.c b/dlls/d3dcompiler_43/utils.c index 4fdda3513f7..60bb5ff8145 100644 --- a/dlls/d3dcompiler_43/utils.c +++ b/dlls/d3dcompiler_43/utils.c @@ -2039,10 +2039,7 @@ static void debug_dump_ir_jump(const struct hlsl_ir_jump *jump) wine_dbg_printf("discard"); break; case HLSL_IR_JUMP_RETURN: - wine_dbg_printf("return "); - if (jump->return_value) - debug_dump_src(jump->return_value); - wine_dbg_printf(";"); + wine_dbg_printf("return"); break; } }
Signed-off-by: Matteo Bruni mbruni@codeweavers.com