Index: llvm/trunk/include/llvm/MC/MCSubtargetInfo.h =================================================================== --- llvm/trunk/include/llvm/MC/MCSubtargetInfo.h +++ llvm/trunk/include/llvm/MC/MCSubtargetInfo.h @@ -159,6 +159,13 @@ /// Initialize an InstrItineraryData instance. void initInstrItins(InstrItineraryData &InstrItins) const; + /// Resolve a variant scheduling class for the given MCInst and CPU. + virtual unsigned + resolveVariantSchedClass(unsigned SchedClass, const MCInst *MI, + unsigned CPUID) const { + return 0; + } + /// Check whether the CPU string is valid. bool isCPUStringValid(StringRef CPU) const { auto Found = std::lower_bound(ProcDesc.begin(), ProcDesc.end(), CPU); Index: llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp =================================================================== --- llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp +++ llvm/trunk/utils/TableGen/InstrInfoEmitter.cpp @@ -67,6 +67,10 @@ /// See file llvm/Target/TargetInstPredicates.td for a description of what is /// a TIIPredicate and how to use it. void emitTIIHelperMethods(raw_ostream &OS); + + /// Expand TIIPredicate definitions to functions that accept a const MCInst + /// reference. + void emitMCIIHelperMethods(raw_ostream &OS); void emitRecord(const CodeGenInstruction &Inst, unsigned Num, Record *InstrInfo, std::map, unsigned> &EL, @@ -347,6 +351,55 @@ OS << "#endif // GET_INSTRINFO_OPERAND_TYPES_ENUM\n\n"; } +void InstrInfoEmitter::emitMCIIHelperMethods(raw_ostream &OS) { + RecVec TIIPredicates = Records.getAllDerivedDefinitions("TIIPredicate"); + if (TIIPredicates.empty()) + return; + + CodeGenTarget &Target = CDP.getTargetInfo(); + const StringRef TargetName = Target.getName(); + formatted_raw_ostream FOS(OS); + + FOS << "#ifdef GET_GENINSTRINFO_MC_DECL\n"; + FOS << "#undef GET_GENINSTRINFO_MC_DECL\n\n"; + + FOS << "namespace llvm {\n"; + FOS << "class MCInst;\n\n"; + + FOS << "namespace " << TargetName << "_MC {\n\n"; + + for (const Record *Rec : TIIPredicates) { + FOS << "bool " << Rec->getValueAsString("FunctionName") + << "(const MCInst &MI);\n"; + } + + FOS << "\n} // end " << TargetName << "_MC namespace\n"; + FOS << "} // end llvm namespace\n\n"; + + FOS << "#endif // GET_GENINSTRINFO_MC_DECL\n\n"; + + FOS << "#ifdef GET_GENINSTRINFO_MC_HELPERS\n"; + FOS << "#undef GET_GENINSTRINFO_MC_HELPERS\n\n"; + + FOS << "namespace llvm {\n"; + FOS << "namespace " << TargetName << "_MC {\n\n"; + + PredicateExpander PE; + PE.setExpandForMC(true); + for (const Record *Rec : TIIPredicates) { + FOS << "bool " << Rec->getValueAsString("FunctionName"); + FOS << "(const MCInst &MI) {\n"; + FOS << " return "; + PE.expandPredicate(FOS, Rec->getValueAsDef("Pred")); + FOS << ";\n}\n"; + } + + FOS << "\n} // end " << TargetName << "_MC namespace\n"; + FOS << "} // end llvm namespace\n\n"; + + FOS << "#endif // GET_GENISTRINFO_MC_HELPERS\n"; +} + void InstrInfoEmitter::emitTIIHelperMethods(raw_ostream &OS) { RecVec TIIPredicates = Records.getAllDerivedDefinitions("TIIPredicate"); if (TIIPredicates.empty()) @@ -490,6 +543,8 @@ emitOperandNameMappings(OS, Target, NumberedInstructions); emitOperandTypesEnum(OS, Target); + + emitMCIIHelperMethods(OS); } void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num, Index: llvm/trunk/utils/TableGen/SubtargetEmitter.cpp =================================================================== --- llvm/trunk/utils/TableGen/SubtargetEmitter.cpp +++ llvm/trunk/utils/TableGen/SubtargetEmitter.cpp @@ -115,6 +115,7 @@ void EmitSchedModelHelpers(const std::string &ClassName, raw_ostream &OS); void emitSchedModelHelpersImpl(raw_ostream &OS, bool OnlyExpandMCInstPredicates = false); + void emitGenMCSubtargetInfo(raw_ostream &OS); void EmitSchedModel(raw_ostream &OS); void EmitHwModeCheck(const std::string &ClassName, raw_ostream &OS); @@ -1645,6 +1646,26 @@ OS << "}\n"; } +void SubtargetEmitter::emitGenMCSubtargetInfo(raw_ostream &OS) { + OS << "struct " << Target + << "GenMCSubtargetInfo : public MCSubtargetInfo {\n"; + OS << " " << Target << "GenMCSubtargetInfo(const Triple &TT, \n" + << " StringRef CPU, StringRef FS, ArrayRef PF,\n" + << " ArrayRef PD,\n" + << " const SubtargetInfoKV *ProcSched,\n" + << " const MCWriteProcResEntry *WPR,\n" + << " const MCWriteLatencyEntry *WL,\n" + << " const MCReadAdvanceEntry *RA, const InstrStage *IS,\n" + << " const unsigned *OC, const unsigned *FP) :\n" + << " MCSubtargetInfo(TT, CPU, FS, PF, PD, ProcSched,\n" + << " WPR, WL, RA, IS, OC, FP) { }\n\n" + << " unsigned resolveVariantSchedClass(unsigned SchedClass,\n" + << " const MCInst *MI, unsigned CPUID) const override {\n"; + emitSchedModelHelpersImpl(OS, /* OnlyExpandMCPredicates */ true); + OS << " }\n"; + OS << "};\n"; +} + // // SubtargetEmitter::run - Main subtarget enumeration emitter. // @@ -1677,10 +1698,12 @@ #endif // MCInstrInfo initialization routine. + emitGenMCSubtargetInfo(OS); + OS << "\nstatic inline MCSubtargetInfo *create" << Target << "MCSubtargetInfoImpl(" << "const Triple &TT, StringRef CPU, StringRef FS) {\n"; - OS << " return new MCSubtargetInfo(TT, CPU, FS, "; + OS << " return new " << Target << "GenMCSubtargetInfo(TT, CPU, FS, "; if (NumFeatures) OS << Target << "FeatureKV, "; else