1212// ===----------------------------------------------------------------------===//
1313
1414#include  < algorithm> 
15- #include  < memory> 
1615#include  < optional> 
1716#include  < system_error> 
1817#include  < utility> 
3332#include  " clang/Analysis/FlowSensitive/TypeErasedDataflowAnalysis.h" 
3433#include  " clang/Analysis/FlowSensitive/Value.h" 
3534#include  " llvm/ADT/ArrayRef.h" 
36- #include  " llvm/ADT/DenseSet.h" 
3735#include  " llvm/ADT/STLExtras.h" 
36+ #include  " llvm/ADT/SmallBitVector.h" 
3837#include  " llvm/Support/Debug.h" 
3938#include  " llvm/Support/Error.h" 
4039
@@ -53,19 +52,14 @@ static int blockIndexInPredecessor(const CFGBlock &Pred,
5352  return  BlockPos - Pred.succ_begin ();
5453}
5554
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 ;
6963}
7064
7165namespace  {
@@ -502,14 +496,15 @@ runTypeErasedDataflowAnalysis(
502496        PostVisitCFG) {
503497  PrettyStackTraceAnalysis CrashInfo (CFCtx, " runTypeErasedDataflowAnalysis"  );
504498
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);
507502
508503  std::vector<std::optional<TypeErasedDataflowAnalysisState>> BlockStates (
509-       CFCtx. getCFG () .size ());
504+       CFG .size ());
510505
511506  //  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 ();
513508  BlockStates[Entry.getBlockID ()] = {Analysis.typeErasedInitialElement (),
514509                                     InitEnv.fork ()};
515510  Worklist.enqueueSuccessors (&Entry);
@@ -553,7 +548,7 @@ runTypeErasedDataflowAnalysis(
553548        llvm::errs () << " Old Env:\n "  ;
554549        OldBlockState->Env .dump ();
555550      });
556-       if  (isLoopHead (*Block)) {
551+       if  (isBackedgeNode (*Block)) {
557552        LatticeJoinEffect Effect1 = Analysis.widenTypeErased (
558553            NewBlockState.Lattice , OldBlockState->Lattice );
559554        LatticeJoinEffect Effect2 =
0 commit comments