From: Zebediah Figura zfigura@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@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");