diff options
Diffstat (limited to 'include/llvm/Instructions.h')
-rw-r--r-- | include/llvm/Instructions.h | 235 |
1 files changed, 158 insertions, 77 deletions
diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h index 52fa8d7f72..13ed8c1f6e 100644 --- a/include/llvm/Instructions.h +++ b/include/llvm/Instructions.h @@ -24,7 +24,6 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/Support/ErrorHandling.h" #include <iterator> -#include <limits.h> namespace llvm { @@ -2468,8 +2467,119 @@ class SwitchInst : public TerminatorInst { protected: virtual SwitchInst *clone_impl() const; public: + + static const unsigned DefaultPseudoIndex = ~0L-1; // -2 + + template <class SwitchInstTy, class ConstantIntTy, class BasicBlockTy> + class CaseIteratorT { + protected: + + SwitchInstTy *SI; + unsigned Index; + + public: + + typedef CaseIteratorT<SwitchInstTy, ConstantIntTy, BasicBlockTy> Self; + + /// Initializes case iterator for given SwitchInst and for given + /// case number. + CaseIteratorT(SwitchInstTy *SI, unsigned CaseNum) { + this->SI = SI; + Index = CaseNum; + } + + /// Initializes case iterator for given SwitchInst and for given + /// TerminatorInst's successor index. + static Self fromSuccessorIndex(SwitchInstTy *SI, unsigned SuccessorIndex) { + assert(SuccessorIndex < SI->getNumSuccessors() && + "Successor index # out of range!"); + return SuccessorIndex != 0 ? + Self(SI, SuccessorIndex - 1) : + Self(SI, DefaultPseudoIndex); + } + + /// Resolves case value for current case. + ConstantIntTy *getCaseValue() { + assert(Index < SI->getNumCases() && "Index out the number of cases."); + return reinterpret_cast<ConstantIntTy*>(SI->getOperand(2 + Index*2)); + } + + /// Resolves successor for current case. + BasicBlockTy *getCaseSuccessor() { + assert((Index < SI->getNumCases() || DefaultPseudoIndex) && + "Index out the number of cases."); + return SI->getSuccessor(getSuccessorIndex()); + } + + /// Returns number of current case. + unsigned getCaseIndex() const { return Index; } + + /// Returns TerminatorInst's successor index for current case successor. + unsigned getSuccessorIndex() const { + assert((Index == DefaultPseudoIndex || Index < SI->getNumCases()) && + "Index out the number of cases."); + return Index != DefaultPseudoIndex ? Index + 1 : 0; + } + + Self operator++() { + // Check index correctness after increment. + // Note: Index == getNumCases() means end(). + assert(Index+1 <= SI->getNumCases() && "Index out the number of cases."); + ++Index; + return *this; + } + Self operator++(int) { + Self tmp = *this; + ++(*this); + return tmp; + } + Self operator--() { + // Check index correctness after decrement. + // Note: Index == getNumCases() means end(). + // Also allow "-1" iterator here. That will became valid after ++. + assert((Index == 0 || Index-1 <= SI->getNumCases()) && + "Index out the number of cases."); + --Index; + return *this; + } + Self operator--(int) { + Self tmp = *this; + --(*this); + return tmp; + } + bool operator==(const Self& RHS) const { + assert(RHS.SI == SI && "Incompatible operators."); + return RHS.Index == Index; + } + bool operator!=(const Self& RHS) const { + assert(RHS.SI == SI && "Incompatible operators."); + return RHS.Index != Index; + } + }; + + typedef CaseIteratorT<const SwitchInst, const ConstantInt, const BasicBlock> + ConstCaseIt; - enum { ErrorIndex = UINT_MAX }; + class CaseIt : public CaseIteratorT<SwitchInst, ConstantInt, BasicBlock> { + + typedef CaseIteratorT<SwitchInst, ConstantInt, BasicBlock> ParentTy; + + public: + + CaseIt(const ParentTy& Src) : ParentTy(Src) {} + CaseIt(SwitchInst *SI, unsigned CaseNum) : ParentTy(SI, CaseNum) {} + + /// Sets the new value for current case. + void setValue(ConstantInt *V) { + assert(Index < SI->getNumCases() && "Index out the number of cases."); + SI->setOperand(2 + Index*2, reinterpret_cast<Value*>(V)); + } + + /// Sets the new successor for current case. + void setSuccessor(BasicBlock *S) { + SI->setSuccessor(getSuccessorIndex(), S); + } + }; static SwitchInst *Create(Value *Value, BasicBlock *Default, unsigned NumCases, Instruction *InsertBefore = 0) { @@ -2479,6 +2589,7 @@ public: unsigned NumCases, BasicBlock *InsertAtEnd) { return new SwitchInst(Value, Default, NumCases, InsertAtEnd); } + ~SwitchInst(); /// Provide fast operand accessors @@ -2502,64 +2613,64 @@ public: return getNumOperands()/2 - 1; } - /// getCaseValue - Return the specified case value. Note that case #0, means - /// first case, not a default case. - ConstantInt *getCaseValue(unsigned i) { - assert(i < getNumCases() && "Illegal case value to get!"); - return reinterpret_cast<ConstantInt*>(getOperand(2 + i*2)); + /// Returns a read/write iterator that points to the first + /// case in SwitchInst. + CaseIt caseBegin() { + return CaseIt(this, 0); } - - /// getCaseValue - Return the specified case value. Note that case #0, means - /// first case, not a default case. - const ConstantInt *getCaseValue(unsigned i) const { - assert(i < getNumCases() && "Illegal case value to get!"); - return reinterpret_cast<const ConstantInt*>(getOperand(2 + i*2)); + /// Returns a read-only iterator that points to the first + /// case in the SwitchInst. + ConstCaseIt caseBegin() const { + return ConstCaseIt(this, 0); } - - // setSuccessorValue - Updates the value associated with the specified - // case. - void setCaseValue(unsigned i, ConstantInt *CaseValue) { - assert(i < getNumCases() && "Case index # out of range!"); - setOperand(2 + i*2, reinterpret_cast<Value*>(CaseValue)); + + /// Returns a read/write iterator that points one past the last + /// in the SwitchInst. + CaseIt caseEnd() { + return CaseIt(this, getNumCases()); } - - /// findCaseValue - Search all of the case values for the specified constant. - /// If it is explicitly handled, return the case number of it, otherwise - /// return ErrorIndex to indicate that it is handled by the default handler. - unsigned findCaseValue(const ConstantInt *C) const { - for (unsigned i = 0, e = getNumCases(); i != e; ++i) - if (getCaseValue(i) == C) - return i; - return ErrorIndex; + /// Returns a read-only iterator that points one past the last + /// in the SwitchInst. + ConstCaseIt caseEnd() const { + return ConstCaseIt(this, getNumCases()); } - - /// resolveSuccessorIndex - Converts case index to index of its successor - /// index in TerminatorInst successors collection. - /// If CaseIndex == ErrorIndex, "default" successor will returned then. - unsigned resolveSuccessorIndex(unsigned CaseIndex) const { - assert((CaseIndex == ErrorIndex || CaseIndex < getNumCases()) && - "Case index # out of range!"); - return CaseIndex != ErrorIndex ? CaseIndex + 1 : 0; + /// Returns an iterator that points to default case. + /// Note: this iterator allows to resolve successor only. Attempt + /// to resolve case value causes an assertion. + CaseIt caseDefault() { + return CaseIt(this, DefaultPseudoIndex); + } + ConstCaseIt caseDefault() const { + return ConstCaseIt(this, DefaultPseudoIndex); } - /// resolveCaseIndex - Converts index of successor in TerminatorInst - /// collection to index of case that corresponds to this successor. - unsigned resolveCaseIndex(unsigned SuccessorIndex) const { - assert(SuccessorIndex < getNumSuccessors() && - "Successor index # out of range!"); - return SuccessorIndex != 0 ? SuccessorIndex - 1 : ErrorIndex; + /// findCaseValue - Search all of the case values for the specified constant. + /// If it is explicitly handled, return the case iterator of it, otherwise + /// return default case iterator to indicate + /// that it is handled by the default handler. + CaseIt findCaseValue(const ConstantInt *C) { + for (CaseIt i = caseBegin(), e = caseEnd(); i != e; ++i) + if (i.getCaseValue() == C) + return i; + return caseDefault(); } - + ConstCaseIt findCaseValue(const ConstantInt *C) const { + for (ConstCaseIt i = caseBegin(), e = caseEnd(); i != e; ++i) + if (i.getCaseValue() == C) + return i; + return caseDefault(); + } + /// findCaseDest - Finds the unique case value for a given successor. Returns /// null if the successor is not found, not unique, or is the default case. ConstantInt *findCaseDest(BasicBlock *BB) { if (BB == getDefaultDest()) return NULL; ConstantInt *CI = NULL; - for (unsigned i = 0, e = getNumCases(); i != e; ++i) { - if (getSuccessor(i + 1) == BB) { + for (CaseIt i = caseBegin(), e = caseEnd(); i != e; ++i) { + if (i.getCaseSuccessor() == BB) { if (CI) return NULL; // Multiple cases lead to BB. - else CI = getCaseValue(i); + else CI = i.getCaseValue(); } } return CI; @@ -2573,7 +2684,7 @@ public: /// from the switch instruction. Note that this operation may reorder the /// remaining cases at index idx and above. /// - void removeCase(unsigned idx); + void removeCase(CaseIt i); unsigned getNumSuccessors() const { return getNumOperands()/2; } BasicBlock *getSuccessor(unsigned idx) const { @@ -2585,36 +2696,6 @@ public: setOperand(idx*2+1, (Value*)NewSucc); } - /// Resolves successor for idx-th case. - /// Use getCaseSuccessor instead of TerminatorInst::getSuccessor, - /// since internal SwitchInst organization of operands/successors is - /// hidden and may be changed in any moment. - BasicBlock *getCaseSuccessor(unsigned idx) const { - return getSuccessor(resolveSuccessorIndex(idx)); - } - - /// Set new successor for idx-th case. - /// Use setCaseSuccessor instead of TerminatorInst::setSuccessor, - /// since internal SwitchInst organization of operands/successors is - /// hidden and may be changed in any moment. - void setCaseSuccessor(unsigned idx, BasicBlock *NewSucc) { - setSuccessor(resolveSuccessorIndex(idx), NewSucc); - } - - // getSuccessorValue - Return the value associated with the specified - // successor. - ConstantInt *getSuccessorValue(unsigned idx) const { - assert(idx < getNumSuccessors() && "Successor # out of range!"); - return reinterpret_cast<ConstantInt*>(getOperand(idx*2)); - } - - // setSuccessorValue - Updates the value associated with the specified - // successor. - void setSuccessorValue(unsigned idx, ConstantInt* SuccessorValue) { - assert(idx < getNumSuccessors() && "Successor # out of range!"); - setOperand(idx*2, reinterpret_cast<Value*>(SuccessorValue)); - } - // Methods for support type inquiry through isa, cast, and dyn_cast: static inline bool classof(const SwitchInst *) { return true; } static inline bool classof(const Instruction *I) { |