Recommit "CodeGen: Maintain a valid CFG during code generation"

When I first tried to commit this patch, the builder pointed after generation
of a loop still into the loop body. This means that code that was supposed to
be generated after the loop was generated right into the loop body. We fixed
this by pointing the builder to the BB after the loop, as soon as code
generation of the loop body itself is finished.

llvm-svn: 150480
This commit is contained in:
Tobias Grosser 2012-02-14 14:02:27 +00:00
parent 2ee5950dd0
commit 0ac9214c2f
1 changed files with 62 additions and 56 deletions

View File

@ -97,18 +97,19 @@ typedef struct {
// @param UB The upper bound of the loop iv.
// @param Stride The number by which the loop iv is incremented after every
// iteration.
static void createLoop(IRBuilder<> *Builder, Value *LB, Value *UB, APInt Stride,
PHINode*& IV, BasicBlock*& AfterBB, Value*& IncrementedIV,
DominatorTree *DT) {
static Value *createLoop(IRBuilder<> *Builder, Value *LB, Value *UB,
APInt Stride, DominatorTree *DT, Pass *P,
BasicBlock **AfterBlock) {
Function *F = Builder->GetInsertBlock()->getParent();
LLVMContext &Context = F->getContext();
BasicBlock *PreheaderBB = Builder->GetInsertBlock();
BasicBlock *HeaderBB = BasicBlock::Create(Context, "polly.loop_header", F);
BasicBlock *BodyBB = BasicBlock::Create(Context, "polly.loop_body", F);
AfterBB = BasicBlock::Create(Context, "polly.after_loop", F);
BasicBlock *AfterBB = SplitBlock(PreheaderBB, Builder->GetInsertPoint()++, P);
AfterBB->setName("polly.loop_after");
Builder->CreateBr(HeaderBB);
PreheaderBB->getTerminator()->setSuccessor(0, HeaderBB);
DT->addNewBlock(HeaderBB, PreheaderBB);
Builder->SetInsertPoint(HeaderBB);
@ -121,27 +122,36 @@ static void createLoop(IRBuilder<> *Builder, Value *LB, Value *UB, APInt Stride,
assert(LoopIVType && "UB is not integer?");
// IV
IV = Builder->CreatePHI(LoopIVType, 2, "polly.loopiv");
PHINode *IV = Builder->CreatePHI(LoopIVType, 2, "polly.loopiv");
IV->addIncoming(LB, PreheaderBB);
// IV increment.
Value *StrideValue = ConstantInt::get(LoopIVType,
Stride.zext(LoopIVType->getBitWidth()));
IncrementedIV = Builder->CreateAdd(IV, StrideValue, "polly.next_loopiv");
Value *IncrementedIV = Builder->CreateAdd(IV, StrideValue,
"polly.next_loopiv");
// Exit condition.
Value *CMP;
if (AtLeastOnce) { // At least on iteration.
UB = Builder->CreateAdd(UB, Builder->getInt64(1));
Value *CMP = Builder->CreateICmpEQ(IV, UB);
Builder->CreateCondBr(CMP, AfterBB, BodyBB);
CMP = Builder->CreateICmpNE(IV, UB);
} else { // Maybe not executed at all.
Value *CMP = Builder->CreateICmpSLE(IV, UB);
Builder->CreateCondBr(CMP, BodyBB, AfterBB);
CMP = Builder->CreateICmpSLE(IV, UB);
}
Builder->CreateCondBr(CMP, BodyBB, AfterBB);
DT->addNewBlock(BodyBB, HeaderBB);
DT->addNewBlock(AfterBB, HeaderBB);
Builder->SetInsertPoint(BodyBB);
Builder->CreateBr(HeaderBB);
IV->addIncoming(IncrementedIV, BodyBB);
DT->changeImmediateDominator(AfterBB, HeaderBB);
Builder->SetInsertPoint(BodyBB->begin());
*AfterBlock = AfterBB;
return IV;
}
class BlockGenerator {
@ -263,7 +273,7 @@ public:
// is used to update the operands of the statements.
// For new statements a relation old->new is inserted in this
// map.
void copyBB(BasicBlock *BB, DominatorTree *DT);
void copyBB(BasicBlock *BB, Pass *P);
};
BlockGenerator::BlockGenerator(IRBuilder<> &B, ValueMapT &vmap,
@ -691,15 +701,11 @@ void BlockGenerator::copyInstruction(const Instruction *Inst, ValueMapT &BBMap,
copyInstScalar(Inst, BBMap);
}
void BlockGenerator::copyBB(BasicBlock *BB, DominatorTree *DT) {
Function *F = Builder.GetInsertBlock()->getParent();
LLVMContext &Context = F->getContext();
BasicBlock *CopyBB = BasicBlock::Create(Context,
"polly." + BB->getName() + ".stmt",
F);
Builder.CreateBr(CopyBB);
DT->addNewBlock(CopyBB, Builder.GetInsertBlock());
Builder.SetInsertPoint(CopyBB);
void BlockGenerator::copyBB(BasicBlock *BB, Pass *P) {
BasicBlock *CopyBB = SplitBlock(Builder.GetInsertBlock(),
Builder.GetInsertPoint(), P);
CopyBB->setName("polly." + BB->getName() + ".stmt");
Builder.SetInsertPoint(CopyBB->begin());
// Create two maps that store the mapping from the original instructions of
// the old basic block to their copies in the new basic block. Those maps
@ -889,6 +895,7 @@ class ClastStmtCodeGen {
ScopDetection *SD;
Dependences *DP;
TargetData *TD;
Pass *P;
// The Builder specifies the current location to code generate at.
IRBuilder<> &Builder;
@ -998,7 +1005,7 @@ public:
ClastStmtCodeGen(Scop *scop, ScalarEvolution &se, DominatorTree *dt,
ScopDetection *sd, Dependences *dp, TargetData *td,
IRBuilder<> &B);
IRBuilder<> &B, Pass *P);
};
}
@ -1069,7 +1076,7 @@ void ClastStmtCodeGen::codegen(const clast_user_stmt *u,
BlockGenerator Generator(Builder, ValueMap, VectorValueMap, *Statement,
scatteringDomain);
Generator.copyBB(BB, DT);
Generator.copyBB(BB, P);
}
void ClastStmtCodeGen::codegen(const clast_block *b) {
@ -1081,9 +1088,7 @@ void ClastStmtCodeGen::codegenForSequential(const clast_for *f,
Value *LowerBound,
Value *UpperBound) {
APInt Stride;
PHINode *IV;
Value *IncrementedIV;
BasicBlock *AfterBB, *HeaderBB, *LastBodyBB;
BasicBlock *AfterBB;
Type *IntPtrTy;
Stride = APInt_from_MPZ(f->stride);
@ -1099,8 +1104,8 @@ void ClastStmtCodeGen::codegenForSequential(const clast_for *f,
UpperBound = ExpGen.codegen(f->UB, IntPtrTy);
}
createLoop(&Builder, LowerBound, UpperBound, Stride, IV, AfterBB,
IncrementedIV, DT);
Value *IV = createLoop(&Builder, LowerBound, UpperBound, Stride, DT, P,
&AfterBB);
// Add loop iv to symbols.
(*clastVars)[f->iterator] = IV;
@ -1110,12 +1115,7 @@ void ClastStmtCodeGen::codegenForSequential(const clast_for *f,
// Loop is finished, so remove its iv from the live symbols.
clastVars->erase(f->iterator);
HeaderBB = *pred_begin(AfterBB);
LastBodyBB = Builder.GetInsertBlock();
Builder.CreateBr(HeaderBB);
IV->addIncoming(IncrementedIV, LastBodyBB);
Builder.SetInsertPoint(AfterBB);
Builder.SetInsertPoint(AfterBB->begin());
}
Function *ClastStmtCodeGen::addOpenMPSubfunction(Module *M) {
@ -1202,6 +1202,7 @@ void ClastStmtCodeGen::addOpenMPSubfunctionBody(Function *FN,
IntegerType *intPtrTy = TD->getIntPtrType(Context);
// Store the previous basic block.
BasicBlock::iterator PrevInsertPoint = Builder.GetInsertPoint();
BasicBlock *PrevBB = Builder.GetInsertBlock();
// Create basic blocks.
@ -1255,22 +1256,22 @@ void ClastStmtCodeGen::addOpenMPSubfunctionBody(Function *FN,
clastVars = &clastVarsOMP;
ExpGen.setIVS(&clastVarsOMP);
Builder.CreateBr(checkNextBB);
Builder.SetInsertPoint(--Builder.GetInsertPoint());
codegenForSequential(f, lowerBound, upperBound);
// Restore the old clastVars.
clastVars = oldClastVars;
ExpGen.setIVS(oldClastVars);
Builder.CreateBr(checkNextBB);
// Add code to terminate this openmp subfunction.
Builder.SetInsertPoint(ExitBB);
Function *endnowaitFunction = M->getFunction("GOMP_loop_end_nowait");
Builder.CreateCall(endnowaitFunction);
Builder.CreateRetVoid();
// Restore the builder back to previous basic block.
Builder.SetInsertPoint(PrevBB);
// Restore the previous insert point.
Builder.SetInsertPoint(PrevInsertPoint);
}
void ClastStmtCodeGen::codegenForOpenMP(const clast_for *f) {
@ -1444,10 +1445,20 @@ Value *ClastStmtCodeGen::codegen(const clast_equation *eq) {
void ClastStmtCodeGen::codegen(const clast_guard *g) {
Function *F = Builder.GetInsertBlock()->getParent();
LLVMContext &Context = F->getContext();
BasicBlock *CondBB = SplitBlock(Builder.GetInsertBlock(),
Builder.GetInsertPoint(), P);
CondBB->setName("polly.cond");
BasicBlock *MergeBB = SplitBlock(CondBB, CondBB->begin(), P);
MergeBB->setName("polly.merge");
BasicBlock *ThenBB = BasicBlock::Create(Context, "polly.then", F);
BasicBlock *MergeBB = BasicBlock::Create(Context, "polly.merge", F);
DT->addNewBlock(ThenBB, Builder.GetInsertBlock());
DT->addNewBlock(MergeBB, Builder.GetInsertBlock());
DT->addNewBlock(ThenBB, CondBB);
DT->changeImmediateDominator(MergeBB, CondBB);
CondBB->getTerminator()->eraseFromParent();
Builder.SetInsertPoint(CondBB);
Value *Predicate = codegen(&(g->eq[0]));
@ -1458,11 +1469,10 @@ void ClastStmtCodeGen::codegen(const clast_guard *g) {
Builder.CreateCondBr(Predicate, ThenBB, MergeBB);
Builder.SetInsertPoint(ThenBB);
Builder.CreateBr(MergeBB);
Builder.SetInsertPoint(ThenBB->begin());
codegen(g->then);
Builder.CreateBr(MergeBB);
Builder.SetInsertPoint(MergeBB);
}
void ClastStmtCodeGen::codegen(const clast_stmt *stmt) {
@ -1486,12 +1496,6 @@ void ClastStmtCodeGen::codegen(const clast_stmt *stmt) {
void ClastStmtCodeGen::addParameters(const CloogNames *names) {
SCEVExpander Rewriter(SE, "polly");
// Create an instruction that specifies the location where the parameters
// are expanded.
CastInst::CreateIntegerCast(ConstantInt::getTrue(Builder.getContext()),
Builder.getInt16Ty(), false, "insertInst",
Builder.GetInsertBlock());
int i = 0;
for (Scop::param_iterator PI = S->param_begin(), PE = S->param_end();
PI != PE; ++PI) {
@ -1525,8 +1529,8 @@ void ClastStmtCodeGen::codegen(const clast_root *r) {
ClastStmtCodeGen::ClastStmtCodeGen(Scop *scop, ScalarEvolution &se,
DominatorTree *dt, ScopDetection *sd,
Dependences *dp, TargetData *td,
IRBuilder<> &B) :
S(scop), SE(se), DT(dt), SD(sd), DP(dp), TD(td), Builder(B),
IRBuilder<> &B, Pass *P) :
S(scop), SE(se), DT(dt), SD(sd), DP(dp), TD(td), P(P), Builder(B),
ExpGen(Builder, NULL) {}
namespace {
@ -1722,8 +1726,12 @@ class CodeGeneration : public ScopPass {
// The builder will be set to startBlock.
BasicBlock *splitBlock = addSplitAndStartBlock(&builder);
BasicBlock *StartBlock = builder.GetInsertBlock();
ClastStmtCodeGen CodeGen(S, *SE, DT, SD, DP, TD, builder);
mergeControlFlow(splitBlock, &builder);
builder.SetInsertPoint(StartBlock->begin());
ClastStmtCodeGen CodeGen(S, *SE, DT, SD, DP, TD, builder, this);
CloogInfo &C = getAnalysis<CloogInfo>();
CodeGen.codegen(C.getClast());
@ -1731,8 +1739,6 @@ class CodeGeneration : public ScopPass {
CodeGen.getParallelLoops().begin(),
CodeGen.getParallelLoops().end());
mergeControlFlow(splitBlock, &builder);
return true;
}