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

Author: Nicolai Hähnle <[email protected]>
Date:   Mon Aug  8 23:13:44 2016 +0200

gallium/radeon: extract common getelementptr logic into get_pointer_into_array

Reviewed-by: Marek Olšák <[email protected]>

---

 .../drivers/radeon/radeon_setup_tgsi_llvm.c        | 105 +++++++++++++--------
 1 file changed, 66 insertions(+), 39 deletions(-)

diff --git a/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c 
b/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c
index 531a8fe..87fc07e 100644
--- a/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c
+++ b/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c
@@ -187,6 +187,41 @@ emit_array_index(struct lp_build_tgsi_soa_context *bld,
        return LLVMBuildAdd(gallivm->builder, addr, 
lp_build_const_int32(gallivm, offset), "");
 }
 
+/**
+ * For indirect registers, construct a pointer directly to the requested
+ * element using getelementptr if possible.
+ *
+ * Returns NULL if the insertelement/extractelement fallback for array access
+ * must be used.
+ */
+static LLVMValueRef
+get_pointer_into_array(struct radeon_llvm_context *ctx,
+                      unsigned file,
+                      unsigned swizzle,
+                      unsigned reg_index,
+                      const struct tgsi_ind_register *reg_indirect)
+{
+       const struct radeon_llvm_array *array;
+       struct gallivm_state *gallivm = ctx->soa.bld_base.base.gallivm;
+       LLVMBuilderRef builder = gallivm->builder;
+       LLVMValueRef idxs[2];
+       LLVMValueRef index;
+
+       if (file != TGSI_FILE_TEMPORARY)
+               return NULL;
+
+       array = get_temp_array(&ctx->soa.bld_base, reg_index, reg_indirect);
+       if (!array || !array->alloca)
+               return NULL;
+
+       index = emit_array_index(&ctx->soa, reg_indirect, reg_index - 
array->range.First);
+       index = LLVMBuildMul(builder, index, lp_build_const_int32(gallivm, 
TGSI_NUM_CHANNELS), "");
+       index = LLVMBuildAdd(builder, index, lp_build_const_int32(gallivm, 
swizzle), "");
+       idxs[0] = ctx->soa.bld_base.uint_bld.zero;
+       idxs[1] = index;
+       return LLVMBuildGEP(builder, array->alloca, idxs, 2, "");
+}
+
 LLVMValueRef
 radeon_llvm_emit_fetch_64bit(struct lp_build_tgsi_context *bld_base,
                             enum tgsi_opcode_type type,
@@ -243,36 +278,32 @@ load_value_from_array(struct lp_build_tgsi_context 
*bld_base,
                      unsigned reg_index,
                      const struct tgsi_ind_register *reg_indirect)
 {
+       struct radeon_llvm_context *ctx = radeon_llvm_context(bld_base);
        struct lp_build_tgsi_soa_context *bld = lp_soa_context(bld_base);
        struct gallivm_state *gallivm = bld_base->base.gallivm;
        LLVMBuilderRef builder = gallivm->builder;
-       struct tgsi_declaration_range range = get_array_range(bld_base, file, 
reg_index, reg_indirect);
-       LLVMValueRef index = emit_array_index(bld, reg_indirect, reg_index - 
range.First);
-       LLVMValueRef array = get_alloca_for_array(bld_base, file, reg_index, 
reg_indirect);
-       LLVMValueRef ptr, val, indices[2];
-
-       if (!array) {
-               /* Handle the case where the array is stored as a vector. */
-               return LLVMBuildExtractElement(builder,
-                               emit_array_fetch(bld_base, file, type, range, 
swizzle),
-                               index, "");
-       }
+       LLVMValueRef ptr;
 
-       index = LLVMBuildMul(builder, index, lp_build_const_int32(gallivm, 
TGSI_NUM_CHANNELS), "");
-       index = LLVMBuildAdd(builder, index, lp_build_const_int32(gallivm, 
swizzle), "");
-       indices[0] = bld_base->uint_bld.zero;
-       indices[1] = index;
-       ptr = LLVMBuildGEP(builder, array, indices, 2, "");
-       val = LLVMBuildLoad(builder, ptr, "");
-       if (tgsi_type_is_64bit(type)) {
-               LLVMValueRef ptr_hi, val_hi;
-               indices[0] = lp_build_const_int32(gallivm, 1);
-               ptr_hi = LLVMBuildGEP(builder, ptr, indices, 1, "");
-               val_hi = LLVMBuildLoad(builder, ptr_hi, "");
-               val = radeon_llvm_emit_fetch_64bit(bld_base, type, val, val_hi);
+       ptr = get_pointer_into_array(ctx, file, swizzle, reg_index, 
reg_indirect);
+       if (ptr) {
+               LLVMValueRef val = LLVMBuildLoad(builder, ptr, "");
+               if (tgsi_type_is_64bit(type)) {
+                       LLVMValueRef ptr_hi, val_hi;
+                       ptr_hi = LLVMBuildGEP(builder, ptr, 
&bld_base->uint_bld.one, 1, "");
+                       val_hi = LLVMBuildLoad(builder, ptr_hi, "");
+                       val = radeon_llvm_emit_fetch_64bit(bld_base, type, val, 
val_hi);
+               }
 
+               return val;
+       } else {
+               struct tgsi_declaration_range range =
+                       get_array_range(bld_base, file, reg_index, 
reg_indirect);
+               LLVMValueRef index =
+                       emit_array_index(bld, reg_indirect, reg_index - 
range.First);
+               LLVMValueRef array =
+                       emit_array_fetch(bld_base, file, type, range, swizzle);
+               return LLVMBuildExtractElement(builder, array, index, "");
        }
-       return val;
 }
 
 static LLVMValueRef
@@ -283,26 +314,22 @@ store_value_to_array(struct lp_build_tgsi_context 
*bld_base,
                     unsigned reg_index,
                     const struct tgsi_ind_register *reg_indirect)
 {
+       struct radeon_llvm_context *ctx = radeon_llvm_context(bld_base);
        struct lp_build_tgsi_soa_context *bld = lp_soa_context(bld_base);
        struct gallivm_state *gallivm = bld_base->base.gallivm;
        LLVMBuilderRef builder = gallivm->builder;
-       struct tgsi_declaration_range range = get_array_range(bld_base, file, 
reg_index, reg_indirect);
-       LLVMValueRef index = emit_array_index(bld, reg_indirect, reg_index - 
range.First);
-       LLVMValueRef array = get_alloca_for_array(bld_base, file, reg_index, 
reg_indirect);
-
-       if (array) {
-               LLVMValueRef indices[2];
-               index = LLVMBuildMul(builder, index, 
lp_build_const_int32(gallivm, TGSI_NUM_CHANNELS), "");
-               index = LLVMBuildAdd(builder, index, 
lp_build_const_int32(gallivm, chan_index), "");
-               indices[0] = bld_base->uint_bld.zero;
-               indices[1] = index;
-               LLVMValueRef pointer = LLVMBuildGEP(builder, array, indices, 2, 
"");
-               LLVMBuildStore(builder, value, pointer);
+       LLVMValueRef ptr;
+
+       ptr = get_pointer_into_array(ctx, file, chan_index, reg_index, 
reg_indirect);
+       if (ptr) {
+               LLVMBuildStore(builder, value, ptr);
                return NULL;
        } else {
-               return LLVMBuildInsertElement(builder,
-                               emit_array_fetch(bld_base, file, 
TGSI_TYPE_FLOAT, range, chan_index),
-                               value, index, "");
+               struct tgsi_declaration_range range = get_array_range(bld_base, 
file, reg_index, reg_indirect);
+               LLVMValueRef index = emit_array_index(bld, reg_indirect, 
reg_index - range.First);
+               LLVMValueRef array =
+                       emit_array_fetch(bld_base, file, TGSI_TYPE_FLOAT, 
range, chan_index);
+               return LLVMBuildInsertElement(builder, array, value, index, "");
        }
 }
 

_______________________________________________
mesa-commit mailing list
[email protected]
https://lists.freedesktop.org/mailman/listinfo/mesa-commit

Reply via email to