29
29
#include " llvm/IR/Intrinsics.h"
30
30
#include " llvm/IR/PatternMatch.h"
31
31
32
+ #define LV_NAME " loop-vectorize"
33
+ #define DEBUG_TYPE LV_NAME
34
+
32
35
using namespace llvm ;
33
36
34
37
void VPlanTransforms::VPInstructionsToVPRecipes (
@@ -1674,25 +1677,24 @@ static bool supportedLoad(VPWidenRecipe *R0, VPValue *V, unsigned Idx) {
1674
1677
return false ;
1675
1678
}
1676
1679
1677
- // / Returns true of \p IR is a consecutive interleave group with \p VF members.
1680
+ // / Returns true if \p IR is a full interleave group with factor and number of
1681
+ // / members both equal to \p VF.
1678
1682
static bool isConsecutiveInterleaveGroup (VPInterleaveRecipe *IR,
1679
1683
ElementCount VF) {
1680
1684
if (!IR)
1681
1685
return false ;
1682
1686
auto IG = IR->getInterleaveGroup ();
1683
1687
return IG->getFactor () == IG->getNumMembers () &&
1684
- IG->getNumMembers () == VF.getKnownMinValue ();
1688
+ IG->getNumMembers () == VF.getFixedValue ();
1685
1689
}
1686
1690
1687
- bool VPlanTransforms::narrowInterleaveGroups (VPlan &Plan, ElementCount VF) {
1691
+ void VPlanTransforms::narrowInterleaveGroups (VPlan &Plan, ElementCount VF) {
1688
1692
using namespace llvm ::VPlanPatternMatch;
1689
1693
if (VF.isScalable ())
1690
- return false ;
1694
+ return ;
1691
1695
1692
- bool Changed = false ;
1693
1696
SmallVector<VPInterleaveRecipe *> StoreGroups;
1694
- for (auto &R : make_early_inc_range (
1695
- *Plan.getVectorLoopRegion ()->getEntryBasicBlock ())) {
1697
+ for (auto &R : *Plan.getVectorLoopRegion ()->getEntryBasicBlock ()) {
1696
1698
if (match (&R, m_BranchOnCount (m_VPValue (), m_VPValue ())) ||
1697
1699
isa<VPCanonicalIVPHIRecipe>(&R))
1698
1700
continue ;
@@ -1701,38 +1703,43 @@ bool VPlanTransforms::narrowInterleaveGroups(VPlan &Plan, ElementCount VF) {
1701
1703
// * phi recipes other than the canonical induction
1702
1704
// * recipes writing to memory except interleave groups
1703
1705
// Only support plans with a canonical induction phi.
1704
- if ((R.isPhi () && !isa<VPCanonicalIVPHIRecipe>(&R)) ||
1705
- (R.mayWriteToMemory () && !isa<VPInterleaveRecipe>(&R)))
1706
- return false ;
1706
+ if (R.isPhi ())
1707
+ return ;
1707
1708
1708
1709
auto *IR = dyn_cast<VPInterleaveRecipe>(&R);
1710
+ if (R.mayWriteToMemory () && !IR)
1711
+ return ;
1712
+
1709
1713
if (!IR)
1710
1714
continue ;
1711
1715
1712
1716
if (!isConsecutiveInterleaveGroup (IR, VF))
1713
- return false ;
1717
+ return ;
1714
1718
if (IR->getStoredValues ().empty ())
1715
1719
continue ;
1716
1720
1717
1721
auto *Lane0 = dyn_cast_or_null<VPWidenRecipe>(
1718
1722
IR->getStoredValues ()[0 ]->getDefiningRecipe ());
1719
1723
if (!Lane0)
1720
- return false ;
1724
+ return ;
1721
1725
for (const auto &[I, V] : enumerate(IR->getStoredValues ())) {
1722
1726
auto *R = dyn_cast<VPWidenRecipe>(V->getDefiningRecipe ());
1723
1727
if (!R || R->getOpcode () != Lane0->getOpcode ())
1724
- return false ;
1728
+ return ;
1725
1729
// Work around captured structured bindings being a C++20 extension.
1726
1730
auto Idx = I;
1727
1731
if (any_of (R->operands (), [Lane0, Idx](VPValue *V) {
1728
1732
return !supportedLoad (Lane0, V, Idx);
1729
1733
}))
1730
- return false ;
1734
+ return ;
1731
1735
}
1732
1736
1733
1737
StoreGroups.push_back (IR);
1734
1738
}
1735
1739
1740
+ if (StoreGroups.empty ())
1741
+ return ;
1742
+
1736
1743
// Narrow operation tree rooted at store groups.
1737
1744
for (auto *StoreGroup : StoreGroups) {
1738
1745
auto *Lane0 = cast<VPWidenRecipe>(
@@ -1769,18 +1776,14 @@ bool VPlanTransforms::narrowInterleaveGroups(VPlan &Plan, ElementCount VF) {
1769
1776
StoreGroup->getDebugLoc ());
1770
1777
S->insertBefore (StoreGroup);
1771
1778
StoreGroup->eraseFromParent ();
1772
- Changed = true ;
1773
1779
}
1774
1780
1775
- if (!Changed)
1776
- return false ;
1777
-
1778
1781
// Adjust induction to reflect that the transformed plan only processes one
1779
1782
// original iteration.
1780
1783
auto *CanIV = Plan.getCanonicalIV ();
1781
1784
VPInstruction *Inc = cast<VPInstruction>(CanIV->getBackedgeValue ());
1782
1785
Inc->setOperand (
1783
1786
1 , Plan.getOrAddLiveIn (ConstantInt::get (CanIV->getScalarType (), 1 )));
1784
1787
removeDeadRecipes (Plan);
1785
- return true ;
1788
+ LLVM_DEBUG ( dbgs () << " Narrowed interleave \n " ) ;
1786
1789
}
0 commit comments