Skip to content
Snippets Groups Projects
Commit 0cec5cb9 authored by Chris Lattner's avatar Chris Lattner
Browse files

Change the canonical induction variable that we insert.

Instead of producing code like this:

Loop:
  X = phi 0, X2
  ...

  X2 = X + 1
  if (X != N-1) goto Loop

We now generate code that looks like this:

Loop:
  X = phi 0, X2
  ...

  X2 = X + 1
  if (X2 != N) goto Loop

This has two big advantages:
  1. The trip count of the loop is now explicit in the code, allowing
     the direct implementation of Loop::getTripCount()
  2. This reduces register pressure in the loop, and allows X and X2 to be
     put into the same register.

As a consequence of the second point, the code we generate for loops went
from:

.LBB2:  # no_exit.1
	...
        mov %EDI, %ESI
        inc %EDI
        cmp %ESI, 2
        mov %ESI, %EDI
        jne .LBB2 # PC rel: no_exit.1

To:

.LBB2:  # no_exit.1
	...
        inc %ESI
        cmp %ESI, 3
        jne .LBB2 # PC rel: no_exit.1

... which has two fewer moves, and uses one less register.

llvm-svn: 12961
parent d9dc4253
No related branches found
No related tags found
No related merge requests found
...@@ -39,10 +39,10 @@ ...@@ -39,10 +39,10 @@
#include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Scalar.h"
#include "llvm/BasicBlock.h" #include "llvm/BasicBlock.h"
#include "llvm/Constant.h" #include "llvm/Constants.h"
#include "llvm/Instructions.h" #include "llvm/Instructions.h"
#include "llvm/Type.h" #include "llvm/Type.h"
#include "llvm/Analysis/ScalarEvolution.h" #include "llvm/Analysis/ScalarEvolutionExpressions.h"
#include "llvm/Analysis/LoopInfo.h" #include "llvm/Analysis/LoopInfo.h"
#include "llvm/Support/CFG.h" #include "llvm/Support/CFG.h"
#include "llvm/Transforms/Utils/Local.h" #include "llvm/Transforms/Utils/Local.h"
...@@ -85,7 +85,7 @@ namespace { ...@@ -85,7 +85,7 @@ namespace {
void EliminatePointerRecurrence(PHINode *PN, BasicBlock *Preheader, void EliminatePointerRecurrence(PHINode *PN, BasicBlock *Preheader,
std::set<Instruction*> &DeadInsts); std::set<Instruction*> &DeadInsts);
void LinearFunctionTestReplace(Loop *L, SCEV *IterationCount, void LinearFunctionTestReplace(Loop *L, SCEV *IterationCount,
Value *IndVar, ScalarEvolutionRewriter &RW); ScalarEvolutionRewriter &RW);
void RewriteLoopExitValues(Loop *L); void RewriteLoopExitValues(Loop *L);
void DeleteTriviallyDeadInstructions(std::set<Instruction*> &Insts); void DeleteTriviallyDeadInstructions(std::set<Instruction*> &Insts);
...@@ -177,12 +177,11 @@ void IndVarSimplify::EliminatePointerRecurrence(PHINode *PN, ...@@ -177,12 +177,11 @@ void IndVarSimplify::EliminatePointerRecurrence(PHINode *PN,
} }
/// LinearFunctionTestReplace - This method rewrites the exit condition of the /// LinearFunctionTestReplace - This method rewrites the exit condition of the
/// loop to be a canonical != comparison against the loop induction variable. /// loop to be a canonical != comparison against the incremented loop induction
/// This pass is able to rewrite the exit tests of any loop where the SCEV /// variable. This pass is able to rewrite the exit tests of any loop where the
/// analysis can determine the trip count of the loop, which is actually a much /// SCEV analysis can determine a loop-invariant trip count of the loop, which
/// broader range than just linear tests. /// is actually a much broader range than just linear tests.
void IndVarSimplify::LinearFunctionTestReplace(Loop *L, SCEV *IterationCount, void IndVarSimplify::LinearFunctionTestReplace(Loop *L, SCEV *IterationCount,
Value *IndVar,
ScalarEvolutionRewriter &RW) { ScalarEvolutionRewriter &RW) {
// Find the exit block for the loop. We can currently only handle loops with // Find the exit block for the loop. We can currently only handle loops with
// a single exit. // a single exit.
...@@ -210,9 +209,17 @@ void IndVarSimplify::LinearFunctionTestReplace(Loop *L, SCEV *IterationCount, ...@@ -210,9 +209,17 @@ void IndVarSimplify::LinearFunctionTestReplace(Loop *L, SCEV *IterationCount,
if (Instruction *Cond = dyn_cast<Instruction>(BI->getCondition())) if (Instruction *Cond = dyn_cast<Instruction>(BI->getCondition()))
InstructionsToDelete.insert(Cond); InstructionsToDelete.insert(Cond);
// The IterationCount expression contains the number of times that the
// backedge actually branches to the loop header. This is one less than the
// number of times the loop executes, so add one to it.
Constant *OneC = ConstantInt::get(IterationCount->getType(), 1);
SCEVHandle TripCount=SCEVAddExpr::get(IterationCount, SCEVUnknown::get(OneC));
Value *IndVar = L->getCanonicalInductionVariableIncrement();
// Expand the code for the iteration count into the preheader of the loop. // Expand the code for the iteration count into the preheader of the loop.
BasicBlock *Preheader = L->getLoopPreheader(); BasicBlock *Preheader = L->getLoopPreheader();
Value *ExitCnt = RW.ExpandCodeFor(IterationCount, Preheader->getTerminator(), Value *ExitCnt = RW.ExpandCodeFor(TripCount, Preheader->getTerminator(),
IndVar->getType()); IndVar->getType());
// Insert a new setne or seteq instruction before the branch. // Insert a new setne or seteq instruction before the branch.
...@@ -368,7 +375,7 @@ void IndVarSimplify::runOnLoop(Loop *L) { ...@@ -368,7 +375,7 @@ void IndVarSimplify::runOnLoop(Loop *L) {
Changed = true; Changed = true;
if (!isa<SCEVCouldNotCompute>(IterationCount)) if (!isa<SCEVCouldNotCompute>(IterationCount))
LinearFunctionTestReplace(L, IterationCount, IndVar, Rewriter); LinearFunctionTestReplace(L, IterationCount, Rewriter);
#if 0 #if 0
// If there were induction variables of other sizes, cast the primary // If there were induction variables of other sizes, cast the primary
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment