X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=utils%2FTableGen%2FCodeGenRegisters.cpp;h=613422549230a327c616d861d000fad1fed2b9d8;hb=b3cabb44c32b5a3aba9b4d23aae9723d498ea7a9;hp=20d439f8f71d95f71784e9553855e84cec38431d;hpb=eca1fcf3d2d8246c45648fea59bd21a4091f9115;p=oota-llvm.git diff --git a/utils/TableGen/CodeGenRegisters.cpp b/utils/TableGen/CodeGenRegisters.cpp index 20d439f8f71..61342254923 100644 --- a/utils/TableGen/CodeGenRegisters.cpp +++ b/utils/TableGen/CodeGenRegisters.cpp @@ -28,15 +28,18 @@ using namespace llvm; //===----------------------------------------------------------------------===// CodeGenSubRegIndex::CodeGenSubRegIndex(Record *R, unsigned Enum) - : TheDef(R), EnumValue(Enum), LaneMask(0) { + : TheDef(R), EnumValue(Enum), LaneMask(0), AllSuperRegsCovered(true) { Name = R->getName(); if (R->getValue("Namespace")) Namespace = R->getValueAsString("Namespace"); + Size = R->getValueAsInt("Size"); + Offset = R->getValueAsInt("Offset"); } CodeGenSubRegIndex::CodeGenSubRegIndex(StringRef N, StringRef Nspace, unsigned Enum) - : TheDef(0), Name(N), Namespace(Nspace), EnumValue(Enum), LaneMask(0) { + : TheDef(0), Name(N), Namespace(Nspace), Size(-1), Offset(-1), + EnumValue(Enum), LaneMask(0), AllSuperRegsCovered(true) { } std::string CodeGenSubRegIndex::getQualifiedName() const { @@ -68,7 +71,7 @@ void CodeGenSubRegIndex::updateComponents(CodeGenRegBank &RegBank) { if (!Parts.empty()) { if (Parts.size() < 2) PrintFatalError(TheDef->getLoc(), - "CoveredBySubRegs must have two or more entries"); + "CoveredBySubRegs must have two or more entries"); SmallVector IdxParts; for (unsigned i = 0, e = Parts.size(); i != e; ++i) IdxParts.push_back(RegBank.getSubRegIdx(Parts[i])); @@ -312,6 +315,11 @@ CodeGenRegister::computeSubRegs(CodeGenRegBank &RegBank) { PrintFatalError(Loc, "Register " + getName() + " has itself as a sub-register"); } + + // Compute AllSuperRegsCovered. + if (!CoveredBySubRegs) + SI->first->AllSuperRegsCovered = false; + // Ensure that every sub-register has a unique name. DenseMap::iterator Ins = SubReg2Idx.insert(std::make_pair(SI->second, SI->first)).first; @@ -520,55 +528,6 @@ CodeGenRegister::addSubRegsPreOrder(SetVector &OSet, OSet.insert(I->second); } -// Compute overlapping registers. -// -// The standard set is all super-registers and all sub-registers, but the -// target description can add arbitrary overlapping registers via the 'Aliases' -// field. This complicates things, but we can compute overlapping sets using -// the following rules: -// -// 1. The relation overlap(A, B) is reflexive and symmetric but not transitive. -// -// 2. overlap(A, B) implies overlap(A, S) for all S in supers(B). -// -// Alternatively: -// -// overlap(A, B) iff there exists: -// A' in { A, subregs(A) } and B' in { B, subregs(B) } such that: -// A' = B' or A' in aliases(B') or B' in aliases(A'). -// -// Here subregs(A) is the full flattened sub-register set returned by -// A.getSubRegs() while aliases(A) is simply the special 'Aliases' field in the -// description of register A. -// -// This also implies that registers with a common sub-register are considered -// overlapping. This can happen when forming register pairs: -// -// P0 = (R0, R1) -// P1 = (R1, R2) -// P2 = (R2, R3) -// -// In this case, we will infer an overlap between P0 and P1 because of the -// shared sub-register R1. There is no overlap between P0 and P2. -// -void CodeGenRegister::computeOverlaps(CodeGenRegister::Set &Overlaps, - const CodeGenRegBank &RegBank) const { - assert(!RegUnits.empty() && "Compute register units before overlaps."); - - // Register units are assigned such that the overlapping registers are the - // super-registers of the root registers of the register units. - for (unsigned rui = 0, rue = RegUnits.size(); rui != rue; ++rui) { - const RegUnit &RU = RegBank.getRegUnit(RegUnits[rui]); - ArrayRef Roots = RU.getRoots(); - for (unsigned ri = 0, re = Roots.size(); ri != re; ++ri) { - const CodeGenRegister *Root = Roots[ri]; - Overlaps.insert(Root); - ArrayRef Supers = Root->getSuperRegs(); - Overlaps.insert(Supers.begin(), Supers.end()); - } - } -} - // Get the sum of this register's unit weights. unsigned CodeGenRegister::getWeight(const CodeGenRegBank &RegBank) const { unsigned Weight = 0; @@ -636,8 +595,10 @@ struct TupleExpander : SetTheory::Expander { Elts.insert(NewReg); // Copy Proto super-classes. - for (unsigned i = 0, e = Proto->getSuperClasses().size(); i != e; ++i) - NewReg->addSuperClass(Proto->getSuperClasses()[i]); + ArrayRef Supers = Proto->getSuperClasses(); + ArrayRef Ranges = Proto->getSuperClassRanges(); + for (unsigned i = 0, e = Supers.size(); i != e; ++i) + NewReg->addSuperClass(Supers[i], Ranges[i]); // Copy Proto fields. for (unsigned i = 0, e = Proto->getValues().size(); i != e; ++i) { @@ -701,7 +662,9 @@ CodeGenRegisterClass::CodeGenRegisterClass(CodeGenRegBank &RegBank, Record *R) // Rename anonymous register classes. if (R->getName().size() > 9 && R->getName()[9] == '.') { static unsigned AnonCounter = 0; - R->setName("AnonRegClass_"+utostr(AnonCounter++)); + R->setName("AnonRegClass_" + utostr(AnonCounter)); + // MSVC2012 ICEs if AnonCounter++ is directly passed to utostr. + ++AnonCounter; } std::vector TypeList = R->getValueAsListOfDefs("RegTypes"); @@ -975,7 +938,7 @@ CodeGenRegBank::CodeGenRegBank(RecordKeeper &Records) { // Read in the register definitions. std::vector Regs = Records.getAllDerivedDefinitions("Register"); - std::sort(Regs.begin(), Regs.end(), LessRecord()); + std::sort(Regs.begin(), Regs.end(), LessRecordRegister()); Registers.reserve(Regs.size()); // Assign the enumeration values. for (unsigned i = 0, e = Regs.size(); i != e; ++i) @@ -984,10 +947,16 @@ CodeGenRegBank::CodeGenRegBank(RecordKeeper &Records) { // Expand tuples and number the new registers. std::vector Tups = Records.getAllDerivedDefinitions("RegisterTuples"); + + std::vector TupRegsCopy; for (unsigned i = 0, e = Tups.size(); i != e; ++i) { const std::vector *TupRegs = Sets.expand(Tups[i]); - for (unsigned j = 0, je = TupRegs->size(); j != je; ++j) - getReg((*TupRegs)[j]); + TupRegsCopy.reserve(TupRegs->size()); + TupRegsCopy.assign(TupRegs->begin(), TupRegs->end()); + std::sort(TupRegsCopy.begin(), TupRegsCopy.end(), LessRecordRegister()); + for (unsigned j = 0, je = TupRegsCopy.size(); j != je; ++j) + getReg((TupRegsCopy)[j]); + TupRegsCopy.clear(); } // Now all the registers are known. Build the object graph of explicit @@ -1129,11 +1098,24 @@ getConcatSubRegIndex(const SmallVector &Parts) { // None exists, synthesize one. std::string Name = Parts.front()->getName(); + // Determine whether all parts are contiguous. + bool isContinuous = true; + unsigned Size = Parts.front()->Size; + unsigned LastOffset = Parts.front()->Offset; + unsigned LastSize = Parts.front()->Size; for (unsigned i = 1, e = Parts.size(); i != e; ++i) { Name += '_'; Name += Parts[i]->getName(); + Size += Parts[i]->Size; + if (Parts[i]->Offset != (LastOffset + LastSize)) + isContinuous = false; + LastOffset = Parts[i]->Offset; + LastSize = Parts[i]->Size; } - return Idx = createSubRegIndex(Name, Parts.front()->getNamespace()); + Idx = createSubRegIndex(Name, Parts.front()->getNamespace()); + Idx->Size = Size; + Idx->Offset = isContinuous ? Parts.front()->Offset : -1; + return Idx; } void CodeGenRegBank::computeComposites() { @@ -1191,12 +1173,25 @@ void CodeGenRegBank::computeComposites() { void CodeGenRegBank::computeSubRegIndexLaneMasks() { // First assign individual bits to all the leaf indices. unsigned Bit = 0; + // Determine mask of lanes that cover their registers. + CoveringLanes = ~0u; for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i) { CodeGenSubRegIndex *Idx = SubRegIndices[i]; if (Idx->getComposites().empty()) { Idx->LaneMask = 1u << Bit; // Share bit 31 in the unlikely case there are more than 32 leafs. - if (Bit < 31) ++Bit; + // + // Sharing bits is harmless; it allows graceful degradation in targets + // with more than 32 vector lanes. They simply get a limited resolution + // view of lanes beyond the 32nd. + // + // See also the comment for getSubRegIndexLaneMask(). + if (Bit < 31) + ++Bit; + else + // Once bit 31 is shared among multiple leafs, the 'lane' it represents + // is no longer covering its registers. + CoveringLanes &= ~(1u << Bit); } else { Idx->LaneMask = 0; } @@ -1206,8 +1201,13 @@ void CodeGenRegBank::computeSubRegIndexLaneMasks() { // by the sub-register graph? This doesn't occur in any known targets. // Inherit lanes from composites. - for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i) - SubRegIndices[i]->computeLaneMask(); + for (unsigned i = 0, e = SubRegIndices.size(); i != e; ++i) { + unsigned Mask = SubRegIndices[i]->computeLaneMask(); + // If some super-registers without CoveredBySubRegs use this index, we can + // no longer assume that the lanes are covering their registers. + if (!SubRegIndices[i]->AllSuperRegsCovered) + CoveringLanes &= ~Mask; + } } namespace {