From c84b8593fb3b344cb5feb2e47c09f9d32ce3be20 Mon Sep 17 00:00:00 2001 From: Krzysztof Parzyszek Date: Thu, 14 Sep 2017 20:44:20 +0000 Subject: [PATCH] Subtarget support for parameterized register class information Implement "checkFeatures" and emitting HW mode check code. Differential Revision: https://reviews.llvm.org/D31959 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@313295 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/MC/MCSubtargetInfo.h | 4 ++++ include/llvm/MC/SubtargetFeature.h | 3 +++ include/llvm/Target/TargetSubtargetInfo.h | 2 ++ lib/MC/MCSubtargetInfo.cpp | 12 ++++++++++++ utils/TableGen/SubtargetEmitter.cpp | 32 ++++++++++++++++++++++++++----- 5 files changed, 48 insertions(+), 5 deletions(-) diff --git a/include/llvm/MC/MCSubtargetInfo.h b/include/llvm/MC/MCSubtargetInfo.h index d1d5d070bf5..dd10881b73a 100644 --- a/include/llvm/MC/MCSubtargetInfo.h +++ b/include/llvm/MC/MCSubtargetInfo.h @@ -118,6 +118,10 @@ public: /// all feature bits implied by the flag. FeatureBitset ApplyFeatureFlag(StringRef FS); + /// Check whether the subtarget features are enabled/disabled as per + /// the provided string, ignoring all other features. + bool checkFeatures(StringRef FS) const; + /// getSchedModelForCPU - Get the machine model of a CPU. /// const MCSchedModel &getSchedModelForCPU(StringRef CPU) const; diff --git a/include/llvm/MC/SubtargetFeature.h b/include/llvm/MC/SubtargetFeature.h index cb036671b75..76c7dd56080 100644 --- a/include/llvm/MC/SubtargetFeature.h +++ b/include/llvm/MC/SubtargetFeature.h @@ -115,6 +115,9 @@ public: ArrayRef CPUTable, ArrayRef FeatureTable); + /// Returns the vector of individual subtarget features. + const std::vector &getFeatures() const { return Features; } + /// Prints feature string. void print(raw_ostream &OS) const; diff --git a/include/llvm/Target/TargetSubtargetInfo.h b/include/llvm/Target/TargetSubtargetInfo.h index 9440c56dcf1..0f42f39595e 100644 --- a/include/llvm/Target/TargetSubtargetInfo.h +++ b/include/llvm/Target/TargetSubtargetInfo.h @@ -110,6 +110,8 @@ public: return nullptr; } + virtual unsigned getHwMode() const { return 0; } + /// Target can subclass this hook to select a different DAG scheduler. virtual RegisterScheduler::FunctionPassCtor getDAGScheduler(CodeGenOpt::Level) const { diff --git a/lib/MC/MCSubtargetInfo.cpp b/lib/MC/MCSubtargetInfo.cpp index 385cdcc6232..bf7a10c285f 100644 --- a/lib/MC/MCSubtargetInfo.cpp +++ b/lib/MC/MCSubtargetInfo.cpp @@ -75,6 +75,18 @@ FeatureBitset MCSubtargetInfo::ApplyFeatureFlag(StringRef FS) { return FeatureBits; } +bool MCSubtargetInfo::checkFeatures(StringRef FS) const { + SubtargetFeatures T(FS); + FeatureBitset Set, All; + for (std::string F : T.getFeatures()) { + SubtargetFeatures::ApplyFeatureFlag(Set, F, ProcFeatures); + if (F[0] == '-') + F[0] = '+'; + SubtargetFeatures::ApplyFeatureFlag(All, F, ProcFeatures); + } + return (FeatureBits & All) == Set; +} + const MCSchedModel &MCSubtargetInfo::getSchedModelForCPU(StringRef CPU) const { assert(ProcSchedModels && "Processor machine model not available!"); diff --git a/utils/TableGen/SubtargetEmitter.cpp b/utils/TableGen/SubtargetEmitter.cpp index d1d873b66aa..cc46481a813 100644 --- a/utils/TableGen/SubtargetEmitter.cpp +++ b/utils/TableGen/SubtargetEmitter.cpp @@ -68,6 +68,7 @@ class SubtargetEmitter { } }; + const CodeGenTarget &TGT; RecordKeeper &Records; CodeGenSchedModels &SchedModels; std::string Target; @@ -106,12 +107,14 @@ class SubtargetEmitter { void EmitProcessorLookup(raw_ostream &OS); void EmitSchedModelHelpers(const std::string &ClassName, raw_ostream &OS); void EmitSchedModel(raw_ostream &OS); + void EmitHwModeCheck(const std::string &ClassName, raw_ostream &OS); void ParseFeaturesFunction(raw_ostream &OS, unsigned NumFeatures, unsigned NumProcs); public: - SubtargetEmitter(RecordKeeper &R, CodeGenTarget &TGT): - Records(R), SchedModels(TGT.getSchedModels()), Target(TGT.getName()) {} + SubtargetEmitter(RecordKeeper &R, CodeGenTarget &TGT) + : TGT(TGT), Records(R), SchedModels(TGT.getSchedModels()), + Target(TGT.getName()) {} void run(raw_ostream &o); }; @@ -1329,6 +1332,22 @@ void SubtargetEmitter::EmitSchedModelHelpers(const std::string &ClassName, << "} // " << ClassName << "::resolveSchedClass\n"; } +void SubtargetEmitter::EmitHwModeCheck(const std::string &ClassName, + raw_ostream &OS) { + const CodeGenHwModes &CGH = TGT.getHwModes(); + assert(CGH.getNumModeIds() > 0); + if (CGH.getNumModeIds() == 1) + return; + + OS << "unsigned " << ClassName << "::getHwMode() const {\n"; + for (unsigned M = 1, NumModes = CGH.getNumModeIds(); M != NumModes; ++M) { + const HwMode &HM = CGH.getMode(M); + OS << " if (checkFeatures(\"" << HM.Features + << "\")) return " << M << ";\n"; + } + OS << " return 0;\n}\n"; +} + // // ParseFeaturesFunction - Produces a subtarget specific function for parsing // the subtarget features string. @@ -1462,9 +1481,11 @@ void SubtargetEmitter::run(raw_ostream &OS) { << " const MachineInstr *DefMI," << " const TargetSchedModel *SchedModel) const override;\n" << " DFAPacketizer *createDFAPacketizer(const InstrItineraryData *IID)" - << " const;\n" - << "};\n"; - OS << "} // end namespace llvm\n\n"; + << " const;\n"; + if (TGT.getHwModes().getNumModeIds() > 1) + OS << " unsigned getHwMode() const override;\n"; + OS << "};\n" + << "} // end namespace llvm\n\n"; OS << "#endif // GET_SUBTARGETINFO_HEADER\n\n"; @@ -1515,6 +1536,7 @@ void SubtargetEmitter::run(raw_ostream &OS) { OS << ") {}\n\n"; EmitSchedModelHelpers(ClassName, OS); + EmitHwModeCheck(ClassName, OS); OS << "} // end namespace llvm\n\n"; -- 2.11.0