David Blaike suggested this as an alternative to the use of owningptr(s) for our memory management, as value semantics allow to avoid the additional interface complexity caused by owningptr while still providing similar memory consistency guarantees. We could also have used a std::vector, but the use of std::vector would yield possibly changing pointers which currently causes problems as for example the memory accesses carry pointers to their parent statements. Such pointers should not change. Reviewer: jblaikie, jdoerfert Differential Revision: http://reviews.llvm.org/D10041 llvm-svn: 238290
89 lines
3.1 KiB
C++
89 lines
3.1 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/CodeGen/IRBuilder.h"
|
|
#include "polly/ScopInfo.h"
|
|
#include "llvm/Analysis/LoopInfo.h"
|
|
#include "llvm/Analysis/RegionInfo.h"
|
|
#include "llvm/Support/Debug.h"
|
|
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
|
|
|
|
using namespace llvm;
|
|
|
|
BasicBlock *polly::executeScopConditionally(Scop &S, Pass *P, Value *RTC) {
|
|
BasicBlock *StartBlock, *SplitBlock, *NewBlock;
|
|
Region &R = S.getRegion();
|
|
PollyIRBuilder Builder(R.getEntry());
|
|
DominatorTree &DT = P->getAnalysis<DominatorTreeWrapperPass>().getDomTree();
|
|
RegionInfo &RI = P->getAnalysis<RegionInfoPass>().getRegionInfo();
|
|
LoopInfo &LI = P->getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
|
|
|
|
// 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(), &DT, &LI);
|
|
if (DT.dominates(R.getEntry(), NewBlock)) {
|
|
BasicBlock *OldBlock = R.getEntry();
|
|
std::string OldName = OldBlock->getName();
|
|
|
|
// Update ScopInfo.
|
|
for (ScopStmt &Stmt : S)
|
|
if (Stmt.getBasicBlock() == OldBlock) {
|
|
Stmt.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(RTC, StartBlock, R.getEntry());
|
|
if (Loop *L = LI.getLoopFor(SplitBlock))
|
|
L->addBasicBlockToLoop(StartBlock, LI);
|
|
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(), &DT, &LI);
|
|
// 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;
|
|
}
|