3333#include " llvm/ADT/ArrayRef.h"
3434#include " llvm/ADT/DenseMap.h"
3535#include " llvm/ADT/MapVector.h"
36+ #include " llvm/ADT/STLExtras.h"
3637#include " llvm/ADT/SetVector.h"
3738#include " llvm/ADT/SmallPtrSet.h"
3839#include " llvm/ADT/SmallVector.h"
@@ -1536,57 +1537,6 @@ static Value *matchCondition(BranchInst *BI, BasicBlock *LoopEntry,
15361537 return nullptr ;
15371538}
15381539
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-
15901540// / Recognizes a strlen idiom by checking for loops that increment
15911541// / a char pointer and then subtract with the base pointer.
15921542// /
@@ -1595,22 +1545,19 @@ static Instruction *getCandidateResInstr(Instruction *EndAddress,
15951545// /
15961546// / The core idiom we are trying to detect is:
15971547// / \code
1598- // / if (str == NULL)
1599- // / goto loop-exit // the precondition of the loop
16001548// / start = str;
16011549// / do {
16021550// / str++;
1603- // / } while(*str!='\0');
1604- // / return (str - start);
1605- // / loop-exit:
1551+ // / } while(*str != '\0');
16061552// / \endcode
16071553// /
16081554// / The transformed output is similar to below c-code:
16091555// / \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
16131558// / \endcode
1559+ // /
1560+ // / Later the pointer subtraction will be folded by InstCombine
16141561bool LoopIdiomRecognize::recognizeAndInsertStrLen () {
16151562 if (DisableLIRPStrlen)
16161563 return false ;
@@ -1620,30 +1567,20 @@ bool LoopIdiomRecognize::recognizeAndInsertStrLen() {
16201567 return false ;
16211568
16221569 // 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 ())
16251572 return false ;
16261573
1627- auto *EntryBI = dyn_cast<BranchInst>(Pre ->getTerminator ());
1574+ auto *EntryBI = dyn_cast<BranchInst>(Preheader ->getTerminator ());
16281575 if (!EntryBI || EntryBI->isConditional ())
16291576 return false ;
16301577
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-
16411578 // The loop exit must be conditioned on an icmp with 0.
16421579 // The icmp operand has to be a load on some SSA reg that increments
16431580 // 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);
16471584
16481585 if (!LoopCond)
16491586 return false ;
@@ -1660,6 +1597,7 @@ bool LoopIdiomRecognize::recognizeAndInsertStrLen() {
16601597 // the loop, indicating strlen calculation.
16611598 auto *IncPtr = LoopLoad->getPointerOperand ();
16621599 const SCEVAddRecExpr *LoadEv = dyn_cast<SCEVAddRecExpr>(SE->getSCEV (IncPtr));
1600+
16631601 if (!LoadEv || LoadEv->getLoop () != CurLoop || !LoadEv->isAffine ())
16641602 return false ;
16651603
@@ -1700,6 +1638,7 @@ bool LoopIdiomRecognize::recognizeAndInsertStrLen() {
17001638 if (!LCSSAPhi || !SE->isSCEVable (LCSSAPhi->getType ()))
17011639 return false ;
17021640
1641+ // This matched the pointer version of the idiom
17031642 if (LCSSAPhi->getIncomingValueForBlock (LoopBody) !=
17041643 LoopLoad->getPointerOperand ())
17051644 return false ;
@@ -1712,35 +1651,34 @@ bool LoopIdiomRecognize::recognizeAndInsertStrLen() {
17121651 return false ;
17131652
17141653 // We can now expand the base of the str
1715- IRBuilder<> Builder (Pre ->getTerminator ());
1654+ IRBuilder<> Builder (Preheader ->getTerminator ());
17161655
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 ))
17191658 return false ;
1720- Value *PreVal = LoopBody->phis ().begin ()->getIncomingValueForBlock (Pre);
1659+ auto *LoopPhi = &*LoopPhiRange.begin ();
1660+ Value *PreVal = LoopPhi->getIncomingValueForBlock (Preheader);
17211661 if (!PreVal)
17221662 return false ;
17231663
17241664 Value *Expanded = nullptr ;
1665+ Type *ExpandedType = nullptr ;
17251666 if (auto *GEP = dyn_cast<GetElementPtrInst>(LoopLoad->getPointerOperand ())) {
17261667 if (GEP->getPointerOperand () != LoopPhi)
17271668 return false ;
17281669 GetElementPtrInst *NewGEP =
17291670 GetElementPtrInst::Create (GEP->getSourceElementType (), PreVal,
17301671 SmallVector<Value *, 4 >(GEP->indices ()),
1731- " newgep" , Pre ->getTerminator ());
1672+ " newgep" , Preheader ->getTerminator ());
17321673 Expanded = NewGEP;
1733- } else if (LoopLoad->getPointerOperand () == LoopPhi)
1674+ ExpandedType = NewGEP->getSourceElementType ();
1675+ } else if (LoopLoad->getPointerOperand () == LoopPhi) {
17341676 Expanded = PreVal;
1677+ ExpandedType = LoopLoad->getType ();
1678+ }
17351679 if (!Expanded)
17361680 return false ;
17371681
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-
17441682 // Ensure that the GEP has the correct index if the pointer was modified.
17451683 // This can happen when the pointer in the user code, outside the loop,
17461684 // walks past a certain pre-checked index of the string.
@@ -1786,11 +1724,12 @@ bool LoopIdiomRecognize::recognizeAndInsertStrLen() {
17861724
17871725 assert (StrLenFunc && " Failed to emit strlen function." );
17881726
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);
17941733
17951734 ConstantInt *NewLoopCond = LoopTerm->getSuccessor (0 ) == LoopBody
17961735 ? Builder.getFalse ()
@@ -1805,7 +1744,7 @@ bool LoopIdiomRecognize::recognizeAndInsertStrLen() {
18051744
18061745 ORE.emit ([&]() {
18071746 return OptimizationRemark (DEBUG_TYPE, " recognizeAndInsertStrLen" ,
1808- CurLoop->getStartLoc (), Pre )
1747+ CurLoop->getStartLoc (), Preheader )
18091748 << " Transformed pointer difference into a call to strlen() function" ;
18101749 });
18111750
0 commit comments