[Mesa-dev] [PATCH] gallivm: deduplicate some indirect register address code

Zack Rusin zackr at vmware.com
Wed Nov 6 14:17:22 PST 2013


Looks good.

Reviewed-by: Zack Rusin <zackr at vmware.com>

----- Original Message -----
> From: Roland Scheidegger <sroland at vmware.com>
> 
> There's only one minor functional change, for immediates the pixel offsets
> are no longer added since the values are all the same for all elements in
> any case (it might be better if those weren't stored as soa vectors in the
> first place maybe).
> ---
>  src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c |  253
>  +++++++++--------------
>  1 file changed, 96 insertions(+), 157 deletions(-)
> 
> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
> b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
> index 75f6def..5f81066 100644
> --- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
> +++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
> @@ -898,6 +898,39 @@ stype_to_fetch(struct lp_build_tgsi_context * bld_base,
>  }
>  
>  static LLVMValueRef
> +get_soa_array_offsets(struct lp_build_context *uint_bld,
> +                      LLVMValueRef indirect_index,
> +                      unsigned chan_index,
> +                      boolean need_perelement_offset)
> +{
> +   struct gallivm_state *gallivm = uint_bld->gallivm;
> +   LLVMValueRef chan_vec =
> +      lp_build_const_int_vec(uint_bld->gallivm, uint_bld->type, chan_index);
> +   LLVMValueRef length_vec =
> +      lp_build_const_int_vec(gallivm, uint_bld->type,
> uint_bld->type.length);
> +   LLVMValueRef index_vec;
> +
> +   /* index_vec = (indirect_index * 4 + chan_index) * length + offsets */
> +   index_vec = lp_build_shl_imm(uint_bld, indirect_index, 2);
> +   index_vec = lp_build_add(uint_bld, index_vec, chan_vec);
> +   index_vec = lp_build_mul(uint_bld, index_vec, length_vec);
> +
> +   if (need_perelement_offset) {
> +      LLVMValueRef pixel_offsets;
> +      int i;
> +     /* build pixel offset vector: {0, 1, 2, 3, ...} */
> +      pixel_offsets = uint_bld->undef;
> +      for (i = 0; i < uint_bld->type.length; i++) {
> +         LLVMValueRef ii = lp_build_const_int32(gallivm, i);
> +         pixel_offsets = LLVMBuildInsertElement(gallivm->builder,
> pixel_offsets,
> +                                                ii, ii, "");
> +      }
> +      index_vec = lp_build_add(uint_bld, index_vec, pixel_offsets);
> +   }
> +   return index_vec;
> +}
> +
> +static LLVMValueRef
>  emit_fetch_constant(
>     struct lp_build_tgsi_context * bld_base,
>     const struct tgsi_full_src_register * reg,
> @@ -908,7 +941,6 @@ emit_fetch_constant(
>     struct gallivm_state *gallivm = bld_base->base.gallivm;
>     LLVMBuilderRef builder = gallivm->builder;
>     struct lp_build_context *uint_bld = &bld_base->uint_bld;
> -   LLVMValueRef indirect_index = NULL;
>     unsigned dimension = 0;
>     LLVMValueRef dimension_index;
>     LLVMValueRef consts_ptr;
> @@ -927,16 +959,15 @@ emit_fetch_constant(
>     consts_ptr = lp_build_array_get(gallivm, bld->consts_ptr,
>     dimension_index);
>  
>     if (reg->Register.Indirect) {
> +      LLVMValueRef indirect_index;
> +      LLVMValueRef swizzle_vec =
> +         lp_build_const_int_vec(gallivm, uint_bld->type, swizzle);
> +      LLVMValueRef index_vec;  /* index into the const buffer */
> +
>        indirect_index = get_indirect_index(bld,
>                                            reg->Register.File,
>                                            reg->Register.Index,
>                                            &reg->Indirect);
> -   }
> -
> -   if (reg->Register.Indirect) {
> -      LLVMValueRef swizzle_vec =
> -         lp_build_const_int_vec(bld->bld_base.base.gallivm, uint_bld->type,
> swizzle);
> -      LLVMValueRef index_vec;  /* index into the const buffer */
>  
>        /* index_vec = indirect_index * 4 + swizzle */
>        index_vec = lp_build_shl_imm(uint_bld, indirect_index, 2);
> @@ -949,7 +980,7 @@ emit_fetch_constant(
>        LLVMValueRef index;  /* index into the const buffer */
>        LLVMValueRef scalar, scalar_ptr;
>  
> -      index = lp_build_const_int32(gallivm, reg->Register.Index*4 +
> swizzle);
> +      index = lp_build_const_int32(gallivm, reg->Register.Index * 4 +
> swizzle);
>  
>        scalar_ptr = LLVMBuildGEP(builder, consts_ptr,
>                                  &index, 1, "");
> @@ -974,49 +1005,32 @@ emit_fetch_immediate(
>     struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
>     struct gallivm_state *gallivm = bld->bld_base.base.gallivm;
>     LLVMBuilderRef builder = gallivm->builder;
> -   struct lp_build_context *uint_bld = &bld_base->uint_bld;
> -   struct lp_build_context *float_bld = &bld_base->base;
>     LLVMValueRef res = NULL;
> -   LLVMValueRef indirect_index = NULL;
>  
>     if (reg->Register.Indirect) {
> +      LLVMValueRef indirect_index;
> +      LLVMValueRef index_vec;  /* index into the immediate register array */
> +      LLVMValueRef imms_array;
> +      LLVMTypeRef fptr_type;
> +
>        indirect_index = get_indirect_index(bld,
>                                            reg->Register.File,
>                                            reg->Register.Index,
>                                            &reg->Indirect);
> -   }
> -
> -   if (reg->Register.Indirect) {
> -      LLVMValueRef swizzle_vec =
> -         lp_build_const_int_vec(bld->bld_base.base.gallivm,
> -                                uint_bld->type, swizzle);
> -      LLVMValueRef length_vec =
> -         lp_build_const_int_vec(bld->bld_base.base.gallivm, uint_bld->type,
> -                                bld->bld_base.base.type.length);
> -      LLVMValueRef index_vec;  /* index into the immediate register array */
> -      LLVMValueRef imms_array;
> -      LLVMValueRef pixel_offsets;
> -      LLVMValueRef offsets[LP_MAX_VECTOR_LENGTH];
> -      LLVMTypeRef float_ptr_type;
> -      int i;
> -
> -      /* build pixel offset vector: {0, 1, 2, 3, ...} */
> -      for (i = 0; i < float_bld->type.length; i++) {
> -         offsets[i] = lp_build_const_int32(gallivm, i);
> -      }
> -      pixel_offsets = LLVMConstVector(offsets, float_bld->type.length);
> -
> -      /* index_vec = (indirect_index * 4 + swizzle) * length */
> -      index_vec = lp_build_shl_imm(uint_bld, indirect_index, 2);
> -      index_vec = lp_build_add(uint_bld, index_vec, swizzle_vec);
> -      index_vec = lp_build_mul(uint_bld, index_vec, length_vec);
> -      index_vec = lp_build_add(uint_bld, index_vec, pixel_offsets);
> +      /*
> +       * Unlike for other reg classes, adding pixel offsets is unnecessary -
> +       * immediates are stored as full vectors (FIXME??? - might be better
> +       * to store them the same as constants) but all elements are the same
> +       * in any case.
> +       */
> +      index_vec = get_soa_array_offsets(&bld_base->uint_bld,
> +                                        indirect_index,
> +                                        swizzle,
> +                                        FALSE);
>  
>        /* cast imms_array pointer to float* */
> -      float_ptr_type = LLVMPointerType(
> -         LLVMFloatTypeInContext(bld->bld_base.base.gallivm->context), 0);
> -      imms_array = LLVMBuildBitCast(builder, bld->imms_array,
> -                                    float_ptr_type, "");
> +      fptr_type = LLVMPointerType(LLVMFloatTypeInContext(gallivm->context),
> 0);
> +      imms_array = LLVMBuildBitCast(builder, bld->imms_array, fptr_type,
> "");
>  
>        /* Gather values from the immediate register array */
>        res = build_gather(&bld_base->base, imms_array, index_vec);
> @@ -1043,46 +1057,27 @@ emit_fetch_input(
>     struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
>     struct gallivm_state *gallivm = bld->bld_base.base.gallivm;
>     LLVMBuilderRef builder = gallivm->builder;
> -   struct lp_build_context *uint_bld = &bld_base->uint_bld;
> -   struct lp_build_context *float_bld = &bld_base->base;
> -   LLVMValueRef indirect_index = NULL;
>     LLVMValueRef res;
>  
>     if (reg->Register.Indirect) {
> +      LLVMValueRef indirect_index;
> +      LLVMValueRef index_vec;  /* index into the input reg array */
> +      LLVMValueRef inputs_array;
> +      LLVMTypeRef fptr_type;
> +
>        indirect_index = get_indirect_index(bld,
>                                            reg->Register.File,
>                                            reg->Register.Index,
>                                            &reg->Indirect);
> -   }
>  
> -   if (reg->Register.Indirect) {
> -      LLVMValueRef swizzle_vec =
> -         lp_build_const_int_vec(gallivm, uint_bld->type, swizzle);
> -      LLVMValueRef length_vec =
> -         lp_build_const_int_vec(gallivm, uint_bld->type,
> bld->bld_base.base.type.length);
> -      LLVMValueRef index_vec;  /* index into the input reg array */
> -      LLVMValueRef inputs_array;
> -      LLVMValueRef pixel_offsets;
> -      LLVMValueRef offsets[LP_MAX_VECTOR_LENGTH];
> -      LLVMTypeRef float_ptr_type;
> -      int i;
> -
> -      /* build pixel offset vector: {0, 1, 2, 3, ...} */
> -      for (i = 0; i < float_bld->type.length; i++) {
> -         offsets[i] = lp_build_const_int32(gallivm, i);
> -      }
> -      pixel_offsets = LLVMConstVector(offsets, float_bld->type.length);
> -
> -      /* index_vec = (indirect_index * 4 + swizzle) * length */
> -      index_vec = lp_build_shl_imm(uint_bld, indirect_index, 2);
> -      index_vec = lp_build_add(uint_bld, index_vec, swizzle_vec);
> -      index_vec = lp_build_mul(uint_bld, index_vec, length_vec);
> -      index_vec = lp_build_add(uint_bld, index_vec, pixel_offsets);
> +      index_vec = get_soa_array_offsets(&bld_base->uint_bld,
> +                                        indirect_index,
> +                                        swizzle,
> +                                        TRUE);
>  
>        /* cast inputs_array pointer to float* */
> -      float_ptr_type =
> LLVMPointerType(LLVMFloatTypeInContext(gallivm->context), 0);
> -      inputs_array = LLVMBuildBitCast(builder, bld->inputs_array,
> -                                      float_ptr_type, "");
> +      fptr_type = LLVMPointerType(LLVMFloatTypeInContext(gallivm->context),
> 0);
> +      inputs_array = LLVMBuildBitCast(builder, bld->inputs_array, fptr_type,
> "");
>  
>        /* Gather values from the input register array */
>        res = build_gather(&bld_base->base, inputs_array, index_vec);
> @@ -1172,47 +1167,27 @@ emit_fetch_temporary(
>     struct lp_build_tgsi_soa_context * bld = lp_soa_context(bld_base);
>     struct gallivm_state *gallivm = bld->bld_base.base.gallivm;
>     LLVMBuilderRef builder = gallivm->builder;
> -   struct lp_build_context *uint_bld = &bld_base->uint_bld;
> -   struct lp_build_context *float_bld = &bld_base->base;
> -   LLVMValueRef indirect_index = NULL;
>     LLVMValueRef res;
>  
>     if (reg->Register.Indirect) {
> +      LLVMValueRef indirect_index;
> +      LLVMValueRef index_vec;  /* index into the temp reg array */
> +      LLVMValueRef temps_array;
> +      LLVMTypeRef fptr_type;
> +
>        indirect_index = get_indirect_index(bld,
>                                            reg->Register.File,
>                                            reg->Register.Index,
>                                            &reg->Indirect);
> -   }
>  
> -   if (reg->Register.Indirect) {
> -      LLVMValueRef swizzle_vec =
> -         lp_build_const_int_vec(bld->bld_base.base.gallivm, uint_bld->type,
> swizzle);
> -      LLVMValueRef length_vec =
> -         lp_build_const_int_vec(bld->bld_base.base.gallivm, uint_bld->type,
> -                                bld->bld_base.base.type.length);
> -      LLVMValueRef index_vec;  /* index into the temp reg array */
> -      LLVMValueRef temps_array;
> -      LLVMValueRef pixel_offsets;
> -      LLVMValueRef offsets[LP_MAX_VECTOR_LENGTH];
> -      LLVMTypeRef float_ptr_type;
> -      int i;
> -
> -      /* build pixel offset vector: {0, 1, 2, 3, ...} */
> -      for (i = 0; i < float_bld->type.length; i++) {
> -         offsets[i] = lp_build_const_int32(gallivm, i);
> -      }
> -      pixel_offsets = LLVMConstVector(offsets, float_bld->type.length);
> -
> -      /* index_vec = (indirect_index * 4 + swizzle) * length */
> -      index_vec = lp_build_shl_imm(uint_bld, indirect_index, 2);
> -      index_vec = lp_build_add(uint_bld, index_vec, swizzle_vec);
> -      index_vec = lp_build_mul(uint_bld, index_vec, length_vec);
> -      index_vec = lp_build_add(uint_bld, index_vec, pixel_offsets);
> +      index_vec = get_soa_array_offsets(&bld_base->uint_bld,
> +                                        indirect_index,
> +                                        swizzle,
> +                                        TRUE);
>  
>        /* cast temps_array pointer to float* */
> -      float_ptr_type =
> LLVMPointerType(LLVMFloatTypeInContext(bld->bld_base.base.gallivm->context),
> 0);
> -      temps_array = LLVMBuildBitCast(builder, bld->temps_array,
> -                                     float_ptr_type, "");
> +      fptr_type = LLVMPointerType(LLVMFloatTypeInContext(gallivm->context),
> 0);
> +      temps_array = LLVMBuildBitCast(builder, bld->temps_array, fptr_type,
> "");
>  
>        /* Gather values from the temporary register array */
>        res = build_gather(&bld_base->base, temps_array, index_vec);
> @@ -1374,6 +1349,7 @@ emit_fetch_predicate(
>     }
>  }
>  
> +
>  /**
>   * Register store.
>   */
> @@ -1392,7 +1368,6 @@ emit_store_chan(
>     const struct tgsi_full_dst_register *reg = &inst->Dst[index];
>     struct lp_build_context *float_bld = &bld_base->base;
>     struct lp_build_context *int_bld = &bld_base->int_bld;
> -   struct lp_build_context *uint_bld = &bld_base->uint_bld;
>     LLVMValueRef indirect_index = NULL;
>     enum tgsi_opcode_type dtype =
>     tgsi_opcode_infer_dst_type(inst->Instruction.Opcode);
>  
> @@ -1446,36 +1421,19 @@ emit_store_chan(
>        value = LLVMBuildBitCast(builder, value, float_bld->vec_type, "");
>  
>        if (reg->Register.Indirect) {
> -         LLVMValueRef chan_vec =
> -            lp_build_const_int_vec(gallivm, uint_bld->type, chan_index);
> -         LLVMValueRef length_vec =
> -            lp_build_const_int_vec(gallivm, uint_bld->type,
> float_bld->type.length);
> -         LLVMValueRef index_vec;  /* indexes into the temp registers */
> +         LLVMValueRef index_vec;  /* indexes into the output registers */
>           LLVMValueRef outputs_array;
> -         LLVMValueRef pixel_offsets;
> -         LLVMTypeRef float_ptr_type;
> -         int i;
> -
> -         /* build pixel offset vector: {0, 1, 2, 3, ...} */
> -         pixel_offsets = uint_bld->undef;
> -         for (i = 0; i < float_bld->type.length; i++) {
> -            LLVMValueRef ii = lp_build_const_int32(gallivm, i);
> -            pixel_offsets = LLVMBuildInsertElement(builder, pixel_offsets,
> -                                                   ii, ii, "");
> -         }
> +         LLVMTypeRef fptr_type;
>  
> -         /* index_vec = (indirect_index * 4 + chan_index) * length + offsets
> */
> -         index_vec = lp_build_shl_imm(uint_bld, indirect_index, 2);
> -         index_vec = lp_build_add(uint_bld, index_vec, chan_vec);
> -         index_vec = lp_build_mul(uint_bld, index_vec, length_vec);
> -         index_vec = lp_build_add(uint_bld, index_vec, pixel_offsets);
> +         index_vec = get_soa_array_offsets(&bld_base->uint_bld,
> +                                           indirect_index,
> +                                           chan_index,
> +                                           TRUE);
>  
> -         float_ptr_type =
> -            LLVMPointerType(LLVMFloatTypeInContext(gallivm->context), 0);
> -         outputs_array = LLVMBuildBitCast(builder, bld->outputs_array,
> -                                          float_ptr_type, "");
> +         fptr_type =
> LLVMPointerType(LLVMFloatTypeInContext(gallivm->context), 0);
> +         outputs_array = LLVMBuildBitCast(builder, bld->outputs_array,
> fptr_type, "");
>  
> -         /* Scatter store values into temp registers */
> +         /* Scatter store values into output registers */
>           emit_mask_scatter(bld, outputs_array, index_vec, value,
>                             &bld->exec_mask, pred);
>        }
> @@ -1491,35 +1449,17 @@ emit_store_chan(
>        value = LLVMBuildBitCast(builder, value, float_bld->vec_type, "");
>  
>        if (reg->Register.Indirect) {
> -         LLVMValueRef chan_vec =
> -            lp_build_const_int_vec(gallivm, uint_bld->type, chan_index);
> -         LLVMValueRef length_vec =
> -            lp_build_const_int_vec(gallivm, uint_bld->type,
> -                                   float_bld->type.length);
>           LLVMValueRef index_vec;  /* indexes into the temp registers */
>           LLVMValueRef temps_array;
> -         LLVMValueRef pixel_offsets;
> -         LLVMTypeRef float_ptr_type;
> -         int i;
> -
> -         /* build pixel offset vector: {0, 1, 2, 3, ...} */
> -         pixel_offsets = uint_bld->undef;
> -         for (i = 0; i < float_bld->type.length; i++) {
> -            LLVMValueRef ii = lp_build_const_int32(gallivm, i);
> -            pixel_offsets = LLVMBuildInsertElement(builder, pixel_offsets,
> -                                                   ii, ii, "");
> -         }
> +         LLVMTypeRef fptr_type;
>  
> -         /* index_vec = (indirect_index * 4 + chan_index) * length + offsets
> */
> -         index_vec = lp_build_shl_imm(uint_bld, indirect_index, 2);
> -         index_vec = lp_build_add(uint_bld, index_vec, chan_vec);
> -         index_vec = lp_build_mul(uint_bld, index_vec, length_vec);
> -         index_vec = lp_build_add(uint_bld, index_vec, pixel_offsets);
> +         index_vec = get_soa_array_offsets(&bld_base->uint_bld,
> +                                           indirect_index,
> +                                           chan_index,
> +                                           TRUE);
>  
> -         float_ptr_type =
> -            LLVMPointerType(LLVMFloatTypeInContext(gallivm->context), 0);
> -         temps_array = LLVMBuildBitCast(builder, bld->temps_array,
> -                                        float_ptr_type, "");
> +         fptr_type =
> LLVMPointerType(LLVMFloatTypeInContext(gallivm->context), 0);
> +         temps_array = LLVMBuildBitCast(builder, bld->temps_array,
> fptr_type, "");
>  
>           /* Scatter store values into temp registers */
>           emit_mask_scatter(bld, temps_array, index_vec, value,
> @@ -1527,8 +1467,7 @@ emit_store_chan(
>        }
>        else {
>           LLVMValueRef temp_ptr;
> -         temp_ptr = lp_get_temp_ptr_soa(bld, reg->Register.Index,
> -                                        chan_index);
> +         temp_ptr = lp_get_temp_ptr_soa(bld, reg->Register.Index,
> chan_index);
>           lp_exec_mask_store(&bld->exec_mask, float_bld, pred, value,
>           temp_ptr);
>        }
>        break;
> --
> 1.7.9.5
> 


More information about the mesa-dev mailing list