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
86 lines
2.9 KiB
C++
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;
|
|
}
|