From 6cee630070b1a7183ed56a8404e812629f5ca538 Mon Sep 17 00:00:00 2001 From: Jim Laskey Date: Tue, 1 Nov 2005 20:06:59 +0000 Subject: [PATCH] Allow itineraries to be passed through the Target Machine. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@24139 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/Target/TargetInstrInfo.h | 1 - include/llvm/Target/TargetInstrItineraries.h | 52 ++++++++++++++++++++ include/llvm/Target/TargetMachine.h | 8 +++ lib/Target/PowerPC/PPCSubtarget.cpp | 1 + lib/Target/PowerPC/PPCSubtarget.h | 9 ++++ lib/Target/PowerPC/PPCTargetMachine.cpp | 3 +- lib/Target/PowerPC/PPCTargetMachine.h | 13 +++-- utils/TableGen/InstrInfoEmitter.cpp | 2 +- utils/TableGen/SubtargetEmitter.cpp | 45 ++++++++++++----- utils/TableGen/SubtargetEmitter.h | 7 +-- 10 files changed, 119 insertions(+), 22 deletions(-) diff --git a/include/llvm/Target/TargetInstrInfo.h b/include/llvm/Target/TargetInstrInfo.h index 7b9cda2a948..8659ef9e39c 100644 --- a/include/llvm/Target/TargetInstrInfo.h +++ b/include/llvm/Target/TargetInstrInfo.h @@ -146,7 +146,6 @@ public: return get(Opcode).numOperands; } - InstrSchedClass getSchedClass(MachineOpCode Opcode) const { return get(Opcode).schedClass; } diff --git a/include/llvm/Target/TargetInstrItineraries.h b/include/llvm/Target/TargetInstrItineraries.h index 3a622c7732f..3be5b9513a2 100644 --- a/include/llvm/Target/TargetInstrItineraries.h +++ b/include/llvm/Target/TargetInstrItineraries.h @@ -16,6 +16,8 @@ #ifndef LLVM_TARGET_TARGETINSTRITINERARIES_H #define LLVM_TARGET_TARGETINSTRITINERARIES_H +#include "llvm/Support/Debug.h" + namespace llvm { //===----------------------------------------------------------------------===// @@ -41,6 +43,56 @@ struct InstrItinerary { }; + +//===----------------------------------------------------------------------===// +// Instruction itinerary Data - Itinerary data supplied by a subtarget to be +// used by a target. +// +class InstrItineraryData { + InstrStage *Stages; // Array of stages selected + unsigned NStages; // Number of stages + InstrItinerary *Itineratries; // Array of itineraries selected + unsigned NItineraries; // Number of itineraries (actually classes) + +public: + + // + // Ctors. + // + InstrItineraryData() + : Stages(NULL), NStages(0), Itineratries(NULL), NItineraries(0) + {} + InstrItineraryData(InstrStage *S, unsigned NS, InstrItinerary *I, unsigned NI) + : Stages(S), NStages(NS), Itineratries(I), NItineraries(NI) + {} + + // + // isEmpty - Returns true if there are no itineraries. + // + inline bool isEmpty() const { return NItineraries == 0; } + + // + // begin - Return the first stage of the itinerary. + // + inline InstrStage *begin(unsigned ItinClassIndx) const { + assert(ItinClassIndx < NItineraries && "Itinerary index out of range"); + unsigned StageIdx = Itineratries[ItinClassIndx].First; + assert(StageIdx < NStages && "Stage index out of range"); + return Stages + StageIdx; + } + + // + // end - Return the last+1 stage of the itinerary. + // + inline InstrStage *end(unsigned ItinClassIndx) const { + assert(ItinClassIndx < NItineraries && "Itinerary index out of range"); + unsigned StageIdx = Itineratries[ItinClassIndx].Last; + assert(StageIdx < NStages && "Stage index out of range"); + return Stages + StageIdx; + } +}; + + } // End llvm namespace #endif diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h index 9c026cc4f6c..aae7d901fbe 100644 --- a/include/llvm/Target/TargetMachine.h +++ b/include/llvm/Target/TargetMachine.h @@ -15,6 +15,7 @@ #define LLVM_TARGET_TARGETMACHINE_H #include "llvm/Target/TargetData.h" +#include "llvm/Target/TargetInstrItineraries.h" #include namespace llvm { @@ -122,6 +123,13 @@ public: /// otherwise return null. /// virtual TargetJITInfo *getJITInfo() { return 0; } + + /// getInstrItineraryData - Returns instruction itinerary data for the target + /// or specific subtarget. + /// + virtual const InstrItineraryData getInstrItineraryData() const { + return InstrItineraryData(); + } // These are deprecated interfaces. virtual const TargetSchedInfo *getSchedInfo() const { return 0; } diff --git a/lib/Target/PowerPC/PPCSubtarget.cpp b/lib/Target/PowerPC/PPCSubtarget.cpp index 94af54c3591..442017d8cd2 100644 --- a/lib/Target/PowerPC/PPCSubtarget.cpp +++ b/lib/Target/PowerPC/PPCSubtarget.cpp @@ -71,6 +71,7 @@ static const char *GetCurrentPowerPCCPU() { PPCSubtarget::PPCSubtarget(const Module &M, const std::string &FS) : StackAlignment(16) + , InstrItins() , IsGigaProcessor(false) , Is64Bit(false) , Has64BitRegs(false) diff --git a/lib/Target/PowerPC/PPCSubtarget.h b/lib/Target/PowerPC/PPCSubtarget.h index a457751886f..3f1454ce527 100644 --- a/lib/Target/PowerPC/PPCSubtarget.h +++ b/lib/Target/PowerPC/PPCSubtarget.h @@ -14,6 +14,7 @@ #ifndef POWERPCSUBTARGET_H #define POWERPCSUBTARGET_H +#include "llvm/Target/TargetInstrItineraries.h" #include "llvm/Target/TargetSubtarget.h" #include @@ -26,6 +27,9 @@ protected: /// stackAlignment - The minimum alignment known to hold of the stack frame on /// entry to the function and which must be maintained by every function. unsigned StackAlignment; + + /// Selected instruction itineraries (one entry per itinerary class.) + InstrItineraryData InstrItins; /// Used by the ISel to turn in optimizations for POWER4-derived architectures bool IsGigaProcessor; @@ -49,6 +53,11 @@ public: /// stack frame on entry to the function and which must be maintained by every /// function for this subtarget. unsigned getStackAlignment() const { return StackAlignment; } + + /// getInstrItins - Return the instruction itineraies based on subtarget + /// selection. + const InstrItineraryData getInstrItineraryData() const { return InstrItins; } + bool hasFSQRT() const { return HasFSQRT; } bool has64BitRegs() const { return Has64BitRegs; } diff --git a/lib/Target/PowerPC/PPCTargetMachine.cpp b/lib/Target/PowerPC/PPCTargetMachine.cpp index bd31e97aed7..9a88750b398 100644 --- a/lib/Target/PowerPC/PPCTargetMachine.cpp +++ b/lib/Target/PowerPC/PPCTargetMachine.cpp @@ -64,7 +64,8 @@ unsigned PPCTargetMachine::getModuleMatchQuality(const Module &M) { PPCTargetMachine::PPCTargetMachine(const Module &M, IntrinsicLowering *IL, const std::string &FS) : TargetMachine("PowerPC", IL, false, 4, 4, 4, 4, 4, 4, 2, 1, 1), - Subtarget(M, FS), FrameInfo(*this, false), JITInfo(*this) { + Subtarget(M, FS), FrameInfo(*this, false), JITInfo(*this), + InstrItins(Subtarget.getInstrItineraryData()) { if (TargetDefault == PPCTarget) { if (Subtarget.isAIX()) PPCTarget = TargetAIX; if (Subtarget.isDarwin()) PPCTarget = TargetDarwin; diff --git a/lib/Target/PowerPC/PPCTargetMachine.h b/lib/Target/PowerPC/PPCTargetMachine.h index 5ba4f322901..1295a599107 100644 --- a/lib/Target/PowerPC/PPCTargetMachine.h +++ b/lib/Target/PowerPC/PPCTargetMachine.h @@ -27,10 +27,11 @@ class GlobalValue; class IntrinsicLowering; class PPCTargetMachine : public TargetMachine { - PPCInstrInfo InstrInfo; - PPCSubtarget Subtarget; - PPCFrameInfo FrameInfo; - PPCJITInfo JITInfo; + PPCInstrInfo InstrInfo; + PPCSubtarget Subtarget; + PPCFrameInfo FrameInfo; + PPCJITInfo JITInfo; + InstrItineraryData InstrItins; public: PPCTargetMachine(const Module &M, IntrinsicLowering *IL, const std::string &FS); @@ -42,6 +43,10 @@ public: virtual const MRegisterInfo *getRegisterInfo() const { return &InstrInfo.getRegisterInfo(); } + virtual const InstrItineraryData getInstrItineraryData() const { + return InstrItins; + } + static unsigned getJITMatchQuality(); diff --git a/utils/TableGen/InstrInfoEmitter.cpp b/utils/TableGen/InstrInfoEmitter.cpp index c911ad3ed6e..3f7d5dbadc1 100644 --- a/utils/TableGen/InstrInfoEmitter.cpp +++ b/utils/TableGen/InstrInfoEmitter.cpp @@ -247,7 +247,7 @@ void InstrInfoEmitter::GatherItinClasses() { for (unsigned i = 0, N = DefList.size(); i < N; i++) { Record *Def = DefList[i]; - ItinClassMap[Def->getName()] = i + 1; + ItinClassMap[Def->getName()] = i; } } diff --git a/utils/TableGen/SubtargetEmitter.cpp b/utils/TableGen/SubtargetEmitter.cpp index 9eb1f67297a..0ec780390cf 100644 --- a/utils/TableGen/SubtargetEmitter.cpp +++ b/utils/TableGen/SubtargetEmitter.cpp @@ -178,8 +178,8 @@ void SubtargetEmitter::CPUKeyValues(std::ostream &OS) { // CollectAllItinClasses - Gathers and enumerates all the itinerary classes. // Returns itinerary class count. // -unsigned SubtargetEmitter::CollectAllItinClasses(std::map - &ItinClassesMap) { +unsigned SubtargetEmitter::CollectAllItinClasses(std::ostream &OS, + std::map &ItinClassesMap) { // Gather and sort all itinerary classes std::vector ItinClassList = Records.getAllDerivedDefinitions("InstrItinClass"); @@ -196,6 +196,11 @@ unsigned SubtargetEmitter::CollectAllItinClasses(std::map ItinClassesMap[Name] = i; } + // Emit size of table + OS<<"\nenum {\n"; + OS<<" ItinClassesSize = " << N << "\n"; + OS<<"};\n"; + // Return itinerary class count return N; } @@ -313,6 +318,11 @@ void SubtargetEmitter::EmitStageData(std::ostream &OS, // End stages table OS << "};\n"; + + // Emit size of table + OS<<"\nenum {\n"; + OS<<" StagesSize = sizeof(Stages)/sizeof(llvm::InstrStage)\n"; + OS<<"};\n"; } // @@ -421,13 +431,18 @@ void SubtargetEmitter::EmitData(std::ostream &OS) { std::vector > ProcList; // Enumerate all the itinerary classes - unsigned NItinClasses = CollectAllItinClasses(ItinClassesMap); - // Emit the stage data - EmitStageData(OS, NItinClasses, ItinClassesMap, ProcList); - // Emit the processor itinerary data - EmitProcessorData(OS, ProcList); - // Emit the processor lookup data - EmitProcessorLookup(OS); + unsigned NItinClasses = CollectAllItinClasses(OS, ItinClassesMap); + // Make sure the rest is worth the effort + HasItineraries = NItinClasses != 0; + + if (HasItineraries) { + // Emit the stage data + EmitStageData(OS, NItinClasses, ItinClassesMap, ProcList); + // Emit the processor itinerary data + EmitProcessorData(OS, ProcList); + // Emit the processor lookup data + EmitProcessorLookup(OS); + } } // @@ -460,9 +475,15 @@ void SubtargetEmitter::ParseFeaturesFunction(std::ostream &OS) { OS << " " << Attribute << " = (Bits & " << Instance << ") != 0;\n"; } - OS << "\n" - << " InstrItinerary *Itin = (InstrItinerary *)" - "Features.getInfo(SubTypeInfoKV, SubTypeInfoKVSize);\n"; + + if (HasItineraries) { + OS << "\n" + << " InstrItinerary *Itinerary = (InstrItinerary *)" + "Features.getInfo(SubTypeInfoKV, SubTypeInfoKVSize);\n" + " InstrItins = InstrItineraryData(Stages, StagesSize, " + "Itinerary, ItinClassesSize);\n"; + } + OS << "}\n"; } diff --git a/utils/TableGen/SubtargetEmitter.h b/utils/TableGen/SubtargetEmitter.h index f882f1d53cf..69feeb2d0f5 100644 --- a/utils/TableGen/SubtargetEmitter.h +++ b/utils/TableGen/SubtargetEmitter.h @@ -27,12 +27,13 @@ class SubtargetEmitter : public TableGenBackend { RecordKeeper &Records; std::string Target; + bool HasItineraries; void Enumeration(std::ostream &OS, const char *ClassName, bool isBits); void FeatureKeyValues(std::ostream &OS); void CPUKeyValues(std::ostream &OS); - unsigned CollectAllItinClasses(std::map - &ItinClassesMap); + unsigned CollectAllItinClasses(std::ostream &OS, + std::map &ItinClassesMap); void FormItineraryString(Record *ItinData, std::string &ItinString, unsigned &NStages); void EmitStageData(std::ostream &OS, unsigned NItinClasses, @@ -45,7 +46,7 @@ class SubtargetEmitter : public TableGenBackend { void ParseFeaturesFunction(std::ostream &OS); public: - SubtargetEmitter(RecordKeeper &R) : Records(R) {} + SubtargetEmitter(RecordKeeper &R) : Records(R), HasItineraries(false) {} // run - Output the subtarget enumerations, returning true on failure. void run(std::ostream &o);