[llvm-commits] CVS: llvm-gcc/gcc/llvm-expand.c
Chris Lattner
lattner at cs.uiuc.edu
Fri May 6 19:17:01 PDT 2005
Changes in directory llvm-gcc/gcc:
llvm-expand.c updated: 1.96 -> 1.97
---
Log message:
Add support for bit counting builtins, implementing
Regression/CFrontend/2005-05-06-CountBuiltins.c
---
Diffs of the changes: (+62 -24)
llvm-expand.c | 86 +++++++++++++++++++++++++++++++++++++++++-----------------
1 files changed, 62 insertions(+), 24 deletions(-)
Index: llvm-gcc/gcc/llvm-expand.c
diff -u llvm-gcc/gcc/llvm-expand.c:1.96 llvm-gcc/gcc/llvm-expand.c:1.97
--- llvm-gcc/gcc/llvm-expand.c:1.96 Thu May 5 22:58:48 2005
+++ llvm-gcc/gcc/llvm-expand.c Fri May 6 21:16:47 2005
@@ -4525,6 +4525,55 @@
return D2V(TheCall);
}
+struct UnaryBuiltinList {
+ const char *Name;
+ llvm_type *Ty;
+ llvm_function *Fn;
+ struct UnaryBuiltinList *Next;
+};
+
+llvm_function *GetUnaryBuiltin(const char *Name, llvm_type *ArgTy) {
+ llvm_type *FnTy;
+
+ static struct UnaryBuiltinList *UnaryBuiltins = 0;
+ struct UnaryBuiltinList *BL;
+
+ /* See if we already created a proto for this. */
+ for (BL = UnaryBuiltins; BL; BL = BL->Next)
+ if (BL->Name == Name && BL->Ty == ArgTy)
+ return BL->Fn;
+
+ BL = (struct UnaryBuiltinList*)xmalloc(sizeof(struct UnaryBuiltinList));
+ BL->Name = Name;
+ BL->Ty = ArgTy;
+ BL->Next = UnaryBuiltins;
+ UnaryBuiltins = BL;
+
+ FnTy = llvm_type_create_function(1, ArgTy);
+ FnTy->Elements[1] = ArgTy;
+ FnTy = llvm_type_get_cannonical_function(FnTy);
+ return BL->Fn = CreateIntrinsicFnWithType(Name, FnTy);
+}
+
+static llvm_value *
+llvm_expand_builtin_unaryop(llvm_function *Fn, const llvm_type *DestTy,
+ tree arglist, const char *FnName) {
+ llvm_value *arg;
+ llvm_instruction *TheCall;
+ if (arglist == 0 || TREE_CHAIN(arglist) != 0) {
+ error("Invalid argument list to `%s'", FnName);
+ return llvm_constant_get_null(DestTy);
+ }
+
+ arg = llvm_expand_expr(Fn, TREE_VALUE(arglist), 0);
+
+ TheCall = llvm_instruction_new(arg->Ty, "tmp", O_Call, 2);
+ TheCall->Operands[0] = G2V(GetUnaryBuiltin(FnName, arg->Ty));
+ TheCall->Operands[1] = arg;
+ append_inst(Fn, TheCall);
+ return cast_if_type_not_equal(Fn, D2V(TheCall), DestTy);
+}
+
static void llvm_expand_builtin_prefetch(llvm_function *Fn, tree arglist) {
llvm_value *Ptr;
llvm_value *arg1 = llvm_constant_uint_0, *arg2 = llvm_constant_uint_0;
@@ -4590,6 +4639,9 @@
append_inst(Fn, Call);
}
+
+
+
/* llvm_expand_builtin - This is patterned off of expand_builtin. */
static llvm_value *llvm_expand_builtin(llvm_function *Fn, tree exp,
llvm_value *DestLoc) {
@@ -4597,6 +4649,7 @@
tree arglist = TREE_OPERAND (exp, 1);
enum built_in_function fcode = DECL_FUNCTION_CODE (fndecl);
llvm_type *DestTy = llvm_type_get_from_tree(TREE_TYPE(exp));
+ llvm_value *Op0, *Op1, *Op2;
if (DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD) {
fprintf(stderr, "UNKNOWN BUILTIN TYPE: \n");
@@ -4683,15 +4736,12 @@
return llvm_expand_builtin_memmove(Fn, arglist);
break;
-
- case BUILT_IN_BZERO: {
- llvm_value *Op0 = llvm_expand_expr(Fn, TREE_VALUE(arglist), 0);
- llvm_value *Op1 = llvm_expand_expr(Fn, TREE_VALUE(TREE_CHAIN(arglist)), 0);
+ case BUILT_IN_BZERO:
+ Op0 = llvm_expand_expr(Fn, TREE_VALUE(arglist), 0);
+ Op1 = llvm_expand_expr(Fn, TREE_VALUE(TREE_CHAIN(arglist)), 0);
EmitMemset(Fn, Op0, llvm_constant_get_null(UByteTy), Op1, 0);
return 0;
- }
- case BUILT_IN_MEMSET: {
- llvm_value *Op0, *Op1, *Op2;
+ case BUILT_IN_MEMSET:
Op0 = llvm_expand_expr(Fn, TREE_VALUE(arglist), 0);
arglist = TREE_CHAIN(arglist);
Op1 = llvm_expand_expr(Fn, TREE_VALUE(arglist), 0);
@@ -4699,7 +4749,6 @@
Op2 = llvm_expand_expr(Fn, TREE_VALUE(arglist), 0);
EmitMemset(Fn, Op0, Op1, Op2, 0);
return Op0;
- }
default:
break;
}
@@ -4849,34 +4898,23 @@
if (target)
return target;
break;
+#endif
case BUILT_IN_CLZ:
case BUILT_IN_CLZL:
case BUILT_IN_CLZLL:
- target = expand_builtin_unop (target_mode, arglist, target,
- subtarget, clz_optab);
- if (target)
- return target;
- break;
-
+ return llvm_expand_builtin_unaryop(Fn, DestTy, arglist, "llvm.ctlz");
case BUILT_IN_CTZ:
case BUILT_IN_CTZL:
case BUILT_IN_CTZLL:
- target = expand_builtin_unop (target_mode, arglist, target,
- subtarget, ctz_optab);
- if (target)
- return target;
- break;
+ return llvm_expand_builtin_unaryop(Fn, DestTy, arglist, "llvm.cttz");
case BUILT_IN_POPCOUNT:
case BUILT_IN_POPCOUNTL:
case BUILT_IN_POPCOUNTLL:
- target = expand_builtin_unop (target_mode, arglist, target,
- subtarget, popcount_optab);
- if (target)
- return target;
- break;
+ return llvm_expand_builtin_unaryop(Fn, DestTy, arglist, "llvm.ctpop");
+#if 0
case BUILT_IN_PARITY:
case BUILT_IN_PARITYL:
case BUILT_IN_PARITYLL:
More information about the llvm-commits
mailing list