1 //===- llvm/Analysis/AssumptionTracker.h - Track @llvm.assume ---*- C++ -*-===//
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 // This file contains a pass that keeps track of @llvm.assume intrinsics in
11 // the functions of a module (allowing assumptions within any function to be
12 // found cheaply by other parts of the optimizer).
14 //===----------------------------------------------------------------------===//
16 #ifndef LLVM_ANALYSIS_ASSUMPTIONTRACKER_H
17 #define LLVM_ANALYSIS_ASSUMPTIONTRACKER_H
19 #include "llvm/ADT/DenseMap.h"
20 #include "llvm/ADT/DenseSet.h"
21 #include "llvm/ADT/SmallSet.h"
22 #include "llvm/IR/Function.h"
23 #include "llvm/IR/Instructions.h"
24 #include "llvm/IR/ValueHandle.h"
25 #include "llvm/Pass.h"
30 /// An immutable pass that tracks @llvm.assume intrinsics in a module.
31 class AssumptionTracker
: public ImmutablePass
{
32 /// A callback value handle applied to function objects, which we use to
33 /// delete our cache of intrinsics for a function when it is deleted.
34 class FunctionCallbackVH
: public CallbackVH
{
35 AssumptionTracker
*AT
;
36 void deleted() override
;
39 typedef DenseMapInfo
<Value
*> DMI
;
41 FunctionCallbackVH(Value
*V
, AssumptionTracker
*AT
= nullptr)
42 : CallbackVH(V
), AT(AT
) {}
45 /// A callback value handle applied to call instructions, which keeps
46 /// track of the call's parent function so that we can remove a
47 /// assumption intrinsic call from our cache when the instruction is
49 class CallCallbackVH
: public CallbackVH
{
50 AssumptionTracker
*AT
;
51 void deleted() override
;
53 // We store the function here because we need it to lookup the set
54 // containing this handle when the underlying CallInst is being deleted.
58 typedef DenseMapInfo
<Instruction
*> DMI
;
60 CallCallbackVH(Instruction
*I
, AssumptionTracker
*AT
= nullptr)
61 : CallbackVH(I
), AT(AT
), F(nullptr) {
62 if (I
!= DMI::getEmptyKey() && I
!= DMI::getTombstoneKey())
63 F
= I
->getParent()->getParent();
66 operator CallInst
*() const {
67 Value
*V
= getValPtr();
68 if (V
== DMI::getEmptyKey() || V
== DMI::getTombstoneKey())
69 return reinterpret_cast<CallInst
*>(V
);
71 return cast
<CallInst
>(V
);
74 CallInst
*operator->() const { return cast
<CallInst
>(getValPtr()); }
75 CallInst
&operator*() const { return *cast
<CallInst
>(getValPtr()); }
78 friend FunctionCallbackVH
;
79 friend CallCallbackVH
;
81 // FIXME: SmallSet might be better here, but it currently has no iterators.
82 typedef DenseSet
<CallCallbackVH
, CallCallbackVH::DMI
> CallHandleSet
;
83 typedef DenseMap
<FunctionCallbackVH
, std::unique_ptr
<CallHandleSet
>,
84 FunctionCallbackVH::DMI
> FunctionCallsMap
;
85 FunctionCallsMap CachedAssumeCalls
;
87 /// Scan the provided function for @llvm.assume intrinsic calls. Returns an
88 /// iterator to the set for this function in the CachedAssumeCalls map.
89 FunctionCallsMap::iterator
scanFunction(Function
*F
);
92 /// Remove the cache of @llvm.assume intrinsics for the given function.
93 void forgetCachedAssumptions(Function
*F
);
95 /// Add an @llvm.assume intrinsic to the cache for its parent function.
96 void registerAssumption(CallInst
*CI
);
98 typedef CallHandleSet::iterator assumption_iterator
;
99 typedef iterator_range
<assumption_iterator
> assumption_range
;
101 inline assumption_range
assumptions(Function
*F
) {
102 FunctionCallsMap::iterator I
= CachedAssumeCalls
.find(F
);
103 if (I
== CachedAssumeCalls
.end()) {
107 return assumption_range(I
->second
->begin(), I
->second
->end());
111 ~AssumptionTracker();
113 void releaseMemory() override
{
114 CachedAssumeCalls
.shrink_and_clear();
117 void verifyAnalysis() const override
;
118 bool doFinalization(Module
&) override
{
123 static char ID
; // Pass identification, replacement for typeid
126 } // end namespace llvm