16
16
#include " llvm/ADT/BitVector.h"
17
17
#include " llvm/ADT/DenseMap.h"
18
18
#include " llvm/ADT/IntEqClasses.h"
19
+ #include " llvm/ADT/PointerUnion.h"
20
+ #include " llvm/ADT/PostOrderIterator.h"
19
21
#include " llvm/ADT/STLExtras.h"
20
22
#include " llvm/ADT/SetVector.h"
21
23
#include " llvm/ADT/SmallPtrSet.h"
@@ -765,7 +767,8 @@ static void sortAndUniqueRegisters(CodeGenRegister::Vec &M) {
765
767
CodeGenRegisterClass::CodeGenRegisterClass (CodeGenRegBank &RegBank,
766
768
const Record *R)
767
769
: TheDef(R), Name(std::string(R->getName ())),
768
- TopoSigs(RegBank.getNumTopoSigs()), EnumValue(-1 ), TSFlags(0 ) {
770
+ RegsWithSuperRegsTopoSigs(RegBank.getNumTopoSigs()), EnumValue(-1 ),
771
+ TSFlags(0 ) {
769
772
GeneratePressureSet = R->getValueAsBit (" GeneratePressureSet" );
770
773
std::vector<const Record *> TypeList = R->getValueAsListOfDefs (" RegTypes" );
771
774
if (TypeList.empty ())
@@ -791,7 +794,8 @@ CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank,
791
794
const CodeGenRegister *Reg = RegBank.getReg ((*Elements)[i]);
792
795
Members.push_back (Reg);
793
796
Artificial &= Reg->Artificial ;
794
- TopoSigs.set (Reg->getTopoSig ());
797
+ if (!Reg->getSuperRegs ().empty ())
798
+ RegsWithSuperRegsTopoSigs.set (Reg->getTopoSig ());
795
799
}
796
800
sortAndUniqueRegisters (Members);
797
801
@@ -849,13 +853,14 @@ CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank,
849
853
CodeGenRegisterClass::CodeGenRegisterClass (CodeGenRegBank &RegBank,
850
854
StringRef Name, Key Props)
851
855
: Members(*Props.Members), TheDef(nullptr ), Name(std::string(Name)),
852
- TopoSigs (RegBank.getNumTopoSigs()), EnumValue(-1 ), RSI(Props.RSI ),
853
- CopyCost(0 ), Allocatable(true ), AllocationPriority(0 ),
856
+ RegsWithSuperRegsTopoSigs (RegBank.getNumTopoSigs()), EnumValue(-1 ),
857
+ RSI(Props.RSI), CopyCost(0 ), Allocatable(true ), AllocationPriority(0 ),
854
858
GlobalPriority(false ), TSFlags(0 ) {
855
859
Artificial = true ;
856
860
GeneratePressureSet = false ;
857
861
for (const auto R : Members) {
858
- TopoSigs.set (R->getTopoSig ());
862
+ if (!R->getSuperRegs ().empty ())
863
+ RegsWithSuperRegsTopoSigs.set (R->getTopoSig ());
859
864
Artificial &= R->Artificial ;
860
865
}
861
866
}
@@ -1173,6 +1178,28 @@ void CodeGenRegisterClass::buildRegUnitSet(
1173
1178
std::back_inserter (RegUnits));
1174
1179
}
1175
1180
1181
+ // Combine our super classes of the given sub-register index with all of their
1182
+ // super classes in turn.
1183
+ void CodeGenRegisterClass::extendSuperRegClasses (CodeGenSubRegIndex *SubIdx) {
1184
+ auto It = SuperRegClasses.find (SubIdx);
1185
+ if (It == SuperRegClasses.end ())
1186
+ return ;
1187
+
1188
+ SmallVector<CodeGenRegisterClass *> MidRCs;
1189
+ MidRCs.insert (MidRCs.end (), It->second .begin (), It->second .end ());
1190
+
1191
+ for (CodeGenRegisterClass *MidRC : MidRCs) {
1192
+ for (auto &Pair : MidRC->SuperRegClasses ) {
1193
+ CodeGenSubRegIndex *ComposedSubIdx = Pair.first ->compose (SubIdx);
1194
+ if (!ComposedSubIdx)
1195
+ continue ;
1196
+
1197
+ for (CodeGenRegisterClass *SuperRC : Pair.second )
1198
+ addSuperRegClass (ComposedSubIdx, SuperRC);
1199
+ }
1200
+ }
1201
+ }
1202
+
1176
1203
// ===----------------------------------------------------------------------===//
1177
1204
// CodeGenRegisterCategory
1178
1205
// ===----------------------------------------------------------------------===//
@@ -1290,6 +1317,8 @@ CodeGenRegBank::CodeGenRegBank(const RecordKeeper &Records,
1290
1317
}
1291
1318
}
1292
1319
1320
+ computeSubRegIndicesRPOT ();
1321
+
1293
1322
// Native register units are associated with a leaf register. They've all been
1294
1323
// discovered now.
1295
1324
NumNativeRegUnits = RegUnits.size ();
@@ -1364,20 +1393,20 @@ void CodeGenRegBank::addToMaps(CodeGenRegisterClass *RC) {
1364
1393
}
1365
1394
1366
1395
// Create a synthetic sub-class if it is missing.
1367
- CodeGenRegisterClass *
1396
+ std::pair< CodeGenRegisterClass *, bool >
1368
1397
CodeGenRegBank::getOrCreateSubClass (const CodeGenRegisterClass *RC,
1369
1398
const CodeGenRegister::Vec *Members,
1370
1399
StringRef Name) {
1371
1400
// Synthetic sub-class has the same size and alignment as RC.
1372
1401
CodeGenRegisterClass::Key K (Members, RC->RSI );
1373
1402
RCKeyMap::const_iterator FoundI = Key2RC.find (K);
1374
1403
if (FoundI != Key2RC.end ())
1375
- return FoundI->second ;
1404
+ return { FoundI->second , false } ;
1376
1405
1377
1406
// Sub-class doesn't exist, create a new one.
1378
1407
RegClasses.emplace_back (*this , Name, K);
1379
1408
addToMaps (&RegClasses.back ());
1380
- return &RegClasses.back ();
1409
+ return { &RegClasses.back (), true } ;
1381
1410
}
1382
1411
1383
1412
CodeGenRegisterClass *CodeGenRegBank::getRegClass (const Record *Def) const {
@@ -1694,6 +1723,81 @@ void CodeGenRegBank::computeSubRegLaneMasks() {
1694
1723
1695
1724
namespace {
1696
1725
1726
+ // A directed graph on sub-register indices with a virtual source node that
1727
+ // has an arc to all other nodes, and an arc from A to B if sub-register index
1728
+ // B can be obtained by composing A with some other sub-register index.
1729
+ struct SubRegIndexCompositionGraph {
1730
+ std::deque<CodeGenSubRegIndex> &SubRegIndices;
1731
+ CodeGenSubRegIndex::CompMap EntryNode;
1732
+
1733
+ SubRegIndexCompositionGraph (std::deque<CodeGenSubRegIndex> &SubRegIndices)
1734
+ : SubRegIndices(SubRegIndices) {
1735
+ for (CodeGenSubRegIndex &Idx : SubRegIndices) {
1736
+ EntryNode.try_emplace (&Idx, &Idx);
1737
+ }
1738
+ }
1739
+ };
1740
+
1741
+ } // namespace
1742
+
1743
+ template <> struct llvm ::GraphTraits<SubRegIndexCompositionGraph> {
1744
+ using NodeRef =
1745
+ PointerUnion<CodeGenSubRegIndex *, const CodeGenSubRegIndex::CompMap *>;
1746
+
1747
+ // Using a reverse iterator causes sub-register indices to appear in their
1748
+ // more natural order in RPOT.
1749
+ using CompMapIt = CodeGenSubRegIndex::CompMap::const_reverse_iterator;
1750
+ struct ChildIteratorType
1751
+ : public iterator_adaptor_base<
1752
+ ChildIteratorType, CompMapIt,
1753
+ typename std::iterator_traits<CompMapIt>::iterator_category,
1754
+ NodeRef> {
1755
+ ChildIteratorType (CompMapIt I)
1756
+ : ChildIteratorType::iterator_adaptor_base(I) {}
1757
+
1758
+ NodeRef operator *() const { return wrapped ()->second ; }
1759
+ };
1760
+
1761
+ static NodeRef getEntryNode (const SubRegIndexCompositionGraph &G) {
1762
+ return &G.EntryNode ;
1763
+ }
1764
+
1765
+ static const CodeGenSubRegIndex::CompMap *children (NodeRef N) {
1766
+ if (auto *Idx = dyn_cast<CodeGenSubRegIndex *>(N))
1767
+ return &Idx->getComposites ();
1768
+ return cast<const CodeGenSubRegIndex::CompMap *>(N);
1769
+ }
1770
+
1771
+ static ChildIteratorType child_begin (NodeRef N) {
1772
+ return ChildIteratorType (children (N)->rbegin ());
1773
+ }
1774
+ static ChildIteratorType child_end (NodeRef N) {
1775
+ return ChildIteratorType (children (N)->rend ());
1776
+ }
1777
+
1778
+ static auto nodes_begin (SubRegIndexCompositionGraph *G) {
1779
+ return G->SubRegIndices .begin ();
1780
+ }
1781
+ static auto nodes_end (SubRegIndexCompositionGraph *G) {
1782
+ return G->SubRegIndices .end ();
1783
+ }
1784
+
1785
+ static unsigned size (SubRegIndexCompositionGraph *G) {
1786
+ return G->SubRegIndices .size ();
1787
+ }
1788
+ };
1789
+
1790
+ void CodeGenRegBank::computeSubRegIndicesRPOT () {
1791
+ SubRegIndexCompositionGraph G (SubRegIndices);
1792
+ ReversePostOrderTraversal<SubRegIndexCompositionGraph> RPOT (G);
1793
+ for (const auto N : RPOT) {
1794
+ if (auto *Idx = dyn_cast<CodeGenSubRegIndex *>(N))
1795
+ SubRegIndicesRPOT.push_back (Idx);
1796
+ }
1797
+ }
1798
+
1799
+ namespace {
1800
+
1697
1801
// UberRegSet is a helper class for computeRegUnitWeights. Each UberRegSet is
1698
1802
// the transitive closure of the union of overlapping register
1699
1803
// classes. Together, the UberRegSets form a partition of the registers. If we
@@ -2323,8 +2427,10 @@ void CodeGenRegBank::inferSubClassWithSubReg(CodeGenRegisterClass *RC) {
2323
2427
if (SubIdx.Artificial )
2324
2428
continue ;
2325
2429
// This is a real subset. See if we have a matching class.
2326
- CodeGenRegisterClass *SubRC = getOrCreateSubClass (
2327
- RC, &I->second , RC->getName () + " _with_" + I->first ->getName ());
2430
+ CodeGenRegisterClass *SubRC =
2431
+ getOrCreateSubClass (RC, &I->second ,
2432
+ RC->getName () + " _with_" + I->first ->getName ())
2433
+ .first ;
2328
2434
RC->setSubClassWithSubReg (&SubIdx, SubRC);
2329
2435
}
2330
2436
}
@@ -2339,24 +2445,30 @@ void CodeGenRegBank::inferSubClassWithSubReg(CodeGenRegisterClass *RC) {
2339
2445
void CodeGenRegBank::inferMatchingSuperRegClass (
2340
2446
CodeGenRegisterClass *RC,
2341
2447
std::list<CodeGenRegisterClass>::iterator FirstSubRegRC) {
2448
+ DenseSet<const CodeGenSubRegIndex *> ImpliedSubRegIndices;
2342
2449
std::vector<std::pair<const CodeGenRegister *, const CodeGenRegister *>>
2343
2450
SubToSuperRegs;
2344
2451
BitVector TopoSigs (getNumTopoSigs ());
2345
2452
2346
- // Iterate in SubRegIndex numerical order to visit synthetic indices last.
2347
- for (auto &SubIdx : SubRegIndices) {
2453
+ // Iterate subregister indices in topological order to visit larger indices
2454
+ // first. This allows us to skip the smaller indices in many cases because
2455
+ // their inferred super-register classes are implied.
2456
+ for (auto *SubIdx : SubRegIndicesRPOT) {
2348
2457
// Skip indexes that aren't fully supported by RC's registers. This was
2349
2458
// computed by inferSubClassWithSubReg() above which should have been
2350
2459
// called first.
2351
- if (RC->getSubClassWithSubReg (&SubIdx) != RC)
2460
+ if (RC->getSubClassWithSubReg (SubIdx) != RC)
2461
+ continue ;
2462
+
2463
+ if (ImpliedSubRegIndices.count (SubIdx))
2352
2464
continue ;
2353
2465
2354
2466
// Build list of (Sub, Super) pairs for this SubIdx, sorted by Sub. Note
2355
2467
// that the list may contain entries with the same Sub but different Supers.
2356
2468
SubToSuperRegs.clear ();
2357
2469
TopoSigs.reset ();
2358
2470
for (const auto Super : RC->getMembers ()) {
2359
- const CodeGenRegister *Sub = Super->getSubRegs ().find (& SubIdx)->second ;
2471
+ const CodeGenRegister *Sub = Super->getSubRegs ().find (SubIdx)->second ;
2360
2472
assert (Sub && " Missing sub-register" );
2361
2473
SubToSuperRegs.emplace_back (Sub, Super);
2362
2474
TopoSigs.set (Sub->getTopoSig ());
@@ -2374,7 +2486,7 @@ void CodeGenRegBank::inferMatchingSuperRegClass(
2374
2486
if (SubRC.Artificial )
2375
2487
continue ;
2376
2488
// Topological shortcut: SubRC members have the wrong shape.
2377
- if (!TopoSigs.anyCommon (SubRC.getTopoSigs ()))
2489
+ if (!TopoSigs.anyCommon (SubRC.getRegsWithSuperRegsTopoSigs ()))
2378
2490
continue ;
2379
2491
// Compute the subset of RC that maps into SubRC with a single linear scan
2380
2492
// through SubToSuperRegs and the members of SubRC.
@@ -2395,15 +2507,54 @@ void CodeGenRegBank::inferMatchingSuperRegClass(
2395
2507
// RC injects completely into SubRC.
2396
2508
sortAndUniqueRegisters (SubSetVec);
2397
2509
if (SubSetVec.size () == RC->getMembers ().size ()) {
2398
- SubRC.addSuperRegClass (&SubIdx, RC);
2510
+ SubRC.addSuperRegClass (SubIdx, RC);
2511
+
2512
+ // We can skip checking subregister indices that can be composed from
2513
+ // the current SubIdx.
2514
+ //
2515
+ // Proof sketch: Let SubRC' be another register class and SubSubIdx
2516
+ // a subregister index that can be composed from SubIdx.
2517
+ //
2518
+ // Calling this function with SubRC in place of RC ensures the existence
2519
+ // of a subclass X of SubRC with the registers that have subregisters in
2520
+ // SubRC'.
2521
+ //
2522
+ // The set of registers in RC with SubSubIdx in SubRC' is equal to the
2523
+ // set of registers in RC with SubIdx in X (because every register in
2524
+ // RC has a corresponding subregister in SubRC), and so checking the
2525
+ // pair (SubSubIdx, SubRC') is redundant with checking (SubIdx, X).
2526
+ for (const auto &SubSubIdx : SubIdx->getComposites ())
2527
+ ImpliedSubRegIndices.insert (SubSubIdx.second );
2528
+
2399
2529
continue ;
2400
2530
}
2401
2531
2402
2532
// Only a subset of RC maps into SubRC. Make sure it is represented by a
2403
2533
// class.
2404
- getOrCreateSubClass (RC, &SubSetVec,
2405
- RC->getName () + " _with_" + SubIdx.getName () + " _in_" +
2406
- SubRC.getName ());
2534
+ //
2535
+ // The name of the inferred register class follows the template
2536
+ // "<RC>_with_<SubIdx>_in_<SubRC>".
2537
+ //
2538
+ // When SubRC is already an inferred class, prefer a name of the form
2539
+ // "<RC>_with_<CompositeSubIdx>_in_<SubSubRC>" over a chain of the form
2540
+ // "<RC>_with_<SubIdx>_in_<OtherRc>_with_<SubSubIdx>_in_<SubSubRC>".
2541
+ CodeGenSubRegIndex *CompositeSubIdx = SubIdx;
2542
+ CodeGenRegisterClass *CompositeSubRC = &SubRC;
2543
+ if (CodeGenSubRegIndex *SubSubIdx = SubRC.getInferredFromSubRegIdx ()) {
2544
+ auto It = SubIdx->getComposites ().find (SubSubIdx);
2545
+ if (It != SubIdx->getComposites ().end ()) {
2546
+ CompositeSubIdx = It->second ;
2547
+ CompositeSubRC = SubRC.getInferredFromRC ();
2548
+ }
2549
+ }
2550
+
2551
+ auto [SubSetRC, Inserted] = getOrCreateSubClass (
2552
+ RC, &SubSetVec,
2553
+ RC->getName () + " _with_" + CompositeSubIdx->getName () + " _in_" +
2554
+ CompositeSubRC->getName ());
2555
+
2556
+ if (Inserted)
2557
+ SubSetRC->setInferredFrom (CompositeSubIdx, CompositeSubRC);
2407
2558
}
2408
2559
}
2409
2560
}
@@ -2438,7 +2589,7 @@ void CodeGenRegBank::computeInferredRegisterClasses() {
2438
2589
inferMatchingSuperRegClass (RC);
2439
2590
2440
2591
// New register classes are created while this loop is running, and we need
2441
- // to visit all of them. I particular, inferMatchingSuperRegClass needs
2592
+ // to visit all of them. In particular, inferMatchingSuperRegClass needs
2442
2593
// to match old super-register classes with sub-register classes created
2443
2594
// after inferMatchingSuperRegClass was called. At this point,
2444
2595
// inferMatchingSuperRegClass has checked SuperRC = [0..rci] with SubRC =
@@ -2451,6 +2602,17 @@ void CodeGenRegBank::computeInferredRegisterClasses() {
2451
2602
FirstNewRC = NextNewRC;
2452
2603
}
2453
2604
}
2605
+
2606
+ // Compute the transitive closure for super-register classes.
2607
+ //
2608
+ // By iterating over sub-register indices in topological order, we only ever
2609
+ // add super-register classes for sub-register indices that have not already
2610
+ // been visited. That allows computing the transitive closure in a single
2611
+ // pass.
2612
+ for (CodeGenSubRegIndex *SubIdx : SubRegIndicesRPOT) {
2613
+ for (CodeGenRegisterClass &SubRC : RegClasses)
2614
+ SubRC.extendSuperRegClasses (SubIdx);
2615
+ }
2454
2616
}
2455
2617
2456
2618
// / getRegisterClassForRegister - Find the register class that contains the
0 commit comments