#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLFunctionalExtras.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/InstSimplifyFolder.h"
#include "llvm/Analysis/OptimizationRemarkEmitter.h"
#include "llvm/CodeGen/AtomicExpand.h"
#include "llvm/CodeGen/AtomicExpandUtils.h"
#include "llvm/CodeGen/RuntimeLibcallUtil.h"
#include "llvm/CodeGen/TargetLowering.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/IR/Attributes.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/InstIterator.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/MemoryModelRelaxationAnnotations.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/User.h"
#include "llvm/IR/Value.h"
#include "llvm/InitializePasses.h"
#include "llvm/Pass.h"
#include "llvm/Support/AtomicOrdering.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Transforms/Utils/LowerAtomic.h"
#include <cassert>
#include <cstdint>
#include <iterator>
usingnamespacellvm;
#define DEBUG_TYPE …
namespace {
class AtomicExpandImpl { … };
class AtomicExpandLegacy : public FunctionPass { … };
struct ReplacementIRBuilder
: IRBuilder<InstSimplifyFolder, IRBuilderCallbackInserter> { … };
}
char AtomicExpandLegacy::ID = …;
char &llvm::AtomicExpandID = …;
INITIALIZE_PASS_BEGIN(AtomicExpandLegacy, DEBUG_TYPE,
"Expand Atomic instructions", false, false)
INITIALIZE_PASS_DEPENDENCY(TargetPassConfig)
INITIALIZE_PASS_END(AtomicExpandLegacy, DEBUG_TYPE,
"Expand Atomic instructions", false, false)
static unsigned getAtomicOpSize(LoadInst *LI) { … }
static unsigned getAtomicOpSize(StoreInst *SI) { … }
static unsigned getAtomicOpSize(AtomicRMWInst *RMWI) { … }
static unsigned getAtomicOpSize(AtomicCmpXchgInst *CASI) { … }
template <typename Inst>
static bool atomicSizeSupported(const TargetLowering *TLI, Inst *I) { … }
bool AtomicExpandImpl::processAtomicInstr(Instruction *I) { … }
bool AtomicExpandImpl::run(Function &F, const TargetMachine *TM) { … }
bool AtomicExpandLegacy::runOnFunction(Function &F) { … }
FunctionPass *llvm::createAtomicExpandLegacyPass() { … }
PreservedAnalyses AtomicExpandPass::run(Function &F,
FunctionAnalysisManager &AM) { … }
bool AtomicExpandImpl::bracketInstWithFences(Instruction *I,
AtomicOrdering Order) { … }
IntegerType *
AtomicExpandImpl::getCorrespondingIntegerType(Type *T, const DataLayout &DL) { … }
LoadInst *AtomicExpandImpl::convertAtomicLoadToIntegerType(LoadInst *LI) { … }
AtomicRMWInst *
AtomicExpandImpl::convertAtomicXchgToIntegerType(AtomicRMWInst *RMWI) { … }
bool AtomicExpandImpl::tryExpandAtomicLoad(LoadInst *LI) { … }
bool AtomicExpandImpl::tryExpandAtomicStore(StoreInst *SI) { … }
bool AtomicExpandImpl::expandAtomicLoadToLL(LoadInst *LI) { … }
bool AtomicExpandImpl::expandAtomicLoadToCmpXchg(LoadInst *LI) { … }
StoreInst *AtomicExpandImpl::convertAtomicStoreToIntegerType(StoreInst *SI) { … }
void AtomicExpandImpl::expandAtomicStore(StoreInst *SI) { … }
static void createCmpXchgInstFun(IRBuilderBase &Builder, Value *Addr,
Value *Loaded, Value *NewVal, Align AddrAlign,
AtomicOrdering MemOpOrder, SyncScope::ID SSID,
Value *&Success, Value *&NewLoaded) { … }
bool AtomicExpandImpl::tryExpandAtomicRMW(AtomicRMWInst *AI) { … }
namespace {
struct PartwordMaskValues { … };
LLVM_ATTRIBUTE_UNUSED
raw_ostream &operator<<(raw_ostream &O, const PartwordMaskValues &PMV) { … }
}
static PartwordMaskValues createMaskInstrs(IRBuilderBase &Builder,
Instruction *I, Type *ValueType,
Value *Addr, Align AddrAlign,
unsigned MinWordSize) { … }
static Value *extractMaskedValue(IRBuilderBase &Builder, Value *WideWord,
const PartwordMaskValues &PMV) { … }
static Value *insertMaskedValue(IRBuilderBase &Builder, Value *WideWord,
Value *Updated, const PartwordMaskValues &PMV) { … }
static Value *performMaskedAtomicOp(AtomicRMWInst::BinOp Op,
IRBuilderBase &Builder, Value *Loaded,
Value *Shifted_Inc, Value *Inc,
const PartwordMaskValues &PMV) { … }
void AtomicExpandImpl::expandPartwordAtomicRMW(
AtomicRMWInst *AI, TargetLoweringBase::AtomicExpansionKind ExpansionKind) { … }
static void copyMetadataForAtomic(Instruction &Dest,
const Instruction &Source) { … }
AtomicRMWInst *AtomicExpandImpl::widenPartwordAtomicRMW(AtomicRMWInst *AI) { … }
bool AtomicExpandImpl::expandPartwordCmpXchg(AtomicCmpXchgInst *CI) { … }
void AtomicExpandImpl::expandAtomicOpToLLSC(
Instruction *I, Type *ResultType, Value *Addr, Align AddrAlign,
AtomicOrdering MemOpOrder,
function_ref<Value *(IRBuilderBase &, Value *)> PerformOp) { … }
void AtomicExpandImpl::expandAtomicRMWToMaskedIntrinsic(AtomicRMWInst *AI) { … }
void AtomicExpandImpl::expandAtomicCmpXchgToMaskedIntrinsic(
AtomicCmpXchgInst *CI) { … }
Value *AtomicExpandImpl::insertRMWLLSCLoop(
IRBuilderBase &Builder, Type *ResultTy, Value *Addr, Align AddrAlign,
AtomicOrdering MemOpOrder,
function_ref<Value *(IRBuilderBase &, Value *)> PerformOp) { … }
AtomicCmpXchgInst *
AtomicExpandImpl::convertCmpXchgToIntegerType(AtomicCmpXchgInst *CI) { … }
bool AtomicExpandImpl::expandAtomicCmpXchg(AtomicCmpXchgInst *CI) { … }
bool AtomicExpandImpl::isIdempotentRMW(AtomicRMWInst *RMWI) { … }
bool AtomicExpandImpl::simplifyIdempotentRMW(AtomicRMWInst *RMWI) { … }
Value *AtomicExpandImpl::insertRMWCmpXchgLoop(
IRBuilderBase &Builder, Type *ResultTy, Value *Addr, Align AddrAlign,
AtomicOrdering MemOpOrder, SyncScope::ID SSID,
function_ref<Value *(IRBuilderBase &, Value *)> PerformOp,
CreateCmpXchgInstFun CreateCmpXchg) { … }
bool AtomicExpandImpl::tryExpandAtomicCmpXchg(AtomicCmpXchgInst *CI) { … }
bool llvm::expandAtomicRMWToCmpXchg(AtomicRMWInst *AI,
CreateCmpXchgInstFun CreateCmpXchg) { … }
static bool canUseSizedAtomicCall(unsigned Size, Align Alignment,
const DataLayout &DL) { … }
void AtomicExpandImpl::expandAtomicLoadToLibcall(LoadInst *I) { … }
void AtomicExpandImpl::expandAtomicStoreToLibcall(StoreInst *I) { … }
void AtomicExpandImpl::expandAtomicCASToLibcall(AtomicCmpXchgInst *I) { … }
static ArrayRef<RTLIB::Libcall> GetRMWLibcall(AtomicRMWInst::BinOp Op) { … }
void AtomicExpandImpl::expandAtomicRMWToLibcall(AtomicRMWInst *I) { … }
bool AtomicExpandImpl::expandAtomicOpToLibcall(
Instruction *I, unsigned Size, Align Alignment, Value *PointerOperand,
Value *ValueOperand, Value *CASExpected, AtomicOrdering Ordering,
AtomicOrdering Ordering2, ArrayRef<RTLIB::Libcall> Libcalls) { … }