Index: llvm/trunk/include/llvm/Target/TargetInstrPredicate.td =================================================================== --- llvm/trunk/include/llvm/Target/TargetInstrPredicate.td +++ llvm/trunk/include/llvm/Target/TargetInstrPredicate.td @@ -198,19 +198,24 @@ MCStatement DefaultCase = default; } +// Base class for function predicates. +class FunctionPredicateBase { + string FunctionName = name; + MCStatement Body = body; +} + // Check that a call to method `Name` in class "XXXGenInstrInfo" (where XXX is -// the `Target` name) returns true. +// the name of a target) returns true. // // TIIPredicate definitions are used to model calls to the target-specific // InstrInfo. A TIIPredicate is treated specially by the InstrInfoEmitter // tablegen backend, which will use it to automatically generate a definition in // the target specific `GenInstrInfo` class. -class TIIPredicate - : MCInstPredicate { - string TargetName = Target; - string FunctionName = Name; - MCStatement Body = body; -} +// +// There cannot be multiple TIIPredicate definitions with the same name for the +// same target. +class TIIPredicate + : FunctionPredicateBase, MCInstPredicate; // A function predicate that takes as input a machine instruction, and returns // a boolean value. Index: llvm/trunk/lib/Target/X86/X86SchedPredicates.td =================================================================== --- llvm/trunk/lib/Target/X86/X86SchedPredicates.td +++ llvm/trunk/lib/Target/X86/X86SchedPredicates.td @@ -53,4 +53,4 @@ // 3-operands LEA. Tablegen automatically generates a new method for it in // X86GenInstrInfo. def IsThreeOperandsLEAFn : - TIIPredicate<"X86", "isThreeOperandsLEA", IsThreeOperandsLEABody>; + TIIPredicate<"isThreeOperandsLEA", IsThreeOperandsLEABody>; Index: llvm/trunk/utils/TableGen/CodeGenSchedule.h =================================================================== --- llvm/trunk/utils/TableGen/CodeGenSchedule.h +++ llvm/trunk/utils/TableGen/CodeGenSchedule.h @@ -465,6 +465,8 @@ void inferSchedClasses(); + void checkMCInstPredicates() const; + void checkCompleteness(); void inferFromRW(ArrayRef OperWrites, ArrayRef OperReads, Index: llvm/trunk/utils/TableGen/CodeGenSchedule.cpp =================================================================== --- llvm/trunk/utils/TableGen/CodeGenSchedule.cpp +++ llvm/trunk/utils/TableGen/CodeGenSchedule.cpp @@ -222,9 +222,36 @@ // Collect optional processor description. collectOptionalProcessorInfo(); + // Check MCInstPredicate definitions. + checkMCInstPredicates(); + checkCompleteness(); } +void CodeGenSchedModels::checkMCInstPredicates() const { + RecVec MCPredicates = Records.getAllDerivedDefinitions("TIIPredicate"); + if (MCPredicates.empty()) + return; + + // A target cannot have multiple TIIPredicate definitions with a same name. + llvm::StringMap TIIPredicates(MCPredicates.size()); + for (const Record *TIIPred : MCPredicates) { + StringRef Name = TIIPred->getValueAsString("FunctionName"); + StringMap::const_iterator It = TIIPredicates.find(Name); + if (It == TIIPredicates.end()) { + TIIPredicates[Name] = TIIPred; + continue; + } + + PrintError(TIIPred->getLoc(), + "TIIPredicate " + Name + " is multiply defined."); + PrintNote(It->second->getLoc(), + " Previous definition of " + Name + " was here."); + PrintFatalError(TIIPred->getLoc(), + "Found conflicting definitions of TIIPredicate."); + } +} + void CodeGenSchedModels::collectRetireControlUnits() { RecVec Units = Records.getAllDerivedDefinitions("RetireControlUnit"); Index: llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp =================================================================== --- llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp +++ llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp @@ -66,11 +66,11 @@ /// This method is used to custom expand TIIPredicate definitions. /// See file llvm/Target/TargetInstPredicates.td for a description of what is /// a TIIPredicate and how to use it. - void emitTIIHelperMethods(raw_ostream &OS); + void emitTIIHelperMethods(raw_ostream &OS, StringRef TargetName); /// Expand TIIPredicate definitions to functions that accept a const MCInst /// reference. - void emitMCIIHelperMethods(raw_ostream &OS); + void emitMCIIHelperMethods(raw_ostream &OS, StringRef TargetName); void emitRecord(const CodeGenInstruction &Inst, unsigned Num, Record *InstrInfo, std::map, unsigned> &EL, @@ -351,14 +351,12 @@ OS << "#endif // GET_INSTRINFO_OPERAND_TYPES_ENUM\n\n"; } -void InstrInfoEmitter::emitMCIIHelperMethods(raw_ostream &OS) { +void InstrInfoEmitter::emitMCIIHelperMethods(raw_ostream &OS, + StringRef TargetName) { RecVec TIIPredicates = Records.getAllDerivedDefinitions("TIIPredicate"); if (TIIPredicates.empty()) return; - CodeGenTarget &Target = CDP.getTargetInfo(); - const StringRef TargetName = Target.getName(); - OS << "#ifdef GET_GENINSTRINFO_MC_DECL\n"; OS << "#undef GET_GENINSTRINFO_MC_DECL\n\n"; @@ -383,7 +381,7 @@ OS << "namespace llvm {\n"; OS << "namespace " << TargetName << "_MC {\n\n"; - PredicateExpander PE; + PredicateExpander PE(TargetName); PE.setExpandForMC(true); for (const Record *Rec : TIIPredicates) { @@ -401,12 +399,13 @@ OS << "#endif // GET_GENISTRINFO_MC_HELPERS\n"; } -void InstrInfoEmitter::emitTIIHelperMethods(raw_ostream &OS) { +void InstrInfoEmitter::emitTIIHelperMethods(raw_ostream &OS, + StringRef TargetName) { RecVec TIIPredicates = Records.getAllDerivedDefinitions("TIIPredicate"); if (TIIPredicates.empty()) return; - PredicateExpander PE; + PredicateExpander PE(TargetName); PE.setExpandForMC(false); PE.setIndentLevel(2); @@ -518,7 +517,7 @@ << "(int CFSetupOpcode = -1, int CFDestroyOpcode = -1, int CatchRetOpcode = -1, int ReturnOpcode = -1);\n" << " ~" << ClassName << "() override = default;\n"; - emitTIIHelperMethods(OS); + emitTIIHelperMethods(OS, TargetName); OS << "\n};\n} // end llvm namespace\n"; @@ -545,7 +544,7 @@ emitOperandTypesEnum(OS, Target); - emitMCIIHelperMethods(OS); + emitMCIIHelperMethods(OS, TargetName); } void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num, Index: llvm/trunk/utils/TableGen/PredicateExpander.h =================================================================== --- llvm/trunk/utils/TableGen/PredicateExpander.h +++ llvm/trunk/utils/TableGen/PredicateExpander.h @@ -30,14 +30,15 @@ bool NegatePredicate; bool ExpandForMC; unsigned IndentLevel; + StringRef TargetName; PredicateExpander(const PredicateExpander &) = delete; PredicateExpander &operator=(const PredicateExpander &) = delete; public: - PredicateExpander() + PredicateExpander(StringRef Target) : EmitCallsByRef(true), NegatePredicate(false), ExpandForMC(false), - IndentLevel(1U) {} + IndentLevel(1U), TargetName(Target) {} bool isByRef() const { return EmitCallsByRef; } bool shouldNegate() const { return NegatePredicate; } bool shouldExpandForMC() const { return ExpandForMC; } @@ -65,8 +66,7 @@ void expandCheckOpcode(raw_ostream &OS, const RecVec &Opcodes); void expandPredicateSequence(raw_ostream &OS, const RecVec &Sequence, bool IsCheckAll); - void expandTIIFunctionCall(raw_ostream &OS, StringRef TargetName, - StringRef MethodName); + void expandTIIFunctionCall(raw_ostream &OS, StringRef MethodName); void expandCheckIsRegOperand(raw_ostream &OS, int OpIndex); void expandCheckIsImmOperand(raw_ostream &OS, int OpIndex); void expandCheckInvalidRegOperand(raw_ostream &OS, int OpIndex); Index: llvm/trunk/utils/TableGen/PredicateExpander.cpp =================================================================== --- llvm/trunk/utils/TableGen/PredicateExpander.cpp +++ llvm/trunk/utils/TableGen/PredicateExpander.cpp @@ -134,14 +134,9 @@ } void PredicateExpander::expandTIIFunctionCall(raw_ostream &OS, - StringRef TargetName, StringRef MethodName) { OS << (shouldNegate() ? "!" : ""); - if (shouldExpandForMC()) - OS << TargetName << "_MC::"; - else - OS << TargetName << "Gen" - << "InstrInfo::"; + OS << TargetName << (shouldExpandForMC() ? "_MC::" : "GenInstrInfo::"); OS << MethodName << (isByRef() ? "(MI)" : "(*MI)"); } @@ -313,8 +308,7 @@ return expandCheckNonPortable(OS, Rec->getValueAsString("CodeBlock")); if (Rec->isSubClassOf("TIIPredicate")) - return expandTIIFunctionCall(OS, Rec->getValueAsString("TargetName"), - Rec->getValueAsString("FunctionName")); + return expandTIIFunctionCall(OS, Rec->getValueAsString("FunctionName")); llvm_unreachable("No known rules to expand this MCInstPredicate"); } Index: llvm/trunk/utils/TableGen/SubtargetEmitter.cpp =================================================================== --- llvm/trunk/utils/TableGen/SubtargetEmitter.cpp +++ llvm/trunk/utils/TableGen/SubtargetEmitter.cpp @@ -1616,7 +1616,7 @@ OS << " case " << VC << ": // " << SC.Name << '\n'; - PredicateExpander PE; + PredicateExpander PE(Target); PE.setByRef(false); PE.setExpandForMC(OnlyExpandMCInstPredicates); for (unsigned PI : ProcIndices) {