aboutsummaryrefslogtreecommitdiffstats
path: root/include/llvm/Instructions.h
diff options
context:
space:
mode:
authorStepan Dyatkovskiy <stpworld@narod.ru>2012-03-08 07:06:20 +0000
committerStepan Dyatkovskiy <stpworld@narod.ru>2012-03-08 07:06:20 +0000
commitc10fa6c801e48771b5eade50afc2fe6abaf08227 (patch)
treeddccc8333a4f1bb205f99748a030ac34fd171f54 /include/llvm/Instructions.h
parent88d2fa438a5b9feb7da77e4beeaa00944ae4168e (diff)
downloadexternal_llvm-c10fa6c801e48771b5eade50afc2fe6abaf08227.zip
external_llvm-c10fa6c801e48771b5eade50afc2fe6abaf08227.tar.gz
external_llvm-c10fa6c801e48771b5eade50afc2fe6abaf08227.tar.bz2
Taken into account Duncan's comments for r149481 dated by 2nd Feb 2012:
http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20120130/136146.html Implemented CaseIterator and it solves almost all described issues: we don't need to mix operand/case/successor indexing anymore. Base iterator class is implemented as a template since it may be initialized either from "const SwitchInst*" or from "SwitchInst*". ConstCaseIt is just a read-only iterator. CaseIt is read-write iterator; it allows to change case successor and case value. Usage of iterator allows totally remove resolveXXXX methods. All indexing convertions done automatically inside the iterator's getters. Main way of iterator usage looks like this: SwitchInst *SI = ... // intialize it somehow for (SwitchInst::CaseIt i = SI->caseBegin(), e = SI->caseEnd(); i != e; ++i) { BasicBlock *BB = i.getCaseSuccessor(); ConstantInt *V = i.getCaseValue(); // Do something. } If you want to convert case number to TerminatorInst successor index, just use getSuccessorIndex iterator's method. If you want initialize iterator from TerminatorInst successor index, use CaseIt::fromSuccessorIndex(...) method. There are also related changes in llvm-clients: klee and clang. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@152297 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/llvm/Instructions.h')
-rw-r--r--include/llvm/Instructions.h235
1 files changed, 158 insertions, 77 deletions
diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h
index 52fa8d7..13ed8c1 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) {