+
+MachineBasicBlock *PHIElimination::SplitCriticalEdge(MachineBasicBlock *A,
+ MachineBasicBlock *B) {
+ assert(A && B && "Missing MBB end point");
+
+ MachineFunction *MF = A->getParent();
+
+ // We may need to update A's terminator, but we can't do that if AnalyzeBranch
+ // fails. If A uses a jump table, we won't touch it.
+ const TargetInstrInfo *TII = MF->getTarget().getInstrInfo();
+ MachineBasicBlock *TBB = 0, *FBB = 0;
+ SmallVector<MachineOperand, 4> Cond;
+ if (TII->AnalyzeBranch(*A, TBB, FBB, Cond))
+ return NULL;
+
+ ++NumSplits;
+
+ MachineBasicBlock *NMBB = MF->CreateMachineBasicBlock();
+ MF->insert(llvm::next(MachineFunction::iterator(A)), NMBB);
+ DEBUG(dbgs() << "PHIElimination splitting critical edge:"
+ " BB#" << A->getNumber()
+ << " -- BB#" << NMBB->getNumber()
+ << " -- BB#" << B->getNumber() << '\n');
+
+ A->ReplaceUsesOfBlockWith(B, NMBB);
+ A->updateTerminator();
+
+ // Insert unconditional "jump B" instruction in NMBB if necessary.
+ NMBB->addSuccessor(B);
+ if (!NMBB->isLayoutSuccessor(B)) {
+ Cond.clear();
+ MF->getTarget().getInstrInfo()->InsertBranch(*NMBB, B, NULL, Cond);
+ }
+
+ // Fix PHI nodes in B so they refer to NMBB instead of A
+ for (MachineBasicBlock::iterator i = B->begin(), e = B->end();
+ i != e && i->getOpcode() == TargetInstrInfo::PHI; ++i)
+ for (unsigned ni = 1, ne = i->getNumOperands(); ni != ne; ni += 2)
+ if (i->getOperand(ni+1).getMBB() == A)
+ i->getOperand(ni+1).setMBB(NMBB);
+
+ if (LiveVariables *LV=getAnalysisIfAvailable<LiveVariables>())
+ LV->addNewBlock(NMBB, A, B);
+
+ if (MachineDominatorTree *MDT=getAnalysisIfAvailable<MachineDominatorTree>())
+ MDT->addNewBlock(NMBB, A);
+
+ return NMBB;
+}
+
+unsigned
+PHIElimination::PHINodeTraits::getHashValue(const MachineInstr *MI) {
+ if (!MI || MI==getEmptyKey() || MI==getTombstoneKey())
+ return DenseMapInfo<MachineInstr*>::getHashValue(MI);
+ unsigned hash = 0;
+ for (unsigned ni = 1, ne = MI->getNumOperands(); ni != ne; ni += 2)
+ hash = hash*37 + DenseMapInfo<BBVRegPair>::
+ getHashValue(BBVRegPair(MI->getOperand(ni+1).getMBB()->getNumber(),
+ MI->getOperand(ni).getReg()));
+ return hash;
+}
+
+bool PHIElimination::PHINodeTraits::isEqual(const MachineInstr *LHS,
+ const MachineInstr *RHS) {
+ const MachineInstr *EmptyKey = getEmptyKey();
+ const MachineInstr *TombstoneKey = getTombstoneKey();
+ if (!LHS || !RHS || LHS==EmptyKey || RHS==EmptyKey ||
+ LHS==TombstoneKey || RHS==TombstoneKey)
+ return LHS==RHS;
+
+ unsigned ne = LHS->getNumOperands();
+ if (ne != RHS->getNumOperands())
+ return false;
+ // Ignore operand 0, the defined register.
+ for (unsigned ni = 1; ni != ne; ni += 2)
+ if (LHS->getOperand(ni).getReg() != RHS->getOperand(ni).getReg() ||
+ LHS->getOperand(ni+1).getMBB() != RHS->getOperand(ni+1).getMBB())
+ return false;
+ return true;
+}