@@ -2450,6 +2450,77 @@ static bool EliminateDeadSwitchCases(SwitchInst *SI) {
2450
2450
return !DeadCases.empty ();
2451
2451
}
2452
2452
2453
+ // / FindPHIForConditionForwarding - If BB would be eligible for simplification
2454
+ // / by TryToSimplifyUncondBranchFromEmptyBlock (i.e. it is empty and terminated
2455
+ // / by an unconditional branch), look at the phi node for BB in the successor
2456
+ // / block and see if the incoming value is equal to CaseValue. If so, return
2457
+ // / the phi node, and set PhiIndex to BB's index in the phi node.
2458
+ static PHINode *FindPHIForConditionForwarding (ConstantInt *CaseValue,
2459
+ BasicBlock *BB,
2460
+ int *PhiIndex) {
2461
+ if (BB->getFirstNonPHIOrDbg () != BB->getTerminator ())
2462
+ return NULL ; // BB must be empty to be a candidate for simplification.
2463
+ if (!BB->getSinglePredecessor ())
2464
+ return NULL ; // BB must be dominated by the switch.
2465
+
2466
+ BranchInst *Branch = dyn_cast<BranchInst>(BB->getTerminator ());
2467
+ if (!Branch || !Branch->isUnconditional ())
2468
+ return NULL ; // Terminator must be unconditional branch.
2469
+
2470
+ BasicBlock *Succ = Branch->getSuccessor (0 );
2471
+
2472
+ BasicBlock::iterator I = Succ->begin ();
2473
+ while (PHINode *PHI = dyn_cast<PHINode>(I++)) {
2474
+ int Idx = PHI->getBasicBlockIndex (BB);
2475
+ assert (Idx >= 0 && " PHI has no entry for predecessor?" );
2476
+
2477
+ Value *InValue = PHI->getIncomingValue (Idx);
2478
+ if (InValue != CaseValue) continue ;
2479
+
2480
+ *PhiIndex = Idx;
2481
+ return PHI;
2482
+ }
2483
+
2484
+ return NULL ;
2485
+ }
2486
+
2487
+ // / ForwardSwitchConditionToPHI - Try to forward the condition of a switch
2488
+ // / instruction to a phi node dominated by the switch, if that would mean that
2489
+ // / some of the destination blocks of the switch can be folded away.
2490
+ // / Returns true if a change is made.
2491
+ static bool ForwardSwitchConditionToPHI (SwitchInst *SI) {
2492
+ typedef DenseMap<PHINode*, SmallVector<int ,4 > > ForwardingNodesMap;
2493
+ ForwardingNodesMap ForwardingNodes;
2494
+
2495
+ for (unsigned I = 1 ; I < SI->getNumCases (); ++I) { // 0 is the default case.
2496
+ ConstantInt *CaseValue = SI->getCaseValue (I);
2497
+ BasicBlock *CaseDest = SI->getSuccessor (I);
2498
+
2499
+ int PhiIndex;
2500
+ PHINode *PHI = FindPHIForConditionForwarding (CaseValue, CaseDest,
2501
+ &PhiIndex);
2502
+ if (!PHI) continue ;
2503
+
2504
+ ForwardingNodes[PHI].push_back (PhiIndex);
2505
+ }
2506
+
2507
+ bool Changed = false ;
2508
+
2509
+ for (ForwardingNodesMap::iterator I = ForwardingNodes.begin (),
2510
+ E = ForwardingNodes.end (); I != E; ++I) {
2511
+ PHINode *Phi = I->first ;
2512
+ SmallVector<int ,4 > &Indexes = I->second ;
2513
+
2514
+ if (Indexes.size () < 2 ) continue ;
2515
+
2516
+ for (size_t I = 0 , E = Indexes.size (); I != E; ++I)
2517
+ Phi->setIncomingValue (Indexes[I], SI->getCondition ());
2518
+ Changed = true ;
2519
+ }
2520
+
2521
+ return Changed;
2522
+ }
2523
+
2453
2524
bool SimplifyCFGOpt::SimplifySwitch (SwitchInst *SI, IRBuilder<> &Builder) {
2454
2525
// If this switch is too complex to want to look at, ignore it.
2455
2526
if (!isValueEqualityComparison (SI))
@@ -2486,6 +2557,9 @@ bool SimplifyCFGOpt::SimplifySwitch(SwitchInst *SI, IRBuilder<> &Builder) {
2486
2557
if (EliminateDeadSwitchCases (SI))
2487
2558
return SimplifyCFG (BB) | true ;
2488
2559
2560
+ if (ForwardSwitchConditionToPHI (SI))
2561
+ return SimplifyCFG (BB) | true ;
2562
+
2489
2563
return false ;
2490
2564
}
2491
2565
0 commit comments