mesa: refactor code and make _mesa_find_temp_intervals() public
authorBrian Paul <brianp@vmware.com>
Fri, 24 Apr 2009 22:28:36 +0000 (16:28 -0600)
committerBrian Paul <brianp@vmware.com>
Fri, 24 Apr 2009 22:28:36 +0000 (16:28 -0600)
src/mesa/shader/prog_optimize.c
src/mesa/shader/prog_optimize.h

index 6ba2e76ff969a3c50b998c09b103d755898aa0d8..a02f5efa4171af74f949376b85341e70eb73121b 100644 (file)
@@ -547,15 +547,13 @@ update_interval(GLint intBegin[], GLint intEnd[], GLuint index, GLuint ic)
 
 
 /**
- * Find the live intervals for each temporary register in the program.
- * For register R, the interval [A,B] indicates that R is referenced
- * from instruction A through instruction B.
- * Special consideration is needed for loops and subroutines.
- * \return GL_TRUE if success, GL_FALSE if we cannot proceed for some reason
+ * Find first/last instruction that references each temporary register.
  */
-static GLboolean
-find_live_intervals(struct gl_program *prog,
-                    struct interval_list *liveIntervals)
+GLboolean
+_mesa_find_temp_intervals(const struct prog_instruction *instructions,
+                          GLuint numInstructions,
+                          GLint intBegin[MAX_PROGRAM_TEMPS],
+                          GLint intEnd[MAX_PROGRAM_TEMPS])
 {
    struct loop_info
    {
@@ -563,26 +561,15 @@ find_live_intervals(struct gl_program *prog,
    };
    struct loop_info loopStack[MAX_LOOP_NESTING];
    GLuint loopStackDepth = 0;
-   GLint intBegin[MAX_PROGRAM_TEMPS], intEnd[MAX_PROGRAM_TEMPS];
    GLuint i;
 
-   /*
-    * Note: we'll return GL_FALSE below if we find relative indexing
-    * into the TEMP register file.  We can't handle that yet.
-    * We also give up on subroutines for now.
-    */
-
-   if (dbg) {
-      _mesa_printf("Optimize: Begin find intervals\n");
-   }
-
    for (i = 0; i < MAX_PROGRAM_TEMPS; i++){
       intBegin[i] = intEnd[i] = -1;
    }
 
    /* Scan instructions looking for temporary registers */
-   for (i = 0; i < prog->NumInstructions; i++) {
-      const struct prog_instruction *inst = prog->Instructions + i;
+   for (i = 0; i < numInstructions; i++) {
+      const struct prog_instruction *inst = instructions + i;
       if (inst->Opcode == OPCODE_BGNLOOP) {
          loopStack[loopStackDepth].Start = i;
          loopStack[loopStackDepth].End = inst->BranchTarget;
@@ -595,7 +582,7 @@ find_live_intervals(struct gl_program *prog,
          return GL_FALSE;
       }
       else {
-         const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode);
+         const GLuint numSrc = 3;/*_mesa_num_inst_src_regs(inst->Opcode);*/
          GLuint j;
          for (j = 0; j < numSrc; j++) {
             if (inst->SrcReg[j].File == PROGRAM_TEMPORARY) {
@@ -624,6 +611,39 @@ find_live_intervals(struct gl_program *prog,
       }
    }
 
+   return GL_TRUE;
+}
+
+
+/**
+ * Find the live intervals for each temporary register in the program.
+ * For register R, the interval [A,B] indicates that R is referenced
+ * from instruction A through instruction B.
+ * Special consideration is needed for loops and subroutines.
+ * \return GL_TRUE if success, GL_FALSE if we cannot proceed for some reason
+ */
+static GLboolean
+find_live_intervals(struct gl_program *prog,
+                    struct interval_list *liveIntervals)
+{
+   GLint intBegin[MAX_PROGRAM_TEMPS], intEnd[MAX_PROGRAM_TEMPS];
+   GLuint i;
+
+   /*
+    * Note: we'll return GL_FALSE below if we find relative indexing
+    * into the TEMP register file.  We can't handle that yet.
+    * We also give up on subroutines for now.
+    */
+
+   if (dbg) {
+      _mesa_printf("Optimize: Begin find intervals\n");
+   }
+
+   /* build intermediate arrays */
+   if (!_mesa_find_temp_intervals(prog->Instructions, prog->NumInstructions,
+                                  intBegin, intEnd))
+      return GL_FALSE;
+
    /* Build live intervals list from intermediate arrays */
    liveIntervals->Num = 0;
    for (i = 0; i < MAX_PROGRAM_TEMPS; i++) {
@@ -794,6 +814,96 @@ _mesa_reallocate_registers(struct gl_program *prog)
 
 
 
+
+
+
+
+#if 0
+static void
+_mesa_find_temporary_live_intervals(struct gl_program *prog,
+                                    GLint firstInst[MAX_PROGRAM_TEMPS],
+                                    GLint lastInst[MAX_PROGRAM_TEMPS])
+{
+   GLuint i;
+
+   for (i = 0; i < MAX_PROGRAM_TEMPS; i++) {
+      firstInst[i] = lastInst[i] = -1;
+   }
+
+   struct loop_info loopStack[MAX_LOOP_NESTING];
+   GLuint loopStackDepth = 0;
+   GLint intBegin[MAX_PROGRAM_TEMPS], intEnd[MAX_PROGRAM_TEMPS];
+   GLuint i;
+
+   /*
+    * Note: we'll return GL_FALSE below if we find relative indexing
+    * into the TEMP register file.  We can't handle that yet.
+    * We also give up on subroutines for now.
+    */
+
+   if (dbg) {
+      _mesa_printf("Optimize: Begin find intervals\n");
+   }
+
+   for (i = 0; i < MAX_PROGRAM_TEMPS; i++){
+      intBegin[i] = intEnd[i] = -1;
+   }
+
+   /* Scan instructions looking for temporary registers */
+   for (i = 0; i < prog->NumInstructions; i++) {
+      const struct prog_instruction *inst = prog->Instructions + i;
+      if (inst->Opcode == OPCODE_BGNLOOP) {
+         loopStack[loopStackDepth].Start = i;
+         loopStack[loopStackDepth].End = inst->BranchTarget;
+         loopStackDepth++;
+      }
+      else if (inst->Opcode == OPCODE_ENDLOOP) {
+         loopStackDepth--;
+      }
+      else if (inst->Opcode == OPCODE_CAL) {
+         return GL_FALSE;
+      }
+      else {
+         const GLuint numSrc = _mesa_num_inst_src_regs(inst->Opcode);
+         GLuint j;
+         for (j = 0; j < numSrc; j++) {
+            if (inst->SrcReg[j].File == PROGRAM_TEMPORARY) {
+               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);
+               }
+            }
+         }
+         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);
+            }
+         }
+      }
+   }
+
+
+
+
+#endif
+
+
+
+
+
+
+
 /**
  * Apply optimizations to the given program to eliminate unnecessary
  * instructions, temp regs, etc.
index d102cfd9fc13fdaf19c76e8387dee8fc4841b6a7..43894a2723772f34cca1a397880c8da867a10d20 100644 (file)
 #ifndef PROG_OPT_H
 #define PROG_OPT_H
 
+
+#include "main/config.h"
+
+
 struct gl_program;
+struct prog_instruction;
+
+
+extern GLboolean
+_mesa_find_temp_intervals(const struct prog_instruction *instructions,
+                          GLuint numInstructions,
+                          GLint intBegin[MAX_PROGRAM_TEMPS],
+                          GLint intEnd[MAX_PROGRAM_TEMPS]);
 
 extern void
 _mesa_optimize_program(GLcontext *ctx, struct gl_program *program);