• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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