From: James Benton Date: Tue, 26 Jun 2012 14:00:14 +0000 (+0100) Subject: gallivm: Added a generic lp_build_print_value which prints a LLVMValueRef. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=789436f1e07a68b632937d9f2101efc5e68f7499;p=mesa.git 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 Reviewed-by: Brian Paul --- diff --git a/src/gallium/auxiliary/gallivm/lp_bld_printf.c b/src/gallium/auxiliary/gallivm/lp_bld_printf.c index 5e359ceaa20..16ef25a8a39 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_printf.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_printf.c @@ -34,151 +34,158 @@ #include "lp_bld_init.h" #include "lp_bld_const.h" #include "lp_bld_printf.h" +#include "lp_bld_type.h" -static int -lp_get_printf_arg_count(const char *fmt) -{ - int count =0; - const char *p = fmt; - int c; - - while ((c = *p++)) { - if (c != '%') - continue; - switch (*p) { - case '\0': - continue; - case '%': - p++; - continue; - case '.': - if (p[1] == '*' && p[2] == 's') { - count += 2; - p += 3; - continue; - } - /* 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. + * Generates LLVM IR to call debug_printf. */ -LLVMValueRef -lp_build_printf(struct gallivm_state *gallivm, const char *fmt, ...) +static LLVMValueRef +lp_build_print_args(struct gallivm_state* gallivm, + int argcount, + LLVMValueRef* args) { - 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; + LLVMTypeRef printf_type; + int i; - 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"); + assert(args); + assert(argcount > 0); + assert(LLVMTypeOf(args[0]) == LLVMPointerType(LLVMInt8TypeInContext(context), 0)); - params[0] = fmtarg; + /* Cast any float arguments to doubles as printf expects */ + for (i = 1; i < argcount; i++) { + LLVMTypeRef type = LLVMTypeOf(args[i]); - 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; + args[i] = LLVMBuildFPExt(builder, args[i], LLVMDoubleTypeInContext(context), ""); } - va_end(arglist); - return LLVMBuildCall(builder, func_printf, params, argcount + 1, ""); -} + 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 float[4] vector. + * Print a LLVM value of any type */ LLVMValueRef -lp_build_print_vec4(struct gallivm_state *gallivm, - const char *msg, LLVMValueRef vec) +lp_build_print_value(struct gallivm_state *gallivm, + const char *msg, + LLVMValueRef value) { LLVMBuilderRef builder = gallivm->builder; - char format[1000]; - LLVMValueRef x, y, z, w; + 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; + } - 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), ""); + 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); + } - util_snprintf(format, sizeof(format), "%s %%f %%f %%f %%f\n", msg); - return lp_build_printf(gallivm, format, x, y, z, w); + /* 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); } -/** - * Print a intt[4] vector. - */ -LLVMValueRef -lp_build_print_ivec4(struct gallivm_state *gallivm, - const char *msg, LLVMValueRef vec) +static int +lp_get_printf_arg_count(const char *fmt) { - 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), ""); + int count =0; + const char *p = fmt; + int c; - util_snprintf(format, sizeof(format), "%s %%i %%i %%i %%i\n", msg); - return lp_build_printf(gallivm, format, x, y, z, w); + while ((c = *p++)) { + if (c != '%') + continue; + switch (*p) { + case '\0': + continue; + case '%': + p++; + continue; + case '.': + if (p[1] == '*' && p[2] == 's') { + count += 2; + p += 3; + continue; + } + /* fallthrough */ + default: + count ++; + } + } + return count; } /** - * Print a uint8[16] vector. + * Generate LLVM IR for a c style printf */ LLVMValueRef -lp_build_print_uvec16(struct gallivm_state *gallivm, - const char *msg, LLVMValueRef vec) +lp_build_printf(struct gallivm_state *gallivm, + const char *fmt, ...) { - LLVMBuilderRef builder = gallivm->builder; - char format[1000]; - LLVMValueRef args[16]; + LLVMValueRef params[50]; + va_list arglist; + int argcount; int i; - for (i = 0; i < 16; ++i) { - args[i] = LLVMBuildExtractElement(builder, vec, lp_build_const_int32(gallivm, i), ""); - } + argcount = lp_get_printf_arg_count(fmt); + assert(Elements(params) >= argcount + 1); - util_snprintf(format, sizeof(format), "%s %%u %%u %%u %%u %%u %%u %%u %%u %%u %%u %%u %%u %%u %%u %%u %%u\n", msg); + va_start(arglist, fmt); + for (i = 1; i <= argcount; i++) { + params[i] = va_arg(arglist, LLVMValueRef); + } + va_end(arglist); - 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); } diff --git a/src/gallium/auxiliary/gallivm/lp_bld_printf.h b/src/gallium/auxiliary/gallivm/lp_bld_printf.h index 7a2b26d41f4..ede93cc834e 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_printf.h +++ b/src/gallium/auxiliary/gallivm/lp_bld_printf.h @@ -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