2
0

AssumptionCache.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  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. #include "llvm/Analysis/AssumptionCache.h"
  15. #include "llvm/IR/CallSite.h"
  16. #include "llvm/IR/Dominators.h"
  17. #include "llvm/IR/Function.h"
  18. #include "llvm/IR/Instructions.h"
  19. #include "llvm/IR/IntrinsicInst.h"
  20. #include "llvm/IR/PassManager.h"
  21. #include "llvm/IR/PatternMatch.h"
  22. #include "llvm/Support/Debug.h"
  23. using namespace llvm;
  24. using namespace llvm::PatternMatch;
  25. void AssumptionCache::scanFunction() {
  26. assert(!Scanned && "Tried to scan the function twice!");
  27. assert(AssumeHandles.empty() && "Already have assumes when scanning!");
  28. // Go through all instructions in all blocks, add all calls to @llvm.assume
  29. // to this cache.
  30. for (BasicBlock &B : F)
  31. for (Instruction &II : B)
  32. if (match(&II, m_Intrinsic<Intrinsic::assume>()))
  33. AssumeHandles.push_back(&II);
  34. // Mark the scan as complete.
  35. Scanned = true;
  36. }
  37. void AssumptionCache::registerAssumption(CallInst *CI) {
  38. assert(match(CI, m_Intrinsic<Intrinsic::assume>()) &&
  39. "Registered call does not call @llvm.assume");
  40. // If we haven't scanned the function yet, just drop this assumption. It will
  41. // be found when we scan later.
  42. if (!Scanned)
  43. return;
  44. AssumeHandles.push_back(CI);
  45. #ifndef NDEBUG
  46. assert(CI->getParent() &&
  47. "Cannot register @llvm.assume call not in a basic block");
  48. assert(&F == CI->getParent()->getParent() &&
  49. "Cannot register @llvm.assume call not in this function");
  50. // We expect the number of assumptions to be small, so in an asserts build
  51. // check that we don't accumulate duplicates and that all assumptions point
  52. // to the same function.
  53. SmallPtrSet<Value *, 16> AssumptionSet;
  54. for (auto &VH : AssumeHandles) {
  55. if (!VH)
  56. continue;
  57. assert(&F == cast<Instruction>(VH)->getParent()->getParent() &&
  58. "Cached assumption not inside this function!");
  59. assert(match(cast<CallInst>(VH), m_Intrinsic<Intrinsic::assume>()) &&
  60. "Cached something other than a call to @llvm.assume!");
  61. assert(AssumptionSet.insert(VH).second &&
  62. "Cache contains multiple copies of a call!");
  63. }
  64. #endif
  65. }
  66. char AssumptionAnalysis::PassID;
  67. PreservedAnalyses AssumptionPrinterPass::run(Function &F,
  68. AnalysisManager<Function> *AM) {
  69. AssumptionCache &AC = AM->getResult<AssumptionAnalysis>(F);
  70. OS << "Cached assumptions for function: " << F.getName() << "\n";
  71. for (auto &VH : AC.assumptions())
  72. if (VH)
  73. OS << " " << *cast<CallInst>(VH)->getArgOperand(0) << "\n";
  74. return PreservedAnalyses::all();
  75. }
  76. void AssumptionCacheTracker::FunctionCallbackVH::deleted() {
  77. auto I = ACT->AssumptionCaches.find_as(cast<Function>(getValPtr()));
  78. if (I != ACT->AssumptionCaches.end())
  79. ACT->AssumptionCaches.erase(I);
  80. // 'this' now dangles!
  81. }
  82. AssumptionCache &AssumptionCacheTracker::getAssumptionCache(Function &F) {
  83. // We probe the function map twice to try and avoid creating a value handle
  84. // around the function in common cases. This makes insertion a bit slower,
  85. // but if we have to insert we're going to scan the whole function so that
  86. // shouldn't matter.
  87. auto I = AssumptionCaches.find_as(&F);
  88. if (I != AssumptionCaches.end())
  89. return *I->second;
  90. // Ok, build a new cache by scanning the function, insert it and the value
  91. // handle into our map, and return the newly populated cache.
  92. auto IP = AssumptionCaches.insert(std::make_pair(
  93. FunctionCallbackVH(&F, this), llvm::make_unique<AssumptionCache>(F)));
  94. assert(IP.second && "Scanning function already in the map?");
  95. return *IP.first->second;
  96. }
  97. void AssumptionCacheTracker::verifyAnalysis() const {
  98. #ifndef NDEBUG
  99. SmallPtrSet<const CallInst *, 4> AssumptionSet;
  100. for (const auto &I : AssumptionCaches) {
  101. for (auto &VH : I.second->assumptions())
  102. if (VH)
  103. AssumptionSet.insert(cast<CallInst>(VH));
  104. for (const BasicBlock &B : cast<Function>(*I.first))
  105. for (const Instruction &II : B)
  106. if (match(&II, m_Intrinsic<Intrinsic::assume>()))
  107. assert(AssumptionSet.count(cast<CallInst>(&II)) &&
  108. "Assumption in scanned function not in cache");
  109. }
  110. #endif
  111. }
  112. AssumptionCacheTracker::AssumptionCacheTracker() : ImmutablePass(ID) {
  113. initializeAssumptionCacheTrackerPass(*PassRegistry::getPassRegistry());
  114. }
  115. AssumptionCacheTracker::~AssumptionCacheTracker() {}
  116. INITIALIZE_PASS(AssumptionCacheTracker, "assumption-cache-tracker",
  117. "Assumption Cache Tracker", false, true)
  118. char AssumptionCacheTracker::ID = 0;