1 //===-- GlobalStatus.cpp - Compute status info for globals -----------------==//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "llvm/ADT/SmallPtrSet.h"
11 #include "llvm/IR/BasicBlock.h"
12 #include "llvm/IR/CallSite.h"
13 #include "llvm/IR/GlobalVariable.h"
14 #include "llvm/IR/IntrinsicInst.h"
15 #include "llvm/Transforms/Utils/GlobalStatus.h"
19 /// Return the stronger of the two ordering. If the two orderings are acquire
20 /// and release, then return AcquireRelease.
22 static AtomicOrdering
strongerOrdering(AtomicOrdering X
, AtomicOrdering Y
) {
23 if (X
== Acquire
&& Y
== Release
)
24 return AcquireRelease
;
25 if (Y
== Acquire
&& X
== Release
)
26 return AcquireRelease
;
27 return (AtomicOrdering
)std::max(X
, Y
);
30 /// It is safe to destroy a constant iff it is only used by constants itself.
31 /// Note that constants cannot be cyclic, so this test is pretty easy to
32 /// implement recursively.
34 bool llvm::isSafeToDestroyConstant(const Constant
*C
) {
35 if (isa
<GlobalValue
>(C
))
38 if (isa
<ConstantInt
>(C
) || isa
<ConstantFP
>(C
))
41 for (const User
*U
: C
->users())
42 if (const Constant
*CU
= dyn_cast
<Constant
>(U
)) {
43 if (!isSafeToDestroyConstant(CU
))
50 static bool analyzeGlobalAux(const Value
*V
, GlobalStatus
&GS
,
51 SmallPtrSetImpl
<const PHINode
*> &PhiUsers
) {
52 for (const Use
&U
: V
->uses()) {
53 const User
*UR
= U
.getUser();
54 if (const ConstantExpr
*CE
= dyn_cast
<ConstantExpr
>(UR
)) {
55 GS
.HasNonInstructionUser
= true;
57 // If the result of the constantexpr isn't pointer type, then we won't
58 // know to expect it in various places. Just reject early.
59 if (!isa
<PointerType
>(CE
->getType()))
62 if (analyzeGlobalAux(CE
, GS
, PhiUsers
))
64 } else if (const Instruction
*I
= dyn_cast
<Instruction
>(UR
)) {
65 if (!GS
.HasMultipleAccessingFunctions
) {
66 const Function
*F
= I
->getParent()->getParent();
67 if (!GS
.AccessingFunction
)
68 GS
.AccessingFunction
= F
;
69 else if (GS
.AccessingFunction
!= F
)
70 GS
.HasMultipleAccessingFunctions
= true;
72 if (const LoadInst
*LI
= dyn_cast
<LoadInst
>(I
)) {
74 // Don't hack on volatile loads.
77 GS
.Ordering
= strongerOrdering(GS
.Ordering
, LI
->getOrdering());
78 } else if (const StoreInst
*SI
= dyn_cast
<StoreInst
>(I
)) {
79 // Don't allow a store OF the address, only stores TO the address.
80 if (SI
->getOperand(0) == V
)
83 // Don't hack on volatile stores.
87 GS
.Ordering
= strongerOrdering(GS
.Ordering
, SI
->getOrdering());
89 // If this is a direct store to the global (i.e., the global is a scalar
90 // value, not an aggregate), keep more specific information about
92 if (GS
.StoredType
!= GlobalStatus::Stored
) {
93 if (const GlobalVariable
*GV
=
94 dyn_cast
<GlobalVariable
>(SI
->getOperand(1))) {
95 Value
*StoredVal
= SI
->getOperand(0);
97 if (Constant
*C
= dyn_cast
<Constant
>(StoredVal
)) {
98 if (C
->isThreadDependent()) {
99 // The stored value changes between threads; don't track it.
104 if (StoredVal
== GV
->getInitializer()) {
105 if (GS
.StoredType
< GlobalStatus::InitializerStored
)
106 GS
.StoredType
= GlobalStatus::InitializerStored
;
107 } else if (isa
<LoadInst
>(StoredVal
) &&
108 cast
<LoadInst
>(StoredVal
)->getOperand(0) == GV
) {
109 if (GS
.StoredType
< GlobalStatus::InitializerStored
)
110 GS
.StoredType
= GlobalStatus::InitializerStored
;
111 } else if (GS
.StoredType
< GlobalStatus::StoredOnce
) {
112 GS
.StoredType
= GlobalStatus::StoredOnce
;
113 GS
.StoredOnceValue
= StoredVal
;
114 } else if (GS
.StoredType
== GlobalStatus::StoredOnce
&&
115 GS
.StoredOnceValue
== StoredVal
) {
118 GS
.StoredType
= GlobalStatus::Stored
;
121 GS
.StoredType
= GlobalStatus::Stored
;
124 } else if (isa
<BitCastInst
>(I
)) {
125 if (analyzeGlobalAux(I
, GS
, PhiUsers
))
127 } else if (isa
<GetElementPtrInst
>(I
)) {
128 if (analyzeGlobalAux(I
, GS
, PhiUsers
))
130 } else if (isa
<SelectInst
>(I
)) {
131 if (analyzeGlobalAux(I
, GS
, PhiUsers
))
133 } else if (const PHINode
*PN
= dyn_cast
<PHINode
>(I
)) {
134 // PHI nodes we can check just like select or GEP instructions, but we
135 // have to be careful about infinite recursion.
136 if (PhiUsers
.insert(PN
).second
) // Not already visited.
137 if (analyzeGlobalAux(I
, GS
, PhiUsers
))
139 } else if (isa
<CmpInst
>(I
)) {
140 GS
.IsCompared
= true;
141 } else if (const MemTransferInst
*MTI
= dyn_cast
<MemTransferInst
>(I
)) {
142 if (MTI
->isVolatile())
144 if (MTI
->getArgOperand(0) == V
)
145 GS
.StoredType
= GlobalStatus::Stored
;
146 if (MTI
->getArgOperand(1) == V
)
148 } else if (const MemSetInst
*MSI
= dyn_cast
<MemSetInst
>(I
)) {
149 assert(MSI
->getArgOperand(0) == V
&& "Memset only takes one pointer!");
150 if (MSI
->isVolatile())
152 GS
.StoredType
= GlobalStatus::Stored
;
153 } else if (ImmutableCallSite C
= I
) {
158 return true; // Any other non-load instruction might take address!
160 } else if (const Constant
*C
= dyn_cast
<Constant
>(UR
)) {
161 GS
.HasNonInstructionUser
= true;
162 // We might have a dead and dangling constant hanging off of here.
163 if (!isSafeToDestroyConstant(C
))
166 GS
.HasNonInstructionUser
= true;
167 // Otherwise must be some other user.
175 bool GlobalStatus::analyzeGlobal(const Value
*V
, GlobalStatus
&GS
) {
176 SmallPtrSet
<const PHINode
*, 16> PhiUsers
;
177 return analyzeGlobalAux(V
, GS
, PhiUsers
);
180 GlobalStatus::GlobalStatus()
181 : IsCompared(false), IsLoaded(false), StoredType(NotStored
),
182 StoredOnceValue(nullptr), AccessingFunction(nullptr),
183 HasMultipleAccessingFunctions(false), HasNonInstructionUser(false),
184 Ordering(NotAtomic
) {}