LLVM API Documentation

AssumptionTracker.cpp
Go to the documentation of this file.
00001 //===- AssumptionTracker.cpp - Track @llvm.assume -------------------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file contains a pass that keeps track of @llvm.assume intrinsics in
00011 // the functions of a module.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #include "llvm/Analysis/AssumptionTracker.h"
00016 #include "llvm/IR/CallSite.h"
00017 #include "llvm/IR/Dominators.h"
00018 #include "llvm/IR/Function.h"
00019 #include "llvm/IR/Instructions.h"
00020 #include "llvm/IR/IntrinsicInst.h"
00021 #include "llvm/IR/PatternMatch.h"
00022 #include "llvm/Support/Debug.h"
00023 using namespace llvm;
00024 using namespace llvm::PatternMatch;
00025 
00026 void AssumptionTracker::FunctionCallbackVH::deleted() {
00027   AT->forgetCachedAssumptions(cast<Function>(getValPtr()));
00028   // 'this' now dangles!
00029 }
00030 
00031 void AssumptionTracker::forgetCachedAssumptions(Function *F) {
00032   CachedAssumeCalls.erase(F);
00033 }
00034 
00035 void AssumptionTracker::CallCallbackVH::deleted() {
00036   assert(F && "delete callback called on dummy handle");
00037   FunctionCallsMap::iterator I = AT->CachedAssumeCalls.find(F);
00038   assert(I != AT->CachedAssumeCalls.end() &&
00039          "Function cleared from the map without removing the values?");
00040 
00041   I->second->erase(*this);
00042   // 'this' now dangles!
00043 }
00044 
00045 AssumptionTracker::FunctionCallsMap::iterator
00046 AssumptionTracker::scanFunction(Function *F) {
00047   auto IP =
00048     CachedAssumeCalls.insert(std::make_pair(FunctionCallbackVH(F, this),
00049                                             std::unique_ptr<CallHandleSet>(
00050                                               new CallHandleSet())));
00051   assert(IP.second && "Scanning function already in the map?");
00052 
00053   FunctionCallsMap::iterator I = IP.first;
00054 
00055   // Go through all instructions in all blocks, add all calls to @llvm.assume
00056   // to our cache.
00057   for (BasicBlock &B : *F)
00058     for (Instruction &II : B)
00059       if (match(cast<Value>(&II), m_Intrinsic<Intrinsic::assume>(m_Value())))
00060         I->second->insert(CallCallbackVH(&II, this));
00061 
00062   return I;
00063 }
00064 
00065 void AssumptionTracker::verifyAnalysis() const {
00066 #ifndef NDEBUG
00067   for (const auto &I : CachedAssumeCalls) {
00068     for (const BasicBlock &B : cast<Function>(*I.first))
00069       for (const Instruction &II : B) {
00070         Instruction *C = const_cast<Instruction*>(&II);
00071         if (match(C, m_Intrinsic<Intrinsic::assume>(m_Value()))) {
00072           assert(I.second->count(CallCallbackVH(C,
00073                    const_cast<AssumptionTracker*>(this))) &&
00074                  "Assumption in scanned function not in cache");
00075         }
00076     }
00077   }
00078 #endif
00079 }
00080 
00081 void AssumptionTracker::registerAssumption(CallInst *CI) {
00082   assert(match(cast<Value>(CI),
00083                m_Intrinsic<Intrinsic::assume>(m_Value())) &&
00084          "Registered call does not call @llvm.assume");
00085   assert(CI->getParent() &&
00086          "Cannot register @llvm.assume call not in a basic block");
00087 
00088   Function *F = CI->getParent()->getParent();
00089   assert(F && "Cannot register @llvm.assume call not in a function");
00090 
00091   FunctionCallsMap::iterator I = CachedAssumeCalls.find(F);
00092   if (I == CachedAssumeCalls.end()) {
00093     // If this function has not already been scanned, then don't do anything
00094     // here. This intrinsic will be found, if it still exists, if the list of
00095     // assumptions in this function is requested at some later point. This
00096     // maintains the following invariant: if a function is present in the
00097     // cache, then its list of assumption intrinsic calls is complete.
00098     return;
00099   }
00100 
00101   I->second->insert(CallCallbackVH(CI, this));
00102 }
00103 
00104 AssumptionTracker::AssumptionTracker() : ImmutablePass(ID) {
00105   initializeAssumptionTrackerPass(*PassRegistry::getPassRegistry());
00106 }
00107 
00108 AssumptionTracker::~AssumptionTracker() {}
00109 
00110 INITIALIZE_PASS(AssumptionTracker, "assumption-tracker", "Assumption Tracker",
00111                 false, true)
00112 char AssumptionTracker::ID = 0;
00113