[PATCH] D72235: [clang-tidy] new altera unroll loops check

2021-03-22 Thread Frank Derry Wanye via Phabricator via cfe-commits
ffrankies added a comment.

Thank you very much!


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72235/new/

https://reviews.llvm.org/D72235

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D72235: [clang-tidy] new altera unroll loops check

2021-03-22 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman closed this revision.
aaron.ballman added a comment.

Thanks! I've commit on your behalf in 5a87f81fe9aee996dfe3a84dd833f0a48e093e7f 



CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72235/new/

https://reviews.llvm.org/D72235

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D72235: [clang-tidy] new altera unroll loops check

2021-03-22 Thread Frank Derry Wanye via Phabricator via cfe-commits
ffrankies marked 7 inline comments as done.
ffrankies added a comment.

@aaron.ballman If there are no more changes, can you please commit this on my 
behalf? My github username is ffrankies .


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72235/new/

https://reviews.llvm.org/D72235

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D72235: [clang-tidy] new altera unroll loops check

2021-03-22 Thread Frank Derry Wanye via Phabricator via cfe-commits
ffrankies updated this revision to Diff 332303.
ffrankies added a comment.

Implemented changes requested by @aaron.ballman


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72235/new/

https://reviews.llvm.org/D72235

Files:
  clang-tools-extra/clang-tidy/altera/AlteraTidyModule.cpp
  clang-tools-extra/clang-tidy/altera/CMakeLists.txt
  clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp
  clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/altera-unroll-loops.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  clang-tools-extra/test/clang-tidy/checkers/altera-unroll-loops.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/altera-unroll-loops.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/altera-unroll-loops.cpp
@@ -0,0 +1,516 @@
+// RUN: %check_clang_tidy %s altera-unroll-loops %t -- -config="{CheckOptions: [{key: "altera-unroll-loops.MaxLoopIterations", value: 50}]}" -header-filter=.*
+// RUN: %check_clang_tidy -check-suffix=MULT %s altera-unroll-loops %t -- -config="{CheckOptions: [{key: "altera-unroll-loops.MaxLoopIterations", value: 5}]}" -header-filter=.* "--" -DMULT
+
+#ifdef MULT
+// For loops with *= and /= increments.
+void for_loop_mult_div_increments(int *A) {
+// *=
+#pragma unroll
+  for (int i = 2; i <= 32; i *= 2)
+A[i]++; // OK
+
+#pragma unroll
+  for (int i = 2; i <= 64; i *= 2)
+// CHECK-MESSAGES-MULT: :[[@LINE-1]]:3: warning: loop likely has a large number of iterations and thus cannot be fully unrolled; to partially unroll this loop, use the '#pragma unroll ' directive [altera-unroll-loops]
+A[i]++; // Not OK
+
+// /=
+#pragma unroll
+  for (int i = 32; i >= 2; i /= 2)
+A[i]++; // OK
+
+#pragma unroll
+  for (int i = 64; i >= 2; i /= 2)
+// CHECK-MESSAGES-MULT: :[[@LINE-1]]:3: warning: loop likely has a large number of iterations and thus cannot be fully unrolled; to partially unroll this loop, use the '#pragma unroll ' directive [altera-unroll-loops]
+A[i]++; // Not OK
+}
+#else
+// Cannot determine loop bounds for while loops.
+void while_loops(int *A) {
+  // Recommend unrolling loops that aren't already unrolled.
+  int j = 0;
+  while (j < 2000) {
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: kernel performance could be improved by unrolling this loop with a '#pragma unroll' directive [altera-unroll-loops]
+A[1] += j;
+j++;
+  }
+
+  do {
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: kernel performance could be improved by unrolling this loop with a '#pragma unroll' directive [altera-unroll-loops]
+A[2] += j;
+j++;
+  } while (j < 2000);
+
+// If a while loop is fully unrolled, add a note recommending partial
+// unrolling.
+#pragma unroll
+  while (j < 2000) {
+// CHECK-MESSAGES: :[[@LINE-1]]:3: note: full unrolling requested, but loop bounds may not be known; to partially unroll this loop, use the '#pragma unroll ' directive
+A[j]++;
+  }
+
+#pragma unroll
+  do {
+// CHECK-MESSAGES: :[[@LINE-1]]:3: note: full unrolling requested, but loop bounds may not be known; to partially unroll this loop, use the '#pragma unroll ' directive
+A[j]++;
+  } while (j < 2000);
+
+// While loop is partially unrolled, no action needed.
+#pragma unroll 4
+  while (j < 2000) {
+A[j]++;
+  }
+
+#pragma unroll 4
+  do {
+A[j]++;
+  } while (j < 2000);
+}
+
+// Range-based for loops.
+void cxx_for_loops(int *A, int vectorSize) {
+  // Loop with known array size should be unrolled.
+  int a[] = {0, 1, 2, 3, 4, 5};
+  for (int k : a) {
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: kernel performance could be improved by unrolling this loop with a '#pragma unroll' directive [altera-unroll-loops]
+A[k]++;
+  }
+
+// Loop with known size correctly unrolled.
+#pragma unroll
+  for (int k : a) {
+A[k]++;
+  }
+
+  // Loop with unknown size should be partially unrolled.
+  int b[vectorSize];
+#pragma unroll
+  for (int k : b) {
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: full unrolling requested, but loop bounds are not known; to partially unroll this loop, use the '#pragma unroll ' directive [altera-unroll-loops]
+k++;
+  }
+
+// Loop with unknown size correctly unrolled.
+#pragma unroll 5
+  for (int k : b) {
+k++;
+  }
+
+  // Loop with large size should be partially unrolled.
+  int c[51];
+#pragma unroll
+  for (int k : c) {
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: loop likely has a large number of iterations and thus cannot be fully unrolled; to partially unroll this loop, use the '#pragma unroll ' directive [altera-unroll-loops]
+A[k]++;
+  }
+
+// Loop with large size correctly unrolled.
+#pragma unroll 5
+  for (int k : c) {
+A[k]++;
+  }
+}
+
+// Simple for loops.
+void for_loops(int *A, int size) {
+  // Recommend unrolling loops that aren't already unrolled.
+  for (int i = 0; i < 2000; ++i) {
+ 

[PATCH] D72235: [clang-tidy] new altera unroll loops check

2021-03-18 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman accepted this revision.
aaron.ballman added a comment.
This revision is now accepted and ready to land.

Mostly just nits for the check, otherwise this LGTM.




Comment at: clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp:65
+}
+if (isa(Loop) || isa(Loop)) {
+  diag(Loop->getBeginLoc(),





Comment at: clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp:83-84
+UnrollLoopsCheck::unrollType(const Stmt *Statement, ASTContext *Context) {
+  const clang::DynTypedNodeList Parents = 
Context->getParents(*Statement);
+  for (const clang::DynTypedNode  : Parents) {
+const auto *ParentStmt = Parent.get();

Pretty sure you don't need to use a qualified name here.



Comment at: clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp:116-120
+  if (isa(Statement)) {
+if (CXXLoopBound)
+  return true;
+return false;
+  }





Comment at: clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp:123
+  // unrolling for these.
+  if (isa(Statement) || isa(Statement))
+return false;





Comment at: clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp:176-177
+  if (isa(Statement)) {
+const auto *LoopBoundExpr = dyn_cast(CXXLoopBound);
+return exprHasLargeNumIterations(LoopBoundExpr, Context);
+  }

The cast isn't necessary (`IntergerLiteral` is already an `Expr`). You should 
probably assert that `CXXLoopBound` isn't null here though.



Comment at: clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp:180-181
+  const auto *ForLoop = dyn_cast(Statement);
+  if (!ForLoop)
+llvm_unreachable("Unknown loop");
+  const Stmt *Initializer = ForLoop->getInit();





Comment at: clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp:196-197
+  }
+  if (!isa(Conditional))
+llvm_unreachable("Conditional is not a binary operator");
+  int EndValue;




CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72235/new/

https://reviews.llvm.org/D72235

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D72235: [clang-tidy] new altera unroll loops check

2021-03-08 Thread Frank Derry Wanye via Phabricator via cfe-commits
ffrankies updated this revision to Diff 329207.
ffrankies added a comment.

- Ran `git-clang-format HEAD^`
- Addressed comments automatically added by the Lint: Pre-merge Checks


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72235/new/

https://reviews.llvm.org/D72235

Files:
  clang-tools-extra/clang-tidy/altera/AlteraTidyModule.cpp
  clang-tools-extra/clang-tidy/altera/CMakeLists.txt
  clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp
  clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/altera-unroll-loops.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  clang-tools-extra/test/clang-tidy/checkers/altera-unroll-loops.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/altera-unroll-loops.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/altera-unroll-loops.cpp
@@ -0,0 +1,516 @@
+// RUN: %check_clang_tidy %s altera-unroll-loops %t -- -config="{CheckOptions: [{key: "altera-unroll-loops.MaxLoopIterations", value: 50}]}" -header-filter=.*
+// RUN: %check_clang_tidy -check-suffix=MULT %s altera-unroll-loops %t -- -config="{CheckOptions: [{key: "altera-unroll-loops.MaxLoopIterations", value: 5}]}" -header-filter=.* "--" -DMULT
+
+#ifdef MULT
+// For loops with *= and /= increments.
+void for_loop_mult_div_increments(int *A) {
+// *=
+#pragma unroll
+  for (int i = 2; i <= 32; i *= 2)
+A[i]++; // OK
+
+#pragma unroll
+  for (int i = 2; i <= 64; i *= 2)
+// CHECK-MESSAGES-MULT: :[[@LINE-1]]:3: warning: loop likely has a large number of iterations and thus cannot be fully unrolled; to partially unroll this loop, use the '#pragma unroll ' directive [altera-unroll-loops]
+A[i]++; // Not OK
+
+// /=
+#pragma unroll
+  for (int i = 32; i >= 2; i /= 2)
+A[i]++; // OK
+
+#pragma unroll
+  for (int i = 64; i >= 2; i /= 2)
+// CHECK-MESSAGES-MULT: :[[@LINE-1]]:3: warning: loop likely has a large number of iterations and thus cannot be fully unrolled; to partially unroll this loop, use the '#pragma unroll ' directive [altera-unroll-loops]
+A[i]++; // Not OK
+}
+#else
+// Cannot determine loop bounds for while loops.
+void while_loops(int *A) {
+  // Recommend unrolling loops that aren't already unrolled.
+  int j = 0;
+  while (j < 2000) {
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: kernel performance could be improved by unrolling this loop with a '#pragma unroll' directive [altera-unroll-loops]
+A[1] += j;
+j++;
+  }
+
+  do {
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: kernel performance could be improved by unrolling this loop with a '#pragma unroll' directive [altera-unroll-loops]
+A[2] += j;
+j++;
+  } while (j < 2000);
+
+// If a while loop is fully unrolled, add a note recommending partial
+// unrolling.
+#pragma unroll
+  while (j < 2000) {
+// CHECK-MESSAGES: :[[@LINE-1]]:3: note: full unrolling requested, but loop bounds may not be known; to partially unroll this loop, use the '#pragma unroll ' directive
+A[j]++;
+  }
+
+#pragma unroll
+  do {
+// CHECK-MESSAGES: :[[@LINE-1]]:3: note: full unrolling requested, but loop bounds may not be known; to partially unroll this loop, use the '#pragma unroll ' directive
+A[j]++;
+  } while (j < 2000);
+
+// While loop is partially unrolled, no action needed.
+#pragma unroll 4
+  while (j < 2000) {
+A[j]++;
+  }
+
+#pragma unroll 4
+  do {
+A[j]++;
+  } while (j < 2000);
+}
+
+// Range-based for loops.
+void cxx_for_loops(int *A, int vectorSize) {
+  // Loop with known array size should be unrolled.
+  int a[] = {0, 1, 2, 3, 4, 5};
+  for (int k : a) {
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: kernel performance could be improved by unrolling this loop with a '#pragma unroll' directive [altera-unroll-loops]
+A[k]++;
+  }
+
+// Loop with known size correctly unrolled.
+#pragma unroll
+  for (int k : a) {
+A[k]++;
+  }
+
+  // Loop with unknown size should be partially unrolled.
+  int b[vectorSize];
+#pragma unroll
+  for (int k : b) {
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: full unrolling requested, but loop bounds are not known; to partially unroll this loop, use the '#pragma unroll ' directive [altera-unroll-loops]
+k++;
+  }
+
+// Loop with unknown size correctly unrolled.
+#pragma unroll 5
+  for (int k : b) {
+k++;
+  }
+
+  // Loop with large size should be partially unrolled.
+  int c[51];
+#pragma unroll
+  for (int k : c) {
+// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: loop likely has a large number of iterations and thus cannot be fully unrolled; to partially unroll this loop, use the '#pragma unroll ' directive [altera-unroll-loops]
+A[k]++;
+  }
+
+// Loop with large size correctly unrolled.
+#pragma unroll 5
+  for (int k : c) {
+A[k]++;
+  }
+}
+
+// Simple for loops.
+void for_loops(int *A, int size) {
+  // Recommend unrolling loops that aren't 

[PATCH] D72235: [clang-tidy] new altera unroll loops check

2021-03-08 Thread Frank Derry Wanye via Phabricator via cfe-commits
ffrankies updated this revision to Diff 329082.
ffrankies marked 6 inline comments as done.
ffrankies added a comment.

Rebased with the latest main branch to fix patch application errors.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72235/new/

https://reviews.llvm.org/D72235

Files:
  clang-tools-extra/clang-tidy/altera/AlteraTidyModule.cpp
  clang-tools-extra/clang-tidy/altera/CMakeLists.txt
  clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp
  clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/altera-unroll-loops.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  clang-tools-extra/test/clang-tidy/checkers/altera-unroll-loops.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/altera-unroll-loops.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/altera-unroll-loops.cpp
@@ -0,0 +1,518 @@
+// RUN: %check_clang_tidy %s altera-unroll-loops %t -- -config="{CheckOptions: [{key: "altera-unroll-loops.MaxLoopIterations", value: 50}]}" -header-filter=.*
+// RUN: %check_clang_tidy -check-suffix=MULT %s altera-unroll-loops %t -- -config="{CheckOptions: [{key: "altera-unroll-loops.MaxLoopIterations", value: 5}]}" -header-filter=.* "--" -DMULT
+
+#ifdef MULT
+// For loops with *= and /= increments.
+void for_loop_mult_div_increments(int *A) {
+// *=
+#pragma unroll
+for (int i = 2; i <= 32; i *= 2)
+A[i]++;  // OK
+
+#pragma unroll
+for (int i = 2; i <= 64; i *= 2)
+// CHECK-MESSAGES-MULT: :[[@LINE-1]]:5: warning: loop likely has a large number of iterations and thus cannot be fully unrolled; to partially unroll this loop, use the '#pragma unroll ' directive [altera-unroll-loops]
+A[i]++;  // Not OK
+
+// /=
+#pragma unroll
+for (int i = 32; i >= 2; i /= 2)
+A[i]++;  // OK
+
+#pragma unroll
+for (int i = 64; i >= 2; i /= 2)
+// CHECK-MESSAGES-MULT: :[[@LINE-1]]:5: warning: loop likely has a large number of iterations and thus cannot be fully unrolled; to partially unroll this loop, use the '#pragma unroll ' directive [altera-unroll-loops]
+A[i]++;  // Not OK
+}
+#else
+// Cannot determine loop bounds for while loops.
+void while_loops(int *A) {
+// Recommend unrolling loops that aren't already unrolled.
+int j = 0;
+while (j < 2000) {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: kernel performance could be improved by unrolling this loop with a '#pragma unroll' directive [altera-unroll-loops]
+A[1] += j;
+j++;
+}
+
+do {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: kernel performance could be improved by unrolling this loop with a '#pragma unroll' directive [altera-unroll-loops]
+A[2] += j;
+j++;
+} while (j < 2000);
+
+// If a while loop is fully unrolled, add a note recommending partial
+// unrolling.
+#pragma unroll
+while (j < 2000) {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: note: full unrolling requested, but loop bounds may not be known; to partially unroll this loop, use the '#pragma unroll ' directive
+A[j]++;
+}
+
+#pragma unroll
+do {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: note: full unrolling requested, but loop bounds may not be known; to partially unroll this loop, use the '#pragma unroll ' directive
+A[j]++;
+} while (j < 2000);
+
+// While loop is partially unrolled, no action needed.
+#pragma unroll 4
+while (j < 2000) {
+A[j]++;
+}
+
+#pragma unroll 4
+do {
+A[j]++;
+} while (j < 2000);
+}
+
+// Range-based for loops.
+void cxx_for_loops(int *A, int vectorSize) {
+// Loop with known array size should be unrolled.
+int a[] = { 0, 1, 2, 3, 4, 5 };
+for (int k : a) {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: kernel performance could be improved by unrolling this loop with a '#pragma unroll' directive [altera-unroll-loops]
+A[k]++;
+}
+
+// Loop with known size correctly unrolled.
+#pragma unroll
+for (int k : a) {
+A[k]++;
+}
+
+// Loop with unknown size should be partially unrolled.
+int b[vectorSize];
+#pragma unroll
+for (int k : b) {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: full unrolling requested, but loop bounds are not known; to partially unroll this loop, use the '#pragma unroll ' directive [altera-unroll-loops]
+k++;
+}
+
+// Loop with unknown size correctly unrolled.
+#pragma unroll 5
+for (int k : b) {
+k++;
+}
+
+// Loop with large size should be partially unrolled.
+int c[51];
+#pragma unroll
+for (int k : c) {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: loop likely has a large number of iterations and thus cannot be fully unrolled; to partially unroll this loop, use the '#pragma unroll ' directive [altera-unroll-loops]
+A[k]++;
+}
+
+// Loop with 

[PATCH] D72235: [clang-tidy] new altera unroll loops check

2021-03-07 Thread Frank Derry Wanye via Phabricator via cfe-commits
ffrankies updated this revision to Diff 328935.
ffrankies marked 4 inline comments as done.
ffrankies added a comment.

- Removed unnecessary braces.
- Simplified boolean return statements.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72235/new/

https://reviews.llvm.org/D72235

Files:
  clang-tools-extra/clang-tidy/altera/AlteraTidyModule.cpp
  clang-tools-extra/clang-tidy/altera/CMakeLists.txt
  clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp
  clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/altera-unroll-loops.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  clang-tools-extra/test/clang-tidy/checkers/altera-unroll-loops.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/altera-unroll-loops.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/altera-unroll-loops.cpp
@@ -0,0 +1,518 @@
+// RUN: %check_clang_tidy %s altera-unroll-loops %t -- -config="{CheckOptions: [{key: "altera-unroll-loops.MaxLoopIterations", value: 50}]}" -header-filter=.*
+// RUN: %check_clang_tidy -check-suffix=MULT %s altera-unroll-loops %t -- -config="{CheckOptions: [{key: "altera-unroll-loops.MaxLoopIterations", value: 5}]}" -header-filter=.* "--" -DMULT
+
+#ifdef MULT
+// For loops with *= and /= increments.
+void for_loop_mult_div_increments(int *A) {
+// *=
+#pragma unroll
+for (int i = 2; i <= 32; i *= 2)
+A[i]++;  // OK
+
+#pragma unroll
+for (int i = 2; i <= 64; i *= 2)
+// CHECK-MESSAGES-MULT: :[[@LINE-1]]:5: warning: loop likely has a large number of iterations and thus cannot be fully unrolled; to partially unroll this loop, use the '#pragma unroll ' directive [altera-unroll-loops]
+A[i]++;  // Not OK
+
+// /=
+#pragma unroll
+for (int i = 32; i >= 2; i /= 2)
+A[i]++;  // OK
+
+#pragma unroll
+for (int i = 64; i >= 2; i /= 2)
+// CHECK-MESSAGES-MULT: :[[@LINE-1]]:5: warning: loop likely has a large number of iterations and thus cannot be fully unrolled; to partially unroll this loop, use the '#pragma unroll ' directive [altera-unroll-loops]
+A[i]++;  // Not OK
+}
+#else
+// Cannot determine loop bounds for while loops.
+void while_loops(int *A) {
+// Recommend unrolling loops that aren't already unrolled.
+int j = 0;
+while (j < 2000) {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: kernel performance could be improved by unrolling this loop with a '#pragma unroll' directive [altera-unroll-loops]
+A[1] += j;
+j++;
+}
+
+do {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: kernel performance could be improved by unrolling this loop with a '#pragma unroll' directive [altera-unroll-loops]
+A[2] += j;
+j++;
+} while (j < 2000);
+
+// If a while loop is fully unrolled, add a note recommending partial
+// unrolling.
+#pragma unroll
+while (j < 2000) {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: note: full unrolling requested, but loop bounds may not be known; to partially unroll this loop, use the '#pragma unroll ' directive
+A[j]++;
+}
+
+#pragma unroll
+do {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: note: full unrolling requested, but loop bounds may not be known; to partially unroll this loop, use the '#pragma unroll ' directive
+A[j]++;
+} while (j < 2000);
+
+// While loop is partially unrolled, no action needed.
+#pragma unroll 4
+while (j < 2000) {
+A[j]++;
+}
+
+#pragma unroll 4
+do {
+A[j]++;
+} while (j < 2000);
+}
+
+// Range-based for loops.
+void cxx_for_loops(int *A, int vectorSize) {
+// Loop with known array size should be unrolled.
+int a[] = { 0, 1, 2, 3, 4, 5 };
+for (int k : a) {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: kernel performance could be improved by unrolling this loop with a '#pragma unroll' directive [altera-unroll-loops]
+A[k]++;
+}
+
+// Loop with known size correctly unrolled.
+#pragma unroll
+for (int k : a) {
+A[k]++;
+}
+
+// Loop with unknown size should be partially unrolled.
+int b[vectorSize];
+#pragma unroll
+for (int k : b) {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: full unrolling requested, but loop bounds are not known; to partially unroll this loop, use the '#pragma unroll ' directive [altera-unroll-loops]
+k++;
+}
+
+// Loop with unknown size correctly unrolled.
+#pragma unroll 5
+for (int k : b) {
+k++;
+}
+
+// Loop with large size should be partially unrolled.
+int c[51];
+#pragma unroll
+for (int k : c) {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: loop likely has a large number of iterations and thus cannot be fully unrolled; to partially unroll this loop, use the '#pragma unroll ' directive [altera-unroll-loops]
+A[k]++;
+}
+
+// Loop 

[PATCH] D72235: [clang-tidy] new altera unroll loops check

2021-03-07 Thread Frank Derry Wanye via Phabricator via cfe-commits
ffrankies updated this revision to Diff 328933.
ffrankies added a comment.

- Surrounded language constructs with double back ticks in 
`clang-tools-extra/docs/clang-tidy/checks/altera-unroll-loops.rst`.
- Removed trailing whitespace.
- Added single quotes around `#pragma unroll`s in diagnostics.
- Added full stops to the comments that didn't have them in 
`clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp`


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72235/new/

https://reviews.llvm.org/D72235

Files:
  clang-tools-extra/clang-tidy/altera/AlteraTidyModule.cpp
  clang-tools-extra/clang-tidy/altera/CMakeLists.txt
  clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp
  clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/altera-unroll-loops.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  clang-tools-extra/test/clang-tidy/checkers/altera-unroll-loops.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/altera-unroll-loops.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/altera-unroll-loops.cpp
@@ -0,0 +1,518 @@
+// RUN: %check_clang_tidy %s altera-unroll-loops %t -- -config="{CheckOptions: [{key: "altera-unroll-loops.MaxLoopIterations", value: 50}]}" -header-filter=.*
+// RUN: %check_clang_tidy -check-suffix=MULT %s altera-unroll-loops %t -- -config="{CheckOptions: [{key: "altera-unroll-loops.MaxLoopIterations", value: 5}]}" -header-filter=.* "--" -DMULT
+
+#ifdef MULT
+// For loops with *= and /= increments.
+void for_loop_mult_div_increments(int *A) {
+// *=
+#pragma unroll
+for (int i = 2; i <= 32; i *= 2)
+A[i]++;  // OK
+
+#pragma unroll
+for (int i = 2; i <= 64; i *= 2)
+// CHECK-MESSAGES-MULT: :[[@LINE-1]]:5: warning: loop likely has a large number of iterations and thus cannot be fully unrolled; to partially unroll this loop, use the '#pragma unroll ' directive [altera-unroll-loops]
+A[i]++;  // Not OK
+
+// /=
+#pragma unroll
+for (int i = 32; i >= 2; i /= 2)
+A[i]++;  // OK
+
+#pragma unroll
+for (int i = 64; i >= 2; i /= 2)
+// CHECK-MESSAGES-MULT: :[[@LINE-1]]:5: warning: loop likely has a large number of iterations and thus cannot be fully unrolled; to partially unroll this loop, use the '#pragma unroll ' directive [altera-unroll-loops]
+A[i]++;  // Not OK
+}
+#else
+// Cannot determine loop bounds for while loops.
+void while_loops(int *A) {
+// Recommend unrolling loops that aren't already unrolled.
+int j = 0;
+while (j < 2000) {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: kernel performance could be improved by unrolling this loop with a '#pragma unroll' directive [altera-unroll-loops]
+A[1] += j;
+j++;
+}
+
+do {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: kernel performance could be improved by unrolling this loop with a '#pragma unroll' directive [altera-unroll-loops]
+A[2] += j;
+j++;
+} while (j < 2000);
+
+// If a while loop is fully unrolled, add a note recommending partial
+// unrolling.
+#pragma unroll
+while (j < 2000) {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: note: full unrolling requested, but loop bounds may not be known; to partially unroll this loop, use the '#pragma unroll ' directive
+A[j]++;
+}
+
+#pragma unroll
+do {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: note: full unrolling requested, but loop bounds may not be known; to partially unroll this loop, use the '#pragma unroll ' directive
+A[j]++;
+} while (j < 2000);
+
+// While loop is partially unrolled, no action needed.
+#pragma unroll 4
+while (j < 2000) {
+A[j]++;
+}
+
+#pragma unroll 4
+do {
+A[j]++;
+} while (j < 2000);
+}
+
+// Range-based for loops.
+void cxx_for_loops(int *A, int vectorSize) {
+// Loop with known array size should be unrolled.
+int a[] = { 0, 1, 2, 3, 4, 5 };
+for (int k : a) {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: kernel performance could be improved by unrolling this loop with a '#pragma unroll' directive [altera-unroll-loops]
+A[k]++;
+}
+
+// Loop with known size correctly unrolled.
+#pragma unroll
+for (int k : a) {
+A[k]++;
+}
+
+// Loop with unknown size should be partially unrolled.
+int b[vectorSize];
+#pragma unroll
+for (int k : b) {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: full unrolling requested, but loop bounds are not known; to partially unroll this loop, use the '#pragma unroll ' directive [altera-unroll-loops]
+k++;
+}
+
+// Loop with unknown size correctly unrolled.
+#pragma unroll 5
+for (int k : b) {
+k++;
+}
+
+// Loop with large size should be partially unrolled.
+int c[51];
+#pragma unroll
+for (int k : c) {
+// CHECK-MESSAGES: 

[PATCH] D72235: [clang-tidy] new altera unroll loops check

2021-03-05 Thread Eugene Zelenko via Phabricator via cfe-commits
Eugene.Zelenko added inline comments.



Comment at: clang-tools-extra/docs/clang-tidy/checks/altera-unroll-loops.rst:15
+
+- This check is unable to determine the number of iterations in a `while` or
+  `do..while` loop; hence if such a loop is fully unrolled, a note is emitted

Please use double back-ticks for language constructs. Same in rest of note text.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72235/new/

https://reviews.llvm.org/D72235

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D72235: [clang-tidy] new altera unroll loops check

2021-03-05 Thread Frank Derry Wanye via Phabricator via cfe-commits
ffrankies updated this revision to Diff 328579.
ffrankies marked 12 inline comments as done.
ffrankies added a comment.

- Added support for `CXXForRangeStmt` loops
- Added support for different for loop increments (`++`, `--`, `+=`, `-=`, 
`*=`, `\=`)
  - Depending on the exit condition, the calculations for the number of 
Iterations may be off by 1, but that should not be an issue performance-wise 
since the threshold for a "large" number of iterations is likely to be 
arbitrary.
  - If any other increment is used in the increment part of the `for` loop, we 
recommend partial unrolling.
- Changed the way `while` and `do..while` loops are handled: because the loop 
variable is changed within the loop body and it is untrivial to determine what 
is happening to it, we now emit a Note diagnostic (instead of warning) 
recommending partial unrolling if a `while` or `do..while` loop is fully 
unrolled.
- Added tests for the above
- Documented the above caveats in 
`clang-tools-extra/docs/clang-tidy/checks/altera-unroll-loops.rst`


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72235/new/

https://reviews.llvm.org/D72235

Files:
  clang-tools-extra/clang-tidy/altera/AlteraTidyModule.cpp
  clang-tools-extra/clang-tidy/altera/CMakeLists.txt
  clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp
  clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/altera-unroll-loops.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  clang-tools-extra/test/clang-tidy/checkers/altera-unroll-loops.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/altera-unroll-loops.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/altera-unroll-loops.cpp
@@ -0,0 +1,518 @@
+// RUN: %check_clang_tidy %s altera-unroll-loops %t -- -config="{CheckOptions: [{key: "altera-unroll-loops.MaxLoopIterations", value: 50}]}" -header-filter=.*
+// RUN: %check_clang_tidy -check-suffix=MULT %s altera-unroll-loops %t -- -config="{CheckOptions: [{key: "altera-unroll-loops.MaxLoopIterations", value: 5}]}" -header-filter=.* "--" -DMULT
+
+#ifdef MULT
+// For loops with *= and /= increments.
+void for_loop_mult_div_increments(int *A) {
+// *=
+#pragma unroll
+for (int i = 2; i <= 32; i *= 2)
+A[i]++;  // OK
+
+#pragma unroll
+for (int i = 2; i <= 64; i *= 2)
+// CHECK-MESSAGES-MULT: :[[@LINE-1]]:5: warning: loop likely has a large number of iterations and thus cannot be fully unrolled; to partially unroll this loop, use the #pragma unroll  directive [altera-unroll-loops]
+A[i]++;  // Not OK
+
+// /=
+#pragma unroll
+for (int i = 32; i >= 2; i /= 2)
+A[i]++;  // OK
+
+#pragma unroll
+for (int i = 64; i >= 2; i /= 2)
+// CHECK-MESSAGES-MULT: :[[@LINE-1]]:5: warning: loop likely has a large number of iterations and thus cannot be fully unrolled; to partially unroll this loop, use the #pragma unroll  directive [altera-unroll-loops]
+A[i]++;  // Not OK
+}
+#else
+// Cannot determine loop bounds for while loops.
+void while_loops(int *A) {
+// Recommend unrolling loops that aren't already unrolled.
+int j = 0;
+while (j < 2000) {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: kernel performance could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[1] += j;
+j++;
+}
+
+do {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: kernel performance could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[2] += j;
+j++;
+} while (j < 2000);
+
+// If a while loop is fully unrolled, add a note recommending partial
+// unrolling.
+#pragma unroll
+while (j < 2000) {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: note: full unrolling requested, but loop bounds may not be known; to partially unroll this loop, use the #pragma unroll  directive
+A[j]++;
+}
+
+#pragma unroll
+do {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: note: full unrolling requested, but loop bounds may not be known; to partially unroll this loop, use the #pragma unroll  directive
+A[j]++;
+} while (j < 2000);
+
+// While loop is partially unrolled, no action needed.
+#pragma unroll 4
+while (j < 2000) {
+A[j]++;
+}
+
+#pragma unroll 4
+do {
+A[j]++;
+} while (j < 2000);
+}
+
+// Range-based for loops.
+void cxx_for_loops(int *A, int vectorSize) {
+// Loop with known array size should be unrolled.
+int a[] = { 0, 1, 2, 3, 4, 5 };
+for (int k : a) {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: kernel performance could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[k]++;
+}
+
+// Loop with known size correctly unrolled.
+#pragma unroll
+for (int k : a) {
+

[PATCH] D72235: [clang-tidy] new altera unroll loops check

2021-01-04 Thread Aaron Ballman via Phabricator via cfe-commits
aaron.ballman added inline comments.



Comment at: clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp:40
+   "kernel performance could be improved by unrolling this loop with a 
"
+   "#pragma unroll directive");
+  break;





Comment at: clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp:43
+case PartiallyUnrolled:
+  // Loop already partially unrolled, do nothing
+  break;





Comment at: clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp:51-52
+   "cannot be fully unrolled; to partially unroll this loop, use "
+   "the #pragma unroll  directive");
+  return;
+}





Comment at: clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp:58
+   "full unrolling requested, but loop bounds are not known; to "
+   "partially unroll this loop, use the #pragma unroll  "
+   "directive");





Comment at: clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp:85
+return NotUnrolled;
+  return NotUnrolled;
+  }

This looks like dead code (it's still inside the switch statement).



Comment at: clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp:111
+const Expr *UnrollLoopsCheck::getCondExpr(const Stmt *Statement) {
+  if (const auto *ForLoop = dyn_cast(Statement))
+return ForLoop->getCond();

Should we also handle `CXXForRangeStmt`? I'm thinking of cases like: `for (int 
i : {1, 2, 3, 4}) {}` or other cases where there's a known bounds.



Comment at: clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp:145
+// safe.
+// The following assumes values go from 0 to Val in increments of 1.
+return Result.Val.getInt() > MaxLoopIterations;

If the check won't work too well if the value is decremented rather than 
incremented, or if it uses an induction variable that increases by something 
other than `1` or `-1`, we should probably document the limitations and 
consider whether we want to note that scenario in the code and bail out (rather 
than produce incorrect diagnostics, assuming we do).



Comment at: clang-tools-extra/docs/clang-tidy/checks/altera-unroll-loops.rst:4
+altera-unroll-loops
+=
+





Comment at: 
clang-tools-extra/test/clang-tidy/checkers/altera-unroll-loops.cpp:359
+}
+// There are no fix-its for this check

Can you also add some test cases where the loop is decrementing rather than 
incrementing, and some tests where the increment is by more than 1?


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72235/new/

https://reviews.llvm.org/D72235

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D72235: [clang-tidy] new altera unroll loops check

2020-12-21 Thread Frank Derry Wanye via Phabricator via cfe-commits
ffrankies updated this revision to Diff 313174.
ffrankies added a comment.

- Addressed comments from @njames93
- Rebased with latest master branch to make sure there are no merge issues with 
the latest committed altera check


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72235/new/

https://reviews.llvm.org/D72235

Files:
  clang-tools-extra/clang-tidy/altera/AlteraTidyModule.cpp
  clang-tools-extra/clang-tidy/altera/CMakeLists.txt
  clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp
  clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/altera-unroll-loops.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  clang-tools-extra/test/clang-tidy/checkers/altera-unroll-loops.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/altera-unroll-loops.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/altera-unroll-loops.cpp
@@ -0,0 +1,359 @@
+// RUN: %check_clang_tidy %s altera-unroll-loops %t -- -config="{CheckOptions: [{key: "altera-unroll-loops.MaxLoopIterations", value: 50}]}" -header-filter=.* "--" --include opencl-c.h -cl-std=CL1.2 -c
+
+// Inner loops should be unrolled
+__kernel void nested_simple_loops(__global int *A) {
+for (int i = 0; i < 1000; ++i) {
+for (int j = 0; j < 2000; ++j) { 
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: kernel performance could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[0] += i + j;
+}
+}
+
+for (int i = 0; i < 1000; ++i) {
+int j = 0;
+while (j < 2000) {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: kernel performance could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[1] += i + j;
+j++;
+}
+}
+
+for (int i = 0; i < 1000; ++i) {
+int j = 0; 
+do {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: kernel performance could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[2] += i + j;
+j++;
+} while (j < 2000);
+}
+
+int i = 0;
+while (i < 1000) {
+for (int j = 0; j < 2000; ++j) {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: kernel performance could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[3] += i + j;
+}
+i++;
+}
+
+i = 0;
+while (i < 1000) {
+int j = 0;
+while (j < 2000) {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: kernel performance could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[4] += i + j;
+j++;
+}
+i++;
+}
+
+i = 0;
+while (i < 1000) {
+int j = 0;
+do {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: kernel performance could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[5] += i + j;
+j++;
+} while (j < 2000);
+i++;
+}
+
+i = 0;
+do {
+for (int j = 0; j < 2000; ++j) {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: kernel performance could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[6] += i + j;
+}
+i++;
+} while (i < 1000);
+
+i = 0;
+do {
+int j = 0;
+while (j < 2000) {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: kernel performance could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[7] += i + j;
+j++;
+}
+i++;
+} while (i < 1000);
+
+i = 0;
+do {
+int j = 0;
+do {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: kernel performance could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[8] += i + j;
+j++;
+} while (j < 2000);
+i++;
+} while (i < 1000);
+
+for (int i = 0; i < 100; ++i) {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: kernel performance could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+printf("Hello");
+}
+
+i = 0;
+while (i < 100) {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: kernel performance could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+i++;
+}
+
+i = 0;
+do {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: kernel performance could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+i++;
+} while (i < 100);
+}
+
+// These loops are all correctly unrolled
+__kernel void unrolled_nested_simple_loops(__global int *A) {
+for (int i = 0; i < 1000; ++i) {
+#pragma 

[PATCH] D72235: [clang-tidy] new altera unroll loops check

2020-12-18 Thread Nathan James via Phabricator via cfe-commits
njames93 added inline comments.



Comment at: clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp:22
+void UnrollLoopsCheck::registerMatchers(MatchFinder *Finder) {
+  const auto ANYLOOP = anyOf(forStmt(), whileStmt(), doStmt());
+  Finder->addMatcher(stmt(allOf(ANYLOOP, // Match all loop types,

Dont use all caps variable names, preferred style is CamelCase.



Comment at: clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp:24-26
+unless(hasDescendant(forStmt())),
+unless(hasDescendant(whileStmt())),
+unless(hasDescendant(doStmt()





Comment at: clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp:35
+  UnrollType Unroll = unrollType(MatchedLoop, Result.Context);
+  if (Unroll == NotUnrolled) {
+diag(MatchedLoop->getBeginLoc(),

This loops like it should be a switch



Comment at: clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp:68
+for (const Attr *Attribute : ParentStmt->getAttrs()) {
+  const auto *LoopHint = static_cast(Attribute);
+  if (LoopHint) {

Shouldn't this by dyn_cast too.



Comment at: clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp:69
+  const auto *LoopHint = static_cast(Attribute);
+  if (LoopHint) {
+switch (LoopHint->getState()) {

To reduce indentations can this be an early exit



Comment at: clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp:79
+  return FullyUnrolled;
+default:
+  return NotUnrolled;

Default statements are usually bad as the prevent compiler diagnostics if the 
enum is ever updated.



Comment at: clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp:93-94
+return false;
+  if (isa(Conditional)) {
+const auto *BinaryOp = static_cast(Conditional);
+const Expr *LHS = BinaryOp->getLHS();





Comment at: clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp:107-120
+  const Expr *Conditional;
+  if (isa(Statement)) {
+const auto *ForLoop = static_cast(Statement);
+Conditional = ForLoop->getCond();
+  }
+  if (isa(Statement)) {
+const auto *WhileLoop = static_cast(Statement);





Comment at: clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp:128
+return false;
+  if (isa(Conditional)) {
+const auto *BinaryOp = static_cast(Conditional);

dyn_cast again



Comment at: clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp:145
+  if (Expression->EvaluateAsRValue(Result, *Context)) {
+if (!(Result.Val.isInt()))
+  return false; // Cannot check number of iterations, return false to be

Elide inner parens



Comment at: clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp:148-150
+if (Result.Val.getInt() > MaxLoopIterations)
+  return true; // Assumes values go from 0 to Val in increments of 1.
+return false; // Number of iterations likely less than MaxLoopIterations.





Comment at: clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.h:31-33
+  UnrollLoopsCheck(StringRef Name, ClangTidyContext *Context)
+  : ClangTidyCheck(Name, Context),
+MaxLoopIterations(Options.get("MaxLoopIterations", 100U)) {}

Should probably define this out of line in the cpp file.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72235/new/

https://reviews.llvm.org/D72235

___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D72235: [clang-tidy] new altera unroll loops check

2020-12-17 Thread Frank Derry Wanye via Phabricator via cfe-commits
ffrankies updated this revision to Diff 312676.
ffrankies added a comment.

- removed unnecessary comment


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72235/new/

https://reviews.llvm.org/D72235

Files:
  clang-tools-extra/clang-tidy/altera/AlteraTidyModule.cpp
  clang-tools-extra/clang-tidy/altera/CMakeLists.txt
  clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp
  clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/altera-unroll-loops.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  clang-tools-extra/test/clang-tidy/checkers/altera-unroll-loops.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/altera-unroll-loops.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/altera-unroll-loops.cpp
@@ -0,0 +1,359 @@
+// RUN: %check_clang_tidy %s altera-unroll-loops %t -- -config="{CheckOptions: [{key: "altera-unroll-loops.MaxLoopIterations", value: 50}]}" -header-filter=.* "--" --include opencl-c.h -cl-std=CL1.2 -c
+
+// Inner loops should be unrolled
+__kernel void nested_simple_loops(__global int *A) {
+for (int i = 0; i < 1000; ++i) {
+for (int j = 0; j < 2000; ++j) { 
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: kernel performance could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[0] += i + j;
+}
+}
+
+for (int i = 0; i < 1000; ++i) {
+int j = 0;
+while (j < 2000) {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: kernel performance could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[1] += i + j;
+j++;
+}
+}
+
+for (int i = 0; i < 1000; ++i) {
+int j = 0; 
+do {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: kernel performance could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[2] += i + j;
+j++;
+} while (j < 2000);
+}
+
+int i = 0;
+while (i < 1000) {
+for (int j = 0; j < 2000; ++j) {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: kernel performance could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[3] += i + j;
+}
+i++;
+}
+
+i = 0;
+while (i < 1000) {
+int j = 0;
+while (j < 2000) {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: kernel performance could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[4] += i + j;
+j++;
+}
+i++;
+}
+
+i = 0;
+while (i < 1000) {
+int j = 0;
+do {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: kernel performance could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[5] += i + j;
+j++;
+} while (j < 2000);
+i++;
+}
+
+i = 0;
+do {
+for (int j = 0; j < 2000; ++j) {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: kernel performance could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[6] += i + j;
+}
+i++;
+} while (i < 1000);
+
+i = 0;
+do {
+int j = 0;
+while (j < 2000) {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: kernel performance could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[7] += i + j;
+j++;
+}
+i++;
+} while (i < 1000);
+
+i = 0;
+do {
+int j = 0;
+do {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: kernel performance could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[8] += i + j;
+j++;
+} while (j < 2000);
+i++;
+} while (i < 1000);
+
+for (int i = 0; i < 100; ++i) {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: kernel performance could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+printf("Hello");
+}
+
+i = 0;
+while (i < 100) {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: kernel performance could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+i++;
+}
+
+i = 0;
+do {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: kernel performance could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+i++;
+} while (i < 100);
+}
+
+// These loops are all correctly unrolled
+__kernel void unrolled_nested_simple_loops(__global int *A) {
+for (int i = 0; i < 1000; ++i) {
+#pragma unroll
+for (int j = 0; j < 50; ++j) {
+A[0] += i + j;
+}
+}
+
+for (int i = 0; i < 

[PATCH] D72235: [clang-tidy] new altera unroll loops check

2020-12-17 Thread Frank Derry Wanye via Phabricator via cfe-commits
ffrankies updated this revision to Diff 312675.
ffrankies marked 9 inline comments as done.
ffrankies added a comment.

- Rebased with master branch
- Diagnostics are re-worded so they're not complete sentences

Check ready for further review


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72235/new/

https://reviews.llvm.org/D72235

Files:
  clang-tools-extra/clang-tidy/altera/AlteraTidyModule.cpp
  clang-tools-extra/clang-tidy/altera/CMakeLists.txt
  clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp
  clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/altera-unroll-loops.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  clang-tools-extra/test/clang-tidy/checkers/altera-unroll-loops.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/altera-unroll-loops.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/altera-unroll-loops.cpp
@@ -0,0 +1,359 @@
+// RUN: %check_clang_tidy %s altera-unroll-loops %t -- -config="{CheckOptions: [{key: "altera-unroll-loops.MaxLoopIterations", value: 50}]}" -header-filter=.* "--" --include opencl-c.h -cl-std=CL1.2 -c
+
+// Inner loops should be unrolled
+__kernel void nested_simple_loops(__global int *A) {
+for (int i = 0; i < 1000; ++i) {
+for (int j = 0; j < 2000; ++j) { 
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: kernel performance could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[0] += i + j;
+}
+}
+
+for (int i = 0; i < 1000; ++i) {
+int j = 0;
+while (j < 2000) {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: kernel performance could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[1] += i + j;
+j++;
+}
+}
+
+for (int i = 0; i < 1000; ++i) {
+int j = 0; 
+do {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: kernel performance could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[2] += i + j;
+j++;
+} while (j < 2000);
+}
+
+int i = 0;
+while (i < 1000) {
+for (int j = 0; j < 2000; ++j) {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: kernel performance could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[3] += i + j;
+}
+i++;
+}
+
+i = 0;
+while (i < 1000) {
+int j = 0;
+while (j < 2000) {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: kernel performance could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[4] += i + j;
+j++;
+}
+i++;
+}
+
+i = 0;
+while (i < 1000) {
+int j = 0;
+do {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: kernel performance could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[5] += i + j;
+j++;
+} while (j < 2000);
+i++;
+}
+
+i = 0;
+do {
+for (int j = 0; j < 2000; ++j) {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: kernel performance could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[6] += i + j;
+}
+i++;
+} while (i < 1000);
+
+i = 0;
+do {
+int j = 0;
+while (j < 2000) {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: kernel performance could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[7] += i + j;
+j++;
+}
+i++;
+} while (i < 1000);
+
+i = 0;
+do {
+int j = 0;
+do {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: kernel performance could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[8] += i + j;
+j++;
+} while (j < 2000);
+i++;
+} while (i < 1000);
+
+for (int i = 0; i < 100; ++i) {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: kernel performance could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+printf("Hello");
+}
+
+i = 0;
+while (i < 100) {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: kernel performance could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+i++;
+}
+
+i = 0;
+do {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: kernel performance could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+i++;
+} while (i < 100);
+}
+
+// These loops are all correctly unrolled
+__kernel void unrolled_nested_simple_loops(__global int *A) {
+for (int i = 0; i < 1000; ++i) {
+

[PATCH] D72235: [clang-tidy] new altera unroll loops check

2020-04-01 Thread Frank Derry Wanye via Phabricator via cfe-commits
ffrankies updated this revision to Diff 254299.
ffrankies added a comment.

Addressed comments by @Eugene.Zelenko

- Removed braces from one-lien if statements
- Release notes on the altera unroll loops check now match the first line of 
documentation.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72235/new/

https://reviews.llvm.org/D72235

Files:
  clang-tools-extra/clang-tidy/CMakeLists.txt
  clang-tools-extra/clang-tidy/ClangTidyForceLinker.h
  clang-tools-extra/clang-tidy/altera/AlteraTidyModule.cpp
  clang-tools-extra/clang-tidy/altera/CMakeLists.txt
  clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp
  clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/altera-unroll-loops.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  clang-tools-extra/docs/clang-tidy/index.rst
  clang-tools-extra/test/clang-tidy/checkers/altera-unroll-loops.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/altera-unroll-loops.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/altera-unroll-loops.cpp
@@ -0,0 +1,359 @@
+// RUN: %check_clang_tidy %s altera-unroll-loops %t -- -config="{CheckOptions: [{key: "altera-unroll-loops.MaxLoopIterations", value: 50}]}" -header-filter=.* "--" --include opencl-c.h -cl-std=CL1.2 -c
+
+// Inner loops should be unrolled
+__kernel void nested_simple_loops(__global int *A) {
+for (int i = 0; i < 1000; ++i) {
+for (int j = 0; j < 2000; ++j) { 
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[0] += i + j;
+}
+}
+
+for (int i = 0; i < 1000; ++i) {
+int j = 0;
+while (j < 2000) {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[1] += i + j;
+j++;
+}
+}
+
+for (int i = 0; i < 1000; ++i) {
+int j = 0; 
+do {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[2] += i + j;
+j++;
+} while (j < 2000);
+}
+
+int i = 0;
+while (i < 1000) {
+for (int j = 0; j < 2000; ++j) {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[3] += i + j;
+}
+i++;
+}
+
+i = 0;
+while (i < 1000) {
+int j = 0;
+while (j < 2000) {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[4] += i + j;
+j++;
+}
+i++;
+}
+
+i = 0;
+while (i < 1000) {
+int j = 0;
+do {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[5] += i + j;
+j++;
+} while (j < 2000);
+i++;
+}
+
+i = 0;
+do {
+for (int j = 0; j < 2000; ++j) {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[6] += i + j;
+}
+i++;
+} while (i < 1000);
+
+i = 0;
+do {
+int j = 0;
+while (j < 2000) {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[7] += i + j;
+j++;
+}
+i++;
+} while (i < 1000);
+
+i = 0;
+do {
+int j = 0;
+do {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[8] += i + j;
+j++;
+} while (j < 2000);
+i++;
+} while (i < 1000);
+
+for (int i = 0; i < 100; ++i) {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+printf("Hello");
+}
+
+i = 0;
+while (i < 100) {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+i++;
+}
+
+i = 0;
+do {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: The performance of the 

[PATCH] D72235: [clang-tidy] new altera unroll loops check

2020-03-04 Thread Eugene Zelenko via Phabricator via cfe-commits
Eugene.Zelenko added inline comments.



Comment at: clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp:41
+  }
+  if (Unroll == PartiallyUnrolled) {
+return;

Please elide braces.



Comment at: clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp:66
+const auto *ParentStmt = Parent.get();
+if (!ParentStmt) {
+  continue;

Please elide braces.



Comment at: clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp:93
+  const Expr *Conditional = getCondExpr(Statement);
+  if (!Conditional) {
+return false;

Please elide braces.



Comment at: clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp:130
+  const Expr *Conditional = getCondExpr(Statement);
+  if (!Conditional) {
+return false;

Please elide braces.



Comment at: clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp:138
+Expr::EvalResult result;
+if (LHS->isEvaluatable(*Context) && !(RHS->isEvaluatable(*Context))) {
+  return exprHasLargeNumIterations(LHS, Context);

Please elide braces.



Comment at: clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp:141
+}
+if (RHS->isEvaluatable(*Context) && !(LHS->isEvaluatable(*Context))) {
+  return exprHasLargeNumIterations(RHS, Context);

Please elide braces.



Comment at: clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp:152
+  if (Expression->EvaluateAsRValue(Result, *Context)) {
+if (!(Result.Val.isInt())) {
+  return false; // Cannot check number of iterations, return false to be

Please elide braces.



Comment at: clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp:156
+}
+if (Result.Val.getInt() > MaxLoopIterations) {
+  return true; // Assumes values go from 0 to Val in increments of 1.

Please elide braces.



Comment at: clang-tools-extra/docs/ReleaseNotes.rst:85
+
+  Finds inner loops that have not been unrolled, as well as fully unrolled
+  loops with unknown loops bounds or a large number of iterations.

Please synchronize with first statement in documentation.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72235/new/

https://reviews.llvm.org/D72235



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D72235: [clang-tidy] new altera unroll loops check

2020-03-04 Thread Frank Derry Wanye via Phabricator via cfe-commits
ffrankies updated this revision to Diff 248322.
ffrankies added a comment.

@Eugene.Zelenko It turns out we were using an old mirror 
 of the clang-tools-extra 
repository, that no longer seems to be updated. I switched to the llvm-project 
 repo, and updated the documentation 
accordingly (some of the formatting is different now). Let me know if I missed 
anything - if not, I will be switching the other checks over to the 
llvm-project repo as well over the coming weeks.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72235/new/

https://reviews.llvm.org/D72235

Files:
  clang-tools-extra/clang-tidy/CMakeLists.txt
  clang-tools-extra/clang-tidy/ClangTidyForceLinker.h
  clang-tools-extra/clang-tidy/altera/AlteraTidyModule.cpp
  clang-tools-extra/clang-tidy/altera/CMakeLists.txt
  clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.cpp
  clang-tools-extra/clang-tidy/altera/UnrollLoopsCheck.h
  clang-tools-extra/docs/ReleaseNotes.rst
  clang-tools-extra/docs/clang-tidy/checks/altera-unroll-loops.rst
  clang-tools-extra/docs/clang-tidy/checks/list.rst
  clang-tools-extra/docs/clang-tidy/index.rst
  clang-tools-extra/test/clang-tidy/checkers/altera-unroll-loops.cpp

Index: clang-tools-extra/test/clang-tidy/checkers/altera-unroll-loops.cpp
===
--- /dev/null
+++ clang-tools-extra/test/clang-tidy/checkers/altera-unroll-loops.cpp
@@ -0,0 +1,359 @@
+// RUN: %check_clang_tidy %s altera-unroll-loops %t -- -config="{CheckOptions: [{key: "altera-unroll-loops.MaxLoopIterations", value: 50}]}" -header-filter=.* "--" --include opencl-c.h -cl-std=CL1.2 -c
+
+// Inner loops should be unrolled
+__kernel void nested_simple_loops(__global int *A) {
+for (int i = 0; i < 1000; ++i) {
+for (int j = 0; j < 2000; ++j) { 
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[0] += i + j;
+}
+}
+
+for (int i = 0; i < 1000; ++i) {
+int j = 0;
+while (j < 2000) {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[1] += i + j;
+j++;
+}
+}
+
+for (int i = 0; i < 1000; ++i) {
+int j = 0; 
+do {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[2] += i + j;
+j++;
+} while (j < 2000);
+}
+
+int i = 0;
+while (i < 1000) {
+for (int j = 0; j < 2000; ++j) {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[3] += i + j;
+}
+i++;
+}
+
+i = 0;
+while (i < 1000) {
+int j = 0;
+while (j < 2000) {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[4] += i + j;
+j++;
+}
+i++;
+}
+
+i = 0;
+while (i < 1000) {
+int j = 0;
+do {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[5] += i + j;
+j++;
+} while (j < 2000);
+i++;
+}
+
+i = 0;
+do {
+for (int j = 0; j < 2000; ++j) {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[6] += i + j;
+}
+i++;
+} while (i < 1000);
+
+i = 0;
+do {
+int j = 0;
+while (j < 2000) {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[7] += i + j;
+j++;
+}
+i++;
+} while (i < 1000);
+
+i = 0;
+do {
+int j = 0;
+do {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[8] += i + j;
+j++;
+} while (j < 2000);
+i++;
+} while (i < 1000);
+
+for (int i = 0; i < 100; ++i) {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+printf("Hello");
+}
+
+i = 

[PATCH] D72235: [clang-tidy] new altera unroll loops check

2020-02-27 Thread Eugene Zelenko via Phabricator via cfe-commits
Eugene.Zelenko added a comment.

Please rebase from master.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72235/new/

https://reviews.llvm.org/D72235



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D72235: [clang-tidy] new altera unroll loops check

2020-02-27 Thread Frank Derry Wanye via Phabricator via cfe-commits
ffrankies updated this revision to Diff 246993.
ffrankies marked 9 inline comments as done.
ffrankies added a comment.

Addressed comments by @Eugene.Zelenko

- Used const auto * when type is mentioned in same sentence
- Fixed formatting in documentation
- Documented default value of `MaxLoopIterations` option


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72235/new/

https://reviews.llvm.org/D72235

Files:
  clang-tidy/CMakeLists.txt
  clang-tidy/ClangTidyForceLinker.h
  clang-tidy/altera/AlteraTidyModule.cpp
  clang-tidy/altera/CMakeLists.txt
  clang-tidy/altera/UnrollLoopsCheck.cpp
  clang-tidy/altera/UnrollLoopsCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/altera-unroll-loops.rst
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/index.rst
  test/clang-tidy/checkers/altera-unroll-loops.cpp

Index: test/clang-tidy/checkers/altera-unroll-loops.cpp
===
--- /dev/null
+++ test/clang-tidy/checkers/altera-unroll-loops.cpp
@@ -0,0 +1,359 @@
+// RUN: %check_clang_tidy %s altera-unroll-loops %t -- -config="{CheckOptions: [{key: "altera-unroll-loops.MaxLoopIterations", value: 50}]}" -header-filter=.* "--" --include opencl-c.h -cl-std=CL1.2 -c
+
+// Inner loops should be unrolled
+__kernel void nested_simple_loops(__global int *A) {
+for (int i = 0; i < 1000; ++i) {
+for (int j = 0; j < 2000; ++j) { 
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[0] += i + j;
+}
+}
+
+for (int i = 0; i < 1000; ++i) {
+int j = 0;
+while (j < 2000) {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[1] += i + j;
+j++;
+}
+}
+
+for (int i = 0; i < 1000; ++i) {
+int j = 0; 
+do {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[2] += i + j;
+j++;
+} while (j < 2000);
+}
+
+int i = 0;
+while (i < 1000) {
+for (int j = 0; j < 2000; ++j) {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[3] += i + j;
+}
+i++;
+}
+
+i = 0;
+while (i < 1000) {
+int j = 0;
+while (j < 2000) {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[4] += i + j;
+j++;
+}
+i++;
+}
+
+i = 0;
+while (i < 1000) {
+int j = 0;
+do {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[5] += i + j;
+j++;
+} while (j < 2000);
+i++;
+}
+
+i = 0;
+do {
+for (int j = 0; j < 2000; ++j) {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[6] += i + j;
+}
+i++;
+} while (i < 1000);
+
+i = 0;
+do {
+int j = 0;
+while (j < 2000) {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[7] += i + j;
+j++;
+}
+i++;
+} while (i < 1000);
+
+i = 0;
+do {
+int j = 0;
+do {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[8] += i + j;
+j++;
+} while (j < 2000);
+i++;
+} while (i < 1000);
+
+for (int i = 0; i < 100; ++i) {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+printf("Hello");
+}
+
+i = 0;
+while (i < 100) {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+i++;
+}
+
+i = 0;
+do {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+i++;
+} while (i < 100);
+}
+
+// These loops are all correctly 

[PATCH] D72235: [clang-tidy] new altera unroll loops check

2020-01-05 Thread Eugene Zelenko via Phabricator via cfe-commits
Eugene.Zelenko added a comment.

I think will be good idea to separate module code in own review or refer to 
previous one of previous reviews as dependency.




Comment at: clang-tidy/altera/UnrollLoopsCheck.cpp:31
+void UnrollLoopsCheck::check(const MatchFinder::MatchResult ) {
+  const Stmt *MatchedLoop = Result.Nodes.getNodeAs("loop");
+  const ASTContext *Context = Result.Context;

Could be const auto *, because type is spelled in same sentence. See 
modernize-use-auto.



Comment at: clang-tidy/altera/UnrollLoopsCheck.cpp:69
+  for (const Attr* Attribute: ParentStmt->getAttrs()) {
+const LoopHintAttr *LoopHint;
+if ((LoopHint = static_cast(Attribute))) {

May be merge declaration with initialization and use const auto *?



Comment at: clang-tidy/altera/UnrollLoopsCheck.cpp:96
+  if (isa(Conditional)) {
+const BinaryOperator *BinaryOp =
+static_cast(Conditional);

Could be const auto *, because type is spelled in same sentence.



Comment at: clang-tidy/altera/UnrollLoopsCheck.cpp:113
+  if (isa(Statement)) {
+const ForStmt *ForLoop = static_cast(Statement);
+Conditional = ForLoop->getCond();

Could be const auto *, because type is spelled in same sentence.



Comment at: clang-tidy/altera/UnrollLoopsCheck.cpp:117
+  if (isa(Statement)) {
+const WhileStmt *WhileLoop = static_cast(Statement);
+Conditional = WhileLoop->getCond();

Could be const auto *, because type is spelled in same sentence.



Comment at: clang-tidy/altera/UnrollLoopsCheck.cpp:121
+  if (isa(Statement)) {
+const DoStmt *DoWhileLoop = static_cast(Statement);
+Conditional = DoWhileLoop->getCond();

Could be const auto *, because type is spelled in same sentence.



Comment at: clang-tidy/altera/UnrollLoopsCheck.cpp:134
+  if (isa(Conditional)) {
+const BinaryOperator *BinaryOp =
+static_cast(Conditional);

Could be const auto *, because type is spelled in same sentence.



Comment at: docs/ReleaseNotes.rst:79
+
+  Finds inner loops that have not been unrolled, as well as fully unrolled 
loops
+  with unknown loops bounds or a large number of iterations.

Please synchronize with first statement in documentation.



Comment at: docs/clang-tidy/checks/altera-unroll-loops.rst:68
+
+   Defines the maximum number of loop iterations that a fully unrolled loop
+   can have.

Please document default value.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72235/new/

https://reviews.llvm.org/D72235



___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[PATCH] D72235: [clang-tidy] new altera unroll loops check

2020-01-05 Thread Frank Derry Wanye via Phabricator via cfe-commits
ffrankies updated this revision to Diff 236270.

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72235/new/

https://reviews.llvm.org/D72235

Files:
  clang-tidy/CMakeLists.txt
  clang-tidy/ClangTidyForceLinker.h
  clang-tidy/altera/AlteraTidyModule.cpp
  clang-tidy/altera/CMakeLists.txt
  clang-tidy/altera/UnrollLoopsCheck.cpp
  clang-tidy/altera/UnrollLoopsCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/altera-unroll-loops.rst
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/index.rst
  test/clang-tidy/checkers/altera-unroll-loops.cpp

Index: test/clang-tidy/checkers/altera-unroll-loops.cpp
===
--- /dev/null
+++ test/clang-tidy/checkers/altera-unroll-loops.cpp
@@ -0,0 +1,359 @@
+// RUN: %check_clang_tidy %s altera-unroll-loops %t -- -config="{CheckOptions: [{key: "altera-unroll-loops.MaxLoopIterations", value: 50}]}" -header-filter=.* "--" --include opencl-c.h -cl-std=CL1.2 -c
+
+// Inner loops should be unrolled
+__kernel void nested_simple_loops(__global int *A) {
+for (int i = 0; i < 1000; ++i) {
+for (int j = 0; j < 2000; ++j) { 
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[0] += i + j;
+}
+}
+
+for (int i = 0; i < 1000; ++i) {
+int j = 0;
+while (j < 2000) {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[1] += i + j;
+j++;
+}
+}
+
+for (int i = 0; i < 1000; ++i) {
+int j = 0; 
+do {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[2] += i + j;
+j++;
+} while (j < 2000);
+}
+
+int i = 0;
+while (i < 1000) {
+for (int j = 0; j < 2000; ++j) {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[3] += i + j;
+}
+i++;
+}
+
+i = 0;
+while (i < 1000) {
+int j = 0;
+while (j < 2000) {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[4] += i + j;
+j++;
+}
+i++;
+}
+
+i = 0;
+while (i < 1000) {
+int j = 0;
+do {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[5] += i + j;
+j++;
+} while (j < 2000);
+i++;
+}
+
+i = 0;
+do {
+for (int j = 0; j < 2000; ++j) {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[6] += i + j;
+}
+i++;
+} while (i < 1000);
+
+i = 0;
+do {
+int j = 0;
+while (j < 2000) {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[7] += i + j;
+j++;
+}
+i++;
+} while (i < 1000);
+
+i = 0;
+do {
+int j = 0;
+do {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[8] += i + j;
+j++;
+} while (j < 2000);
+i++;
+} while (i < 1000);
+
+for (int i = 0; i < 100; ++i) {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+printf("Hello");
+}
+
+i = 0;
+while (i < 100) {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+i++;
+}
+
+i = 0;
+do {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+i++;
+} while (i < 100);
+}
+
+// These loops are all correctly unrolled
+__kernel void unrolled_nested_simple_loops(__global int *A) {
+for (int i = 0; i < 1000; ++i) {
+#pragma unroll
+for (int j = 0; j < 50; ++j) {
+A[0] += i + j;
+}
+}
+
+for (int i = 0; i < 1000; ++i) {
+  

[PATCH] D72235: [clang-tidy] new altera unroll loops check

2020-01-05 Thread Frank Derry Wanye via Phabricator via cfe-commits
ffrankies created this revision.
ffrankies added reviewers: aaron.ballman, hokein, alexfh.
ffrankies added projects: clang-tools-extra, clang, LLVM.
Herald added subscribers: mgehre, arphaman, zzheng, xazax.hun, Anastasia, 
mgorny.
ffrankies updated this revision to Diff 236270.
ffrankies updated this revision to Diff 236271.

This lint check is a part of the FLOCL (FPGA Linters for OpenCL) project out of 
the Synergy Lab at Virginia Tech.

FLOCL is a set of lint checks aimed at FPGA developers who write code in OpenCL.

The altera unroll loops check finds inner loops that have not been unrolled, as 
well as fully-unrolled loops that should be partially unrolled due to unknown 
loop bounds or a large number of loop iterations.

Based on the Altera SDK for OpenCL: Best Practices Guide


https://reviews.llvm.org/D72235

Files:
  clang-tidy/CMakeLists.txt
  clang-tidy/ClangTidyForceLinker.h
  clang-tidy/altera/AlteraTidyModule.cpp
  clang-tidy/altera/CMakeLists.txt
  clang-tidy/altera/UnrollLoopsCheck.cpp
  clang-tidy/altera/UnrollLoopsCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/altera-unroll-loops.rst
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/index.rst
  test/clang-tidy/checkers/altera-unroll-loops.cpp

Index: test/clang-tidy/checkers/altera-unroll-loops.cpp
===
--- /dev/null
+++ test/clang-tidy/checkers/altera-unroll-loops.cpp
@@ -0,0 +1,359 @@
+// RUN: %check_clang_tidy %s altera-unroll-loops %t -- -config="{CheckOptions: [{key: "altera-unroll-loops.MaxLoopIterations", value: 50}]}" -header-filter=.* "--" --include opencl-c.h -cl-std=CL1.2 -c
+
+// Inner loops should be unrolled
+__kernel void nested_simple_loops(__global int *A) {
+for (int i = 0; i < 1000; ++i) {
+for (int j = 0; j < 2000; ++j) { 
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[0] += i + j;
+}
+}
+
+for (int i = 0; i < 1000; ++i) {
+int j = 0;
+while (j < 2000) {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[1] += i + j;
+j++;
+}
+}
+
+for (int i = 0; i < 1000; ++i) {
+int j = 0; 
+do {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[2] += i + j;
+j++;
+} while (j < 2000);
+}
+
+int i = 0;
+while (i < 1000) {
+for (int j = 0; j < 2000; ++j) {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[3] += i + j;
+}
+i++;
+}
+
+i = 0;
+while (i < 1000) {
+int j = 0;
+while (j < 2000) {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[4] += i + j;
+j++;
+}
+i++;
+}
+
+i = 0;
+while (i < 1000) {
+int j = 0;
+do {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[5] += i + j;
+j++;
+} while (j < 2000);
+i++;
+}
+
+i = 0;
+do {
+for (int j = 0; j < 2000; ++j) {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[6] += i + j;
+}
+i++;
+} while (i < 1000);
+
+i = 0;
+do {
+int j = 0;
+while (j < 2000) {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[7] += i + j;
+j++;
+}
+i++;
+} while (i < 1000);
+
+i = 0;
+do {
+int j = 0;
+do {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[8] += i + j;
+j++;
+} while (j < 2000);
+i++;
+} while (i < 1000);
+
+for (int i = 0; i < 100; ++i) {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+printf("Hello");
+}
+
+i = 0;
+while (i < 100) {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: 

[PATCH] D72235: [clang-tidy] new altera unroll loops check

2020-01-05 Thread Frank Derry Wanye via Phabricator via cfe-commits
ffrankies updated this revision to Diff 236271.

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D72235/new/

https://reviews.llvm.org/D72235

Files:
  clang-tidy/CMakeLists.txt
  clang-tidy/ClangTidyForceLinker.h
  clang-tidy/altera/AlteraTidyModule.cpp
  clang-tidy/altera/CMakeLists.txt
  clang-tidy/altera/UnrollLoopsCheck.cpp
  clang-tidy/altera/UnrollLoopsCheck.h
  docs/ReleaseNotes.rst
  docs/clang-tidy/checks/altera-unroll-loops.rst
  docs/clang-tidy/checks/list.rst
  docs/clang-tidy/index.rst
  test/clang-tidy/checkers/altera-unroll-loops.cpp

Index: test/clang-tidy/checkers/altera-unroll-loops.cpp
===
--- /dev/null
+++ test/clang-tidy/checkers/altera-unroll-loops.cpp
@@ -0,0 +1,359 @@
+// RUN: %check_clang_tidy %s altera-unroll-loops %t -- -config="{CheckOptions: [{key: "altera-unroll-loops.MaxLoopIterations", value: 50}]}" -header-filter=.* "--" --include opencl-c.h -cl-std=CL1.2 -c
+
+// Inner loops should be unrolled
+__kernel void nested_simple_loops(__global int *A) {
+for (int i = 0; i < 1000; ++i) {
+for (int j = 0; j < 2000; ++j) { 
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[0] += i + j;
+}
+}
+
+for (int i = 0; i < 1000; ++i) {
+int j = 0;
+while (j < 2000) {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[1] += i + j;
+j++;
+}
+}
+
+for (int i = 0; i < 1000; ++i) {
+int j = 0; 
+do {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[2] += i + j;
+j++;
+} while (j < 2000);
+}
+
+int i = 0;
+while (i < 1000) {
+for (int j = 0; j < 2000; ++j) {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[3] += i + j;
+}
+i++;
+}
+
+i = 0;
+while (i < 1000) {
+int j = 0;
+while (j < 2000) {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[4] += i + j;
+j++;
+}
+i++;
+}
+
+i = 0;
+while (i < 1000) {
+int j = 0;
+do {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[5] += i + j;
+j++;
+} while (j < 2000);
+i++;
+}
+
+i = 0;
+do {
+for (int j = 0; j < 2000; ++j) {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[6] += i + j;
+}
+i++;
+} while (i < 1000);
+
+i = 0;
+do {
+int j = 0;
+while (j < 2000) {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[7] += i + j;
+j++;
+}
+i++;
+} while (i < 1000);
+
+i = 0;
+do {
+int j = 0;
+do {
+// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+A[8] += i + j;
+j++;
+} while (j < 2000);
+i++;
+} while (i < 1000);
+
+for (int i = 0; i < 100; ++i) {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+printf("Hello");
+}
+
+i = 0;
+while (i < 100) {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+i++;
+}
+
+i = 0;
+do {
+// CHECK-MESSAGES: :[[@LINE-1]]:5: warning: The performance of the kernel could be improved by unrolling this loop with a #pragma unroll directive [altera-unroll-loops]
+i++;
+} while (i < 100);
+}
+
+// These loops are all correctly unrolled
+__kernel void unrolled_nested_simple_loops(__global int *A) {
+for (int i = 0; i < 1000; ++i) {
+#pragma unroll
+for (int j = 0; j < 50; ++j) {
+A[0] += i + j;
+}
+}
+
+for (int i = 0; i < 1000; ++i) {
+