LLVM: lib/Frontend/Atomic/Atomic.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
12#include
13
14using namespace llvm;
15
17 if (ValTy->isFloatingPointTy())
18 return ValTy->isX86_FP80Ty() || CmpXchg;
19 return !ValTy->isIntegerTy() && !ValTy->isPointerTy();
20}
21
23 bool CmpXchg) {
29 Builder->CreateAlignedLoad(AtomicTy, Ptr, AtomicAlign, "atomic-load");
30 Load->setAtomic(AO);
31 if (IsVolatile)
32 Load->setVolatile(true);
34 return Load;
35}
36
41 for (Value *Arg : Args)
44 Module *M = Builder->GetInsertBlock()->getModule();
45
46
47 AttrBuilder fnAttrBuilder(ctx);
48 fnAttrBuilder.addAttribute(Attribute::NoUnwind);
49 fnAttrBuilder.addAttribute(Attribute::WillReturn);
50 AttributeList fnAttrs =
51 AttributeList::get(ctx, AttributeList::FunctionIndex, fnAttrBuilder);
52 FunctionCallee LibcallFn = M->getOrInsertFunction(fnName, FnType, fnAttrs);
55}
56
61
62
63
64
65
66
67 constexpr uint64_t IntBits = 32;
68
69
70
71
72 Value *Args[6] = {
75 ExpectedVal,
76 DesiredVal,
79 true)),
82 true)),
83 };
86 return std::make_pair(ExpectedVal, Result);
87}
88
91 AtomicOrdering Failure, bool IsVolatile, bool IsWeak) {
92
94 auto *Inst = Builder->CreateAtomicCmpXchg(Addr, ExpectedVal, DesiredVal,
97
98
99 Inst->setVolatile(IsVolatile);
100 Inst->setWeak(IsWeak);
101 auto *PreviousVal = Builder->CreateExtractValue(Inst, 0);
102 auto *SuccessFailureVal = Builder->CreateExtractValue(Inst, 1);
103 return std::make_pair(PreviousVal, SuccessFailureVal);
104}
105
106std::pair<LoadInst *, AllocaInst *>
110 Type *ResultTy;
112 AttributeList Attr;
113 Module *M = Builder->GetInsertBlock()->getModule();
115 Args.push_back(
116 ConstantInt::get(DL.getIntPtrType(Ctx), this->getAtomicSizeInBits() / 8));
117
120 Args.push_back(PtrVal);
121
122 auto CurrentIP = Builder->saveIP();
126 Builder->restoreIP(CurrentIP);
127 const Align AllocaAlignment = DL.getPrefTypeAlign(SizedIntTy);
129 Args.push_back(AllocaResult);
132 Args.push_back(OrderingVal);
133
136 for (Value *Arg : Args)
137 ArgTys.push_back(Arg->getType());
140 M->getOrInsertFunction("__atomic_load", FnType, Attr);
142 Call->setAttributes(Attr);
143 return std::make_pair(
144 Builder->CreateAlignedLoad(Ty, AllocaResult, AllocaAlignment),
145 AllocaResult);
146}
147
151 AttributeList Attr;
152 Module *M = Builder->GetInsertBlock()->getModule();
154 Args.push_back(
155 ConstantInt::get(DL.getIntPtrType(Ctx), this->getAtomicSizeInBits() / 8));
156
159 Args.push_back(PtrVal);
160
161 auto CurrentIP = Builder->saveIP();
163 Value *SourceAlloca = Builder->CreateAlloca(Source->getType());
164 Builder->restoreIP(CurrentIP);
165 Builder->CreateStore(Source, SourceAlloca);
166 SourceAlloca = Builder->CreatePointerBitCastOrAddrSpaceCast(
167 SourceAlloca, Builder->getPtrTy());
168 Args.push_back(SourceAlloca);
169
172 Args.push_back(OrderingVal);
173
175 for (Value *Arg : Args)
176 ArgTys.push_back(Arg->getType());
179 M->getOrInsertFunction("__atomic_store", FnType, Attr);
181 Call->setAttributes(Attr);
182}
183
186 AtomicOrdering Failure, bool IsVolatile, bool IsWeak) {
189 Failure);
190
192 Failure, IsVolatile, IsWeak);
193 return Res;
194}
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static StringRef getName(Value *V)
Class for arbitrary precision integers.
an instruction to allocate memory on the stack
void setAlignment(Align Align)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
LLVM_ABI std::pair< Value *, Value * > EmitAtomicCompareExchange(Value *ExpectedVal, Value *DesiredVal, AtomicOrdering Success, AtomicOrdering Failure, bool IsVolatile, bool IsWeak)
Definition Atomic.cpp:184
virtual AllocaInst * CreateAlloca(Type *Ty, const Twine &Name) const =0
LLVM_ABI std::pair< LoadInst *, AllocaInst * > EmitAtomicLoadLibcall(AtomicOrdering AO)
Definition Atomic.cpp:107
LLVM_ABI std::pair< Value *, Value * > EmitAtomicCompareExchangeOp(Value *ExpectedVal, Value *DesiredVal, AtomicOrdering Success, AtomicOrdering Failure, bool IsVolatile=false, bool IsWeak=false)
Definition Atomic.cpp:89
uint64_t getAtomicSizeInBits() const
LLVM_ABI Value * EmitAtomicLoadOp(AtomicOrdering AO, bool IsVolatile, bool CmpXchg=false)
Definition Atomic.cpp:22
virtual Value * getAtomicPointer() const =0
LLVM_ABI std::pair< Value *, Value * > EmitAtomicCompareExchangeLibcall(Value *ExpectedVal, Value *DesiredVal, AtomicOrdering Success, AtomicOrdering Failure)
Definition Atomic.cpp:57
LLVM_ABI bool shouldCastToInt(Type *ValTy, bool CmpXchg)
Definition Atomic.cpp:16
uint64_t AtomicSizeInBits
LLVM_ABI void EmitAtomicStoreLibcall(AtomicOrdering AO, Value *Source)
Definition Atomic.cpp:148
IRBuilderBase::InsertPoint AllocaIP
LLVMContext & getLLVMContext() const
Value * getAtomicAddressAsAtomicIntPointer() const
virtual void decorateWithTBAA(Instruction *I)=0
LLVM_ABI CallInst * EmitAtomicLibcall(StringRef fnName, Type *ResultType, ArrayRef< Value * > Args)
Definition Atomic.cpp:37
Value * getAtomicSizeValue() const
bool shouldUseLibcall() const
Align getAtomicAlignment() const
This class represents a function call, abstracting a target machine's calling convention.
This is an important base class in LLVM.
static LLVM_ABI Constant * getIntegerValue(Type *Ty, const APInt &V)
Return the value for an integer or pointer constant, or a vector thereof, with the given scalar value...
A parsed version of the target data layout string in and methods for querying it.
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
Class to represent function types.
static LLVM_ABI FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
static LLVM_ABI IntegerType * get(LLVMContext &C, unsigned NumBits)
This static method is the primary way of constructing an IntegerType.
This is an important class for using LLVM in a threaded context.
An instruction for reading from memory.
A Module instance is used to store all the information related to an LLVM module.
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the default address space (address sp...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
static LLVM_ABI IntegerType * getInt1Ty(LLVMContext &C)
static LLVM_ABI IntegerType * getIntNTy(LLVMContext &C, unsigned N)
LLVM Value Representation.
@ System
Synchronized with respect to all concurrently executing threads.
This is an optimization pass for GlobalISel generic memory operations.
AtomicOrderingCABI toCABI(AtomicOrdering AO)
@ Success
The lock was released successfully.
AtomicOrdering
Atomic ordering for LLVM's memory model.
This struct is a compact representation of a valid (non-zero power of two) alignment.