[llvm-commits] CVS: gcc-3.4/gcc/llvm-expand.c
Chris Lattner
lattner at cs.uiuc.edu
Fri Feb 13 22:09:01 PST 2004
Changes in directory gcc-3.4/gcc:
llvm-expand.c updated: 1.10 -> 1.11
---
Log message:
Implement __builtin_frame_address/__builtin_return_address
Implement __builtin_memcpy/__builtin_bzero
---
Diffs of the changes: (+97 -17)
Index: gcc-3.4/gcc/llvm-expand.c
diff -u gcc-3.4/gcc/llvm-expand.c:1.10 gcc-3.4/gcc/llvm-expand.c:1.11
--- gcc-3.4/gcc/llvm-expand.c:1.10 Fri Feb 13 16:12:53 2004
+++ gcc-3.4/gcc/llvm-expand.c Fri Feb 13 22:07:54 2004
@@ -347,6 +347,34 @@
append_inst(Fn, I);
}
+/* EmitMemset - Fill the specified destination with SIZE bytes of VAL. If an
+ * alignment is known of the destination pointer and size, it may be specified.
+ */
+static void EmitMemset(llvm_function *Fn, llvm_value *DestPtr, llvm_value *Val,
+ llvm_value *Size, unsigned Alignment) {
+ static llvm_function *llvm_memset_fn = 0;
+ static llvm_type *size_tTy = 0;
+
+ llvm_instruction *I;
+ if (!llvm_memset_fn) {
+ llvm_type *FnTy = llvm_type_create_function(4, VoidTy);
+ FnTy->Elements[1] = VoidPtrTy;
+ FnTy->Elements[2] = UByteTy;
+ FnTy->Elements[3] = size_tTy = llvm_type_get_from_tree(size_type_node);
+ FnTy->Elements[4] = UIntTy;
+ FnTy = llvm_type_get_cannonical_function(FnTy);
+ llvm_memset_fn = CreateIntrinsicFnWithType("llvm.memset", FnTy);
+ }
+
+ I = llvm_instruction_new(VoidTy, "", O_Call, 5);
+ I->Operands[0] = G2V(llvm_memset_fn);
+ I->Operands[1] = cast_if_type_not_equal(Fn, DestPtr, VoidPtrTy);
+ I->Operands[2] = cast_if_type_not_equal(Fn, Val, UByteTy);
+ I->Operands[3] = cast_if_type_not_equal(Fn, Size, size_tTy);
+ I->Operands[4] = llvm_constant_new_integral(UIntTy, Alignment);
+ append_inst(Fn, I);
+}
+
/* llvm_copy_aggregate - Given two pointers to structures, copy *SrcPtr into
* *DestPtr, element by element.
@@ -3772,7 +3800,7 @@
* If the size of the array is too small (i.e. we didn't know the size,
* so we said it was zero), make it larger.
*/
- if (FieldOffset >= Size)
+ if ((unsigned)FieldOffset >= Size)
{
/*
* Increase the size of the LLVM array type.
@@ -4122,6 +4150,54 @@
return append_inst(Fn, create_alloca_inst("tmp", SByteTy, Size));
}
+static llvm_value *llvm_expand_builtin_return_frame_address(llvm_function *Fn,
+ tree arglist,
+ int isFrameAddress){
+ static llvm_function *BRAFn = 0, *BFAFn = 0;
+ llvm_function *TheFn;
+ llvm_value *Arg;
+ llvm_instruction *TheCall;
+ if (arglist == 0)
+ return llvm_constant_get_null(VoidPtrTy);
+ if (!host_integerp(TREE_VALUE(arglist), 1)) {
+ if (isFrameAddress)
+ error("invalid arg to `__builtin_frame_address'");
+ else
+ error("invalid arg to `__builtin_return_address'");
+ return llvm_constant_get_null(VoidPtrTy);
+ }
+
+ Arg = llvm_expand_expr(Fn, TREE_VALUE(arglist), 0);
+ assert(llvm_value_is_constant(Arg) && "No constant to builtinreturnaddress?");
+
+ if (!isFrameAddress) {
+ if (BRAFn == 0) {
+ llvm_type *FnTy = llvm_type_create_function(1, VoidPtrTy);
+ FnTy->Elements[1] = UIntTy;
+ FnTy = llvm_type_get_cannonical_function(FnTy);
+ BRAFn = CreateIntrinsicFnWithType("llvm.returnaddress", FnTy);
+ }
+
+ TheFn = BRAFn;
+ } else {
+ if (BFAFn == 0) {
+ llvm_type *FnTy = llvm_type_create_function(1, VoidPtrTy);
+ FnTy->Elements[1] = UIntTy;
+ FnTy = llvm_type_get_cannonical_function(FnTy);
+ BFAFn = CreateIntrinsicFnWithType("llvm.frameaddress", FnTy);
+ }
+
+ TheFn = BFAFn;
+ }
+
+ TheCall = llvm_instruction_new(VoidPtrTy, "tmp", O_Call, 2);
+ TheCall->Operands[0] = G2V(TheFn);
+ TheCall->Operands[1] = cast_if_type_not_equal(Fn, Arg, UIntTy);
+ append_inst(Fn, TheCall);
+ return D2V(TheCall);
+}
+
+
/* llvm_expand_builtin - This is patterned off of expand_builtin. */
static llvm_value *llvm_expand_builtin(llvm_function *Fn, tree exp,
llvm_value *DestLoc) {
@@ -4155,10 +4231,8 @@
case BUILT_IN_ATAN2:
case BUILT_IN_ATAN2F:
case BUILT_IN_ATAN2L:
- case BUILT_IN_MEMSET:
case BUILT_IN_MEMCMP:
case BUILT_IN_BCMP:
- case BUILT_IN_BZERO:
case BUILT_IN_INDEX:
case BUILT_IN_RINDEX:
case BUILT_IN_STRCHR:
@@ -4207,6 +4281,23 @@
case BUILT_IN_MEMCPY:
assert(DestLoc == 0 && "memcpy doesn't return aggregate!");
return llvm_expand_builtin_memcpy(Fn, arglist);
+
+ 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);
+ EmitMemset(Fn, Op0, llvm_constant_get_null(UByteTy), Op1, 0);
+ return 0;
+ }
+ case BUILT_IN_MEMSET: {
+ llvm_value *Op0, *Op1, *Op2;
+ Op0 = llvm_expand_expr(Fn, TREE_VALUE(arglist), 0);
+ arglist = TREE_CHAIN(arglist);
+ Op1 = llvm_expand_expr(Fn, TREE_VALUE(arglist), 0);
+ arglist = TREE_CHAIN(arglist);
+ Op2 = llvm_expand_expr(Fn, TREE_VALUE(arglist), 0);
+ EmitMemset(Fn, Op0, Op1, Op2, 0);
+ return Op0;
+ }
default:
break;
}
@@ -4332,11 +4423,12 @@
case BUILT_IN_ALLOCA:
return llvm_expand_builtin_alloca(Fn, arglist);
-#if 0
case BUILT_IN_FRAME_ADDRESS:
case BUILT_IN_RETURN_ADDRESS:
- return expand_builtin_frame_address (exp);
+ return llvm_expand_builtin_return_frame_address(Fn, arglist,
+ fcode == BUILT_IN_FRAME_ADDRESS);
+#if 0
/* Returns the address of the area where the structure is returned.
0 otherwise. */
case BUILT_IN_AGGREGATE_INCOMING_ADDRESS:
@@ -4456,18 +4548,6 @@
case BUILT_IN_RINDEX:
case BUILT_IN_STRRCHR:
target = expand_builtin_strrchr (arglist, target, mode);
- if (target)
- return target;
- break;
-
- case BUILT_IN_MEMSET:
- target = expand_builtin_memset (exp, target, mode);
- if (target)
- return target;
- break;
-
- case BUILT_IN_BZERO:
- target = expand_builtin_bzero (exp);
if (target)
return target;
break;
More information about the llvm-commits
mailing list