Mesa (glsl2): mesa: Extend register lifetimes to the end of the largest loop required.

Eric Anholt anholt at kemper.freedesktop.org
Thu Jul 8 04:38:20 UTC 2010


Module: Mesa
Branch: glsl2
Commit: 25cda5039df0da6c2c65f1cac1bfc750c0c16e82
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=25cda5039df0da6c2c65f1cac1bfc750c0c16e82

Author: Eric Anholt <eric at anholt.net>
Date:   Wed Jul  7 21:28:28 2010 -0700

mesa: Extend register lifetimes to the end of the largest loop required.

Previously, a register defined at main scope and used in a loop in a
loop could end up getting marked as needed only from the definition
outside of the loops to the end of the inner loop, and we would
cleverly slot in something else in its register in the end of the
outer loop.

Fixes glsl-vs-loop-nested and glsl-fs-loop-nested on glsl2.  This
doesn't happen much on master because the original compiler does its
own register allocation, so we find little we can do with linear scan
register (re)allocation.

---

 src/mesa/shader/prog_optimize.c |   40 ++++++++++++++++++++++----------------
 1 files changed, 23 insertions(+), 17 deletions(-)

diff --git a/src/mesa/shader/prog_optimize.c b/src/mesa/shader/prog_optimize.c
index 2941a17..bd120b8 100644
--- a/src/mesa/shader/prog_optimize.c
+++ b/src/mesa/shader/prog_optimize.c
@@ -728,14 +728,32 @@ sort_interval_list_by_start(struct interval_list *list)
 #endif
 }
 
+struct loop_info
+{
+   GLuint Start, End;  /**< Start, end instructions of loop */
+};
 
 /**
  * Update the intermediate interval info for register 'index' and
  * instruction 'ic'.
  */
 static void
-update_interval(GLint intBegin[], GLint intEnd[], GLuint index, GLuint ic)
+update_interval(GLint intBegin[], GLint intEnd[],
+		struct loop_info *loopStack, GLuint loopStackDepth,
+		GLuint index, GLuint ic)
 {
+   int i;
+
+   /* If the register is used in a loop, extend its lifetime through the end
+    * of the outermost loop that doesn't contain its definition.
+    */
+   for (i = 0; i < loopStackDepth; i++) {
+      if (intBegin[index] < loopStack[i].Start) {
+	 ic = loopStack[i].End;
+	 break;
+      }
+   }
+
    ASSERT(index < MAX_PROGRAM_TEMPS);
    if (intBegin[index] == -1) {
       ASSERT(intEnd[index] == -1);
@@ -756,10 +774,6 @@ _mesa_find_temp_intervals(const struct prog_instruction *instructions,
                           GLint intBegin[MAX_PROGRAM_TEMPS],
                           GLint intEnd[MAX_PROGRAM_TEMPS])
 {
-   struct loop_info
-   {
-      GLuint Start, End;  /**< Start, end instructions of loop */
-   };
    struct loop_info loopStack[MAX_LOOP_NESTING];
    GLuint loopStackDepth = 0;
    GLuint i;
@@ -790,24 +804,16 @@ _mesa_find_temp_intervals(const struct prog_instruction *instructions,
                const GLuint index = inst->SrcReg[j].Index;
                if (inst->SrcReg[j].RelAddr)
                   return GL_FALSE;
-               update_interval(intBegin, intEnd, index, i);
-               if (loopStackDepth > 0) {
-                  /* extend temp register's interval to end of loop */
-                  GLuint loopEnd = loopStack[loopStackDepth - 1].End;
-                  update_interval(intBegin, intEnd, index, loopEnd);
-               }
+               update_interval(intBegin, intEnd, loopStack, loopStackDepth,
+			       index, i);
             }
          }
          if (inst->DstReg.File == PROGRAM_TEMPORARY) {
             const GLuint index = inst->DstReg.Index;
             if (inst->DstReg.RelAddr)
                return GL_FALSE;
-            update_interval(intBegin, intEnd, index, i);
-            if (loopStackDepth > 0) {
-               /* extend temp register's interval to end of loop */
-               GLuint loopEnd = loopStack[loopStackDepth - 1].End;
-               update_interval(intBegin, intEnd, index, loopEnd);
-            }
+            update_interval(intBegin, intEnd, loopStack, loopStackDepth,
+			    index, i);
          }
       }
    }




More information about the mesa-commit mailing list