41 cl::desc(
"Enable verification of assumption cache"),
45 AssumptionCache::getOrInsertAffectedValues(
Value *V) {
48 auto AVI = AffectedValues.find_as(V);
49 if (AVI != AffectedValues.end())
52 auto AVIP = AffectedValues.
insert(
53 {AffectedValueCallbackVH(V, this), SmallVector<WeakTrackingVH, 1>()});
54 return AVIP.first->second;
62 auto AddAffected = [&Affected](
Value *V) {
63 if (isa<Argument>(V)) {
65 }
else if (
auto *
I = dyn_cast<Instruction>(V)) {
73 if (isa<Instruction>(Op) || isa<Argument>(Op))
89 auto AddAffectedFromEq = [&AddAffected](
Value *V) {
108 AddAffectedFromEq(A);
109 AddAffectedFromEq(B);
113 for (
auto &AV : Affected) {
114 auto &AVV = getOrInsertAffectedValues(AV);
115 if (
std::find(AVV.begin(), AVV.end(), CI) == AVV.end())
120 void AssumptionCache::AffectedValueCallbackVH::deleted() {
121 auto AVI = AC->AffectedValues.find(getValPtr());
122 if (AVI != AC->AffectedValues.end())
123 AC->AffectedValues.erase(AVI);
127 void AssumptionCache::copyAffectedValuesInCache(
Value *OV,
Value *
NV) {
128 auto &NAVV = getOrInsertAffectedValues(NV);
129 auto AVI = AffectedValues.find(OV);
130 if (AVI == AffectedValues.end())
133 for (
auto &A : AVI->second)
134 if (
std::find(NAVV.begin(), NAVV.end(), A) == NAVV.end())
138 void AssumptionCache::AffectedValueCallbackVH::allUsesReplacedWith(
Value *NV) {
139 if (!isa<Instruction>(NV) && !isa<Argument>(NV))
144 AC->copyAffectedValuesInCache(getValPtr(), NV);
150 void AssumptionCache::scanFunction() {
151 assert(!Scanned &&
"Tried to scan the function twice!");
152 assert(AssumeHandles.empty() &&
"Already have assumes when scanning!");
158 if (
match(&II, m_Intrinsic<Intrinsic::assume>()))
159 AssumeHandles.push_back(&II);
165 for (
auto &A : AssumeHandles)
166 updateAffectedValues(cast<CallInst>(A));
170 assert(
match(CI, m_Intrinsic<Intrinsic::assume>()) &&
171 "Registered call does not call @llvm.assume");
178 AssumeHandles.push_back(CI);
182 "Cannot register @llvm.assume call not in a basic block");
184 "Cannot register @llvm.assume call not in this function");
190 for (
auto &VH : AssumeHandles) {
195 "Cached assumption not inside this function!");
196 assert(
match(cast<CallInst>(VH), m_Intrinsic<Intrinsic::assume>()) &&
197 "Cached something other than a call to @llvm.assume!");
198 assert(AssumptionSet.insert(VH).second &&
199 "Cache contains multiple copies of a call!");
203 updateAffectedValues(CI);
212 OS <<
"Cached assumptions for function: " << F.
getName() <<
"\n";
215 OS <<
" " << *cast<CallInst>(VH)->getArgOperand(0) <<
"\n";
220 void AssumptionCacheTracker::FunctionCallbackVH::deleted() {
221 auto I = ACT->AssumptionCaches.find_as(cast<Function>(getValPtr()));
222 if (
I != ACT->AssumptionCaches.end())
223 ACT->AssumptionCaches.erase(
I);
232 auto I = AssumptionCaches.find_as(&F);
233 if (
I != AssumptionCaches.end())
238 auto IP = AssumptionCaches.insert(std::make_pair(
239 FunctionCallbackVH(&F,
this), llvm::make_unique<AssumptionCache>(F)));
240 assert(IP.second &&
"Scanning function already in the map?");
241 return *IP.first->second;
253 for (
const auto &
I : AssumptionCaches) {
254 for (
auto &VH :
I.second->assumptions())
256 AssumptionSet.
insert(cast<CallInst>(VH));
260 if (
match(&II, m_Intrinsic<Intrinsic::assume>()) &&
261 !AssumptionSet.
count(cast<CallInst>(&II)))
275 "Assumption Cache Tracker",
false,
true)
class_match< Value > m_Value()
Match an arbitrary value and ignore it.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
DiagnosticInfoOptimizationBase::Argument NV
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
LLVM_ATTRIBUTE_NORETURN void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
This class represents lattice values for constants.
void push_back(const T &Elt)
This class represents a function call, abstracting a target machine's calling convention.
An immutable pass that tracks lazily created AssumptionCache objects.
A cache of @llvm.assume calls within a function.
MutableArrayRef< WeakTrackingVH > assumptions()
Access the list of assumption handles currently tracked for this function.
Value * getArgOperand(unsigned i) const
bool match(Val *V, const Pattern &P)
class_match< ConstantInt > m_ConstantInt()
Match an arbitrary ConstantInt and ignore it.
initializer< Ty > init(const Ty &Val)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
A set of analyses that are preserved following a run of a transformation pass.
LLVM Basic Block Representation.
CastClass_match< OpTy, Instruction::BitCast > m_BitCast(const OpTy &Op)
Matches BitCast.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
BinOpPred_match< LHS, RHS, is_bitwiselogic_op > m_BitwiseLogic(const LHS &L, const RHS &R)
Matches bitwise logic operations.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
auto find(R &&Range, const T &Val) -> decltype(adl_begin(Range))
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly...
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
A function analysis which provides an AssumptionCache.
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM)
This is the shared class of boolean and integer constants.
ImmutablePass class - This class is used to provide information that does not need to be run...
~AssumptionCacheTracker() override
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
void updateAffectedValues(CallInst *CI)
Update the cache of values being affected by this assumption (i.e.
CastClass_match< OpTy, Instruction::PtrToInt > m_PtrToInt(const OpTy &Op)
Matches PtrToInt.
BinOpPred_match< LHS, RHS, is_shift_op > m_Shift(const LHS &L, const RHS &R)
Matches shift operations.
iterator insert(iterator I, T &&Elt)
void registerAssumption(CallInst *CI)
Add an @llvm.assume intrinsic to this function's cache.
StringRef getName() const
Return a constant reference to the value's name.
const Function * getParent() const
Return the enclosing method, or null if none.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
LLVM Value Representation.
static const Function * getParent(const Value *V)
static cl::opt< bool > VerifyAssumptionCache("verify-assumption-cache", cl::Hidden, cl::desc("Enable verification of assumption cache"), cl::init(false))
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.
A special type used by analysis passes to provide an address that identifies that particular analysis...
BinaryOp_match< ValTy, cst_pred_ty< is_all_ones >, Instruction::Xor, true > m_Not(const ValTy &V)
Matches a 'Not' as 'xor V, -1' or 'xor -1, V'.
const BasicBlock * getParent() const
CmpClass_match< LHS, RHS, ICmpInst, ICmpInst::Predicate > m_ICmp(ICmpInst::Predicate &Pred, const LHS &L, const RHS &R)