]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Analysis/AssumptionCache.cpp
Merge ^/head r313644 through r313895.
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Analysis / AssumptionCache.cpp
1 //===- AssumptionCache.cpp - Cache finding @llvm.assume calls -------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains a pass that keeps track of @llvm.assume intrinsics in
11 // the functions of a module.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #include "llvm/Analysis/AssumptionCache.h"
16 #include "llvm/IR/CallSite.h"
17 #include "llvm/IR/Dominators.h"
18 #include "llvm/IR/Function.h"
19 #include "llvm/IR/Instructions.h"
20 #include "llvm/IR/IntrinsicInst.h"
21 #include "llvm/IR/PassManager.h"
22 #include "llvm/IR/PatternMatch.h"
23 #include "llvm/Support/Debug.h"
24 using namespace llvm;
25 using namespace llvm::PatternMatch;
26
27 SmallVector<WeakVH, 1> &AssumptionCache::getOrInsertAffectedValues(Value *V) {
28   // Try using find_as first to avoid creating extra value handles just for the
29   // purpose of doing the lookup.
30   auto AVI = AffectedValues.find_as(V);
31   if (AVI != AffectedValues.end())
32     return AVI->second;
33
34   auto AVIP = AffectedValues.insert({
35       AffectedValueCallbackVH(V, this), SmallVector<WeakVH, 1>()});
36   return AVIP.first->second;
37 }
38
39 void AssumptionCache::updateAffectedValues(CallInst *CI) {
40   // Note: This code must be kept in-sync with the code in
41   // computeKnownBitsFromAssume in ValueTracking.
42
43   SmallVector<Value *, 16> Affected;
44   auto AddAffected = [&Affected](Value *V) {
45     if (isa<Argument>(V)) {
46       Affected.push_back(V);
47     } else if (auto *I = dyn_cast<Instruction>(V)) {
48       Affected.push_back(I);
49
50       if (I->getOpcode() == Instruction::BitCast ||
51           I->getOpcode() == Instruction::PtrToInt) {
52         auto *Op = I->getOperand(0);
53         if (isa<Instruction>(Op) || isa<Argument>(Op))
54           Affected.push_back(Op);
55       }
56     }
57   };
58
59   Value *Cond = CI->getArgOperand(0), *A, *B;
60   AddAffected(Cond);
61
62   CmpInst::Predicate Pred;
63   if (match(Cond, m_ICmp(Pred, m_Value(A), m_Value(B)))) {
64     AddAffected(A);
65     AddAffected(B);
66
67     if (Pred == ICmpInst::ICMP_EQ) {
68       // For equality comparisons, we handle the case of bit inversion.
69       auto AddAffectedFromEq = [&AddAffected](Value *V) {
70         Value *A;
71         if (match(V, m_Not(m_Value(A)))) {
72           AddAffected(A);
73           V = A;
74         }
75
76         Value *B;
77         ConstantInt *C;
78         // (A & B) or (A | B) or (A ^ B).
79         if (match(V,
80                   m_CombineOr(m_And(m_Value(A), m_Value(B)),
81                     m_CombineOr(m_Or(m_Value(A), m_Value(B)),
82                                 m_Xor(m_Value(A), m_Value(B)))))) {
83           AddAffected(A);
84           AddAffected(B);
85         // (A << C) or (A >>_s C) or (A >>_u C) where C is some constant.
86         } else if (match(V,
87                          m_CombineOr(m_Shl(m_Value(A), m_ConstantInt(C)),
88                            m_CombineOr(m_LShr(m_Value(A), m_ConstantInt(C)),
89                                        m_AShr(m_Value(A),
90                                               m_ConstantInt(C)))))) {
91           AddAffected(A);
92         }
93       };
94
95       AddAffectedFromEq(A);
96       AddAffectedFromEq(B);
97     }
98   }
99
100   for (auto &AV : Affected) {
101     auto &AVV = getOrInsertAffectedValues(AV);
102     if (std::find(AVV.begin(), AVV.end(), CI) == AVV.end())
103       AVV.push_back(CI);
104   }
105 }
106
107 void AssumptionCache::AffectedValueCallbackVH::deleted() {
108   auto AVI = AC->AffectedValues.find(getValPtr());
109   if (AVI != AC->AffectedValues.end())
110     AC->AffectedValues.erase(AVI);
111   // 'this' now dangles!
112 }
113
114 void AssumptionCache::copyAffectedValuesInCache(Value *OV, Value *NV) {
115   auto &NAVV = getOrInsertAffectedValues(NV);
116   auto AVI = AffectedValues.find(OV);
117   if (AVI == AffectedValues.end())
118     return;
119
120   for (auto &A : AVI->second)
121     if (std::find(NAVV.begin(), NAVV.end(), A) == NAVV.end())
122       NAVV.push_back(A);
123 }
124
125 void AssumptionCache::AffectedValueCallbackVH::allUsesReplacedWith(Value *NV) {
126   if (!isa<Instruction>(NV) && !isa<Argument>(NV))
127     return;
128
129   // Any assumptions that affected this value now affect the new value.
130
131   AC->copyAffectedValuesInCache(getValPtr(), NV);
132   // 'this' now might dangle! If the AffectedValues map was resized to add an
133   // entry for NV then this object might have been destroyed in favor of some
134   // copy in the grown map.
135 }
136
137 void AssumptionCache::scanFunction() {
138   assert(!Scanned && "Tried to scan the function twice!");
139   assert(AssumeHandles.empty() && "Already have assumes when scanning!");
140
141   // Go through all instructions in all blocks, add all calls to @llvm.assume
142   // to this cache.
143   for (BasicBlock &B : F)
144     for (Instruction &II : B)
145       if (match(&II, m_Intrinsic<Intrinsic::assume>()))
146         AssumeHandles.push_back(&II);
147
148   // Mark the scan as complete.
149   Scanned = true;
150
151   // Update affected values.
152   for (auto &A : AssumeHandles)
153     updateAffectedValues(cast<CallInst>(A));
154 }
155
156 void AssumptionCache::registerAssumption(CallInst *CI) {
157   assert(match(CI, m_Intrinsic<Intrinsic::assume>()) &&
158          "Registered call does not call @llvm.assume");
159
160   // If we haven't scanned the function yet, just drop this assumption. It will
161   // be found when we scan later.
162   if (!Scanned)
163     return;
164
165   AssumeHandles.push_back(CI);
166
167 #ifndef NDEBUG
168   assert(CI->getParent() &&
169          "Cannot register @llvm.assume call not in a basic block");
170   assert(&F == CI->getParent()->getParent() &&
171          "Cannot register @llvm.assume call not in this function");
172
173   // We expect the number of assumptions to be small, so in an asserts build
174   // check that we don't accumulate duplicates and that all assumptions point
175   // to the same function.
176   SmallPtrSet<Value *, 16> AssumptionSet;
177   for (auto &VH : AssumeHandles) {
178     if (!VH)
179       continue;
180
181     assert(&F == cast<Instruction>(VH)->getParent()->getParent() &&
182            "Cached assumption not inside this function!");
183     assert(match(cast<CallInst>(VH), m_Intrinsic<Intrinsic::assume>()) &&
184            "Cached something other than a call to @llvm.assume!");
185     assert(AssumptionSet.insert(VH).second &&
186            "Cache contains multiple copies of a call!");
187   }
188 #endif
189
190   updateAffectedValues(CI);
191 }
192
193 AnalysisKey AssumptionAnalysis::Key;
194
195 PreservedAnalyses AssumptionPrinterPass::run(Function &F,
196                                              FunctionAnalysisManager &AM) {
197   AssumptionCache &AC = AM.getResult<AssumptionAnalysis>(F);
198
199   OS << "Cached assumptions for function: " << F.getName() << "\n";
200   for (auto &VH : AC.assumptions())
201     if (VH)
202       OS << "  " << *cast<CallInst>(VH)->getArgOperand(0) << "\n";
203
204   return PreservedAnalyses::all();
205 }
206
207 void AssumptionCacheTracker::FunctionCallbackVH::deleted() {
208   auto I = ACT->AssumptionCaches.find_as(cast<Function>(getValPtr()));
209   if (I != ACT->AssumptionCaches.end())
210     ACT->AssumptionCaches.erase(I);
211   // 'this' now dangles!
212 }
213
214 AssumptionCache &AssumptionCacheTracker::getAssumptionCache(Function &F) {
215   // We probe the function map twice to try and avoid creating a value handle
216   // around the function in common cases. This makes insertion a bit slower,
217   // but if we have to insert we're going to scan the whole function so that
218   // shouldn't matter.
219   auto I = AssumptionCaches.find_as(&F);
220   if (I != AssumptionCaches.end())
221     return *I->second;
222
223   // Ok, build a new cache by scanning the function, insert it and the value
224   // handle into our map, and return the newly populated cache.
225   auto IP = AssumptionCaches.insert(std::make_pair(
226       FunctionCallbackVH(&F, this), llvm::make_unique<AssumptionCache>(F)));
227   assert(IP.second && "Scanning function already in the map?");
228   return *IP.first->second;
229 }
230
231 void AssumptionCacheTracker::verifyAnalysis() const {
232 #ifndef NDEBUG
233   SmallPtrSet<const CallInst *, 4> AssumptionSet;
234   for (const auto &I : AssumptionCaches) {
235     for (auto &VH : I.second->assumptions())
236       if (VH)
237         AssumptionSet.insert(cast<CallInst>(VH));
238
239     for (const BasicBlock &B : cast<Function>(*I.first))
240       for (const Instruction &II : B)
241         if (match(&II, m_Intrinsic<Intrinsic::assume>()))
242           assert(AssumptionSet.count(cast<CallInst>(&II)) &&
243                  "Assumption in scanned function not in cache");
244   }
245 #endif
246 }
247
248 AssumptionCacheTracker::AssumptionCacheTracker() : ImmutablePass(ID) {
249   initializeAssumptionCacheTrackerPass(*PassRegistry::getPassRegistry());
250 }
251
252 AssumptionCacheTracker::~AssumptionCacheTracker() {}
253
254 INITIALIZE_PASS(AssumptionCacheTracker, "assumption-cache-tracker",
255                 "Assumption Cache Tracker", false, true)
256 char AssumptionCacheTracker::ID = 0;