clang API Documentation

CGAtomic.cpp
Go to the documentation of this file.
00001 //===--- CGAtomic.cpp - Emit LLVM IR for atomic operations ----------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file contains the code for emitting atomic operations.
00011 //
00012 //===----------------------------------------------------------------------===//
00013 
00014 #include "CodeGenFunction.h"
00015 #include "CGCall.h"
00016 #include "CodeGenModule.h"
00017 #include "clang/AST/ASTContext.h"
00018 #include "clang/CodeGen/CGFunctionInfo.h"
00019 #include "llvm/ADT/StringExtras.h"
00020 #include "llvm/IR/DataLayout.h"
00021 #include "llvm/IR/Intrinsics.h"
00022 #include "llvm/IR/Operator.h"
00023 
00024 using namespace clang;
00025 using namespace CodeGen;
00026 
00027 namespace {
00028   class AtomicInfo {
00029     CodeGenFunction &CGF;
00030     QualType AtomicTy;
00031     QualType ValueTy;
00032     uint64_t AtomicSizeInBits;
00033     uint64_t ValueSizeInBits;
00034     CharUnits AtomicAlign;
00035     CharUnits ValueAlign;
00036     CharUnits LValueAlign;
00037     TypeEvaluationKind EvaluationKind;
00038     bool UseLibcall;
00039   public:
00040     AtomicInfo(CodeGenFunction &CGF, LValue &lvalue) : CGF(CGF) {
00041       assert(lvalue.isSimple());
00042 
00043       AtomicTy = lvalue.getType();
00044       ValueTy = AtomicTy->castAs<AtomicType>()->getValueType();
00045       EvaluationKind = CGF.getEvaluationKind(ValueTy);
00046 
00047       ASTContext &C = CGF.getContext();
00048 
00049       uint64_t ValueAlignInBits;
00050       uint64_t AtomicAlignInBits;
00051       TypeInfo ValueTI = C.getTypeInfo(ValueTy);
00052       ValueSizeInBits = ValueTI.Width;
00053       ValueAlignInBits = ValueTI.Align;
00054 
00055       TypeInfo AtomicTI = C.getTypeInfo(AtomicTy);
00056       AtomicSizeInBits = AtomicTI.Width;
00057       AtomicAlignInBits = AtomicTI.Align;
00058 
00059       assert(ValueSizeInBits <= AtomicSizeInBits);
00060       assert(ValueAlignInBits <= AtomicAlignInBits);
00061 
00062       AtomicAlign = C.toCharUnitsFromBits(AtomicAlignInBits);
00063       ValueAlign = C.toCharUnitsFromBits(ValueAlignInBits);
00064       if (lvalue.getAlignment().isZero())
00065         lvalue.setAlignment(AtomicAlign);
00066 
00067       UseLibcall =
00068         (AtomicSizeInBits > uint64_t(C.toBits(lvalue.getAlignment())) ||
00069          AtomicSizeInBits > C.getTargetInfo().getMaxAtomicInlineWidth());
00070     }
00071 
00072     QualType getAtomicType() const { return AtomicTy; }
00073     QualType getValueType() const { return ValueTy; }
00074     CharUnits getAtomicAlignment() const { return AtomicAlign; }
00075     CharUnits getValueAlignment() const { return ValueAlign; }
00076     uint64_t getAtomicSizeInBits() const { return AtomicSizeInBits; }
00077     uint64_t getValueSizeInBits() const { return AtomicSizeInBits; }
00078     TypeEvaluationKind getEvaluationKind() const { return EvaluationKind; }
00079     bool shouldUseLibcall() const { return UseLibcall; }
00080 
00081     /// Is the atomic size larger than the underlying value type?
00082     ///
00083     /// Note that the absence of padding does not mean that atomic
00084     /// objects are completely interchangeable with non-atomic
00085     /// objects: we might have promoted the alignment of a type
00086     /// without making it bigger.
00087     bool hasPadding() const {
00088       return (ValueSizeInBits != AtomicSizeInBits);
00089     }
00090 
00091     bool emitMemSetZeroIfNecessary(LValue dest) const;
00092 
00093     llvm::Value *getAtomicSizeValue() const {
00094       CharUnits size = CGF.getContext().toCharUnitsFromBits(AtomicSizeInBits);
00095       return CGF.CGM.getSize(size);
00096     }
00097 
00098     /// Cast the given pointer to an integer pointer suitable for
00099     /// atomic operations.
00100     llvm::Value *emitCastToAtomicIntPointer(llvm::Value *addr) const;
00101 
00102     /// Turn an atomic-layout object into an r-value.
00103     RValue convertTempToRValue(llvm::Value *addr,
00104                                AggValueSlot resultSlot,
00105                                SourceLocation loc) const;
00106 
00107     /// Copy an atomic r-value into atomic-layout memory.
00108     void emitCopyIntoMemory(RValue rvalue, LValue lvalue) const;
00109 
00110     /// Project an l-value down to the value field.
00111     LValue projectValue(LValue lvalue) const {
00112       llvm::Value *addr = lvalue.getAddress();
00113       if (hasPadding())
00114         addr = CGF.Builder.CreateStructGEP(addr, 0);
00115 
00116       return LValue::MakeAddr(addr, getValueType(), lvalue.getAlignment(),
00117                               CGF.getContext(), lvalue.getTBAAInfo());
00118     }
00119 
00120     /// Materialize an atomic r-value in atomic-layout memory.
00121     llvm::Value *materializeRValue(RValue rvalue) const;
00122 
00123   private:
00124     bool requiresMemSetZero(llvm::Type *type) const;
00125   };
00126 }
00127 
00128 static RValue emitAtomicLibcall(CodeGenFunction &CGF,
00129                                 StringRef fnName,
00130                                 QualType resultType,
00131                                 CallArgList &args) {
00132   const CGFunctionInfo &fnInfo =
00133     CGF.CGM.getTypes().arrangeFreeFunctionCall(resultType, args,
00134             FunctionType::ExtInfo(), RequiredArgs::All);
00135   llvm::FunctionType *fnTy = CGF.CGM.getTypes().GetFunctionType(fnInfo);
00136   llvm::Constant *fn = CGF.CGM.CreateRuntimeFunction(fnTy, fnName);
00137   return CGF.EmitCall(fnInfo, fn, ReturnValueSlot(), args);
00138 }
00139 
00140 /// Does a store of the given IR type modify the full expected width?
00141 static bool isFullSizeType(CodeGenModule &CGM, llvm::Type *type,
00142                            uint64_t expectedSize) {
00143   return (CGM.getDataLayout().getTypeStoreSize(type) * 8 == expectedSize);
00144 }
00145 
00146 /// Does the atomic type require memsetting to zero before initialization?
00147 ///
00148 /// The IR type is provided as a way of making certain queries faster.
00149 bool AtomicInfo::requiresMemSetZero(llvm::Type *type) const {
00150   // If the atomic type has size padding, we definitely need a memset.
00151   if (hasPadding()) return true;
00152 
00153   // Otherwise, do some simple heuristics to try to avoid it:
00154   switch (getEvaluationKind()) {
00155   // For scalars and complexes, check whether the store size of the
00156   // type uses the full size.
00157   case TEK_Scalar:
00158     return !isFullSizeType(CGF.CGM, type, AtomicSizeInBits);
00159   case TEK_Complex:
00160     return !isFullSizeType(CGF.CGM, type->getStructElementType(0),
00161                            AtomicSizeInBits / 2);
00162 
00163   // Padding in structs has an undefined bit pattern.  User beware.
00164   case TEK_Aggregate:
00165     return false;
00166   }
00167   llvm_unreachable("bad evaluation kind");
00168 }
00169 
00170 bool AtomicInfo::emitMemSetZeroIfNecessary(LValue dest) const {
00171   llvm::Value *addr = dest.getAddress();
00172   if (!requiresMemSetZero(addr->getType()->getPointerElementType()))
00173     return false;
00174 
00175   CGF.Builder.CreateMemSet(addr, llvm::ConstantInt::get(CGF.Int8Ty, 0),
00176                            AtomicSizeInBits / 8,
00177                            dest.getAlignment().getQuantity());
00178   return true;
00179 }
00180 
00181 static void emitAtomicCmpXchg(CodeGenFunction &CGF, AtomicExpr *E, bool IsWeak,
00182                               llvm::Value *Dest, llvm::Value *Ptr,
00183                               llvm::Value *Val1, llvm::Value *Val2,
00184                               uint64_t Size, unsigned Align,
00185                               llvm::AtomicOrdering SuccessOrder,
00186                               llvm::AtomicOrdering FailureOrder) {
00187   // Note that cmpxchg doesn't support weak cmpxchg, at least at the moment.
00188   llvm::LoadInst *Expected = CGF.Builder.CreateLoad(Val1);
00189   Expected->setAlignment(Align);
00190   llvm::LoadInst *Desired = CGF.Builder.CreateLoad(Val2);
00191   Desired->setAlignment(Align);
00192 
00193   llvm::AtomicCmpXchgInst *Pair = CGF.Builder.CreateAtomicCmpXchg(
00194       Ptr, Expected, Desired, SuccessOrder, FailureOrder);
00195   Pair->setVolatile(E->isVolatile());
00196   Pair->setWeak(IsWeak);
00197 
00198   // Cmp holds the result of the compare-exchange operation: true on success,
00199   // false on failure.
00200   llvm::Value *Old = CGF.Builder.CreateExtractValue(Pair, 0);
00201   llvm::Value *Cmp = CGF.Builder.CreateExtractValue(Pair, 1);
00202 
00203   // This basic block is used to hold the store instruction if the operation
00204   // failed.
00205   llvm::BasicBlock *StoreExpectedBB =
00206       CGF.createBasicBlock("cmpxchg.store_expected", CGF.CurFn);
00207 
00208   // This basic block is the exit point of the operation, we should end up
00209   // here regardless of whether or not the operation succeeded.
00210   llvm::BasicBlock *ContinueBB =
00211       CGF.createBasicBlock("cmpxchg.continue", CGF.CurFn);
00212 
00213   // Update Expected if Expected isn't equal to Old, otherwise branch to the
00214   // exit point.
00215   CGF.Builder.CreateCondBr(Cmp, ContinueBB, StoreExpectedBB);
00216 
00217   CGF.Builder.SetInsertPoint(StoreExpectedBB);
00218   // Update the memory at Expected with Old's value.
00219   llvm::StoreInst *StoreExpected = CGF.Builder.CreateStore(Old, Val1);
00220   StoreExpected->setAlignment(Align);
00221   // Finally, branch to the exit point.
00222   CGF.Builder.CreateBr(ContinueBB);
00223 
00224   CGF.Builder.SetInsertPoint(ContinueBB);
00225   // Update the memory at Dest with Cmp's value.
00226   CGF.EmitStoreOfScalar(Cmp, CGF.MakeAddrLValue(Dest, E->getType()));
00227   return;
00228 }
00229 
00230 /// Given an ordering required on success, emit all possible cmpxchg
00231 /// instructions to cope with the provided (but possibly only dynamically known)
00232 /// FailureOrder.
00233 static void emitAtomicCmpXchgFailureSet(CodeGenFunction &CGF, AtomicExpr *E,
00234                                         bool IsWeak, llvm::Value *Dest,
00235                                         llvm::Value *Ptr, llvm::Value *Val1,
00236                                         llvm::Value *Val2,
00237                                         llvm::Value *FailureOrderVal,
00238                                         uint64_t Size, unsigned Align,
00239                                         llvm::AtomicOrdering SuccessOrder) {
00240   llvm::AtomicOrdering FailureOrder;
00241   if (llvm::ConstantInt *FO = dyn_cast<llvm::ConstantInt>(FailureOrderVal)) {
00242     switch (FO->getSExtValue()) {
00243     default:
00244       FailureOrder = llvm::Monotonic;
00245       break;
00246     case AtomicExpr::AO_ABI_memory_order_consume:
00247     case AtomicExpr::AO_ABI_memory_order_acquire:
00248       FailureOrder = llvm::Acquire;
00249       break;
00250     case AtomicExpr::AO_ABI_memory_order_seq_cst:
00251       FailureOrder = llvm::SequentiallyConsistent;
00252       break;
00253     }
00254     if (FailureOrder >= SuccessOrder) {
00255       // Don't assert on undefined behaviour.
00256       FailureOrder =
00257         llvm::AtomicCmpXchgInst::getStrongestFailureOrdering(SuccessOrder);
00258     }
00259     emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, Size, Align,
00260                       SuccessOrder, FailureOrder);
00261     return;
00262   }
00263 
00264   // Create all the relevant BB's
00265   llvm::BasicBlock *MonotonicBB = nullptr, *AcquireBB = nullptr,
00266                    *SeqCstBB = nullptr;
00267   MonotonicBB = CGF.createBasicBlock("monotonic_fail", CGF.CurFn);
00268   if (SuccessOrder != llvm::Monotonic && SuccessOrder != llvm::Release)
00269     AcquireBB = CGF.createBasicBlock("acquire_fail", CGF.CurFn);
00270   if (SuccessOrder == llvm::SequentiallyConsistent)
00271     SeqCstBB = CGF.createBasicBlock("seqcst_fail", CGF.CurFn);
00272 
00273   llvm::BasicBlock *ContBB = CGF.createBasicBlock("atomic.continue", CGF.CurFn);
00274 
00275   llvm::SwitchInst *SI = CGF.Builder.CreateSwitch(FailureOrderVal, MonotonicBB);
00276 
00277   // Emit all the different atomics
00278 
00279   // MonotonicBB is arbitrarily chosen as the default case; in practice, this
00280   // doesn't matter unless someone is crazy enough to use something that
00281   // doesn't fold to a constant for the ordering.
00282   CGF.Builder.SetInsertPoint(MonotonicBB);
00283   emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2,
00284                     Size, Align, SuccessOrder, llvm::Monotonic);
00285   CGF.Builder.CreateBr(ContBB);
00286 
00287   if (AcquireBB) {
00288     CGF.Builder.SetInsertPoint(AcquireBB);
00289     emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2,
00290                       Size, Align, SuccessOrder, llvm::Acquire);
00291     CGF.Builder.CreateBr(ContBB);
00292     SI->addCase(CGF.Builder.getInt32(AtomicExpr::AO_ABI_memory_order_consume),
00293                 AcquireBB);
00294     SI->addCase(CGF.Builder.getInt32(AtomicExpr::AO_ABI_memory_order_acquire),
00295                 AcquireBB);
00296   }
00297   if (SeqCstBB) {
00298     CGF.Builder.SetInsertPoint(SeqCstBB);
00299     emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2,
00300                       Size, Align, SuccessOrder, llvm::SequentiallyConsistent);
00301     CGF.Builder.CreateBr(ContBB);
00302     SI->addCase(CGF.Builder.getInt32(AtomicExpr::AO_ABI_memory_order_seq_cst),
00303                 SeqCstBB);
00304   }
00305 
00306   CGF.Builder.SetInsertPoint(ContBB);
00307 }
00308 
00309 static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, llvm::Value *Dest,
00310                          llvm::Value *Ptr, llvm::Value *Val1, llvm::Value *Val2,
00311                          llvm::Value *IsWeak, llvm::Value *FailureOrder,
00312                          uint64_t Size, unsigned Align,
00313                          llvm::AtomicOrdering Order) {
00314   llvm::AtomicRMWInst::BinOp Op = llvm::AtomicRMWInst::Add;
00315   llvm::Instruction::BinaryOps PostOp = (llvm::Instruction::BinaryOps)0;
00316 
00317   switch (E->getOp()) {
00318   case AtomicExpr::AO__c11_atomic_init:
00319     llvm_unreachable("Already handled!");
00320 
00321   case AtomicExpr::AO__c11_atomic_compare_exchange_strong:
00322     emitAtomicCmpXchgFailureSet(CGF, E, false, Dest, Ptr, Val1, Val2,
00323                                 FailureOrder, Size, Align, Order);
00324     return;
00325   case AtomicExpr::AO__c11_atomic_compare_exchange_weak:
00326     emitAtomicCmpXchgFailureSet(CGF, E, true, Dest, Ptr, Val1, Val2,
00327                                 FailureOrder, Size, Align, Order);
00328     return;
00329   case AtomicExpr::AO__atomic_compare_exchange:
00330   case AtomicExpr::AO__atomic_compare_exchange_n: {
00331     if (llvm::ConstantInt *IsWeakC = dyn_cast<llvm::ConstantInt>(IsWeak)) {
00332       emitAtomicCmpXchgFailureSet(CGF, E, IsWeakC->getZExtValue(), Dest, Ptr,
00333                                   Val1, Val2, FailureOrder, Size, Align, Order);
00334     } else {
00335       // Create all the relevant BB's
00336       llvm::BasicBlock *StrongBB =
00337           CGF.createBasicBlock("cmpxchg.strong", CGF.CurFn);
00338       llvm::BasicBlock *WeakBB = CGF.createBasicBlock("cmxchg.weak", CGF.CurFn);
00339       llvm::BasicBlock *ContBB =
00340           CGF.createBasicBlock("cmpxchg.continue", CGF.CurFn);
00341 
00342       llvm::SwitchInst *SI = CGF.Builder.CreateSwitch(IsWeak, WeakBB);
00343       SI->addCase(CGF.Builder.getInt1(false), StrongBB);
00344 
00345       CGF.Builder.SetInsertPoint(StrongBB);
00346       emitAtomicCmpXchgFailureSet(CGF, E, false, Dest, Ptr, Val1, Val2,
00347                                   FailureOrder, Size, Align, Order);
00348       CGF.Builder.CreateBr(ContBB);
00349 
00350       CGF.Builder.SetInsertPoint(WeakBB);
00351       emitAtomicCmpXchgFailureSet(CGF, E, true, Dest, Ptr, Val1, Val2,
00352                                   FailureOrder, Size, Align, Order);
00353       CGF.Builder.CreateBr(ContBB);
00354 
00355       CGF.Builder.SetInsertPoint(ContBB);
00356     }
00357     return;
00358   }
00359   case AtomicExpr::AO__c11_atomic_load:
00360   case AtomicExpr::AO__atomic_load_n:
00361   case AtomicExpr::AO__atomic_load: {
00362     llvm::LoadInst *Load = CGF.Builder.CreateLoad(Ptr);
00363     Load->setAtomic(Order);
00364     Load->setAlignment(Size);
00365     Load->setVolatile(E->isVolatile());
00366     llvm::StoreInst *StoreDest = CGF.Builder.CreateStore(Load, Dest);
00367     StoreDest->setAlignment(Align);
00368     return;
00369   }
00370 
00371   case AtomicExpr::AO__c11_atomic_store:
00372   case AtomicExpr::AO__atomic_store:
00373   case AtomicExpr::AO__atomic_store_n: {
00374     assert(!Dest && "Store does not return a value");
00375     llvm::LoadInst *LoadVal1 = CGF.Builder.CreateLoad(Val1);
00376     LoadVal1->setAlignment(Align);
00377     llvm::StoreInst *Store = CGF.Builder.CreateStore(LoadVal1, Ptr);
00378     Store->setAtomic(Order);
00379     Store->setAlignment(Size);
00380     Store->setVolatile(E->isVolatile());
00381     return;
00382   }
00383 
00384   case AtomicExpr::AO__c11_atomic_exchange:
00385   case AtomicExpr::AO__atomic_exchange_n:
00386   case AtomicExpr::AO__atomic_exchange:
00387     Op = llvm::AtomicRMWInst::Xchg;
00388     break;
00389 
00390   case AtomicExpr::AO__atomic_add_fetch:
00391     PostOp = llvm::Instruction::Add;
00392     // Fall through.
00393   case AtomicExpr::AO__c11_atomic_fetch_add:
00394   case AtomicExpr::AO__atomic_fetch_add:
00395     Op = llvm::AtomicRMWInst::Add;
00396     break;
00397 
00398   case AtomicExpr::AO__atomic_sub_fetch:
00399     PostOp = llvm::Instruction::Sub;
00400     // Fall through.
00401   case AtomicExpr::AO__c11_atomic_fetch_sub:
00402   case AtomicExpr::AO__atomic_fetch_sub:
00403     Op = llvm::AtomicRMWInst::Sub;
00404     break;
00405 
00406   case AtomicExpr::AO__atomic_and_fetch:
00407     PostOp = llvm::Instruction::And;
00408     // Fall through.
00409   case AtomicExpr::AO__c11_atomic_fetch_and:
00410   case AtomicExpr::AO__atomic_fetch_and:
00411     Op = llvm::AtomicRMWInst::And;
00412     break;
00413 
00414   case AtomicExpr::AO__atomic_or_fetch:
00415     PostOp = llvm::Instruction::Or;
00416     // Fall through.
00417   case AtomicExpr::AO__c11_atomic_fetch_or:
00418   case AtomicExpr::AO__atomic_fetch_or:
00419     Op = llvm::AtomicRMWInst::Or;
00420     break;
00421 
00422   case AtomicExpr::AO__atomic_xor_fetch:
00423     PostOp = llvm::Instruction::Xor;
00424     // Fall through.
00425   case AtomicExpr::AO__c11_atomic_fetch_xor:
00426   case AtomicExpr::AO__atomic_fetch_xor:
00427     Op = llvm::AtomicRMWInst::Xor;
00428     break;
00429 
00430   case AtomicExpr::AO__atomic_nand_fetch:
00431     PostOp = llvm::Instruction::And;
00432     // Fall through.
00433   case AtomicExpr::AO__atomic_fetch_nand:
00434     Op = llvm::AtomicRMWInst::Nand;
00435     break;
00436   }
00437 
00438   llvm::LoadInst *LoadVal1 = CGF.Builder.CreateLoad(Val1);
00439   LoadVal1->setAlignment(Align);
00440   llvm::AtomicRMWInst *RMWI =
00441       CGF.Builder.CreateAtomicRMW(Op, Ptr, LoadVal1, Order);
00442   RMWI->setVolatile(E->isVolatile());
00443 
00444   // For __atomic_*_fetch operations, perform the operation again to
00445   // determine the value which was written.
00446   llvm::Value *Result = RMWI;
00447   if (PostOp)
00448     Result = CGF.Builder.CreateBinOp(PostOp, RMWI, LoadVal1);
00449   if (E->getOp() == AtomicExpr::AO__atomic_nand_fetch)
00450     Result = CGF.Builder.CreateNot(Result);
00451   llvm::StoreInst *StoreDest = CGF.Builder.CreateStore(Result, Dest);
00452   StoreDest->setAlignment(Align);
00453 }
00454 
00455 // This function emits any expression (scalar, complex, or aggregate)
00456 // into a temporary alloca.
00457 static llvm::Value *
00458 EmitValToTemp(CodeGenFunction &CGF, Expr *E) {
00459   llvm::Value *DeclPtr = CGF.CreateMemTemp(E->getType(), ".atomictmp");
00460   CGF.EmitAnyExprToMem(E, DeclPtr, E->getType().getQualifiers(),
00461                        /*Init*/ true);
00462   return DeclPtr;
00463 }
00464 
00465 static void
00466 AddDirectArgument(CodeGenFunction &CGF, CallArgList &Args,
00467                   bool UseOptimizedLibcall, llvm::Value *Val, QualType ValTy,
00468                   SourceLocation Loc, CharUnits SizeInChars) {
00469   if (UseOptimizedLibcall) {
00470     // Load value and pass it to the function directly.
00471     unsigned Align = CGF.getContext().getTypeAlignInChars(ValTy).getQuantity();
00472     int64_t SizeInBits = CGF.getContext().toBits(SizeInChars);
00473     ValTy =
00474         CGF.getContext().getIntTypeForBitwidth(SizeInBits, /*Signed=*/false);
00475     llvm::Type *IPtrTy = llvm::IntegerType::get(CGF.getLLVMContext(),
00476                                                 SizeInBits)->getPointerTo();
00477     Val = CGF.EmitLoadOfScalar(CGF.Builder.CreateBitCast(Val, IPtrTy), false,
00478                                Align, CGF.getContext().getPointerType(ValTy),
00479                                Loc);
00480     // Coerce the value into an appropriately sized integer type.
00481     Args.add(RValue::get(Val), ValTy);
00482   } else {
00483     // Non-optimized functions always take a reference.
00484     Args.add(RValue::get(CGF.EmitCastToVoidPtr(Val)),
00485                          CGF.getContext().VoidPtrTy);
00486   }
00487 }
00488 
00489 RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E, llvm::Value *Dest) {
00490   QualType AtomicTy = E->getPtr()->getType()->getPointeeType();
00491   QualType MemTy = AtomicTy;
00492   if (const AtomicType *AT = AtomicTy->getAs<AtomicType>())
00493     MemTy = AT->getValueType();
00494   CharUnits sizeChars = getContext().getTypeSizeInChars(AtomicTy);
00495   uint64_t Size = sizeChars.getQuantity();
00496   CharUnits alignChars = getContext().getTypeAlignInChars(AtomicTy);
00497   unsigned Align = alignChars.getQuantity();
00498   unsigned MaxInlineWidthInBits =
00499     getTarget().getMaxAtomicInlineWidth();
00500   bool UseLibcall = (Size != Align ||
00501                      getContext().toBits(sizeChars) > MaxInlineWidthInBits);
00502 
00503   llvm::Value *IsWeak = nullptr, *OrderFail = nullptr, *Val1 = nullptr,
00504               *Val2 = nullptr;
00505   llvm::Value *Ptr = EmitScalarExpr(E->getPtr());
00506 
00507   if (E->getOp() == AtomicExpr::AO__c11_atomic_init) {
00508     assert(!Dest && "Init does not return a value");
00509     LValue lvalue = LValue::MakeAddr(Ptr, AtomicTy, alignChars, getContext());
00510     EmitAtomicInit(E->getVal1(), lvalue);
00511     return RValue::get(nullptr);
00512   }
00513 
00514   llvm::Value *Order = EmitScalarExpr(E->getOrder());
00515 
00516   switch (E->getOp()) {
00517   case AtomicExpr::AO__c11_atomic_init:
00518     llvm_unreachable("Already handled!");
00519 
00520   case AtomicExpr::AO__c11_atomic_load:
00521   case AtomicExpr::AO__atomic_load_n:
00522     break;
00523 
00524   case AtomicExpr::AO__atomic_load:
00525     Dest = EmitScalarExpr(E->getVal1());
00526     break;
00527 
00528   case AtomicExpr::AO__atomic_store:
00529     Val1 = EmitScalarExpr(E->getVal1());
00530     break;
00531 
00532   case AtomicExpr::AO__atomic_exchange:
00533     Val1 = EmitScalarExpr(E->getVal1());
00534     Dest = EmitScalarExpr(E->getVal2());
00535     break;
00536 
00537   case AtomicExpr::AO__c11_atomic_compare_exchange_strong:
00538   case AtomicExpr::AO__c11_atomic_compare_exchange_weak:
00539   case AtomicExpr::AO__atomic_compare_exchange_n:
00540   case AtomicExpr::AO__atomic_compare_exchange:
00541     Val1 = EmitScalarExpr(E->getVal1());
00542     if (E->getOp() == AtomicExpr::AO__atomic_compare_exchange)
00543       Val2 = EmitScalarExpr(E->getVal2());
00544     else
00545       Val2 = EmitValToTemp(*this, E->getVal2());
00546     OrderFail = EmitScalarExpr(E->getOrderFail());
00547     if (E->getNumSubExprs() == 6)
00548       IsWeak = EmitScalarExpr(E->getWeak());
00549     break;
00550 
00551   case AtomicExpr::AO__c11_atomic_fetch_add:
00552   case AtomicExpr::AO__c11_atomic_fetch_sub:
00553     if (MemTy->isPointerType()) {
00554       // For pointer arithmetic, we're required to do a bit of math:
00555       // adding 1 to an int* is not the same as adding 1 to a uintptr_t.
00556       // ... but only for the C11 builtins. The GNU builtins expect the
00557       // user to multiply by sizeof(T).
00558       QualType Val1Ty = E->getVal1()->getType();
00559       llvm::Value *Val1Scalar = EmitScalarExpr(E->getVal1());
00560       CharUnits PointeeIncAmt =
00561           getContext().getTypeSizeInChars(MemTy->getPointeeType());
00562       Val1Scalar = Builder.CreateMul(Val1Scalar, CGM.getSize(PointeeIncAmt));
00563       Val1 = CreateMemTemp(Val1Ty, ".atomictmp");
00564       EmitStoreOfScalar(Val1Scalar, MakeAddrLValue(Val1, Val1Ty));
00565       break;
00566     }
00567     // Fall through.
00568   case AtomicExpr::AO__atomic_fetch_add:
00569   case AtomicExpr::AO__atomic_fetch_sub:
00570   case AtomicExpr::AO__atomic_add_fetch:
00571   case AtomicExpr::AO__atomic_sub_fetch:
00572   case AtomicExpr::AO__c11_atomic_store:
00573   case AtomicExpr::AO__c11_atomic_exchange:
00574   case AtomicExpr::AO__atomic_store_n:
00575   case AtomicExpr::AO__atomic_exchange_n:
00576   case AtomicExpr::AO__c11_atomic_fetch_and:
00577   case AtomicExpr::AO__c11_atomic_fetch_or:
00578   case AtomicExpr::AO__c11_atomic_fetch_xor:
00579   case AtomicExpr::AO__atomic_fetch_and:
00580   case AtomicExpr::AO__atomic_fetch_or:
00581   case AtomicExpr::AO__atomic_fetch_xor:
00582   case AtomicExpr::AO__atomic_fetch_nand:
00583   case AtomicExpr::AO__atomic_and_fetch:
00584   case AtomicExpr::AO__atomic_or_fetch:
00585   case AtomicExpr::AO__atomic_xor_fetch:
00586   case AtomicExpr::AO__atomic_nand_fetch:
00587     Val1 = EmitValToTemp(*this, E->getVal1());
00588     break;
00589   }
00590 
00591   if (!E->getType()->isVoidType() && !Dest)
00592     Dest = CreateMemTemp(E->getType(), ".atomicdst");
00593 
00594   // Use a library call.  See: http://gcc.gnu.org/wiki/Atomic/GCCMM/LIbrary .
00595   if (UseLibcall) {
00596     bool UseOptimizedLibcall = false;
00597     switch (E->getOp()) {
00598     case AtomicExpr::AO__c11_atomic_fetch_add:
00599     case AtomicExpr::AO__atomic_fetch_add:
00600     case AtomicExpr::AO__c11_atomic_fetch_and:
00601     case AtomicExpr::AO__atomic_fetch_and:
00602     case AtomicExpr::AO__c11_atomic_fetch_or:
00603     case AtomicExpr::AO__atomic_fetch_or:
00604     case AtomicExpr::AO__c11_atomic_fetch_sub:
00605     case AtomicExpr::AO__atomic_fetch_sub:
00606     case AtomicExpr::AO__c11_atomic_fetch_xor:
00607     case AtomicExpr::AO__atomic_fetch_xor:
00608       // For these, only library calls for certain sizes exist.
00609       UseOptimizedLibcall = true;
00610       break;
00611     default:
00612       // Only use optimized library calls for sizes for which they exist.
00613       if (Size == 1 || Size == 2 || Size == 4 || Size == 8)
00614         UseOptimizedLibcall = true;
00615       break;
00616     }
00617 
00618     CallArgList Args;
00619     if (!UseOptimizedLibcall) {
00620       // For non-optimized library calls, the size is the first parameter
00621       Args.add(RValue::get(llvm::ConstantInt::get(SizeTy, Size)),
00622                getContext().getSizeType());
00623     }
00624     // Atomic address is the first or second parameter
00625     Args.add(RValue::get(EmitCastToVoidPtr(Ptr)), getContext().VoidPtrTy);
00626 
00627     std::string LibCallName;
00628     QualType LoweredMemTy =
00629       MemTy->isPointerType() ? getContext().getIntPtrType() : MemTy;
00630     QualType RetTy;
00631     bool HaveRetTy = false;
00632     switch (E->getOp()) {
00633     // There is only one libcall for compare an exchange, because there is no
00634     // optimisation benefit possible from a libcall version of a weak compare
00635     // and exchange.
00636     // bool __atomic_compare_exchange(size_t size, void *mem, void *expected,
00637     //                                void *desired, int success, int failure)
00638     // bool __atomic_compare_exchange_N(T *mem, T *expected, T desired,
00639     //                                  int success, int failure)
00640     case AtomicExpr::AO__c11_atomic_compare_exchange_weak:
00641     case AtomicExpr::AO__c11_atomic_compare_exchange_strong:
00642     case AtomicExpr::AO__atomic_compare_exchange:
00643     case AtomicExpr::AO__atomic_compare_exchange_n:
00644       LibCallName = "__atomic_compare_exchange";
00645       RetTy = getContext().BoolTy;
00646       HaveRetTy = true;
00647       Args.add(RValue::get(EmitCastToVoidPtr(Val1)), getContext().VoidPtrTy);
00648       AddDirectArgument(*this, Args, UseOptimizedLibcall, Val2, MemTy,
00649                         E->getExprLoc(), sizeChars);
00650       Args.add(RValue::get(Order), getContext().IntTy);
00651       Order = OrderFail;
00652       break;
00653     // void __atomic_exchange(size_t size, void *mem, void *val, void *return,
00654     //                        int order)
00655     // T __atomic_exchange_N(T *mem, T val, int order)
00656     case AtomicExpr::AO__c11_atomic_exchange:
00657     case AtomicExpr::AO__atomic_exchange_n:
00658     case AtomicExpr::AO__atomic_exchange:
00659       LibCallName = "__atomic_exchange";
00660       AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1, MemTy,
00661                         E->getExprLoc(), sizeChars);
00662       break;
00663     // void __atomic_store(size_t size, void *mem, void *val, int order)
00664     // void __atomic_store_N(T *mem, T val, int order)
00665     case AtomicExpr::AO__c11_atomic_store:
00666     case AtomicExpr::AO__atomic_store:
00667     case AtomicExpr::AO__atomic_store_n:
00668       LibCallName = "__atomic_store";
00669       RetTy = getContext().VoidTy;
00670       HaveRetTy = true;
00671       AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1, MemTy,
00672                         E->getExprLoc(), sizeChars);
00673       break;
00674     // void __atomic_load(size_t size, void *mem, void *return, int order)
00675     // T __atomic_load_N(T *mem, int order)
00676     case AtomicExpr::AO__c11_atomic_load:
00677     case AtomicExpr::AO__atomic_load:
00678     case AtomicExpr::AO__atomic_load_n:
00679       LibCallName = "__atomic_load";
00680       break;
00681     // T __atomic_fetch_add_N(T *mem, T val, int order)
00682     case AtomicExpr::AO__c11_atomic_fetch_add:
00683     case AtomicExpr::AO__atomic_fetch_add:
00684       LibCallName = "__atomic_fetch_add";
00685       AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1, LoweredMemTy,
00686                         E->getExprLoc(), sizeChars);
00687       break;
00688     // T __atomic_fetch_and_N(T *mem, T val, int order)
00689     case AtomicExpr::AO__c11_atomic_fetch_and:
00690     case AtomicExpr::AO__atomic_fetch_and:
00691       LibCallName = "__atomic_fetch_and";
00692       AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1, MemTy,
00693                         E->getExprLoc(), sizeChars);
00694       break;
00695     // T __atomic_fetch_or_N(T *mem, T val, int order)
00696     case AtomicExpr::AO__c11_atomic_fetch_or:
00697     case AtomicExpr::AO__atomic_fetch_or:
00698       LibCallName = "__atomic_fetch_or";
00699       AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1, MemTy,
00700                         E->getExprLoc(), sizeChars);
00701       break;
00702     // T __atomic_fetch_sub_N(T *mem, T val, int order)
00703     case AtomicExpr::AO__c11_atomic_fetch_sub:
00704     case AtomicExpr::AO__atomic_fetch_sub:
00705       LibCallName = "__atomic_fetch_sub";
00706       AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1, LoweredMemTy,
00707                         E->getExprLoc(), sizeChars);
00708       break;
00709     // T __atomic_fetch_xor_N(T *mem, T val, int order)
00710     case AtomicExpr::AO__c11_atomic_fetch_xor:
00711     case AtomicExpr::AO__atomic_fetch_xor:
00712       LibCallName = "__atomic_fetch_xor";
00713       AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1, MemTy,
00714                         E->getExprLoc(), sizeChars);
00715       break;
00716     default: return EmitUnsupportedRValue(E, "atomic library call");
00717     }
00718 
00719     // Optimized functions have the size in their name.
00720     if (UseOptimizedLibcall)
00721       LibCallName += "_" + llvm::utostr(Size);
00722     // By default, assume we return a value of the atomic type.
00723     if (!HaveRetTy) {
00724       if (UseOptimizedLibcall) {
00725         // Value is returned directly.
00726         // The function returns an appropriately sized integer type.
00727         RetTy = getContext().getIntTypeForBitwidth(
00728             getContext().toBits(sizeChars), /*Signed=*/false);
00729       } else {
00730         // Value is returned through parameter before the order.
00731         RetTy = getContext().VoidTy;
00732         Args.add(RValue::get(EmitCastToVoidPtr(Dest)),
00733                  getContext().VoidPtrTy);
00734       }
00735     }
00736     // order is always the last parameter
00737     Args.add(RValue::get(Order),
00738              getContext().IntTy);
00739 
00740     const CGFunctionInfo &FuncInfo =
00741         CGM.getTypes().arrangeFreeFunctionCall(RetTy, Args,
00742             FunctionType::ExtInfo(), RequiredArgs::All);
00743     llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FuncInfo);
00744     llvm::Constant *Func = CGM.CreateRuntimeFunction(FTy, LibCallName);
00745     RValue Res = EmitCall(FuncInfo, Func, ReturnValueSlot(), Args);
00746     if (!RetTy->isVoidType()) {
00747       if (UseOptimizedLibcall) {
00748         if (HaveRetTy)
00749           return Res;
00750         llvm::StoreInst *StoreDest = Builder.CreateStore(
00751             Res.getScalarVal(),
00752             Builder.CreateBitCast(Dest, FTy->getReturnType()->getPointerTo()));
00753         StoreDest->setAlignment(Align);
00754       }
00755     }
00756     if (E->getType()->isVoidType())
00757       return RValue::get(nullptr);
00758     return convertTempToRValue(Dest, E->getType(), E->getExprLoc());
00759   }
00760 
00761   bool IsStore = E->getOp() == AtomicExpr::AO__c11_atomic_store ||
00762                  E->getOp() == AtomicExpr::AO__atomic_store ||
00763                  E->getOp() == AtomicExpr::AO__atomic_store_n;
00764   bool IsLoad = E->getOp() == AtomicExpr::AO__c11_atomic_load ||
00765                 E->getOp() == AtomicExpr::AO__atomic_load ||
00766                 E->getOp() == AtomicExpr::AO__atomic_load_n;
00767 
00768   llvm::Type *IPtrTy =
00769       llvm::IntegerType::get(getLLVMContext(), Size * 8)->getPointerTo();
00770   llvm::Value *OrigDest = Dest;
00771   Ptr = Builder.CreateBitCast(Ptr, IPtrTy);
00772   if (Val1) Val1 = Builder.CreateBitCast(Val1, IPtrTy);
00773   if (Val2) Val2 = Builder.CreateBitCast(Val2, IPtrTy);
00774   if (Dest && !E->isCmpXChg()) Dest = Builder.CreateBitCast(Dest, IPtrTy);
00775 
00776   if (isa<llvm::ConstantInt>(Order)) {
00777     int ord = cast<llvm::ConstantInt>(Order)->getZExtValue();
00778     switch (ord) {
00779     case AtomicExpr::AO_ABI_memory_order_relaxed:
00780       EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail,
00781                    Size, Align, llvm::Monotonic);
00782       break;
00783     case AtomicExpr::AO_ABI_memory_order_consume:
00784     case AtomicExpr::AO_ABI_memory_order_acquire:
00785       if (IsStore)
00786         break; // Avoid crashing on code with undefined behavior
00787       EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail,
00788                    Size, Align, llvm::Acquire);
00789       break;
00790     case AtomicExpr::AO_ABI_memory_order_release:
00791       if (IsLoad)
00792         break; // Avoid crashing on code with undefined behavior
00793       EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail,
00794                    Size, Align, llvm::Release);
00795       break;
00796     case AtomicExpr::AO_ABI_memory_order_acq_rel:
00797       if (IsLoad || IsStore)
00798         break; // Avoid crashing on code with undefined behavior
00799       EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail,
00800                    Size, Align, llvm::AcquireRelease);
00801       break;
00802     case AtomicExpr::AO_ABI_memory_order_seq_cst:
00803       EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail,
00804                    Size, Align, llvm::SequentiallyConsistent);
00805       break;
00806     default: // invalid order
00807       // We should not ever get here normally, but it's hard to
00808       // enforce that in general.
00809       break;
00810     }
00811     if (E->getType()->isVoidType())
00812       return RValue::get(nullptr);
00813     return convertTempToRValue(OrigDest, E->getType(), E->getExprLoc());
00814   }
00815 
00816   // Long case, when Order isn't obviously constant.
00817 
00818   // Create all the relevant BB's
00819   llvm::BasicBlock *MonotonicBB = nullptr, *AcquireBB = nullptr,
00820                    *ReleaseBB = nullptr, *AcqRelBB = nullptr,
00821                    *SeqCstBB = nullptr;
00822   MonotonicBB = createBasicBlock("monotonic", CurFn);
00823   if (!IsStore)
00824     AcquireBB = createBasicBlock("acquire", CurFn);
00825   if (!IsLoad)
00826     ReleaseBB = createBasicBlock("release", CurFn);
00827   if (!IsLoad && !IsStore)
00828     AcqRelBB = createBasicBlock("acqrel", CurFn);
00829   SeqCstBB = createBasicBlock("seqcst", CurFn);
00830   llvm::BasicBlock *ContBB = createBasicBlock("atomic.continue", CurFn);
00831 
00832   // Create the switch for the split
00833   // MonotonicBB is arbitrarily chosen as the default case; in practice, this
00834   // doesn't matter unless someone is crazy enough to use something that
00835   // doesn't fold to a constant for the ordering.
00836   Order = Builder.CreateIntCast(Order, Builder.getInt32Ty(), false);
00837   llvm::SwitchInst *SI = Builder.CreateSwitch(Order, MonotonicBB);
00838 
00839   // Emit all the different atomics
00840   Builder.SetInsertPoint(MonotonicBB);
00841   EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail,
00842                Size, Align, llvm::Monotonic);
00843   Builder.CreateBr(ContBB);
00844   if (!IsStore) {
00845     Builder.SetInsertPoint(AcquireBB);
00846     EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail,
00847                  Size, Align, llvm::Acquire);
00848     Builder.CreateBr(ContBB);
00849     SI->addCase(Builder.getInt32(AtomicExpr::AO_ABI_memory_order_consume),
00850                 AcquireBB);
00851     SI->addCase(Builder.getInt32(AtomicExpr::AO_ABI_memory_order_acquire),
00852                 AcquireBB);
00853   }
00854   if (!IsLoad) {
00855     Builder.SetInsertPoint(ReleaseBB);
00856     EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail,
00857                  Size, Align, llvm::Release);
00858     Builder.CreateBr(ContBB);
00859     SI->addCase(Builder.getInt32(AtomicExpr::AO_ABI_memory_order_release),
00860                 ReleaseBB);
00861   }
00862   if (!IsLoad && !IsStore) {
00863     Builder.SetInsertPoint(AcqRelBB);
00864     EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail,
00865                  Size, Align, llvm::AcquireRelease);
00866     Builder.CreateBr(ContBB);
00867     SI->addCase(Builder.getInt32(AtomicExpr::AO_ABI_memory_order_acq_rel),
00868                 AcqRelBB);
00869   }
00870   Builder.SetInsertPoint(SeqCstBB);
00871   EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail,
00872                Size, Align, llvm::SequentiallyConsistent);
00873   Builder.CreateBr(ContBB);
00874   SI->addCase(Builder.getInt32(AtomicExpr::AO_ABI_memory_order_seq_cst),
00875               SeqCstBB);
00876 
00877   // Cleanup and return
00878   Builder.SetInsertPoint(ContBB);
00879   if (E->getType()->isVoidType())
00880     return RValue::get(nullptr);
00881   return convertTempToRValue(OrigDest, E->getType(), E->getExprLoc());
00882 }
00883 
00884 llvm::Value *AtomicInfo::emitCastToAtomicIntPointer(llvm::Value *addr) const {
00885   unsigned addrspace =
00886     cast<llvm::PointerType>(addr->getType())->getAddressSpace();
00887   llvm::IntegerType *ty =
00888     llvm::IntegerType::get(CGF.getLLVMContext(), AtomicSizeInBits);
00889   return CGF.Builder.CreateBitCast(addr, ty->getPointerTo(addrspace));
00890 }
00891 
00892 RValue AtomicInfo::convertTempToRValue(llvm::Value *addr,
00893                                        AggValueSlot resultSlot,
00894                                        SourceLocation loc) const {
00895   if (EvaluationKind == TEK_Aggregate)
00896     return resultSlot.asRValue();
00897 
00898   // Drill into the padding structure if we have one.
00899   if (hasPadding())
00900     addr = CGF.Builder.CreateStructGEP(addr, 0);
00901 
00902   // Otherwise, just convert the temporary to an r-value using the
00903   // normal conversion routine.
00904   return CGF.convertTempToRValue(addr, getValueType(), loc);
00905 }
00906 
00907 /// Emit a load from an l-value of atomic type.  Note that the r-value
00908 /// we produce is an r-value of the atomic *value* type.
00909 RValue CodeGenFunction::EmitAtomicLoad(LValue src, SourceLocation loc,
00910                                        AggValueSlot resultSlot) {
00911   AtomicInfo atomics(*this, src);
00912 
00913   // Check whether we should use a library call.
00914   if (atomics.shouldUseLibcall()) {
00915     llvm::Value *tempAddr;
00916     if (!resultSlot.isIgnored()) {
00917       assert(atomics.getEvaluationKind() == TEK_Aggregate);
00918       tempAddr = resultSlot.getAddr();
00919     } else {
00920       tempAddr = CreateMemTemp(atomics.getAtomicType(), "atomic-load-temp");
00921     }
00922 
00923     // void __atomic_load(size_t size, void *mem, void *return, int order);
00924     CallArgList args;
00925     args.add(RValue::get(atomics.getAtomicSizeValue()),
00926              getContext().getSizeType());
00927     args.add(RValue::get(EmitCastToVoidPtr(src.getAddress())),
00928              getContext().VoidPtrTy);
00929     args.add(RValue::get(EmitCastToVoidPtr(tempAddr)),
00930              getContext().VoidPtrTy);
00931     args.add(RValue::get(llvm::ConstantInt::get(
00932                  IntTy, AtomicExpr::AO_ABI_memory_order_seq_cst)),
00933              getContext().IntTy);
00934     emitAtomicLibcall(*this, "__atomic_load", getContext().VoidTy, args);
00935 
00936     // Produce the r-value.
00937     return atomics.convertTempToRValue(tempAddr, resultSlot, loc);
00938   }
00939 
00940   // Okay, we're doing this natively.
00941   llvm::Value *addr = atomics.emitCastToAtomicIntPointer(src.getAddress());
00942   llvm::LoadInst *load = Builder.CreateLoad(addr, "atomic-load");
00943   load->setAtomic(llvm::SequentiallyConsistent);
00944 
00945   // Other decoration.
00946   load->setAlignment(src.getAlignment().getQuantity());
00947   if (src.isVolatileQualified())
00948     load->setVolatile(true);
00949   if (src.getTBAAInfo())
00950     CGM.DecorateInstruction(load, src.getTBAAInfo());
00951 
00952   // Okay, turn that back into the original value type.
00953   QualType valueType = atomics.getValueType();
00954   llvm::Value *result = load;
00955 
00956   // If we're ignoring an aggregate return, don't do anything.
00957   if (atomics.getEvaluationKind() == TEK_Aggregate && resultSlot.isIgnored())
00958     return RValue::getAggregate(nullptr, false);
00959 
00960   // The easiest way to do this this is to go through memory, but we
00961   // try not to in some easy cases.
00962   if (atomics.getEvaluationKind() == TEK_Scalar && !atomics.hasPadding()) {
00963     llvm::Type *resultTy = CGM.getTypes().ConvertTypeForMem(valueType);
00964     if (isa<llvm::IntegerType>(resultTy)) {
00965       assert(result->getType() == resultTy);
00966       result = EmitFromMemory(result, valueType);
00967     } else if (isa<llvm::PointerType>(resultTy)) {
00968       result = Builder.CreateIntToPtr(result, resultTy);
00969     } else {
00970       result = Builder.CreateBitCast(result, resultTy);
00971     }
00972     return RValue::get(result);
00973   }
00974 
00975   // Create a temporary.  This needs to be big enough to hold the
00976   // atomic integer.
00977   llvm::Value *temp;
00978   bool tempIsVolatile = false;
00979   CharUnits tempAlignment;
00980   if (atomics.getEvaluationKind() == TEK_Aggregate) {
00981     assert(!resultSlot.isIgnored());
00982     temp = resultSlot.getAddr();
00983     tempAlignment = atomics.getValueAlignment();
00984     tempIsVolatile = resultSlot.isVolatile();
00985   } else {
00986     temp = CreateMemTemp(atomics.getAtomicType(), "atomic-load-temp");
00987     tempAlignment = atomics.getAtomicAlignment();
00988   }
00989 
00990   // Slam the integer into the temporary.
00991   llvm::Value *castTemp = atomics.emitCastToAtomicIntPointer(temp);
00992   Builder.CreateAlignedStore(result, castTemp, tempAlignment.getQuantity())
00993     ->setVolatile(tempIsVolatile);
00994 
00995   return atomics.convertTempToRValue(temp, resultSlot, loc);
00996 }
00997 
00998 
00999 
01000 /// Copy an r-value into memory as part of storing to an atomic type.
01001 /// This needs to create a bit-pattern suitable for atomic operations.
01002 void AtomicInfo::emitCopyIntoMemory(RValue rvalue, LValue dest) const {
01003   // If we have an r-value, the rvalue should be of the atomic type,
01004   // which means that the caller is responsible for having zeroed
01005   // any padding.  Just do an aggregate copy of that type.
01006   if (rvalue.isAggregate()) {
01007     CGF.EmitAggregateCopy(dest.getAddress(),
01008                           rvalue.getAggregateAddr(),
01009                           getAtomicType(),
01010                           (rvalue.isVolatileQualified()
01011                            || dest.isVolatileQualified()),
01012                           dest.getAlignment());
01013     return;
01014   }
01015 
01016   // Okay, otherwise we're copying stuff.
01017 
01018   // Zero out the buffer if necessary.
01019   emitMemSetZeroIfNecessary(dest);
01020 
01021   // Drill past the padding if present.
01022   dest = projectValue(dest);
01023 
01024   // Okay, store the rvalue in.
01025   if (rvalue.isScalar()) {
01026     CGF.EmitStoreOfScalar(rvalue.getScalarVal(), dest, /*init*/ true);
01027   } else {
01028     CGF.EmitStoreOfComplex(rvalue.getComplexVal(), dest, /*init*/ true);
01029   }
01030 }
01031 
01032 
01033 /// Materialize an r-value into memory for the purposes of storing it
01034 /// to an atomic type.
01035 llvm::Value *AtomicInfo::materializeRValue(RValue rvalue) const {
01036   // Aggregate r-values are already in memory, and EmitAtomicStore
01037   // requires them to be values of the atomic type.
01038   if (rvalue.isAggregate())
01039     return rvalue.getAggregateAddr();
01040 
01041   // Otherwise, make a temporary and materialize into it.
01042   llvm::Value *temp = CGF.CreateMemTemp(getAtomicType(), "atomic-store-temp");
01043   LValue tempLV = CGF.MakeAddrLValue(temp, getAtomicType(), getAtomicAlignment());
01044   emitCopyIntoMemory(rvalue, tempLV);
01045   return temp;
01046 }
01047 
01048 /// Emit a store to an l-value of atomic type.
01049 ///
01050 /// Note that the r-value is expected to be an r-value *of the atomic
01051 /// type*; this means that for aggregate r-values, it should include
01052 /// storage for any padding that was necessary.
01053 void CodeGenFunction::EmitAtomicStore(RValue rvalue, LValue dest, bool isInit) {
01054   // If this is an aggregate r-value, it should agree in type except
01055   // maybe for address-space qualification.
01056   assert(!rvalue.isAggregate() ||
01057          rvalue.getAggregateAddr()->getType()->getPointerElementType()
01058            == dest.getAddress()->getType()->getPointerElementType());
01059 
01060   AtomicInfo atomics(*this, dest);
01061 
01062   // If this is an initialization, just put the value there normally.
01063   if (isInit) {
01064     atomics.emitCopyIntoMemory(rvalue, dest);
01065     return;
01066   }
01067 
01068   // Check whether we should use a library call.
01069   if (atomics.shouldUseLibcall()) {
01070     // Produce a source address.
01071     llvm::Value *srcAddr = atomics.materializeRValue(rvalue);
01072 
01073     // void __atomic_store(size_t size, void *mem, void *val, int order)
01074     CallArgList args;
01075     args.add(RValue::get(atomics.getAtomicSizeValue()),
01076              getContext().getSizeType());
01077     args.add(RValue::get(EmitCastToVoidPtr(dest.getAddress())),
01078              getContext().VoidPtrTy);
01079     args.add(RValue::get(EmitCastToVoidPtr(srcAddr)),
01080              getContext().VoidPtrTy);
01081     args.add(RValue::get(llvm::ConstantInt::get(
01082                  IntTy, AtomicExpr::AO_ABI_memory_order_seq_cst)),
01083              getContext().IntTy);
01084     emitAtomicLibcall(*this, "__atomic_store", getContext().VoidTy, args);
01085     return;
01086   }
01087 
01088   // Okay, we're doing this natively.
01089   llvm::Value *intValue;
01090 
01091   // If we've got a scalar value of the right size, try to avoid going
01092   // through memory.
01093   if (rvalue.isScalar() && !atomics.hasPadding()) {
01094     llvm::Value *value = rvalue.getScalarVal();
01095     if (isa<llvm::IntegerType>(value->getType())) {
01096       intValue = value;
01097     } else {
01098       llvm::IntegerType *inputIntTy =
01099         llvm::IntegerType::get(getLLVMContext(), atomics.getValueSizeInBits());
01100       if (isa<llvm::PointerType>(value->getType())) {
01101         intValue = Builder.CreatePtrToInt(value, inputIntTy);
01102       } else {
01103         intValue = Builder.CreateBitCast(value, inputIntTy);
01104       }
01105     }
01106 
01107   // Otherwise, we need to go through memory.
01108   } else {
01109     // Put the r-value in memory.
01110     llvm::Value *addr = atomics.materializeRValue(rvalue);
01111 
01112     // Cast the temporary to the atomic int type and pull a value out.
01113     addr = atomics.emitCastToAtomicIntPointer(addr);
01114     intValue = Builder.CreateAlignedLoad(addr,
01115                                  atomics.getAtomicAlignment().getQuantity());
01116   }
01117 
01118   // Do the atomic store.
01119   llvm::Value *addr = atomics.emitCastToAtomicIntPointer(dest.getAddress());
01120   llvm::StoreInst *store = Builder.CreateStore(intValue, addr);
01121 
01122   // Initializations don't need to be atomic.
01123   if (!isInit) store->setAtomic(llvm::SequentiallyConsistent);
01124 
01125   // Other decoration.
01126   store->setAlignment(dest.getAlignment().getQuantity());
01127   if (dest.isVolatileQualified())
01128     store->setVolatile(true);
01129   if (dest.getTBAAInfo())
01130     CGM.DecorateInstruction(store, dest.getTBAAInfo());
01131 }
01132 
01133 void CodeGenFunction::EmitAtomicInit(Expr *init, LValue dest) {
01134   AtomicInfo atomics(*this, dest);
01135 
01136   switch (atomics.getEvaluationKind()) {
01137   case TEK_Scalar: {
01138     llvm::Value *value = EmitScalarExpr(init);
01139     atomics.emitCopyIntoMemory(RValue::get(value), dest);
01140     return;
01141   }
01142 
01143   case TEK_Complex: {
01144     ComplexPairTy value = EmitComplexExpr(init);
01145     atomics.emitCopyIntoMemory(RValue::getComplex(value), dest);
01146     return;
01147   }
01148 
01149   case TEK_Aggregate: {
01150     // Fix up the destination if the initializer isn't an expression
01151     // of atomic type.
01152     bool Zeroed = false;
01153     if (!init->getType()->isAtomicType()) {
01154       Zeroed = atomics.emitMemSetZeroIfNecessary(dest);
01155       dest = atomics.projectValue(dest);
01156     }
01157 
01158     // Evaluate the expression directly into the destination.
01159     AggValueSlot slot = AggValueSlot::forLValue(dest,
01160                                         AggValueSlot::IsNotDestructed,
01161                                         AggValueSlot::DoesNotNeedGCBarriers,
01162                                         AggValueSlot::IsNotAliased,
01163                                         Zeroed ? AggValueSlot::IsZeroed :
01164                                                  AggValueSlot::IsNotZeroed);
01165 
01166     EmitAggExpr(init, slot);
01167     return;
01168   }
01169   }
01170   llvm_unreachable("bad evaluation kind");
01171 }