34 if ((
X == AtomicOrdering::Acquire &&
Y == AtomicOrdering::Release) ||
35 (
Y == AtomicOrdering::Acquire &&
X == AtomicOrdering::Release))
36 return AtomicOrdering::AcquireRelease;
47 while (!Worklist.
empty()) {
51 if (isa<GlobalValue>(
C) || isa<ConstantData>(
C))
54 for (
const User *U :
C->users()) {
55 if (
const Constant *
CU = dyn_cast<Constant>(U))
67 if (GV->isExternallyInitialized())
70 for (
const Use &U : V->uses()) {
71 const User *UR = U.getUser();
72 if (
const Constant *
C = dyn_cast<Constant>(UR)) {
74 if (CE && isa<PointerType>(CE->getType())) {
84 }
else if (
const Instruction *
I = dyn_cast<Instruction>(UR)) {
85 if (!GS.HasMultipleAccessingFunctions) {
86 const Function *
F =
I->getParent()->getParent();
87 if (!GS.AccessingFunction)
88 GS.AccessingFunction =
F;
89 else if (GS.AccessingFunction !=
F)
90 GS.HasMultipleAccessingFunctions =
true;
92 if (
const LoadInst *LI = dyn_cast<LoadInst>(
I)) {
98 }
else if (
const StoreInst *SI = dyn_cast<StoreInst>(
I)) {
100 if (SI->getOperand(0) == V)
104 if (SI->isVolatile())
115 const Value *
Ptr = SI->getPointerOperand()->stripPointerCasts();
117 Value *StoredVal = SI->getOperand(0);
119 if (
Constant *
C = dyn_cast<Constant>(StoredVal)) {
120 if (
C->isThreadDependent()) {
126 if (GV->hasInitializer() && StoredVal == GV->getInitializer()) {
129 }
else if (isa<LoadInst>(StoredVal) &&
130 cast<LoadInst>(StoredVal)->getOperand(0) == GV) {
135 GS.StoredOnceStore = SI;
137 GS.getStoredOnceValue() == StoredVal) {
146 }
else if (isa<GetElementPtrInst>(
I) || isa<AddrSpaceCastInst>(
I)) {
151 }
else if (isa<SelectInst>(
I) || isa<PHINode>(
I)) {
156 if (VisitedUsers.
insert(
I).second)
159 }
else if (isa<CmpInst>(
I)) {
160 GS.IsCompared =
true;
162 if (MTI->isVolatile())
164 if (MTI->getArgOperand(0) == V)
166 if (MTI->getArgOperand(1) == V)
168 }
else if (
const MemSetInst *MSI = dyn_cast<MemSetInst>(
I)) {
169 assert(MSI->getArgOperand(0) == V &&
"Memset only takes one pointer!");
170 if (MSI->isVolatile())
173 }
else if (
const auto *CB = dyn_cast<CallBase>(
I)) {
174 if (CB->getIntrinsicID() == Intrinsic::threadlocal_address) {
178 if (!CB->isCallee(&U))
Atomic ordering constants.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
static bool analyzeGlobalAux(const Value *V, GlobalStatus &GS, SmallPtrSetImpl< const Value * > &VisitedUsers)
static AtomicOrdering strongerOrdering(AtomicOrdering X, AtomicOrdering Y)
Return the stronger of the two ordering.
This defines the Use class.
static GCMetadataPrinterRegistry::Add< OcamlGCMetadataPrinter > Y("ocaml", "ocaml 3.10-compatible collector")
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file defines the SmallPtrSet class.
A constant value that is initialized with an expression using other constant values.
This is an important base class in LLVM.
An instruction for reading from memory.
This class wraps the llvm.memset and llvm.memset.inline intrinsics.
This class wraps the llvm.memcpy/memmove intrinsics.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
A Use represents the edge between a Value definition and its users.
LLVM Value Representation.
@ C
The default llvm calling convention, compatible with C.
This is an optimization pass for GlobalISel generic memory operations.
bool isSafeToDestroyConstant(const Constant *C)
It is safe to destroy a constant iff it is only used by constants itself.
AtomicOrdering
Atomic ordering for LLVM's memory model.
As we analyze each global or thread-local variable, keep track of some information about it.
@ Stored
This global is stored to by multiple values or something else that we cannot track.
@ InitializerStored
This global is stored to, but the only thing stored is the constant it was initialized with.
@ StoredOnce
This global is stored to, but only its initializer and one other value is ever stored to it.
static bool analyzeGlobal(const Value *V, GlobalStatus &GS)
Look at all uses of the global and fill in the GlobalStatus structure.