Skip to content

Commit 24fc8f0

Browse files
authored
[llvm][OpenMP][NFC] Cleanup AtomicInfo (#119199)
This PR refactors functionality from llvm/include/llvm/Frontend/Atomic/Atomic.h into llvm/lib/llvm/Frontend/Atomic/Atomic.cpp.
1 parent bda7aad commit 24fc8f0

File tree

4 files changed

+184
-183
lines changed

4 files changed

+184
-183
lines changed

llvm/include/llvm/Frontend/Atomic/Atomic.h

Lines changed: 36 additions & 166 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
//===--- Atomic.h - Codegen of atomic operations
2-
//---------------------------===//
1+
//===--- Atomic.h - Codegen of atomic operations ------------------------===//
32
//
43
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
54
// See https://llvm.org/LICENSE.txt for license information.
@@ -10,46 +9,39 @@
109
#ifndef LLVM_FRONTEND_ATOMIC_ATOMIC_H
1110
#define LLVM_FRONTEND_ATOMIC_ATOMIC_H
1211

13-
#include "llvm/ADT/DenseMap.h"
14-
#include "llvm/IR/DataLayout.h"
15-
#include "llvm/IR/Instructions.h"
16-
#include "llvm/IR/Intrinsics.h"
12+
#include "llvm/IR/IRBuilder.h"
1713
#include "llvm/IR/Module.h"
18-
#include "llvm/IR/Operator.h"
19-
#include "llvm/IR/RuntimeLibcalls.h"
2014

2115
namespace llvm {
22-
23-
template <typename IRBuilderTy> struct AtomicInfo {
24-
25-
IRBuilderTy *Builder;
16+
class AtomicInfo {
17+
protected:
18+
IRBuilderBase *Builder;
2619
Type *Ty;
2720
uint64_t AtomicSizeInBits;
2821
uint64_t ValueSizeInBits;
29-
llvm::Align AtomicAlign;
30-
llvm::Align ValueAlign;
22+
Align AtomicAlign;
23+
Align ValueAlign;
3124
bool UseLibcall;
3225

3326
public:
34-
AtomicInfo(IRBuilderTy *Builder, Type *Ty, uint64_t AtomicSizeInBits,
35-
uint64_t ValueSizeInBits, llvm::Align AtomicAlign,
36-
llvm::Align ValueAlign, bool UseLibcall)
27+
AtomicInfo(IRBuilderBase *Builder, Type *Ty, uint64_t AtomicSizeInBits,
28+
uint64_t ValueSizeInBits, Align AtomicAlign, Align ValueAlign,
29+
bool UseLibcall)
3730
: Builder(Builder), Ty(Ty), AtomicSizeInBits(AtomicSizeInBits),
3831
ValueSizeInBits(ValueSizeInBits), AtomicAlign(AtomicAlign),
3932
ValueAlign(ValueAlign), UseLibcall(UseLibcall) {}
4033

4134
virtual ~AtomicInfo() = default;
4235

43-
llvm::Align getAtomicAlignment() const { return AtomicAlign; }
36+
Align getAtomicAlignment() const { return AtomicAlign; }
4437
uint64_t getAtomicSizeInBits() const { return AtomicSizeInBits; }
4538
uint64_t getValueSizeInBits() const { return ValueSizeInBits; }
4639
bool shouldUseLibcall() const { return UseLibcall; }
47-
llvm::Type *getAtomicTy() const { return Ty; }
40+
Type *getAtomicTy() const { return Ty; }
4841

49-
virtual llvm::Value *getAtomicPointer() const = 0;
42+
virtual Value *getAtomicPointer() const = 0;
5043
virtual void decorateWithTBAA(Instruction *I) = 0;
51-
virtual llvm::AllocaInst *CreateAlloca(llvm::Type *Ty,
52-
const llvm::Twine &Name) const = 0;
44+
virtual AllocaInst *CreateAlloca(Type *Ty, const Twine &Name) const = 0;
5345

5446
/*
5547
* Is the atomic size larger than the underlying value type?
@@ -62,90 +54,28 @@ template <typename IRBuilderTy> struct AtomicInfo {
6254

6355
LLVMContext &getLLVMContext() const { return Builder->getContext(); }
6456

65-
static bool shouldCastToInt(llvm::Type *ValTy, bool CmpXchg) {
66-
if (ValTy->isFloatingPointTy())
67-
return ValTy->isX86_FP80Ty() || CmpXchg;
68-
return !ValTy->isIntegerTy() && !ValTy->isPointerTy();
69-
}
57+
bool shouldCastToInt(Type *ValTy, bool CmpXchg);
7058

71-
llvm::Value *EmitAtomicLoadOp(llvm::AtomicOrdering AO, bool IsVolatile,
72-
bool CmpXchg = false) {
73-
Value *Ptr = getAtomicPointer();
74-
Type *AtomicTy = Ty;
75-
if (shouldCastToInt(Ty, CmpXchg))
76-
AtomicTy = llvm::IntegerType::get(getLLVMContext(), AtomicSizeInBits);
77-
LoadInst *Load =
78-
Builder->CreateAlignedLoad(AtomicTy, Ptr, AtomicAlign, "atomic-load");
79-
Load->setAtomic(AO);
80-
if (IsVolatile)
81-
Load->setVolatile(true);
82-
decorateWithTBAA(Load);
83-
return Load;
84-
}
59+
Value *EmitAtomicLoadOp(AtomicOrdering AO, bool IsVolatile,
60+
bool CmpXchg = false);
8561

86-
static CallInst *EmitAtomicLibcall(IRBuilderTy *Builder, StringRef fnName,
87-
Type *ResultType, ArrayRef<Value *> Args) {
88-
LLVMContext &ctx = Builder->getContext();
89-
SmallVector<Type *, 6> ArgTys;
90-
for (Value *Arg : Args)
91-
ArgTys.push_back(Arg->getType());
92-
FunctionType *FnType = FunctionType::get(ResultType, ArgTys, false);
93-
Module *M = Builder->GetInsertBlock()->getModule();
94-
95-
// TODO: Use llvm::TargetLowering for Libcall ABI
96-
llvm::AttrBuilder fnAttrBuilder(ctx);
97-
fnAttrBuilder.addAttribute(llvm::Attribute::NoUnwind);
98-
fnAttrBuilder.addAttribute(llvm::Attribute::WillReturn);
99-
llvm::AttributeList fnAttrs = llvm::AttributeList::get(
100-
ctx, llvm::AttributeList::FunctionIndex, fnAttrBuilder);
101-
FunctionCallee LibcallFn = M->getOrInsertFunction(fnName, FnType, fnAttrs);
102-
CallInst *Call = Builder->CreateCall(LibcallFn, Args);
103-
return Call;
104-
}
62+
CallInst *EmitAtomicLibcall(StringRef fnName, Type *ResultType,
63+
ArrayRef<Value *> Args);
10564

106-
llvm::Value *getAtomicSizeValue() const {
65+
Value *getAtomicSizeValue() const {
10766
LLVMContext &ctx = getLLVMContext();
108-
10967
// TODO: Get from llvm::TargetMachine / clang::TargetInfo
110-
// if clang shares this codegen in future
68+
// if clang shares this codegen in future
11169
constexpr uint16_t SizeTBits = 64;
11270
constexpr uint16_t BitsPerByte = 8;
113-
return llvm::ConstantInt::get(llvm::IntegerType::get(ctx, SizeTBits),
114-
AtomicSizeInBits / BitsPerByte);
71+
return ConstantInt::get(IntegerType::get(ctx, SizeTBits),
72+
AtomicSizeInBits / BitsPerByte);
11573
}
11674

117-
std::pair<llvm::Value *, llvm::Value *> EmitAtomicCompareExchangeLibcall(
118-
llvm::Value *ExpectedVal, llvm::Value *DesiredVal,
119-
llvm::AtomicOrdering Success, llvm::AtomicOrdering Failure) {
120-
LLVMContext &ctx = getLLVMContext();
121-
122-
// __atomic_compare_exchange's expected and desired are passed by pointers
123-
// FIXME: types
124-
125-
// TODO: Get from llvm::TargetMachine / clang::TargetInfo
126-
// if clang shares this codegen in future
127-
constexpr uint64_t IntBits = 32;
128-
129-
// bool __atomic_compare_exchange(size_t size, void *obj, void *expected,
130-
// void *desired, int success, int failure);
131-
llvm::Value *Args[6] = {
132-
getAtomicSizeValue(),
133-
getAtomicPointer(),
134-
ExpectedVal,
135-
DesiredVal,
136-
llvm::Constant::getIntegerValue(
137-
llvm::IntegerType::get(ctx, IntBits),
138-
llvm::APInt(IntBits, static_cast<uint64_t>(Success),
139-
/*signed=*/true)),
140-
llvm::Constant::getIntegerValue(
141-
llvm::IntegerType::get(ctx, IntBits),
142-
llvm::APInt(IntBits, static_cast<uint64_t>(Failure),
143-
/*signed=*/true)),
144-
};
145-
auto Result = EmitAtomicLibcall(Builder, "__atomic_compare_exchange",
146-
llvm::IntegerType::getInt1Ty(ctx), Args);
147-
return std::make_pair(ExpectedVal, Result);
148-
}
75+
std::pair<Value *, Value *>
76+
EmitAtomicCompareExchangeLibcall(Value *ExpectedVal, Value *DesiredVal,
77+
AtomicOrdering Success,
78+
AtomicOrdering Failure);
14979

15080
Value *castToAtomicIntPointer(Value *addr) const {
15181
return addr; // opaque pointer
@@ -155,77 +85,17 @@ template <typename IRBuilderTy> struct AtomicInfo {
15585
return castToAtomicIntPointer(getAtomicPointer());
15686
}
15787

158-
std::pair<llvm::Value *, llvm::Value *>
159-
EmitAtomicCompareExchangeOp(llvm::Value *ExpectedVal, llvm::Value *DesiredVal,
160-
llvm::AtomicOrdering Success,
161-
llvm::AtomicOrdering Failure,
162-
bool IsVolatile = false, bool IsWeak = false) {
163-
// Do the atomic store.
164-
Value *Addr = getAtomicAddressAsAtomicIntPointer();
165-
auto *Inst = Builder->CreateAtomicCmpXchg(Addr, ExpectedVal, DesiredVal,
166-
getAtomicAlignment(), Success,
167-
Failure, llvm::SyncScope::System);
168-
// Other decoration.
169-
Inst->setVolatile(IsVolatile);
170-
Inst->setWeak(IsWeak);
171-
172-
auto *PreviousVal = Builder->CreateExtractValue(Inst, /*Idxs=*/0);
173-
auto *SuccessFailureVal = Builder->CreateExtractValue(Inst, /*Idxs=*/1);
174-
return std::make_pair(PreviousVal, SuccessFailureVal);
175-
}
88+
std::pair<Value *, Value *>
89+
EmitAtomicCompareExchangeOp(Value *ExpectedVal, Value *DesiredVal,
90+
AtomicOrdering Success, AtomicOrdering Failure,
91+
bool IsVolatile = false, bool IsWeak = false);
17692

177-
std::pair<llvm::Value *, llvm::Value *>
178-
EmitAtomicCompareExchange(llvm::Value *ExpectedVal, llvm::Value *DesiredVal,
179-
llvm::AtomicOrdering Success,
180-
llvm::AtomicOrdering Failure, bool IsVolatile,
181-
bool IsWeak) {
182-
if (shouldUseLibcall())
183-
return EmitAtomicCompareExchangeLibcall(ExpectedVal, DesiredVal, Success,
184-
Failure);
185-
186-
auto Res = EmitAtomicCompareExchangeOp(ExpectedVal, DesiredVal, Success,
187-
Failure, IsVolatile, IsWeak);
188-
return Res;
189-
}
93+
std::pair<Value *, Value *>
94+
EmitAtomicCompareExchange(Value *ExpectedVal, Value *DesiredVal,
95+
AtomicOrdering Success, AtomicOrdering Failure,
96+
bool IsVolatile, bool IsWeak);
19097

191-
// void __atomic_load(size_t size, void *mem, void *return, int order);
192-
std::pair<llvm::LoadInst *, llvm::AllocaInst *>
193-
EmitAtomicLoadLibcall(llvm::AtomicOrdering AO) {
194-
LLVMContext &Ctx = getLLVMContext();
195-
Type *SizedIntTy = Type::getIntNTy(Ctx, getAtomicSizeInBits());
196-
Type *ResultTy;
197-
SmallVector<Value *, 6> Args;
198-
AttributeList Attr;
199-
Module *M = Builder->GetInsertBlock()->getModule();
200-
const DataLayout &DL = M->getDataLayout();
201-
Args.push_back(ConstantInt::get(DL.getIntPtrType(Ctx),
202-
this->getAtomicSizeInBits() / 8));
203-
204-
Value *PtrVal = getAtomicPointer();
205-
PtrVal = Builder->CreateAddrSpaceCast(PtrVal, PointerType::getUnqual(Ctx));
206-
Args.push_back(PtrVal);
207-
AllocaInst *AllocaResult =
208-
CreateAlloca(Ty, getAtomicPointer()->getName() + "atomic.temp.load");
209-
const Align AllocaAlignment = DL.getPrefTypeAlign(SizedIntTy);
210-
AllocaResult->setAlignment(AllocaAlignment);
211-
Args.push_back(AllocaResult);
212-
Constant *OrderingVal =
213-
ConstantInt::get(Type::getInt32Ty(Ctx), (int)toCABI(AO));
214-
Args.push_back(OrderingVal);
215-
216-
ResultTy = Type::getVoidTy(Ctx);
217-
SmallVector<Type *, 6> ArgTys;
218-
for (Value *Arg : Args)
219-
ArgTys.push_back(Arg->getType());
220-
FunctionType *FnType = FunctionType::get(ResultTy, ArgTys, false);
221-
FunctionCallee LibcallFn =
222-
M->getOrInsertFunction("__atomic_load", FnType, Attr);
223-
CallInst *Call = Builder->CreateCall(LibcallFn, Args);
224-
Call->setAttributes(Attr);
225-
return std::make_pair(
226-
Builder->CreateAlignedLoad(Ty, AllocaResult, AllocaAlignment),
227-
AllocaResult);
228-
}
98+
std::pair<LoadInst *, AllocaInst *> EmitAtomicLoadLibcall(AtomicOrdering AO);
22999
};
230100
} // end namespace llvm
231101

llvm/include/llvm/Frontend/OpenMP/OMPIRBuilder.h

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -480,16 +480,15 @@ class OpenMPIRBuilder {
480480
T(Triple(M.getTargetTriple())) {}
481481
~OpenMPIRBuilder();
482482

483-
class AtomicInfo : public llvm::AtomicInfo<IRBuilder<>> {
483+
class AtomicInfo : public llvm::AtomicInfo {
484484
llvm::Value *AtomicVar;
485485

486486
public:
487487
AtomicInfo(IRBuilder<> *Builder, llvm::Type *Ty, uint64_t AtomicSizeInBits,
488488
uint64_t ValueSizeInBits, llvm::Align AtomicAlign,
489489
llvm::Align ValueAlign, bool UseLibcall, llvm::Value *AtomicVar)
490-
: llvm::AtomicInfo<IRBuilder<>>(Builder, Ty, AtomicSizeInBits,
491-
ValueSizeInBits, AtomicAlign,
492-
ValueAlign, UseLibcall),
490+
: llvm::AtomicInfo(Builder, Ty, AtomicSizeInBits, ValueSizeInBits,
491+
AtomicAlign, ValueAlign, UseLibcall),
493492
AtomicVar(AtomicVar) {}
494493

495494
llvm::Value *getAtomicPointer() const override { return AtomicVar; }
@@ -3156,15 +3155,6 @@ class OpenMPIRBuilder {
31563155
AtomicUpdateCallbackTy &UpdateOp, bool VolatileX,
31573156
bool IsXBinopExpr);
31583157

3159-
std::pair<llvm::LoadInst *, llvm::AllocaInst *>
3160-
EmitAtomicLoadLibcall(Value *X, Type *XElemTy, llvm::AtomicOrdering AO,
3161-
uint64_t AtomicSizeInBits);
3162-
3163-
std::pair<llvm::Value *, llvm::Value *> EmitAtomicCompareExchangeLibcall(
3164-
Value *X, Type *XElemTy, uint64_t AtomicSizeInBits,
3165-
llvm::Value *ExpectedVal, llvm::Value *DesiredVal,
3166-
llvm::AtomicOrdering Success, llvm::AtomicOrdering Failure);
3167-
31683158
/// Emit the binary op. described by \p RMWOp, using \p Src1 and \p Src2 .
31693159
///
31703160
/// \Return The instruction

0 commit comments

Comments
 (0)