@@ -1420,65 +1420,65 @@ EliminateDuplicatePHINodesNaiveImpl(BasicBlock *BB,
14201420 return Changed;
14211421}
14221422
1423- static bool
1424- EliminateDuplicatePHINodesSetBasedImpl (BasicBlock *BB,
1425- SmallPtrSetImpl<PHINode *> &ToRemove) {
1426- // This implementation doesn't currently consider undef operands
1427- // specially. Theoretically, two phis which are identical except for
1428- // one having an undef where the other doesn't could be collapsed.
1423+ // This implementation doesn't currently consider undef operands
1424+ // specially. Theoretically, two phis which are identical except for
1425+ // one having an undef where the other doesn't could be collapsed.
14291426
1430- struct PHIDenseMapInfo {
1431- static PHINode *getEmptyKey () {
1432- return DenseMapInfo<PHINode *>::getEmptyKey ();
1433- }
1427+ struct PHIDenseMapInfo {
1428+ static PHINode *getEmptyKey () {
1429+ return DenseMapInfo<PHINode *>::getEmptyKey ();
1430+ }
14341431
1435- static PHINode *getTombstoneKey () {
1436- return DenseMapInfo<PHINode *>::getTombstoneKey ();
1437- }
1432+ static PHINode *getTombstoneKey () {
1433+ return DenseMapInfo<PHINode *>::getTombstoneKey ();
1434+ }
14381435
1439- static bool isSentinel (PHINode *PN) {
1440- return PN == getEmptyKey () || PN == getTombstoneKey ();
1441- }
1436+ static bool isSentinel (const PHINode *PN) {
1437+ return PN == getEmptyKey () || PN == getTombstoneKey ();
1438+ }
14421439
1443- // WARNING: this logic must be kept in sync with
1444- // Instruction::isIdenticalToWhenDefined()!
1445- static unsigned getHashValueImpl (PHINode *PN) {
1446- // Compute a hash value on the operands. Instcombine will likely have
1447- // sorted them, which helps expose duplicates, but we have to check all
1448- // the operands to be safe in case instcombine hasn't run.
1449- return static_cast <unsigned >(
1450- hash_combine (hash_combine_range (PN->operand_values ()),
1451- hash_combine_range (PN->blocks ())));
1452- }
1440+ // WARNING: this logic must be kept in sync with
1441+ // Instruction::isIdenticalToWhenDefined()!
1442+ static unsigned getHashValueImpl (const PHINode *PN) {
1443+ // Compute a hash value on the operands. Instcombine will likely have
1444+ // sorted them, which helps expose duplicates, but we have to check all
1445+ // the operands to be safe in case instcombine hasn't run.
1446+ return static_cast <unsigned >(
1447+ hash_combine (hash_combine_range (PN->operand_values ()),
1448+ hash_combine_range (PN->blocks ())));
1449+ }
14531450
1454- static unsigned getHashValue (PHINode *PN) {
1451+ static unsigned getHashValue (const PHINode *PN) {
14551452#ifndef NDEBUG
1456- // If -phicse-debug-hash was specified, return a constant -- this
1457- // will force all hashing to collide, so we'll exhaustively search
1458- // the table for a match, and the assertion in isEqual will fire if
1459- // there's a bug causing equal keys to hash differently.
1460- if (PHICSEDebugHash)
1461- return 0 ;
1453+ // If -phicse-debug-hash was specified, return a constant -- this
1454+ // will force all hashing to collide, so we'll exhaustively search
1455+ // the table for a match, and the assertion in isEqual will fire if
1456+ // there's a bug causing equal keys to hash differently.
1457+ if (PHICSEDebugHash)
1458+ return 0 ;
14621459#endif
1463- return getHashValueImpl (PN);
1464- }
1460+ return getHashValueImpl (PN);
1461+ }
14651462
1466- static bool isEqualImpl (PHINode *LHS, PHINode *RHS) {
1467- if (isSentinel (LHS) || isSentinel (RHS))
1468- return LHS == RHS;
1469- return LHS->isIdenticalTo (RHS);
1470- }
1463+ static bool isEqualImpl (const PHINode *LHS, const PHINode *RHS) {
1464+ if (isSentinel (LHS) || isSentinel (RHS))
1465+ return LHS == RHS;
1466+ return LHS->isIdenticalTo (RHS);
1467+ }
14711468
1472- static bool isEqual (PHINode *LHS, PHINode *RHS) {
1473- // These comparisons are nontrivial, so assert that equality implies
1474- // hash equality (DenseMap demands this as an invariant).
1475- bool Result = isEqualImpl (LHS, RHS);
1476- assert (!Result || (isSentinel (LHS) && LHS == RHS) ||
1477- getHashValueImpl (LHS) == getHashValueImpl (RHS));
1478- return Result;
1479- }
1480- };
1469+ static bool isEqual (const PHINode *LHS, const PHINode *RHS) {
1470+ // These comparisons are nontrivial, so assert that equality implies
1471+ // hash equality (DenseMap demands this as an invariant).
1472+ bool Result = isEqualImpl (LHS, RHS);
1473+ assert (!Result || (isSentinel (LHS) && LHS == RHS) ||
1474+ getHashValueImpl (LHS) == getHashValueImpl (RHS));
1475+ return Result;
1476+ }
1477+ };
14811478
1479+ static bool
1480+ EliminateDuplicatePHINodesSetBasedImpl (BasicBlock *BB,
1481+ SmallPtrSetImpl<PHINode *> &ToRemove) {
14821482 // Set of unique PHINodes.
14831483 DenseSet<PHINode *, PHIDenseMapInfo> PHISet;
14841484 PHISet.reserve (4 * PHICSENumPHISmallSize);
@@ -1525,6 +1525,111 @@ bool llvm::EliminateDuplicatePHINodes(BasicBlock *BB) {
15251525 return Changed;
15261526}
15271527
1528+ #ifndef NDEBUG // Should this be under EXPENSIVE_CHECKS?
1529+ // New PHI nodes should not reference one another but they may reference
1530+ // themselves or existing PHI nodes, and existing PHI nodes may reference new
1531+ // PHI nodes.
1532+ static bool
1533+ PHIAreRefEachOther (const iterator_range<BasicBlock::phi_iterator> &NewPHIs) {
1534+ SmallPtrSet<PHINode *, 8 > NewPHISet;
1535+ for (PHINode &PN : NewPHIs)
1536+ NewPHISet.insert (&PN);
1537+ for (PHINode &PHI : NewPHIs) {
1538+ for (Value *V : PHI.incoming_values ()) {
1539+ PHINode *IncPHI = dyn_cast<PHINode>(V);
1540+ if (IncPHI && IncPHI != &PHI && NewPHISet.contains (IncPHI))
1541+ return true ;
1542+ }
1543+ }
1544+ return false ;
1545+ }
1546+ #endif
1547+
1548+ bool EliminateNewDuplicatePHINodesN2 (BasicBlock *BB,
1549+ BasicBlock::phi_iterator FirstExistingPN) {
1550+ auto ReplaceIfIdentical = [](PHINode &PHI, PHINode &ReplPHI) {
1551+ if (!PHI.isIdenticalToWhenDefined (&ReplPHI))
1552+ return false ;
1553+ PHI.replaceAllUsesWith (&ReplPHI);
1554+ PHI.eraseFromParent ();
1555+ return true ;
1556+ };
1557+
1558+ // Deduplicate new PHIs first to reduce the number of comparisons on the
1559+ // following new -> existing pass.
1560+ bool Changed = false ;
1561+ for (auto I = BB->phis ().begin (); I != FirstExistingPN; ++I) {
1562+ for (auto J = std::next (I); J != FirstExistingPN;) {
1563+ Changed |= ReplaceIfIdentical (*J++, *I);
1564+ }
1565+ }
1566+
1567+ // Iterate over existing PHIs and replace identical new PHIs.
1568+ for (PHINode &ExistingPHI : make_range (FirstExistingPN, BB->phis ().end ())) {
1569+ auto I = BB->phis ().begin ();
1570+ assert (I != FirstExistingPN); // Should be at least one new PHI.
1571+ do {
1572+ Changed |= ReplaceIfIdentical (*I++, ExistingPHI);
1573+ } while (I != FirstExistingPN);
1574+ if (BB->phis ().begin () == FirstExistingPN)
1575+ return Changed;
1576+ }
1577+ return Changed;
1578+ }
1579+
1580+ bool EliminateNewDuplicatePHINodesSet (
1581+ BasicBlock *BB, BasicBlock::phi_iterator FirstExistingPN) {
1582+ auto Replace = [](PHINode &PHI, PHINode &ReplPHI) {
1583+ PHI.replaceAllUsesWith (&ReplPHI);
1584+ PHI.eraseFromParent ();
1585+ return true ;
1586+ };
1587+
1588+ DenseSet<PHINode *, PHIDenseMapInfo> NewPHISet;
1589+ NewPHISet.reserve (4 * PHICSENumPHISmallSize);
1590+
1591+ // Deduplicate new PHIs, note that NewPHISet remains consistent because new
1592+ // PHIs are not reference each other.
1593+ bool Changed = false ;
1594+ for (PHINode &NewPHI :
1595+ make_early_inc_range (make_range (BB->phis ().begin (), FirstExistingPN))) {
1596+ auto [I, Inserted] = NewPHISet.insert (&NewPHI);
1597+ if (!Inserted)
1598+ Changed |= Replace (NewPHI, **I);
1599+ }
1600+
1601+ // Iterate over existing PHIs and replace matching new PHIs.
1602+ for (PHINode &ExistingPHI : make_range (FirstExistingPN, BB->phis ().end ())) {
1603+ assert (!NewPHISet.empty ()); // Should be at least one new PHI.
1604+ auto I = NewPHISet.find (&ExistingPHI);
1605+ if (I == NewPHISet.end ())
1606+ continue ;
1607+ Changed |= Replace (**I, ExistingPHI);
1608+ NewPHISet.erase (I);
1609+ if (NewPHISet.empty ())
1610+ return Changed;
1611+ }
1612+ return Changed;
1613+ }
1614+
1615+ bool llvm::EliminateNewDuplicatePHINodes (
1616+ BasicBlock *BB, BasicBlock::phi_iterator FirstExistingPN) {
1617+
1618+ if (hasNItemsOrLess (BB->phis (), 1 ))
1619+ return false ;
1620+
1621+ auto NewPHIs = make_range (BB->phis ().begin (), FirstExistingPN);
1622+ assert (!PHIAreRefEachOther (NewPHIs));
1623+
1624+ // Both functions perform identical pass over existing PHIs and differ in time
1625+ // spent on new PHI duplicate check which depends on the number of new PHIs.
1626+ // Therefore make a choice based on the number of new PHIs and not the total
1627+ // number of PHIs in the block.
1628+ return hasNItemsOrLess (NewPHIs, PHICSENumPHISmallSize)
1629+ ? EliminateNewDuplicatePHINodesN2 (BB, FirstExistingPN)
1630+ : EliminateNewDuplicatePHINodesSet (BB, FirstExistingPN);
1631+ }
1632+
15281633Align llvm::tryEnforceAlignment (Value *V, Align PrefAlign,
15291634 const DataLayout &DL) {
15301635 V = V->stripPointerCasts ();
0 commit comments