| //===- CodeGenSchedule.h - Scheduling Machine Models ------------*- C++ -*-===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This file defines structures to encapsulate the machine model as decribed in |
| // the target description. |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef CODEGEN_SCHEDULE_H |
| #define CODEGEN_SCHEDULE_H |
| |
| #include "llvm/TableGen/Record.h" |
| #include "llvm/Support/ErrorHandling.h" |
| #include "llvm/ADT/DenseMap.h" |
| #include "llvm/ADT/StringMap.h" |
| |
| namespace llvm { |
| |
| class CodeGenTarget; |
| |
| // Scheduling class. |
| // |
| // Each instruction description will be mapped to a scheduling class. It may be |
| // an explicitly defined itinerary class, or an inferred class in which case |
| // ItinClassDef == NULL. |
| struct CodeGenSchedClass { |
| std::string Name; |
| unsigned Index; |
| Record *ItinClassDef; |
| |
| CodeGenSchedClass(): Index(0), ItinClassDef(0) {} |
| CodeGenSchedClass(Record *rec): Index(0), ItinClassDef(rec) { |
| Name = rec->getName(); |
| } |
| }; |
| |
| // Processor model. |
| // |
| // ModelName is a unique name used to name an instantiation of MCSchedModel. |
| // |
| // ModelDef is NULL for inferred Models. This happens when a processor defines |
| // an itinerary but no machine model. If the processer defines neither a machine |
| // model nor itinerary, then ModelDef remains pointing to NoModel. NoModel has |
| // the special "NoModel" field set to true. |
| // |
| // ItinsDef always points to a valid record definition, but may point to the |
| // default NoItineraries. NoItineraries has an empty list of InstrItinData |
| // records. |
| // |
| // ItinDefList orders this processor's InstrItinData records by SchedClass idx. |
| struct CodeGenProcModel { |
| std::string ModelName; |
| Record *ModelDef; |
| Record *ItinsDef; |
| |
| // Array of InstrItinData records indexed by CodeGenSchedClass::Index. |
| // The list is empty if the subtarget has no itineraries. |
| std::vector<Record *> ItinDefList; |
| |
| CodeGenProcModel(const std::string &Name, Record *MDef, Record *IDef): |
| ModelName(Name), ModelDef(MDef), ItinsDef(IDef) {} |
| }; |
| |
| // Top level container for machine model data. |
| class CodeGenSchedModels { |
| RecordKeeper &Records; |
| const CodeGenTarget &Target; |
| |
| // List of unique SchedClasses. |
| std::vector<CodeGenSchedClass> SchedClasses; |
| |
| // Map SchedClass name to itinerary index. |
| // These are either explicit itinerary classes or inferred classes. |
| StringMap<unsigned> SchedClassIdxMap; |
| |
| // SchedClass indices 1 up to and including NumItineraryClasses identify |
| // itinerary classes that are explicitly used for this target's instruction |
| // definitions. NoItinerary always has index 0 regardless of whether it is |
| // explicitly referenced. |
| // |
| // Any inferred SchedClass have a index greater than NumItineraryClasses. |
| unsigned NumItineraryClasses; |
| |
| // List of unique processor models. |
| std::vector<CodeGenProcModel> ProcModels; |
| |
| // Map Processor's MachineModel + ProcItin fields to a CodeGenProcModel index. |
| typedef DenseMap<std::pair<Record*, Record*>, unsigned> ProcModelMapTy; |
| ProcModelMapTy ProcModelMap; |
| |
| // True if any processors have nonempty itineraries. |
| bool HasProcItineraries; |
| |
| public: |
| CodeGenSchedModels(RecordKeeper& RK, const CodeGenTarget &TGT); |
| |
| // Check if any instructions are assigned to an explicit itinerary class other |
| // than NoItinerary. |
| bool hasItineraryClasses() const { return NumItineraryClasses > 0; } |
| |
| // Return the number of itinerary classes in use by this target's instruction |
| // descriptions, not including "NoItinerary". |
| unsigned numItineraryClasses() const { |
| return NumItineraryClasses; |
| } |
| |
| // Get a SchedClass from its index. |
| const CodeGenSchedClass &getSchedClass(unsigned Idx) { |
| assert(Idx < SchedClasses.size() && "bad SchedClass index"); |
| return SchedClasses[Idx]; |
| } |
| |
| // Get an itinerary class's index. Value indices are '0' for NoItinerary up to |
| // and including numItineraryClasses(). |
| unsigned getItinClassIdx(Record *ItinDef) const { |
| assert(SchedClassIdxMap.count(ItinDef->getName()) && "missing ItinClass"); |
| unsigned Idx = SchedClassIdxMap.lookup(ItinDef->getName()); |
| assert(Idx <= NumItineraryClasses && "bad ItinClass index"); |
| return Idx; |
| } |
| |
| bool hasProcessorItineraries() const { |
| return HasProcItineraries; |
| } |
| |
| // Get an existing machine model for a processor definition. |
| const CodeGenProcModel &getProcModel(Record *ProcDef) const { |
| unsigned idx = getProcModelIdx(ProcDef); |
| assert(idx < ProcModels.size() && "missing machine model"); |
| return ProcModels[idx]; |
| } |
| |
| // Iterate over the unique processor models. |
| typedef std::vector<CodeGenProcModel>::const_iterator ProcIter; |
| ProcIter procModelBegin() const { return ProcModels.begin(); } |
| ProcIter procModelEnd() const { return ProcModels.end(); } |
| |
| private: |
| // Get a key that can uniquely identify a machine model. |
| ProcModelMapTy::key_type getProcModelKey(Record *ProcDef) const { |
| Record *ModelDef = ProcDef->getValueAsDef("SchedModel"); |
| Record *ItinsDef = ProcDef->getValueAsDef("ProcItin"); |
| return std::make_pair(ModelDef, ItinsDef); |
| } |
| |
| // Get the unique index of a machine model. |
| unsigned getProcModelIdx(Record *ProcDef) const { |
| ProcModelMapTy::const_iterator I = |
| ProcModelMap.find(getProcModelKey(ProcDef)); |
| if (I == ProcModelMap.end()) |
| return ProcModels.size(); |
| return I->second; |
| } |
| |
| // Initialize a new processor model if it is unique. |
| void addProcModel(Record *ProcDef); |
| |
| void CollectSchedClasses(); |
| void CollectProcModels(); |
| void CollectProcItin(CodeGenProcModel &ProcModel, |
| std::vector<Record*> ItinRecords); |
| }; |
| |
| } // namespace llvm |
| |
| #endif |