r308592 - Revert "[StaticAnalyzer] Completely unrolling specific loops with known bound option"

Peter Szecsi via cfe-commits cfe-commits at lists.llvm.org
Thu Jul 20 00:35:11 PDT 2017


Author: szepet
Date: Thu Jul 20 00:35:11 2017
New Revision: 308592

URL: http://llvm.org/viewvc/llvm-project?rev=308592&view=rev
Log:
Revert "[StaticAnalyzer] Completely unrolling specific loops with known bound option"

Revert r308561 and r308558.

Clang-ppc64be-linux seems to crash while running the test cases.


Removed:
    cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/LoopUnrolling.h
    cfe/trunk/lib/StaticAnalyzer/Core/LoopUnrolling.cpp
    cfe/trunk/test/Analysis/loop-unrolling.cpp
Modified:
    cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
    cfe/trunk/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/CMakeLists.txt
    cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
    cfe/trunk/test/Analysis/analyzer-config.c
    cfe/trunk/test/Analysis/analyzer-config.cpp

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h?rev=308592&r1=308591&r2=308592&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/AnalyzerOptions.h Thu Jul 20 00:35:11 2017
@@ -275,9 +275,6 @@ private:
   /// \sa shouldWidenLoops
   Optional<bool> WidenLoops;
 
-  /// \sa shouldUnrollLoops
-  Optional<bool> UnrollLoops;
-
   /// \sa shouldDisplayNotesAsEvents
   Optional<bool> DisplayNotesAsEvents;
 
@@ -563,11 +560,7 @@ public:
   /// This is controlled by the 'widen-loops' config option.
   bool shouldWidenLoops();
 
-  /// Returns true if the analysis should try to unroll loops with known bounds.
-  /// This is controlled by the 'unroll-loops' config option.
-  bool shouldUnrollLoops();
-
-    /// Returns true if the bug reporter should transparently treat extra note
+  /// Returns true if the bug reporter should transparently treat extra note
   /// diagnostic pieces as event diagnostic pieces. Useful when the diagnostic
   /// consumer doesn't support the extra note pieces.
   ///

Removed: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/LoopUnrolling.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/LoopUnrolling.h?rev=308591&view=auto
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/LoopUnrolling.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/LoopUnrolling.h (removed)
@@ -1,33 +0,0 @@
-//===--- LoopUnrolling.h - Unroll loops -------------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// This header contains the declarations of functions which are used to decide
-/// which loops should be completely unrolled and mark their corresponding
-/// CFGBlocks.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_LOOPUNROLLING_H
-#define LLVM_CLANG_STATICANALYZER_CORE_PATHSENSITIVE_LOOPUNROLLING_H
-
-#include "clang/Analysis/CFG.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ProgramState.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/ExplodedGraph.h"
-
-namespace clang {
-namespace ento {
-ProgramStateRef markLoopAsUnrolled(const Stmt *Term, ProgramStateRef State,
-                                   CFGStmtMap *StmtToBlockMap);
-bool isUnrolledLoopBlock(const CFGBlock *Block, ExplodedNode *Prev);
-bool shouldCompletelyUnroll(const Stmt *LoopStmt, ASTContext &ASTCtx);
-
-} // end namespace ento
-} // end namespace clang
-
-#endif

Modified: cfe/trunk/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp?rev=308592&r1=308591&r2=308592&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Checkers/ExprInspectionChecker.cpp Thu Jul 20 00:35:11 2017
@@ -272,7 +272,6 @@ void ExprInspectionChecker::checkEndAnal
 
     reportBug(llvm::to_string(NumTimesReached), BR, N);
   }
-  ReachedStats.clear();
 }
 
 void ExprInspectionChecker::analyzerCrash(const CallExpr *CE,

Modified: cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp?rev=308592&r1=308591&r2=308592&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/AnalyzerOptions.cpp Thu Jul 20 00:35:11 2017
@@ -375,12 +375,6 @@ bool AnalyzerOptions::shouldWidenLoops()
   return WidenLoops.getValue();
 }
 
-bool AnalyzerOptions::shouldUnrollLoops() {
-  if (!UnrollLoops.hasValue())
-    UnrollLoops = getBooleanOption("unroll-loops", /*Default=*/false);
-  return UnrollLoops.getValue();
-}
-
 bool AnalyzerOptions::shouldDisplayNotesAsEvents() {
   if (!DisplayNotesAsEvents.hasValue())
     DisplayNotesAsEvents =

Modified: cfe/trunk/lib/StaticAnalyzer/Core/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/CMakeLists.txt?rev=308592&r1=308591&r2=308592&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/CMakeLists.txt (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/CMakeLists.txt Thu Jul 20 00:35:11 2017
@@ -35,7 +35,6 @@ add_clang_library(clangStaticAnalyzerCor
   ExprEngineObjC.cpp
   FunctionSummary.cpp
   HTMLDiagnostics.cpp
-  LoopUnrolling.cpp
   LoopWidening.cpp
   MemRegion.cpp
   PathDiagnostic.cpp
@@ -55,7 +54,6 @@ add_clang_library(clangStaticAnalyzerCor
 
   LINK_LIBS
   clangAST
-  clangASTMatchers
   clangAnalysis
   clangBasic
   clangLex

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp?rev=308592&r1=308591&r2=308592&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngine.cpp Thu Jul 20 00:35:11 2017
@@ -17,7 +17,6 @@
 #include "PrettyStackTraceLocationContext.h"
 #include "clang/AST/CharUnits.h"
 #include "clang/AST/ParentMap.h"
-#include "clang/Analysis/CFGStmtMap.h"
 #include "clang/AST/StmtCXX.h"
 #include "clang/AST/StmtObjC.h"
 #include "clang/Basic/Builtins.h"
@@ -28,7 +27,6 @@
 #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
 #include "clang/StaticAnalyzer/Core/PathSensitive/LoopWidening.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/LoopUnrolling.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/Support/SaveAndRestore.h"
 #include "llvm/Support/raw_ostream.h"
@@ -1499,27 +1497,6 @@ void ExprEngine::processCFGBlockEntrance
                                          NodeBuilderWithSinks &nodeBuilder,
                                          ExplodedNode *Pred) {
   PrettyStackTraceLocationContext CrashInfo(Pred->getLocationContext());
-  // If we reach a loop which has a known bound (and meets
-  // other constraints) then consider completely unrolling it.
-  if (AMgr.options.shouldUnrollLoops()) {
-    const CFGBlock *ActualBlock = nodeBuilder.getContext().getBlock();
-    const Stmt *Term = ActualBlock->getTerminator();
-    if (Term && shouldCompletelyUnroll(Term, AMgr.getASTContext())) {
-      ProgramStateRef UnrolledState =
-              markLoopAsUnrolled(Term, Pred->getState(),
-                                 Pred->getLocationContext()
-                                         ->getAnalysisDeclContext()
-                                         ->getCFGStmtMap());
-      if (UnrolledState != Pred->getState())
-        nodeBuilder.generateNode(UnrolledState, Pred);
-      return;
-    }
-
-    if (isUnrolledLoopBlock(ActualBlock, Pred))
-      return;
-    if (ActualBlock->empty())
-      return;
-  }
 
   // If this block is terminated by a loop and it has already been visited the
   // maximum number of times, widen the loop.
@@ -1687,6 +1664,7 @@ void ExprEngine::processBranch(const Stm
   const LocationContext *LCtx = Pred->getLocationContext();
   PrettyStackTraceLocationContext StackCrashInfo(LCtx);
   currBldrCtx = &BldCtx;
+
   // Check for NULL conditions; e.g. "for(;;)"
   if (!Condition) {
     BranchNodeBuilder NullCondBldr(Pred, Dst, BldCtx, DstT, DstF);

Removed: cfe/trunk/lib/StaticAnalyzer/Core/LoopUnrolling.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/LoopUnrolling.cpp?rev=308591&view=auto
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/LoopUnrolling.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/LoopUnrolling.cpp (removed)
@@ -1,203 +0,0 @@
-//===--- LoopUnrolling.cpp - Unroll loops -----------------------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// This file contains functions which are used to decide if a loop worth to be
-/// unrolled. Moreover contains function which mark the CFGBlocks which belongs
-/// to the unrolled loop and store them in ProgramState.
-///
-//===----------------------------------------------------------------------===//
-
-#include "clang/Analysis/CFGStmtMap.h"
-#include "clang/ASTMatchers/ASTMatchers.h"
-#include "clang/ASTMatchers/ASTMatchFinder.h"
-#include "clang/AST/ParentMap.h"
-#include "clang/AST/StmtVisitor.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
-#include "clang/StaticAnalyzer/Core/PathSensitive/LoopUnrolling.h"
-#include "llvm/ADT/Statistic.h"
-
-using namespace clang;
-using namespace ento;
-using namespace clang::ast_matchers;
-
-#define DEBUG_TYPE "LoopUnrolling"
-
-STATISTIC(NumTimesLoopUnrolled,
-          "The # of times a loop has got completely unrolled");
-
-REGISTER_MAP_WITH_PROGRAMSTATE(UnrolledLoops, const Stmt *, const CFGStmtMap *)
-
-namespace clang {
-namespace ento {
-
-static bool isLoopStmt(const Stmt *S) {
-  return S && (isa<ForStmt>(S) || isa<WhileStmt>(S) || isa<DoStmt>(S));
-}
-
-static internal::Matcher<Stmt> simpleCondition(StringRef BindName) {
-  return binaryOperator(
-      anyOf(hasOperatorName("<"), hasOperatorName(">"), hasOperatorName("<="),
-            hasOperatorName(">="), hasOperatorName("!=")),
-      hasEitherOperand(ignoringParenImpCasts(
-          declRefExpr(to(varDecl(hasType(isInteger())).bind(BindName))))),
-      hasEitherOperand(ignoringParenImpCasts(integerLiteral())));
-}
-
-static internal::Matcher<Stmt> changeIntBoundNode(StringRef NodeName) {
-  return anyOf(hasDescendant(unaryOperator(
-                   anyOf(hasOperatorName("--"), hasOperatorName("++")),
-                   hasUnaryOperand(ignoringParenImpCasts(
-                       declRefExpr(to(varDecl(equalsBoundNode(NodeName)))))))),
-               hasDescendant(binaryOperator(
-                   anyOf(hasOperatorName("="), hasOperatorName("+="),
-                         hasOperatorName("/="), hasOperatorName("*="),
-                         hasOperatorName("-=")),
-                   hasLHS(ignoringParenImpCasts(
-                       declRefExpr(to(varDecl(equalsBoundNode(NodeName)))))))));
-}
-
-static internal::Matcher<Stmt> callByRef(StringRef NodeName) {
-  return hasDescendant(callExpr(forEachArgumentWithParam(
-      declRefExpr(to(varDecl(equalsBoundNode(NodeName)))),
-      parmVarDecl(hasType(references(qualType(unless(isConstQualified()))))))));
-}
-
-static internal::Matcher<Stmt> assignedToRef(StringRef NodeName) {
-  return hasDescendant(varDecl(
-      allOf(hasType(referenceType()),
-            hasInitializer(anyOf(
-                initListExpr(has(
-                    declRefExpr(to(varDecl(equalsBoundNode(NodeName)))))),
-                declRefExpr(to(varDecl(equalsBoundNode(NodeName)))))))));
-}
-
-static internal::Matcher<Stmt> getAddrTo(StringRef NodeName) {
-  return hasDescendant(unaryOperator(
-      hasOperatorName("&"),
-      hasUnaryOperand(declRefExpr(hasDeclaration(equalsBoundNode(NodeName))))));
-}
-
-static internal::Matcher<Stmt> hasSuspiciousStmt(StringRef NodeName) {
-  return anyOf(hasDescendant(gotoStmt()), hasDescendant(switchStmt()),
-               // Escaping and not known mutation of the loop counter is handled
-               // by exclusion of assigning and address-of operators and
-               // pass-by-ref function calls on the loop counter from the body.
-               changeIntBoundNode(NodeName), callByRef(NodeName),
-               getAddrTo(NodeName), assignedToRef(NodeName));
-}
-
-static internal::Matcher<Stmt> forLoopMatcher() {
-  return forStmt(
-             hasCondition(simpleCondition("initVarName")),
-             // Initialization should match the form: 'int i = 6' or 'i = 42'.
-             hasLoopInit(
-                 anyOf(declStmt(hasSingleDecl(
-                           varDecl(allOf(hasInitializer(integerLiteral()),
-                                         equalsBoundNode("initVarName"))))),
-                       binaryOperator(hasLHS(declRefExpr(to(varDecl(
-                                          equalsBoundNode("initVarName"))))),
-                                      hasRHS(integerLiteral())))),
-             // Incrementation should be a simple increment or decrement
-             // operator call.
-             hasIncrement(unaryOperator(
-                 anyOf(hasOperatorName("++"), hasOperatorName("--")),
-                 hasUnaryOperand(declRefExpr(
-                     to(varDecl(allOf(equalsBoundNode("initVarName"),
-                                      hasType(isInteger())))))))),
-             unless(hasBody(hasSuspiciousStmt("initVarName")))).bind("forLoop");
-}
-
-bool shouldCompletelyUnroll(const Stmt *LoopStmt, ASTContext &ASTCtx) {
-
-  if (!isLoopStmt(LoopStmt))
-    return false;
-
-  // TODO: Match the cases where the bound is not a concrete literal but an
-  // integer with known value
-
-  auto Matches = match(forLoopMatcher(), *LoopStmt, ASTCtx);
-  return !Matches.empty();
-}
-
-namespace {
-class LoopBlockVisitor : public ConstStmtVisitor<LoopBlockVisitor> {
-public:
-  LoopBlockVisitor(llvm::SmallPtrSet<const CFGBlock *, 8> &BS) : BlockSet(BS) {}
-
-  void VisitChildren(const Stmt *S) {
-    for (const Stmt *Child : S->children())
-      if (Child)
-        Visit(Child);
-  }
-
-  void VisitStmt(const Stmt *S) {
-    // In case of nested loops we only unroll the inner loop if it's marked too.
-    if (!S || (isLoopStmt(S) && S != LoopStmt))
-      return;
-    BlockSet.insert(StmtToBlockMap->getBlock(S));
-    VisitChildren(S);
-  }
-
-  void setBlocksOfLoop(const Stmt *Loop, const CFGStmtMap *M) {
-    BlockSet.clear();
-    StmtToBlockMap = M;
-    LoopStmt = Loop;
-    Visit(LoopStmt);
-  }
-
-private:
-  llvm::SmallPtrSet<const CFGBlock *, 8> &BlockSet;
-  const CFGStmtMap *StmtToBlockMap;
-  const Stmt *LoopStmt;
-};
-}
-// TODO: refactor this function using ScopeContext - once we have the
-// information when the simulation reaches the end of the loop we can cleanup
-// the state
-bool isUnrolledLoopBlock(const CFGBlock *Block, ExplodedNode *Prev) {
-  const Stmt *Term = Block->getTerminator();
-  auto State = Prev->getState();
-  // In case of nested loops in an inlined function should not be unrolled only
-  // if the inner loop is marked.
-  if (Term && isLoopStmt(Term) && !State->contains<UnrolledLoops>(Term))
-    return false;
-
-  const CFGBlock *SearchedBlock;
-  llvm::SmallPtrSet<const CFGBlock *, 8> BlockSet;
-  LoopBlockVisitor LBV(BlockSet);
-  // Check the CFGBlocks of every marked loop.
-  for (auto &E : State->get<UnrolledLoops>()) {
-    SearchedBlock = Block;
-    const StackFrameContext *StackFrame = Prev->getStackFrame();
-    LBV.setBlocksOfLoop(E.first, E.second);
-    // In case of an inlined function call check if any of its callSiteBlock is
-    // marked.
-    while (SearchedBlock && BlockSet.find(SearchedBlock) == BlockSet.end()) {
-      SearchedBlock = StackFrame->getCallSiteBlock();
-      StackFrame = StackFrame->getParent()->getCurrentStackFrame();
-    }
-
-    if (SearchedBlock)
-      return true;
-  }
-  return false;
-}
-
-ProgramStateRef markLoopAsUnrolled(const Stmt *Term, ProgramStateRef State,
-                                   CFGStmtMap *StmtToBlockMap) {
-  if (State->contains<UnrolledLoops>(Term))
-    return State;
-
-  State = State->set<UnrolledLoops>(Term, StmtToBlockMap);
-  ++NumTimesLoopUnrolled;
-  return State;
-}
-}
-}

Modified: cfe/trunk/test/Analysis/analyzer-config.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/analyzer-config.c?rev=308592&r1=308591&r2=308592&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/analyzer-config.c (original)
+++ cfe/trunk/test/Analysis/analyzer-config.c Thu Jul 20 00:35:11 2017
@@ -27,7 +27,6 @@ void foo() {
 // CHECK-NEXT: min-cfg-size-treat-functions-as-large = 14
 // CHECK-NEXT: mode = deep
 // CHECK-NEXT: region-store-small-struct-limit = 2
-// CHECK-NEXT: unroll-loops = false
 // CHECK-NEXT: widen-loops = false
 // CHECK-NEXT: [stats]
-// CHECK-NEXT: num-entries = 18
+// CHECK-NEXT: num-entries = 17

Modified: cfe/trunk/test/Analysis/analyzer-config.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/analyzer-config.cpp?rev=308592&r1=308591&r2=308592&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/analyzer-config.cpp (original)
+++ cfe/trunk/test/Analysis/analyzer-config.cpp Thu Jul 20 00:35:11 2017
@@ -38,7 +38,6 @@ public:
 // CHECK-NEXT: min-cfg-size-treat-functions-as-large = 14
 // CHECK-NEXT: mode = deep
 // CHECK-NEXT: region-store-small-struct-limit = 2
-// CHECK-NEXT: unroll-loops = false
 // CHECK-NEXT: widen-loops = false
 // CHECK-NEXT: [stats]
-// CHECK-NEXT: num-entries = 23
+// CHECK-NEXT: num-entries = 22

Removed: cfe/trunk/test/Analysis/loop-unrolling.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/loop-unrolling.cpp?rev=308591&view=auto
==============================================================================
--- cfe/trunk/test/Analysis/loop-unrolling.cpp (original)
+++ cfe/trunk/test/Analysis/loop-unrolling.cpp (removed)
@@ -1,181 +0,0 @@
-// REQUIRES: asserts
-// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -analyzer-config unroll-loops=true -analyzer-stats -verify -std=c++11 %s 2>&1 | FileCheck %s
-
-void clang_analyzer_numTimesReached();
-
-int getNum();
-void foo(int &);
-// Testing for loops.
-int simple_unroll1() {
-  int a[9];
-  int k = 42;
-  for (int i = 0; i < 9; i++) {
-    clang_analyzer_numTimesReached(); // expected-warning {{9}}
-    a[i] = 42;
-  }
-  int b = 22 / (k - 42); // expected-warning {{Division by zero}}
-  return 0;
-}
-
-int simple_unroll2() {
-  int a[9];
-  int k = 42;
-  int i;
-  for (i = 0; i < 9; i++) {
-    clang_analyzer_numTimesReached(); // expected-warning {{9}}
-    a[i] = 42;
-  }
-  int b = 22 / (k - 42); // expected-warning {{Division by zero}}
-  return 0;
-}
-
-int simple_no_unroll1() {
-  int a[9];
-  int k = 42;
-  for (int i = 0; i < 9; i++) {
-    clang_analyzer_numTimesReached(); // expected-warning {{4}}
-    a[i] = 42;
-    foo(i);
-  }
-  int b = 22 / (k - 42); // expected-warning {{Division by zero}}
-  return 0;
-}
-
-int simple_no_unroll2() {
-  int a[9];
-  int k = 42;
-  int i;
-  for (i = 0; i < 9; i++) {
-    clang_analyzer_numTimesReached(); // expected-warning {{4}}
-    a[i] = 42;
-    i += getNum();
-  }
-  int b = 22 / (k - 42); // expected-warning {{Division by zero}}
-  return 0;
-}
-
-int simple_no_unroll3() {
-  int a[9];
-  int k = 42;
-  int i;
-  for (i = 0; i < 9; i++) {
-    clang_analyzer_numTimesReached(); // expected-warning {{4}}
-    a[i] = 42;
-    (void)&i;
-  }
-  int b = 22 / (k - 42); // no-warning
-  return 0;
-}
-
-int simple_no_unroll4() {
-  int a[9];
-  int k = 42;
-  int i;
-  for (i = 0; i < 9; i++) {
-    clang_analyzer_numTimesReached(); // expected-warning {{4}}
-    a[i] = 42;
-    int &j = i;
-  }
-  int b = 22 / (k - 42); // no-warning
-  return 0;
-}
-
-int simple_no_unroll5() {
-  int a[9];
-  int k = 42;
-  int i;
-  for (i = 0; i < 9; i++) {
-    clang_analyzer_numTimesReached(); // expected-warning {{4}}
-    a[i] = 42;
-    int &j{i};
-  }
-  int b = 22 / (k - 42); // no-warning
-  return 0;
-}
-
-int nested_outer_unrolled() {
-  int a[9];
-  int k = 42;
-  int j = 0;
-  for (int i = 0; i < 9; i++) {
-    clang_analyzer_numTimesReached(); // expected-warning {{16}}
-    for (j = 0; j < getNum(); ++j) {
-      clang_analyzer_numTimesReached(); // expected-warning {{15}}
-      a[j] = 22;
-    }
-    a[i] = 42;
-  }
-  int b = 22 / (k - 42); // no-warning
-  return 0;
-}
-
-int nested_inner_unrolled() {
-  int a[9];
-  int k = 42;
-  int j = 0;
-  for (int i = 0; i < getNum(); i++) {
-    clang_analyzer_numTimesReached(); // expected-warning {{4}}
-    for (j = 0; j < 8; ++j) {
-      clang_analyzer_numTimesReached(); // expected-warning {{32}}
-      a[j] = 22;
-    }
-    a[i] = 42;
-  }
-  int b = 22 / (k - 42); // expected-warning {{Division by zero}}
-  return 0;
-}
-
-int nested_both_unrolled() {
-  int a[9];
-  int k = 42;
-  int j = 0;
-  for (int i = 0; i < 7; i++) {
-    clang_analyzer_numTimesReached(); // expected-warning {{7}}
-    for (j = 0; j < 6; ++j) {
-      clang_analyzer_numTimesReached(); // expected-warning {{42}}
-      a[j] = 22;
-    }
-    a[i] = 42;
-  }
-  int b = 22 / (k - 42); // expected-warning {{Division by zero}}
-  return 0;
-}
-
-int simple_known_bound_loop() {
-  for (int i = 2; i < 12; i++) {
-    // This function is inlined in nested_inlined_unroll1()
-    clang_analyzer_numTimesReached(); // expected-warning {{90}}
-  }
-  return 0;
-}
-
-int simple_unknown_bound_loop() {
-  for (int i = 2; i < getNum(); i++) {
-    clang_analyzer_numTimesReached(); // expected-warning {{10}}
-  }
-  return 0;
-}
-
-int nested_inlined_unroll1() {
-  int k;
-  for (int i = 0; i < 9; i++) {
-    clang_analyzer_numTimesReached(); // expected-warning {{9}}
-    k = simple_known_bound_loop(); // no reevaluation without inlining
-  }
-  int a = 22 / k; // expected-warning {{Division by zero}}
-  return 0;
-}
-
-int nested_inlined_no_unroll1() {
-  int k;
-  for (int i = 0; i < 9; i++) {
-    clang_analyzer_numTimesReached(); // expected-warning {{26}}
-    k = simple_unknown_bound_loop(); // reevaluation without inlining
-  }
-  int a = 22 / k; // no-warning
-  return 0;
-}
-
-// CHECK: ... Statistics Collected ...
-// CHECK: 5 ExprEngine       - The # of times we re-evaluated a call without inlining
-// CHECK: 9 LoopUnrolling    - The # of times a loop has got completely unrolled




More information about the cfe-commits mailing list