From: Francisco Casas fcasas@codeweavers.com
This node type is intended for use during parse-time.
While we parse an indexing expression such as "a[3]", we don't know if it will end up as part of an expression (in which case it must be folded into a load) or it is for the lhs of a store (in which case it must be folded into the store's deref).
---
This patch adds what may be considered dead-code, but this is promptly used in the following patch. I organized it this way to somewhat ease the review. --- libs/vkd3d-shader/hlsl.c | 60 ++++++++++++++++++++++++++++++++ libs/vkd3d-shader/hlsl.h | 15 ++++++++ libs/vkd3d-shader/hlsl.y | 1 + libs/vkd3d-shader/hlsl_codegen.c | 9 +++++ 4 files changed, 85 insertions(+)
diff --git a/libs/vkd3d-shader/hlsl.c b/libs/vkd3d-shader/hlsl.c index 24822e97..4dcc0685 100644 --- a/libs/vkd3d-shader/hlsl.c +++ b/libs/vkd3d-shader/hlsl.c @@ -1274,6 +1274,28 @@ struct hlsl_ir_swizzle *hlsl_new_swizzle(struct hlsl_ctx *ctx, DWORD s, unsigned return swizzle; }
+struct hlsl_ir_node *hlsl_new_index(struct hlsl_ctx *ctx, struct hlsl_ir_node *val, + struct hlsl_ir_node *idx, const struct vkd3d_shader_location *loc) +{ + struct hlsl_type *type = val->data_type; + struct hlsl_ir_index *index; + + if (!(index = hlsl_alloc(ctx, sizeof(*index)))) + return NULL; + + if (type->type == HLSL_CLASS_OBJECT) + type = type->e.resource_format; + else if (type->type == HLSL_CLASS_MATRIX) + type = hlsl_get_vector_type(ctx, type->base_type, type->dimx); + else + type = hlsl_get_element_type_from_path_index(ctx, type, idx); + + init_node(&index->node, HLSL_IR_INDEX, type, loc); + hlsl_src_from_node(&index->val, val); + hlsl_src_from_node(&index->idx, idx); + return &index->node; +} + struct hlsl_ir_jump *hlsl_new_jump(struct hlsl_ctx *ctx, enum hlsl_ir_jump_type type, struct vkd3d_shader_location loc) { struct hlsl_ir_jump *jump; @@ -1533,6 +1555,17 @@ static struct hlsl_ir_node *clone_swizzle(struct hlsl_ctx *ctx, return &dst->node; }
+static struct hlsl_ir_node *clone_index(struct hlsl_ctx *ctx, struct clone_instr_map *map, + struct hlsl_ir_index *src) +{ + struct hlsl_ir_node *dst; + + if (!(dst = hlsl_new_index(ctx, map_instr(map, src->val.node), map_instr(map, src->idx.node), + &src->node.loc))) + return NULL; + return dst; +} + static struct hlsl_ir_node *clone_instr(struct hlsl_ctx *ctx, struct clone_instr_map *map, const struct hlsl_ir_node *instr) { @@ -1550,6 +1583,9 @@ static struct hlsl_ir_node *clone_instr(struct hlsl_ctx *ctx, case HLSL_IR_IF: return clone_if(ctx, map, hlsl_ir_if(instr));
+ case HLSL_IR_INDEX: + return clone_index(ctx, map, hlsl_ir_index(instr)); + case HLSL_IR_JUMP: return clone_jump(ctx, hlsl_ir_jump(instr));
@@ -1939,6 +1975,7 @@ const char *hlsl_node_type_to_string(enum hlsl_ir_node_type type) "HLSL_IR_CONSTANT", "HLSL_IR_EXPR", "HLSL_IR_IF", + "HLSL_IR_INDEX", "HLSL_IR_LOAD", "HLSL_IR_LOOP", "HLSL_IR_JUMP", @@ -2317,6 +2354,14 @@ static void dump_ir_swizzle(struct vkd3d_string_buffer *buffer, const struct hls } }
+static void dump_ir_index(struct vkd3d_string_buffer *buffer, const struct hlsl_ir_index *index) +{ + dump_src(buffer, &index->val); + vkd3d_string_buffer_printf(buffer, "[idx:"); + dump_src(buffer, &index->idx); + vkd3d_string_buffer_printf(buffer, "]"); +} + static void dump_instr(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, const struct hlsl_ir_node *instr) { if (instr->index) @@ -2344,6 +2389,10 @@ static void dump_instr(struct hlsl_ctx *ctx, struct vkd3d_string_buffer *buffer, dump_ir_if(ctx, buffer, hlsl_ir_if(instr)); break;
+ case HLSL_IR_INDEX: + dump_ir_index(buffer, hlsl_ir_index(instr)); + break; + case HLSL_IR_JUMP: dump_ir_jump(buffer, hlsl_ir_jump(instr)); break; @@ -2518,6 +2567,13 @@ static void free_ir_swizzle(struct hlsl_ir_swizzle *swizzle) vkd3d_free(swizzle); }
+static void free_ir_index(struct hlsl_ir_index *index) +{ + hlsl_src_remove(&index->val); + hlsl_src_remove(&index->idx); + vkd3d_free(index); +} + void hlsl_free_instr(struct hlsl_ir_node *node) { assert(list_empty(&node->uses)); @@ -2540,6 +2596,10 @@ void hlsl_free_instr(struct hlsl_ir_node *node) free_ir_if(hlsl_ir_if(node)); break;
+ case HLSL_IR_INDEX: + free_ir_index(hlsl_ir_index(node)); + break; + case HLSL_IR_JUMP: free_ir_jump(hlsl_ir_jump(node)); break; diff --git a/libs/vkd3d-shader/hlsl.h b/libs/vkd3d-shader/hlsl.h index 24d0f517..f801349d 100644 --- a/libs/vkd3d-shader/hlsl.h +++ b/libs/vkd3d-shader/hlsl.h @@ -252,6 +252,7 @@ enum hlsl_ir_node_type HLSL_IR_CONSTANT, HLSL_IR_EXPR, HLSL_IR_IF, + HLSL_IR_INDEX, HLSL_IR_LOAD, HLSL_IR_LOOP, HLSL_IR_JUMP, @@ -538,6 +539,12 @@ struct hlsl_ir_swizzle DWORD swizzle; };
+struct hlsl_ir_index +{ + struct hlsl_ir_node node; + struct hlsl_src val, idx; +}; + /* Reference to a variable, or a part of it (e.g. a vector within a matrix within a struct). */ struct hlsl_deref { @@ -848,6 +855,12 @@ static inline struct hlsl_ir_swizzle *hlsl_ir_swizzle(const struct hlsl_ir_node return CONTAINING_RECORD(node, struct hlsl_ir_swizzle, node); }
+static inline struct hlsl_ir_index *hlsl_ir_index(const struct hlsl_ir_node *node) +{ + assert(node->type == HLSL_IR_INDEX); + return CONTAINING_RECORD(node, struct hlsl_ir_index, node); +} + static inline void hlsl_src_from_node(struct hlsl_src *src, struct hlsl_ir_node *node) { src->node = node; @@ -1048,6 +1061,8 @@ struct hlsl_ir_store *hlsl_new_store_index(struct hlsl_ctx *ctx, const struct hl struct hlsl_ir_store *hlsl_new_store_component(struct hlsl_ctx *ctx, struct hlsl_block *block, const struct hlsl_deref *lhs, unsigned int comp, struct hlsl_ir_node *rhs);
+struct hlsl_ir_node *hlsl_new_index(struct hlsl_ctx *ctx, struct hlsl_ir_node *val, + struct hlsl_ir_node *idx, const struct vkd3d_shader_location *loc); struct hlsl_ir_loop *hlsl_new_loop(struct hlsl_ctx *ctx, struct vkd3d_shader_location loc); struct hlsl_ir_resource_load *hlsl_new_resource_load(struct hlsl_ctx *ctx, const struct hlsl_resource_load_params *params, const struct vkd3d_shader_location *loc); diff --git a/libs/vkd3d-shader/hlsl.y b/libs/vkd3d-shader/hlsl.y index e011ea24..bc0de136 100644 --- a/libs/vkd3d-shader/hlsl.y +++ b/libs/vkd3d-shader/hlsl.y @@ -1153,6 +1153,7 @@ static unsigned int evaluate_array_dimension(struct hlsl_ir_node *node) }
case HLSL_IR_EXPR: + case HLSL_IR_INDEX: case HLSL_IR_LOAD: case HLSL_IR_RESOURCE_LOAD: case HLSL_IR_SWIZZLE: diff --git a/libs/vkd3d-shader/hlsl_codegen.c b/libs/vkd3d-shader/hlsl_codegen.c index 65bd9d4c..4c0b2dc2 100644 --- a/libs/vkd3d-shader/hlsl_codegen.c +++ b/libs/vkd3d-shader/hlsl_codegen.c @@ -2155,6 +2155,7 @@ static bool dce(struct hlsl_ctx *ctx, struct hlsl_ir_node *instr, void *context) { case HLSL_IR_CONSTANT: case HLSL_IR_EXPR: + case HLSL_IR_INDEX: case HLSL_IR_LOAD: case HLSL_IR_RESOURCE_LOAD: case HLSL_IR_SWIZZLE: @@ -2394,6 +2395,14 @@ static void compute_liveness_recurse(struct hlsl_block *block, unsigned int loop swizzle->val.node->last_read = instr->index; break; } + case HLSL_IR_INDEX: + { + struct hlsl_ir_index *index = hlsl_ir_index(instr); + + index->val.node->last_read = instr->index; + index->idx.node->last_read = instr->index; + break; + } case HLSL_IR_CONSTANT: case HLSL_IR_JUMP: break;