Index: llvm/trunk/docs/TableGen/LangRef.rst =================================================================== --- llvm/trunk/docs/TableGen/LangRef.rst +++ llvm/trunk/docs/TableGen/LangRef.rst @@ -125,6 +125,7 @@ .. productionlist:: Class: "class" `TokIdentifier` [`TemplateArgList`] `ObjectBody` + TemplateArgList: "<" `Declaration` ("," `Declaration`)* ">" A ``class`` declaration creates a record which other records can inherit from. A class can be parametrized by a list of "template arguments", whose @@ -145,8 +146,9 @@ class will inherit no fields from it since the record expansion is done when the record is parsed. -.. productionlist:: - TemplateArgList: "<" `Declaration` ("," `Declaration`)* ">" +Every class has an implicit template argument called ``NAME``, which is set +to the name of the instantiating ``def`` or ``defm``. The result is undefined +if the class is instantiated by an anonymous record. Declarations ------------ @@ -246,6 +248,8 @@ int Baz = Bar; } +* the implicit template argument ``NAME`` in a ``class`` or ``multiclass`` + .. productionlist:: SimpleValue: `TokInteger` @@ -332,31 +336,56 @@ ``def`` ------- -.. TODO:: - There can be pastes in the names here, like ``#NAME#``. Look into that - and document it (it boils down to ParseIDValue with IDParseMode == - ParseNameMode). ParseObjectName calls into the general ParseValue, with - the only different from "arbitrary expression parsing" being IDParseMode - == Mode. - .. productionlist:: - Def: "def" `TokIdentifier` `ObjectBody` - -Defines a record whose name is given by the :token:`TokIdentifier`. The -fields of the record are inherited from the base classes and defined in the -body. + Def: "def" [`Value`] `ObjectBody` + +Defines a record whose name is given by the optional :token:`Value`. The value +is parsed in a special mode where global identifiers (records and variables +defined by ``defset``) are not recognized, and all unrecognized identifiers +are interpreted as strings. + +If no name is given, the record is anonymous. The final name of anonymous +records is undefined, but globally unique. Special handling occurs if this ``def`` appears inside a ``multiclass`` or a ``foreach``. +When a non-anonymous record is defined in a multiclass and the given name +does not contain a reference to the implicit template argument ``NAME``, such +a reference will automatically be prepended. That is, the following are +equivalent inside a multiclass:: + + def Foo; + def NAME#Foo; + ``defm`` -------- .. productionlist:: - Defm: "defm" [`TokIdentifier`] ":" `BaseClassListNE` ";" + Defm: "defm" [`Value`] ":" `BaseClassListNE` ";" + +The :token:`BaseClassList` is a list of at least one ``multiclass`` and any +number of ``class``'s. The ``multiclass``'s must occur before any ``class``'s. + +Instantiates all records defined in all given ``multiclass``'s and adds the +given ``class``'s as superclasses. + +The name is parsed in the same special mode used by ``def``. If the name is +missing, a globally unique string is used instead (but instantiated records +are not considered to be anonymous, unless they were originally defined by an +anonymous ``def``) That is, the following have different semantics:: + + defm : SomeMultiClass<...>; // some globally unique name + defm "" : SomeMultiClass<...>; // empty name string + +When it occurs inside a multiclass, the second variant is equivalent to +``defm NAME : ...``. More generally, when ``defm`` occurs in a multiclass and +its name does not contain a reference to the implicit template argument +``NAME``, such a reference will automatically be prepended. That is, the +following are equivalent inside a multiclass:: -Note that in the :token:`BaseClassList`, all of the ``multiclass``'s must -precede any ``class``'s that appear. + defm Foo : SomeMultiClass<...>; + defm NAME#Foo : SomeMultiClass<...>; ``defset`` ---------- Index: llvm/trunk/docs/TableGen/index.rst =================================================================== --- llvm/trunk/docs/TableGen/index.rst +++ llvm/trunk/docs/TableGen/index.rst @@ -171,13 +171,6 @@ feature of TableGen is that it allows the end-user to define the abstractions they prefer to use when describing their information. -Each ``def`` record has a special entry called "NAME". This is the name of the -record ("``ADD32rr``" above). In the general case ``def`` names can be formed -from various kinds of string processing expressions and ``NAME`` resolves to the -final value obtained after resolving all of those expressions. The user may -refer to ``NAME`` anywhere she desires to use the ultimate name of the ``def``. -``NAME`` should not be defined anywhere else in user code to avoid conflicts. - Syntax ====== Index: llvm/trunk/include/llvm/TableGen/Record.h =================================================================== --- llvm/trunk/include/llvm/TableGen/Record.h +++ llvm/trunk/include/llvm/TableGen/Record.h @@ -1357,30 +1357,31 @@ unsigned ID; bool IsAnonymous; + bool IsClass; - void init(); void checkName(); public: // Constructs a record. explicit Record(Init *N, ArrayRef locs, RecordKeeper &records, - bool Anonymous = false) : - Name(N), Locs(locs.begin(), locs.end()), TrackedRecords(records), - ID(LastID++), IsAnonymous(Anonymous) { - init(); + bool Anonymous = false, bool Class = false) + : Name(N), Locs(locs.begin(), locs.end()), TrackedRecords(records), + ID(LastID++), IsAnonymous(Anonymous), IsClass(Class) { + checkName(); } - explicit Record(StringRef N, ArrayRef locs, RecordKeeper &records) - : Record(StringInit::get(N), locs, records) {} + explicit Record(StringRef N, ArrayRef locs, RecordKeeper &records, + bool Class = false) + : Record(StringInit::get(N), locs, records, false, Class) {} // When copy-constructing a Record, we must still guarantee a globally unique // ID number. Don't copy TheInit either since it's owned by the original // record. All other fields can be copied normally. - Record(const Record &O) : - Name(O.Name), Locs(O.Locs), TemplateArgs(O.TemplateArgs), - Values(O.Values), SuperClasses(O.SuperClasses), - TrackedRecords(O.TrackedRecords), ID(LastID++), - IsAnonymous(O.IsAnonymous) { } + Record(const Record &O) + : Name(O.Name), Locs(O.Locs), TemplateArgs(O.TemplateArgs), + Values(O.Values), SuperClasses(O.SuperClasses), + TrackedRecords(O.TrackedRecords), ID(LastID++), + IsAnonymous(O.IsAnonymous), IsClass(O.IsClass) { } static unsigned getNewUID() { return LastID++; } @@ -1407,6 +1408,8 @@ /// get the corresponding DefInit. DefInit *getDefInit(); + bool isClass() const { return IsClass; } + ArrayRef getTemplateArgs() const { return TemplateArgs; } @@ -1452,13 +1455,6 @@ void addValue(const RecordVal &RV) { assert(getValue(RV.getNameInit()) == nullptr && "Value already added!"); Values.push_back(RV); - if (Values.size() > 1) - // Keep NAME at the end of the list. It makes record dumps a - // bit prettier and allows TableGen tests to be written more - // naturally. Tests can use CHECK-NEXT to look for Record - // fields they expect to see after a def. They can't do that if - // NAME is the first Record field. - std::swap(Values[Values.size() - 2], Values[Values.size() - 1]); } void removeValue(Init *Name) { @@ -1905,6 +1901,21 @@ Init *resolve(Init *VarName) override; }; +/// Do not resolve anything, but keep track of whether a given variable was +/// referenced. +class HasReferenceResolver final : public Resolver { + Init *VarNameToTrack; + bool Found = false; + +public: + explicit HasReferenceResolver(Init *VarNameToTrack) + : Resolver(nullptr), VarNameToTrack(VarNameToTrack) {} + + bool found() const { return Found; } + + Init *resolve(Init *VarName) override; +}; + } // end namespace llvm #endif // LLVM_TABLEGEN_RECORD_H Index: llvm/trunk/lib/TableGen/Record.cpp =================================================================== --- llvm/trunk/lib/TableGen/Record.cpp +++ llvm/trunk/lib/TableGen/Record.cpp @@ -1572,10 +1572,8 @@ Record *NewRec = NewRecOwner.get(); // Copy values from class to instance - for (const RecordVal &Val : Class->getValues()) { - if (Val.getName() != "NAME") - NewRec->addValue(Val); - } + for (const RecordVal &Val : Class->getValues()) + NewRec->addValue(Val); // Substitute and resolve template arguments ArrayRef TArgs = Class->getTemplateArgs(); @@ -1845,14 +1843,6 @@ unsigned Record::LastID = 0; -void Record::init() { - checkName(); - - // Every record potentially has a def at the top. This value is - // replaced with the top-level def name at instantiation time. - addValue(RecordVal(StringInit::get("NAME"), StringRecTy::get(), false)); -} - void Record::checkName() { // Ensure the record name has string type. const TypedInit *TypedName = cast(Name); @@ -2260,3 +2250,10 @@ FoundUnresolved = true; return I; } + +Init *HasReferenceResolver::resolve(Init *VarName) +{ + if (VarName == VarNameToTrack) + Found = true; + return nullptr; +} Index: llvm/trunk/lib/TableGen/TGParser.h =================================================================== --- llvm/trunk/lib/TableGen/TGParser.h +++ llvm/trunk/lib/TableGen/TGParser.h @@ -126,10 +126,9 @@ // iteration space. typedef std::vector IterSet; - bool addDefOne(std::unique_ptr Rec, Init *DefmName, - IterSet &IterVals); - bool addDefForeach(Record *Rec, Init *DefmName, IterSet &IterVals); - bool addDef(std::unique_ptr Rec, Init *DefmName); + bool addDefOne(std::unique_ptr Rec, IterSet &IterVals); + bool addDefForeach(Record *Rec, IterSet &IterVals); + bool addDef(std::unique_ptr Rec); private: // Parser methods. bool ParseObjectList(MultiClass *MC = nullptr); Index: llvm/trunk/lib/TableGen/TGParser.cpp =================================================================== --- llvm/trunk/lib/TableGen/TGParser.cpp +++ llvm/trunk/lib/TableGen/TGParser.cpp @@ -110,6 +110,16 @@ } } +/// Return the qualified version of the implicit 'NAME' template argument. +static Init *QualifiedNameOfImplicitName(Record &Rec, + MultiClass *MC = nullptr) { + return QualifyName(Rec, MC, StringInit::get("NAME"), MC ? "::" : ":"); +} + +static Init *QualifiedNameOfImplicitName(MultiClass *MC) { + return QualifiedNameOfImplicitName(MC->Rec, MC); +} + bool TGParser::AddValue(Record *CurRec, SMLoc Loc, const RecordVal &RV) { if (!CurRec) CurRec = &CurMultiClass->Rec; @@ -234,6 +244,14 @@ CurRec->removeValue(TArgs[i]); } + Init *Name; + if (CurRec->isClass()) + Name = + VarInit::get(QualifiedNameOfImplicitName(*CurRec), StringRecTy::get()); + else + Name = CurRec->getNameInit(); + R.set(QualifiedNameOfImplicitName(*SC), Name); + CurRec->resolveReferences(R); // Since everything went well, we can now set the "superclass" list for the @@ -259,80 +277,45 @@ bool TGParser::AddSubMultiClass(MultiClass *CurMC, SubMultiClassReference &SubMultiClass) { MultiClass *SMC = SubMultiClass.MC; - Record *CurRec = &CurMC->Rec; - - // Add all of the values in the subclass into the current class. - for (const auto &SMCVal : SMC->Rec.getValues()) - if (AddValue(CurRec, SubMultiClass.RefRange.Start, SMCVal)) - return true; - - unsigned newDefStart = CurMC->DefPrototypes.size(); - - // Add all of the defs in the subclass into the current multiclass. - for (const std::unique_ptr &R : SMC->DefPrototypes) { - // Clone the def and add it to the current multiclass - auto NewDef = make_unique(*R); - - // Add all of the values in the superclass into the current def. - for (const auto &MCVal : CurRec->getValues()) - if (AddValue(NewDef.get(), SubMultiClass.RefRange.Start, MCVal)) - return true; - - CurMC->DefPrototypes.push_back(std::move(NewDef)); - } ArrayRef SMCTArgs = SMC->Rec.getTemplateArgs(); - - // Ensure that an appropriate number of template arguments are - // specified. if (SMCTArgs.size() < SubMultiClass.TemplateArgs.size()) return Error(SubMultiClass.RefRange.Start, "More template args specified than expected"); - // Loop over all of the template arguments, setting them to the specified - // value or leaving them as the default if necessary. - MapResolver CurRecResolver(CurRec); - + // Prepare the mapping of template argument name to value, filling in default + // values if necessary. + SmallVector, 8> TemplateArgs; for (unsigned i = 0, e = SMCTArgs.size(); i != e; ++i) { if (i < SubMultiClass.TemplateArgs.size()) { - // If a value is specified for this template arg, set it in the - // superclass now. - if (SetValue(CurRec, SubMultiClass.RefRange.Start, SMCTArgs[i], - None, SubMultiClass.TemplateArgs[i])) - return true; - - // If a value is specified for this template arg, set it in the - // new defs now. - for (const auto &Def : - makeArrayRef(CurMC->DefPrototypes).slice(newDefStart)) { - if (SetValue(Def.get(), SubMultiClass.RefRange.Start, SMCTArgs[i], - None, SubMultiClass.TemplateArgs[i])) - return true; + TemplateArgs.emplace_back(SMCTArgs[i], SubMultiClass.TemplateArgs[i]); + } else { + Init *Default = SMC->Rec.getValue(SMCTArgs[i])->getValue(); + if (!Default->isComplete()) { + return Error(SubMultiClass.RefRange.Start, + "value not specified for template argument #" + Twine(i) + + " (" + SMCTArgs[i]->getAsUnquotedString() + + ") of multiclass '" + SMC->Rec.getNameInitAsString() + + "'"); } - } else if (!CurRec->getValue(SMCTArgs[i])->getValue()->isComplete()) { - return Error(SubMultiClass.RefRange.Start, - "Value not specified for template argument #" + - Twine(i) + " (" + SMCTArgs[i]->getAsUnquotedString() + - ") of subclass '" + SMC->Rec.getNameInitAsString() + "'!"); + TemplateArgs.emplace_back(SMCTArgs[i], Default); } - - CurRecResolver.set(SMCTArgs[i], CurRec->getValue(SMCTArgs[i])->getValue()); - - CurRec->removeValue(SMCTArgs[i]); } - CurRec->resolveReferences(CurRecResolver); + TemplateArgs.emplace_back( + QualifiedNameOfImplicitName(SMC), + VarInit::get(QualifiedNameOfImplicitName(CurMC), StringRecTy::get())); - for (const auto &Def : - makeArrayRef(CurMC->DefPrototypes).slice(newDefStart)) { - MapResolver R(Def.get()); + // Add all of the defs in the subclass into the current multiclass. + for (const std::unique_ptr &Rec : SMC->DefPrototypes) { + auto NewDef = make_unique(*Rec); - for (Init *SMCTArg : SMCTArgs) { - R.set(SMCTArg, Def->getValue(SMCTArg)->getValue()); - Def->removeValue(SMCTArg); - } + MapResolver R(NewDef.get()); + for (const auto &TArg : TemplateArgs) + R.set(TArg.first, TArg.second); + NewDef->resolveReferences(R); - Def->resolveReferences(R); + CurMC->DefPrototypes.push_back(std::move(NewDef)); } return false; @@ -343,18 +326,18 @@ /// /// Apply foreach loops, resolve internal variable references, and add to the /// current multi class or the global record keeper as appropriate. -bool TGParser::addDef(std::unique_ptr Rec, Init *DefmName) { +bool TGParser::addDef(std::unique_ptr Rec) { IterSet IterVals; if (Loops.empty()) - return addDefOne(std::move(Rec), DefmName, IterVals); + return addDefOne(std::move(Rec), IterVals); - return addDefForeach(Rec.get(), DefmName, IterVals); + return addDefForeach(Rec.get(), IterVals); } /// Recursive helper function for addDef/addDefOne to resolve references to /// foreach variables. -bool TGParser::addDefForeach(Record *Rec, Init *DefmName, IterSet &IterVals) { +bool TGParser::addDefForeach(Record *Rec, IterSet &IterVals) { if (IterVals.size() != Loops.size()) { assert(IterVals.size() < Loops.size()); ForeachLoop &CurLoop = Loops[IterVals.size()]; @@ -363,7 +346,7 @@ // Process each value. for (unsigned i = 0; i < List->size(); ++i) { IterVals.push_back(IterRecord(CurLoop.IterVar, List->getElement(i))); - if (addDefForeach(Rec, DefmName, IterVals)) + if (addDefForeach(Rec, IterVals)) return true; IterVals.pop_back(); } @@ -374,13 +357,12 @@ // for this point in the iteration space. Instantiate a new record to // reflect this combination of values. auto IterRec = make_unique(*Rec); - return addDefOne(std::move(IterRec), DefmName, IterVals); + return addDefOne(std::move(IterRec), IterVals); } /// After resolving foreach loops, add the record as a prototype to the /// current multiclass, or resolve fully and add to the record keeper. -bool TGParser::addDefOne(std::unique_ptr Rec, Init *DefmName, - IterSet &IterVals) { +bool TGParser::addDefOne(std::unique_ptr Rec, IterSet &IterVals) { MapResolver R(Rec.get()); for (IterRecord &IR : IterVals) @@ -389,32 +371,21 @@ Rec->resolveReferences(R); if (CurMultiClass) { - for (const auto &Proto : CurMultiClass->DefPrototypes) { - if (Proto->getNameInit() == Rec->getNameInit()) { - if (!Rec->isAnonymous()) { + if (!Rec->isAnonymous()) { + for (const auto &Proto : CurMultiClass->DefPrototypes) { + if (Proto->getNameInit() == Rec->getNameInit()) { PrintError(Rec->getLoc(), Twine("def '") + Rec->getNameInitAsString() + "' already defined in this multiclass!"); PrintNote(Proto->getLoc(), "location of previous definition"); return true; } - Rec->setName(Records.getNewAnonymousName()); - break; } } CurMultiClass->DefPrototypes.emplace_back(std::move(Rec)); return false; } - // Name construction is an incoherent mess. Unfortunately, existing .td - // files rely on pretty much all the quirks and implementation details of - // this. - if (DefmName) { - MapResolver R(Rec.get()); - R.set(StringInit::get("NAME"), DefmName); - Rec->resolveReferences(R); - } - if (Record *Prev = Records.getDef(Rec->getNameInitAsString())) { if (!Rec->isAnonymous()) { PrintError(Rec->getLoc(), @@ -488,7 +459,20 @@ if (CurMultiClass) CurRec = &CurMultiClass->Rec; - return ParseValue(CurRec, StringRecTy::get(), ParseNameMode); + Init *Name = ParseValue(CurRec, StringRecTy::get(), ParseNameMode); + if (!Name) + return nullptr; + + if (CurMultiClass) { + Init *NameStr = QualifiedNameOfImplicitName(CurMultiClass); + HasReferenceResolver R(NameStr); + Name->resolveReferences(R); + if (!R.found()) + Name = BinOpInit::getStrConcat(VarInit::get(NameStr, StringRecTy::get()), + Name); + } + + return Name; } /// ParseClassID - Parse and resolve a reference to a class name. This returns @@ -798,30 +782,23 @@ if (CurRec) { if (const RecordVal *RV = CurRec->getValue(Name)) return VarInit::get(Name, RV->getType()); - - Init *TemplateArgName = QualifyName(*CurRec, CurMultiClass, Name, ":"); - - if (CurMultiClass) - TemplateArgName = QualifyName(CurMultiClass->Rec, CurMultiClass, Name, - "::"); - - if (CurRec->isTemplateArg(TemplateArgName)) { - const RecordVal *RV = CurRec->getValue(TemplateArgName); - assert(RV && "Template arg doesn't exist??"); - return VarInit::get(TemplateArgName, RV->getType()); - } } - if (CurMultiClass) { - if (Name->getValue() == "NAME") - return VarInit::get(Name, StringRecTy::get()); - - Init *MCName = QualifyName(CurMultiClass->Rec, CurMultiClass, Name, "::"); - - if (CurMultiClass->Rec.isTemplateArg(MCName)) { - const RecordVal *RV = CurMultiClass->Rec.getValue(MCName); + if ((CurRec && CurRec->isClass()) || CurMultiClass) { + Init *TemplateArgName; + if (CurMultiClass) { + TemplateArgName = + QualifyName(CurMultiClass->Rec, CurMultiClass, Name, "::"); + } else + TemplateArgName = QualifyName(*CurRec, CurMultiClass, Name, ":"); + + Record *TemplateRec = CurMultiClass ? &CurMultiClass->Rec : CurRec; + if (TemplateRec->isTemplateArg(TemplateArgName)) { + const RecordVal *RV = TemplateRec->getValue(TemplateArgName); assert(RV && "Template arg doesn't exist??"); - return VarInit::get(MCName, RV->getType()); + return VarInit::get(TemplateArgName, RV->getType()); + } else if (Name->getValue() == "NAME") { + return VarInit::get(TemplateArgName, StringRecTy::get()); } } @@ -840,15 +817,12 @@ // Allow self-references of concrete defs, but delay the lookup so that we // get the correct type. - if (CurRec && !CurMultiClass && CurRec->getNameInit() == Name) + if (CurRec && !CurRec->isClass() && !CurMultiClass && + CurRec->getNameInit() == Name) return UnOpInit::get(UnOpInit::CAST, Name, CurRec->getType()); - if (Mode == ParseValueMode) { - Error(NameLoc, "Variable not defined: '" + Name->getValue() + "'"); - return nullptr; - } - - return Name; + Error(NameLoc, "Variable not defined: '" + Name->getValue() + "'"); + return nullptr; } /// ParseOperation - Parse an operator. This returns null on error. @@ -2169,8 +2143,14 @@ return nullptr; } + std::string Str = Lex.getCurStrVal(); + if (Str == "NAME") { + TokError("'" + Str + "' is a reserved variable name"); + return nullptr; + } + SMLoc IdLoc = Lex.getLoc(); - Init *DeclName = StringInit::get(Lex.getCurStrVal()); + Init *DeclName = StringInit::get(Str); Lex.Lex(); if (ParsingTemplateArgs) { @@ -2471,7 +2451,7 @@ if (ParseObjectBody(CurRec.get())) return true; - return addDef(std::move(CurRec), nullptr); + return addDef(std::move(CurRec)); } /// ParseDefset - Parse a defset statement. @@ -2585,7 +2565,7 @@ Record *CurRec = Records.getClass(Lex.getCurStrVal()); if (CurRec) { // If the body was previously defined, this is an error. - if (CurRec->getValues().size() > 1 || // Account for NAME. + if (!CurRec->getValues().empty() || !CurRec->getSuperClasses().empty() || !CurRec->getTemplateArgs().empty()) return TokError("Class '" + CurRec->getNameInitAsString() + @@ -2593,7 +2573,8 @@ } else { // If this is the first reference to this class, create and add it. auto NewRec = - llvm::make_unique(Lex.getCurStrVal(), Lex.getLoc(), Records); + llvm::make_unique(Lex.getCurStrVal(), Lex.getLoc(), Records, + /*Class=*/true); CurRec = NewRec.get(); Records.addClass(std::move(NewRec)); } @@ -2604,7 +2585,6 @@ if (ParseTemplateArgList(CurRec)) return true; - // Finally, parse the object body. return ParseObjectBody(CurRec); } @@ -2802,8 +2782,14 @@ Init *DefmName = ParseObjectName(CurMultiClass); if (!DefmName) return true; - if (isa(DefmName)) + if (isa(DefmName)) { DefmName = Records.getNewAnonymousName(); + if (CurMultiClass) + DefmName = BinOpInit::getStrConcat( + VarInit::get(QualifiedNameOfImplicitName(CurMultiClass), + StringRecTy::get()), + DefmName); + } if (Lex.getCode() != tgtok::colon) return TokError("expected ':' after defm identifier"); @@ -2836,10 +2822,10 @@ return Error(SubClassLoc, "more template args specified than multiclass expects"); - DenseMap TemplateArgs; + SmallVector, 8> TemplateArgs; for (unsigned i = 0, e = TArgs.size(); i != e; ++i) { if (i < TemplateVals.size()) { - TemplateArgs.insert({TArgs[i], TemplateVals[i]}); + TemplateArgs.emplace_back(TArgs[i], TemplateVals[i]); } else { Init *Default = MC->Rec.getValue(TArgs[i])->getValue(); if (!Default->isComplete()) { @@ -2849,45 +2835,20 @@ ") of multiclass '" + MC->Rec.getNameInitAsString() + "'"); } - TemplateArgs.insert({TArgs[i], Default}); + TemplateArgs.emplace_back(TArgs[i], Default); } } + TemplateArgs.emplace_back(QualifiedNameOfImplicitName(MC), DefmName); + // Loop over all the def's in the multiclass, instantiating each one. for (const std::unique_ptr &DefProto : MC->DefPrototypes) { - bool ResolveName = true; auto CurRec = make_unique(*DefProto); CurRec->appendLoc(SubClassLoc); - if (StringInit *NameString = - dyn_cast(CurRec->getNameInit())) { - // We have a fully expanded string so there are no operators to - // resolve. We should concatenate the given prefix and name. - // - // TODO: This MUST happen before template argument resolution. This - // does not make sense and should be changed, but at the time of - // writing, there are existing .td files which rely on this - // implementation detail. It's a bad idea and should be fixed. - // See test/TableGen/name-resolution-consistency.td for some - // examples. - CurRec->setName(BinOpInit::getStrConcat(DefmName, NameString)); - ResolveName = false; - } - MapResolver R(CurRec.get()); - - if (ResolveName) { - // If the proto's name wasn't resolved, we probably have a reference to - // NAME and need to replace it. - // - // TODO: Whether the name is resolved is basically determined by magic. - // Unfortunately, existing .td files depend on it. - R.set(StringInit::get("NAME"), DefmName); - } - for (const auto &TArg : TemplateArgs) R.set(TArg.first, TArg.second); - CurRec->resolveReferences(R); NewRecDefs.emplace_back(std::move(CurRec)); @@ -2937,7 +2898,7 @@ if (ApplyLetStack(CurRec.get())) return true; - addDef(std::move(CurRec), DefmName); + addDef(std::move(CurRec)); } if (Lex.getCode() != tgtok::semi) Index: llvm/trunk/lib/Target/AArch64/AArch64InstrFormats.td =================================================================== --- llvm/trunk/lib/Target/AArch64/AArch64InstrFormats.td +++ llvm/trunk/lib/Target/AArch64/AArch64InstrFormats.td @@ -8655,14 +8655,14 @@ // The immediate form of AdvSIMD post-indexed addressing is encoded with // register post-index addressing from the zero register. -multiclass SIMDLdStAliases { // E.g. "ld1 { v0.8b, v1.8b }, [x1], #16" // "ld1\t$Vt, [$Rn], #16" // may get mapped to // (LD1Twov8b_POST VecListTwo8b:$Vt, GPR64sp:$Rn, XZR) def : InstAlias(NAME # Count # "v" # layout # "_POST") + (!cast(BaseName # Count # "v" # layout # "_POST") GPR64sp:$Rn, !cast("VecList" # Count # layout):$Vt, XZR), 1>; @@ -8672,7 +8672,7 @@ // may get mapped to // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, XZR) def : InstAlias(NAME # Count # "v" # layout # "_POST") + (!cast(BaseName # Count # "v" # layout # "_POST") GPR64sp:$Rn, !cast("VecList" # Count # Size):$Vt, XZR), 0>; @@ -8682,7 +8682,7 @@ // may get mapped to // (LD1Twov8b VecListTwo64:$Vt, GPR64sp:$Rn) def : InstAlias(NAME # Count # "v" # layout) + (!cast(BaseName # Count # "v" # layout) !cast("VecList" # Count # Size):$Vt, GPR64sp:$Rn), 0>; @@ -8691,14 +8691,14 @@ // may get mapped to // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, GPR64pi8:$Xm) def : InstAlias(NAME # Count # "v" # layout # "_POST") + (!cast(BaseName # Count # "v" # layout # "_POST") GPR64sp:$Rn, !cast("VecList" # Count # Size):$Vt, !cast("GPR64pi" # Offset):$Xm), 0>; } -multiclass BaseSIMDLdN opcode> { +multiclass BaseSIMDLdN opcode> { let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { def v16b: BaseSIMDLdSt<1, 1, opcode, 0b00, asm, (outs !cast(veclist # "16b"):$Vt), @@ -8760,18 +8760,18 @@ !cast("GPR64pi" # Offset64):$Xm)>; } - defm : SIMDLdStAliases; - defm : SIMDLdStAliases; - defm : SIMDLdStAliases; - defm : SIMDLdStAliases; - defm : SIMDLdStAliases; - defm : SIMDLdStAliases; - defm : SIMDLdStAliases; + defm : SIMDLdStAliases; + defm : SIMDLdStAliases; + defm : SIMDLdStAliases; + defm : SIMDLdStAliases; + defm : SIMDLdStAliases; + defm : SIMDLdStAliases; + defm : SIMDLdStAliases; } // Only ld1/st1 has a v1d version. -multiclass BaseSIMDStN opcode> { +multiclass BaseSIMDStN opcode> { let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in { def v16b : BaseSIMDLdSt<1, 0, opcode, 0b00, asm, (outs), (ins !cast(veclist # "16b"):$Vt, @@ -8832,18 +8832,18 @@ !cast("GPR64pi" # Offset64):$Xm)>; } - defm : SIMDLdStAliases; - defm : SIMDLdStAliases; - defm : SIMDLdStAliases; - defm : SIMDLdStAliases; - defm : SIMDLdStAliases; - defm : SIMDLdStAliases; - defm : SIMDLdStAliases; + defm : SIMDLdStAliases; + defm : SIMDLdStAliases; + defm : SIMDLdStAliases; + defm : SIMDLdStAliases; + defm : SIMDLdStAliases; + defm : SIMDLdStAliases; + defm : SIMDLdStAliases; } -multiclass BaseSIMDLd1 opcode> - : BaseSIMDLdN { + : BaseSIMDLdN { // LD1 instructions have extra "1d" variants. let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in { @@ -8858,12 +8858,12 @@ !cast("GPR64pi" # Offset64):$Xm)>; } - defm : SIMDLdStAliases; + defm : SIMDLdStAliases; } -multiclass BaseSIMDSt1 opcode> - : BaseSIMDStN { + : BaseSIMDStN { // ST1 instructions have extra "1d" variants. let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in { @@ -8878,45 +8878,45 @@ !cast("GPR64pi" # Offset64):$Xm)>; } - defm : SIMDLdStAliases; + defm : SIMDLdStAliases; } multiclass SIMDLd1Multiple { - defm One : BaseSIMDLd1<"One", asm, "VecListOne", 16, 8, 0b0111>; - defm Two : BaseSIMDLd1<"Two", asm, "VecListTwo", 32, 16, 0b1010>; - defm Three : BaseSIMDLd1<"Three", asm, "VecListThree", 48, 24, 0b0110>; - defm Four : BaseSIMDLd1<"Four", asm, "VecListFour", 64, 32, 0b0010>; + defm One : BaseSIMDLd1; + defm Two : BaseSIMDLd1; + defm Three : BaseSIMDLd1; + defm Four : BaseSIMDLd1; } multiclass SIMDSt1Multiple { - defm One : BaseSIMDSt1<"One", asm, "VecListOne", 16, 8, 0b0111>; - defm Two : BaseSIMDSt1<"Two", asm, "VecListTwo", 32, 16, 0b1010>; - defm Three : BaseSIMDSt1<"Three", asm, "VecListThree", 48, 24, 0b0110>; - defm Four : BaseSIMDSt1<"Four", asm, "VecListFour", 64, 32, 0b0010>; + defm One : BaseSIMDSt1; + defm Two : BaseSIMDSt1; + defm Three : BaseSIMDSt1; + defm Four : BaseSIMDSt1; } multiclass SIMDLd2Multiple { - defm Two : BaseSIMDLdN<"Two", asm, "VecListTwo", 32, 16, 0b1000>; + defm Two : BaseSIMDLdN; } multiclass SIMDSt2Multiple { - defm Two : BaseSIMDStN<"Two", asm, "VecListTwo", 32, 16, 0b1000>; + defm Two : BaseSIMDStN; } multiclass SIMDLd3Multiple { - defm Three : BaseSIMDLdN<"Three", asm, "VecListThree", 48, 24, 0b0100>; + defm Three : BaseSIMDLdN; } multiclass SIMDSt3Multiple { - defm Three : BaseSIMDStN<"Three", asm, "VecListThree", 48, 24, 0b0100>; + defm Three : BaseSIMDStN; } multiclass SIMDLd4Multiple { - defm Four : BaseSIMDLdN<"Four", asm, "VecListFour", 64, 32, 0b0000>; + defm Four : BaseSIMDLdN; } multiclass SIMDSt4Multiple { - defm Four : BaseSIMDStN<"Four", asm, "VecListFour", 64, 32, 0b0000>; + defm Four : BaseSIMDStN; } //--- @@ -8981,14 +8981,14 @@ let Inst{11-10} = size; } -multiclass SIMDLdrAliases { // E.g. "ld1r { v0.8b }, [x1], #1" // "ld1r.8b\t$Vt, [$Rn], #1" // may get mapped to // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR) def : InstAlias(NAME # "v" # layout # "_POST") + (!cast(BaseName # "v" # layout # "_POST") GPR64sp:$Rn, !cast("VecList" # Count # layout):$Vt, XZR), 1>; @@ -8998,7 +8998,7 @@ // may get mapped to // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR) def : InstAlias(NAME # "v" # layout # "_POST") + (!cast(BaseName # "v" # layout # "_POST") GPR64sp:$Rn, !cast("VecList" # Count # Size):$Vt, XZR), 0>; @@ -9008,7 +9008,7 @@ // may get mapped to // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn) def : InstAlias(NAME # "v" # layout) + (!cast(BaseName # "v" # layout) !cast("VecList" # Count # Size):$Vt, GPR64sp:$Rn), 0>; @@ -9017,7 +9017,7 @@ // may get mapped to // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm) def : InstAlias(NAME # "v" # layout # "_POST") + (!cast(BaseName # "v" # layout # "_POST") GPR64sp:$Rn, !cast("VecList" # Count # Size):$Vt, !cast("GPR64pi" # Offset):$Xm), 0>; @@ -9067,14 +9067,14 @@ !cast("VecList" # Count # "2d"), !cast("GPR64pi" # Offset8)>; - defm : SIMDLdrAliases; - defm : SIMDLdrAliases; - defm : SIMDLdrAliases; - defm : SIMDLdrAliases; - defm : SIMDLdrAliases; - defm : SIMDLdrAliases; - defm : SIMDLdrAliases; - defm : SIMDLdrAliases; + defm : SIMDLdrAliases; + defm : SIMDLdrAliases; + defm : SIMDLdrAliases; + defm : SIMDLdrAliases; + defm : SIMDLdrAliases; + defm : SIMDLdrAliases; + defm : SIMDLdrAliases; + defm : SIMDLdrAliases; } class SIMDLdStSingleB opcode, string asm, @@ -9432,31 +9432,31 @@ } multiclass SIMDLdSt1SingleAliases { - defm : SIMDLdStSingleAliases; - defm : SIMDLdStSingleAliases; - defm : SIMDLdStSingleAliases; - defm : SIMDLdStSingleAliases; + defm "" : SIMDLdStSingleAliases; + defm "" : SIMDLdStSingleAliases; + defm "" : SIMDLdStSingleAliases; + defm "" : SIMDLdStSingleAliases; } multiclass SIMDLdSt2SingleAliases { - defm : SIMDLdStSingleAliases; - defm : SIMDLdStSingleAliases; - defm : SIMDLdStSingleAliases; - defm : SIMDLdStSingleAliases; + defm "" : SIMDLdStSingleAliases; + defm "" : SIMDLdStSingleAliases; + defm "" : SIMDLdStSingleAliases; + defm "" : SIMDLdStSingleAliases; } multiclass SIMDLdSt3SingleAliases { - defm : SIMDLdStSingleAliases; - defm : SIMDLdStSingleAliases; - defm : SIMDLdStSingleAliases; - defm : SIMDLdStSingleAliases; + defm "" : SIMDLdStSingleAliases; + defm "" : SIMDLdStSingleAliases; + defm "" : SIMDLdStSingleAliases; + defm "" : SIMDLdStSingleAliases; } multiclass SIMDLdSt4SingleAliases { - defm : SIMDLdStSingleAliases; - defm : SIMDLdStSingleAliases; - defm : SIMDLdStSingleAliases; - defm : SIMDLdStSingleAliases; + defm "" : SIMDLdStSingleAliases; + defm "" : SIMDLdStSingleAliases; + defm "" : SIMDLdStSingleAliases; + defm "" : SIMDLdStSingleAliases; } } // end of 'let Predicates = [HasNEON]' Index: llvm/trunk/lib/Target/AMDGPU/BUFInstructions.td =================================================================== --- llvm/trunk/lib/Target/AMDGPU/BUFInstructions.td +++ llvm/trunk/lib/Target/AMDGPU/BUFInstructions.td @@ -52,19 +52,19 @@ ""))))); } -class MUBUFAddr64Table { +class MUBUFAddr64Table { bit IsAddr64 = is_addr64; - string OpName = NAME # suffix; + string OpName = Name; } -class MUBUFLdsTable { +class MUBUFLdsTable { bit IsLds = is_lds; - string OpName = NAME # suffix; + string OpName = Name; } -class MTBUFAddr64Table { +class MTBUFAddr64Table { bit IsAddr64 = is_addr64; - string OpName = NAME # suffix; + string OpName = Name; } //===----------------------------------------------------------------------===// @@ -219,13 +219,13 @@ [(set load_vt:$vdata, (ld (MUBUFOffset v4i32:$srsrc, i32:$soffset, i16:$offset, i8:$dfmt, i8:$nfmt, i1:$glc, i1:$slc, i1:$tfe)))]>, - MTBUFAddr64Table<0>; + MTBUFAddr64Table<0, NAME>; def _ADDR64 : MTBUF_Load_Pseudo , - MTBUFAddr64Table<1>; + MTBUFAddr64Table<1, NAME>; def _OFFEN : MTBUF_Load_Pseudo ; def _IDXEN : MTBUF_Load_Pseudo ; @@ -265,13 +265,13 @@ [(st store_vt:$vdata, (MUBUFOffset v4i32:$srsrc, i32:$soffset, i16:$offset, i8:$dfmt, i8:$nfmt, i1:$glc, i1:$slc, i1:$tfe))]>, - MTBUFAddr64Table<0>; + MTBUFAddr64Table<0, NAME>; def _ADDR64 : MTBUF_Store_Pseudo , - MTBUFAddr64Table<1>; + MTBUFAddr64Table<1, NAME>; def _OFFEN : MTBUF_Store_Pseudo ; def _IDXEN : MTBUF_Store_Pseudo ; @@ -474,7 +474,7 @@ [], [(set load_vt:$vdata, (ld (MUBUFOffset v4i32:$srsrc, i32:$soffset, i16:$offset, i1:$glc, i1:$slc, i1:$tfe)))])>, - MUBUFAddr64Table<0, !if(isLds, "_LDS", "")>; + MUBUFAddr64Table<0, NAME # !if(isLds, "_LDS", "")>; def _ADDR64 : MUBUF_Load_Pseudo , - MUBUFAddr64Table<1, !if(isLds, "_LDS", "")>; + MUBUFAddr64Table<1, NAME # !if(isLds, "_LDS", "")>; def _OFFEN : MUBUF_Load_Pseudo ; def _IDXEN : MUBUF_Load_Pseudo ; @@ -530,12 +530,12 @@ def _OFFSET : MUBUF_Store_Pseudo , - MUBUFAddr64Table<0>; + MUBUFAddr64Table<0, NAME>; def _ADDR64 : MUBUF_Store_Pseudo , - MUBUFAddr64Table<1>; + MUBUFAddr64Table<1, NAME>; def _OFFEN : MUBUF_Store_Pseudo ; def _IDXEN : MUBUF_Store_Pseudo ; @@ -666,9 +666,9 @@ SDPatternOperator atomic> { def _OFFSET : MUBUF_AtomicNoRet_Pseudo , - MUBUFAddr64Table <0>; + MUBUFAddr64Table <0, NAME>; def _ADDR64 : MUBUF_AtomicNoRet_Pseudo , - MUBUFAddr64Table <1>; + MUBUFAddr64Table <1, NAME>; def _OFFEN : MUBUF_AtomicNoRet_Pseudo ; def _IDXEN : MUBUF_AtomicNoRet_Pseudo ; def _BOTHEN : MUBUF_AtomicNoRet_Pseudo ; @@ -677,13 +677,13 @@ [(set vdataType:$vdata, (atomic (MUBUFOffsetAtomic v4i32:$srsrc, i32:$soffset, i16:$offset, i1:$slc), vdataType:$vdata_in))]>, - MUBUFAddr64Table <0, "_RTN">; + MUBUFAddr64Table <0, NAME # "_RTN">; def _ADDR64_RTN : MUBUF_AtomicRet_Pseudo , - MUBUFAddr64Table <1, "_RTN">; + MUBUFAddr64Table <1, NAME # "_RTN">; def _OFFEN_RTN : MUBUF_AtomicRet_Pseudo ; def _IDXEN_RTN : MUBUF_AtomicRet_Pseudo ; @@ -1663,26 +1663,26 @@ multiclass MUBUF_Real_AllAddr_Lds_si op> { def _OFFSET_si : MUBUF_Real_si (NAME#"_OFFSET")>, - MUBUFLdsTable<0, "_OFFSET_si">; + MUBUFLdsTable<0, NAME # "_OFFSET_si">; def _ADDR64_si : MUBUF_Real_si (NAME#"_ADDR64")>, - MUBUFLdsTable<0, "_ADDR64_si">; + MUBUFLdsTable<0, NAME # "_ADDR64_si">; def _OFFEN_si : MUBUF_Real_si (NAME#"_OFFEN")>, - MUBUFLdsTable<0, "_OFFEN_si">; + MUBUFLdsTable<0, NAME # "_OFFEN_si">; def _IDXEN_si : MUBUF_Real_si (NAME#"_IDXEN")>, - MUBUFLdsTable<0, "_IDXEN_si">; + MUBUFLdsTable<0, NAME # "_IDXEN_si">; def _BOTHEN_si : MUBUF_Real_si (NAME#"_BOTHEN")>, - MUBUFLdsTable<0, "_BOTHEN_si">; + MUBUFLdsTable<0, NAME # "_BOTHEN_si">; def _LDS_OFFSET_si : MUBUF_Real_si (NAME#"_LDS_OFFSET")>, - MUBUFLdsTable<1, "_OFFSET_si">; + MUBUFLdsTable<1, NAME # "_OFFSET_si">; def _LDS_ADDR64_si : MUBUF_Real_si (NAME#"_LDS_ADDR64")>, - MUBUFLdsTable<1, "_ADDR64_si">; + MUBUFLdsTable<1, NAME # "_ADDR64_si">; def _LDS_OFFEN_si : MUBUF_Real_si (NAME#"_LDS_OFFEN")>, - MUBUFLdsTable<1, "_OFFEN_si">; + MUBUFLdsTable<1, NAME # "_OFFEN_si">; def _LDS_IDXEN_si : MUBUF_Real_si (NAME#"_LDS_IDXEN")>, - MUBUFLdsTable<1, "_IDXEN_si">; + MUBUFLdsTable<1, NAME # "_IDXEN_si">; def _LDS_BOTHEN_si : MUBUF_Real_si (NAME#"_LDS_BOTHEN")>, - MUBUFLdsTable<1, "_BOTHEN_si">; + MUBUFLdsTable<1, NAME # "_BOTHEN_si">; } multiclass MUBUF_Real_Atomic_si op> : MUBUF_Real_AllAddr_si { @@ -1846,22 +1846,22 @@ multiclass MUBUF_Real_AllAddr_Lds_vi op> { def _OFFSET_vi : MUBUF_Real_vi (NAME#"_OFFSET")>, - MUBUFLdsTable<0, "_OFFSET_vi">; + MUBUFLdsTable<0, NAME # "_OFFSET_vi">; def _OFFEN_vi : MUBUF_Real_vi (NAME#"_OFFEN")>, - MUBUFLdsTable<0, "_OFFEN_vi">; + MUBUFLdsTable<0, NAME # "_OFFEN_vi">; def _IDXEN_vi : MUBUF_Real_vi (NAME#"_IDXEN")>, - MUBUFLdsTable<0, "_IDXEN_vi">; + MUBUFLdsTable<0, NAME # "_IDXEN_vi">; def _BOTHEN_vi : MUBUF_Real_vi (NAME#"_BOTHEN")>, - MUBUFLdsTable<0, "_BOTHEN_vi">; + MUBUFLdsTable<0, NAME # "_BOTHEN_vi">; def _LDS_OFFSET_vi : MUBUF_Real_vi (NAME#"_LDS_OFFSET")>, - MUBUFLdsTable<1, "_OFFSET_vi">; + MUBUFLdsTable<1, NAME # "_OFFSET_vi">; def _LDS_OFFEN_vi : MUBUF_Real_vi (NAME#"_LDS_OFFEN")>, - MUBUFLdsTable<1, "_OFFEN_vi">; + MUBUFLdsTable<1, NAME # "_OFFEN_vi">; def _LDS_IDXEN_vi : MUBUF_Real_vi (NAME#"_LDS_IDXEN")>, - MUBUFLdsTable<1, "_IDXEN_vi">; + MUBUFLdsTable<1, NAME # "_IDXEN_vi">; def _LDS_BOTHEN_vi : MUBUF_Real_vi (NAME#"_LDS_BOTHEN")>, - MUBUFLdsTable<1, "_BOTHEN_vi">; + MUBUFLdsTable<1, NAME # "_BOTHEN_vi">; } class MUBUF_Real_gfx80 op, MUBUF_Pseudo ps> : Index: llvm/trunk/lib/Target/AMDGPU/MIMGInstructions.td =================================================================== --- llvm/trunk/lib/Target/AMDGPU/MIMGInstructions.td +++ llvm/trunk/lib/Target/AMDGPU/MIMGInstructions.td @@ -280,15 +280,15 @@ multiclass MIMG_Sampler_Src_Helper op, string asm, RegisterClass dst_rc, int channels, bit wqm> { - defm : MIMG_Sampler_Src_Helper_Helper ; + defm "" : MIMG_Sampler_Src_Helper_Helper ; let d16 = 1 in { let SubtargetPredicate = HasPackedD16VMem in { - defm : MIMG_Sampler_Src_Helper_Helper ; + defm "" : MIMG_Sampler_Src_Helper_Helper ; } // End HasPackedD16VMem. let SubtargetPredicate = HasUnpackedD16VMem, DecoderNamespace = "GFX80_UNPACKED" in { - defm : MIMG_Sampler_Src_Helper_Helper ; + defm "" : MIMG_Sampler_Src_Helper_Helper ; } // End HasUnpackedD16VMem. } // End d16 = 1. } @@ -348,15 +348,15 @@ } multiclass MIMG_Gather op, string asm, bit wqm=0> { - defm : MIMG_Gather_Src_Helper; + defm "" : MIMG_Gather_Src_Helper; let d16 = 1 in { let AssemblerPredicate = HasPackedD16VMem in { - defm : MIMG_Gather_Src_Helper; + defm "" : MIMG_Gather_Src_Helper; } // End HasPackedD16VMem. let AssemblerPredicate = HasUnpackedD16VMem, DecoderNamespace = "GFX80_UNPACKED" in { - defm : MIMG_Gather_Src_Helper; + defm "" : MIMG_Gather_Src_Helper; } // End HasUnpackedD16VMem. } // End d16 = 1. } Index: llvm/trunk/lib/Target/X86/X86InstrAVX512.td =================================================================== --- llvm/trunk/lib/Target/X86/X86InstrAVX512.td +++ llvm/trunk/lib/Target/X86/X86InstrAVX512.td @@ -1130,26 +1130,28 @@ //--- // broadcast with a scalar argument. multiclass avx512_broadcast_scalar opc, string OpcodeStr, + string Name, X86VectorVTInfo DestInfo, X86VectorVTInfo SrcInfo> { def : Pat<(DestInfo.VT (X86VBroadcast SrcInfo.FRC:$src)), - (!cast(NAME#DestInfo.ZSuffix#r) + (!cast(Name#DestInfo.ZSuffix#r) (COPY_TO_REGCLASS SrcInfo.FRC:$src, SrcInfo.RC))>; def : Pat<(DestInfo.VT (vselect DestInfo.KRCWM:$mask, (X86VBroadcast SrcInfo.FRC:$src), DestInfo.RC:$src0)), - (!cast(NAME#DestInfo.ZSuffix#rk) + (!cast(Name#DestInfo.ZSuffix#rk) DestInfo.RC:$src0, DestInfo.KRCWM:$mask, (COPY_TO_REGCLASS SrcInfo.FRC:$src, SrcInfo.RC))>; def : Pat<(DestInfo.VT (vselect DestInfo.KRCWM:$mask, (X86VBroadcast SrcInfo.FRC:$src), DestInfo.ImmAllZerosV)), - (!cast(NAME#DestInfo.ZSuffix#rkz) + (!cast(Name#DestInfo.ZSuffix#rkz) DestInfo.KRCWM:$mask, (COPY_TO_REGCLASS SrcInfo.FRC:$src, SrcInfo.RC))>; } // Split version to allow mask and broadcast node to be different types. This // helps support the 32x2 broadcasts. multiclass avx512_broadcast_rm_split opc, string OpcodeStr, + string Name, SchedWrite SchedRR, SchedWrite SchedRM, X86VectorVTInfo MaskInfo, X86VectorVTInfo DestInfo, @@ -1189,7 +1191,7 @@ (DestInfo.VT (UnmaskedOp (SrcInfo.VT (scalar_to_vector (SrcInfo.ScalarLdFrag addr:$src))))))), - (!cast(NAME#MaskInfo.ZSuffix#m) addr:$src)>; + (!cast(Name#MaskInfo.ZSuffix#m) addr:$src)>; def : Pat<(MaskInfo.VT (vselect MaskInfo.KRCWM:$mask, (bitconvert (DestInfo.VT @@ -1197,7 +1199,7 @@ (SrcInfo.VT (scalar_to_vector (SrcInfo.ScalarLdFrag addr:$src)))))), MaskInfo.RC:$src0)), - (!cast(NAME#DestInfo.ZSuffix#mk) + (!cast(Name#DestInfo.ZSuffix#mk) MaskInfo.RC:$src0, MaskInfo.KRCWM:$mask, addr:$src)>; def : Pat<(MaskInfo.VT (vselect MaskInfo.KRCWM:$mask, (bitconvert @@ -1206,53 +1208,58 @@ (SrcInfo.VT (scalar_to_vector (SrcInfo.ScalarLdFrag addr:$src)))))), MaskInfo.ImmAllZerosV)), - (!cast(NAME#MaskInfo.ZSuffix#mkz) + (!cast(Name#MaskInfo.ZSuffix#mkz) MaskInfo.KRCWM:$mask, addr:$src)>; } // Helper class to force mask and broadcast result to same type. -multiclass avx512_broadcast_rm opc, string OpcodeStr, +multiclass avx512_broadcast_rm opc, string OpcodeStr, string Name, SchedWrite SchedRR, SchedWrite SchedRM, X86VectorVTInfo DestInfo, X86VectorVTInfo SrcInfo> : - avx512_broadcast_rm_split; multiclass avx512_fp_broadcast_sd opc, string OpcodeStr, AVX512VLVectorVTInfo _> { let Predicates = [HasAVX512] in { - defm Z : avx512_broadcast_rm, - avx512_broadcast_scalar, - EVEX_V512; + avx512_broadcast_scalar, + EVEX_V512; } let Predicates = [HasVLX] in { - defm Z256 : avx512_broadcast_rm, - avx512_broadcast_scalar, - EVEX_V256; + avx512_broadcast_scalar, + EVEX_V256; } } multiclass avx512_fp_broadcast_ss opc, string OpcodeStr, AVX512VLVectorVTInfo _> { let Predicates = [HasAVX512] in { - defm Z : avx512_broadcast_rm, - avx512_broadcast_scalar, - EVEX_V512; + avx512_broadcast_scalar, + EVEX_V512; } let Predicates = [HasVLX] in { - defm Z256 : avx512_broadcast_rm, - avx512_broadcast_scalar, - EVEX_V256; - defm Z128 : avx512_broadcast_rm, + EVEX_V256; + defm Z128 : avx512_broadcast_rm, - avx512_broadcast_scalar, - EVEX_V128; + avx512_broadcast_scalar, + EVEX_V128; } } defm VBROADCASTSS : avx512_fp_broadcast_ss<0x18, "vbroadcastss", @@ -1335,29 +1342,30 @@ // Provide aliases for broadcast from the same register class that // automatically does the extract. -multiclass avx512_int_broadcast_rm_lowering { def : Pat<(DestInfo.VT (X86VBroadcast (SrcInfo.VT SrcInfo.RC:$src))), - (!cast(NAME#DestInfo.ZSuffix#"r") + (!cast(Name#DestInfo.ZSuffix#"r") (EXTRACT_SUBREG (SrcInfo.VT SrcInfo.RC:$src), sub_xmm))>; } multiclass avx512_int_broadcast_rm_vl opc, string OpcodeStr, AVX512VLVectorVTInfo _, Predicate prd> { let Predicates = [prd] in { - defm Z : avx512_broadcast_rm, - avx512_int_broadcast_rm_lowering<_.info512, _.info256>, + avx512_int_broadcast_rm_lowering, EVEX_V512; // Defined separately to avoid redefinition. - defm Z_Alt : avx512_int_broadcast_rm_lowering<_.info512, _.info512>; + defm Z_Alt : avx512_int_broadcast_rm_lowering; } let Predicates = [prd, HasVLX] in { - defm Z256 : avx512_broadcast_rm, - avx512_int_broadcast_rm_lowering<_.info256, _.info256>, + avx512_int_broadcast_rm_lowering, EVEX_V256; - defm Z128 : avx512_broadcast_rm, EVEX_V128; } @@ -1656,12 +1664,12 @@ multiclass avx512_common_broadcast_32x2 opc, string OpcodeStr, AVX512VLVectorVTInfo _Dst, AVX512VLVectorVTInfo _Src> { let Predicates = [HasDQI] in - defm Z : avx512_broadcast_rm_split, EVEX_V512; let Predicates = [HasDQI, HasVLX] in - defm Z256 : avx512_broadcast_rm_split, EVEX_V256; @@ -1672,7 +1680,7 @@ avx512_common_broadcast_32x2 { let Predicates = [HasDQI, HasVLX] in - defm Z128 : avx512_broadcast_rm_split, EVEX_V128; @@ -2279,7 +2287,8 @@ }]>; multiclass avx512_icmp_cc opc, string Suffix, SDNode OpNode, - X86FoldableSchedWrite sched, X86VectorVTInfo _> { + X86FoldableSchedWrite sched, X86VectorVTInfo _, + string Name> { let isCommutable = 1 in def rri : AVX512AIi8(NAME#_.ZSuffix#"rmi") _.RC:$src1, addr:$src2, + (!cast(Name#_.ZSuffix#"rmi") _.RC:$src1, addr:$src2, (CommutePCMPCC imm:$cc))>; def : Pat<(and _.KRCWM:$mask, (OpNode (bitconvert (_.LdFrag addr:$src2)), (_.VT _.RC:$src1), imm:$cc)), - (!cast(NAME#_.ZSuffix#"rmik") _.KRCWM:$mask, + (!cast(Name#_.ZSuffix#"rmik") _.KRCWM:$mask, _.RC:$src1, addr:$src2, (CommutePCMPCC imm:$cc))>; } multiclass avx512_icmp_cc_rmb opc, string Suffix, SDNode OpNode, - X86FoldableSchedWrite sched, X86VectorVTInfo _> : - avx512_icmp_cc { + X86FoldableSchedWrite sched, X86VectorVTInfo _, + string Name> : + avx512_icmp_cc { def rmib : AVX512AIi8(NAME#_.ZSuffix#"rmib") _.RC:$src1, addr:$src2, + (!cast(Name#_.ZSuffix#"rmib") _.RC:$src1, addr:$src2, (CommutePCMPCC imm:$cc))>; def : Pat<(and _.KRCWM:$mask, (OpNode (X86VBroadcast (_.ScalarLdFrag addr:$src2)), (_.VT _.RC:$src1), imm:$cc)), - (!cast(NAME#_.ZSuffix#"rmibk") _.KRCWM:$mask, + (!cast(Name#_.ZSuffix#"rmibk") _.KRCWM:$mask, _.RC:$src1, addr:$src2, (CommutePCMPCC imm:$cc))>; } @@ -2421,14 +2431,16 @@ X86SchedWriteWidths sched, AVX512VLVectorVTInfo VTInfo, Predicate prd> { let Predicates = [prd] in - defm Z : avx512_icmp_cc, - EVEX_V512; + defm Z : avx512_icmp_cc, + EVEX_V512; let Predicates = [prd, HasVLX] in { - defm Z256 : avx512_icmp_cc, - EVEX_V256; - defm Z128 : avx512_icmp_cc, - EVEX_V128; + defm Z256 : avx512_icmp_cc, + EVEX_V256; + defm Z128 : avx512_icmp_cc, + EVEX_V128; } } @@ -2437,13 +2449,13 @@ AVX512VLVectorVTInfo VTInfo, Predicate prd> { let Predicates = [prd] in defm Z : avx512_icmp_cc_rmb, EVEX_V512; + VTInfo.info512, NAME>, EVEX_V512; let Predicates = [prd, HasVLX] in { defm Z256 : avx512_icmp_cc_rmb, EVEX_V256; + VTInfo.info256, NAME>, EVEX_V256; defm Z128 : avx512_icmp_cc_rmb, EVEX_V128; + VTInfo.info128, NAME>, EVEX_V128; } } @@ -2474,7 +2486,8 @@ avx512vl_i64_info, HasAVX512>, VEX_W, EVEX_CD8<64, CD8VF>; -multiclass avx512_vcmp_common { +multiclass avx512_vcmp_common { defm rri : AVX512_maskable_cmp<0xC2, MRMSrcReg, _, (outs _.KRC:$dst), (ins _.RC:$src1, _.RC:$src2,AVXCC:$cc), "vcmp${cc}"#_.Suffix, @@ -2533,26 +2546,26 @@ // Patterns for selecting with loads in other operand. def : Pat<(X86cmpm (_.LdFrag addr:$src2), (_.VT _.RC:$src1), CommutableCMPCC:$cc), - (!cast(NAME#_.ZSuffix#"rmi") _.RC:$src1, addr:$src2, + (!cast(Name#_.ZSuffix#"rmi") _.RC:$src1, addr:$src2, imm:$cc)>; def : Pat<(and _.KRCWM:$mask, (X86cmpm (_.LdFrag addr:$src2), (_.VT _.RC:$src1), CommutableCMPCC:$cc)), - (!cast(NAME#_.ZSuffix#"rmik") _.KRCWM:$mask, + (!cast(Name#_.ZSuffix#"rmik") _.KRCWM:$mask, _.RC:$src1, addr:$src2, imm:$cc)>; def : Pat<(X86cmpm (X86VBroadcast (_.ScalarLdFrag addr:$src2)), (_.VT _.RC:$src1), CommutableCMPCC:$cc), - (!cast(NAME#_.ZSuffix#"rmbi") _.RC:$src1, addr:$src2, + (!cast(Name#_.ZSuffix#"rmbi") _.RC:$src1, addr:$src2, imm:$cc)>; def : Pat<(and _.KRCWM:$mask, (X86cmpm (X86VBroadcast (_.ScalarLdFrag addr:$src2)), (_.VT _.RC:$src1), CommutableCMPCC:$cc)), - (!cast(NAME#_.ZSuffix#"rmbik") _.KRCWM:$mask, + (!cast(Name#_.ZSuffix#"rmbik") _.KRCWM:$mask, _.RC:$src1, addr:$src2, imm:$cc)>; } @@ -2582,13 +2595,13 @@ multiclass avx512_vcmp { let Predicates = [HasAVX512] in { - defm Z : avx512_vcmp_common, + defm Z : avx512_vcmp_common, avx512_vcmp_sae, EVEX_V512; } let Predicates = [HasAVX512,HasVLX] in { - defm Z128 : avx512_vcmp_common, EVEX_V128; - defm Z256 : avx512_vcmp_common, EVEX_V256; + defm Z128 : avx512_vcmp_common, EVEX_V128; + defm Z256 : avx512_vcmp_common, EVEX_V256; } } @@ -3236,7 +3249,7 @@ // AVX-512 - Aligned and unaligned load and store // -multiclass avx512_load opc, string OpcodeStr, +multiclass avx512_load opc, string OpcodeStr, string Name, X86VectorVTInfo _, PatFrag ld_frag, PatFrag mload, X86SchedWriteMoveLS Sched, bit NoRMPattern = 0, SDPatternOperator SelectOprr = vselect> { @@ -3290,13 +3303,13 @@ _.ExeDomain>, EVEX, EVEX_KZ, Sched<[Sched.RM]>; } def : Pat<(_.VT (mload addr:$ptr, _.KRCWM:$mask, undef)), - (!cast(NAME#_.ZSuffix##rmkz) _.KRCWM:$mask, addr:$ptr)>; + (!cast(Name#_.ZSuffix##rmkz) _.KRCWM:$mask, addr:$ptr)>; def : Pat<(_.VT (mload addr:$ptr, _.KRCWM:$mask, _.ImmAllZerosV)), - (!cast(NAME#_.ZSuffix##rmkz) _.KRCWM:$mask, addr:$ptr)>; + (!cast(Name#_.ZSuffix##rmkz) _.KRCWM:$mask, addr:$ptr)>; def : Pat<(_.VT (mload addr:$ptr, _.KRCWM:$mask, (_.VT _.RC:$src0))), - (!cast(NAME#_.ZSuffix##rmk) _.RC:$src0, + (!cast(Name#_.ZSuffix##rmk) _.RC:$src0, _.KRCWM:$mask, addr:$ptr)>; } @@ -3305,15 +3318,15 @@ X86SchedWriteMoveLSWidths Sched, bit NoRMPattern = 0> { let Predicates = [prd] in - defm Z : avx512_load, EVEX_V512; let Predicates = [prd, HasVLX] in { - defm Z256 : avx512_load, EVEX_V256; - defm Z128 : avx512_load, EVEX_V128; } @@ -3325,21 +3338,21 @@ bit NoRMPattern = 0, SDPatternOperator SelectOprr = vselect> { let Predicates = [prd] in - defm Z : avx512_load, EVEX_V512; let Predicates = [prd, HasVLX] in { - defm Z256 : avx512_load, EVEX_V256; - defm Z128 : avx512_load, EVEX_V128; } } -multiclass avx512_store opc, string OpcodeStr, +multiclass avx512_store opc, string OpcodeStr, string BaseName, X86VectorVTInfo _, PatFrag st_frag, PatFrag mstore, string Name, X86SchedWriteMoveLS Sched, bit NoMRPattern = 0> { @@ -3375,8 +3388,8 @@ [], _.ExeDomain>, EVEX, EVEX_K, Sched<[Sched.MR]>; def: Pat<(mstore addr:$ptr, _.KRCWM:$mask, (_.VT _.RC:$src)), - (!cast(NAME#_.ZSuffix##mrk) addr:$ptr, - _.KRCWM:$mask, _.RC:$src)>; + (!cast(BaseName#_.ZSuffix##mrk) addr:$ptr, + _.KRCWM:$mask, _.RC:$src)>; } multiclass avx512_store_vl< bits<8> opc, string OpcodeStr, @@ -3384,14 +3397,14 @@ string Name, X86SchedWriteMoveLSWidths Sched, bit NoMRPattern = 0> { let Predicates = [prd] in - defm Z : avx512_store, EVEX_V512; let Predicates = [prd, HasVLX] in { - defm Z256 : avx512_store, EVEX_V256; - defm Z128 : avx512_store, EVEX_V128; } @@ -3402,15 +3415,15 @@ string Name, X86SchedWriteMoveLSWidths Sched, bit NoMRPattern = 0> { let Predicates = [prd] in - defm Z : avx512_store, EVEX_V512; let Predicates = [prd, HasVLX] in { - defm Z256 : avx512_store, EVEX_V256; - defm Z128 : avx512_store, EVEX_V128; } @@ -5479,7 +5492,7 @@ multiclass avx512_vptest opc, string OpcodeStr, PatFrag OpNode, X86FoldableSchedWrite sched, X86VectorVTInfo _, - string Suffix> { + string Name> { let ExeDomain = _.ExeDomain in { let isCommutable = 1 in defm rr : AVX512_maskable_cmp(NAME # Suffix # _.ZSuffix # "rr") + (_.KVT (!cast(Name # _.ZSuffix # "rr") _.RC:$src, _.RC:$src))>; def : Pat<(_.KVT (and _.KRC:$mask, (OpNode _.RC:$src, _.ImmAllZerosV))), - (_.KVT (!cast(NAME # Suffix # _.ZSuffix # "rrk") + (_.KVT (!cast(Name # _.ZSuffix # "rrk") _.KRC:$mask, _.RC:$src, _.RC:$src))>; } @@ -5526,11 +5539,11 @@ // Use 512bit version to implement 128/256 bit in case NoVLX. multiclass avx512_vptest_lowering { + X86VectorVTInfo _, string Name> { def : Pat<(_.KVT (OpNode (bitconvert (_.i64VT (and _.RC:$src1, _.RC:$src2))), _.ImmAllZerosV)), (_.KVT (COPY_TO_REGCLASS - (!cast(NAME # Suffix # "Zrr") + (!cast(Name # "Zrr") (INSERT_SUBREG (ExtendInfo.VT (IMPLICIT_DEF)), _.RC:$src1, _.SubRegIdx), (INSERT_SUBREG (ExtendInfo.VT (IMPLICIT_DEF)), @@ -5541,7 +5554,7 @@ (OpNode (bitconvert (_.i64VT (and _.RC:$src1, _.RC:$src2))), _.ImmAllZerosV))), (COPY_TO_REGCLASS - (!cast(NAME # Suffix # "Zrrk") + (!cast(Name # "Zrrk") (COPY_TO_REGCLASS _.KRC:$mask, ExtendInfo.KRC), (INSERT_SUBREG (ExtendInfo.VT (IMPLICIT_DEF)), _.RC:$src1, _.SubRegIdx), @@ -5551,7 +5564,7 @@ def : Pat<(_.KVT (OpNode _.RC:$src, _.ImmAllZerosV)), (_.KVT (COPY_TO_REGCLASS - (!cast(NAME # Suffix # "Zrr") + (!cast(Name # "Zrr") (INSERT_SUBREG (ExtendInfo.VT (IMPLICIT_DEF)), _.RC:$src, _.SubRegIdx), (INSERT_SUBREG (ExtendInfo.VT (IMPLICIT_DEF)), @@ -5560,7 +5573,7 @@ def : Pat<(_.KVT (and _.KRC:$mask, (OpNode _.RC:$src, _.ImmAllZerosV))), (COPY_TO_REGCLASS - (!cast(NAME # Suffix # "Zrrk") + (!cast(Name # "Zrrk") (COPY_TO_REGCLASS _.KRC:$mask, ExtendInfo.KRC), (INSERT_SUBREG (ExtendInfo.VT (IMPLICIT_DEF)), _.RC:$src, _.SubRegIdx), @@ -5570,57 +5583,56 @@ } multiclass avx512_vptest_dq_sizes opc, string OpcodeStr, PatFrag OpNode, - X86SchedWriteWidths sched, AVX512VLVectorVTInfo _, - string Suffix> { + X86SchedWriteWidths sched, AVX512VLVectorVTInfo _> { let Predicates = [HasAVX512] in - defm Z : avx512_vptest, + defm Z : avx512_vptest, avx512_vptest_mb, EVEX_V512; let Predicates = [HasAVX512, HasVLX] in { - defm Z256 : avx512_vptest, + defm Z256 : avx512_vptest, avx512_vptest_mb, EVEX_V256; - defm Z128 : avx512_vptest, + defm Z128 : avx512_vptest, avx512_vptest_mb, EVEX_V128; } let Predicates = [HasAVX512, NoVLX] in { - defm Z256_Alt : avx512_vptest_lowering< OpNode, _.info512, _.info256, Suffix>; - defm Z128_Alt : avx512_vptest_lowering< OpNode, _.info512, _.info128, Suffix>; + defm Z256_Alt : avx512_vptest_lowering< OpNode, _.info512, _.info256, NAME>; + defm Z128_Alt : avx512_vptest_lowering< OpNode, _.info512, _.info128, NAME>; } } multiclass avx512_vptest_dq opc, string OpcodeStr, PatFrag OpNode, X86SchedWriteWidths sched> { defm D : avx512_vptest_dq_sizes; + avx512vl_i32_info>; defm Q : avx512_vptest_dq_sizes, VEX_W; + avx512vl_i64_info>, VEX_W; } multiclass avx512_vptest_wb opc, string OpcodeStr, PatFrag OpNode, X86SchedWriteWidths sched> { let Predicates = [HasBWI] in { defm WZ: avx512_vptest, EVEX_V512, VEX_W; + v32i16_info, NAME#"W">, EVEX_V512, VEX_W; defm BZ: avx512_vptest, EVEX_V512; + v64i8_info, NAME#"B">, EVEX_V512; } let Predicates = [HasVLX, HasBWI] in { defm WZ256: avx512_vptest, EVEX_V256, VEX_W; + v16i16x_info, NAME#"W">, EVEX_V256, VEX_W; defm WZ128: avx512_vptest, EVEX_V128, VEX_W; + v8i16x_info, NAME#"W">, EVEX_V128, VEX_W; defm BZ256: avx512_vptest, EVEX_V256; + v32i8x_info, NAME#"B">, EVEX_V256; defm BZ128: avx512_vptest, EVEX_V128; + v16i8x_info, NAME#"B">, EVEX_V128; } let Predicates = [HasAVX512, NoVLX] in { - defm BZ256_Alt : avx512_vptest_lowering; - defm BZ128_Alt : avx512_vptest_lowering; - defm WZ256_Alt : avx512_vptest_lowering; - defm WZ128_Alt : avx512_vptest_lowering; + defm BZ256_Alt : avx512_vptest_lowering; + defm BZ128_Alt : avx512_vptest_lowering; + defm WZ256_Alt : avx512_vptest_lowering; + defm WZ128_Alt : avx512_vptest_lowering; } } @@ -8414,7 +8426,7 @@ } multiclass avx512_sqrt_scalar opc, string OpcodeStr, X86FoldableSchedWrite sched, - X86VectorVTInfo _, string SUFF, Intrinsic Intr> { + X86VectorVTInfo _, string Name, Intrinsic Intr> { let ExeDomain = _.ExeDomain in { defm r_Int : AVX512_maskable_scalar(NAME#SUFF#Zr) + (!cast(Name#Zr) (_.EltVT (IMPLICIT_DEF)), _.FRC:$src)>; def : Pat<(Intr VR128X:$src), - (!cast(NAME#SUFF#Zr_Int) VR128X:$src, + (!cast(Name#Zr_Int) VR128X:$src, VR128X:$src)>; } let Predicates = [HasAVX512, OptForSize] in { def : Pat<(_.EltVT (fsqrt (load addr:$src))), - (!cast(NAME#SUFF#Zm) + (!cast(Name#Zm) (_.EltVT (IMPLICIT_DEF)), addr:$src)>; def : Pat<(Intr _.ScalarIntMemCPat:$src2), - (!cast(NAME#SUFF#Zm_Int) + (!cast(Name#Zm_Int) (_.VT (IMPLICIT_DEF)), addr:$src2)>; } } multiclass avx512_sqrt_scalar_all opc, string OpcodeStr, X86SchedWriteSizes sched> { - defm SSZ : avx512_sqrt_scalar, EVEX_CD8<32, CD8VT1>, EVEX_4V, XS, NotMemoryFoldable; - defm SDZ : avx512_sqrt_scalar, EVEX_CD8<64, CD8VT1>, EVEX_4V, XD, VEX_W, NotMemoryFoldable; @@ -8639,15 +8651,16 @@ multiclass avx512_trunc_mr_lowering { + PatFrag truncFrag, PatFrag mtruncFrag, + string Name> { def : Pat<(truncFrag (SrcInfo.VT SrcInfo.RC:$src), addr:$dst), - (!cast(NAME#SrcInfo.ZSuffix##mr) + (!cast(Name#SrcInfo.ZSuffix##mr) addr:$dst, SrcInfo.RC:$src)>; def : Pat<(mtruncFrag addr:$dst, SrcInfo.KRCWM:$mask, (SrcInfo.VT SrcInfo.RC:$src)), - (!cast(NAME#SrcInfo.ZSuffix##mrk) + (!cast(Name#SrcInfo.ZSuffix##mrk) addr:$dst, SrcInfo.KRCWM:$mask, SrcInfo.RC:$src)>; } @@ -8664,18 +8677,18 @@ defm Z128: avx512_trunc_common, avx512_trunc_mr_lowering, EVEX_V128; + truncFrag, mtruncFrag, NAME>, EVEX_V128; defm Z256: avx512_trunc_common, avx512_trunc_mr_lowering, EVEX_V256; + truncFrag, mtruncFrag, NAME>, EVEX_V256; } let Predicates = [prd] in defm Z: avx512_trunc_common, avx512_trunc_mr_lowering, EVEX_V512; + truncFrag, mtruncFrag, NAME>, EVEX_V512; } multiclass avx512_trunc_qb opc, string OpcodeStr, SDNode OpNode, @@ -9292,11 +9305,12 @@ // Use 512bit version to implement 128/256 bit in case NoVLX. multiclass convert_vector_to_mask_lowering { + X86VectorVTInfo _, + string Name> { def : Pat<(_.KVT (X86pcmpgtm _.ImmAllZerosV, (_.VT _.RC:$src))), (_.KVT (COPY_TO_REGCLASS - (!cast(NAME#"Zrr") + (!cast(Name#"Zrr") (INSERT_SUBREG (ExtendInfo.VT (IMPLICIT_DEF)), _.RC:$src, _.SubRegIdx)), _.KRC))>; @@ -9315,8 +9329,8 @@ EVEX_V128; } let Predicates = [prd, NoVLX] in { - defm Z256_Alt : convert_vector_to_mask_lowering; - defm Z128_Alt : convert_vector_to_mask_lowering; + defm Z256_Alt : convert_vector_to_mask_lowering; + defm Z128_Alt : convert_vector_to_mask_lowering; } } @@ -9365,10 +9379,10 @@ Sched<[sched.Folded]>; } -multiclass compress_by_vec_width_lowering { +multiclass compress_by_vec_width_lowering { def : Pat<(X86mCompressingStore addr:$dst, _.KRCWM:$mask, (_.VT _.RC:$src)), - (!cast(NAME#_.ZSuffix##mrk) + (!cast(Name#_.ZSuffix##mrk) addr:$dst, _.KRCWM:$mask, _.RC:$src)>; } @@ -9378,13 +9392,13 @@ Predicate Pred = HasAVX512> { let Predicates = [Pred] in defm Z : compress_by_vec_width_common, - compress_by_vec_width_lowering, EVEX_V512; + compress_by_vec_width_lowering, EVEX_V512; let Predicates = [Pred, HasVLX] in { defm Z256 : compress_by_vec_width_common, - compress_by_vec_width_lowering, EVEX_V256; + compress_by_vec_width_lowering, EVEX_V256; defm Z128 : compress_by_vec_width_common, - compress_by_vec_width_lowering, EVEX_V128; + compress_by_vec_width_lowering, EVEX_V128; } } @@ -9414,19 +9428,19 @@ Sched<[sched.Folded, ReadAfterLd]>; } -multiclass expand_by_vec_width_lowering { +multiclass expand_by_vec_width_lowering { def : Pat<(_.VT (X86mExpandingLoad addr:$src, _.KRCWM:$mask, undef)), - (!cast(NAME#_.ZSuffix##rmkz) + (!cast(Name#_.ZSuffix##rmkz) _.KRCWM:$mask, addr:$src)>; def : Pat<(_.VT (X86mExpandingLoad addr:$src, _.KRCWM:$mask, _.ImmAllZerosV)), - (!cast(NAME#_.ZSuffix##rmkz) + (!cast(Name#_.ZSuffix##rmkz) _.KRCWM:$mask, addr:$src)>; def : Pat<(_.VT (X86mExpandingLoad addr:$src, _.KRCWM:$mask, (_.VT _.RC:$src0))), - (!cast(NAME#_.ZSuffix##rmk) + (!cast(Name#_.ZSuffix##rmk) _.RC:$src0, _.KRCWM:$mask, addr:$src)>; } @@ -9436,13 +9450,13 @@ Predicate Pred = HasAVX512> { let Predicates = [Pred] in defm Z : expand_by_vec_width, - expand_by_vec_width_lowering, EVEX_V512; + expand_by_vec_width_lowering, EVEX_V512; let Predicates = [Pred, HasVLX] in { defm Z256 : expand_by_vec_width, - expand_by_vec_width_lowering, EVEX_V256; + expand_by_vec_width_lowering, EVEX_V256; defm Z128 : expand_by_vec_width, - expand_by_vec_width_lowering, EVEX_V128; + expand_by_vec_width_lowering, EVEX_V128; } } @@ -10584,7 +10598,8 @@ }]>; multiclass avx512_ternlog opc, string OpcodeStr, SDNode OpNode, - X86FoldableSchedWrite sched, X86VectorVTInfo _>{ + X86FoldableSchedWrite sched, X86VectorVTInfo _, + string Name>{ let Constraints = "$src1 = $dst", ExeDomain = _.ExeDomain in { defm rri : AVX512_maskable_3src(NAME#_.ZSuffix#rrik) _.RC:$src1, _.KRCWM:$mask, + (!cast(Name#_.ZSuffix#rrik) _.RC:$src1, _.KRCWM:$mask, _.RC:$src2, _.RC:$src3, (VPTERNLOG321_imm8 imm:$src4))>; def : Pat<(_.VT (vselect _.KRCWM:$mask, (OpNode _.RC:$src2, _.RC:$src1, _.RC:$src3, (i8 imm:$src4)), _.RC:$src1)), - (!cast(NAME#_.ZSuffix#rrik) _.RC:$src1, _.KRCWM:$mask, + (!cast(Name#_.ZSuffix#rrik) _.RC:$src1, _.KRCWM:$mask, _.RC:$src2, _.RC:$src3, (VPTERNLOG213_imm8 imm:$src4))>; // Additional patterns for matching loads in other positions. def : Pat<(_.VT (OpNode (bitconvert (_.LdFrag addr:$src3)), _.RC:$src2, _.RC:$src1, (i8 imm:$src4))), - (!cast(NAME#_.ZSuffix#rmi) _.RC:$src1, _.RC:$src2, + (!cast(Name#_.ZSuffix#rmi) _.RC:$src1, _.RC:$src2, addr:$src3, (VPTERNLOG321_imm8 imm:$src4))>; def : Pat<(_.VT (OpNode _.RC:$src1, (bitconvert (_.LdFrag addr:$src3)), _.RC:$src2, (i8 imm:$src4))), - (!cast(NAME#_.ZSuffix#rmi) _.RC:$src1, _.RC:$src2, + (!cast(Name#_.ZSuffix#rmi) _.RC:$src1, _.RC:$src2, addr:$src3, (VPTERNLOG132_imm8 imm:$src4))>; // Additional patterns for matching zero masking with loads in other @@ -10644,13 +10659,13 @@ (OpNode (bitconvert (_.LdFrag addr:$src3)), _.RC:$src2, _.RC:$src1, (i8 imm:$src4)), _.ImmAllZerosV)), - (!cast(NAME#_.ZSuffix#rmikz) _.RC:$src1, _.KRCWM:$mask, + (!cast(Name#_.ZSuffix#rmikz) _.RC:$src1, _.KRCWM:$mask, _.RC:$src2, addr:$src3, (VPTERNLOG321_imm8 imm:$src4))>; def : Pat<(_.VT (vselect _.KRCWM:$mask, (OpNode _.RC:$src1, (bitconvert (_.LdFrag addr:$src3)), _.RC:$src2, (i8 imm:$src4)), _.ImmAllZerosV)), - (!cast(NAME#_.ZSuffix#rmikz) _.RC:$src1, _.KRCWM:$mask, + (!cast(Name#_.ZSuffix#rmikz) _.RC:$src1, _.KRCWM:$mask, _.RC:$src2, addr:$src3, (VPTERNLOG132_imm8 imm:$src4))>; // Additional patterns for matching masked loads with different @@ -10659,42 +10674,42 @@ (OpNode _.RC:$src1, (bitconvert (_.LdFrag addr:$src3)), _.RC:$src2, (i8 imm:$src4)), _.RC:$src1)), - (!cast(NAME#_.ZSuffix#rmik) _.RC:$src1, _.KRCWM:$mask, + (!cast(Name#_.ZSuffix#rmik) _.RC:$src1, _.KRCWM:$mask, _.RC:$src2, addr:$src3, (VPTERNLOG132_imm8 imm:$src4))>; def : Pat<(_.VT (vselect _.KRCWM:$mask, (OpNode (bitconvert (_.LdFrag addr:$src3)), _.RC:$src2, _.RC:$src1, (i8 imm:$src4)), _.RC:$src1)), - (!cast(NAME#_.ZSuffix#rmik) _.RC:$src1, _.KRCWM:$mask, + (!cast(Name#_.ZSuffix#rmik) _.RC:$src1, _.KRCWM:$mask, _.RC:$src2, addr:$src3, (VPTERNLOG321_imm8 imm:$src4))>; def : Pat<(_.VT (vselect _.KRCWM:$mask, (OpNode _.RC:$src2, _.RC:$src1, (bitconvert (_.LdFrag addr:$src3)), (i8 imm:$src4)), _.RC:$src1)), - (!cast(NAME#_.ZSuffix#rmik) _.RC:$src1, _.KRCWM:$mask, + (!cast(Name#_.ZSuffix#rmik) _.RC:$src1, _.KRCWM:$mask, _.RC:$src2, addr:$src3, (VPTERNLOG213_imm8 imm:$src4))>; def : Pat<(_.VT (vselect _.KRCWM:$mask, (OpNode _.RC:$src2, (bitconvert (_.LdFrag addr:$src3)), _.RC:$src1, (i8 imm:$src4)), _.RC:$src1)), - (!cast(NAME#_.ZSuffix#rmik) _.RC:$src1, _.KRCWM:$mask, + (!cast(Name#_.ZSuffix#rmik) _.RC:$src1, _.KRCWM:$mask, _.RC:$src2, addr:$src3, (VPTERNLOG231_imm8 imm:$src4))>; def : Pat<(_.VT (vselect _.KRCWM:$mask, (OpNode (bitconvert (_.LdFrag addr:$src3)), _.RC:$src1, _.RC:$src2, (i8 imm:$src4)), _.RC:$src1)), - (!cast(NAME#_.ZSuffix#rmik) _.RC:$src1, _.KRCWM:$mask, + (!cast(Name#_.ZSuffix#rmik) _.RC:$src1, _.KRCWM:$mask, _.RC:$src2, addr:$src3, (VPTERNLOG312_imm8 imm:$src4))>; // Additional patterns for matching broadcasts in other positions. def : Pat<(_.VT (OpNode (X86VBroadcast (_.ScalarLdFrag addr:$src3)), _.RC:$src2, _.RC:$src1, (i8 imm:$src4))), - (!cast(NAME#_.ZSuffix#rmbi) _.RC:$src1, _.RC:$src2, + (!cast(Name#_.ZSuffix#rmbi) _.RC:$src1, _.RC:$src2, addr:$src3, (VPTERNLOG321_imm8 imm:$src4))>; def : Pat<(_.VT (OpNode _.RC:$src1, (X86VBroadcast (_.ScalarLdFrag addr:$src3)), _.RC:$src2, (i8 imm:$src4))), - (!cast(NAME#_.ZSuffix#rmbi) _.RC:$src1, _.RC:$src2, + (!cast(Name#_.ZSuffix#rmbi) _.RC:$src1, _.RC:$src2, addr:$src3, (VPTERNLOG132_imm8 imm:$src4))>; // Additional patterns for matching zero masking with broadcasts in other @@ -10703,7 +10718,7 @@ (OpNode (X86VBroadcast (_.ScalarLdFrag addr:$src3)), _.RC:$src2, _.RC:$src1, (i8 imm:$src4)), _.ImmAllZerosV)), - (!cast(NAME#_.ZSuffix#rmbikz) _.RC:$src1, + (!cast(Name#_.ZSuffix#rmbikz) _.RC:$src1, _.KRCWM:$mask, _.RC:$src2, addr:$src3, (VPTERNLOG321_imm8 imm:$src4))>; def : Pat<(_.VT (vselect _.KRCWM:$mask, @@ -10711,7 +10726,7 @@ (X86VBroadcast (_.ScalarLdFrag addr:$src3)), _.RC:$src2, (i8 imm:$src4)), _.ImmAllZerosV)), - (!cast(NAME#_.ZSuffix#rmbikz) _.RC:$src1, + (!cast(Name#_.ZSuffix#rmbikz) _.RC:$src1, _.KRCWM:$mask, _.RC:$src2, addr:$src3, (VPTERNLOG132_imm8 imm:$src4))>; @@ -10722,32 +10737,32 @@ (X86VBroadcast (_.ScalarLdFrag addr:$src3)), _.RC:$src2, (i8 imm:$src4)), _.RC:$src1)), - (!cast(NAME#_.ZSuffix#rmbik) _.RC:$src1, _.KRCWM:$mask, + (!cast(Name#_.ZSuffix#rmbik) _.RC:$src1, _.KRCWM:$mask, _.RC:$src2, addr:$src3, (VPTERNLOG132_imm8 imm:$src4))>; def : Pat<(_.VT (vselect _.KRCWM:$mask, (OpNode (X86VBroadcast (_.ScalarLdFrag addr:$src3)), _.RC:$src2, _.RC:$src1, (i8 imm:$src4)), _.RC:$src1)), - (!cast(NAME#_.ZSuffix#rmbik) _.RC:$src1, _.KRCWM:$mask, + (!cast(Name#_.ZSuffix#rmbik) _.RC:$src1, _.KRCWM:$mask, _.RC:$src2, addr:$src3, (VPTERNLOG321_imm8 imm:$src4))>; def : Pat<(_.VT (vselect _.KRCWM:$mask, (OpNode _.RC:$src2, _.RC:$src1, (X86VBroadcast (_.ScalarLdFrag addr:$src3)), (i8 imm:$src4)), _.RC:$src1)), - (!cast(NAME#_.ZSuffix#rmbik) _.RC:$src1, _.KRCWM:$mask, + (!cast(Name#_.ZSuffix#rmbik) _.RC:$src1, _.KRCWM:$mask, _.RC:$src2, addr:$src3, (VPTERNLOG213_imm8 imm:$src4))>; def : Pat<(_.VT (vselect _.KRCWM:$mask, (OpNode _.RC:$src2, (X86VBroadcast (_.ScalarLdFrag addr:$src3)), _.RC:$src1, (i8 imm:$src4)), _.RC:$src1)), - (!cast(NAME#_.ZSuffix#rmbik) _.RC:$src1, _.KRCWM:$mask, + (!cast(Name#_.ZSuffix#rmbik) _.RC:$src1, _.KRCWM:$mask, _.RC:$src2, addr:$src3, (VPTERNLOG231_imm8 imm:$src4))>; def : Pat<(_.VT (vselect _.KRCWM:$mask, (OpNode (X86VBroadcast (_.ScalarLdFrag addr:$src3)), _.RC:$src1, _.RC:$src2, (i8 imm:$src4)), _.RC:$src1)), - (!cast(NAME#_.ZSuffix#rmbik) _.RC:$src1, _.KRCWM:$mask, + (!cast(Name#_.ZSuffix#rmbik) _.RC:$src1, _.KRCWM:$mask, _.RC:$src2, addr:$src3, (VPTERNLOG312_imm8 imm:$src4))>; } @@ -10755,12 +10770,12 @@ AVX512VLVectorVTInfo _> { let Predicates = [HasAVX512] in defm Z : avx512_ternlog<0x25, OpcodeStr, X86vpternlog, sched.ZMM, - _.info512>, EVEX_V512; + _.info512, NAME>, EVEX_V512; let Predicates = [HasAVX512, HasVLX] in { defm Z128 : avx512_ternlog<0x25, OpcodeStr, X86vpternlog, sched.XMM, - _.info128>, EVEX_V128; + _.info128, NAME>, EVEX_V128; defm Z256 : avx512_ternlog<0x25, OpcodeStr, X86vpternlog, sched.YMM, - _.info256>, EVEX_V256; + _.info256, NAME>, EVEX_V256; } } Index: llvm/trunk/lib/Target/X86/X86InstrSSE.td =================================================================== --- llvm/trunk/lib/Target/X86/X86InstrSSE.td +++ llvm/trunk/lib/Target/X86/X86InstrSSE.td @@ -2740,7 +2740,7 @@ Operand intmemop, ComplexPattern int_cpat, Intrinsic Intr, SDNode OpNode, Domain d, X86FoldableSchedWrite sched, - Predicate target, string Suffix> { + Predicate target> { let hasSideEffects = 0 in { def r : I(NAME#Suffix##r_Int) VR128:$src, VR128:$src)>; + (!cast(NAME#r_Int) VR128:$src, VR128:$src)>; } // We don't want to fold scalar loads into these instructions unless // optimizing for size. This is because the folded instruction will have a @@ -2779,7 +2779,7 @@ // rcpss mem, %xmm0 let Predicates = [target, OptForSize] in { def : Pat<(Intr int_cpat:$src2), - (!cast(NAME#Suffix##m_Int) + (!cast(NAME#m_Int) (vt (IMPLICIT_DEF)), addr:$src2)>; } } @@ -2789,8 +2789,7 @@ X86MemOperand x86memop, Operand intmemop, ComplexPattern int_cpat, Intrinsic Intr, SDNode OpNode, Domain d, - X86FoldableSchedWrite sched, Predicate target, - string Suffix> { + X86FoldableSchedWrite sched, Predicate target> { let hasSideEffects = 0 in { def r : I("V"#NAME#Suffix##r) + def : Pat<(OpNode RC:$src), (!cast(NAME#r) (ScalarVT (IMPLICIT_DEF)), RC:$src)>; def : Pat<(Intr VR128:$src), - (!cast("V"#NAME#Suffix##r_Int) VR128:$src, + (!cast(NAME#r_Int) VR128:$src, VR128:$src)>; } let Predicates = [target, OptForSize] in { def : Pat<(Intr int_cpat:$src2), - (!cast("V"#NAME#Suffix##m_Int) + (!cast(NAME#m_Int) (vt (IMPLICIT_DEF)), addr:$src2)>; def : Pat<(ScalarVT (OpNode (load addr:$src))), - (!cast("V"#NAME#Suffix##m) (ScalarVT (IMPLICIT_DEF)), + (!cast(NAME#m) (ScalarVT (IMPLICIT_DEF)), addr:$src)>; } } @@ -2915,11 +2914,11 @@ defm SS : sse_fp_unop_s("int_x86_sse_"##OpcodeStr##_ss), OpNode, - SSEPackedSingle, sched.Scl, UseSSE1, "SS">, XS; + SSEPackedSingle, sched.Scl, UseSSE1>, XS; defm V#NAME#SS : avx_fp_unop_s("int_x86_sse_"##OpcodeStr##_ss), OpNode, - SSEPackedSingle, sched.Scl, AVXTarget, "SS">, XS, VEX_4V, + SSEPackedSingle, sched.Scl, AVXTarget>, XS, VEX_4V, VEX_LIG, VEX_WIG, NotMemoryFoldable; } @@ -2928,11 +2927,11 @@ defm SD : sse_fp_unop_s("int_x86_sse2_"##OpcodeStr##_sd), - OpNode, SSEPackedDouble, sched.Scl, UseSSE2, "SD">, XD; + OpNode, SSEPackedDouble, sched.Scl, UseSSE2>, XD; defm V#NAME#SD : avx_fp_unop_s("int_x86_sse2_"##OpcodeStr##_sd), - OpNode, SSEPackedDouble, sched.Scl, AVXTarget, "SD">, + OpNode, SSEPackedDouble, sched.Scl, AVXTarget>, XD, VEX_4V, VEX_LIG, VEX_WIG, NotMemoryFoldable; } Index: llvm/trunk/test/TableGen/Dag.td =================================================================== --- llvm/trunk/test/TableGen/Dag.td +++ llvm/trunk/test/TableGen/Dag.td @@ -60,7 +60,6 @@ // CHECK-NEXT: dag Dag1 = (somedef1 1); // CHECK-NEXT: dag Dag2 = (somedef1 2); // CHECK-NEXT: dag Dag3 = (somedef1 2); -// CHECK-NEXT: NAME = ? // CHECK-NEXT: } @@ -69,7 +68,6 @@ // CHECK-NEXT: dag Dag1 = (somedef1 1); // CHECK-NEXT: dag Dag2 = (somedef2 2); // CHECK-NEXT: dag Dag3 = (somedef2 2); -// CHECK-NEXT: NAME = ? // CHECK-NEXT: } def VAL5 : bar { Index: llvm/trunk/test/TableGen/MultiClassDefName.td =================================================================== --- llvm/trunk/test/TableGen/MultiClassDefName.td +++ llvm/trunk/test/TableGen/MultiClassDefName.td @@ -43,7 +43,7 @@ def ZFizz#s : C; } -defm : MC3<"Buzz">; +defm "" : MC3<"Buzz">; // CHECK: def ZFizzBuzz // CHECK: string name = "Buzz"; Index: llvm/trunk/test/TableGen/lisp.td =================================================================== --- llvm/trunk/test/TableGen/lisp.td +++ llvm/trunk/test/TableGen/lisp.td @@ -5,14 +5,12 @@ // CHECK-NEXT: string element = "Jeffrey Sinclair"; // CHECK-NEXT: list rest = []; // CHECK-NEXT: int null = 1; -// CHECK-NEXT: string NAME = ?; // CHECK-NEXT: } // CHECK-NEXT: def Three { // CHECK-NEXT: list names = ["Tom", "Dick", "Harry"]; // CHECK-NEXT: string element = "Tom"; // CHECK-NEXT: list rest = ["Dick", "Harry"]; // CHECK-NEXT: int null = 0; -// CHECK-NEXT: string NAME = ?; // CHECK-NEXT: } class List n> { Index: llvm/trunk/test/TableGen/name-resolution-consistency.td =================================================================== --- llvm/trunk/test/TableGen/name-resolution-consistency.td +++ llvm/trunk/test/TableGen/name-resolution-consistency.td @@ -1,57 +1,56 @@ // RUN: llvm-tblgen %s | FileCheck %s // XFAIL: vg_leak -// This test demonstrates a number of inconsistencies in how NAME is resolved -// and record names are constructed. -// -// The TODO lines describe a suggested consistent behavior that would result -// from: -// (1) Treating NAME as an implicit multiclass template argument and -// (2) always storing the name of (non-anonymous) prototype records in -// multiclasses with at least one explicit reference to NAME. -// -// Unfortunately, several backends (including X86) rely quite heavily on the -// current inconsistent behavior and would have to be fixed. - // CHECK: def B0a { // CHECK: string e = "B0"; // CHECK: } // CHECK: def B0ba { -// TODO: expect "B0b" here -// CHECK: string a = "B0"; +// CHECK: string a = "B0b"; // CHECK: string b = "B0"; // CHECK: } +// CHECK: def B0bys { +// CHECK: string f = "B0b"; +// CHECK: string g = "B0"; +// CHECK: } + // CHECK: def B0cza { -// TODO: expect "B0cz" here -// CHECK: string a = "B0"; +// CHECK: string a = "B0cz"; // CHECK: string b = "B0"; // CHECK: } -// TODO: expect this to be named 'xB0b' -// CHECK: def B0xb { -// TODO: expect "B0b" here -// CHECK: string c = "b"; -// CHECK: string d = "b"; +// CHECK: def B0czyt { +// CHECK: string f = "B0cz"; +// CHECK: string g = "B0"; // CHECK: } -// TODO: expect this to be named B0bys -// CHECK: def B0ys { -// TODO: expect "B0b" here -// CHECK: string f = "b"; -// CHECK: string g = "b"; +// CHECK: def C0 { +// CHECK: string a = "C0"; +// CHECK: string b = "C0"; +// CHECK: string c = "a"; // CHECK: } -// CHECK: def xB0cz { -// CHECK: string c = "B0cz"; -// CHECK: string d = "B0cz"; +// CHECK: def D0a { +// CHECK: string a = "D0a"; +// CHECK: string b = "D0a"; +// CHECK: string c = "D0"; // CHECK: } -// TODO: expect this to be named B0czyt -// CHECK: def yt { -// CHECK: string f = "B0cz"; -// CHECK: string g = "B0cz"; +// CHECK: def D0b { +// CHECK: string a = "D0b"; +// CHECK: string b = "D0b"; +// CHECK: string c = "a"; +// CHECK: } + +// CHECK: def xB0b { +// CHECK: string c = "B0b"; +// CHECK: string d = "B0"; +// CHECK: } + +// CHECK: def xB0cz { +// CHECK: string c = "B0cz"; +// CHECK: string d = "B0"; // CHECK: } multiclass A { @@ -82,3 +81,21 @@ } defm B0 : B<"z", "t">; + +class Cbase { + string a = NAME; +} + +class C : Cbase { + string b = NAME; + string c = arg; +} + +def C0 : C<"a">; + +multiclass D { + def a : C; + def b : C; +} + +defm D0 : D<"a">; Index: llvm/trunk/test/TableGen/subst.td =================================================================== --- llvm/trunk/test/TableGen/subst.td +++ llvm/trunk/test/TableGen/subst.td @@ -28,51 +28,40 @@ // CHECK-NEXT: class AName { // CHECK-NEXT: string name = !subst("FIRST", "John", !subst("LAST", "Smith", AName:name)); // CHECK-NEXT: Honorific honorific = !subst(TVAR, Mr, AName:honorific); -// CHECK-NEXT: string NAME = ?; // CHECK-NEXT: } // CHECK-NEXT: class Honorific { // CHECK-NEXT: string honorific = Honorific:t; -// CHECK-NEXT: string NAME = ?; // CHECK-NEXT: } // CHECK-NEXT: class Name { // CHECK-NEXT: string name = Name:n; // CHECK-NEXT: Honorific honorific = Name:t; -// CHECK-NEXT: string NAME = ?; // CHECK-NEXT: } // CHECK-NEXT: ------------- Defs ----------------- // CHECK-NEXT: def JaneSmith { // CHECK-NEXT: string name = "Jane Smith"; // CHECK-NEXT: Honorific honorific = Ms; -// CHECK-NEXT: string NAME = ?; // CHECK-NEXT: } // CHECK-NEXT: def JimmyJohnson { // CHECK-NEXT: string name = "Jimmy Johnson"; // CHECK-NEXT: Honorific honorific = Mr; -// CHECK-NEXT: string NAME = ?; // CHECK-NEXT: } // CHECK-NEXT: def JohnSmith { // CHECK-NEXT: string name = "John Smith"; // CHECK-NEXT: Honorific honorific = Mr; -// CHECK-NEXT: string NAME = ?; // CHECK-NEXT: } // CHECK-NEXT: def JohnSmithJones { // CHECK-NEXT: string name = "John Smith-Jones"; // CHECK-NEXT: Honorific honorific = Mr; -// CHECK-NEXT: string NAME = ?; // CHECK-NEXT: } // CHECK-NEXT: def Mr // CHECK-NEXT: string honorific = "Mr."; -// CHECK-NEXT: string NAME = ?; // CHECK-NEXT: } // CHECK-NEXT: def Mrs { // CHECK-NEXT: string honorific = "Mrs."; -// CHECK-NEXT: string NAME = ?; // CHECK-NEXT: } // CHECK-NEXT: def Ms { // CHECK-NEXT: string honorific = "Ms."; -// CHECK-NEXT: string NAME = ?; // CHECK-NEXT: } // CHECK-NEXT: def TVAR { // CHECK-NEXT: string honorific = "Bogus"; -// CHECK-NEXT: string NAME = ?; // CHECK-NEXT: }