[llvm-commits] [llvm-gcc-4.2] r55017 - in /llvm-gcc-4.2/trunk/gcc: llvm-convert.cpp llvm-internal.h
Dale Johannesen
dalej at apple.com
Tue Aug 19 15:47:32 PDT 2008
Author: johannes
Date: Tue Aug 19 17:47:32 2008
New Revision: 55017
URL: http://llvm.org/viewvc/llvm-project?rev=55017&view=rev
Log:
Some refactoring of atomic builtins code.
Add __sync_lock_release (sizes 1, 2, 4, 8).
Modified:
llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
llvm-gcc-4.2/trunk/gcc/llvm-internal.h
Modified: llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp?rev=55017&r1=55016&r2=55017&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Tue Aug 19 17:47:32 2008
@@ -4275,6 +4275,27 @@
TargetBuiltinCache.clear();
}
+Value *
+TreeToLLVM::BuildBinaryAtomicBuiltin(tree exp, Intrinsic::ID id) {
+ const Type *ResultTy = ConvertType(TREE_TYPE(exp));
+ tree arglist = TREE_OPERAND(exp, 1);
+ Value* C[2] = {
+ Emit(TREE_VALUE(arglist), 0),
+ Emit(TREE_VALUE(TREE_CHAIN(arglist)), 0)
+ };
+ const Type* Ty[2];
+ Ty[0] = ResultTy;
+ Ty[1] = PointerType::getUnqual(ResultTy);
+ C[0] = Builder.CreateBitCast(C[0], Ty[1]);
+ C[1] = Builder.CreateIntCast(C[1], Ty[0], "cast");
+ Value *Result =
+ Builder.CreateCall(Intrinsic::getDeclaration(TheModule, id,
+ Ty, 2),
+ C, C + 2);
+ Result = Builder.CreateIntToPtr(Result, ResultTy);
+ return Result;
+}
+
/// EmitBuiltinCall - exp is a call to fndecl, a builtin function. Try to emit
/// the call in a special way, setting Result to the scalar result if necessary.
/// If we can't handle the builtin, return false, otherwise return true.
@@ -4573,23 +4594,7 @@
case BUILT_IN_FETCH_AND_ADD_4:
case BUILT_IN_FETCH_AND_ADD_8:
case BUILT_IN_FETCH_AND_ADD_16: {
- const Type *ResultTy = ConvertType(TREE_TYPE(exp));
- tree arglist = TREE_OPERAND(exp, 1);
- Value* C[2] = {
- Emit(TREE_VALUE(arglist), 0),
- Emit(TREE_VALUE(TREE_CHAIN(arglist)), 0)
- };
- const Type* Ty[2];
- Ty[0] = ResultTy;
- Ty[1] = PointerType::getUnqual(ResultTy);
- C[0] = Builder.CreateBitCast(C[0], Ty[1]);
- C[1] = Builder.CreateIntCast(C[1], Ty[0], "cast");
- Result =
- Builder.CreateCall(Intrinsic::getDeclaration(TheModule,
- Intrinsic::atomic_load_add,
- Ty, 2),
- C, C + 2);
- Result = Builder.CreateIntToPtr(Result, ResultTy);
+ Result = BuildBinaryAtomicBuiltin(exp, Intrinsic::atomic_load_add);
return true;
}
case BUILT_IN_FETCH_AND_SUB_1:
@@ -4597,23 +4602,7 @@
case BUILT_IN_FETCH_AND_SUB_4:
case BUILT_IN_FETCH_AND_SUB_8:
case BUILT_IN_FETCH_AND_SUB_16: {
- const Type *ResultTy = ConvertType(TREE_TYPE(exp));
- tree arglist = TREE_OPERAND(exp, 1);
- Value* C[2] = {
- Emit(TREE_VALUE(arglist), 0),
- Emit(TREE_VALUE(TREE_CHAIN(arglist)), 0)
- };
- const Type* Ty[2];
- Ty[0] = ResultTy;
- Ty[1] = PointerType::getUnqual(ResultTy);
- C[0] = Builder.CreateBitCast(C[0], Ty[1]);
- C[1] = Builder.CreateIntCast(C[1], Ty[0], "cast");
- Result =
- Builder.CreateCall(Intrinsic::getDeclaration(TheModule,
- Intrinsic::atomic_load_sub,
- Ty, 2),
- C, C + 2);
- Result = Builder.CreateIntToPtr(Result, ResultTy);
+ Result = BuildBinaryAtomicBuiltin(exp, Intrinsic::atomic_load_sub);
return true;
}
case BUILT_IN_FETCH_AND_OR_1:
@@ -4621,23 +4610,7 @@
case BUILT_IN_FETCH_AND_OR_4:
case BUILT_IN_FETCH_AND_OR_8:
case BUILT_IN_FETCH_AND_OR_16: {
- const Type *ResultTy = ConvertType(TREE_TYPE(exp));
- tree arglist = TREE_OPERAND(exp, 1);
- Value* C[2] = {
- Emit(TREE_VALUE(arglist), 0),
- Emit(TREE_VALUE(TREE_CHAIN(arglist)), 0)
- };
- const Type* Ty[2];
- Ty[0] = ResultTy;
- Ty[1] = PointerType::getUnqual(ResultTy);
- C[0] = Builder.CreateBitCast(C[0], Ty[1]);
- C[1] = Builder.CreateIntCast(C[1], Ty[0], "cast");
- Result =
- Builder.CreateCall(Intrinsic::getDeclaration(TheModule,
- Intrinsic::atomic_load_or,
- Ty, 2),
- C, C + 2);
- Result = Builder.CreateIntToPtr(Result, ResultTy);
+ Result = BuildBinaryAtomicBuiltin(exp, Intrinsic::atomic_load_or);
return true;
}
case BUILT_IN_FETCH_AND_AND_1:
@@ -4645,23 +4618,7 @@
case BUILT_IN_FETCH_AND_AND_4:
case BUILT_IN_FETCH_AND_AND_8:
case BUILT_IN_FETCH_AND_AND_16: {
- const Type *ResultTy = ConvertType(TREE_TYPE(exp));
- tree arglist = TREE_OPERAND(exp, 1);
- Value* C[2] = {
- Emit(TREE_VALUE(arglist), 0),
- Emit(TREE_VALUE(TREE_CHAIN(arglist)), 0)
- };
- const Type* Ty[2];
- Ty[0] = ResultTy;
- Ty[1] = PointerType::getUnqual(ResultTy);
- C[0] = Builder.CreateBitCast(C[0], Ty[1]);
- C[1] = Builder.CreateIntCast(C[1], Ty[0], "cast");
- Result =
- Builder.CreateCall(Intrinsic::getDeclaration(TheModule,
- Intrinsic::atomic_load_and,
- Ty, 2),
- C, C + 2);
- Result = Builder.CreateIntToPtr(Result, ResultTy);
+ Result = BuildBinaryAtomicBuiltin(exp, Intrinsic::atomic_load_and);
return true;
}
case BUILT_IN_FETCH_AND_XOR_1:
@@ -4669,23 +4626,7 @@
case BUILT_IN_FETCH_AND_XOR_4:
case BUILT_IN_FETCH_AND_XOR_8:
case BUILT_IN_FETCH_AND_XOR_16: {
- const Type *ResultTy = ConvertType(TREE_TYPE(exp));
- tree arglist = TREE_OPERAND(exp, 1);
- Value* C[2] = {
- Emit(TREE_VALUE(arglist), 0),
- Emit(TREE_VALUE(TREE_CHAIN(arglist)), 0)
- };
- const Type* Ty[2];
- Ty[0] = ResultTy;
- Ty[1] = PointerType::getUnqual(ResultTy);
- C[0] = Builder.CreateBitCast(C[0], Ty[1]);
- C[1] = Builder.CreateIntCast(C[1], Ty[0], "cast");
- Result =
- Builder.CreateCall(Intrinsic::getDeclaration(TheModule,
- Intrinsic::atomic_load_xor,
- Ty, 2),
- C, C + 2);
- Result = Builder.CreateIntToPtr(Result, ResultTy);
+ Result = BuildBinaryAtomicBuiltin(exp, Intrinsic::atomic_load_xor);
return true;
}
case BUILT_IN_FETCH_AND_NAND_1:
@@ -4693,23 +4634,7 @@
case BUILT_IN_FETCH_AND_NAND_4:
case BUILT_IN_FETCH_AND_NAND_8:
case BUILT_IN_FETCH_AND_NAND_16: {
- const Type *ResultTy = ConvertType(TREE_TYPE(exp));
- tree arglist = TREE_OPERAND(exp, 1);
- Value* C[2] = {
- Emit(TREE_VALUE(arglist), 0),
- Emit(TREE_VALUE(TREE_CHAIN(arglist)), 0)
- };
- const Type* Ty[2];
- Ty[0] = ResultTy;
- Ty[1] = PointerType::getUnqual(ResultTy);
- C[0] = Builder.CreateBitCast(C[0], Ty[1]);
- C[1] = Builder.CreateIntCast(C[1], Ty[0], "cast");
- Result =
- Builder.CreateCall(Intrinsic::getDeclaration(TheModule,
- Intrinsic::atomic_load_nand,
- Ty, 2),
- C, C + 2);
- Result = Builder.CreateIntToPtr(Result, ResultTy);
+ Result = BuildBinaryAtomicBuiltin(exp, Intrinsic::atomic_load_nand);
return true;
}
case BUILT_IN_LOCK_TEST_AND_SET_1:
@@ -4717,25 +4642,7 @@
case BUILT_IN_LOCK_TEST_AND_SET_4:
case BUILT_IN_LOCK_TEST_AND_SET_8:
case BUILT_IN_LOCK_TEST_AND_SET_16: {
- const Type *ResultTy = ConvertType(TREE_TYPE(exp));
- tree arglist = TREE_OPERAND(exp, 1);
- Value* C[2] = {
- Emit(TREE_VALUE(arglist), 0),
- Emit(TREE_VALUE(TREE_CHAIN(arglist)), 0)
- };
-
- const Type* Ty[2];
- Ty[0] = ResultTy;
- Ty[1] = PointerType::getUnqual(ResultTy);
- C[0] = Builder.CreateBitCast(C[0], Ty[1]);
- C[1] = Builder.CreateIntCast(C[1], Ty[0], "cast");
- Result =
- Builder.CreateCall(Intrinsic::getDeclaration(TheModule,
- Intrinsic::atomic_swap,
- Ty, 2),
- C, C + 2);
-
- Result = Builder.CreateIntToPtr(Result, ResultTy);
+ Result = BuildBinaryAtomicBuiltin(exp, Intrinsic::atomic_swap);
return true;
}
case BUILT_IN_ADD_AND_FETCH_1:
@@ -4889,6 +4796,39 @@
return true;
}
+ case BUILT_IN_LOCK_RELEASE_1:
+ case BUILT_IN_LOCK_RELEASE_2:
+ case BUILT_IN_LOCK_RELEASE_4:
+ case BUILT_IN_LOCK_RELEASE_8:
+ case BUILT_IN_LOCK_RELEASE_16: {
+ // This is effectively a volatile store of 0, and has no return value.
+ // The argument has typically been coerced to "volatile void*"; the
+ // only way to find the size of the operation is from the builtin
+ // opcode.
+ tree type;
+ switch(DECL_FUNCTION_CODE(fndecl)) {
+ case BUILT_IN_LOCK_RELEASE_1:
+ type = unsigned_char_type_node; break;
+ case BUILT_IN_LOCK_RELEASE_2:
+ type = short_unsigned_type_node; break;
+ case BUILT_IN_LOCK_RELEASE_4:
+ type = unsigned_type_node; break;
+ case BUILT_IN_LOCK_RELEASE_8:
+ type = long_long_unsigned_type_node; break;
+ case BUILT_IN_LOCK_RELEASE_16: // not handled; should use SSE on x86
+ default:
+ abort();
+ }
+ tree arglist = TREE_OPERAND(exp, 1);
+ tree t1 = build1 (INDIRECT_REF, type, TREE_VALUE (arglist));
+ TREE_THIS_VOLATILE(t1) = 1;
+ tree t = build2 (MODIFY_EXPR, type, t1,
+ build_int_cst (type, (HOST_WIDE_INT)0));
+ EmitMODIFY_EXPR(t, 0);
+ Result = 0;
+ return true;
+ }
+
#endif //FIXME: these break the build for backends that haven't implemented them
Modified: llvm-gcc-4.2/trunk/gcc/llvm-internal.h
URL: http://llvm.org/viewvc/llvm-project/llvm-gcc-4.2/trunk/gcc/llvm-internal.h?rev=55017&r1=55016&r2=55017&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-internal.h (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-internal.h Tue Aug 19 17:47:32 2008
@@ -524,6 +524,7 @@
Value *BuildVector(const std::vector<Value*> &Elts);
Value *BuildVector(Value *Elt, ...);
Value *BuildVectorShuffle(Value *InVec1, Value *InVec2, ...);
+ Value *BuildBinaryAtomicBuiltin(tree_node *exp, Intrinsic::ID id);
// Builtin Function Expansion.
bool EmitBuiltinCall(tree_node *exp, tree_node *fndecl,
More information about the llvm-commits
mailing list