OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/simplified-operator.h" | 5 #include "src/compiler/simplified-operator.h" |
6 | 6 |
7 #include "src/base/lazy-instance.h" | 7 #include "src/base/lazy-instance.h" |
8 #include "src/compiler/opcodes.h" | 8 #include "src/compiler/opcodes.h" |
9 #include "src/compiler/operator.h" | 9 #include "src/compiler/operator.h" |
10 #include "src/types.h" | 10 #include "src/types.h" |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
170 DCHECK(op->opcode() == IrOpcode::kLoadElement || | 170 DCHECK(op->opcode() == IrOpcode::kLoadElement || |
171 op->opcode() == IrOpcode::kStoreElement); | 171 op->opcode() == IrOpcode::kStoreElement); |
172 return OpParameter<ElementAccess>(op); | 172 return OpParameter<ElementAccess>(op); |
173 } | 173 } |
174 | 174 |
175 Type* TypeOf(const Operator* op) { | 175 Type* TypeOf(const Operator* op) { |
176 DCHECK_EQ(IrOpcode::kTypeGuard, op->opcode()); | 176 DCHECK_EQ(IrOpcode::kTypeGuard, op->opcode()); |
177 return OpParameter<Type*>(op); | 177 return OpParameter<Type*>(op); |
178 } | 178 } |
179 | 179 |
| 180 BinaryOperationHints::Hint BinaryOperationHintOf(const Operator* op) { |
| 181 DCHECK(op->opcode() == IrOpcode::kSpeculativeNumberAdd || |
| 182 op->opcode() == IrOpcode::kSpeculativeNumberSubtract); |
| 183 return OpParameter<BinaryOperationHints::Hint>(op); |
| 184 } |
| 185 |
180 #define PURE_OP_LIST(V) \ | 186 #define PURE_OP_LIST(V) \ |
181 V(BooleanNot, Operator::kNoProperties, 1) \ | 187 V(BooleanNot, Operator::kNoProperties, 1) \ |
182 V(BooleanToNumber, Operator::kNoProperties, 1) \ | 188 V(BooleanToNumber, Operator::kNoProperties, 1) \ |
183 V(NumberEqual, Operator::kCommutative, 2) \ | 189 V(NumberEqual, Operator::kCommutative, 2) \ |
184 V(NumberLessThan, Operator::kNoProperties, 2) \ | 190 V(NumberLessThan, Operator::kNoProperties, 2) \ |
185 V(NumberLessThanOrEqual, Operator::kNoProperties, 2) \ | 191 V(NumberLessThanOrEqual, Operator::kNoProperties, 2) \ |
186 V(NumberAdd, Operator::kCommutative, 2) \ | 192 V(NumberAdd, Operator::kCommutative, 2) \ |
187 V(NumberSubtract, Operator::kNoProperties, 2) \ | 193 V(NumberSubtract, Operator::kNoProperties, 2) \ |
188 V(NumberMultiply, Operator::kCommutative, 2) \ | 194 V(NumberMultiply, Operator::kCommutative, 2) \ |
189 V(NumberDivide, Operator::kNoProperties, 2) \ | 195 V(NumberDivide, Operator::kNoProperties, 2) \ |
(...skipping 30 matching lines...) Expand all Loading... |
220 V(ObjectIsCallable, Operator::kNoProperties, 1) \ | 226 V(ObjectIsCallable, Operator::kNoProperties, 1) \ |
221 V(ObjectIsNumber, Operator::kNoProperties, 1) \ | 227 V(ObjectIsNumber, Operator::kNoProperties, 1) \ |
222 V(ObjectIsReceiver, Operator::kNoProperties, 1) \ | 228 V(ObjectIsReceiver, Operator::kNoProperties, 1) \ |
223 V(ObjectIsSmi, Operator::kNoProperties, 1) \ | 229 V(ObjectIsSmi, Operator::kNoProperties, 1) \ |
224 V(ObjectIsString, Operator::kNoProperties, 1) \ | 230 V(ObjectIsString, Operator::kNoProperties, 1) \ |
225 V(ObjectIsUndetectable, Operator::kNoProperties, 1) \ | 231 V(ObjectIsUndetectable, Operator::kNoProperties, 1) \ |
226 V(StringEqual, Operator::kCommutative, 2) \ | 232 V(StringEqual, Operator::kCommutative, 2) \ |
227 V(StringLessThan, Operator::kNoProperties, 2) \ | 233 V(StringLessThan, Operator::kNoProperties, 2) \ |
228 V(StringLessThanOrEqual, Operator::kNoProperties, 2) | 234 V(StringLessThanOrEqual, Operator::kNoProperties, 2) |
229 | 235 |
| 236 #define CHECKED_OP_LIST(V) \ |
| 237 V(CheckedUint32ToInt32) \ |
| 238 V(CheckedFloat64ToInt32) \ |
| 239 V(CheckedTaggedToInt32) \ |
| 240 V(CheckedTaggedToFloat64) |
| 241 |
230 struct SimplifiedOperatorGlobalCache final { | 242 struct SimplifiedOperatorGlobalCache final { |
231 #define PURE(Name, properties, input_count) \ | 243 #define PURE(Name, properties, input_count) \ |
232 struct Name##Operator final : public Operator { \ | 244 struct Name##Operator final : public Operator { \ |
233 Name##Operator() \ | 245 Name##Operator() \ |
234 : Operator(IrOpcode::k##Name, Operator::kPure | properties, #Name, \ | 246 : Operator(IrOpcode::k##Name, Operator::kPure | properties, #Name, \ |
235 input_count, 0, 0, 1, 0, 0) {} \ | 247 input_count, 0, 0, 1, 0, 0) {} \ |
236 }; \ | 248 }; \ |
237 Name##Operator k##Name; | 249 Name##Operator k##Name; |
238 PURE_OP_LIST(PURE) | 250 PURE_OP_LIST(PURE) |
239 #undef PURE | 251 #undef PURE |
240 | 252 |
| 253 #define CHECKED(Name) \ |
| 254 struct Name##Operator final : public Operator { \ |
| 255 Name##Operator() \ |
| 256 : Operator(IrOpcode::k##Name, Operator::kNoThrow, #Name, 1, 1, 1, 1, \ |
| 257 1, 1) {} \ |
| 258 }; \ |
| 259 Name##Operator k##Name; |
| 260 CHECKED_OP_LIST(CHECKED) |
| 261 #undef CHECKED |
| 262 |
241 template <PretenureFlag kPretenure> | 263 template <PretenureFlag kPretenure> |
242 struct AllocateOperator final : public Operator1<PretenureFlag> { | 264 struct AllocateOperator final : public Operator1<PretenureFlag> { |
243 AllocateOperator() | 265 AllocateOperator() |
244 : Operator1<PretenureFlag>(IrOpcode::kAllocate, Operator::kNoThrow, | 266 : Operator1<PretenureFlag>(IrOpcode::kAllocate, Operator::kNoThrow, |
245 "Allocate", 1, 1, 1, 1, 1, 0, kPretenure) {} | 267 "Allocate", 1, 1, 1, 1, 1, 0, kPretenure) {} |
246 }; | 268 }; |
247 AllocateOperator<NOT_TENURED> kAllocateNotTenuredOperator; | 269 AllocateOperator<NOT_TENURED> kAllocateNotTenuredOperator; |
248 AllocateOperator<TENURED> kAllocateTenuredOperator; | 270 AllocateOperator<TENURED> kAllocateTenuredOperator; |
249 | 271 |
250 #define BUFFER_ACCESS(Type, type, TYPE, ctype, size) \ | 272 #define BUFFER_ACCESS(Type, type, TYPE, ctype, size) \ |
(...skipping 18 matching lines...) Expand all Loading... |
269 }; | 291 }; |
270 | 292 |
271 | 293 |
272 static base::LazyInstance<SimplifiedOperatorGlobalCache>::type kCache = | 294 static base::LazyInstance<SimplifiedOperatorGlobalCache>::type kCache = |
273 LAZY_INSTANCE_INITIALIZER; | 295 LAZY_INSTANCE_INITIALIZER; |
274 | 296 |
275 | 297 |
276 SimplifiedOperatorBuilder::SimplifiedOperatorBuilder(Zone* zone) | 298 SimplifiedOperatorBuilder::SimplifiedOperatorBuilder(Zone* zone) |
277 : cache_(kCache.Get()), zone_(zone) {} | 299 : cache_(kCache.Get()), zone_(zone) {} |
278 | 300 |
279 | |
280 #define GET_FROM_CACHE(Name, properties, input_count) \ | 301 #define GET_FROM_CACHE(Name, properties, input_count) \ |
281 const Operator* SimplifiedOperatorBuilder::Name() { return &cache_.k##Name; } | 302 const Operator* SimplifiedOperatorBuilder::Name() { return &cache_.k##Name; } |
282 PURE_OP_LIST(GET_FROM_CACHE) | 303 PURE_OP_LIST(GET_FROM_CACHE) |
283 #undef GET_FROM_CACHE | 304 #undef GET_FROM_CACHE |
284 | 305 |
| 306 #define GET_FROM_CACHE(Name) \ |
| 307 const Operator* SimplifiedOperatorBuilder::Name() { return &cache_.k##Name; } |
| 308 CHECKED_OP_LIST(GET_FROM_CACHE) |
| 309 #undef GET_FROM_CACHE |
285 | 310 |
286 const Operator* SimplifiedOperatorBuilder::ReferenceEqual(Type* type) { | 311 const Operator* SimplifiedOperatorBuilder::ReferenceEqual(Type* type) { |
287 return new (zone()) Operator(IrOpcode::kReferenceEqual, | 312 return new (zone()) Operator(IrOpcode::kReferenceEqual, |
288 Operator::kCommutative | Operator::kPure, | 313 Operator::kCommutative | Operator::kPure, |
289 "ReferenceEqual", 2, 0, 0, 1, 0, 0); | 314 "ReferenceEqual", 2, 0, 0, 1, 0, 0); |
290 } | 315 } |
291 | 316 |
292 const Operator* SimplifiedOperatorBuilder::TypeGuard(Type* type) { | 317 const Operator* SimplifiedOperatorBuilder::TypeGuard(Type* type) { |
293 class TypeGuardOperator final : public Operator1<Type*> { | 318 class TypeGuardOperator final : public Operator1<Type*> { |
294 public: | 319 public: |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
336 #define STORE_BUFFER(Type, type, TYPE, ctype, size) \ | 361 #define STORE_BUFFER(Type, type, TYPE, ctype, size) \ |
337 case kExternal##Type##Array: \ | 362 case kExternal##Type##Array: \ |
338 return &cache_.kStoreBuffer##Type; | 363 return &cache_.kStoreBuffer##Type; |
339 TYPED_ARRAYS(STORE_BUFFER) | 364 TYPED_ARRAYS(STORE_BUFFER) |
340 #undef STORE_BUFFER | 365 #undef STORE_BUFFER |
341 } | 366 } |
342 UNREACHABLE(); | 367 UNREACHABLE(); |
343 return nullptr; | 368 return nullptr; |
344 } | 369 } |
345 | 370 |
| 371 const Operator* SimplifiedOperatorBuilder::SpeculativeNumberAdd( |
| 372 BinaryOperationHints::Hint hint) { |
| 373 return new (zone()) Operator1<BinaryOperationHints::Hint>( |
| 374 IrOpcode::kSpeculativeNumberAdd, Operator::kNoThrow, |
| 375 "SpeculativeNumberAdd", 2, 1, 1, 1, 1, 1, hint); |
| 376 } |
| 377 |
| 378 const Operator* SimplifiedOperatorBuilder::SpeculativeNumberSubtract( |
| 379 BinaryOperationHints::Hint hint) { |
| 380 return new (zone()) Operator1<BinaryOperationHints::Hint>( |
| 381 IrOpcode::kSpeculativeNumberSubtract, Operator::kNoThrow, |
| 382 "SpeculativeNumberSubtract", 2, 1, 1, 1, 1, 1, hint); |
| 383 } |
346 | 384 |
347 #define ACCESS_OP_LIST(V) \ | 385 #define ACCESS_OP_LIST(V) \ |
348 V(LoadField, FieldAccess, Operator::kNoWrite, 1, 1, 1) \ | 386 V(LoadField, FieldAccess, Operator::kNoWrite, 1, 1, 1) \ |
349 V(StoreField, FieldAccess, Operator::kNoRead, 2, 1, 0) \ | 387 V(StoreField, FieldAccess, Operator::kNoRead, 2, 1, 0) \ |
350 V(LoadElement, ElementAccess, Operator::kNoWrite, 2, 1, 1) \ | 388 V(LoadElement, ElementAccess, Operator::kNoWrite, 2, 1, 1) \ |
351 V(StoreElement, ElementAccess, Operator::kNoRead, 3, 1, 0) | 389 V(StoreElement, ElementAccess, Operator::kNoRead, 3, 1, 0) |
352 | 390 |
353 | 391 |
354 #define ACCESS(Name, Type, properties, value_input_count, control_input_count, \ | 392 #define ACCESS(Name, Type, properties, value_input_count, control_input_count, \ |
355 output_count) \ | 393 output_count) \ |
356 const Operator* SimplifiedOperatorBuilder::Name(const Type& access) { \ | 394 const Operator* SimplifiedOperatorBuilder::Name(const Type& access) { \ |
357 return new (zone()) \ | 395 return new (zone()) \ |
358 Operator1<Type>(IrOpcode::k##Name, Operator::kNoThrow | properties, \ | 396 Operator1<Type>(IrOpcode::k##Name, Operator::kNoThrow | properties, \ |
359 #Name, value_input_count, 1, control_input_count, \ | 397 #Name, value_input_count, 1, control_input_count, \ |
360 output_count, 1, 0, access); \ | 398 output_count, 1, 0, access); \ |
361 } | 399 } |
362 ACCESS_OP_LIST(ACCESS) | 400 ACCESS_OP_LIST(ACCESS) |
363 #undef ACCESS | 401 #undef ACCESS |
364 | 402 |
365 } // namespace compiler | 403 } // namespace compiler |
366 } // namespace internal | 404 } // namespace internal |
367 } // namespace v8 | 405 } // namespace v8 |
OLD | NEW |