blob: ee76e7a2bc1db71db0cbe65eca621d2a894bdc8f [file] [log] [blame]
Argyrios Kyrtzidisd2592a32010-12-22 18:53:44 +00001//==- BlockCounter.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//
Argyrios Kyrtzidisd2592a32010-12-22 18:53:44 +000010// This file defines BlockCounter, an abstract data type used to count
Ted Kremenek8e49dd62008-02-12 18:08:17 +000011// the number of times a given block has been visited along a path
Argyrios Kyrtzidisd2592a32010-12-22 18:53:44 +000012// analyzed by CoreEngine.
Ted Kremenek8e49dd62008-02-12 18:08:17 +000013//
14//===----------------------------------------------------------------------===//
15
Argyrios Kyrtzidisd2592a32010-12-22 18:53:44 +000016#include "clang/GR/PathSensitive/BlockCounter.h"
Ted Kremenek8e49dd62008-02-12 18:08:17 +000017#include "llvm/ADT/ImmutableMap.h"
18
19using namespace clang;
Argyrios Kyrtzidis5a4f98f2010-12-22 18:53:20 +000020using namespace GR;
Ted Kremenek8e49dd62008-02-12 18:08:17 +000021
Zhongxing Xud9e0c0f2010-03-23 05:05:02 +000022namespace {
23
24class CountKey {
25 const StackFrameContext *CallSite;
26 unsigned BlockID;
27
28public:
29 CountKey(const StackFrameContext *CS, unsigned ID)
30 : CallSite(CS), BlockID(ID) {}
31
32 bool operator==(const CountKey &RHS) const {
33 return (CallSite == RHS.CallSite) && (BlockID == RHS.BlockID);
34 }
35
36 bool operator<(const CountKey &RHS) const {
37 return (CallSite == RHS.CallSite) ? (BlockID < RHS.BlockID)
38 : (CallSite < RHS.CallSite);
39 }
40
41 void Profile(llvm::FoldingSetNodeID &ID) const {
42 ID.AddPointer(CallSite);
43 ID.AddInteger(BlockID);
44 }
45};
46
47}
48
49typedef llvm::ImmutableMap<CountKey, unsigned> CountMap;
Ted Kremenek8e49dd62008-02-12 18:08:17 +000050
51static inline CountMap GetMap(void* D) {
52 return CountMap(static_cast<CountMap::TreeTy*>(D));
53}
54
55static inline CountMap::Factory& GetFactory(void* F) {
56 return *static_cast<CountMap::Factory*>(F);
57}
58
Argyrios Kyrtzidisd2592a32010-12-22 18:53:44 +000059unsigned BlockCounter::getNumVisited(const StackFrameContext *CallSite,
Zhongxing Xud9e0c0f2010-03-23 05:05:02 +000060 unsigned BlockID) const {
Ted Kremenek8e49dd62008-02-12 18:08:17 +000061 CountMap M = GetMap(Data);
Zhongxing Xud9e0c0f2010-03-23 05:05:02 +000062 CountMap::data_type* T = M.lookup(CountKey(CallSite, BlockID));
Ted Kremeneke8fdc832008-07-07 16:21:19 +000063 return T ? *T : 0;
Ted Kremenek8e49dd62008-02-12 18:08:17 +000064}
65
Argyrios Kyrtzidisd2592a32010-12-22 18:53:44 +000066BlockCounter::Factory::Factory(llvm::BumpPtrAllocator& Alloc) {
Ted Kremenek8e49dd62008-02-12 18:08:17 +000067 F = new CountMap::Factory(Alloc);
68}
69
Argyrios Kyrtzidisd2592a32010-12-22 18:53:44 +000070BlockCounter::Factory::~Factory() {
Ted Kremenek5617fae2008-03-06 08:09:22 +000071 delete static_cast<CountMap::Factory*>(F);
Ted Kremenek8e49dd62008-02-12 18:08:17 +000072}
73
Argyrios Kyrtzidisd2592a32010-12-22 18:53:44 +000074BlockCounter
75BlockCounter::Factory::IncrementCount(BlockCounter BC,
Zhongxing Xud9e0c0f2010-03-23 05:05:02 +000076 const StackFrameContext *CallSite,
77 unsigned BlockID) {
Argyrios Kyrtzidisd2592a32010-12-22 18:53:44 +000078 return BlockCounter(GetFactory(F).add(GetMap(BC.Data),
Zhongxing Xud9e0c0f2010-03-23 05:05:02 +000079 CountKey(CallSite, BlockID),
80 BC.getNumVisited(CallSite, BlockID)+1).getRoot());
Ted Kremenek8e49dd62008-02-12 18:08:17 +000081}
82
Argyrios Kyrtzidisd2592a32010-12-22 18:53:44 +000083BlockCounter
84BlockCounter::Factory::GetEmptyCounter() {
85 return BlockCounter(GetFactory(F).getEmptyMap().getRoot());
Ted Kremenek8e49dd62008-02-12 18:08:17 +000086}