static const unsigned DefaultPseudoIndex = static_cast<unsigned>(~0L-1);
template <class SwitchInstTy, class ConstantIntTy, class BasicBlockTy>
- class CaseIteratorT {
+ class CaseIteratorT
+ : public iterator_facade_base<
+ CaseIteratorT<SwitchInstTy, ConstantIntTy, BasicBlockTy>,
+ std::random_access_iterator_tag,
+ CaseIteratorT<SwitchInstTy, ConstantIntTy, BasicBlockTy>> {
protected:
SwitchInstTy *SI;
- unsigned Index;
+ ptrdiff_t Index;
public:
typedef CaseIteratorT<SwitchInstTy, ConstantIntTy, BasicBlockTy> Self;
+ /// Default constructed iterator is in an invalid state until assigned to
+ /// a case for a particular switch.
+ CaseIteratorT() : SI(nullptr) {}
+
/// Initializes case iterator for given SwitchInst and for given
/// case number.
CaseIteratorT(SwitchInstTy *SI, unsigned CaseNum) {
return Index != DefaultPseudoIndex ? Index + 1 : 0;
}
- Self operator++() {
- // Check index correctness after increment.
+ Self &operator+=(ptrdiff_t N) {
+ // Check index correctness after addition.
// Note: Index == getNumCases() means end().
- assert(Index+1 <= SI->getNumCases() && "Index out the number of cases.");
- ++Index;
+ assert(Index + N >= 0 && Index + N <= SI->getNumCases() &&
+ "Index out the number of cases.");
+ Index += N;
return *this;
}
- Self operator++(int) {
- Self tmp = *this;
- ++(*this);
- return tmp;
- }
- Self operator--() {
- // Check index correctness after decrement.
+ Self &operator-=(ptrdiff_t N) {
+ // Check index correctness after subtraction.
// Note: Index == getNumCases() means end().
- // Also allow "-1" iterator here. That will became valid after ++.
- assert((Index == 0 || Index-1 <= SI->getNumCases()) &&
+ assert(Index - N >= 0 && Index - N <= SI->getNumCases() &&
"Index out the number of cases.");
- --Index;
+ Index -= N;
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;
+ assert(SI == RHS.SI && "Incompatible operators.");
+ return Index == RHS.Index;
}
- Self &operator*() {
- return *this;
+ bool operator<(const Self& RHS) const {
+ assert(SI == RHS.SI && "Incompatible operators.");
+ return Index < RHS.Index;
}
+ Self &operator*() { return *this; }
+ const Self &operator*() const { return *this; }
};
typedef CaseIteratorT<const SwitchInst, const ConstantInt, const BasicBlock>
/// index idx and above.
/// Note:
/// This action invalidates iterators for all cases following the one removed,
- /// including the case_end() iterator.
- void removeCase(CaseIt i);
+ /// including the case_end() iterator. It returns an iterator for the next
+ /// case.
+ CaseIt removeCase(CaseIt i);
unsigned getNumSuccessors() const { return getNumOperands()/2; }
BasicBlock *getSuccessor(unsigned idx) const {
/// removeCase - This method removes the specified case and its successor
/// from the switch instruction.
-void SwitchInst::removeCase(CaseIt i) {
+SwitchInst::CaseIt SwitchInst::removeCase(CaseIt i) {
unsigned idx = i.getCaseIndex();
assert(2 + idx*2 < getNumOperands() && "Case index out of range!!!");
OL[NumOps-2].set(nullptr);
OL[NumOps-2+1].set(nullptr);
setNumHungOffUseOperands(NumOps-2);
+
+ return CaseIt(this, idx);
}
/// growOperands - grow operands - This grows the operand list in response
// Analyse each switch case in turn. This is done in reverse order so that
// removing a case doesn't cause trouble for the iteration.
bool Changed = false;
- for (SwitchInst::CaseIt CI = SI->case_end(), CE = SI->case_begin(); CI-- != CE;
- ) {
+ for (auto CI = SI->case_begin(), CE = SI->case_end(); CI != CE;) {
ConstantInt *Case = CI.getCaseValue();
// Check to see if the switch condition is equal to/not equal to the case
if (State == LazyValueInfo::False) {
// This case never fires - remove it.
CI.getCaseSuccessor()->removePredecessor(BB);
- SI->removeCase(CI); // Does not invalidate the iterator.
+ CI = SI->removeCase(CI);
+ CE = SI->case_end();
// The condition can be modified by removePredecessor's PHI simplification
// logic.
++NumDeadCases;
Changed = true;
- } else if (State == LazyValueInfo::True) {
+ continue;
+ }
+ if (State == LazyValueInfo::True) {
// This case always fires. Arrange for the switch to be turned into an
// unconditional branch by replacing the switch condition with the case
// value.
Changed = true;
break;
}
+
+ // Increment the case iterator sense we didn't delete it.
+ ++CI;
}
if (Changed)
}
// Figure out which case it goes to.
- for (SwitchInst::CaseIt i = SI->case_begin(), e = SI->case_end();
- i != e; ++i) {
+ for (auto i = SI->case_begin(), e = SI->case_end(); i != e;) {
// Found case matching a constant operand?
if (i.getCaseValue() == CI) {
TheOnlyDest = i.getCaseSuccessor();
}
// Remove this entry.
DefaultDest->removePredecessor(SI->getParent());
- SI->removeCase(i);
- --i; --e;
+ i = SI->removeCase(i);
+ e = SI->case_end();
continue;
}
// We do this by reseting "TheOnlyDest" to null when we find two non-equal
// destinations.
if (i.getCaseSuccessor() != TheOnlyDest) TheOnlyDest = nullptr;
+
+ // Increment this iterator as we haven't removed the case.
+ ++i;
}
if (CI && !TheOnlyDest) {
}
}
} else if (auto *SI = dyn_cast<SwitchInst>(TI)) {
- for (SwitchInst::CaseIt i = SI->case_begin(), e = SI->case_end(); i != e;
- ++i)
- if (i.getCaseSuccessor() == BB) {
- BB->removePredecessor(SI->getParent());
- SI->removeCase(i);
- --i;
- --e;
- Changed = true;
+ for (auto i = SI->case_begin(), e = SI->case_end(); i != e;) {
+ if (i.getCaseSuccessor() != BB) {
+ ++i;
+ continue;
}
+ BB->removePredecessor(SI->getParent());
+ i = SI->removeCase(i);
+ e = SI->case_end();
+ Changed = true;
+ }
} else if (auto *II = dyn_cast<InvokeInst>(TI)) {
if (II->getUnwindDest() == BB) {
removeUnwindEdge(TI->getParent());