summaryrefslogtreecommitdiffstats
path: root/llvm/include
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/include')
-rw-r--r--llvm/include/llvm/ADT/iterator.h6
-rw-r--r--llvm/include/llvm/Analysis/CFGPrinter.h3
-rw-r--r--llvm/include/llvm/IR/Instructions.h191
3 files changed, 125 insertions, 75 deletions
diff --git a/llvm/include/llvm/ADT/iterator.h b/llvm/include/llvm/ADT/iterator.h
index 8f162da1b54..28dcdf9613e 100644
--- a/llvm/include/llvm/ADT/iterator.h
+++ b/llvm/include/llvm/ADT/iterator.h
@@ -165,9 +165,15 @@ public:
return !static_cast<const DerivedT *>(this)->operator<(RHS);
}
+ PointerT operator->() { return &static_cast<DerivedT *>(this)->operator*(); }
PointerT operator->() const {
return &static_cast<const DerivedT *>(this)->operator*();
}
+ ReferenceProxy operator[](DifferenceTypeT n) {
+ static_assert(IsRandomAccess,
+ "Subscripting is only defined for random access iterators.");
+ return ReferenceProxy(static_cast<DerivedT *>(this)->operator+(n));
+ }
ReferenceProxy operator[](DifferenceTypeT n) const {
static_assert(IsRandomAccess,
"Subscripting is only defined for random access iterators.");
diff --git a/llvm/include/llvm/Analysis/CFGPrinter.h b/llvm/include/llvm/Analysis/CFGPrinter.h
index efaa9d6df8e..5786769cc50 100644
--- a/llvm/include/llvm/Analysis/CFGPrinter.h
+++ b/llvm/include/llvm/Analysis/CFGPrinter.h
@@ -140,8 +140,7 @@ struct DOTGraphTraits<const Function*> : public DefaultDOTGraphTraits {
std::string Str;
raw_string_ostream OS(Str);
- SwitchInst::ConstCaseIt Case =
- SwitchInst::ConstCaseIt::fromSuccessorIndex(SI, SuccNo);
+ auto Case = *SwitchInst::ConstCaseIt::fromSuccessorIndex(SI, SuccNo);
OS << Case.getCaseValue()->getValue();
return OS.str();
}
diff --git a/llvm/include/llvm/IR/Instructions.h b/llvm/include/llvm/IR/Instructions.h
index 2a55048c133..dbbe6eed114 100644
--- a/llvm/include/llvm/IR/Instructions.h
+++ b/llvm/include/llvm/IR/Instructions.h
@@ -3096,49 +3096,39 @@ public:
// -2
static const unsigned DefaultPseudoIndex = static_cast<unsigned>(~0L-1);
- template <class SwitchInstT, class ConstantIntT, class BasicBlockT>
- class CaseIteratorT
- : public iterator_facade_base<
- CaseIteratorT<SwitchInstT, ConstantIntT, BasicBlockT>,
- std::random_access_iterator_tag,
- CaseIteratorT<SwitchInstT, ConstantIntT, BasicBlockT>> {
+ template <typename CaseHandleT> class CaseIteratorT;
+
+ /// A handle to a particular switch case. It exposes a convenient interface
+ /// to both the case value and the successor block.
+ ///
+ /// We define this as a template and instantiate it to form both a const and
+ /// non-const handle.
+ template <typename SwitchInstT, typename ConstantIntT, typename BasicBlockT>
+ class CaseHandleT {
+ // Directly befriend both const and non-const iterators.
+ friend class SwitchInst::CaseIteratorT<
+ CaseHandleT<SwitchInstT, ConstantIntT, BasicBlockT>>;
+
protected:
+ // Expose the switch type we're parameterized with to the iterator.
+ typedef SwitchInstT SwitchInstType;
+
SwitchInstT *SI;
ptrdiff_t Index;
- public:
- typedef CaseIteratorT<SwitchInstT, ConstantIntT, BasicBlockT> 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(SwitchInstT *SI, unsigned CaseNum) {
- this->SI = SI;
- Index = CaseNum;
- }
-
- /// Initializes case iterator for given SwitchInst and for given
- /// TerminatorInst's successor index.
- static Self fromSuccessorIndex(SwitchInstT *SI, unsigned SuccessorIndex) {
- assert(SuccessorIndex < SI->getNumSuccessors() &&
- "Successor index # out of range!");
- return SuccessorIndex != 0 ?
- Self(SI, SuccessorIndex - 1) :
- Self(SI, DefaultPseudoIndex);
- }
+ CaseHandleT() = default;
+ CaseHandleT(SwitchInstT *SI, ptrdiff_t Index) : SI(SI), Index(Index) {}
+ public:
/// Resolves case value for current case.
- ConstantIntT *getCaseValue() {
+ ConstantIntT *getCaseValue() const {
assert((unsigned)Index < SI->getNumCases() &&
"Index out the number of cases.");
return reinterpret_cast<ConstantIntT *>(SI->getOperand(2 + Index * 2));
}
/// Resolves successor for current case.
- BasicBlockT *getCaseSuccessor() {
+ BasicBlockT *getCaseSuccessor() const {
assert(((unsigned)Index < SI->getNumCases() ||
(unsigned)Index == DefaultPseudoIndex) &&
"Index out the number of cases.");
@@ -3156,43 +3146,20 @@ public:
return (unsigned)Index != DefaultPseudoIndex ? Index + 1 : 0;
}
- Self &operator+=(ptrdiff_t N) {
- // Check index correctness after addition.
- // Note: Index == getNumCases() means end().
- assert(Index + N >= 0 && (unsigned)(Index + N) <= SI->getNumCases() &&
- "Index out the number of cases.");
- Index += N;
- return *this;
- }
- Self &operator-=(ptrdiff_t N) {
- // Check index correctness after subtraction.
- // Note: Index == getNumCases() means end().
- assert(Index - N >= 0 && (unsigned)(Index - N) <= SI->getNumCases() &&
- "Index out the number of cases.");
- Index -= N;
- return *this;
- }
- bool operator==(const Self& RHS) const {
+ bool operator==(const CaseHandleT &RHS) const {
assert(SI == RHS.SI && "Incompatible operators.");
return Index == RHS.Index;
}
- 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>
- ConstCaseIt;
+ typedef CaseHandleT<const SwitchInst, const ConstantInt, const BasicBlock>
+ ConstCaseHandle;
- class CaseIt : public CaseIteratorT<SwitchInst, ConstantInt, BasicBlock> {
- typedef CaseIteratorT<SwitchInst, ConstantInt, BasicBlock> ParentTy;
+ class CaseHandle : public CaseHandleT<SwitchInst, ConstantInt, BasicBlock> {
+ friend class SwitchInst::CaseIteratorT<CaseHandle>;
public:
- CaseIt(const ParentTy &Src) : ParentTy(Src) {}
- CaseIt(SwitchInst *SI, unsigned CaseNum) : ParentTy(SI, CaseNum) {}
+ CaseHandle(SwitchInst *SI, ptrdiff_t Index) : CaseHandleT(SI, Index) {}
/// Sets the new value for current case.
void setValue(ConstantInt *V) {
@@ -3207,6 +3174,74 @@ public:
}
};
+ template <typename CaseHandleT>
+ class CaseIteratorT
+ : public iterator_facade_base<CaseIteratorT<CaseHandleT>,
+ std::random_access_iterator_tag,
+ CaseHandleT> {
+ typedef typename CaseHandleT::SwitchInstType SwitchInstT;
+
+ CaseHandleT Case;
+
+ public:
+ /// Default constructed iterator is in an invalid state until assigned to
+ /// a case for a particular switch.
+ CaseIteratorT() = default;
+
+ /// Initializes case iterator for given SwitchInst and for given
+ /// case number.
+ CaseIteratorT(SwitchInstT *SI, unsigned CaseNum) : Case(SI, CaseNum) {}
+
+ /// Initializes case iterator for given SwitchInst and for given
+ /// TerminatorInst's successor index.
+ static CaseIteratorT fromSuccessorIndex(SwitchInstT *SI,
+ unsigned SuccessorIndex) {
+ assert(SuccessorIndex < SI->getNumSuccessors() &&
+ "Successor index # out of range!");
+ return SuccessorIndex != 0 ? CaseIteratorT(SI, SuccessorIndex - 1)
+ : CaseIteratorT(SI, DefaultPseudoIndex);
+ }
+
+ /// Support converting to the const variant. This will be a no-op for const
+ /// variant.
+ operator CaseIteratorT<ConstCaseHandle>() const {
+ return CaseIteratorT<ConstCaseHandle>(Case.SI, Case.Index);
+ }
+
+ CaseIteratorT &operator+=(ptrdiff_t N) {
+ // Check index correctness after addition.
+ // Note: Index == getNumCases() means end().
+ assert(Case.Index + N >= 0 &&
+ (unsigned)(Case.Index + N) <= Case.SI->getNumCases() &&
+ "Case.Index out the number of cases.");
+ Case.Index += N;
+ return *this;
+ }
+ CaseIteratorT &operator-=(ptrdiff_t N) {
+ // Check index correctness after subtraction.
+ // Note: Case.Index == getNumCases() means end().
+ assert(Case.Index - N >= 0 &&
+ (unsigned)(Case.Index - N) <= Case.SI->getNumCases() &&
+ "Case.Index out the number of cases.");
+ Case.Index -= N;
+ return *this;
+ }
+ ptrdiff_t operator-(const CaseIteratorT &RHS) const {
+ assert(Case.SI == RHS.Case.SI && "Incompatible operators.");
+ return Case.Index - RHS.Case.Index;
+ }
+ bool operator==(const CaseIteratorT &RHS) const { return Case == RHS.Case; }
+ bool operator<(const CaseIteratorT &RHS) const {
+ assert(Case.SI == RHS.Case.SI && "Incompatible operators.");
+ return Case.Index < RHS.Case.Index;
+ }
+ CaseHandleT &operator*() { return Case; }
+ const CaseHandleT &operator*() const { return Case; }
+ };
+
+ typedef CaseIteratorT<CaseHandle> CaseIt;
+ typedef CaseIteratorT<ConstCaseHandle> ConstCaseIt;
+
static SwitchInst *Create(Value *Value, BasicBlock *Default,
unsigned NumCases,
Instruction *InsertBefore = nullptr) {
@@ -3290,30 +3325,40 @@ public:
/// default case iterator to indicate that it is handled by the default
/// handler.
CaseIt findCaseValue(const ConstantInt *C) {
- for (CaseIt i = case_begin(), e = case_end(); i != e; ++i)
- if (i.getCaseValue() == C)
- return i;
+ CaseIt I = llvm::find_if(
+ cases(), [C](CaseHandle &Case) { return Case.getCaseValue() == C; });
+ if (I != case_end())
+ return I;
+
return case_default();
}
ConstCaseIt findCaseValue(const ConstantInt *C) const {
- for (ConstCaseIt i = case_begin(), e = case_end(); i != e; ++i)
- if (i.getCaseValue() == C)
- return i;
+ ConstCaseIt I = llvm::find_if(cases(), [C](ConstCaseHandle &Case) {
+ return Case.getCaseValue() == C;
+ });
+ if (I != case_end())
+ return I;
+
return case_default();
}
/// 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 nullptr;
+ if (BB == getDefaultDest())
+ return nullptr;
ConstantInt *CI = nullptr;
- for (CaseIt i = case_begin(), e = case_end(); i != e; ++i) {
- if (i.getCaseSuccessor() == BB) {
- if (CI) return nullptr; // Multiple cases lead to BB.
- else CI = i.getCaseValue();
- }
+ for (auto Case : cases()) {
+ if (Case.getCaseSuccessor() != BB)
+ continue;
+
+ if (CI)
+ return nullptr; // Multiple cases lead to BB.
+
+ CI = Case.getCaseValue();
}
+
return CI;
}
@@ -3330,7 +3375,7 @@ public:
/// This action invalidates iterators for all cases following the one removed,
/// including the case_end() iterator. It returns an iterator for the next
/// case.
- CaseIt removeCase(CaseIt i);
+ CaseIt removeCase(CaseIt I);
unsigned getNumSuccessors() const { return getNumOperands()/2; }
BasicBlock *getSuccessor(unsigned idx) const {
OpenPOWER on IntegriCloud