[llvm-commits] [llvm-gcc-4.2] r55159 - in /llvm-gcc-4.2/trunk/gcc: llvm-convert.cpp llvm-internal.h
Dale Johannesen
dalej at apple.com
Thu Aug 21 17:57:32 PDT 2008
Author: johannes
Date: Thu Aug 21 19:57:31 2008
New Revision: 55159
URL: http://llvm.org/viewvc/llvm-project?rev=55159&view=rev
Log:
For __sync_bool_compare_and_swap the return type
is not good enough, need to look at the function
opcode to deduce the right IR function.
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=55159&r1=55158&r2=55159&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-convert.cpp Thu Aug 21 19:57:31 2008
@@ -4296,6 +4296,34 @@
return Result;
}
+Value *
+TreeToLLVM::BuildCmpAndSwapAtomicBuiltin(tree exp, tree type, bool isBool) {
+ const Type *ResultTy = ConvertType(type);
+ tree arglist = TREE_OPERAND(exp, 1);
+ Value* C[3] = {
+ Emit(TREE_VALUE(arglist), 0),
+ Emit(TREE_VALUE(TREE_CHAIN(arglist)), 0),
+ Emit(TREE_VALUE(TREE_CHAIN(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");
+ C[2] = Builder.CreateIntCast(C[2], Ty[0], "cast");
+
+ Value *Result =
+ Builder.CreateCall(Intrinsic::getDeclaration(TheModule,
+ Intrinsic::atomic_cmp_swap,
+ Ty, 2),
+ C, C + 3);
+ if (isBool)
+ Result = Builder.CreateICmpEQ(Result, C[1]);
+ else
+ 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.
@@ -4547,47 +4575,38 @@
// The type of the first argument is not reliable for choosing the
// right llvm function; if the original type is not volatile, gcc has
// helpfully changed it to "volatile void *" at this point. The
- // original type can be recovered from the function type.
+ // original type can be recovered from the function type in most cases.
+ // For lock_release and bool_compare_and_swap even that is not good
+ // enough, we have to key off the opcode.
// Note that Intrinsic::getDeclaration expects the type list in reversed
// order, while CreateCall expects the parameter list in normal order.
+ case BUILT_IN_BOOL_COMPARE_AND_SWAP_1: {
+ Result = BuildCmpAndSwapAtomicBuiltin(exp, unsigned_char_type_node, true);
+ return true;
+ }
+ case BUILT_IN_BOOL_COMPARE_AND_SWAP_2: {
+ Result = BuildCmpAndSwapAtomicBuiltin(exp, short_unsigned_type_node, true);
+ return true;
+ }
+ case BUILT_IN_BOOL_COMPARE_AND_SWAP_4: {
+ Result = BuildCmpAndSwapAtomicBuiltin(exp, unsigned_type_node, true);
+ return true;
+ }
+ case BUILT_IN_BOOL_COMPARE_AND_SWAP_8: {
+ Result = BuildCmpAndSwapAtomicBuiltin(exp, long_long_unsigned_type_node,
+ true);
+ return true;
+ }
+ case BUILT_IN_BOOL_COMPARE_AND_SWAP_16:
+ abort(); // not handled; should use SSE on x86
case BUILT_IN_VAL_COMPARE_AND_SWAP_1:
case BUILT_IN_VAL_COMPARE_AND_SWAP_2:
case BUILT_IN_VAL_COMPARE_AND_SWAP_4:
case BUILT_IN_VAL_COMPARE_AND_SWAP_8:
- case BUILT_IN_VAL_COMPARE_AND_SWAP_16:
- case BUILT_IN_BOOL_COMPARE_AND_SWAP_1:
- case BUILT_IN_BOOL_COMPARE_AND_SWAP_2:
- case BUILT_IN_BOOL_COMPARE_AND_SWAP_4:
- case BUILT_IN_BOOL_COMPARE_AND_SWAP_8:
- case BUILT_IN_BOOL_COMPARE_AND_SWAP_16: {
- const Type *ResultTy = ConvertType(TREE_TYPE(exp));
- tree arglist = TREE_OPERAND(exp, 1);
- Value* C[3] = {
- Emit(TREE_VALUE(arglist), 0),
- Emit(TREE_VALUE(TREE_CHAIN(arglist)), 0),
- Emit(TREE_VALUE(TREE_CHAIN(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");
- C[2] = Builder.CreateIntCast(C[2], Ty[0], "cast");
-
- Result =
- Builder.CreateCall(Intrinsic::getDeclaration(TheModule,
- Intrinsic::atomic_cmp_swap,
- Ty, 2),
- C, C + 3);
- if (((DECL_FUNCTION_CODE(fndecl)) == BUILT_IN_BOOL_COMPARE_AND_SWAP_1) ||
- ((DECL_FUNCTION_CODE(fndecl)) == BUILT_IN_BOOL_COMPARE_AND_SWAP_2) ||
- ((DECL_FUNCTION_CODE(fndecl)) == BUILT_IN_BOOL_COMPARE_AND_SWAP_4) ||
- ((DECL_FUNCTION_CODE(fndecl)) == BUILT_IN_BOOL_COMPARE_AND_SWAP_8) ||
- ((DECL_FUNCTION_CODE(fndecl)) == BUILT_IN_BOOL_COMPARE_AND_SWAP_16))
- Result = Builder.CreateICmpEQ(Result, C[1]);
- else
- Result = Builder.CreateIntToPtr(Result, ResultTy);
- return true;
+ case BUILT_IN_VAL_COMPARE_AND_SWAP_16: {
+ tree type = TREE_TYPE(exp);
+ Result = BuildCmpAndSwapAtomicBuiltin(exp, type, false);
+ return true;
}
case BUILT_IN_FETCH_AND_ADD_1:
case BUILT_IN_FETCH_AND_ADD_2:
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=55159&r1=55158&r2=55159&view=diff
==============================================================================
--- llvm-gcc-4.2/trunk/gcc/llvm-internal.h (original)
+++ llvm-gcc-4.2/trunk/gcc/llvm-internal.h Thu Aug 21 19:57:31 2008
@@ -525,6 +525,8 @@
Value *BuildVector(Value *Elt, ...);
Value *BuildVectorShuffle(Value *InVec1, Value *InVec2, ...);
Value *BuildBinaryAtomicBuiltin(tree_node *exp, Intrinsic::ID id);
+ Value *BuildCmpAndSwapAtomicBuiltin(tree_node *exp, tree_node *type,
+ bool isBool);
// Builtin Function Expansion.
bool EmitBuiltinCall(tree_node *exp, tree_node *fndecl,
More information about the llvm-commits
mailing list