blob: 9da0145732b3868d020bb67ad53d547d4b9229f5 [file] [log] [blame]
Andrew Trick2661b412012-07-07 04:00:00 +00001//===- CodeGenSchedule.h - Scheduling Machine Models ------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file defines structures to encapsulate the machine model as decribed in
11// the target description.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef CODEGEN_SCHEDULE_H
16#define CODEGEN_SCHEDULE_H
17
18#include "llvm/TableGen/Record.h"
19#include "llvm/Support/ErrorHandling.h"
20#include "llvm/ADT/DenseMap.h"
21#include "llvm/ADT/StringMap.h"
22
23namespace llvm {
24
25class CodeGenTarget;
26
27// Scheduling class.
28//
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.
32struct CodeGenSchedClass {
33 std::string Name;
34 unsigned Index;
35 Record *ItinClassDef;
36
37 CodeGenSchedClass(): Index(0), ItinClassDef(0) {}
38 CodeGenSchedClass(Record *rec): Index(0), ItinClassDef(rec) {
39 Name = rec->getName();
40 }
41};
42
43// Processor model.
44//
45// ModelName is a unique name used to name an instantiation of MCSchedModel.
46//
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.
51//
52// ItinsDef always points to a valid record definition, but may point to the
53// default NoItineraries. NoItineraries has an empty list of InstrItinData
54// records.
55//
56// ItinDefList orders this processor's InstrItinData records by SchedClass idx.
57struct CodeGenProcModel {
58 std::string ModelName;
59 Record *ModelDef;
60 Record *ItinsDef;
61
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;
65
66 CodeGenProcModel(const std::string &Name, Record *MDef, Record *IDef):
67 ModelName(Name), ModelDef(MDef), ItinsDef(IDef) {}
68};
69
70// Top level container for machine model data.
71class CodeGenSchedModels {
72 RecordKeeper &Records;
73 const CodeGenTarget &Target;
74
75 // List of unique SchedClasses.
76 std::vector<CodeGenSchedClass> SchedClasses;
77
78 // Map SchedClass name to itinerary index.
79 // These are either explicit itinerary classes or inferred classes.
80 StringMap<unsigned> SchedClassIdxMap;
81
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.
86 //
87 // Any inferred SchedClass have a index greater than NumItineraryClasses.
88 unsigned NumItineraryClasses;
89
90 // List of unique processor models.
91 std::vector<CodeGenProcModel> ProcModels;
92
93 // Map Processor's MachineModel + ProcItin fields to a CodeGenProcModel index.
94 typedef DenseMap<std::pair<Record*, Record*>, unsigned> ProcModelMapTy;
95 ProcModelMapTy ProcModelMap;
96
97 // True if any processors have nonempty itineraries.
98 bool HasProcItineraries;
99
100public:
101 CodeGenSchedModels(RecordKeeper& RK, const CodeGenTarget &TGT);
102
103 // Check if any instructions are assigned to an explicit itinerary class other
104 // than NoItinerary.
105 bool hasItineraryClasses() const { return NumItineraryClasses > 0; }
106
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;
111 }
112
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];
117 }
118
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");
125 return Idx;
126 }
127
128 bool hasProcessorItineraries() const {
129 return HasProcItineraries;
130 }
131
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];
137 }
138
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(); }
143
144private:
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);
150 }
151
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();
158 return I->second;
159 }
160
161 // Initialize a new processor model if it is unique.
162 void addProcModel(Record *ProcDef);
163
164 void CollectSchedClasses();
165 void CollectProcModels();
166 void CollectProcItin(CodeGenProcModel &ProcModel,
167 std::vector<Record*> ItinRecords);
168};
169
170} // namespace llvm
171
172#endif