Move the code that uses SCEVs prior to creating the new loops.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@168601 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Nadav Rotem
2012-11-26 19:51:46 +00:00
parent d642baf4be
commit 22689b6034

View File

@ -113,10 +113,10 @@ class SingleBlockLoopVectorizer {
public: public:
/// Ctor. /// Ctor.
SingleBlockLoopVectorizer(Loop *Orig, ScalarEvolution *Se, LoopInfo *Li, SingleBlockLoopVectorizer(Loop *Orig, ScalarEvolution *Se, LoopInfo *Li,
DominatorTree *dt, DataLayout *dl, DominatorTree *Dt, DataLayout *Dl,
LPPassManager *Lpm, LPPassManager *Lpm,
unsigned VecWidth): unsigned VecWidth):
OrigLoop(Orig), SE(Se), LI(Li), DT(dt), DL(dl), LPM(Lpm), VF(VecWidth), OrigLoop(Orig), SE(Se), LI(Li), DT(Dt), DL(Dl), LPM(Lpm), VF(VecWidth),
Builder(Se->getContext()), Induction(0), OldInduction(0) { } Builder(Se->getContext()), Induction(0), OldInduction(0) { }
// Perform the actual loop widening (vectorization). // Perform the actual loop widening (vectorization).
@ -133,8 +133,8 @@ public:
private: private:
/// Add code that checks at runtime if the accessed arrays overlap. /// Add code that checks at runtime if the accessed arrays overlap.
/// Returns the comperator value or NULL if no check is needed. /// Returns the comperator value or NULL if no check is needed.
Value* addRuntimeCheck(LoopVectorizationLegality *Legal, Value *addRuntimeCheck(LoopVectorizationLegality *Legal,
Instruction *Loc); Instruction *Loc);
/// Create an empty loop, based on the loop ranges of the old loop. /// Create an empty loop, based on the loop ranges of the old loop.
void createEmptyLoop(LoopVectorizationLegality *Legal); void createEmptyLoop(LoopVectorizationLegality *Legal);
/// Copy and widen the instructions from the old loop. /// Copy and widen the instructions from the old loop.
@ -179,7 +179,7 @@ private:
LoopInfo *LI; LoopInfo *LI;
// Dominator Tree. // Dominator Tree.
DominatorTree *DT; DominatorTree *DT;
// Data Layout; // Data Layout.
DataLayout *DL; DataLayout *DL;
// Loop Pass Manager; // Loop Pass Manager;
LPPassManager *LPM; LPPassManager *LPM;
@ -725,14 +725,14 @@ SingleBlockLoopVectorizer::addRuntimeCheck(LoopVectorizationLegality *Legal,
Starts[j], Ends[i], "bound1", Loc); Starts[j], Ends[i], "bound1", Loc);
Value *IsConflict = BinaryOperator::Create(Instruction::And, Cmp0, Cmp1, Value *IsConflict = BinaryOperator::Create(Instruction::And, Cmp0, Cmp1,
"found.conflict", Loc); "found.conflict", Loc);
if (MemoryRuntimeCheck) { if (MemoryRuntimeCheck)
MemoryRuntimeCheck = BinaryOperator::Create(Instruction::Or, MemoryRuntimeCheck = BinaryOperator::Create(Instruction::Or,
MemoryRuntimeCheck, MemoryRuntimeCheck,
IsConflict, IsConflict,
"conflict.rdx", Loc); "conflict.rdx", Loc);
} else { else
MemoryRuntimeCheck = IsConflict; MemoryRuntimeCheck = IsConflict;
}
} }
} }
@ -770,6 +770,11 @@ SingleBlockLoopVectorizer::createEmptyLoop(LoopVectorizationLegality *Legal) {
... ...
*/ */
BasicBlock *OldBasicBlock = OrigLoop->getHeader();
BasicBlock *BypassBlock = OrigLoop->getLoopPreheader();
BasicBlock *ExitBlock = OrigLoop->getExitBlock();
assert(ExitBlock && "Must have an exit block");
// Some loops have a single integer induction variable, while other loops // Some loops have a single integer induction variable, while other loops
// don't. One example is c++ iterators that often have multiple pointer // don't. One example is c++ iterators that often have multiple pointer
// induction variables. In the code below we also support a case where we // induction variables. In the code below we also support a case where we
@ -786,10 +791,13 @@ SingleBlockLoopVectorizer::createEmptyLoop(LoopVectorizationLegality *Legal) {
ExitCount = SE->getAddExpr(ExitCount, ExitCount = SE->getAddExpr(ExitCount,
SE->getConstant(ExitCount->getType(), 1)); SE->getConstant(ExitCount->getType(), 1));
// This is the original scalar-loop preheader. // Expand the trip count and place the new instructions in the preheader.
BasicBlock *BypassBlock = OrigLoop->getLoopPreheader(); // Notice that the pre-header does not change, only the loop body.
BasicBlock *ExitBlock = OrigLoop->getExitBlock(); SCEVExpander Exp(*SE, "induction");
assert(ExitBlock && "Must have an exit block");
// Count holds the overall loop count (N).
Value *Count = Exp.expandCodeFor(ExitCount, ExitCount->getType(),
BypassBlock->getTerminator());
// The loop index does not have to start at Zero. Find the original start // The loop index does not have to start at Zero. Find the original start
// value from the induction PHI node. If we don't have an induction variable // value from the induction PHI node. If we don't have an induction variable
@ -801,18 +809,23 @@ SingleBlockLoopVectorizer::createEmptyLoop(LoopVectorizationLegality *Legal) {
assert(OrigLoop->getNumBlocks() == 1 && "Invalid loop"); assert(OrigLoop->getNumBlocks() == 1 && "Invalid loop");
assert(BypassBlock && "Invalid loop structure"); assert(BypassBlock && "Invalid loop structure");
// Generate the code that checks in runtime if arrays overlap.
Value *MemoryRuntimeCheck = addRuntimeCheck(Legal,
BypassBlock->getTerminator());
// Split the single block loop into the two loop structure described above.
BasicBlock *VectorPH = BasicBlock *VectorPH =
BypassBlock->splitBasicBlock(BypassBlock->getTerminator(), "vector.ph"); BypassBlock->splitBasicBlock(BypassBlock->getTerminator(), "vector.ph");
BasicBlock *VecBody = VectorPH->splitBasicBlock(VectorPH->getTerminator(), BasicBlock *VecBody =
"vector.body"); VectorPH->splitBasicBlock(VectorPH->getTerminator(), "vector.body");
BasicBlock *MiddleBlock =
BasicBlock *MiddleBlock = VecBody->splitBasicBlock(VecBody->getTerminator(), VecBody->splitBasicBlock(VecBody->getTerminator(), "middle.block");
"middle.block");
BasicBlock *ScalarPH = BasicBlock *ScalarPH =
MiddleBlock->splitBasicBlock(MiddleBlock->getTerminator(), MiddleBlock->splitBasicBlock(MiddleBlock->getTerminator(), "scalar.ph");
"scalar.preheader");
// Find the induction variable. // This is the location in which we add all of the logic for bypassing
BasicBlock *OldBasicBlock = OrigLoop->getHeader(); // the new vector loop.
Instruction *Loc = BypassBlock->getTerminator();
// Use this IR builder to create the loop instructions (Phi, Br, Cmp) // Use this IR builder to create the loop instructions (Phi, Br, Cmp)
// inside the loop. // inside the loop.
@ -822,14 +835,6 @@ SingleBlockLoopVectorizer::createEmptyLoop(LoopVectorizationLegality *Legal) {
Induction = Builder.CreatePHI(IdxTy, 2, "index"); Induction = Builder.CreatePHI(IdxTy, 2, "index");
Constant *Step = ConstantInt::get(IdxTy, VF); Constant *Step = ConstantInt::get(IdxTy, VF);
// Expand the trip count and place the new instructions in the preheader.
// Notice that the pre-header does not change, only the loop body.
SCEVExpander Exp(*SE, "induction");
Instruction *Loc = BypassBlock->getTerminator();
// Count holds the overall loop count (N).
Value *Count = Exp.expandCodeFor(ExitCount, ExitCount->getType(), Loc);
// We may need to extend the index in case there is a type mismatch. // We may need to extend the index in case there is a type mismatch.
// We know that the count starts at zero and does not overflow. // We know that the count starts at zero and does not overflow.
if (Count->getType() != IdxTy) { if (Count->getType() != IdxTy) {
@ -859,8 +864,6 @@ SingleBlockLoopVectorizer::createEmptyLoop(LoopVectorizationLegality *Legal) {
StartIdx, StartIdx,
"cmp.zero", Loc); "cmp.zero", Loc);
Value *MemoryRuntimeCheck = addRuntimeCheck(Legal, Loc);
// If we are using memory runtime checks, include them in. // If we are using memory runtime checks, include them in.
if (MemoryRuntimeCheck) if (MemoryRuntimeCheck)
Cmp = BinaryOperator::Create(Instruction::Or, Cmp, MemoryRuntimeCheck, Cmp = BinaryOperator::Create(Instruction::Or, Cmp, MemoryRuntimeCheck,
@ -1053,7 +1056,7 @@ SingleBlockLoopVectorizer::vectorizeLoop(LoopVectorizationLegality *Legal) {
continue; continue;
} }
// Handle pointer inductions: // Handle pointer inductions.
assert(P->getType()->isPointerTy() && "Unexpected type."); assert(P->getType()->isPointerTy() && "Unexpected type.");
Value *StartIdx = OldInduction ? Value *StartIdx = OldInduction ?
Legal->getInductionVars()->lookup(OldInduction) : Legal->getInductionVars()->lookup(OldInduction) :