[Mesa-dev] [PATCH 01/12] radeon/llvm: use bitcasts for integers

Vadim Girlin vadimgirlin at gmail.com
Mon May 7 10:08:43 PDT 2012


We're using float as default type, so basically for every instruction that
wants other types for dst/src operands we need to perform the bitcast
to/from default float. Currently bitcast produces no-op MOV instruction,
will be eliminated later.

Signed-off-by: Vadim Girlin <vadimgirlin at gmail.com>
---
 src/gallium/drivers/r600/r600_llvm.c               |    4 +-
 src/gallium/drivers/radeon/radeon_llvm.h           |   31 ++++++++++++++
 .../drivers/radeon/radeon_setup_tgsi_llvm.c        |   43 ++++++++++++++++++--
 3 files changed, 73 insertions(+), 5 deletions(-)

diff --git a/src/gallium/drivers/r600/r600_llvm.c b/src/gallium/drivers/r600/r600_llvm.c
index d467baf..a36760c 100644
--- a/src/gallium/drivers/r600/r600_llvm.c
+++ b/src/gallium/drivers/r600/r600_llvm.c
@@ -21,10 +21,12 @@ static LLVMValueRef llvm_fetch_const(
 	enum tgsi_opcode_type type,
 	unsigned swizzle)
 {
-	return lp_build_intrinsic_unary(bld_base->base.gallivm->builder,
+	LLVMValueRef cval = lp_build_intrinsic_unary(bld_base->base.gallivm->builder,
 		"llvm.AMDGPU.load.const", bld_base->base.elem_type,
 		lp_build_const_int32(bld_base->base.gallivm,
 		radeon_llvm_reg_index_soa(reg->Register.Index, swizzle)));
+
+	return bitcast(bld_base, type, cval);
 }
 
 static void llvm_load_input(
diff --git a/src/gallium/drivers/radeon/radeon_llvm.h b/src/gallium/drivers/radeon/radeon_llvm.h
index 9be7f90..39b1214 100644
--- a/src/gallium/drivers/radeon/radeon_llvm.h
+++ b/src/gallium/drivers/radeon/radeon_llvm.h
@@ -105,6 +105,37 @@ struct radeon_llvm_context {
 	struct gallivm_state gallivm;
 };
 
+static inline LLVMValueRef bitcast(
+		struct lp_build_tgsi_context * bld_base,
+		enum tgsi_opcode_type type,
+		LLVMValueRef value
+)
+{
+	LLVMBuilderRef builder = bld_base->base.gallivm->builder;
+	LLVMContextRef ctx = bld_base->base.gallivm->context;
+	LLVMTypeRef dst_type;
+
+	switch (type) {
+	case TGSI_TYPE_UNSIGNED:
+	case TGSI_TYPE_SIGNED:
+		dst_type = LLVMInt32TypeInContext(ctx);
+		break;
+	case TGSI_TYPE_UNTYPED:
+	case TGSI_TYPE_FLOAT:
+		dst_type = LLVMFloatTypeInContext(ctx);
+		break;
+	default:
+		dst_type = 0;
+		break;
+	}
+
+	if (dst_type)
+		return LLVMBuildBitCast(builder, value, dst_type, "");
+	else
+		return value;
+}
+
+
 void radeon_llvm_context_init(struct radeon_llvm_context * ctx);
 
 void radeon_llvm_dispose(struct radeon_llvm_context * ctx);
diff --git a/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c b/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c
index d3c493c..06af134 100644
--- a/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c
+++ b/src/gallium/drivers/radeon/radeon_setup_tgsi_llvm.c
@@ -113,8 +113,25 @@ emit_fetch_immediate(
 	enum tgsi_opcode_type type,
 	unsigned swizzle)
 {
+	LLVMTypeRef ctype;
+	LLVMContextRef ctx = bld_base->base.gallivm->context;
+
+	switch (type) {
+	case TGSI_TYPE_UNSIGNED:
+	case TGSI_TYPE_SIGNED:
+		ctype = LLVMInt32TypeInContext(ctx);
+		break;
+	case TGSI_TYPE_UNTYPED:
+	case TGSI_TYPE_FLOAT:
+		ctype = LLVMFloatTypeInContext(ctx);
+		break;
+	default:
+		ctype = 0;
+		break;
+	}
+
 	struct lp_build_tgsi_soa_context *bld = lp_soa_context(bld_base);
-	return bld->immediates[reg->Register.Index][swizzle];
+	return LLVMConstBitCast(bld->immediates[reg->Register.Index][swizzle], ctype);
 }
 
 static LLVMValueRef
@@ -135,7 +152,7 @@ emit_fetch_input(
 		return lp_build_gather_values(bld_base->base.gallivm, values,
 						TGSI_NUM_CHANNELS);
 	} else {
-		return ctx->inputs[radeon_llvm_reg_index_soa(reg->Register.Index, swizzle)];
+		return bitcast(bld_base, type, ctx->inputs[radeon_llvm_reg_index_soa(reg->Register.Index, swizzle)]);
 	}
 }
 
@@ -156,7 +173,7 @@ emit_fetch_temporary(
 	} else {
 		LLVMValueRef temp_ptr;
 		temp_ptr = lp_get_temp_ptr_soa(bld, reg->Register.Index, swizzle);
-		return LLVMBuildLoad(builder, temp_ptr, "");
+		return bitcast(bld_base,type,LLVMBuildLoad(builder, temp_ptr, ""));
 	}
 }
 
@@ -305,6 +322,9 @@ emit_store(
 		default:
 			return;
 		}
+
+		value = bitcast(bld_base, TGSI_TYPE_FLOAT, value);
+
 		LLVMBuildStore(builder, value, temp_ptr);
 	}
 }
@@ -502,6 +522,20 @@ static void tex_fetch_args(
 	emit_data->dst_type = LLVMVectorType(bld_base->base.elem_type, 4);
 }
 
+static void emit_immediate(struct lp_build_tgsi_context * bld_base,
+		const struct tgsi_full_immediate *imm)
+{
+	unsigned i;
+	struct radeon_llvm_context * ctx = radeon_llvm_context(bld_base);
+
+	for (i = 0; i < 4; ++i) {
+		ctx->soa.immediates[ctx->soa.num_immediates][i] =
+				LLVMConstInt(bld_base->uint_bld.elem_type, imm->u[i].Uint, false   );
+	}
+
+	ctx->soa.num_immediates++;
+}
+
 void radeon_llvm_context_init(struct radeon_llvm_context * ctx)
 {
 	struct lp_type type;
@@ -541,12 +575,13 @@ void radeon_llvm_context_init(struct radeon_llvm_context * ctx)
 
 	lp_build_context_init(&bld_base->base, &ctx->gallivm, type);
 	lp_build_context_init(&ctx->soa.bld_base.uint_bld, &ctx->gallivm, lp_uint_type(type));
+	lp_build_context_init(&ctx->soa.bld_base.int_bld, &ctx->gallivm, lp_int_type(type));
 
 	bld_base->soa = 1;
 	bld_base->emit_store = emit_store;
 	bld_base->emit_swizzle = emit_swizzle;
 	bld_base->emit_declaration = emit_declaration;
-	bld_base->emit_immediate = lp_emit_immediate_soa;
+	bld_base->emit_immediate = emit_immediate;
 
 	bld_base->emit_fetch_funcs[TGSI_FILE_IMMEDIATE] = emit_fetch_immediate;
 	bld_base->emit_fetch_funcs[TGSI_FILE_INPUT] = emit_fetch_input;
-- 
1.7.10.1



More information about the mesa-dev mailing list