summaryrefslogtreecommitdiff
path: root/include/llvm/Transforms/Utils/CodeExtractor.h
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2012-05-04 10:18:49 +0000
committerChandler Carruth <chandlerc@gmail.com>2012-05-04 10:18:49 +0000
commit99650c9088c5dd4b6788a99b63c82d13e0518961 (patch)
treeec254839206a3ca624d38af398ba831dbd053cb4 /include/llvm/Transforms/Utils/CodeExtractor.h
parentfd5abd546e8e035755005a654d60d6f5f74cfe2c (diff)
downloadllvm-99650c9088c5dd4b6788a99b63c82d13e0518961.tar.gz
llvm-99650c9088c5dd4b6788a99b63c82d13e0518961.tar.bz2
llvm-99650c9088c5dd4b6788a99b63c82d13e0518961.tar.xz
Move the CodeExtractor utility to a dedicated header file / source file,
and expose it as a utility class rather than as free function wrappers. The simple free-function interface works well for the bugpoint-specific pass's uses of code extraction, but in an upcoming patch for more advanced code extraction, they simply don't expose a rich enough interface. I need to expose various stages of the process of doing the code extraction and query information to decide whether or not to actually complete the extraction or give up. Rather than build up a new predicate model and pass that into these functions, just take the class that was actually implementing the functions and lift it up into a proper interface that can be used to perform code extraction. The interface is cleaned up and re-documented to work better in a header. It also is now setup to accept the blocks to be extracted in the constructor rather than in a method. In passing this essentially reverts my previous commit here exposing a block-level query for eligibility of extraction. That is no longer necessary with the more rich interface as clients can query the extraction object for eligibility directly. This will reduce the number of walks of the input basic block sequence by quite a bit which is useful if this enters the normal optimization pipeline. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@156163 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/llvm/Transforms/Utils/CodeExtractor.h')
-rw-r--r--include/llvm/Transforms/Utils/CodeExtractor.h110
1 files changed, 110 insertions, 0 deletions
diff --git a/include/llvm/Transforms/Utils/CodeExtractor.h b/include/llvm/Transforms/Utils/CodeExtractor.h
new file mode 100644
index 0000000000..7268a3c6b6
--- /dev/null
+++ b/include/llvm/Transforms/Utils/CodeExtractor.h
@@ -0,0 +1,110 @@
+//===-- Transform/Utils/CodeExtractor.h - Code extraction util --*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// A utility to support extracting code from one function into its own
+// stand-alone function.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TRANSFORMS_UTILS_CODE_EXTRACTOR_H
+#define LLVM_TRANSFORMS_UTILS_CODE_EXTRACTOR_H
+
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/SetVector.h"
+
+namespace llvm {
+ class BasicBlock;
+ class DominatorTree;
+ class Function;
+ class Loop;
+ class Module;
+ class Type;
+ class Value;
+
+ /// \brief Utility class for extracting code into a new function.
+ ///
+ /// This utility provides a simple interface for extracting some sequence of
+ /// code into its own function, replacing it with a call to that function. It
+ /// also provides various methods to query about the nature and result of
+ /// such a transformation.
+ ///
+ /// The rough algorithm used is:
+ /// 1) Find both the inputs and outputs for the extracted region.
+ /// 2) Pass the inputs as arguments, remapping them within the extracted
+ /// function to arguments.
+ /// 3) Add allocas for any scalar outputs, adding all of the outputs' allocas
+ /// as arguments, and inserting stores to the arguments for any scalars.
+ class CodeExtractor {
+ typedef SetVector<Value *> ValueSet;
+
+ // Various bits of state computed on construction.
+ DominatorTree *const DT;
+ const bool AggregateArgs;
+
+ // Bits of intermediate state computed at various phases of extraction.
+ SetVector<BasicBlock *> Blocks;
+ unsigned NumExitBlocks;
+ Type *RetTy;
+
+ public:
+ /// \brief Create a code extractor for a single basic block.
+ ///
+ /// In this formation, we don't require a dominator tree. The given basic
+ /// block is set up for extraction.
+ CodeExtractor(BasicBlock *BB, bool AggregateArgs = false);
+
+ /// \brief Create a code extractor for a sequence of blocks.
+ ///
+ /// Given a sequence of basic blocks where the first block in the sequence
+ /// dominates the rest, prepare a code extractor object for pulling this
+ /// sequence out into its new function. When a DominatorTree is also given,
+ /// extra checking and transformations are enabled.
+ CodeExtractor(ArrayRef<BasicBlock *> BBs, DominatorTree *DT = 0,
+ bool AggregateArgs = false);
+
+ /// \brief Create a code extractor for a loop body.
+ ///
+ /// Behaves just like the generic code sequence constructor, but uses the
+ /// block sequence of the loop.
+ CodeExtractor(DominatorTree &DT, Loop &L, bool AggregateArgs = false);
+
+ /// \brief Perform the extraction, returning the new function.
+ ///
+ /// Returns zero when called on a CodeExtractor instance where isEligible
+ /// returns false.
+ Function *extractCodeRegion();
+
+ /// \brief Test whether this code extractor is eligible.
+ ///
+ /// Based on the blocks used when constructing the code extractor,
+ /// determine whether it is eligible for extraction.
+ bool isEligible() { return !Blocks.empty(); };
+
+ private:
+ void severSplitPHINodes(BasicBlock *&Header);
+ void splitReturnBlocks();
+ void findInputsOutputs(ValueSet &inputs, ValueSet &outputs);
+
+ Function *constructFunction(const ValueSet &inputs,
+ const ValueSet &outputs,
+ BasicBlock *header,
+ BasicBlock *newRootNode, BasicBlock *newHeader,
+ Function *oldFunction, Module *M);
+
+ void moveCodeToFunction(Function *newFunction);
+
+ void emitCallAndSwitchStatement(Function *newFunction,
+ BasicBlock *newHeader,
+ ValueSet &inputs,
+ ValueSet &outputs);
+
+ };
+}
+
+#endif