#include "llvm/DerivedTypes.h"
#include "llvm/Attributes.h"
#include "llvm/CallingConv.h"
+#include "llvm/Support/IntegersSubset.h"
+#include "llvm/Support/IntegersSubsetMapping.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/ErrorHandling.h"
// checkGEPType - Simple wrapper function to give a better assertion failure
// message on bad indexes for a gep instruction.
//
-static inline Type *checkGEPType(Type *Ty) {
+inline Type *checkGEPType(Type *Ty) {
assert(Ty && "Invalid GetElementPtrInst indices for type!");
return Ty;
}
/// getNumClauses - Get the number of clauses for this landing pad.
unsigned getNumClauses() const { return getNumOperands() - 1; }
- /// reserveClauses - Grow the size of the operand list to accomodate the new
+ /// reserveClauses - Grow the size of the operand list to accommodate the new
/// number of clauses.
void reserveClauses(unsigned Size) { growOperands(Size); }
virtual SwitchInst *clone_impl() const;
public:
+ template <class SwitchInstTy, class ConstantIntTy, class BasicBlockTy>
+ class CaseIteratorT;
+
+ typedef CaseIteratorT<const SwitchInst, const ConstantInt, const BasicBlock>
+ ConstCaseIt;
+
+ class CaseIt;
+
// -2
static const unsigned DefaultPseudoIndex = static_cast<unsigned>(~0L-1);
+ static SwitchInst *Create(Value *Value, BasicBlock *Default,
+ unsigned NumCases, Instruction *InsertBefore = 0) {
+ return new SwitchInst(Value, Default, NumCases, InsertBefore);
+ }
+ static SwitchInst *Create(Value *Value, BasicBlock *Default,
+ unsigned NumCases, BasicBlock *InsertAtEnd) {
+ return new SwitchInst(Value, Default, NumCases, InsertAtEnd);
+ }
+
+ ~SwitchInst();
+
+ /// Provide fast operand accessors
+ DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
+
+ // Accessor Methods for Switch stmt
+ Value *getCondition() const { return getOperand(0); }
+ void setCondition(Value *V) { setOperand(0, V); }
+
+ BasicBlock *getDefaultDest() const {
+ return cast<BasicBlock>(getOperand(1));
+ }
+
+ void setDefaultDest(BasicBlock *DefaultCase) {
+ setOperand(1, reinterpret_cast<Value*>(DefaultCase));
+ }
+
+ /// getNumCases - return the number of 'cases' in this switch instruction,
+ /// except the default case
+ unsigned getNumCases() const {
+ return getNumOperands()/2 - 1;
+ }
+
+ /// Returns a read/write iterator that points to the first
+ /// case in SwitchInst.
+ CaseIt case_begin() {
+ return CaseIt(this, 0);
+ }
+ /// Returns a read-only iterator that points to the first
+ /// case in the SwitchInst.
+ ConstCaseIt case_begin() const {
+ return ConstCaseIt(this, 0);
+ }
+
+ /// Returns a read/write iterator that points one past the last
+ /// in the SwitchInst.
+ CaseIt case_end() {
+ return CaseIt(this, getNumCases());
+ }
+ /// Returns a read-only iterator that points one past the last
+ /// in the SwitchInst.
+ ConstCaseIt case_end() const {
+ return ConstCaseIt(this, getNumCases());
+ }
+ /// 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.
+ /// Also note, that increment and decrement also causes an assertion and
+ /// makes iterator invalid.
+ CaseIt case_default() {
+ return CaseIt(this, DefaultPseudoIndex);
+ }
+ ConstCaseIt case_default() const {
+ return ConstCaseIt(this, DefaultPseudoIndex);
+ }
+
+ /// 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 = case_begin(), e = case_end(); i != e; ++i)
+ if (i.getCaseValueEx().isSatisfies(IntItem::fromConstantInt(C)))
+ return i;
+ return case_default();
+ }
+ ConstCaseIt findCaseValue(const ConstantInt *C) const {
+ for (ConstCaseIt i = case_begin(), e = case_end(); i != e; ++i)
+ if (i.getCaseValueEx().isSatisfies(IntItem::fromConstantInt(C)))
+ return i;
+ return case_default();
+ }
+
+ /// 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 (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();
+ }
+ }
+ return CI;
+ }
+
+ /// 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(IntegersSubset& 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; }
+ BasicBlock *getSuccessor(unsigned idx) const {
+ assert(idx < getNumSuccessors() &&"Successor idx out of range for switch!");
+ return cast<BasicBlock>(getOperand(idx*2+1));
+ }
+ void setSuccessor(unsigned idx, BasicBlock *NewSucc) {
+ 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;
+ }
+
+ // Case iterators definition.
+
template <class SwitchInstTy, class ConstantIntTy, class BasicBlockTy>
class CaseIteratorT {
protected:
}
/// 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));
+ IntegersSubset CaseRanges =
+ reinterpret_cast<Constant*>(SI->getOperand(2 + Index*2));
+ IntegersSubset::Range R = CaseRanges.getItem(0);
+
+ // FIXME: Currently we work with ConstantInt based cases.
+ // So return CaseValue as ConstantInt.
+ return R.getLow().toConstantInt();
+ }
+
+ /// Resolves case value for current case.
+ IntegersSubset 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());
}
return RHS.Index != Index;
}
};
-
- typedef CaseIteratorT<const SwitchInst, const ConstantInt, const BasicBlock>
- ConstCaseIt;
class CaseIt : public CaseIteratorT<SwitchInst, ConstantInt, BasicBlock> {
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));
+ IntegersSubsetToBB Mapping;
+ // FIXME: Currently we work with ConstantInt based cases.
+ // So inititalize IntItem container directly from ConstantInt.
+ Mapping.add(IntItem::fromConstantInt(V));
+ SI->setOperand(2 + Index*2,
+ reinterpret_cast<Value*>((Constant*)Mapping.getCase()));
+ }
+
+ /// Sets the new value for current case.
+ void setValueEx(IntegersSubset& 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.
}
};
- static SwitchInst *Create(Value *Value, BasicBlock *Default,
- unsigned NumCases, Instruction *InsertBefore = 0) {
- return new SwitchInst(Value, Default, NumCases, InsertBefore);
- }
- static SwitchInst *Create(Value *Value, BasicBlock *Default,
- unsigned NumCases, BasicBlock *InsertAtEnd) {
- return new SwitchInst(Value, Default, NumCases, InsertAtEnd);
- }
-
- ~SwitchInst();
-
- /// Provide fast operand accessors
- DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);
-
- // Accessor Methods for Switch stmt
- Value *getCondition() const { return getOperand(0); }
- void setCondition(Value *V) { setOperand(0, V); }
-
- BasicBlock *getDefaultDest() const {
- return cast<BasicBlock>(getOperand(1));
- }
-
- void setDefaultDest(BasicBlock *DefaultCase) {
- setOperand(1, reinterpret_cast<Value*>(DefaultCase));
- }
-
- /// getNumCases - return the number of 'cases' in this switch instruction,
- /// except the default case
- unsigned getNumCases() const {
- return getNumOperands()/2 - 1;
- }
-
- /// Returns a read/write iterator that points to the first
- /// case in SwitchInst.
- CaseIt caseBegin() {
- return CaseIt(this, 0);
- }
- /// Returns a read-only iterator that points to the first
- /// case in the SwitchInst.
- ConstCaseIt caseBegin() const {
- return ConstCaseIt(this, 0);
- }
-
- /// Returns a read/write iterator that points one past the last
- /// in the SwitchInst.
- CaseIt caseEnd() {
- return CaseIt(this, getNumCases());
- }
- /// Returns a read-only iterator that points one past the last
- /// in the SwitchInst.
- ConstCaseIt caseEnd() const {
- return ConstCaseIt(this, getNumCases());
- }
- /// 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);
- }
-
- /// 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 (CaseIt i = caseBegin(), e = caseEnd(); i != e; ++i) {
- if (i.getCaseSuccessor() == BB) {
- if (CI) return NULL; // Multiple cases lead to BB.
- else CI = i.getCaseValue();
- }
- }
- return CI;
- }
-
- /// addCase - Add an entry to the switch instruction...
- ///
- void addCase(ConstantInt *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.
- ///
- void removeCase(CaseIt i);
-
- unsigned getNumSuccessors() const { return getNumOperands()/2; }
- BasicBlock *getSuccessor(unsigned idx) const {
- assert(idx < getNumSuccessors() &&"Successor idx out of range for switch!");
- return cast<BasicBlock>(getOperand(idx*2+1));
- }
- void setSuccessor(unsigned idx, BasicBlock *NewSucc) {
- assert(idx < getNumSuccessors() && "Successor # out of range for switch!");
- setOperand(idx*2+1, (Value*)NewSucc);
- }
-
// 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) {
return I->getOpcode() == Instruction::Switch;