From 627d6a6b044b3916996cb9f50ce7f911f2196565 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Fri, 7 Aug 2009 01:16:59 +0100 Subject: llvmpipe: Move intrinsic helpers to a separate module. --- src/gallium/drivers/llvmpipe/SConscript | 1 + src/gallium/drivers/llvmpipe/lp_bld_arit.c | 48 +++-------------- src/gallium/drivers/llvmpipe/lp_bld_intr.c | 87 ++++++++++++++++++++++++++++++ src/gallium/drivers/llvmpipe/lp_bld_intr.h | 51 ++++++++++++++++++ 4 files changed, 145 insertions(+), 42 deletions(-) create mode 100644 src/gallium/drivers/llvmpipe/lp_bld_intr.c create mode 100644 src/gallium/drivers/llvmpipe/lp_bld_intr.h (limited to 'src/gallium/drivers/llvmpipe') diff --git a/src/gallium/drivers/llvmpipe/SConscript b/src/gallium/drivers/llvmpipe/SConscript index 85d0a737fa..58e6a888e8 100644 --- a/src/gallium/drivers/llvmpipe/SConscript +++ b/src/gallium/drivers/llvmpipe/SConscript @@ -12,6 +12,7 @@ llvmpipe = env.ConvenienceLibrary( 'lp_fs_llvm.c', 'lp_bld_arit.c', 'lp_bld_const.c', + 'lp_bld_intr.c', 'lp_bld_pack.c', 'lp_bld_unpack.c', 'lp_bld_load.c', diff --git a/src/gallium/drivers/llvmpipe/lp_bld_arit.c b/src/gallium/drivers/llvmpipe/lp_bld_arit.c index 5dc1b7c968..461c01310c 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_arit.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_arit.c @@ -48,46 +48,10 @@ #include "util/u_debug.h" #include "lp_bld_type.h" +#include "lp_bld_intr.h" #include "lp_bld_arit.h" -static LLVMValueRef -lp_build_intrinsic_binary(LLVMBuilderRef builder, - const char *name, - LLVMValueRef a, - LLVMValueRef b) -{ - LLVMModuleRef module = LLVMGetGlobalParent(LLVMGetBasicBlockParent(LLVMGetInsertBlock(builder))); - LLVMValueRef function; - LLVMValueRef args[2]; - - function = LLVMGetNamedFunction(module, name); - if(!function) { - LLVMTypeRef type = LLVMTypeOf(a); - LLVMTypeRef arg_types[2]; - arg_types[0] = type; - arg_types[1] = type; - function = LLVMAddFunction(module, name, LLVMFunctionType(type, arg_types, 2, 0)); - LLVMSetFunctionCallConv(function, LLVMCCallConv); - LLVMSetLinkage(function, LLVMExternalLinkage); - } - assert(LLVMIsDeclaration(function)); - -#ifdef DEBUG - /* We shouldn't use only constants with intrinsics, as they won't be - * propagated by LLVM optimization passes. - */ - if(LLVMIsConstant(a) && LLVMIsConstant(b)) - debug_printf("warning: invoking intrinsic \"%s\" with constants\n"); -#endif - - args[0] = a; - args[1] = b; - - return LLVMBuildCall(builder, function, args, 2, ""); -} - - static LLVMValueRef lp_build_min_simple(struct lp_build_context *bld, LLVMValueRef a, @@ -116,7 +80,7 @@ lp_build_min_simple(struct lp_build_context *bld, #endif if(intrinsic) - return lp_build_intrinsic_binary(bld->builder, intrinsic, a, b); + return lp_build_intrinsic_binary(bld->builder, intrinsic, lp_build_vec_type(bld->type), a, b); if(type.floating) cond = LLVMBuildFCmp(bld->builder, LLVMRealULT, a, b, ""); @@ -154,7 +118,7 @@ lp_build_max_simple(struct lp_build_context *bld, #endif if(intrinsic) - return lp_build_intrinsic_binary(bld->builder, intrinsic, a, b); + return lp_build_intrinsic_binary(bld->builder, intrinsic, lp_build_vec_type(bld->type), a, b); if(type.floating) cond = LLVMBuildFCmp(bld->builder, LLVMRealULT, a, b, ""); @@ -221,7 +185,7 @@ lp_build_add(struct lp_build_context *bld, #endif if(intrinsic) - return lp_build_intrinsic_binary(bld->builder, intrinsic, a, b); + return lp_build_intrinsic_binary(bld->builder, intrinsic, lp_build_vec_type(bld->type), a, b); } if(LLVMIsConstant(a) && LLVMIsConstant(b)) @@ -268,7 +232,7 @@ lp_build_sub(struct lp_build_context *bld, #endif if(intrinsic) - return lp_build_intrinsic_binary(bld->builder, intrinsic, a, b); + return lp_build_intrinsic_binary(bld->builder, intrinsic, lp_build_vec_type(bld->type), a, b); } if(LLVMIsConstant(a) && LLVMIsConstant(b)) @@ -443,7 +407,7 @@ lp_build_mul(struct lp_build_context *bld, abh = lp_build_mul_u8n(bld->builder, ah, bh); /* PACKUSWB */ - ab = lp_build_intrinsic_binary(bld->builder, "llvm.x86.sse2.packuswb.128" , abl, abh); + ab = lp_build_intrinsic_binary(bld->builder, "llvm.x86.sse2.packuswb.128" , i16x8, abl, abh); /* NOP */ ab = LLVMBuildBitCast(bld->builder, ab, i8x16, ""); diff --git a/src/gallium/drivers/llvmpipe/lp_bld_intr.c b/src/gallium/drivers/llvmpipe/lp_bld_intr.c new file mode 100644 index 0000000000..c055f8f38c --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_bld_intr.c @@ -0,0 +1,87 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + + +/** + * @file + * Helper + * + * LLVM IR doesn't support all basic arithmetic operations we care about (most + * notably min/max and saturated operations), and it is often necessary to + * resort machine-specific intrinsics directly. The functions here hide all + * these implementation details from the other modules. + * + * We also do simple expressions simplification here. Reasons are: + * - it is very easy given we have all necessary information readily available + * - LLVM optimization passes fail to simplify several vector expressions + * - We often know value constraints which the optimization passes have no way + * of knowing, such as when source arguments are known to be in [0, 1] range. + * + * @author Jose Fonseca + */ + + +#include "util/u_debug.h" + +#include "lp_bld_intr.h" + + +LLVMValueRef +lp_build_intrinsic_binary(LLVMBuilderRef builder, + const char *name, + LLVMTypeRef ret_type, + LLVMValueRef a, + LLVMValueRef b) +{ + LLVMModuleRef module = LLVMGetGlobalParent(LLVMGetBasicBlockParent(LLVMGetInsertBlock(builder))); + LLVMValueRef function; + LLVMValueRef args[2]; + + function = LLVMGetNamedFunction(module, name); + if(!function) { + LLVMTypeRef arg_types[2]; + arg_types[0] = LLVMTypeOf(a); + arg_types[1] = LLVMTypeOf(b); + function = LLVMAddFunction(module, name, LLVMFunctionType(ret_type, arg_types, 2, 0)); + LLVMSetFunctionCallConv(function, LLVMCCallConv); + LLVMSetLinkage(function, LLVMExternalLinkage); + } + assert(LLVMIsDeclaration(function)); + +#ifdef DEBUG + /* We shouldn't use only constants with intrinsics, as they won't be + * propagated by LLVM optimization passes. + */ + if(LLVMIsConstant(a) && LLVMIsConstant(b)) + debug_printf("warning: invoking intrinsic \"%s\" with constants\n"); +#endif + + args[0] = a; + args[1] = b; + + return LLVMBuildCall(builder, function, args, 2, ""); +} diff --git a/src/gallium/drivers/llvmpipe/lp_bld_intr.h b/src/gallium/drivers/llvmpipe/lp_bld_intr.h new file mode 100644 index 0000000000..67f596c2b5 --- /dev/null +++ b/src/gallium/drivers/llvmpipe/lp_bld_intr.h @@ -0,0 +1,51 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * @file + * Helper arithmetic functions. + * + * @author Jose Fonseca + */ + + +#ifndef LP_BLD_INTR_H +#define LP_BLD_INTR_H + + +#include + + +LLVMValueRef +lp_build_intrinsic_binary(LLVMBuilderRef builder, + const char *name, + LLVMTypeRef ret_type, + LLVMValueRef a, + LLVMValueRef b); + + +#endif /* !LP_BLD_INTR_H */ -- cgit v1.2.3