Index: lib/CodeGen/CodeGenPrepare.cpp =================================================================== --- lib/CodeGen/CodeGenPrepare.cpp +++ lib/CodeGen/CodeGenPrepare.cpp @@ -711,9 +711,30 @@ return MadeChange; } +static bool AllUsesDominatedByBlock(Instruction *Inst, BasicBlock *BB, + DominatorTree &DT) { + for (Use &U : Inst->uses()) { + // Determine the block of the use. + Instruction *UseInst = cast(U.getUser()); + BasicBlock *UseBlock = UseInst->getParent(); + if (PHINode *PN = dyn_cast(UseInst)) { + // PHI nodes use the operand in the predecessor block, not the block with + // the PHI. + unsigned Num = PHINode::getIncomingValueNumForOperand(U.getOperandNo()); + UseBlock = PN->getIncomingBlock(Num); + } + // Check that it dominates. + if (!DT.dominates(BB, UseBlock)) + return false; + } + return true; +} + bool CodeGenPrepare::isMergingEmptyBlockProfitable(BasicBlock *BB, BasicBlock *DestBB, bool isPreheader) { + Function &F = *BB->getParent(); + DominatorTree DT(F); // Do not delete loop preheaders if doing so would create a critical edge. // Loop preheaders can be good locations to spill registers. If the // preheader is deleted and we create a critical edge, registers may be @@ -755,6 +776,15 @@ return true; SmallPtrSet SameIncomingValueBBs; + SmallVector PNs; + + bool HasAllUsesDominatedByPred = true; + for (auto DestBBI = DestBB->begin(); + auto *DestPN = dyn_cast(&*DestBBI); ++DestBBI) { + if (HasAllUsesDominatedByPred && !AllUsesDominatedByBlock(DestPN, Pred, DT)) + HasAllUsesDominatedByPred = false; + PNs.push_back(DestPN); + } // Find all other incoming blocks from which incoming values of all PHIs in // DestBB are the same as the ones from BB. @@ -764,16 +794,10 @@ if (DestBBPred == BB) continue; - bool HasAllSameValue = true; - BasicBlock::const_iterator DestBBI = DestBB->begin(); - while (const PHINode *DestPN = dyn_cast(DestBBI++)) { - if (DestPN->getIncomingValueForBlock(BB) != - DestPN->getIncomingValueForBlock(DestBBPred)) { - HasAllSameValue = false; - break; - } - } - if (HasAllSameValue) + if (llvm::none_of(PNs, [&](PHINode *PN) { + return (PN->getIncomingValueForBlock(BB) != + PN->getIncomingValueForBlock(DestBBPred)); + })) SameIncomingValueBBs.insert(DestBBPred); } @@ -783,9 +807,18 @@ if (SameIncomingValueBBs.count(Pred)) return true; + // Check to see if none of the phis have constant incoming values for BB and + // all the uses of phis are dominated by Pred, in such case extra COPYs are + // likely not added, so there is no reason to skip merging. + if (HasAllUsesDominatedByPred && llvm::none_of(PNs, [BB] (PHINode *PN) { + return isa(PN->getIncomingValueForBlock(BB)); + })) { + dbgs()<getName()<<"\n"; + return true; + } + if (!BFI) { - Function &F = *BB->getParent(); - LoopInfo LI{DominatorTree(F)}; + LoopInfo LI{DT}; BPI.reset(new BranchProbabilityInfo(F, LI)); BFI.reset(new BlockFrequencyInfo(F, *BPI, LI)); } Index: test/Transforms/CodeGenPrepare/skip-merging-case-block.ll =================================================================== --- test/Transforms/CodeGenPrepare/skip-merging-case-block.ll +++ test/Transforms/CodeGenPrepare/skip-merging-case-block.ll @@ -3,6 +3,55 @@ target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128" target triple = "aarch64--linux-gnu" +; Expect to skip merge empty block b14 int b16 +; as it is unlikely to be executed. +; CHECK-LABEL: @f_skip_merge +; CHECK-LABEL: b2: +; CHECK i11 0, label %b14 +define i64 @f_skip_merge(i64 %a0, i64 %a1) local_unnamed_addr #0 { +b2: + %v3 = lshr i64 %a1, 52 + %v4 = trunc i64 %v3 to i11 + switch i11 %v4, label %b15 [ + i11 -1, label %b5 + i11 0, label %b14 + ] + +b5: ; preds = %b2 + %cmp = icmp eq i64 %a1, 0 + br i1 %cmp, label %b13, label %b6 + +b6: ; preds = %b5 + %v7 = or i64 %a1, 2251799813685248 + br i1 undef, label %b8, label %b10 + +b8: ; preds = %b6 + %v9 = select i1 undef, i64 %v7, i64 undef + br label %b16 + +b10: ; preds = %b6 + br i1 undef, label %b16, label %b11 + +b11: ; preds = %b10 + %v12 = select i1 undef, i64 undef, i64 %v7 + br label %b16 + +b13: ; preds = %b5 + br label %b16 + +b14: ; preds = %b2 + br label %b16 + +b15: ; preds = %b2 + br label %b16 + +; CHECK-LABEL: b16: +; CHECK %v17 = phi i64 [ -2251799813685248, %b14 ], [ 0, %b15 ], [ %v12, %b11 ], [ %v9, %b8 ], [ %v7, %b10 ], [ 1, %b5 ] +b16: ; preds = %b15, %b14, %b13, %b11, %b10, %b8 + %v17 = phi i64 [ 1, %b13 ], [ -2251799813685248, %b14 ], [ 0, %b15 ], [ %v12, %b11 ], [ %v9, %b8 ], [ %v7, %b10 ] + ret i64 %v17 +} + ; Expect to skip merging two empty blocks (sw.bb and sw.bb2) into sw.epilog ; as both of them are unlikely executed. define i32 @f_switch(i32 %c) {