forked from OSchip/llvm-project
[analyzer; alternate edges] - eliminate unnecessary edges where between parents and subexpressions.
llvm-svn: 181086
This commit is contained in:
parent
ccb6d1ea0c
commit
bcd6b0d891
|
@ -1738,10 +1738,13 @@ GenerateAlternateExtensivePathDiagnostic(PathDiagnostic& PD,
|
||||||
return report->isValid();
|
return report->isValid();
|
||||||
}
|
}
|
||||||
|
|
||||||
const Stmt *getLocParent(PathDiagnosticLocation L, ParentMap &PM) {
|
const Stmt *getLocStmt(PathDiagnosticLocation L) {
|
||||||
if (!L.isValid())
|
if (!L.isValid())
|
||||||
return 0;
|
return 0;
|
||||||
const Stmt *S = L.asStmt();
|
return L.asStmt();
|
||||||
|
}
|
||||||
|
|
||||||
|
const Stmt *getStmtParent(const Stmt *S, ParentMap &PM) {
|
||||||
if (!S)
|
if (!S)
|
||||||
return 0;
|
return 0;
|
||||||
return PM.getParent(S);
|
return PM.getParent(S);
|
||||||
|
@ -1752,6 +1755,7 @@ static bool optimizeEdges(PathPieces &path,
|
||||||
bool hasChanges = false;
|
bool hasChanges = false;
|
||||||
const LocationContext *LC = LCM[&path];
|
const LocationContext *LC = LCM[&path];
|
||||||
assert(LC);
|
assert(LC);
|
||||||
|
bool isFirst = true;
|
||||||
|
|
||||||
for (PathPieces::iterator I = path.begin(), E = path.end(); I != E; ++I) {
|
for (PathPieces::iterator I = path.begin(), E = path.end(); I != E; ++I) {
|
||||||
PathPieces::iterator NextI = I; ++NextI;
|
PathPieces::iterator NextI = I; ++NextI;
|
||||||
|
@ -1771,13 +1775,34 @@ static bool optimizeEdges(PathPieces &path,
|
||||||
if (!PieceI)
|
if (!PieceI)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
ParentMap &PM = LC->getParentMap();
|
||||||
|
const Stmt *s1Start = getLocStmt(PieceI->getStartLocation());
|
||||||
|
const Stmt *s1End = getLocStmt(PieceI->getEndLocation());
|
||||||
|
const Stmt *level1 = getStmtParent(s1Start, PM);
|
||||||
|
const Stmt *level2 = getStmtParent(s1End, PM);
|
||||||
|
|
||||||
|
if (isFirst) {
|
||||||
|
isFirst = false;
|
||||||
|
// Apply the "first edge" case for Rule III. here.
|
||||||
|
if (level1 && level2 && level2 == PM.getParent(level1)) {
|
||||||
|
path.erase(I);
|
||||||
|
// Since we are erasing the current edge at the start of the
|
||||||
|
// path, just return now so we start analyzing the start of the path
|
||||||
|
// again.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PathDiagnosticControlFlowPiece *PieceNextI =
|
PathDiagnosticControlFlowPiece *PieceNextI =
|
||||||
dyn_cast<PathDiagnosticControlFlowPiece>(*NextI);
|
dyn_cast<PathDiagnosticControlFlowPiece>(*NextI);
|
||||||
|
|
||||||
if (!PieceNextI)
|
if (!PieceNextI)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ParentMap &PM = LC->getParentMap();
|
const Stmt *s2Start = getLocStmt(PieceNextI->getStartLocation());
|
||||||
|
const Stmt *s2End = getLocStmt(PieceNextI->getEndLocation());
|
||||||
|
const Stmt *level3 = getStmtParent(s2Start, PM);
|
||||||
|
const Stmt *level4 = getStmtParent(s2End, PM);
|
||||||
|
|
||||||
// Rule I.
|
// Rule I.
|
||||||
//
|
//
|
||||||
|
@ -1791,11 +1816,7 @@ static bool optimizeEdges(PathPieces &path,
|
||||||
//
|
//
|
||||||
// NOTE: this will be limited later in cases where we add barriers
|
// NOTE: this will be limited later in cases where we add barriers
|
||||||
// to prevent this optimization.
|
// to prevent this optimization.
|
||||||
const Stmt *level1 = getLocParent(PieceI->getStartLocation(), PM);
|
//
|
||||||
const Stmt *level2 = getLocParent(PieceI->getEndLocation(), PM);
|
|
||||||
const Stmt *level3 = getLocParent(PieceNextI->getStartLocation(), PM);
|
|
||||||
const Stmt *level4 = getLocParent(PieceNextI->getEndLocation(), PM);
|
|
||||||
|
|
||||||
if (level1 && level1 == level2 && level1 == level3 && level1 == level4) {
|
if (level1 && level1 == level2 && level1 == level3 && level1 == level4) {
|
||||||
PieceI->setEndLocation(PieceNextI->getEndLocation());
|
PieceI->setEndLocation(PieceNextI->getEndLocation());
|
||||||
path.erase(NextI);
|
path.erase(NextI);
|
||||||
|
@ -1822,6 +1843,45 @@ static bool optimizeEdges(PathPieces &path,
|
||||||
hasChanges = true;
|
hasChanges = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Rule III.
|
||||||
|
//
|
||||||
|
// Eliminate unnecessary edges where we descend to a subexpression from
|
||||||
|
// a statement at the same level as our parent.
|
||||||
|
//
|
||||||
|
// NOTE: this will be limited later in cases where we add barriers
|
||||||
|
// to prevent this optimization.
|
||||||
|
//
|
||||||
|
// For example:
|
||||||
|
//
|
||||||
|
// (1.1 -> 1.1.1) -> (1.1.1 -> X) becomes (1.1 -> X).
|
||||||
|
//
|
||||||
|
if (level1 && level2 && level1 == PM.getParent(level2)) {
|
||||||
|
PieceI->setEndLocation(PieceNextI->getEndLocation());
|
||||||
|
path.erase(NextI);
|
||||||
|
hasChanges = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Rule IV.
|
||||||
|
//
|
||||||
|
// Eliminate unnecessary edges where we ascend from a subexpression to
|
||||||
|
// a statement at the same level as our parent.
|
||||||
|
//
|
||||||
|
// NOTE: this will be limited later in cases where we add barriers
|
||||||
|
// to prevent this optimization.
|
||||||
|
//
|
||||||
|
// For example:
|
||||||
|
//
|
||||||
|
// (X -> 1.1.1) -> (1.1.1 -> 1.1) becomes (X -> 1.1).
|
||||||
|
// [first edge] (1.1.1 -> 1.1) -> eliminate
|
||||||
|
//
|
||||||
|
if (level2 && level4 && level2 == level3 && level4 == PM.getParent(level2)){
|
||||||
|
PieceI->setEndLocation(PieceNextI->getEndLocation());
|
||||||
|
path.erase(NextI);
|
||||||
|
hasChanges = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// No changes.
|
// No changes.
|
||||||
|
|
Loading…
Reference in New Issue