+// \brief Update the first occurrence of the "switch statement" BB in the PHI
+// node with the "new" BB. The other occurrences will:
+//
+// 1) Be updated by subsequent calls to this function. Switch statements may
+// have more than one outcoming edge into the same BB if they all have the same
+// value. When the switch statement is converted these incoming edges are now
+// coming from multiple BBs.
+// 2) Removed if subsequent incoming values now share the same case, i.e.,
+// multiple outcome edges are condensed into one. This is necessary to keep the
+// number of phi values equal to the number of branches to SuccBB.
+static void fixPhis(BasicBlock *SuccBB, BasicBlock *OrigBB, BasicBlock *NewBB,
+ unsigned NumMergedCases) {
+ for (BasicBlock::iterator I = SuccBB->begin(), IE = SuccBB->getFirstNonPHI();
+ I != IE; ++I) {
+ PHINode *PN = cast<PHINode>(I);
+
+ // Only update the first occurence.
+ unsigned Idx = 0, E = PN->getNumIncomingValues();
+ unsigned LocalNumMergedCases = NumMergedCases;
+ for (; Idx != E; ++Idx) {
+ if (PN->getIncomingBlock(Idx) == OrigBB) {
+ PN->setIncomingBlock(Idx, NewBB);
+ break;
+ }
+ }
+
+ // Remove additional occurences coming from condensed cases and keep the
+ // number of incoming values equal to the number of branches to SuccBB.
+ for (++Idx; LocalNumMergedCases > 0 && Idx < E; ++Idx)
+ if (PN->getIncomingBlock(Idx) == OrigBB) {
+ PN->removeIncomingValue(Idx);
+ LocalNumMergedCases--;
+ }
+ }