Mesa (master): glsl: Make most ir_instruction::as_subclass() functions non-virtual.

Matt Turner mattst88 at kemper.freedesktop.org
Wed Jun 4 00:59:27 UTC 2014


Module: Mesa
Branch: master
Commit: ac25cf55aff6ec81bc36dc9f3257b0c7a6dd17d3
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=ac25cf55aff6ec81bc36dc9f3257b0c7a6dd17d3

Author: Matt Turner <mattst88 at gmail.com>
Date:   Fri May 30 19:26:30 2014 -0700

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 <juhapekka.heikkila at gmail.com>

---

 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 585c31c..2afafe4 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);




More information about the mesa-commit mailing list