1 //===--- CGAtomic.cpp - Emit LLVM IR for atomic operations ----------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains the code for emitting atomic operations.
12 //===----------------------------------------------------------------------===//
14 #include "CodeGenFunction.h"
16 #include "CodeGenModule.h"
17 #include "clang/AST/ASTContext.h"
18 #include "llvm/IR/DataLayout.h"
19 #include "llvm/IR/Intrinsics.h"
20 #include "llvm/IR/Operator.h"
22 using namespace clang;
23 using namespace CodeGen;
25 // The ABI values for various atomic memory orderings.
26 enum AtomicOrderingKind {
27 AO_ABI_memory_order_relaxed = 0,
28 AO_ABI_memory_order_consume = 1,
29 AO_ABI_memory_order_acquire = 2,
30 AO_ABI_memory_order_release = 3,
31 AO_ABI_memory_order_acq_rel = 4,
32 AO_ABI_memory_order_seq_cst = 5
40 uint64_t AtomicSizeInBits;
41 uint64_t ValueSizeInBits;
42 CharUnits AtomicAlign;
44 CharUnits LValueAlign;
45 TypeEvaluationKind EvaluationKind;
48 AtomicInfo(CodeGenFunction &CGF, LValue &lvalue) : CGF(CGF) {
49 assert(lvalue.isSimple());
51 AtomicTy = lvalue.getType();
52 ValueTy = AtomicTy->castAs<AtomicType>()->getValueType();
53 EvaluationKind = CGF.getEvaluationKind(ValueTy);
55 ASTContext &C = CGF.getContext();
57 uint64_t valueAlignInBits;
58 llvm::tie(ValueSizeInBits, valueAlignInBits) = C.getTypeInfo(ValueTy);
60 uint64_t atomicAlignInBits;
61 llvm::tie(AtomicSizeInBits, atomicAlignInBits) = C.getTypeInfo(AtomicTy);
63 assert(ValueSizeInBits <= AtomicSizeInBits);
64 assert(valueAlignInBits <= atomicAlignInBits);
66 AtomicAlign = C.toCharUnitsFromBits(atomicAlignInBits);
67 ValueAlign = C.toCharUnitsFromBits(valueAlignInBits);
68 if (lvalue.getAlignment().isZero())
69 lvalue.setAlignment(AtomicAlign);
72 (AtomicSizeInBits > uint64_t(C.toBits(lvalue.getAlignment())) ||
73 AtomicSizeInBits > C.getTargetInfo().getMaxAtomicInlineWidth());
76 QualType getAtomicType() const { return AtomicTy; }
77 QualType getValueType() const { return ValueTy; }
78 CharUnits getAtomicAlignment() const { return AtomicAlign; }
79 CharUnits getValueAlignment() const { return ValueAlign; }
80 uint64_t getAtomicSizeInBits() const { return AtomicSizeInBits; }
81 uint64_t getValueSizeInBits() const { return AtomicSizeInBits; }
82 TypeEvaluationKind getEvaluationKind() const { return EvaluationKind; }
83 bool shouldUseLibcall() const { return UseLibcall; }
85 /// Is the atomic size larger than the underlying value type?
87 /// Note that the absence of padding does not mean that atomic
88 /// objects are completely interchangeable with non-atomic
89 /// objects: we might have promoted the alignment of a type
90 /// without making it bigger.
91 bool hasPadding() const {
92 return (ValueSizeInBits != AtomicSizeInBits);
95 void emitMemSetZeroIfNecessary(LValue dest) const;
97 llvm::Value *getAtomicSizeValue() const {
98 CharUnits size = CGF.getContext().toCharUnitsFromBits(AtomicSizeInBits);
99 return CGF.CGM.getSize(size);
102 /// Cast the given pointer to an integer pointer suitable for
103 /// atomic operations.
104 llvm::Value *emitCastToAtomicIntPointer(llvm::Value *addr) const;
106 /// Turn an atomic-layout object into an r-value.
107 RValue convertTempToRValue(llvm::Value *addr,
108 AggValueSlot resultSlot) const;
110 /// Copy an atomic r-value into atomic-layout memory.
111 void emitCopyIntoMemory(RValue rvalue, LValue lvalue) const;
113 /// Project an l-value down to the value field.
114 LValue projectValue(LValue lvalue) const {
115 llvm::Value *addr = lvalue.getAddress();
117 addr = CGF.Builder.CreateStructGEP(addr, 0);
119 return LValue::MakeAddr(addr, getValueType(), lvalue.getAlignment(),
120 CGF.getContext(), lvalue.getTBAAInfo());
123 /// Materialize an atomic r-value in atomic-layout memory.
124 llvm::Value *materializeRValue(RValue rvalue) const;
127 bool requiresMemSetZero(llvm::Type *type) const;
131 static RValue emitAtomicLibcall(CodeGenFunction &CGF,
135 const CGFunctionInfo &fnInfo =
136 CGF.CGM.getTypes().arrangeFreeFunctionCall(resultType, args,
137 FunctionType::ExtInfo(), RequiredArgs::All);
138 llvm::FunctionType *fnTy = CGF.CGM.getTypes().GetFunctionType(fnInfo);
139 llvm::Constant *fn = CGF.CGM.CreateRuntimeFunction(fnTy, fnName);
140 return CGF.EmitCall(fnInfo, fn, ReturnValueSlot(), args);
143 /// Does a store of the given IR type modify the full expected width?
144 static bool isFullSizeType(CodeGenModule &CGM, llvm::Type *type,
145 uint64_t expectedSize) {
146 return (CGM.getDataLayout().getTypeStoreSize(type) * 8 == expectedSize);
149 /// Does the atomic type require memsetting to zero before initialization?
151 /// The IR type is provided as a way of making certain queries faster.
152 bool AtomicInfo::requiresMemSetZero(llvm::Type *type) const {
153 // If the atomic type has size padding, we definitely need a memset.
154 if (hasPadding()) return true;
156 // Otherwise, do some simple heuristics to try to avoid it:
157 switch (getEvaluationKind()) {
158 // For scalars and complexes, check whether the store size of the
159 // type uses the full size.
161 return !isFullSizeType(CGF.CGM, type, AtomicSizeInBits);
163 return !isFullSizeType(CGF.CGM, type->getStructElementType(0),
164 AtomicSizeInBits / 2);
166 // Just be pessimistic about aggregates.
170 llvm_unreachable("bad evaluation kind");
173 void AtomicInfo::emitMemSetZeroIfNecessary(LValue dest) const {
174 llvm::Value *addr = dest.getAddress();
175 if (!requiresMemSetZero(addr->getType()->getPointerElementType()))
178 CGF.Builder.CreateMemSet(addr, llvm::ConstantInt::get(CGF.Int8Ty, 0),
179 AtomicSizeInBits / 8,
180 dest.getAlignment().getQuantity());
184 EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, llvm::Value *Dest,
185 llvm::Value *Ptr, llvm::Value *Val1, llvm::Value *Val2,
186 uint64_t Size, unsigned Align, llvm::AtomicOrdering Order) {
187 llvm::AtomicRMWInst::BinOp Op = llvm::AtomicRMWInst::Add;
188 llvm::Instruction::BinaryOps PostOp = (llvm::Instruction::BinaryOps)0;
190 switch (E->getOp()) {
191 case AtomicExpr::AO__c11_atomic_init:
192 llvm_unreachable("Already handled!");
194 case AtomicExpr::AO__c11_atomic_compare_exchange_strong:
195 case AtomicExpr::AO__c11_atomic_compare_exchange_weak:
196 case AtomicExpr::AO__atomic_compare_exchange:
197 case AtomicExpr::AO__atomic_compare_exchange_n: {
198 // Note that cmpxchg only supports specifying one ordering and
199 // doesn't support weak cmpxchg, at least at the moment.
200 llvm::LoadInst *LoadVal1 = CGF.Builder.CreateLoad(Val1);
201 LoadVal1->setAlignment(Align);
202 llvm::LoadInst *LoadVal2 = CGF.Builder.CreateLoad(Val2);
203 LoadVal2->setAlignment(Align);
204 llvm::AtomicCmpXchgInst *CXI =
205 CGF.Builder.CreateAtomicCmpXchg(Ptr, LoadVal1, LoadVal2, Order);
206 CXI->setVolatile(E->isVolatile());
207 llvm::StoreInst *StoreVal1 = CGF.Builder.CreateStore(CXI, Val1);
208 StoreVal1->setAlignment(Align);
209 llvm::Value *Cmp = CGF.Builder.CreateICmpEQ(CXI, LoadVal1);
210 CGF.EmitStoreOfScalar(Cmp, CGF.MakeAddrLValue(Dest, E->getType()));
214 case AtomicExpr::AO__c11_atomic_load:
215 case AtomicExpr::AO__atomic_load_n:
216 case AtomicExpr::AO__atomic_load: {
217 llvm::LoadInst *Load = CGF.Builder.CreateLoad(Ptr);
218 Load->setAtomic(Order);
219 Load->setAlignment(Size);
220 Load->setVolatile(E->isVolatile());
221 llvm::StoreInst *StoreDest = CGF.Builder.CreateStore(Load, Dest);
222 StoreDest->setAlignment(Align);
226 case AtomicExpr::AO__c11_atomic_store:
227 case AtomicExpr::AO__atomic_store:
228 case AtomicExpr::AO__atomic_store_n: {
229 assert(!Dest && "Store does not return a value");
230 llvm::LoadInst *LoadVal1 = CGF.Builder.CreateLoad(Val1);
231 LoadVal1->setAlignment(Align);
232 llvm::StoreInst *Store = CGF.Builder.CreateStore(LoadVal1, Ptr);
233 Store->setAtomic(Order);
234 Store->setAlignment(Size);
235 Store->setVolatile(E->isVolatile());
239 case AtomicExpr::AO__c11_atomic_exchange:
240 case AtomicExpr::AO__atomic_exchange_n:
241 case AtomicExpr::AO__atomic_exchange:
242 Op = llvm::AtomicRMWInst::Xchg;
245 case AtomicExpr::AO__atomic_add_fetch:
246 PostOp = llvm::Instruction::Add;
248 case AtomicExpr::AO__c11_atomic_fetch_add:
249 case AtomicExpr::AO__atomic_fetch_add:
250 Op = llvm::AtomicRMWInst::Add;
253 case AtomicExpr::AO__atomic_sub_fetch:
254 PostOp = llvm::Instruction::Sub;
256 case AtomicExpr::AO__c11_atomic_fetch_sub:
257 case AtomicExpr::AO__atomic_fetch_sub:
258 Op = llvm::AtomicRMWInst::Sub;
261 case AtomicExpr::AO__atomic_and_fetch:
262 PostOp = llvm::Instruction::And;
264 case AtomicExpr::AO__c11_atomic_fetch_and:
265 case AtomicExpr::AO__atomic_fetch_and:
266 Op = llvm::AtomicRMWInst::And;
269 case AtomicExpr::AO__atomic_or_fetch:
270 PostOp = llvm::Instruction::Or;
272 case AtomicExpr::AO__c11_atomic_fetch_or:
273 case AtomicExpr::AO__atomic_fetch_or:
274 Op = llvm::AtomicRMWInst::Or;
277 case AtomicExpr::AO__atomic_xor_fetch:
278 PostOp = llvm::Instruction::Xor;
280 case AtomicExpr::AO__c11_atomic_fetch_xor:
281 case AtomicExpr::AO__atomic_fetch_xor:
282 Op = llvm::AtomicRMWInst::Xor;
285 case AtomicExpr::AO__atomic_nand_fetch:
286 PostOp = llvm::Instruction::And;
288 case AtomicExpr::AO__atomic_fetch_nand:
289 Op = llvm::AtomicRMWInst::Nand;
293 llvm::LoadInst *LoadVal1 = CGF.Builder.CreateLoad(Val1);
294 LoadVal1->setAlignment(Align);
295 llvm::AtomicRMWInst *RMWI =
296 CGF.Builder.CreateAtomicRMW(Op, Ptr, LoadVal1, Order);
297 RMWI->setVolatile(E->isVolatile());
299 // For __atomic_*_fetch operations, perform the operation again to
300 // determine the value which was written.
301 llvm::Value *Result = RMWI;
303 Result = CGF.Builder.CreateBinOp(PostOp, RMWI, LoadVal1);
304 if (E->getOp() == AtomicExpr::AO__atomic_nand_fetch)
305 Result = CGF.Builder.CreateNot(Result);
306 llvm::StoreInst *StoreDest = CGF.Builder.CreateStore(Result, Dest);
307 StoreDest->setAlignment(Align);
310 // This function emits any expression (scalar, complex, or aggregate)
311 // into a temporary alloca.
313 EmitValToTemp(CodeGenFunction &CGF, Expr *E) {
314 llvm::Value *DeclPtr = CGF.CreateMemTemp(E->getType(), ".atomictmp");
315 CGF.EmitAnyExprToMem(E, DeclPtr, E->getType().getQualifiers(),
320 RValue CodeGenFunction::EmitAtomicExpr(AtomicExpr *E, llvm::Value *Dest) {
321 QualType AtomicTy = E->getPtr()->getType()->getPointeeType();
322 QualType MemTy = AtomicTy;
323 if (const AtomicType *AT = AtomicTy->getAs<AtomicType>())
324 MemTy = AT->getValueType();
325 CharUnits sizeChars = getContext().getTypeSizeInChars(AtomicTy);
326 uint64_t Size = sizeChars.getQuantity();
327 CharUnits alignChars = getContext().getTypeAlignInChars(AtomicTy);
328 unsigned Align = alignChars.getQuantity();
329 unsigned MaxInlineWidthInBits =
330 getTarget().getMaxAtomicInlineWidth();
331 bool UseLibcall = (Size != Align ||
332 getContext().toBits(sizeChars) > MaxInlineWidthInBits);
334 llvm::Value *Ptr, *Order, *OrderFail = 0, *Val1 = 0, *Val2 = 0;
335 Ptr = EmitScalarExpr(E->getPtr());
337 if (E->getOp() == AtomicExpr::AO__c11_atomic_init) {
338 assert(!Dest && "Init does not return a value");
339 LValue lvalue = LValue::MakeAddr(Ptr, AtomicTy, alignChars, getContext());
340 EmitAtomicInit(E->getVal1(), lvalue);
341 return RValue::get(0);
344 Order = EmitScalarExpr(E->getOrder());
346 switch (E->getOp()) {
347 case AtomicExpr::AO__c11_atomic_init:
348 llvm_unreachable("Already handled!");
350 case AtomicExpr::AO__c11_atomic_load:
351 case AtomicExpr::AO__atomic_load_n:
354 case AtomicExpr::AO__atomic_load:
355 Dest = EmitScalarExpr(E->getVal1());
358 case AtomicExpr::AO__atomic_store:
359 Val1 = EmitScalarExpr(E->getVal1());
362 case AtomicExpr::AO__atomic_exchange:
363 Val1 = EmitScalarExpr(E->getVal1());
364 Dest = EmitScalarExpr(E->getVal2());
367 case AtomicExpr::AO__c11_atomic_compare_exchange_strong:
368 case AtomicExpr::AO__c11_atomic_compare_exchange_weak:
369 case AtomicExpr::AO__atomic_compare_exchange_n:
370 case AtomicExpr::AO__atomic_compare_exchange:
371 Val1 = EmitScalarExpr(E->getVal1());
372 if (E->getOp() == AtomicExpr::AO__atomic_compare_exchange)
373 Val2 = EmitScalarExpr(E->getVal2());
375 Val2 = EmitValToTemp(*this, E->getVal2());
376 OrderFail = EmitScalarExpr(E->getOrderFail());
377 // Evaluate and discard the 'weak' argument.
378 if (E->getNumSubExprs() == 6)
379 EmitScalarExpr(E->getWeak());
382 case AtomicExpr::AO__c11_atomic_fetch_add:
383 case AtomicExpr::AO__c11_atomic_fetch_sub:
384 if (MemTy->isPointerType()) {
385 // For pointer arithmetic, we're required to do a bit of math:
386 // adding 1 to an int* is not the same as adding 1 to a uintptr_t.
387 // ... but only for the C11 builtins. The GNU builtins expect the
388 // user to multiply by sizeof(T).
389 QualType Val1Ty = E->getVal1()->getType();
390 llvm::Value *Val1Scalar = EmitScalarExpr(E->getVal1());
391 CharUnits PointeeIncAmt =
392 getContext().getTypeSizeInChars(MemTy->getPointeeType());
393 Val1Scalar = Builder.CreateMul(Val1Scalar, CGM.getSize(PointeeIncAmt));
394 Val1 = CreateMemTemp(Val1Ty, ".atomictmp");
395 EmitStoreOfScalar(Val1Scalar, MakeAddrLValue(Val1, Val1Ty));
399 case AtomicExpr::AO__atomic_fetch_add:
400 case AtomicExpr::AO__atomic_fetch_sub:
401 case AtomicExpr::AO__atomic_add_fetch:
402 case AtomicExpr::AO__atomic_sub_fetch:
403 case AtomicExpr::AO__c11_atomic_store:
404 case AtomicExpr::AO__c11_atomic_exchange:
405 case AtomicExpr::AO__atomic_store_n:
406 case AtomicExpr::AO__atomic_exchange_n:
407 case AtomicExpr::AO__c11_atomic_fetch_and:
408 case AtomicExpr::AO__c11_atomic_fetch_or:
409 case AtomicExpr::AO__c11_atomic_fetch_xor:
410 case AtomicExpr::AO__atomic_fetch_and:
411 case AtomicExpr::AO__atomic_fetch_or:
412 case AtomicExpr::AO__atomic_fetch_xor:
413 case AtomicExpr::AO__atomic_fetch_nand:
414 case AtomicExpr::AO__atomic_and_fetch:
415 case AtomicExpr::AO__atomic_or_fetch:
416 case AtomicExpr::AO__atomic_xor_fetch:
417 case AtomicExpr::AO__atomic_nand_fetch:
418 Val1 = EmitValToTemp(*this, E->getVal1());
422 if (!E->getType()->isVoidType() && !Dest)
423 Dest = CreateMemTemp(E->getType(), ".atomicdst");
425 // Use a library call. See: http://gcc.gnu.org/wiki/Atomic/GCCMM/LIbrary .
428 SmallVector<QualType, 5> Params;
430 // Size is always the first parameter
431 Args.add(RValue::get(llvm::ConstantInt::get(SizeTy, Size)),
432 getContext().getSizeType());
433 // Atomic address is always the second parameter
434 Args.add(RValue::get(EmitCastToVoidPtr(Ptr)),
435 getContext().VoidPtrTy);
437 const char* LibCallName;
438 QualType RetTy = getContext().VoidTy;
439 switch (E->getOp()) {
440 // There is only one libcall for compare an exchange, because there is no
441 // optimisation benefit possible from a libcall version of a weak compare
443 // bool __atomic_compare_exchange(size_t size, void *obj, void *expected,
444 // void *desired, int success, int failure)
445 case AtomicExpr::AO__c11_atomic_compare_exchange_weak:
446 case AtomicExpr::AO__c11_atomic_compare_exchange_strong:
447 case AtomicExpr::AO__atomic_compare_exchange:
448 case AtomicExpr::AO__atomic_compare_exchange_n:
449 LibCallName = "__atomic_compare_exchange";
450 RetTy = getContext().BoolTy;
451 Args.add(RValue::get(EmitCastToVoidPtr(Val1)),
452 getContext().VoidPtrTy);
453 Args.add(RValue::get(EmitCastToVoidPtr(Val2)),
454 getContext().VoidPtrTy);
455 Args.add(RValue::get(Order),
459 // void __atomic_exchange(size_t size, void *mem, void *val, void *return,
461 case AtomicExpr::AO__c11_atomic_exchange:
462 case AtomicExpr::AO__atomic_exchange_n:
463 case AtomicExpr::AO__atomic_exchange:
464 LibCallName = "__atomic_exchange";
465 Args.add(RValue::get(EmitCastToVoidPtr(Val1)),
466 getContext().VoidPtrTy);
467 Args.add(RValue::get(EmitCastToVoidPtr(Dest)),
468 getContext().VoidPtrTy);
470 // void __atomic_store(size_t size, void *mem, void *val, int order)
471 case AtomicExpr::AO__c11_atomic_store:
472 case AtomicExpr::AO__atomic_store:
473 case AtomicExpr::AO__atomic_store_n:
474 LibCallName = "__atomic_store";
475 Args.add(RValue::get(EmitCastToVoidPtr(Val1)),
476 getContext().VoidPtrTy);
478 // void __atomic_load(size_t size, void *mem, void *return, int order)
479 case AtomicExpr::AO__c11_atomic_load:
480 case AtomicExpr::AO__atomic_load:
481 case AtomicExpr::AO__atomic_load_n:
482 LibCallName = "__atomic_load";
483 Args.add(RValue::get(EmitCastToVoidPtr(Dest)),
484 getContext().VoidPtrTy);
486 default: return EmitUnsupportedRValue(E, "atomic library call");
488 // order is always the last parameter
489 Args.add(RValue::get(Order),
492 const CGFunctionInfo &FuncInfo =
493 CGM.getTypes().arrangeFreeFunctionCall(RetTy, Args,
494 FunctionType::ExtInfo(), RequiredArgs::All);
495 llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FuncInfo);
496 llvm::Constant *Func = CGM.CreateRuntimeFunction(FTy, LibCallName);
497 RValue Res = EmitCall(FuncInfo, Func, ReturnValueSlot(), Args);
500 if (E->getType()->isVoidType())
501 return RValue::get(0);
502 return convertTempToRValue(Dest, E->getType());
505 bool IsStore = E->getOp() == AtomicExpr::AO__c11_atomic_store ||
506 E->getOp() == AtomicExpr::AO__atomic_store ||
507 E->getOp() == AtomicExpr::AO__atomic_store_n;
508 bool IsLoad = E->getOp() == AtomicExpr::AO__c11_atomic_load ||
509 E->getOp() == AtomicExpr::AO__atomic_load ||
510 E->getOp() == AtomicExpr::AO__atomic_load_n;
513 llvm::IntegerType::get(getLLVMContext(), Size * 8)->getPointerTo();
514 llvm::Value *OrigDest = Dest;
515 Ptr = Builder.CreateBitCast(Ptr, IPtrTy);
516 if (Val1) Val1 = Builder.CreateBitCast(Val1, IPtrTy);
517 if (Val2) Val2 = Builder.CreateBitCast(Val2, IPtrTy);
518 if (Dest && !E->isCmpXChg()) Dest = Builder.CreateBitCast(Dest, IPtrTy);
520 if (isa<llvm::ConstantInt>(Order)) {
521 int ord = cast<llvm::ConstantInt>(Order)->getZExtValue();
523 case AO_ABI_memory_order_relaxed:
524 EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, Size, Align,
527 case AO_ABI_memory_order_consume:
528 case AO_ABI_memory_order_acquire:
530 break; // Avoid crashing on code with undefined behavior
531 EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, Size, Align,
534 case AO_ABI_memory_order_release:
536 break; // Avoid crashing on code with undefined behavior
537 EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, Size, Align,
540 case AO_ABI_memory_order_acq_rel:
541 if (IsLoad || IsStore)
542 break; // Avoid crashing on code with undefined behavior
543 EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, Size, Align,
544 llvm::AcquireRelease);
546 case AO_ABI_memory_order_seq_cst:
547 EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, Size, Align,
548 llvm::SequentiallyConsistent);
550 default: // invalid order
551 // We should not ever get here normally, but it's hard to
552 // enforce that in general.
555 if (E->getType()->isVoidType())
556 return RValue::get(0);
557 return convertTempToRValue(OrigDest, E->getType());
560 // Long case, when Order isn't obviously constant.
562 // Create all the relevant BB's
563 llvm::BasicBlock *MonotonicBB = 0, *AcquireBB = 0, *ReleaseBB = 0,
564 *AcqRelBB = 0, *SeqCstBB = 0;
565 MonotonicBB = createBasicBlock("monotonic", CurFn);
567 AcquireBB = createBasicBlock("acquire", CurFn);
569 ReleaseBB = createBasicBlock("release", CurFn);
570 if (!IsLoad && !IsStore)
571 AcqRelBB = createBasicBlock("acqrel", CurFn);
572 SeqCstBB = createBasicBlock("seqcst", CurFn);
573 llvm::BasicBlock *ContBB = createBasicBlock("atomic.continue", CurFn);
575 // Create the switch for the split
576 // MonotonicBB is arbitrarily chosen as the default case; in practice, this
577 // doesn't matter unless someone is crazy enough to use something that
578 // doesn't fold to a constant for the ordering.
579 Order = Builder.CreateIntCast(Order, Builder.getInt32Ty(), false);
580 llvm::SwitchInst *SI = Builder.CreateSwitch(Order, MonotonicBB);
582 // Emit all the different atomics
583 Builder.SetInsertPoint(MonotonicBB);
584 EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, Size, Align,
586 Builder.CreateBr(ContBB);
588 Builder.SetInsertPoint(AcquireBB);
589 EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, Size, Align,
591 Builder.CreateBr(ContBB);
592 SI->addCase(Builder.getInt32(1), AcquireBB);
593 SI->addCase(Builder.getInt32(2), AcquireBB);
596 Builder.SetInsertPoint(ReleaseBB);
597 EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, Size, Align,
599 Builder.CreateBr(ContBB);
600 SI->addCase(Builder.getInt32(3), ReleaseBB);
602 if (!IsLoad && !IsStore) {
603 Builder.SetInsertPoint(AcqRelBB);
604 EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, Size, Align,
605 llvm::AcquireRelease);
606 Builder.CreateBr(ContBB);
607 SI->addCase(Builder.getInt32(4), AcqRelBB);
609 Builder.SetInsertPoint(SeqCstBB);
610 EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, Size, Align,
611 llvm::SequentiallyConsistent);
612 Builder.CreateBr(ContBB);
613 SI->addCase(Builder.getInt32(5), SeqCstBB);
615 // Cleanup and return
616 Builder.SetInsertPoint(ContBB);
617 if (E->getType()->isVoidType())
618 return RValue::get(0);
619 return convertTempToRValue(OrigDest, E->getType());
622 llvm::Value *AtomicInfo::emitCastToAtomicIntPointer(llvm::Value *addr) const {
624 cast<llvm::PointerType>(addr->getType())->getAddressSpace();
625 llvm::IntegerType *ty =
626 llvm::IntegerType::get(CGF.getLLVMContext(), AtomicSizeInBits);
627 return CGF.Builder.CreateBitCast(addr, ty->getPointerTo(addrspace));
630 RValue AtomicInfo::convertTempToRValue(llvm::Value *addr,
631 AggValueSlot resultSlot) const {
632 if (EvaluationKind == TEK_Aggregate) {
633 // Nothing to do if the result is ignored.
634 if (resultSlot.isIgnored()) return resultSlot.asRValue();
636 assert(resultSlot.getAddr() == addr || hasPadding());
638 // In these cases, we should have emitted directly into the result slot.
639 if (!hasPadding() || resultSlot.isValueOfAtomic())
640 return resultSlot.asRValue();
642 // Otherwise, fall into the common path.
645 // Drill into the padding structure if we have one.
647 addr = CGF.Builder.CreateStructGEP(addr, 0);
649 // If we're emitting to an aggregate, copy into the result slot.
650 if (EvaluationKind == TEK_Aggregate) {
651 CGF.EmitAggregateCopy(resultSlot.getAddr(), addr, getValueType(),
652 resultSlot.isVolatile());
653 return resultSlot.asRValue();
656 // Otherwise, just convert the temporary to an r-value using the
657 // normal conversion routine.
658 return CGF.convertTempToRValue(addr, getValueType());
661 /// Emit a load from an l-value of atomic type. Note that the r-value
662 /// we produce is an r-value of the atomic *value* type.
663 RValue CodeGenFunction::EmitAtomicLoad(LValue src, AggValueSlot resultSlot) {
664 AtomicInfo atomics(*this, src);
666 // Check whether we should use a library call.
667 if (atomics.shouldUseLibcall()) {
668 llvm::Value *tempAddr;
669 if (resultSlot.isValueOfAtomic()) {
670 assert(atomics.getEvaluationKind() == TEK_Aggregate);
671 tempAddr = resultSlot.getPaddedAtomicAddr();
672 } else if (!resultSlot.isIgnored() && !atomics.hasPadding()) {
673 assert(atomics.getEvaluationKind() == TEK_Aggregate);
674 tempAddr = resultSlot.getAddr();
676 tempAddr = CreateMemTemp(atomics.getAtomicType(), "atomic-load-temp");
679 // void __atomic_load(size_t size, void *mem, void *return, int order);
681 args.add(RValue::get(atomics.getAtomicSizeValue()),
682 getContext().getSizeType());
683 args.add(RValue::get(EmitCastToVoidPtr(src.getAddress())),
684 getContext().VoidPtrTy);
685 args.add(RValue::get(EmitCastToVoidPtr(tempAddr)),
686 getContext().VoidPtrTy);
687 args.add(RValue::get(llvm::ConstantInt::get(IntTy,
688 AO_ABI_memory_order_seq_cst)),
690 emitAtomicLibcall(*this, "__atomic_load", getContext().VoidTy, args);
692 // Produce the r-value.
693 return atomics.convertTempToRValue(tempAddr, resultSlot);
696 // Okay, we're doing this natively.
697 llvm::Value *addr = atomics.emitCastToAtomicIntPointer(src.getAddress());
698 llvm::LoadInst *load = Builder.CreateLoad(addr, "atomic-load");
699 load->setAtomic(llvm::SequentiallyConsistent);
702 load->setAlignment(src.getAlignment().getQuantity());
703 if (src.isVolatileQualified())
704 load->setVolatile(true);
705 if (src.getTBAAInfo())
706 CGM.DecorateInstruction(load, src.getTBAAInfo());
708 // Okay, turn that back into the original value type.
709 QualType valueType = atomics.getValueType();
710 llvm::Value *result = load;
712 // If we're ignoring an aggregate return, don't do anything.
713 if (atomics.getEvaluationKind() == TEK_Aggregate && resultSlot.isIgnored())
714 return RValue::getAggregate(0, false);
716 // The easiest way to do this this is to go through memory, but we
717 // try not to in some easy cases.
718 if (atomics.getEvaluationKind() == TEK_Scalar && !atomics.hasPadding()) {
719 llvm::Type *resultTy = CGM.getTypes().ConvertTypeForMem(valueType);
720 if (isa<llvm::IntegerType>(resultTy)) {
721 assert(result->getType() == resultTy);
722 result = EmitFromMemory(result, valueType);
723 } else if (isa<llvm::PointerType>(resultTy)) {
724 result = Builder.CreateIntToPtr(result, resultTy);
726 result = Builder.CreateBitCast(result, resultTy);
728 return RValue::get(result);
731 // Create a temporary. This needs to be big enough to hold the
734 bool tempIsVolatile = false;
735 CharUnits tempAlignment;
736 if (atomics.getEvaluationKind() == TEK_Aggregate &&
737 (!atomics.hasPadding() || resultSlot.isValueOfAtomic())) {
738 assert(!resultSlot.isIgnored());
739 if (resultSlot.isValueOfAtomic()) {
740 temp = resultSlot.getPaddedAtomicAddr();
741 tempAlignment = atomics.getAtomicAlignment();
743 temp = resultSlot.getAddr();
744 tempAlignment = atomics.getValueAlignment();
746 tempIsVolatile = resultSlot.isVolatile();
748 temp = CreateMemTemp(atomics.getAtomicType(), "atomic-load-temp");
749 tempAlignment = atomics.getAtomicAlignment();
752 // Slam the integer into the temporary.
753 llvm::Value *castTemp = atomics.emitCastToAtomicIntPointer(temp);
754 Builder.CreateAlignedStore(result, castTemp, tempAlignment.getQuantity())
755 ->setVolatile(tempIsVolatile);
757 return atomics.convertTempToRValue(temp, resultSlot);
762 /// Copy an r-value into memory as part of storing to an atomic type.
763 /// This needs to create a bit-pattern suitable for atomic operations.
764 void AtomicInfo::emitCopyIntoMemory(RValue rvalue, LValue dest) const {
765 // If we have an r-value, the rvalue should be of the atomic type,
766 // which means that the caller is responsible for having zeroed
767 // any padding. Just do an aggregate copy of that type.
768 if (rvalue.isAggregate()) {
769 CGF.EmitAggregateCopy(dest.getAddress(),
770 rvalue.getAggregateAddr(),
772 (rvalue.isVolatileQualified()
773 || dest.isVolatileQualified()),
774 dest.getAlignment());
778 // Okay, otherwise we're copying stuff.
780 // Zero out the buffer if necessary.
781 emitMemSetZeroIfNecessary(dest);
783 // Drill past the padding if present.
784 dest = projectValue(dest);
786 // Okay, store the rvalue in.
787 if (rvalue.isScalar()) {
788 CGF.EmitStoreOfScalar(rvalue.getScalarVal(), dest, /*init*/ true);
790 CGF.EmitStoreOfComplex(rvalue.getComplexVal(), dest, /*init*/ true);
795 /// Materialize an r-value into memory for the purposes of storing it
796 /// to an atomic type.
797 llvm::Value *AtomicInfo::materializeRValue(RValue rvalue) const {
798 // Aggregate r-values are already in memory, and EmitAtomicStore
799 // requires them to be values of the atomic type.
800 if (rvalue.isAggregate())
801 return rvalue.getAggregateAddr();
803 // Otherwise, make a temporary and materialize into it.
804 llvm::Value *temp = CGF.CreateMemTemp(getAtomicType(), "atomic-store-temp");
805 LValue tempLV = CGF.MakeAddrLValue(temp, getAtomicType(), getAtomicAlignment());
806 emitCopyIntoMemory(rvalue, tempLV);
810 /// Emit a store to an l-value of atomic type.
812 /// Note that the r-value is expected to be an r-value *of the atomic
813 /// type*; this means that for aggregate r-values, it should include
814 /// storage for any padding that was necessary.
815 void CodeGenFunction::EmitAtomicStore(RValue rvalue, LValue dest,
817 // If this is an aggregate r-value, it should agree in type except
818 // maybe for address-space qualification.
819 assert(!rvalue.isAggregate() ||
820 rvalue.getAggregateAddr()->getType()->getPointerElementType()
821 == dest.getAddress()->getType()->getPointerElementType());
823 AtomicInfo atomics(*this, dest);
825 // If this is an initialization, just put the value there normally.
827 atomics.emitCopyIntoMemory(rvalue, dest);
831 // Check whether we should use a library call.
832 if (atomics.shouldUseLibcall()) {
833 // Produce a source address.
834 llvm::Value *srcAddr = atomics.materializeRValue(rvalue);
836 // void __atomic_store(size_t size, void *mem, void *val, int order)
838 args.add(RValue::get(atomics.getAtomicSizeValue()),
839 getContext().getSizeType());
840 args.add(RValue::get(EmitCastToVoidPtr(dest.getAddress())),
841 getContext().VoidPtrTy);
842 args.add(RValue::get(EmitCastToVoidPtr(srcAddr)),
843 getContext().VoidPtrTy);
844 args.add(RValue::get(llvm::ConstantInt::get(IntTy,
845 AO_ABI_memory_order_seq_cst)),
847 emitAtomicLibcall(*this, "__atomic_store", getContext().VoidTy, args);
851 // Okay, we're doing this natively.
852 llvm::Value *intValue;
854 // If we've got a scalar value of the right size, try to avoid going
856 if (rvalue.isScalar() && !atomics.hasPadding()) {
857 llvm::Value *value = rvalue.getScalarVal();
858 if (isa<llvm::IntegerType>(value->getType())) {
861 llvm::IntegerType *inputIntTy =
862 llvm::IntegerType::get(getLLVMContext(), atomics.getValueSizeInBits());
863 if (isa<llvm::PointerType>(value->getType())) {
864 intValue = Builder.CreatePtrToInt(value, inputIntTy);
866 intValue = Builder.CreateBitCast(value, inputIntTy);
870 // Otherwise, we need to go through memory.
872 // Put the r-value in memory.
873 llvm::Value *addr = atomics.materializeRValue(rvalue);
875 // Cast the temporary to the atomic int type and pull a value out.
876 addr = atomics.emitCastToAtomicIntPointer(addr);
877 intValue = Builder.CreateAlignedLoad(addr,
878 atomics.getAtomicAlignment().getQuantity());
881 // Do the atomic store.
882 llvm::Value *addr = atomics.emitCastToAtomicIntPointer(dest.getAddress());
883 llvm::StoreInst *store = Builder.CreateStore(intValue, addr);
885 // Initializations don't need to be atomic.
886 if (!isInit) store->setAtomic(llvm::SequentiallyConsistent);
889 store->setAlignment(dest.getAlignment().getQuantity());
890 if (dest.isVolatileQualified())
891 store->setVolatile(true);
892 if (dest.getTBAAInfo())
893 CGM.DecorateInstruction(store, dest.getTBAAInfo());
896 void CodeGenFunction::EmitAtomicInit(Expr *init, LValue dest) {
897 AtomicInfo atomics(*this, dest);
899 switch (atomics.getEvaluationKind()) {
901 llvm::Value *value = EmitScalarExpr(init);
902 atomics.emitCopyIntoMemory(RValue::get(value), dest);
907 ComplexPairTy value = EmitComplexExpr(init);
908 atomics.emitCopyIntoMemory(RValue::getComplex(value), dest);
912 case TEK_Aggregate: {
913 // Memset the buffer first if there's any possibility of
914 // uninitialized internal bits.
915 atomics.emitMemSetZeroIfNecessary(dest);
917 // HACK: whether the initializer actually has an atomic type
918 // doesn't really seem reliable right now.
919 if (!init->getType()->isAtomicType()) {
920 dest = atomics.projectValue(dest);
923 // Evaluate the expression directly into the destination.
924 AggValueSlot slot = AggValueSlot::forLValue(dest,
925 AggValueSlot::IsNotDestructed,
926 AggValueSlot::DoesNotNeedGCBarriers,
927 AggValueSlot::IsNotAliased);
928 EmitAggExpr(init, slot);
932 llvm_unreachable("bad evaluation kind");