mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-14 11:32:34 +00:00
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. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@12961 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
92020faa2c
commit
59fdaeeae8
@ -39,10 +39,10 @@
|
||||
|
||||
#include "llvm/Transforms/Scalar.h"
|
||||
#include "llvm/BasicBlock.h"
|
||||
#include "llvm/Constant.h"
|
||||
#include "llvm/Constants.h"
|
||||
#include "llvm/Instructions.h"
|
||||
#include "llvm/Type.h"
|
||||
#include "llvm/Analysis/ScalarEvolution.h"
|
||||
#include "llvm/Analysis/ScalarEvolutionExpressions.h"
|
||||
#include "llvm/Analysis/LoopInfo.h"
|
||||
#include "llvm/Support/CFG.h"
|
||||
#include "llvm/Transforms/Utils/Local.h"
|
||||
@ -85,7 +85,7 @@ namespace {
|
||||
void EliminatePointerRecurrence(PHINode *PN, BasicBlock *Preheader,
|
||||
std::set<Instruction*> &DeadInsts);
|
||||
void LinearFunctionTestReplace(Loop *L, SCEV *IterationCount,
|
||||
Value *IndVar, ScalarEvolutionRewriter &RW);
|
||||
ScalarEvolutionRewriter &RW);
|
||||
void RewriteLoopExitValues(Loop *L);
|
||||
|
||||
void DeleteTriviallyDeadInstructions(std::set<Instruction*> &Insts);
|
||||
@ -177,12 +177,11 @@ void IndVarSimplify::EliminatePointerRecurrence(PHINode *PN,
|
||||
}
|
||||
|
||||
/// LinearFunctionTestReplace - This method rewrites the exit condition of the
|
||||
/// loop to be a canonical != comparison against the loop induction variable.
|
||||
/// This pass is able to rewrite the exit tests of any loop where the SCEV
|
||||
/// analysis can determine the trip count of the loop, which is actually a much
|
||||
/// broader range than just linear tests.
|
||||
/// loop to be a canonical != comparison against the incremented loop induction
|
||||
/// variable. This pass is able to rewrite the exit tests of any loop where the
|
||||
/// SCEV analysis can determine a loop-invariant trip count of the loop, which
|
||||
/// is actually a much broader range than just linear tests.
|
||||
void IndVarSimplify::LinearFunctionTestReplace(Loop *L, SCEV *IterationCount,
|
||||
Value *IndVar,
|
||||
ScalarEvolutionRewriter &RW) {
|
||||
// Find the exit block for the loop. We can currently only handle loops with
|
||||
// a single exit.
|
||||
@ -210,9 +209,17 @@ void IndVarSimplify::LinearFunctionTestReplace(Loop *L, SCEV *IterationCount,
|
||||
if (Instruction *Cond = dyn_cast<Instruction>(BI->getCondition()))
|
||||
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.
|
||||
BasicBlock *Preheader = L->getLoopPreheader();
|
||||
Value *ExitCnt = RW.ExpandCodeFor(IterationCount, Preheader->getTerminator(),
|
||||
Value *ExitCnt = RW.ExpandCodeFor(TripCount, Preheader->getTerminator(),
|
||||
IndVar->getType());
|
||||
|
||||
// Insert a new setne or seteq instruction before the branch.
|
||||
@ -368,7 +375,7 @@ void IndVarSimplify::runOnLoop(Loop *L) {
|
||||
Changed = true;
|
||||
|
||||
if (!isa<SCEVCouldNotCompute>(IterationCount))
|
||||
LinearFunctionTestReplace(L, IterationCount, IndVar, Rewriter);
|
||||
LinearFunctionTestReplace(L, IterationCount, Rewriter);
|
||||
|
||||
#if 0
|
||||
// If there were induction variables of other sizes, cast the primary
|
||||
|
Loading…
Reference in New Issue
Block a user