#include "llvm/DerivedTypes.h"
#include "llvm/Attributes.h"
#include "llvm/CallingConv.h"
+#include "llvm/Support/ConstantRangesSet.h"
+#include "llvm/Support/CRSBuilder.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/ErrorHandling.h"
virtual SwitchInst *clone_impl() const;
public:
- static const unsigned DefaultPseudoIndex = ~0L-1; // -2
+ // -2
+ static const unsigned DefaultPseudoIndex = static_cast<unsigned>(~0L-1);
template <class SwitchInstTy, class ConstantIntTy, class BasicBlockTy>
class CaseIteratorT {
}
/// Resolves case value for current case.
+ /// @Deprecated
ConstantIntTy *getCaseValue() {
assert(Index < SI->getNumCases() && "Index out the number of cases.");
- return reinterpret_cast<ConstantIntTy*>(SI->getOperand(2 + Index*2));
+ ConstantRangesSet CRS =
+ reinterpret_cast<Constant*>(SI->getOperand(2 + Index*2));
+ ConstantRangesSet::Range R = CRS.getItem(0);
+ return R.Low;
+ }
+
+ /// Resolves case value for current case.
+ ConstantRangesSet getCaseValueEx() {
+ assert(Index < SI->getNumCases() && "Index out the number of cases.");
+ return reinterpret_cast<Constant*>(SI->getOperand(2 + Index*2));
}
/// Resolves successor for current case.
BasicBlockTy *getCaseSuccessor() {
- assert((Index < SI->getNumCases() || DefaultPseudoIndex) &&
+ assert((Index < SI->getNumCases() ||
+ Index == DefaultPseudoIndex) &&
"Index out the number of cases.");
return SI->getSuccessor(getSuccessorIndex());
}
CaseIt(SwitchInst *SI, unsigned CaseNum) : ParentTy(SI, CaseNum) {}
/// Sets the new value for current case.
+ /// @Deprecated.
void setValue(ConstantInt *V) {
assert(Index < SI->getNumCases() && "Index out the number of cases.");
- SI->setOperand(2 + Index*2, reinterpret_cast<Value*>(V));
+ CRSBuilder CB;
+ CB.add(V);
+ SI->setOperand(2 + Index*2,
+ reinterpret_cast<Value*>((Constant*)CB.getCase()));
+ }
+
+ /// Sets the new value for current case.
+ void setValueEx(ConstantRangesSet& V) {
+ assert(Index < SI->getNumCases() && "Index out the number of cases.");
+ SI->setOperand(2 + Index*2, reinterpret_cast<Value*>((Constant*)V));
}
/// Sets the new successor for current case.
/// Returns a read/write iterator that points to the first
/// case in SwitchInst.
- CaseIt caseBegin() {
+ CaseIt case_begin() {
return CaseIt(this, 0);
}
/// Returns a read-only iterator that points to the first
/// case in the SwitchInst.
- ConstCaseIt caseBegin() const {
+ ConstCaseIt case_begin() const {
return ConstCaseIt(this, 0);
}
/// Returns a read/write iterator that points one past the last
/// in the SwitchInst.
- CaseIt caseEnd() {
+ CaseIt case_end() {
return CaseIt(this, getNumCases());
}
/// Returns a read-only iterator that points one past the last
/// in the SwitchInst.
- ConstCaseIt caseEnd() const {
+ ConstCaseIt case_end() const {
return ConstCaseIt(this, getNumCases());
}
- /// Returns an iterator that points to default case.
+ /// Returns an iterator that points to the default case.
/// Note: this iterator allows to resolve successor only. Attempt
/// to resolve case value causes an assertion.
- CaseIt caseDefault() {
+ /// Also note, that increment and decrement also causes an assertion and
+ /// makes iterator invalid.
+ CaseIt case_default() {
return CaseIt(this, DefaultPseudoIndex);
}
- ConstCaseIt caseDefault() const {
+ ConstCaseIt case_default() const {
return ConstCaseIt(this, DefaultPseudoIndex);
}
/// 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)
+ for (CaseIt i = case_begin(), e = case_end(); i != e; ++i)
+ if (i.getCaseValueEx().isSatisfies(C))
return i;
- return caseDefault();
+ return case_default();
}
ConstCaseIt findCaseValue(const ConstantInt *C) const {
- for (ConstCaseIt i = caseBegin(), e = caseEnd(); i != e; ++i)
- if (i.getCaseValue() == C)
+ for (ConstCaseIt i = case_begin(), e = case_end(); i != e; ++i)
+ if (i.getCaseValueEx().isSatisfies(C))
return i;
- return caseDefault();
+ return case_default();
}
/// findCaseDest - Finds the unique case value for a given successor. Returns
if (BB == getDefaultDest()) return NULL;
ConstantInt *CI = NULL;
- for (CaseIt i = caseBegin(), e = caseEnd(); i != e; ++i) {
+ for (CaseIt i = case_begin(), e = case_end(); i != e; ++i) {
if (i.getCaseSuccessor() == BB) {
if (CI) return NULL; // Multiple cases lead to BB.
else CI = i.getCaseValue();
}
/// addCase - Add an entry to the switch instruction...
- ///
+ /// @Deprecated
+ /// Note:
+ /// This action invalidates case_end(). Old case_end() iterator will
+ /// point to the added case.
void addCase(ConstantInt *OnVal, BasicBlock *Dest);
+
+ /// addCase - Add an entry to the switch instruction.
+ /// Note:
+ /// This action invalidates case_end(). Old case_end() iterator will
+ /// point to the added case.
+ void addCase(ConstantRangesSet& OnVal, BasicBlock *Dest);
/// removeCase - This method removes the specified case and its successor
/// from the switch instruction. Note that this operation may reorder the
/// remaining cases at 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);
unsigned getNumSuccessors() const { return getNumOperands()/2; }
assert(idx < getNumSuccessors() && "Successor # out of range for switch!");
setOperand(idx*2+1, (Value*)NewSucc);
}
+
+ 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;
+ }
// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const SwitchInst *) { return true; }