LoopVectorize: Keep the IRBuilder on the stack.

No functionality change.

llvm-svn: 166274
This commit is contained in:
Benjamin Kramer 2012-10-19 08:42:02 +00:00
parent dab8043048
commit 319cb771b2
1 changed files with 36 additions and 41 deletions

View File

@ -67,11 +67,7 @@ public:
SingleBlockLoopVectorizer(Loop *OrigLoop, ScalarEvolution *Se, LoopInfo *Li, SingleBlockLoopVectorizer(Loop *OrigLoop, ScalarEvolution *Se, LoopInfo *Li,
LPPassManager *Lpm, unsigned VecWidth): LPPassManager *Lpm, unsigned VecWidth):
Orig(OrigLoop), SE(Se), LI(Li), LPM(Lpm), VF(VecWidth), Orig(OrigLoop), SE(Se), LI(Li), LPM(Lpm), VF(VecWidth),
Builder(0), Induction(0), OldInduction(0) { } Builder(Se->getContext()), Induction(0), OldInduction(0) { }
~SingleBlockLoopVectorizer() {
delete Builder;
}
// Perform the actual loop widening (vectorization). // Perform the actual loop widening (vectorization).
void vectorize() { void vectorize() {
@ -131,7 +127,7 @@ private:
unsigned VF; unsigned VF;
// The builder that we use // The builder that we use
IRBuilder<> *Builder; IRBuilder<> Builder;
// --- Vectorization state --- // --- Vectorization state ---
@ -241,9 +237,9 @@ Value *SingleBlockLoopVectorizer::getBroadcastInstrs(Value *V) {
Value *Zeros = ConstantAggregateZero::get(VectorType::get(I32, VF)); Value *Zeros = ConstantAggregateZero::get(VectorType::get(I32, VF));
Value *UndefVal = UndefValue::get(VTy); Value *UndefVal = UndefValue::get(VTy);
// Insert the value into a new vector. // Insert the value into a new vector.
Value *SingleElem = Builder->CreateInsertElement(UndefVal, V, Zero); Value *SingleElem = Builder.CreateInsertElement(UndefVal, V, Zero);
// Broadcast the scalar into all locations in the vector. // Broadcast the scalar into all locations in the vector.
Value *Shuf = Builder->CreateShuffleVector(SingleElem, UndefVal, Zeros, Value *Shuf = Builder.CreateShuffleVector(SingleElem, UndefVal, Zeros,
"broadcast"); "broadcast");
// We are accessing the induction variable. Make sure to promote the // We are accessing the induction variable. Make sure to promote the
// index for each consecutive SIMD lane. This adds 0,1,2 ... to all lanes. // index for each consecutive SIMD lane. This adds 0,1,2 ... to all lanes.
@ -269,7 +265,7 @@ Value *SingleBlockLoopVectorizer::getConsecutiveVector(Value* Val) {
// Add the consecutive indices to the vector value. // Add the consecutive indices to the vector value.
Constant *Cv = ConstantVector::get(Indices); Constant *Cv = ConstantVector::get(Indices);
assert(Cv->getType() == Val->getType() && "Invalid consecutive vec"); assert(Cv->getType() == Val->getType() && "Invalid consecutive vec");
return Builder->CreateAdd(Val, Cv, "induction"); return Builder.CreateAdd(Val, Cv, "induction");
} }
@ -364,18 +360,18 @@ void SingleBlockLoopVectorizer::scalarizeInstruction(Instruction *Instr) {
Value *Op = Params[op]; Value *Op = Params[op];
// Param is a vector. Need to extract the right lane. // Param is a vector. Need to extract the right lane.
if (Op->getType()->isVectorTy()) if (Op->getType()->isVectorTy())
Op = Builder->CreateExtractElement(Op, Builder->getInt32(i)); Op = Builder.CreateExtractElement(Op, Builder.getInt32(i));
Cloned->setOperand(op, Op); Cloned->setOperand(op, Op);
} }
// Place the cloned scalar in the new loop. // Place the cloned scalar in the new loop.
Builder->Insert(Cloned); Builder.Insert(Cloned);
// If the original scalar returns a value we need to place it in a vector // If the original scalar returns a value we need to place it in a vector
// so that future users will be able to use it. // so that future users will be able to use it.
if (!IsVoidRetTy) if (!IsVoidRetTy)
VecResults = Builder->CreateInsertElement(VecResults, Cloned, VecResults = Builder.CreateInsertElement(VecResults, Cloned,
Builder->getInt32(i)); Builder.getInt32(i));
} }
if (!IsVoidRetTy) if (!IsVoidRetTy)
@ -439,11 +435,10 @@ void SingleBlockLoopVectorizer::createEmptyLoop() {
// 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.
Builder = new IRBuilder<>(VecBody); Builder.SetInsertPoint(VecBody->getFirstInsertionPt());
Builder->SetInsertPoint(VecBody->getFirstInsertionPt());
// Generate the induction variable. // Generate the induction variable.
Induction = Builder->CreatePHI(IdxTy, 2, "index"); Induction = Builder.CreatePHI(IdxTy, 2, "index");
Constant *Zero = ConstantInt::get(IdxTy, 0); Constant *Zero = ConstantInt::get(IdxTy, 0);
Constant *Step = ConstantInt::get(IdxTy, VF); Constant *Step = ConstantInt::get(IdxTy, VF);
@ -494,12 +489,12 @@ void SingleBlockLoopVectorizer::createEmptyLoop() {
MiddleBlock->getTerminator()->eraseFromParent(); MiddleBlock->getTerminator()->eraseFromParent();
// Create i+1 and fill the PHINode. // Create i+1 and fill the PHINode.
Value *NextIdx = Builder->CreateAdd(Induction, Step, "index.next"); Value *NextIdx = Builder.CreateAdd(Induction, Step, "index.next");
Induction->addIncoming(Zero, VectorPH); Induction->addIncoming(Zero, VectorPH);
Induction->addIncoming(NextIdx, VecBody); Induction->addIncoming(NextIdx, VecBody);
// Create the compare. // Create the compare.
Value *ICmp = Builder->CreateICmpEQ(NextIdx, CountRoundDown); Value *ICmp = Builder.CreateICmpEQ(NextIdx, CountRoundDown);
Builder->CreateCondBr(ICmp, MiddleBlock, VecBody); Builder.CreateCondBr(ICmp, MiddleBlock, VecBody);
// Now we have two terminators. Remove the old one from the block. // Now we have two terminators. Remove the old one from the block.
VecBody->getTerminator()->eraseFromParent(); VecBody->getTerminator()->eraseFromParent();
@ -509,7 +504,7 @@ void SingleBlockLoopVectorizer::createEmptyLoop() {
OldInduction->setIncomingValue(BlockIdx, CountRoundDown); OldInduction->setIncomingValue(BlockIdx, CountRoundDown);
// Get ready to start creating new instructions into the vectorized body. // Get ready to start creating new instructions into the vectorized body.
Builder->SetInsertPoint(VecBody->getFirstInsertionPt()); Builder.SetInsertPoint(VecBody->getFirstInsertionPt());
// Register the new loop. // Register the new loop.
Loop* Lp = new Loop(); Loop* Lp = new Loop();
@ -562,7 +557,7 @@ void SingleBlockLoopVectorizer::vectorizeLoop() {
Value *A = getVectorValue(Inst->getOperand(0)); Value *A = getVectorValue(Inst->getOperand(0));
Value *B = getVectorValue(Inst->getOperand(1)); Value *B = getVectorValue(Inst->getOperand(1));
// Use this vector value for all users of the original instruction. // Use this vector value for all users of the original instruction.
WidenMap[Inst] = Builder->CreateBinOp(BinOp->getOpcode(), A, B); WidenMap[Inst] = Builder.CreateBinOp(BinOp->getOpcode(), A, B);
break; break;
} }
case Instruction::Select: { case Instruction::Select: {
@ -570,7 +565,7 @@ void SingleBlockLoopVectorizer::vectorizeLoop() {
Value *A = getVectorValue(Inst->getOperand(0)); Value *A = getVectorValue(Inst->getOperand(0));
Value *B = getVectorValue(Inst->getOperand(1)); Value *B = getVectorValue(Inst->getOperand(1));
Value *C = getVectorValue(Inst->getOperand(2)); Value *C = getVectorValue(Inst->getOperand(2));
WidenMap[Inst] = Builder->CreateSelect(A, B, C); WidenMap[Inst] = Builder.CreateSelect(A, B, C);
break; break;
} }
@ -582,9 +577,9 @@ void SingleBlockLoopVectorizer::vectorizeLoop() {
Value *A = getVectorValue(Inst->getOperand(0)); Value *A = getVectorValue(Inst->getOperand(0));
Value *B = getVectorValue(Inst->getOperand(1)); Value *B = getVectorValue(Inst->getOperand(1));
if (FCmp) if (FCmp)
WidenMap[Inst] = Builder->CreateFCmp(Cmp->getPredicate(), A, B); WidenMap[Inst] = Builder.CreateFCmp(Cmp->getPredicate(), A, B);
else else
WidenMap[Inst] = Builder->CreateICmp(Cmp->getPredicate(), A, B); WidenMap[Inst] = Builder.CreateICmp(Cmp->getPredicate(), A, B);
break; break;
} }
@ -605,10 +600,10 @@ void SingleBlockLoopVectorizer::vectorizeLoop() {
GetElementPtrInst *Gep2 = cast<GetElementPtrInst>(Gep->clone()); GetElementPtrInst *Gep2 = cast<GetElementPtrInst>(Gep->clone());
unsigned NumOperands = Gep->getNumOperands(); unsigned NumOperands = Gep->getNumOperands();
Gep2->setOperand(NumOperands - 1, Induction); Gep2->setOperand(NumOperands - 1, Induction);
Ptr = Builder->Insert(Gep2); Ptr = Builder.Insert(Gep2);
Ptr = Builder->CreateBitCast(Ptr, StTy->getPointerTo()); Ptr = Builder.CreateBitCast(Ptr, StTy->getPointerTo());
Value *Val = getVectorValue(SI->getValueOperand()); Value *Val = getVectorValue(SI->getValueOperand());
Builder->CreateStore(Val, Ptr)->setAlignment(Alignment); Builder.CreateStore(Val, Ptr)->setAlignment(Alignment);
break; break;
} }
case Instruction::Load: { case Instruction::Load: {
@ -629,9 +624,9 @@ void SingleBlockLoopVectorizer::vectorizeLoop() {
GetElementPtrInst *Gep2 = cast<GetElementPtrInst>(Gep->clone()); GetElementPtrInst *Gep2 = cast<GetElementPtrInst>(Gep->clone());
unsigned NumOperands = Gep->getNumOperands(); unsigned NumOperands = Gep->getNumOperands();
Gep2->setOperand(NumOperands - 1, Induction); Gep2->setOperand(NumOperands - 1, Induction);
Ptr = Builder->Insert(Gep2); Ptr = Builder.Insert(Gep2);
Ptr = Builder->CreateBitCast(Ptr, RetTy->getPointerTo()); Ptr = Builder.CreateBitCast(Ptr, RetTy->getPointerTo());
LI = Builder->CreateLoad(Ptr); LI = Builder.CreateLoad(Ptr);
LI->setAlignment(Alignment); LI->setAlignment(Alignment);
// Use this vector value for all users of the load. // Use this vector value for all users of the load.
WidenMap[Inst] = LI; WidenMap[Inst] = LI;
@ -653,7 +648,7 @@ void SingleBlockLoopVectorizer::vectorizeLoop() {
CastInst *CI = dyn_cast<CastInst>(Inst); CastInst *CI = dyn_cast<CastInst>(Inst);
Value *A = getVectorValue(Inst->getOperand(0)); Value *A = getVectorValue(Inst->getOperand(0));
Type *DestTy = VectorType::get(CI->getType()->getScalarType(), VF); Type *DestTy = VectorType::get(CI->getType()->getScalarType(), VF);
WidenMap[Inst] = Builder->CreateCast(CI->getOpcode(), A, DestTy); WidenMap[Inst] = Builder.CreateCast(CI->getOpcode(), A, DestTy);
break; break;
} }