Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:55

0001 //===--- Atomic.h - Codegen of atomic operations ------------------------===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLVM_FRONTEND_ATOMIC_ATOMIC_H
0010 #define LLVM_FRONTEND_ATOMIC_ATOMIC_H
0011 
0012 #include "llvm/IR/IRBuilder.h"
0013 #include "llvm/IR/Module.h"
0014 
0015 namespace llvm {
0016 class AtomicInfo {
0017 protected:
0018   IRBuilderBase *Builder;
0019   Type *Ty;
0020   uint64_t AtomicSizeInBits;
0021   uint64_t ValueSizeInBits;
0022   Align AtomicAlign;
0023   Align ValueAlign;
0024   bool UseLibcall;
0025 
0026 public:
0027   AtomicInfo(IRBuilderBase *Builder, Type *Ty, uint64_t AtomicSizeInBits,
0028              uint64_t ValueSizeInBits, Align AtomicAlign, Align ValueAlign,
0029              bool UseLibcall)
0030       : Builder(Builder), Ty(Ty), AtomicSizeInBits(AtomicSizeInBits),
0031         ValueSizeInBits(ValueSizeInBits), AtomicAlign(AtomicAlign),
0032         ValueAlign(ValueAlign), UseLibcall(UseLibcall) {}
0033 
0034   virtual ~AtomicInfo() = default;
0035 
0036   Align getAtomicAlignment() const { return AtomicAlign; }
0037   uint64_t getAtomicSizeInBits() const { return AtomicSizeInBits; }
0038   uint64_t getValueSizeInBits() const { return ValueSizeInBits; }
0039   bool shouldUseLibcall() const { return UseLibcall; }
0040   Type *getAtomicTy() const { return Ty; }
0041 
0042   virtual Value *getAtomicPointer() const = 0;
0043   virtual void decorateWithTBAA(Instruction *I) = 0;
0044   virtual AllocaInst *CreateAlloca(Type *Ty, const Twine &Name) const = 0;
0045 
0046   /*
0047    * Is the atomic size larger than the underlying value type?
0048    * Note that the absence of padding does not mean that atomic
0049    * objects are completely interchangeable with non-atomic
0050    * objects: we might have promoted the alignment of a type
0051    * without making it bigger.
0052    */
0053   bool hasPadding() const { return (ValueSizeInBits != AtomicSizeInBits); }
0054 
0055   LLVMContext &getLLVMContext() const { return Builder->getContext(); }
0056 
0057   bool shouldCastToInt(Type *ValTy, bool CmpXchg);
0058 
0059   Value *EmitAtomicLoadOp(AtomicOrdering AO, bool IsVolatile,
0060                           bool CmpXchg = false);
0061 
0062   CallInst *EmitAtomicLibcall(StringRef fnName, Type *ResultType,
0063                               ArrayRef<Value *> Args);
0064 
0065   Value *getAtomicSizeValue() const {
0066     LLVMContext &ctx = getLLVMContext();
0067     // TODO: Get from llvm::TargetMachine / clang::TargetInfo
0068     // if clang shares this codegen in future
0069     constexpr uint16_t SizeTBits = 64;
0070     constexpr uint16_t BitsPerByte = 8;
0071     return ConstantInt::get(IntegerType::get(ctx, SizeTBits),
0072                             AtomicSizeInBits / BitsPerByte);
0073   }
0074 
0075   std::pair<Value *, Value *>
0076   EmitAtomicCompareExchangeLibcall(Value *ExpectedVal, Value *DesiredVal,
0077                                    AtomicOrdering Success,
0078                                    AtomicOrdering Failure);
0079 
0080   Value *castToAtomicIntPointer(Value *addr) const {
0081     return addr; // opaque pointer
0082   }
0083 
0084   Value *getAtomicAddressAsAtomicIntPointer() const {
0085     return castToAtomicIntPointer(getAtomicPointer());
0086   }
0087 
0088   std::pair<Value *, Value *>
0089   EmitAtomicCompareExchangeOp(Value *ExpectedVal, Value *DesiredVal,
0090                               AtomicOrdering Success, AtomicOrdering Failure,
0091                               bool IsVolatile = false, bool IsWeak = false);
0092 
0093   std::pair<Value *, Value *>
0094   EmitAtomicCompareExchange(Value *ExpectedVal, Value *DesiredVal,
0095                             AtomicOrdering Success, AtomicOrdering Failure,
0096                             bool IsVolatile, bool IsWeak);
0097 
0098   std::pair<LoadInst *, AllocaInst *> EmitAtomicLoadLibcall(AtomicOrdering AO);
0099 };
0100 } // end namespace llvm
0101 
0102 #endif /* LLVM_FRONTEND_ATOMIC_ATOMIC_H */