CodeGenSchedule.h revision 2661b411ccc81b1fe19194d3f43b2630cbef3f28
1//===- 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
173