Mesa (master): llvmpipe: switch to using dynamic stack allocation instead of registers

Zack Rusin zack at kemper.freedesktop.org
Tue Feb 9 02:51:42 UTC 2010


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

Author: Zack Rusin <zackr at vmware.com>
Date:   Mon Feb  8 21:50:33 2010 -0500

llvmpipe: switch to using dynamic stack allocation instead of registers

with mutable vars we don't need to follow the phi nodes. meaning that
control flow becomes trivial as we don't have scan the rest of the tgsi
to figure out the variable usage anymore. futhermore the memory2register
pass promotes alloca/store/load to registers while inserting the right phi
nodes. so we get simplicity and performance.

---

 src/gallium/auxiliary/gallivm/lp_bld_logic.c    |   12 ++++++
 src/gallium/auxiliary/gallivm/lp_bld_logic.h    |    2 +
 src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c |   48 +++++++++++++++++++++-
 src/gallium/drivers/llvmpipe/lp_state_fs.c      |   11 +++--
 4 files changed, 65 insertions(+), 8 deletions(-)

diff --git a/src/gallium/auxiliary/gallivm/lp_bld_logic.c b/src/gallium/auxiliary/gallivm/lp_bld_logic.c
index d23de4f..41ac81b 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_logic.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_logic.c
@@ -419,3 +419,15 @@ lp_build_select_aos(struct lp_build_context *bld,
 #endif
    }
 }
+
+LLVMValueRef
+lp_build_alloca(struct lp_build_context *bld)
+{
+   const struct lp_type type = bld->type;
+
+   if (type.length > 1) { /*vector*/
+      return LLVMBuildAlloca(bld->builder, lp_build_vec_type(type), "");
+   } else { /*scalar*/
+      return LLVMBuildAlloca(bld->builder, lp_build_elem_type(type), "");
+   }
+}
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_logic.h b/src/gallium/auxiliary/gallivm/lp_bld_logic.h
index 40d64eb..a399ebf 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_logic.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_logic.h
@@ -76,5 +76,7 @@ lp_build_select_aos(struct lp_build_context *bld,
                     LLVMValueRef b,
                     const boolean cond[4]);
 
+LLVMValueRef
+lp_build_alloca(struct lp_build_context *bld);
 
 #endif /* !LP_BLD_LOGIC_H */
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
index 85e3b1b..a52c6c5 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
@@ -185,7 +185,7 @@ emit_fetch(
          break;
 
       case TGSI_FILE_TEMPORARY:
-         res = bld->temps[reg->Register.Index][swizzle];
+         res = LLVMBuildLoad(bld->base.builder, bld->temps[reg->Register.Index][swizzle], "");
          if(!res)
             return bld->base.undef;
          break;
@@ -287,11 +287,13 @@ emit_store(
 
    switch( reg->Register.File ) {
    case TGSI_FILE_OUTPUT:
-      bld->outputs[reg->Register.Index][chan_index] = value;
+      LLVMBuildStore(bld->base.builder, value,
+                     bld->outputs[reg->Register.Index][chan_index]);
       break;
 
    case TGSI_FILE_TEMPORARY:
-      bld->temps[reg->Register.Index][chan_index] = value;
+      LLVMBuildStore(bld->base.builder, value,
+                     bld->temps[reg->Register.Index][chan_index]);
       break;
 
    case TGSI_FILE_ADDRESS:
@@ -438,6 +440,42 @@ indirect_temp_reference(const struct tgsi_full_instruction *inst)
    return FALSE;
 }
 
+static int
+emit_declaration(
+   struct lp_build_tgsi_soa_context *bld,
+   const struct tgsi_full_declaration *decl)
+{
+   unsigned first = decl->Range.First;
+   unsigned last = decl->Range.Last;
+   unsigned idx, i;
+
+   for (idx = first; idx <= last; ++idx) {
+      boolean ok;
+
+      switch (decl->Declaration.File) {
+      case TGSI_FILE_TEMPORARY:
+         for (i = 0; i < NUM_CHANNELS; i++)
+            bld->temps[idx][i] = lp_build_alloca(&bld->base);
+         ok = TRUE;
+         break;
+
+      case TGSI_FILE_OUTPUT:
+         for (i = 0; i < NUM_CHANNELS; i++)
+            bld->outputs[idx][i] = lp_build_alloca(&bld->base);
+         ok = TRUE;
+         break;
+
+      default:
+         /* don't need to declare other vars */
+         ok = TRUE;
+      }
+
+      if (!ok)
+         return FALSE;
+   }
+
+   return TRUE;
+}
 
 static int
 emit_instruction(
@@ -1429,6 +1467,10 @@ lp_build_tgsi_soa(LLVMBuilderRef builder,
       switch( parse.FullToken.Token.Type ) {
       case TGSI_TOKEN_TYPE_DECLARATION:
          /* Inputs already interpolated */
+         {
+            if (!emit_declaration( &bld, &parse.FullToken.FullDeclaration ))
+               _debug_printf("warning: failed to define LLVM variable\n");
+         }
          break;
 
       case TGSI_TOKEN_TYPE_INSTRUCTION:
diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c
index 320e2b7..2001a95 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_fs.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c
@@ -468,20 +468,21 @@ generate_fs(struct llvmpipe_context *lp,
    for (attrib = 0; attrib < shader->info.num_outputs; ++attrib) {
       for(chan = 0; chan < NUM_CHANNELS; ++chan) {
          if(outputs[attrib][chan]) {
-            lp_build_name(outputs[attrib][chan], "output%u.%u.%c", i, attrib, "xyzw"[chan]);
+            LLVMValueRef out = LLVMBuildLoad(builder, outputs[attrib][chan], "");
+            lp_build_name(out, "output%u.%u.%c", i, attrib, "xyzw"[chan]);
 
             switch (shader->info.output_semantic_name[attrib]) {
             case TGSI_SEMANTIC_COLOR:
                {
                   unsigned cbuf = shader->info.output_semantic_index[attrib];
 
-                  lp_build_name(outputs[attrib][chan], "color%u.%u.%c", i, attrib, "rgba"[chan]);
+                  lp_build_name(out, "color%u.%u.%c", i, attrib, "rgba"[chan]);
 
                   /* Alpha test */
                   /* XXX: should the alpha reference value be passed separately? */
 		  /* XXX: should only test the final assignment to alpha */
                   if(cbuf == 0 && chan == 3) {
-                     LLVMValueRef alpha = outputs[attrib][chan];
+                     LLVMValueRef alpha = out;
                      LLVMValueRef alpha_ref_value;
                      alpha_ref_value = lp_jit_context_alpha_ref_value(builder, context_ptr);
                      alpha_ref_value = lp_build_broadcast(builder, vec_type, alpha_ref_value);
@@ -489,13 +490,13 @@ generate_fs(struct llvmpipe_context *lp,
                                          &mask, alpha, alpha_ref_value);
                   }
 
-		  color[cbuf][chan] = outputs[attrib][chan];
+		  color[cbuf][chan] = out;
                   break;
                }
 
             case TGSI_SEMANTIC_POSITION:
                if(chan == 2)
-                  z = outputs[attrib][chan];
+                  z = out;
                break;
             }
          }




More information about the mesa-commit mailing list