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