1 //==- GRBlockCounter.h - ADT for counting block visits -------------*- C++ -*-//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
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
12 // analyzed by GRCoreEngine.
14 //===----------------------------------------------------------------------===//
16 #include "clang/GR/PathSensitive/GRBlockCounter.h"
17 #include "llvm/ADT/ImmutableMap.h"
19 using namespace clang
;
25 const StackFrameContext
*CallSite
;
29 CountKey(const StackFrameContext
*CS
, unsigned ID
)
30 : CallSite(CS
), BlockID(ID
) {}
32 bool operator==(const CountKey
&RHS
) const {
33 return (CallSite
== RHS
.CallSite
) && (BlockID
== RHS
.BlockID
);
36 bool operator<(const CountKey
&RHS
) const {
37 return (CallSite
== RHS
.CallSite
) ? (BlockID
< RHS
.BlockID
)
38 : (CallSite
< RHS
.CallSite
);
41 void Profile(llvm::FoldingSetNodeID
&ID
) const {
42 ID
.AddPointer(CallSite
);
43 ID
.AddInteger(BlockID
);
49 typedef llvm::ImmutableMap
<CountKey
, unsigned> CountMap
;
51 static inline CountMap
GetMap(void* D
) {
52 return CountMap(static_cast<CountMap::TreeTy
*>(D
));
55 static inline CountMap::Factory
& GetFactory(void* F
) {
56 return *static_cast<CountMap::Factory
*>(F
);
59 unsigned GRBlockCounter::getNumVisited(const StackFrameContext
*CallSite
,
60 unsigned BlockID
) const {
61 CountMap M
= GetMap(Data
);
62 CountMap::data_type
* T
= M
.lookup(CountKey(CallSite
, BlockID
));
66 GRBlockCounter::Factory::Factory(llvm::BumpPtrAllocator
& Alloc
) {
67 F
= new CountMap::Factory(Alloc
);
70 GRBlockCounter::Factory::~Factory() {
71 delete static_cast<CountMap::Factory
*>(F
);
75 GRBlockCounter::Factory::IncrementCount(GRBlockCounter BC
,
76 const StackFrameContext
*CallSite
,
78 return GRBlockCounter(GetFactory(F
).add(GetMap(BC
.Data
),
79 CountKey(CallSite
, BlockID
),
80 BC
.getNumVisited(CallSite
, BlockID
)+1).getRoot());
84 GRBlockCounter::Factory::GetEmptyCounter() {
85 return GRBlockCounter(GetFactory(F
).getEmptyMap().getRoot());