12
12
// ===----------------------------------------------------------------------===//
13
13
14
14
#include < algorithm>
15
- #include < memory>
16
15
#include < optional>
17
16
#include < system_error>
18
17
#include < utility>
33
32
#include " clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h"
34
33
#include " clang/Analysis/FlowSensitive/Value.h"
35
34
#include " llvm/ADT/ArrayRef.h"
36
- #include " llvm/ADT/DenseSet.h"
37
35
#include " llvm/ADT/STLExtras.h"
36
+ #include " llvm/ADT/SmallBitVector.h"
38
37
#include " llvm/Support/Debug.h"
39
38
#include " llvm/Support/Error.h"
40
39
@@ -53,19 +52,14 @@ static int blockIndexInPredecessor(const CFGBlock &Pred,
53
52
return BlockPos - Pred.succ_begin ();
54
53
}
55
54
56
- static bool isLoopHead (const CFGBlock &B) {
57
- if (const auto *T = B.getTerminatorStmt ())
58
- switch (T->getStmtClass ()) {
59
- case Stmt::WhileStmtClass:
60
- case Stmt::DoStmtClass:
61
- case Stmt::ForStmtClass:
62
- case Stmt::CXXForRangeStmtClass:
63
- return true ;
64
- default :
65
- return false ;
66
- }
67
-
68
- return false ;
55
+ // A "backedge" node is a block introduced in the CFG exclusively to indicate a
56
+ // loop backedge. They are exactly identified by the presence of a non-null
57
+ // pointer to the entry block of the loop condition. Note that this is not
58
+ // necessarily the block with the loop statement as terminator, because
59
+ // short-circuit operators will result in multiple blocks encoding the loop
60
+ // condition, only one of which will contain the loop statement as terminator.
61
+ static bool isBackedgeNode (const CFGBlock &B) {
62
+ return B.getLoopTarget () != nullptr ;
69
63
}
70
64
71
65
namespace {
@@ -502,14 +496,15 @@ runTypeErasedDataflowAnalysis(
502
496
PostVisitCFG) {
503
497
PrettyStackTraceAnalysis CrashInfo (CFCtx, " runTypeErasedDataflowAnalysis" );
504
498
505
- PostOrderCFGView POV (&CFCtx.getCFG ());
506
- ForwardDataflowWorklist Worklist (CFCtx.getCFG (), &POV);
499
+ const clang::CFG &CFG = CFCtx.getCFG ();
500
+ PostOrderCFGView POV (&CFG);
501
+ ForwardDataflowWorklist Worklist (CFG, &POV);
507
502
508
503
std::vector<std::optional<TypeErasedDataflowAnalysisState>> BlockStates (
509
- CFCtx. getCFG () .size ());
504
+ CFG .size ());
510
505
511
506
// The entry basic block doesn't contain statements so it can be skipped.
512
- const CFGBlock &Entry = CFCtx. getCFG () .getEntry ();
507
+ const CFGBlock &Entry = CFG .getEntry ();
513
508
BlockStates[Entry.getBlockID ()] = {Analysis.typeErasedInitialElement (),
514
509
InitEnv.fork ()};
515
510
Worklist.enqueueSuccessors (&Entry);
@@ -553,7 +548,7 @@ runTypeErasedDataflowAnalysis(
553
548
llvm::errs () << " Old Env:\n " ;
554
549
OldBlockState->Env .dump ();
555
550
});
556
- if (isLoopHead (*Block)) {
551
+ if (isBackedgeNode (*Block)) {
557
552
LatticeJoinEffect Effect1 = Analysis.widenTypeErased (
558
553
NewBlockState.Lattice , OldBlockState->Lattice );
559
554
LatticeJoinEffect Effect2 =
0 commit comments