SwitchInst refactoring.
authorStepan Dyatkovskiy <stpworld@narod.ru>
Wed, 1 Feb 2012 07:49:51 +0000 (07:49 +0000)
committerStepan Dyatkovskiy <stpworld@narod.ru>
Wed, 1 Feb 2012 07:49:51 +0000 (07:49 +0000)
The purpose of refactoring is to hide operand roles from SwitchInst user (programmer). If you want to play with operands directly, probably you will need lower level methods than SwitchInst ones (TerminatorInst or may be User). After this patch we can reorganize SwitchInst operands and successors as we want.

What was done:

1. Changed semantics of index inside the getCaseValue method:
getCaseValue(0) means "get first case", not a condition. Use getCondition() if you want to resolve the condition. I propose don't mix SwitchInst case indexing with low level indexing (TI successors indexing, User's operands indexing), since it may be dangerous.
2. By the same reason findCaseValue(ConstantInt*) returns actual number of case value. 0 means first case, not default. If there is no case with given value, ErrorIndex will returned.
3. Added getCaseSuccessor method. I propose to avoid usage of TerminatorInst::getSuccessor if you want to resolve case successor BB. Use getCaseSuccessor instead, since internal SwitchInst organization of operands/successors is hidden and may be changed in any moment.
4. Added resolveSuccessorIndex and resolveCaseIndex. The main purpose of these methods is to see how case successors are really mapped in TerminatorInst.
4.1 "resolveSuccessorIndex" was created if you need to level down from SwitchInst to TerminatorInst. It returns TerminatorInst's successor index for given case successor.
4.2 "resolveCaseIndex" converts low level successors index to case index that curresponds to the given successor.

Note: There are also related compatability fix patches for dragonegg, klee, llvm-gcc-4.0, llvm-gcc-4.2, safecode, clang.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@149481 91177308-0d34-0410-b5e6-96231b3b80d8

26 files changed:
include/llvm/Analysis/CFGPrinter.h
include/llvm/Instructions.h
lib/Analysis/LazyValueInfo.cpp
lib/Analysis/SparsePropagation.cpp
lib/Bitcode/Writer/BitcodeWriter.cpp
lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
lib/ExecutionEngine/Interpreter/Execution.cpp
lib/Target/CBackend/CBackend.cpp
lib/Target/CppBackend/CPPBackend.cpp
lib/Transforms/IPO/GlobalOpt.cpp
lib/Transforms/InstCombine/InstructionCombining.cpp
lib/Transforms/Scalar/GVN.cpp
lib/Transforms/Scalar/JumpThreading.cpp
lib/Transforms/Scalar/LoopUnswitch.cpp
lib/Transforms/Scalar/SCCP.cpp
lib/Transforms/Utils/CloneFunction.cpp
lib/Transforms/Utils/CodeExtractor.cpp
lib/Transforms/Utils/Local.cpp
lib/Transforms/Utils/LowerExpectIntrinsic.cpp
lib/Transforms/Utils/LowerSwitch.cpp
lib/Transforms/Utils/SimplifyCFG.cpp
lib/VMCore/AsmWriter.cpp
lib/VMCore/Instructions.cpp
lib/VMCore/Verifier.cpp
tools/llvm-diff/DifferenceEngine.cpp

index 8f7ebcb0f93d564b06e3ff58891358f81a529178..2cde838fc004c0ab1dcb2094455fa151ea50c510 100644 (file)
@@ -95,7 +95,8 @@ struct DOTGraphTraits<const Function*> : public DefaultDOTGraphTraits {
       
       std::string Str;
       raw_string_ostream OS(Str);
-      OS << SI->getCaseValue(SuccNo)->getValue();
+      unsigned Case = SI->resolveCaseIndex(SuccNo);
+      OS << SI->getCaseValue(Case)->getValue();
       return OS.str();
     }    
     return "";
index c27c6fa097f6e1e7543f250eb02db2df73939334..bb6a6ffdd8bb278e07aecea1d0df1ca9e123e0c1 100644 (file)
@@ -24,6 +24,7 @@
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/ErrorHandling.h"
 #include <iterator>
+#include <limits.h>
 
 namespace llvm {
 
@@ -2467,6 +2468,9 @@ class SwitchInst : public TerminatorInst {
 protected:
   virtual SwitchInst *clone_impl() const;
 public:
+
+  enum { ErrorIndex = UINT_MAX };
+
   static SwitchInst *Create(Value *Value, BasicBlock *Default,
                             unsigned NumCases, Instruction *InsertBefore = 0) {
     return new SwitchInst(Value, Default, NumCases, InsertBefore);
@@ -2488,34 +2492,62 @@ public:
     return cast<BasicBlock>(getOperand(1));
   }
 
-  /// getNumCases - return the number of 'cases' in this switch instruction.
-  /// Note that case #0 is always the default case.
+  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;
+    return getNumOperands()/2 - 1;
   }
 
-  /// getCaseValue - Return the specified case value.  Note that case #0, the
-  /// default destination, does not have a case value.
+  /// getCaseValue - Return the specified case value. Note that case #0, means
+  /// first case, not a default case.
   ConstantInt *getCaseValue(unsigned i) {
-    assert(i && i < getNumCases() && "Illegal case value to get!");
-    return getSuccessorValue(i);
+    assert(i < getNumCases() && "Illegal case value to get!");
+    return reinterpret_cast<ConstantInt*>(getOperand(2 + i*2));
   }
 
-  /// getCaseValue - Return the specified case value.  Note that case #0, the
-  /// default destination, does not have a case value.
+  /// getCaseValue - Return the specified case value. Note that case #0, means
+  /// first case, not a default case.
   const ConstantInt *getCaseValue(unsigned i) const {
-    assert(i && i < getNumCases() && "Illegal case value to get!");
-    return getSuccessorValue(i);
+    assert(i < getNumCases() && "Illegal case value to get!");
+    return reinterpret_cast<const ConstantInt*>(getOperand(2 + i*2));
+  }
+
+  // setSuccessorValue - Updates the value associated with the specified
+  // case.
+  void setCaseValue(unsigned i, ConstantInt *CaseValue) {
+    assert(i < getNumCases() && "Case index # out of range!");
+    setOperand(2 + i*2, reinterpret_cast<Value*>(CaseValue));
   }
 
   /// findCaseValue - Search all of the case values for the specified constant.
   /// If it is explicitly handled, return the case number of it, otherwise
-  /// return 0 to indicate that it is handled by the default handler.
+  /// return ErrorIndex to indicate that it is handled by the default handler.
   unsigned findCaseValue(const ConstantInt *C) const {
-    for (unsigned i = 1, e = getNumCases(); i != e; ++i)
+    for (unsigned i = 0, e = getNumCases(); i != e; ++i)
       if (getCaseValue(i) == C)
         return i;
-    return 0;
+    return ErrorIndex;
+  }
+  
+  /// resolveSuccessorIndex - Converts case index to index of its successor
+  /// index in TerminatorInst successors collection.
+  /// If CaseIndex == ErrorIndex, "default" successor will returned then. 
+  unsigned resolveSuccessorIndex(unsigned CaseIndex) const {
+    assert((CaseIndex == ErrorIndex || CaseIndex < getNumCases()) &&
+           "Case index # out of range!");
+    return CaseIndex != ErrorIndex ? CaseIndex + 1 : 0;
+  }
+  
+  /// resolveCaseIndex - Converts index of successor in TerminatorInst
+  /// collection to index of case that corresponds to this successor.
+  unsigned resolveCaseIndex(unsigned SuccessorIndex) const {
+    assert(SuccessorIndex < getNumSuccessors() &&
+           "Successor index # out of range!");    
+    return SuccessorIndex != 0 ? SuccessorIndex - 1 : ErrorIndex; 
   }
 
   /// findCaseDest - Finds the unique case value for a given successor. Returns
@@ -2524,8 +2556,8 @@ public:
     if (BB == getDefaultDest()) return NULL;
 
     ConstantInt *CI = NULL;
-    for (unsigned i = 1, e = getNumCases(); i != e; ++i) {
-      if (getSuccessor(i) == BB) {
+    for (unsigned i = 0, e = getNumCases(); i != e; ++i) {
+      if (getSuccessor(i + 1) == BB) {
         if (CI) return NULL;   // Multiple cases lead to BB.
         else CI = getCaseValue(i);
       }
@@ -2537,9 +2569,8 @@ public:
   ///
   void addCase(ConstantInt *OnVal, BasicBlock *Dest);
 
-  /// removeCase - This method removes the specified successor from the switch
-  /// instruction.  Note that this cannot be used to remove the default
-  /// destination (successor #0). Also note that this operation may reorder the
+  /// 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(unsigned idx);
@@ -2554,6 +2585,22 @@ public:
     setOperand(idx*2+1, (Value*)NewSucc);
   }
 
+  /// Resolves successor for idx-th case.
+  /// Use getCaseSuccessor instead of TerminatorInst::getSuccessor,
+  /// since internal SwitchInst organization of operands/successors is
+  /// hidden and may be changed in any moment.
+  BasicBlock *getCaseSuccessor(unsigned idx) const {
+    return getSuccessor(resolveSuccessorIndex(idx));
+  }
+
+  /// Set new successor for idx-th case.
+  /// Use setCaseSuccessor instead of TerminatorInst::setSuccessor,
+  /// since internal SwitchInst organization of operands/successors is
+  /// hidden and may be changed in any moment.
+  void setCaseSuccessor(unsigned idx, BasicBlock *NewSucc) {
+    setSuccessor(resolveSuccessorIndex(idx), NewSucc);
+  }
+
   // getSuccessorValue - Return the value associated with the specified
   // successor.
   ConstantInt *getSuccessorValue(unsigned idx) const {
index 950d4a6537842a706e829df47d06742457d43f68..e1c099e43560034b10caa399cf6f10e2d0fcbd6b 100644 (file)
@@ -854,8 +854,8 @@ bool LazyValueInfoCache::getEdgeValue(Value *Val, BasicBlock *BBFrom,
       // BBFrom to BBTo.
       unsigned NumEdges = 0;
       ConstantInt *EdgeVal = 0;
-      for (unsigned i = 1, e = SI->getNumSuccessors(); i != e; ++i) {
-        if (SI->getSuccessor(i) != BBTo) continue;
+      for (unsigned i = 0, e = SI->getNumCases(); i != e; ++i) {
+        if (SI->getCaseSuccessor(i) != BBTo) continue;
         if (NumEdges++) break;
         EdgeVal = SI->getCaseValue(i);
       }
index 035bceaf2706425e25dac11a974000435c13a6e4..0c7d05f91daadd9782bb51d04ba3177306b857fa 100644 (file)
@@ -195,7 +195,8 @@ void SparseSolver::getFeasibleSuccessors(TerminatorInst &TI,
     return;
   }
   
-  Succs[SI.findCaseValue(cast<ConstantInt>(C))] = true;
+  unsigned CCase = SI.findCaseValue(cast<ConstantInt>(C));
+  Succs[SI.resolveSuccessorIndex(CCase)] = true;
 }
 
 
index d58f7cf73df8c14bbb0d9a3950312ab7bc0ec1bd..81d5720126010d1ec8c9689acfc7b94bed6c099a 100644 (file)
@@ -1162,10 +1162,17 @@ static void WriteInstruction(const Instruction &I, unsigned InstID,
     }
     break;
   case Instruction::Switch:
-    Code = bitc::FUNC_CODE_INST_SWITCH;
-    Vals.push_back(VE.getTypeID(I.getOperand(0)->getType()));
-    for (unsigned i = 0, e = I.getNumOperands(); i != e; ++i)
-      Vals.push_back(VE.getValueID(I.getOperand(i)));
+    {
+      Code = bitc::FUNC_CODE_INST_SWITCH;
+      SwitchInst &SI = cast<SwitchInst>(I);
+      Vals.push_back(VE.getTypeID(SI.getCondition()->getType()));
+      Vals.push_back(VE.getValueID(SI.getCondition()));
+      Vals.push_back(VE.getValueID(SI.getDefaultDest()));
+      for (unsigned i = 0, e = SI.getNumCases(); i != e; ++i) {
+        Vals.push_back(VE.getValueID(SI.getCaseValue(i)));
+        Vals.push_back(VE.getValueID(SI.getCaseSuccessor(i)));
+      }
+    }
     break;
   case Instruction::IndirectBr:
     Code = bitc::FUNC_CODE_INST_INDIRECTBR;
index 8286f57914c8b1c419ca1c92af3291629a25aa59..d46d8e41bb0808cf710c927d385bc032bdff47f4 100644 (file)
@@ -2209,7 +2209,7 @@ bool SelectionDAGBuilder::handleBTSplitSwitchCase(CaseRec& CR,
 
   CaseRange LHSR(CR.Range.first, Pivot);
   CaseRange RHSR(Pivot, CR.Range.second);
-  Constant *C = Pivot->Low;
+  const Constant *C = Pivot->Low;
   MachineBasicBlock *FalseBB = 0, *TrueBB = 0;
 
   // We know that we branch to the LHS if the Value being switched on is
@@ -2402,14 +2402,14 @@ size_t SelectionDAGBuilder::Clusterify(CaseVector& Cases,
 
   BranchProbabilityInfo *BPI = FuncInfo.BPI;
   // Start with "simple" cases
-  for (size_t i = 1; i < SI.getNumSuccessors(); ++i) {
-    BasicBlock *SuccBB = SI.getSuccessor(i);
+  for (size_t i = 0; i < SI.getNumCases(); ++i) {
+    BasicBlock *SuccBB = SI.getCaseSuccessor(i);
     MachineBasicBlock *SMBB = FuncInfo.MBBMap[SuccBB];
 
     uint32_t ExtraWeight = BPI ? BPI->getEdgeWeight(SI.getParent(), SuccBB) : 0;
 
-    Cases.push_back(Case(SI.getSuccessorValue(i),
-                         SI.getSuccessorValue(i),
+    Cases.push_back(Case(SI.getCaseValue(i),
+                         SI.getCaseValue(i),
                          SMBB, ExtraWeight));
   }
   std::sort(Cases.begin(), Cases.end(), CaseCmp());
@@ -2476,7 +2476,7 @@ void SelectionDAGBuilder::visitSwitch(const SwitchInst &SI) {
 
   // If there is only the default destination, branch to it if it is not the
   // next basic block.  Otherwise, just fall through.
-  if (SI.getNumCases() == 1) {
+  if (!SI.getNumCases()) {
     // Update machine-CFG edges.
 
     // If this is not a fall-through branch, emit the branch.
index 36bdf38c48e7bb308604856570d26fda76d86250..62c55053e1b39477a93a0a0923e8a711113ec204 100644 (file)
@@ -130,13 +130,13 @@ private:
   /// Case - A struct to record the Value for a switch case, and the
   /// case's target basic block.
   struct Case {
-    Constant* Low;
-    Constant* High;
+    const Constant *Low;
+    const Constant *High;
     MachineBasicBlock* BB;
     uint32_t ExtraWeight;
 
     Case() : Low(0), High(0), BB(0), ExtraWeight(0) { }
-    Case(Constant* low, Constant* high, MachineBasicBlock* bb,
+    Case(const Constant *low, const Constant *high, MachineBasicBlock *bb,
          uint32_t extraweight) : Low(low), High(high), BB(bb),
          ExtraWeight(extraweight) { }
 
index d8065e1650e093e18498e6fa99164ad3c6628ce2..1af40ddc532bb8ce633c9d93c0ee075541452ea1 100644 (file)
@@ -670,10 +670,10 @@ void Interpreter::visitSwitchInst(SwitchInst &I) {
   BasicBlock *Dest = 0;
   unsigned NumCases = I.getNumCases();
   // Skip the first item since that's the default case.
-  for (unsigned i = 1; i < NumCases; ++i) {
+  for (unsigned i = 0; i < NumCases; ++i) {
     GenericValue CaseVal = getOperandValue(I.getCaseValue(i), SF);
     if (executeICMP_EQ(CondVal, CaseVal, ElTy).IntVal != 0) {
-      Dest = cast<BasicBlock>(I.getSuccessor(i));
+      Dest = cast<BasicBlock>(I.getCaseSuccessor(i));
       break;
     }
   }
index 8c83bc349a8e7d61ce901cf8073832986fd08779..b841a5c8d6678e042a000c94b765d013b5e362ad 100644 (file)
@@ -2449,9 +2449,9 @@ void CWriter::visitSwitchInst(SwitchInst &SI) {
 
   unsigned NumCases = SI.getNumCases();
   // Skip the first item since that's the default case.
-  for (unsigned i = 1; i < NumCases; ++i) {
+  for (unsigned i = 0; i < NumCases; ++i) {
     ConstantInt* CaseVal = SI.getCaseValue(i);
-    BasicBlock* Succ = SI.getSuccessor(i);
+    BasicBlock* Succ = SI.getCaseSuccessor(i);
     Out << "  case ";
     writeOperand(CaseVal);
     Out << ":\n";
index de73a72ac4911a9cb066215670f2cc2697ab8c3a..956afcc317d2d26dd4d467ab47dd50df0cab1088 100644 (file)
@@ -1115,9 +1115,9 @@ void CppWriter::printInstruction(const Instruction *I,
         << SI->getNumCases() << ", " << bbname << ");";
     nl(Out);
     unsigned NumCases = SI->getNumCases();
-    for (unsigned i = 1; i < NumCases; ++i) {
+    for (unsigned i = 0; i < NumCases; ++i) {
       const ConstantInt* CaseVal = SI->getCaseValue(i);
-      const BasicBlock* BB = SI->getSuccessor(i);
+      const BasicBlock *BB = SI->getCaseSuccessor(i);
       Out << iName << "->addCase("
           << getOpName(CaseVal) << ", "
           << getOpName(BB) << ");";
index 2f963d1583533eff6142ff76d6a53db61812318d..884d8836182639aea69055cbeae2940e09805888 100644 (file)
@@ -2455,7 +2455,8 @@ static bool EvaluateFunction(Function *F, Constant *&RetVal,
         ConstantInt *Val =
           dyn_cast<ConstantInt>(getVal(Values, SI->getCondition()));
         if (!Val) return false;  // Cannot determine.
-        NewBB = SI->getSuccessor(SI->findCaseValue(Val));
+        unsigned ValTISucc = SI->resolveSuccessorIndex(SI->findCaseValue(Val));
+        NewBB = SI->getSuccessor(ValTISucc);
       } else if (IndirectBrInst *IBI = dyn_cast<IndirectBrInst>(CurInst)) {
         Value *Val = getVal(Values, IBI->getAddress())->stripPointerCasts();
         if (BlockAddress *BA = dyn_cast<BlockAddress>(Val))
index 64ed817e75c862b61f308218c5ced9d43b31191d..0294d2a5ace23ce5426e939423d0b1638aebd9de 100644 (file)
@@ -1251,13 +1251,13 @@ Instruction *InstCombiner::visitSwitchInst(SwitchInst &SI) {
         // change 'switch (X+4) case 1:' into 'switch (X) case -3'
         unsigned NumCases = SI.getNumCases();
         // Skip the first item since that's the default case.
-        for (unsigned i = 1; i < NumCases; ++i) {
+        for (unsigned i = 0; i < NumCases; ++i) {
           ConstantInt* CaseVal = SI.getCaseValue(i);
           Constant* NewCaseVal = ConstantExpr::getSub(cast<Constant>(CaseVal),
                                                       AddRHS);
           assert(isa<ConstantInt>(NewCaseVal) &&
                  "Result of expression should be constant");
-          SI.setSuccessorValue(i, cast<ConstantInt>(NewCaseVal));
+          SI.setCaseValue(i, cast<ConstantInt>(NewCaseVal));
         }
         SI.setCondition(I->getOperand(0));
         Worklist.Add(I);
@@ -1877,15 +1877,15 @@ static bool AddReachableCodeToWorklist(BasicBlock *BB,
     } else if (SwitchInst *SI = dyn_cast<SwitchInst>(TI)) {
       if (ConstantInt *Cond = dyn_cast<ConstantInt>(SI->getCondition())) {
         // See if this is an explicit destination.
-        for (unsigned i = 1, e = SI->getNumSuccessors(); i != e; ++i)
+        for (unsigned i = 0, e = SI->getNumCases(); i != e; ++i)
           if (SI->getCaseValue(i) == Cond) {
-            BasicBlock *ReachableBB = SI->getSuccessor(i);
+            BasicBlock *ReachableBB = SI->getCaseSuccessor(i);
             Worklist.push_back(ReachableBB);
             continue;
           }
         
         // Otherwise it is the default destination.
-        Worklist.push_back(SI->getSuccessor(0));
+        Worklist.push_back(SI->getDefaultDest());
         continue;
       }
     }
index d39ef3d688d8320b49d7b839cccbb4e8e363064d..bdcbfb07d6f8ca433b3750c5340faf8fa23cf219 100644 (file)
@@ -2085,8 +2085,8 @@ bool GVN::processInstruction(Instruction *I) {
     Value *SwitchCond = SI->getCondition();
     BasicBlock *Parent = SI->getParent();
     bool Changed = false;
-    for (unsigned i = 1, e = SI->getNumCases(); i != e; ++i) {
-      BasicBlock *Dst = SI->getSuccessor(i);
+    for (unsigned i = 0, e = SI->getNumCases(); i != e; ++i) {
+      BasicBlock *Dst = SI->getCaseSuccessor(i);
       if (isOnlyReachableViaThisEdge(Parent, Dst, DT))
         Changed |= propagateEquality(SwitchCond, SI->getCaseValue(i), Dst);
     }
index c78db3fc3e7f4c84103e5274d0d98bbacfcfbbd4..fa25a8fcd77b9a1031ef94c7ed7f3007c3fef42d 100644 (file)
@@ -1086,9 +1086,10 @@ bool JumpThreading::ProcessThreadableEdges(Value *Cond, BasicBlock *BB,
       DestBB = 0;
     else if (BranchInst *BI = dyn_cast<BranchInst>(BB->getTerminator()))
       DestBB = BI->getSuccessor(cast<ConstantInt>(Val)->isZero());
-    else if (SwitchInst *SI = dyn_cast<SwitchInst>(BB->getTerminator()))
-      DestBB = SI->getSuccessor(SI->findCaseValue(cast<ConstantInt>(Val)));
-    else {
+    else if (SwitchInst *SI = dyn_cast<SwitchInst>(BB->getTerminator())) {
+      unsigned ValCase = SI->findCaseValue(cast<ConstantInt>(Val));
+      DestBB = SI->getSuccessor(SI->resolveSuccessorIndex(ValCase));
+    } else {
       assert(isa<IndirectBrInst>(BB->getTerminator())
               && "Unexpected terminator");
       DestBB = cast<BlockAddress>(Val)->getBasicBlock();
index 678652d6462eb6722780ec6f8cbd9a6c94021eaf..2c75f637f4ab4ec3eea1ec451594208f0be771ea 100644 (file)
@@ -436,7 +436,7 @@ bool LoopUnswitch::processCurrentLoop() {
       Value *LoopCond = FindLIVLoopCondition(SI->getCondition(), 
                                              currentLoop, Changed);
       unsigned NumCases = SI->getNumCases(); 
-      if (LoopCond && NumCases > 1) {
+      if (LoopCond && NumCases) {
         // Find a value to unswitch on:
         // FIXME: this should chose the most expensive case!
         // FIXME: scan for a case with a non-critical edge?
@@ -445,7 +445,7 @@ bool LoopUnswitch::processCurrentLoop() {
         // Do not process same value again and again.
         // At this point we have some cases already unswitched and
         // some not yet unswitched. Let's find the first not yet unswitched one.
-        for (unsigned i = 1; i < NumCases; ++i) {
+        for (unsigned i = 0; i < NumCases; ++i) {
           Constant* UnswitchValCandidate = SI->getCaseValue(i);
           if (!BranchesInfo.isUnswitched(SI, UnswitchValCandidate)) {
             UnswitchVal = UnswitchValCandidate;
@@ -574,10 +574,10 @@ bool LoopUnswitch::IsTrivialUnswitchCondition(Value *Cond, Constant **Val,
     // this. 
     // Note that we can't trivially unswitch on the default case or
     // on already unswitched cases.
-    for (unsigned i = 1, e = SI->getNumSuccessors(); i != e; ++i) {
+    for (unsigned i = 0, e = SI->getNumCases(); i != e; ++i) {
       BasicBlock* LoopExitCandidate;
       if ((LoopExitCandidate = isTrivialLoopExitBlock(currentLoop, 
-                                               SI->getSuccessor(i)))) {
+                                               SI->getCaseSuccessor(i)))) {
         // Okay, we found a trivial case, remember the value that is trivial.
         ConstantInt* CaseVal = SI->getCaseValue(i);
 
@@ -1118,14 +1118,15 @@ void LoopUnswitch::RewriteLoopBodyWithConditionConstant(Loop *L, Value *LIC,
     if (SI == 0 || !isa<ConstantInt>(Val)) continue;
     
     unsigned DeadCase = SI->findCaseValue(cast<ConstantInt>(Val));
-    if (DeadCase == 0) continue;  // Default case is live for multiple values.
+    // Default case is live for multiple values.
+    if (DeadCase == SwitchInst::ErrorIndex) continue;
     
     // Found a dead case value.  Don't remove PHI nodes in the 
     // successor if they become single-entry, those PHI nodes may
     // be in the Users list.
 
     BasicBlock *Switch = SI->getParent();
-    BasicBlock *SISucc = SI->getSuccessor(DeadCase);
+    BasicBlock *SISucc = SI->getCaseSuccessor(DeadCase);
     BasicBlock *Latch = L->getLoopLatch();
     
     BranchesInfo.setUnswitched(SI, Val);
@@ -1145,7 +1146,7 @@ void LoopUnswitch::RewriteLoopBodyWithConditionConstant(Loop *L, Value *LIC,
     // Compute the successors instead of relying on the return value
     // of SplitEdge, since it may have split the switch successor
     // after PHI nodes.
-    BasicBlock *NewSISucc = SI->getSuccessor(DeadCase);
+    BasicBlock *NewSISucc = SI->getCaseSuccessor(DeadCase);
     BasicBlock *OldSISucc = *succ_begin(NewSISucc);
     // Create an "unreachable" destination.
     BasicBlock *Abort = BasicBlock::Create(Context, "us-unreachable",
index 1f8f452c36cae3b35a9f329ed43f7951954c7c41..4274b509d2f28472e3b90227302db15c2a422d1b 100644 (file)
@@ -550,7 +550,7 @@ void SCCPSolver::getFeasibleSuccessors(TerminatorInst &TI,
   }
 
   if (SwitchInst *SI = dyn_cast<SwitchInst>(&TI)) {
-    if (TI.getNumSuccessors() < 2) {
+    if (!SI->getNumCases()) {
       Succs[0] = true;
       return;
     }
@@ -564,7 +564,7 @@ void SCCPSolver::getFeasibleSuccessors(TerminatorInst &TI,
       return;
     }
 
-    Succs[SI->findCaseValue(CI)] = true;
+    Succs[SI->resolveSuccessorIndex(SI->findCaseValue(CI))] = true;
     return;
   }
 
@@ -614,7 +614,7 @@ bool SCCPSolver::isEdgeFeasible(BasicBlock *From, BasicBlock *To) {
     return true;
 
   if (SwitchInst *SI = dyn_cast<SwitchInst>(TI)) {
-    if (SI->getNumSuccessors() < 2)
+    if (SI->getNumCases() < 1)
       return true;
 
     LatticeVal SCValue = getValueState(SI->getCondition());
@@ -624,9 +624,9 @@ bool SCCPSolver::isEdgeFeasible(BasicBlock *From, BasicBlock *To) {
       return !SCValue.isUndefined();
 
     // Make sure to skip the "default value" which isn't a value
-    for (unsigned i = 1, E = SI->getNumSuccessors(); i != E; ++i)
-      if (SI->getSuccessorValue(i) == CI) // Found the taken branch.
-        return SI->getSuccessor(i) == To;
+    for (unsigned i = 0, E = SI->getNumCases(); i != E; ++i)
+      if (SI->getCaseValue(i) == CI) // Found the taken branch.
+        return SI->getCaseSuccessor(i) == To;
 
     // If the constant value is not equal to any of the branches, we must
     // execute default branch.
@@ -1487,7 +1487,7 @@ bool SCCPSolver::ResolvedUndefsIn(Function &F) {
     }
 
     if (SwitchInst *SI = dyn_cast<SwitchInst>(TI)) {
-      if (SI->getNumSuccessors() < 2)   // no cases
+      if (!SI->getNumCases())
         continue;
       if (!getValueState(SI->getCondition()).isUndefined())
         continue;
@@ -1495,12 +1495,12 @@ bool SCCPSolver::ResolvedUndefsIn(Function &F) {
       // If the input to SCCP is actually switch on undef, fix the undef to
       // the first constant.
       if (isa<UndefValue>(SI->getCondition())) {
-        SI->setCondition(SI->getCaseValue(1));
-        markEdgeExecutable(BB, TI->getSuccessor(1));
+        SI->setCondition(SI->getCaseValue(0));
+        markEdgeExecutable(BB, SI->getCaseSuccessor(0));
         return true;
       }
 
-      markForcedConstant(SI->getCondition(), SI->getCaseValue(1));
+      markForcedConstant(SI->getCondition(), SI->getCaseValue(0));
       return true;
     }
   }
index 6ddbed2bbea67d7d4103cf7d2293debcc20beda0..f817a21cbd098446d541f2d5370ed9a6e6d7e898 100644 (file)
@@ -314,7 +314,8 @@ void PruningFunctionCloner::CloneBlock(const BasicBlock *BB,
       Cond = dyn_cast_or_null<ConstantInt>(V);
     }
     if (Cond) {     // Constant fold to uncond branch!
-      BasicBlock *Dest = SI->getSuccessor(SI->findCaseValue(Cond));
+      unsigned CaseIndex = SI->findCaseValue(Cond);
+      BasicBlock *Dest = SI->getSuccessor(SI->resolveSuccessorIndex(CaseIndex));
       VMap[OldTI] = BranchInst::Create(Dest, NewBB);
       ToClone.push_back(Dest);
       TerminatorDone = true;
index 5f47ebb782021fb65dc488fd70da2246c1e66b29..429919b79a483c21f2b0fa39144161e4a5a9887e 100644 (file)
@@ -615,9 +615,9 @@ emitCallAndSwitchStatement(Function *newFunction, BasicBlock *codeReplacer,
   default:
     // Otherwise, make the default destination of the switch instruction be one
     // of the other successors.
-    TheSwitch->setOperand(0, call);
-    TheSwitch->setSuccessor(0, TheSwitch->getSuccessor(NumExitBlocks));
-    TheSwitch->removeCase(NumExitBlocks);  // Remove redundant case
+    TheSwitch->setCondition(call);
+    TheSwitch->setDefaultDest(TheSwitch->getSuccessor(NumExitBlocks));
+    TheSwitch->removeCase(NumExitBlocks-1);  // Remove redundant case
     break;
   }
 }
index 4dd93cf2c7599d04d4117e507ec3169d54ef1f9f..336d8f63ec266b8f8caf9411f12fe58b365e00cb 100644 (file)
@@ -106,22 +106,20 @@ bool llvm::ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions) {
     // If we are switching on a constant, we can convert the switch into a
     // single branch instruction!
     ConstantInt *CI = dyn_cast<ConstantInt>(SI->getCondition());
-    BasicBlock *TheOnlyDest = SI->getSuccessor(0);  // The default dest
+    BasicBlock *TheOnlyDest = SI->getDefaultDest();  // The default dest
     BasicBlock *DefaultDest = TheOnlyDest;
-    assert(TheOnlyDest == SI->getDefaultDest() &&
-           "Default destination is not successor #0?");
 
     // Figure out which case it goes to.
-    for (unsigned i = 1, e = SI->getNumSuccessors(); i != e; ++i) {
+    for (unsigned i = 0, e = SI->getNumCases(); i != e; ++i) {
       // Found case matching a constant operand?
-      if (SI->getSuccessorValue(i) == CI) {
-        TheOnlyDest = SI->getSuccessor(i);
+      if (SI->getCaseValue(i) == CI) {
+        TheOnlyDest = SI->getCaseSuccessor(i);
         break;
       }
 
       // Check to see if this branch is going to the same place as the default
       // dest.  If so, eliminate it as an explicit compare.
-      if (SI->getSuccessor(i) == DefaultDest) {
+      if (SI->getCaseSuccessor(i) == DefaultDest) {
         // Remove this entry.
         DefaultDest->removePredecessor(SI->getParent());
         SI->removeCase(i);
@@ -132,7 +130,7 @@ bool llvm::ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions) {
       // Otherwise, check to see if the switch only branches to one destination.
       // We do this by reseting "TheOnlyDest" to null when we find two non-equal
       // destinations.
-      if (SI->getSuccessor(i) != TheOnlyDest) TheOnlyDest = 0;
+      if (SI->getCaseSuccessor(i) != TheOnlyDest) TheOnlyDest = 0;
     }
 
     if (CI && !TheOnlyDest) {
@@ -166,14 +164,14 @@ bool llvm::ConstantFoldTerminator(BasicBlock *BB, bool DeleteDeadConditions) {
       return true;
     }
     
-    if (SI->getNumSuccessors() == 2) {
+    if (SI->getNumCases() == 1) {
       // Otherwise, we can fold this switch into a conditional branch
       // instruction if it has only one non-default destination.
       Value *Cond = Builder.CreateICmpEQ(SI->getCondition(),
-                                         SI->getSuccessorValue(1), "cond");
+                                         SI->getCaseValue(0), "cond");
 
       // Insert the new branch.
-      Builder.CreateCondBr(Cond, SI->getSuccessor(1), SI->getSuccessor(0));
+      Builder.CreateCondBr(Cond, SI->getCaseSuccessor(0), SI->getDefaultDest());
 
       // Delete the old switch.
       SI->eraseFromParent();
index 9fdc06a7136a4d63759bd97672e93fe709951477..df8d68ec8bab2ce2e2b889a980a6eb49418b3f3f 100644 (file)
@@ -76,11 +76,14 @@ bool LowerExpectIntrinsic::HandleSwitchExpect(SwitchInst *SI) {
   unsigned caseNo = SI->findCaseValue(ExpectedValue);
   std::vector<Value *> Vec;
   unsigned n = SI->getNumCases();
-  Vec.resize(n + 1); // +1 for MDString
+  Vec.resize(n + 1 + 1); // +1 for MDString and +1 for default case
 
   Vec[0] = MDString::get(Context, "branch_weights");
+  Vec[1] = ConstantInt::get(Int32Ty, SwitchInst::ErrorIndex == caseNo ?
+                            LikelyBranchWeight : UnlikelyBranchWeight);
   for (unsigned i = 0; i < n; ++i) {
-    Vec[i + 1] = ConstantInt::get(Int32Ty, i == caseNo ? LikelyBranchWeight : UnlikelyBranchWeight);
+    Vec[i + 1 + 1] = ConstantInt::get(Int32Ty, i == caseNo ?
+        LikelyBranchWeight : UnlikelyBranchWeight);
   }
 
   MDNode *WeightsNode = llvm::MDNode::get(Context, Vec);
index 686178ca01cc1e3294b11733eb64d41d2758a05e..424f564774252a63eb317d7ec36d7a713a44163c 100644 (file)
@@ -237,10 +237,10 @@ unsigned LowerSwitch::Clusterify(CaseVector& Cases, SwitchInst *SI) {
   unsigned numCmps = 0;
 
   // Start with "simple" cases
-  for (unsigned i = 1; i < SI->getNumSuccessors(); ++i)
-    Cases.push_back(CaseRange(SI->getSuccessorValue(i),
-                              SI->getSuccessorValue(i),
-                              SI->getSuccessor(i)));
+  for (unsigned i = 0; i < SI->getNumCases(); ++i)
+    Cases.push_back(CaseRange(SI->getCaseValue(i),
+                              SI->getCaseValue(i),
+                              SI->getCaseSuccessor(i)));
   std::sort(Cases.begin(), Cases.end(), CaseCmp());
 
   // Merge case into clusters
@@ -281,7 +281,7 @@ void LowerSwitch::processSwitchInst(SwitchInst *SI) {
   BasicBlock* Default = SI->getDefaultDest();
 
   // If there is only the default destination, don't bother with the code below.
-  if (SI->getNumCases() == 1) {
+  if (!SI->getNumCases()) {
     BranchInst::Create(SI->getDefaultDest(), CurBlock);
     CurBlock->getInstList().erase(SI);
     return;
index d5ae609679f26a49ce83891059cbb09114a6a3e2..a938b9964982b73918bce7a21fc35645d307d192 100644 (file)
@@ -481,8 +481,9 @@ GetValueEqualityComparisonCases(TerminatorInst *TI,
                                                       BasicBlock*> > &Cases) {
   if (SwitchInst *SI = dyn_cast<SwitchInst>(TI)) {
     Cases.reserve(SI->getNumCases());
-    for (unsigned i = 1, e = SI->getNumCases(); i != e; ++i)
-      Cases.push_back(std::make_pair(SI->getCaseValue(i), SI->getSuccessor(i)));
+    for (unsigned i = 0, e = SI->getNumCases(); i != e; ++i)
+      Cases.push_back(std::make_pair(SI->getCaseValue(i),
+                                     SI->getCaseSuccessor(i)));
     return SI->getDefaultDest();
   }
 
@@ -605,11 +606,13 @@ SimplifyEqualityComparisonWithOnlyPredecessor(TerminatorInst *TI,
     DEBUG(dbgs() << "Threading pred instr: " << *Pred->getTerminator()
                  << "Through successor TI: " << *TI);
 
-    for (unsigned i = SI->getNumCases()-1; i != 0; --i)
+    for (unsigned i = SI->getNumCases(); i != 0;) {
+      --i;
       if (DeadCases.count(SI->getCaseValue(i))) {
-        SI->getSuccessor(i)->removePredecessor(TI->getParent());
+        SI->getCaseSuccessor(i)->removePredecessor(TI->getParent());
         SI->removeCase(i);
       }
+    }
 
     DEBUG(dbgs() << "Leaving: " << *TI << "\n");
     return true;
@@ -2007,8 +2010,10 @@ static bool SimplifySwitchOnSelect(SwitchInst *SI, SelectInst *Select) {
 
   // Find the relevant condition and destinations.
   Value *Condition = Select->getCondition();
-  BasicBlock *TrueBB = SI->getSuccessor(SI->findCaseValue(TrueVal));
-  BasicBlock *FalseBB = SI->getSuccessor(SI->findCaseValue(FalseVal));
+  unsigned TrueCase = SI->findCaseValue(TrueVal);
+  unsigned FalseCase = SI->findCaseValue(FalseVal);
+  BasicBlock *TrueBB = SI->getSuccessor(SI->resolveSuccessorIndex(TrueCase));
+  BasicBlock *FalseBB = SI->getSuccessor(SI->resolveSuccessorIndex(FalseCase));
 
   // Perform the actual simplification.
   return SimplifyTerminatorOnSelect(SI, Condition, TrueBB, FalseBB);
@@ -2092,7 +2097,7 @@ static bool TryToSimplifyUncondBranchWithICmpInIt(ICmpInst *ICI,
   // Ok, the block is reachable from the default dest.  If the constant we're
   // comparing exists in one of the other edges, then we can constant fold ICI
   // and zap it.
-  if (SI->findCaseValue(Cst) != 0) {
+  if (SI->findCaseValue(Cst) != SwitchInst::ErrorIndex) {
     Value *V;
     if (ICI->getPredicate() == ICmpInst::ICMP_EQ)
       V = ConstantInt::getFalse(BB->getContext());
@@ -2465,8 +2470,8 @@ bool SimplifyCFGOpt::SimplifyUnreachable(UnreachableInst *UI) {
         }
       }
     } else if (SwitchInst *SI = dyn_cast<SwitchInst>(TI)) {
-      for (unsigned i = 1, e = SI->getNumCases(); i != e; ++i)
-        if (SI->getSuccessor(i) == BB) {
+      for (unsigned i = 0, e = SI->getNumCases(); i != e; ++i)
+        if (SI->getCaseSuccessor(i) == BB) {
           BB->removePredecessor(SI->getParent());
           SI->removeCase(i);
           --i; --e;
@@ -2474,11 +2479,11 @@ bool SimplifyCFGOpt::SimplifyUnreachable(UnreachableInst *UI) {
         }
       // If the default value is unreachable, figure out the most popular
       // destination and make it the default.
-      if (SI->getSuccessor(0) == BB) {
+      if (SI->getDefaultDest() == BB) {
         std::map<BasicBlock*, std::pair<unsigned, unsigned> > Popularity;
-        for (unsigned i = 1, e = SI->getNumCases(); i != e; ++i) {
+        for (unsigned i = 0, e = SI->getNumCases(); i != e; ++i) {
           std::pair<unsigned, unsigned> &entry =
-              Popularity[SI->getSuccessor(i)];
+              Popularity[SI->getCaseSuccessor(i)];
           if (entry.first == 0) {
             entry.first = 1;
             entry.second = i;
@@ -2503,7 +2508,7 @@ bool SimplifyCFGOpt::SimplifyUnreachable(UnreachableInst *UI) {
         if (MaxBlock) {
           // Make this the new default, allowing us to delete any explicit
           // edges to it.
-          SI->setSuccessor(0, MaxBlock);
+          SI->setDefaultDest(MaxBlock);
           Changed = true;
           
           // If MaxBlock has phinodes in it, remove MaxPop-1 entries from
@@ -2512,8 +2517,8 @@ bool SimplifyCFGOpt::SimplifyUnreachable(UnreachableInst *UI) {
             for (unsigned i = 0; i != MaxPop-1; ++i)
               MaxBlock->removePredecessor(SI->getParent());
           
-          for (unsigned i = 1, e = SI->getNumCases(); i != e; ++i)
-            if (SI->getSuccessor(i) == MaxBlock) {
+          for (unsigned i = 0, e = SI->getNumCases(); i != e; ++i)
+            if (SI->getCaseSuccessor(i) == MaxBlock) {
               SI->removeCase(i);
               --i; --e;
             }
@@ -2555,17 +2560,17 @@ bool SimplifyCFGOpt::SimplifyUnreachable(UnreachableInst *UI) {
 /// TurnSwitchRangeIntoICmp - Turns a switch with that contains only a
 /// integer range comparison into a sub, an icmp and a branch.
 static bool TurnSwitchRangeIntoICmp(SwitchInst *SI, IRBuilder<> &Builder) {
-  assert(SI->getNumCases() > 2 && "Degenerate switch?");
+  assert(SI->getNumCases() > 1 && "Degenerate switch?");
 
   // Make sure all cases point to the same destination and gather the values.
   SmallVector<ConstantInt *, 16> Cases;
-  Cases.push_back(SI->getCaseValue(1));
-  for (unsigned I = 2, E = SI->getNumCases(); I != E; ++I) {
-    if (SI->getSuccessor(I-1) != SI->getSuccessor(I))
+  Cases.push_back(SI->getCaseValue(0));
+  for (unsigned I = 1, E = SI->getNumCases(); I != E; ++I) {
+    if (SI->getCaseSuccessor(I-1) != SI->getCaseSuccessor(I))
       return false;
     Cases.push_back(SI->getCaseValue(I));
   }
-  assert(Cases.size() == SI->getNumCases()-1 && "Not all cases gathered");
+  assert(Cases.size() == SI->getNumCases() && "Not all cases gathered");
 
   // Sort the case values, then check if they form a range we can transform.
   array_pod_sort(Cases.begin(), Cases.end(), ConstantIntSortPredicate);
@@ -2575,18 +2580,18 @@ static bool TurnSwitchRangeIntoICmp(SwitchInst *SI, IRBuilder<> &Builder) {
   }
 
   Constant *Offset = ConstantExpr::getNeg(Cases.back());
-  Constant *NumCases = ConstantInt::get(Offset->getType(), SI->getNumCases()-1);
+  Constant *NumCases = ConstantInt::get(Offset->getType(), SI->getNumCases());
 
   Value *Sub = SI->getCondition();
   if (!Offset->isNullValue())
     Sub = Builder.CreateAdd(Sub, Offset, Sub->getName()+".off");
   Value *Cmp = Builder.CreateICmpULT(Sub, NumCases, "switch");
-  Builder.CreateCondBr(Cmp, SI->getSuccessor(1), SI->getDefaultDest());
+  Builder.CreateCondBr(Cmp, SI->getCaseSuccessor(0), SI->getDefaultDest());
 
   // Prune obsolete incoming values off the successor's PHI nodes.
-  for (BasicBlock::iterator BBI = SI->getSuccessor(1)->begin();
+  for (BasicBlock::iterator BBI = SI->getCaseSuccessor(0)->begin();
        isa<PHINode>(BBI); ++BBI) {
-    for (unsigned I = 0, E = SI->getNumCases()-2; I != E; ++I)
+    for (unsigned I = 0, E = SI->getNumCases()-1; I != E; ++I)
       cast<PHINode>(BBI)->removeIncomingValue(SI->getParent());
   }
   SI->eraseFromParent();
@@ -2604,7 +2609,7 @@ static bool EliminateDeadSwitchCases(SwitchInst *SI) {
 
   // Gather dead cases.
   SmallVector<ConstantInt*, 8> DeadCases;
-  for (unsigned I = 1, E = SI->getNumCases(); I != E; ++I) {
+  for (unsigned I = 0, E = SI->getNumCases(); I != E; ++I) {
     if ((SI->getCaseValue(I)->getValue() & KnownZero) != 0 ||
         (SI->getCaseValue(I)->getValue() & KnownOne) != KnownOne) {
       DeadCases.push_back(SI->getCaseValue(I));
@@ -2616,8 +2621,10 @@ static bool EliminateDeadSwitchCases(SwitchInst *SI) {
   // Remove dead cases from the switch.
   for (unsigned I = 0, E = DeadCases.size(); I != E; ++I) {
     unsigned Case = SI->findCaseValue(DeadCases[I]);
+    assert(Case != SwitchInst::ErrorIndex &&
+           "Case was not found. Probably mistake in DeadCases forming.");
     // Prune unused values from PHI nodes.
-    SI->getSuccessor(Case)->removePredecessor(SI->getParent());
+    SI->getCaseSuccessor(Case)->removePredecessor(SI->getParent());
     SI->removeCase(Case);
   }
 
@@ -2666,9 +2673,9 @@ static bool ForwardSwitchConditionToPHI(SwitchInst *SI) {
   typedef DenseMap<PHINode*, SmallVector<int,4> > ForwardingNodesMap;
   ForwardingNodesMap ForwardingNodes;
 
-  for (unsigned I = 1; I < SI->getNumCases(); ++I) { // 0 is the default case.
+  for (unsigned I = 0; I < SI->getNumCases(); ++I) { // 0 is the default case.
     ConstantInt *CaseValue = SI->getCaseValue(I);
-    BasicBlock *CaseDest = SI->getSuccessor(I);
+    BasicBlock *CaseDest = SI->getCaseSuccessor(I);
 
     int PhiIndex;
     PHINode *PHI = FindPHIForConditionForwarding(CaseValue, CaseDest,
index eb0f66196deea8a574416b220b89674c60b68239..e6576c5bf7efb0e1c5d3a351aa070c9bc35f5372 100644 (file)
@@ -1738,13 +1738,12 @@ void AssemblyWriter::printInstruction(const Instruction &I) {
     Out << ", ";
     writeOperand(SI.getDefaultDest(), true);
     Out << " [";
-    // Skip the first item since that's the default case.
     unsigned NumCases = SI.getNumCases();
-    for (unsigned i = 1; i < NumCases; ++i) {
+    for (unsigned i = 0; i < NumCases; ++i) {
       Out << "\n    ";
       writeOperand(SI.getCaseValue(i), true);
       Out << ", ";
-      writeOperand(SI.getSuccessor(i), true);
+      writeOperand(SI.getCaseSuccessor(i), true);
     }
     Out << "\n  ]";
   } else if (isa<IndirectBrInst>(I)) {
index 301791dd0beb183a8c5ad0b16f2a4191bb4d585a..c0e6844271f6250b50901aa9f2deb7ca6861e678 100644 (file)
@@ -3195,31 +3195,29 @@ SwitchInst::~SwitchInst() {
 /// addCase - Add an entry to the switch instruction...
 ///
 void SwitchInst::addCase(ConstantInt *OnVal, BasicBlock *Dest) {
+  unsigned NewCaseIdx = getNumCases(); 
   unsigned OpNo = NumOperands;
   if (OpNo+2 > ReservedSpace)
     growOperands();  // Get more space!
   // Initialize some new operands.
   assert(OpNo+1 < ReservedSpace && "Growing didn't work!");
   NumOperands = OpNo+2;
-  OperandList[OpNo] = OnVal;
-  OperandList[OpNo+1] = Dest;
+  setCaseValue(NewCaseIdx, OnVal);
+  setCaseSuccessor(NewCaseIdx, Dest);
 }
 
-/// removeCase - This method removes the specified successor from the switch
-/// instruction.  Note that this cannot be used to remove the default
-/// destination (successor #0).
-///
+/// removeCase - This method removes the specified case and its successor
+/// from the switch instruction.
 void SwitchInst::removeCase(unsigned idx) {
-  assert(idx != 0 && "Cannot remove the default case!");
-  assert(idx*2 < getNumOperands() && "Successor index out of range!!!");
+  assert(2 + idx*2 < getNumOperands() && "Case index out of range!!!");
 
   unsigned NumOps = getNumOperands();
   Use *OL = OperandList;
 
   // Overwrite this case with the end of the list.
-  if ((idx + 1) * 2 != NumOps) {
-    OL[idx * 2] = OL[NumOps - 2];
-    OL[idx * 2 + 1] = OL[NumOps - 1];
+  if (2 + (idx + 1) * 2 != NumOps) {
+    OL[2 + idx * 2] = OL[NumOps - 2];
+    OL[2 + idx * 2 + 1] = OL[NumOps - 1];
   }
 
   // Nuke the last value.
index b678f251b3f12693b7133e572f95db6c5c3a16d7..642930352f4a18a9693b1192a0dcde899d86058f 100644 (file)
@@ -812,7 +812,7 @@ void Verifier::visitSwitchInst(SwitchInst &SI) {
   // have the same type as the switched-on value.
   Type *SwitchTy = SI.getCondition()->getType();
   SmallPtrSet<ConstantInt*, 32> Constants;
-  for (unsigned i = 1, e = SI.getNumCases(); i != e; ++i) {
+  for (unsigned i = 0, e = SI.getNumCases(); i != e; ++i) {
     Assert1(SI.getCaseValue(i)->getType() == SwitchTy,
             "Switch constants must all be same type as switch value!", &SI);
     Assert2(Constants.insert(SI.getCaseValue(i)),
index e827b23a73253519d7c41daf8aaf38ee34cc6590..8113fd4c667c336120d5d5a9ea028dc4cfc38043 100644 (file)
@@ -319,13 +319,13 @@ class FunctionDifferenceEngine {
       bool Difference = false;
 
       DenseMap<ConstantInt*,BasicBlock*> LCases;
-      for (unsigned I = 1, E = LI->getNumCases(); I != E; ++I)
-        LCases[LI->getCaseValue(I)] = LI->getSuccessor(I);
-      for (unsigned I = 1, E = RI->getNumCases(); I != E; ++I) {
+      for (unsigned I = 0, E = LI->getNumCases(); I != E; ++I)
+        LCases[LI->getCaseValue(I)] = LI->getCaseSuccessor(I);
+      for (unsigned I = 0, E = RI->getNumCases(); I != E; ++I) {
         ConstantInt *CaseValue = RI->getCaseValue(I);
         BasicBlock *LCase = LCases[CaseValue];
         if (LCase) {
-          if (TryUnify) tryUnify(LCase, RI->getSuccessor(I));
+          if (TryUnify) tryUnify(LCase, RI->getCaseSuccessor(I));
           LCases.erase(CaseValue);
         } else if (Complain || !Difference) {
           if (Complain)