gallivm: Refactor lp_build_broadcast(_scalar) to share code.
authorJosé Fonseca <jfonseca@vmware.com>
Thu, 28 Jun 2012 17:07:10 +0000 (18:07 +0100)
committerJosé Fonseca <jfonseca@vmware.com>
Thu, 28 Jun 2012 19:20:34 +0000 (20:20 +0100)
Doesn't really change the generated assembly, but produces more compact IR,
and of course, makes code more consistent.

Reviewed-by: Brian Paul <brianp@vmware.com>
src/gallium/auxiliary/gallivm/lp_bld_swizzle.c

index 7169360..5d44068 100644 (file)
@@ -47,14 +47,34 @@ lp_build_broadcast(struct gallivm_state *gallivm,
                    LLVMTypeRef vec_type,
                    LLVMValueRef scalar)
 {
-   const unsigned n = LLVMGetVectorSize(vec_type);
    LLVMValueRef res;
-   unsigned i;
 
-   res = LLVMGetUndef(vec_type);
-   for(i = 0; i < n; ++i) {
-      LLVMValueRef index = lp_build_const_int32(gallivm, i);
-      res = LLVMBuildInsertElement(gallivm->builder, res, scalar, index, "");
+   if (LLVMGetTypeKind(vec_type) != LLVMVectorTypeKind) {
+      /* scalar */
+      assert(vec_type == LLVMTypeOf(scalar));
+      res = scalar;
+   } else {
+      LLVMBuilderRef builder = gallivm->builder;
+      const unsigned length = LLVMGetVectorSize(vec_type);
+      LLVMValueRef undef = LLVMGetUndef(vec_type);
+      LLVMTypeRef i32_type = LLVMInt32TypeInContext(gallivm->context);
+
+      assert(LLVMGetElementType(vec_type) == LLVMTypeOf(scalar));
+
+      if (HAVE_LLVM >= 0x207) {
+         /* The shuffle vector is always made of int32 elements */
+         LLVMTypeRef i32_vec_type = LLVMVectorType(i32_type, length);
+         res = LLVMBuildInsertElement(builder, undef, scalar, LLVMConstNull(i32_type), "");
+         res = LLVMBuildShuffleVector(builder, res, undef, LLVMConstNull(i32_vec_type), "");
+      } else {
+         /* XXX: The above path provokes a bug in LLVM 2.6 */
+         unsigned i;
+         res = undef;
+         for(i = 0; i < length; ++i) {
+            LLVMValueRef index = lp_build_const_int32(gallivm, i);
+            res = LLVMBuildInsertElement(builder, res, scalar, index, "");
+         }
+      }
    }
 
    return res;
@@ -68,37 +88,9 @@ LLVMValueRef
 lp_build_broadcast_scalar(struct lp_build_context *bld,
                           LLVMValueRef scalar)
 {
-   LLVMBuilderRef builder = bld->gallivm->builder;
-   const struct lp_type type = bld->type;
-
-   assert(lp_check_elem_type(type, LLVMTypeOf(scalar)));
-
-   if (type.length == 1) {
-      return scalar;
-   }
-   else {
-      LLVMValueRef res;
+   assert(lp_check_elem_type(bld->type, LLVMTypeOf(scalar)));
 
-#if HAVE_LLVM >= 0x207
-      /* The shuffle vector is always made of int32 elements */
-      struct lp_type i32_vec_type = lp_type_int_vec(32);
-      i32_vec_type.length = type.length;
-
-      res = LLVMBuildInsertElement(builder, bld->undef, scalar,
-                                   lp_build_const_int32(bld->gallivm, 0), "");
-      res = LLVMBuildShuffleVector(builder, res, bld->undef,
-                                   lp_build_const_int_vec(bld->gallivm, i32_vec_type, 0), "");
-#else
-      /* XXX: The above path provokes a bug in LLVM 2.6 */
-      unsigned i;
-      res = bld->undef;
-      for(i = 0; i < type.length; ++i) {
-         LLVMValueRef index = lp_build_const_int32(bld->gallivm, i);
-         res = LLVMBuildInsertElement(builder, res, scalar, index, "");
-      }
-#endif
-      return res;
-   }
+   return lp_build_broadcast(bld->gallivm, bld->vec_type, scalar);
 }