LLVM  4.0.0
AssumptionCache.cpp
Go to the documentation of this file.
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 
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 
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,
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,
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 
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 
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 
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 
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 
250 }
251 
253 
254 INITIALIZE_PASS(AssumptionCacheTracker, "assumption-cache-tracker",
255  "Assumption Cache Tracker", false, true)
256 char AssumptionCacheTracker::ID = 0;
BinaryOp_match< LHS, RHS, Instruction::And > m_And(const LHS &L, const RHS &R)
Definition: PatternMatch.h:506
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
Definition: PatternMatch.h:64
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
DiagnosticInfoOptimizationBase::Argument NV
This class represents a function call, abstracting a target machine's calling convention.
size_type count(PtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
Definition: SmallPtrSet.h:380
An immutable pass that tracks lazily created AssumptionCache objects.
BinaryOp_match< LHS, RHS, Instruction::AShr > m_AShr(const LHS &L, const RHS &R)
Definition: PatternMatch.h:536
A cache of .assume calls within a function.
const Function * getParent() const
Return the enclosing method, or null if none.
Definition: BasicBlock.h:100
StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:191
bool match(Val *V, const Pattern &P)
Definition: PatternMatch.h:41
BinaryOp_match< LHS, RHS, Instruction::Xor > m_Xor(const LHS &L, const RHS &R)
Definition: PatternMatch.h:518
not_match< LHS > m_Not(const LHS &L)
Definition: PatternMatch.h:854
#define F(x, y, z)
Definition: MD5.cpp:51
match_combine_or< LTy, RTy > m_CombineOr(const LTy &L, const RTy &R)
Combine two pattern matchers matching L || R.
Definition: PatternMatch.h:117
class_match< ConstantInt > m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
Definition: PatternMatch.h:75
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
BinaryOp_match< LHS, RHS, Instruction::LShr > m_LShr(const LHS &L, const RHS &R)
Definition: PatternMatch.h:530
A set of analyses that are preserved following a run of a transformation pass.
Definition: PassManager.h:107
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs...ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Definition: PassManager.h:653
LLVM Basic Block Representation.
Definition: BasicBlock.h:51
BinaryOp_match< LHS, RHS, Instruction::Or > m_Or(const LHS &L, const RHS &R)
Definition: PatternMatch.h:512
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Definition: SmallPtrSet.h:368
BinaryOp_match< LHS, RHS, Instruction::Shl > m_Shl(const LHS &L, const RHS &R)
Definition: PatternMatch.h:524
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
Definition: InstrTypes.h:880
MutableArrayRef< WeakVH > assumptions()
Access the list of assumption handles currently tracked for this function.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: PassManager.h:113
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:36
A function analysis which provides an AssumptionCache.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
This is the shared class of boolean and integer constants.
Definition: Constants.h:88
ImmutablePass class - This class is used to provide information that does not need to be run...
Definition: Pass.h:266
auto find(R &&Range, const T &Val) -> decltype(std::begin(Range))
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:757
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:843
void updateAffectedValues(CallInst *CI)
Update the cache of values being affected by this assumption (i.e.
static GCRegistry::Add< ShadowStackGC > C("shadow-stack","Very portable GC for uncooperative code generators")
Value * getArgOperand(unsigned i) const
getArgOperand/setArgOperand - Return/set the i-th call argument.
iterator insert(iterator I, T &&Elt)
Definition: SmallVector.h:464
void registerAssumption(CallInst *CI)
Add an .assume intrinsic to this function's cache.
#define I(x, y, z)
Definition: MD5.cpp:54
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
Definition: Value.h:71
static const Function * getParent(const Value *V)
AssumptionCache & getAssumptionCache(Function &F)
Get the cached assumptions for a function.
A container for analyses that lazily runs them and caches their results.
void initializeAssumptionCacheTrackerPass(PassRegistry &)
void verifyAnalysis() const override
verifyAnalysis() - This member can be implemented by a analysis pass to check state of analysis infor...
This header defines various interfaces for pass management in LLVM.
static GCRegistry::Add< ErlangGC > A("erlang","erlang-compatible garbage collector")
A special type used by analysis passes to provide an address that identifies that particular analysis...
Definition: PassManager.h:64
const BasicBlock * getParent() const
Definition: Instruction.h:62
CmpClass_match< LHS, RHS, ICmpInst, ICmpInst::Predicate > m_ICmp(ICmpInst::Predicate &Pred, const LHS &L, const RHS &R)
Definition: PatternMatch.h:726