зеркало из https://github.com/microsoft/clang-1.git
Added initial support into the flow-sensitive dataflow solver to visit the Block-level expression
in a block's terminator. This expression is visited within a block, but it is accessed by the terminator. This is important to observe because for live-variables analysis the block-level expression is live between the terminator and where the expression occurs in the block. So far this hasn't been an issue to not observe this because the block-level expression used in the terminator is always the last one in the block, and we have never queried the liveness information about this point (but before the terminator). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@49709 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Родитель
9d7af51f0f
Коммит
37622081d8
|
@ -159,7 +159,7 @@ public:
|
|||
|
||||
if (I != M.end()) {
|
||||
TF.getVal().copyValues(I->second);
|
||||
ProcessBlock(B, recordStmtValues);
|
||||
ProcessBlock(B, recordStmtValues, AnalysisDirTag());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -192,7 +192,7 @@ private:
|
|||
while (!WorkList.isEmpty()) {
|
||||
const CFGBlock* B = WorkList.dequeue();
|
||||
ProcessMerge(cfg,B);
|
||||
ProcessBlock(B, recordStmtValues);
|
||||
ProcessBlock(B, recordStmtValues, AnalysisDirTag());
|
||||
UpdateEdges(cfg,B,TF.getVal());
|
||||
}
|
||||
}
|
||||
|
@ -230,11 +230,23 @@ private:
|
|||
|
||||
// Set the data for the block.
|
||||
D.getBlockDataMap()[B].copyValues(V);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// ProcessBlock - Process the transfer functions for a given block.
|
||||
void ProcessBlock(const CFGBlock* B, bool recordStmtValues) {
|
||||
void ProcessBlock(const CFGBlock* B, bool recordStmtValues,
|
||||
dataflow::forward_analysis_tag) {
|
||||
|
||||
for (StmtItr I=ItrTraits::StmtBegin(B), E=ItrTraits::StmtEnd(B); I!=E;++I)
|
||||
ProcessStmt(*I, recordStmtValues, AnalysisDirTag());
|
||||
|
||||
if (Stmt* Term = (Stmt*) B->getTerminator()) TF.VisitTerminator(Term);
|
||||
}
|
||||
|
||||
void ProcessBlock(const CFGBlock* B, bool recordStmtValues,
|
||||
dataflow::backward_analysis_tag) {
|
||||
|
||||
if (Stmt* Term = (Stmt*) B->getTerminator()) TF.VisitTerminator(Term);
|
||||
|
||||
for (StmtItr I=ItrTraits::StmtBegin(B), E=ItrTraits::StmtEnd(B); I!=E;++I)
|
||||
ProcessStmt(*I, recordStmtValues, AnalysisDirTag());
|
||||
}
|
||||
|
|
|
@ -73,7 +73,8 @@ public:
|
|||
void VisitAssign(BinaryOperator* B);
|
||||
void VisitDeclStmt(DeclStmt* DS);
|
||||
void VisitUnaryOperator(UnaryOperator* U);
|
||||
void Visit(Stmt *S);
|
||||
void Visit(Stmt *S);
|
||||
void VisitTerminator(Stmt* S);
|
||||
};
|
||||
|
||||
void TransferFuncs::Visit(Stmt *S) {
|
||||
|
@ -90,6 +91,23 @@ void TransferFuncs::Visit(Stmt *S) {
|
|||
// For block-level expressions, mark that they are live.
|
||||
LiveState(S,AD) = Alive;
|
||||
}
|
||||
|
||||
void TransferFuncs::VisitTerminator(Stmt* S) {
|
||||
return;
|
||||
|
||||
for (Stmt::child_iterator I = S->child_begin(), E = S->child_end();
|
||||
I != E; ++I) {
|
||||
|
||||
Stmt* Child = *I;
|
||||
if (!Child) continue;
|
||||
|
||||
if (getCFG().isBlkExpr(Child)) {
|
||||
LiveState(Child, AD) = Alive;
|
||||
return; // Only one "condition" expression.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TransferFuncs::VisitDeclRefExpr(DeclRefExpr* DR) {
|
||||
if (VarDecl* V = dyn_cast<VarDecl>(DR->getDecl()))
|
||||
|
|
|
@ -75,6 +75,8 @@ public:
|
|||
|
||||
bool Visit(Stmt *S);
|
||||
bool BlockStmt_VisitExpr(Expr* E);
|
||||
|
||||
void VisitTerminator(Stmt* T) { Visit(T); }
|
||||
|
||||
BlockVarDecl* FindBlockVarDecl(Stmt* S);
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче