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 "llvm/IR/DataLayout.h"
19 #include "llvm/IR/Intrinsics.h"
20 #include "llvm/IR/Operator.h"
21
22 using namespace clang;
23 using namespace CodeGen;
24
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
33 };
34
35 namespace {
36 class AtomicInfo {
37 CodeGenFunction &CGF;
38 QualType AtomicTy;
39 QualType ValueTy;
40 uint64_t AtomicSizeInBits;
41 uint64_t ValueSizeInBits;
42 CharUnits AtomicAlign;
43 CharUnits ValueAlign;
44 CharUnits LValueAlign;
45 TypeEvaluationKind EvaluationKind;
46 bool UseLibcall;
47 public:
AtomicInfo(CodeGenFunction & CGF,LValue & lvalue)48 AtomicInfo(CodeGenFunction &CGF, LValue &lvalue) : CGF(CGF) {
49 assert(lvalue.isSimple());
50
51 AtomicTy = lvalue.getType();
52 ValueTy = AtomicTy->castAs<AtomicType>()->getValueType();
53 EvaluationKind = CGF.getEvaluationKind(ValueTy);
54
55 ASTContext &C = CGF.getContext();
56
57 uint64_t valueAlignInBits;
58 llvm::tie(ValueSizeInBits, valueAlignInBits) = C.getTypeInfo(ValueTy);
59
60 uint64_t atomicAlignInBits;
61 llvm::tie(AtomicSizeInBits, atomicAlignInBits) = C.getTypeInfo(AtomicTy);
62
63 assert(ValueSizeInBits <= AtomicSizeInBits);
64 assert(valueAlignInBits <= atomicAlignInBits);
65
66 AtomicAlign = C.toCharUnitsFromBits(atomicAlignInBits);
67 ValueAlign = C.toCharUnitsFromBits(valueAlignInBits);
68 if (lvalue.getAlignment().isZero())
69 lvalue.setAlignment(AtomicAlign);
70
71 UseLibcall =
72 (AtomicSizeInBits > uint64_t(C.toBits(lvalue.getAlignment())) ||
73 AtomicSizeInBits > C.getTargetInfo().getMaxAtomicInlineWidth());
74 }
75
getAtomicType() const76 QualType getAtomicType() const { return AtomicTy; }
getValueType() const77 QualType getValueType() const { return ValueTy; }
getAtomicAlignment() const78 CharUnits getAtomicAlignment() const { return AtomicAlign; }
getValueAlignment() const79 CharUnits getValueAlignment() const { return ValueAlign; }
getAtomicSizeInBits() const80 uint64_t getAtomicSizeInBits() const { return AtomicSizeInBits; }
getValueSizeInBits() const81 uint64_t getValueSizeInBits() const { return AtomicSizeInBits; }
getEvaluationKind() const82 TypeEvaluationKind getEvaluationKind() const { return EvaluationKind; }
shouldUseLibcall() const83 bool shouldUseLibcall() const { return UseLibcall; }
84
85 /// Is the atomic size larger than the underlying value type?
86 ///
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.
hasPadding() const91 bool hasPadding() const {
92 return (ValueSizeInBits != AtomicSizeInBits);
93 }
94
95 void emitMemSetZeroIfNecessary(LValue dest) const;
96
getAtomicSizeValue() const97 llvm::Value *getAtomicSizeValue() const {
98 CharUnits size = CGF.getContext().toCharUnitsFromBits(AtomicSizeInBits);
99 return CGF.CGM.getSize(size);
100 }
101
102 /// Cast the given pointer to an integer pointer suitable for
103 /// atomic operations.
104 llvm::Value *emitCastToAtomicIntPointer(llvm::Value *addr) const;
105
106 /// Turn an atomic-layout object into an r-value.
107 RValue convertTempToRValue(llvm::Value *addr,
108 AggValueSlot resultSlot) const;
109
110 /// Copy an atomic r-value into atomic-layout memory.
111 void emitCopyIntoMemory(RValue rvalue, LValue lvalue) const;
112
113 /// Project an l-value down to the value field.
projectValue(LValue lvalue) const114 LValue projectValue(LValue lvalue) const {
115 llvm::Value *addr = lvalue.getAddress();
116 if (hasPadding())
117 addr = CGF.Builder.CreateStructGEP(addr, 0);
118
119 return LValue::MakeAddr(addr, getValueType(), lvalue.getAlignment(),
120 CGF.getContext(), lvalue.getTBAAInfo());
121 }
122
123 /// Materialize an atomic r-value in atomic-layout memory.
124 llvm::Value *materializeRValue(RValue rvalue) const;
125
126 private:
127 bool requiresMemSetZero(llvm::Type *type) const;
128 };
129 }
130
emitAtomicLibcall(CodeGenFunction & CGF,StringRef fnName,QualType resultType,CallArgList & args)131 static RValue emitAtomicLibcall(CodeGenFunction &CGF,
132 StringRef fnName,
133 QualType resultType,
134 CallArgList &args) {
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);
141 }
142
143 /// Does a store of the given IR type modify the full expected width?
isFullSizeType(CodeGenModule & CGM,llvm::Type * type,uint64_t expectedSize)144 static bool isFullSizeType(CodeGenModule &CGM, llvm::Type *type,
145 uint64_t expectedSize) {
146 return (CGM.getDataLayout().getTypeStoreSize(type) * 8 == expectedSize);
147 }
148
149 /// Does the atomic type require memsetting to zero before initialization?
150 ///
151 /// The IR type is provided as a way of making certain queries faster.
requiresMemSetZero(llvm::Type * type) const152 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;
155
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.
160 case TEK_Scalar:
161 return !isFullSizeType(CGF.CGM, type, AtomicSizeInBits);
162 case TEK_Complex:
163 return !isFullSizeType(CGF.CGM, type->getStructElementType(0),
164 AtomicSizeInBits / 2);
165
166 // Just be pessimistic about aggregates.
167 case TEK_Aggregate:
168 return true;
169 }
170 llvm_unreachable("bad evaluation kind");
171 }
172
emitMemSetZeroIfNecessary(LValue dest) const173 void AtomicInfo::emitMemSetZeroIfNecessary(LValue dest) const {
174 llvm::Value *addr = dest.getAddress();
175 if (!requiresMemSetZero(addr->getType()->getPointerElementType()))
176 return;
177
178 CGF.Builder.CreateMemSet(addr, llvm::ConstantInt::get(CGF.Int8Ty, 0),
179 AtomicSizeInBits / 8,
180 dest.getAlignment().getQuantity());
181 }
182
183 static void
EmitAtomicOp(CodeGenFunction & CGF,AtomicExpr * E,llvm::Value * Dest,llvm::Value * Ptr,llvm::Value * Val1,llvm::Value * Val2,uint64_t Size,unsigned Align,llvm::AtomicOrdering Order)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;
189
190 switch (E->getOp()) {
191 case AtomicExpr::AO__c11_atomic_init:
192 llvm_unreachable("Already handled!");
193
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()));
211 return;
212 }
213
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);
223 return;
224 }
225
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());
236 return;
237 }
238
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;
243 break;
244
245 case AtomicExpr::AO__atomic_add_fetch:
246 PostOp = llvm::Instruction::Add;
247 // Fall through.
248 case AtomicExpr::AO__c11_atomic_fetch_add:
249 case AtomicExpr::AO__atomic_fetch_add:
250 Op = llvm::AtomicRMWInst::Add;
251 break;
252
253 case AtomicExpr::AO__atomic_sub_fetch:
254 PostOp = llvm::Instruction::Sub;
255 // Fall through.
256 case AtomicExpr::AO__c11_atomic_fetch_sub:
257 case AtomicExpr::AO__atomic_fetch_sub:
258 Op = llvm::AtomicRMWInst::Sub;
259 break;
260
261 case AtomicExpr::AO__atomic_and_fetch:
262 PostOp = llvm::Instruction::And;
263 // Fall through.
264 case AtomicExpr::AO__c11_atomic_fetch_and:
265 case AtomicExpr::AO__atomic_fetch_and:
266 Op = llvm::AtomicRMWInst::And;
267 break;
268
269 case AtomicExpr::AO__atomic_or_fetch:
270 PostOp = llvm::Instruction::Or;
271 // Fall through.
272 case AtomicExpr::AO__c11_atomic_fetch_or:
273 case AtomicExpr::AO__atomic_fetch_or:
274 Op = llvm::AtomicRMWInst::Or;
275 break;
276
277 case AtomicExpr::AO__atomic_xor_fetch:
278 PostOp = llvm::Instruction::Xor;
279 // Fall through.
280 case AtomicExpr::AO__c11_atomic_fetch_xor:
281 case AtomicExpr::AO__atomic_fetch_xor:
282 Op = llvm::AtomicRMWInst::Xor;
283 break;
284
285 case AtomicExpr::AO__atomic_nand_fetch:
286 PostOp = llvm::Instruction::And;
287 // Fall through.
288 case AtomicExpr::AO__atomic_fetch_nand:
289 Op = llvm::AtomicRMWInst::Nand;
290 break;
291 }
292
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());
298
299 // For __atomic_*_fetch operations, perform the operation again to
300 // determine the value which was written.
301 llvm::Value *Result = RMWI;
302 if (PostOp)
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);
308 }
309
310 // This function emits any expression (scalar, complex, or aggregate)
311 // into a temporary alloca.
312 static llvm::Value *
EmitValToTemp(CodeGenFunction & CGF,Expr * E)313 EmitValToTemp(CodeGenFunction &CGF, Expr *E) {
314 llvm::Value *DeclPtr = CGF.CreateMemTemp(E->getType(), ".atomictmp");
315 CGF.EmitAnyExprToMem(E, DeclPtr, E->getType().getQualifiers(),
316 /*Init*/ true);
317 return DeclPtr;
318 }
319
EmitAtomicExpr(AtomicExpr * E,llvm::Value * Dest)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 getContext().getTargetInfo().getMaxAtomicInlineWidth();
331 bool UseLibcall = (Size != Align ||
332 getContext().toBits(sizeChars) > MaxInlineWidthInBits);
333
334 llvm::Value *Ptr, *Order, *OrderFail = 0, *Val1 = 0, *Val2 = 0;
335 Ptr = EmitScalarExpr(E->getPtr());
336
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);
342 }
343
344 Order = EmitScalarExpr(E->getOrder());
345
346 switch (E->getOp()) {
347 case AtomicExpr::AO__c11_atomic_init:
348 llvm_unreachable("Already handled!");
349
350 case AtomicExpr::AO__c11_atomic_load:
351 case AtomicExpr::AO__atomic_load_n:
352 break;
353
354 case AtomicExpr::AO__atomic_load:
355 Dest = EmitScalarExpr(E->getVal1());
356 break;
357
358 case AtomicExpr::AO__atomic_store:
359 Val1 = EmitScalarExpr(E->getVal1());
360 break;
361
362 case AtomicExpr::AO__atomic_exchange:
363 Val1 = EmitScalarExpr(E->getVal1());
364 Dest = EmitScalarExpr(E->getVal2());
365 break;
366
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());
374 else
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());
380 break;
381
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));
396 break;
397 }
398 // Fall through.
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());
419 break;
420 }
421
422 if (!E->getType()->isVoidType() && !Dest)
423 Dest = CreateMemTemp(E->getType(), ".atomicdst");
424
425 // Use a library call. See: http://gcc.gnu.org/wiki/Atomic/GCCMM/LIbrary .
426 if (UseLibcall) {
427
428 SmallVector<QualType, 5> Params;
429 CallArgList Args;
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);
436
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
442 // and exchange.
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),
456 getContext().IntTy);
457 Order = OrderFail;
458 break;
459 // void __atomic_exchange(size_t size, void *mem, void *val, void *return,
460 // int order)
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);
469 break;
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);
477 break;
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);
485 break;
486 #if 0
487 // These are only defined for 1-16 byte integers. It is not clear what
488 // their semantics would be on anything else...
489 case AtomicExpr::Add: LibCallName = "__atomic_fetch_add_generic"; break;
490 case AtomicExpr::Sub: LibCallName = "__atomic_fetch_sub_generic"; break;
491 case AtomicExpr::And: LibCallName = "__atomic_fetch_and_generic"; break;
492 case AtomicExpr::Or: LibCallName = "__atomic_fetch_or_generic"; break;
493 case AtomicExpr::Xor: LibCallName = "__atomic_fetch_xor_generic"; break;
494 #endif
495 default: return EmitUnsupportedRValue(E, "atomic library call");
496 }
497 // order is always the last parameter
498 Args.add(RValue::get(Order),
499 getContext().IntTy);
500
501 const CGFunctionInfo &FuncInfo =
502 CGM.getTypes().arrangeFreeFunctionCall(RetTy, Args,
503 FunctionType::ExtInfo(), RequiredArgs::All);
504 llvm::FunctionType *FTy = CGM.getTypes().GetFunctionType(FuncInfo);
505 llvm::Constant *Func = CGM.CreateRuntimeFunction(FTy, LibCallName);
506 RValue Res = EmitCall(FuncInfo, Func, ReturnValueSlot(), Args);
507 if (E->isCmpXChg())
508 return Res;
509 if (E->getType()->isVoidType())
510 return RValue::get(0);
511 return convertTempToRValue(Dest, E->getType());
512 }
513
514 bool IsStore = E->getOp() == AtomicExpr::AO__c11_atomic_store ||
515 E->getOp() == AtomicExpr::AO__atomic_store ||
516 E->getOp() == AtomicExpr::AO__atomic_store_n;
517 bool IsLoad = E->getOp() == AtomicExpr::AO__c11_atomic_load ||
518 E->getOp() == AtomicExpr::AO__atomic_load ||
519 E->getOp() == AtomicExpr::AO__atomic_load_n;
520
521 llvm::Type *IPtrTy =
522 llvm::IntegerType::get(getLLVMContext(), Size * 8)->getPointerTo();
523 llvm::Value *OrigDest = Dest;
524 Ptr = Builder.CreateBitCast(Ptr, IPtrTy);
525 if (Val1) Val1 = Builder.CreateBitCast(Val1, IPtrTy);
526 if (Val2) Val2 = Builder.CreateBitCast(Val2, IPtrTy);
527 if (Dest && !E->isCmpXChg()) Dest = Builder.CreateBitCast(Dest, IPtrTy);
528
529 if (isa<llvm::ConstantInt>(Order)) {
530 int ord = cast<llvm::ConstantInt>(Order)->getZExtValue();
531 switch (ord) {
532 case AO_ABI_memory_order_relaxed:
533 EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, Size, Align,
534 llvm::Monotonic);
535 break;
536 case AO_ABI_memory_order_consume:
537 case AO_ABI_memory_order_acquire:
538 if (IsStore)
539 break; // Avoid crashing on code with undefined behavior
540 EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, Size, Align,
541 llvm::Acquire);
542 break;
543 case AO_ABI_memory_order_release:
544 if (IsLoad)
545 break; // Avoid crashing on code with undefined behavior
546 EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, Size, Align,
547 llvm::Release);
548 break;
549 case AO_ABI_memory_order_acq_rel:
550 if (IsLoad || IsStore)
551 break; // Avoid crashing on code with undefined behavior
552 EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, Size, Align,
553 llvm::AcquireRelease);
554 break;
555 case AO_ABI_memory_order_seq_cst:
556 EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, Size, Align,
557 llvm::SequentiallyConsistent);
558 break;
559 default: // invalid order
560 // We should not ever get here normally, but it's hard to
561 // enforce that in general.
562 break;
563 }
564 if (E->getType()->isVoidType())
565 return RValue::get(0);
566 return convertTempToRValue(OrigDest, E->getType());
567 }
568
569 // Long case, when Order isn't obviously constant.
570
571 // Create all the relevant BB's
572 llvm::BasicBlock *MonotonicBB = 0, *AcquireBB = 0, *ReleaseBB = 0,
573 *AcqRelBB = 0, *SeqCstBB = 0;
574 MonotonicBB = createBasicBlock("monotonic", CurFn);
575 if (!IsStore)
576 AcquireBB = createBasicBlock("acquire", CurFn);
577 if (!IsLoad)
578 ReleaseBB = createBasicBlock("release", CurFn);
579 if (!IsLoad && !IsStore)
580 AcqRelBB = createBasicBlock("acqrel", CurFn);
581 SeqCstBB = createBasicBlock("seqcst", CurFn);
582 llvm::BasicBlock *ContBB = createBasicBlock("atomic.continue", CurFn);
583
584 // Create the switch for the split
585 // MonotonicBB is arbitrarily chosen as the default case; in practice, this
586 // doesn't matter unless someone is crazy enough to use something that
587 // doesn't fold to a constant for the ordering.
588 Order = Builder.CreateIntCast(Order, Builder.getInt32Ty(), false);
589 llvm::SwitchInst *SI = Builder.CreateSwitch(Order, MonotonicBB);
590
591 // Emit all the different atomics
592 Builder.SetInsertPoint(MonotonicBB);
593 EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, Size, Align,
594 llvm::Monotonic);
595 Builder.CreateBr(ContBB);
596 if (!IsStore) {
597 Builder.SetInsertPoint(AcquireBB);
598 EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, Size, Align,
599 llvm::Acquire);
600 Builder.CreateBr(ContBB);
601 SI->addCase(Builder.getInt32(1), AcquireBB);
602 SI->addCase(Builder.getInt32(2), AcquireBB);
603 }
604 if (!IsLoad) {
605 Builder.SetInsertPoint(ReleaseBB);
606 EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, Size, Align,
607 llvm::Release);
608 Builder.CreateBr(ContBB);
609 SI->addCase(Builder.getInt32(3), ReleaseBB);
610 }
611 if (!IsLoad && !IsStore) {
612 Builder.SetInsertPoint(AcqRelBB);
613 EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, Size, Align,
614 llvm::AcquireRelease);
615 Builder.CreateBr(ContBB);
616 SI->addCase(Builder.getInt32(4), AcqRelBB);
617 }
618 Builder.SetInsertPoint(SeqCstBB);
619 EmitAtomicOp(*this, E, Dest, Ptr, Val1, Val2, Size, Align,
620 llvm::SequentiallyConsistent);
621 Builder.CreateBr(ContBB);
622 SI->addCase(Builder.getInt32(5), SeqCstBB);
623
624 // Cleanup and return
625 Builder.SetInsertPoint(ContBB);
626 if (E->getType()->isVoidType())
627 return RValue::get(0);
628 return convertTempToRValue(OrigDest, E->getType());
629 }
630
emitCastToAtomicIntPointer(llvm::Value * addr) const631 llvm::Value *AtomicInfo::emitCastToAtomicIntPointer(llvm::Value *addr) const {
632 unsigned addrspace =
633 cast<llvm::PointerType>(addr->getType())->getAddressSpace();
634 llvm::IntegerType *ty =
635 llvm::IntegerType::get(CGF.getLLVMContext(), AtomicSizeInBits);
636 return CGF.Builder.CreateBitCast(addr, ty->getPointerTo(addrspace));
637 }
638
convertTempToRValue(llvm::Value * addr,AggValueSlot resultSlot) const639 RValue AtomicInfo::convertTempToRValue(llvm::Value *addr,
640 AggValueSlot resultSlot) const {
641 if (EvaluationKind == TEK_Aggregate) {
642 // Nothing to do if the result is ignored.
643 if (resultSlot.isIgnored()) return resultSlot.asRValue();
644
645 assert(resultSlot.getAddr() == addr || hasPadding());
646
647 // In these cases, we should have emitted directly into the result slot.
648 if (!hasPadding() || resultSlot.isValueOfAtomic())
649 return resultSlot.asRValue();
650
651 // Otherwise, fall into the common path.
652 }
653
654 // Drill into the padding structure if we have one.
655 if (hasPadding())
656 addr = CGF.Builder.CreateStructGEP(addr, 0);
657
658 // If we're emitting to an aggregate, copy into the result slot.
659 if (EvaluationKind == TEK_Aggregate) {
660 CGF.EmitAggregateCopy(resultSlot.getAddr(), addr, getValueType(),
661 resultSlot.isVolatile());
662 return resultSlot.asRValue();
663 }
664
665 // Otherwise, just convert the temporary to an r-value using the
666 // normal conversion routine.
667 return CGF.convertTempToRValue(addr, getValueType());
668 }
669
670 /// Emit a load from an l-value of atomic type. Note that the r-value
671 /// we produce is an r-value of the atomic *value* type.
EmitAtomicLoad(LValue src,AggValueSlot resultSlot)672 RValue CodeGenFunction::EmitAtomicLoad(LValue src, AggValueSlot resultSlot) {
673 AtomicInfo atomics(*this, src);
674
675 // Check whether we should use a library call.
676 if (atomics.shouldUseLibcall()) {
677 llvm::Value *tempAddr;
678 if (resultSlot.isValueOfAtomic()) {
679 assert(atomics.getEvaluationKind() == TEK_Aggregate);
680 tempAddr = resultSlot.getPaddedAtomicAddr();
681 } else if (!resultSlot.isIgnored() && !atomics.hasPadding()) {
682 assert(atomics.getEvaluationKind() == TEK_Aggregate);
683 tempAddr = resultSlot.getAddr();
684 } else {
685 tempAddr = CreateMemTemp(atomics.getAtomicType(), "atomic-load-temp");
686 }
687
688 // void __atomic_load(size_t size, void *mem, void *return, int order);
689 CallArgList args;
690 args.add(RValue::get(atomics.getAtomicSizeValue()),
691 getContext().getSizeType());
692 args.add(RValue::get(EmitCastToVoidPtr(src.getAddress())),
693 getContext().VoidPtrTy);
694 args.add(RValue::get(EmitCastToVoidPtr(tempAddr)),
695 getContext().VoidPtrTy);
696 args.add(RValue::get(llvm::ConstantInt::get(IntTy,
697 AO_ABI_memory_order_seq_cst)),
698 getContext().IntTy);
699 emitAtomicLibcall(*this, "__atomic_load", getContext().VoidTy, args);
700
701 // Produce the r-value.
702 return atomics.convertTempToRValue(tempAddr, resultSlot);
703 }
704
705 // Okay, we're doing this natively.
706 llvm::Value *addr = atomics.emitCastToAtomicIntPointer(src.getAddress());
707 llvm::LoadInst *load = Builder.CreateLoad(addr, "atomic-load");
708 load->setAtomic(llvm::SequentiallyConsistent);
709
710 // Other decoration.
711 load->setAlignment(src.getAlignment().getQuantity());
712 if (src.isVolatileQualified())
713 load->setVolatile(true);
714 if (src.getTBAAInfo())
715 CGM.DecorateInstruction(load, src.getTBAAInfo());
716
717 // Okay, turn that back into the original value type.
718 QualType valueType = atomics.getValueType();
719 llvm::Value *result = load;
720
721 // If we're ignoring an aggregate return, don't do anything.
722 if (atomics.getEvaluationKind() == TEK_Aggregate && resultSlot.isIgnored())
723 return RValue::getAggregate(0, false);
724
725 // The easiest way to do this this is to go through memory, but we
726 // try not to in some easy cases.
727 if (atomics.getEvaluationKind() == TEK_Scalar && !atomics.hasPadding()) {
728 llvm::Type *resultTy = CGM.getTypes().ConvertTypeForMem(valueType);
729 if (isa<llvm::IntegerType>(resultTy)) {
730 assert(result->getType() == resultTy);
731 result = EmitFromMemory(result, valueType);
732 } else if (isa<llvm::PointerType>(resultTy)) {
733 result = Builder.CreateIntToPtr(result, resultTy);
734 } else {
735 result = Builder.CreateBitCast(result, resultTy);
736 }
737 return RValue::get(result);
738 }
739
740 // Create a temporary. This needs to be big enough to hold the
741 // atomic integer.
742 llvm::Value *temp;
743 bool tempIsVolatile = false;
744 CharUnits tempAlignment;
745 if (atomics.getEvaluationKind() == TEK_Aggregate &&
746 (!atomics.hasPadding() || resultSlot.isValueOfAtomic())) {
747 assert(!resultSlot.isIgnored());
748 if (resultSlot.isValueOfAtomic()) {
749 temp = resultSlot.getPaddedAtomicAddr();
750 tempAlignment = atomics.getAtomicAlignment();
751 } else {
752 temp = resultSlot.getAddr();
753 tempAlignment = atomics.getValueAlignment();
754 }
755 tempIsVolatile = resultSlot.isVolatile();
756 } else {
757 temp = CreateMemTemp(atomics.getAtomicType(), "atomic-load-temp");
758 tempAlignment = atomics.getAtomicAlignment();
759 }
760
761 // Slam the integer into the temporary.
762 llvm::Value *castTemp = atomics.emitCastToAtomicIntPointer(temp);
763 Builder.CreateAlignedStore(result, castTemp, tempAlignment.getQuantity())
764 ->setVolatile(tempIsVolatile);
765
766 return atomics.convertTempToRValue(temp, resultSlot);
767 }
768
769
770
771 /// Copy an r-value into memory as part of storing to an atomic type.
772 /// This needs to create a bit-pattern suitable for atomic operations.
emitCopyIntoMemory(RValue rvalue,LValue dest) const773 void AtomicInfo::emitCopyIntoMemory(RValue rvalue, LValue dest) const {
774 // If we have an r-value, the rvalue should be of the atomic type,
775 // which means that the caller is responsible for having zeroed
776 // any padding. Just do an aggregate copy of that type.
777 if (rvalue.isAggregate()) {
778 CGF.EmitAggregateCopy(dest.getAddress(),
779 rvalue.getAggregateAddr(),
780 getAtomicType(),
781 (rvalue.isVolatileQualified()
782 || dest.isVolatileQualified()),
783 dest.getAlignment());
784 return;
785 }
786
787 // Okay, otherwise we're copying stuff.
788
789 // Zero out the buffer if necessary.
790 emitMemSetZeroIfNecessary(dest);
791
792 // Drill past the padding if present.
793 dest = projectValue(dest);
794
795 // Okay, store the rvalue in.
796 if (rvalue.isScalar()) {
797 CGF.EmitStoreOfScalar(rvalue.getScalarVal(), dest, /*init*/ true);
798 } else {
799 CGF.EmitStoreOfComplex(rvalue.getComplexVal(), dest, /*init*/ true);
800 }
801 }
802
803
804 /// Materialize an r-value into memory for the purposes of storing it
805 /// to an atomic type.
materializeRValue(RValue rvalue) const806 llvm::Value *AtomicInfo::materializeRValue(RValue rvalue) const {
807 // Aggregate r-values are already in memory, and EmitAtomicStore
808 // requires them to be values of the atomic type.
809 if (rvalue.isAggregate())
810 return rvalue.getAggregateAddr();
811
812 // Otherwise, make a temporary and materialize into it.
813 llvm::Value *temp = CGF.CreateMemTemp(getAtomicType(), "atomic-store-temp");
814 LValue tempLV = CGF.MakeAddrLValue(temp, getAtomicType(), getAtomicAlignment());
815 emitCopyIntoMemory(rvalue, tempLV);
816 return temp;
817 }
818
819 /// Emit a store to an l-value of atomic type.
820 ///
821 /// Note that the r-value is expected to be an r-value *of the atomic
822 /// type*; this means that for aggregate r-values, it should include
823 /// storage for any padding that was necessary.
EmitAtomicStore(RValue rvalue,LValue dest,bool isInit)824 void CodeGenFunction::EmitAtomicStore(RValue rvalue, LValue dest,
825 bool isInit) {
826 // If this is an aggregate r-value, it should agree in type except
827 // maybe for address-space qualification.
828 assert(!rvalue.isAggregate() ||
829 rvalue.getAggregateAddr()->getType()->getPointerElementType()
830 == dest.getAddress()->getType()->getPointerElementType());
831
832 AtomicInfo atomics(*this, dest);
833
834 // If this is an initialization, just put the value there normally.
835 if (isInit) {
836 atomics.emitCopyIntoMemory(rvalue, dest);
837 return;
838 }
839
840 // Check whether we should use a library call.
841 if (atomics.shouldUseLibcall()) {
842 // Produce a source address.
843 llvm::Value *srcAddr = atomics.materializeRValue(rvalue);
844
845 // void __atomic_store(size_t size, void *mem, void *val, int order)
846 CallArgList args;
847 args.add(RValue::get(atomics.getAtomicSizeValue()),
848 getContext().getSizeType());
849 args.add(RValue::get(EmitCastToVoidPtr(dest.getAddress())),
850 getContext().VoidPtrTy);
851 args.add(RValue::get(EmitCastToVoidPtr(srcAddr)),
852 getContext().VoidPtrTy);
853 args.add(RValue::get(llvm::ConstantInt::get(IntTy,
854 AO_ABI_memory_order_seq_cst)),
855 getContext().IntTy);
856 emitAtomicLibcall(*this, "__atomic_store", getContext().VoidTy, args);
857 return;
858 }
859
860 // Okay, we're doing this natively.
861 llvm::Value *intValue;
862
863 // If we've got a scalar value of the right size, try to avoid going
864 // through memory.
865 if (rvalue.isScalar() && !atomics.hasPadding()) {
866 llvm::Value *value = rvalue.getScalarVal();
867 if (isa<llvm::IntegerType>(value->getType())) {
868 intValue = value;
869 } else {
870 llvm::IntegerType *inputIntTy =
871 llvm::IntegerType::get(getLLVMContext(), atomics.getValueSizeInBits());
872 if (isa<llvm::PointerType>(value->getType())) {
873 intValue = Builder.CreatePtrToInt(value, inputIntTy);
874 } else {
875 intValue = Builder.CreateBitCast(value, inputIntTy);
876 }
877 }
878
879 // Otherwise, we need to go through memory.
880 } else {
881 // Put the r-value in memory.
882 llvm::Value *addr = atomics.materializeRValue(rvalue);
883
884 // Cast the temporary to the atomic int type and pull a value out.
885 addr = atomics.emitCastToAtomicIntPointer(addr);
886 intValue = Builder.CreateAlignedLoad(addr,
887 atomics.getAtomicAlignment().getQuantity());
888 }
889
890 // Do the atomic store.
891 llvm::Value *addr = atomics.emitCastToAtomicIntPointer(dest.getAddress());
892 llvm::StoreInst *store = Builder.CreateStore(intValue, addr);
893
894 // Initializations don't need to be atomic.
895 if (!isInit) store->setAtomic(llvm::SequentiallyConsistent);
896
897 // Other decoration.
898 store->setAlignment(dest.getAlignment().getQuantity());
899 if (dest.isVolatileQualified())
900 store->setVolatile(true);
901 if (dest.getTBAAInfo())
902 CGM.DecorateInstruction(store, dest.getTBAAInfo());
903 }
904
EmitAtomicInit(Expr * init,LValue dest)905 void CodeGenFunction::EmitAtomicInit(Expr *init, LValue dest) {
906 AtomicInfo atomics(*this, dest);
907
908 switch (atomics.getEvaluationKind()) {
909 case TEK_Scalar: {
910 llvm::Value *value = EmitScalarExpr(init);
911 atomics.emitCopyIntoMemory(RValue::get(value), dest);
912 return;
913 }
914
915 case TEK_Complex: {
916 ComplexPairTy value = EmitComplexExpr(init);
917 atomics.emitCopyIntoMemory(RValue::getComplex(value), dest);
918 return;
919 }
920
921 case TEK_Aggregate: {
922 // Memset the buffer first if there's any possibility of
923 // uninitialized internal bits.
924 atomics.emitMemSetZeroIfNecessary(dest);
925
926 // HACK: whether the initializer actually has an atomic type
927 // doesn't really seem reliable right now.
928 if (!init->getType()->isAtomicType()) {
929 dest = atomics.projectValue(dest);
930 }
931
932 // Evaluate the expression directly into the destination.
933 AggValueSlot slot = AggValueSlot::forLValue(dest,
934 AggValueSlot::IsNotDestructed,
935 AggValueSlot::DoesNotNeedGCBarriers,
936 AggValueSlot::IsNotAliased);
937 EmitAggExpr(init, slot);
938 return;
939 }
940 }
941 llvm_unreachable("bad evaluation kind");
942 }
943