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 (isStrongerThan(FailureOrder, SuccessOrder)) { 451 // Don't assert on undefined behavior "failure argument shall be no 452 // stronger than the success argument". 453 FailureOrder = 454 llvm::AtomicCmpXchgInst::getStrongestFailureOrdering(SuccessOrder); 455 } 456 emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, Size, 457 SuccessOrder, FailureOrder); 458 return; 459 } 460 461 // Create all the relevant BB's 462 llvm::BasicBlock *MonotonicBB = nullptr, *AcquireBB = nullptr, 463 *SeqCstBB = nullptr; 464 MonotonicBB = CGF.createBasicBlock("monotonic_fail", CGF.CurFn); 465 if (SuccessOrder != llvm::AtomicOrdering::Monotonic && 466 SuccessOrder != llvm::AtomicOrdering::Release) 467 AcquireBB = CGF.createBasicBlock("acquire_fail", CGF.CurFn); 468 if (SuccessOrder == llvm::AtomicOrdering::SequentiallyConsistent) 469 SeqCstBB = CGF.createBasicBlock("seqcst_fail", CGF.CurFn); 470 471 llvm::BasicBlock *ContBB = CGF.createBasicBlock("atomic.continue", CGF.CurFn); 472 473 llvm::SwitchInst *SI = CGF.Builder.CreateSwitch(FailureOrderVal, MonotonicBB); 474 475 // Emit all the different atomics 476 477 // MonotonicBB is arbitrarily chosen as the default case; in practice, this 478 // doesn't matter unless someone is crazy enough to use something that 479 // doesn't fold to a constant for the ordering. 480 CGF.Builder.SetInsertPoint(MonotonicBB); 481 emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, 482 Size, SuccessOrder, llvm::AtomicOrdering::Monotonic); 483 CGF.Builder.CreateBr(ContBB); 484 485 if (AcquireBB) { 486 CGF.Builder.SetInsertPoint(AcquireBB); 487 emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, 488 Size, SuccessOrder, llvm::AtomicOrdering::Acquire); 489 CGF.Builder.CreateBr(ContBB); 490 SI->addCase(CGF.Builder.getInt32(AtomicExpr::AO_ABI_memory_order_consume), 491 AcquireBB); 492 SI->addCase(CGF.Builder.getInt32(AtomicExpr::AO_ABI_memory_order_acquire), 493 AcquireBB); 494 } 495 if (SeqCstBB) { 496 CGF.Builder.SetInsertPoint(SeqCstBB); 497 emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, Size, SuccessOrder, 498 llvm::AtomicOrdering::SequentiallyConsistent); 499 CGF.Builder.CreateBr(ContBB); 500 SI->addCase(CGF.Builder.getInt32(AtomicExpr::AO_ABI_memory_order_seq_cst), 501 SeqCstBB); 502 } 503 504 CGF.Builder.SetInsertPoint(ContBB); 505 } 506 507 static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, Address Dest, 508 Address Ptr, Address Val1, Address Val2, 509 llvm::Value *IsWeak, llvm::Value *FailureOrder, 510 uint64_t Size, llvm::AtomicOrdering Order) { 511 llvm::AtomicRMWInst::BinOp Op = llvm::AtomicRMWInst::Add; 512 llvm::Instruction::BinaryOps PostOp = (llvm::Instruction::BinaryOps)0; 513 514 switch (E->getOp()) { 515 case AtomicExpr::AO__c11_atomic_init: 516 llvm_unreachable("Already handled!"); 517 518 case AtomicExpr::AO__c11_atomic_compare_exchange_strong: 519 emitAtomicCmpXchgFailureSet(CGF, E, false, Dest, Ptr, Val1, Val2, 520 FailureOrder, Size, Order); 521 return; 522 case AtomicExpr::AO__c11_atomic_compare_exchange_weak: 523 emitAtomicCmpXchgFailureSet(CGF, E, true, Dest, Ptr, Val1, Val2, 524 FailureOrder, Size, Order); 525 return; 526 case AtomicExpr::AO__atomic_compare_exchange: 527 case AtomicExpr::AO__atomic_compare_exchange_n: { 528 if (llvm::ConstantInt *IsWeakC = dyn_cast<llvm::ConstantInt>(IsWeak)) { 529 emitAtomicCmpXchgFailureSet(CGF, E, IsWeakC->getZExtValue(), Dest, Ptr, 530 Val1, Val2, FailureOrder, Size, Order); 531 } else { 532 // Create all the relevant BB's 533 llvm::BasicBlock *StrongBB = 534 CGF.createBasicBlock("cmpxchg.strong", CGF.CurFn); 535 llvm::BasicBlock *WeakBB = CGF.createBasicBlock("cmxchg.weak", CGF.CurFn); 536 llvm::BasicBlock *ContBB = 537 CGF.createBasicBlock("cmpxchg.continue", CGF.CurFn); 538 539 llvm::SwitchInst *SI = CGF.Builder.CreateSwitch(IsWeak, WeakBB); 540 SI->addCase(CGF.Builder.getInt1(false), StrongBB); 541 542 CGF.Builder.SetInsertPoint(StrongBB); 543 emitAtomicCmpXchgFailureSet(CGF, E, false, Dest, Ptr, Val1, Val2, 544 FailureOrder, Size, Order); 545 CGF.Builder.CreateBr(ContBB); 546 547 CGF.Builder.SetInsertPoint(WeakBB); 548 emitAtomicCmpXchgFailureSet(CGF, E, true, Dest, Ptr, Val1, Val2, 549 FailureOrder, Size, Order); 550 CGF.Builder.CreateBr(ContBB); 551 552 CGF.Builder.SetInsertPoint(ContBB); 553 } 554 return; 555 } 556 case AtomicExpr::AO__c11_atomic_load: 557 case AtomicExpr::AO__atomic_load_n: 558 case AtomicExpr::AO__atomic_load: { 559 llvm::LoadInst *Load = CGF.Builder.CreateLoad(Ptr); 560 Load->setAtomic(Order); 561 Load->setVolatile(E->isVolatile()); 562 CGF.Builder.CreateStore(Load, Dest); 563 return; 564 } 565 566 case AtomicExpr::AO__c11_atomic_store: 567 case AtomicExpr::AO__atomic_store: 568 case AtomicExpr::AO__atomic_store_n: { 569 llvm::Value *LoadVal1 = CGF.Builder.CreateLoad(Val1); 570 llvm::StoreInst *Store = CGF.Builder.CreateStore(LoadVal1, Ptr); 571 Store->setAtomic(Order); 572 Store->setVolatile(E->isVolatile()); 573 return; 574 } 575 576 case AtomicExpr::AO__c11_atomic_exchange: 577 case AtomicExpr::AO__atomic_exchange_n: 578 case AtomicExpr::AO__atomic_exchange: 579 Op = llvm::AtomicRMWInst::Xchg; 580 break; 581 582 case AtomicExpr::AO__atomic_add_fetch: 583 PostOp = llvm::Instruction::Add; 584 // Fall through. 585 case AtomicExpr::AO__c11_atomic_fetch_add: 586 case AtomicExpr::AO__atomic_fetch_add: 587 Op = llvm::AtomicRMWInst::Add; 588 break; 589 590 case AtomicExpr::AO__atomic_sub_fetch: 591 PostOp = llvm::Instruction::Sub; 592 // Fall through. 593 case AtomicExpr::AO__c11_atomic_fetch_sub: 594 case AtomicExpr::AO__atomic_fetch_sub: 595 Op = llvm::AtomicRMWInst::Sub; 596 break; 597 598 case AtomicExpr::AO__atomic_and_fetch: 599 PostOp = llvm::Instruction::And; 600 // Fall through. 601 case AtomicExpr::AO__c11_atomic_fetch_and: 602 case AtomicExpr::AO__atomic_fetch_and: 603 Op = llvm::AtomicRMWInst::And; 604 break; 605 606 case AtomicExpr::AO__atomic_or_fetch: 607 PostOp = llvm::Instruction::Or; 608 // Fall through. 609 case AtomicExpr::AO__c11_atomic_fetch_or: 610 case AtomicExpr::AO__atomic_fetch_or: 611 Op = llvm::AtomicRMWInst::Or; 612 break; 613 614 case AtomicExpr::AO__atomic_xor_fetch: 615 PostOp = llvm::Instruction::Xor; 616 // Fall through. 617 case AtomicExpr::AO__c11_atomic_fetch_xor: 618 case AtomicExpr::AO__atomic_fetch_xor: 619 Op = llvm::AtomicRMWInst::Xor; 620 break; 621 622 case AtomicExpr::AO__atomic_nand_fetch: 623 PostOp = llvm::Instruction::And; // the NOT is special cased below 624 // Fall through. 625 case AtomicExpr::AO__atomic_fetch_nand: 626 Op = llvm::AtomicRMWInst::Nand; 627 break; 628 } 629 630 llvm::Value *LoadVal1 = CGF.Builder.CreateLoad(Val1); 631 llvm::AtomicRMWInst *RMWI = 632 CGF.Builder.CreateAtomicRMW(Op, Ptr.getPointer(), LoadVal1, Order); 633 RMWI->setVolatile(E->isVolatile()); 634 635 // For __atomic_*_fetch operations, perform the operation again to 636 // determine the value which was written. 637 llvm::Value *Result = RMWI; 638 if (PostOp) 639 Result = CGF.Builder.CreateBinOp(PostOp, RMWI, LoadVal1); 640 if (E->getOp() == AtomicExpr::AO__atomic_nand_fetch) 641 Result = CGF.Builder.CreateNot(Result); 642 CGF.Builder.CreateStore(Result, Dest); 643 } 644 645 // This function emits any expression (scalar, complex, or aggregate) 646 // into a temporary alloca. 647 static Address 648 EmitValToTemp(CodeGenFunction &CGF, Expr *E) { 649 Address DeclPtr = CGF.CreateMemTemp(E->getType(), ".atomictmp"); 650 CGF.EmitAnyExprToMem(E, DeclPtr, E->getType().getQualifiers(), 651 /*Init*/ true); 652 return DeclPtr; 653 } 654 655 static void 656 AddDirectArgument(CodeGenFunction &CGF, CallArgList &Args, 657 bool UseOptimizedLibcall, llvm::Value *Val, QualType ValTy, 658 SourceLocation Loc, CharUnits SizeInChars) { 659 if (UseOptimizedLibcall) { 660 // Load value and pass it to the function directly. 661 CharUnits Align = CGF.getContext().getTypeAlignInChars(ValTy); 662 int64_t SizeInBits = CGF.getContext().toBits(SizeInChars); 663 ValTy = 664 CGF.getContext().getIntTypeForBitwidth(SizeInBits, /*Signed=*/false); 665 llvm::Type *IPtrTy = llvm::IntegerType::get(CGF.getLLVMContext(), 666 SizeInBits)->getPointerTo(); 667 Address Ptr = Address(CGF.Builder.CreateBitCast(Val, IPtrTy), Align); 668 Val = CGF.EmitLoadOfScalar(Ptr, false, 669 CGF.getContext().getPointerType(ValTy), 670 Loc); 671 // Coerce the value into an appropriately sized integer type. 672 Args.add(RValue::get(Val), ValTy); 673 } else { 674 // Non-optimized functions always take a reference. 675 Args.add(RValue::get(CGF.EmitCastToVoidPtr(Val)), 676 CGF.getContext().VoidPtrTy); 677 } 678 } 679 680 RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E) { 681 QualType AtomicTy = E->getPtr()->getType()->getPointeeType(); 682 QualType MemTy = AtomicTy; 683 if (const AtomicType *AT = AtomicTy->getAs<AtomicType>()) 684 MemTy = AT->getValueType(); 685 CharUnits sizeChars, alignChars; 686 std::tie(sizeChars, alignChars) = getContext().getTypeInfoInChars(AtomicTy); 687 uint64_t Size = sizeChars.getQuantity(); 688 unsigned MaxInlineWidthInBits = getTarget().getMaxAtomicInlineWidth(); 689 bool UseLibcall = (sizeChars != alignChars || 690 getContext().toBits(sizeChars) > MaxInlineWidthInBits); 691 692 llvm::Value *IsWeak = nullptr, *OrderFail = nullptr; 693 694 Address Val1 = Address::invalid(); 695 Address Val2 = Address::invalid(); 696 Address Dest = Address::invalid(); 697 Address Ptr(EmitScalarExpr(E->getPtr()), alignChars); 698 699 if (E->getOp() == AtomicExpr::AO__c11_atomic_init) { 700 LValue lvalue = MakeAddrLValue(Ptr, AtomicTy); 701 EmitAtomicInit(E->getVal1(), lvalue); 702 return RValue::get(nullptr); 703 } 704 705 llvm::Value *Order = EmitScalarExpr(E->getOrder()); 706 707 switch (E->getOp()) { 708 case AtomicExpr::AO__c11_atomic_init: 709 llvm_unreachable("Already handled above with EmitAtomicInit!"); 710 711 case AtomicExpr::AO__c11_atomic_load: 712 case AtomicExpr::AO__atomic_load_n: 713 break; 714 715 case AtomicExpr::AO__atomic_load: 716 Dest = EmitPointerWithAlignment(E->getVal1()); 717 break; 718 719 case AtomicExpr::AO__atomic_store: 720 Val1 = EmitPointerWithAlignment(E->getVal1()); 721 break; 722 723 case AtomicExpr::AO__atomic_exchange: 724 Val1 = EmitPointerWithAlignment(E->getVal1()); 725 Dest = EmitPointerWithAlignment(E->getVal2()); 726 break; 727 728 case AtomicExpr::AO__c11_atomic_compare_exchange_strong: 729 case AtomicExpr::AO__c11_atomic_compare_exchange_weak: 730 case AtomicExpr::AO__atomic_compare_exchange_n: 731 case AtomicExpr::AO__atomic_compare_exchange: 732 Val1 = EmitPointerWithAlignment(E->getVal1()); 733 if (E->getOp() == AtomicExpr::AO__atomic_compare_exchange) 734 Val2 = EmitPointerWithAlignment(E->getVal2()); 735 else 736 Val2 = EmitValToTemp(*this, E->getVal2()); 737 OrderFail = EmitScalarExpr(E->getOrderFail()); 738 if (E->getNumSubExprs() == 6) 739 IsWeak = EmitScalarExpr(E->getWeak()); 740 break; 741 742 case AtomicExpr::AO__c11_atomic_fetch_add: 743 case AtomicExpr::AO__c11_atomic_fetch_sub: 744 if (MemTy->isPointerType()) { 745 // For pointer arithmetic, we're required to do a bit of math: 746 // adding 1 to an int* is not the same as adding 1 to a uintptr_t. 747 // ... but only for the C11 builtins. The GNU builtins expect the 748 // user to multiply by sizeof(T). 749 QualType Val1Ty = E->getVal1()->getType(); 750 llvm::Value *Val1Scalar = EmitScalarExpr(E->getVal1()); 751 CharUnits PointeeIncAmt = 752 getContext().getTypeSizeInChars(MemTy->getPointeeType()); 753 Val1Scalar = Builder.CreateMul(Val1Scalar, CGM.getSize(PointeeIncAmt)); 754 auto Temp = CreateMemTemp(Val1Ty, ".atomictmp"); 755 Val1 = Temp; 756 EmitStoreOfScalar(Val1Scalar, MakeAddrLValue(Temp, Val1Ty)); 757 break; 758 } 759 // Fall through. 760 case AtomicExpr::AO__atomic_fetch_add: 761 case AtomicExpr::AO__atomic_fetch_sub: 762 case AtomicExpr::AO__atomic_add_fetch: 763 case AtomicExpr::AO__atomic_sub_fetch: 764 case AtomicExpr::AO__c11_atomic_store: 765 case AtomicExpr::AO__c11_atomic_exchange: 766 case AtomicExpr::AO__atomic_store_n: 767 case AtomicExpr::AO__atomic_exchange_n: 768 case AtomicExpr::AO__c11_atomic_fetch_and: 769 case AtomicExpr::AO__c11_atomic_fetch_or: 770 case AtomicExpr::AO__c11_atomic_fetch_xor: 771 case AtomicExpr::AO__atomic_fetch_and: 772 case AtomicExpr::AO__atomic_fetch_or: 773 case AtomicExpr::AO__atomic_fetch_xor: 774 case AtomicExpr::AO__atomic_fetch_nand: 775 case AtomicExpr::AO__atomic_and_fetch: 776 case AtomicExpr::AO__atomic_or_fetch: 777 case AtomicExpr::AO__atomic_xor_fetch: 778 case AtomicExpr::AO__atomic_nand_fetch: 779 Val1 = EmitValToTemp(*this, E->getVal1()); 780 break; 781 } 782 783 QualType RValTy = E->getType().getUnqualifiedType(); 784 785 // The inlined atomics only function on iN types, where N is a power of 2. We 786 // need to make sure (via temporaries if necessary) that all incoming values 787 // are compatible. 788 LValue AtomicVal = MakeAddrLValue(Ptr, AtomicTy); 789 AtomicInfo Atomics(*this, AtomicVal); 790 791 Ptr = Atomics.emitCastToAtomicIntPointer(Ptr); 792 if (Val1.isValid()) Val1 = Atomics.convertToAtomicIntPointer(Val1); 793 if (Val2.isValid()) Val2 = Atomics.convertToAtomicIntPointer(Val2); 794 if (Dest.isValid()) 795 Dest = Atomics.emitCastToAtomicIntPointer(Dest); 796 else if (E->isCmpXChg()) 797 Dest = CreateMemTemp(RValTy, "cmpxchg.bool"); 798 else if (!RValTy->isVoidType()) 799 Dest = Atomics.emitCastToAtomicIntPointer(Atomics.CreateTempAlloca()); 800 801 // Use a library call. See: http://gcc.gnu.org/wiki/Atomic/GCCMM/LIbrary . 802 if (UseLibcall) { 803 bool UseOptimizedLibcall = false; 804 switch (E->getOp()) { 805 case AtomicExpr::AO__c11_atomic_init: 806 llvm_unreachable("Already handled above with EmitAtomicInit!"); 807 808 case AtomicExpr::AO__c11_atomic_fetch_add: 809 case AtomicExpr::AO__atomic_fetch_add: 810 case AtomicExpr::AO__c11_atomic_fetch_and: 811 case AtomicExpr::AO__atomic_fetch_and: 812 case AtomicExpr::AO__c11_atomic_fetch_or: 813 case AtomicExpr::AO__atomic_fetch_or: 814 case AtomicExpr::AO__atomic_fetch_nand: 815 case AtomicExpr::AO__c11_atomic_fetch_sub: 816 case AtomicExpr::AO__atomic_fetch_sub: 817 case AtomicExpr::AO__c11_atomic_fetch_xor: 818 case AtomicExpr::AO__atomic_fetch_xor: 819 case AtomicExpr::AO__atomic_add_fetch: 820 case AtomicExpr::AO__atomic_and_fetch: 821 case AtomicExpr::AO__atomic_nand_fetch: 822 case AtomicExpr::AO__atomic_or_fetch: 823 case AtomicExpr::AO__atomic_sub_fetch: 824 case AtomicExpr::AO__atomic_xor_fetch: 825 // For these, only library calls for certain sizes exist. 826 UseOptimizedLibcall = true; 827 break; 828 829 case AtomicExpr::AO__c11_atomic_load: 830 case AtomicExpr::AO__c11_atomic_store: 831 case AtomicExpr::AO__c11_atomic_exchange: 832 case AtomicExpr::AO__c11_atomic_compare_exchange_weak: 833 case AtomicExpr::AO__c11_atomic_compare_exchange_strong: 834 case AtomicExpr::AO__atomic_load_n: 835 case AtomicExpr::AO__atomic_load: 836 case AtomicExpr::AO__atomic_store_n: 837 case AtomicExpr::AO__atomic_store: 838 case AtomicExpr::AO__atomic_exchange_n: 839 case AtomicExpr::AO__atomic_exchange: 840 case AtomicExpr::AO__atomic_compare_exchange_n: 841 case AtomicExpr::AO__atomic_compare_exchange: 842 // Only use optimized library calls for sizes for which they exist. 843 if (Size == 1 || Size == 2 || Size == 4 || Size == 8) 844 UseOptimizedLibcall = true; 845 break; 846 } 847 848 CallArgList Args; 849 if (!UseOptimizedLibcall) { 850 // For non-optimized library calls, the size is the first parameter 851 Args.add(RValue::get(llvm::ConstantInt::get(SizeTy, Size)), 852 getContext().getSizeType()); 853 } 854 // Atomic address is the first or second parameter 855 Args.add(RValue::get(EmitCastToVoidPtr(Ptr.getPointer())), 856 getContext().VoidPtrTy); 857 858 std::string LibCallName; 859 QualType LoweredMemTy = 860 MemTy->isPointerType() ? getContext().getIntPtrType() : MemTy; 861 QualType RetTy; 862 bool HaveRetTy = false; 863 llvm::Instruction::BinaryOps PostOp = (llvm::Instruction::BinaryOps)0; 864 switch (E->getOp()) { 865 case AtomicExpr::AO__c11_atomic_init: 866 llvm_unreachable("Already handled!"); 867 868 // There is only one libcall for compare an exchange, because there is no 869 // optimisation benefit possible from a libcall version of a weak compare 870 // and exchange. 871 // bool __atomic_compare_exchange(size_t size, void *mem, void *expected, 872 // void *desired, int success, int failure) 873 // bool __atomic_compare_exchange_N(T *mem, T *expected, T desired, 874 // int success, int failure) 875 case AtomicExpr::AO__c11_atomic_compare_exchange_weak: 876 case AtomicExpr::AO__c11_atomic_compare_exchange_strong: 877 case AtomicExpr::AO__atomic_compare_exchange: 878 case AtomicExpr::AO__atomic_compare_exchange_n: 879 LibCallName = "__atomic_compare_exchange"; 880 RetTy = getContext().BoolTy; 881 HaveRetTy = true; 882 Args.add(RValue::get(EmitCastToVoidPtr(Val1.getPointer())), 883 getContext().VoidPtrTy); 884 AddDirectArgument(*this, Args, UseOptimizedLibcall, Val2.getPointer(), 885 MemTy, E->getExprLoc(), sizeChars); 886 Args.add(RValue::get(Order), getContext().IntTy); 887 Order = OrderFail; 888 break; 889 // void __atomic_exchange(size_t size, void *mem, void *val, void *return, 890 // int order) 891 // T __atomic_exchange_N(T *mem, T val, int order) 892 case AtomicExpr::AO__c11_atomic_exchange: 893 case AtomicExpr::AO__atomic_exchange_n: 894 case AtomicExpr::AO__atomic_exchange: 895 LibCallName = "__atomic_exchange"; 896 AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1.getPointer(), 897 MemTy, E->getExprLoc(), sizeChars); 898 break; 899 // void __atomic_store(size_t size, void *mem, void *val, int order) 900 // void __atomic_store_N(T *mem, T val, int order) 901 case AtomicExpr::AO__c11_atomic_store: 902 case AtomicExpr::AO__atomic_store: 903 case AtomicExpr::AO__atomic_store_n: 904 LibCallName = "__atomic_store"; 905 RetTy = getContext().VoidTy; 906 HaveRetTy = true; 907 AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1.getPointer(), 908 MemTy, E->getExprLoc(), sizeChars); 909 break; 910 // void __atomic_load(size_t size, void *mem, void *return, int order) 911 // T __atomic_load_N(T *mem, int order) 912 case AtomicExpr::AO__c11_atomic_load: 913 case AtomicExpr::AO__atomic_load: 914 case AtomicExpr::AO__atomic_load_n: 915 LibCallName = "__atomic_load"; 916 break; 917 // T __atomic_add_fetch_N(T *mem, T val, int order) 918 // T __atomic_fetch_add_N(T *mem, T val, int order) 919 case AtomicExpr::AO__atomic_add_fetch: 920 PostOp = llvm::Instruction::Add; 921 // Fall through. 922 case AtomicExpr::AO__c11_atomic_fetch_add: 923 case AtomicExpr::AO__atomic_fetch_add: 924 LibCallName = "__atomic_fetch_add"; 925 AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1.getPointer(), 926 LoweredMemTy, E->getExprLoc(), sizeChars); 927 break; 928 // T __atomic_and_fetch_N(T *mem, T val, int order) 929 // T __atomic_fetch_and_N(T *mem, T val, int order) 930 case AtomicExpr::AO__atomic_and_fetch: 931 PostOp = llvm::Instruction::And; 932 // Fall through. 933 case AtomicExpr::AO__c11_atomic_fetch_and: 934 case AtomicExpr::AO__atomic_fetch_and: 935 LibCallName = "__atomic_fetch_and"; 936 AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1.getPointer(), 937 MemTy, E->getExprLoc(), sizeChars); 938 break; 939 // T __atomic_or_fetch_N(T *mem, T val, int order) 940 // T __atomic_fetch_or_N(T *mem, T val, int order) 941 case AtomicExpr::AO__atomic_or_fetch: 942 PostOp = llvm::Instruction::Or; 943 // Fall through. 944 case AtomicExpr::AO__c11_atomic_fetch_or: 945 case AtomicExpr::AO__atomic_fetch_or: 946 LibCallName = "__atomic_fetch_or"; 947 AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1.getPointer(), 948 MemTy, E->getExprLoc(), sizeChars); 949 break; 950 // T __atomic_sub_fetch_N(T *mem, T val, int order) 951 // T __atomic_fetch_sub_N(T *mem, T val, int order) 952 case AtomicExpr::AO__atomic_sub_fetch: 953 PostOp = llvm::Instruction::Sub; 954 // Fall through. 955 case AtomicExpr::AO__c11_atomic_fetch_sub: 956 case AtomicExpr::AO__atomic_fetch_sub: 957 LibCallName = "__atomic_fetch_sub"; 958 AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1.getPointer(), 959 LoweredMemTy, E->getExprLoc(), sizeChars); 960 break; 961 // T __atomic_xor_fetch_N(T *mem, T val, int order) 962 // T __atomic_fetch_xor_N(T *mem, T val, int order) 963 case AtomicExpr::AO__atomic_xor_fetch: 964 PostOp = llvm::Instruction::Xor; 965 // Fall through. 966 case AtomicExpr::AO__c11_atomic_fetch_xor: 967 case AtomicExpr::AO__atomic_fetch_xor: 968 LibCallName = "__atomic_fetch_xor"; 969 AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1.getPointer(), 970 MemTy, E->getExprLoc(), sizeChars); 971 break; 972 // T __atomic_nand_fetch_N(T *mem, T val, int order) 973 // T __atomic_fetch_nand_N(T *mem, T val, int order) 974 case AtomicExpr::AO__atomic_nand_fetch: 975 PostOp = llvm::Instruction::And; // the NOT is special cased below 976 // Fall through. 977 case AtomicExpr::AO__atomic_fetch_nand: 978 LibCallName = "__atomic_fetch_nand"; 979 AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1.getPointer(), 980 MemTy, E->getExprLoc(), sizeChars); 981 break; 982 } 983 984 // Optimized functions have the size in their name. 985 if (UseOptimizedLibcall) 986 LibCallName += "_" + llvm::utostr(Size); 987 // By default, assume we return a value of the atomic type. 988 if (!HaveRetTy) { 989 if (UseOptimizedLibcall) { 990 // Value is returned directly. 991 // The function returns an appropriately sized integer type. 992 RetTy = getContext().getIntTypeForBitwidth( 993 getContext().toBits(sizeChars), /*Signed=*/false); 994 } else { 995 // Value is returned through parameter before the order. 996 RetTy = getContext().VoidTy; 997 Args.add(RValue::get(EmitCastToVoidPtr(Dest.getPointer())), 998 getContext().VoidPtrTy); 999 } 1000 } 1001 // order is always the last parameter 1002 Args.add(RValue::get(Order), 1003 getContext().IntTy); 1004 1005 // PostOp is only needed for the atomic_*_fetch operations, and 1006 // thus is only needed for and implemented in the 1007 // UseOptimizedLibcall codepath. 1008 assert(UseOptimizedLibcall || !PostOp); 1009 1010 RValue Res = emitAtomicLibcall(*this, LibCallName, RetTy, Args); 1011 // The value is returned directly from the libcall. 1012 if (E->isCmpXChg()) 1013 return Res; 1014 1015 // The value is returned directly for optimized libcalls but the expr 1016 // provided an out-param. 1017 if (UseOptimizedLibcall && Res.getScalarVal()) { 1018 llvm::Value *ResVal = Res.getScalarVal(); 1019 if (PostOp) { 1020 llvm::Value *LoadVal1 = Args[1].RV.getScalarVal(); 1021 ResVal = Builder.CreateBinOp(PostOp, ResVal, LoadVal1); 1022 } 1023 if (E->getOp() == AtomicExpr::AO__atomic_nand_fetch) 1024 ResVal = Builder.CreateNot(ResVal); 1025 1026 Builder.CreateStore( 1027 ResVal, 1028 Builder.CreateBitCast(Dest, ResVal->getType()->getPointerTo())); 1029 } 1030 1031 if (RValTy->isVoidType()) 1032 return RValue::get(nullptr); 1033 1034 return convertTempToRValue( 1035 Builder.CreateBitCast(Dest, ConvertTypeForMem(RValTy)->getPointerTo()), 1036 RValTy, E->getExprLoc()); 1037 } 1038 1039 bool IsStore = E->getOp() == AtomicExpr::AO__c11_atomic_store || 1040 E->getOp() == AtomicExpr::AO__atomic_store || 1041 E->getOp() == AtomicExpr::AO__atomic_store_n; 1042 bool IsLoad = E->getOp() == AtomicExpr::AO__c11_atomic_load || 1043 E->getOp() == AtomicExpr::AO__atomic_load || 1044 E->getOp() == AtomicExpr::AO__atomic_load_n; 1045 1046 if (isa<llvm::ConstantInt>(Order)) { 1047 int ord = cast<llvm::ConstantInt>(Order)->getZExtValue(); 1048 switch (ord) { 1049 case AtomicExpr::AO_ABI_memory_order_relaxed: 1050 EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, 1051 Size, llvm::AtomicOrdering::Monotonic); 1052 break; 1053 case AtomicExpr::AO_ABI_memory_order_consume: 1054 case AtomicExpr::AO_ABI_memory_order_acquire: 1055 if (IsStore) 1056 break; // Avoid crashing on code with undefined behavior 1057 EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, 1058 Size, llvm::AtomicOrdering::Acquire); 1059 break; 1060 case AtomicExpr::AO_ABI_memory_order_release: 1061 if (IsLoad) 1062 break; // Avoid crashing on code with undefined behavior 1063 EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, 1064 Size, llvm::AtomicOrdering::Release); 1065 break; 1066 case AtomicExpr::AO_ABI_memory_order_acq_rel: 1067 if (IsLoad || IsStore) 1068 break; // Avoid crashing on code with undefined behavior 1069 EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, 1070 Size, llvm::AtomicOrdering::AcquireRelease); 1071 break; 1072 case AtomicExpr::AO_ABI_memory_order_seq_cst: 1073 EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, 1074 Size, llvm::AtomicOrdering::SequentiallyConsistent); 1075 break; 1076 default: // invalid order 1077 // We should not ever get here normally, but it's hard to 1078 // enforce that in general. 1079 break; 1080 } 1081 if (RValTy->isVoidType()) 1082 return RValue::get(nullptr); 1083 1084 return convertTempToRValue( 1085 Builder.CreateBitCast(Dest, ConvertTypeForMem(RValTy)->getPointerTo()), 1086 RValTy, E->getExprLoc()); 1087 } 1088 1089 // Long case, when Order isn't obviously constant. 1090 1091 // Create all the relevant BB's 1092 llvm::BasicBlock *MonotonicBB = nullptr, *AcquireBB = nullptr, 1093 *ReleaseBB = nullptr, *AcqRelBB = nullptr, 1094 *SeqCstBB = nullptr; 1095 MonotonicBB = createBasicBlock("monotonic", CurFn); 1096 if (!IsStore) 1097 AcquireBB = createBasicBlock("acquire", CurFn); 1098 if (!IsLoad) 1099 ReleaseBB = createBasicBlock("release", CurFn); 1100 if (!IsLoad && !IsStore) 1101 AcqRelBB = createBasicBlock("acqrel", CurFn); 1102 SeqCstBB = createBasicBlock("seqcst", CurFn); 1103 llvm::BasicBlock *ContBB = createBasicBlock("atomic.continue", CurFn); 1104 1105 // Create the switch for the split 1106 // MonotonicBB is arbitrarily chosen as the default case; in practice, this 1107 // doesn't matter unless someone is crazy enough to use something that 1108 // doesn't fold to a constant for the ordering. 1109 Order = Builder.CreateIntCast(Order, Builder.getInt32Ty(), false); 1110 llvm::SwitchInst *SI = Builder.CreateSwitch(Order, MonotonicBB); 1111 1112 // Emit all the different atomics 1113 Builder.SetInsertPoint(MonotonicBB); 1114 EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, 1115 Size, llvm::AtomicOrdering::Monotonic); 1116 Builder.CreateBr(ContBB); 1117 if (!IsStore) { 1118 Builder.SetInsertPoint(AcquireBB); 1119 EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, 1120 Size, llvm::AtomicOrdering::Acquire); 1121 Builder.CreateBr(ContBB); 1122 SI->addCase(Builder.getInt32(AtomicExpr::AO_ABI_memory_order_consume), 1123 AcquireBB); 1124 SI->addCase(Builder.getInt32(AtomicExpr::AO_ABI_memory_order_acquire), 1125 AcquireBB); 1126 } 1127 if (!IsLoad) { 1128 Builder.SetInsertPoint(ReleaseBB); 1129 EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, 1130 Size, llvm::AtomicOrdering::Release); 1131 Builder.CreateBr(ContBB); 1132 SI->addCase(Builder.getInt32(AtomicExpr::AO_ABI_memory_order_release), 1133 ReleaseBB); 1134 } 1135 if (!IsLoad && !IsStore) { 1136 Builder.SetInsertPoint(AcqRelBB); 1137 EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, 1138 Size, llvm::AtomicOrdering::AcquireRelease); 1139 Builder.CreateBr(ContBB); 1140 SI->addCase(Builder.getInt32(AtomicExpr::AO_ABI_memory_order_acq_rel), 1141 AcqRelBB); 1142 } 1143 Builder.SetInsertPoint(SeqCstBB); 1144 EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, 1145 Size, llvm::AtomicOrdering::SequentiallyConsistent); 1146 Builder.CreateBr(ContBB); 1147 SI->addCase(Builder.getInt32(AtomicExpr::AO_ABI_memory_order_seq_cst), 1148 SeqCstBB); 1149 1150 // Cleanup and return 1151 Builder.SetInsertPoint(ContBB); 1152 if (RValTy->isVoidType()) 1153 return RValue::get(nullptr); 1154 1155 assert(Atomics.getValueSizeInBits() <= Atomics.getAtomicSizeInBits()); 1156 return convertTempToRValue( 1157 Builder.CreateBitCast(Dest, ConvertTypeForMem(RValTy)->getPointerTo()), 1158 RValTy, E->getExprLoc()); 1159 } 1160 1161 Address AtomicInfo::emitCastToAtomicIntPointer(Address addr) const { 1162 unsigned addrspace = 1163 cast<llvm::PointerType>(addr.getPointer()->getType())->getAddressSpace(); 1164 llvm::IntegerType *ty = 1165 llvm::IntegerType::get(CGF.getLLVMContext(), AtomicSizeInBits); 1166 return CGF.Builder.CreateBitCast(addr, ty->getPointerTo(addrspace)); 1167 } 1168 1169 Address AtomicInfo::convertToAtomicIntPointer(Address Addr) const { 1170 llvm::Type *Ty = Addr.getElementType(); 1171 uint64_t SourceSizeInBits = CGF.CGM.getDataLayout().getTypeSizeInBits(Ty); 1172 if (SourceSizeInBits != AtomicSizeInBits) { 1173 Address Tmp = CreateTempAlloca(); 1174 CGF.Builder.CreateMemCpy(Tmp, Addr, 1175 std::min(AtomicSizeInBits, SourceSizeInBits) / 8); 1176 Addr = Tmp; 1177 } 1178 1179 return emitCastToAtomicIntPointer(Addr); 1180 } 1181 1182 RValue AtomicInfo::convertAtomicTempToRValue(Address addr, 1183 AggValueSlot resultSlot, 1184 SourceLocation loc, 1185 bool asValue) const { 1186 if (LVal.isSimple()) { 1187 if (EvaluationKind == TEK_Aggregate) 1188 return resultSlot.asRValue(); 1189 1190 // Drill into the padding structure if we have one. 1191 if (hasPadding()) 1192 addr = CGF.Builder.CreateStructGEP(addr, 0, CharUnits()); 1193 1194 // Otherwise, just convert the temporary to an r-value using the 1195 // normal conversion routine. 1196 return CGF.convertTempToRValue(addr, getValueType(), loc); 1197 } 1198 if (!asValue) 1199 // Get RValue from temp memory as atomic for non-simple lvalues 1200 return RValue::get(CGF.Builder.CreateLoad(addr)); 1201 if (LVal.isBitField()) 1202 return CGF.EmitLoadOfBitfieldLValue( 1203 LValue::MakeBitfield(addr, LVal.getBitFieldInfo(), LVal.getType(), 1204 LVal.getAlignmentSource())); 1205 if (LVal.isVectorElt()) 1206 return CGF.EmitLoadOfLValue( 1207 LValue::MakeVectorElt(addr, LVal.getVectorIdx(), LVal.getType(), 1208 LVal.getAlignmentSource()), loc); 1209 assert(LVal.isExtVectorElt()); 1210 return CGF.EmitLoadOfExtVectorElementLValue(LValue::MakeExtVectorElt( 1211 addr, LVal.getExtVectorElts(), LVal.getType(), 1212 LVal.getAlignmentSource())); 1213 } 1214 1215 RValue AtomicInfo::ConvertIntToValueOrAtomic(llvm::Value *IntVal, 1216 AggValueSlot ResultSlot, 1217 SourceLocation Loc, 1218 bool AsValue) const { 1219 // Try not to in some easy cases. 1220 assert(IntVal->getType()->isIntegerTy() && "Expected integer value"); 1221 if (getEvaluationKind() == TEK_Scalar && 1222 (((!LVal.isBitField() || 1223 LVal.getBitFieldInfo().Size == ValueSizeInBits) && 1224 !hasPadding()) || 1225 !AsValue)) { 1226 auto *ValTy = AsValue 1227 ? CGF.ConvertTypeForMem(ValueTy) 1228 : getAtomicAddress().getType()->getPointerElementType(); 1229 if (ValTy->isIntegerTy()) { 1230 assert(IntVal->getType() == ValTy && "Different integer types."); 1231 return RValue::get(CGF.EmitFromMemory(IntVal, ValueTy)); 1232 } else if (ValTy->isPointerTy()) 1233 return RValue::get(CGF.Builder.CreateIntToPtr(IntVal, ValTy)); 1234 else if (llvm::CastInst::isBitCastable(IntVal->getType(), ValTy)) 1235 return RValue::get(CGF.Builder.CreateBitCast(IntVal, ValTy)); 1236 } 1237 1238 // Create a temporary. This needs to be big enough to hold the 1239 // atomic integer. 1240 Address Temp = Address::invalid(); 1241 bool TempIsVolatile = false; 1242 if (AsValue && getEvaluationKind() == TEK_Aggregate) { 1243 assert(!ResultSlot.isIgnored()); 1244 Temp = ResultSlot.getAddress(); 1245 TempIsVolatile = ResultSlot.isVolatile(); 1246 } else { 1247 Temp = CreateTempAlloca(); 1248 } 1249 1250 // Slam the integer into the temporary. 1251 Address CastTemp = emitCastToAtomicIntPointer(Temp); 1252 CGF.Builder.CreateStore(IntVal, CastTemp) 1253 ->setVolatile(TempIsVolatile); 1254 1255 return convertAtomicTempToRValue(Temp, ResultSlot, Loc, AsValue); 1256 } 1257 1258 void AtomicInfo::EmitAtomicLoadLibcall(llvm::Value *AddForLoaded, 1259 llvm::AtomicOrdering AO, bool) { 1260 // void __atomic_load(size_t size, void *mem, void *return, int order); 1261 CallArgList Args; 1262 Args.add(RValue::get(getAtomicSizeValue()), CGF.getContext().getSizeType()); 1263 Args.add(RValue::get(CGF.EmitCastToVoidPtr(getAtomicPointer())), 1264 CGF.getContext().VoidPtrTy); 1265 Args.add(RValue::get(CGF.EmitCastToVoidPtr(AddForLoaded)), 1266 CGF.getContext().VoidPtrTy); 1267 Args.add(RValue::get( 1268 llvm::ConstantInt::get(CGF.IntTy, translateAtomicOrdering(AO))), 1269 CGF.getContext().IntTy); 1270 emitAtomicLibcall(CGF, "__atomic_load", CGF.getContext().VoidTy, Args); 1271 } 1272 1273 llvm::Value *AtomicInfo::EmitAtomicLoadOp(llvm::AtomicOrdering AO, 1274 bool IsVolatile) { 1275 // Okay, we're doing this natively. 1276 Address Addr = getAtomicAddressAsAtomicIntPointer(); 1277 llvm::LoadInst *Load = CGF.Builder.CreateLoad(Addr, "atomic-load"); 1278 Load->setAtomic(AO); 1279 1280 // Other decoration. 1281 if (IsVolatile) 1282 Load->setVolatile(true); 1283 if (LVal.getTBAAInfo()) 1284 CGF.CGM.DecorateInstructionWithTBAA(Load, LVal.getTBAAInfo()); 1285 return Load; 1286 } 1287 1288 /// An LValue is a candidate for having its loads and stores be made atomic if 1289 /// we are operating under /volatile:ms *and* the LValue itself is volatile and 1290 /// performing such an operation can be performed without a libcall. 1291 bool CodeGenFunction::LValueIsSuitableForInlineAtomic(LValue LV) { 1292 if (!CGM.getCodeGenOpts().MSVolatile) return false; 1293 AtomicInfo AI(*this, LV); 1294 bool IsVolatile = LV.isVolatile() || hasVolatileMember(LV.getType()); 1295 // An atomic is inline if we don't need to use a libcall. 1296 bool AtomicIsInline = !AI.shouldUseLibcall(); 1297 return IsVolatile && AtomicIsInline; 1298 } 1299 1300 /// An type is a candidate for having its loads and stores be made atomic if 1301 /// we are operating under /volatile:ms *and* we know the access is volatile and 1302 /// performing such an operation can be performed without a libcall. 1303 bool CodeGenFunction::typeIsSuitableForInlineAtomic(QualType Ty, 1304 bool IsVolatile) const { 1305 // The operation must be volatile for us to make it atomic. 1306 if (!IsVolatile) 1307 return false; 1308 // The -fms-volatile flag must be passed for us to adopt this behavior. 1309 if (!CGM.getCodeGenOpts().MSVolatile) 1310 return false; 1311 1312 // An atomic is inline if we don't need to use a libcall (e.g. it is builtin). 1313 if (!getContext().getTargetInfo().hasBuiltinAtomic( 1314 getContext().getTypeSize(Ty), getContext().getTypeAlign(Ty))) 1315 return false; 1316 1317 // MSVC doesn't seem to do this for types wider than a pointer. 1318 if (getContext().getTypeSize(Ty) > 1319 getContext().getTypeSize(getContext().getIntPtrType())) 1320 return false; 1321 return true; 1322 } 1323 1324 RValue CodeGenFunction::EmitAtomicLoad(LValue LV, SourceLocation SL, 1325 AggValueSlot Slot) { 1326 llvm::AtomicOrdering AO; 1327 bool IsVolatile = LV.isVolatileQualified(); 1328 if (LV.getType()->isAtomicType()) { 1329 AO = llvm::AtomicOrdering::SequentiallyConsistent; 1330 } else { 1331 AO = llvm::AtomicOrdering::Acquire; 1332 IsVolatile = true; 1333 } 1334 return EmitAtomicLoad(LV, SL, AO, IsVolatile, Slot); 1335 } 1336 1337 RValue AtomicInfo::EmitAtomicLoad(AggValueSlot ResultSlot, SourceLocation Loc, 1338 bool AsValue, llvm::AtomicOrdering AO, 1339 bool IsVolatile) { 1340 // Check whether we should use a library call. 1341 if (shouldUseLibcall()) { 1342 Address TempAddr = Address::invalid(); 1343 if (LVal.isSimple() && !ResultSlot.isIgnored()) { 1344 assert(getEvaluationKind() == TEK_Aggregate); 1345 TempAddr = ResultSlot.getAddress(); 1346 } else 1347 TempAddr = CreateTempAlloca(); 1348 1349 EmitAtomicLoadLibcall(TempAddr.getPointer(), AO, IsVolatile); 1350 1351 // Okay, turn that back into the original value or whole atomic (for 1352 // non-simple lvalues) type. 1353 return convertAtomicTempToRValue(TempAddr, ResultSlot, Loc, AsValue); 1354 } 1355 1356 // Okay, we're doing this natively. 1357 auto *Load = EmitAtomicLoadOp(AO, IsVolatile); 1358 1359 // If we're ignoring an aggregate return, don't do anything. 1360 if (getEvaluationKind() == TEK_Aggregate && ResultSlot.isIgnored()) 1361 return RValue::getAggregate(Address::invalid(), false); 1362 1363 // Okay, turn that back into the original value or atomic (for non-simple 1364 // lvalues) type. 1365 return ConvertIntToValueOrAtomic(Load, ResultSlot, Loc, AsValue); 1366 } 1367 1368 /// Emit a load from an l-value of atomic type. Note that the r-value 1369 /// we produce is an r-value of the atomic *value* type. 1370 RValue CodeGenFunction::EmitAtomicLoad(LValue src, SourceLocation loc, 1371 llvm::AtomicOrdering AO, bool IsVolatile, 1372 AggValueSlot resultSlot) { 1373 AtomicInfo Atomics(*this, src); 1374 return Atomics.EmitAtomicLoad(resultSlot, loc, /*AsValue=*/true, AO, 1375 IsVolatile); 1376 } 1377 1378 /// Copy an r-value into memory as part of storing to an atomic type. 1379 /// This needs to create a bit-pattern suitable for atomic operations. 1380 void AtomicInfo::emitCopyIntoMemory(RValue rvalue) const { 1381 assert(LVal.isSimple()); 1382 // If we have an r-value, the rvalue should be of the atomic type, 1383 // which means that the caller is responsible for having zeroed 1384 // any padding. Just do an aggregate copy of that type. 1385 if (rvalue.isAggregate()) { 1386 CGF.EmitAggregateCopy(getAtomicAddress(), 1387 rvalue.getAggregateAddress(), 1388 getAtomicType(), 1389 (rvalue.isVolatileQualified() 1390 || LVal.isVolatileQualified())); 1391 return; 1392 } 1393 1394 // Okay, otherwise we're copying stuff. 1395 1396 // Zero out the buffer if necessary. 1397 emitMemSetZeroIfNecessary(); 1398 1399 // Drill past the padding if present. 1400 LValue TempLVal = projectValue(); 1401 1402 // Okay, store the rvalue in. 1403 if (rvalue.isScalar()) { 1404 CGF.EmitStoreOfScalar(rvalue.getScalarVal(), TempLVal, /*init*/ true); 1405 } else { 1406 CGF.EmitStoreOfComplex(rvalue.getComplexVal(), TempLVal, /*init*/ true); 1407 } 1408 } 1409 1410 1411 /// Materialize an r-value into memory for the purposes of storing it 1412 /// to an atomic type. 1413 Address AtomicInfo::materializeRValue(RValue rvalue) const { 1414 // Aggregate r-values are already in memory, and EmitAtomicStore 1415 // requires them to be values of the atomic type. 1416 if (rvalue.isAggregate()) 1417 return rvalue.getAggregateAddress(); 1418 1419 // Otherwise, make a temporary and materialize into it. 1420 LValue TempLV = CGF.MakeAddrLValue(CreateTempAlloca(), getAtomicType()); 1421 AtomicInfo Atomics(CGF, TempLV); 1422 Atomics.emitCopyIntoMemory(rvalue); 1423 return TempLV.getAddress(); 1424 } 1425 1426 llvm::Value *AtomicInfo::convertRValueToInt(RValue RVal) const { 1427 // If we've got a scalar value of the right size, try to avoid going 1428 // through memory. 1429 if (RVal.isScalar() && (!hasPadding() || !LVal.isSimple())) { 1430 llvm::Value *Value = RVal.getScalarVal(); 1431 if (isa<llvm::IntegerType>(Value->getType())) 1432 return CGF.EmitToMemory(Value, ValueTy); 1433 else { 1434 llvm::IntegerType *InputIntTy = llvm::IntegerType::get( 1435 CGF.getLLVMContext(), 1436 LVal.isSimple() ? getValueSizeInBits() : getAtomicSizeInBits()); 1437 if (isa<llvm::PointerType>(Value->getType())) 1438 return CGF.Builder.CreatePtrToInt(Value, InputIntTy); 1439 else if (llvm::BitCastInst::isBitCastable(Value->getType(), InputIntTy)) 1440 return CGF.Builder.CreateBitCast(Value, InputIntTy); 1441 } 1442 } 1443 // Otherwise, we need to go through memory. 1444 // Put the r-value in memory. 1445 Address Addr = materializeRValue(RVal); 1446 1447 // Cast the temporary to the atomic int type and pull a value out. 1448 Addr = emitCastToAtomicIntPointer(Addr); 1449 return CGF.Builder.CreateLoad(Addr); 1450 } 1451 1452 std::pair<llvm::Value *, llvm::Value *> AtomicInfo::EmitAtomicCompareExchangeOp( 1453 llvm::Value *ExpectedVal, llvm::Value *DesiredVal, 1454 llvm::AtomicOrdering Success, llvm::AtomicOrdering Failure, bool IsWeak) { 1455 // Do the atomic store. 1456 Address Addr = getAtomicAddressAsAtomicIntPointer(); 1457 auto *Inst = CGF.Builder.CreateAtomicCmpXchg(Addr.getPointer(), 1458 ExpectedVal, DesiredVal, 1459 Success, Failure); 1460 // Other decoration. 1461 Inst->setVolatile(LVal.isVolatileQualified()); 1462 Inst->setWeak(IsWeak); 1463 1464 // Okay, turn that back into the original value type. 1465 auto *PreviousVal = CGF.Builder.CreateExtractValue(Inst, /*Idxs=*/0); 1466 auto *SuccessFailureVal = CGF.Builder.CreateExtractValue(Inst, /*Idxs=*/1); 1467 return std::make_pair(PreviousVal, SuccessFailureVal); 1468 } 1469 1470 llvm::Value * 1471 AtomicInfo::EmitAtomicCompareExchangeLibcall(llvm::Value *ExpectedAddr, 1472 llvm::Value *DesiredAddr, 1473 llvm::AtomicOrdering Success, 1474 llvm::AtomicOrdering Failure) { 1475 // bool __atomic_compare_exchange(size_t size, void *obj, void *expected, 1476 // void *desired, int success, int failure); 1477 CallArgList Args; 1478 Args.add(RValue::get(getAtomicSizeValue()), CGF.getContext().getSizeType()); 1479 Args.add(RValue::get(CGF.EmitCastToVoidPtr(getAtomicPointer())), 1480 CGF.getContext().VoidPtrTy); 1481 Args.add(RValue::get(CGF.EmitCastToVoidPtr(ExpectedAddr)), 1482 CGF.getContext().VoidPtrTy); 1483 Args.add(RValue::get(CGF.EmitCastToVoidPtr(DesiredAddr)), 1484 CGF.getContext().VoidPtrTy); 1485 Args.add(RValue::get(llvm::ConstantInt::get( 1486 CGF.IntTy, translateAtomicOrdering(Success))), 1487 CGF.getContext().IntTy); 1488 Args.add(RValue::get(llvm::ConstantInt::get( 1489 CGF.IntTy, translateAtomicOrdering(Failure))), 1490 CGF.getContext().IntTy); 1491 auto SuccessFailureRVal = emitAtomicLibcall(CGF, "__atomic_compare_exchange", 1492 CGF.getContext().BoolTy, Args); 1493 1494 return SuccessFailureRVal.getScalarVal(); 1495 } 1496 1497 std::pair<RValue, llvm::Value *> AtomicInfo::EmitAtomicCompareExchange( 1498 RValue Expected, RValue Desired, llvm::AtomicOrdering Success, 1499 llvm::AtomicOrdering Failure, bool IsWeak) { 1500 if (isStrongerThan(Failure, Success)) 1501 // Don't assert on undefined behavior "failure argument shall be no stronger 1502 // than the success argument". 1503 Failure = llvm::AtomicCmpXchgInst::getStrongestFailureOrdering(Success); 1504 1505 // Check whether we should use a library call. 1506 if (shouldUseLibcall()) { 1507 // Produce a source address. 1508 Address ExpectedAddr = materializeRValue(Expected); 1509 Address DesiredAddr = materializeRValue(Desired); 1510 auto *Res = EmitAtomicCompareExchangeLibcall(ExpectedAddr.getPointer(), 1511 DesiredAddr.getPointer(), 1512 Success, Failure); 1513 return std::make_pair( 1514 convertAtomicTempToRValue(ExpectedAddr, AggValueSlot::ignored(), 1515 SourceLocation(), /*AsValue=*/false), 1516 Res); 1517 } 1518 1519 // If we've got a scalar value of the right size, try to avoid going 1520 // through memory. 1521 auto *ExpectedVal = convertRValueToInt(Expected); 1522 auto *DesiredVal = convertRValueToInt(Desired); 1523 auto Res = EmitAtomicCompareExchangeOp(ExpectedVal, DesiredVal, Success, 1524 Failure, IsWeak); 1525 return std::make_pair( 1526 ConvertIntToValueOrAtomic(Res.first, AggValueSlot::ignored(), 1527 SourceLocation(), /*AsValue=*/false), 1528 Res.second); 1529 } 1530 1531 static void 1532 EmitAtomicUpdateValue(CodeGenFunction &CGF, AtomicInfo &Atomics, RValue OldRVal, 1533 const llvm::function_ref<RValue(RValue)> &UpdateOp, 1534 Address DesiredAddr) { 1535 RValue UpRVal; 1536 LValue AtomicLVal = Atomics.getAtomicLValue(); 1537 LValue DesiredLVal; 1538 if (AtomicLVal.isSimple()) { 1539 UpRVal = OldRVal; 1540 DesiredLVal = CGF.MakeAddrLValue(DesiredAddr, AtomicLVal.getType()); 1541 } else { 1542 // Build new lvalue for temp address 1543 Address Ptr = Atomics.materializeRValue(OldRVal); 1544 LValue UpdateLVal; 1545 if (AtomicLVal.isBitField()) { 1546 UpdateLVal = 1547 LValue::MakeBitfield(Ptr, AtomicLVal.getBitFieldInfo(), 1548 AtomicLVal.getType(), 1549 AtomicLVal.getAlignmentSource()); 1550 DesiredLVal = 1551 LValue::MakeBitfield(DesiredAddr, AtomicLVal.getBitFieldInfo(), 1552 AtomicLVal.getType(), 1553 AtomicLVal.getAlignmentSource()); 1554 } else if (AtomicLVal.isVectorElt()) { 1555 UpdateLVal = LValue::MakeVectorElt(Ptr, AtomicLVal.getVectorIdx(), 1556 AtomicLVal.getType(), 1557 AtomicLVal.getAlignmentSource()); 1558 DesiredLVal = LValue::MakeVectorElt( 1559 DesiredAddr, AtomicLVal.getVectorIdx(), AtomicLVal.getType(), 1560 AtomicLVal.getAlignmentSource()); 1561 } else { 1562 assert(AtomicLVal.isExtVectorElt()); 1563 UpdateLVal = LValue::MakeExtVectorElt(Ptr, AtomicLVal.getExtVectorElts(), 1564 AtomicLVal.getType(), 1565 AtomicLVal.getAlignmentSource()); 1566 DesiredLVal = LValue::MakeExtVectorElt( 1567 DesiredAddr, AtomicLVal.getExtVectorElts(), AtomicLVal.getType(), 1568 AtomicLVal.getAlignmentSource()); 1569 } 1570 UpdateLVal.setTBAAInfo(AtomicLVal.getTBAAInfo()); 1571 DesiredLVal.setTBAAInfo(AtomicLVal.getTBAAInfo()); 1572 UpRVal = CGF.EmitLoadOfLValue(UpdateLVal, SourceLocation()); 1573 } 1574 // Store new value in the corresponding memory area 1575 RValue NewRVal = UpdateOp(UpRVal); 1576 if (NewRVal.isScalar()) { 1577 CGF.EmitStoreThroughLValue(NewRVal, DesiredLVal); 1578 } else { 1579 assert(NewRVal.isComplex()); 1580 CGF.EmitStoreOfComplex(NewRVal.getComplexVal(), DesiredLVal, 1581 /*isInit=*/false); 1582 } 1583 } 1584 1585 void AtomicInfo::EmitAtomicUpdateLibcall( 1586 llvm::AtomicOrdering AO, const llvm::function_ref<RValue(RValue)> &UpdateOp, 1587 bool IsVolatile) { 1588 auto Failure = llvm::AtomicCmpXchgInst::getStrongestFailureOrdering(AO); 1589 1590 Address ExpectedAddr = CreateTempAlloca(); 1591 1592 EmitAtomicLoadLibcall(ExpectedAddr.getPointer(), AO, IsVolatile); 1593 auto *ContBB = CGF.createBasicBlock("atomic_cont"); 1594 auto *ExitBB = CGF.createBasicBlock("atomic_exit"); 1595 CGF.EmitBlock(ContBB); 1596 Address DesiredAddr = CreateTempAlloca(); 1597 if ((LVal.isBitField() && BFI.Size != ValueSizeInBits) || 1598 requiresMemSetZero(getAtomicAddress().getElementType())) { 1599 auto *OldVal = CGF.Builder.CreateLoad(ExpectedAddr); 1600 CGF.Builder.CreateStore(OldVal, DesiredAddr); 1601 } 1602 auto OldRVal = convertAtomicTempToRValue(ExpectedAddr, 1603 AggValueSlot::ignored(), 1604 SourceLocation(), /*AsValue=*/false); 1605 EmitAtomicUpdateValue(CGF, *this, OldRVal, UpdateOp, DesiredAddr); 1606 auto *Res = 1607 EmitAtomicCompareExchangeLibcall(ExpectedAddr.getPointer(), 1608 DesiredAddr.getPointer(), 1609 AO, Failure); 1610 CGF.Builder.CreateCondBr(Res, ExitBB, ContBB); 1611 CGF.EmitBlock(ExitBB, /*IsFinished=*/true); 1612 } 1613 1614 void AtomicInfo::EmitAtomicUpdateOp( 1615 llvm::AtomicOrdering AO, const llvm::function_ref<RValue(RValue)> &UpdateOp, 1616 bool IsVolatile) { 1617 auto Failure = llvm::AtomicCmpXchgInst::getStrongestFailureOrdering(AO); 1618 1619 // Do the atomic load. 1620 auto *OldVal = EmitAtomicLoadOp(AO, IsVolatile); 1621 // For non-simple lvalues perform compare-and-swap procedure. 1622 auto *ContBB = CGF.createBasicBlock("atomic_cont"); 1623 auto *ExitBB = CGF.createBasicBlock("atomic_exit"); 1624 auto *CurBB = CGF.Builder.GetInsertBlock(); 1625 CGF.EmitBlock(ContBB); 1626 llvm::PHINode *PHI = CGF.Builder.CreatePHI(OldVal->getType(), 1627 /*NumReservedValues=*/2); 1628 PHI->addIncoming(OldVal, CurBB); 1629 Address NewAtomicAddr = CreateTempAlloca(); 1630 Address NewAtomicIntAddr = emitCastToAtomicIntPointer(NewAtomicAddr); 1631 if ((LVal.isBitField() && BFI.Size != ValueSizeInBits) || 1632 requiresMemSetZero(getAtomicAddress().getElementType())) { 1633 CGF.Builder.CreateStore(PHI, NewAtomicIntAddr); 1634 } 1635 auto OldRVal = ConvertIntToValueOrAtomic(PHI, AggValueSlot::ignored(), 1636 SourceLocation(), /*AsValue=*/false); 1637 EmitAtomicUpdateValue(CGF, *this, OldRVal, UpdateOp, NewAtomicAddr); 1638 auto *DesiredVal = CGF.Builder.CreateLoad(NewAtomicIntAddr); 1639 // Try to write new value using cmpxchg operation 1640 auto Res = EmitAtomicCompareExchangeOp(PHI, DesiredVal, AO, Failure); 1641 PHI->addIncoming(Res.first, CGF.Builder.GetInsertBlock()); 1642 CGF.Builder.CreateCondBr(Res.second, ExitBB, ContBB); 1643 CGF.EmitBlock(ExitBB, /*IsFinished=*/true); 1644 } 1645 1646 static void EmitAtomicUpdateValue(CodeGenFunction &CGF, AtomicInfo &Atomics, 1647 RValue UpdateRVal, Address DesiredAddr) { 1648 LValue AtomicLVal = Atomics.getAtomicLValue(); 1649 LValue DesiredLVal; 1650 // Build new lvalue for temp address 1651 if (AtomicLVal.isBitField()) { 1652 DesiredLVal = 1653 LValue::MakeBitfield(DesiredAddr, AtomicLVal.getBitFieldInfo(), 1654 AtomicLVal.getType(), 1655 AtomicLVal.getAlignmentSource()); 1656 } else if (AtomicLVal.isVectorElt()) { 1657 DesiredLVal = 1658 LValue::MakeVectorElt(DesiredAddr, AtomicLVal.getVectorIdx(), 1659 AtomicLVal.getType(), 1660 AtomicLVal.getAlignmentSource()); 1661 } else { 1662 assert(AtomicLVal.isExtVectorElt()); 1663 DesiredLVal = LValue::MakeExtVectorElt( 1664 DesiredAddr, AtomicLVal.getExtVectorElts(), AtomicLVal.getType(), 1665 AtomicLVal.getAlignmentSource()); 1666 } 1667 DesiredLVal.setTBAAInfo(AtomicLVal.getTBAAInfo()); 1668 // Store new value in the corresponding memory area 1669 assert(UpdateRVal.isScalar()); 1670 CGF.EmitStoreThroughLValue(UpdateRVal, DesiredLVal); 1671 } 1672 1673 void AtomicInfo::EmitAtomicUpdateLibcall(llvm::AtomicOrdering AO, 1674 RValue UpdateRVal, bool IsVolatile) { 1675 auto Failure = llvm::AtomicCmpXchgInst::getStrongestFailureOrdering(AO); 1676 1677 Address ExpectedAddr = CreateTempAlloca(); 1678 1679 EmitAtomicLoadLibcall(ExpectedAddr.getPointer(), AO, IsVolatile); 1680 auto *ContBB = CGF.createBasicBlock("atomic_cont"); 1681 auto *ExitBB = CGF.createBasicBlock("atomic_exit"); 1682 CGF.EmitBlock(ContBB); 1683 Address DesiredAddr = CreateTempAlloca(); 1684 if ((LVal.isBitField() && BFI.Size != ValueSizeInBits) || 1685 requiresMemSetZero(getAtomicAddress().getElementType())) { 1686 auto *OldVal = CGF.Builder.CreateLoad(ExpectedAddr); 1687 CGF.Builder.CreateStore(OldVal, DesiredAddr); 1688 } 1689 EmitAtomicUpdateValue(CGF, *this, UpdateRVal, DesiredAddr); 1690 auto *Res = 1691 EmitAtomicCompareExchangeLibcall(ExpectedAddr.getPointer(), 1692 DesiredAddr.getPointer(), 1693 AO, Failure); 1694 CGF.Builder.CreateCondBr(Res, ExitBB, ContBB); 1695 CGF.EmitBlock(ExitBB, /*IsFinished=*/true); 1696 } 1697 1698 void AtomicInfo::EmitAtomicUpdateOp(llvm::AtomicOrdering AO, RValue UpdateRVal, 1699 bool IsVolatile) { 1700 auto Failure = llvm::AtomicCmpXchgInst::getStrongestFailureOrdering(AO); 1701 1702 // Do the atomic load. 1703 auto *OldVal = EmitAtomicLoadOp(AO, IsVolatile); 1704 // For non-simple lvalues perform compare-and-swap procedure. 1705 auto *ContBB = CGF.createBasicBlock("atomic_cont"); 1706 auto *ExitBB = CGF.createBasicBlock("atomic_exit"); 1707 auto *CurBB = CGF.Builder.GetInsertBlock(); 1708 CGF.EmitBlock(ContBB); 1709 llvm::PHINode *PHI = CGF.Builder.CreatePHI(OldVal->getType(), 1710 /*NumReservedValues=*/2); 1711 PHI->addIncoming(OldVal, CurBB); 1712 Address NewAtomicAddr = CreateTempAlloca(); 1713 Address NewAtomicIntAddr = emitCastToAtomicIntPointer(NewAtomicAddr); 1714 if ((LVal.isBitField() && BFI.Size != ValueSizeInBits) || 1715 requiresMemSetZero(getAtomicAddress().getElementType())) { 1716 CGF.Builder.CreateStore(PHI, NewAtomicIntAddr); 1717 } 1718 EmitAtomicUpdateValue(CGF, *this, UpdateRVal, NewAtomicAddr); 1719 auto *DesiredVal = CGF.Builder.CreateLoad(NewAtomicIntAddr); 1720 // Try to write new value using cmpxchg operation 1721 auto Res = EmitAtomicCompareExchangeOp(PHI, DesiredVal, AO, Failure); 1722 PHI->addIncoming(Res.first, CGF.Builder.GetInsertBlock()); 1723 CGF.Builder.CreateCondBr(Res.second, ExitBB, ContBB); 1724 CGF.EmitBlock(ExitBB, /*IsFinished=*/true); 1725 } 1726 1727 void AtomicInfo::EmitAtomicUpdate( 1728 llvm::AtomicOrdering AO, const llvm::function_ref<RValue(RValue)> &UpdateOp, 1729 bool IsVolatile) { 1730 if (shouldUseLibcall()) { 1731 EmitAtomicUpdateLibcall(AO, UpdateOp, IsVolatile); 1732 } else { 1733 EmitAtomicUpdateOp(AO, UpdateOp, IsVolatile); 1734 } 1735 } 1736 1737 void AtomicInfo::EmitAtomicUpdate(llvm::AtomicOrdering AO, RValue UpdateRVal, 1738 bool IsVolatile) { 1739 if (shouldUseLibcall()) { 1740 EmitAtomicUpdateLibcall(AO, UpdateRVal, IsVolatile); 1741 } else { 1742 EmitAtomicUpdateOp(AO, UpdateRVal, IsVolatile); 1743 } 1744 } 1745 1746 void CodeGenFunction::EmitAtomicStore(RValue rvalue, LValue lvalue, 1747 bool isInit) { 1748 bool IsVolatile = lvalue.isVolatileQualified(); 1749 llvm::AtomicOrdering AO; 1750 if (lvalue.getType()->isAtomicType()) { 1751 AO = llvm::AtomicOrdering::SequentiallyConsistent; 1752 } else { 1753 AO = llvm::AtomicOrdering::Release; 1754 IsVolatile = true; 1755 } 1756 return EmitAtomicStore(rvalue, lvalue, AO, IsVolatile, isInit); 1757 } 1758 1759 /// Emit a store to an l-value of atomic type. 1760 /// 1761 /// Note that the r-value is expected to be an r-value *of the atomic 1762 /// type*; this means that for aggregate r-values, it should include 1763 /// storage for any padding that was necessary. 1764 void CodeGenFunction::EmitAtomicStore(RValue rvalue, LValue dest, 1765 llvm::AtomicOrdering AO, bool IsVolatile, 1766 bool isInit) { 1767 // If this is an aggregate r-value, it should agree in type except 1768 // maybe for address-space qualification. 1769 assert(!rvalue.isAggregate() || 1770 rvalue.getAggregateAddress().getElementType() 1771 == dest.getAddress().getElementType()); 1772 1773 AtomicInfo atomics(*this, dest); 1774 LValue LVal = atomics.getAtomicLValue(); 1775 1776 // If this is an initialization, just put the value there normally. 1777 if (LVal.isSimple()) { 1778 if (isInit) { 1779 atomics.emitCopyIntoMemory(rvalue); 1780 return; 1781 } 1782 1783 // Check whether we should use a library call. 1784 if (atomics.shouldUseLibcall()) { 1785 // Produce a source address. 1786 Address srcAddr = atomics.materializeRValue(rvalue); 1787 1788 // void __atomic_store(size_t size, void *mem, void *val, int order) 1789 CallArgList args; 1790 args.add(RValue::get(atomics.getAtomicSizeValue()), 1791 getContext().getSizeType()); 1792 args.add(RValue::get(EmitCastToVoidPtr(atomics.getAtomicPointer())), 1793 getContext().VoidPtrTy); 1794 args.add(RValue::get(EmitCastToVoidPtr(srcAddr.getPointer())), 1795 getContext().VoidPtrTy); 1796 args.add(RValue::get(llvm::ConstantInt::get( 1797 IntTy, AtomicInfo::translateAtomicOrdering(AO))), 1798 getContext().IntTy); 1799 emitAtomicLibcall(*this, "__atomic_store", getContext().VoidTy, args); 1800 return; 1801 } 1802 1803 // Okay, we're doing this natively. 1804 llvm::Value *intValue = atomics.convertRValueToInt(rvalue); 1805 1806 // Do the atomic store. 1807 Address addr = 1808 atomics.emitCastToAtomicIntPointer(atomics.getAtomicAddress()); 1809 intValue = Builder.CreateIntCast( 1810 intValue, addr.getElementType(), /*isSigned=*/false); 1811 llvm::StoreInst *store = Builder.CreateStore(intValue, addr); 1812 1813 // Initializations don't need to be atomic. 1814 if (!isInit) 1815 store->setAtomic(AO); 1816 1817 // Other decoration. 1818 if (IsVolatile) 1819 store->setVolatile(true); 1820 if (dest.getTBAAInfo()) 1821 CGM.DecorateInstructionWithTBAA(store, dest.getTBAAInfo()); 1822 return; 1823 } 1824 1825 // Emit simple atomic update operation. 1826 atomics.EmitAtomicUpdate(AO, rvalue, IsVolatile); 1827 } 1828 1829 /// Emit a compare-and-exchange op for atomic type. 1830 /// 1831 std::pair<RValue, llvm::Value *> CodeGenFunction::EmitAtomicCompareExchange( 1832 LValue Obj, RValue Expected, RValue Desired, SourceLocation Loc, 1833 llvm::AtomicOrdering Success, llvm::AtomicOrdering Failure, bool IsWeak, 1834 AggValueSlot Slot) { 1835 // If this is an aggregate r-value, it should agree in type except 1836 // maybe for address-space qualification. 1837 assert(!Expected.isAggregate() || 1838 Expected.getAggregateAddress().getElementType() == 1839 Obj.getAddress().getElementType()); 1840 assert(!Desired.isAggregate() || 1841 Desired.getAggregateAddress().getElementType() == 1842 Obj.getAddress().getElementType()); 1843 AtomicInfo Atomics(*this, Obj); 1844 1845 return Atomics.EmitAtomicCompareExchange(Expected, Desired, Success, Failure, 1846 IsWeak); 1847 } 1848 1849 void CodeGenFunction::EmitAtomicUpdate( 1850 LValue LVal, llvm::AtomicOrdering AO, 1851 const llvm::function_ref<RValue(RValue)> &UpdateOp, bool IsVolatile) { 1852 AtomicInfo Atomics(*this, LVal); 1853 Atomics.EmitAtomicUpdate(AO, UpdateOp, IsVolatile); 1854 } 1855 1856 void CodeGenFunction::EmitAtomicInit(Expr *init, LValue dest) { 1857 AtomicInfo atomics(*this, dest); 1858 1859 switch (atomics.getEvaluationKind()) { 1860 case TEK_Scalar: { 1861 llvm::Value *value = EmitScalarExpr(init); 1862 atomics.emitCopyIntoMemory(RValue::get(value)); 1863 return; 1864 } 1865 1866 case TEK_Complex: { 1867 ComplexPairTy value = EmitComplexExpr(init); 1868 atomics.emitCopyIntoMemory(RValue::getComplex(value)); 1869 return; 1870 } 1871 1872 case TEK_Aggregate: { 1873 // Fix up the destination if the initializer isn't an expression 1874 // of atomic type. 1875 bool Zeroed = false; 1876 if (!init->getType()->isAtomicType()) { 1877 Zeroed = atomics.emitMemSetZeroIfNecessary(); 1878 dest = atomics.projectValue(); 1879 } 1880 1881 // Evaluate the expression directly into the destination. 1882 AggValueSlot slot = AggValueSlot::forLValue(dest, 1883 AggValueSlot::IsNotDestructed, 1884 AggValueSlot::DoesNotNeedGCBarriers, 1885 AggValueSlot::IsNotAliased, 1886 Zeroed ? AggValueSlot::IsZeroed : 1887 AggValueSlot::IsNotZeroed); 1888 1889 EmitAggExpr(init, slot); 1890 return; 1891 } 1892 } 1893 llvm_unreachable("bad evaluation kind"); 1894 } 1895