1 //===--- CGAtomic.cpp - Emit LLVM IR for atomic operations ----------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file contains the code for emitting atomic operations. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "CodeGenFunction.h" 15 #include "CGCall.h" 16 #include "CGRecordLayout.h" 17 #include "CodeGenModule.h" 18 #include "clang/AST/ASTContext.h" 19 #include "clang/CodeGen/CGFunctionInfo.h" 20 #include "llvm/ADT/StringExtras.h" 21 #include "llvm/IR/DataLayout.h" 22 #include "llvm/IR/Intrinsics.h" 23 #include "llvm/IR/Operator.h" 24 25 using namespace clang; 26 using namespace CodeGen; 27 28 namespace { 29 class AtomicInfo { 30 CodeGenFunction &CGF; 31 QualType AtomicTy; 32 QualType ValueTy; 33 uint64_t AtomicSizeInBits; 34 uint64_t ValueSizeInBits; 35 CharUnits AtomicAlign; 36 CharUnits ValueAlign; 37 CharUnits LValueAlign; 38 TypeEvaluationKind EvaluationKind; 39 bool UseLibcall; 40 LValue LVal; 41 CGBitFieldInfo BFI; 42 public: 43 AtomicInfo(CodeGenFunction &CGF, LValue &lvalue) 44 : CGF(CGF), AtomicSizeInBits(0), ValueSizeInBits(0), 45 EvaluationKind(TEK_Scalar), UseLibcall(true) { 46 assert(!lvalue.isGlobalReg()); 47 ASTContext &C = CGF.getContext(); 48 if (lvalue.isSimple()) { 49 AtomicTy = lvalue.getType(); 50 if (auto *ATy = AtomicTy->getAs<AtomicType>()) 51 ValueTy = ATy->getValueType(); 52 else 53 ValueTy = AtomicTy; 54 EvaluationKind = CGF.getEvaluationKind(ValueTy); 55 56 uint64_t ValueAlignInBits; 57 uint64_t AtomicAlignInBits; 58 TypeInfo ValueTI = C.getTypeInfo(ValueTy); 59 ValueSizeInBits = ValueTI.Width; 60 ValueAlignInBits = ValueTI.Align; 61 62 TypeInfo AtomicTI = C.getTypeInfo(AtomicTy); 63 AtomicSizeInBits = AtomicTI.Width; 64 AtomicAlignInBits = AtomicTI.Align; 65 66 assert(ValueSizeInBits <= AtomicSizeInBits); 67 assert(ValueAlignInBits <= AtomicAlignInBits); 68 69 AtomicAlign = C.toCharUnitsFromBits(AtomicAlignInBits); 70 ValueAlign = C.toCharUnitsFromBits(ValueAlignInBits); 71 if (lvalue.getAlignment().isZero()) 72 lvalue.setAlignment(AtomicAlign); 73 74 LVal = lvalue; 75 } else if (lvalue.isBitField()) { 76 ValueTy = lvalue.getType(); 77 ValueSizeInBits = C.getTypeSize(ValueTy); 78 auto &OrigBFI = lvalue.getBitFieldInfo(); 79 auto Offset = OrigBFI.Offset % C.toBits(lvalue.getAlignment()); 80 AtomicSizeInBits = C.toBits( 81 C.toCharUnitsFromBits(Offset + OrigBFI.Size + C.getCharWidth() - 1) 82 .alignTo(lvalue.getAlignment())); 83 auto VoidPtrAddr = CGF.EmitCastToVoidPtr(lvalue.getBitFieldPointer()); 84 auto OffsetInChars = 85 (C.toCharUnitsFromBits(OrigBFI.Offset) / lvalue.getAlignment()) * 86 lvalue.getAlignment(); 87 VoidPtrAddr = CGF.Builder.CreateConstGEP1_64( 88 VoidPtrAddr, OffsetInChars.getQuantity()); 89 auto Addr = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( 90 VoidPtrAddr, 91 CGF.Builder.getIntNTy(AtomicSizeInBits)->getPointerTo(), 92 "atomic_bitfield_base"); 93 BFI = OrigBFI; 94 BFI.Offset = Offset; 95 BFI.StorageSize = AtomicSizeInBits; 96 BFI.StorageOffset += OffsetInChars; 97 LVal = LValue::MakeBitfield(Address(Addr, lvalue.getAlignment()), 98 BFI, lvalue.getType(), 99 lvalue.getAlignmentSource()); 100 LVal.setTBAAInfo(lvalue.getTBAAInfo()); 101 AtomicTy = C.getIntTypeForBitwidth(AtomicSizeInBits, OrigBFI.IsSigned); 102 if (AtomicTy.isNull()) { 103 llvm::APInt Size( 104 /*numBits=*/32, 105 C.toCharUnitsFromBits(AtomicSizeInBits).getQuantity()); 106 AtomicTy = C.getConstantArrayType(C.CharTy, Size, ArrayType::Normal, 107 /*IndexTypeQuals=*/0); 108 } 109 AtomicAlign = ValueAlign = lvalue.getAlignment(); 110 } else if (lvalue.isVectorElt()) { 111 ValueTy = lvalue.getType()->getAs<VectorType>()->getElementType(); 112 ValueSizeInBits = C.getTypeSize(ValueTy); 113 AtomicTy = lvalue.getType(); 114 AtomicSizeInBits = C.getTypeSize(AtomicTy); 115 AtomicAlign = ValueAlign = lvalue.getAlignment(); 116 LVal = lvalue; 117 } else { 118 assert(lvalue.isExtVectorElt()); 119 ValueTy = lvalue.getType(); 120 ValueSizeInBits = C.getTypeSize(ValueTy); 121 AtomicTy = ValueTy = CGF.getContext().getExtVectorType( 122 lvalue.getType(), lvalue.getExtVectorAddress() 123 .getElementType()->getVectorNumElements()); 124 AtomicSizeInBits = C.getTypeSize(AtomicTy); 125 AtomicAlign = ValueAlign = lvalue.getAlignment(); 126 LVal = lvalue; 127 } 128 UseLibcall = !C.getTargetInfo().hasBuiltinAtomic( 129 AtomicSizeInBits, C.toBits(lvalue.getAlignment())); 130 } 131 132 QualType getAtomicType() const { return AtomicTy; } 133 QualType getValueType() const { return ValueTy; } 134 CharUnits getAtomicAlignment() const { return AtomicAlign; } 135 CharUnits getValueAlignment() const { return ValueAlign; } 136 uint64_t getAtomicSizeInBits() const { return AtomicSizeInBits; } 137 uint64_t getValueSizeInBits() const { return ValueSizeInBits; } 138 TypeEvaluationKind getEvaluationKind() const { return EvaluationKind; } 139 bool shouldUseLibcall() const { return UseLibcall; } 140 const LValue &getAtomicLValue() const { return LVal; } 141 llvm::Value *getAtomicPointer() const { 142 if (LVal.isSimple()) 143 return LVal.getPointer(); 144 else if (LVal.isBitField()) 145 return LVal.getBitFieldPointer(); 146 else if (LVal.isVectorElt()) 147 return LVal.getVectorPointer(); 148 assert(LVal.isExtVectorElt()); 149 return LVal.getExtVectorPointer(); 150 } 151 Address getAtomicAddress() const { 152 return Address(getAtomicPointer(), getAtomicAlignment()); 153 } 154 155 Address getAtomicAddressAsAtomicIntPointer() const { 156 return emitCastToAtomicIntPointer(getAtomicAddress()); 157 } 158 159 /// Is the atomic size larger than the underlying value type? 160 /// 161 /// Note that the absence of padding does not mean that atomic 162 /// objects are completely interchangeable with non-atomic 163 /// objects: we might have promoted the alignment of a type 164 /// without making it bigger. 165 bool hasPadding() const { 166 return (ValueSizeInBits != AtomicSizeInBits); 167 } 168 169 bool emitMemSetZeroIfNecessary() const; 170 171 llvm::Value *getAtomicSizeValue() const { 172 CharUnits size = CGF.getContext().toCharUnitsFromBits(AtomicSizeInBits); 173 return CGF.CGM.getSize(size); 174 } 175 176 /// Cast the given pointer to an integer pointer suitable for atomic 177 /// operations if the source. 178 Address emitCastToAtomicIntPointer(Address Addr) const; 179 180 /// If Addr is compatible with the iN that will be used for an atomic 181 /// operation, bitcast it. Otherwise, create a temporary that is suitable 182 /// and copy the value across. 183 Address convertToAtomicIntPointer(Address Addr) const; 184 185 /// Turn an atomic-layout object into an r-value. 186 RValue convertAtomicTempToRValue(Address addr, AggValueSlot resultSlot, 187 SourceLocation loc, bool AsValue) const; 188 189 /// \brief Converts a rvalue to integer value. 190 llvm::Value *convertRValueToInt(RValue RVal) const; 191 192 RValue ConvertIntToValueOrAtomic(llvm::Value *IntVal, 193 AggValueSlot ResultSlot, 194 SourceLocation Loc, bool AsValue) const; 195 196 /// Copy an atomic r-value into atomic-layout memory. 197 void emitCopyIntoMemory(RValue rvalue) const; 198 199 /// Project an l-value down to the value field. 200 LValue projectValue() const { 201 assert(LVal.isSimple()); 202 Address addr = getAtomicAddress(); 203 if (hasPadding()) 204 addr = CGF.Builder.CreateStructGEP(addr, 0, CharUnits()); 205 206 return LValue::MakeAddr(addr, getValueType(), CGF.getContext(), 207 LVal.getAlignmentSource(), LVal.getTBAAInfo()); 208 } 209 210 /// \brief Emits atomic load. 211 /// \returns Loaded value. 212 RValue EmitAtomicLoad(AggValueSlot ResultSlot, SourceLocation Loc, 213 bool AsValue, llvm::AtomicOrdering AO, 214 bool IsVolatile); 215 216 /// \brief Emits atomic compare-and-exchange sequence. 217 /// \param Expected Expected value. 218 /// \param Desired Desired value. 219 /// \param Success Atomic ordering for success operation. 220 /// \param Failure Atomic ordering for failed operation. 221 /// \param IsWeak true if atomic operation is weak, false otherwise. 222 /// \returns Pair of values: previous value from storage (value type) and 223 /// boolean flag (i1 type) with true if success and false otherwise. 224 std::pair<RValue, llvm::Value *> 225 EmitAtomicCompareExchange(RValue Expected, RValue Desired, 226 llvm::AtomicOrdering Success = 227 llvm::AtomicOrdering::SequentiallyConsistent, 228 llvm::AtomicOrdering Failure = 229 llvm::AtomicOrdering::SequentiallyConsistent, 230 bool IsWeak = false); 231 232 /// \brief Emits atomic update. 233 /// \param AO Atomic ordering. 234 /// \param UpdateOp Update operation for the current lvalue. 235 void EmitAtomicUpdate(llvm::AtomicOrdering AO, 236 const llvm::function_ref<RValue(RValue)> &UpdateOp, 237 bool IsVolatile); 238 /// \brief Emits atomic update. 239 /// \param AO Atomic ordering. 240 void EmitAtomicUpdate(llvm::AtomicOrdering AO, RValue UpdateRVal, 241 bool IsVolatile); 242 243 /// Materialize an atomic r-value in atomic-layout memory. 244 Address materializeRValue(RValue rvalue) const; 245 246 /// \brief Translates LLVM atomic ordering to GNU atomic ordering for 247 /// libcalls. 248 static AtomicExpr::AtomicOrderingKind 249 translateAtomicOrdering(const llvm::AtomicOrdering AO); 250 251 /// \brief Creates temp alloca for intermediate operations on atomic value. 252 Address CreateTempAlloca() const; 253 private: 254 bool requiresMemSetZero(llvm::Type *type) const; 255 256 257 /// \brief Emits atomic load as a libcall. 258 void EmitAtomicLoadLibcall(llvm::Value *AddForLoaded, 259 llvm::AtomicOrdering AO, bool IsVolatile); 260 /// \brief Emits atomic load as LLVM instruction. 261 llvm::Value *EmitAtomicLoadOp(llvm::AtomicOrdering AO, bool IsVolatile); 262 /// \brief Emits atomic compare-and-exchange op as a libcall. 263 llvm::Value *EmitAtomicCompareExchangeLibcall( 264 llvm::Value *ExpectedAddr, llvm::Value *DesiredAddr, 265 llvm::AtomicOrdering Success = 266 llvm::AtomicOrdering::SequentiallyConsistent, 267 llvm::AtomicOrdering Failure = 268 llvm::AtomicOrdering::SequentiallyConsistent); 269 /// \brief Emits atomic compare-and-exchange op as LLVM instruction. 270 std::pair<llvm::Value *, llvm::Value *> EmitAtomicCompareExchangeOp( 271 llvm::Value *ExpectedVal, llvm::Value *DesiredVal, 272 llvm::AtomicOrdering Success = 273 llvm::AtomicOrdering::SequentiallyConsistent, 274 llvm::AtomicOrdering Failure = 275 llvm::AtomicOrdering::SequentiallyConsistent, 276 bool IsWeak = false); 277 /// \brief Emit atomic update as libcalls. 278 void 279 EmitAtomicUpdateLibcall(llvm::AtomicOrdering AO, 280 const llvm::function_ref<RValue(RValue)> &UpdateOp, 281 bool IsVolatile); 282 /// \brief Emit atomic update as LLVM instructions. 283 void EmitAtomicUpdateOp(llvm::AtomicOrdering AO, 284 const llvm::function_ref<RValue(RValue)> &UpdateOp, 285 bool IsVolatile); 286 /// \brief Emit atomic update as libcalls. 287 void EmitAtomicUpdateLibcall(llvm::AtomicOrdering AO, RValue UpdateRVal, 288 bool IsVolatile); 289 /// \brief Emit atomic update as LLVM instructions. 290 void EmitAtomicUpdateOp(llvm::AtomicOrdering AO, RValue UpdateRal, 291 bool IsVolatile); 292 }; 293 } 294 295 AtomicExpr::AtomicOrderingKind 296 AtomicInfo::translateAtomicOrdering(const llvm::AtomicOrdering AO) { 297 switch (AO) { 298 case llvm::AtomicOrdering::Unordered: 299 case llvm::AtomicOrdering::NotAtomic: 300 case llvm::AtomicOrdering::Monotonic: 301 return AtomicExpr::AO_ABI_memory_order_relaxed; 302 case llvm::AtomicOrdering::Acquire: 303 return AtomicExpr::AO_ABI_memory_order_acquire; 304 case llvm::AtomicOrdering::Release: 305 return AtomicExpr::AO_ABI_memory_order_release; 306 case llvm::AtomicOrdering::AcquireRelease: 307 return AtomicExpr::AO_ABI_memory_order_acq_rel; 308 case llvm::AtomicOrdering::SequentiallyConsistent: 309 return AtomicExpr::AO_ABI_memory_order_seq_cst; 310 } 311 llvm_unreachable("Unhandled AtomicOrdering"); 312 } 313 314 Address AtomicInfo::CreateTempAlloca() const { 315 Address TempAlloca = CGF.CreateMemTemp( 316 (LVal.isBitField() && ValueSizeInBits > AtomicSizeInBits) ? ValueTy 317 : AtomicTy, 318 getAtomicAlignment(), 319 "atomic-temp"); 320 // Cast to pointer to value type for bitfields. 321 if (LVal.isBitField()) 322 return CGF.Builder.CreatePointerBitCastOrAddrSpaceCast( 323 TempAlloca, getAtomicAddress().getType()); 324 return TempAlloca; 325 } 326 327 static RValue emitAtomicLibcall(CodeGenFunction &CGF, 328 StringRef fnName, 329 QualType resultType, 330 CallArgList &args) { 331 const CGFunctionInfo &fnInfo = 332 CGF.CGM.getTypes().arrangeBuiltinFunctionCall(resultType, args); 333 llvm::FunctionType *fnTy = CGF.CGM.getTypes().GetFunctionType(fnInfo); 334 llvm::Constant *fn = CGF.CGM.CreateRuntimeFunction(fnTy, fnName); 335 return CGF.EmitCall(fnInfo, fn, ReturnValueSlot(), args); 336 } 337 338 /// Does a store of the given IR type modify the full expected width? 339 static bool isFullSizeType(CodeGenModule &CGM, llvm::Type *type, 340 uint64_t expectedSize) { 341 return (CGM.getDataLayout().getTypeStoreSize(type) * 8 == expectedSize); 342 } 343 344 /// Does the atomic type require memsetting to zero before initialization? 345 /// 346 /// The IR type is provided as a way of making certain queries faster. 347 bool AtomicInfo::requiresMemSetZero(llvm::Type *type) const { 348 // If the atomic type has size padding, we definitely need a memset. 349 if (hasPadding()) return true; 350 351 // Otherwise, do some simple heuristics to try to avoid it: 352 switch (getEvaluationKind()) { 353 // For scalars and complexes, check whether the store size of the 354 // type uses the full size. 355 case TEK_Scalar: 356 return !isFullSizeType(CGF.CGM, type, AtomicSizeInBits); 357 case TEK_Complex: 358 return !isFullSizeType(CGF.CGM, type->getStructElementType(0), 359 AtomicSizeInBits / 2); 360 361 // Padding in structs has an undefined bit pattern. User beware. 362 case TEK_Aggregate: 363 return false; 364 } 365 llvm_unreachable("bad evaluation kind"); 366 } 367 368 bool AtomicInfo::emitMemSetZeroIfNecessary() const { 369 assert(LVal.isSimple()); 370 llvm::Value *addr = LVal.getPointer(); 371 if (!requiresMemSetZero(addr->getType()->getPointerElementType())) 372 return false; 373 374 CGF.Builder.CreateMemSet( 375 addr, llvm::ConstantInt::get(CGF.Int8Ty, 0), 376 CGF.getContext().toCharUnitsFromBits(AtomicSizeInBits).getQuantity(), 377 LVal.getAlignment().getQuantity()); 378 return true; 379 } 380 381 static void emitAtomicCmpXchg(CodeGenFunction &CGF, AtomicExpr *E, bool IsWeak, 382 Address Dest, Address Ptr, 383 Address Val1, Address Val2, 384 uint64_t Size, 385 llvm::AtomicOrdering SuccessOrder, 386 llvm::AtomicOrdering FailureOrder) { 387 // Note that cmpxchg doesn't support weak cmpxchg, at least at the moment. 388 llvm::Value *Expected = CGF.Builder.CreateLoad(Val1); 389 llvm::Value *Desired = CGF.Builder.CreateLoad(Val2); 390 391 llvm::AtomicCmpXchgInst *Pair = CGF.Builder.CreateAtomicCmpXchg( 392 Ptr.getPointer(), Expected, Desired, SuccessOrder, FailureOrder); 393 Pair->setVolatile(E->isVolatile()); 394 Pair->setWeak(IsWeak); 395 396 // Cmp holds the result of the compare-exchange operation: true on success, 397 // false on failure. 398 llvm::Value *Old = CGF.Builder.CreateExtractValue(Pair, 0); 399 llvm::Value *Cmp = CGF.Builder.CreateExtractValue(Pair, 1); 400 401 // This basic block is used to hold the store instruction if the operation 402 // failed. 403 llvm::BasicBlock *StoreExpectedBB = 404 CGF.createBasicBlock("cmpxchg.store_expected", CGF.CurFn); 405 406 // This basic block is the exit point of the operation, we should end up 407 // here regardless of whether or not the operation succeeded. 408 llvm::BasicBlock *ContinueBB = 409 CGF.createBasicBlock("cmpxchg.continue", CGF.CurFn); 410 411 // Update Expected if Expected isn't equal to Old, otherwise branch to the 412 // exit point. 413 CGF.Builder.CreateCondBr(Cmp, ContinueBB, StoreExpectedBB); 414 415 CGF.Builder.SetInsertPoint(StoreExpectedBB); 416 // Update the memory at Expected with Old's value. 417 CGF.Builder.CreateStore(Old, Val1); 418 // Finally, branch to the exit point. 419 CGF.Builder.CreateBr(ContinueBB); 420 421 CGF.Builder.SetInsertPoint(ContinueBB); 422 // Update the memory at Dest with Cmp's value. 423 CGF.EmitStoreOfScalar(Cmp, CGF.MakeAddrLValue(Dest, E->getType())); 424 } 425 426 /// Given an ordering required on success, emit all possible cmpxchg 427 /// instructions to cope with the provided (but possibly only dynamically known) 428 /// FailureOrder. 429 static void emitAtomicCmpXchgFailureSet(CodeGenFunction &CGF, AtomicExpr *E, 430 bool IsWeak, Address Dest, 431 Address Ptr, Address Val1, 432 Address Val2, 433 llvm::Value *FailureOrderVal, 434 uint64_t Size, 435 llvm::AtomicOrdering SuccessOrder) { 436 llvm::AtomicOrdering FailureOrder; 437 if (llvm::ConstantInt *FO = dyn_cast<llvm::ConstantInt>(FailureOrderVal)) { 438 switch (FO->getSExtValue()) { 439 default: 440 FailureOrder = llvm::AtomicOrdering::Monotonic; 441 break; 442 case AtomicExpr::AO_ABI_memory_order_consume: 443 case AtomicExpr::AO_ABI_memory_order_acquire: 444 FailureOrder = llvm::AtomicOrdering::Acquire; 445 break; 446 case AtomicExpr::AO_ABI_memory_order_seq_cst: 447 FailureOrder = llvm::AtomicOrdering::SequentiallyConsistent; 448 break; 449 } 450 if (FailureOrder >= SuccessOrder) { 451 // Don't assert on undefined behaviour. 452 FailureOrder = 453 llvm::AtomicCmpXchgInst::getStrongestFailureOrdering(SuccessOrder); 454 } 455 emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, Size, 456 SuccessOrder, FailureOrder); 457 return; 458 } 459 460 // Create all the relevant BB's 461 llvm::BasicBlock *MonotonicBB = nullptr, *AcquireBB = nullptr, 462 *SeqCstBB = nullptr; 463 MonotonicBB = CGF.createBasicBlock("monotonic_fail", CGF.CurFn); 464 if (SuccessOrder != llvm::AtomicOrdering::Monotonic && 465 SuccessOrder != llvm::AtomicOrdering::Release) 466 AcquireBB = CGF.createBasicBlock("acquire_fail", CGF.CurFn); 467 if (SuccessOrder == llvm::AtomicOrdering::SequentiallyConsistent) 468 SeqCstBB = CGF.createBasicBlock("seqcst_fail", CGF.CurFn); 469 470 llvm::BasicBlock *ContBB = CGF.createBasicBlock("atomic.continue", CGF.CurFn); 471 472 llvm::SwitchInst *SI = CGF.Builder.CreateSwitch(FailureOrderVal, MonotonicBB); 473 474 // Emit all the different atomics 475 476 // MonotonicBB is arbitrarily chosen as the default case; in practice, this 477 // doesn't matter unless someone is crazy enough to use something that 478 // doesn't fold to a constant for the ordering. 479 CGF.Builder.SetInsertPoint(MonotonicBB); 480 emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, 481 Size, SuccessOrder, llvm::AtomicOrdering::Monotonic); 482 CGF.Builder.CreateBr(ContBB); 483 484 if (AcquireBB) { 485 CGF.Builder.SetInsertPoint(AcquireBB); 486 emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, 487 Size, SuccessOrder, llvm::AtomicOrdering::Acquire); 488 CGF.Builder.CreateBr(ContBB); 489 SI->addCase(CGF.Builder.getInt32(AtomicExpr::AO_ABI_memory_order_consume), 490 AcquireBB); 491 SI->addCase(CGF.Builder.getInt32(AtomicExpr::AO_ABI_memory_order_acquire), 492 AcquireBB); 493 } 494 if (SeqCstBB) { 495 CGF.Builder.SetInsertPoint(SeqCstBB); 496 emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, Size, SuccessOrder, 497 llvm::AtomicOrdering::SequentiallyConsistent); 498 CGF.Builder.CreateBr(ContBB); 499 SI->addCase(CGF.Builder.getInt32(AtomicExpr::AO_ABI_memory_order_seq_cst), 500 SeqCstBB); 501 } 502 503 CGF.Builder.SetInsertPoint(ContBB); 504 } 505 506 static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, Address Dest, 507 Address Ptr, Address Val1, Address Val2, 508 llvm::Value *IsWeak, llvm::Value *FailureOrder, 509 uint64_t Size, llvm::AtomicOrdering Order) { 510 llvm::AtomicRMWInst::BinOp Op = llvm::AtomicRMWInst::Add; 511 llvm::Instruction::BinaryOps PostOp = (llvm::Instruction::BinaryOps)0; 512 513 switch (E->getOp()) { 514 case AtomicExpr::AO__c11_atomic_init: 515 llvm_unreachable("Already handled!"); 516 517 case AtomicExpr::AO__c11_atomic_compare_exchange_strong: 518 emitAtomicCmpXchgFailureSet(CGF, E, false, Dest, Ptr, Val1, Val2, 519 FailureOrder, Size, Order); 520 return; 521 case AtomicExpr::AO__c11_atomic_compare_exchange_weak: 522 emitAtomicCmpXchgFailureSet(CGF, E, true, Dest, Ptr, Val1, Val2, 523 FailureOrder, Size, Order); 524 return; 525 case AtomicExpr::AO__atomic_compare_exchange: 526 case AtomicExpr::AO__atomic_compare_exchange_n: { 527 if (llvm::ConstantInt *IsWeakC = dyn_cast<llvm::ConstantInt>(IsWeak)) { 528 emitAtomicCmpXchgFailureSet(CGF, E, IsWeakC->getZExtValue(), Dest, Ptr, 529 Val1, Val2, FailureOrder, Size, Order); 530 } else { 531 // Create all the relevant BB's 532 llvm::BasicBlock *StrongBB = 533 CGF.createBasicBlock("cmpxchg.strong", CGF.CurFn); 534 llvm::BasicBlock *WeakBB = CGF.createBasicBlock("cmxchg.weak", CGF.CurFn); 535 llvm::BasicBlock *ContBB = 536 CGF.createBasicBlock("cmpxchg.continue", CGF.CurFn); 537 538 llvm::SwitchInst *SI = CGF.Builder.CreateSwitch(IsWeak, WeakBB); 539 SI->addCase(CGF.Builder.getInt1(false), StrongBB); 540 541 CGF.Builder.SetInsertPoint(StrongBB); 542 emitAtomicCmpXchgFailureSet(CGF, E, false, Dest, Ptr, Val1, Val2, 543 FailureOrder, Size, Order); 544 CGF.Builder.CreateBr(ContBB); 545 546 CGF.Builder.SetInsertPoint(WeakBB); 547 emitAtomicCmpXchgFailureSet(CGF, E, true, Dest, Ptr, Val1, Val2, 548 FailureOrder, Size, Order); 549 CGF.Builder.CreateBr(ContBB); 550 551 CGF.Builder.SetInsertPoint(ContBB); 552 } 553 return; 554 } 555 case AtomicExpr::AO__c11_atomic_load: 556 case AtomicExpr::AO__atomic_load_n: 557 case AtomicExpr::AO__atomic_load: { 558 llvm::LoadInst *Load = CGF.Builder.CreateLoad(Ptr); 559 Load->setAtomic(Order); 560 Load->setVolatile(E->isVolatile()); 561 CGF.Builder.CreateStore(Load, Dest); 562 return; 563 } 564 565 case AtomicExpr::AO__c11_atomic_store: 566 case AtomicExpr::AO__atomic_store: 567 case AtomicExpr::AO__atomic_store_n: { 568 llvm::Value *LoadVal1 = CGF.Builder.CreateLoad(Val1); 569 llvm::StoreInst *Store = CGF.Builder.CreateStore(LoadVal1, Ptr); 570 Store->setAtomic(Order); 571 Store->setVolatile(E->isVolatile()); 572 return; 573 } 574 575 case AtomicExpr::AO__c11_atomic_exchange: 576 case AtomicExpr::AO__atomic_exchange_n: 577 case AtomicExpr::AO__atomic_exchange: 578 Op = llvm::AtomicRMWInst::Xchg; 579 break; 580 581 case AtomicExpr::AO__atomic_add_fetch: 582 PostOp = llvm::Instruction::Add; 583 // Fall through. 584 case AtomicExpr::AO__c11_atomic_fetch_add: 585 case AtomicExpr::AO__atomic_fetch_add: 586 Op = llvm::AtomicRMWInst::Add; 587 break; 588 589 case AtomicExpr::AO__atomic_sub_fetch: 590 PostOp = llvm::Instruction::Sub; 591 // Fall through. 592 case AtomicExpr::AO__c11_atomic_fetch_sub: 593 case AtomicExpr::AO__atomic_fetch_sub: 594 Op = llvm::AtomicRMWInst::Sub; 595 break; 596 597 case AtomicExpr::AO__atomic_and_fetch: 598 PostOp = llvm::Instruction::And; 599 // Fall through. 600 case AtomicExpr::AO__c11_atomic_fetch_and: 601 case AtomicExpr::AO__atomic_fetch_and: 602 Op = llvm::AtomicRMWInst::And; 603 break; 604 605 case AtomicExpr::AO__atomic_or_fetch: 606 PostOp = llvm::Instruction::Or; 607 // Fall through. 608 case AtomicExpr::AO__c11_atomic_fetch_or: 609 case AtomicExpr::AO__atomic_fetch_or: 610 Op = llvm::AtomicRMWInst::Or; 611 break; 612 613 case AtomicExpr::AO__atomic_xor_fetch: 614 PostOp = llvm::Instruction::Xor; 615 // Fall through. 616 case AtomicExpr::AO__c11_atomic_fetch_xor: 617 case AtomicExpr::AO__atomic_fetch_xor: 618 Op = llvm::AtomicRMWInst::Xor; 619 break; 620 621 case AtomicExpr::AO__atomic_nand_fetch: 622 PostOp = llvm::Instruction::And; // the NOT is special cased below 623 // Fall through. 624 case AtomicExpr::AO__atomic_fetch_nand: 625 Op = llvm::AtomicRMWInst::Nand; 626 break; 627 } 628 629 llvm::Value *LoadVal1 = CGF.Builder.CreateLoad(Val1); 630 llvm::AtomicRMWInst *RMWI = 631 CGF.Builder.CreateAtomicRMW(Op, Ptr.getPointer(), LoadVal1, Order); 632 RMWI->setVolatile(E->isVolatile()); 633 634 // For __atomic_*_fetch operations, perform the operation again to 635 // determine the value which was written. 636 llvm::Value *Result = RMWI; 637 if (PostOp) 638 Result = CGF.Builder.CreateBinOp(PostOp, RMWI, LoadVal1); 639 if (E->getOp() == AtomicExpr::AO__atomic_nand_fetch) 640 Result = CGF.Builder.CreateNot(Result); 641 CGF.Builder.CreateStore(Result, Dest); 642 } 643 644 // This function emits any expression (scalar, complex, or aggregate) 645 // into a temporary alloca. 646 static Address 647 EmitValToTemp(CodeGenFunction &CGF, Expr *E) { 648 Address DeclPtr = CGF.CreateMemTemp(E->getType(), ".atomictmp"); 649 CGF.EmitAnyExprToMem(E, DeclPtr, E->getType().getQualifiers(), 650 /*Init*/ true); 651 return DeclPtr; 652 } 653 654 static void 655 AddDirectArgument(CodeGenFunction &CGF, CallArgList &Args, 656 bool UseOptimizedLibcall, llvm::Value *Val, QualType ValTy, 657 SourceLocation Loc, CharUnits SizeInChars) { 658 if (UseOptimizedLibcall) { 659 // Load value and pass it to the function directly. 660 CharUnits Align = CGF.getContext().getTypeAlignInChars(ValTy); 661 int64_t SizeInBits = CGF.getContext().toBits(SizeInChars); 662 ValTy = 663 CGF.getContext().getIntTypeForBitwidth(SizeInBits, /*Signed=*/false); 664 llvm::Type *IPtrTy = llvm::IntegerType::get(CGF.getLLVMContext(), 665 SizeInBits)->getPointerTo(); 666 Address Ptr = Address(CGF.Builder.CreateBitCast(Val, IPtrTy), Align); 667 Val = CGF.EmitLoadOfScalar(Ptr, false, 668 CGF.getContext().getPointerType(ValTy), 669 Loc); 670 // Coerce the value into an appropriately sized integer type. 671 Args.add(RValue::get(Val), ValTy); 672 } else { 673 // Non-optimized functions always take a reference. 674 Args.add(RValue::get(CGF.EmitCastToVoidPtr(Val)), 675 CGF.getContext().VoidPtrTy); 676 } 677 } 678 679 RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) { 680 QualType AtomicTy = E->getPtr()->getType()->getPointeeType(); 681 QualType MemTy = AtomicTy; 682 if (const AtomicType *AT = AtomicTy->getAs<AtomicType>()) 683 MemTy = AT->getValueType(); 684 CharUnits sizeChars, alignChars; 685 std::tie(sizeChars, alignChars) = getContext().getTypeInfoInChars(AtomicTy); 686 uint64_t Size = sizeChars.getQuantity(); 687 unsigned MaxInlineWidthInBits = getTarget().getMaxAtomicInlineWidth(); 688 bool UseLibcall = (sizeChars != alignChars || 689 getContext().toBits(sizeChars) > MaxInlineWidthInBits); 690 691 llvm::Value *IsWeak = nullptr, *OrderFail = nullptr; 692 693 Address Val1 = Address::invalid(); 694 Address Val2 = Address::invalid(); 695 Address Dest = Address::invalid(); 696 Address Ptr(EmitScalarExpr(E->getPtr()), alignChars); 697 698 if (E->getOp() == AtomicExpr::AO__c11_atomic_init) { 699 LValue lvalue = MakeAddrLValue(Ptr, AtomicTy); 700 EmitAtomicInit(E->getVal1(), lvalue); 701 return RValue::get(nullptr); 702 } 703 704 llvm::Value *Order = EmitScalarExpr(E->getOrder()); 705 706 switch (E->getOp()) { 707 case AtomicExpr::AO__c11_atomic_init: 708 llvm_unreachable("Already handled above with EmitAtomicInit!"); 709 710 case AtomicExpr::AO__c11_atomic_load: 711 case AtomicExpr::AO__atomic_load_n: 712 break; 713 714 case AtomicExpr::AO__atomic_load: 715 Dest = EmitPointerWithAlignment(E->getVal1()); 716 break; 717 718 case AtomicExpr::AO__atomic_store: 719 Val1 = EmitPointerWithAlignment(E->getVal1()); 720 break; 721 722 case AtomicExpr::AO__atomic_exchange: 723 Val1 = EmitPointerWithAlignment(E->getVal1()); 724 Dest = EmitPointerWithAlignment(E->getVal2()); 725 break; 726 727 case AtomicExpr::AO__c11_atomic_compare_exchange_strong: 728 case AtomicExpr::AO__c11_atomic_compare_exchange_weak: 729 case AtomicExpr::AO__atomic_compare_exchange_n: 730 case AtomicExpr::AO__atomic_compare_exchange: 731 Val1 = EmitPointerWithAlignment(E->getVal1()); 732 if (E->getOp() == AtomicExpr::AO__atomic_compare_exchange) 733 Val2 = EmitPointerWithAlignment(E->getVal2()); 734 else 735 Val2 = EmitValToTemp(*this, E->getVal2()); 736 OrderFail = EmitScalarExpr(E->getOrderFail()); 737 if (E->getNumSubExprs() == 6) 738 IsWeak = EmitScalarExpr(E->getWeak()); 739 break; 740 741 case AtomicExpr::AO__c11_atomic_fetch_add: 742 case AtomicExpr::AO__c11_atomic_fetch_sub: 743 if (MemTy->isPointerType()) { 744 // For pointer arithmetic, we're required to do a bit of math: 745 // adding 1 to an int* is not the same as adding 1 to a uintptr_t. 746 // ... but only for the C11 builtins. The GNU builtins expect the 747 // user to multiply by sizeof(T). 748 QualType Val1Ty = E->getVal1()->getType(); 749 llvm::Value *Val1Scalar = EmitScalarExpr(E->getVal1()); 750 CharUnits PointeeIncAmt = 751 getContext().getTypeSizeInChars(MemTy->getPointeeType()); 752 Val1Scalar = Builder.CreateMul(Val1Scalar, CGM.getSize(PointeeIncAmt)); 753 auto Temp = CreateMemTemp(Val1Ty, ".atomictmp"); 754 Val1 = Temp; 755 EmitStoreOfScalar(Val1Scalar, MakeAddrLValue(Temp, Val1Ty)); 756 break; 757 } 758 // Fall through. 759 case AtomicExpr::AO__atomic_fetch_add: 760 case AtomicExpr::AO__atomic_fetch_sub: 761 case AtomicExpr::AO__atomic_add_fetch: 762 case AtomicExpr::AO__atomic_sub_fetch: 763 case AtomicExpr::AO__c11_atomic_store: 764 case AtomicExpr::AO__c11_atomic_exchange: 765 case AtomicExpr::AO__atomic_store_n: 766 case AtomicExpr::AO__atomic_exchange_n: 767 case AtomicExpr::AO__c11_atomic_fetch_and: 768 case AtomicExpr::AO__c11_atomic_fetch_or: 769 case AtomicExpr::AO__c11_atomic_fetch_xor: 770 case AtomicExpr::AO__atomic_fetch_and: 771 case AtomicExpr::AO__atomic_fetch_or: 772 case AtomicExpr::AO__atomic_fetch_xor: 773 case AtomicExpr::AO__atomic_fetch_nand: 774 case AtomicExpr::AO__atomic_and_fetch: 775 case AtomicExpr::AO__atomic_or_fetch: 776 case AtomicExpr::AO__atomic_xor_fetch: 777 case AtomicExpr::AO__atomic_nand_fetch: 778 Val1 = EmitValToTemp(*this, E->getVal1()); 779 break; 780 } 781 782 QualType RValTy = E->getType().getUnqualifiedType(); 783 784 // The inlined atomics only function on iN types, where N is a power of 2. We 785 // need to make sure (via temporaries if necessary) that all incoming values 786 // are compatible. 787 LValue AtomicVal = MakeAddrLValue(Ptr, AtomicTy); 788 AtomicInfo Atomics(*this, AtomicVal); 789 790 Ptr = Atomics.emitCastToAtomicIntPointer(Ptr); 791 if (Val1.isValid()) Val1 = Atomics.convertToAtomicIntPointer(Val1); 792 if (Val2.isValid()) Val2 = Atomics.convertToAtomicIntPointer(Val2); 793 if (Dest.isValid()) 794 Dest = Atomics.emitCastToAtomicIntPointer(Dest); 795 else if (E->isCmpXChg()) 796 Dest = CreateMemTemp(RValTy, "cmpxchg.bool"); 797 else if (!RValTy->isVoidType()) 798 Dest = Atomics.emitCastToAtomicIntPointer(Atomics.CreateTempAlloca()); 799 800 // Use a library call. See: http://gcc.gnu.org/wiki/Atomic/GCCMM/LIbrary . 801 if (UseLibcall) { 802 bool UseOptimizedLibcall = false; 803 switch (E->getOp()) { 804 case AtomicExpr::AO__c11_atomic_init: 805 llvm_unreachable("Already handled above with EmitAtomicInit!"); 806 807 case AtomicExpr::AO__c11_atomic_fetch_add: 808 case AtomicExpr::AO__atomic_fetch_add: 809 case AtomicExpr::AO__c11_atomic_fetch_and: 810 case AtomicExpr::AO__atomic_fetch_and: 811 case AtomicExpr::AO__c11_atomic_fetch_or: 812 case AtomicExpr::AO__atomic_fetch_or: 813 case AtomicExpr::AO__atomic_fetch_nand: 814 case AtomicExpr::AO__c11_atomic_fetch_sub: 815 case AtomicExpr::AO__atomic_fetch_sub: 816 case AtomicExpr::AO__c11_atomic_fetch_xor: 817 case AtomicExpr::AO__atomic_fetch_xor: 818 case AtomicExpr::AO__atomic_add_fetch: 819 case AtomicExpr::AO__atomic_and_fetch: 820 case AtomicExpr::AO__atomic_nand_fetch: 821 case AtomicExpr::AO__atomic_or_fetch: 822 case AtomicExpr::AO__atomic_sub_fetch: 823 case AtomicExpr::AO__atomic_xor_fetch: 824 // For these, only library calls for certain sizes exist. 825 UseOptimizedLibcall = true; 826 break; 827 828 case AtomicExpr::AO__c11_atomic_load: 829 case AtomicExpr::AO__c11_atomic_store: 830 case AtomicExpr::AO__c11_atomic_exchange: 831 case AtomicExpr::AO__c11_atomic_compare_exchange_weak: 832 case AtomicExpr::AO__c11_atomic_compare_exchange_strong: 833 case AtomicExpr::AO__atomic_load_n: 834 case AtomicExpr::AO__atomic_load: 835 case AtomicExpr::AO__atomic_store_n: 836 case AtomicExpr::AO__atomic_store: 837 case AtomicExpr::AO__atomic_exchange_n: 838 case AtomicExpr::AO__atomic_exchange: 839 case AtomicExpr::AO__atomic_compare_exchange_n: 840 case AtomicExpr::AO__atomic_compare_exchange: 841 // Only use optimized library calls for sizes for which they exist. 842 if (Size == 1 || Size == 2 || Size == 4 || Size == 8) 843 UseOptimizedLibcall = true; 844 break; 845 } 846 847 CallArgList Args; 848 if (!UseOptimizedLibcall) { 849 // For non-optimized library calls, the size is the first parameter 850 Args.add(RValue::get(llvm::ConstantInt::get(SizeTy, Size)), 851 getContext().getSizeType()); 852 } 853 // Atomic address is the first or second parameter 854 Args.add(RValue::get(EmitCastToVoidPtr(Ptr.getPointer())), 855 getContext().VoidPtrTy); 856 857 std::string LibCallName; 858 QualType LoweredMemTy = 859 MemTy->isPointerType() ? getContext().getIntPtrType() : MemTy; 860 QualType RetTy; 861 bool HaveRetTy = false; 862 llvm::Instruction::BinaryOps PostOp = (llvm::Instruction::BinaryOps)0; 863 switch (E->getOp()) { 864 case AtomicExpr::AO__c11_atomic_init: 865 llvm_unreachable("Already handled!"); 866 867 // There is only one libcall for compare an exchange, because there is no 868 // optimisation benefit possible from a libcall version of a weak compare 869 // and exchange. 870 // bool __atomic_compare_exchange(size_t size, void *mem, void *expected, 871 // void *desired, int success, int failure) 872 // bool __atomic_compare_exchange_N(T *mem, T *expected, T desired, 873 // int success, int failure) 874 case AtomicExpr::AO__c11_atomic_compare_exchange_weak: 875 case AtomicExpr::AO__c11_atomic_compare_exchange_strong: 876 case AtomicExpr::AO__atomic_compare_exchange: 877 case AtomicExpr::AO__atomic_compare_exchange_n: 878 LibCallName = "__atomic_compare_exchange"; 879 RetTy = getContext().BoolTy; 880 HaveRetTy = true; 881 Args.add(RValue::get(EmitCastToVoidPtr(Val1.getPointer())), 882 getContext().VoidPtrTy); 883 AddDirectArgument(*this, Args, UseOptimizedLibcall, Val2.getPointer(), 884 MemTy, E->getExprLoc(), sizeChars); 885 Args.add(RValue::get(Order), getContext().IntTy); 886 Order = OrderFail; 887 break; 888 // void __atomic_exchange(size_t size, void *mem, void *val, void *return, 889 // int order) 890 // T __atomic_exchange_N(T *mem, T val, int order) 891 case AtomicExpr::AO__c11_atomic_exchange: 892 case AtomicExpr::AO__atomic_exchange_n: 893 case AtomicExpr::AO__atomic_exchange: 894 LibCallName = "__atomic_exchange"; 895 AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1.getPointer(), 896 MemTy, E->getExprLoc(), sizeChars); 897 break; 898 // void __atomic_store(size_t size, void *mem, void *val, int order) 899 // void __atomic_store_N(T *mem, T val, int order) 900 case AtomicExpr::AO__c11_atomic_store: 901 case AtomicExpr::AO__atomic_store: 902 case AtomicExpr::AO__atomic_store_n: 903 LibCallName = "__atomic_store"; 904 RetTy = getContext().VoidTy; 905 HaveRetTy = true; 906 AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1.getPointer(), 907 MemTy, E->getExprLoc(), sizeChars); 908 break; 909 // void __atomic_load(size_t size, void *mem, void *return, int order) 910 // T __atomic_load_N(T *mem, int order) 911 case AtomicExpr::AO__c11_atomic_load: 912 case AtomicExpr::AO__atomic_load: 913 case AtomicExpr::AO__atomic_load_n: 914 LibCallName = "__atomic_load"; 915 break; 916 // T __atomic_add_fetch_N(T *mem, T val, int order) 917 // T __atomic_fetch_add_N(T *mem, T val, int order) 918 case AtomicExpr::AO__atomic_add_fetch: 919 PostOp = llvm::Instruction::Add; 920 // Fall through. 921 case AtomicExpr::AO__c11_atomic_fetch_add: 922 case AtomicExpr::AO__atomic_fetch_add: 923 LibCallName = "__atomic_fetch_add"; 924 AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1.getPointer(), 925 LoweredMemTy, E->getExprLoc(), sizeChars); 926 break; 927 // T __atomic_and_fetch_N(T *mem, T val, int order) 928 // T __atomic_fetch_and_N(T *mem, T val, int order) 929 case AtomicExpr::AO__atomic_and_fetch: 930 PostOp = llvm::Instruction::And; 931 // Fall through. 932 case AtomicExpr::AO__c11_atomic_fetch_and: 933 case AtomicExpr::AO__atomic_fetch_and: 934 LibCallName = "__atomic_fetch_and"; 935 AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1.getPointer(), 936 MemTy, E->getExprLoc(), sizeChars); 937 break; 938 // T __atomic_or_fetch_N(T *mem, T val, int order) 939 // T __atomic_fetch_or_N(T *mem, T val, int order) 940 case AtomicExpr::AO__atomic_or_fetch: 941 PostOp = llvm::Instruction::Or; 942 // Fall through. 943 case AtomicExpr::AO__c11_atomic_fetch_or: 944 case AtomicExpr::AO__atomic_fetch_or: 945 LibCallName = "__atomic_fetch_or"; 946 AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1.getPointer(), 947 MemTy, E->getExprLoc(), sizeChars); 948 break; 949 // T __atomic_sub_fetch_N(T *mem, T val, int order) 950 // T __atomic_fetch_sub_N(T *mem, T val, int order) 951 case AtomicExpr::AO__atomic_sub_fetch: 952 PostOp = llvm::Instruction::Sub; 953 // Fall through. 954 case AtomicExpr::AO__c11_atomic_fetch_sub: 955 case AtomicExpr::AO__atomic_fetch_sub: 956 LibCallName = "__atomic_fetch_sub"; 957 AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1.getPointer(), 958 LoweredMemTy, E->getExprLoc(), sizeChars); 959 break; 960 // T __atomic_xor_fetch_N(T *mem, T val, int order) 961 // T __atomic_fetch_xor_N(T *mem, T val, int order) 962 case AtomicExpr::AO__atomic_xor_fetch: 963 PostOp = llvm::Instruction::Xor; 964 // Fall through. 965 case AtomicExpr::AO__c11_atomic_fetch_xor: 966 case AtomicExpr::AO__atomic_fetch_xor: 967 LibCallName = "__atomic_fetch_xor"; 968 AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1.getPointer(), 969 MemTy, E->getExprLoc(), sizeChars); 970 break; 971 // T __atomic_nand_fetch_N(T *mem, T val, int order) 972 // T __atomic_fetch_nand_N(T *mem, T val, int order) 973 case AtomicExpr::AO__atomic_nand_fetch: 974 PostOp = llvm::Instruction::And; // the NOT is special cased below 975 // Fall through. 976 case AtomicExpr::AO__atomic_fetch_nand: 977 LibCallName = "__atomic_fetch_nand"; 978 AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1.getPointer(), 979 MemTy, E->getExprLoc(), sizeChars); 980 break; 981 } 982 983 // Optimized functions have the size in their name. 984 if (UseOptimizedLibcall) 985 LibCallName += "_" + llvm::utostr(Size); 986 // By default, assume we return a value of the atomic type. 987 if (!HaveRetTy) { 988 if (UseOptimizedLibcall) { 989 // Value is returned directly. 990 // The function returns an appropriately sized integer type. 991 RetTy = getContext().getIntTypeForBitwidth( 992 getContext().toBits(sizeChars), /*Signed=*/false); 993 } else { 994 // Value is returned through parameter before the order. 995 RetTy = getContext().VoidTy; 996 Args.add(RValue::get(EmitCastToVoidPtr(Dest.getPointer())), 997 getContext().VoidPtrTy); 998 } 999 } 1000 // order is always the last parameter 1001 Args.add(RValue::get(Order), 1002 getContext().IntTy); 1003 1004 // PostOp is only needed for the atomic_*_fetch operations, and 1005 // thus is only needed for and implemented in the 1006 // UseOptimizedLibcall codepath. 1007 assert(UseOptimizedLibcall || !PostOp); 1008 1009 RValue Res = emitAtomicLibcall(*this, LibCallName, RetTy, Args); 1010 // The value is returned directly from the libcall. 1011 if (E->isCmpXChg()) 1012 return Res; 1013 1014 // The value is returned directly for optimized libcalls but the expr 1015 // provided an out-param. 1016 if (UseOptimizedLibcall && Res.getScalarVal()) { 1017 llvm::Value *ResVal = Res.getScalarVal(); 1018 if (PostOp) { 1019 llvm::Value *LoadVal1 = Args[1].RV.getScalarVal(); 1020 ResVal = Builder.CreateBinOp(PostOp, ResVal, LoadVal1); 1021 } 1022 if (E->getOp() == AtomicExpr::AO__atomic_nand_fetch) 1023 ResVal = Builder.CreateNot(ResVal); 1024 1025 Builder.CreateStore( 1026 ResVal, 1027 Builder.CreateBitCast(Dest, ResVal->getType()->getPointerTo())); 1028 } 1029 1030 if (RValTy->isVoidType()) 1031 return RValue::get(nullptr); 1032 1033 return convertTempToRValue( 1034 Builder.CreateBitCast(Dest, ConvertTypeForMem(RValTy)->getPointerTo()), 1035 RValTy, E->getExprLoc()); 1036 } 1037 1038 bool IsStore = E->getOp() == AtomicExpr::AO__c11_atomic_store || 1039 E->getOp() == AtomicExpr::AO__atomic_store || 1040 E->getOp() == AtomicExpr::AO__atomic_store_n; 1041 bool IsLoad = E->getOp() == AtomicExpr::AO__c11_atomic_load || 1042 E->getOp() == AtomicExpr::AO__atomic_load || 1043 E->getOp() == AtomicExpr::AO__atomic_load_n; 1044 1045 if (isa<llvm::ConstantInt>(Order)) { 1046 int ord = cast<llvm::ConstantInt>(Order)->getZExtValue(); 1047 switch (ord) { 1048 case AtomicExpr::AO_ABI_memory_order_relaxed: 1049 EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, 1050 Size, llvm::AtomicOrdering::Monotonic); 1051 break; 1052 case AtomicExpr::AO_ABI_memory_order_consume: 1053 case AtomicExpr::AO_ABI_memory_order_acquire: 1054 if (IsStore) 1055 break; // Avoid crashing on code with undefined behavior 1056 EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, 1057 Size, llvm::AtomicOrdering::Acquire); 1058 break; 1059 case AtomicExpr::AO_ABI_memory_order_release: 1060 if (IsLoad) 1061 break; // Avoid crashing on code with undefined behavior 1062 EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, 1063 Size, llvm::AtomicOrdering::Release); 1064 break; 1065 case AtomicExpr::AO_ABI_memory_order_acq_rel: 1066 if (IsLoad || IsStore) 1067 break; // Avoid crashing on code with undefined behavior 1068 EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, 1069 Size, llvm::AtomicOrdering::AcquireRelease); 1070 break; 1071 case AtomicExpr::AO_ABI_memory_order_seq_cst: 1072 EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, 1073 Size, llvm::AtomicOrdering::SequentiallyConsistent); 1074 break; 1075 default: // invalid order 1076 // We should not ever get here normally, but it's hard to 1077 // enforce that in general. 1078 break; 1079 } 1080 if (RValTy->isVoidType()) 1081 return RValue::get(nullptr); 1082 1083 return convertTempToRValue( 1084 Builder.CreateBitCast(Dest, ConvertTypeForMem(RValTy)->getPointerTo()), 1085 RValTy, E->getExprLoc()); 1086 } 1087 1088 // Long case, when Order isn't obviously constant. 1089 1090 // Create all the relevant BB's 1091 llvm::BasicBlock *MonotonicBB = nullptr, *AcquireBB = nullptr, 1092 *ReleaseBB = nullptr, *AcqRelBB = nullptr, 1093 *SeqCstBB = nullptr; 1094 MonotonicBB = createBasicBlock("monotonic", CurFn); 1095 if (!IsStore) 1096 AcquireBB = createBasicBlock("acquire", CurFn); 1097 if (!IsLoad) 1098 ReleaseBB = createBasicBlock("release", CurFn); 1099 if (!IsLoad && !IsStore) 1100 AcqRelBB = createBasicBlock("acqrel", CurFn); 1101 SeqCstBB = createBasicBlock("seqcst", CurFn); 1102 llvm::BasicBlock *ContBB = createBasicBlock("atomic.continue", CurFn); 1103 1104 // Create the switch for the split 1105 // MonotonicBB is arbitrarily chosen as the default case; in practice, this 1106 // doesn't matter unless someone is crazy enough to use something that 1107 // doesn't fold to a constant for the ordering. 1108 Order = Builder.CreateIntCast(Order, Builder.getInt32Ty(), false); 1109 llvm::SwitchInst *SI = Builder.CreateSwitch(Order, MonotonicBB); 1110 1111 // Emit all the different atomics 1112 Builder.SetInsertPoint(MonotonicBB); 1113 EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, 1114 Size, llvm::AtomicOrdering::Monotonic); 1115 Builder.CreateBr(ContBB); 1116 if (!IsStore) { 1117 Builder.SetInsertPoint(AcquireBB); 1118 EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, 1119 Size, llvm::AtomicOrdering::Acquire); 1120 Builder.CreateBr(ContBB); 1121 SI->addCase(Builder.getInt32(AtomicExpr::AO_ABI_memory_order_consume), 1122 AcquireBB); 1123 SI->addCase(Builder.getInt32(AtomicExpr::AO_ABI_memory_order_acquire), 1124 AcquireBB); 1125 } 1126 if (!IsLoad) { 1127 Builder.SetInsertPoint(ReleaseBB); 1128 EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, 1129 Size, llvm::AtomicOrdering::Release); 1130 Builder.CreateBr(ContBB); 1131 SI->addCase(Builder.getInt32(AtomicExpr::AO_ABI_memory_order_release), 1132 ReleaseBB); 1133 } 1134 if (!IsLoad && !IsStore) { 1135 Builder.SetInsertPoint(AcqRelBB); 1136 EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, 1137 Size, llvm::AtomicOrdering::AcquireRelease); 1138 Builder.CreateBr(ContBB); 1139 SI->addCase(Builder.getInt32(AtomicExpr::AO_ABI_memory_order_acq_rel), 1140 AcqRelBB); 1141 } 1142 Builder.SetInsertPoint(SeqCstBB); 1143 EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, 1144 Size, llvm::AtomicOrdering::SequentiallyConsistent); 1145 Builder.CreateBr(ContBB); 1146 SI->addCase(Builder.getInt32(AtomicExpr::AO_ABI_memory_order_seq_cst), 1147 SeqCstBB); 1148 1149 // Cleanup and return 1150 Builder.SetInsertPoint(ContBB); 1151 if (RValTy->isVoidType()) 1152 return RValue::get(nullptr); 1153 1154 assert(Atomics.getValueSizeInBits() <= Atomics.getAtomicSizeInBits()); 1155 return convertTempToRValue( 1156 Builder.CreateBitCast(Dest, ConvertTypeForMem(RValTy)->getPointerTo()), 1157 RValTy, E->getExprLoc()); 1158 } 1159 1160 Address AtomicInfo::emitCastToAtomicIntPointer(Address addr) const { 1161 unsigned addrspace = 1162 cast<llvm::PointerType>(addr.getPointer()->getType())->getAddressSpace(); 1163 llvm::IntegerType *ty = 1164 llvm::IntegerType::get(CGF.getLLVMContext(), AtomicSizeInBits); 1165 return CGF.Builder.CreateBitCast(addr, ty->getPointerTo(addrspace)); 1166 } 1167 1168 Address AtomicInfo::convertToAtomicIntPointer(Address Addr) const { 1169 llvm::Type *Ty = Addr.getElementType(); 1170 uint64_t SourceSizeInBits = CGF.CGM.getDataLayout().getTypeSizeInBits(Ty); 1171 if (SourceSizeInBits != AtomicSizeInBits) { 1172 Address Tmp = CreateTempAlloca(); 1173 CGF.Builder.CreateMemCpy(Tmp, Addr, 1174 std::min(AtomicSizeInBits, SourceSizeInBits) / 8); 1175 Addr = Tmp; 1176 } 1177 1178 return emitCastToAtomicIntPointer(Addr); 1179 } 1180 1181 RValue AtomicInfo::convertAtomicTempToRValue(Address addr, 1182 AggValueSlot resultSlot, 1183 SourceLocation loc, 1184 bool asValue) const { 1185 if (LVal.isSimple()) { 1186 if (EvaluationKind == TEK_Aggregate) 1187 return resultSlot.asRValue(); 1188 1189 // Drill into the padding structure if we have one. 1190 if (hasPadding()) 1191 addr = CGF.Builder.CreateStructGEP(addr, 0, CharUnits()); 1192 1193 // Otherwise, just convert the temporary to an r-value using the 1194 // normal conversion routine. 1195 return CGF.convertTempToRValue(addr, getValueType(), loc); 1196 } 1197 if (!asValue) 1198 // Get RValue from temp memory as atomic for non-simple lvalues 1199 return RValue::get(CGF.Builder.CreateLoad(addr)); 1200 if (LVal.isBitField()) 1201 return CGF.EmitLoadOfBitfieldLValue( 1202 LValue::MakeBitfield(addr, LVal.getBitFieldInfo(), LVal.getType(), 1203 LVal.getAlignmentSource())); 1204 if (LVal.isVectorElt()) 1205 return CGF.EmitLoadOfLValue( 1206 LValue::MakeVectorElt(addr, LVal.getVectorIdx(), LVal.getType(), 1207 LVal.getAlignmentSource()), loc); 1208 assert(LVal.isExtVectorElt()); 1209 return CGF.EmitLoadOfExtVectorElementLValue(LValue::MakeExtVectorElt( 1210 addr, LVal.getExtVectorElts(), LVal.getType(), 1211 LVal.getAlignmentSource())); 1212 } 1213 1214 RValue AtomicInfo::ConvertIntToValueOrAtomic(llvm::Value *IntVal, 1215 AggValueSlot ResultSlot, 1216 SourceLocation Loc, 1217 bool AsValue) const { 1218 // Try not to in some easy cases. 1219 assert(IntVal->getType()->isIntegerTy() && "Expected integer value"); 1220 if (getEvaluationKind() == TEK_Scalar && 1221 (((!LVal.isBitField() || 1222 LVal.getBitFieldInfo().Size == ValueSizeInBits) && 1223 !hasPadding()) || 1224 !AsValue)) { 1225 auto *ValTy = AsValue 1226 ? CGF.ConvertTypeForMem(ValueTy) 1227 : getAtomicAddress().getType()->getPointerElementType(); 1228 if (ValTy->isIntegerTy()) { 1229 assert(IntVal->getType() == ValTy && "Different integer types."); 1230 return RValue::get(CGF.EmitFromMemory(IntVal, ValueTy)); 1231 } else if (ValTy->isPointerTy()) 1232 return RValue::get(CGF.Builder.CreateIntToPtr(IntVal, ValTy)); 1233 else if (llvm::CastInst::isBitCastable(IntVal->getType(), ValTy)) 1234 return RValue::get(CGF.Builder.CreateBitCast(IntVal, ValTy)); 1235 } 1236 1237 // Create a temporary. This needs to be big enough to hold the 1238 // atomic integer. 1239 Address Temp = Address::invalid(); 1240 bool TempIsVolatile = false; 1241 if (AsValue && getEvaluationKind() == TEK_Aggregate) { 1242 assert(!ResultSlot.isIgnored()); 1243 Temp = ResultSlot.getAddress(); 1244 TempIsVolatile = ResultSlot.isVolatile(); 1245 } else { 1246 Temp = CreateTempAlloca(); 1247 } 1248 1249 // Slam the integer into the temporary. 1250 Address CastTemp = emitCastToAtomicIntPointer(Temp); 1251 CGF.Builder.CreateStore(IntVal, CastTemp) 1252 ->setVolatile(TempIsVolatile); 1253 1254 return convertAtomicTempToRValue(Temp, ResultSlot, Loc, AsValue); 1255 } 1256 1257 void AtomicInfo::EmitAtomicLoadLibcall(llvm::Value *AddForLoaded, 1258 llvm::AtomicOrdering AO, bool) { 1259 // void __atomic_load(size_t size, void *mem, void *return, int order); 1260 CallArgList Args; 1261 Args.add(RValue::get(getAtomicSizeValue()), CGF.getContext().getSizeType()); 1262 Args.add(RValue::get(CGF.EmitCastToVoidPtr(getAtomicPointer())), 1263 CGF.getContext().VoidPtrTy); 1264 Args.add(RValue::get(CGF.EmitCastToVoidPtr(AddForLoaded)), 1265 CGF.getContext().VoidPtrTy); 1266 Args.add(RValue::get( 1267 llvm::ConstantInt::get(CGF.IntTy, translateAtomicOrdering(AO))), 1268 CGF.getContext().IntTy); 1269 emitAtomicLibcall(CGF, "__atomic_load", CGF.getContext().VoidTy, Args); 1270 } 1271 1272 llvm::Value *AtomicInfo::EmitAtomicLoadOp(llvm::AtomicOrdering AO, 1273 bool IsVolatile) { 1274 // Okay, we're doing this natively. 1275 Address Addr = getAtomicAddressAsAtomicIntPointer(); 1276 llvm::LoadInst *Load = CGF.Builder.CreateLoad(Addr, "atomic-load"); 1277 Load->setAtomic(AO); 1278 1279 // Other decoration. 1280 if (IsVolatile) 1281 Load->setVolatile(true); 1282 if (LVal.getTBAAInfo()) 1283 CGF.CGM.DecorateInstructionWithTBAA(Load, LVal.getTBAAInfo()); 1284 return Load; 1285 } 1286 1287 /// An LValue is a candidate for having its loads and stores be made atomic if 1288 /// we are operating under /volatile:ms *and* the LValue itself is volatile and 1289 /// performing such an operation can be performed without a libcall. 1290 bool CodeGenFunction::LValueIsSuitableForInlineAtomic(LValue LV) { 1291 if (!CGM.getCodeGenOpts().MSVolatile) return false; 1292 AtomicInfo AI(*this, LV); 1293 bool IsVolatile = LV.isVolatile() || hasVolatileMember(LV.getType()); 1294 // An atomic is inline if we don't need to use a libcall. 1295 bool AtomicIsInline = !AI.shouldUseLibcall(); 1296 return IsVolatile && AtomicIsInline; 1297 } 1298 1299 /// An type is a candidate for having its loads and stores be made atomic if 1300 /// we are operating under /volatile:ms *and* we know the access is volatile and 1301 /// performing such an operation can be performed without a libcall. 1302 bool CodeGenFunction::typeIsSuitableForInlineAtomic(QualType Ty, 1303 bool IsVolatile) const { 1304 // The operation must be volatile for us to make it atomic. 1305 if (!IsVolatile) 1306 return false; 1307 // The -fms-volatile flag must be passed for us to adopt this behavior. 1308 if (!CGM.getCodeGenOpts().MSVolatile) 1309 return false; 1310 1311 // An atomic is inline if we don't need to use a libcall (e.g. it is builtin). 1312 if (!getContext().getTargetInfo().hasBuiltinAtomic( 1313 getContext().getTypeSize(Ty), getContext().getTypeAlign(Ty))) 1314 return false; 1315 1316 // MSVC doesn't seem to do this for types wider than a pointer. 1317 if (getContext().getTypeSize(Ty) > 1318 getContext().getTypeSize(getContext().getIntPtrType())) 1319 return false; 1320 return true; 1321 } 1322 1323 RValue CodeGenFunction::EmitAtomicLoad(LValue LV, SourceLocation SL, 1324 AggValueSlot Slot) { 1325 llvm::AtomicOrdering AO; 1326 bool IsVolatile = LV.isVolatileQualified(); 1327 if (LV.getType()->isAtomicType()) { 1328 AO = llvm::AtomicOrdering::SequentiallyConsistent; 1329 } else { 1330 AO = llvm::AtomicOrdering::Acquire; 1331 IsVolatile = true; 1332 } 1333 return EmitAtomicLoad(LV, SL, AO, IsVolatile, Slot); 1334 } 1335 1336 RValue AtomicInfo::EmitAtomicLoad(AggValueSlot ResultSlot, SourceLocation Loc, 1337 bool AsValue, llvm::AtomicOrdering AO, 1338 bool IsVolatile) { 1339 // Check whether we should use a library call. 1340 if (shouldUseLibcall()) { 1341 Address TempAddr = Address::invalid(); 1342 if (LVal.isSimple() && !ResultSlot.isIgnored()) { 1343 assert(getEvaluationKind() == TEK_Aggregate); 1344 TempAddr = ResultSlot.getAddress(); 1345 } else 1346 TempAddr = CreateTempAlloca(); 1347 1348 EmitAtomicLoadLibcall(TempAddr.getPointer(), AO, IsVolatile); 1349 1350 // Okay, turn that back into the original value or whole atomic (for 1351 // non-simple lvalues) type. 1352 return convertAtomicTempToRValue(TempAddr, ResultSlot, Loc, AsValue); 1353 } 1354 1355 // Okay, we're doing this natively. 1356 auto *Load = EmitAtomicLoadOp(AO, IsVolatile); 1357 1358 // If we're ignoring an aggregate return, don't do anything. 1359 if (getEvaluationKind() == TEK_Aggregate && ResultSlot.isIgnored()) 1360 return RValue::getAggregate(Address::invalid(), false); 1361 1362 // Okay, turn that back into the original value or atomic (for non-simple 1363 // lvalues) type. 1364 return ConvertIntToValueOrAtomic(Load, ResultSlot, Loc, AsValue); 1365 } 1366 1367 /// Emit a load from an l-value of atomic type. Note that the r-value 1368 /// we produce is an r-value of the atomic *value* type. 1369 RValue CodeGenFunction::EmitAtomicLoad(LValue src, SourceLocation loc, 1370 llvm::AtomicOrdering AO, bool IsVolatile, 1371 AggValueSlot resultSlot) { 1372 AtomicInfo Atomics(*this, src); 1373 return Atomics.EmitAtomicLoad(resultSlot, loc, /*AsValue=*/true, AO, 1374 IsVolatile); 1375 } 1376 1377 /// Copy an r-value into memory as part of storing to an atomic type. 1378 /// This needs to create a bit-pattern suitable for atomic operations. 1379 void AtomicInfo::emitCopyIntoMemory(RValue rvalue) const { 1380 assert(LVal.isSimple()); 1381 // If we have an r-value, the rvalue should be of the atomic type, 1382 // which means that the caller is responsible for having zeroed 1383 // any padding. Just do an aggregate copy of that type. 1384 if (rvalue.isAggregate()) { 1385 CGF.EmitAggregateCopy(getAtomicAddress(), 1386 rvalue.getAggregateAddress(), 1387 getAtomicType(), 1388 (rvalue.isVolatileQualified() 1389 || LVal.isVolatileQualified())); 1390 return; 1391 } 1392 1393 // Okay, otherwise we're copying stuff. 1394 1395 // Zero out the buffer if necessary. 1396 emitMemSetZeroIfNecessary(); 1397 1398 // Drill past the padding if present. 1399 LValue TempLVal = projectValue(); 1400 1401 // Okay, store the rvalue in. 1402 if (rvalue.isScalar()) { 1403 CGF.EmitStoreOfScalar(rvalue.getScalarVal(), TempLVal, /*init*/ true); 1404 } else { 1405 CGF.EmitStoreOfComplex(rvalue.getComplexVal(), TempLVal, /*init*/ true); 1406 } 1407 } 1408 1409 1410 /// Materialize an r-value into memory for the purposes of storing it 1411 /// to an atomic type. 1412 Address AtomicInfo::materializeRValue(RValue rvalue) const { 1413 // Aggregate r-values are already in memory, and EmitAtomicStore 1414 // requires them to be values of the atomic type. 1415 if (rvalue.isAggregate()) 1416 return rvalue.getAggregateAddress(); 1417 1418 // Otherwise, make a temporary and materialize into it. 1419 LValue TempLV = CGF.MakeAddrLValue(CreateTempAlloca(), getAtomicType()); 1420 AtomicInfo Atomics(CGF, TempLV); 1421 Atomics.emitCopyIntoMemory(rvalue); 1422 return TempLV.getAddress(); 1423 } 1424 1425 llvm::Value *AtomicInfo::convertRValueToInt(RValue RVal) const { 1426 // If we've got a scalar value of the right size, try to avoid going 1427 // through memory. 1428 if (RVal.isScalar() && (!hasPadding() || !LVal.isSimple())) { 1429 llvm::Value *Value = RVal.getScalarVal(); 1430 if (isa<llvm::IntegerType>(Value->getType())) 1431 return CGF.EmitToMemory(Value, ValueTy); 1432 else { 1433 llvm::IntegerType *InputIntTy = llvm::IntegerType::get( 1434 CGF.getLLVMContext(), 1435 LVal.isSimple() ? getValueSizeInBits() : getAtomicSizeInBits()); 1436 if (isa<llvm::PointerType>(Value->getType())) 1437 return CGF.Builder.CreatePtrToInt(Value, InputIntTy); 1438 else if (llvm::BitCastInst::isBitCastable(Value->getType(), InputIntTy)) 1439 return CGF.Builder.CreateBitCast(Value, InputIntTy); 1440 } 1441 } 1442 // Otherwise, we need to go through memory. 1443 // Put the r-value in memory. 1444 Address Addr = materializeRValue(RVal); 1445 1446 // Cast the temporary to the atomic int type and pull a value out. 1447 Addr = emitCastToAtomicIntPointer(Addr); 1448 return CGF.Builder.CreateLoad(Addr); 1449 } 1450 1451 std::pair<llvm::Value *, llvm::Value *> AtomicInfo::EmitAtomicCompareExchangeOp( 1452 llvm::Value *ExpectedVal, llvm::Value *DesiredVal, 1453 llvm::AtomicOrdering Success, llvm::AtomicOrdering Failure, bool IsWeak) { 1454 // Do the atomic store. 1455 Address Addr = getAtomicAddressAsAtomicIntPointer(); 1456 auto *Inst = CGF.Builder.CreateAtomicCmpXchg(Addr.getPointer(), 1457 ExpectedVal, DesiredVal, 1458 Success, Failure); 1459 // Other decoration. 1460 Inst->setVolatile(LVal.isVolatileQualified()); 1461 Inst->setWeak(IsWeak); 1462 1463 // Okay, turn that back into the original value type. 1464 auto *PreviousVal = CGF.Builder.CreateExtractValue(Inst, /*Idxs=*/0); 1465 auto *SuccessFailureVal = CGF.Builder.CreateExtractValue(Inst, /*Idxs=*/1); 1466 return std::make_pair(PreviousVal, SuccessFailureVal); 1467 } 1468 1469 llvm::Value * 1470 AtomicInfo::EmitAtomicCompareExchangeLibcall(llvm::Value *ExpectedAddr, 1471 llvm::Value *DesiredAddr, 1472 llvm::AtomicOrdering Success, 1473 llvm::AtomicOrdering Failure) { 1474 // bool __atomic_compare_exchange(size_t size, void *obj, void *expected, 1475 // void *desired, int success, int failure); 1476 CallArgList Args; 1477 Args.add(RValue::get(getAtomicSizeValue()), CGF.getContext().getSizeType()); 1478 Args.add(RValue::get(CGF.EmitCastToVoidPtr(getAtomicPointer())), 1479 CGF.getContext().VoidPtrTy); 1480 Args.add(RValue::get(CGF.EmitCastToVoidPtr(ExpectedAddr)), 1481 CGF.getContext().VoidPtrTy); 1482 Args.add(RValue::get(CGF.EmitCastToVoidPtr(DesiredAddr)), 1483 CGF.getContext().VoidPtrTy); 1484 Args.add(RValue::get(llvm::ConstantInt::get( 1485 CGF.IntTy, translateAtomicOrdering(Success))), 1486 CGF.getContext().IntTy); 1487 Args.add(RValue::get(llvm::ConstantInt::get( 1488 CGF.IntTy, translateAtomicOrdering(Failure))), 1489 CGF.getContext().IntTy); 1490 auto SuccessFailureRVal = emitAtomicLibcall(CGF, "__atomic_compare_exchange", 1491 CGF.getContext().BoolTy, Args); 1492 1493 return SuccessFailureRVal.getScalarVal(); 1494 } 1495 1496 std::pair<RValue, llvm::Value *> AtomicInfo::EmitAtomicCompareExchange( 1497 RValue Expected, RValue Desired, llvm::AtomicOrdering Success, 1498 llvm::AtomicOrdering Failure, bool IsWeak) { 1499 if (Failure >= Success) 1500 // Don't assert on undefined behavior. 1501 Failure = llvm::AtomicCmpXchgInst::getStrongestFailureOrdering(Success); 1502 1503 // Check whether we should use a library call. 1504 if (shouldUseLibcall()) { 1505 // Produce a source address. 1506 Address ExpectedAddr = materializeRValue(Expected); 1507 Address DesiredAddr = materializeRValue(Desired); 1508 auto *Res = EmitAtomicCompareExchangeLibcall(ExpectedAddr.getPointer(), 1509 DesiredAddr.getPointer(), 1510 Success, Failure); 1511 return std::make_pair( 1512 convertAtomicTempToRValue(ExpectedAddr, AggValueSlot::ignored(), 1513 SourceLocation(), /*AsValue=*/false), 1514 Res); 1515 } 1516 1517 // If we've got a scalar value of the right size, try to avoid going 1518 // through memory. 1519 auto *ExpectedVal = convertRValueToInt(Expected); 1520 auto *DesiredVal = convertRValueToInt(Desired); 1521 auto Res = EmitAtomicCompareExchangeOp(ExpectedVal, DesiredVal, Success, 1522 Failure, IsWeak); 1523 return std::make_pair( 1524 ConvertIntToValueOrAtomic(Res.first, AggValueSlot::ignored(), 1525 SourceLocation(), /*AsValue=*/false), 1526 Res.second); 1527 } 1528 1529 static void 1530 EmitAtomicUpdateValue(CodeGenFunction &CGF, AtomicInfo &Atomics, RValue OldRVal, 1531 const llvm::function_ref<RValue(RValue)> &UpdateOp, 1532 Address DesiredAddr) { 1533 RValue UpRVal; 1534 LValue AtomicLVal = Atomics.getAtomicLValue(); 1535 LValue DesiredLVal; 1536 if (AtomicLVal.isSimple()) { 1537 UpRVal = OldRVal; 1538 DesiredLVal = CGF.MakeAddrLValue(DesiredAddr, AtomicLVal.getType()); 1539 } else { 1540 // Build new lvalue for temp address 1541 Address Ptr = Atomics.materializeRValue(OldRVal); 1542 LValue UpdateLVal; 1543 if (AtomicLVal.isBitField()) { 1544 UpdateLVal = 1545 LValue::MakeBitfield(Ptr, AtomicLVal.getBitFieldInfo(), 1546 AtomicLVal.getType(), 1547 AtomicLVal.getAlignmentSource()); 1548 DesiredLVal = 1549 LValue::MakeBitfield(DesiredAddr, AtomicLVal.getBitFieldInfo(), 1550 AtomicLVal.getType(), 1551 AtomicLVal.getAlignmentSource()); 1552 } else if (AtomicLVal.isVectorElt()) { 1553 UpdateLVal = LValue::MakeVectorElt(Ptr, AtomicLVal.getVectorIdx(), 1554 AtomicLVal.getType(), 1555 AtomicLVal.getAlignmentSource()); 1556 DesiredLVal = LValue::MakeVectorElt( 1557 DesiredAddr, AtomicLVal.getVectorIdx(), AtomicLVal.getType(), 1558 AtomicLVal.getAlignmentSource()); 1559 } else { 1560 assert(AtomicLVal.isExtVectorElt()); 1561 UpdateLVal = LValue::MakeExtVectorElt(Ptr, AtomicLVal.getExtVectorElts(), 1562 AtomicLVal.getType(), 1563 AtomicLVal.getAlignmentSource()); 1564 DesiredLVal = LValue::MakeExtVectorElt( 1565 DesiredAddr, AtomicLVal.getExtVectorElts(), AtomicLVal.getType(), 1566 AtomicLVal.getAlignmentSource()); 1567 } 1568 UpdateLVal.setTBAAInfo(AtomicLVal.getTBAAInfo()); 1569 DesiredLVal.setTBAAInfo(AtomicLVal.getTBAAInfo()); 1570 UpRVal = CGF.EmitLoadOfLValue(UpdateLVal, SourceLocation()); 1571 } 1572 // Store new value in the corresponding memory area 1573 RValue NewRVal = UpdateOp(UpRVal); 1574 if (NewRVal.isScalar()) { 1575 CGF.EmitStoreThroughLValue(NewRVal, DesiredLVal); 1576 } else { 1577 assert(NewRVal.isComplex()); 1578 CGF.EmitStoreOfComplex(NewRVal.getComplexVal(), DesiredLVal, 1579 /*isInit=*/false); 1580 } 1581 } 1582 1583 void AtomicInfo::EmitAtomicUpdateLibcall( 1584 llvm::AtomicOrdering AO, const llvm::function_ref<RValue(RValue)> &UpdateOp, 1585 bool IsVolatile) { 1586 auto Failure = llvm::AtomicCmpXchgInst::getStrongestFailureOrdering(AO); 1587 1588 Address ExpectedAddr = CreateTempAlloca(); 1589 1590 EmitAtomicLoadLibcall(ExpectedAddr.getPointer(), AO, IsVolatile); 1591 auto *ContBB = CGF.createBasicBlock("atomic_cont"); 1592 auto *ExitBB = CGF.createBasicBlock("atomic_exit"); 1593 CGF.EmitBlock(ContBB); 1594 Address DesiredAddr = CreateTempAlloca(); 1595 if ((LVal.isBitField() && BFI.Size != ValueSizeInBits) || 1596 requiresMemSetZero(getAtomicAddress().getElementType())) { 1597 auto *OldVal = CGF.Builder.CreateLoad(ExpectedAddr); 1598 CGF.Builder.CreateStore(OldVal, DesiredAddr); 1599 } 1600 auto OldRVal = convertAtomicTempToRValue(ExpectedAddr, 1601 AggValueSlot::ignored(), 1602 SourceLocation(), /*AsValue=*/false); 1603 EmitAtomicUpdateValue(CGF, *this, OldRVal, UpdateOp, DesiredAddr); 1604 auto *Res = 1605 EmitAtomicCompareExchangeLibcall(ExpectedAddr.getPointer(), 1606 DesiredAddr.getPointer(), 1607 AO, Failure); 1608 CGF.Builder.CreateCondBr(Res, ExitBB, ContBB); 1609 CGF.EmitBlock(ExitBB, /*IsFinished=*/true); 1610 } 1611 1612 void AtomicInfo::EmitAtomicUpdateOp( 1613 llvm::AtomicOrdering AO, const llvm::function_ref<RValue(RValue)> &UpdateOp, 1614 bool IsVolatile) { 1615 auto Failure = llvm::AtomicCmpXchgInst::getStrongestFailureOrdering(AO); 1616 1617 // Do the atomic load. 1618 auto *OldVal = EmitAtomicLoadOp(AO, IsVolatile); 1619 // For non-simple lvalues perform compare-and-swap procedure. 1620 auto *ContBB = CGF.createBasicBlock("atomic_cont"); 1621 auto *ExitBB = CGF.createBasicBlock("atomic_exit"); 1622 auto *CurBB = CGF.Builder.GetInsertBlock(); 1623 CGF.EmitBlock(ContBB); 1624 llvm::PHINode *PHI = CGF.Builder.CreatePHI(OldVal->getType(), 1625 /*NumReservedValues=*/2); 1626 PHI->addIncoming(OldVal, CurBB); 1627 Address NewAtomicAddr = CreateTempAlloca(); 1628 Address NewAtomicIntAddr = emitCastToAtomicIntPointer(NewAtomicAddr); 1629 if ((LVal.isBitField() && BFI.Size != ValueSizeInBits) || 1630 requiresMemSetZero(getAtomicAddress().getElementType())) { 1631 CGF.Builder.CreateStore(PHI, NewAtomicIntAddr); 1632 } 1633 auto OldRVal = ConvertIntToValueOrAtomic(PHI, AggValueSlot::ignored(), 1634 SourceLocation(), /*AsValue=*/false); 1635 EmitAtomicUpdateValue(CGF, *this, OldRVal, UpdateOp, NewAtomicAddr); 1636 auto *DesiredVal = CGF.Builder.CreateLoad(NewAtomicIntAddr); 1637 // Try to write new value using cmpxchg operation 1638 auto Res = EmitAtomicCompareExchangeOp(PHI, DesiredVal, AO, Failure); 1639 PHI->addIncoming(Res.first, CGF.Builder.GetInsertBlock()); 1640 CGF.Builder.CreateCondBr(Res.second, ExitBB, ContBB); 1641 CGF.EmitBlock(ExitBB, /*IsFinished=*/true); 1642 } 1643 1644 static void EmitAtomicUpdateValue(CodeGenFunction &CGF, AtomicInfo &Atomics, 1645 RValue UpdateRVal, Address DesiredAddr) { 1646 LValue AtomicLVal = Atomics.getAtomicLValue(); 1647 LValue DesiredLVal; 1648 // Build new lvalue for temp address 1649 if (AtomicLVal.isBitField()) { 1650 DesiredLVal = 1651 LValue::MakeBitfield(DesiredAddr, AtomicLVal.getBitFieldInfo(), 1652 AtomicLVal.getType(), 1653 AtomicLVal.getAlignmentSource()); 1654 } else if (AtomicLVal.isVectorElt()) { 1655 DesiredLVal = 1656 LValue::MakeVectorElt(DesiredAddr, AtomicLVal.getVectorIdx(), 1657 AtomicLVal.getType(), 1658 AtomicLVal.getAlignmentSource()); 1659 } else { 1660 assert(AtomicLVal.isExtVectorElt()); 1661 DesiredLVal = LValue::MakeExtVectorElt( 1662 DesiredAddr, AtomicLVal.getExtVectorElts(), AtomicLVal.getType(), 1663 AtomicLVal.getAlignmentSource()); 1664 } 1665 DesiredLVal.setTBAAInfo(AtomicLVal.getTBAAInfo()); 1666 // Store new value in the corresponding memory area 1667 assert(UpdateRVal.isScalar()); 1668 CGF.EmitStoreThroughLValue(UpdateRVal, DesiredLVal); 1669 } 1670 1671 void AtomicInfo::EmitAtomicUpdateLibcall(llvm::AtomicOrdering AO, 1672 RValue UpdateRVal, bool IsVolatile) { 1673 auto Failure = llvm::AtomicCmpXchgInst::getStrongestFailureOrdering(AO); 1674 1675 Address ExpectedAddr = CreateTempAlloca(); 1676 1677 EmitAtomicLoadLibcall(ExpectedAddr.getPointer(), AO, IsVolatile); 1678 auto *ContBB = CGF.createBasicBlock("atomic_cont"); 1679 auto *ExitBB = CGF.createBasicBlock("atomic_exit"); 1680 CGF.EmitBlock(ContBB); 1681 Address DesiredAddr = CreateTempAlloca(); 1682 if ((LVal.isBitField() && BFI.Size != ValueSizeInBits) || 1683 requiresMemSetZero(getAtomicAddress().getElementType())) { 1684 auto *OldVal = CGF.Builder.CreateLoad(ExpectedAddr); 1685 CGF.Builder.CreateStore(OldVal, DesiredAddr); 1686 } 1687 EmitAtomicUpdateValue(CGF, *this, UpdateRVal, DesiredAddr); 1688 auto *Res = 1689 EmitAtomicCompareExchangeLibcall(ExpectedAddr.getPointer(), 1690 DesiredAddr.getPointer(), 1691 AO, Failure); 1692 CGF.Builder.CreateCondBr(Res, ExitBB, ContBB); 1693 CGF.EmitBlock(ExitBB, /*IsFinished=*/true); 1694 } 1695 1696 void AtomicInfo::EmitAtomicUpdateOp(llvm::AtomicOrdering AO, RValue UpdateRVal, 1697 bool IsVolatile) { 1698 auto Failure = llvm::AtomicCmpXchgInst::getStrongestFailureOrdering(AO); 1699 1700 // Do the atomic load. 1701 auto *OldVal = EmitAtomicLoadOp(AO, IsVolatile); 1702 // For non-simple lvalues perform compare-and-swap procedure. 1703 auto *ContBB = CGF.createBasicBlock("atomic_cont"); 1704 auto *ExitBB = CGF.createBasicBlock("atomic_exit"); 1705 auto *CurBB = CGF.Builder.GetInsertBlock(); 1706 CGF.EmitBlock(ContBB); 1707 llvm::PHINode *PHI = CGF.Builder.CreatePHI(OldVal->getType(), 1708 /*NumReservedValues=*/2); 1709 PHI->addIncoming(OldVal, CurBB); 1710 Address NewAtomicAddr = CreateTempAlloca(); 1711 Address NewAtomicIntAddr = emitCastToAtomicIntPointer(NewAtomicAddr); 1712 if ((LVal.isBitField() && BFI.Size != ValueSizeInBits) || 1713 requiresMemSetZero(getAtomicAddress().getElementType())) { 1714 CGF.Builder.CreateStore(PHI, NewAtomicIntAddr); 1715 } 1716 EmitAtomicUpdateValue(CGF, *this, UpdateRVal, NewAtomicAddr); 1717 auto *DesiredVal = CGF.Builder.CreateLoad(NewAtomicIntAddr); 1718 // Try to write new value using cmpxchg operation 1719 auto Res = EmitAtomicCompareExchangeOp(PHI, DesiredVal, AO, Failure); 1720 PHI->addIncoming(Res.first, CGF.Builder.GetInsertBlock()); 1721 CGF.Builder.CreateCondBr(Res.second, ExitBB, ContBB); 1722 CGF.EmitBlock(ExitBB, /*IsFinished=*/true); 1723 } 1724 1725 void AtomicInfo::EmitAtomicUpdate( 1726 llvm::AtomicOrdering AO, const llvm::function_ref<RValue(RValue)> &UpdateOp, 1727 bool IsVolatile) { 1728 if (shouldUseLibcall()) { 1729 EmitAtomicUpdateLibcall(AO, UpdateOp, IsVolatile); 1730 } else { 1731 EmitAtomicUpdateOp(AO, UpdateOp, IsVolatile); 1732 } 1733 } 1734 1735 void AtomicInfo::EmitAtomicUpdate(llvm::AtomicOrdering AO, RValue UpdateRVal, 1736 bool IsVolatile) { 1737 if (shouldUseLibcall()) { 1738 EmitAtomicUpdateLibcall(AO, UpdateRVal, IsVolatile); 1739 } else { 1740 EmitAtomicUpdateOp(AO, UpdateRVal, IsVolatile); 1741 } 1742 } 1743 1744 void CodeGenFunction::EmitAtomicStore(RValue rvalue, LValue lvalue, 1745 bool isInit) { 1746 bool IsVolatile = lvalue.isVolatileQualified(); 1747 llvm::AtomicOrdering AO; 1748 if (lvalue.getType()->isAtomicType()) { 1749 AO = llvm::AtomicOrdering::SequentiallyConsistent; 1750 } else { 1751 AO = llvm::AtomicOrdering::Release; 1752 IsVolatile = true; 1753 } 1754 return EmitAtomicStore(rvalue, lvalue, AO, IsVolatile, isInit); 1755 } 1756 1757 /// Emit a store to an l-value of atomic type. 1758 /// 1759 /// Note that the r-value is expected to be an r-value *of the atomic 1760 /// type*; this means that for aggregate r-values, it should include 1761 /// storage for any padding that was necessary. 1762 void CodeGenFunction::EmitAtomicStore(RValue rvalue, LValue dest, 1763 llvm::AtomicOrdering AO, bool IsVolatile, 1764 bool isInit) { 1765 // If this is an aggregate r-value, it should agree in type except 1766 // maybe for address-space qualification. 1767 assert(!rvalue.isAggregate() || 1768 rvalue.getAggregateAddress().getElementType() 1769 == dest.getAddress().getElementType()); 1770 1771 AtomicInfo atomics(*this, dest); 1772 LValue LVal = atomics.getAtomicLValue(); 1773 1774 // If this is an initialization, just put the value there normally. 1775 if (LVal.isSimple()) { 1776 if (isInit) { 1777 atomics.emitCopyIntoMemory(rvalue); 1778 return; 1779 } 1780 1781 // Check whether we should use a library call. 1782 if (atomics.shouldUseLibcall()) { 1783 // Produce a source address. 1784 Address srcAddr = atomics.materializeRValue(rvalue); 1785 1786 // void __atomic_store(size_t size, void *mem, void *val, int order) 1787 CallArgList args; 1788 args.add(RValue::get(atomics.getAtomicSizeValue()), 1789 getContext().getSizeType()); 1790 args.add(RValue::get(EmitCastToVoidPtr(atomics.getAtomicPointer())), 1791 getContext().VoidPtrTy); 1792 args.add(RValue::get(EmitCastToVoidPtr(srcAddr.getPointer())), 1793 getContext().VoidPtrTy); 1794 args.add(RValue::get(llvm::ConstantInt::get( 1795 IntTy, AtomicInfo::translateAtomicOrdering(AO))), 1796 getContext().IntTy); 1797 emitAtomicLibcall(*this, "__atomic_store", getContext().VoidTy, args); 1798 return; 1799 } 1800 1801 // Okay, we're doing this natively. 1802 llvm::Value *intValue = atomics.convertRValueToInt(rvalue); 1803 1804 // Do the atomic store. 1805 Address addr = 1806 atomics.emitCastToAtomicIntPointer(atomics.getAtomicAddress()); 1807 intValue = Builder.CreateIntCast( 1808 intValue, addr.getElementType(), /*isSigned=*/false); 1809 llvm::StoreInst *store = Builder.CreateStore(intValue, addr); 1810 1811 // Initializations don't need to be atomic. 1812 if (!isInit) 1813 store->setAtomic(AO); 1814 1815 // Other decoration. 1816 if (IsVolatile) 1817 store->setVolatile(true); 1818 if (dest.getTBAAInfo()) 1819 CGM.DecorateInstructionWithTBAA(store, dest.getTBAAInfo()); 1820 return; 1821 } 1822 1823 // Emit simple atomic update operation. 1824 atomics.EmitAtomicUpdate(AO, rvalue, IsVolatile); 1825 } 1826 1827 /// Emit a compare-and-exchange op for atomic type. 1828 /// 1829 std::pair<RValue, llvm::Value *> CodeGenFunction::EmitAtomicCompareExchange( 1830 LValue Obj, RValue Expected, RValue Desired, SourceLocation Loc, 1831 llvm::AtomicOrdering Success, llvm::AtomicOrdering Failure, bool IsWeak, 1832 AggValueSlot Slot) { 1833 // If this is an aggregate r-value, it should agree in type except 1834 // maybe for address-space qualification. 1835 assert(!Expected.isAggregate() || 1836 Expected.getAggregateAddress().getElementType() == 1837 Obj.getAddress().getElementType()); 1838 assert(!Desired.isAggregate() || 1839 Desired.getAggregateAddress().getElementType() == 1840 Obj.getAddress().getElementType()); 1841 AtomicInfo Atomics(*this, Obj); 1842 1843 return Atomics.EmitAtomicCompareExchange(Expected, Desired, Success, Failure, 1844 IsWeak); 1845 } 1846 1847 void CodeGenFunction::EmitAtomicUpdate( 1848 LValue LVal, llvm::AtomicOrdering AO, 1849 const llvm::function_ref<RValue(RValue)> &UpdateOp, bool IsVolatile) { 1850 AtomicInfo Atomics(*this, LVal); 1851 Atomics.EmitAtomicUpdate(AO, UpdateOp, IsVolatile); 1852 } 1853 1854 void CodeGenFunction::EmitAtomicInit(Expr *init, LValue dest) { 1855 AtomicInfo atomics(*this, dest); 1856 1857 switch (atomics.getEvaluationKind()) { 1858 case TEK_Scalar: { 1859 llvm::Value *value = EmitScalarExpr(init); 1860 atomics.emitCopyIntoMemory(RValue::get(value)); 1861 return; 1862 } 1863 1864 case TEK_Complex: { 1865 ComplexPairTy value = EmitComplexExpr(init); 1866 atomics.emitCopyIntoMemory(RValue::getComplex(value)); 1867 return; 1868 } 1869 1870 case TEK_Aggregate: { 1871 // Fix up the destination if the initializer isn't an expression 1872 // of atomic type. 1873 bool Zeroed = false; 1874 if (!init->getType()->isAtomicType()) { 1875 Zeroed = atomics.emitMemSetZeroIfNecessary(); 1876 dest = atomics.projectValue(); 1877 } 1878 1879 // Evaluate the expression directly into the destination. 1880 AggValueSlot slot = AggValueSlot::forLValue(dest, 1881 AggValueSlot::IsNotDestructed, 1882 AggValueSlot::DoesNotNeedGCBarriers, 1883 AggValueSlot::IsNotAliased, 1884 Zeroed ? AggValueSlot::IsZeroed : 1885 AggValueSlot::IsNotZeroed); 1886 1887 EmitAggExpr(init, slot); 1888 return; 1889 } 1890 } 1891 llvm_unreachable("bad evaluation kind"); 1892 } 1893