Remove redundant checks added by loop unrolling
Benjamin Poulain
benjamin at webkit.org
Sat Nov 29 12:59:23 PST 2014
Hi,
I noticed the optimized code generated for loops often include redundant
checks that the size is not zero.
For example, code like this:
unsigned total = 0;
for (unsigned i = 0; i < size; ++i) { ...
when optimized, generate the following prologue:
entry:
%cmp4 = icmp eq i32 %size, 0
br i1 %cmp4, label %for.end, label %for.body.lr.ph
for.body.lr.ph: ; preds = %entry
%0 = add i32 %size, -1
%xtraiter = and i32 %size, 3
%lcmp.mod = icmp ne i32 %xtraiter, 0
%lcmp.overflow = icmp eq i32 %size, 0
%lcmp.or = or i1 %lcmp.overflow, %lcmp.mod
br i1 %lcmp.or, label %for.body.prol, label %for.body.lr.ph.split
Notice the redundant test for "icmp eq i32 %size, 0". When compiled to
target, we have one redundant check per loop that can never be true.
The extra check for size==0 comes from LoopUnroll. It is never optimized
out because LoopUnrollPass is run after the passes that could eliminate
redundant conditions.
I have attached a patch that fixes the problem. For every pass of
LoopUnroll, I added a GVN pass to remove every redundant conditions and
branches. My patch is without test, I need guidance on how to properly
test this.
Benjamin
-------------- next part --------------
diff --git lib/Transforms/IPO/PassManagerBuilder.cpp lib/Transforms/IPO/PassManagerBuilder.cpp
index 0414caa..cd9a3e7 100644
--- lib/Transforms/IPO/PassManagerBuilder.cpp
+++ lib/Transforms/IPO/PassManagerBuilder.cpp
@@ -275,8 +275,10 @@ void PassManagerBuilder::populateModulePassManager(PassManagerBase &MPM) {
MPM.add(createEarlyCSEPass()); // Catch trivial redundancies
// BBVectorize may have significantly shortened a loop body; unroll again.
- if (!DisableUnrollLoops)
- MPM.add(createLoopUnrollPass());
+ if (!DisableUnrollLoops) {
+ MPM.add(createLoopUnrollPass()); // Unroll small loops
+ MPM.add(createGVNPass(DisableGVNLoadPRE)); // Remove redundancies
+ }
}
}
@@ -340,8 +342,10 @@ void PassManagerBuilder::populateModulePassManager(PassManagerBase &MPM) {
MPM.add(createEarlyCSEPass()); // Catch trivial redundancies
// BBVectorize may have significantly shortened a loop body; unroll again.
- if (!DisableUnrollLoops)
- MPM.add(createLoopUnrollPass());
+ if (!DisableUnrollLoops) {
+ MPM.add(createLoopUnrollPass()); // Unroll small loops
+ MPM.add(createGVNPass(DisableGVNLoadPRE)); // Remove redundancies
+ }
}
}
@@ -349,8 +353,10 @@ void PassManagerBuilder::populateModulePassManager(PassManagerBase &MPM) {
MPM.add(createCFGSimplificationPass());
MPM.add(createInstructionCombiningPass());
- if (!DisableUnrollLoops)
- MPM.add(createLoopUnrollPass()); // Unroll small loops
+ if (!DisableUnrollLoops) {
+ MPM.add(createLoopUnrollPass()); // Unroll small loops
+ MPM.add(createGVNPass(DisableGVNLoadPRE)); // Remove redundancies
+ }
// After vectorization and unrolling, assume intrinsics may tell us more
// about pointer alignments.
More information about the llvm-commits
mailing list