From ac25cf55aff6ec81bc36dc9f3257b0c7a6dd17d3 Mon Sep 17 00:00:00 2001 From: Matt Turner Date: Fri, 30 May 2014 19:26:30 -0700 Subject: [PATCH] glsl: Make most ir_instruction::as_subclass() functions non-virtual. There are several common ways to check whether an object is a particular subclass: dynamic_cast<>, the as_subclass() pattern, or explicit enum tags. We originally used the virtual as_subclass methods, but later added enum tags as they are much nicer for debugging. Since we have the enum tags, we don't necessarily need to use virtual functions to implement the as_subclass() methods. We can just check the tag and return the pointer or NULL. This saves 18 entries in the vtable, and instead of two pointer dereferences per as_subclass() call most are only three inline instructions. Compile time of sam3/112.frag (the longest compile in a recent shader-db run) is reduced by 5% from 348 to 329 ms (n=500). perf stat of this workload shows: 24.14% reduction in iTLB-loads: 285,543 -> 216,606 42.55% reduction in iTLB-load-misses: 18,785 -> 10,792 Reviewed-by: Juha-Pekka Heikkila --- src/glsl/ir.h | 161 ++++++++++++++++---------------------------------- 1 file changed, 52 insertions(+), 109 deletions(-) diff --git a/src/glsl/ir.h b/src/glsl/ir.h index 585c31c2db6..2afafe4b5c7 100644 --- a/src/glsl/ir.h +++ b/src/glsl/ir.h @@ -117,24 +117,58 @@ public: * Additional downcast functions will be added as needed. */ /*@{*/ - virtual class ir_variable * as_variable() { return NULL; } - virtual class ir_function * as_function() { return NULL; } - virtual class ir_dereference * as_dereference() { return NULL; } - virtual class ir_dereference_array * as_dereference_array() { return NULL; } - virtual class ir_dereference_variable *as_dereference_variable() { return NULL; } - virtual class ir_dereference_record *as_dereference_record() { return NULL; } - virtual class ir_expression * as_expression() { return NULL; } - virtual class ir_rvalue * as_rvalue() { return NULL; } - virtual class ir_loop * as_loop() { return NULL; } - virtual class ir_assignment * as_assignment() { return NULL; } - virtual class ir_call * as_call() { return NULL; } - virtual class ir_return * as_return() { return NULL; } - virtual class ir_if * as_if() { return NULL; } - virtual class ir_swizzle * as_swizzle() { return NULL; } - virtual class ir_texture * as_texture() { return NULL; } - virtual class ir_constant * as_constant() { return NULL; } - virtual class ir_discard * as_discard() { return NULL; } - virtual class ir_jump * as_jump() { return NULL; } + class ir_rvalue *as_rvalue() + { + if (ir_type == ir_type_dereference_array || + ir_type == ir_type_dereference_record || + ir_type == ir_type_dereference_variable || + ir_type == ir_type_constant || + ir_type == ir_type_expression || + ir_type == ir_type_swizzle || + ir_type == ir_type_texture) + return (class ir_rvalue *) this; + return NULL; + } + + class ir_dereference *as_dereference() + { + if (ir_type == ir_type_dereference_array || + ir_type == ir_type_dereference_record || + ir_type == ir_type_dereference_variable) + return (class ir_dereference *) this; + return NULL; + } + + class ir_jump *as_jump() + { + if (ir_type == ir_type_loop_jump || + ir_type == ir_type_return || + ir_type == ir_type_discard) + return (class ir_jump *) this; + return NULL; + } + + #define AS_CHILD(TYPE) \ + class ir_##TYPE * as_##TYPE() \ + { \ + return ir_type == ir_type_##TYPE ? (ir_##TYPE *) this : NULL; \ + } + AS_CHILD(variable) + AS_CHILD(function) + AS_CHILD(dereference_array) + AS_CHILD(dereference_variable) + AS_CHILD(dereference_record) + AS_CHILD(expression) + AS_CHILD(loop) + AS_CHILD(assignment) + AS_CHILD(call) + AS_CHILD(return) + AS_CHILD(if) + AS_CHILD(swizzle) + AS_CHILD(texture) + AS_CHILD(constant) + AS_CHILD(discard) + #undef AS_CHILD /*@}*/ /** @@ -179,11 +213,6 @@ public: virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL); - virtual ir_rvalue * as_rvalue() - { - return this; - } - ir_rvalue *as_rvalue_to_saturate(); virtual bool is_lvalue() const @@ -384,11 +413,6 @@ public: virtual ir_variable *clone(void *mem_ctx, struct hash_table *ht) const; - virtual ir_variable *as_variable() - { - return this; - } - virtual void accept(ir_visitor *v) { v->visit(this); @@ -919,11 +943,6 @@ public: virtual ir_function *clone(void *mem_ctx, struct hash_table *ht) const; - virtual ir_function *as_function() - { - return this; - } - virtual void accept(ir_visitor *v) { v->visit(this); @@ -992,11 +1011,6 @@ public: virtual ir_if *clone(void *mem_ctx, struct hash_table *ht) const; - virtual ir_if *as_if() - { - return this; - } - virtual void accept(ir_visitor *v) { v->visit(this); @@ -1028,11 +1042,6 @@ public: virtual ir_visitor_status accept(ir_hierarchical_visitor *); - virtual ir_loop *as_loop() - { - return this; - } - /** List of ir_instruction that make up the body of the loop. */ exec_list body_instructions; }; @@ -1063,11 +1072,6 @@ public: virtual ir_visitor_status accept(ir_hierarchical_visitor *); - virtual ir_assignment * as_assignment() - { - return this; - } - /** * Get a whole variable written by an assignment * @@ -1431,11 +1435,6 @@ public: */ ir_expression(int op, ir_rvalue *op0, ir_rvalue *op1, ir_rvalue *op2); - virtual ir_expression *as_expression() - { - return this; - } - virtual bool equals(ir_instruction *ir, enum ir_node_type ignore = ir_type_unset); virtual ir_expression *clone(void *mem_ctx, struct hash_table *ht) const; @@ -1526,11 +1525,6 @@ public: virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL); - virtual ir_call *as_call() - { - return this; - } - virtual void accept(ir_visitor *v) { v->visit(this); @@ -1583,12 +1577,6 @@ protected: : ir_instruction(t) { } - -public: - virtual ir_jump *as_jump() - { - return this; - } }; class ir_return : public ir_jump { @@ -1605,11 +1593,6 @@ public: virtual ir_return *clone(void *mem_ctx, struct hash_table *) const; - virtual ir_return *as_return() - { - return this; - } - ir_rvalue *get_value() const { return value; @@ -1696,11 +1679,6 @@ public: virtual ir_visitor_status accept(ir_hierarchical_visitor *); - virtual ir_discard *as_discard() - { - return this; - } - ir_rvalue *condition; }; /*@}*/ @@ -1766,11 +1744,6 @@ public: v->visit(this); } - virtual ir_texture *as_texture() - { - return this; - } - virtual ir_visitor_status accept(ir_hierarchical_visitor *); virtual bool equals(ir_instruction *ir, enum ir_node_type ignore = ir_type_unset); @@ -1862,11 +1835,6 @@ public: virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL); - virtual ir_swizzle *as_swizzle() - { - return this; - } - /** * Construct an ir_swizzle from the textual representation. Can fail. */ @@ -1908,11 +1876,6 @@ class ir_dereference : public ir_rvalue { public: virtual ir_dereference *clone(void *mem_ctx, struct hash_table *) const = 0; - virtual ir_dereference *as_dereference() - { - return this; - } - bool is_lvalue() const; /** @@ -1937,11 +1900,6 @@ public: virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL); - virtual ir_dereference_variable *as_dereference_variable() - { - return this; - } - virtual bool equals(ir_instruction *ir, enum ir_node_type ignore = ir_type_unset); /** @@ -1988,11 +1946,6 @@ public: virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL); - virtual ir_dereference_array *as_dereference_array() - { - return this; - } - virtual bool equals(ir_instruction *ir, enum ir_node_type ignore = ir_type_unset); /** @@ -2029,11 +1982,6 @@ public: virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL); - virtual ir_dereference_record *as_dereference_record() - { - return this; - } - /** * Get the variable that is ultimately referenced by an r-value */ @@ -2099,11 +2047,6 @@ public: virtual ir_constant *constant_expression_value(struct hash_table *variable_context = NULL); - virtual ir_constant *as_constant() - { - return this; - } - virtual void accept(ir_visitor *v) { v->visit(this); -- 2.30.2