Specify SubRegIndex components on the index itself.

It is simpler to define a composite index directly:

  def ssub_2 : SubRegIndex<[dsub_1, ssub_0]>;
  def ssub_3 : SubRegIndex<[dsub_1, ssub_1]>;

Than specifying the composite indices on each register:

  CompositeIndices = [(ssub_2 dsub_1, ssub_0),
                      (ssub_3 dsub_1, ssub_1)] in ...

This also makes it clear that SubRegIndex composition is supposed to be
unique.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@149556 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Jakob Stoklund Olesen 2012-02-01 23:16:41 +00:00
parent ebf8c27cae
commit b5af2d943e
3 changed files with 82 additions and 26 deletions

View File

@ -22,8 +22,12 @@ include "llvm/Intrinsics.td"
class RegisterClass; // Forward def
// SubRegIndex - Use instances of SubRegIndex to identify subregisters.
class SubRegIndex {
class SubRegIndex<list<SubRegIndex> comps = []> {
string Namespace = "";
// ComposedOf - A list of two SubRegIndex instances, [A, B].
// This indicates that this SubRegIndex is the result of composing A and B.
list<SubRegIndex> ComposedOf = comps;
}
// RegAltNameIndex - The alternate name set to use for register operands of

View File

@ -49,6 +49,19 @@ std::string CodeGenSubRegIndex::getQualifiedName() const {
return N;
}
void CodeGenSubRegIndex::updateComponents(CodeGenRegBank &RegBank) {
std::vector<Record*> Comps = TheDef->getValueAsListOfDefs("ComposedOf");
if (Comps.empty())
return;
if (Comps.size() != 2)
throw TGError(TheDef->getLoc(), "ComposedOf must have exactly two entries");
CodeGenSubRegIndex *A = RegBank.getSubRegIdx(Comps[0]);
CodeGenSubRegIndex *B = RegBank.getSubRegIdx(Comps[1]);
CodeGenSubRegIndex *X = A->addComposite(B, this);
if (X)
throw TGError(TheDef->getLoc(), "Ambiguous ComposedOf entries");
}
void CodeGenSubRegIndex::cleanComposites() {
// Clean out redundant mappings of the form this+X -> X.
for (CompMap::iterator i = Composed.begin(), e = Composed.end(); i != e;) {
@ -75,15 +88,6 @@ const std::string &CodeGenRegister::getName() const {
return TheDef->getName();
}
namespace {
struct Orphan {
CodeGenRegister *SubReg;
CodeGenSubRegIndex *First, *Second;
Orphan(CodeGenRegister *r, CodeGenSubRegIndex *a, CodeGenSubRegIndex *b)
: SubReg(r), First(a), Second(b) {}
};
}
const CodeGenRegister::SubRegMap &
CodeGenRegister::getSubRegs(CodeGenRegBank &RegBank) {
// Only compute this map once.
@ -92,28 +96,29 @@ CodeGenRegister::getSubRegs(CodeGenRegBank &RegBank) {
SubRegsComplete = true;
std::vector<Record*> SubList = TheDef->getValueAsListOfDefs("SubRegs");
std::vector<Record*> Indices = TheDef->getValueAsListOfDefs("SubRegIndices");
if (SubList.size() != Indices.size())
std::vector<Record*> IdxList = TheDef->getValueAsListOfDefs("SubRegIndices");
if (SubList.size() != IdxList.size())
throw TGError(TheDef->getLoc(), "Register " + getName() +
" SubRegIndices doesn't match SubRegs");
// First insert the direct subregs and make sure they are fully indexed.
SmallVector<CodeGenSubRegIndex*, 8> Indices;
for (unsigned i = 0, e = SubList.size(); i != e; ++i) {
CodeGenRegister *SR = RegBank.getReg(SubList[i]);
CodeGenSubRegIndex *Idx = RegBank.getSubRegIdx(Indices[i]);
CodeGenSubRegIndex *Idx = RegBank.getSubRegIdx(IdxList[i]);
Indices.push_back(Idx);
if (!SubRegs.insert(std::make_pair(Idx, SR)).second)
throw TGError(TheDef->getLoc(), "SubRegIndex " + Idx->getName() +
" appears twice in Register " + getName());
}
// Keep track of inherited subregs and how they can be reached.
SmallVector<Orphan, 8> Orphans;
SmallPtrSet<CodeGenRegister*, 8> Orphans;
// Clone inherited subregs and place duplicate entries on Orphans.
// Clone inherited subregs and place duplicate entries in Orphans.
// Here the order is important - earlier subregs take precedence.
for (unsigned i = 0, e = SubList.size(); i != e; ++i) {
CodeGenRegister *SR = RegBank.getReg(SubList[i]);
CodeGenSubRegIndex *Idx = RegBank.getSubRegIdx(Indices[i]);
const SubRegMap &Map = SR->getSubRegs(RegBank);
// Add this as a super-register of SR now all sub-registers are in the list.
@ -124,7 +129,7 @@ CodeGenRegister::getSubRegs(CodeGenRegBank &RegBank) {
for (SubRegMap::const_iterator SI = Map.begin(), SE = Map.end(); SI != SE;
++SI) {
if (!SubRegs.insert(*SI).second)
Orphans.push_back(Orphan(SI->second, Idx, SI->first));
Orphans.insert(SI->second);
// Noop sub-register indexes are possible, so avoid duplicates.
if (SI->second != SR)
@ -132,6 +137,33 @@ CodeGenRegister::getSubRegs(CodeGenRegBank &RegBank) {
}
}
// Expand any composed subreg indices.
// If dsub_2 has ComposedOf = [qsub_1, dsub_0], and this register has a
// qsub_1 subreg, add a dsub_2 subreg. Keep growing Indices and process
// expanded subreg indices recursively.
for (unsigned i = 0; i != Indices.size(); ++i) {
CodeGenSubRegIndex *Idx = Indices[i];
const CodeGenSubRegIndex::CompMap &Comps = Idx->getComposites();
CodeGenRegister *SR = SubRegs[Idx];
const SubRegMap &Map = SR->getSubRegs(RegBank);
// Look at the possible compositions of Idx.
// They may not all be supported by SR.
for (CodeGenSubRegIndex::CompMap::const_iterator I = Comps.begin(),
E = Comps.end(); I != E; ++I) {
SubRegMap::const_iterator SRI = Map.find(I->first);
if (SRI == Map.end())
continue; // Idx + I->first doesn't exist in SR.
// Add I->second as a name for the subreg SRI->second, assuming it is
// orphaned, and the name isn't already used for something else.
if (SubRegs.count(I->second) || !Orphans.erase(SRI->second))
continue;
// We found a new name for the orphaned sub-register.
SubRegs.insert(std::make_pair(I->second, SRI->second));
Indices.push_back(I->second);
}
}
// Process the composites.
ListInit *Comps = TheDef->getValueAsListInit("CompositeIndices");
for (unsigned i = 0, e = Comps->size(); i != e; ++i) {
@ -167,19 +199,33 @@ CodeGenRegister::getSubRegs(CodeGenRegBank &RegBank) {
SubRegs[BaseIdx] = R2;
// R2 is no longer an orphan.
for (unsigned j = 0, je = Orphans.size(); j != je; ++j)
if (Orphans[j].SubReg == R2)
Orphans[j].SubReg = 0;
Orphans.erase(R2);
}
// Now Orphans contains the inherited subregisters without a direct index.
// Create inferred indexes for all missing entries.
for (unsigned i = 0, e = Orphans.size(); i != e; ++i) {
Orphan &O = Orphans[i];
if (!O.SubReg)
continue;
SubRegs[RegBank.getCompositeSubRegIndex(O.First, O.Second)] =
O.SubReg;
// Work backwards in the Indices vector in order to compose subregs bottom-up.
// Consider this subreg sequence:
//
// qsub_1 -> dsub_0 -> ssub_0
//
// The qsub_1 -> dsub_0 composition becomes dsub_2, so the ssub_0 register
// can be reached in two different ways:
//
// qsub_1 -> ssub_0
// dsub_2 -> ssub_0
//
// We pick the latter composition because another register may have [dsub_0,
// dsub_1, dsub_2] subregs without neccessarily having a qsub_1 subreg. The
// dsub_2 -> ssub_0 composition can be shared.
while (!Indices.empty() && !Orphans.empty()) {
CodeGenSubRegIndex *Idx = Indices.pop_back_val();
CodeGenRegister *SR = SubRegs[Idx];
const SubRegMap &Map = SR->getSubRegs(RegBank);
for (SubRegMap::const_iterator SI = Map.begin(), SE = Map.end(); SI != SE;
++SI)
if (Orphans.erase(SI->second))
SubRegs[RegBank.getCompositeSubRegIndex(Idx, SI->first)] = SI->second;
}
return SubRegs;
}
@ -590,6 +636,9 @@ CodeGenRegBank::CodeGenRegBank(RecordKeeper &Records) : Records(Records) {
NumNamedIndices = SRIs.size();
for (unsigned i = 0, e = SRIs.size(); i != e; ++i)
getSubRegIdx(SRIs[i]);
// Build composite maps from ComposedOf fields.
for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i)
SubRegIndices[i]->updateComponents(*this);
// Read in the register definitions.
std::vector<Record*> Regs = Records.getAllDerivedDefinitions("Register");

View File

@ -71,6 +71,9 @@ namespace llvm {
return (Ins.second || Ins.first->second == B) ? 0 : Ins.first->second;
}
// Update the composite maps of components specified in 'ComposedOf'.
void updateComponents(CodeGenRegBank&);
// Clean out redundant composite mappings.
void cleanComposites();