[llvm-commits] [dragonegg] r141189 - in /dragonegg/trunk: include/dragonegg/Internals.h src/Convert.cpp

Duncan Sands baldrick at free.fr
Wed Oct 5 10:00:40 PDT 2011


Author: baldrick
Date: Wed Oct  5 12:00:39 2011
New Revision: 141189

URL: http://llvm.org/viewvc/llvm-project?rev=141189&view=rev
Log:
Port commit 139562 (efriedma) from llvm-gcc.  Original commit message:
Convert llvm-gcc to use the new atomic instructions.

I would appreciate if someone would do the same conversion for dragonegg.

Modified:
    dragonegg/trunk/include/dragonegg/Internals.h
    dragonegg/trunk/src/Convert.cpp

Modified: dragonegg/trunk/include/dragonegg/Internals.h
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/include/dragonegg/Internals.h?rev=141189&r1=141188&r2=141189&view=diff
==============================================================================
--- dragonegg/trunk/include/dragonegg/Internals.h (original)
+++ dragonegg/trunk/include/dragonegg/Internals.h Wed Oct  5 12:00:39 2011
@@ -601,13 +601,13 @@
   void EmitModifyOfRegisterVariable(tree_node *vardecl, Value *RHS);
 
   // Helpers for Builtin Function Expansion.
-  void EmitMemoryBarrier(bool ll, bool ls, bool sl, bool ss, bool device);
   Value *BuildVector(const std::vector<Value*> &Elts);
   Value *BuildVector(Value *Elt, ...);
   Value *BuildVectorShuffle(Value *InVec1, Value *InVec2, ...);
-  Value *BuildBinaryAtomicBuiltin(gimple_statement_d *stmt, Intrinsic::ID id);
-  Value *BuildCmpAndSwapAtomicBuiltin(gimple_statement_d *stmt, unsigned Bits,
-                                      bool isBool);
+  Value *BuildBinaryAtomic(gimple_statement_d *stmt, AtomicRMWInst::BinOp Kind,
+                           unsigned PostOp = 0);
+  Value *BuildCmpAndSwapAtomic(gimple_statement_d *stmt, unsigned Bits,
+                               bool isBool);
 
   // Builtin Function Expansion.
   bool EmitBuiltinCall(gimple_statement_d *stmt, tree_node *fndecl,

Modified: dragonegg/trunk/src/Convert.cpp
URL: http://llvm.org/viewvc/llvm-project/dragonegg/trunk/src/Convert.cpp?rev=141189&r1=141188&r2=141189&view=diff
==============================================================================
--- dragonegg/trunk/src/Convert.cpp (original)
+++ dragonegg/trunk/src/Convert.cpp Wed Oct  5 12:00:39 2011
@@ -3561,22 +3561,8 @@
 /// builtin number.
 static std::vector<Constant*> TargetBuiltinCache;
 
-void TreeToLLVM::EmitMemoryBarrier(bool ll, bool ls, bool sl, bool ss,
-                                   bool device) {
-  Value* C[5];
-  C[0] = Builder.getInt1(ll);
-  C[1] = Builder.getInt1(ls);
-  C[2] = Builder.getInt1(sl);
-  C[3] = Builder.getInt1(ss);
-  C[4] = Builder.getInt1(device);
-
-  Builder.CreateCall(Intrinsic::getDeclaration(TheModule,
-                                               Intrinsic::memory_barrier),
-                     C);
-}
-
-Value *
-TreeToLLVM::BuildBinaryAtomicBuiltin(gimple stmt, Intrinsic::ID id) {
+Value *TreeToLLVM::BuildBinaryAtomic(gimple stmt, AtomicRMWInst::BinOp Kind,
+                                     unsigned PostOp) {
   tree return_type = gimple_call_return_type(stmt);
   Type *ResultTy = ConvertType(return_type);
   Value* C[2] = {
@@ -3590,32 +3576,17 @@
   C[1] = Builder.CreateIntCast(C[1], Ty[0],
                                /*isSigned*/!TYPE_UNSIGNED(return_type),
                                "cast");
-  // The gcc builtins are also full memory barriers.
-  // FIXME: __sync_lock_test_and_set and __sync_lock_release require less.
-#if defined(TARGET_ARM) && defined(CONFIG_DARWIN_H)
-  EmitMemoryBarrier(true, true, true, true, false);
-#else
-  EmitMemoryBarrier(true, true, true, true, true);
-#endif
-
-  Value *Result =
-    Builder.CreateCall(Intrinsic::getDeclaration(TheModule, id, Ty), C);
-
-  // The gcc builtins are also full memory barriers.
-  // FIXME: __sync_lock_test_and_set and __sync_lock_release require less.
-#if defined(TARGET_ARM) && defined(CONFIG_DARWIN_H)
-  EmitMemoryBarrier(true, true, true, true, false);
-#else
-  EmitMemoryBarrier(true, true, true, true, true);
-#endif
+  Value *Result = Builder.CreateAtomicRMW(Kind, C[0], C[1],
+                                          SequentiallyConsistent);
+  if (PostOp)
+    Result = Builder.CreateBinOp(Instruction::BinaryOps(PostOp), Result, C[1]);
 
   Result = Builder.CreateIntToPtr(Result, ResultTy);
   return Result;
 }
 
 Value *
-TreeToLLVM::BuildCmpAndSwapAtomicBuiltin(gimple stmt, unsigned Bits,
-                                         bool isBool) {
+TreeToLLVM::BuildCmpAndSwapAtomic(gimple stmt, unsigned Bits, bool isBool) {
   tree ptr = gimple_call_arg(stmt, 0);
   tree old_val = gimple_call_arg(stmt, 1);
   tree new_val = gimple_call_arg(stmt, 2);
@@ -3632,28 +3603,9 @@
                                  !TYPE_UNSIGNED(TREE_TYPE(new_val)), MemTy,
                                  !TYPE_UNSIGNED(TREE_TYPE(new_val)));
 
-  // The gcc builtins are also full memory barriers.
-  // FIXME: __sync_lock_test_and_set and __sync_lock_release require less.
-#if defined(TARGET_ARM) && defined(CONFIG_DARWIN_H)
-  EmitMemoryBarrier(true, true, true, true, false);
-#else
-  EmitMemoryBarrier(true, true, true, true, true);
-#endif
-
-  Value *Ops[3] = { Ptr, Old_Val, New_Val };
-  Type* Ty[2] = { MemTy, MemPtrTy };
-  Value *Result =
-    Builder.CreateCall(Intrinsic::getDeclaration(TheModule,
-                                                 Intrinsic::atomic_cmp_swap,
-                                                 Ty), Ops);
-
-  // The gcc builtins are also full memory barriers.
-  // FIXME: __sync_lock_test_and_set and __sync_lock_release require less.
-#if defined(TARGET_ARM) && defined(CONFIG_DARWIN_H)
-  EmitMemoryBarrier(true, true, true, true, false);
-#else
-  EmitMemoryBarrier(true, true, true, true, true);
-#endif
+  Value *C[3] = { Ptr, Old_Val, New_Val };
+  Value *Result = Builder.CreateAtomicCmpXchg(C[0], C[1], C[2],
+                                              SequentiallyConsistent);
 
   if (isBool)
     Result = Builder.CreateICmpEQ(Result, Old_Val);
@@ -4044,17 +3996,10 @@
 //TODO    return true;
 //TODO  }
 
-  case BUILT_IN_SYNCHRONIZE: {
+  case BUILT_IN_SYNCHRONIZE:
     // We assume like gcc appears to, that this only applies to cached memory.
-    Value* C[5];
-    C[0] = C[1] = C[2] = C[3] = Builder.getTrue();
-    C[4] = Builder.getFalse();
-
-    Builder.CreateCall(Intrinsic::getDeclaration(TheModule,
-                                                 Intrinsic::memory_barrier),
-                       C);
+    Builder.CreateFence(llvm::SequentiallyConsistent);
     return true;
-  }
 #if defined(TARGET_ALPHA) || defined(TARGET_386) || defined(TARGET_POWERPC) \
     || defined(TARGET_ARM)
     // gcc uses many names for the sync intrinsics
@@ -4067,38 +4012,38 @@
     // 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(stmt, BITS_PER_UNIT, true);
+    Result = BuildCmpAndSwapAtomic(stmt, BITS_PER_UNIT, true);
     return true;
   case BUILT_IN_BOOL_COMPARE_AND_SWAP_2:
-    Result = BuildCmpAndSwapAtomicBuiltin(stmt, 2*BITS_PER_UNIT, true);
+    Result = BuildCmpAndSwapAtomic(stmt, 2*BITS_PER_UNIT, true);
     return true;
   case BUILT_IN_BOOL_COMPARE_AND_SWAP_4:
-    Result = BuildCmpAndSwapAtomicBuiltin(stmt, 4*BITS_PER_UNIT, true);
+    Result = BuildCmpAndSwapAtomic(stmt, 4*BITS_PER_UNIT, true);
     return true;
   case BUILT_IN_BOOL_COMPARE_AND_SWAP_8:
 #if defined(TARGET_POWERPC)
     if (!TARGET_64BIT)
       return false;
 #endif
-    Result = BuildCmpAndSwapAtomicBuiltin(stmt, 8*BITS_PER_UNIT, true);
+    Result = BuildCmpAndSwapAtomic(stmt, 8*BITS_PER_UNIT, true);
     return true;
 
     // Fall through.
   case BUILT_IN_VAL_COMPARE_AND_SWAP_1:
-    Result = BuildCmpAndSwapAtomicBuiltin(stmt, BITS_PER_UNIT, false);
+    Result = BuildCmpAndSwapAtomic(stmt, BITS_PER_UNIT, false);
     return true;
   case BUILT_IN_VAL_COMPARE_AND_SWAP_2:
-    Result = BuildCmpAndSwapAtomicBuiltin(stmt, 2*BITS_PER_UNIT, false);
+    Result = BuildCmpAndSwapAtomic(stmt, 2*BITS_PER_UNIT, false);
     return true;
   case BUILT_IN_VAL_COMPARE_AND_SWAP_4:
-    Result = BuildCmpAndSwapAtomicBuiltin(stmt, 4*BITS_PER_UNIT, false);
+    Result = BuildCmpAndSwapAtomic(stmt, 4*BITS_PER_UNIT, false);
     return true;
   case BUILT_IN_VAL_COMPARE_AND_SWAP_8:
 #if defined(TARGET_POWERPC)
     if (!TARGET_64BIT)
       return false;
 #endif
-    Result = BuildCmpAndSwapAtomicBuiltin(stmt, 8*BITS_PER_UNIT, false);
+    Result = BuildCmpAndSwapAtomic(stmt, 8*BITS_PER_UNIT, false);
     return true;
 
   case BUILT_IN_FETCH_AND_ADD_8:
@@ -4109,7 +4054,7 @@
   case BUILT_IN_FETCH_AND_ADD_1:
   case BUILT_IN_FETCH_AND_ADD_2:
   case BUILT_IN_FETCH_AND_ADD_4: {
-    Result = BuildBinaryAtomicBuiltin(stmt, Intrinsic::atomic_load_add);
+    Result = BuildBinaryAtomic(stmt, AtomicRMWInst::Add);
     return true;
   }
   case BUILT_IN_FETCH_AND_SUB_8:
@@ -4120,7 +4065,7 @@
   case BUILT_IN_FETCH_AND_SUB_1:
   case BUILT_IN_FETCH_AND_SUB_2:
   case BUILT_IN_FETCH_AND_SUB_4: {
-    Result = BuildBinaryAtomicBuiltin(stmt, Intrinsic::atomic_load_sub);
+    Result = BuildBinaryAtomic(stmt, AtomicRMWInst::Sub);
     return true;
   }
   case BUILT_IN_FETCH_AND_OR_8:
@@ -4131,7 +4076,7 @@
   case BUILT_IN_FETCH_AND_OR_1:
   case BUILT_IN_FETCH_AND_OR_2:
   case BUILT_IN_FETCH_AND_OR_4: {
-    Result = BuildBinaryAtomicBuiltin(stmt, Intrinsic::atomic_load_or);
+    Result = BuildBinaryAtomic(stmt, AtomicRMWInst::Or);
     return true;
   }
   case BUILT_IN_FETCH_AND_AND_8:
@@ -4142,7 +4087,7 @@
   case BUILT_IN_FETCH_AND_AND_1:
   case BUILT_IN_FETCH_AND_AND_2:
   case BUILT_IN_FETCH_AND_AND_4: {
-    Result = BuildBinaryAtomicBuiltin(stmt, Intrinsic::atomic_load_and);
+    Result = BuildBinaryAtomic(stmt, AtomicRMWInst::And);
     return true;
   }
   case BUILT_IN_FETCH_AND_XOR_8:
@@ -4153,7 +4098,7 @@
   case BUILT_IN_FETCH_AND_XOR_1:
   case BUILT_IN_FETCH_AND_XOR_2:
   case BUILT_IN_FETCH_AND_XOR_4: {
-    Result = BuildBinaryAtomicBuiltin(stmt, Intrinsic::atomic_load_xor);
+    Result = BuildBinaryAtomic(stmt, AtomicRMWInst::Xor);
     return true;
   }
   case BUILT_IN_FETCH_AND_NAND_8:
@@ -4164,7 +4109,7 @@
   case BUILT_IN_FETCH_AND_NAND_1:
   case BUILT_IN_FETCH_AND_NAND_2:
   case BUILT_IN_FETCH_AND_NAND_4: {
-    Result = BuildBinaryAtomicBuiltin(stmt, Intrinsic::atomic_load_nand);
+    Result = BuildBinaryAtomic(stmt, AtomicRMWInst::Nand);
     return true;
   }
   case BUILT_IN_LOCK_TEST_AND_SET_8:
@@ -4175,7 +4120,7 @@
   case BUILT_IN_LOCK_TEST_AND_SET_1:
   case BUILT_IN_LOCK_TEST_AND_SET_2:
   case BUILT_IN_LOCK_TEST_AND_SET_4: {
-    Result = BuildBinaryAtomicBuiltin(stmt, Intrinsic::atomic_swap);
+    Result = BuildBinaryAtomic(stmt, AtomicRMWInst::Xchg);
     return true;
   }
 
@@ -4186,47 +4131,9 @@
 #endif
   case BUILT_IN_ADD_AND_FETCH_1:
   case BUILT_IN_ADD_AND_FETCH_2:
-  case BUILT_IN_ADD_AND_FETCH_4: {
-    tree return_type = gimple_call_return_type(stmt);
-    Type *ResultTy = ConvertType(return_type);
-    Value* C[2] = {
-      EmitMemory(gimple_call_arg(stmt, 0)),
-      EmitMemory(gimple_call_arg(stmt, 1))
-    };
-    Type* Ty[2];
-    Ty[0] = ResultTy;
-    Ty[1] = ResultTy->getPointerTo();
-    C[0] = Builder.CreateBitCast(C[0], Ty[1]);
-    C[1] = Builder.CreateIntCast(C[1], Ty[0],
-                                 /*isSigned*/!TYPE_UNSIGNED(return_type),
-                                 "cast");
-
-    // The gcc builtins are also full memory barriers.
-    // FIXME: __sync_lock_test_and_set and __sync_lock_release require less.
-#if defined(TARGET_ARM) && defined(CONFIG_DARWIN_H)
-    EmitMemoryBarrier(true, true, true, true, false);
-#else
-    EmitMemoryBarrier(true, true, true, true, true);
-#endif
-
-    Result =
-      Builder.CreateCall(Intrinsic::getDeclaration(TheModule,
-                                                   Intrinsic::atomic_load_add,
-                                                   Ty),
-                         C);
-
-    // The gcc builtins are also full memory barriers.
-    // FIXME: __sync_lock_test_and_set and __sync_lock_release require less.
-#if defined(TARGET_ARM) && defined(CONFIG_DARWIN_H)
-    EmitMemoryBarrier(true, true, true, true, false);
-#else
-    EmitMemoryBarrier(true, true, true, true, true);
-#endif
-
-    Result = Builder.CreateAdd(Result, C[1]);
-    Result = Builder.CreateIntToPtr(Result, ResultTy);
+  case BUILT_IN_ADD_AND_FETCH_4:
+    Result = BuildBinaryAtomic(stmt, AtomicRMWInst::Add, Instruction::Add);
     return true;
-  }
   case BUILT_IN_SUB_AND_FETCH_8:
 #if defined(TARGET_POWERPC)
     if (!TARGET_64BIT)
@@ -4234,47 +4141,9 @@
 #endif
   case BUILT_IN_SUB_AND_FETCH_1:
   case BUILT_IN_SUB_AND_FETCH_2:
-  case BUILT_IN_SUB_AND_FETCH_4: {
-    tree return_type = gimple_call_return_type(stmt);
-    Type *ResultTy = ConvertType(return_type);
-    Value* C[2] = {
-      EmitMemory(gimple_call_arg(stmt, 0)),
-      EmitMemory(gimple_call_arg(stmt, 1))
-    };
-    Type* Ty[2];
-    Ty[0] = ResultTy;
-    Ty[1] = ResultTy->getPointerTo();
-    C[0] = Builder.CreateBitCast(C[0], Ty[1]);
-    C[1] = Builder.CreateIntCast(C[1], Ty[0],
-                                 /*isSigned*/!TYPE_UNSIGNED(return_type),
-                                 "cast");
-
-    // The gcc builtins are also full memory barriers.
-    // FIXME: __sync_lock_test_and_set and __sync_lock_release require less.
-#if defined(TARGET_ARM) && defined(CONFIG_DARWIN_H)
-    EmitMemoryBarrier(true, true, true, true, false);
-#else
-    EmitMemoryBarrier(true, true, true, true, true);
-#endif
-
-    Result =
-      Builder.CreateCall(Intrinsic::getDeclaration(TheModule,
-                                                   Intrinsic::atomic_load_sub,
-                                                   Ty),
-                         C);
-
-    // The gcc builtins are also full memory barriers.
-    // FIXME: __sync_lock_test_and_set and __sync_lock_release require less.
-#if defined(TARGET_ARM) && defined(CONFIG_DARWIN_H)
-    EmitMemoryBarrier(true, true, true, true, false);
-#else
-    EmitMemoryBarrier(true, true, true, true, true);
-#endif
-
-    Result = Builder.CreateSub(Result, C[1]);
-    Result = Builder.CreateIntToPtr(Result, ResultTy);
+  case BUILT_IN_SUB_AND_FETCH_4:
+    Result = BuildBinaryAtomic(stmt, AtomicRMWInst::Sub, Instruction::Sub);
     return true;
-  }
   case BUILT_IN_OR_AND_FETCH_8:
 #if defined(TARGET_POWERPC)
     if (!TARGET_64BIT)
@@ -4282,47 +4151,9 @@
 #endif
   case BUILT_IN_OR_AND_FETCH_1:
   case BUILT_IN_OR_AND_FETCH_2:
-  case BUILT_IN_OR_AND_FETCH_4: {
-    tree return_type = gimple_call_return_type(stmt);
-    Type *ResultTy = ConvertType(return_type);
-    Value* C[2] = {
-      EmitMemory(gimple_call_arg(stmt, 0)),
-      EmitMemory(gimple_call_arg(stmt, 1))
-    };
-    Type* Ty[2];
-    Ty[0] = ResultTy;
-    Ty[1] = ResultTy->getPointerTo();
-    C[0] = Builder.CreateBitCast(C[0], Ty[1]);
-    C[1] = Builder.CreateIntCast(C[1], Ty[0],
-                                 /*isSigned*/!TYPE_UNSIGNED(return_type),
-                                 "cast");
-
-    // The gcc builtins are also full memory barriers.
-    // FIXME: __sync_lock_test_and_set and __sync_lock_release require less.
-#if defined(TARGET_ARM) && defined(CONFIG_DARWIN_H)
-    EmitMemoryBarrier(true, true, true, true, false);
-#else
-    EmitMemoryBarrier(true, true, true, true, true);
-#endif
-
-    Result =
-      Builder.CreateCall(Intrinsic::getDeclaration(TheModule,
-                                                   Intrinsic::atomic_load_or,
-                                                   Ty),
-                         C);
-
-    // The gcc builtins are also full memory barriers.
-    // FIXME: __sync_lock_test_and_set and __sync_lock_release require less.
-#if defined(TARGET_ARM) && defined(CONFIG_DARWIN_H)
-    EmitMemoryBarrier(true, true, true, true, false);
-#else
-    EmitMemoryBarrier(true, true, true, true, true);
-#endif
-
-    Result = Builder.CreateOr(Result, C[1]);
-    Result = Builder.CreateIntToPtr(Result, ResultTy);
+  case BUILT_IN_OR_AND_FETCH_4:
+    Result = BuildBinaryAtomic(stmt, AtomicRMWInst::Or, Instruction::Or);
     return true;
-  }
   case BUILT_IN_AND_AND_FETCH_8:
 #if defined(TARGET_POWERPC)
     if (!TARGET_64BIT)
@@ -4330,47 +4161,9 @@
 #endif
   case BUILT_IN_AND_AND_FETCH_1:
   case BUILT_IN_AND_AND_FETCH_2:
-  case BUILT_IN_AND_AND_FETCH_4: {
-    tree return_type = gimple_call_return_type(stmt);
-    Type *ResultTy = ConvertType(return_type);
-    Value* C[2] = {
-      EmitMemory(gimple_call_arg(stmt, 0)),
-      EmitMemory(gimple_call_arg(stmt, 1))
-    };
-    Type* Ty[2];
-    Ty[0] = ResultTy;
-    Ty[1] = ResultTy->getPointerTo();
-    C[0] = Builder.CreateBitCast(C[0], Ty[1]);
-    C[1] = Builder.CreateIntCast(C[1], Ty[0],
-                                 /*isSigned*/!TYPE_UNSIGNED(return_type),
-                                 "cast");
-
-    // The gcc builtins are also full memory barriers.
-    // FIXME: __sync_lock_test_and_set and __sync_lock_release require less.
-#if defined(TARGET_ARM) && defined(CONFIG_DARWIN_H)
-    EmitMemoryBarrier(true, true, true, true, false);
-#else
-    EmitMemoryBarrier(true, true, true, true, true);
-#endif
-
-    Result =
-      Builder.CreateCall(Intrinsic::getDeclaration(TheModule,
-                                                   Intrinsic::atomic_load_and,
-                                                   Ty),
-                         C);
-
-    // The gcc builtins are also full memory barriers.
-    // FIXME: __sync_lock_test_and_set and __sync_lock_release require less.
-#if defined(TARGET_ARM) && defined(CONFIG_DARWIN_H)
-    EmitMemoryBarrier(true, true, true, true, false);
-#else
-    EmitMemoryBarrier(true, true, true, true, true);
-#endif
-
-    Result = Builder.CreateAnd(Result, C[1]);
-    Result = Builder.CreateIntToPtr(Result, ResultTy);
+  case BUILT_IN_AND_AND_FETCH_4:
+    Result = BuildBinaryAtomic(stmt, AtomicRMWInst::And, Instruction::And);
     return true;
-  }
   case BUILT_IN_XOR_AND_FETCH_8:
 #if defined(TARGET_POWERPC)
     if (!TARGET_64BIT)
@@ -4378,47 +4171,9 @@
 #endif
   case BUILT_IN_XOR_AND_FETCH_1:
   case BUILT_IN_XOR_AND_FETCH_2:
-  case BUILT_IN_XOR_AND_FETCH_4: {
-    tree return_type = gimple_call_return_type(stmt);
-    Type *ResultTy = ConvertType(return_type);
-    Value* C[2] = {
-      EmitMemory(gimple_call_arg(stmt, 0)),
-      EmitMemory(gimple_call_arg(stmt, 1))
-    };
-    Type* Ty[2];
-    Ty[0] = ResultTy;
-    Ty[1] = ResultTy->getPointerTo();
-    C[0] = Builder.CreateBitCast(C[0], Ty[1]);
-    C[1] = Builder.CreateIntCast(C[1], Ty[0],
-                                 /*isSigned*/!TYPE_UNSIGNED(return_type),
-                                 "cast");
-
-    // The gcc builtins are also full memory barriers.
-    // FIXME: __sync_lock_test_and_set and __sync_lock_release require less.
-#if defined(TARGET_ARM) && defined(CONFIG_DARWIN_H)
-    EmitMemoryBarrier(true, true, true, true, false);
-#else
-    EmitMemoryBarrier(true, true, true, true, true);
-#endif
-
-    Result =
-      Builder.CreateCall(Intrinsic::getDeclaration(TheModule,
-                                                   Intrinsic::atomic_load_xor,
-                                                   Ty),
-                         C);
-
-    // The gcc builtins are also full memory barriers.
-    // FIXME: __sync_lock_test_and_set and __sync_lock_release require less.
-#if defined(TARGET_ARM) && defined(CONFIG_DARWIN_H)
-    EmitMemoryBarrier(true, true, true, true, false);
-#else
-    EmitMemoryBarrier(true, true, true, true, true);
-#endif
-
-    Result = Builder.CreateXor(Result, C[1]);
-    Result = Builder.CreateIntToPtr(Result, ResultTy);
+  case BUILT_IN_XOR_AND_FETCH_4:
+    Result = BuildBinaryAtomic(stmt, AtomicRMWInst::Xor, Instruction::Xor);
     return true;
-  }
   case BUILT_IN_NAND_AND_FETCH_8:
 #if defined(TARGET_POWERPC)
     if (!TARGET_64BIT)
@@ -4440,28 +4195,8 @@
     C[1] = Builder.CreateIntCast(C[1], Ty[0],
                                  /*isSigned*/!TYPE_UNSIGNED(return_type),
                                  "cast");
-
-    // The gcc builtins are also full memory barriers.
-    // FIXME: __sync_lock_test_and_set and __sync_lock_release require less.
-#if defined(TARGET_ARM) && defined(CONFIG_DARWIN_H)
-    EmitMemoryBarrier(true, true, true, true, false);
-#else
-    EmitMemoryBarrier(true, true, true, true, true);
-#endif
-
-    Result =
-      Builder.CreateCall(Intrinsic::getDeclaration(TheModule,
-                                                   Intrinsic::atomic_load_nand,
-                                                   Ty),
-                         C);
-
-    // The gcc builtins are also full memory barriers.
-    // FIXME: __sync_lock_test_and_set and __sync_lock_release require less.
-#if defined(TARGET_ARM) && defined(CONFIG_DARWIN_H)
-    EmitMemoryBarrier(true, true, true, true, false);
-#else
-    EmitMemoryBarrier(true, true, true, true, true);
-#endif
+    Value *Result = Builder.CreateAtomicRMW(AtomicRMWInst::Nand, C[0], C[1],
+                                            SequentiallyConsistent);
 
     Result = Builder.CreateAnd(Builder.CreateNot(Result), C[1]);
     Result = Builder.CreateIntToPtr(Result, ResultTy);
@@ -4477,6 +4212,9 @@
     // The argument has typically been coerced to "volatile void*"; the
     // only way to find the size of the operation is from the builtin
     // opcode.
+    // FIXME: This is wrong; it works to some extent on x86 if the optimizer
+    // doesn't get too clever, and is horribly broken anywhere else.  It needs
+    // to use "store atomic [...] release".
     Type *Ty;
     switch(DECL_FUNCTION_CODE(fndecl)) {
       case BUILT_IN_LOCK_RELEASE_16:    // not handled; should use SSE on x86





More information about the llvm-commits mailing list