[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