-/// \brief Find the instruction we should insert the constant materialization
-/// before.
-static Instruction *getMatInsertPt(Instruction *I, const DominatorTree *DT) {
- if (!isa<PHINode>(I) && !isa<LandingPadInst>(I)) // Simple case.
- return I;
-
- // We can't insert directly before a phi node or landing pad. Insert before
- // the terminator of the dominating block.
- assert(&I->getParent()->getParent()->getEntryBlock() != I->getParent() &&
- "PHI or landing pad in entry block!");
- BasicBlock *IDom = DT->getNode(I->getParent())->getIDom()->getBlock();
- return IDom->getTerminator();
-}
-
-/// \brief Find an insertion point that dominates all uses.
-Instruction *ConstantHoisting::
-FindConstantInsertionPoint(Function &F, const ConstantInfo &CI) const {
- BasicBlock *Entry = &F.getEntryBlock();
-
- // Collect all basic blocks.
- SmallPtrSet<BasicBlock *, 4> BBs;
- ConstantInfo::RebasedConstantListType::const_iterator RCI, RCE;
- for (RCI = CI.RebasedConstants.begin(), RCE = CI.RebasedConstants.end();
- RCI != RCE; ++RCI)
- for (SmallVectorImpl<User *>::const_iterator U = RCI->Uses.begin(),
- E = RCI->Uses.end(); U != E; ++U)
- CollectBasicBlocks(BBs, F, *U);
-
- if (BBs.count(Entry))
- return getMatInsertPt(&Entry->front(), DT);
-
- while (BBs.size() >= 2) {
- BasicBlock *BB, *BB1, *BB2;
- BB1 = *BBs.begin();
- BB2 = *std::next(BBs.begin());
- BB = DT->findNearestCommonDominator(BB1, BB2);
- if (BB == Entry)
- return getMatInsertPt(&Entry->front(), DT);
- BBs.erase(BB1);
- BBs.erase(BB2);
- BBs.insert(BB);
+/// \brief Updates the operand at Idx in instruction Inst with the result of
+/// instruction Mat. If the instruction is a PHI node then special
+/// handling for duplicate values form the same incomming basic block is
+/// required.
+/// \return The update will always succeed, but the return value indicated if
+/// Mat was used for the update or not.
+static bool updateOperand(Instruction *Inst, unsigned Idx, Instruction *Mat) {
+ if (auto PHI = dyn_cast<PHINode>(Inst)) {
+ // Check if any previous operand of the PHI node has the same incoming basic
+ // block. This is a very odd case that happens when the incoming basic block
+ // has a switch statement. In this case use the same value as the previous
+ // operand(s), otherwise we will fail verification due to different values.
+ // The values are actually the same, but the variable names are different
+ // and the verifier doesn't like that.
+ BasicBlock *IncomingBB = PHI->getIncomingBlock(Idx);
+ for (unsigned i = 0; i < Idx; ++i) {
+ if (PHI->getIncomingBlock(i) == IncomingBB) {
+ Value *IncomingVal = PHI->getIncomingValue(i);
+ Inst->setOperand(Idx, IncomingVal);
+ return false;
+ }
+ }