diff options
Diffstat (limited to 'include/llvm/BasicBlock.h')
-rw-r--r-- | include/llvm/BasicBlock.h | 246 |
1 files changed, 246 insertions, 0 deletions
diff --git a/include/llvm/BasicBlock.h b/include/llvm/BasicBlock.h new file mode 100644 index 0000000000..6873ef2deb --- /dev/null +++ b/include/llvm/BasicBlock.h @@ -0,0 +1,246 @@ +//===-- llvm/BasicBlock.h - Represent a basic block in the VM ----*- C++ -*--=// +// +// This file contains the declaration of the BasicBlock class, which represents +// a single basic block in the VM. +// +// Note that basic blocks themselves are Def's, because they are referenced +// by instructions like branches and can go in switch tables and stuff... +// +// This may see wierd at first, but it's really pretty cool. :) +// +//===----------------------------------------------------------------------===// +// +// Note that well formed basic blocks are formed of a list of instructions +// followed by a single TerminatorInst instruction. TerminatorInst's may not +// occur in the middle of basic blocks, and must terminate the blocks. +// +// This code allows malformed basic blocks to occur, because it may be useful +// in the intermediate stage of analysis or modification of a program. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_BASICBLOCK_H +#define LLVM_BASICBLOCK_H + +#include "llvm/Value.h" // Get the definition of Value +#include "llvm/ValueHolder.h" +#include "llvm/InstrTypes.h" +#include <list> + +class Instruction; +class Method; +class BasicBlock; +class TerminatorInst; + +typedef UseTy<BasicBlock> BasicBlockUse; + +class BasicBlock : public Value { // Basic blocks are data objects also +public: + typedef ValueHolder<Instruction, BasicBlock> InstListType; +private : + InstListType InstList; + + friend class ValueHolder<BasicBlock,Method>; + void setParent(Method *parent); + +public: + BasicBlock(const string &Name = "", Method *Parent = 0); + ~BasicBlock(); + + // Specialize setName to take care of symbol table majik + virtual void setName(const string &name); + + const Method *getParent() const { return (const Method*)InstList.getParent();} + Method *getParent() { return (Method*)InstList.getParent(); } + + const InstListType &getInstList() const { return InstList; } + InstListType &getInstList() { return InstList; } + + // getTerminator() - If this is a well formed basic block, then this returns + // a pointer to the terminator instruction. If it is not, then you get a null + // pointer back. + // + TerminatorInst *getTerminator(); + const TerminatorInst *const getTerminator() const; + + // hasConstantPoolReferences() - This predicate is true if there is a + // reference to this basic block in the constant pool for this method. For + // example, if a block is reached through a switch table, that table resides + // in the constant pool, and the basic block is reference from it. + // + bool hasConstantPoolReferences() const; + + // dropAllReferences() - This function causes all the subinstructions to "let + // go" of all references that they are maintaining. This allows one to + // 'delete' a whole class at a time, even though there may be circular + // references... first all references are dropped, and all use counts go to + // zero. Then everything is delete'd for real. Note that no operations are + // valid on an object that has "dropped all references", except operator + // delete. + // + void dropAllReferences(); + + // splitBasicBlock - This splits a basic block into two at the specified + // instruction. Note that all instructions BEFORE the specified iterator stay + // as part of the original basic block, an unconditional branch is added to + // the new BB, and the rest of the instructions in the BB are moved to the new + // BB, including the old terminator. The newly formed BasicBlock is returned. + // This function invalidates the specified iterator. + // + // Note that this only works on well formed basic blocks (must have a + // terminator), and 'I' must not be the end of instruction list (which would + // cause a degenerate basic block to be formed, having a terminator inside of + // the basic block). + // + BasicBlock *splitBasicBlock(InstListType::iterator I); + + //===--------------------------------------------------------------------===// + // Predecessor iterator code + //===--------------------------------------------------------------------===// + // + // This is used to figure out what basic blocks we could be coming from. + // + + // Forward declare iterator class template... + template <class _Ptr, class _USE_iterator> class PredIterator; + + typedef PredIterator<BasicBlock*, use_iterator> pred_iterator; + typedef PredIterator<const BasicBlock*, + use_const_iterator> pred_const_iterator; + + inline pred_iterator pred_begin() ; + inline pred_const_iterator pred_begin() const; + inline pred_iterator pred_end() ; + inline pred_const_iterator pred_end() const; + + //===--------------------------------------------------------------------===// + // Successor iterator code + //===--------------------------------------------------------------------===// + // + // This is used to figure out what basic blocks we could be going to... + // + + // Forward declare iterator class template... + template <class _Term, class _BB> class SuccIterator; + + typedef SuccIterator<TerminatorInst*, BasicBlock*> succ_iterator; + typedef SuccIterator<const TerminatorInst*, + const BasicBlock*> succ_const_iterator; + + inline succ_iterator succ_begin() ; + inline succ_const_iterator succ_begin() const; + inline succ_iterator succ_end() ; + inline succ_const_iterator succ_end() const; + + //===--------------------------------------------------------------------===// + // END of interesting code... + //===--------------------------------------------------------------------===// + // + // Thank god C++ compilers are good at stomping out tons of templated code... + // + template <class _Ptr, class _USE_iterator> // Predecessor Iterator + class PredIterator { + const _Ptr ThisBB; + _USE_iterator It; + public: + typedef PredIterator<_Ptr,_USE_iterator> _Self; + + typedef bidirectional_iterator_tag iterator_category; + typedef _Ptr pointer; + + inline PredIterator(_Ptr BB) : ThisBB(BB), It(BB->use_begin()) {} + inline PredIterator(_Ptr BB, bool) : ThisBB(BB), It(BB->use_end()) {} + + inline bool operator==(const _Self& x) const { return It == x.It; } + inline bool operator!=(const _Self& x) const { return !operator==(x); } + + inline pointer operator*() const { + assert ((*It)->getValueType() == Value::InstructionVal); + return ((Instruction *)(*It))->getParent(); + } + inline pointer *operator->() const { return &(operator*()); } + + inline _Self& operator++() { // Preincrement + do { // Loop to ignore constant pool references + ++It; + } while (It != ThisBB->use_end() && + ((*It)->getValueType() != Value::ConstantVal)); + + // DOES THIS WORK??? + //((*It)->getValueType() != Value::BasicBlockVal)); + return *this; + } + + inline _Self operator++(int) { // Postincrement + _Self tmp = *this; ++*this; return tmp; + } + + inline _Self& operator--() { --It; return *this; } // Predecrement + inline _Self operator--(int) { // Postdecrement + _Self tmp = *this; --*this; return tmp; + } + }; + + template <class _Term, class _BB> // Successor Iterator + class SuccIterator { + const _Term Term; + unsigned idx; + public: + typedef SuccIterator<_Term, _BB> _Self; + typedef forward_iterator_tag iterator_category; + typedef _BB pointer; + + inline SuccIterator(_Term T) : Term(T), idx(0) {} // begin iterator + inline SuccIterator(_Term T, bool) + : Term(T), idx(Term->getNumSuccessors()) {} // end iterator + + inline bool operator==(const _Self& x) const { return idx == x.idx; } + inline bool operator!=(const _Self& x) const { return !operator==(x); } + + inline pointer operator*() const { return Term->getSuccessor(idx); } + inline pointer *operator->() const { return &(operator*()); } + + inline _Self& operator++() { ++idx; return *this; } // Preincrement + inline _Self operator++(int) { // Postincrement + _Self tmp = *this; ++*this; return tmp; + } + + inline _Self& operator--() { --idx; return *this; } // Predecrement + inline _Self operator--(int) { // Postdecrement + _Self tmp = *this; --*this; return tmp; + } + }; +}; + + +//===--------------------------------------------------------------------===// +// Implement some stuff prototyped above... +//===--------------------------------------------------------------------===// + +inline BasicBlock::pred_iterator BasicBlock::pred_begin() { + return pred_iterator(this); +} +inline BasicBlock::pred_const_iterator BasicBlock::pred_begin() const { + return pred_const_iterator(this); +} +inline BasicBlock::pred_iterator BasicBlock::pred_end() { + return pred_iterator(this,true); +} +inline BasicBlock::pred_const_iterator BasicBlock::pred_end() const { + return pred_const_iterator(this,true); +} + +inline BasicBlock::succ_iterator BasicBlock::succ_begin() { + return succ_iterator(getTerminator()); +} +inline BasicBlock::succ_const_iterator BasicBlock::succ_begin() const { + return succ_const_iterator(getTerminator()); +} +inline BasicBlock::succ_iterator BasicBlock::succ_end() { + return succ_iterator(getTerminator(),true); +} +inline BasicBlock::succ_const_iterator BasicBlock::succ_end() const { + return succ_const_iterator(getTerminator(),true); +} + +#endif |