LLVM  3.7.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 void AssumptionCache::scanFunction() {
28  assert(!Scanned && "Tried to scan the function twice!");
29  assert(AssumeHandles.empty() && "Already have assumes when scanning!");
30 
31  // Go through all instructions in all blocks, add all calls to @llvm.assume
32  // to this cache.
33  for (BasicBlock &B : F)
34  for (Instruction &II : B)
35  if (match(&II, m_Intrinsic<Intrinsic::assume>()))
36  AssumeHandles.push_back(&II);
37 
38  // Mark the scan as complete.
39  Scanned = true;
40 }
41 
43  assert(match(CI, m_Intrinsic<Intrinsic::assume>()) &&
44  "Registered call does not call @llvm.assume");
45 
46  // If we haven't scanned the function yet, just drop this assumption. It will
47  // be found when we scan later.
48  if (!Scanned)
49  return;
50 
51  AssumeHandles.push_back(CI);
52 
53 #ifndef NDEBUG
54  assert(CI->getParent() &&
55  "Cannot register @llvm.assume call not in a basic block");
56  assert(&F == CI->getParent()->getParent() &&
57  "Cannot register @llvm.assume call not in this function");
58 
59  // We expect the number of assumptions to be small, so in an asserts build
60  // check that we don't accumulate duplicates and that all assumptions point
61  // to the same function.
62  SmallPtrSet<Value *, 16> AssumptionSet;
63  for (auto &VH : AssumeHandles) {
64  if (!VH)
65  continue;
66 
67  assert(&F == cast<Instruction>(VH)->getParent()->getParent() &&
68  "Cached assumption not inside this function!");
69  assert(match(cast<CallInst>(VH), m_Intrinsic<Intrinsic::assume>()) &&
70  "Cached something other than a call to @llvm.assume!");
71  assert(AssumptionSet.insert(VH).second &&
72  "Cache contains multiple copies of a call!");
73  }
74 #endif
75 }
76 
77 char AssumptionAnalysis::PassID;
78 
82 
83  OS << "Cached assumptions for function: " << F.getName() << "\n";
84  for (auto &VH : AC.assumptions())
85  if (VH)
86  OS << " " << *cast<CallInst>(VH)->getArgOperand(0) << "\n";
87 
88  return PreservedAnalyses::all();
89 }
90 
91 void AssumptionCacheTracker::FunctionCallbackVH::deleted() {
92  auto I = ACT->AssumptionCaches.find_as(cast<Function>(getValPtr()));
93  if (I != ACT->AssumptionCaches.end())
94  ACT->AssumptionCaches.erase(I);
95  // 'this' now dangles!
96 }
97 
99  // We probe the function map twice to try and avoid creating a value handle
100  // around the function in common cases. This makes insertion a bit slower,
101  // but if we have to insert we're going to scan the whole function so that
102  // shouldn't matter.
103  auto I = AssumptionCaches.find_as(&F);
104  if (I != AssumptionCaches.end())
105  return *I->second;
106 
107  // Ok, build a new cache by scanning the function, insert it and the value
108  // handle into our map, and return the newly populated cache.
109  auto IP = AssumptionCaches.insert(std::make_pair(
110  FunctionCallbackVH(&F, this), llvm::make_unique<AssumptionCache>(F)));
111  assert(IP.second && "Scanning function already in the map?");
112  return *IP.first->second;
113 }
114 
116 #ifndef NDEBUG
117  SmallPtrSet<const CallInst *, 4> AssumptionSet;
118  for (const auto &I : AssumptionCaches) {
119  for (auto &VH : I.second->assumptions())
120  if (VH)
121  AssumptionSet.insert(cast<CallInst>(VH));
122 
123  for (const BasicBlock &B : cast<Function>(*I.first))
124  for (const Instruction &II : B)
125  if (match(&II, m_Intrinsic<Intrinsic::assume>()))
126  assert(AssumptionSet.count(cast<CallInst>(&II)) &&
127  "Assumption in scanned function not in cache");
128  }
129 #endif
130 }
131 
134 }
135 
137 
138 INITIALIZE_PASS(AssumptionCacheTracker, "assumption-cache-tracker",
139  "Assumption Cache Tracker", false, true)
140 char AssumptionCacheTracker::ID = 0;
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
CallInst - 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:276
An immutable pass that tracks lazily created AssumptionCache objects.
A cache of .assume calls within a function.
const Function * getParent() const
Return the enclosing method, or null if none.
Definition: BasicBlock.h:111
F(f)
StringRef getName() const
Return a constant reference to the value's name.
Definition: Value.cpp:188
bool match(Val *V, const Pattern &P)
Definition: PatternMatch.h:41
An abstract set of preserved analyses following a transformation pass run.
Definition: PassManager.h:69
LLVM Basic Block Representation.
Definition: BasicBlock.h:65
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:264
MutableArrayRef< WeakVH > assumptions()
Access the list of assumption handles currently tracked for this fuction.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: PassManager.h:91
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
Definition: PassSupport.h:56
A function analysis which provides an AssumptionCache.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements...
Definition: SmallPtrSet.h:299
ImmutablePass class - This class is used to provide information that does not need to be run...
Definition: Pass.h:262
PassT::Result & getResult(IRUnitT &IR)
Get the result of an analysis pass for this module.
Definition: PassManager.h:311
void registerAssumption(CallInst *CI)
Add an .assume intrinsic to this function's cache.
#define I(x, y, z)
Definition: MD5.cpp:54
PreservedAnalyses run(Function &F, AnalysisManager< Function > *AM)
static const Function * getParent(const Value *V)
AssumptionCache & getAssumptionCache(Function &F)
Get the cached assumptions for a function.
A generic analysis pass manager with lazy running and caching of 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.
const BasicBlock * getParent() const
Definition: Instruction.h:72