1 //===- CodeGenSchedule.h - Scheduling Machine Models ------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines structures to encapsulate the machine model as decribed in
11 // the target description.
13 //===----------------------------------------------------------------------===//
15 #ifndef CODEGEN_SCHEDULE_H
16 #define CODEGEN_SCHEDULE_H
18 #include "llvm/TableGen/Record.h"
19 #include "llvm/Support/ErrorHandling.h"
20 #include "llvm/ADT/DenseMap.h"
21 #include "llvm/ADT/StringMap.h"
29 // Each instruction description will be mapped to a scheduling class. It may be
30 // an explicitly defined itinerary class, or an inferred class in which case
31 // ItinClassDef == NULL.
32 struct CodeGenSchedClass {
37 CodeGenSchedClass(): Index(0), ItinClassDef(0) {}
38 CodeGenSchedClass(Record *rec): Index(0), ItinClassDef(rec) {
39 Name = rec->getName();
45 // ModelName is a unique name used to name an instantiation of MCSchedModel.
47 // ModelDef is NULL for inferred Models. This happens when a processor defines
48 // an itinerary but no machine model. If the processer defines neither a machine
49 // model nor itinerary, then ModelDef remains pointing to NoModel. NoModel has
50 // the special "NoModel" field set to true.
52 // ItinsDef always points to a valid record definition, but may point to the
53 // default NoItineraries. NoItineraries has an empty list of InstrItinData
56 // ItinDefList orders this processor's InstrItinData records by SchedClass idx.
57 struct CodeGenProcModel {
58 std::string ModelName;
62 // Array of InstrItinData records indexed by CodeGenSchedClass::Index.
63 // The list is empty if the subtarget has no itineraries.
64 std::vector<Record *> ItinDefList;
66 CodeGenProcModel(const std::string &Name, Record *MDef, Record *IDef):
67 ModelName(Name), ModelDef(MDef), ItinsDef(IDef) {}
70 // Top level container for machine model data.
71 class CodeGenSchedModels {
72 RecordKeeper &Records;
73 const CodeGenTarget &Target;
75 // List of unique SchedClasses.
76 std::vector<CodeGenSchedClass> SchedClasses;
78 // Map SchedClass name to itinerary index.
79 // These are either explicit itinerary classes or inferred classes.
80 StringMap<unsigned> SchedClassIdxMap;
82 // SchedClass indices 1 up to and including NumItineraryClasses identify
83 // itinerary classes that are explicitly used for this target's instruction
84 // definitions. NoItinerary always has index 0 regardless of whether it is
85 // explicitly referenced.
87 // Any inferred SchedClass have a index greater than NumItineraryClasses.
88 unsigned NumItineraryClasses;
90 // List of unique processor models.
91 std::vector<CodeGenProcModel> ProcModels;
93 // Map Processor's MachineModel + ProcItin fields to a CodeGenProcModel index.
94 typedef DenseMap<std::pair<Record*, Record*>, unsigned> ProcModelMapTy;
95 ProcModelMapTy ProcModelMap;
97 // True if any processors have nonempty itineraries.
98 bool HasProcItineraries;
101 CodeGenSchedModels(RecordKeeper& RK, const CodeGenTarget &TGT);
103 // Check if any instructions are assigned to an explicit itinerary class other
105 bool hasItineraryClasses() const { return NumItineraryClasses > 0; }
107 // Return the number of itinerary classes in use by this target's instruction
108 // descriptions, not including "NoItinerary".
109 unsigned numItineraryClasses() const {
110 return NumItineraryClasses;
113 // Get a SchedClass from its index.
114 const CodeGenSchedClass &getSchedClass(unsigned Idx) {
115 assert(Idx < SchedClasses.size() && "bad SchedClass index");
116 return SchedClasses[Idx];
119 // Get an itinerary class's index. Value indices are '0' for NoItinerary up to
120 // and including numItineraryClasses().
121 unsigned getItinClassIdx(Record *ItinDef) const {
122 assert(SchedClassIdxMap.count(ItinDef->getName()) && "missing ItinClass");
123 unsigned Idx = SchedClassIdxMap.lookup(ItinDef->getName());
124 assert(Idx <= NumItineraryClasses && "bad ItinClass index");
128 bool hasProcessorItineraries() const {
129 return HasProcItineraries;
132 // Get an existing machine model for a processor definition.
133 const CodeGenProcModel &getProcModel(Record *ProcDef) const {
134 unsigned idx = getProcModelIdx(ProcDef);
135 assert(idx < ProcModels.size() && "missing machine model");
136 return ProcModels[idx];
139 // Iterate over the unique processor models.
140 typedef std::vector<CodeGenProcModel>::const_iterator ProcIter;
141 ProcIter procModelBegin() const { return ProcModels.begin(); }
142 ProcIter procModelEnd() const { return ProcModels.end(); }
145 // Get a key that can uniquely identify a machine model.
146 ProcModelMapTy::key_type getProcModelKey(Record *ProcDef) const {
147 Record *ModelDef = ProcDef->getValueAsDef("SchedModel");
148 Record *ItinsDef = ProcDef->getValueAsDef("ProcItin");
149 return std::make_pair(ModelDef, ItinsDef);
152 // Get the unique index of a machine model.
153 unsigned getProcModelIdx(Record *ProcDef) const {
154 ProcModelMapTy::const_iterator I =
155 ProcModelMap.find(getProcModelKey(ProcDef));
156 if (I == ProcModelMap.end())
157 return ProcModels.size();
161 // Initialize a new processor model if it is unique.
162 void addProcModel(Record *ProcDef);
164 void CollectSchedClasses();
165 void CollectProcModels();
166 void CollectProcItin(CodeGenProcModel &ProcModel,
167 std::vector<Record*> ItinRecords);