|
8 | 8 |
|
9 | 9 | #include "llvm/Transforms/Utils/GlobalStatus.h" |
10 | 10 | #include "llvm/ADT/SmallPtrSet.h" |
| 11 | +#include "llvm/Analysis/ValueTracking.h" |
11 | 12 | #include "llvm/IR/BasicBlock.h" |
12 | 13 | #include "llvm/IR/Constant.h" |
13 | 14 | #include "llvm/IR/Constants.h" |
|
17 | 18 | #include "llvm/IR/Instruction.h" |
18 | 19 | #include "llvm/IR/Instructions.h" |
19 | 20 | #include "llvm/IR/IntrinsicInst.h" |
| 21 | +#include "llvm/IR/PatternMatch.h" |
20 | 22 | #include "llvm/IR/Use.h" |
21 | 23 | #include "llvm/IR/User.h" |
22 | 24 | #include "llvm/IR/Value.h" |
|
26 | 28 | #include <cassert> |
27 | 29 |
|
28 | 30 | using namespace llvm; |
| 31 | +using namespace llvm::PatternMatch; |
29 | 32 |
|
30 | 33 | /// Return the stronger of the two ordering. If the two orderings are acquire |
31 | 34 | /// and release, then return AcquireRelease. |
@@ -61,45 +64,6 @@ bool llvm::isSafeToDestroyConstant(const Constant *C) { |
61 | 64 | return true; |
62 | 65 | } |
63 | 66 |
|
64 | | -static bool |
65 | | -maybePointerToDifferentObjectRecursive(Value *V, |
66 | | - SmallPtrSetImpl<Value *> &Visited) { |
67 | | - if (!Visited.insert(V).second) |
68 | | - return false; |
69 | | - |
70 | | - if (Visited.size() > 32) |
71 | | - return true; |
72 | | - |
73 | | - // PtrToInt may be used to construct a pointer to a different object. Loads |
74 | | - // and calls may return a pointer for a different object. |
75 | | - if (isa<PtrToIntInst, LoadInst, CallInst>(V)) |
76 | | - return true; |
77 | | - |
78 | | - if (auto *CE = dyn_cast<ConstantExpr>(V)) { |
79 | | - if (CE->getOpcode() == Instruction::PtrToInt) |
80 | | - return true; |
81 | | - |
82 | | - for (auto &Op : CE->operands()) { |
83 | | - if (maybePointerToDifferentObjectRecursive(Op.get(), Visited)) |
84 | | - return true; |
85 | | - } |
86 | | - return false; |
87 | | - } |
88 | | - |
89 | | - if (auto *U = dyn_cast<User>(V)) { |
90 | | - for (auto &Op : U->operands()) { |
91 | | - if (maybePointerToDifferentObjectRecursive(Op.get(), Visited)) |
92 | | - return true; |
93 | | - } |
94 | | - } |
95 | | - return false; |
96 | | -} |
97 | | - |
98 | | -bool maybePointerToDifferentObject(Value *V) { |
99 | | - SmallPtrSet<Value *, 32> Visited; |
100 | | - return maybePointerToDifferentObjectRecursive(V, Visited); |
101 | | -} |
102 | | - |
103 | 67 | static bool analyzeGlobalAux(const Value *V, GlobalStatus &GS, |
104 | 68 | SmallPtrSetImpl<const Value *> &VisitedUsers) { |
105 | 69 | if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(V)) |
@@ -198,10 +162,15 @@ static bool analyzeGlobalAux(const Value *V, GlobalStatus &GS, |
198 | 162 | } else if (isa<CmpInst>(I)) { |
199 | 163 | GS.IsCompared = true; |
200 | 164 |
|
201 | | - if (VisitedUsers.insert(I).second) { |
202 | | - for (Value *Op : I->operands()) |
203 | | - if (Op != V && maybePointerToDifferentObject(Op)) |
204 | | - return true; |
| 165 | + const Value *UO = nullptr; |
| 166 | + for (Value *Op : I->operands()) { |
| 167 | + if (match(Op, m_Zero())) |
| 168 | + continue; |
| 169 | + const Value *OpUO = getUnderlyingObject(Op); |
| 170 | + if (!UO) |
| 171 | + UO = OpUO; |
| 172 | + if (!OpUO || UO != OpUO) |
| 173 | + return true; |
205 | 174 | } |
206 | 175 | } else if (const MemTransferInst *MTI = dyn_cast<MemTransferInst>(I)) { |
207 | 176 | if (MTI->isVolatile()) |
|
0 commit comments