llvm.org GIT mirror llvm / ad0b3b2
Generate a table-driven version of TRI::composeSubRegIndices(). Explicitly allow composition of null sub-register indices, and handle that common case in an inlinable stub. Use a compressed table implementation instead of the previous nested switches which generated pretty bad code. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@167190 91177308-0d34-0410-b5e6-96231b3b80d8 Jakob Stoklund Olesen 8 years ago
2 changed file(s) with 117 addition(s) and 31 deletion(s). Raw diff Collapse all Expand all
475475 /// composeSubRegIndices - Return the subregister index you get from composing
476476 /// two subregister indices.
477477 ///
478 /// The special null sub-register index composes as the identity.
479 ///
478480 /// If R:a:b is the same register as R:c, then composeSubRegIndices(a, b)
479481 /// returns c. Note that composeSubRegIndices does not tell you about illegal
480482 /// compositions. If R does not have a subreg a, or R:a does not have a subreg
484486 /// ssub_0:S0 - ssub_3:S3 subregs.
485487 /// If you compose subreg indices dsub_1, ssub_0 you get ssub_2.
486488 ///
487 virtual unsigned composeSubRegIndices(unsigned a, unsigned b) const {
488 // This default implementation is correct for most targets.
489 return b;
490 }
491
489 unsigned composeSubRegIndices(unsigned a, unsigned b) const {
490 if (!a) return b;
491 if (!b) return a;
492 return composeSubRegIndicesImpl(a, b);
493 }
494
495 protected:
496 /// Overridden by TableGen in targets that have sub-registers.
497 virtual unsigned composeSubRegIndicesImpl(unsigned, unsigned) const {
498 llvm_unreachable("Target has no sub-registers");
499 }
500
501 public:
492502 /// getCommonSuperRegClass - Find a common super-register class if it exists.
493503 ///
494504 /// Find a register class, SuperRC and two sub-register indices, PreA and
6161
6262 void EmitRegUnitPressure(raw_ostream &OS, const CodeGenRegBank &RegBank,
6363 const std::string &ClassName);
64 void emitComposeSubRegIndices(raw_ostream &OS, CodeGenRegBank &RegBank,
65 const std::string &ClassName);
6466 };
6567 } // End anonymous namespace
6668
527529
528530 static void printDiff16(raw_ostream &OS, uint16_t Val) {
529531 OS << Val;
532 }
533
534 // Try to combine Idx's compose map into Vec if it is compatible.
535 // Return false if it's not possible.
536 static bool combine(const CodeGenSubRegIndex *Idx,
537 SmallVectorImpl &Vec) {
538 const CodeGenSubRegIndex::CompMap &Map = Idx->getComposites();
539 for (CodeGenSubRegIndex::CompMap::const_iterator
540 I = Map.begin(), E = Map.end(); I != E; ++I) {
541 CodeGenSubRegIndex *&Entry = Vec[I->first->EnumValue - 1];
542 if (Entry && Entry != I->second)
543 return false;
544 }
545
546 // All entries are compatible. Make it so.
547 for (CodeGenSubRegIndex::CompMap::const_iterator
548 I = Map.begin(), E = Map.end(); I != E; ++I)
549 Vec[I->first->EnumValue - 1] = I->second;
550 return true;
551 }
552
553 static const char *getMinimalTypeForRange(uint64_t Range) {
554 assert(Range < 0xFFFFFFFFULL && "Enum too large");
555 if (Range > 0xFFFF)
556 return "uint32_t";
557 if (Range > 0xFF)
558 return "uint16_t";
559 return "uint8_t";
560 }
561
562 void
563 RegisterInfoEmitter::emitComposeSubRegIndices(raw_ostream &OS,
564 CodeGenRegBank &RegBank,
565 const std::string &ClName) {
566 ArrayRef SubRegIndices = RegBank.getSubRegIndices();
567 OS << "unsigned " << ClName
568 << "::composeSubRegIndicesImpl(unsigned IdxA, unsigned IdxB) const {\n";
569
570 // Many sub-register indexes are composition-compatible, meaning that
571 //
572 // compose(IdxA, IdxB) == compose(IdxA', IdxB)
573 //
574 // for many IdxA, IdxA' pairs. Not all sub-register indexes can be composed.
575 // The illegal entries can be use as wildcards to compress the table further.
576
577 // Map each Sub-register index to a compatible table row.
578 SmallVector RowMap;
579 SmallVector, 4> Rows;
580
581 for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i) {
582 unsigned Found = ~0u;
583 for (unsigned r = 0, re = Rows.size(); r != re; ++r) {
584 if (combine(SubRegIndices[i], Rows[r])) {
585 Found = r;
586 break;
587 }
588 }
589 if (Found == ~0u) {
590 Found = Rows.size();
591 Rows.resize(Found + 1);
592 Rows.back().resize(SubRegIndices.size());
593 combine(SubRegIndices[i], Rows.back());
594 }
595 RowMap.push_back(Found);
596 }
597
598 // Output the row map if there is multiple rows.
599 if (Rows.size() > 1) {
600 OS << " static const " << getMinimalTypeForRange(Rows.size())
601 << " RowMap[" << SubRegIndices.size() << "] = {\n ";
602 for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i)
603 OS << RowMap[i] << ", ";
604 OS << "\n };\n";
605 }
606
607 // Output the rows.
608 OS << " static const " << getMinimalTypeForRange(SubRegIndices.size()+1)
609 << " Rows[" << Rows.size() << "][" << SubRegIndices.size() << "] = {\n";
610 for (unsigned r = 0, re = Rows.size(); r != re; ++r) {
611 OS << " { ";
612 for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i)
613 if (Rows[r][i])
614 OS << Rows[r][i]->EnumValue << ", ";
615 else
616 OS << "0, ";
617 OS << "},\n";
618 }
619 OS << " };\n\n";
620
621 OS << " --IdxA; assert(IdxA < " << SubRegIndices.size() << ");\n"
622 << " --IdxB; assert(IdxB < " << SubRegIndices.size() << ");\n";
623 if (Rows.size() > 1)
624 OS << " return Rows[RowMap[IdxA]][IdxB];\n";
625 else
626 OS << " return Rows[0][IdxB];\n";
627 OS << "}\n\n";
530628 }
531629
532630 //
801899 << " virtual bool needsStackRealignment(const MachineFunction &) const\n"
802900 << " { return false; }\n";
803901 if (!RegBank.getSubRegIndices().empty()) {
804 OS << " virtual unsigned composeSubRegIndices(unsigned, unsigned) const;\n"
902 OS << " virtual unsigned composeSubRegIndicesImpl"
903 << "(unsigned, unsigned) const;\n"
805904 << " virtual const TargetRegisterClass *"
806905 "getSubClassWithSubReg(const TargetRegisterClass*, unsigned) const;\n";
807906 }
10531152
10541153 std::string ClassName = Target.getName() + "GenRegisterInfo";
10551154
1056 // Emit composeSubRegIndices
1057 if (!SubRegIndices.empty()) {
1058 OS << "unsigned " << ClassName
1059 << "::composeSubRegIndices(unsigned IdxA, unsigned IdxB) const {\n"
1060 << " switch (IdxA) {\n"
1061 << " default:\n return IdxB;\n";
1062 for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i) {
1063 bool Open = false;
1064 for (unsigned j = 0; j != e; ++j) {
1065 CodeGenSubRegIndex *Comp = SubRegIndices[i]->compose(SubRegIndices[j]);
1066 if (Comp && Comp != SubRegIndices[j]) {
1067 if (!Open) {
1068 OS << " case " << SubRegIndices[i]->getQualifiedName()
1069 << ": switch(IdxB) {\n default: return IdxB;\n";
1070 Open = true;
1071 }
1072 OS << " case " << SubRegIndices[j]->getQualifiedName()
1073 << ": return " << Comp->getQualifiedName() << ";\n";
1074 }
1075 }
1076 if (Open)
1077 OS << " }\n";
1078 }
1079 OS << " }\n}\n\n";
1080 }
1155 if (!SubRegIndices.empty())
1156 emitComposeSubRegIndices(OS, RegBank, ClassName);
10811157
10821158 // Emit getSubClassWithSubReg.
10831159 if (!SubRegIndices.empty()) {