@@ -283,7 +283,7 @@ static APInt constructOperandMask(ArrayRef<int64_t> Indices) {
283
283
284
284
static void
285
285
processSTIPredicate (STIPredicateFunction &Fn,
286
- const DenseMap<Record *, unsigned > &ProcModelMap) {
286
+ const ProcModelMapTy &ProcModelMap) {
287
287
DenseMap<const Record *, unsigned > Opcode2Index;
288
288
using OpcodeMapPair = std::pair<const Record *, OpcodeInfo>;
289
289
std::vector<OpcodeMapPair> OpcodeMappings;
@@ -1338,8 +1338,7 @@ class PredTransitions {
1338
1338
PredTransitions (CodeGenSchedModels &sm): SchedModels(sm) {}
1339
1339
1340
1340
bool substituteVariantOperand (const SmallVectorImpl<unsigned > &RWSeq,
1341
- bool IsRead, bool IsForAnyCPU,
1342
- unsigned StartIdx);
1341
+ bool IsRead, unsigned StartIdx);
1343
1342
1344
1343
bool substituteVariants (const PredTransition &Trans);
1345
1344
@@ -1413,29 +1412,6 @@ bool PredTransitions::mutuallyExclusive(Record *PredDef,
1413
1412
return false ;
1414
1413
}
1415
1414
1416
- static bool hasAliasedVariants (const CodeGenSchedRW &RW,
1417
- CodeGenSchedModels &SchedModels) {
1418
- if (RW.HasVariants )
1419
- return true ;
1420
-
1421
- for (Record *Alias : RW.Aliases ) {
1422
- const CodeGenSchedRW &AliasRW =
1423
- SchedModels.getSchedRW (Alias->getValueAsDef (" AliasRW" ));
1424
- if (AliasRW.HasVariants )
1425
- return true ;
1426
- if (AliasRW.IsSequence ) {
1427
- IdxVec ExpandedRWs;
1428
- SchedModels.expandRWSequence (AliasRW.Index , ExpandedRWs, AliasRW.IsRead );
1429
- for (unsigned SI : ExpandedRWs) {
1430
- if (hasAliasedVariants (SchedModels.getSchedRW (SI, AliasRW.IsRead ),
1431
- SchedModels))
1432
- return true ;
1433
- }
1434
- }
1435
- }
1436
- return false ;
1437
- }
1438
-
1439
1415
static std::vector<Record *> getAllPredicates (ArrayRef<TransVariant> Variants,
1440
1416
ArrayRef<unsigned > ProcIndices) {
1441
1417
std::vector<Record *> Preds;
@@ -1613,21 +1589,7 @@ pushVariant(const TransVariant &VInfo, bool IsRead) {
1613
1589
// starts. RWSeq must be applied to all transitions between StartIdx and the end
1614
1590
// of TransVec.
1615
1591
bool PredTransitions::substituteVariantOperand (
1616
- const SmallVectorImpl<unsigned > &RWSeq, bool IsRead, bool IsForAnyCPU,
1617
- unsigned StartIdx) {
1618
-
1619
- auto CollectAndAddVariants = [&](unsigned TransIdx,
1620
- const CodeGenSchedRW &SchedRW) {
1621
- // Distribute this partial PredTransition across intersecting variants.
1622
- // This will push a copies of TransVec[TransIdx] on the back of TransVec.
1623
- std::vector<TransVariant> IntersectingVariants;
1624
- getIntersectingVariants (SchedRW, TransIdx, IntersectingVariants);
1625
- // Now expand each variant on top of its copy of the transition.
1626
- for (const TransVariant &IV : IntersectingVariants)
1627
- pushVariant (IV, IsRead);
1628
- return !IntersectingVariants.empty ();
1629
- };
1630
-
1592
+ const SmallVectorImpl<unsigned > &RWSeq, bool IsRead, unsigned StartIdx) {
1631
1593
bool Subst = false ;
1632
1594
// Visit each original RW within the current sequence.
1633
1595
for (SmallVectorImpl<unsigned >::const_iterator
@@ -1636,35 +1598,24 @@ bool PredTransitions::substituteVariantOperand(
1636
1598
// Push this RW on all partial PredTransitions or distribute variants.
1637
1599
// New PredTransitions may be pushed within this loop which should not be
1638
1600
// revisited (TransEnd must be loop invariant).
1639
- bool HasAliases = false , WasPushed = false ;
1640
1601
for (unsigned TransIdx = StartIdx, TransEnd = TransVec.size ();
1641
1602
TransIdx != TransEnd; ++TransIdx) {
1642
- // In the common case, push RW onto the current operand's sequence.
1643
- if (!hasAliasedVariants (SchedRW, SchedModels)) {
1603
+ // Distribute this partial PredTransition across intersecting variants.
1604
+ // This will push a copies of TransVec[TransIdx] on the back of TransVec.
1605
+ std::vector<TransVariant> IntersectingVariants;
1606
+ getIntersectingVariants (SchedRW, TransIdx, IntersectingVariants);
1607
+ // Now expand each variant on top of its copy of the transition.
1608
+ for (const TransVariant &IV : IntersectingVariants)
1609
+ pushVariant (IV, IsRead);
1610
+ if (IntersectingVariants.empty ()) {
1644
1611
if (IsRead)
1645
1612
TransVec[TransIdx].ReadSequences .back ().push_back (*RWI);
1646
1613
else
1647
1614
TransVec[TransIdx].WriteSequences .back ().push_back (*RWI);
1648
1615
continue ;
1616
+ } else {
1617
+ Subst = true ;
1649
1618
}
1650
- HasAliases = true ;
1651
- WasPushed |= CollectAndAddVariants (TransIdx, SchedRW);
1652
- Subst |= WasPushed;
1653
- }
1654
- if (IsRead && IsForAnyCPU && HasAliases && !WasPushed) {
1655
- // If we're here this means that in some sched class:
1656
- // a) We have read variant for CPU A
1657
- // b) We have write variant for CPU B
1658
- // b) We don't have write variant for CPU A
1659
- // d) We must expand all read/write variants (IsForAnyCPU is true)
1660
- // e) We couldn't expand SchedRW because TransVec doesn't have
1661
- // any transition with compatible CPU ID.
1662
- // In such case we create new empty transition with zero (AnyCPU)
1663
- // index.
1664
- TransVec.reserve (TransVec.size () + 1 );
1665
- TransVec.emplace_back (TransVec[StartIdx].PredTerm );
1666
- TransVec.back ().ReadSequences .emplace_back ();
1667
- Subst |= CollectAndAddVariants (TransVec.size () - 1 , SchedRW);
1668
1619
}
1669
1620
}
1670
1621
return Subst;
@@ -1683,7 +1634,7 @@ bool PredTransitions::substituteVariants(const PredTransition &Trans) {
1683
1634
bool Subst = false ;
1684
1635
TransVec.emplace_back (Trans.PredTerm , Trans.ProcIndices );
1685
1636
1686
- bool IsForAnyCPU = llvm::count (Trans.ProcIndices , 0 );
1637
+ assert (! llvm::count (Trans.ProcIndices , 0 ) );
1687
1638
// Visit each original write sequence.
1688
1639
for (SmallVectorImpl<SmallVector<unsigned ,4 >>::const_iterator
1689
1640
WSI = Trans.WriteSequences .begin (), WSE = Trans.WriteSequences .end ();
@@ -1693,8 +1644,7 @@ bool PredTransitions::substituteVariants(const PredTransition &Trans) {
1693
1644
TransVec.begin () + StartIdx, E = TransVec.end (); I != E; ++I) {
1694
1645
I->WriteSequences .emplace_back ();
1695
1646
}
1696
- Subst |=
1697
- substituteVariantOperand (*WSI, /* IsRead=*/ false , IsForAnyCPU, StartIdx);
1647
+ Subst |= substituteVariantOperand (*WSI, /* IsRead=*/ false , StartIdx);
1698
1648
}
1699
1649
// Visit each original read sequence.
1700
1650
for (SmallVectorImpl<SmallVector<unsigned ,4 >>::const_iterator
@@ -1705,8 +1655,7 @@ bool PredTransitions::substituteVariants(const PredTransition &Trans) {
1705
1655
TransVec.begin () + StartIdx, E = TransVec.end (); I != E; ++I) {
1706
1656
I->ReadSequences .emplace_back ();
1707
1657
}
1708
- Subst |=
1709
- substituteVariantOperand (*RSI, /* IsRead=*/ true , IsForAnyCPU, StartIdx);
1658
+ Subst |= substituteVariantOperand (*RSI, /* IsRead=*/ true , StartIdx);
1710
1659
}
1711
1660
return Subst;
1712
1661
}
@@ -1745,6 +1694,10 @@ static void inferFromTransitions(ArrayRef<PredTransition> LastTransitions,
1745
1694
// requires creating a new SchedClass.
1746
1695
for (ArrayRef<PredTransition>::iterator
1747
1696
I = LastTransitions.begin (), E = LastTransitions.end (); I != E; ++I) {
1697
+ // Variant expansion (substituteVariants) may create unconditional
1698
+ // transitions. We don't need to build sched classes for them.
1699
+ if (I->PredTerm .empty ())
1700
+ continue ;
1748
1701
IdxVec OperWritesVariant, OperReadsVariant;
1749
1702
addSequences (SchedModels, I->WriteSequences , OperWritesVariant, false );
1750
1703
addSequences (SchedModels, I->ReadSequences , OperReadsVariant, true );
@@ -1777,6 +1730,26 @@ static void inferFromTransitions(ArrayRef<PredTransition> LastTransitions,
1777
1730
}
1778
1731
}
1779
1732
1733
+ std::vector<unsigned > CodeGenSchedModels::getAllProcIndices () const {
1734
+ std::vector<unsigned > ProcIdVec;
1735
+ for (const auto &PM : ProcModelMap)
1736
+ if (PM.second != 0 )
1737
+ ProcIdVec.push_back (PM.second );
1738
+ return ProcIdVec;
1739
+ }
1740
+
1741
+ static std::vector<PredTransition>
1742
+ makePerProcessorTransitions (const PredTransition &Trans,
1743
+ ArrayRef<unsigned > ProcIndices) {
1744
+ std::vector<PredTransition> PerCpuTransVec;
1745
+ for (unsigned ProcId : ProcIndices) {
1746
+ assert (ProcId != 0 );
1747
+ PerCpuTransVec.push_back (Trans);
1748
+ PerCpuTransVec.back ().ProcIndices .assign (1 , ProcId);
1749
+ }
1750
+ return PerCpuTransVec;
1751
+ }
1752
+
1780
1753
// Create new SchedClasses for the given ReadWrite list. If any of the
1781
1754
// ReadWrites refers to a SchedVariant, create a new SchedClass for each variant
1782
1755
// of the ReadWrite list, following Aliases if necessary.
@@ -1812,6 +1785,10 @@ void CodeGenSchedModels::inferFromRW(ArrayRef<unsigned> OperWrites,
1812
1785
}
1813
1786
LLVM_DEBUG (dbgs () << ' \n ' );
1814
1787
1788
+ LastTransitions = makePerProcessorTransitions (
1789
+ LastTransitions[0 ], llvm::count (ProcIndices, 0 )
1790
+ ? ArrayRef<unsigned >(getAllProcIndices ())
1791
+ : ProcIndices);
1815
1792
// Collect all PredTransitions for individual operands.
1816
1793
// Iterate until no variant writes remain.
1817
1794
bool SubstitutedAny;
@@ -1823,9 +1800,6 @@ void CodeGenSchedModels::inferFromRW(ArrayRef<unsigned> OperWrites,
1823
1800
LLVM_DEBUG (Transitions.dump ());
1824
1801
LastTransitions.swap (Transitions.TransVec );
1825
1802
} while (SubstitutedAny);
1826
- // If the first transition has no variants, nothing to do.
1827
- if (LastTransitions[0 ].PredTerm .empty ())
1828
- return ;
1829
1803
1830
1804
// WARNING: We are about to mutate the SchedClasses vector. Do not refer to
1831
1805
// OperWrites, OperReads, or ProcIndices after calling inferFromTransitions.
0 commit comments