llvm.org GIT mirror llvm / ab8be96
Sink SubtargetFeature and TargetInstrItineraries (renamed MCInstrItineraries) into MC. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@134049 91177308-0d34-0410-b5e6-96231b3b80d8 Evan Cheng 8 years ago
26 changed file(s) with 787 addition(s) and 791 deletion(s). Raw diff Collapse all Expand all
0 //===-- llvm/MC/MCInstrItineraries.h - Scheduling ---------------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file describes the structures used for instruction
10 // itineraries, stages, and operand reads/writes. This is used by
11 // schedulers to determine instruction stages and latencies.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #ifndef LLVM_MC_MCINSTRITINERARIES_H
16 #define LLVM_MC_MCINSTRITINERARIES_H
17
18 #include
19
20 namespace llvm {
21
22 //===----------------------------------------------------------------------===//
23 /// Instruction stage - These values represent a non-pipelined step in
24 /// the execution of an instruction. Cycles represents the number of
25 /// discrete time slots needed to complete the stage. Units represent
26 /// the choice of functional units that can be used to complete the
27 /// stage. Eg. IntUnit1, IntUnit2. NextCycles indicates how many
28 /// cycles should elapse from the start of this stage to the start of
29 /// the next stage in the itinerary. A value of -1 indicates that the
30 /// next stage should start immediately after the current one.
31 /// For example:
32 ///
33 /// { 1, x, -1 }
34 /// indicates that the stage occupies FU x for 1 cycle and that
35 /// the next stage starts immediately after this one.
36 ///
37 /// { 2, x|y, 1 }
38 /// indicates that the stage occupies either FU x or FU y for 2
39 /// consecuative cycles and that the next stage starts one cycle
40 /// after this stage starts. That is, the stage requirements
41 /// overlap in time.
42 ///
43 /// { 1, x, 0 }
44 /// indicates that the stage occupies FU x for 1 cycle and that
45 /// the next stage starts in this same cycle. This can be used to
46 /// indicate that the instruction requires multiple stages at the
47 /// same time.
48 ///
49 /// FU reservation can be of two different kinds:
50 /// - FUs which instruction actually requires
51 /// - FUs which instruction just reserves. Reserved unit is not available for
52 /// execution of other instruction. However, several instructions can reserve
53 /// the same unit several times.
54 /// Such two types of units reservation is used to model instruction domain
55 /// change stalls, FUs using the same resource (e.g. same register file), etc.
56
57 struct InstrStage {
58 enum ReservationKinds {
59 Required = 0,
60 Reserved = 1
61 };
62
63 unsigned Cycles_; ///< Length of stage in machine cycles
64 unsigned Units_; ///< Choice of functional units
65 int NextCycles_; ///< Number of machine cycles to next stage
66 ReservationKinds Kind_; ///< Kind of the FU reservation
67
68 /// getCycles - returns the number of cycles the stage is occupied
69 unsigned getCycles() const {
70 return Cycles_;
71 }
72
73 /// getUnits - returns the choice of FUs
74 unsigned getUnits() const {
75 return Units_;
76 }
77
78 ReservationKinds getReservationKind() const {
79 return Kind_;
80 }
81
82 /// getNextCycles - returns the number of cycles from the start of
83 /// this stage to the start of the next stage in the itinerary
84 unsigned getNextCycles() const {
85 return (NextCycles_ >= 0) ? (unsigned)NextCycles_ : Cycles_;
86 }
87 };
88
89
90 //===----------------------------------------------------------------------===//
91 /// Instruction itinerary - An itinerary represents the scheduling
92 /// information for an instruction. This includes a set of stages
93 /// occupies by the instruction, and the pipeline cycle in which
94 /// operands are read and written.
95 ///
96 struct InstrItinerary {
97 unsigned NumMicroOps; ///< # of micro-ops, 0 means it's variable
98 unsigned FirstStage; ///< Index of first stage in itinerary
99 unsigned LastStage; ///< Index of last + 1 stage in itinerary
100 unsigned FirstOperandCycle; ///< Index of first operand rd/wr
101 unsigned LastOperandCycle; ///< Index of last + 1 operand rd/wr
102 };
103
104
105 //===----------------------------------------------------------------------===//
106 /// Instruction itinerary Data - Itinerary data supplied by a subtarget to be
107 /// used by a target.
108 ///
109 class InstrItineraryData {
110 public:
111 const InstrStage *Stages; ///< Array of stages selected
112 const unsigned *OperandCycles; ///< Array of operand cycles selected
113 const unsigned *Forwardings; ///< Array of pipeline forwarding pathes
114 const InstrItinerary *Itineraries; ///< Array of itineraries selected
115 unsigned IssueWidth; ///< Max issue per cycle. 0=Unknown.
116
117 /// Ctors.
118 ///
119 InstrItineraryData() : Stages(0), OperandCycles(0), Forwardings(0),
120 Itineraries(0), IssueWidth(0) {}
121
122 InstrItineraryData(const InstrStage *S, const unsigned *OS,
123 const unsigned *F, const InstrItinerary *I)
124 : Stages(S), OperandCycles(OS), Forwardings(F), Itineraries(I),
125 IssueWidth(0) {}
126
127 /// isEmpty - Returns true if there are no itineraries.
128 ///
129 bool isEmpty() const { return Itineraries == 0; }
130
131 /// isEndMarker - Returns true if the index is for the end marker
132 /// itinerary.
133 ///
134 bool isEndMarker(unsigned ItinClassIndx) const {
135 return ((Itineraries[ItinClassIndx].FirstStage == ~0U) &&
136 (Itineraries[ItinClassIndx].LastStage == ~0U));
137 }
138
139 /// beginStage - Return the first stage of the itinerary.
140 ///
141 const InstrStage *beginStage(unsigned ItinClassIndx) const {
142 unsigned StageIdx = Itineraries[ItinClassIndx].FirstStage;
143 return Stages + StageIdx;
144 }
145
146 /// endStage - Return the last+1 stage of the itinerary.
147 ///
148 const InstrStage *endStage(unsigned ItinClassIndx) const {
149 unsigned StageIdx = Itineraries[ItinClassIndx].LastStage;
150 return Stages + StageIdx;
151 }
152
153 /// getStageLatency - Return the total stage latency of the given
154 /// class. The latency is the maximum completion time for any stage
155 /// in the itinerary.
156 ///
157 unsigned getStageLatency(unsigned ItinClassIndx) const {
158 // If the target doesn't provide itinerary information, use a simple
159 // non-zero default value for all instructions. Some target's provide a
160 // dummy (Generic) itinerary which should be handled as if it's itinerary is
161 // empty. We identify this by looking for a reference to stage zero (invalid
162 // stage). This is different from beginStage == endState != 0, which could
163 // be used for zero-latency pseudo ops.
164 if (isEmpty() || Itineraries[ItinClassIndx].FirstStage == 0)
165 return 1;
166
167 // Calculate the maximum completion time for any stage.
168 unsigned Latency = 0, StartCycle = 0;
169 for (const InstrStage *IS = beginStage(ItinClassIndx),
170 *E = endStage(ItinClassIndx); IS != E; ++IS) {
171 Latency = std::max(Latency, StartCycle + IS->getCycles());
172 StartCycle += IS->getNextCycles();
173 }
174
175 return Latency;
176 }
177
178 /// getOperandCycle - Return the cycle for the given class and
179 /// operand. Return -1 if no cycle is specified for the operand.
180 ///
181 int getOperandCycle(unsigned ItinClassIndx, unsigned OperandIdx) const {
182 if (isEmpty())
183 return -1;
184
185 unsigned FirstIdx = Itineraries[ItinClassIndx].FirstOperandCycle;
186 unsigned LastIdx = Itineraries[ItinClassIndx].LastOperandCycle;
187 if ((FirstIdx + OperandIdx) >= LastIdx)
188 return -1;
189
190 return (int)OperandCycles[FirstIdx + OperandIdx];
191 }
192
193 /// hasPipelineForwarding - Return true if there is a pipeline forwarding
194 /// between instructions of itinerary classes DefClass and UseClasses so that
195 /// value produced by an instruction of itinerary class DefClass, operand
196 /// index DefIdx can be bypassed when it's read by an instruction of
197 /// itinerary class UseClass, operand index UseIdx.
198 bool hasPipelineForwarding(unsigned DefClass, unsigned DefIdx,
199 unsigned UseClass, unsigned UseIdx) const {
200 unsigned FirstDefIdx = Itineraries[DefClass].FirstOperandCycle;
201 unsigned LastDefIdx = Itineraries[DefClass].LastOperandCycle;
202 if ((FirstDefIdx + DefIdx) >= LastDefIdx)
203 return false;
204 if (Forwardings[FirstDefIdx + DefIdx] == 0)
205 return false;
206
207 unsigned FirstUseIdx = Itineraries[UseClass].FirstOperandCycle;
208 unsigned LastUseIdx = Itineraries[UseClass].LastOperandCycle;
209 if ((FirstUseIdx + UseIdx) >= LastUseIdx)
210 return false;
211
212 return Forwardings[FirstDefIdx + DefIdx] ==
213 Forwardings[FirstUseIdx + UseIdx];
214 }
215
216 /// getOperandLatency - Compute and return the use operand latency of a given
217 /// itinerary class and operand index if the value is produced by an
218 /// instruction of the specified itinerary class and def operand index.
219 int getOperandLatency(unsigned DefClass, unsigned DefIdx,
220 unsigned UseClass, unsigned UseIdx) const {
221 if (isEmpty())
222 return -1;
223
224 int DefCycle = getOperandCycle(DefClass, DefIdx);
225 if (DefCycle == -1)
226 return -1;
227
228 int UseCycle = getOperandCycle(UseClass, UseIdx);
229 if (UseCycle == -1)
230 return -1;
231
232 UseCycle = DefCycle - UseCycle + 1;
233 if (UseCycle > 0 &&
234 hasPipelineForwarding(DefClass, DefIdx, UseClass, UseIdx))
235 // FIXME: This assumes one cycle benefit for every pipeline forwarding.
236 --UseCycle;
237 return UseCycle;
238 }
239
240 /// isMicroCoded - Return true if the instructions in the given class decode
241 /// to more than one micro-ops.
242 bool isMicroCoded(unsigned ItinClassIndx) const {
243 if (isEmpty())
244 return false;
245 return Itineraries[ItinClassIndx].NumMicroOps != 1;
246 }
247 };
248
249
250 } // End llvm namespace
251
252 #endif
0 //===-- llvm/MC/SubtargetFeature.h - CPU characteristics --------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines and manages user or tool specified CPU characteristics.
10 // The intent is to be able to package specific features that should or should
11 // not be used on a specific target processor. A tool, such as llc, could, as
12 // as example, gather chip info from the command line, a long with features
13 // that should be used on that chip.
14 //
15 //===----------------------------------------------------------------------===//
16
17 #ifndef LLVM_MC_SUBTARGETFEATURE_H
18 #define LLVM_MC_SUBTARGETFEATURE_H
19
20 #include
21 #include
22 #include "llvm/ADT/Triple.h"
23 #include "llvm/Support/DataTypes.h"
24
25 namespace llvm {
26 class raw_ostream;
27
28 //===----------------------------------------------------------------------===//
29 ///
30 /// SubtargetFeatureKV - Used to provide key value pairs for feature and
31 /// CPU bit flags.
32 //
33 struct SubtargetFeatureKV {
34 const char *Key; // K-V key string
35 const char *Desc; // Help descriptor
36 uint64_t Value; // K-V integer value
37 uint64_t Implies; // K-V bit mask
38
39 // Compare routine for std binary search
40 bool operator<(const SubtargetFeatureKV &S) const {
41 return strcmp(Key, S.Key) < 0;
42 }
43 };
44
45 //===----------------------------------------------------------------------===//
46 ///
47 /// SubtargetInfoKV - Used to provide key value pairs for CPU and arbitrary
48 /// pointers.
49 //
50 struct SubtargetInfoKV {
51 const char *Key; // K-V key string
52 void *Value; // K-V pointer value
53
54 // Compare routine for std binary search
55 bool operator<(const SubtargetInfoKV &S) const {
56 return strcmp(Key, S.Key) < 0;
57 }
58 };
59
60 //===----------------------------------------------------------------------===//
61 ///
62 /// SubtargetFeatures - Manages the enabling and disabling of subtarget
63 /// specific features. Features are encoded as a string of the form
64 /// "cpu,+attr1,+attr2,-attr3,...,+attrN"
65 /// A comma separates each feature from the next (all lowercase.)
66 /// The first feature is always the CPU subtype (eg. pentiumm). If the CPU
67 /// value is "generic" then the CPU subtype should be generic for the target.
68 /// Each of the remaining features is prefixed with + or - indicating whether
69 /// that feature should be enabled or disabled contrary to the cpu
70 /// specification.
71 ///
72
73 class SubtargetFeatures {
74 std::vector Features; // Subtarget features as a vector
75 public:
76 explicit SubtargetFeatures(const std::string &Initial = std::string());
77
78 /// Features string accessors.
79 std::string getString() const;
80 void setString(const std::string &Initial);
81
82 /// Set the CPU string. Replaces previous setting. Setting to "" clears CPU.
83 void setCPU(const std::string &String);
84
85 /// Setting CPU string only if no string is set.
86 void setCPUIfNone(const std::string &String);
87
88 /// Returns current CPU string.
89 const std::string & getCPU() const;
90
91 /// Adding Features.
92 void AddFeature(const std::string &String, bool IsEnabled = true);
93
94 /// Get feature bits.
95 uint64_t getBits(const SubtargetFeatureKV *CPUTable,
96 size_t CPUTableSize,
97 const SubtargetFeatureKV *FeatureTable,
98 size_t FeatureTableSize);
99
100 /// Get info pointer
101 void *getInfo(const SubtargetInfoKV *Table, size_t TableSize);
102
103 /// Print feature string.
104 void print(raw_ostream &OS) const;
105
106 // Dump feature info.
107 void dump() const;
108
109 /// Retrieve a formatted string of the default features for the specified
110 /// target triple.
111 void getDefaultSubtargetFeatures(const std::string &CPU,
112 const Triple& Triple);
113 };
114
115 } // End namespace llvm
116
117 #endif
+0
-118
include/llvm/Target/SubtargetFeature.h less more
None //===-- llvm/Target/SubtargetFeature.h - CPU characteristics ----*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file defines and manages user or tool specified CPU characteristics.
10 // The intent is to be able to package specific features that should or should
11 // not be used on a specific target processor. A tool, such as llc, could, as
12 // as example, gather chip info from the command line, a long with features
13 // that should be used on that chip.
14 //
15 //===----------------------------------------------------------------------===//
16
17 #ifndef LLVM_TARGET_SUBTARGETFEATURE_H
18 #define LLVM_TARGET_SUBTARGETFEATURE_H
19
20 #include
21 #include
22 #include "llvm/ADT/Triple.h"
23 #include "llvm/Support/DataTypes.h"
24
25 namespace llvm {
26 class raw_ostream;
27
28 //===----------------------------------------------------------------------===//
29 ///
30 /// SubtargetFeatureKV - Used to provide key value pairs for feature and
31 /// CPU bit flags.
32 //
33 struct SubtargetFeatureKV {
34 const char *Key; // K-V key string
35 const char *Desc; // Help descriptor
36 uint64_t Value; // K-V integer value
37 uint64_t Implies; // K-V bit mask
38
39 // Compare routine for std binary search
40 bool operator<(const SubtargetFeatureKV &S) const {
41 return strcmp(Key, S.Key) < 0;
42 }
43 };
44
45 //===----------------------------------------------------------------------===//
46 ///
47 /// SubtargetInfoKV - Used to provide key value pairs for CPU and arbitrary
48 /// pointers.
49 //
50 struct SubtargetInfoKV {
51 const char *Key; // K-V key string
52 void *Value; // K-V pointer value
53
54 // Compare routine for std binary search
55 bool operator<(const SubtargetInfoKV &S) const {
56 return strcmp(Key, S.Key) < 0;
57 }
58 };
59
60 //===----------------------------------------------------------------------===//
61 ///
62 /// SubtargetFeatures - Manages the enabling and disabling of subtarget
63 /// specific features. Features are encoded as a string of the form
64 /// "cpu,+attr1,+attr2,-attr3,...,+attrN"
65 /// A comma separates each feature from the next (all lowercase.)
66 /// The first feature is always the CPU subtype (eg. pentiumm). If the CPU
67 /// value is "generic" then the CPU subtype should be generic for the target.
68 /// Each of the remaining features is prefixed with + or - indicating whether
69 /// that feature should be enabled or disabled contrary to the cpu
70 /// specification.
71 ///
72
73 class SubtargetFeatures {
74 std::vector Features; // Subtarget features as a vector
75 public:
76 explicit SubtargetFeatures(const std::string &Initial = std::string());
77
78 /// Features string accessors.
79 std::string getString() const;
80 void setString(const std::string &Initial);
81
82 /// Set the CPU string. Replaces previous setting. Setting to "" clears CPU.
83 void setCPU(const std::string &String);
84
85 /// Setting CPU string only if no string is set.
86 void setCPUIfNone(const std::string &String);
87
88 /// Returns current CPU string.
89 const std::string & getCPU() const;
90
91 /// Adding Features.
92 void AddFeature(const std::string &String, bool IsEnabled = true);
93
94 /// Get feature bits.
95 uint64_t getBits(const SubtargetFeatureKV *CPUTable,
96 size_t CPUTableSize,
97 const SubtargetFeatureKV *FeatureTable,
98 size_t FeatureTableSize);
99
100 /// Get info pointer
101 void *getInfo(const SubtargetInfoKV *Table, size_t TableSize);
102
103 /// Print feature string.
104 void print(raw_ostream &OS) const;
105
106 // Dump feature info.
107 void dump() const;
108
109 /// Retrieve a formatted string of the default features for the specified
110 /// target triple.
111 void getDefaultSubtargetFeatures(const std::string &CPU,
112 const Triple& Triple);
113 };
114
115 } // End namespace llvm
116
117 #endif
+0
-253
include/llvm/Target/TargetInstrItineraries.h less more
None //===-- llvm/Target/TargetInstrItineraries.h - Scheduling -------*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file describes the structures used for instruction
10 // itineraries, stages, and operand reads/writes. This is used by
11 // schedulers to determine instruction stages and latencies.
12 //
13 //===----------------------------------------------------------------------===//
14
15 #ifndef LLVM_TARGET_TARGETINSTRITINERARIES_H
16 #define LLVM_TARGET_TARGETINSTRITINERARIES_H
17
18 #include
19
20 namespace llvm {
21
22 //===----------------------------------------------------------------------===//
23 /// Instruction stage - These values represent a non-pipelined step in
24 /// the execution of an instruction. Cycles represents the number of
25 /// discrete time slots needed to complete the stage. Units represent
26 /// the choice of functional units that can be used to complete the
27 /// stage. Eg. IntUnit1, IntUnit2. NextCycles indicates how many
28 /// cycles should elapse from the start of this stage to the start of
29 /// the next stage in the itinerary. A value of -1 indicates that the
30 /// next stage should start immediately after the current one.
31 /// For example:
32 ///
33 /// { 1, x, -1 }
34 /// indicates that the stage occupies FU x for 1 cycle and that
35 /// the next stage starts immediately after this one.
36 ///
37 /// { 2, x|y, 1 }
38 /// indicates that the stage occupies either FU x or FU y for 2
39 /// consecuative cycles and that the next stage starts one cycle
40 /// after this stage starts. That is, the stage requirements
41 /// overlap in time.
42 ///
43 /// { 1, x, 0 }
44 /// indicates that the stage occupies FU x for 1 cycle and that
45 /// the next stage starts in this same cycle. This can be used to
46 /// indicate that the instruction requires multiple stages at the
47 /// same time.
48 ///
49 /// FU reservation can be of two different kinds:
50 /// - FUs which instruction actually requires
51 /// - FUs which instruction just reserves. Reserved unit is not available for
52 /// execution of other instruction. However, several instructions can reserve
53 /// the same unit several times.
54 /// Such two types of units reservation is used to model instruction domain
55 /// change stalls, FUs using the same resource (e.g. same register file), etc.
56
57 struct InstrStage {
58 enum ReservationKinds {
59 Required = 0,
60 Reserved = 1
61 };
62
63 unsigned Cycles_; ///< Length of stage in machine cycles
64 unsigned Units_; ///< Choice of functional units
65 int NextCycles_; ///< Number of machine cycles to next stage
66 ReservationKinds Kind_; ///< Kind of the FU reservation
67
68 /// getCycles - returns the number of cycles the stage is occupied
69 unsigned getCycles() const {
70 return Cycles_;
71 }
72
73 /// getUnits - returns the choice of FUs
74 unsigned getUnits() const {
75 return Units_;
76 }
77
78 ReservationKinds getReservationKind() const {
79 return Kind_;
80 }
81
82 /// getNextCycles - returns the number of cycles from the start of
83 /// this stage to the start of the next stage in the itinerary
84 unsigned getNextCycles() const {
85 return (NextCycles_ >= 0) ? (unsigned)NextCycles_ : Cycles_;
86 }
87 };
88
89
90 //===----------------------------------------------------------------------===//
91 /// Instruction itinerary - An itinerary represents the scheduling
92 /// information for an instruction. This includes a set of stages
93 /// occupies by the instruction, and the pipeline cycle in which
94 /// operands are read and written.
95 ///
96 struct InstrItinerary {
97 unsigned NumMicroOps; ///< # of micro-ops, 0 means it's variable
98 unsigned FirstStage; ///< Index of first stage in itinerary
99 unsigned LastStage; ///< Index of last + 1 stage in itinerary
100 unsigned FirstOperandCycle; ///< Index of first operand rd/wr
101 unsigned LastOperandCycle; ///< Index of last + 1 operand rd/wr
102 };
103
104
105 //===----------------------------------------------------------------------===//
106 /// Instruction itinerary Data - Itinerary data supplied by a subtarget to be
107 /// used by a target.
108 ///
109 class InstrItineraryData {
110 public:
111 const InstrStage *Stages; ///< Array of stages selected
112 const unsigned *OperandCycles; ///< Array of operand cycles selected
113 const unsigned *Forwardings; ///< Array of pipeline forwarding pathes
114 const InstrItinerary *Itineraries; ///< Array of itineraries selected
115 unsigned IssueWidth; ///< Max issue per cycle. 0=Unknown.
116
117 /// Ctors.
118 ///
119 InstrItineraryData() : Stages(0), OperandCycles(0), Forwardings(0),
120 Itineraries(0), IssueWidth(0) {}
121
122 InstrItineraryData(const InstrStage *S, const unsigned *OS,
123 const unsigned *F, const InstrItinerary *I)
124 : Stages(S), OperandCycles(OS), Forwardings(F), Itineraries(I),
125 IssueWidth(0) {}
126
127 /// isEmpty - Returns true if there are no itineraries.
128 ///
129 bool isEmpty() const { return Itineraries == 0; }
130
131 /// isEndMarker - Returns true if the index is for the end marker
132 /// itinerary.
133 ///
134 bool isEndMarker(unsigned ItinClassIndx) const {
135 return ((Itineraries[ItinClassIndx].FirstStage == ~0U) &&
136 (Itineraries[ItinClassIndx].LastStage == ~0U));
137 }
138
139 /// beginStage - Return the first stage of the itinerary.
140 ///
141 const InstrStage *beginStage(unsigned ItinClassIndx) const {
142 unsigned StageIdx = Itineraries[ItinClassIndx].FirstStage;
143 return Stages + StageIdx;
144 }
145
146 /// endStage - Return the last+1 stage of the itinerary.
147 ///
148 const InstrStage *endStage(unsigned ItinClassIndx) const {
149 unsigned StageIdx = Itineraries[ItinClassIndx].LastStage;
150 return Stages + StageIdx;
151 }
152
153 /// getStageLatency - Return the total stage latency of the given
154 /// class. The latency is the maximum completion time for any stage
155 /// in the itinerary.
156 ///
157 unsigned getStageLatency(unsigned ItinClassIndx) const {
158 // If the target doesn't provide itinerary information, use a simple
159 // non-zero default value for all instructions. Some target's provide a
160 // dummy (Generic) itinerary which should be handled as if it's itinerary is
161 // empty. We identify this by looking for a reference to stage zero (invalid
162 // stage). This is different from beginStage == endState != 0, which could
163 // be used for zero-latency pseudo ops.
164 if (isEmpty() || Itineraries[ItinClassIndx].FirstStage == 0)
165 return 1;
166
167 // Calculate the maximum completion time for any stage.
168 unsigned Latency = 0, StartCycle = 0;
169 for (const InstrStage *IS = beginStage(ItinClassIndx),
170 *E = endStage(ItinClassIndx); IS != E; ++IS) {
171 Latency = std::max(Latency, StartCycle + IS->getCycles());
172 StartCycle += IS->getNextCycles();
173 }
174
175 return Latency;
176 }
177
178 /// getOperandCycle - Return the cycle for the given class and
179 /// operand. Return -1 if no cycle is specified for the operand.
180 ///
181 int getOperandCycle(unsigned ItinClassIndx, unsigned OperandIdx) const {
182 if (isEmpty())
183 return -1;
184
185 unsigned FirstIdx = Itineraries[ItinClassIndx].FirstOperandCycle;
186 unsigned LastIdx = Itineraries[ItinClassIndx].LastOperandCycle;
187 if ((FirstIdx + OperandIdx) >= LastIdx)
188 return -1;
189
190 return (int)OperandCycles[FirstIdx + OperandIdx];
191 }
192
193 /// hasPipelineForwarding - Return true if there is a pipeline forwarding
194 /// between instructions of itinerary classes DefClass and UseClasses so that
195 /// value produced by an instruction of itinerary class DefClass, operand
196 /// index DefIdx can be bypassed when it's read by an instruction of
197 /// itinerary class UseClass, operand index UseIdx.
198 bool hasPipelineForwarding(unsigned DefClass, unsigned DefIdx,
199 unsigned UseClass, unsigned UseIdx) const {
200 unsigned FirstDefIdx = Itineraries[DefClass].FirstOperandCycle;
201 unsigned LastDefIdx = Itineraries[DefClass].LastOperandCycle;
202 if ((FirstDefIdx + DefIdx) >= LastDefIdx)
203 return false;
204 if (Forwardings[FirstDefIdx + DefIdx] == 0)
205 return false;
206
207 unsigned FirstUseIdx = Itineraries[UseClass].FirstOperandCycle;
208 unsigned LastUseIdx = Itineraries[UseClass].LastOperandCycle;
209 if ((FirstUseIdx + UseIdx) >= LastUseIdx)
210 return false;
211
212 return Forwardings[FirstDefIdx + DefIdx] ==
213 Forwardings[FirstUseIdx + UseIdx];
214 }
215
216 /// getOperandLatency - Compute and return the use operand latency of a given
217 /// itinerary class and operand index if the value is produced by an
218 /// instruction of the specified itinerary class and def operand index.
219 int getOperandLatency(unsigned DefClass, unsigned DefIdx,
220 unsigned UseClass, unsigned UseIdx) const {
221 if (isEmpty())
222 return -1;
223
224 int DefCycle = getOperandCycle(DefClass, DefIdx);
225 if (DefCycle == -1)
226 return -1;
227
228 int UseCycle = getOperandCycle(UseClass, UseIdx);
229 if (UseCycle == -1)
230 return -1;
231
232 UseCycle = DefCycle - UseCycle + 1;
233 if (UseCycle > 0 &&
234 hasPipelineForwarding(DefClass, DefIdx, UseClass, UseIdx))
235 // FIXME: This assumes one cycle benefit for every pipeline forwarding.
236 --UseCycle;
237 return UseCycle;
238 }
239
240 /// isMicroCoded - Return true if the instructions in the given class decode
241 /// to more than one micro-ops.
242 bool isMicroCoded(unsigned ItinClassIndx) const {
243 if (isEmpty())
244 return false;
245 return Itineraries[ItinClassIndx].NumMicroOps != 1;
246 }
247 };
248
249
250 } // End llvm namespace
251
252 #endif
1313 #ifndef LLVM_TARGET_TARGETMACHINE_H
1414 #define LLVM_TARGET_TARGETMACHINE_H
1515
16 #include "llvm/Target/TargetInstrItineraries.h"
1716 #include
1817 #include
1918
2019 namespace llvm {
2120
21 class InstrItineraryData;
22 class JITCodeEmitter;
23 class MCAsmInfo;
24 class MCContext;
25 class Pass;
26 class PassManager;
27 class PassManagerBase;
2228 class Target;
23 class MCAsmInfo;
2429 class TargetData;
25 class TargetSubtarget;
30 class TargetELFWriterInfo;
31 class TargetFrameLowering;
2632 class TargetInstrInfo;
2733 class TargetIntrinsicInfo;
2834 class TargetJITInfo;
2935 class TargetLowering;
36 class TargetRegisterInfo;
3037 class TargetSelectionDAGInfo;
31 class TargetFrameLowering;
32 class JITCodeEmitter;
33 class MCContext;
34 class TargetRegisterInfo;
35 class PassManagerBase;
36 class PassManager;
37 class Pass;
38 class TargetELFWriterInfo;
38 class TargetSubtarget;
3939 class formatted_raw_ostream;
4040 class raw_ostream;
4141
1717 #include "llvm/CodeGen/MachineModuleInfo.h"
1818 #include "llvm/CodeGen/MachineFunctionPass.h"
1919 #include "llvm/CodeGen/MachineLoopInfo.h"
20 #include "llvm/MC/MCInstrItineraries.h"
2021 #include "llvm/Target/TargetInstrInfo.h"
21 #include "llvm/Target/TargetInstrItineraries.h"
2222 #include "llvm/Target/TargetLowering.h"
2323 #include "llvm/Target/TargetMachine.h"
2424 #include "llvm/Target/TargetRegisterInfo.h"
2727 #include "llvm/CodeGen/MachineMemOperand.h"
2828 #include "llvm/CodeGen/MachineRegisterInfo.h"
2929 #include "llvm/CodeGen/PseudoSourceValue.h"
30 #include "llvm/MC/MCInstrItineraries.h"
3031 #include "llvm/Target/TargetLowering.h"
3132 #include "llvm/Target/TargetRegisterInfo.h"
3233 #include "llvm/Target/TargetInstrInfo.h"
33 #include "llvm/Target/TargetInstrItineraries.h"
3434 #include "llvm/Target/TargetMachine.h"
3535 #include "llvm/Analysis/AliasAnalysis.h"
3636 #include "llvm/ADT/DenseMap.h"
2020 #include "llvm/CodeGen/MachineMemOperand.h"
2121 #include "llvm/CodeGen/MachineRegisterInfo.h"
2222 #include "llvm/CodeGen/PseudoSourceValue.h"
23 #include "llvm/MC/MCInstrItineraries.h"
2324 #include "llvm/Target/TargetMachine.h"
2425 #include "llvm/Target/TargetInstrInfo.h"
2526 #include "llvm/Target/TargetRegisterInfo.h"
1515 #define DEBUG_TYPE ::llvm::ScoreboardHazardRecognizer::DebugType
1616 #include "llvm/CodeGen/ScoreboardHazardRecognizer.h"
1717 #include "llvm/CodeGen/ScheduleDAG.h"
18 #include "llvm/MC/MCInstrItineraries.h"
1819 #include "llvm/Support/Debug.h"
1920 #include "llvm/Support/ErrorHandling.h"
2021 #include "llvm/Support/raw_ostream.h"
2122 #include "llvm/Target/TargetInstrInfo.h"
22 #include "llvm/Target/TargetInstrItineraries.h"
2323
2424 using namespace llvm;
2525
1616 #include "ScheduleDAGSDNodes.h"
1717 #include "InstrEmitter.h"
1818 #include "llvm/CodeGen/SelectionDAG.h"
19 #include "llvm/MC/MCInstrItineraries.h"
1920 #include "llvm/Target/TargetMachine.h"
2021 #include "llvm/Target/TargetInstrInfo.h"
2122 #include "llvm/Target/TargetLowering.h"
1515 #include "llvm/ExecutionEngine/ExecutionEngine.h"
1616 #include "llvm/Module.h"
1717 #include "llvm/ADT/Triple.h"
18 #include "llvm/MC/SubtargetFeature.h"
1819 #include "llvm/Support/CommandLine.h"
1920 #include "llvm/Support/raw_ostream.h"
2021 #include "llvm/Support/Host.h"
21 #include "llvm/Target/SubtargetFeature.h"
2222 #include "llvm/Target/TargetMachine.h"
2323 #include "llvm/Target/TargetRegistry.h"
2424 using namespace llvm;
0 //===- SubtargetFeature.cpp - CPU characteristics Implementation ----------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the SubtargetFeature interface.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "llvm/MC/SubtargetFeature.h"
14 #include "llvm/Support/Debug.h"
15 #include "llvm/Support/raw_ostream.h"
16 #include "llvm/ADT/StringExtras.h"
17 #include
18 #include
19 #include
20 #include
21 using namespace llvm;
22
23 //===----------------------------------------------------------------------===//
24 // Static Helper Functions
25 //===----------------------------------------------------------------------===//
26
27 /// hasFlag - Determine if a feature has a flag; '+' or '-'
28 ///
29 static inline bool hasFlag(const std::string &Feature) {
30 assert(!Feature.empty() && "Empty string");
31 // Get first character
32 char Ch = Feature[0];
33 // Check if first character is '+' or '-' flag
34 return Ch == '+' || Ch =='-';
35 }
36
37 /// StripFlag - Return string stripped of flag.
38 ///
39 static inline std::string StripFlag(const std::string &Feature) {
40 return hasFlag(Feature) ? Feature.substr(1) : Feature;
41 }
42
43 /// isEnabled - Return true if enable flag; '+'.
44 ///
45 static inline bool isEnabled(const std::string &Feature) {
46 assert(!Feature.empty() && "Empty string");
47 // Get first character
48 char Ch = Feature[0];
49 // Check if first character is '+' for enabled
50 return Ch == '+';
51 }
52
53 /// PrependFlag - Return a string with a prepended flag; '+' or '-'.
54 ///
55 static inline std::string PrependFlag(const std::string &Feature,
56 bool IsEnabled) {
57 assert(!Feature.empty() && "Empty string");
58 if (hasFlag(Feature)) return Feature;
59 return std::string(IsEnabled ? "+" : "-") + Feature;
60 }
61
62 /// Split - Splits a string of comma separated items in to a vector of strings.
63 ///
64 static void Split(std::vector &V, const std::string &S) {
65 // Start at beginning of string.
66 size_t Pos = 0;
67 while (true) {
68 // Find the next comma
69 size_t Comma = S.find(',', Pos);
70 // If no comma found then the rest of the string is used
71 if (Comma == std::string::npos) {
72 // Add string to vector
73 V.push_back(S.substr(Pos));
74 break;
75 }
76 // Otherwise add substring to vector
77 V.push_back(S.substr(Pos, Comma - Pos));
78 // Advance to next item
79 Pos = Comma + 1;
80 }
81 }
82
83 /// Join a vector of strings to a string with a comma separating each element.
84 ///
85 static std::string Join(const std::vector &V) {
86 // Start with empty string.
87 std::string Result;
88 // If the vector is not empty
89 if (!V.empty()) {
90 // Start with the CPU feature
91 Result = V[0];
92 // For each successive feature
93 for (size_t i = 1; i < V.size(); i++) {
94 // Add a comma
95 Result += ",";
96 // Add the feature
97 Result += V[i];
98 }
99 }
100 // Return the features string
101 return Result;
102 }
103
104 /// Adding features.
105 void SubtargetFeatures::AddFeature(const std::string &String,
106 bool IsEnabled) {
107 // Don't add empty features
108 if (!String.empty()) {
109 // Convert to lowercase, prepend flag and add to vector
110 Features.push_back(PrependFlag(LowercaseString(String), IsEnabled));
111 }
112 }
113
114 /// Find KV in array using binary search.
115 template const T *Find(const std::string &S, const T *A, size_t L) {
116 // Make the lower bound element we're looking for
117 T KV;
118 KV.Key = S.c_str();
119 // Determine the end of the array
120 const T *Hi = A + L;
121 // Binary search the array
122 const T *F = std::lower_bound(A, Hi, KV);
123 // If not found then return NULL
124 if (F == Hi || std::string(F->Key) != S) return NULL;
125 // Return the found array item
126 return F;
127 }
128
129 /// getLongestEntryLength - Return the length of the longest entry in the table.
130 ///
131 static size_t getLongestEntryLength(const SubtargetFeatureKV *Table,
132 size_t Size) {
133 size_t MaxLen = 0;
134 for (size_t i = 0; i < Size; i++)
135 MaxLen = std::max(MaxLen, std::strlen(Table[i].Key));
136 return MaxLen;
137 }
138
139 /// Display help for feature choices.
140 ///
141 static void Help(const SubtargetFeatureKV *CPUTable, size_t CPUTableSize,
142 const SubtargetFeatureKV *FeatTable, size_t FeatTableSize) {
143 // Determine the length of the longest CPU and Feature entries.
144 unsigned MaxCPULen = getLongestEntryLength(CPUTable, CPUTableSize);
145 unsigned MaxFeatLen = getLongestEntryLength(FeatTable, FeatTableSize);
146
147 // Print the CPU table.
148 errs() << "Available CPUs for this target:\n\n";
149 for (size_t i = 0; i != CPUTableSize; i++)
150 errs() << " " << CPUTable[i].Key
151 << std::string(MaxCPULen - std::strlen(CPUTable[i].Key), ' ')
152 << " - " << CPUTable[i].Desc << ".\n";
153 errs() << "\n";
154
155 // Print the Feature table.
156 errs() << "Available features for this target:\n\n";
157 for (size_t i = 0; i != FeatTableSize; i++)
158 errs() << " " << FeatTable[i].Key
159 << std::string(MaxFeatLen - std::strlen(FeatTable[i].Key), ' ')
160 << " - " << FeatTable[i].Desc << ".\n";
161 errs() << "\n";
162
163 errs() << "Use +feature to enable a feature, or -feature to disable it.\n"
164 << "For example, llc -mcpu=mycpu -mattr=+feature1,-feature2\n";
165 std::exit(1);
166 }
167
168 //===----------------------------------------------------------------------===//
169 // SubtargetFeatures Implementation
170 //===----------------------------------------------------------------------===//
171
172 SubtargetFeatures::SubtargetFeatures(const std::string &Initial) {
173 // Break up string into separate features
174 Split(Features, Initial);
175 }
176
177
178 std::string SubtargetFeatures::getString() const {
179 return Join(Features);
180 }
181 void SubtargetFeatures::setString(const std::string &Initial) {
182 // Throw out old features
183 Features.clear();
184 // Break up string into separate features
185 Split(Features, LowercaseString(Initial));
186 }
187
188
189 /// setCPU - Set the CPU string. Replaces previous setting. Setting to ""
190 /// clears CPU.
191 void SubtargetFeatures::setCPU(const std::string &String) {
192 Features[0] = LowercaseString(String);
193 }
194
195
196 /// setCPUIfNone - Setting CPU string only if no string is set.
197 ///
198 void SubtargetFeatures::setCPUIfNone(const std::string &String) {
199 if (Features[0].empty()) setCPU(String);
200 }
201
202 /// getCPU - Returns current CPU.
203 ///
204 const std::string & SubtargetFeatures::getCPU() const {
205 return Features[0];
206 }
207
208
209 /// SetImpliedBits - For each feature that is (transitively) implied by this
210 /// feature, set it.
211 ///
212 static
213 void SetImpliedBits(uint64_t &Bits, const SubtargetFeatureKV *FeatureEntry,
214 const SubtargetFeatureKV *FeatureTable,
215 size_t FeatureTableSize) {
216 for (size_t i = 0; i < FeatureTableSize; ++i) {
217 const SubtargetFeatureKV &FE = FeatureTable[i];
218
219 if (FeatureEntry->Value == FE.Value) continue;
220
221 if (FeatureEntry->Implies & FE.Value) {
222 Bits |= FE.Value;
223 SetImpliedBits(Bits, &FE, FeatureTable, FeatureTableSize);
224 }
225 }
226 }
227
228 /// ClearImpliedBits - For each feature that (transitively) implies this
229 /// feature, clear it.
230 ///
231 static
232 void ClearImpliedBits(uint64_t &Bits, const SubtargetFeatureKV *FeatureEntry,
233 const SubtargetFeatureKV *FeatureTable,
234 size_t FeatureTableSize) {
235 for (size_t i = 0; i < FeatureTableSize; ++i) {
236 const SubtargetFeatureKV &FE = FeatureTable[i];
237
238 if (FeatureEntry->Value == FE.Value) continue;
239
240 if (FE.Implies & FeatureEntry->Value) {
241 Bits &= ~FE.Value;
242 ClearImpliedBits(Bits, &FE, FeatureTable, FeatureTableSize);
243 }
244 }
245 }
246
247 /// getBits - Get feature bits.
248 ///
249 uint64_t SubtargetFeatures::getBits(const SubtargetFeatureKV *CPUTable,
250 size_t CPUTableSize,
251 const SubtargetFeatureKV *FeatureTable,
252 size_t FeatureTableSize) {
253 assert(CPUTable && "missing CPU table");
254 assert(FeatureTable && "missing features table");
255 #ifndef NDEBUG
256 for (size_t i = 1; i < CPUTableSize; i++) {
257 assert(strcmp(CPUTable[i - 1].Key, CPUTable[i].Key) < 0 &&
258 "CPU table is not sorted");
259 }
260 for (size_t i = 1; i < FeatureTableSize; i++) {
261 assert(strcmp(FeatureTable[i - 1].Key, FeatureTable[i].Key) < 0 &&
262 "CPU features table is not sorted");
263 }
264 #endif
265 uint64_t Bits = 0; // Resulting bits
266
267 // Check if help is needed
268 if (Features[0] == "help")
269 Help(CPUTable, CPUTableSize, FeatureTable, FeatureTableSize);
270
271 // Find CPU entry
272 const SubtargetFeatureKV *CPUEntry =
273 Find(Features[0], CPUTable, CPUTableSize);
274 // If there is a match
275 if (CPUEntry) {
276 // Set base feature bits
277 Bits = CPUEntry->Value;
278
279 // Set the feature implied by this CPU feature, if any.
280 for (size_t i = 0; i < FeatureTableSize; ++i) {
281 const SubtargetFeatureKV &FE = FeatureTable[i];
282 if (CPUEntry->Value & FE.Value)
283 SetImpliedBits(Bits, &FE, FeatureTable, FeatureTableSize);
284 }
285 } else {
286 errs() << "'" << Features[0]
287 << "' is not a recognized processor for this target"
288 << " (ignoring processor)\n";
289 }
290 // Iterate through each feature
291 for (size_t i = 1; i < Features.size(); i++) {
292 const std::string &Feature = Features[i];
293
294 // Check for help
295 if (Feature == "+help")
296 Help(CPUTable, CPUTableSize, FeatureTable, FeatureTableSize);
297
298 // Find feature in table.
299 const SubtargetFeatureKV *FeatureEntry =
300 Find(StripFlag(Feature), FeatureTable, FeatureTableSize);
301 // If there is a match
302 if (FeatureEntry) {
303 // Enable/disable feature in bits
304 if (isEnabled(Feature)) {
305 Bits |= FeatureEntry->Value;
306
307 // For each feature that this implies, set it.
308 SetImpliedBits(Bits, FeatureEntry, FeatureTable, FeatureTableSize);
309 } else {
310 Bits &= ~FeatureEntry->Value;
311
312 // For each feature that implies this, clear it.
313 ClearImpliedBits(Bits, FeatureEntry, FeatureTable, FeatureTableSize);
314 }
315 } else {
316 errs() << "'" << Feature
317 << "' is not a recognized feature for this target"
318 << " (ignoring feature)\n";
319 }
320 }
321
322 return Bits;
323 }
324
325 /// Get info pointer
326 void *SubtargetFeatures::getInfo(const SubtargetInfoKV *Table,
327 size_t TableSize) {
328 assert(Table && "missing table");
329 #ifndef NDEBUG
330 for (size_t i = 1; i < TableSize; i++) {
331 assert(strcmp(Table[i - 1].Key, Table[i].Key) < 0 && "Table is not sorted");
332 }
333 #endif
334
335 // Find entry
336 const SubtargetInfoKV *Entry = Find(Features[0], Table, TableSize);
337
338 if (Entry) {
339 return Entry->Value;
340 } else {
341 errs() << "'" << Features[0]
342 << "' is not a recognized processor for this target"
343 << " (ignoring processor)\n";
344 return NULL;
345 }
346 }
347
348 /// print - Print feature string.
349 ///
350 void SubtargetFeatures::print(raw_ostream &OS) const {
351 for (size_t i = 0, e = Features.size(); i != e; ++i)
352 OS << Features[i] << " ";
353 OS << "\n";
354 }
355
356 /// dump - Dump feature info.
357 ///
358 void SubtargetFeatures::dump() const {
359 print(dbgs());
360 }
361
362 /// getDefaultSubtargetFeatures - Return a string listing the features
363 /// associated with the target triple.
364 ///
365 /// FIXME: This is an inelegant way of specifying the features of a
366 /// subtarget. It would be better if we could encode this information
367 /// into the IR. See .
368 ///
369 void SubtargetFeatures::getDefaultSubtargetFeatures(const std::string &CPU,
370 const Triple& Triple) {
371 setCPU(CPU);
372
373 if (Triple.getVendor() == Triple::Apple) {
374 if (Triple.getArch() == Triple::ppc) {
375 // powerpc-apple-*
376 AddFeature("altivec");
377 } else if (Triple.getArch() == Triple::ppc64) {
378 // powerpc64-apple-*
379 AddFeature("64bit");
380 AddFeature("altivec");
381 }
382 }
383 }
1313 #ifndef ARMSUBTARGET_H
1414 #define ARMSUBTARGET_H
1515
16 #include "llvm/Target/TargetInstrItineraries.h"
17 #include "llvm/Target/TargetMachine.h"
1816 #include "llvm/Target/TargetSubtarget.h"
17 #include "llvm/MC/MCInstrItineraries.h"
1918 #include "llvm/ADT/Triple.h"
2019 #include
2120
1313 #ifndef ALPHASUBTARGET_H
1414 #define ALPHASUBTARGET_H
1515
16 #include "llvm/Target/TargetInstrItineraries.h"
1716 #include "llvm/Target/TargetSubtarget.h"
18
17 #include "llvm/MC/MCInstrItineraries.h"
1918 #include
2019
2120 namespace llvm {
1313 #ifndef CELLSUBTARGET_H
1414 #define CELLSUBTARGET_H
1515
16 #include "llvm/Target/TargetInstrItineraries.h"
1716 #include "llvm/Target/TargetSubtarget.h"
18
17 #include "llvm/MC/MCInstrItineraries.h"
1918 #include
2019
2120 namespace llvm {
1414 #define MBLAZESUBTARGET_H
1515
1616 #include "llvm/Target/TargetSubtarget.h"
17 #include "llvm/Target/TargetMachine.h"
18
17 #include "llvm/MC/MCInstrItineraries.h"
1918 #include
2019
2120 namespace llvm {
1414 #define MIPSSUBTARGET_H
1515
1616 #include "llvm/Target/TargetSubtarget.h"
17 #include "llvm/Target/TargetMachine.h"
18
17 #include "llvm/MC/MCInstrItineraries.h"
1918 #include
2019
2120 namespace llvm {
1313 #ifndef POWERPCSUBTARGET_H
1414 #define POWERPCSUBTARGET_H
1515
16 #include "llvm/Target/TargetSubtarget.h"
17 #include "llvm/MC/MCInstrItineraries.h"
1618 #include "llvm/ADT/Triple.h"
17 #include "llvm/Target/TargetInstrItineraries.h"
18 #include "llvm/Target/TargetSubtarget.h"
19
2019 #include
2120
2221 // GCC #defines PPC on Linux but we use it as our namespace name
+0
-384
lib/Target/SubtargetFeature.cpp less more
None //===- SubtargetFeature.cpp - CPU characteristics Implementation ----------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the SubtargetFeature interface.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #include "llvm/Target/SubtargetFeature.h"
14 #include "llvm/Support/Debug.h"
15 #include "llvm/Support/raw_ostream.h"
16 #include "llvm/ADT/StringExtras.h"
17 #include
18 #include
19 #include
20 #include
21 using namespace llvm;
22
23 //===----------------------------------------------------------------------===//
24 // Static Helper Functions
25 //===----------------------------------------------------------------------===//
26
27 /// hasFlag - Determine if a feature has a flag; '+' or '-'
28 ///
29 static inline bool hasFlag(const std::string &Feature) {
30 assert(!Feature.empty() && "Empty string");
31 // Get first character
32 char Ch = Feature[0];
33 // Check if first character is '+' or '-' flag
34 return Ch == '+' || Ch =='-';
35 }
36
37 /// StripFlag - Return string stripped of flag.
38 ///
39 static inline std::string StripFlag(const std::string &Feature) {
40 return hasFlag(Feature) ? Feature.substr(1) : Feature;
41 }
42
43 /// isEnabled - Return true if enable flag; '+'.
44 ///
45 static inline bool isEnabled(const std::string &Feature) {
46 assert(!Feature.empty() && "Empty string");
47 // Get first character
48 char Ch = Feature[0];
49 // Check if first character is '+' for enabled
50 return Ch == '+';
51 }
52
53 /// PrependFlag - Return a string with a prepended flag; '+' or '-'.
54 ///
55 static inline std::string PrependFlag(const std::string &Feature,
56 bool IsEnabled) {
57 assert(!Feature.empty() && "Empty string");
58 if (hasFlag(Feature)) return Feature;
59 return std::string(IsEnabled ? "+" : "-") + Feature;
60 }
61
62 /// Split - Splits a string of comma separated items in to a vector of strings.
63 ///
64 static void Split(std::vector &V, const std::string &S) {
65 // Start at beginning of string.
66 size_t Pos = 0;
67 while (true) {
68 // Find the next comma
69 size_t Comma = S.find(',', Pos);
70 // If no comma found then the rest of the string is used
71 if (Comma == std::string::npos) {
72 // Add string to vector
73 V.push_back(S.substr(Pos));
74 break;
75 }
76 // Otherwise add substring to vector
77 V.push_back(S.substr(Pos, Comma - Pos));
78 // Advance to next item
79 Pos = Comma + 1;
80 }
81 }
82
83 /// Join a vector of strings to a string with a comma separating each element.
84 ///
85 static std::string Join(const std::vector &V) {
86 // Start with empty string.
87 std::string Result;
88 // If the vector is not empty
89 if (!V.empty()) {
90 // Start with the CPU feature
91 Result = V[0];
92 // For each successive feature
93 for (size_t i = 1; i < V.size(); i++) {
94 // Add a comma
95 Result += ",";
96 // Add the feature
97 Result += V[i];
98 }
99 }
100 // Return the features string
101 return Result;
102 }
103
104 /// Adding features.
105 void SubtargetFeatures::AddFeature(const std::string &String,
106 bool IsEnabled) {
107 // Don't add empty features
108 if (!String.empty()) {
109 // Convert to lowercase, prepend flag and add to vector
110 Features.push_back(PrependFlag(LowercaseString(String), IsEnabled));
111 }
112 }
113
114 /// Find KV in array using binary search.
115 template const T *Find(const std::string &S, const T *A, size_t L) {
116 // Make the lower bound element we're looking for
117 T KV;
118 KV.Key = S.c_str();
119 // Determine the end of the array
120 const T *Hi = A + L;
121 // Binary search the array
122 const T *F = std::lower_bound(A, Hi, KV);
123 // If not found then return NULL
124 if (F == Hi || std::string(F->Key) != S) return NULL;
125 // Return the found array item
126 return F;
127 }
128
129 /// getLongestEntryLength - Return the length of the longest entry in the table.
130 ///
131 static size_t getLongestEntryLength(const SubtargetFeatureKV *Table,
132 size_t Size) {
133 size_t MaxLen = 0;
134 for (size_t i = 0; i < Size; i++)
135 MaxLen = std::max(MaxLen, std::strlen(Table[i].Key));
136 return MaxLen;
137 }
138
139 /// Display help for feature choices.
140 ///
141 static void Help(const SubtargetFeatureKV *CPUTable, size_t CPUTableSize,
142 const SubtargetFeatureKV *FeatTable, size_t FeatTableSize) {
143 // Determine the length of the longest CPU and Feature entries.
144 unsigned MaxCPULen = getLongestEntryLength(CPUTable, CPUTableSize);
145 unsigned MaxFeatLen = getLongestEntryLength(FeatTable, FeatTableSize);
146
147 // Print the CPU table.
148 errs() << "Available CPUs for this target:\n\n";
149 for (size_t i = 0; i != CPUTableSize; i++)
150 errs() << " " << CPUTable[i].Key
151 << std::string(MaxCPULen - std::strlen(CPUTable[i].Key), ' ')
152 << " - " << CPUTable[i].Desc << ".\n";
153 errs() << "\n";
154
155 // Print the Feature table.
156 errs() << "Available features for this target:\n\n";
157 for (size_t i = 0; i != FeatTableSize; i++)
158 errs() << " " << FeatTable[i].Key
159 << std::string(MaxFeatLen - std::strlen(FeatTable[i].Key), ' ')
160 << " - " << FeatTable[i].Desc << ".\n";
161 errs() << "\n";
162
163 errs() << "Use +feature to enable a feature, or -feature to disable it.\n"
164 << "For example, llc -mcpu=mycpu -mattr=+feature1,-feature2\n";
165 std::exit(1);
166 }
167
168 //===----------------------------------------------------------------------===//
169 // SubtargetFeatures Implementation
170 //===----------------------------------------------------------------------===//
171
172 SubtargetFeatures::SubtargetFeatures(const std::string &Initial) {
173 // Break up string into separate features
174 Split(Features, Initial);
175 }
176
177
178 std::string SubtargetFeatures::getString() const {
179 return Join(Features);
180 }
181 void SubtargetFeatures::setString(const std::string &Initial) {
182 // Throw out old features
183 Features.clear();
184 // Break up string into separate features
185 Split(Features, LowercaseString(Initial));
186 }
187
188
189 /// setCPU - Set the CPU string. Replaces previous setting. Setting to ""
190 /// clears CPU.
191 void SubtargetFeatures::setCPU(const std::string &String) {
192 Features[0] = LowercaseString(String);
193 }
194
195
196 /// setCPUIfNone - Setting CPU string only if no string is set.
197 ///
198 void SubtargetFeatures::setCPUIfNone(const std::string &String) {
199 if (Features[0].empty()) setCPU(String);
200 }
201
202 /// getCPU - Returns current CPU.
203 ///
204 const std::string & SubtargetFeatures::getCPU() const {
205 return Features[0];
206 }
207
208
209 /// SetImpliedBits - For each feature that is (transitively) implied by this
210 /// feature, set it.
211 ///
212 static
213 void SetImpliedBits(uint64_t &Bits, const SubtargetFeatureKV *FeatureEntry,
214 const SubtargetFeatureKV *FeatureTable,
215 size_t FeatureTableSize) {
216 for (size_t i = 0; i < FeatureTableSize; ++i) {
217 const SubtargetFeatureKV &FE = FeatureTable[i];
218
219 if (FeatureEntry->Value == FE.Value) continue;
220
221 if (FeatureEntry->Implies & FE.Value) {
222 Bits |= FE.Value;
223 SetImpliedBits(Bits, &FE, FeatureTable, FeatureTableSize);
224 }
225 }
226 }
227
228 /// ClearImpliedBits - For each feature that (transitively) implies this
229 /// feature, clear it.
230 ///
231 static
232 void ClearImpliedBits(uint64_t &Bits, const SubtargetFeatureKV *FeatureEntry,
233 const SubtargetFeatureKV *FeatureTable,
234 size_t FeatureTableSize) {
235 for (size_t i = 0; i < FeatureTableSize; ++i) {
236 const SubtargetFeatureKV &FE = FeatureTable[i];
237
238 if (FeatureEntry->Value == FE.Value) continue;
239
240 if (FE.Implies & FeatureEntry->Value) {
241 Bits &= ~FE.Value;
242 ClearImpliedBits(Bits, &FE, FeatureTable, FeatureTableSize);
243 }
244 }
245 }
246
247 /// getBits - Get feature bits.
248 ///
249 uint64_t SubtargetFeatures::getBits(const SubtargetFeatureKV *CPUTable,
250 size_t CPUTableSize,
251 const SubtargetFeatureKV *FeatureTable,
252 size_t FeatureTableSize) {
253 assert(CPUTable && "missing CPU table");
254 assert(FeatureTable && "missing features table");
255 #ifndef NDEBUG
256 for (size_t i = 1; i < CPUTableSize; i++) {
257 assert(strcmp(CPUTable[i - 1].Key, CPUTable[i].Key) < 0 &&
258 "CPU table is not sorted");
259 }
260 for (size_t i = 1; i < FeatureTableSize; i++) {
261 assert(strcmp(FeatureTable[i - 1].Key, FeatureTable[i].Key) < 0 &&
262 "CPU features table is not sorted");
263 }
264 #endif
265 uint64_t Bits = 0; // Resulting bits
266
267 // Check if help is needed
268 if (Features[0] == "help")
269 Help(CPUTable, CPUTableSize, FeatureTable, FeatureTableSize);
270
271 // Find CPU entry
272 const SubtargetFeatureKV *CPUEntry =
273 Find(Features[0], CPUTable, CPUTableSize);
274 // If there is a match
275 if (CPUEntry) {
276 // Set base feature bits
277 Bits = CPUEntry->Value;
278
279 // Set the feature implied by this CPU feature, if any.
280 for (size_t i = 0; i < FeatureTableSize; ++i) {
281 const SubtargetFeatureKV &FE = FeatureTable[i];
282 if (CPUEntry->Value & FE.Value)
283 SetImpliedBits(Bits, &FE, FeatureTable, FeatureTableSize);
284 }
285 } else {
286 errs() << "'" << Features[0]
287 << "' is not a recognized processor for this target"
288 << " (ignoring processor)\n";
289 }
290 // Iterate through each feature
291 for (size_t i = 1; i < Features.size(); i++) {
292 const std::string &Feature = Features[i];
293
294 // Check for help
295 if (Feature == "+help")
296 Help(CPUTable, CPUTableSize, FeatureTable, FeatureTableSize);
297
298 // Find feature in table.
299 const SubtargetFeatureKV *FeatureEntry =
300 Find(StripFlag(Feature), FeatureTable, FeatureTableSize);
301 // If there is a match
302 if (FeatureEntry) {
303 // Enable/disable feature in bits
304 if (isEnabled(Feature)) {
305 Bits |= FeatureEntry->Value;
306
307 // For each feature that this implies, set it.
308 SetImpliedBits(Bits, FeatureEntry, FeatureTable, FeatureTableSize);
309 } else {
310 Bits &= ~FeatureEntry->Value;
311
312 // For each feature that implies this, clear it.
313 ClearImpliedBits(Bits, FeatureEntry, FeatureTable, FeatureTableSize);
314 }
315 } else {
316 errs() << "'" << Feature
317 << "' is not a recognized feature for this target"
318 << " (ignoring feature)\n";
319 }
320 }
321
322 return Bits;
323 }
324
325 /// Get info pointer
326 void *SubtargetFeatures::getInfo(const SubtargetInfoKV *Table,
327 size_t TableSize) {
328 assert(Table && "missing table");
329 #ifndef NDEBUG
330 for (size_t i = 1; i < TableSize; i++) {
331 assert(strcmp(Table[i - 1].Key, Table[i].Key) < 0 && "Table is not sorted");
332 }
333 #endif
334
335 // Find entry
336 const SubtargetInfoKV *Entry = Find(Features[0], Table, TableSize);
337
338 if (Entry) {
339 return Entry->Value;
340 } else {
341 errs() << "'" << Features[0]
342 << "' is not a recognized processor for this target"
343 << " (ignoring processor)\n";
344 return NULL;
345 }
346 }
347
348 /// print - Print feature string.
349 ///
350 void SubtargetFeatures::print(raw_ostream &OS) const {
351 for (size_t i = 0, e = Features.size(); i != e; ++i)
352 OS << Features[i] << " ";
353 OS << "\n";
354 }
355
356 /// dump - Dump feature info.
357 ///
358 void SubtargetFeatures::dump() const {
359 print(dbgs());
360 }
361
362 /// getDefaultSubtargetFeatures - Return a string listing the features
363 /// associated with the target triple.
364 ///
365 /// FIXME: This is an inelegant way of specifying the features of a
366 /// subtarget. It would be better if we could encode this information
367 /// into the IR. See .
368 ///
369 void SubtargetFeatures::getDefaultSubtargetFeatures(const std::string &CPU,
370 const Triple& Triple) {
371 setCPU(CPU);
372
373 if (Triple.getVendor() == Triple::Apple) {
374 if (Triple.getArch() == Triple::ppc) {
375 // powerpc-apple-*
376 AddFeature("altivec");
377 } else if (Triple.getArch() == Triple::ppc64) {
378 // powerpc64-apple-*
379 AddFeature("64bit");
380 AddFeature("altivec");
381 }
382 }
383 }
1111 //===----------------------------------------------------------------------===//
1212
1313 #include "llvm/Target/TargetInstrInfo.h"
14 #include "llvm/Target/TargetInstrItineraries.h"
1514 #include "llvm/Target/TargetRegisterInfo.h"
1615 #include "llvm/CodeGen/SelectionDAGNodes.h"
1716 #include "llvm/MC/MCAsmInfo.h"
17 #include "llvm/MC/MCInstrItineraries.h"
1818 #include "llvm/Support/ErrorHandling.h"
1919 #include
2020 using namespace llvm;
2121 #include "llvm/CodeGen/LinkAllAsmWriterComponents.h"
2222 #include "llvm/CodeGen/LinkAllCodegenComponents.h"
2323 #include "llvm/Config/config.h"
24 #include "llvm/MC/SubtargetFeature.h"
2425 #include "llvm/Support/CommandLine.h"
2526 #include "llvm/Support/Debug.h"
2627 #include "llvm/Support/FormattedStream.h"
3031 #include "llvm/Support/ToolOutputFile.h"
3132 #include "llvm/Support/Host.h"
3233 #include "llvm/Support/Signals.h"
33 #include "llvm/Target/SubtargetFeature.h"
3434 #include "llvm/Target/TargetData.h"
3535 #include "llvm/Target/TargetMachine.h"
3636 #include "llvm/Target/TargetRegistry.h"
1818 #include "llvm/MC/MCInstPrinter.h"
1919 #include "llvm/MC/MCSectionMachO.h"
2020 #include "llvm/MC/MCStreamer.h"
21 #include "llvm/MC/SubtargetFeature.h"
2122 #include "llvm/Target/TargetAsmBackend.h"
2223 #include "llvm/Target/TargetAsmParser.h"
2324 #include "llvm/Target/TargetData.h"
2425 #include "llvm/Target/TargetRegistry.h"
25 #include "llvm/Target/SubtargetFeature.h" // FIXME.
2626 #include "llvm/Target/TargetAsmInfo.h" // FIXME.
2727 #include "llvm/Target/TargetLowering.h" // FIXME.
2828 #include "llvm/Target/TargetLoweringObjectFile.h" // FIXME.
2525 #include "llvm/Bitcode/ReaderWriter.h"
2626 #include "llvm/MC/MCAsmInfo.h"
2727 #include "llvm/MC/MCContext.h"
28 #include "llvm/MC/SubtargetFeature.h"
2829 #include "llvm/Target/Mangler.h"
29 #include "llvm/Target/SubtargetFeature.h"
3030 #include "llvm/Target/TargetOptions.h"
3131 #include "llvm/Target/TargetData.h"
3232 #include "llvm/Target/TargetMachine.h"
2828 #include "llvm/Support/SourceMgr.h"
2929 #include "llvm/Support/system_error.h"
3030 #include "llvm/Target/Mangler.h"
31 #include "llvm/Target/SubtargetFeature.h"
3231 #include "llvm/MC/MCAsmInfo.h"
3332 #include "llvm/MC/MCContext.h"
3433 #include "llvm/MC/MCExpr.h"
3635 #include "llvm/MC/MCParser/MCAsmParser.h"
3736 #include "llvm/MC/MCStreamer.h"
3837 #include "llvm/MC/MCSymbol.h"
38 #include "llvm/MC/SubtargetFeature.h"
3939 #include "llvm/Target/TargetAsmParser.h"
4040 #include "llvm/Target/TargetMachine.h"
4141 #include "llvm/Target/TargetRegistry.h"
653653
654654 OS << "#include \"llvm/Support/Debug.h\"\n";
655655 OS << "#include \"llvm/Support/raw_ostream.h\"\n";
656 OS << "#include \"llvm/Target/SubtargetFeature.h\"\n";
657 OS << "#include \"llvm/Target/TargetInstrItineraries.h\"\n\n";
656 OS << "#include \"llvm/MC/SubtargetFeature.h\"\n";
657 OS << "#include \"llvm/MC/MCInstrItineraries.h\"\n\n";
658658
659659 // Enumeration(OS, "FuncUnit", true);
660660 // OS<<"\n";
1414 #define SUBTARGET_EMITTER_H
1515
1616 #include "TableGenBackend.h"
17 #include "llvm/Target/TargetInstrItineraries.h"
17 #include "llvm/MC/MCInstrItineraries.h"
1818 #include
1919 #include
2020 #include