mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-29 06:10:48 +00:00
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. llvm-svn: 167190
This commit is contained in:
parent
17a434c0ae
commit
4498c89d5f
@ -476,6 +476,8 @@ public:
|
||||
/// composeSubRegIndices - Return the subregister index you get from composing
|
||||
/// two subregister indices.
|
||||
///
|
||||
/// The special null sub-register index composes as the identity.
|
||||
///
|
||||
/// If R:a:b is the same register as R:c, then composeSubRegIndices(a, b)
|
||||
/// returns c. Note that composeSubRegIndices does not tell you about illegal
|
||||
/// compositions. If R does not have a subreg a, or R:a does not have a subreg
|
||||
@ -485,11 +487,19 @@ public:
|
||||
/// ssub_0:S0 - ssub_3:S3 subregs.
|
||||
/// If you compose subreg indices dsub_1, ssub_0 you get ssub_2.
|
||||
///
|
||||
virtual unsigned composeSubRegIndices(unsigned a, unsigned b) const {
|
||||
// This default implementation is correct for most targets.
|
||||
return b;
|
||||
unsigned composeSubRegIndices(unsigned a, unsigned b) const {
|
||||
if (!a) return b;
|
||||
if (!b) return a;
|
||||
return composeSubRegIndicesImpl(a, b);
|
||||
}
|
||||
|
||||
protected:
|
||||
/// Overridden by TableGen in targets that have sub-registers.
|
||||
virtual unsigned composeSubRegIndicesImpl(unsigned, unsigned) const {
|
||||
llvm_unreachable("Target has no sub-registers");
|
||||
}
|
||||
|
||||
public:
|
||||
/// getCommonSuperRegClass - Find a common super-register class if it exists.
|
||||
///
|
||||
/// Find a register class, SuperRC and two sub-register indices, PreA and
|
||||
|
@ -62,6 +62,8 @@ private:
|
||||
|
||||
void EmitRegUnitPressure(raw_ostream &OS, const CodeGenRegBank &RegBank,
|
||||
const std::string &ClassName);
|
||||
void emitComposeSubRegIndices(raw_ostream &OS, CodeGenRegBank &RegBank,
|
||||
const std::string &ClassName);
|
||||
};
|
||||
} // End anonymous namespace
|
||||
|
||||
@ -530,6 +532,102 @@ static void printDiff16(raw_ostream &OS, uint16_t Val) {
|
||||
OS << Val;
|
||||
}
|
||||
|
||||
// Try to combine Idx's compose map into Vec if it is compatible.
|
||||
// Return false if it's not possible.
|
||||
static bool combine(const CodeGenSubRegIndex *Idx,
|
||||
SmallVectorImpl<CodeGenSubRegIndex*> &Vec) {
|
||||
const CodeGenSubRegIndex::CompMap &Map = Idx->getComposites();
|
||||
for (CodeGenSubRegIndex::CompMap::const_iterator
|
||||
I = Map.begin(), E = Map.end(); I != E; ++I) {
|
||||
CodeGenSubRegIndex *&Entry = Vec[I->first->EnumValue - 1];
|
||||
if (Entry && Entry != I->second)
|
||||
return false;
|
||||
}
|
||||
|
||||
// All entries are compatible. Make it so.
|
||||
for (CodeGenSubRegIndex::CompMap::const_iterator
|
||||
I = Map.begin(), E = Map.end(); I != E; ++I)
|
||||
Vec[I->first->EnumValue - 1] = I->second;
|
||||
return true;
|
||||
}
|
||||
|
||||
static const char *getMinimalTypeForRange(uint64_t Range) {
|
||||
assert(Range < 0xFFFFFFFFULL && "Enum too large");
|
||||
if (Range > 0xFFFF)
|
||||
return "uint32_t";
|
||||
if (Range > 0xFF)
|
||||
return "uint16_t";
|
||||
return "uint8_t";
|
||||
}
|
||||
|
||||
void
|
||||
RegisterInfoEmitter::emitComposeSubRegIndices(raw_ostream &OS,
|
||||
CodeGenRegBank &RegBank,
|
||||
const std::string &ClName) {
|
||||
ArrayRef<CodeGenSubRegIndex*> SubRegIndices = RegBank.getSubRegIndices();
|
||||
OS << "unsigned " << ClName
|
||||
<< "::composeSubRegIndicesImpl(unsigned IdxA, unsigned IdxB) const {\n";
|
||||
|
||||
// Many sub-register indexes are composition-compatible, meaning that
|
||||
//
|
||||
// compose(IdxA, IdxB) == compose(IdxA', IdxB)
|
||||
//
|
||||
// for many IdxA, IdxA' pairs. Not all sub-register indexes can be composed.
|
||||
// The illegal entries can be use as wildcards to compress the table further.
|
||||
|
||||
// Map each Sub-register index to a compatible table row.
|
||||
SmallVector<unsigned, 4> RowMap;
|
||||
SmallVector<SmallVector<CodeGenSubRegIndex*, 4>, 4> Rows;
|
||||
|
||||
for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i) {
|
||||
unsigned Found = ~0u;
|
||||
for (unsigned r = 0, re = Rows.size(); r != re; ++r) {
|
||||
if (combine(SubRegIndices[i], Rows[r])) {
|
||||
Found = r;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (Found == ~0u) {
|
||||
Found = Rows.size();
|
||||
Rows.resize(Found + 1);
|
||||
Rows.back().resize(SubRegIndices.size());
|
||||
combine(SubRegIndices[i], Rows.back());
|
||||
}
|
||||
RowMap.push_back(Found);
|
||||
}
|
||||
|
||||
// Output the row map if there is multiple rows.
|
||||
if (Rows.size() > 1) {
|
||||
OS << " static const " << getMinimalTypeForRange(Rows.size())
|
||||
<< " RowMap[" << SubRegIndices.size() << "] = {\n ";
|
||||
for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i)
|
||||
OS << RowMap[i] << ", ";
|
||||
OS << "\n };\n";
|
||||
}
|
||||
|
||||
// Output the rows.
|
||||
OS << " static const " << getMinimalTypeForRange(SubRegIndices.size()+1)
|
||||
<< " Rows[" << Rows.size() << "][" << SubRegIndices.size() << "] = {\n";
|
||||
for (unsigned r = 0, re = Rows.size(); r != re; ++r) {
|
||||
OS << " { ";
|
||||
for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i)
|
||||
if (Rows[r][i])
|
||||
OS << Rows[r][i]->EnumValue << ", ";
|
||||
else
|
||||
OS << "0, ";
|
||||
OS << "},\n";
|
||||
}
|
||||
OS << " };\n\n";
|
||||
|
||||
OS << " --IdxA; assert(IdxA < " << SubRegIndices.size() << ");\n"
|
||||
<< " --IdxB; assert(IdxB < " << SubRegIndices.size() << ");\n";
|
||||
if (Rows.size() > 1)
|
||||
OS << " return Rows[RowMap[IdxA]][IdxB];\n";
|
||||
else
|
||||
OS << " return Rows[0][IdxB];\n";
|
||||
OS << "}\n\n";
|
||||
}
|
||||
|
||||
//
|
||||
// runMCDesc - Print out MC register descriptions.
|
||||
//
|
||||
@ -802,7 +900,8 @@ RegisterInfoEmitter::runTargetHeader(raw_ostream &OS, CodeGenTarget &Target,
|
||||
<< " virtual bool needsStackRealignment(const MachineFunction &) const\n"
|
||||
<< " { return false; }\n";
|
||||
if (!RegBank.getSubRegIndices().empty()) {
|
||||
OS << " virtual unsigned composeSubRegIndices(unsigned, unsigned) const;\n"
|
||||
OS << " virtual unsigned composeSubRegIndicesImpl"
|
||||
<< "(unsigned, unsigned) const;\n"
|
||||
<< " virtual const TargetRegisterClass *"
|
||||
"getSubClassWithSubReg(const TargetRegisterClass*, unsigned) const;\n";
|
||||
}
|
||||
@ -1054,31 +1153,8 @@ RegisterInfoEmitter::runTargetDesc(raw_ostream &OS, CodeGenTarget &Target,
|
||||
|
||||
std::string ClassName = Target.getName() + "GenRegisterInfo";
|
||||
|
||||
// Emit composeSubRegIndices
|
||||
if (!SubRegIndices.empty()) {
|
||||
OS << "unsigned " << ClassName
|
||||
<< "::composeSubRegIndices(unsigned IdxA, unsigned IdxB) const {\n"
|
||||
<< " switch (IdxA) {\n"
|
||||
<< " default:\n return IdxB;\n";
|
||||
for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i) {
|
||||
bool Open = false;
|
||||
for (unsigned j = 0; j != e; ++j) {
|
||||
CodeGenSubRegIndex *Comp = SubRegIndices[i]->compose(SubRegIndices[j]);
|
||||
if (Comp && Comp != SubRegIndices[j]) {
|
||||
if (!Open) {
|
||||
OS << " case " << SubRegIndices[i]->getQualifiedName()
|
||||
<< ": switch(IdxB) {\n default: return IdxB;\n";
|
||||
Open = true;
|
||||
}
|
||||
OS << " case " << SubRegIndices[j]->getQualifiedName()
|
||||
<< ": return " << Comp->getQualifiedName() << ";\n";
|
||||
}
|
||||
}
|
||||
if (Open)
|
||||
OS << " }\n";
|
||||
}
|
||||
OS << " }\n}\n\n";
|
||||
}
|
||||
if (!SubRegIndices.empty())
|
||||
emitComposeSubRegIndices(OS, RegBank, ClassName);
|
||||
|
||||
// Emit getSubClassWithSubReg.
|
||||
if (!SubRegIndices.empty()) {
|
||||
|
Loading…
Reference in New Issue
Block a user