33
33
#include " llvm/ADT/ArrayRef.h"
34
34
#include " llvm/ADT/DenseMap.h"
35
35
#include " llvm/ADT/MapVector.h"
36
+ #include " llvm/ADT/STLExtras.h"
36
37
#include " llvm/ADT/SetVector.h"
37
38
#include " llvm/ADT/SmallPtrSet.h"
38
39
#include " llvm/ADT/SmallVector.h"
@@ -1536,57 +1537,6 @@ static Value *matchCondition(BranchInst *BI, BasicBlock *LoopEntry,
1536
1537
return nullptr ;
1537
1538
}
1538
1539
1539
- // / getCandidateResInstr - If there is strlen calculated, return the Result
1540
- // / instruction based on the \p OpWidth passed, else return nullptr
1541
- static Instruction *getCandidateResInstr (Instruction *EndAddress,
1542
- Value *StartAddress,
1543
- unsigned OpWidth) {
1544
- using namespace llvm ::PatternMatch;
1545
-
1546
- assert (StartAddress && " Valid start address required." );
1547
-
1548
- // lambda expression to check that the instruction has a single user
1549
- auto GetSingleUser = [](Instruction *I) -> User * {
1550
- if (I->hasOneUse ())
1551
- return *I->user_begin ();
1552
- return nullptr ;
1553
- };
1554
-
1555
- // The pointer to the end address should only have one use which is a pointer
1556
- // to int instruction.
1557
- auto *TmpUser = GetSingleUser (EndAddress);
1558
- if (!TmpUser)
1559
- return nullptr ;
1560
-
1561
- if (PtrToIntInst *PToI = dyn_cast<PtrToIntInst>(TmpUser)) {
1562
- // The only user of the PtrToIntInst should be the sub instruction that
1563
- // calculates the difference b/w the two pointer operands.
1564
- TmpUser = GetSingleUser (PToI);
1565
- if (!TmpUser)
1566
- return nullptr ;
1567
- Instruction *Inst = dyn_cast<Instruction>(TmpUser);
1568
-
1569
- if (!Inst || Inst->getOpcode () != Instruction::Sub ||
1570
- Inst->getOperand (0 ) != PToI)
1571
- return nullptr ;
1572
- Value *MatchAddr;
1573
- if (match (Inst->getOperand (1 ), m_PtrToInt (m_Value (MatchAddr)))) {
1574
- if (MatchAddr != StartAddress)
1575
- return nullptr ;
1576
-
1577
- // We found the candidate sub instruction
1578
- switch (OpWidth) {
1579
- case 8 :
1580
- return Inst;
1581
- default :
1582
- return nullptr ;
1583
- }
1584
- }
1585
- }
1586
-
1587
- return nullptr ;
1588
- }
1589
-
1590
1540
// / Recognizes a strlen idiom by checking for loops that increment
1591
1541
// / a char pointer and then subtract with the base pointer.
1592
1542
// /
@@ -1595,22 +1545,19 @@ static Instruction *getCandidateResInstr(Instruction *EndAddress,
1595
1545
// /
1596
1546
// / The core idiom we are trying to detect is:
1597
1547
// / \code
1598
- // / if (str == NULL)
1599
- // / goto loop-exit // the precondition of the loop
1600
1548
// / start = str;
1601
1549
// / do {
1602
1550
// / str++;
1603
- // / } while(*str!='\0');
1604
- // / return (str - start);
1605
- // / loop-exit:
1551
+ // / } while(*str != '\0');
1606
1552
// / \endcode
1607
1553
// /
1608
1554
// / The transformed output is similar to below c-code:
1609
1555
// / \code
1610
- // / if (str == NULL)
1611
- // / goto loop-exit // the precondition of the loop
1612
- // / return strlen(str);
1556
+ // / str = start + strlen(start)
1557
+ // / len = str - start
1613
1558
// / \endcode
1559
+ // /
1560
+ // / Later the pointer subtraction will be folded by InstCombine
1614
1561
bool LoopIdiomRecognize::recognizeAndInsertStrLen () {
1615
1562
if (DisableLIRPStrlen)
1616
1563
return false ;
@@ -1620,30 +1567,20 @@ bool LoopIdiomRecognize::recognizeAndInsertStrLen() {
1620
1567
return false ;
1621
1568
1622
1569
// It should have a preheader containing nothing but an unconditional branch.
1623
- auto *Pre = CurLoop->getLoopPreheader ();
1624
- if (!Pre || &Pre ->front () != Pre ->getTerminator ())
1570
+ auto *Preheader = CurLoop->getLoopPreheader ();
1571
+ if (!Preheader || &Preheader ->front () != Preheader ->getTerminator ())
1625
1572
return false ;
1626
1573
1627
- auto *EntryBI = dyn_cast<BranchInst>(Pre ->getTerminator ());
1574
+ auto *EntryBI = dyn_cast<BranchInst>(Preheader ->getTerminator ());
1628
1575
if (!EntryBI || EntryBI->isConditional ())
1629
1576
return false ;
1630
1577
1631
- // It should have a precondition block
1632
- auto *PreCondBB = Pre->getSinglePredecessor ();
1633
- if (!PreCondBB)
1634
- return false ;
1635
-
1636
- // The precondition terminator instruction should skip the loop body based on
1637
- // an icmp with zero/null.
1638
- if (!matchCondition (dyn_cast<BranchInst>(PreCondBB->getTerminator ()), Pre))
1639
- return false ;
1640
-
1641
1578
// The loop exit must be conditioned on an icmp with 0.
1642
1579
// The icmp operand has to be a load on some SSA reg that increments
1643
1580
// by 1 in the loop.
1644
- auto *LoopBody = *( CurLoop->block_begin () );
1645
- auto *LoopTerm = dyn_cast<BranchInst>(LoopBody->getTerminator ());
1646
- auto *LoopCond = matchCondition (LoopTerm, LoopBody);
1581
+ BasicBlock *LoopBody = *CurLoop->block_begin ();
1582
+ BranchInst *LoopTerm = dyn_cast<BranchInst>(LoopBody->getTerminator ());
1583
+ Value *LoopCond = matchCondition (LoopTerm, LoopBody);
1647
1584
1648
1585
if (!LoopCond)
1649
1586
return false ;
@@ -1660,6 +1597,7 @@ bool LoopIdiomRecognize::recognizeAndInsertStrLen() {
1660
1597
// the loop, indicating strlen calculation.
1661
1598
auto *IncPtr = LoopLoad->getPointerOperand ();
1662
1599
const SCEVAddRecExpr *LoadEv = dyn_cast<SCEVAddRecExpr>(SE->getSCEV (IncPtr));
1600
+
1663
1601
if (!LoadEv || LoadEv->getLoop () != CurLoop || !LoadEv->isAffine ())
1664
1602
return false ;
1665
1603
@@ -1700,6 +1638,7 @@ bool LoopIdiomRecognize::recognizeAndInsertStrLen() {
1700
1638
if (!LCSSAPhi || !SE->isSCEVable (LCSSAPhi->getType ()))
1701
1639
return false ;
1702
1640
1641
+ // This matched the pointer version of the idiom
1703
1642
if (LCSSAPhi->getIncomingValueForBlock (LoopBody) !=
1704
1643
LoopLoad->getPointerOperand ())
1705
1644
return false ;
@@ -1712,35 +1651,34 @@ bool LoopIdiomRecognize::recognizeAndInsertStrLen() {
1712
1651
return false ;
1713
1652
1714
1653
// We can now expand the base of the str
1715
- IRBuilder<> Builder (Pre ->getTerminator ());
1654
+ IRBuilder<> Builder (Preheader ->getTerminator ());
1716
1655
1717
- PHINode *LoopPhi = &* LoopBody->phis (). begin ();
1718
- if (!LoopPhi || ++LoopBody-> phis (). begin () != LoopBody-> phis (). end ( ))
1656
+ auto LoopPhiRange = LoopBody->phis ();
1657
+ if (!hasNItems (LoopPhiRange, 1 ))
1719
1658
return false ;
1720
- Value *PreVal = LoopBody->phis ().begin ()->getIncomingValueForBlock (Pre);
1659
+ auto *LoopPhi = &*LoopPhiRange.begin ();
1660
+ Value *PreVal = LoopPhi->getIncomingValueForBlock (Preheader);
1721
1661
if (!PreVal)
1722
1662
return false ;
1723
1663
1724
1664
Value *Expanded = nullptr ;
1665
+ Type *ExpandedType = nullptr ;
1725
1666
if (auto *GEP = dyn_cast<GetElementPtrInst>(LoopLoad->getPointerOperand ())) {
1726
1667
if (GEP->getPointerOperand () != LoopPhi)
1727
1668
return false ;
1728
1669
GetElementPtrInst *NewGEP =
1729
1670
GetElementPtrInst::Create (GEP->getSourceElementType (), PreVal,
1730
1671
SmallVector<Value *, 4 >(GEP->indices ()),
1731
- " newgep" , Pre ->getTerminator ());
1672
+ " newgep" , Preheader ->getTerminator ());
1732
1673
Expanded = NewGEP;
1733
- } else if (LoopLoad->getPointerOperand () == LoopPhi)
1674
+ ExpandedType = NewGEP->getSourceElementType ();
1675
+ } else if (LoopLoad->getPointerOperand () == LoopPhi) {
1734
1676
Expanded = PreVal;
1677
+ ExpandedType = LoopLoad->getType ();
1678
+ }
1735
1679
if (!Expanded)
1736
1680
return false ;
1737
1681
1738
- // Check that the LoopExitBB is calculating the string length and identify
1739
- // the instruction that has the string length calculation
1740
- Instruction *ResInst = getCandidateResInstr (LCSSAPhi, PreVal, OpWidth);
1741
- if (!ResInst)
1742
- return false ;
1743
-
1744
1682
// Ensure that the GEP has the correct index if the pointer was modified.
1745
1683
// This can happen when the pointer in the user code, outside the loop,
1746
1684
// walks past a certain pre-checked index of the string.
@@ -1786,11 +1724,12 @@ bool LoopIdiomRecognize::recognizeAndInsertStrLen() {
1786
1724
1787
1725
assert (StrLenFunc && " Failed to emit strlen function." );
1788
1726
1789
- // Replace the subtraction instruction by the result of strlen
1790
- ResInst->replaceAllUsesWith (StrLenFunc);
1791
-
1792
- // Remove the loop-exit branch and delete dead instructions
1793
- RecursivelyDeleteTriviallyDeadInstructions (ResInst, TLI);
1727
+ // Replace LCSSA Phi use with new pointer to the null terminator
1728
+ SmallVector<Value *, 4 > NewBaseIndex{StrLenFunc};
1729
+ GetElementPtrInst *NewEndPtr = GetElementPtrInst::Create (
1730
+ ExpandedType, Expanded, NewBaseIndex, " end" , Preheader->getTerminator ());
1731
+ LCSSAPhi->replaceAllUsesWith (NewEndPtr);
1732
+ RecursivelyDeleteDeadPHINode (LCSSAPhi);
1794
1733
1795
1734
ConstantInt *NewLoopCond = LoopTerm->getSuccessor (0 ) == LoopBody
1796
1735
? Builder.getFalse ()
@@ -1805,7 +1744,7 @@ bool LoopIdiomRecognize::recognizeAndInsertStrLen() {
1805
1744
1806
1745
ORE.emit ([&]() {
1807
1746
return OptimizationRemark (DEBUG_TYPE, " recognizeAndInsertStrLen" ,
1808
- CurLoop->getStartLoc (), Pre )
1747
+ CurLoop->getStartLoc (), Preheader )
1809
1748
<< " Transformed pointer difference into a call to strlen() function" ;
1810
1749
});
1811
1750
0 commit comments