gallivm: Added a generic lp_build_print_value which prints a LLVMValueRef.

Updated lp_build_printf to share common code.
Removed specific lp_build_print_vecX.

Reviewed-by: José Fonseca <jfonseca@vmware.com>
Reviewed-by: Brian Paul <brianp@vmware.com>
This commit is contained in:
James Benton
2012-06-26 15:00:14 +01:00
committed by José Fonseca
parent 45fc069600
commit 789436f1e0
2 changed files with 123 additions and 123 deletions
+120 -113
View File
@@ -34,6 +34,104 @@
#include "lp_bld_init.h"
#include "lp_bld_const.h"
#include "lp_bld_printf.h"
#include "lp_bld_type.h"
/**
* Generates LLVM IR to call debug_printf.
*/
static LLVMValueRef
lp_build_print_args(struct gallivm_state* gallivm,
int argcount,
LLVMValueRef* args)
{
LLVMBuilderRef builder = gallivm->builder;
LLVMContextRef context = gallivm->context;
LLVMValueRef func_printf;
LLVMTypeRef printf_type;
int i;
assert(args);
assert(argcount > 0);
assert(LLVMTypeOf(args[0]) == LLVMPointerType(LLVMInt8TypeInContext(context), 0));
/* Cast any float arguments to doubles as printf expects */
for (i = 1; i < argcount; i++) {
LLVMTypeRef type = LLVMTypeOf(args[i]);
if (LLVMGetTypeKind(type) == LLVMFloatTypeKind)
args[i] = LLVMBuildFPExt(builder, args[i], LLVMDoubleTypeInContext(context), "");
}
printf_type = LLVMFunctionType(LLVMInt32TypeInContext(context), NULL, 0, 1);
func_printf = lp_build_const_int_pointer(gallivm, func_to_pointer((func_pointer)debug_printf));
func_printf = LLVMBuildBitCast(builder, func_printf, LLVMPointerType(printf_type, 0), "debug_printf");
return LLVMBuildCall(builder, func_printf, args, argcount, "");
}
/**
* Print a LLVM value of any type
*/
LLVMValueRef
lp_build_print_value(struct gallivm_state *gallivm,
const char *msg,
LLVMValueRef value)
{
LLVMBuilderRef builder = gallivm->builder;
LLVMTypeKind type_kind;
LLVMTypeRef type_ref;
LLVMValueRef params[2 + LP_MAX_VECTOR_LENGTH];
char type_fmt[4] = " %x";
char format[2 + 3 * LP_MAX_VECTOR_LENGTH + 2] = "%s";
unsigned length;
unsigned i;
type_ref = LLVMTypeOf(value);
type_kind = LLVMGetTypeKind(type_ref);
if (type_kind == LLVMVectorTypeKind) {
length = LLVMGetVectorSize(type_ref);
type_ref = LLVMGetElementType(type_ref);
type_kind = LLVMGetTypeKind(type_ref);
} else {
length = 1;
}
if (type_kind == LLVMFloatTypeKind || type_kind == LLVMDoubleTypeKind) {
type_fmt[2] = 'f';
} else if (type_kind == LLVMIntegerTypeKind) {
if (LLVMGetIntTypeWidth(type_ref) == 8) {
type_fmt[2] = 'u';
} else {
type_fmt[2] = 'i';
}
} else {
/* Unsupported type */
assert(0);
}
/* Create format string and arguments */
assert(strlen(format) + strlen(type_fmt) * length + 2 <= sizeof format);
params[1] = lp_build_const_string(gallivm, msg);
if (length == 1) {
util_strncat(format, type_fmt, sizeof format);
params[2] = value;
} else {
for (i = 0; i < length; ++i) {
util_strncat(format, type_fmt, sizeof format);
params[2 + i] = LLVMBuildExtractElement(builder, value, lp_build_const_int32(gallivm, i), "");
}
}
util_strncat(format, "\n", sizeof format);
params[0] = lp_build_const_string(gallivm, format);
return lp_build_print_args(gallivm, 2 + length, params);
}
static int
@@ -48,137 +146,46 @@ lp_get_printf_arg_count(const char *fmt)
continue;
switch (*p) {
case '\0':
continue;
continue;
case '%':
p++;
continue;
case '.':
if (p[1] == '*' && p[2] == 's') {
count += 2;
p += 3;
p++;
continue;
case '.':
if (p[1] == '*' && p[2] == 's') {
count += 2;
p += 3;
continue;
}
/* fallthrough */
default:
count ++;
}
/* fallthrough */
default:
count ++;
}
}
return count;
}
/**
* lp_build_printf.
*
* Build printf call in LLVM IR. The output goes to stdout.
* The additional variable arguments need to have type
* LLVMValueRef.
* Generate LLVM IR for a c style printf
*/
LLVMValueRef
lp_build_printf(struct gallivm_state *gallivm, const char *fmt, ...)
lp_build_printf(struct gallivm_state *gallivm,
const char *fmt, ...)
{
va_list arglist;
int i = 0;
int argcount = lp_get_printf_arg_count(fmt);
LLVMBuilderRef builder = gallivm->builder;
LLVMContextRef context = gallivm->context;
LLVMValueRef params[50];
LLVMValueRef fmtarg = lp_build_const_string(gallivm, fmt);
LLVMTypeRef printf_type;
LLVMValueRef func_printf;
va_list arglist;
int argcount;
int i;
argcount = lp_get_printf_arg_count(fmt);
assert(Elements(params) >= argcount + 1);
printf_type = LLVMFunctionType(LLVMIntTypeInContext(context, 32), NULL, 0, 1);
func_printf = lp_build_const_int_pointer(gallivm, func_to_pointer((func_pointer)debug_printf));
func_printf = LLVMBuildBitCast(gallivm->builder, func_printf,
LLVMPointerType(printf_type, 0),
"debug_printf");
params[0] = fmtarg;
va_start(arglist, fmt);
for (i = 1; i <= argcount; i++) {
LLVMValueRef val = va_arg(arglist, LLVMValueRef);
LLVMTypeRef type = LLVMTypeOf(val);
/* printf wants doubles, so lets convert so that
* we can actually print them */
if (LLVMGetTypeKind(type) == LLVMFloatTypeKind)
val = LLVMBuildFPExt(builder, val, LLVMDoubleTypeInContext(context), "");
params[i] = val;
params[i] = va_arg(arglist, LLVMValueRef);
}
va_end(arglist);
return LLVMBuildCall(builder, func_printf, params, argcount + 1, "");
}
/**
* Print a float[4] vector.
*/
LLVMValueRef
lp_build_print_vec4(struct gallivm_state *gallivm,
const char *msg, LLVMValueRef vec)
{
LLVMBuilderRef builder = gallivm->builder;
char format[1000];
LLVMValueRef x, y, z, w;
x = LLVMBuildExtractElement(builder, vec, lp_build_const_int32(gallivm, 0), "");
y = LLVMBuildExtractElement(builder, vec, lp_build_const_int32(gallivm, 1), "");
z = LLVMBuildExtractElement(builder, vec, lp_build_const_int32(gallivm, 2), "");
w = LLVMBuildExtractElement(builder, vec, lp_build_const_int32(gallivm, 3), "");
util_snprintf(format, sizeof(format), "%s %%f %%f %%f %%f\n", msg);
return lp_build_printf(gallivm, format, x, y, z, w);
}
/**
* Print a intt[4] vector.
*/
LLVMValueRef
lp_build_print_ivec4(struct gallivm_state *gallivm,
const char *msg, LLVMValueRef vec)
{
LLVMBuilderRef builder = gallivm->builder;
char format[1000];
LLVMValueRef x, y, z, w;
x = LLVMBuildExtractElement(builder, vec, lp_build_const_int32(gallivm, 0), "");
y = LLVMBuildExtractElement(builder, vec, lp_build_const_int32(gallivm, 1), "");
z = LLVMBuildExtractElement(builder, vec, lp_build_const_int32(gallivm, 2), "");
w = LLVMBuildExtractElement(builder, vec, lp_build_const_int32(gallivm, 3), "");
util_snprintf(format, sizeof(format), "%s %%i %%i %%i %%i\n", msg);
return lp_build_printf(gallivm, format, x, y, z, w);
}
/**
* Print a uint8[16] vector.
*/
LLVMValueRef
lp_build_print_uvec16(struct gallivm_state *gallivm,
const char *msg, LLVMValueRef vec)
{
LLVMBuilderRef builder = gallivm->builder;
char format[1000];
LLVMValueRef args[16];
int i;
for (i = 0; i < 16; ++i) {
args[i] = LLVMBuildExtractElement(builder, vec, lp_build_const_int32(gallivm, i), "");
}
util_snprintf(format, sizeof(format), "%s %%u %%u %%u %%u %%u %%u %%u %%u %%u %%u %%u %%u %%u %%u %%u %%u\n", msg);
return lp_build_printf(
gallivm, format,
args[ 0], args[ 1], args[ 2], args[ 3],
args[ 4], args[ 5], args[ 6], args[ 7],
args[ 8], args[ 9], args[10], args[11],
args[12], args[13], args[14], args[15]);
params[0] = lp_build_const_string(gallivm, fmt);
return lp_build_print_args(gallivm, argcount + 1, params);
}
+3 -10
View File
@@ -39,16 +39,9 @@ lp_build_printf(struct gallivm_state *gallivm,
const char *fmt, ...);
LLVMValueRef
lp_build_print_vec4(struct gallivm_state *gallivm,
const char *msg, LLVMValueRef vec);
LLVMValueRef
lp_build_print_ivec4(struct gallivm_state *gallivm,
const char *msg, LLVMValueRef vec);
LLVMValueRef
lp_build_print_uvec16(struct gallivm_state *gallivm,
const char *msg, LLVMValueRef vec);
lp_build_print_value(struct gallivm_state *gallivm,
const char *msg,
LLVMValueRef value);
#endif