+
+ uint16_t hash() const {
+ uint32_t NumberOfCases = (uint32_t)getNumCases();
+ uint16_t Hash = (0xFFFF & NumberOfCases) ^ (NumberOfCases >> 16);
+ for (ConstCaseIt i = case_begin(), e = case_end();
+ i != e; ++i) {
+ uint32_t NumItems = (uint32_t)i.getCaseValueEx().getNumItems();
+ Hash = (Hash << 1) ^ (0xFFFF & NumItems) ^ (NumItems >> 16);
+ }
+ return Hash;
+ }
+
+ // Case iterators definition.
+
+ template <class SwitchInstTy, class ConstantIntTy,
+ class SubsetsItTy, class BasicBlockTy>
+ class CaseIteratorT {
+ protected:
+
+ SwitchInstTy *SI;
+ unsigned long Index;
+ SubsetsItTy SubsetIt;
+
+ /// Initializes case iterator for given SwitchInst and for given
+ /// case number.
+ friend class SwitchInst;
+ CaseIteratorT(SwitchInstTy *SI, unsigned SuccessorIndex,
+ SubsetsItTy CaseValueIt) {
+ this->SI = SI;
+ Index = SuccessorIndex;
+ this->SubsetIt = CaseValueIt;
+ }
+
+ public:
+ typedef typename SubsetsItTy::reference IntegersSubsetRef;
+ typedef CaseIteratorT<SwitchInstTy, ConstantIntTy,
+ SubsetsItTy, BasicBlockTy> Self;
+
+ CaseIteratorT(SwitchInstTy *SI, unsigned CaseNum) {
+ this->SI = SI;
+ Index = CaseNum;
+ SubsetIt = SI->TheSubsets.begin();
+ std::advance(SubsetIt, 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.
+ /// @deprecated
+ ConstantIntTy *getCaseValue() {
+ assert(Index < SI->getNumCases() && "Index out the number of cases.");
+ IntegersSubsetRef CaseRanges = *SubsetIt;
+
+ // FIXME: Currently we work with ConstantInt based cases.
+ // So return CaseValue as ConstantInt.
+ return CaseRanges.getSingleNumber(0).toConstantInt();
+ }
+
+ /// Resolves case value for current case.
+ IntegersSubsetRef getCaseValueEx() {
+ assert(Index < SI->getNumCases() && "Index out the number of cases.");
+ return *SubsetIt;
+ }
+
+ /// Resolves successor for current case.
+ BasicBlockTy *getCaseSuccessor() {
+ assert((Index < SI->getNumCases() ||
+ Index == 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;
+ if (Index == 0)
+ SubsetIt = SI->TheSubsets.begin();
+ else
+ ++SubsetIt;
+ 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 ++.
+ unsigned NumCases = SI->getNumCases();
+ assert((Index == 0 || Index-1 <= NumCases) &&
+ "Index out the number of cases.");
+ --Index;
+ if (Index == NumCases) {
+ SubsetIt = SI->TheSubsets.end();
+ return *this;
+ }
+
+ if (Index != -1UL)
+ --SubsetIt;
+
+ 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;
+ }
+ };
+
+ class CaseIt : public CaseIteratorT<SwitchInst, ConstantInt,
+ SubsetsIt, BasicBlock> {
+ typedef CaseIteratorT<SwitchInst, ConstantInt, SubsetsIt, BasicBlock>
+ ParentTy;
+
+ protected:
+ friend class SwitchInst;
+ CaseIt(SwitchInst *SI, unsigned CaseNum, SubsetsIt SubsetIt) :
+ ParentTy(SI, CaseNum, SubsetIt) {}
+
+ void updateCaseValueOperand(IntegersSubset& V) {
+ SI->setOperand(2 + Index*2, reinterpret_cast<Value*>((Constant*)V));
+ }
+
+ public:
+
+ CaseIt(SwitchInst *SI, unsigned CaseNum) : ParentTy(SI, CaseNum) {}
+
+ CaseIt(const ParentTy& Src) : ParentTy(Src) {}
+
+ /// Sets the new value for current case.
+ /// @deprecated.
+ void setValue(ConstantInt *V) {
+ assert(Index < SI->getNumCases() && "Index out the number of cases.");
+ IntegersSubsetToBB Mapping;
+ // FIXME: Currently we work with ConstantInt based cases.
+ // So inititalize IntItem container directly from ConstantInt.
+ Mapping.add(IntItem::fromConstantInt(V));
+ *SubsetIt = Mapping.getCase();
+ updateCaseValueOperand(*SubsetIt);
+ }
+
+ /// Sets the new value for current case.
+ void setValueEx(IntegersSubset& V) {
+ assert(Index < SI->getNumCases() && "Index out the number of cases.");
+ *SubsetIt = V;
+ updateCaseValueOperand(*SubsetIt);
+ }
+
+ /// Sets the new successor for current case.
+ void setSuccessor(BasicBlock *S) {
+ SI->setSuccessor(getSuccessorIndex(), S);
+ }
+ };