[llvm-commits] [polly] r157605 - in /polly/trunk: include/polly/CodeGen/Utils.h lib/CodeGen/CMakeLists.txt lib/CodeGen/CodeGeneration.cpp lib/CodeGen/Utils.cpp
Tobias Grosser
grosser at fim.uni-passau.de
Tue May 29 02:11:54 PDT 2012
Author: grosser
Date: Tue May 29 04:11:54 2012
New Revision: 157605
URL: http://llvm.org/viewvc/llvm-project?rev=157605&view=rev
Log:
Move executeScopConditionally() into its own file
We will reuse this function for the isl code generator.
Added:
polly/trunk/include/polly/CodeGen/Utils.h
polly/trunk/lib/CodeGen/Utils.cpp
Modified:
polly/trunk/lib/CodeGen/CMakeLists.txt
polly/trunk/lib/CodeGen/CodeGeneration.cpp
Added: polly/trunk/include/polly/CodeGen/Utils.h
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/include/polly/CodeGen/Utils.h?rev=157605&view=auto
==============================================================================
--- polly/trunk/include/polly/CodeGen/Utils.h (added)
+++ polly/trunk/include/polly/CodeGen/Utils.h Tue May 29 04:11:54 2012
@@ -0,0 +1,63 @@
+//===- Utils.h - Utility functions for 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.
+//===----------------------------------------------------------------------===//
+
+#ifndef POLLY_CODEGEN_UTILS_H
+#define POLLY_CODEGEN_UTILS_H
+
+namespace llvm {
+ class Pass;
+ class BasicBlock;
+}
+
+namespace polly {
+
+ class Scop;
+
+/// @brief Execute a Scop conditionally.
+///
+/// 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)
+///
+/// @param S The Scop to execute conditionally.
+/// @param PassInfo A reference to the pass calling this function.
+/// @return BasicBlock The 'StartBlock' to which new code can be added.
+llvm::BasicBlock *executeScopConditionally(Scop &S, llvm::Pass *PassInfo);
+
+}
+#endif
+
Modified: polly/trunk/lib/CodeGen/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/CodeGen/CMakeLists.txt?rev=157605&r1=157604&r2=157605&view=diff
==============================================================================
--- polly/trunk/lib/CodeGen/CMakeLists.txt (original)
+++ polly/trunk/lib/CodeGen/CMakeLists.txt Tue May 29 04:11:54 2012
@@ -14,4 +14,5 @@
${CLOOG_FILES}
${ISL_CODEGEN_FILES}
LoopGenerators.cpp
+ Utils.cpp
)
Modified: polly/trunk/lib/CodeGen/CodeGeneration.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/CodeGen/CodeGeneration.cpp?rev=157605&r1=157604&r2=157605&view=diff
==============================================================================
--- polly/trunk/lib/CodeGen/CodeGeneration.cpp (original)
+++ polly/trunk/lib/CodeGen/CodeGeneration.cpp Tue May 29 04:11:54 2012
@@ -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 @@
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;
- }
+ assert(S.getRegion().isSimple() && "Only simple regions are supported");
- // 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);
- }
+ BasicBlock *StartBlock = executeScopConditionally(S, this);
- Builder->CreateBr(MergeBlock);
- MergeBlock->setName("polly.merge_new_and_old");
-
- 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";
}
Added: polly/trunk/lib/CodeGen/Utils.cpp
URL: http://llvm.org/viewvc/llvm-project/polly/trunk/lib/CodeGen/Utils.cpp?rev=157605&view=auto
==============================================================================
--- polly/trunk/lib/CodeGen/Utils.cpp (added)
+++ polly/trunk/lib/CodeGen/Utils.cpp Tue May 29 04:11:54 2012
@@ -0,0 +1,84 @@
+//===--- 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/Support/Debug.h"
+#include "llvm/Support/IRBuilder.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.replaceEntry(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.replaceExit(MergeBlock);
+ }
+
+ Builder.CreateBr(MergeBlock);
+ MergeBlock->setName("polly.merge_new_and_old");
+
+ if (DT.dominates(SplitBlock, MergeBlock))
+ DT.changeImmediateDominator(MergeBlock, SplitBlock);
+ return StartBlock;
+}
More information about the llvm-commits
mailing list