1//===--- Atomic.h - Codegen of atomic operations ------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_FRONTEND_ATOMIC_ATOMIC_H
10#define LLVM_FRONTEND_ATOMIC_ATOMIC_H
11
12#include "llvm/IR/IRBuilder.h"
13#include "llvm/IR/Module.h"
14#include "llvm/Support/Compiler.h"
15
16namespace llvm {
17class AtomicInfo {
18protected:
19 IRBuilderBase *Builder;
20 Type *Ty;
21 uint64_t AtomicSizeInBits;
22 uint64_t ValueSizeInBits;
23 Align AtomicAlign;
24 Align ValueAlign;
25 bool UseLibcall;
26 IRBuilderBase::InsertPoint AllocaIP;
27
28public:
29 AtomicInfo(IRBuilderBase *Builder, Type *Ty, uint64_t AtomicSizeInBits,
30 uint64_t ValueSizeInBits, Align AtomicAlign, Align ValueAlign,
31 bool UseLibcall, IRBuilderBase::InsertPoint AllocaIP)
32 : Builder(Builder), Ty(Ty), AtomicSizeInBits(AtomicSizeInBits),
33 ValueSizeInBits(ValueSizeInBits), AtomicAlign(AtomicAlign),
34 ValueAlign(ValueAlign), UseLibcall(UseLibcall), AllocaIP(AllocaIP) {}
35
36 virtual ~AtomicInfo() = default;
37
38 Align getAtomicAlignment() const { return AtomicAlign; }
39 uint64_t getAtomicSizeInBits() const { return AtomicSizeInBits; }
40 uint64_t getValueSizeInBits() const { return ValueSizeInBits; }
41 bool shouldUseLibcall() const { return UseLibcall; }
42 Type *getAtomicTy() const { return Ty; }
43
44 virtual Value *getAtomicPointer() const = 0;
45 virtual void decorateWithTBAA(Instruction *I) = 0;
46 virtual AllocaInst *CreateAlloca(Type *Ty, const Twine &Name) const = 0;
47
48 /*
49 * Is the atomic size larger than the underlying value type?
50 * Note that the absence of padding does not mean that atomic
51 * objects are completely interchangeable with non-atomic
52 * objects: we might have promoted the alignment of a type
53 * without making it bigger.
54 */
55 bool hasPadding() const { return (ValueSizeInBits != AtomicSizeInBits); }
56
57 LLVMContext &getLLVMContext() const { return Builder->getContext(); }
58
59 LLVM_ABI bool shouldCastToInt(Type *ValTy, bool CmpXchg);
60
61 LLVM_ABI Value *EmitAtomicLoadOp(AtomicOrdering AO, bool IsVolatile,
62 bool CmpXchg = false);
63
64 LLVM_ABI CallInst *EmitAtomicLibcall(StringRef fnName, Type *ResultType,
65 ArrayRef<Value *> Args);
66
67 Value *getAtomicSizeValue() const {
68 LLVMContext &ctx = getLLVMContext();
69 // TODO: Get from llvm::TargetMachine / clang::TargetInfo
70 // if clang shares this codegen in future
71 constexpr uint16_t SizeTBits = 64;
72 constexpr uint16_t BitsPerByte = 8;
73 return ConstantInt::get(Ty: IntegerType::get(C&: ctx, NumBits: SizeTBits),
74 V: AtomicSizeInBits / BitsPerByte);
75 }
76
77 LLVM_ABI std::pair<Value *, Value *>
78 EmitAtomicCompareExchangeLibcall(Value *ExpectedVal, Value *DesiredVal,
79 AtomicOrdering Success,
80 AtomicOrdering Failure);
81
82 Value *castToAtomicIntPointer(Value *addr) const {
83 return addr; // opaque pointer
84 }
85
86 Value *getAtomicAddressAsAtomicIntPointer() const {
87 return castToAtomicIntPointer(addr: getAtomicPointer());
88 }
89
90 LLVM_ABI std::pair<Value *, Value *>
91 EmitAtomicCompareExchangeOp(Value *ExpectedVal, Value *DesiredVal,
92 AtomicOrdering Success, AtomicOrdering Failure,
93 bool IsVolatile = false, bool IsWeak = false);
94
95 LLVM_ABI std::pair<Value *, Value *>
96 EmitAtomicCompareExchange(Value *ExpectedVal, Value *DesiredVal,
97 AtomicOrdering Success, AtomicOrdering Failure,
98 bool IsVolatile, bool IsWeak);
99
100 LLVM_ABI std::pair<LoadInst *, AllocaInst *>
101 EmitAtomicLoadLibcall(AtomicOrdering AO);
102
103 LLVM_ABI void EmitAtomicStoreLibcall(AtomicOrdering AO, Value *Source);
104};
105} // end namespace llvm
106
107#endif /* LLVM_FRONTEND_ATOMIC_ATOMIC_H */
108

source code of llvm/include/llvm/Frontend/Atomic/Atomic.h