diff --git a/include/llvm/Analysis/InstForest.h b/include/llvm/Analysis/InstForest.h deleted file mode 100644 index 8d5451da4e1..00000000000 --- a/include/llvm/Analysis/InstForest.h +++ /dev/null @@ -1,298 +0,0 @@ -//===- llvm/Analysis/InstForest.h - Partition Func into forest --*- C++ -*-===// -// -// The LLVM Compiler Infrastructure -// -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This interface is used to partition a method into a forest of instruction -// trees, where the following invariants hold: -// -// 1. The instructions in a tree are all related to each other through use -// relationships. -// 2. All instructions in a tree are members of the same basic block -// 3. All instructions in a tree (with the exception of the root), may have only -// a single user. -// -//===----------------------------------------------------------------------===// - -#ifndef LLVM_ANALYSIS_INSTFOREST_H -#define LLVM_ANALYSIS_INSTFOREST_H - -#include "llvm/Function.h" -#include "Support/Tree.h" -#include - -namespace llvm { - -template class InstTreeNode; -template class InstForest; - -//===----------------------------------------------------------------------===// -// Class InstTreeNode -//===----------------------------------------------------------------------===// -// -// There is an instance of this class for each node in the instruction forest. -// There should be a node for every instruction in the tree, as well as -// Temporary nodes that correspond to other trees in the forest and to variables -// and global variables. Constants have their own special node. -// -template -class InstTreeNode : - public Tree, - std::pair, Payload> > { - - friend class InstForest; - typedef Tree, - std::pair, Payload> > super; - - // Constants used for the node type value - enum NodeTypeTy { - ConstNode = Value::ConstantVal, - BasicBlockNode = Value::BasicBlockVal, - InstructionNode = Value::InstructionVal, - TemporaryNode = -1 - }; - - // Helper functions to make accessing our data nicer... - const Value *getValue() const { return this->getTreeData().first.first; } - Value *getValue() { return this->getTreeData().first.first; } - enum NodeTypeTy getNodeType() const { - return (enum NodeTypeTy)this->getTreeData().first.second; - } - - InstTreeNode(const InstTreeNode &); // Do not implement - void operator=(const InstTreeNode &); // Do not implement - - // Only creatable by InstForest - InstTreeNode(InstForest &IF, Value *V, InstTreeNode *Parent); - bool CanMergeInstIntoTree(Instruction *Inst); -public: - // Accessor functions... - inline Payload &getData() { return this->getTreeData().second; } - inline const Payload &getData() const { return this->getTreeData().second; } - - // Type checking functions... - inline bool isConstant() const { return getNodeType() == ConstNode; } - inline bool isBasicBlock() const { return getNodeType() == BasicBlockNode; } - inline bool isInstruction() const { return getNodeType() == InstructionNode; } - inline bool isTemporary() const { return getNodeType() == TemporaryNode; } - - // Accessors for different node types... - inline Constant *getConstant() { - return cast(getValue()); - } - inline const Constant *getConstant() const { - return cast(getValue()); - } - inline BasicBlock *getBasicBlock() { - return cast(getValue()); - } - inline const BasicBlock *getBasicBlock() const { - return cast(getValue()); - } - inline Instruction *getInstruction() { - assert(isInstruction() && "getInstruction() on non instruction node!"); - return cast(getValue()); - } - inline const Instruction *getInstruction() const { - assert(isInstruction() && "getInstruction() on non instruction node!"); - return cast(getValue()); - } - inline Instruction *getTemporary() { - assert(isTemporary() && "getTemporary() on non temporary node!"); - return cast(getValue()); - } - inline const Instruction *getTemporary() const { - assert(isTemporary() && "getTemporary() on non temporary node!"); - return cast(getValue()); - } - -public: - // print - Called by operator<< below... - void print(std::ostream &o, unsigned Indent) const { - o << std::string(Indent*2, ' '); - switch (getNodeType()) { - case ConstNode : o << "Constant : "; break; - case BasicBlockNode : o << "BasicBlock : " << getValue()->getName() << "\n"; - return; - case InstructionNode: o << "Instruction: "; break; - case TemporaryNode : o << "Temporary : "; break; - default: o << "UNKNOWN NODE TYPE: " << getNodeType() << "\n"; abort(); - } - - o << *getValue(); - if (!isa(getValue())) o << "\n"; - - for (unsigned i = 0; i < this->getNumChildren(); ++i) - this->getChild(i)->print(o, Indent+1); - } -}; - -template -inline std::ostream &operator<<(std::ostream &o, - const InstTreeNode *N) { - N->print(o, 0); return o; -} - -//===----------------------------------------------------------------------===// -// Class InstForest -//===----------------------------------------------------------------------===// -// -// This class represents the instruction forest itself. It exposes iterators -// to an underlying vector of Instruction Trees. Each root of the tree is -// guaranteed to be an instruction node. The constructor builds the forest. -// -template -class InstForest : public std::vector *> { - friend class InstTreeNode; - - typedef typename std::vector *>::const_iterator const_iterator; - - // InstMap - Map contains entries for ALL instructions in the method and the - // InstTreeNode that they correspond to. - // - std::map *> InstMap; - - void addInstMapping(Instruction *I, InstTreeNode *IN) { - InstMap.insert(std::make_pair(I, IN)); - } - - void removeInstFromRootList(Instruction *I) { - for (unsigned i = this->size(); i > 0; --i) - if ((*this)[i-1]->getValue() == I) { - this->erase(this->begin()+i-1); - return; - } - } - -public: - // ctor - Create an instruction forest for the specified method... - InstForest(Function *F) { - for (Function::iterator BB = F->begin(), BBE = F->end(); BB != BBE; ++BB) - for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) - if (!getInstNode(I)) { // Do we already have a tree for this inst? - // No, create one! InstTreeNode ctor automatically adds the - // created node into our InstMap - push_back(new InstTreeNode(*this, I, 0)); - } - } - - // dtor - Free the trees... - ~InstForest() { - for (unsigned i = this->size(); i != 0; --i) - delete (*this)[i-1]; - } - - // getInstNode - Return the instruction node that corresponds to the specified - // instruction... This node may be embeded in a larger tree, in which case - // the parent pointer can be used to find the root of the tree. - // - inline InstTreeNode *getInstNode(Instruction *Inst) { - typename std::map *>::iterator I = - InstMap.find(Inst); - if (I != InstMap.end()) return I->second; - return 0; - } - inline const InstTreeNode *getInstNode(const Instruction *Inst)const{ - typename std::map*>::const_iterator I = - InstMap.find(Inst); - if (I != InstMap.end()) return I->second; - return 0; - } - - // print - Called by operator<< below... - void print(std::ostream &out) const { - for (const_iterator I = this->begin(), E = this->end(); I != E; ++I) - out << *I; - } -}; - -template -inline std::ostream &operator<<(std::ostream &o, const InstForest &IF){ - IF.print(o); return o; -} - - -//===----------------------------------------------------------------------===// -// Method Implementations -//===----------------------------------------------------------------------===// - -// CanMergeInstIntoTree - Return true if it is allowed to merge the specified -// instruction into 'this' instruction tree. This is allowed iff: -// 1. The instruction is in the same basic block as the current one -// 2. The instruction has only one use -// -template -bool InstTreeNode::CanMergeInstIntoTree(Instruction *I) { - if (!I->use_empty() && !I->hasOneUse()) return false; - return I->getParent() == cast(getValue())->getParent(); -} - - -// InstTreeNode ctor - This constructor creates the instruction tree for the -// specified value. If the value is an instruction, it recursively creates the -// internal/child nodes and adds them to the instruction forest. -// -template -InstTreeNode::InstTreeNode(InstForest &IF, Value *V, - InstTreeNode *Parent) : super(Parent) { - this->getTreeData().first.first = V; // Save tree node - - if (!isa(V)) { - assert(isa(V) || isa(V) || isa(V) && - "Unrecognized value type for InstForest Partition!"); - if (isa(V)) - if (isa(V)) - this->getTreeData().first.second = TemporaryNode; - else - this->getTreeData().first.second = ConstNode; - else if (isa(V)) - this->getTreeData().first.second = BasicBlockNode; - else - this->getTreeData().first.second = TemporaryNode; - - return; - } - - // Must be an instruction then... see if we can include it in this tree! - Instruction *I = cast(V); - if (Parent && !Parent->CanMergeInstIntoTree(I)) { - // Not root node of tree, but mult uses? - this->getTreeData().first.second = TemporaryNode; // Must be a temporary! - return; - } - - // Otherwise, we are an internal instruction node. We must process our - // uses and add them as children of this node. - // - std::vector Children; - - // Make sure that the forest knows about us! - IF.addInstMapping(I, this); - - // Walk the operands of the instruction adding children for all of the uses - // of the instruction... - // - for (Instruction::op_iterator OI = I->op_begin(); OI != I->op_end(); ++OI) { - Value *Operand = *OI; - InstTreeNode *IN = IF.getInstNode(dyn_cast(Operand)); - if (IN && CanMergeInstIntoTree(cast(Operand))) { - Children.push_back(IN); - IF.removeInstFromRootList(cast(Operand)); - } else { - // No node for this child yet... create one now! - Children.push_back(new InstTreeNode(IF, *OI, this)); - } - } - - setChildren(Children); - this->getTreeData().first.second = InstructionNode; -} - -} // End llvm namespace - -#endif -