@@ -97,6 +97,7 @@ using namespace llvm;
97
97
STATISTIC (NumMemSet, " Number of memset's formed from loop stores" );
98
98
STATISTIC (NumMemCpy, " Number of memcpy's formed from loop load+stores" );
99
99
STATISTIC (NumMemMove, " Number of memmove's formed from loop load+stores" );
100
+ STATISTIC (NumStrLen, " Number of strlen's formed from loop loads" );
100
101
STATISTIC (
101
102
NumShiftUntilBitTest,
102
103
" Number of uncountable loops recognized as 'shift until bitttest' idiom" );
@@ -126,6 +127,14 @@ static cl::opt<bool, true>
126
127
cl::location(DisableLIRP::Memcpy), cl::init(false ),
127
128
cl::ReallyHidden);
128
129
130
+ bool DisableLIRP::Strlen;
131
+ static cl::opt<bool , true >
132
+ DisableLIRPStrlen (" disable-" DEBUG_TYPE " -strlen" ,
133
+ cl::desc (" Proceed with loop idiom recognize pass, but do "
134
+ " not convert loop(s) to strlen." ),
135
+ cl::location(DisableLIRP::Strlen), cl::init(false ),
136
+ cl::ReallyHidden);
137
+
129
138
static cl::opt<bool > UseLIRCodeSizeHeurs (
130
139
" use-lir-code-size-heurs" ,
131
140
cl::desc (" Use loop idiom recognition code size heuristics when compiling"
@@ -246,6 +255,7 @@ class LoopIdiomRecognize {
246
255
247
256
bool recognizeShiftUntilBitTest ();
248
257
bool recognizeShiftUntilZero ();
258
+ bool recognizeAndInsertStrLen ();
249
259
250
260
// / @}
251
261
};
@@ -1507,9 +1517,11 @@ static Value *matchCondition(BranchInst *BI, BasicBlock *LoopEntry,
1507
1517
if (!Cond)
1508
1518
return nullptr ;
1509
1519
1510
- ConstantInt *CmpZero = dyn_cast<ConstantInt>(Cond->getOperand (1 ));
1511
- if (!CmpZero || !CmpZero->isZero ())
1512
- return nullptr ;
1520
+ if (!isa<ConstantPointerNull>(Cond->getOperand (1 ))) {
1521
+ ConstantInt *CmpZero = dyn_cast<ConstantInt>(Cond->getOperand (1 ));
1522
+ if (!CmpZero || !CmpZero->isZero ())
1523
+ return nullptr ;
1524
+ }
1513
1525
1514
1526
BasicBlock *TrueSucc = BI->getSuccessor (0 );
1515
1527
BasicBlock *FalseSucc = BI->getSuccessor (1 );
@@ -1524,6 +1536,284 @@ static Value *matchCondition(BranchInst *BI, BasicBlock *LoopEntry,
1524
1536
return nullptr ;
1525
1537
}
1526
1538
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
+ // / Recognizes a strlen idiom by checking for loops that increment
1591
+ // / a char pointer and then subtract with the base pointer.
1592
+ // /
1593
+ // / If detected, transforms the relevant code to a strlen function
1594
+ // / call, and returns true; otherwise, returns false.
1595
+ // /
1596
+ // / The core idiom we are trying to detect is:
1597
+ // / \code
1598
+ // / if (str == NULL)
1599
+ // / goto loop-exit // the precondition of the loop
1600
+ // / start = str;
1601
+ // / do {
1602
+ // / str++;
1603
+ // / } while(*str!='\0');
1604
+ // / return (str - start);
1605
+ // / loop-exit:
1606
+ // / \endcode
1607
+ // /
1608
+ // / The transformed output is similar to below c-code:
1609
+ // / \code
1610
+ // / if (str == NULL)
1611
+ // / goto loop-exit // the precondition of the loop
1612
+ // / return strlen(str);
1613
+ // / \endcode
1614
+ bool LoopIdiomRecognize::recognizeAndInsertStrLen () {
1615
+ if (DisableLIRPStrlen)
1616
+ return false ;
1617
+
1618
+ // Give up if the loop has multiple blocks or multiple backedges.
1619
+ if (CurLoop->getNumBackEdges () != 1 || CurLoop->getNumBlocks () != 1 )
1620
+ return false ;
1621
+
1622
+ // It should have a preheader containing nothing but an unconditional branch.
1623
+ auto *Pre = CurLoop->getLoopPreheader ();
1624
+ if (!Pre || &Pre->front () != Pre->getTerminator ())
1625
+ return false ;
1626
+
1627
+ auto *EntryBI = dyn_cast<BranchInst>(Pre->getTerminator ());
1628
+ if (!EntryBI || EntryBI->isConditional ())
1629
+ return false ;
1630
+
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
+ // The loop exit must be conditioned on an icmp with 0.
1642
+ // The icmp operand has to be a load on some SSA reg that increments
1643
+ // 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);
1647
+
1648
+ if (!LoopCond)
1649
+ return false ;
1650
+
1651
+ auto *LoopLoad = dyn_cast<LoadInst>(LoopCond);
1652
+ if (!LoopLoad || LoopLoad->getPointerAddressSpace () != 0 )
1653
+ return false ;
1654
+
1655
+ Type *OperandType = LoopLoad->getType ();
1656
+ if (!OperandType || !OperandType->isIntegerTy ())
1657
+ return false ;
1658
+
1659
+ // See if the pointer expression is an AddRec with step 1 ({n,+,1}) on
1660
+ // the loop, indicating strlen calculation.
1661
+ auto *IncPtr = LoopLoad->getPointerOperand ();
1662
+ const SCEVAddRecExpr *LoadEv = dyn_cast<SCEVAddRecExpr>(SE->getSCEV (IncPtr));
1663
+ if (!LoadEv || LoadEv->getLoop () != CurLoop || !LoadEv->isAffine ())
1664
+ return false ;
1665
+
1666
+ const SCEVConstant *Step =
1667
+ dyn_cast<SCEVConstant>(LoadEv->getStepRecurrence (*SE));
1668
+ if (!Step)
1669
+ return false ;
1670
+
1671
+ unsigned int ConstIntValue = 0 ;
1672
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(Step->getValue ()))
1673
+ ConstIntValue = CI->getZExtValue ();
1674
+
1675
+ unsigned OpWidth = OperandType->getIntegerBitWidth ();
1676
+ if (OpWidth != ConstIntValue * 8 )
1677
+ return false ;
1678
+ if (OpWidth != 8 )
1679
+ return false ;
1680
+
1681
+ // Scan every instruction in the loop to ensure there are no side effects.
1682
+ for (auto &I : *LoopBody)
1683
+ if (I.mayHaveSideEffects ())
1684
+ return false ;
1685
+
1686
+ auto *LoopExitBB = CurLoop->getExitBlock ();
1687
+ if (!LoopExitBB)
1688
+ return false ;
1689
+
1690
+ // Check that the loop exit block is valid:
1691
+ // It needs to have exactly one LCSSA Phi which is an AddRec.
1692
+ PHINode *LCSSAPhi = nullptr ;
1693
+ for (PHINode &PN : LoopExitBB->phis ()) {
1694
+ if (!LCSSAPhi && PN.getNumIncomingValues () == 1 )
1695
+ LCSSAPhi = &PN;
1696
+ else
1697
+ return false ;
1698
+ }
1699
+
1700
+ if (!LCSSAPhi || !SE->isSCEVable (LCSSAPhi->getType ()))
1701
+ return false ;
1702
+
1703
+ if (LCSSAPhi->getIncomingValueForBlock (LoopBody) !=
1704
+ LoopLoad->getPointerOperand ())
1705
+ return false ;
1706
+
1707
+ const SCEVAddRecExpr *LCSSAEv =
1708
+ dyn_cast<SCEVAddRecExpr>(SE->getSCEV (LCSSAPhi->getIncomingValue (0 )));
1709
+
1710
+ if (!LCSSAEv || !dyn_cast<SCEVUnknown>(SE->getPointerBase (LCSSAEv)) ||
1711
+ !LCSSAEv->isAffine ())
1712
+ return false ;
1713
+
1714
+ // We can now expand the base of the str
1715
+ IRBuilder<> Builder (Pre->getTerminator ());
1716
+
1717
+ PHINode *LoopPhi = &*LoopBody->phis ().begin ();
1718
+ if (!LoopPhi || ++LoopBody->phis ().begin () != LoopBody->phis ().end ())
1719
+ return false ;
1720
+ Value *PreVal = LoopBody->phis ().begin ()->getIncomingValueForBlock (Pre);
1721
+ if (!PreVal)
1722
+ return false ;
1723
+
1724
+ Value *Expanded = nullptr ;
1725
+ if (auto *GEP = dyn_cast<GetElementPtrInst>(LoopLoad->getPointerOperand ())) {
1726
+ if (GEP->getPointerOperand () != LoopPhi)
1727
+ return false ;
1728
+ GetElementPtrInst *NewGEP =
1729
+ GetElementPtrInst::Create (GEP->getSourceElementType (), PreVal,
1730
+ SmallVector<Value *, 4 >(GEP->indices ()),
1731
+ " newgep" , Pre->getTerminator ());
1732
+ Expanded = NewGEP;
1733
+ } else if (LoopLoad->getPointerOperand () == LoopPhi)
1734
+ Expanded = PreVal;
1735
+ if (!Expanded)
1736
+ return false ;
1737
+
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
+ // Ensure that the GEP has the correct index if the pointer was modified.
1745
+ // This can happen when the pointer in the user code, outside the loop,
1746
+ // walks past a certain pre-checked index of the string.
1747
+ if (auto *GEP = dyn_cast<GEPOperator>(Expanded)) {
1748
+ if (GEP->getNumOperands () != 2 )
1749
+ return false ;
1750
+
1751
+ ConstantInt *I0 = dyn_cast<ConstantInt>(GEP->getOperand (1 ));
1752
+ if (!I0)
1753
+ return false ;
1754
+
1755
+ int64_t Index = I0->getSExtValue (); // GEP index
1756
+ auto *SAdd = dyn_cast<SCEVAddExpr>(LoadEv->getStart ());
1757
+ if (!SAdd || SAdd->getNumOperands () != 2 )
1758
+ return false ;
1759
+
1760
+ auto *SAdd0 = dyn_cast<SCEVConstant>(SAdd->getOperand (0 ));
1761
+ if (!SAdd0)
1762
+ return false ;
1763
+
1764
+ ConstantInt *CInt = SAdd0->getValue (); // SCEV index
1765
+ assert (CInt && " Expecting CInt to be valid." );
1766
+ int64_t Offset = CInt->getSExtValue ();
1767
+
1768
+ // Update the index based on the Offset
1769
+ assert ((Offset * 8 ) % GEP->getSourceElementType ()->getIntegerBitWidth () ==
1770
+ 0 &&
1771
+ " Invalid offset" );
1772
+ int64_t NewIndex =
1773
+ (Offset * 8 ) / GEP->getSourceElementType ()->getIntegerBitWidth () -
1774
+ Index;
1775
+ Value *NewIndexVal =
1776
+ ConstantInt::get (GEP->getOperand (1 )->getType (), NewIndex);
1777
+ GEP->setOperand (1 , NewIndexVal);
1778
+ }
1779
+
1780
+ Value *StrLenFunc = nullptr ;
1781
+ switch (OpWidth) {
1782
+ case 8 :
1783
+ StrLenFunc = emitStrLen (Expanded, Builder, *DL, TLI);
1784
+ break ;
1785
+ }
1786
+
1787
+ assert (StrLenFunc && " Failed to emit strlen function." );
1788
+
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);
1794
+
1795
+ ConstantInt *NewLoopCond = LoopTerm->getSuccessor (0 ) == LoopBody
1796
+ ? Builder.getFalse ()
1797
+ : Builder.getTrue ();
1798
+ LoopTerm->setCondition (NewLoopCond);
1799
+
1800
+ deleteDeadInstruction (cast<Instruction>(LoopCond));
1801
+ deleteDeadInstruction (cast<Instruction>(IncPtr));
1802
+ SE->forgetLoop (CurLoop);
1803
+
1804
+ LLVM_DEBUG (dbgs () << " Formed strlen: " << *StrLenFunc << " \n " );
1805
+
1806
+ ORE.emit ([&]() {
1807
+ return OptimizationRemark (DEBUG_TYPE, " recognizeAndInsertStrLen" ,
1808
+ CurLoop->getStartLoc (), Pre)
1809
+ << " Transformed pointer difference into a call to strlen() function" ;
1810
+ });
1811
+
1812
+ ++NumStrLen;
1813
+
1814
+ return true ;
1815
+ }
1816
+
1527
1817
// / Check if the given conditional branch is based on an unsigned less-than
1528
1818
// / comparison between a variable and a constant, and if the comparison is false
1529
1819
// / the control yields to the loop entry. If the branch matches the behaviour,
0 commit comments