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.