summaryrefslogtreecommitdiffstats
path: root/polly/lib/CodeGen/CodeGeneration.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'polly/lib/CodeGen/CodeGeneration.cpp')
-rw-r--r--polly/lib/CodeGen/CodeGeneration.cpp148
1 files changed, 11 insertions, 137 deletions
diff --git a/polly/lib/CodeGen/CodeGeneration.cpp b/polly/lib/CodeGen/CodeGeneration.cpp
index 13aa4d76950..9cb708f09ca 100644
--- a/polly/lib/CodeGen/CodeGeneration.cpp
+++ b/polly/lib/CodeGen/CodeGeneration.cpp
@@ -31,6 +31,7 @@
#include "polly/CodeGen/CodeGeneration.h"
#include "polly/CodeGen/BlockGenerators.h"
#include "polly/CodeGen/LoopGenerators.h"
+#include "polly/CodeGen/Utils.h"
#include "polly/Support/GICHelper.h"
#include "llvm/Module.h"
@@ -752,163 +753,36 @@ ClastStmtCodeGen::ClastStmtCodeGen(Scop *scop, IRBuilder<> &B, Pass *P) :
namespace {
class CodeGeneration : public ScopPass {
- Region *region;
- Scop *S;
- DominatorTree *DT;
- RegionInfo *RI;
-
- std::vector<std::string> parallelLoops;
+ std::vector<std::string> ParallelLoops;
public:
static char ID;
CodeGeneration() : ScopPass(ID) {}
- // Split the entry edge of the region and generate a new basic block on this
- // edge. This function also updates ScopInfo and RegionInfo.
- //
- // @param region The region where the entry edge will be splitted.
- BasicBlock *splitEdgeAdvanced(Region *region) {
- BasicBlock *newBlock;
- BasicBlock *splitBlock;
-
- newBlock = SplitEdge(region->getEnteringBlock(), region->getEntry(), this);
-
- if (DT->dominates(region->getEntry(), newBlock)) {
- BasicBlock *OldBlock = region->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);
- region->replaceEntry(newBlock);
- RI->setRegionFor(newBlock, region);
- } else {
- RI->setRegionFor(newBlock, region->getParent());
- splitBlock = newBlock;
- }
- return splitBlock;
- }
+ bool runOnScop(Scop &S) {
+ ParallelLoops.clear();
- // Create a split block that branches either to the old code or to a new basic
- // block where the new code can be inserted.
- //
- // @param Builder A builder that will be set to point to a basic block, where
- // the new code can be generated.
- // @return The split basic block.
- BasicBlock *addSplitAndStartBlock(IRBuilder<> *Builder) {
- BasicBlock *StartBlock, *SplitBlock;
-
- SplitBlock = splitEdgeAdvanced(region);
- 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, region->getEntry());
- DT->addNewBlock(StartBlock, SplitBlock);
- Builder->SetInsertPoint(StartBlock);
- return SplitBlock;
- }
-
- // Merge the control flow of the newly generated code with the existing code.
- //
- // @param SplitBlock The basic block where the control flow was split between
- // old and new version of the Scop.
- // @param Builder An IRBuilder that points to the last instruction of the
- // newly generated code.
- void mergeControlFlow(BasicBlock *SplitBlock, IRBuilder<> *Builder) {
- BasicBlock *MergeBlock;
- Region *R = region;
-
- 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(), this);
- // SplitEdge will never split R->getExit(), as R->getExit() has more than
- // one predecessor. Hence, mergeBlock is always a newly generated block.
- R->replaceExit(MergeBlock);
- }
+ assert(S.getRegion().isSimple() && "Only simple regions are supported");
- Builder->CreateBr(MergeBlock);
- MergeBlock->setName("polly.merge_new_and_old");
+ BasicBlock *StartBlock = executeScopConditionally(S, this);
- if (DT->dominates(SplitBlock, MergeBlock))
- DT->changeImmediateDominator(MergeBlock, SplitBlock);
- }
+ IRBuilder<> Builder(StartBlock->begin());
- bool runOnScop(Scop &scop) {
- S = &scop;
- region = &S->getRegion();
- DT = &getAnalysis<DominatorTree>();
- RI = &getAnalysis<RegionInfo>();
-
- parallelLoops.clear();
-
- assert(region->isSimple() && "Only simple regions are supported");
-
- // In the CFG the optimized code of the SCoP is generated next to the
- // original code. Both the new and the original version of the code remain
- // in the CFG. A branch statement decides which version is executed.
- // For now, we always execute the new version (the old one is dead code
- // eliminated by the cleanup passes). In the future we may decide to execute
- // the new version only if certain run time checks succeed. This will be
- // useful to support constructs for which we cannot prove all assumptions at
- // compile time.
- //
- // Before transformation:
- //
- // bb0
- // |
- // orig_scop
- // |
- // bb1
- //
- // After transformation:
- // bb0
- // |
- // polly.splitBlock
- // / \.
- // | startBlock
- // | |
- // orig_scop new_scop
- // \ /
- // \ /
- // bb1 (joinBlock)
- IRBuilder<> builder(region->getEntry());
-
- // The builder will be set to startBlock.
- BasicBlock *splitBlock = addSplitAndStartBlock(&builder);
- BasicBlock *StartBlock = builder.GetInsertBlock();
-
- mergeControlFlow(splitBlock, &builder);
- builder.SetInsertPoint(StartBlock->begin());
-
- ClastStmtCodeGen CodeGen(S, builder, this);
+ ClastStmtCodeGen CodeGen(&S, Builder, this);
CloogInfo &C = getAnalysis<CloogInfo>();
CodeGen.codegen(C.getClast());
- parallelLoops.insert(parallelLoops.begin(),
+ ParallelLoops.insert(ParallelLoops.begin(),
CodeGen.getParallelLoops().begin(),
CodeGen.getParallelLoops().end());
-
return true;
}
virtual void printScop(raw_ostream &OS) const {
- for (std::vector<std::string>::const_iterator PI = parallelLoops.begin(),
- PE = parallelLoops.end(); PI != PE; ++PI)
+ for (std::vector<std::string>::const_iterator PI = ParallelLoops.begin(),
+ PE = ParallelLoops.end(); PI != PE; ++PI)
OS << "Parallel loop with iterator '" << *PI << "' generated\n";
}
OpenPOWER on IntegriCloud