llvmpipe: More intrinsic helpers.

This commit is contained in:
José Fonseca
2009-08-10 23:22:40 +01:00
parent 50d77141e8
commit 36249348ed
2 changed files with 140 additions and 23 deletions
+98 -22
View File
@@ -50,6 +50,46 @@
#include "lp_bld_intr.h"
LLVMValueRef
lp_build_intrinsic(LLVMBuilderRef builder,
const char *name,
LLVMTypeRef ret_type,
LLVMValueRef *args,
unsigned num_args)
{
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;
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);
}
assert(LLVMIsDeclaration(function));
return LLVMBuildCall(builder, function, args, num_args, "");
}
LLVMValueRef
lp_build_intrinsic_unary(LLVMBuilderRef builder,
const char *name,
LLVMTypeRef ret_type,
LLVMValueRef a)
{
return lp_build_intrinsic(builder, name, ret_type, &a, 1);
}
LLVMValueRef
lp_build_intrinsic_binary(LLVMBuilderRef builder,
const char *name,
@@ -57,31 +97,67 @@ lp_build_intrinsic_binary(LLVMBuilderRef builder,
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, "");
return lp_build_intrinsic(builder, name, ret_type, args, 2);
}
LLVMValueRef
lp_build_intrinsic_map(LLVMBuilderRef builder,
const char *name,
LLVMTypeRef ret_type,
LLVMValueRef *args,
unsigned num_args)
{
LLVMTypeRef ret_elem_type = LLVMGetElementType(ret_type);
unsigned n = LLVMGetVectorSize(ret_type);
unsigned i, j;
LLVMValueRef res;
assert(num_args <= LP_MAX_FUNC_ARGS);
res = LLVMGetUndef(ret_type);
for(i = 0; i < n; ++i) {
LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, 0);
LLVMValueRef arg_elems[LP_MAX_FUNC_ARGS];
LLVMValueRef res_elem;
for(j = 0; j < num_args; ++j)
arg_elems[j] = LLVMBuildExtractElement(builder, args[j], index, "");
res_elem = lp_build_intrinsic(builder, name, ret_elem_type, arg_elems, num_args);
res = LLVMBuildInsertElement(builder, res, res_elem, index, "");
}
return res;
}
LLVMValueRef
lp_build_intrinsic_map_unary(LLVMBuilderRef builder,
const char *name,
LLVMTypeRef ret_type,
LLVMValueRef a)
{
return lp_build_intrinsic_map(builder, name, ret_type, &a, 1);
}
LLVMValueRef
lp_build_intrinsic_map_binary(LLVMBuilderRef builder,
const char *name,
LLVMTypeRef ret_type,
LLVMValueRef a,
LLVMValueRef b)
{
LLVMValueRef args[2];
args[0] = a;
args[1] = b;
return lp_build_intrinsic_map(builder, name, ret_type, args, 2);
}
+42 -1
View File
@@ -27,7 +27,7 @@
/**
* @file
* Helper arithmetic functions.
* Helper functions for calling intrinsics.
*
* @author Jose Fonseca <jfonseca@vmware.com>
*/
@@ -40,6 +40,24 @@
#include <llvm-c/Core.h>
#define LP_MAX_FUNC_ARGS 32
LLVMValueRef
lp_build_intrinsic(LLVMBuilderRef builder,
const char *name,
LLVMTypeRef ret_type,
LLVMValueRef *args,
unsigned num_args);
LLVMValueRef
lp_build_intrinsic_unary(LLVMBuilderRef builder,
const char *name,
LLVMTypeRef ret_type,
LLVMValueRef a);
LLVMValueRef
lp_build_intrinsic_binary(LLVMBuilderRef builder,
const char *name,
@@ -48,4 +66,27 @@ lp_build_intrinsic_binary(LLVMBuilderRef builder,
LLVMValueRef b);
LLVMValueRef
lp_build_intrinsic_map(LLVMBuilderRef builder,
const char *name,
LLVMTypeRef ret_type,
LLVMValueRef *args,
unsigned num_args);
LLVMValueRef
lp_build_intrinsic_map_unary(LLVMBuilderRef builder,
const char *name,
LLVMTypeRef ret_type,
LLVMValueRef a);
LLVMValueRef
lp_build_intrinsic_map_binary(LLVMBuilderRef builder,
const char *name,
LLVMTypeRef ret_type,
LLVMValueRef a,
LLVMValueRef b);
#endif /* !LP_BLD_INTR_H */