зеркало из https://github.com/microsoft/clang-1.git
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:
Родитель
ee5ab9f7a6
Коммит
d9e0c0fc47
|
@ -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;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
|
Загрузка…
Ссылка в новой задаче