forked from OSchip/llvm-project
Enhance dataflow analyses to recognize branch statements in the CFG used as hooks for the initialization of condition variables.
llvm-svn: 92119
This commit is contained in:
parent
bb2f57dd39
commit
9c951ab4f1
|
@ -25,6 +25,25 @@ public:
|
|||
void VisitStmt(Stmt* S) {
|
||||
static_cast< ImplClass* >(this)->VisitChildren(S);
|
||||
}
|
||||
|
||||
void VisitConditionVariableInit(Stmt *S) {
|
||||
assert(S == this->getCurrentBlkStmt());
|
||||
VarDecl *CondVar = 0;
|
||||
switch (S->getStmtClass()) {
|
||||
#define CONDVAR_CASE(CLASS) \
|
||||
case Stmt::CLASS ## Class:\
|
||||
CondVar = cast<CLASS>(S)->getConditionVariable();\
|
||||
break;
|
||||
CONDVAR_CASE(IfStmt)
|
||||
CONDVAR_CASE(ForStmt)
|
||||
CONDVAR_CASE(SwitchStmt)
|
||||
CONDVAR_CASE(WhileStmt)
|
||||
#undef CONDVAR_CASE
|
||||
default:
|
||||
assert(false && "Infeasible");
|
||||
}
|
||||
static_cast<ImplClass*>(this)->Visit(CondVar->getInit());
|
||||
}
|
||||
|
||||
// Defining operator() allows the visitor to be used as a C++ style functor.
|
||||
void operator()(Stmt* S) { static_cast<ImplClass*>(this)->BlockStmt_Visit(S);}
|
||||
|
|
|
@ -54,6 +54,13 @@ public:
|
|||
else
|
||||
return RetTy();
|
||||
}
|
||||
|
||||
/// VisitConditionVariableInit - Handle the initialization of condition
|
||||
/// variables at branches. Valid statements include IfStmt, ForStmt,
|
||||
/// WhileStmt, and SwitchStmt.
|
||||
RetTy VisitConditionVariableInit(Stmt *S) {
|
||||
return RetTy();
|
||||
}
|
||||
|
||||
/// BlockVisit_XXX - Visitor methods for visiting the "root" statements in
|
||||
/// CFGBlocks. Root statements are the statements that appear explicitly in
|
||||
|
@ -65,6 +72,11 @@ public:
|
|||
NullifyStmt cleanup(CurrentBlkStmt);
|
||||
|
||||
switch (S->getStmtClass()) {
|
||||
case Stmt::IfStmtClass:
|
||||
case Stmt::ForStmtClass:
|
||||
case Stmt::WhileStmtClass:
|
||||
case Stmt::SwitchStmtClass:
|
||||
return static_cast<ImplClass*>(this)->VisitConditionVariableInit(S);
|
||||
|
||||
DISPATCH_CASE(StmtExpr)
|
||||
DISPATCH_CASE(ConditionalOperator)
|
||||
|
|
|
@ -112,6 +112,11 @@ public:
|
|||
void VisitUnaryOperator(UnaryOperator* U);
|
||||
void Visit(Stmt *S);
|
||||
void VisitTerminator(CFGBlock* B);
|
||||
|
||||
/// VisitConditionVariableInit - Handle the initialization of condition
|
||||
/// variables at branches. Valid statements include IfStmt, ForStmt,
|
||||
/// WhileStmt, and SwitchStmt.
|
||||
void VisitConditionVariableInit(Stmt *S);
|
||||
|
||||
void SetTopValue(LiveVariables::ValTy& V) {
|
||||
V = AD.AlwaysLive;
|
||||
|
@ -126,7 +131,9 @@ void TransferFuncs::Visit(Stmt *S) {
|
|||
if (AD.Observer)
|
||||
AD.Observer->ObserveStmt(S,AD,LiveState);
|
||||
|
||||
if (getCFG().isBlkExpr(S)) LiveState(S,AD) = Dead;
|
||||
if (getCFG().isBlkExpr(S))
|
||||
LiveState(S, AD) = Dead;
|
||||
|
||||
StmtVisitor<TransferFuncs,void>::Visit(S);
|
||||
}
|
||||
else if (!getCFG().isBlkExpr(S)) {
|
||||
|
@ -142,6 +149,11 @@ void TransferFuncs::Visit(Stmt *S) {
|
|||
LiveState(S,AD) = Alive;
|
||||
}
|
||||
}
|
||||
|
||||
void TransferFuncs::VisitConditionVariableInit(Stmt *S) {
|
||||
assert(!getCFG().isBlkExpr(S));
|
||||
CFGRecStmtVisitor<TransferFuncs>::VisitConditionVariableInit(S);
|
||||
}
|
||||
|
||||
void TransferFuncs::VisitTerminator(CFGBlock* B) {
|
||||
|
||||
|
|
Loading…
Reference in New Issue