X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fgallium%2Fdrivers%2Fllvmpipe%2Flp_bld_intr.c;h=9895749d5686978930db5537b2cf0e7be64b0d38;hb=caf2cf884cb32883e9af07dbe36ca9648bae1821;hp=a2051211b7a13780cee70150c22d7101db207b11;hpb=36249348ed6dfae63ef2b81e6db88c975a801f2a;p=mesa.git diff --git a/src/gallium/drivers/llvmpipe/lp_bld_intr.c b/src/gallium/drivers/llvmpipe/lp_bld_intr.c index a2051211b7a..9895749d568 100644 --- a/src/gallium/drivers/llvmpipe/lp_bld_intr.c +++ b/src/gallium/drivers/llvmpipe/lp_bld_intr.c @@ -28,18 +28,17 @@ /** * @file - * Helper + * Helpers for emiting intrinsic calls. * - * 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. + * LLVM vanilla IR doesn't represent all basic arithmetic operations we care + * about, and it is often necessary to resort target-specific intrinsics for + * performance, convenience. * - * 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. + * Ideally we would like to stay away from target specific intrinsics and + * move all the instruction selection logic into upstream LLVM where it belongs. + * + * These functions are also used for calling C functions provided by us from + * generated LLVM code. * * @author Jose Fonseca */ @@ -50,6 +49,37 @@ #include "lp_bld_intr.h" +LLVMValueRef +lp_declare_intrinsic(LLVMModuleRef module, + const char *name, + LLVMTypeRef ret_type, + LLVMTypeRef *arg_types, + unsigned num_args) +{ + LLVMTypeRef function_type; + LLVMValueRef function; + + assert(!LLVMGetNamedFunction(module, name)); + + function_type = LLVMFunctionType(ret_type, arg_types, num_args, 0); + function = LLVMAddFunction(module, name, function_type); + + LLVMSetFunctionCallConv(function, LLVMCCallConv); + LLVMSetLinkage(function, LLVMExternalLinkage); + + assert(LLVMIsDeclaration(function)); + + if(name[0] == 'l' && + name[1] == 'l' && + name[2] == 'v' && + name[3] == 'm' && + name[4] == '.') + assert(LLVMGetIntrinsicID(function)); + + return function; +} + + LLVMValueRef lp_build_intrinsic(LLVMBuilderRef builder, const char *name, @@ -60,21 +90,20 @@ lp_build_intrinsic(LLVMBuilderRef builder, LLVMModuleRef module = LLVMGetGlobalParent(LLVMGetBasicBlockParent(LLVMGetInsertBlock(builder))); LLVMValueRef function; - assert(num_args <= LP_MAX_FUNC_ARGS); - function = LLVMGetNamedFunction(module, name); if(!function) { LLVMTypeRef arg_types[LP_MAX_FUNC_ARGS]; unsigned i; + + assert(num_args <= LP_MAX_FUNC_ARGS); + for(i = 0; i < num_args; ++i) { assert(args[i]); arg_types[i] = LLVMTypeOf(args[i]); } - function = LLVMAddFunction(module, name, LLVMFunctionType(ret_type, arg_types, num_args, 0)); - LLVMSetFunctionCallConv(function, LLVMCCallConv); - LLVMSetLinkage(function, LLVMExternalLinkage); + + function = lp_declare_intrinsic(module, name, ret_type, arg_types, num_args); } - assert(LLVMIsDeclaration(function)); return LLVMBuildCall(builder, function, args, num_args, ""); }