Teach the code extractor how to extract a sequence of blocks from
authorChandler Carruth <chandlerc@gmail.com>
Fri, 4 May 2012 21:33:30 +0000 (21:33 +0000)
committerChandler Carruth <chandlerc@gmail.com>
Fri, 4 May 2012 21:33:30 +0000 (21:33 +0000)
RegionInfo's RegionNode. This mirrors the logic for automating the
extraction from a Loop.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@156208 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/Transforms/Utils/CodeExtractor.h
lib/Transforms/Utils/CodeExtractor.cpp

index dafe730f1423bce5487f5a84b5479e42baf2fceb..48f3d48c6f4dcd0071260b8dc7d358cbd0d4f300 100644 (file)
@@ -24,6 +24,7 @@ namespace llvm {
   class Function;
   class Loop;
   class Module;
+  class RegionNode;
   class Type;
   class Value;
 
@@ -74,6 +75,13 @@ namespace llvm {
     /// block sequence of the loop.
     CodeExtractor(DominatorTree &DT, Loop &L, bool AggregateArgs = false);
 
+    /// \brief Create a code extractor for a region node.
+    ///
+    /// Behaves just like the generic code sequence constructor, but uses the
+    /// block sequence of the region node passed in.
+    CodeExtractor(DominatorTree &DT, const RegionNode &RN,
+                  bool AggregateArgs = false);
+
     /// \brief Perform the extraction, returning the new function.
     ///
     /// Returns zero when called on a CodeExtractor instance where isEligible
index b23787dc49bf211d8630120cd447eeb60887d117..f10dbbeef2d790b0f44aa74cedb6201191179f0f 100644 (file)
@@ -23,6 +23,8 @@
 #include "llvm/Pass.h"
 #include "llvm/Analysis/Dominators.h"
 #include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Analysis/RegionInfo.h"
+#include "llvm/Analysis/RegionIterator.h"
 #include "llvm/Analysis/Verifier.h"
 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
 #include "llvm/Support/CommandLine.h"
@@ -63,16 +65,16 @@ static bool isBlockValidForExtraction(const BasicBlock &BB) {
 }
 
 /// \brief Build a set of blocks to extract if the input blocks are viable.
-static SetVector<BasicBlock *>
-buildExtractionBlockSet(ArrayRef<BasicBlock *> BBs) {
+template <typename IteratorT>
+static SetVector<BasicBlock *> buildExtractionBlockSet(IteratorT BBBegin,
+                                                       IteratorT BBEnd) {
   SetVector<BasicBlock *> Result;
 
-  assert(!BBs.empty());
+  assert(BBBegin != BBEnd);
 
   // Loop over the blocks, adding them to our set-vector, and aborting with an
   // empty set if we encounter invalid blocks.
-  for (ArrayRef<BasicBlock *>::iterator I = BBs.begin(), E = BBs.end();
-       I != E; ++I) {
+  for (IteratorT I = BBBegin, E = BBEnd; I != E; ++I) {
     if (!Result.insert(*I))
       llvm_unreachable("Repeated basic blocks in extraction input");
 
@@ -83,8 +85,8 @@ buildExtractionBlockSet(ArrayRef<BasicBlock *> BBs) {
   }
 
 #ifndef NDEBUG
-  for (ArrayRef<BasicBlock *>::iterator I = llvm::next(BBs.begin()),
-                                        E = BBs.end();
+  for (SetVector<BasicBlock *>::iterator I = llvm::next(Result.begin()),
+                                         E = Result.end();
        I != E; ++I)
     for (pred_iterator PI = pred_begin(*I), PE = pred_end(*I);
          PI != PE; ++PI)
@@ -96,6 +98,24 @@ buildExtractionBlockSet(ArrayRef<BasicBlock *> BBs) {
   return Result;
 }
 
+/// \brief Helper to call buildExtractionBlockSet with an ArrayRef.
+static SetVector<BasicBlock *>
+buildExtractionBlockSet(ArrayRef<BasicBlock *> BBs) {
+  return buildExtractionBlockSet(BBs.begin(), BBs.end());
+}
+
+/// \brief Helper to call buildExtractionBlockSet with a RegionNode.
+static SetVector<BasicBlock *>
+buildExtractionBlockSet(const RegionNode &RN) {
+  if (!RN.isSubRegion())
+    // Just a single BasicBlock.
+    return buildExtractionBlockSet(RN.getNodeAs<BasicBlock>());
+
+  const Region &R = *RN.getNodeAs<Region>();
+
+  return buildExtractionBlockSet(R.block_begin(), R.block_end());
+}
+
 CodeExtractor::CodeExtractor(BasicBlock *BB, bool AggregateArgs)
   : DT(0), AggregateArgs(AggregateArgs||AggregateArgsOpt),
     Blocks(buildExtractionBlockSet(BB)), NumExitBlocks(~0U) {}
@@ -109,6 +129,11 @@ CodeExtractor::CodeExtractor(DominatorTree &DT, Loop &L, bool AggregateArgs)
   : DT(&DT), AggregateArgs(AggregateArgs||AggregateArgsOpt),
     Blocks(buildExtractionBlockSet(L.getBlocks())), NumExitBlocks(~0U) {}
 
+CodeExtractor::CodeExtractor(DominatorTree &DT, const RegionNode &RN,
+                             bool AggregateArgs)
+  : DT(&DT), AggregateArgs(AggregateArgs||AggregateArgsOpt),
+    Blocks(buildExtractionBlockSet(RN)), NumExitBlocks(~0U) {}
+
 /// definedInRegion - Return true if the specified value is defined in the
 /// extracted region.
 static bool definedInRegion(const SetVector<BasicBlock *> &Blocks, Value *V) {