BlockCounter.cpp 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. //==- BlockCounter.h - ADT for counting block visits -------------*- C++ -*-//
  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 defines BlockCounter, an abstract data type used to count
  11. // the number of times a given block has been visited along a path
  12. // analyzed by CoreEngine.
  13. //
  14. //===----------------------------------------------------------------------===//
  15. #include "clang/StaticAnalyzer/PathSensitive/BlockCounter.h"
  16. #include "llvm/ADT/ImmutableMap.h"
  17. using namespace clang;
  18. using namespace ento;
  19. namespace {
  20. class CountKey {
  21. const StackFrameContext *CallSite;
  22. unsigned BlockID;
  23. public:
  24. CountKey(const StackFrameContext *CS, unsigned ID)
  25. : CallSite(CS), BlockID(ID) {}
  26. bool operator==(const CountKey &RHS) const {
  27. return (CallSite == RHS.CallSite) && (BlockID == RHS.BlockID);
  28. }
  29. bool operator<(const CountKey &RHS) const {
  30. return (CallSite == RHS.CallSite) ? (BlockID < RHS.BlockID)
  31. : (CallSite < RHS.CallSite);
  32. }
  33. void Profile(llvm::FoldingSetNodeID &ID) const {
  34. ID.AddPointer(CallSite);
  35. ID.AddInteger(BlockID);
  36. }
  37. };
  38. }
  39. typedef llvm::ImmutableMap<CountKey, unsigned> CountMap;
  40. static inline CountMap GetMap(void* D) {
  41. return CountMap(static_cast<CountMap::TreeTy*>(D));
  42. }
  43. static inline CountMap::Factory& GetFactory(void* F) {
  44. return *static_cast<CountMap::Factory*>(F);
  45. }
  46. unsigned BlockCounter::getNumVisited(const StackFrameContext *CallSite,
  47. unsigned BlockID) const {
  48. CountMap M = GetMap(Data);
  49. CountMap::data_type* T = M.lookup(CountKey(CallSite, BlockID));
  50. return T ? *T : 0;
  51. }
  52. BlockCounter::Factory::Factory(llvm::BumpPtrAllocator& Alloc) {
  53. F = new CountMap::Factory(Alloc);
  54. }
  55. BlockCounter::Factory::~Factory() {
  56. delete static_cast<CountMap::Factory*>(F);
  57. }
  58. BlockCounter
  59. BlockCounter::Factory::IncrementCount(BlockCounter BC,
  60. const StackFrameContext *CallSite,
  61. unsigned BlockID) {
  62. return BlockCounter(GetFactory(F).add(GetMap(BC.Data),
  63. CountKey(CallSite, BlockID),
  64. BC.getNumVisited(CallSite, BlockID)+1).getRoot());
  65. }
  66. BlockCounter
  67. BlockCounter::Factory::GetEmptyCounter() {
  68. return BlockCounter(GetFactory(F).getEmptyMap().getRoot());
  69. }