Skip to content

Commit a0f6c18

Browse files
author
Hal Finkel
committed
Add a loop rerolling pass
This adds a loop rerolling pass: the opposite of (partial) loop unrolling. The transformation aims to take loops like this: for (int i = 0; i < 3200; i += 5) { a[i] += alpha * b[i]; a[i + 1] += alpha * b[i + 1]; a[i + 2] += alpha * b[i + 2]; a[i + 3] += alpha * b[i + 3]; a[i + 4] += alpha * b[i + 4]; } and turn them into this: for (int i = 0; i < 3200; ++i) { a[i] += alpha * b[i]; } and loops like this: for (int i = 0; i < 500; ++i) { x[3*i] = foo(0); x[3*i+1] = foo(0); x[3*i+2] = foo(0); } and turn them into this: for (int i = 0; i < 1500; ++i) { x[i] = foo(0); } There are two motivations for this transformation: 1. Code-size reduction (especially relevant, obviously, when compiling for code size). 2. Providing greater choice to the loop vectorizer (and generic unroller) to choose the unrolling factor (and a better ability to vectorize). The loop vectorizer can take vector lengths and register pressure into account when choosing an unrolling factor, for example, and a pre-unrolled loop limits that choice. This is especially problematic if the manual unrolling was optimized for a machine different from the current target. The current implementation is limited to single basic-block loops only. The rerolling recognition should work regardless of how the loop iterations are intermixed within the loop body (subject to dependency and side-effect constraints), but the significant restriction is that the order of the instructions in each iteration must be identical. This seems sufficient to capture all current use cases. This pass is not currently enabled by default at any optimization level. llvm-svn: 194939
1 parent d337bf2 commit a0f6c18

File tree

10 files changed

+1630
-0
lines changed

10 files changed

+1630
-0
lines changed

llvm/include/llvm-c/Transforms/Scalar.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,9 @@ void LLVMAddLoopIdiomPass(LLVMPassManagerRef PM);
6565
/** See llvm::createLoopRotatePass function. */
6666
void LLVMAddLoopRotatePass(LLVMPassManagerRef PM);
6767

68+
/** See llvm::createLoopRerollPass function. */
69+
void LLVMAddLoopRerollPass(LLVMPassManagerRef PM);
70+
6871
/** See llvm::createLoopUnrollPass function. */
6972
void LLVMAddLoopUnrollPass(LLVMPassManagerRef PM);
7073

llvm/include/llvm/InitializePasses.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,7 @@ void initializeLoopRotatePass(PassRegistry&);
162162
void initializeLoopSimplifyPass(PassRegistry&);
163163
void initializeLoopStrengthReducePass(PassRegistry&);
164164
void initializeGlobalMergePass(PassRegistry&);
165+
void initializeLoopRerollPass(PassRegistry&);
165166
void initializeLoopUnrollPass(PassRegistry&);
166167
void initializeLoopUnswitchPass(PassRegistry&);
167168
void initializeLoopIdiomRecognizePass(PassRegistry&);

llvm/include/llvm/LinkAllPasses.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ namespace {
9191
(void) llvm::createLoopExtractorPass();
9292
(void) llvm::createLoopSimplifyPass();
9393
(void) llvm::createLoopStrengthReducePass();
94+
(void) llvm::createLoopRerollPass();
9495
(void) llvm::createLoopUnrollPass();
9596
(void) llvm::createLoopUnswitchPass();
9697
(void) llvm::createLoopIdiomPass();

llvm/include/llvm/Transforms/Scalar.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,12 @@ Pass *createLoopInstSimplifyPass();
143143
Pass *createLoopUnrollPass(int Threshold = -1, int Count = -1,
144144
int AllowPartial = -1, int Runtime = -1);
145145

146+
//===----------------------------------------------------------------------===//
147+
//
148+
// LoopReroll - This pass is a simple loop rerolling pass.
149+
//
150+
Pass *createLoopRerollPass();
151+
146152
//===----------------------------------------------------------------------===//
147153
//
148154
// LoopRotate - This pass is a simple loop rotating pass.

llvm/lib/Transforms/IPO/PassManagerBuilder.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ static cl::opt<bool> UseNewSROA("use-new-sroa",
5454
cl::init(true), cl::Hidden,
5555
cl::desc("Enable the new, experimental SROA pass"));
5656

57+
static cl::opt<bool>
58+
RunLoopRerolling("reroll-loops", cl::Hidden,
59+
cl::desc("Run the loop rerolling pass"));
60+
5761
PassManagerBuilder::PassManagerBuilder() {
5862
OptLevel = 2;
5963
SizeLevel = 0;
@@ -216,6 +220,8 @@ void PassManagerBuilder::populateModulePassManager(PassManagerBase &MPM) {
216220

217221
addExtensionsToPM(EP_ScalarOptimizerLate, MPM);
218222

223+
if (RunLoopRerolling)
224+
MPM.add(createLoopRerollPass());
219225
if (SLPVectorize)
220226
MPM.add(createSLPVectorizerPass()); // Vectorize parallel scalar chains.
221227

llvm/lib/Transforms/Scalar/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ add_llvm_library(LLVMScalarOpts
1616
LoopInstSimplify.cpp
1717
LoopRotation.cpp
1818
LoopStrengthReduce.cpp
19+
LoopRerollPass.cpp
1920
LoopUnrollPass.cpp
2021
LoopUnswitch.cpp
2122
LowerAtomic.cpp

0 commit comments

Comments
 (0)