21#include "llvm/ADT/DenseMap.h"
22#include "llvm/IR/DataLayout.h"
23#include "llvm/IR/Intrinsics.h"
35 CharUnits AtomicAlign;
42 AtomicInfo(CodeGenFunction &CGF, LValue &lvalue)
43 : CGF(CGF), AtomicSizeInBits(0), ValueSizeInBits(0),
45 assert(!lvalue.isGlobalReg());
47 if (lvalue.isSimple()) {
48 AtomicTy = lvalue.getType();
49 if (
auto *ATy = AtomicTy->
getAs<AtomicType>())
50 ValueTy = ATy->getValueType();
57 TypeInfo ValueTI =
C.getTypeInfo(ValueTy);
58 ValueSizeInBits = ValueTI.
Width;
59 ValueAlignInBits = ValueTI.
Align;
61 TypeInfo AtomicTI =
C.getTypeInfo(AtomicTy);
62 AtomicSizeInBits = AtomicTI.
Width;
63 AtomicAlignInBits = AtomicTI.
Align;
65 assert(ValueSizeInBits <= AtomicSizeInBits);
66 assert(ValueAlignInBits <= AtomicAlignInBits);
68 AtomicAlign =
C.toCharUnitsFromBits(AtomicAlignInBits);
69 ValueAlign =
C.toCharUnitsFromBits(ValueAlignInBits);
70 if (lvalue.getAlignment().isZero())
71 lvalue.setAlignment(AtomicAlign);
74 }
else if (lvalue.isBitField()) {
75 ValueTy = lvalue.getType();
76 ValueSizeInBits =
C.getTypeSize(ValueTy);
77 auto &OrigBFI = lvalue.getBitFieldInfo();
78 auto Offset = OrigBFI.Offset %
C.toBits(lvalue.getAlignment());
79 AtomicSizeInBits =
C.toBits(
80 C.toCharUnitsFromBits(Offset + OrigBFI.Size +
C.getCharWidth() - 1)
81 .alignTo(lvalue.getAlignment()));
82 llvm::Value *BitFieldPtr = lvalue.getRawBitFieldPointer(CGF);
84 (
C.toCharUnitsFromBits(OrigBFI.Offset) / lvalue.getAlignment()) *
85 lvalue.getAlignment();
86 llvm::Value *StoragePtr = CGF.
Builder.CreateConstGEP1_64(
87 CGF.
Int8Ty, BitFieldPtr, OffsetInChars.getQuantity());
94 llvm::Type *StorageTy = CGF.
Builder.getIntNTy(AtomicSizeInBits);
95 LVal = LValue::MakeBitfield(
96 Address(StoragePtr, StorageTy, lvalue.getAlignment()), BFI,
97 lvalue.getType(), lvalue.getBaseInfo(), lvalue.getTBAAInfo());
98 AtomicTy =
C.getIntTypeForBitwidth(AtomicSizeInBits, OrigBFI.IsSigned);
102 C.toCharUnitsFromBits(AtomicSizeInBits).getQuantity());
103 AtomicTy =
C.getConstantArrayType(
C.CharTy, Size,
nullptr,
104 ArraySizeModifier::Normal,
107 AtomicAlign = ValueAlign = lvalue.getAlignment();
108 }
else if (lvalue.isVectorElt()) {
109 ValueTy = lvalue.getType()->
castAs<VectorType>()->getElementType();
110 ValueSizeInBits =
C.getTypeSize(ValueTy);
111 AtomicTy = lvalue.getType();
112 AtomicSizeInBits =
C.getTypeSize(AtomicTy);
113 AtomicAlign = ValueAlign = lvalue.getAlignment();
116 assert(lvalue.isExtVectorElt());
117 ValueTy = lvalue.getType();
118 ValueSizeInBits =
C.getTypeSize(ValueTy);
121 lvalue.getExtVectorAddress().getElementType())
123 AtomicSizeInBits =
C.getTypeSize(AtomicTy);
124 AtomicAlign = ValueAlign = lvalue.getAlignment();
127 UseLibcall = !
C.getTargetInfo().hasBuiltinAtomic(
128 AtomicSizeInBits,
C.toBits(lvalue.getAlignment()));
131 QualType getAtomicType()
const {
return AtomicTy; }
132 QualType getValueType()
const {
return ValueTy; }
133 CharUnits getAtomicAlignment()
const {
return AtomicAlign; }
134 uint64_t getAtomicSizeInBits()
const {
return AtomicSizeInBits; }
135 uint64_t getValueSizeInBits()
const {
return ValueSizeInBits; }
137 bool shouldUseLibcall()
const {
return UseLibcall; }
138 const LValue &getAtomicLValue()
const {
return LVal; }
139 llvm::Value *getAtomicPointer()
const {
141 return LVal.emitRawPointer(CGF);
142 else if (LVal.isBitField())
143 return LVal.getRawBitFieldPointer(CGF);
144 else if (LVal.isVectorElt())
145 return LVal.getRawVectorPointer(CGF);
146 assert(LVal.isExtVectorElt());
147 return LVal.getRawExtVectorPointer(CGF);
149 Address getAtomicAddress()
const {
152 ElTy = LVal.getAddress().getElementType();
153 else if (LVal.isBitField())
154 ElTy = LVal.getBitFieldAddress().getElementType();
155 else if (LVal.isVectorElt())
156 ElTy = LVal.getVectorAddress().getElementType();
158 ElTy = LVal.getExtVectorAddress().getElementType();
159 return Address(getAtomicPointer(), ElTy, getAtomicAlignment());
162 Address getAtomicAddressAsAtomicIntPointer()
const {
163 return castToAtomicIntPointer(getAtomicAddress());
172 bool hasPadding()
const {
173 return (ValueSizeInBits != AtomicSizeInBits);
176 bool emitMemSetZeroIfNecessary()
const;
178 llvm::Value *getAtomicSizeValue()
const {
185 Address castToAtomicIntPointer(Address
Addr)
const;
190 Address convertToAtomicIntPointer(Address
Addr)
const;
193 RValue convertAtomicTempToRValue(Address addr, AggValueSlot resultSlot,
194 SourceLocation loc,
bool AsValue)
const;
196 llvm::Value *getScalarRValValueOrNull(RValue RVal)
const;
199 llvm::Value *convertRValueToInt(RValue RVal,
bool CmpXchg =
false)
const;
201 RValue ConvertToValueOrAtomic(llvm::Value *IntVal, AggValueSlot ResultSlot,
202 SourceLocation Loc,
bool AsValue,
203 bool CmpXchg =
false)
const;
206 void emitCopyIntoMemory(RValue rvalue)
const;
209 LValue projectValue()
const {
210 assert(LVal.isSimple());
211 Address addr = getAtomicAddress();
215 return LValue::MakeAddr(addr, getValueType(), CGF.
getContext(),
216 LVal.getBaseInfo(), LVal.getTBAAInfo());
221 RValue EmitAtomicLoad(AggValueSlot ResultSlot, SourceLocation Loc,
222 bool AsValue, llvm::AtomicOrdering AO,
233 std::pair<RValue, llvm::Value *>
234 EmitAtomicCompareExchange(RValue Expected, RValue Desired,
236 llvm::AtomicOrdering::SequentiallyConsistent,
238 llvm::AtomicOrdering::SequentiallyConsistent,
239 bool IsWeak =
false);
244 void EmitAtomicUpdate(llvm::AtomicOrdering AO,
245 const llvm::function_ref<RValue(RValue)> &UpdateOp,
249 void EmitAtomicUpdate(llvm::AtomicOrdering AO, RValue UpdateRVal,
253 Address materializeRValue(RValue rvalue)
const;
256 Address CreateTempAlloca()
const;
258 bool requiresMemSetZero(llvm::Type *
type)
const;
262 void EmitAtomicLoadLibcall(llvm::Value *AddForLoaded,
263 llvm::AtomicOrdering AO,
bool IsVolatile);
265 llvm::Value *EmitAtomicLoadOp(llvm::AtomicOrdering AO,
bool IsVolatile,
266 bool CmpXchg =
false);
268 llvm::Value *EmitAtomicCompareExchangeLibcall(
269 llvm::Value *ExpectedAddr, llvm::Value *DesiredAddr,
271 llvm::AtomicOrdering::SequentiallyConsistent,
273 llvm::AtomicOrdering::SequentiallyConsistent);
275 std::pair<llvm::Value *, llvm::Value *> EmitAtomicCompareExchangeOp(
276 llvm::Value *ExpectedVal, llvm::Value *DesiredVal,
278 llvm::AtomicOrdering::SequentiallyConsistent,
280 llvm::AtomicOrdering::SequentiallyConsistent,
281 bool IsWeak =
false);
284 EmitAtomicUpdateLibcall(llvm::AtomicOrdering AO,
285 const llvm::function_ref<RValue(RValue)> &UpdateOp,
288 void EmitAtomicUpdateOp(llvm::AtomicOrdering AO,
289 const llvm::function_ref<RValue(RValue)> &UpdateOp,
292 void EmitAtomicUpdateLibcall(llvm::AtomicOrdering AO, RValue UpdateRVal,
295 void EmitAtomicUpdateOp(llvm::AtomicOrdering AO, RValue UpdateRal,
300Address AtomicInfo::CreateTempAlloca()
const {
303 QualType TmpTy = (LVal.isBitField() && ValueSizeInBits > AtomicSizeInBits)
309 if (LVal.isBitField())
311 TempAlloca, getAtomicAddress().
getType(),
312 getAtomicAddress().getElementType());
324 fnAttrB.addAttribute(llvm::Attribute::NoUnwind);
325 fnAttrB.addAttribute(llvm::Attribute::WillReturn);
326 llvm::AttributeList fnAttrs = llvm::AttributeList::get(
327 CGF.
getLLVMContext(), llvm::AttributeList::FunctionIndex, fnAttrB);
329 llvm::FunctionCallee fn =
337 uint64_t expectedSize) {
344bool AtomicInfo::requiresMemSetZero(llvm::Type *
type)
const {
346 if (hasPadding())
return true;
349 switch (getEvaluationKind()) {
356 AtomicSizeInBits / 2);
362 llvm_unreachable(
"bad evaluation kind");
365bool AtomicInfo::emitMemSetZeroIfNecessary()
const {
366 assert(LVal.isSimple());
367 Address addr = LVal.getAddress();
374 LVal.getAlignment().getAsAlign());
381 uint64_t Size, llvm::AtomicOrdering SuccessOrder,
382 llvm::AtomicOrdering FailureOrder,
383 llvm::SyncScope::ID
Scope) {
391 Pair->setWeak(IsWeak);
396 llvm::Value *Old = CGF.
Builder.CreateExtractValue(Pair, 0);
397 llvm::Value *
Cmp = CGF.
Builder.CreateExtractValue(Pair, 1);
401 llvm::BasicBlock *StoreExpectedBB =
406 llvm::BasicBlock *ContinueBB =
411 CGF.
Builder.CreateCondBr(
Cmp, ContinueBB, StoreExpectedBB);
413 CGF.
Builder.SetInsertPoint(StoreExpectedBB);
417 uint64_t ExpectedSizeInBytes = DL.getTypeStoreSize(
ExpectedType);
419 if (ExpectedSizeInBytes == Size) {
425 llvm::Type *OldType = Old->getType();
441 CGF.
Builder.CreateBr(ContinueBB);
443 CGF.
Builder.SetInsertPoint(ContinueBB);
454 llvm::Value *FailureOrderVal, uint64_t Size,
455 llvm::AtomicOrdering SuccessOrder, llvm::SyncScope::ID
Scope) {
456 llvm::AtomicOrdering FailureOrder;
457 if (llvm::ConstantInt *FO = dyn_cast<llvm::ConstantInt>(FailureOrderVal)) {
458 auto FOS = FO->getSExtValue();
459 if (!llvm::isValidAtomicOrderingCABI(FOS))
460 FailureOrder = llvm::AtomicOrdering::Monotonic;
462 switch ((llvm::AtomicOrderingCABI)FOS) {
463 case llvm::AtomicOrderingCABI::relaxed:
466 case llvm::AtomicOrderingCABI::release:
467 case llvm::AtomicOrderingCABI::acq_rel:
468 FailureOrder = llvm::AtomicOrdering::Monotonic;
470 case llvm::AtomicOrderingCABI::consume:
471 case llvm::AtomicOrderingCABI::acquire:
472 FailureOrder = llvm::AtomicOrdering::Acquire;
474 case llvm::AtomicOrderingCABI::seq_cst:
475 FailureOrder = llvm::AtomicOrdering::SequentiallyConsistent;
483 Size, SuccessOrder, FailureOrder,
Scope);
496 llvm::SwitchInst *SI = CGF.
Builder.CreateSwitch(FailureOrderVal, MonotonicBB);
498 SI->addCase(CGF.
Builder.getInt32((
int)llvm::AtomicOrderingCABI::consume),
500 SI->addCase(CGF.
Builder.getInt32((
int)llvm::AtomicOrderingCABI::acquire),
502 SI->addCase(CGF.
Builder.getInt32((
int)llvm::AtomicOrderingCABI::seq_cst),
506 CGF.
Builder.SetInsertPoint(MonotonicBB);
508 SuccessOrder, llvm::AtomicOrdering::Monotonic,
Scope);
511 CGF.
Builder.SetInsertPoint(AcquireBB);
513 SuccessOrder, llvm::AtomicOrdering::Acquire,
Scope);
516 CGF.
Builder.SetInsertPoint(SeqCstBB);
518 SuccessOrder, llvm::AtomicOrdering::SequentiallyConsistent,
522 CGF.
Builder.SetInsertPoint(ContBB);
532 const bool IsFP = OldVal->getType()->isFloatingPointTy();
535 llvm::Intrinsic::ID IID = (Op == AtomicExpr::AO__atomic_max_fetch ||
536 Op == AtomicExpr::AO__scoped_atomic_max_fetch)
537 ? llvm::Intrinsic::maxnum
538 : llvm::Intrinsic::minnum;
539 return Builder.CreateBinaryIntrinsic(IID, OldVal, RHS, llvm::FMFSource(),
543 llvm::CmpInst::Predicate Pred;
546 llvm_unreachable(
"Unexpected min/max operation");
547 case AtomicExpr::AO__atomic_max_fetch:
548 case AtomicExpr::AO__scoped_atomic_max_fetch:
549 Pred = IsSigned ? llvm::CmpInst::ICMP_SGT : llvm::CmpInst::ICMP_UGT;
551 case AtomicExpr::AO__atomic_min_fetch:
552 case AtomicExpr::AO__scoped_atomic_min_fetch:
553 Pred = IsSigned ? llvm::CmpInst::ICMP_SLT : llvm::CmpInst::ICMP_ULT;
556 llvm::Value *
Cmp = Builder.CreateICmp(Pred, OldVal, RHS,
"tst");
557 return Builder.CreateSelect(
Cmp, OldVal, RHS,
"newval");
562 Address ExpectedResult, llvm::Value *IsWeak,
563 llvm::Value *FailureOrder, uint64_t Size,
564 llvm::AtomicOrdering Order,
565 llvm::SyncScope::ID
Scope) {
566 llvm::AtomicRMWInst::BinOp Op = llvm::AtomicRMWInst::Add;
567 bool PostOpMinMax =
false;
570 switch (E->
getOp()) {
571 case AtomicExpr::AO__c11_atomic_init:
572 case AtomicExpr::AO__opencl_atomic_init:
573 llvm_unreachable(
"Already handled!");
575 case AtomicExpr::AO__c11_atomic_compare_exchange_strong:
576 case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
577 case AtomicExpr::AO__opencl_atomic_compare_exchange_strong:
579 ExpectedResult, FailureOrder, Size, Order,
582 case AtomicExpr::AO__c11_atomic_compare_exchange_weak:
583 case AtomicExpr::AO__opencl_atomic_compare_exchange_weak:
584 case AtomicExpr::AO__hip_atomic_compare_exchange_weak:
586 ExpectedResult, FailureOrder, Size, Order,
589 case AtomicExpr::AO__atomic_compare_exchange:
590 case AtomicExpr::AO__atomic_compare_exchange_n:
591 case AtomicExpr::AO__scoped_atomic_compare_exchange:
592 case AtomicExpr::AO__scoped_atomic_compare_exchange_n: {
593 if (llvm::ConstantInt *IsWeakC = dyn_cast<llvm::ConstantInt>(IsWeak)) {
595 Val1, Val2, ExpectedResult, FailureOrder,
599 llvm::BasicBlock *StrongBB =
602 llvm::BasicBlock *ContBB =
605 llvm::SwitchInst *SI = CGF.
Builder.CreateSwitch(IsWeak, WeakBB);
606 SI->addCase(CGF.
Builder.getInt1(
false), StrongBB);
608 CGF.
Builder.SetInsertPoint(StrongBB);
610 ExpectedResult, FailureOrder, Size, Order,
614 CGF.
Builder.SetInsertPoint(WeakBB);
616 ExpectedResult, FailureOrder, Size, Order,
620 CGF.
Builder.SetInsertPoint(ContBB);
624 case AtomicExpr::AO__c11_atomic_load:
625 case AtomicExpr::AO__opencl_atomic_load:
626 case AtomicExpr::AO__hip_atomic_load:
627 case AtomicExpr::AO__atomic_load_n:
628 case AtomicExpr::AO__atomic_load:
629 case AtomicExpr::AO__scoped_atomic_load_n:
630 case AtomicExpr::AO__scoped_atomic_load: {
632 Load->setAtomic(Order,
Scope);
641 case AtomicExpr::AO__c11_atomic_store:
642 case AtomicExpr::AO__opencl_atomic_store:
643 case AtomicExpr::AO__hip_atomic_store:
644 case AtomicExpr::AO__atomic_store:
645 case AtomicExpr::AO__atomic_store_n:
646 case AtomicExpr::AO__scoped_atomic_store:
647 case AtomicExpr::AO__scoped_atomic_store_n: {
650 Store->setAtomic(Order,
Scope);
657 case AtomicExpr::AO__c11_atomic_exchange:
658 case AtomicExpr::AO__hip_atomic_exchange:
659 case AtomicExpr::AO__opencl_atomic_exchange:
660 case AtomicExpr::AO__atomic_exchange_n:
661 case AtomicExpr::AO__atomic_exchange:
662 case AtomicExpr::AO__scoped_atomic_exchange_n:
663 case AtomicExpr::AO__scoped_atomic_exchange:
664 Op = llvm::AtomicRMWInst::Xchg;
667 case AtomicExpr::AO__atomic_add_fetch:
668 case AtomicExpr::AO__scoped_atomic_add_fetch:
670 : llvm::Instruction::Add;
672 case AtomicExpr::AO__c11_atomic_fetch_add:
673 case AtomicExpr::AO__hip_atomic_fetch_add:
674 case AtomicExpr::AO__opencl_atomic_fetch_add:
675 case AtomicExpr::AO__atomic_fetch_add:
676 case AtomicExpr::AO__scoped_atomic_fetch_add:
678 : llvm::AtomicRMWInst::Add;
681 case AtomicExpr::AO__atomic_sub_fetch:
682 case AtomicExpr::AO__scoped_atomic_sub_fetch:
684 : llvm::Instruction::Sub;
686 case AtomicExpr::AO__c11_atomic_fetch_sub:
687 case AtomicExpr::AO__hip_atomic_fetch_sub:
688 case AtomicExpr::AO__opencl_atomic_fetch_sub:
689 case AtomicExpr::AO__atomic_fetch_sub:
690 case AtomicExpr::AO__scoped_atomic_fetch_sub:
692 : llvm::AtomicRMWInst::Sub;
695 case AtomicExpr::AO__atomic_min_fetch:
696 case AtomicExpr::AO__scoped_atomic_min_fetch:
699 case AtomicExpr::AO__c11_atomic_fetch_min:
700 case AtomicExpr::AO__hip_atomic_fetch_min:
701 case AtomicExpr::AO__opencl_atomic_fetch_min:
702 case AtomicExpr::AO__atomic_fetch_min:
703 case AtomicExpr::AO__scoped_atomic_fetch_min:
705 ? llvm::AtomicRMWInst::FMin
707 ? llvm::AtomicRMWInst::Min
708 : llvm::AtomicRMWInst::UMin);
711 case AtomicExpr::AO__atomic_fetch_fminimum:
712 case AtomicExpr::AO__scoped_atomic_fetch_fminimum:
714 "fminimum operations only support floating-point types");
715 Op = llvm::AtomicRMWInst::FMinimum;
718 case AtomicExpr::AO__atomic_fetch_fminimum_num:
719 case AtomicExpr::AO__scoped_atomic_fetch_fminimum_num:
721 "fminimum_num operations only support floating-point types");
722 Op = llvm::AtomicRMWInst::FMinimumNum;
725 case AtomicExpr::AO__atomic_max_fetch:
726 case AtomicExpr::AO__scoped_atomic_max_fetch:
729 case AtomicExpr::AO__c11_atomic_fetch_max:
730 case AtomicExpr::AO__hip_atomic_fetch_max:
731 case AtomicExpr::AO__opencl_atomic_fetch_max:
732 case AtomicExpr::AO__atomic_fetch_max:
733 case AtomicExpr::AO__scoped_atomic_fetch_max:
735 ? llvm::AtomicRMWInst::FMax
737 ? llvm::AtomicRMWInst::Max
738 : llvm::AtomicRMWInst::UMax);
741 case AtomicExpr::AO__atomic_fetch_fmaximum:
742 case AtomicExpr::AO__scoped_atomic_fetch_fmaximum:
744 "fmaximum operations only support floating-point types");
745 Op = llvm::AtomicRMWInst::FMaximum;
748 case AtomicExpr::AO__atomic_fetch_fmaximum_num:
749 case AtomicExpr::AO__scoped_atomic_fetch_fmaximum_num:
751 "fmaximum_num operations only support floating-point types");
752 Op = llvm::AtomicRMWInst::FMaximumNum;
755 case AtomicExpr::AO__atomic_and_fetch:
756 case AtomicExpr::AO__scoped_atomic_and_fetch:
757 PostOp = llvm::Instruction::And;
759 case AtomicExpr::AO__c11_atomic_fetch_and:
760 case AtomicExpr::AO__hip_atomic_fetch_and:
761 case AtomicExpr::AO__opencl_atomic_fetch_and:
762 case AtomicExpr::AO__atomic_fetch_and:
763 case AtomicExpr::AO__scoped_atomic_fetch_and:
764 Op = llvm::AtomicRMWInst::And;
767 case AtomicExpr::AO__atomic_or_fetch:
768 case AtomicExpr::AO__scoped_atomic_or_fetch:
769 PostOp = llvm::Instruction::Or;
771 case AtomicExpr::AO__c11_atomic_fetch_or:
772 case AtomicExpr::AO__hip_atomic_fetch_or:
773 case AtomicExpr::AO__opencl_atomic_fetch_or:
774 case AtomicExpr::AO__atomic_fetch_or:
775 case AtomicExpr::AO__scoped_atomic_fetch_or:
776 Op = llvm::AtomicRMWInst::Or;
779 case AtomicExpr::AO__atomic_xor_fetch:
780 case AtomicExpr::AO__scoped_atomic_xor_fetch:
781 PostOp = llvm::Instruction::Xor;
783 case AtomicExpr::AO__c11_atomic_fetch_xor:
784 case AtomicExpr::AO__hip_atomic_fetch_xor:
785 case AtomicExpr::AO__opencl_atomic_fetch_xor:
786 case AtomicExpr::AO__atomic_fetch_xor:
787 case AtomicExpr::AO__scoped_atomic_fetch_xor:
788 Op = llvm::AtomicRMWInst::Xor;
791 case AtomicExpr::AO__atomic_nand_fetch:
792 case AtomicExpr::AO__scoped_atomic_nand_fetch:
793 PostOp = llvm::Instruction::And;
795 case AtomicExpr::AO__c11_atomic_fetch_nand:
796 case AtomicExpr::AO__atomic_fetch_nand:
797 case AtomicExpr::AO__scoped_atomic_fetch_nand:
798 Op = llvm::AtomicRMWInst::Nand;
801 case AtomicExpr::AO__atomic_fetch_uinc:
802 case AtomicExpr::AO__scoped_atomic_fetch_uinc:
803 Op = llvm::AtomicRMWInst::UIncWrap;
805 case AtomicExpr::AO__atomic_fetch_udec:
806 case AtomicExpr::AO__scoped_atomic_fetch_udec:
807 Op = llvm::AtomicRMWInst::UDecWrap;
810 case AtomicExpr::AO__atomic_test_and_set: {
811 llvm::AtomicRMWInst *RMWI =
822 case AtomicExpr::AO__atomic_clear: {
823 llvm::StoreInst *Store =
825 Store->setAtomic(Order,
Scope);
834 llvm::AtomicRMWInst *RMWI =
840 llvm::Value *
Result = RMWI;
846 Result = CGF.
Builder.CreateBinOp((llvm::Instruction::BinaryOps)PostOp, RMWI,
848 if (E->
getOp() == AtomicExpr::AO__atomic_nand_fetch ||
849 E->
getOp() == AtomicExpr::AO__scoped_atomic_nand_fetch)
871 if (ValTy->isFloatingPointTy())
872 return ValTy->isX86_FP80Ty() || CmpXchg;
873 return !ValTy->isIntegerTy() && !ValTy->isPointerTy();
878 Address OriginalVal1, llvm::Value *IsWeak,
879 llvm::Value *FailureOrder, uint64_t Size,
880 llvm::AtomicOrdering Order, llvm::Value *
Scope) {
881 auto ScopeModel =
Expr->getScopeModel();
886 llvm::SyncScope::ID SS;
896 SS = llvm::SyncScope::System;
898 FailureOrder, Size, Order, SS);
903 if (
auto SC = dyn_cast<llvm::ConstantInt>(
Scope)) {
908 FailureOrder, Size, Order, SCID);
914 auto Scopes = ScopeModel->getRuntimeValues();
915 llvm::DenseMap<unsigned, llvm::BasicBlock *> BB;
916 for (
auto S : Scopes)
919 llvm::BasicBlock *ContBB =
922 auto *SC = Builder.CreateIntCast(
Scope, Builder.getInt32Ty(),
false);
925 auto FallBack = ScopeModel->getFallBackValue();
926 llvm::SwitchInst *SI = Builder.CreateSwitch(SC, BB[FallBack]);
927 for (
auto S : Scopes) {
930 SI->addCase(Builder.getInt32(S), B);
932 Builder.SetInsertPoint(B);
934 FailureOrder, Size, Order,
938 Builder.CreateBr(ContBB);
941 Builder.SetInsertPoint(ContBB);
950 MemTy = AT->getValueType();
951 llvm::Value *IsWeak =
nullptr, *OrderFail =
nullptr;
958 if (E->
getOp() == AtomicExpr::AO__c11_atomic_init ||
959 E->
getOp() == AtomicExpr::AO__opencl_atomic_init) {
965 auto TInfo =
getContext().getTypeInfoInChars(AtomicTy);
966 uint64_t Size = TInfo.Width.getQuantity();
967 unsigned MaxInlineWidthInBits =
getTarget().getMaxAtomicInlineWidth();
970 getContext().toCharUnitsFromBits(MaxInlineWidthInBits);
973 bool Oversized =
getContext().toBits(TInfo.Width) > MaxInlineWidthInBits;
976 << (int)TInfo.Width.getQuantity()
981 << (int)TInfo.Width.getQuantity() << (int)MaxInlineWidth.
getQuantity();
988 switch (E->
getOp()) {
989 case AtomicExpr::AO__c11_atomic_init:
990 case AtomicExpr::AO__opencl_atomic_init:
991 llvm_unreachable(
"Already handled above with EmitAtomicInit!");
993 case AtomicExpr::AO__atomic_load_n:
994 case AtomicExpr::AO__scoped_atomic_load_n:
995 case AtomicExpr::AO__c11_atomic_load:
996 case AtomicExpr::AO__opencl_atomic_load:
997 case AtomicExpr::AO__hip_atomic_load:
998 case AtomicExpr::AO__atomic_test_and_set:
999 case AtomicExpr::AO__atomic_clear:
1002 case AtomicExpr::AO__atomic_load:
1003 case AtomicExpr::AO__scoped_atomic_load:
1007 case AtomicExpr::AO__atomic_store:
1008 case AtomicExpr::AO__scoped_atomic_store:
1012 case AtomicExpr::AO__atomic_exchange:
1013 case AtomicExpr::AO__scoped_atomic_exchange:
1018 case AtomicExpr::AO__atomic_compare_exchange:
1019 case AtomicExpr::AO__atomic_compare_exchange_n:
1020 case AtomicExpr::AO__c11_atomic_compare_exchange_weak:
1021 case AtomicExpr::AO__c11_atomic_compare_exchange_strong:
1022 case AtomicExpr::AO__hip_atomic_compare_exchange_weak:
1023 case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
1024 case AtomicExpr::AO__opencl_atomic_compare_exchange_weak:
1025 case AtomicExpr::AO__opencl_atomic_compare_exchange_strong:
1026 case AtomicExpr::AO__scoped_atomic_compare_exchange:
1027 case AtomicExpr::AO__scoped_atomic_compare_exchange_n:
1029 if (E->
getOp() == AtomicExpr::AO__atomic_compare_exchange ||
1030 E->
getOp() == AtomicExpr::AO__scoped_atomic_compare_exchange)
1035 if (E->
getOp() == AtomicExpr::AO__atomic_compare_exchange_n ||
1036 E->
getOp() == AtomicExpr::AO__atomic_compare_exchange ||
1037 E->
getOp() == AtomicExpr::AO__scoped_atomic_compare_exchange_n ||
1038 E->
getOp() == AtomicExpr::AO__scoped_atomic_compare_exchange)
1042 case AtomicExpr::AO__c11_atomic_fetch_add:
1043 case AtomicExpr::AO__c11_atomic_fetch_sub:
1044 case AtomicExpr::AO__hip_atomic_fetch_add:
1045 case AtomicExpr::AO__hip_atomic_fetch_sub:
1046 case AtomicExpr::AO__opencl_atomic_fetch_add:
1047 case AtomicExpr::AO__opencl_atomic_fetch_sub:
1057 Val1Scalar =
Builder.CreateMul(Val1Scalar,
CGM.getSize(PointeeIncAmt));
1064 case AtomicExpr::AO__atomic_fetch_add:
1065 case AtomicExpr::AO__atomic_fetch_max:
1066 case AtomicExpr::AO__atomic_fetch_min:
1067 case AtomicExpr::AO__atomic_fetch_sub:
1068 case AtomicExpr::AO__atomic_add_fetch:
1069 case AtomicExpr::AO__atomic_max_fetch:
1070 case AtomicExpr::AO__atomic_min_fetch:
1071 case AtomicExpr::AO__atomic_sub_fetch:
1072 case AtomicExpr::AO__c11_atomic_fetch_max:
1073 case AtomicExpr::AO__c11_atomic_fetch_min:
1074 case AtomicExpr::AO__opencl_atomic_fetch_max:
1075 case AtomicExpr::AO__opencl_atomic_fetch_min:
1076 case AtomicExpr::AO__hip_atomic_fetch_max:
1077 case AtomicExpr::AO__hip_atomic_fetch_min:
1078 case AtomicExpr::AO__scoped_atomic_fetch_add:
1079 case AtomicExpr::AO__scoped_atomic_fetch_max:
1080 case AtomicExpr::AO__scoped_atomic_fetch_min:
1081 case AtomicExpr::AO__scoped_atomic_fetch_sub:
1082 case AtomicExpr::AO__scoped_atomic_fetch_fminimum:
1083 case AtomicExpr::AO__scoped_atomic_fetch_fmaximum:
1084 case AtomicExpr::AO__scoped_atomic_fetch_fminimum_num:
1085 case AtomicExpr::AO__scoped_atomic_fetch_fmaximum_num:
1086 case AtomicExpr::AO__scoped_atomic_add_fetch:
1087 case AtomicExpr::AO__scoped_atomic_max_fetch:
1088 case AtomicExpr::AO__scoped_atomic_min_fetch:
1089 case AtomicExpr::AO__scoped_atomic_sub_fetch:
1092 case AtomicExpr::AO__atomic_fetch_and:
1093 case AtomicExpr::AO__atomic_fetch_nand:
1094 case AtomicExpr::AO__atomic_fetch_or:
1095 case AtomicExpr::AO__atomic_fetch_xor:
1096 case AtomicExpr::AO__atomic_fetch_uinc:
1097 case AtomicExpr::AO__atomic_fetch_udec:
1098 case AtomicExpr::AO__atomic_and_fetch:
1099 case AtomicExpr::AO__atomic_nand_fetch:
1100 case AtomicExpr::AO__atomic_or_fetch:
1101 case AtomicExpr::AO__atomic_xor_fetch:
1102 case AtomicExpr::AO__atomic_store_n:
1103 case AtomicExpr::AO__atomic_exchange_n:
1104 case AtomicExpr::AO__c11_atomic_fetch_and:
1105 case AtomicExpr::AO__c11_atomic_fetch_nand:
1106 case AtomicExpr::AO__c11_atomic_fetch_or:
1107 case AtomicExpr::AO__c11_atomic_fetch_xor:
1108 case AtomicExpr::AO__c11_atomic_store:
1109 case AtomicExpr::AO__c11_atomic_exchange:
1110 case AtomicExpr::AO__hip_atomic_fetch_and:
1111 case AtomicExpr::AO__hip_atomic_fetch_or:
1112 case AtomicExpr::AO__hip_atomic_fetch_xor:
1113 case AtomicExpr::AO__hip_atomic_store:
1114 case AtomicExpr::AO__hip_atomic_exchange:
1115 case AtomicExpr::AO__opencl_atomic_fetch_and:
1116 case AtomicExpr::AO__opencl_atomic_fetch_or:
1117 case AtomicExpr::AO__opencl_atomic_fetch_xor:
1118 case AtomicExpr::AO__opencl_atomic_store:
1119 case AtomicExpr::AO__opencl_atomic_exchange:
1120 case AtomicExpr::AO__scoped_atomic_fetch_and:
1121 case AtomicExpr::AO__scoped_atomic_fetch_nand:
1122 case AtomicExpr::AO__scoped_atomic_fetch_or:
1123 case AtomicExpr::AO__scoped_atomic_fetch_xor:
1124 case AtomicExpr::AO__scoped_atomic_and_fetch:
1125 case AtomicExpr::AO__scoped_atomic_nand_fetch:
1126 case AtomicExpr::AO__scoped_atomic_or_fetch:
1127 case AtomicExpr::AO__scoped_atomic_xor_fetch:
1128 case AtomicExpr::AO__scoped_atomic_store_n:
1129 case AtomicExpr::AO__scoped_atomic_exchange_n:
1130 case AtomicExpr::AO__scoped_atomic_fetch_uinc:
1131 case AtomicExpr::AO__scoped_atomic_fetch_udec:
1132 case AtomicExpr::AO__atomic_fetch_fminimum:
1133 case AtomicExpr::AO__atomic_fetch_fmaximum:
1134 case AtomicExpr::AO__atomic_fetch_fminimum_num:
1135 case AtomicExpr::AO__atomic_fetch_fmaximum_num:
1141 bool ShouldCastToIntPtrTy =
1148 AtomicInfo Atomics(*
this, AtomicVal);
1151 if (ShouldCastToIntPtrTy) {
1152 Ptr = Atomics.castToAtomicIntPointer(Ptr);
1154 Val1 = Atomics.convertToAtomicIntPointer(Val1);
1156 Val2 = Atomics.convertToAtomicIntPointer(Val2);
1159 if (ShouldCastToIntPtrTy)
1160 Dest = Atomics.castToAtomicIntPointer(Dest);
1164 Dest = Atomics.CreateTempAlloca();
1165 if (ShouldCastToIntPtrTy)
1166 Dest = Atomics.castToAtomicIntPointer(Dest);
1169 bool PowerOf2Size = (Size & (Size - 1)) == 0;
1170 bool UseLibcall = !PowerOf2Size || (Size > 16);
1190 auto CastToGenericAddrSpace = [&](llvm::Value *
V,
QualType PT) {
1197 auto *DestType = llvm::PointerType::get(
getLLVMContext(), DestAS);
1207 std::string LibCallName;
1209 bool HaveRetTy =
false;
1210 switch (E->
getOp()) {
1211 case AtomicExpr::AO__c11_atomic_init:
1212 case AtomicExpr::AO__opencl_atomic_init:
1213 llvm_unreachable(
"Already handled!");
1220 case AtomicExpr::AO__atomic_compare_exchange:
1221 case AtomicExpr::AO__atomic_compare_exchange_n:
1222 case AtomicExpr::AO__c11_atomic_compare_exchange_weak:
1223 case AtomicExpr::AO__c11_atomic_compare_exchange_strong:
1224 case AtomicExpr::AO__hip_atomic_compare_exchange_weak:
1225 case AtomicExpr::AO__hip_atomic_compare_exchange_strong:
1226 case AtomicExpr::AO__opencl_atomic_compare_exchange_weak:
1227 case AtomicExpr::AO__opencl_atomic_compare_exchange_strong:
1228 case AtomicExpr::AO__scoped_atomic_compare_exchange:
1229 case AtomicExpr::AO__scoped_atomic_compare_exchange_n:
1230 LibCallName =
"__atomic_compare_exchange";
1244 case AtomicExpr::AO__atomic_exchange:
1245 case AtomicExpr::AO__atomic_exchange_n:
1246 case AtomicExpr::AO__c11_atomic_exchange:
1247 case AtomicExpr::AO__hip_atomic_exchange:
1248 case AtomicExpr::AO__opencl_atomic_exchange:
1249 case AtomicExpr::AO__scoped_atomic_exchange:
1250 case AtomicExpr::AO__scoped_atomic_exchange_n:
1251 LibCallName =
"__atomic_exchange";
1257 case AtomicExpr::AO__atomic_store:
1258 case AtomicExpr::AO__atomic_store_n:
1259 case AtomicExpr::AO__c11_atomic_store:
1260 case AtomicExpr::AO__hip_atomic_store:
1261 case AtomicExpr::AO__opencl_atomic_store:
1262 case AtomicExpr::AO__scoped_atomic_store:
1263 case AtomicExpr::AO__scoped_atomic_store_n:
1264 LibCallName =
"__atomic_store";
1272 case AtomicExpr::AO__atomic_load:
1273 case AtomicExpr::AO__atomic_load_n:
1274 case AtomicExpr::AO__c11_atomic_load:
1275 case AtomicExpr::AO__hip_atomic_load:
1276 case AtomicExpr::AO__opencl_atomic_load:
1277 case AtomicExpr::AO__scoped_atomic_load:
1278 case AtomicExpr::AO__scoped_atomic_load_n:
1279 LibCallName =
"__atomic_load";
1281 case AtomicExpr::AO__atomic_add_fetch:
1282 case AtomicExpr::AO__scoped_atomic_add_fetch:
1283 case AtomicExpr::AO__atomic_fetch_add:
1284 case AtomicExpr::AO__c11_atomic_fetch_add:
1285 case AtomicExpr::AO__hip_atomic_fetch_add:
1286 case AtomicExpr::AO__opencl_atomic_fetch_add:
1287 case AtomicExpr::AO__scoped_atomic_fetch_add:
1288 case AtomicExpr::AO__atomic_and_fetch:
1289 case AtomicExpr::AO__scoped_atomic_and_fetch:
1290 case AtomicExpr::AO__atomic_fetch_and:
1291 case AtomicExpr::AO__c11_atomic_fetch_and:
1292 case AtomicExpr::AO__hip_atomic_fetch_and:
1293 case AtomicExpr::AO__opencl_atomic_fetch_and:
1294 case AtomicExpr::AO__scoped_atomic_fetch_and:
1295 case AtomicExpr::AO__atomic_or_fetch:
1296 case AtomicExpr::AO__scoped_atomic_or_fetch:
1297 case AtomicExpr::AO__atomic_fetch_or:
1298 case AtomicExpr::AO__c11_atomic_fetch_or:
1299 case AtomicExpr::AO__hip_atomic_fetch_or:
1300 case AtomicExpr::AO__opencl_atomic_fetch_or:
1301 case AtomicExpr::AO__scoped_atomic_fetch_or:
1302 case AtomicExpr::AO__atomic_sub_fetch:
1303 case AtomicExpr::AO__scoped_atomic_sub_fetch:
1304 case AtomicExpr::AO__atomic_fetch_sub:
1305 case AtomicExpr::AO__c11_atomic_fetch_sub:
1306 case AtomicExpr::AO__hip_atomic_fetch_sub:
1307 case AtomicExpr::AO__opencl_atomic_fetch_sub:
1308 case AtomicExpr::AO__scoped_atomic_fetch_sub:
1309 case AtomicExpr::AO__atomic_xor_fetch:
1310 case AtomicExpr::AO__scoped_atomic_xor_fetch:
1311 case AtomicExpr::AO__atomic_fetch_xor:
1312 case AtomicExpr::AO__c11_atomic_fetch_xor:
1313 case AtomicExpr::AO__hip_atomic_fetch_xor:
1314 case AtomicExpr::AO__opencl_atomic_fetch_xor:
1315 case AtomicExpr::AO__scoped_atomic_fetch_xor:
1316 case AtomicExpr::AO__atomic_nand_fetch:
1317 case AtomicExpr::AO__atomic_fetch_nand:
1318 case AtomicExpr::AO__c11_atomic_fetch_nand:
1319 case AtomicExpr::AO__scoped_atomic_fetch_nand:
1320 case AtomicExpr::AO__scoped_atomic_nand_fetch:
1321 case AtomicExpr::AO__atomic_min_fetch:
1322 case AtomicExpr::AO__atomic_fetch_min:
1323 case AtomicExpr::AO__c11_atomic_fetch_min:
1324 case AtomicExpr::AO__hip_atomic_fetch_min:
1325 case AtomicExpr::AO__opencl_atomic_fetch_min:
1326 case AtomicExpr::AO__scoped_atomic_fetch_min:
1327 case AtomicExpr::AO__scoped_atomic_min_fetch:
1328 case AtomicExpr::AO__atomic_max_fetch:
1329 case AtomicExpr::AO__atomic_fetch_max:
1330 case AtomicExpr::AO__c11_atomic_fetch_max:
1331 case AtomicExpr::AO__hip_atomic_fetch_max:
1332 case AtomicExpr::AO__opencl_atomic_fetch_max:
1333 case AtomicExpr::AO__scoped_atomic_fetch_max:
1334 case AtomicExpr::AO__scoped_atomic_max_fetch:
1335 case AtomicExpr::AO__atomic_fetch_fminimum:
1336 case AtomicExpr::AO__atomic_fetch_fmaximum:
1337 case AtomicExpr::AO__atomic_fetch_fminimum_num:
1338 case AtomicExpr::AO__atomic_fetch_fmaximum_num:
1339 case AtomicExpr::AO__scoped_atomic_fetch_fminimum:
1340 case AtomicExpr::AO__scoped_atomic_fetch_fmaximum:
1341 case AtomicExpr::AO__scoped_atomic_fetch_fminimum_num:
1342 case AtomicExpr::AO__scoped_atomic_fetch_fmaximum_num:
1343 case AtomicExpr::AO__scoped_atomic_fetch_uinc:
1344 case AtomicExpr::AO__scoped_atomic_fetch_udec:
1345 case AtomicExpr::AO__atomic_test_and_set:
1346 case AtomicExpr::AO__atomic_clear:
1347 case AtomicExpr::AO__atomic_fetch_uinc:
1348 case AtomicExpr::AO__atomic_fetch_udec:
1349 llvm_unreachable(
"Integral atomic operations always become atomicrmw!");
1354 std::string(
"__opencl") + StringRef(LibCallName).drop_front(1).str();
1382 bool IsStore = E->
getOp() == AtomicExpr::AO__c11_atomic_store ||
1383 E->
getOp() == AtomicExpr::AO__opencl_atomic_store ||
1384 E->
getOp() == AtomicExpr::AO__hip_atomic_store ||
1385 E->
getOp() == AtomicExpr::AO__atomic_store ||
1386 E->
getOp() == AtomicExpr::AO__atomic_store_n ||
1387 E->
getOp() == AtomicExpr::AO__scoped_atomic_store ||
1388 E->
getOp() == AtomicExpr::AO__scoped_atomic_store_n ||
1389 E->
getOp() == AtomicExpr::AO__atomic_clear;
1390 bool IsLoad = E->
getOp() == AtomicExpr::AO__c11_atomic_load ||
1391 E->
getOp() == AtomicExpr::AO__opencl_atomic_load ||
1392 E->
getOp() == AtomicExpr::AO__hip_atomic_load ||
1393 E->
getOp() == AtomicExpr::AO__atomic_load ||
1394 E->
getOp() == AtomicExpr::AO__atomic_load_n ||
1395 E->
getOp() == AtomicExpr::AO__scoped_atomic_load ||
1396 E->
getOp() == AtomicExpr::AO__scoped_atomic_load_n;
1402 if (llvm::isValidAtomicOrderingCABI(ord))
1403 switch ((llvm::AtomicOrderingCABI)ord) {
1404 case llvm::AtomicOrderingCABI::relaxed:
1405 EmitAtomicOp(*
this, E, Dest, Ptr, Val1, Val2, OriginalVal1, IsWeak,
1406 OrderFail, Size, llvm::AtomicOrdering::Monotonic,
Scope);
1408 case llvm::AtomicOrderingCABI::consume:
1409 case llvm::AtomicOrderingCABI::acquire:
1412 EmitAtomicOp(*
this, E, Dest, Ptr, Val1, Val2, OriginalVal1, IsWeak,
1413 OrderFail, Size, llvm::AtomicOrdering::Acquire,
Scope);
1415 case llvm::AtomicOrderingCABI::release:
1418 EmitAtomicOp(*
this, E, Dest, Ptr, Val1, Val2, OriginalVal1, IsWeak,
1419 OrderFail, Size, llvm::AtomicOrdering::Release,
Scope);
1421 case llvm::AtomicOrderingCABI::acq_rel:
1422 if (IsLoad || IsStore)
1424 EmitAtomicOp(*
this, E, Dest, Ptr, Val1, Val2, OriginalVal1, IsWeak,
1425 OrderFail, Size, llvm::AtomicOrdering::AcquireRelease,
1428 case llvm::AtomicOrderingCABI::seq_cst:
1429 EmitAtomicOp(*
this, E, Dest, Ptr, Val1, Val2, OriginalVal1, IsWeak,
1431 llvm::AtomicOrdering::SequentiallyConsistent,
Scope);
1444 llvm::BasicBlock *MonotonicBB =
nullptr, *AcquireBB =
nullptr,
1445 *ReleaseBB =
nullptr, *AcqRelBB =
nullptr,
1446 *SeqCstBB =
nullptr;
1452 if (!IsLoad && !IsStore)
1461 Order =
Builder.CreateIntCast(Order,
Builder.getInt32Ty(),
false);
1462 llvm::SwitchInst *SI =
Builder.CreateSwitch(Order, MonotonicBB);
1465 Builder.SetInsertPoint(MonotonicBB);
1466 EmitAtomicOp(*
this, E, Dest, Ptr, Val1, Val2, OriginalVal1, IsWeak, OrderFail,
1467 Size, llvm::AtomicOrdering::Monotonic,
Scope);
1470 Builder.SetInsertPoint(AcquireBB);
1471 EmitAtomicOp(*
this, E, Dest, Ptr, Val1, Val2, OriginalVal1, IsWeak,
1472 OrderFail, Size, llvm::AtomicOrdering::Acquire,
Scope);
1474 SI->addCase(
Builder.getInt32((
int)llvm::AtomicOrderingCABI::consume),
1476 SI->addCase(
Builder.getInt32((
int)llvm::AtomicOrderingCABI::acquire),
1480 Builder.SetInsertPoint(ReleaseBB);
1481 EmitAtomicOp(*
this, E, Dest, Ptr, Val1, Val2, OriginalVal1, IsWeak,
1482 OrderFail, Size, llvm::AtomicOrdering::Release,
Scope);
1484 SI->addCase(
Builder.getInt32((
int)llvm::AtomicOrderingCABI::release),
1487 if (!IsLoad && !IsStore) {
1488 Builder.SetInsertPoint(AcqRelBB);
1489 EmitAtomicOp(*
this, E, Dest, Ptr, Val1, Val2, OriginalVal1, IsWeak,
1490 OrderFail, Size, llvm::AtomicOrdering::AcquireRelease,
Scope);
1492 SI->addCase(
Builder.getInt32((
int)llvm::AtomicOrderingCABI::acq_rel),
1495 Builder.SetInsertPoint(SeqCstBB);
1496 EmitAtomicOp(*
this, E, Dest, Ptr, Val1, Val2, OriginalVal1, IsWeak, OrderFail,
1497 Size, llvm::AtomicOrdering::SequentiallyConsistent,
Scope);
1499 SI->addCase(
Builder.getInt32((
int)llvm::AtomicOrderingCABI::seq_cst),
1503 Builder.SetInsertPoint(ContBB);
1507 assert(Atomics.getValueSizeInBits() <= Atomics.getAtomicSizeInBits());
1513 llvm::IntegerType *ty =
1519 llvm::Type *Ty =
Addr.getElementType();
1521 if (SourceSizeInBits != AtomicSizeInBits) {
1522 Address Tmp = CreateTempAlloca();
1529 std::min(AtomicSizeInBits, SourceSizeInBits) / 8);
1533 return castToAtomicIntPointer(
Addr);
1536RValue AtomicInfo::convertAtomicTempToRValue(Address addr,
1537 AggValueSlot resultSlot,
1539 bool asValue)
const {
1540 if (LVal.isSimple()) {
1555 if (LVal.isBitField())
1557 LValue::MakeBitfield(addr, LVal.getBitFieldInfo(), LVal.getType(),
1558 LVal.getBaseInfo(), TBAAAccessInfo()), loc);
1559 if (LVal.isVectorElt())
1561 LValue::MakeVectorElt(addr, LVal.getVectorIdx(), LVal.getType(),
1562 LVal.getBaseInfo(), TBAAAccessInfo()), loc);
1563 assert(LVal.isExtVectorElt());
1565 addr, LVal.getExtVectorElts(), LVal.getType(),
1566 LVal.getBaseInfo(), TBAAAccessInfo()));
1569RValue AtomicInfo::ConvertToValueOrAtomic(llvm::Value *Val,
1570 AggValueSlot ResultSlot,
1571 SourceLocation Loc,
bool AsValue,
1572 bool CmpXchg)
const {
1574 assert((Val->getType()->isIntegerTy() || Val->getType()->isPointerTy() ||
1575 Val->getType()->isIEEELikeFPTy()) &&
1576 "Expected integer, pointer or floating point value when converting "
1579 (((!LVal.isBitField() ||
1580 LVal.getBitFieldInfo().Size == ValueSizeInBits) &&
1583 auto *ValTy = AsValue
1585 : getAtomicAddress().getElementType();
1587 assert((!ValTy->isIntegerTy() || Val->getType() == ValTy) &&
1588 "Different integer types.");
1591 if (llvm::CastInst::isBitCastable(Val->getType(), ValTy))
1598 bool TempIsVolatile =
false;
1604 Temp = CreateTempAlloca();
1608 Address CastTemp = castToAtomicIntPointer(Temp);
1611 return convertAtomicTempToRValue(Temp, ResultSlot, Loc, AsValue);
1614void AtomicInfo::EmitAtomicLoadLibcall(llvm::Value *AddForLoaded,
1615 llvm::AtomicOrdering AO,
bool) {
1627llvm::Value *AtomicInfo::EmitAtomicLoadOp(llvm::AtomicOrdering AO,
1628 bool IsVolatile,
bool CmpXchg) {
1632 Addr = castToAtomicIntPointer(
Addr);
1634 Load->setAtomic(AO);
1639 Load->setVolatile(
true);
1648 if (!
CGM.getLangOpts().MSVolatile)
return false;
1649 AtomicInfo AI(*
this, LV);
1652 bool AtomicIsInline = !AI.shouldUseLibcall();
1657 return IsVolatile && AtomicIsInline;
1662 llvm::AtomicOrdering AO;
1665 AO = llvm::AtomicOrdering::SequentiallyConsistent;
1667 AO = llvm::AtomicOrdering::Acquire;
1674 bool AsValue, llvm::AtomicOrdering AO,
1677 if (shouldUseLibcall()) {
1679 if (LVal.isSimple() && !ResultSlot.
isIgnored()) {
1683 TempAddr = CreateTempAlloca();
1685 EmitAtomicLoadLibcall(TempAddr.
emitRawPointer(CGF), AO, IsVolatile);
1689 return convertAtomicTempToRValue(TempAddr, ResultSlot, Loc, AsValue);
1693 auto *Load = EmitAtomicLoadOp(AO, IsVolatile);
1701 return ConvertToValueOrAtomic(Load, ResultSlot, Loc, AsValue);
1707 llvm::AtomicOrdering AO,
bool IsVolatile,
1709 AtomicInfo Atomics(*
this, src);
1710 return Atomics.EmitAtomicLoad(resultSlot, loc,
true, AO,
1716void AtomicInfo::emitCopyIntoMemory(
RValue rvalue)
const {
1717 assert(LVal.isSimple());
1726 LVal.isVolatileQualified();
1735 emitMemSetZeroIfNecessary();
1738 LValue TempLVal = projectValue();
1751Address AtomicInfo::materializeRValue(RValue rvalue)
const {
1758 LValue TempLV = CGF.
MakeAddrLValue(CreateTempAlloca(), getAtomicType());
1759 AtomicInfo Atomics(CGF, TempLV);
1760 Atomics.emitCopyIntoMemory(rvalue);
1761 return TempLV.getAddress();
1764llvm::Value *AtomicInfo::getScalarRValValueOrNull(RValue RVal)
const {
1765 if (RVal.
isScalar() && (!hasPadding() || !LVal.isSimple()))
1770llvm::Value *AtomicInfo::convertRValueToInt(RValue RVal,
bool CmpXchg)
const {
1773 if (llvm::Value *
Value = getScalarRValValueOrNull(RVal)) {
1777 llvm::IntegerType *InputIntTy = llvm::IntegerType::get(
1779 LVal.isSimple() ? getValueSizeInBits() : getAtomicSizeInBits());
1780 if (llvm::BitCastInst::isBitCastable(
Value->getType(), InputIntTy))
1789 Addr = castToAtomicIntPointer(
Addr);
1793std::pair<llvm::Value *, llvm::Value *> AtomicInfo::EmitAtomicCompareExchangeOp(
1794 llvm::Value *ExpectedVal, llvm::Value *DesiredVal,
1795 llvm::AtomicOrdering
Success, llvm::AtomicOrdering
Failure,
bool IsWeak) {
1797 Address Addr = getAtomicAddressAsAtomicIntPointer();
1801 Inst->setVolatile(LVal.isVolatileQualified());
1802 Inst->setWeak(IsWeak);
1806 auto *PreviousVal = CGF.
Builder.CreateExtractValue(Inst, 0);
1807 auto *SuccessFailureVal = CGF.
Builder.CreateExtractValue(Inst, 1);
1808 return std::make_pair(PreviousVal, SuccessFailureVal);
1812AtomicInfo::EmitAtomicCompareExchangeLibcall(llvm::Value *ExpectedAddr,
1813 llvm::Value *DesiredAddr,
1815 llvm::AtomicOrdering
Failure) {
1824 llvm::ConstantInt::get(CGF.
IntTy, (
int)llvm::toCABI(
Success))),
1827 llvm::ConstantInt::get(CGF.
IntTy, (
int)llvm::toCABI(
Failure))),
1832 return SuccessFailureRVal.getScalarVal();
1835std::pair<RValue, llvm::Value *> AtomicInfo::EmitAtomicCompareExchange(
1836 RValue Expected, RValue Desired, llvm::AtomicOrdering
Success,
1837 llvm::AtomicOrdering
Failure,
bool IsWeak) {
1839 if (shouldUseLibcall()) {
1841 Address ExpectedAddr = materializeRValue(Expected);
1843 llvm::Value *DesiredPtr = materializeRValue(Desired).emitRawPointer(CGF);
1844 auto *Res = EmitAtomicCompareExchangeLibcall(ExpectedPtr, DesiredPtr,
1846 return std::make_pair(
1848 SourceLocation(),
false),
1854 auto *ExpectedVal = convertRValueToInt(Expected,
true);
1855 auto *DesiredVal = convertRValueToInt(Desired,
true);
1856 auto Res = EmitAtomicCompareExchangeOp(ExpectedVal, DesiredVal,
Success,
1858 return std::make_pair(
1860 SourceLocation(),
false,
1870 LValue AtomicLVal = Atomics.getAtomicLValue();
1872 if (AtomicLVal.isSimple()) {
1874 DesiredLVal = CGF.
MakeAddrLValue(DesiredAddr, AtomicLVal.getType());
1877 Address Ptr = Atomics.materializeRValue(OldRVal);
1879 if (AtomicLVal.isBitField()) {
1881 LValue::MakeBitfield(Ptr, AtomicLVal.getBitFieldInfo(),
1882 AtomicLVal.getType(),
1883 AtomicLVal.getBaseInfo(),
1884 AtomicLVal.getTBAAInfo());
1886 LValue::MakeBitfield(DesiredAddr, AtomicLVal.getBitFieldInfo(),
1887 AtomicLVal.getType(), AtomicLVal.getBaseInfo(),
1888 AtomicLVal.getTBAAInfo());
1889 }
else if (AtomicLVal.isVectorElt()) {
1890 UpdateLVal = LValue::MakeVectorElt(Ptr, AtomicLVal.getVectorIdx(),
1891 AtomicLVal.getType(),
1892 AtomicLVal.getBaseInfo(),
1893 AtomicLVal.getTBAAInfo());
1894 DesiredLVal = LValue::MakeVectorElt(
1895 DesiredAddr, AtomicLVal.getVectorIdx(), AtomicLVal.getType(),
1896 AtomicLVal.getBaseInfo(), AtomicLVal.getTBAAInfo());
1898 assert(AtomicLVal.isExtVectorElt());
1899 UpdateLVal = LValue::MakeExtVectorElt(Ptr, AtomicLVal.getExtVectorElts(),
1900 AtomicLVal.getType(),
1901 AtomicLVal.getBaseInfo(),
1902 AtomicLVal.getTBAAInfo());
1903 DesiredLVal = LValue::MakeExtVectorElt(
1904 DesiredAddr, AtomicLVal.getExtVectorElts(), AtomicLVal.getType(),
1905 AtomicLVal.getBaseInfo(), AtomicLVal.getTBAAInfo());
1910 RValue NewRVal = UpdateOp(UpRVal);
1920void AtomicInfo::EmitAtomicUpdateLibcall(
1921 llvm::AtomicOrdering AO,
const llvm::function_ref<RValue(RValue)> &UpdateOp,
1923 auto Failure = llvm::AtomicCmpXchgInst::getStrongestFailureOrdering(AO);
1925 Address ExpectedAddr = CreateTempAlloca();
1927 EmitAtomicLoadLibcall(ExpectedAddr.
emitRawPointer(CGF), AO, IsVolatile);
1931 Address DesiredAddr = CreateTempAlloca();
1932 if ((LVal.isBitField() && BFI.
Size != ValueSizeInBits) ||
1933 requiresMemSetZero(getAtomicAddress().getElementType())) {
1937 auto OldRVal = convertAtomicTempToRValue(ExpectedAddr,
1939 SourceLocation(),
false);
1944 EmitAtomicCompareExchangeLibcall(ExpectedPtr, DesiredPtr, AO,
Failure);
1945 CGF.
Builder.CreateCondBr(Res, ExitBB, ContBB);
1949void AtomicInfo::EmitAtomicUpdateOp(
1950 llvm::AtomicOrdering AO,
const llvm::function_ref<RValue(RValue)> &UpdateOp,
1952 auto Failure = llvm::AtomicCmpXchgInst::getStrongestFailureOrdering(AO);
1955 auto *OldVal = EmitAtomicLoadOp(
Failure, IsVolatile,
true);
1959 auto *CurBB = CGF.
Builder.GetInsertBlock();
1961 llvm::PHINode *PHI = CGF.
Builder.CreatePHI(OldVal->getType(),
1963 PHI->addIncoming(OldVal, CurBB);
1964 Address NewAtomicAddr = CreateTempAlloca();
1967 ? castToAtomicIntPointer(NewAtomicAddr)
1970 if ((LVal.isBitField() && BFI.
Size != ValueSizeInBits) ||
1971 requiresMemSetZero(getAtomicAddress().getElementType())) {
1975 SourceLocation(),
false,
1980 auto Res = EmitAtomicCompareExchangeOp(PHI, DesiredVal, AO,
Failure);
1981 PHI->addIncoming(Res.first, CGF.
Builder.GetInsertBlock());
1982 CGF.
Builder.CreateCondBr(Res.second, ExitBB, ContBB);
1988 LValue AtomicLVal = Atomics.getAtomicLValue();
1991 if (AtomicLVal.isBitField()) {
1993 LValue::MakeBitfield(DesiredAddr, AtomicLVal.getBitFieldInfo(),
1994 AtomicLVal.getType(), AtomicLVal.getBaseInfo(),
1995 AtomicLVal.getTBAAInfo());
1996 }
else if (AtomicLVal.isVectorElt()) {
1998 LValue::MakeVectorElt(DesiredAddr, AtomicLVal.getVectorIdx(),
1999 AtomicLVal.getType(), AtomicLVal.getBaseInfo(),
2000 AtomicLVal.getTBAAInfo());
2002 assert(AtomicLVal.isExtVectorElt());
2003 DesiredLVal = LValue::MakeExtVectorElt(
2004 DesiredAddr, AtomicLVal.getExtVectorElts(), AtomicLVal.getType(),
2005 AtomicLVal.getBaseInfo(), AtomicLVal.getTBAAInfo());
2012void AtomicInfo::EmitAtomicUpdateLibcall(llvm::AtomicOrdering AO,
2013 RValue UpdateRVal,
bool IsVolatile) {
2014 auto Failure = llvm::AtomicCmpXchgInst::getStrongestFailureOrdering(AO);
2016 Address ExpectedAddr = CreateTempAlloca();
2018 EmitAtomicLoadLibcall(ExpectedAddr.
emitRawPointer(CGF), AO, IsVolatile);
2022 Address DesiredAddr = CreateTempAlloca();
2023 if ((LVal.isBitField() && BFI.
Size != ValueSizeInBits) ||
2024 requiresMemSetZero(getAtomicAddress().getElementType())) {
2032 EmitAtomicCompareExchangeLibcall(ExpectedPtr, DesiredPtr, AO,
Failure);
2033 CGF.
Builder.CreateCondBr(Res, ExitBB, ContBB);
2037void AtomicInfo::EmitAtomicUpdateOp(llvm::AtomicOrdering AO, RValue UpdateRVal,
2039 auto Failure = llvm::AtomicCmpXchgInst::getStrongestFailureOrdering(AO);
2042 auto *OldVal = EmitAtomicLoadOp(
Failure, IsVolatile,
true);
2046 auto *CurBB = CGF.
Builder.GetInsertBlock();
2048 llvm::PHINode *PHI = CGF.
Builder.CreatePHI(OldVal->getType(),
2050 PHI->addIncoming(OldVal, CurBB);
2051 Address NewAtomicAddr = CreateTempAlloca();
2052 Address NewAtomicIntAddr = castToAtomicIntPointer(NewAtomicAddr);
2053 if ((LVal.isBitField() && BFI.
Size != ValueSizeInBits) ||
2054 requiresMemSetZero(getAtomicAddress().getElementType())) {
2060 auto Res = EmitAtomicCompareExchangeOp(PHI, DesiredVal, AO,
Failure);
2061 PHI->addIncoming(Res.first, CGF.
Builder.GetInsertBlock());
2062 CGF.
Builder.CreateCondBr(Res.second, ExitBB, ContBB);
2066void AtomicInfo::EmitAtomicUpdate(
2067 llvm::AtomicOrdering AO,
const llvm::function_ref<RValue(RValue)> &UpdateOp,
2069 if (shouldUseLibcall()) {
2070 EmitAtomicUpdateLibcall(AO, UpdateOp, IsVolatile);
2072 EmitAtomicUpdateOp(AO, UpdateOp, IsVolatile);
2076void AtomicInfo::EmitAtomicUpdate(llvm::AtomicOrdering AO, RValue UpdateRVal,
2078 if (shouldUseLibcall()) {
2079 EmitAtomicUpdateLibcall(AO, UpdateRVal, IsVolatile);
2081 EmitAtomicUpdateOp(AO, UpdateRVal, IsVolatile);
2088 llvm::AtomicOrdering AO;
2090 AO = llvm::AtomicOrdering::SequentiallyConsistent;
2092 AO = llvm::AtomicOrdering::Release;
2104 llvm::AtomicOrdering AO,
bool IsVolatile,
2112 AtomicInfo atomics(*
this, dest);
2113 LValue LVal = atomics.getAtomicLValue();
2118 atomics.emitCopyIntoMemory(rvalue);
2123 if (atomics.shouldUseLibcall()) {
2125 Address srcAddr = atomics.materializeRValue(rvalue);
2142 llvm::Value *ValToStore = atomics.convertRValueToInt(rvalue);
2146 if (llvm::Value *
Value = atomics.getScalarRValValueOrNull(rvalue))
2148 Addr = atomics.castToAtomicIntPointer(
Addr);
2149 ValToStore =
Builder.CreateIntCast(ValToStore,
Addr.getElementType(),
2152 llvm::StoreInst *store =
Builder.CreateStore(ValToStore,
Addr);
2154 if (AO == llvm::AtomicOrdering::Acquire)
2155 AO = llvm::AtomicOrdering::Monotonic;
2156 else if (AO == llvm::AtomicOrdering::AcquireRelease)
2157 AO = llvm::AtomicOrdering::Release;
2160 store->setAtomic(AO);
2166 store->setVolatile(
true);
2172 atomics.EmitAtomicUpdate(AO, rvalue, IsVolatile);
2179 llvm::AtomicOrdering
Success, llvm::AtomicOrdering
Failure,
bool IsWeak,
2184 Expected.getAggregateAddress().getElementType() ==
2189 AtomicInfo Atomics(*
this, Obj);
2195llvm::AtomicRMWInst *
2197 llvm::Value *Val, llvm::AtomicOrdering Order,
2198 llvm::SyncScope::ID SSID,
2200 llvm::AtomicRMWInst *RMW =
2201 Builder.CreateAtomicRMW(Op,
Addr, Val, Order, SSID);
2207 llvm::SyncScope::ID SSID) {
2208 llvm::FenceInst *Fence =
Builder.CreateFence(Order, SSID);
2214 LValue LVal, llvm::AtomicOrdering AO,
2215 const llvm::function_ref<
RValue(
RValue)> &UpdateOp,
bool IsVolatile) {
2216 AtomicInfo Atomics(*
this, LVal);
2217 Atomics.EmitAtomicUpdate(AO, UpdateOp, IsVolatile);
2221 AtomicInfo atomics(*
this, dest);
2223 switch (atomics.getEvaluationKind()) {
2239 bool Zeroed =
false;
2241 Zeroed = atomics.emitMemSetZeroIfNecessary();
2242 dest = atomics.projectValue();
2256 llvm_unreachable(
"bad evaluation kind");
Defines the clang::ASTContext interface.
static llvm::Value * EmitPostAtomicMinMax(CGBuilderTy &Builder, AtomicExpr::AtomicOp Op, bool IsSigned, llvm::Value *OldVal, llvm::Value *RHS)
Duplicate the atomic min/max operation in conventional IR for the builtin variants that return the ne...
static void EmitAtomicUpdateValue(CodeGenFunction &CGF, AtomicInfo &Atomics, RValue OldRVal, const llvm::function_ref< RValue(RValue)> &UpdateOp, Address DesiredAddr)
static Address EmitValToTemp(CodeGenFunction &CGF, Expr *E)
static RValue emitAtomicLibcall(CodeGenFunction &CGF, StringRef fnName, QualType resultType, CallArgList &args)
static void EmitAtomicOp(CodeGenFunction &CGF, AtomicExpr *E, Address Dest, Address Ptr, Address Val1, Address Val2, Address ExpectedResult, llvm::Value *IsWeak, llvm::Value *FailureOrder, uint64_t Size, llvm::AtomicOrdering Order, llvm::SyncScope::ID Scope)
static Address EmitPointerWithAlignment(const Expr *E, LValueBaseInfo *BaseInfo, TBAAAccessInfo *TBAAInfo, KnownNonNull_t IsKnownNonNull, CodeGenFunction &CGF)
static bool shouldCastToInt(mlir::Type valueTy, bool cmpxchg)
Return true if.
static void emitAtomicCmpXchg(CIRGenFunction &cgf, AtomicExpr *e, bool isWeak, Address dest, Address ptr, Address val1, Address val2, uint64_t size, cir::MemOrder successOrder, cir::MemOrder failureOrder, cir::SyncScopeKind scope)
static bool isFullSizeType(CIRGenModule &cgm, mlir::Type ty, uint64_t expectedSize)
Does a store of the given IR type modify the full expected width?
static void emitAtomicCmpXchgFailureSet(CIRGenFunction &cgf, AtomicExpr *e, bool isWeak, Address dest, Address ptr, Address val1, Address val2, Expr *failureOrderExpr, uint64_t size, cir::MemOrder successOrder, cir::SyncScopeKind scope)
Result
Implement __builtin_bit_cast and related operations.
static QualType getPointeeType(const MemRegion *R)
QualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
QualType getExtVectorType(QualType VectorType, unsigned NumElts) const
Return the unique reference to an extended vector type of the specified element type and size.
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load,...
static std::unique_ptr< AtomicScopeModel > getScopeModel(AtomicOp Op)
Get atomic scope model for the atomic op code.
QualType getValueType() const
SourceLocation getBeginLoc() const LLVM_READONLY
Expr * getOrderFail() const
CharUnits - This is an opaque type for sizes expressed in character units.
llvm::Align getAsAlign() const
getAsAlign - Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit b...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
bool isMultipleOf(CharUnits N) const
Test whether this is a multiple of the other value.
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
CharUnits getAlignment() const
llvm::Type * getElementType() const
Return the type of the values stored in this address.
Address withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
static AggValueSlot ignored()
ignored - Returns an aggregate value slot indicating that the aggregate value is being ignored.
Address getAddress() const
static AggValueSlot forLValue(const LValue &LV, IsDestructed_t isDestructed, NeedsGCBarriers_t needsGC, IsAliased_t isAliased, Overlap_t mayOverlap, IsZeroed_t isZeroed=IsNotZeroed, IsSanitizerChecked_t isChecked=IsNotSanitizerChecked)
A scoped helper to set the current source atom group for CGDebugInfo::addInstToCurrentSourceAtom.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
Address CreatePointerBitCastOrAddrSpaceCast(Address Addr, llvm::Type *Ty, llvm::Type *ElementTy, const llvm::Twine &Name="")
llvm::CallInst * CreateMemSet(Address Dest, llvm::Value *Value, llvm::Value *Size, bool IsVolatile=false)
Address CreateStructGEP(Address Addr, unsigned Index, const llvm::Twine &Name="")
llvm::AtomicCmpXchgInst * CreateAtomicCmpXchg(Address Addr, llvm::Value *Cmp, llvm::Value *New, llvm::AtomicOrdering SuccessOrdering, llvm::AtomicOrdering FailureOrdering, llvm::SyncScope::ID SSID=llvm::SyncScope::System)
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
llvm::CallInst * CreateMemCpy(Address Dest, Address Src, llvm::Value *Size, bool IsVolatile=false)
Address CreateAddrSpaceCast(Address Addr, llvm::Type *Ty, llvm::Type *ElementTy, const llvm::Twine &Name="")
static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())
CGFunctionInfo - Class to encapsulate the information about a function definition.
CallArgList - Type for representing both the value and type of arguments in a call.
void add(RValue rvalue, QualType type)
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::Value * performAddrSpaceCast(llvm::Value *Src, llvm::Type *DestTy)
void EmitAtomicInit(Expr *E, LValue lvalue)
RValue convertTempToRValue(Address addr, QualType type, SourceLocation Loc)
Given the address of a temporary variable, produce an r-value of its type.
bool hasVolatileMember(QualType T)
hasVolatileMember - returns true if aggregate type has a volatile member.
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
void addInstToCurrentSourceAtom(llvm::Instruction *KeyInstruction, llvm::Value *Backup)
See CGDebugInfo::addInstToCurrentSourceAtom.
const LangOptions & getLangOpts() const
void EmitAtomicUpdate(LValue LVal, llvm::AtomicOrdering AO, const llvm::function_ref< RValue(RValue)> &UpdateOp, bool IsVolatile)
std::pair< RValue, llvm::Value * > EmitAtomicCompareExchange(LValue Obj, RValue Expected, RValue Desired, SourceLocation Loc, llvm::AtomicOrdering Success=llvm::AtomicOrdering::SequentiallyConsistent, llvm::AtomicOrdering Failure=llvm::AtomicOrdering::SequentiallyConsistent, bool IsWeak=false, AggValueSlot Slot=AggValueSlot::ignored())
Emit a compare-and-exchange op for atomic type.
void maybeAttachRangeForLoad(llvm::LoadInst *Load, QualType Ty, SourceLocation Loc)
void EmitAggregateCopy(LValue Dest, LValue Src, QualType EltTy, AggValueSlot::Overlap_t MayOverlap, bool isVolatile=false)
EmitAggregateCopy - Emit an aggregate copy.
const TargetInfo & getTarget() const
RValue EmitLoadOfLValue(LValue V, SourceLocation Loc)
EmitLoadOfLValue - Given an expression that represents a value lvalue, this method emits the address ...
RValue EmitAtomicLoad(LValue LV, SourceLocation SL, AggValueSlot Slot=AggValueSlot::ignored())
CGDebugInfo * getDebugInfo()
llvm::Value * getTypeSize(QualType Ty)
Returns calculated size of the specified type.
llvm::Value * EmitToMemory(llvm::Value *Value, QualType Ty)
EmitToMemory - Change a scalar value from its value representation to its in-memory representation.
llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp", llvm::Value *ArraySize=nullptr)
CreateTempAlloca - This creates an alloca and inserts it into the entry block if ArraySize is nullptr...
ComplexPairTy EmitComplexExpr(const Expr *E, bool IgnoreReal=false, bool IgnoreImag=false)
EmitComplexExpr - Emit the computation of the specified expression of complex type,...
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **CallOrInvoke, bool IsMustTail, SourceLocation Loc, bool IsVirtualFunctionPointerThunk=false)
EmitCall - Generate a call of the given function, expecting the given result type,...
const TargetCodeGenInfo & getTargetHooks() const
RawAddress CreateMemTempWithoutCast(QualType T, const Twine &Name="tmp")
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen without...
llvm::FenceInst * emitAtomicFence(llvm::AtomicOrdering Order, llvm::SyncScope::ID SSID=llvm::SyncScope::System)
Emit a fence instruction, applying relevant target-specific metadata when applicable.
ASTContext & getContext() const
void EmitStoreOfComplex(ComplexPairTy V, LValue dest, bool isInit)
EmitStoreOfComplex - Store a complex number into the specified l-value.
void EmitStoreThroughLValue(RValue Src, LValue Dst, bool isInit=false)
EmitStoreThroughLValue - Store the specified rvalue into the specified lvalue, where both are guarant...
llvm::AtomicRMWInst * emitAtomicRMWInst(llvm::AtomicRMWInst::BinOp Op, Address Addr, llvm::Value *Val, llvm::AtomicOrdering Order=llvm::AtomicOrdering::SequentiallyConsistent, llvm::SyncScope::ID SSID=llvm::SyncScope::System, const AtomicExpr *AE=nullptr)
Emit an atomicrmw instruction, and applying relevant metadata when applicable.
void EmitAnyExprToMem(const Expr *E, Address Location, Qualifiers Quals, bool IsInitializer)
EmitAnyExprToMem - Emits the code necessary to evaluate an arbitrary expression into the given memory...
llvm::Type * ConvertTypeForMem(QualType T)
RValue EmitLoadOfBitfieldLValue(LValue LV, SourceLocation Loc)
RValue EmitAtomicExpr(AtomicExpr *E)
static TypeEvaluationKind getEvaluationKind(QualType T)
getEvaluationKind - Return the TypeEvaluationKind of QualType T.
bool LValueIsSuitableForInlineAtomic(LValue Src)
An LValue is a candidate for having its loads and stores be made atomic if we are operating under /vo...
void EmitAggExpr(const Expr *E, AggValueSlot AS)
EmitAggExpr - Emit the computation of the specified expression of aggregate type.
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
RValue EmitLoadOfExtVectorElementLValue(LValue V)
LValue MakeAddrLValue(Address Addr, QualType T, AlignmentSource Source=AlignmentSource::Type)
void EmitAtomicStore(RValue rvalue, LValue lvalue, bool isInit)
llvm::Value * EmitFromMemory(llvm::Value *Value, QualType Ty)
EmitFromMemory - Change a scalar value from its memory representation to its value representation.
std::pair< llvm::Value *, llvm::Value * > ComplexPairTy
llvm::LLVMContext & getLLVMContext()
void EmitStoreOfScalar(llvm::Value *Value, Address Addr, bool Volatile, QualType Ty, AlignmentSource Source=AlignmentSource::Type, bool isInit=false, bool isNontemporal=false)
EmitStoreOfScalar - Store a scalar value to an address, taking care to appropriately convert from the...
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
This class organizes the cross-function state that is used while generating LLVM code.
llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)
Create or return a runtime function declaration with the specified type and name.
const LangOptions & getLangOpts() const
CodeGenTypes & getTypes()
const llvm::DataLayout & getDataLayout() const
void DecorateInstructionWithTBAA(llvm::Instruction *Inst, TBAAAccessInfo TBAAInfo)
DecorateInstructionWithTBAA - Decorate the instruction with a TBAA tag.
llvm::LLVMContext & getLLVMContext()
llvm::ConstantInt * getSize(CharUnits numChars)
Emit the given number of characters as a value of type size_t.
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.
const CGFunctionInfo & arrangeBuiltinFunctionCall(QualType resultType, const CallArgList &args)
LValue - This represents an lvalue references.
bool isVolatileQualified() const
Address getAddress() const
TBAAAccessInfo getTBAAInfo() const
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
static RValue get(llvm::Value *V)
static RValue getAggregate(Address addr, bool isVolatile=false)
Convert an Address to an RValue.
static RValue getComplex(llvm::Value *V1, llvm::Value *V2)
Address getAggregateAddress() const
getAggregateAddr() - Return the Value* of the address of the aggregate.
llvm::Value * getScalarVal() const
getScalarVal() - Return the Value* of this scalar value.
bool isVolatileQualified() const
std::pair< llvm::Value *, llvm::Value * > getComplexVal() const
getComplexVal - Return the real/imag components of this complex value.
ReturnValueSlot - Contains the address where the return value of a function can be stored,...
llvm::SyncScope::ID getLLVMSyncScopeID(const LangOptions &LangOpts, SyncScope Scope, llvm::AtomicOrdering Ordering, llvm::LLVMContext &Ctx) const
Get the syncscope used in LLVM IR as a SyncScope ID.
virtual void setTargetAtomicMetadata(CodeGenFunction &CGF, llvm::Instruction &AtomicInst, const AtomicExpr *Expr=nullptr) const
Allow the target to apply other metadata to an atomic instruction.
Concrete class used by the front-end to report problems and issues.
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
This represents one expression.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
PointerType - C99 6.7.5.1 - Pointer Declarators.
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
LangAS getAddressSpace() const
Return the address space of this type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
Scope - A scope is a transient data structure that is used while parsing the program.
Encodes a location in the source.
bool isSignedIntegerType() const
Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...
bool isPointerType() const
const T * castAs() const
Member-template castAs<specific type>.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isAtomicType() const
bool isFloatingType() const
const T * getAs() const
Member-template getAs<specific type>'.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
@ Address
A pointer to a ValueDecl.
bool Load(InterpState &S, CodePtr OpPC)
Top level wrappers for InstallAPI frontend operations.
bool isa(CodeGen::Address addr)
@ Success
Annotation was successful.
llvm::Expected< QualType > ExpectedType
llvm::StringRef getAsString(SyncScope S)
U cast(CodeGen::Address addr)
CharUnits StorageOffset
The offset of the bitfield storage from the start of the struct.
unsigned Offset
The offset within a contiguous run of bitfields that are represented as a single "field" within the L...
unsigned Size
The total size of the bit-field, in bits.
unsigned StorageSize
The storage size in bits which should be used when accessing this bitfield.
llvm::PointerType * VoidPtrTy
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
llvm::IntegerType * SizeTy
llvm::IntegerType * IntTy
int
llvm::PointerType * DefaultPtrTy