From 30ba82933c433611e05b07ef95da36bba8721b8b Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Fri, 4 May 2012 21:33:30 +0000 Subject: [PATCH] Teach the code extractor how to extract a sequence of blocks from 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 | 8 ++++ lib/Transforms/Utils/CodeExtractor.cpp | 39 +++++++++++++++---- 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/include/llvm/Transforms/Utils/CodeExtractor.h b/include/llvm/Transforms/Utils/CodeExtractor.h index dafe730f142..48f3d48c6f4 100644 --- a/include/llvm/Transforms/Utils/CodeExtractor.h +++ b/include/llvm/Transforms/Utils/CodeExtractor.h @@ -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 diff --git a/lib/Transforms/Utils/CodeExtractor.cpp b/lib/Transforms/Utils/CodeExtractor.cpp index b23787dc49b..f10dbbeef2d 100644 --- a/lib/Transforms/Utils/CodeExtractor.cpp +++ b/lib/Transforms/Utils/CodeExtractor.cpp @@ -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 -buildExtractionBlockSet(ArrayRef BBs) { +template +static SetVector buildExtractionBlockSet(IteratorT BBBegin, + IteratorT BBEnd) { SetVector 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::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 BBs) { } #ifndef NDEBUG - for (ArrayRef::iterator I = llvm::next(BBs.begin()), - E = BBs.end(); + for (SetVector::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 BBs) { return Result; } +/// \brief Helper to call buildExtractionBlockSet with an ArrayRef. +static SetVector +buildExtractionBlockSet(ArrayRef BBs) { + return buildExtractionBlockSet(BBs.begin(), BBs.end()); +} + +/// \brief Helper to call buildExtractionBlockSet with a RegionNode. +static SetVector +buildExtractionBlockSet(const RegionNode &RN) { + if (!RN.isSubRegion()) + // Just a single BasicBlock. + return buildExtractionBlockSet(RN.getNodeAs()); + + const Region &R = *RN.getNodeAs(); + + 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 &Blocks, Value *V) {