blob: 75fb16a2d5f5059a390b84de16c4de51cec3ae2f [file] [log] [blame]
Ted Kremenek8e49dd62008-02-12 18:08:17 +00001//==- GRBlockCounter.h - ADT for counting block visits -------------*- C++ -*-//
Mike Stump1eb44332009-09-09 15:08:12 +00002//
Ted Kremenek8e49dd62008-02-12 18:08:17 +00003// 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 GRBlockCounter, an abstract data type used to count
11// the number of times a given block has been visited along a path
Ted Kremenek4d4dd852008-02-13 17:41:41 +000012// analyzed by GRCoreEngine.
Ted Kremenek8e49dd62008-02-12 18:08:17 +000013//
14//===----------------------------------------------------------------------===//
15
Ted Kremenek1309f9a2010-01-25 04:41:41 +000016#include "clang/Checker/PathSensitive/GRBlockCounter.h"
Ted Kremenek8e49dd62008-02-12 18:08:17 +000017#include "llvm/ADT/ImmutableMap.h"
18
19using namespace clang;
20
Zhongxing Xud9e0c0f2010-03-23 05:05:02 +000021namespace {
22
23class CountKey {
24 const StackFrameContext *CallSite;
25 unsigned BlockID;
26
27public:
28 CountKey(const StackFrameContext *CS, unsigned ID)
29 : CallSite(CS), BlockID(ID) {}
30
31 bool operator==(const CountKey &RHS) const {
32 return (CallSite == RHS.CallSite) && (BlockID == RHS.BlockID);
33 }
34
35 bool operator<(const CountKey &RHS) const {
36 return (CallSite == RHS.CallSite) ? (BlockID < RHS.BlockID)
37 : (CallSite < RHS.CallSite);
38 }
39
40 void Profile(llvm::FoldingSetNodeID &ID) const {
41 ID.AddPointer(CallSite);
42 ID.AddInteger(BlockID);
43 }
44};
45
46}
47
48typedef llvm::ImmutableMap<CountKey, unsigned> CountMap;
Ted Kremenek8e49dd62008-02-12 18:08:17 +000049
50static inline CountMap GetMap(void* D) {
51 return CountMap(static_cast<CountMap::TreeTy*>(D));
52}
53
54static inline CountMap::Factory& GetFactory(void* F) {
55 return *static_cast<CountMap::Factory*>(F);
56}
57
Zhongxing Xud9e0c0f2010-03-23 05:05:02 +000058unsigned GRBlockCounter::getNumVisited(const StackFrameContext *CallSite,
59 unsigned BlockID) const {
Ted Kremenek8e49dd62008-02-12 18:08:17 +000060 CountMap M = GetMap(Data);
Zhongxing Xud9e0c0f2010-03-23 05:05:02 +000061 CountMap::data_type* T = M.lookup(CountKey(CallSite, BlockID));
Ted Kremeneke8fdc832008-07-07 16:21:19 +000062 return T ? *T : 0;
Ted Kremenek8e49dd62008-02-12 18:08:17 +000063}
64
65GRBlockCounter::Factory::Factory(llvm::BumpPtrAllocator& Alloc) {
66 F = new CountMap::Factory(Alloc);
67}
68
69GRBlockCounter::Factory::~Factory() {
Ted Kremenek5617fae2008-03-06 08:09:22 +000070 delete static_cast<CountMap::Factory*>(F);
Ted Kremenek8e49dd62008-02-12 18:08:17 +000071}
72
73GRBlockCounter
Zhongxing Xud9e0c0f2010-03-23 05:05:02 +000074GRBlockCounter::Factory::IncrementCount(GRBlockCounter BC,
75 const StackFrameContext *CallSite,
76 unsigned BlockID) {
Ted Kremenek3baf6722010-11-24 00:54:37 +000077 return GRBlockCounter(GetFactory(F).add(GetMap(BC.Data),
Zhongxing Xud9e0c0f2010-03-23 05:05:02 +000078 CountKey(CallSite, BlockID),
79 BC.getNumVisited(CallSite, BlockID)+1).getRoot());
Ted Kremenek8e49dd62008-02-12 18:08:17 +000080}
81
82GRBlockCounter
83GRBlockCounter::Factory::GetEmptyCounter() {
Ted Kremenek3baf6722010-11-24 00:54:37 +000084 return GRBlockCounter(GetFactory(F).getEmptyMap().getRoot());
Ted Kremenek8e49dd62008-02-12 18:08:17 +000085}