[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