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 "CodeGenModule.h" 17 #include "clang/AST/ASTContext.h" 18 #include "clang/CodeGen/CGFunctionInfo.h" 19 #include "llvm/ADT/StringExtras.h" 20 #include "llvm/IR/DataLayout.h" 21 #include "llvm/IR/Intrinsics.h" 22 #include "llvm/IR/Operator.h" 23 24 using namespace clang; 25 using namespace CodeGen; 26 27 namespace { 28 class AtomicInfo { 29 CodeGenFunction &CGF; 30 QualType AtomicTy; 31 QualType ValueTy; 32 uint64_t AtomicSizeInBits; 33 uint64_t ValueSizeInBits; 34 CharUnits AtomicAlign; 35 CharUnits ValueAlign; 36 CharUnits LValueAlign; 37 TypeEvaluationKind EvaluationKind; 38 bool UseLibcall; 39 public: 40 AtomicInfo(CodeGenFunction &CGF, LValue &lvalue) : CGF(CGF) { 41 assert(lvalue.isSimple()); 42 43 AtomicTy = lvalue.getType(); 44 ValueTy = AtomicTy->castAs<AtomicType>()->getValueType(); 45 EvaluationKind = CGF.getEvaluationKind(ValueTy); 46 47 ASTContext &C = CGF.getContext(); 48 49 uint64_t ValueAlignInBits; 50 uint64_t AtomicAlignInBits; 51 TypeInfo ValueTI = C.getTypeInfo(ValueTy); 52 ValueSizeInBits = ValueTI.Width; 53 ValueAlignInBits = ValueTI.Align; 54 55 TypeInfo AtomicTI = C.getTypeInfo(AtomicTy); 56 AtomicSizeInBits = AtomicTI.Width; 57 AtomicAlignInBits = AtomicTI.Align; 58 59 assert(ValueSizeInBits <= AtomicSizeInBits); 60 assert(ValueAlignInBits <= AtomicAlignInBits); 61 62 AtomicAlign = C.toCharUnitsFromBits(AtomicAlignInBits); 63 ValueAlign = C.toCharUnitsFromBits(ValueAlignInBits); 64 if (lvalue.getAlignment().isZero()) 65 lvalue.setAlignment(AtomicAlign); 66 67 UseLibcall = 68 (AtomicSizeInBits > uint64_t(C.toBits(lvalue.getAlignment())) || 69 AtomicSizeInBits > C.getTargetInfo().getMaxAtomicInlineWidth()); 70 } 71 72 QualType getAtomicType() const { return AtomicTy; } 73 QualType getValueType() const { return ValueTy; } 74 CharUnits getAtomicAlignment() const { return AtomicAlign; } 75 CharUnits getValueAlignment() const { return ValueAlign; } 76 uint64_t getAtomicSizeInBits() const { return AtomicSizeInBits; } 77 uint64_t getValueSizeInBits() const { return AtomicSizeInBits; } 78 TypeEvaluationKind getEvaluationKind() const { return EvaluationKind; } 79 bool shouldUseLibcall() const { return UseLibcall; } 80 81 /// Is the atomic size larger than the underlying value type? 82 /// 83 /// Note that the absence of padding does not mean that atomic 84 /// objects are completely interchangeable with non-atomic 85 /// objects: we might have promoted the alignment of a type 86 /// without making it bigger. 87 bool hasPadding() const { 88 return (ValueSizeInBits != AtomicSizeInBits); 89 } 90 91 bool emitMemSetZeroIfNecessary(LValue dest) const; 92 93 llvm::Value *getAtomicSizeValue() const { 94 CharUnits size = CGF.getContext().toCharUnitsFromBits(AtomicSizeInBits); 95 return CGF.CGM.getSize(size); 96 } 97 98 /// Cast the given pointer to an integer pointer suitable for 99 /// atomic operations. 100 llvm::Value *emitCastToAtomicIntPointer(llvm::Value *addr) const; 101 102 /// Turn an atomic-layout object into an r-value. 103 RValue convertTempToRValue(llvm::Value *addr, 104 AggValueSlot resultSlot, 105 SourceLocation loc) const; 106 107 /// Copy an atomic r-value into atomic-layout memory. 108 void emitCopyIntoMemory(RValue rvalue, LValue lvalue) const; 109 110 /// Project an l-value down to the value field. 111 LValue projectValue(LValue lvalue) const { 112 llvm::Value *addr = lvalue.getAddress(); 113 if (hasPadding()) 114 addr = CGF.Builder.CreateStructGEP(addr, 0); 115 116 return LValue::MakeAddr(addr, getValueType(), lvalue.getAlignment(), 117 CGF.getContext(), lvalue.getTBAAInfo()); 118 } 119 120 /// Materialize an atomic r-value in atomic-layout memory. 121 llvm::Value *materializeRValue(RValue rvalue) const; 122 123 private: 124 bool requiresMemSetZero(llvm::Type *type) const; 125 }; 126 } 127 128 static RValue emitAtomicLibcall(CodeGenFunction &CGF, 129 StringRef fnName, 130 QualType resultType, 131 CallArgList &args) { 132 const CGFunctionInfo &fnInfo = 133 CGF.CGM.getTypes().arrangeFreeFunctionCall(resultType, args, 134 FunctionType::ExtInfo(), RequiredArgs::All); 135 llvm::FunctionType *fnTy = CGF.CGM.getTypes().GetFunctionType(fnInfo); 136 llvm::Constant *fn = CGF.CGM.CreateRuntimeFunction(fnTy, fnName); 137 return CGF.EmitCall(fnInfo, fn, ReturnValueSlot(), args); 138 } 139 140 /// Does a store of the given IR type modify the full expected width? 141 static bool isFullSizeType(CodeGenModule &CGM, llvm::Type *type, 142 uint64_t expectedSize) { 143 return (CGM.getDataLayout().getTypeStoreSize(type) * 8 == expectedSize); 144 } 145 146 /// Does the atomic type require memsetting to zero before initialization? 147 /// 148 /// The IR type is provided as a way of making certain queries faster. 149 bool AtomicInfo::requiresMemSetZero(llvm::Type *type) const { 150 // If the atomic type has size padding, we definitely need a memset. 151 if (hasPadding()) return true; 152 153 // Otherwise, do some simple heuristics to try to avoid it: 154 switch (getEvaluationKind()) { 155 // For scalars and complexes, check whether the store size of the 156 // type uses the full size. 157 case TEK_Scalar: 158 return !isFullSizeType(CGF.CGM, type, AtomicSizeInBits); 159 case TEK_Complex: 160 return !isFullSizeType(CGF.CGM, type->getStructElementType(0), 161 AtomicSizeInBits / 2); 162 163 // Padding in structs has an undefined bit pattern. User beware. 164 case TEK_Aggregate: 165 return false; 166 } 167 llvm_unreachable("bad evaluation kind"); 168 } 169 170 bool AtomicInfo::emitMemSetZeroIfNecessary(LValue dest) const { 171 llvm::Value *addr = dest.getAddress(); 172 if (!requiresMemSetZero(addr->getType()->getPointerElementType())) 173 return false; 174 175 CGF.Builder.CreateMemSet(addr, llvm::ConstantInt::get(CGF.Int8Ty, 0), 176 AtomicSizeInBits / 8, 177 dest.getAlignment().getQuantity()); 178 return true; 179 } 180 181 static void emitAtomicCmpXchg(CodeGenFunction &CGF, AtomicExpr *E, bool IsWeak, 182 llvm::Value *Dest, llvm::Value *Ptr, 183 llvm::Value *Val1, llvm::Value *Val2, 184 uint64_t Size, unsigned Align, 185 llvm::AtomicOrdering SuccessOrder, 186 llvm::AtomicOrdering FailureOrder) { 187 // Note that cmpxchg doesn't support weak cmpxchg, at least at the moment. 188 llvm::LoadInst *Expected = CGF.Builder.CreateLoad(Val1); 189 Expected->setAlignment(Align); 190 llvm::LoadInst *Desired = CGF.Builder.CreateLoad(Val2); 191 Desired->setAlignment(Align); 192 193 llvm::AtomicCmpXchgInst *Pair = CGF.Builder.CreateAtomicCmpXchg( 194 Ptr, Expected, Desired, SuccessOrder, FailureOrder); 195 Pair->setVolatile(E->isVolatile()); 196 Pair->setWeak(IsWeak); 197 198 // Cmp holds the result of the compare-exchange operation: true on success, 199 // false on failure. 200 llvm::Value *Old = CGF.Builder.CreateExtractValue(Pair, 0); 201 llvm::Value *Cmp = CGF.Builder.CreateExtractValue(Pair, 1); 202 203 // This basic block is used to hold the store instruction if the operation 204 // failed. 205 llvm::BasicBlock *StoreExpectedBB = 206 CGF.createBasicBlock("cmpxchg.store_expected", CGF.CurFn); 207 208 // This basic block is the exit point of the operation, we should end up 209 // here regardless of whether or not the operation succeeded. 210 llvm::BasicBlock *ContinueBB = 211 CGF.createBasicBlock("cmpxchg.continue", CGF.CurFn); 212 213 // Update Expected if Expected isn't equal to Old, otherwise branch to the 214 // exit point. 215 CGF.Builder.CreateCondBr(Cmp, ContinueBB, StoreExpectedBB); 216 217 CGF.Builder.SetInsertPoint(StoreExpectedBB); 218 // Update the memory at Expected with Old's value. 219 llvm::StoreInst *StoreExpected = CGF.Builder.CreateStore(Old, Val1); 220 StoreExpected->setAlignment(Align); 221 // Finally, branch to the exit point. 222 CGF.Builder.CreateBr(ContinueBB); 223 224 CGF.Builder.SetInsertPoint(ContinueBB); 225 // Update the memory at Dest with Cmp's value. 226 CGF.EmitStoreOfScalar(Cmp, CGF.MakeAddrLValue(Dest, E->getType())); 227 return; 228 } 229 230 /// Given an ordering required on success, emit all possible cmpxchg 231 /// instructions to cope with the provided (but possibly only dynamically known) 232 /// FailureOrder. 233 static void emitAtomicCmpXchgFailureSet(CodeGenFunction &CGF, AtomicExpr *E, 234 bool IsWeak, llvm::Value *Dest, 235 llvm::Value *Ptr, llvm::Value *Val1, 236 llvm::Value *Val2, 237 llvm::Value *FailureOrderVal, 238 uint64_t Size, unsigned Align, 239 llvm::AtomicOrdering SuccessOrder) { 240 llvm::AtomicOrdering FailureOrder; 241 if (llvm::ConstantInt *FO = dyn_cast<llvm::ConstantInt>(FailureOrderVal)) { 242 switch (FO->getSExtValue()) { 243 default: 244 FailureOrder = llvm::Monotonic; 245 break; 246 case AtomicExpr::AO_ABI_memory_order_consume: 247 case AtomicExpr::AO_ABI_memory_order_acquire: 248 FailureOrder = llvm::Acquire; 249 break; 250 case AtomicExpr::AO_ABI_memory_order_seq_cst: 251 FailureOrder = llvm::SequentiallyConsistent; 252 break; 253 } 254 if (FailureOrder >= SuccessOrder) { 255 // Don't assert on undefined behaviour. 256 FailureOrder = 257 llvm::AtomicCmpXchgInst::getStrongestFailureOrdering(SuccessOrder); 258 } 259 emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, Size, Align, 260 SuccessOrder, FailureOrder); 261 return; 262 } 263 264 // Create all the relevant BB's 265 llvm::BasicBlock *MonotonicBB = nullptr, *AcquireBB = nullptr, 266 *SeqCstBB = nullptr; 267 MonotonicBB = CGF.createBasicBlock("monotonic_fail", CGF.CurFn); 268 if (SuccessOrder != llvm::Monotonic && SuccessOrder != llvm::Release) 269 AcquireBB = CGF.createBasicBlock("acquire_fail", CGF.CurFn); 270 if (SuccessOrder == llvm::SequentiallyConsistent) 271 SeqCstBB = CGF.createBasicBlock("seqcst_fail", CGF.CurFn); 272 273 llvm::BasicBlock *ContBB = CGF.createBasicBlock("atomic.continue", CGF.CurFn); 274 275 llvm::SwitchInst *SI = CGF.Builder.CreateSwitch(FailureOrderVal, MonotonicBB); 276 277 // Emit all the different atomics 278 279 // MonotonicBB is arbitrarily chosen as the default case; in practice, this 280 // doesn't matter unless someone is crazy enough to use something that 281 // doesn't fold to a constant for the ordering. 282 CGF.Builder.SetInsertPoint(MonotonicBB); 283 emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, 284 Size, Align, SuccessOrder, llvm::Monotonic); 285 CGF.Builder.CreateBr(ContBB); 286 287 if (AcquireBB) { 288 CGF.Builder.SetInsertPoint(AcquireBB); 289 emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, 290 Size, Align, SuccessOrder, llvm::Acquire); 291 CGF.Builder.CreateBr(ContBB); 292 SI->addCase(CGF.Builder.getInt32(AtomicExpr::AO_ABI_memory_order_consume), 293 AcquireBB); 294 SI->addCase(CGF.Builder.getInt32(AtomicExpr::AO_ABI_memory_order_acquire), 295 AcquireBB); 296 } 297 if (SeqCstBB) { 298 CGF.Builder.SetInsertPoint(SeqCstBB); 299 emitAtomicCmpXchg(CGF, E, IsWeak, Dest, Ptr, Val1, Val2, 300 Size, Align, SuccessOrder, llvm::SequentiallyConsistent); 301 CGF.Builder.CreateBr(ContBB); 302 SI->addCase(CGF.Builder.getInt32(AtomicExpr::AO_ABI_memory_order_seq_cst), 303 SeqCstBB); 304 } 305 306 CGF.Builder.SetInsertPoint(ContBB); 307 } 308 309 static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, llvm::Value *Dest, 310 llvm::Value *Ptr, llvm::Value *Val1, llvm::Value *Val2, 311 llvm::Value *IsWeak, llvm::Value *FailureOrder, 312 uint64_t Size, unsigned Align, 313 llvm::AtomicOrdering Order) { 314 llvm::AtomicRMWInst::BinOp Op = llvm::AtomicRMWInst::Add; 315 llvm::Instruction::BinaryOps PostOp = (llvm::Instruction::BinaryOps)0; 316 317 switch (E->getOp()) { 318 case AtomicExpr::AO__c11_atomic_init: 319 llvm_unreachable("Already handled!"); 320 321 case AtomicExpr::AO__c11_atomic_compare_exchange_strong: 322 emitAtomicCmpXchgFailureSet(CGF, E, false, Dest, Ptr, Val1, Val2, 323 FailureOrder, Size, Align, Order); 324 return; 325 case AtomicExpr::AO__c11_atomic_compare_exchange_weak: 326 emitAtomicCmpXchgFailureSet(CGF, E, true, Dest, Ptr, Val1, Val2, 327 FailureOrder, Size, Align, Order); 328 return; 329 case AtomicExpr::AO__atomic_compare_exchange: 330 case AtomicExpr::AO__atomic_compare_exchange_n: { 331 if (llvm::ConstantInt *IsWeakC = dyn_cast<llvm::ConstantInt>(IsWeak)) { 332 emitAtomicCmpXchgFailureSet(CGF, E, IsWeakC->getZExtValue(), Dest, Ptr, 333 Val1, Val2, FailureOrder, Size, Align, Order); 334 } else { 335 // Create all the relevant BB's 336 llvm::BasicBlock *StrongBB = 337 CGF.createBasicBlock("cmpxchg.strong", CGF.CurFn); 338 llvm::BasicBlock *WeakBB = CGF.createBasicBlock("cmxchg.weak", CGF.CurFn); 339 llvm::BasicBlock *ContBB = 340 CGF.createBasicBlock("cmpxchg.continue", CGF.CurFn); 341 342 llvm::SwitchInst *SI = CGF.Builder.CreateSwitch(IsWeak, WeakBB); 343 SI->addCase(CGF.Builder.getInt1(false), StrongBB); 344 345 CGF.Builder.SetInsertPoint(StrongBB); 346 emitAtomicCmpXchgFailureSet(CGF, E, false, Dest, Ptr, Val1, Val2, 347 FailureOrder, Size, Align, Order); 348 CGF.Builder.CreateBr(ContBB); 349 350 CGF.Builder.SetInsertPoint(WeakBB); 351 emitAtomicCmpXchgFailureSet(CGF, E, true, Dest, Ptr, Val1, Val2, 352 FailureOrder, Size, Align, Order); 353 CGF.Builder.CreateBr(ContBB); 354 355 CGF.Builder.SetInsertPoint(ContBB); 356 } 357 return; 358 } 359 case AtomicExpr::AO__c11_atomic_load: 360 case AtomicExpr::AO__atomic_load_n: 361 case AtomicExpr::AO__atomic_load: { 362 llvm::LoadInst *Load = CGF.Builder.CreateLoad(Ptr); 363 Load->setAtomic(Order); 364 Load->setAlignment(Size); 365 Load->setVolatile(E->isVolatile()); 366 llvm::StoreInst *StoreDest = CGF.Builder.CreateStore(Load, Dest); 367 StoreDest->setAlignment(Align); 368 return; 369 } 370 371 case AtomicExpr::AO__c11_atomic_store: 372 case AtomicExpr::AO__atomic_store: 373 case AtomicExpr::AO__atomic_store_n: { 374 assert(!Dest && "Store does not return a value"); 375 llvm::LoadInst *LoadVal1 = CGF.Builder.CreateLoad(Val1); 376 LoadVal1->setAlignment(Align); 377 llvm::StoreInst *Store = CGF.Builder.CreateStore(LoadVal1, Ptr); 378 Store->setAtomic(Order); 379 Store->setAlignment(Size); 380 Store->setVolatile(E->isVolatile()); 381 return; 382 } 383 384 case AtomicExpr::AO__c11_atomic_exchange: 385 case AtomicExpr::AO__atomic_exchange_n: 386 case AtomicExpr::AO__atomic_exchange: 387 Op = llvm::AtomicRMWInst::Xchg; 388 break; 389 390 case AtomicExpr::AO__atomic_add_fetch: 391 PostOp = llvm::Instruction::Add; 392 // Fall through. 393 case AtomicExpr::AO__c11_atomic_fetch_add: 394 case AtomicExpr::AO__atomic_fetch_add: 395 Op = llvm::AtomicRMWInst::Add; 396 break; 397 398 case AtomicExpr::AO__atomic_sub_fetch: 399 PostOp = llvm::Instruction::Sub; 400 // Fall through. 401 case AtomicExpr::AO__c11_atomic_fetch_sub: 402 case AtomicExpr::AO__atomic_fetch_sub: 403 Op = llvm::AtomicRMWInst::Sub; 404 break; 405 406 case AtomicExpr::AO__atomic_and_fetch: 407 PostOp = llvm::Instruction::And; 408 // Fall through. 409 case AtomicExpr::AO__c11_atomic_fetch_and: 410 case AtomicExpr::AO__atomic_fetch_and: 411 Op = llvm::AtomicRMWInst::And; 412 break; 413 414 case AtomicExpr::AO__atomic_or_fetch: 415 PostOp = llvm::Instruction::Or; 416 // Fall through. 417 case AtomicExpr::AO__c11_atomic_fetch_or: 418 case AtomicExpr::AO__atomic_fetch_or: 419 Op = llvm::AtomicRMWInst::Or; 420 break; 421 422 case AtomicExpr::AO__atomic_xor_fetch: 423 PostOp = llvm::Instruction::Xor; 424 // Fall through. 425 case AtomicExpr::AO__c11_atomic_fetch_xor: 426 case AtomicExpr::AO__atomic_fetch_xor: 427 Op = llvm::AtomicRMWInst::Xor; 428 break; 429 430 case AtomicExpr::AO__atomic_nand_fetch: 431 PostOp = llvm::Instruction::And; 432 // Fall through. 433 case AtomicExpr::AO__atomic_fetch_nand: 434 Op = llvm::AtomicRMWInst::Nand; 435 break; 436 } 437 438 llvm::LoadInst *LoadVal1 = CGF.Builder.CreateLoad(Val1); 439 LoadVal1->setAlignment(Align); 440 llvm::AtomicRMWInst *RMWI = 441 CGF.Builder.CreateAtomicRMW(Op, Ptr, LoadVal1, Order); 442 RMWI->setVolatile(E->isVolatile()); 443 444 // For __atomic_*_fetch operations, perform the operation again to 445 // determine the value which was written. 446 llvm::Value *Result = RMWI; 447 if (PostOp) 448 Result = CGF.Builder.CreateBinOp(PostOp, RMWI, LoadVal1); 449 if (E->getOp() == AtomicExpr::AO__atomic_nand_fetch) 450 Result = CGF.Builder.CreateNot(Result); 451 llvm::StoreInst *StoreDest = CGF.Builder.CreateStore(Result, Dest); 452 StoreDest->setAlignment(Align); 453 } 454 455 // This function emits any expression (scalar, complex, or aggregate) 456 // into a temporary alloca. 457 static llvm::Value * 458 EmitValToTemp(CodeGenFunction &CGF, Expr *E) { 459 llvm::Value *DeclPtr = CGF.CreateMemTemp(E->getType(), ".atomictmp"); 460 CGF.EmitAnyExprToMem(E, DeclPtr, E->getType().getQualifiers(), 461 /*Init*/ true); 462 return DeclPtr; 463 } 464 465 static void 466 AddDirectArgument(CodeGenFunction &CGF, CallArgList &Args, 467 bool UseOptimizedLibcall, llvm::Value *Val, QualType ValTy, 468 SourceLocation Loc, CharUnits SizeInChars) { 469 if (UseOptimizedLibcall) { 470 // Load value and pass it to the function directly. 471 unsigned Align = CGF.getContext().getTypeAlignInChars(ValTy).getQuantity(); 472 int64_t SizeInBits = CGF.getContext().toBits(SizeInChars); 473 ValTy = 474 CGF.getContext().getIntTypeForBitwidth(SizeInBits, /*Signed=*/false); 475 llvm::Type *IPtrTy = llvm::IntegerType::get(CGF.getLLVMContext(), 476 SizeInBits)->getPointerTo(); 477 Val = CGF.EmitLoadOfScalar(CGF.Builder.CreateBitCast(Val, IPtrTy), false, 478 Align, CGF.getContext().getPointerType(ValTy), 479 Loc); 480 // Coerce the value into an appropriately sized integer type. 481 Args.add(RValue::get(Val), ValTy); 482 } else { 483 // Non-optimized functions always take a reference. 484 Args.add(RValue::get(CGF.EmitCastToVoidPtr(Val)), 485 CGF.getContext().VoidPtrTy); 486 } 487 } 488 489 RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E, llvm::Value *Dest) { 490 QualType AtomicTy = E->getPtr()->getType()->getPointeeType(); 491 QualType MemTy = AtomicTy; 492 if (const AtomicType *AT = AtomicTy->getAs<AtomicType>()) 493 MemTy = AT->getValueType(); 494 CharUnits sizeChars = getContext().getTypeSizeInChars(AtomicTy); 495 uint64_t Size = sizeChars.getQuantity(); 496 CharUnits alignChars = getContext().getTypeAlignInChars(AtomicTy); 497 unsigned Align = alignChars.getQuantity(); 498 unsigned MaxInlineWidthInBits = 499 getTarget().getMaxAtomicInlineWidth(); 500 bool UseLibcall = (Size != Align || 501 getContext().toBits(sizeChars) > MaxInlineWidthInBits); 502 503 llvm::Value *IsWeak = nullptr, *OrderFail = nullptr, *Val1 = nullptr, 504 *Val2 = nullptr; 505 llvm::Value *Ptr = EmitScalarExpr(E->getPtr()); 506 507 if (E->getOp() == AtomicExpr::AO__c11_atomic_init) { 508 assert(!Dest && "Init does not return a value"); 509 LValue lvalue = LValue::MakeAddr(Ptr, AtomicTy, alignChars, getContext()); 510 EmitAtomicInit(E->getVal1(), lvalue); 511 return RValue::get(nullptr); 512 } 513 514 llvm::Value *Order = EmitScalarExpr(E->getOrder()); 515 516 switch (E->getOp()) { 517 case AtomicExpr::AO__c11_atomic_init: 518 llvm_unreachable("Already handled!"); 519 520 case AtomicExpr::AO__c11_atomic_load: 521 case AtomicExpr::AO__atomic_load_n: 522 break; 523 524 case AtomicExpr::AO__atomic_load: 525 Dest = EmitScalarExpr(E->getVal1()); 526 break; 527 528 case AtomicExpr::AO__atomic_store: 529 Val1 = EmitScalarExpr(E->getVal1()); 530 break; 531 532 case AtomicExpr::AO__atomic_exchange: 533 Val1 = EmitScalarExpr(E->getVal1()); 534 Dest = EmitScalarExpr(E->getVal2()); 535 break; 536 537 case AtomicExpr::AO__c11_atomic_compare_exchange_strong: 538 case AtomicExpr::AO__c11_atomic_compare_exchange_weak: 539 case AtomicExpr::AO__atomic_compare_exchange_n: 540 case AtomicExpr::AO__atomic_compare_exchange: 541 Val1 = EmitScalarExpr(E->getVal1()); 542 if (E->getOp() == AtomicExpr::AO__atomic_compare_exchange) 543 Val2 = EmitScalarExpr(E->getVal2()); 544 else 545 Val2 = EmitValToTemp(*this, E->getVal2()); 546 OrderFail = EmitScalarExpr(E->getOrderFail()); 547 if (E->getNumSubExprs() == 6) 548 IsWeak = EmitScalarExpr(E->getWeak()); 549 break; 550 551 case AtomicExpr::AO__c11_atomic_fetch_add: 552 case AtomicExpr::AO__c11_atomic_fetch_sub: 553 if (MemTy->isPointerType()) { 554 // For pointer arithmetic, we're required to do a bit of math: 555 // adding 1 to an int* is not the same as adding 1 to a uintptr_t. 556 // ... but only for the C11 builtins. The GNU builtins expect the 557 // user to multiply by sizeof(T). 558 QualType Val1Ty = E->getVal1()->getType(); 559 llvm::Value *Val1Scalar = EmitScalarExpr(E->getVal1()); 560 CharUnits PointeeIncAmt = 561 getContext().getTypeSizeInChars(MemTy->getPointeeType()); 562 Val1Scalar = Builder.CreateMul(Val1Scalar, CGM.getSize(PointeeIncAmt)); 563 Val1 = CreateMemTemp(Val1Ty, ".atomictmp"); 564 EmitStoreOfScalar(Val1Scalar, MakeAddrLValue(Val1, Val1Ty)); 565 break; 566 } 567 // Fall through. 568 case AtomicExpr::AO__atomic_fetch_add: 569 case AtomicExpr::AO__atomic_fetch_sub: 570 case AtomicExpr::AO__atomic_add_fetch: 571 case AtomicExpr::AO__atomic_sub_fetch: 572 case AtomicExpr::AO__c11_atomic_store: 573 case AtomicExpr::AO__c11_atomic_exchange: 574 case AtomicExpr::AO__atomic_store_n: 575 case AtomicExpr::AO__atomic_exchange_n: 576 case AtomicExpr::AO__c11_atomic_fetch_and: 577 case AtomicExpr::AO__c11_atomic_fetch_or: 578 case AtomicExpr::AO__c11_atomic_fetch_xor: 579 case AtomicExpr::AO__atomic_fetch_and: 580 case AtomicExpr::AO__atomic_fetch_or: 581 case AtomicExpr::AO__atomic_fetch_xor: 582 case AtomicExpr::AO__atomic_fetch_nand: 583 case AtomicExpr::AO__atomic_and_fetch: 584 case AtomicExpr::AO__atomic_or_fetch: 585 case AtomicExpr::AO__atomic_xor_fetch: 586 case AtomicExpr::AO__atomic_nand_fetch: 587 Val1 = EmitValToTemp(*this, E->getVal1()); 588 break; 589 } 590 591 auto GetDest = [&] { 592 if (!E->getType()->isVoidType() && !Dest) 593 Dest = CreateMemTemp(E->getType(), ".atomicdst"); 594 return Dest; 595 }; 596 597 // Use a library call. See: http://gcc.gnu.org/wiki/Atomic/GCCMM/LIbrary . 598 if (UseLibcall) { 599 bool UseOptimizedLibcall = false; 600 switch (E->getOp()) { 601 case AtomicExpr::AO__c11_atomic_fetch_add: 602 case AtomicExpr::AO__atomic_fetch_add: 603 case AtomicExpr::AO__c11_atomic_fetch_and: 604 case AtomicExpr::AO__atomic_fetch_and: 605 case AtomicExpr::AO__c11_atomic_fetch_or: 606 case AtomicExpr::AO__atomic_fetch_or: 607 case AtomicExpr::AO__c11_atomic_fetch_sub: 608 case AtomicExpr::AO__atomic_fetch_sub: 609 case AtomicExpr::AO__c11_atomic_fetch_xor: 610 case AtomicExpr::AO__atomic_fetch_xor: 611 // For these, only library calls for certain sizes exist. 612 UseOptimizedLibcall = true; 613 break; 614 default: 615 // Only use optimized library calls for sizes for which they exist. 616 if (Size == 1 || Size == 2 || Size == 4 || Size == 8) 617 UseOptimizedLibcall = true; 618 break; 619 } 620 621 CallArgList Args; 622 if (!UseOptimizedLibcall) { 623 // For non-optimized library calls, the size is the first parameter 624 Args.add(RValue::get(llvm::ConstantInt::get(SizeTy, Size)), 625 getContext().getSizeType()); 626 } 627 // Atomic address is the first or second parameter 628 Args.add(RValue::get(EmitCastToVoidPtr(Ptr)), getContext().VoidPtrTy); 629 630 std::string LibCallName; 631 QualType LoweredMemTy = 632 MemTy->isPointerType() ? getContext().getIntPtrType() : MemTy; 633 QualType RetTy; 634 bool HaveRetTy = false; 635 switch (E->getOp()) { 636 // There is only one libcall for compare an exchange, because there is no 637 // optimisation benefit possible from a libcall version of a weak compare 638 // and exchange. 639 // bool __atomic_compare_exchange(size_t size, void *mem, void *expected, 640 // void *desired, int success, int failure) 641 // bool __atomic_compare_exchange_N(T *mem, T *expected, T desired, 642 // int success, int failure) 643 case AtomicExpr::AO__c11_atomic_compare_exchange_weak: 644 case AtomicExpr::AO__c11_atomic_compare_exchange_strong: 645 case AtomicExpr::AO__atomic_compare_exchange: 646 case AtomicExpr::AO__atomic_compare_exchange_n: 647 LibCallName = "__atomic_compare_exchange"; 648 RetTy = getContext().BoolTy; 649 HaveRetTy = true; 650 Args.add(RValue::get(EmitCastToVoidPtr(Val1)), getContext().VoidPtrTy); 651 AddDirectArgument(*this, Args, UseOptimizedLibcall, Val2, MemTy, 652 E->getExprLoc(), sizeChars); 653 Args.add(RValue::get(Order), getContext().IntTy); 654 Order = OrderFail; 655 break; 656 // void __atomic_exchange(size_t size, void *mem, void *val, void *return, 657 // int order) 658 // T __atomic_exchange_N(T *mem, T val, int order) 659 case AtomicExpr::AO__c11_atomic_exchange: 660 case AtomicExpr::AO__atomic_exchange_n: 661 case AtomicExpr::AO__atomic_exchange: 662 LibCallName = "__atomic_exchange"; 663 AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1, MemTy, 664 E->getExprLoc(), sizeChars); 665 break; 666 // void __atomic_store(size_t size, void *mem, void *val, int order) 667 // void __atomic_store_N(T *mem, T val, int order) 668 case AtomicExpr::AO__c11_atomic_store: 669 case AtomicExpr::AO__atomic_store: 670 case AtomicExpr::AO__atomic_store_n: 671 LibCallName = "__atomic_store"; 672 RetTy = getContext().VoidTy; 673 HaveRetTy = true; 674 AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1, MemTy, 675 E->getExprLoc(), sizeChars); 676 break; 677 // void __atomic_load(size_t size, void *mem, void *return, int order) 678 // T __atomic_load_N(T *mem, int order) 679 case AtomicExpr::AO__c11_atomic_load: 680 case AtomicExpr::AO__atomic_load: 681 case AtomicExpr::AO__atomic_load_n: 682 LibCallName = "__atomic_load"; 683 break; 684 // T __atomic_fetch_add_N(T *mem, T val, int order) 685 case AtomicExpr::AO__c11_atomic_fetch_add: 686 case AtomicExpr::AO__atomic_fetch_add: 687 LibCallName = "__atomic_fetch_add"; 688 AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1, LoweredMemTy, 689 E->getExprLoc(), sizeChars); 690 break; 691 // T __atomic_fetch_and_N(T *mem, T val, int order) 692 case AtomicExpr::AO__c11_atomic_fetch_and: 693 case AtomicExpr::AO__atomic_fetch_and: 694 LibCallName = "__atomic_fetch_and"; 695 AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1, MemTy, 696 E->getExprLoc(), sizeChars); 697 break; 698 // T __atomic_fetch_or_N(T *mem, T val, int order) 699 case AtomicExpr::AO__c11_atomic_fetch_or: 700 case AtomicExpr::AO__atomic_fetch_or: 701 LibCallName = "__atomic_fetch_or"; 702 AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1, MemTy, 703 E->getExprLoc(), sizeChars); 704 break; 705 // T __atomic_fetch_sub_N(T *mem, T val, int order) 706 case AtomicExpr::AO__c11_atomic_fetch_sub: 707 case AtomicExpr::AO__atomic_fetch_sub: 708 LibCallName = "__atomic_fetch_sub"; 709 AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1, LoweredMemTy, 710 E->getExprLoc(), sizeChars); 711 break; 712 // T __atomic_fetch_xor_N(T *mem, T val, int order) 713 case AtomicExpr::AO__c11_atomic_fetch_xor: 714 case AtomicExpr::AO__atomic_fetch_xor: 715 LibCallName = "__atomic_fetch_xor"; 716 AddDirectArgument(*this, Args, UseOptimizedLibcall, Val1, MemTy, 717 E->getExprLoc(), sizeChars); 718 break; 719 default: return EmitUnsupportedRValue(E, "atomic library call"); 720 } 721 722 // Optimized functions have the size in their name. 723 if (UseOptimizedLibcall) 724 LibCallName += "_" + llvm::utostr(Size); 725 // By default, assume we return a value of the atomic type. 726 if (!HaveRetTy) { 727 if (UseOptimizedLibcall) { 728 // Value is returned directly. 729 // The function returns an appropriately sized integer type. 730 RetTy = getContext().getIntTypeForBitwidth( 731 getContext().toBits(sizeChars), /*Signed=*/false); 732 } else { 733 // Value is returned through parameter before the order. 734 RetTy = getContext().VoidTy; 735 Args.add(RValue::get(EmitCastToVoidPtr(Dest)), getContext().VoidPtrTy); 736 } 737 } 738 // order is always the last parameter 739 Args.add(RValue::get(Order), 740 getContext().IntTy); 741 742 RValue Res = emitAtomicLibcall(*this, LibCallName, RetTy, Args); 743 // The value is returned directly from the libcall. 744 if (HaveRetTy && !RetTy->isVoidType()) 745 return Res; 746 // The value is returned via an explicit out param. 747 if (RetTy->isVoidType()) 748 return RValue::get(nullptr); 749 // The value is returned directly for optimized libcalls but the caller is 750 // expected an out-param. 751 if (UseOptimizedLibcall) { 752 llvm::Value *ResVal = Res.getScalarVal(); 753 llvm::StoreInst *StoreDest = Builder.CreateStore( 754 ResVal, 755 Builder.CreateBitCast(GetDest(), ResVal->getType()->getPointerTo())); 756 StoreDest->setAlignment(Align); 757 } 758 return convertTempToRValue(Dest, E->getType(), E->getExprLoc()); 759 } 760 761 bool IsStore = E->getOp() == AtomicExpr::AO__c11_atomic_store || 762 E->getOp() == AtomicExpr::AO__atomic_store || 763 E->getOp() == AtomicExpr::AO__atomic_store_n; 764 bool IsLoad = E->getOp() == AtomicExpr::AO__c11_atomic_load || 765 E->getOp() == AtomicExpr::AO__atomic_load || 766 E->getOp() == AtomicExpr::AO__atomic_load_n; 767 768 llvm::Type *ITy = 769 llvm::IntegerType::get(getLLVMContext(), Size * 8); 770 llvm::Value *OrigDest = GetDest(); 771 Ptr = Builder.CreateBitCast( 772 Ptr, ITy->getPointerTo(Ptr->getType()->getPointerAddressSpace())); 773 if (Val1) Val1 = Builder.CreateBitCast(Val1, ITy->getPointerTo()); 774 if (Val2) Val2 = Builder.CreateBitCast(Val2, ITy->getPointerTo()); 775 if (Dest && !E->isCmpXChg()) 776 Dest = Builder.CreateBitCast(Dest, ITy->getPointerTo()); 777 778 if (isa<llvm::ConstantInt>(Order)) { 779 int ord = cast<llvm::ConstantInt>(Order)->getZExtValue(); 780 switch (ord) { 781 case AtomicExpr::AO_ABI_memory_order_relaxed: 782 EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, 783 Size, Align, llvm::Monotonic); 784 break; 785 case AtomicExpr::AO_ABI_memory_order_consume: 786 case AtomicExpr::AO_ABI_memory_order_acquire: 787 if (IsStore) 788 break; // Avoid crashing on code with undefined behavior 789 EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, 790 Size, Align, llvm::Acquire); 791 break; 792 case AtomicExpr::AO_ABI_memory_order_release: 793 if (IsLoad) 794 break; // Avoid crashing on code with undefined behavior 795 EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, 796 Size, Align, llvm::Release); 797 break; 798 case AtomicExpr::AO_ABI_memory_order_acq_rel: 799 if (IsLoad || IsStore) 800 break; // Avoid crashing on code with undefined behavior 801 EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, 802 Size, Align, llvm::AcquireRelease); 803 break; 804 case AtomicExpr::AO_ABI_memory_order_seq_cst: 805 EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, 806 Size, Align, llvm::SequentiallyConsistent); 807 break; 808 default: // invalid order 809 // We should not ever get here normally, but it's hard to 810 // enforce that in general. 811 break; 812 } 813 if (E->getType()->isVoidType()) 814 return RValue::get(nullptr); 815 return convertTempToRValue(OrigDest, E->getType(), E->getExprLoc()); 816 } 817 818 // Long case, when Order isn't obviously constant. 819 820 // Create all the relevant BB's 821 llvm::BasicBlock *MonotonicBB = nullptr, *AcquireBB = nullptr, 822 *ReleaseBB = nullptr, *AcqRelBB = nullptr, 823 *SeqCstBB = nullptr; 824 MonotonicBB = createBasicBlock("monotonic", CurFn); 825 if (!IsStore) 826 AcquireBB = createBasicBlock("acquire", CurFn); 827 if (!IsLoad) 828 ReleaseBB = createBasicBlock("release", CurFn); 829 if (!IsLoad && !IsStore) 830 AcqRelBB = createBasicBlock("acqrel", CurFn); 831 SeqCstBB = createBasicBlock("seqcst", CurFn); 832 llvm::BasicBlock *ContBB = createBasicBlock("atomic.continue", CurFn); 833 834 // Create the switch for the split 835 // MonotonicBB is arbitrarily chosen as the default case; in practice, this 836 // doesn't matter unless someone is crazy enough to use something that 837 // doesn't fold to a constant for the ordering. 838 Order = Builder.CreateIntCast(Order, Builder.getInt32Ty(), false); 839 llvm::SwitchInst *SI = Builder.CreateSwitch(Order, MonotonicBB); 840 841 // Emit all the different atomics 842 Builder.SetInsertPoint(MonotonicBB); 843 EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, 844 Size, Align, llvm::Monotonic); 845 Builder.CreateBr(ContBB); 846 if (!IsStore) { 847 Builder.SetInsertPoint(AcquireBB); 848 EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, 849 Size, Align, llvm::Acquire); 850 Builder.CreateBr(ContBB); 851 SI->addCase(Builder.getInt32(AtomicExpr::AO_ABI_memory_order_consume), 852 AcquireBB); 853 SI->addCase(Builder.getInt32(AtomicExpr::AO_ABI_memory_order_acquire), 854 AcquireBB); 855 } 856 if (!IsLoad) { 857 Builder.SetInsertPoint(ReleaseBB); 858 EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, 859 Size, Align, llvm::Release); 860 Builder.CreateBr(ContBB); 861 SI->addCase(Builder.getInt32(AtomicExpr::AO_ABI_memory_order_release), 862 ReleaseBB); 863 } 864 if (!IsLoad && !IsStore) { 865 Builder.SetInsertPoint(AcqRelBB); 866 EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, 867 Size, Align, llvm::AcquireRelease); 868 Builder.CreateBr(ContBB); 869 SI->addCase(Builder.getInt32(AtomicExpr::AO_ABI_memory_order_acq_rel), 870 AcqRelBB); 871 } 872 Builder.SetInsertPoint(SeqCstBB); 873 EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, IsWeak, OrderFail, 874 Size, Align, llvm::SequentiallyConsistent); 875 Builder.CreateBr(ContBB); 876 SI->addCase(Builder.getInt32(AtomicExpr::AO_ABI_memory_order_seq_cst), 877 SeqCstBB); 878 879 // Cleanup and return 880 Builder.SetInsertPoint(ContBB); 881 if (E->getType()->isVoidType()) 882 return RValue::get(nullptr); 883 return convertTempToRValue(OrigDest, E->getType(), E->getExprLoc()); 884 } 885 886 llvm::Value *AtomicInfo::emitCastToAtomicIntPointer(llvm::Value *addr) const { 887 unsigned addrspace = 888 cast<llvm::PointerType>(addr->getType())->getAddressSpace(); 889 llvm::IntegerType *ty = 890 llvm::IntegerType::get(CGF.getLLVMContext(), AtomicSizeInBits); 891 return CGF.Builder.CreateBitCast(addr, ty->getPointerTo(addrspace)); 892 } 893 894 RValue AtomicInfo::convertTempToRValue(llvm::Value *addr, 895 AggValueSlot resultSlot, 896 SourceLocation loc) const { 897 if (EvaluationKind == TEK_Aggregate) 898 return resultSlot.asRValue(); 899 900 // Drill into the padding structure if we have one. 901 if (hasPadding()) 902 addr = CGF.Builder.CreateStructGEP(addr, 0); 903 904 // Otherwise, just convert the temporary to an r-value using the 905 // normal conversion routine. 906 return CGF.convertTempToRValue(addr, getValueType(), loc); 907 } 908 909 /// Emit a load from an l-value of atomic type. Note that the r-value 910 /// we produce is an r-value of the atomic *value* type. 911 RValue CodeGenFunction::EmitAtomicLoad(LValue src, SourceLocation loc, 912 AggValueSlot resultSlot) { 913 AtomicInfo atomics(*this, src); 914 915 // Check whether we should use a library call. 916 if (atomics.shouldUseLibcall()) { 917 llvm::Value *tempAddr; 918 if (!resultSlot.isIgnored()) { 919 assert(atomics.getEvaluationKind() == TEK_Aggregate); 920 tempAddr = resultSlot.getAddr(); 921 } else { 922 tempAddr = CreateMemTemp(atomics.getAtomicType(), "atomic-load-temp"); 923 } 924 925 // void __atomic_load(size_t size, void *mem, void *return, int order); 926 CallArgList args; 927 args.add(RValue::get(atomics.getAtomicSizeValue()), 928 getContext().getSizeType()); 929 args.add(RValue::get(EmitCastToVoidPtr(src.getAddress())), 930 getContext().VoidPtrTy); 931 args.add(RValue::get(EmitCastToVoidPtr(tempAddr)), 932 getContext().VoidPtrTy); 933 args.add(RValue::get(llvm::ConstantInt::get( 934 IntTy, AtomicExpr::AO_ABI_memory_order_seq_cst)), 935 getContext().IntTy); 936 emitAtomicLibcall(*this, "__atomic_load", getContext().VoidTy, args); 937 938 // Produce the r-value. 939 return atomics.convertTempToRValue(tempAddr, resultSlot, loc); 940 } 941 942 // Okay, we're doing this natively. 943 llvm::Value *addr = atomics.emitCastToAtomicIntPointer(src.getAddress()); 944 llvm::LoadInst *load = Builder.CreateLoad(addr, "atomic-load"); 945 load->setAtomic(llvm::SequentiallyConsistent); 946 947 // Other decoration. 948 load->setAlignment(src.getAlignment().getQuantity()); 949 if (src.isVolatileQualified()) 950 load->setVolatile(true); 951 if (src.getTBAAInfo()) 952 CGM.DecorateInstruction(load, src.getTBAAInfo()); 953 954 // Okay, turn that back into the original value type. 955 QualType valueType = atomics.getValueType(); 956 llvm::Value *result = load; 957 958 // If we're ignoring an aggregate return, don't do anything. 959 if (atomics.getEvaluationKind() == TEK_Aggregate && resultSlot.isIgnored()) 960 return RValue::getAggregate(nullptr, false); 961 962 // The easiest way to do this this is to go through memory, but we 963 // try not to in some easy cases. 964 if (atomics.getEvaluationKind() == TEK_Scalar && !atomics.hasPadding()) { 965 llvm::Type *resultTy = CGM.getTypes().ConvertTypeForMem(valueType); 966 if (isa<llvm::IntegerType>(resultTy)) { 967 assert(result->getType() == resultTy); 968 result = EmitFromMemory(result, valueType); 969 } else if (isa<llvm::PointerType>(resultTy)) { 970 result = Builder.CreateIntToPtr(result, resultTy); 971 } else { 972 result = Builder.CreateBitCast(result, resultTy); 973 } 974 return RValue::get(result); 975 } 976 977 // Create a temporary. This needs to be big enough to hold the 978 // atomic integer. 979 llvm::Value *temp; 980 bool tempIsVolatile = false; 981 CharUnits tempAlignment; 982 if (atomics.getEvaluationKind() == TEK_Aggregate) { 983 assert(!resultSlot.isIgnored()); 984 temp = resultSlot.getAddr(); 985 tempAlignment = atomics.getValueAlignment(); 986 tempIsVolatile = resultSlot.isVolatile(); 987 } else { 988 temp = CreateMemTemp(atomics.getAtomicType(), "atomic-load-temp"); 989 tempAlignment = atomics.getAtomicAlignment(); 990 } 991 992 // Slam the integer into the temporary. 993 llvm::Value *castTemp = atomics.emitCastToAtomicIntPointer(temp); 994 Builder.CreateAlignedStore(result, castTemp, tempAlignment.getQuantity()) 995 ->setVolatile(tempIsVolatile); 996 997 return atomics.convertTempToRValue(temp, resultSlot, loc); 998 } 999 1000 1001 1002 /// Copy an r-value into memory as part of storing to an atomic type. 1003 /// This needs to create a bit-pattern suitable for atomic operations. 1004 void AtomicInfo::emitCopyIntoMemory(RValue rvalue, LValue dest) const { 1005 // If we have an r-value, the rvalue should be of the atomic type, 1006 // which means that the caller is responsible for having zeroed 1007 // any padding. Just do an aggregate copy of that type. 1008 if (rvalue.isAggregate()) { 1009 CGF.EmitAggregateCopy(dest.getAddress(), 1010 rvalue.getAggregateAddr(), 1011 getAtomicType(), 1012 (rvalue.isVolatileQualified() 1013 || dest.isVolatileQualified()), 1014 dest.getAlignment()); 1015 return; 1016 } 1017 1018 // Okay, otherwise we're copying stuff. 1019 1020 // Zero out the buffer if necessary. 1021 emitMemSetZeroIfNecessary(dest); 1022 1023 // Drill past the padding if present. 1024 dest = projectValue(dest); 1025 1026 // Okay, store the rvalue in. 1027 if (rvalue.isScalar()) { 1028 CGF.EmitStoreOfScalar(rvalue.getScalarVal(), dest, /*init*/ true); 1029 } else { 1030 CGF.EmitStoreOfComplex(rvalue.getComplexVal(), dest, /*init*/ true); 1031 } 1032 } 1033 1034 1035 /// Materialize an r-value into memory for the purposes of storing it 1036 /// to an atomic type. 1037 llvm::Value *AtomicInfo::materializeRValue(RValue rvalue) const { 1038 // Aggregate r-values are already in memory, and EmitAtomicStore 1039 // requires them to be values of the atomic type. 1040 if (rvalue.isAggregate()) 1041 return rvalue.getAggregateAddr(); 1042 1043 // Otherwise, make a temporary and materialize into it. 1044 llvm::Value *temp = CGF.CreateMemTemp(getAtomicType(), "atomic-store-temp"); 1045 LValue tempLV = CGF.MakeAddrLValue(temp, getAtomicType(), getAtomicAlignment()); 1046 emitCopyIntoMemory(rvalue, tempLV); 1047 return temp; 1048 } 1049 1050 /// Emit a store to an l-value of atomic type. 1051 /// 1052 /// Note that the r-value is expected to be an r-value *of the atomic 1053 /// type*; this means that for aggregate r-values, it should include 1054 /// storage for any padding that was necessary. 1055 void CodeGenFunction::EmitAtomicStore(RValue rvalue, LValue dest, bool isInit) { 1056 // If this is an aggregate r-value, it should agree in type except 1057 // maybe for address-space qualification. 1058 assert(!rvalue.isAggregate() || 1059 rvalue.getAggregateAddr()->getType()->getPointerElementType() 1060 == dest.getAddress()->getType()->getPointerElementType()); 1061 1062 AtomicInfo atomics(*this, dest); 1063 1064 // If this is an initialization, just put the value there normally. 1065 if (isInit) { 1066 atomics.emitCopyIntoMemory(rvalue, dest); 1067 return; 1068 } 1069 1070 // Check whether we should use a library call. 1071 if (atomics.shouldUseLibcall()) { 1072 // Produce a source address. 1073 llvm::Value *srcAddr = atomics.materializeRValue(rvalue); 1074 1075 // void __atomic_store(size_t size, void *mem, void *val, int order) 1076 CallArgList args; 1077 args.add(RValue::get(atomics.getAtomicSizeValue()), 1078 getContext().getSizeType()); 1079 args.add(RValue::get(EmitCastToVoidPtr(dest.getAddress())), 1080 getContext().VoidPtrTy); 1081 args.add(RValue::get(EmitCastToVoidPtr(srcAddr)), 1082 getContext().VoidPtrTy); 1083 args.add(RValue::get(llvm::ConstantInt::get( 1084 IntTy, AtomicExpr::AO_ABI_memory_order_seq_cst)), 1085 getContext().IntTy); 1086 emitAtomicLibcall(*this, "__atomic_store", getContext().VoidTy, args); 1087 return; 1088 } 1089 1090 // Okay, we're doing this natively. 1091 llvm::Value *intValue; 1092 1093 // If we've got a scalar value of the right size, try to avoid going 1094 // through memory. 1095 if (rvalue.isScalar() && !atomics.hasPadding()) { 1096 llvm::Value *value = rvalue.getScalarVal(); 1097 if (isa<llvm::IntegerType>(value->getType())) { 1098 intValue = value; 1099 } else { 1100 llvm::IntegerType *inputIntTy = 1101 llvm::IntegerType::get(getLLVMContext(), atomics.getValueSizeInBits()); 1102 if (isa<llvm::PointerType>(value->getType())) { 1103 intValue = Builder.CreatePtrToInt(value, inputIntTy); 1104 } else { 1105 intValue = Builder.CreateBitCast(value, inputIntTy); 1106 } 1107 } 1108 1109 // Otherwise, we need to go through memory. 1110 } else { 1111 // Put the r-value in memory. 1112 llvm::Value *addr = atomics.materializeRValue(rvalue); 1113 1114 // Cast the temporary to the atomic int type and pull a value out. 1115 addr = atomics.emitCastToAtomicIntPointer(addr); 1116 intValue = Builder.CreateAlignedLoad(addr, 1117 atomics.getAtomicAlignment().getQuantity()); 1118 } 1119 1120 // Do the atomic store. 1121 llvm::Value *addr = atomics.emitCastToAtomicIntPointer(dest.getAddress()); 1122 llvm::StoreInst *store = Builder.CreateStore(intValue, addr); 1123 1124 // Initializations don't need to be atomic. 1125 if (!isInit) store->setAtomic(llvm::SequentiallyConsistent); 1126 1127 // Other decoration. 1128 store->setAlignment(dest.getAlignment().getQuantity()); 1129 if (dest.isVolatileQualified()) 1130 store->setVolatile(true); 1131 if (dest.getTBAAInfo()) 1132 CGM.DecorateInstruction(store, dest.getTBAAInfo()); 1133 } 1134 1135 void CodeGenFunction::EmitAtomicInit(Expr *init, LValue dest) { 1136 AtomicInfo atomics(*this, dest); 1137 1138 switch (atomics.getEvaluationKind()) { 1139 case TEK_Scalar: { 1140 llvm::Value *value = EmitScalarExpr(init); 1141 atomics.emitCopyIntoMemory(RValue::get(value), dest); 1142 return; 1143 } 1144 1145 case TEK_Complex: { 1146 ComplexPairTy value = EmitComplexExpr(init); 1147 atomics.emitCopyIntoMemory(RValue::getComplex(value), dest); 1148 return; 1149 } 1150 1151 case TEK_Aggregate: { 1152 // Fix up the destination if the initializer isn't an expression 1153 // of atomic type. 1154 bool Zeroed = false; 1155 if (!init->getType()->isAtomicType()) { 1156 Zeroed = atomics.emitMemSetZeroIfNecessary(dest); 1157 dest = atomics.projectValue(dest); 1158 } 1159 1160 // Evaluate the expression directly into the destination. 1161 AggValueSlot slot = AggValueSlot::forLValue(dest, 1162 AggValueSlot::IsNotDestructed, 1163 AggValueSlot::DoesNotNeedGCBarriers, 1164 AggValueSlot::IsNotAliased, 1165 Zeroed ? AggValueSlot::IsZeroed : 1166 AggValueSlot::IsNotZeroed); 1167 1168 EmitAggExpr(init, slot); 1169 return; 1170 } 1171 } 1172 llvm_unreachable("bad evaluation kind"); 1173 } 1174