1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-19 02:52:53 +02:00

[RFC][Patch 2/3] Add a MCSubtargetInfo hook to resolve variant scheduling classes.

This patch is the second of a sequence of three patches related to LLVM-dev RFC
"MC support for varinat scheduling classes".
https://lists.llvm.org/pipermail/llvm-dev/2018-May/123181.html

The goal of this patch is to enable the resolution of variant classes in MC with
the help of a new method named `MCSubtargetInfo::resolveVariantSchedClass()`.

This patch also teaches the SubtargetEmitter how to automatically generate the
definition of method resolveVariantSchedClass().  That definition is emitted
within a sub-class of MCSubtargetInfo named XXXGenMCSubtargetInfo (where XXX is
the name of the Target).

Differential Revision: https://reviews.llvm.org/D47077

llvm-svn: 333286
This commit is contained in:
Andrea Di Biagio 2018-05-25 16:02:43 +00:00
parent c26fd3adc6
commit d69daf9e61
3 changed files with 86 additions and 1 deletions

View File

@ -159,6 +159,13 @@ public:
/// 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);

View File

@ -67,6 +67,10 @@ private:
/// 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<std::vector<Record*>, unsigned> &EL,
@ -347,6 +351,55 @@ void InstrInfoEmitter::emitOperandTypesEnum(raw_ostream &OS,
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 @@ void InstrInfoEmitter::run(raw_ostream &OS) {
emitOperandNameMappings(OS, Target, NumberedInstructions);
emitOperandTypesEnum(OS, Target);
emitMCIIHelperMethods(OS);
}
void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num,

View File

@ -115,6 +115,7 @@ class SubtargetEmitter {
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 @@ void SubtargetEmitter::ParseFeaturesFunction(raw_ostream &OS,
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<SubtargetFeatureKV> PF,\n"
<< " ArrayRef<SubtargetFeatureKV> 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 @@ void SubtargetEmitter::run(raw_ostream &OS) {
#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