Line data Source code
1 : // Copyright 2015 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #include "src/compiler/instruction-scheduler.h"
6 :
7 : namespace v8 {
8 : namespace internal {
9 : namespace compiler {
10 :
11 0 : bool InstructionScheduler::SchedulerSupported() { return true; }
12 :
13 :
14 0 : int InstructionScheduler::GetTargetInstructionFlags(
15 : const Instruction* instr) const {
16 0 : switch (instr->arch_opcode()) {
17 : case kX64Add:
18 : case kX64Add32:
19 : case kX64And:
20 : case kX64And32:
21 : case kX64Cmp:
22 : case kX64Cmp32:
23 : case kX64Cmp16:
24 : case kX64Cmp8:
25 : case kX64Test:
26 : case kX64Test32:
27 : case kX64Test16:
28 : case kX64Test8:
29 : case kX64Or:
30 : case kX64Or32:
31 : case kX64Xor:
32 : case kX64Xor32:
33 : case kX64Sub:
34 : case kX64Sub32:
35 : case kX64Imul:
36 : case kX64Imul32:
37 : case kX64ImulHigh32:
38 : case kX64UmulHigh32:
39 : case kX64Not:
40 : case kX64Not32:
41 : case kX64Neg:
42 : case kX64Neg32:
43 : case kX64Shl:
44 : case kX64Shl32:
45 : case kX64Shr:
46 : case kX64Shr32:
47 : case kX64Sar:
48 : case kX64Sar32:
49 : case kX64Ror:
50 : case kX64Ror32:
51 : case kX64Lzcnt:
52 : case kX64Lzcnt32:
53 : case kX64Tzcnt:
54 : case kX64Tzcnt32:
55 : case kX64Popcnt:
56 : case kX64Popcnt32:
57 : case kSSEFloat32Cmp:
58 : case kSSEFloat32Add:
59 : case kSSEFloat32Sub:
60 : case kSSEFloat32Mul:
61 : case kSSEFloat32Div:
62 : case kSSEFloat32Abs:
63 : case kSSEFloat32Neg:
64 : case kSSEFloat32Sqrt:
65 : case kSSEFloat32Round:
66 : case kSSEFloat32ToFloat64:
67 : case kSSEFloat64Cmp:
68 : case kSSEFloat64Add:
69 : case kSSEFloat64Sub:
70 : case kSSEFloat64Mul:
71 : case kSSEFloat64Div:
72 : case kSSEFloat64Mod:
73 : case kSSEFloat64Abs:
74 : case kSSEFloat64Neg:
75 : case kSSEFloat64Sqrt:
76 : case kSSEFloat64Round:
77 : case kSSEFloat32Max:
78 : case kSSEFloat64Max:
79 : case kSSEFloat32Min:
80 : case kSSEFloat64Min:
81 : case kSSEFloat64ToFloat32:
82 : case kSSEFloat32ToInt32:
83 : case kSSEFloat32ToUint32:
84 : case kSSEFloat64ToInt32:
85 : case kSSEFloat64ToUint32:
86 : case kSSEFloat64ToInt64:
87 : case kSSEFloat32ToInt64:
88 : case kSSEFloat64ToUint64:
89 : case kSSEFloat32ToUint64:
90 : case kSSEInt32ToFloat64:
91 : case kSSEInt32ToFloat32:
92 : case kSSEInt64ToFloat32:
93 : case kSSEInt64ToFloat64:
94 : case kSSEUint64ToFloat32:
95 : case kSSEUint64ToFloat64:
96 : case kSSEUint32ToFloat64:
97 : case kSSEUint32ToFloat32:
98 : case kSSEFloat64ExtractLowWord32:
99 : case kSSEFloat64ExtractHighWord32:
100 : case kSSEFloat64InsertLowWord32:
101 : case kSSEFloat64InsertHighWord32:
102 : case kSSEFloat64LoadLowWord32:
103 : case kSSEFloat64SilenceNaN:
104 : case kAVXFloat32Cmp:
105 : case kAVXFloat32Add:
106 : case kAVXFloat32Sub:
107 : case kAVXFloat32Mul:
108 : case kAVXFloat32Div:
109 : case kAVXFloat64Cmp:
110 : case kAVXFloat64Add:
111 : case kAVXFloat64Sub:
112 : case kAVXFloat64Mul:
113 : case kAVXFloat64Div:
114 : case kAVXFloat64Abs:
115 : case kAVXFloat64Neg:
116 : case kAVXFloat32Abs:
117 : case kAVXFloat32Neg:
118 : case kX64BitcastFI:
119 : case kX64BitcastDL:
120 : case kX64BitcastIF:
121 : case kX64BitcastLD:
122 : case kX64Lea32:
123 : case kX64Lea:
124 : case kX64Dec32:
125 : case kX64Inc32:
126 : case kX64I32x4Splat:
127 : case kX64I32x4ExtractLane:
128 : case kX64I32x4ReplaceLane:
129 : case kX64I32x4Shl:
130 : case kX64I32x4ShrS:
131 : case kX64I32x4Add:
132 : case kX64I32x4Sub:
133 : case kX64I32x4Mul:
134 : case kX64I32x4MinS:
135 : case kX64I32x4MaxS:
136 : case kX64I32x4Eq:
137 : case kX64I32x4Ne:
138 : case kX64I32x4ShrU:
139 : case kX64I32x4MinU:
140 : case kX64I32x4MaxU:
141 : case kX64I16x8Splat:
142 : case kX64I16x8ExtractLane:
143 : case kX64I16x8ReplaceLane:
144 : case kX64I16x8Shl:
145 : case kX64I16x8ShrS:
146 : case kX64I16x8Add:
147 : case kX64I16x8AddSaturateS:
148 : case kX64I16x8Sub:
149 : case kX64I16x8SubSaturateS:
150 : case kX64I16x8Mul:
151 : case kX64I16x8MinS:
152 : case kX64I16x8MaxS:
153 : case kX64I16x8Eq:
154 : case kX64I16x8Ne:
155 : case kX64I16x8ShrU:
156 : case kX64I16x8AddSaturateU:
157 : case kX64I16x8SubSaturateU:
158 : case kX64I16x8MinU:
159 : case kX64I16x8MaxU:
160 : case kX64I8x16Splat:
161 : case kX64I8x16ExtractLane:
162 : case kX64I8x16ReplaceLane:
163 : case kX64I8x16Add:
164 : case kX64I8x16AddSaturateS:
165 : case kX64I8x16Sub:
166 : case kX64I8x16SubSaturateS:
167 : case kX64I8x16MinS:
168 : case kX64I8x16MaxS:
169 : case kX64I8x16Eq:
170 : case kX64I8x16Ne:
171 : case kX64I8x16AddSaturateU:
172 : case kX64I8x16SubSaturateU:
173 : case kX64I8x16MinU:
174 : case kX64I8x16MaxU:
175 : case kX64S128Select:
176 : case kX64S128Zero:
177 : return (instr->addressing_mode() == kMode_None)
178 : ? kNoOpcodeFlags
179 0 : : kIsLoadOperation | kHasSideEffect;
180 :
181 : case kX64Idiv:
182 : case kX64Idiv32:
183 : case kX64Udiv:
184 : case kX64Udiv32:
185 : return (instr->addressing_mode() == kMode_None)
186 : ? kMayNeedDeoptCheck
187 0 : : kMayNeedDeoptCheck | kIsLoadOperation | kHasSideEffect;
188 :
189 : case kX64Movsxbl:
190 : case kX64Movzxbl:
191 : case kX64Movsxbq:
192 : case kX64Movzxbq:
193 : case kX64Movsxwl:
194 : case kX64Movzxwl:
195 : case kX64Movsxwq:
196 : case kX64Movzxwq:
197 : case kX64Movsxlq:
198 : DCHECK(instr->InputCount() >= 1);
199 0 : return instr->InputAt(0)->IsRegister() ? kNoOpcodeFlags
200 0 : : kIsLoadOperation;
201 :
202 : case kX64Movb:
203 : case kX64Movw:
204 : return kHasSideEffect;
205 :
206 : case kX64Movl:
207 0 : if (instr->HasOutput()) {
208 : DCHECK(instr->InputCount() >= 1);
209 0 : return instr->InputAt(0)->IsRegister() ? kNoOpcodeFlags
210 0 : : kIsLoadOperation;
211 : } else {
212 : return kHasSideEffect;
213 : }
214 :
215 : case kX64Movq:
216 : case kX64Movsd:
217 : case kX64Movss:
218 0 : return instr->HasOutput() ? kIsLoadOperation : kHasSideEffect;
219 :
220 : case kX64StackCheck:
221 0 : return kIsLoadOperation;
222 :
223 : case kX64Push:
224 : case kX64Poke:
225 : return kHasSideEffect;
226 :
227 : #define CASE(Name) case k##Name:
228 : COMMON_ARCH_OPCODE_LIST(CASE)
229 : #undef CASE
230 : // Already covered in architecture independent code.
231 0 : UNREACHABLE();
232 : }
233 :
234 0 : UNREACHABLE();
235 : return kNoOpcodeFlags;
236 : }
237 :
238 :
239 0 : int InstructionScheduler::GetInstructionLatency(const Instruction* instr) {
240 : // Basic latency modeling for x64 instructions. They have been determined
241 : // in an empirical way.
242 0 : switch (instr->arch_opcode()) {
243 : case kCheckedLoadInt8:
244 : case kCheckedLoadUint8:
245 : case kCheckedLoadInt16:
246 : case kCheckedLoadUint16:
247 : case kCheckedLoadWord32:
248 : case kCheckedLoadWord64:
249 : case kCheckedLoadFloat32:
250 : case kCheckedLoadFloat64:
251 : case kCheckedStoreWord8:
252 : case kCheckedStoreWord16:
253 : case kCheckedStoreWord32:
254 : case kCheckedStoreWord64:
255 : case kCheckedStoreFloat32:
256 : case kCheckedStoreFloat64:
257 : case kSSEFloat64Mul:
258 : return 5;
259 : case kX64Imul:
260 : case kX64Imul32:
261 : case kX64ImulHigh32:
262 : case kX64UmulHigh32:
263 : case kSSEFloat32Cmp:
264 : case kSSEFloat32Add:
265 : case kSSEFloat32Sub:
266 : case kSSEFloat32Abs:
267 : case kSSEFloat32Neg:
268 : case kSSEFloat64Cmp:
269 : case kSSEFloat64Add:
270 : case kSSEFloat64Sub:
271 : case kSSEFloat64Max:
272 : case kSSEFloat64Min:
273 : case kSSEFloat64Abs:
274 : case kSSEFloat64Neg:
275 : return 3;
276 : case kSSEFloat32Mul:
277 : case kSSEFloat32ToFloat64:
278 : case kSSEFloat64ToFloat32:
279 : case kSSEFloat32Round:
280 : case kSSEFloat64Round:
281 : case kSSEFloat32ToInt32:
282 : case kSSEFloat32ToUint32:
283 : case kSSEFloat64ToInt32:
284 : case kSSEFloat64ToUint32:
285 : return 4;
286 : case kX64Idiv:
287 : return 49;
288 : case kX64Idiv32:
289 : return 35;
290 : case kX64Udiv:
291 : return 38;
292 : case kX64Udiv32:
293 : return 26;
294 : case kSSEFloat32Div:
295 : case kSSEFloat64Div:
296 : case kSSEFloat32Sqrt:
297 : case kSSEFloat64Sqrt:
298 : return 13;
299 : case kSSEFloat32ToInt64:
300 : case kSSEFloat64ToInt64:
301 : case kSSEFloat32ToUint64:
302 : case kSSEFloat64ToUint64:
303 : return 10;
304 : case kSSEFloat64Mod:
305 : return 50;
306 : case kArchTruncateDoubleToI:
307 : return 6;
308 : default:
309 : return 1;
310 : }
311 : }
312 :
313 : } // namespace compiler
314 : } // namespace internal
315 : } // namespace v8
|