summaryrefslogtreecommitdiff
path: root/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
diff options
context:
space:
mode:
authorZack Rusin <zackr@vmware.com>2010-02-08 21:50:33 -0500
committerZack Rusin <zackr@vmware.com>2010-02-08 21:50:33 -0500
commit85c7ec70ad41c8ada75a4cbace83d16815d3e2c5 (patch)
tree7154254e4d6c26e27e410524f814a52329ff46d3 /src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
parent257267ee9817d67e6963e81766a121c367478f65 (diff)
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.
Diffstat (limited to 'src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c')
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c48
1 files changed, 45 insertions, 3 deletions
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
index 85e3b1bdd4..a52c6c5028 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: