Tobias Grosser 03fc9acbe5 Codegen: Replace region exit and entries recursively
During code generation we split the original entry and exit basic blocks
of the scop to make room for the newly generated code. To keep the region tree
up to date, we need to update the region tree. This patch ensures that not only
the region of the scop is updated, but also all child regions that share the
same entry or exit block.

We have now test case here, as the bug is only exposed by the subsequent commit.
The test cases of that commit also cover this bug.

Contributed-by: Star Tan <tanmx_star@yeah.net>
llvm-svn: 179158
2013-04-10 06:55:20 +00:00

86 lines
2.9 KiB
C++

//===--- Utils.cpp - Utility functions for the code generation --*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains utility functions for the code generation.
//
//===----------------------------------------------------------------------===//
#include "polly/CodeGen/Utils.h"
#include "polly/ScopInfo.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/Support/Debug.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
using namespace llvm;
BasicBlock *polly::executeScopConditionally(Scop &S, Pass *PassInfo) {
BasicBlock *StartBlock, *SplitBlock, *NewBlock;
Region &R = S.getRegion();
IRBuilder<> Builder(R.getEntry());
DominatorTree &DT = PassInfo->getAnalysis<DominatorTree>();
RegionInfo &RI = PassInfo->getAnalysis<RegionInfo>();
// Split the entry edge of the region and generate a new basic block on this
// edge. This function also updates ScopInfo and RegionInfo.
NewBlock = SplitEdge(R.getEnteringBlock(), R.getEntry(), PassInfo);
if (DT.dominates(R.getEntry(), NewBlock)) {
BasicBlock *OldBlock = R.getEntry();
std::string OldName = OldBlock->getName();
// Update ScopInfo.
for (Scop::iterator SI = S.begin(), SE = S.end(); SI != SE; ++SI)
if ((*SI)->getBasicBlock() == OldBlock) {
(*SI)->setBasicBlock(NewBlock);
break;
}
// Update RegionInfo.
SplitBlock = OldBlock;
OldBlock->setName("polly.split");
NewBlock->setName(OldName);
R.replaceEntryRecursive(NewBlock);
RI.setRegionFor(NewBlock, &R);
} else {
RI.setRegionFor(NewBlock, R.getParent());
SplitBlock = NewBlock;
}
SplitBlock->setName("polly.split_new_and_old");
Function *F = SplitBlock->getParent();
StartBlock = BasicBlock::Create(F->getContext(), "polly.start", F);
SplitBlock->getTerminator()->eraseFromParent();
Builder.SetInsertPoint(SplitBlock);
Builder.CreateCondBr(Builder.getTrue(), StartBlock, R.getEntry());
DT.addNewBlock(StartBlock, SplitBlock);
Builder.SetInsertPoint(StartBlock);
BasicBlock *MergeBlock;
if (R.getExit()->getSinglePredecessor())
// No splitEdge required. A block with a single predecessor cannot have
// PHI nodes that would complicate life.
MergeBlock = R.getExit();
else {
MergeBlock = SplitEdge(R.getExitingBlock(), R.getExit(), PassInfo);
// SplitEdge will never split R.getExit(), as R.getExit() has more than
// one predecessor. Hence, mergeBlock is always a newly generated block.
R.replaceExitRecursive(MergeBlock);
RI.setRegionFor(MergeBlock, &R);
}
Builder.CreateBr(MergeBlock);
MergeBlock->setName("polly.merge_new_and_old");
if (DT.dominates(SplitBlock, MergeBlock))
DT.changeImmediateDominator(MergeBlock, SplitBlock);
return StartBlock;
}