Since we now may have basicblocks with the same block is in different function,

change the block counter map from unsigned -> unsigned to 
<StackFrameContext*, unsigned> -> unsigned.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@99255 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Zhongxing Xu 2010-03-23 05:05:02 +00:00
Родитель ee5ab9f7a6
Коммит d9e0c0fc47
7 изменённых файлов: 62 добавлений и 19 удалений

Просмотреть файл

@ -22,6 +22,8 @@ namespace llvm {
namespace clang {
class StackFrameContext;
class GRBlockCounter {
void* Data;
@ -30,7 +32,8 @@ class GRBlockCounter {
public:
GRBlockCounter() : Data(0) {}
unsigned getNumVisited(unsigned BlockID) const;
unsigned getNumVisited(const StackFrameContext *CallSite,
unsigned BlockID) const;
class Factory {
void* F;
@ -39,7 +42,9 @@ public:
~Factory();
GRBlockCounter GetEmptyCounter();
GRBlockCounter IncrementCount(GRBlockCounter BC, unsigned BlockID);
GRBlockCounter IncrementCount(GRBlockCounter BC,
const StackFrameContext *CallSite,
unsigned BlockID);
};
friend class Factory;

Просмотреть файл

@ -82,7 +82,7 @@ class GRCoreEngine {
void ProcessStmt(CFGElement E, GRStmtNodeBuilder& Builder);
bool ProcessBlockEntrance(CFGBlock* Blk, const GRState* State,
bool ProcessBlockEntrance(CFGBlock* Blk, const ExplodedNode *Pred,
GRBlockCounter BC);
@ -174,7 +174,9 @@ public:
GRBlockCounter getBlockCounter() const { return Eng.WList->getBlockCounter();}
unsigned getCurrentBlockCount() const {
return getBlockCounter().getNumVisited(B.getBlockID());
return getBlockCounter().getNumVisited(
Pred->getLocationContext()->getCurrentStackFrame(),
B.getBlockID());
}
ExplodedNode* generateNode(PostStmt PP,const GRState* St,ExplodedNode* Pred) {
@ -434,7 +436,9 @@ public:
}
unsigned getCurrentBlockCount() const {
return getBlockCounter().getNumVisited(B.getBlockID());
return getBlockCounter().getNumVisited(
Pred->getLocationContext()->getCurrentStackFrame(),
B.getBlockID());
}
ExplodedNode* generateNode(const GRState* State, const void *tag = 0,

Просмотреть файл

@ -153,7 +153,7 @@ public:
/// ProcessBlockEntrance - Called by GRCoreEngine when start processing
/// a CFGBlock. This method returns true if the analysis should continue
/// exploring the given path, and false otherwise.
bool ProcessBlockEntrance(CFGBlock* B, const GRState* St,
bool ProcessBlockEntrance(CFGBlock* B, const ExplodedNode *Pred,
GRBlockCounter BC);
/// ProcessBranch - Called by GRCoreEngine. Used to generate successor

Просмотреть файл

@ -47,7 +47,7 @@ public:
/// ProcessBlockEntrance - Called by GRCoreEngine when start processing
/// a CFGBlock. This method returns true if the analysis should continue
/// exploring the given path, and false otherwise.
virtual bool ProcessBlockEntrance(CFGBlock* B, const GRState* St,
virtual bool ProcessBlockEntrance(CFGBlock* B, const ExplodedNode *Pred,
GRBlockCounter BC) = 0;
/// ProcessBranch - Called by GRCoreEngine. Used to generate successor

Просмотреть файл

@ -18,7 +18,34 @@
using namespace clang;
typedef llvm::ImmutableMap<unsigned,unsigned> CountMap;
namespace {
class CountKey {
const StackFrameContext *CallSite;
unsigned BlockID;
public:
CountKey(const StackFrameContext *CS, unsigned ID)
: CallSite(CS), BlockID(ID) {}
bool operator==(const CountKey &RHS) const {
return (CallSite == RHS.CallSite) && (BlockID == RHS.BlockID);
}
bool operator<(const CountKey &RHS) const {
return (CallSite == RHS.CallSite) ? (BlockID < RHS.BlockID)
: (CallSite < RHS.CallSite);
}
void Profile(llvm::FoldingSetNodeID &ID) const {
ID.AddPointer(CallSite);
ID.AddInteger(BlockID);
}
};
}
typedef llvm::ImmutableMap<CountKey, unsigned> CountMap;
static inline CountMap GetMap(void* D) {
return CountMap(static_cast<CountMap::TreeTy*>(D));
@ -28,9 +55,10 @@ static inline CountMap::Factory& GetFactory(void* F) {
return *static_cast<CountMap::Factory*>(F);
}
unsigned GRBlockCounter::getNumVisited(unsigned BlockID) const {
unsigned GRBlockCounter::getNumVisited(const StackFrameContext *CallSite,
unsigned BlockID) const {
CountMap M = GetMap(Data);
CountMap::data_type* T = M.lookup(BlockID);
CountMap::data_type* T = M.lookup(CountKey(CallSite, BlockID));
return T ? *T : 0;
}
@ -43,9 +71,12 @@ GRBlockCounter::Factory::~Factory() {
}
GRBlockCounter
GRBlockCounter::Factory::IncrementCount(GRBlockCounter BC, unsigned BlockID) {
return GRBlockCounter(GetFactory(F).Add(GetMap(BC.Data), BlockID,
BC.getNumVisited(BlockID)+1).getRoot());
GRBlockCounter::Factory::IncrementCount(GRBlockCounter BC,
const StackFrameContext *CallSite,
unsigned BlockID) {
return GRBlockCounter(GetFactory(F).Add(GetMap(BC.Data),
CountKey(CallSite, BlockID),
BC.getNumVisited(CallSite, BlockID)+1).getRoot());
}
GRBlockCounter

Просмотреть файл

@ -126,9 +126,9 @@ void GRCoreEngine::ProcessStmt(CFGElement E, GRStmtNodeBuilder& Builder) {
SubEngine.ProcessStmt(E, Builder);
}
bool GRCoreEngine::ProcessBlockEntrance(CFGBlock* Blk, const GRState* State,
bool GRCoreEngine::ProcessBlockEntrance(CFGBlock* Blk, const ExplodedNode *Pred,
GRBlockCounter BC) {
return SubEngine.ProcessBlockEntrance(Blk, State, BC);
return SubEngine.ProcessBlockEntrance(Blk, Pred, BC);
}
void GRCoreEngine::ProcessBranch(Stmt* Condition, Stmt* Terminator,
@ -256,7 +256,7 @@ void GRCoreEngine::HandleBlockEdge(const BlockEdge& L, ExplodedNode* Pred) {
// FIXME: Should we allow ProcessBlockEntrance to also manipulate state?
if (ProcessBlockEntrance(Blk, Pred->State, WList->getBlockCounter()))
if (ProcessBlockEntrance(Blk, Pred, WList->getBlockCounter()))
GenerateNode(BlockEntrance(Blk, Pred->getLocationContext()), Pred->State, Pred);
}
@ -265,7 +265,9 @@ void GRCoreEngine::HandleBlockEntrance(const BlockEntrance& L,
// Increment the block counter.
GRBlockCounter Counter = WList->getBlockCounter();
Counter = BCounterFactory.IncrementCount(Counter, L.getBlock()->getBlockID());
Counter = BCounterFactory.IncrementCount(Counter,
Pred->getLocationContext()->getCurrentStackFrame(),
L.getBlock()->getBlockID());
WList->setBlockCounter(Counter);
// Process the entrance of the block.

Просмотреть файл

@ -944,10 +944,11 @@ void GRExprEngine::VisitLValue(Expr* Ex, ExplodedNode* Pred,
// Block entrance. (Update counters).
//===----------------------------------------------------------------------===//
bool GRExprEngine::ProcessBlockEntrance(CFGBlock* B, const GRState*,
bool GRExprEngine::ProcessBlockEntrance(CFGBlock* B, const ExplodedNode *Pred,
GRBlockCounter BC) {
return BC.getNumVisited(B->getBlockID()) < 3;
return BC.getNumVisited(Pred->getLocationContext()->getCurrentStackFrame(),
B->getBlockID()) < 3;
}
//===----------------------------------------------------------------------===//