5 #include "src/compiler/simplified-operator.h" 7 #include "src/base/lazy-instance.h" 8 #include "src/compiler/opcodes.h" 9 #include "src/compiler/operator.h" 10 #include "src/compiler/types.h" 11 #include "src/handles-inl.h" 12 #include "src/objects-inl.h" 13 #include "src/objects/map.h" 14 #include "src/objects/name.h" 20 size_t hash_value(BaseTaggedness base_taggedness) {
21 return static_cast<uint8_t
>(base_taggedness);
24 std::ostream& operator<<(std::ostream& os, BaseTaggedness base_taggedness) {
25 switch (base_taggedness) {
27 return os <<
"untagged base";
29 return os <<
"tagged base";
34 bool operator==(FieldAccess
const& lhs, FieldAccess
const& rhs) {
38 return lhs.base_is_tagged == rhs.base_is_tagged && lhs.offset == rhs.offset &&
39 lhs.map.address() == rhs.map.address() &&
40 lhs.machine_type == rhs.machine_type;
43 size_t hash_value(FieldAccess
const& access) {
47 return base::hash_combine(access.base_is_tagged, access.offset,
51 size_t hash_value(LoadSensitivity load_sensitivity) {
52 return static_cast<size_t>(load_sensitivity);
55 std::ostream& operator<<(std::ostream& os, LoadSensitivity load_sensitivity) {
56 switch (load_sensitivity) {
57 case LoadSensitivity::kCritical:
58 return os <<
"Critical";
59 case LoadSensitivity::kSafe:
61 case LoadSensitivity::kUnsafe:
62 return os <<
"Unsafe";
67 std::ostream& operator<<(std::ostream& os, FieldAccess
const& access) {
68 os <<
"[" << access.base_is_tagged <<
", " << access.offset <<
", ";
71 if (access.name.ToHandle(&name)) {
76 if (access.map.ToHandle(&map)) {
77 os << Brief(*map) <<
", ";
80 os << access.type <<
", " << access.machine_type <<
", " 81 << access.write_barrier_kind;
82 if (FLAG_untrusted_code_mitigations) {
83 os <<
", " << access.load_sensitivity;
90 void Operator1<FieldAccess>::PrintParameter(std::ostream& os,
91 PrintVerbosity verbose)
const {
92 if (verbose == PrintVerbosity::kVerbose) {
95 os <<
"[+" << parameter().offset <<
"]";
99 bool operator==(ElementAccess
const& lhs, ElementAccess
const& rhs) {
103 return lhs.base_is_tagged == rhs.base_is_tagged &&
104 lhs.header_size == rhs.header_size &&
105 lhs.machine_type == rhs.machine_type;
108 size_t hash_value(ElementAccess
const& access) {
112 return base::hash_combine(access.base_is_tagged, access.header_size,
113 access.machine_type);
117 std::ostream& operator<<(std::ostream& os, ElementAccess
const& access) {
118 os << access.base_is_tagged <<
", " << access.header_size <<
", " 119 << access.type <<
", " << access.machine_type <<
", " 120 << access.write_barrier_kind;
121 if (FLAG_untrusted_code_mitigations) {
122 os <<
", " << access.load_sensitivity;
127 const FieldAccess& FieldAccessOf(
const Operator* op) {
129 DCHECK(op->opcode() == IrOpcode::kLoadField ||
130 op->opcode() == IrOpcode::kStoreField);
131 return OpParameter<FieldAccess>(op);
135 const ElementAccess& ElementAccessOf(
const Operator* op) {
137 DCHECK(op->opcode() == IrOpcode::kLoadElement ||
138 op->opcode() == IrOpcode::kStoreElement);
139 return OpParameter<ElementAccess>(op);
142 ExternalArrayType ExternalArrayTypeOf(
const Operator* op) {
143 DCHECK(op->opcode() == IrOpcode::kLoadTypedElement ||
144 op->opcode() == IrOpcode::kLoadDataViewElement ||
145 op->opcode() == IrOpcode::kStoreTypedElement ||
146 op->opcode() == IrOpcode::kStoreDataViewElement);
147 return OpParameter<ExternalArrayType>(op);
150 ConvertReceiverMode ConvertReceiverModeOf(Operator
const* op) {
151 DCHECK_EQ(IrOpcode::kConvertReceiver, op->opcode());
152 return OpParameter<ConvertReceiverMode>(op);
155 size_t hash_value(CheckFloat64HoleMode mode) {
156 return static_cast<size_t>(mode);
159 std::ostream& operator<<(std::ostream& os, CheckFloat64HoleMode mode) {
161 case CheckFloat64HoleMode::kAllowReturnHole:
162 return os <<
"allow-return-hole";
163 case CheckFloat64HoleMode::kNeverReturnHole:
164 return os <<
"never-return-hole";
169 CheckFloat64HoleParameters
const& CheckFloat64HoleParametersOf(
170 Operator
const* op) {
171 DCHECK_EQ(IrOpcode::kCheckFloat64Hole, op->opcode());
172 return OpParameter<CheckFloat64HoleParameters>(op);
175 std::ostream& operator<<(std::ostream& os,
176 CheckFloat64HoleParameters
const& params) {
178 if (params.feedback().IsValid()) os <<
"; " << params.feedback();
182 size_t hash_value(
const CheckFloat64HoleParameters& params) {
183 return base::hash_combine(params.mode(), params.feedback());
186 bool operator==(CheckFloat64HoleParameters
const& lhs,
187 CheckFloat64HoleParameters
const& rhs) {
188 return lhs.mode() == rhs.mode() && lhs.feedback() == rhs.feedback();
191 bool operator!=(CheckFloat64HoleParameters
const& lhs,
192 CheckFloat64HoleParameters
const& rhs) {
193 return !(lhs == rhs);
196 CheckForMinusZeroMode CheckMinusZeroModeOf(
const Operator* op) {
197 DCHECK(op->opcode() == IrOpcode::kChangeFloat64ToTagged ||
198 op->opcode() == IrOpcode::kCheckedInt32Mul);
199 return OpParameter<CheckForMinusZeroMode>(op);
202 size_t hash_value(CheckForMinusZeroMode mode) {
203 return static_cast<size_t>(mode);
206 std::ostream& operator<<(std::ostream& os, CheckForMinusZeroMode mode) {
208 case CheckForMinusZeroMode::kCheckForMinusZero:
209 return os <<
"check-for-minus-zero";
210 case CheckForMinusZeroMode::kDontCheckForMinusZero:
211 return os <<
"dont-check-for-minus-zero";
216 std::ostream& operator<<(std::ostream& os, CheckMapsFlags flags) {
218 if (flags & CheckMapsFlag::kTryMigrateInstance) {
219 os <<
"TryMigrateInstance";
222 if (empty) os <<
"None";
226 MapsParameterInfo::MapsParameterInfo(ZoneHandleSet<Map>
const& maps)
227 : maps_(maps), instance_type_(Nothing<InstanceType>()) {
228 DCHECK_LT(0, maps.size());
229 instance_type_ = Just(maps.at(0)->instance_type());
230 for (
size_t i = 1;
i < maps.size(); ++
i) {
231 if (instance_type_.FromJust() != maps.at(
i)->instance_type()) {
232 instance_type_ = Nothing<InstanceType>();
238 std::ostream& operator<<(std::ostream& os, MapsParameterInfo
const& p) {
239 ZoneHandleSet<Map>
const& maps = p.maps();
240 InstanceType instance_type;
241 if (p.instance_type().To(&instance_type)) {
242 os <<
", " << instance_type;
244 for (
size_t i = 0;
i < maps.size(); ++
i) {
245 os <<
", " << Brief(*maps[
i]);
250 bool operator==(MapsParameterInfo
const& lhs, MapsParameterInfo
const& rhs) {
251 return lhs.maps() == rhs.maps();
254 bool operator!=(MapsParameterInfo
const& lhs, MapsParameterInfo
const& rhs) {
255 return !(lhs == rhs);
258 size_t hash_value(MapsParameterInfo
const& p) {
return hash_value(p.maps()); }
260 bool operator==(CheckMapsParameters
const& lhs,
261 CheckMapsParameters
const& rhs) {
262 return lhs.flags() == rhs.flags() && lhs.maps() == rhs.maps() &&
263 lhs.feedback() == rhs.feedback();
266 size_t hash_value(CheckMapsParameters
const& p) {
267 return base::hash_combine(p.flags(), p.maps(), p.feedback());
270 std::ostream& operator<<(std::ostream& os, CheckMapsParameters
const& p) {
271 os << p.flags() << p.maps_info();
272 if (p.feedback().IsValid()) {
273 os <<
"; " << p.feedback();
278 CheckMapsParameters
const& CheckMapsParametersOf(Operator
const* op) {
279 DCHECK_EQ(IrOpcode::kCheckMaps, op->opcode());
280 return OpParameter<CheckMapsParameters>(op);
283 MapsParameterInfo
const& CompareMapsParametersOf(Operator
const* op) {
284 DCHECK_EQ(IrOpcode::kCompareMaps, op->opcode());
285 return OpParameter<MapsParameterInfo>(op);
288 MapsParameterInfo
const& MapGuardMapsOf(Operator
const* op) {
289 DCHECK_EQ(IrOpcode::kMapGuard, op->opcode());
290 return OpParameter<MapsParameterInfo>(op);
293 size_t hash_value(CheckTaggedInputMode mode) {
294 return static_cast<size_t>(mode);
297 std::ostream& operator<<(std::ostream& os, CheckTaggedInputMode mode) {
299 case CheckTaggedInputMode::kNumber:
300 return os <<
"Number";
301 case CheckTaggedInputMode::kNumberOrOddball:
302 return os <<
"NumberOrOddball";
307 std::ostream& operator<<(std::ostream& os, GrowFastElementsMode mode) {
309 case GrowFastElementsMode::kDoubleElements:
310 return os <<
"DoubleElements";
311 case GrowFastElementsMode::kSmiOrObjectElements:
312 return os <<
"SmiOrObjectElements";
317 bool operator==(
const GrowFastElementsParameters& lhs,
318 const GrowFastElementsParameters& rhs) {
319 return lhs.mode() == rhs.mode() && lhs.feedback() == rhs.feedback();
322 inline size_t hash_value(
const GrowFastElementsParameters& params) {
323 return base::hash_combine(params.mode(), params.feedback());
326 std::ostream& operator<<(std::ostream& os,
327 const GrowFastElementsParameters& params) {
329 if (params.feedback().IsValid()) {
330 os << params.feedback();
335 const GrowFastElementsParameters& GrowFastElementsParametersOf(
336 const Operator* op) {
337 DCHECK_EQ(IrOpcode::kMaybeGrowFastElements, op->opcode());
338 return OpParameter<GrowFastElementsParameters>(op);
341 bool operator==(ElementsTransition
const& lhs, ElementsTransition
const& rhs) {
342 return lhs.mode() == rhs.mode() &&
343 lhs.source().address() == rhs.source().address() &&
344 lhs.target().address() == rhs.target().address();
347 size_t hash_value(ElementsTransition transition) {
348 return base::hash_combine(static_cast<uint8_t>(transition.mode()),
349 transition.source().address(),
350 transition.target().address());
353 std::ostream& operator<<(std::ostream& os, ElementsTransition transition) {
354 switch (transition.mode()) {
355 case ElementsTransition::kFastTransition:
356 return os <<
"fast-transition from " << Brief(*transition.source())
357 <<
" to " << Brief(*transition.target());
358 case ElementsTransition::kSlowTransition:
359 return os <<
"slow-transition from " << Brief(*transition.source())
360 <<
" to " << Brief(*transition.target());
365 ElementsTransition
const& ElementsTransitionOf(
const Operator* op) {
366 DCHECK_EQ(IrOpcode::kTransitionElementsKind, op->opcode());
367 return OpParameter<ElementsTransition>(op);
373 class TransitionAndStoreElementParameters final {
375 TransitionAndStoreElementParameters(Handle<Map> double_map,
376 Handle<Map> fast_map);
378 Handle<Map> double_map()
const {
return double_map_; }
379 Handle<Map> fast_map()
const {
return fast_map_; }
382 Handle<Map>
const double_map_;
383 Handle<Map>
const fast_map_;
386 TransitionAndStoreElementParameters::TransitionAndStoreElementParameters(
387 Handle<Map> double_map, Handle<Map> fast_map)
388 : double_map_(double_map), fast_map_(fast_map) {}
390 bool operator==(TransitionAndStoreElementParameters
const& lhs,
391 TransitionAndStoreElementParameters
const& rhs) {
392 return lhs.fast_map().address() == rhs.fast_map().address() &&
393 lhs.double_map().address() == rhs.double_map().address();
396 size_t hash_value(TransitionAndStoreElementParameters parameters) {
397 return base::hash_combine(parameters.fast_map().address(),
398 parameters.double_map().address());
401 std::ostream& operator<<(std::ostream& os,
402 TransitionAndStoreElementParameters parameters) {
403 return os <<
"fast-map" << Brief(*parameters.fast_map()) <<
" double-map" 404 << Brief(*parameters.double_map());
412 class TransitionAndStoreNonNumberElementParameters final {
414 TransitionAndStoreNonNumberElementParameters(Handle<Map> fast_map,
417 Handle<Map> fast_map()
const {
return fast_map_; }
418 Type value_type()
const {
return value_type_; }
421 Handle<Map>
const fast_map_;
425 TransitionAndStoreNonNumberElementParameters::
426 TransitionAndStoreNonNumberElementParameters(Handle<Map> fast_map,
428 : fast_map_(fast_map), value_type_(value_type) {}
430 bool operator==(TransitionAndStoreNonNumberElementParameters
const& lhs,
431 TransitionAndStoreNonNumberElementParameters
const& rhs) {
432 return lhs.fast_map().address() == rhs.fast_map().address() &&
433 lhs.value_type() == rhs.value_type();
436 size_t hash_value(TransitionAndStoreNonNumberElementParameters parameters) {
437 return base::hash_combine(parameters.fast_map().address(),
438 parameters.value_type());
441 std::ostream& operator<<(
442 std::ostream& os, TransitionAndStoreNonNumberElementParameters parameters) {
443 return os << parameters.value_type() <<
", fast-map" 444 << Brief(*parameters.fast_map());
452 class TransitionAndStoreNumberElementParameters final {
454 explicit TransitionAndStoreNumberElementParameters(Handle<Map> double_map);
456 Handle<Map> double_map()
const {
return double_map_; }
459 Handle<Map>
const double_map_;
462 TransitionAndStoreNumberElementParameters::
463 TransitionAndStoreNumberElementParameters(Handle<Map> double_map)
464 : double_map_(double_map) {}
466 bool operator==(TransitionAndStoreNumberElementParameters
const& lhs,
467 TransitionAndStoreNumberElementParameters
const& rhs) {
468 return lhs.double_map().address() == rhs.double_map().address();
471 size_t hash_value(TransitionAndStoreNumberElementParameters parameters) {
472 return base::hash_combine(parameters.double_map().address());
475 std::ostream& operator<<(std::ostream& os,
476 TransitionAndStoreNumberElementParameters parameters) {
477 return os <<
"double-map" << Brief(*parameters.double_map());
482 Handle<Map> DoubleMapParameterOf(
const Operator* op) {
483 if (op->opcode() == IrOpcode::kTransitionAndStoreElement) {
484 return OpParameter<TransitionAndStoreElementParameters>(op).double_map();
485 }
else if (op->opcode() == IrOpcode::kTransitionAndStoreNumberElement) {
486 return OpParameter<TransitionAndStoreNumberElementParameters>(op)
490 return Handle<Map>::null();
493 Type ValueTypeParameterOf(
const Operator* op) {
494 DCHECK_EQ(IrOpcode::kTransitionAndStoreNonNumberElement, op->opcode());
495 return OpParameter<TransitionAndStoreNonNumberElementParameters>(op)
499 Handle<Map> FastMapParameterOf(
const Operator* op) {
500 if (op->opcode() == IrOpcode::kTransitionAndStoreElement) {
501 return OpParameter<TransitionAndStoreElementParameters>(op).fast_map();
502 }
else if (op->opcode() == IrOpcode::kTransitionAndStoreNonNumberElement) {
503 return OpParameter<TransitionAndStoreNonNumberElementParameters>(op)
507 return Handle<Map>::null();
510 std::ostream& operator<<(std::ostream& os, NumberOperationHint hint) {
512 case NumberOperationHint::kSignedSmall:
513 return os <<
"SignedSmall";
514 case NumberOperationHint::kSignedSmallInputs:
515 return os <<
"SignedSmallInputs";
516 case NumberOperationHint::kSigned32:
517 return os <<
"Signed32";
518 case NumberOperationHint::kNumber:
519 return os <<
"Number";
520 case NumberOperationHint::kNumberOrOddball:
521 return os <<
"NumberOrOddball";
526 size_t hash_value(NumberOperationHint hint) {
527 return static_cast<uint8_t
>(hint);
530 NumberOperationHint NumberOperationHintOf(
const Operator* op) {
531 DCHECK(op->opcode() == IrOpcode::kSpeculativeNumberAdd ||
532 op->opcode() == IrOpcode::kSpeculativeNumberSubtract ||
533 op->opcode() == IrOpcode::kSpeculativeNumberMultiply ||
534 op->opcode() == IrOpcode::kSpeculativeNumberDivide ||
535 op->opcode() == IrOpcode::kSpeculativeNumberModulus ||
536 op->opcode() == IrOpcode::kSpeculativeNumberShiftLeft ||
537 op->opcode() == IrOpcode::kSpeculativeNumberShiftRight ||
538 op->opcode() == IrOpcode::kSpeculativeNumberShiftRightLogical ||
539 op->opcode() == IrOpcode::kSpeculativeNumberBitwiseAnd ||
540 op->opcode() == IrOpcode::kSpeculativeNumberBitwiseOr ||
541 op->opcode() == IrOpcode::kSpeculativeNumberBitwiseXor ||
542 op->opcode() == IrOpcode::kSpeculativeNumberEqual ||
543 op->opcode() == IrOpcode::kSpeculativeNumberLessThan ||
544 op->opcode() == IrOpcode::kSpeculativeNumberLessThanOrEqual ||
545 op->opcode() == IrOpcode::kSpeculativeSafeIntegerAdd ||
546 op->opcode() == IrOpcode::kSpeculativeSafeIntegerSubtract);
547 return OpParameter<NumberOperationHint>(op);
550 bool operator==(NumberOperationParameters
const& lhs,
551 NumberOperationParameters
const& rhs) {
552 return lhs.hint() == rhs.hint() && lhs.feedback() == rhs.feedback();
555 size_t hash_value(NumberOperationParameters
const& p) {
556 return base::hash_combine(p.hint(), p.feedback());
559 std::ostream& operator<<(std::ostream& os, NumberOperationParameters
const& p) {
560 return os << p.hint() <<
" " << p.feedback();
563 NumberOperationParameters
const& NumberOperationParametersOf(
564 Operator
const* op) {
565 DCHECK_EQ(IrOpcode::kSpeculativeToNumber, op->opcode());
566 return OpParameter<NumberOperationParameters>(op);
569 size_t hash_value(AllocateParameters info) {
570 return base::hash_combine(info.type(), info.pretenure());
573 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
574 AllocateParameters info) {
575 return os << info.type() <<
", " << info.pretenure();
578 bool operator==(AllocateParameters
const& lhs, AllocateParameters
const& rhs) {
579 return lhs.pretenure() == rhs.pretenure() && lhs.type() == rhs.type();
582 PretenureFlag PretenureFlagOf(
const Operator* op) {
583 if (op->opcode() == IrOpcode::kNewDoubleElements ||
584 op->opcode() == IrOpcode::kNewSmiOrObjectElements) {
585 return OpParameter<PretenureFlag>(op);
587 DCHECK(op->opcode() == IrOpcode::kAllocate ||
588 op->opcode() == IrOpcode::kAllocateRaw);
589 return OpParameter<AllocateParameters>(op).pretenure();
592 Type AllocateTypeOf(
const Operator* op) {
593 DCHECK_EQ(IrOpcode::kAllocate, op->opcode());
594 return OpParameter<AllocateParameters>(op).type();
597 UnicodeEncoding UnicodeEncodingOf(
const Operator* op) {
598 DCHECK(op->opcode() == IrOpcode::kStringFromSingleCodePoint ||
599 op->opcode() == IrOpcode::kStringCodePointAt);
600 return OpParameter<UnicodeEncoding>(op);
603 AbortReason AbortReasonOf(
const Operator* op) {
604 DCHECK_EQ(IrOpcode::kRuntimeAbort, op->opcode());
605 return static_cast<AbortReason
>(OpParameter<int>(op));
608 const CheckTaggedInputParameters& CheckTaggedInputParametersOf(
609 const Operator* op) {
610 DCHECK(op->opcode() == IrOpcode::kCheckedTruncateTaggedToWord32 ||
611 op->opcode() == IrOpcode::kCheckedTaggedToFloat64);
612 return OpParameter<CheckTaggedInputParameters>(op);
615 std::ostream& operator<<(std::ostream& os,
616 const CheckTaggedInputParameters& params) {
618 if (params.feedback().IsValid()) {
619 os <<
"; " << params.feedback();
624 size_t hash_value(
const CheckTaggedInputParameters& params) {
625 return base::hash_combine(params.mode(), params.feedback());
628 bool operator==(CheckTaggedInputParameters
const& lhs,
629 CheckTaggedInputParameters
const& rhs) {
630 return lhs.mode() == rhs.mode() && lhs.feedback() == rhs.feedback();
633 const CheckMinusZeroParameters& CheckMinusZeroParametersOf(
const Operator* op) {
634 DCHECK(op->opcode() == IrOpcode::kCheckedTaggedToInt32 ||
635 op->opcode() == IrOpcode::kCheckedTaggedToInt64 ||
636 op->opcode() == IrOpcode::kCheckedFloat64ToInt32 ||
637 op->opcode() == IrOpcode::kCheckedFloat64ToInt64);
638 return OpParameter<CheckMinusZeroParameters>(op);
641 std::ostream& operator<<(std::ostream& os,
642 const CheckMinusZeroParameters& params) {
644 if (params.feedback().IsValid()) {
645 os <<
"; " << params.feedback();
650 size_t hash_value(
const CheckMinusZeroParameters& params) {
651 return base::hash_combine(params.mode(), params.feedback());
654 bool operator==(CheckMinusZeroParameters
const& lhs,
655 CheckMinusZeroParameters
const& rhs) {
656 return lhs.mode() == rhs.mode() && lhs.feedback() == rhs.feedback();
659 #define PURE_OP_LIST(V) \ 660 V(BooleanNot, Operator::kNoProperties, 1, 0) \ 661 V(NumberEqual, Operator::kCommutative, 2, 0) \ 662 V(NumberLessThan, Operator::kNoProperties, 2, 0) \ 663 V(NumberLessThanOrEqual, Operator::kNoProperties, 2, 0) \ 664 V(NumberAdd, Operator::kCommutative, 2, 0) \ 665 V(NumberSubtract, Operator::kNoProperties, 2, 0) \ 666 V(NumberMultiply, Operator::kCommutative, 2, 0) \ 667 V(NumberDivide, Operator::kNoProperties, 2, 0) \ 668 V(NumberModulus, Operator::kNoProperties, 2, 0) \ 669 V(NumberBitwiseOr, Operator::kCommutative, 2, 0) \ 670 V(NumberBitwiseXor, Operator::kCommutative, 2, 0) \ 671 V(NumberBitwiseAnd, Operator::kCommutative, 2, 0) \ 672 V(NumberShiftLeft, Operator::kNoProperties, 2, 0) \ 673 V(NumberShiftRight, Operator::kNoProperties, 2, 0) \ 674 V(NumberShiftRightLogical, Operator::kNoProperties, 2, 0) \ 675 V(NumberImul, Operator::kCommutative, 2, 0) \ 676 V(NumberAbs, Operator::kNoProperties, 1, 0) \ 677 V(NumberClz32, Operator::kNoProperties, 1, 0) \ 678 V(NumberCeil, Operator::kNoProperties, 1, 0) \ 679 V(NumberFloor, Operator::kNoProperties, 1, 0) \ 680 V(NumberFround, Operator::kNoProperties, 1, 0) \ 681 V(NumberAcos, Operator::kNoProperties, 1, 0) \ 682 V(NumberAcosh, Operator::kNoProperties, 1, 0) \ 683 V(NumberAsin, Operator::kNoProperties, 1, 0) \ 684 V(NumberAsinh, Operator::kNoProperties, 1, 0) \ 685 V(NumberAtan, Operator::kNoProperties, 1, 0) \ 686 V(NumberAtan2, Operator::kNoProperties, 2, 0) \ 687 V(NumberAtanh, Operator::kNoProperties, 1, 0) \ 688 V(NumberCbrt, Operator::kNoProperties, 1, 0) \ 689 V(NumberCos, Operator::kNoProperties, 1, 0) \ 690 V(NumberCosh, Operator::kNoProperties, 1, 0) \ 691 V(NumberExp, Operator::kNoProperties, 1, 0) \ 692 V(NumberExpm1, Operator::kNoProperties, 1, 0) \ 693 V(NumberLog, Operator::kNoProperties, 1, 0) \ 694 V(NumberLog1p, Operator::kNoProperties, 1, 0) \ 695 V(NumberLog10, Operator::kNoProperties, 1, 0) \ 696 V(NumberLog2, Operator::kNoProperties, 1, 0) \ 697 V(NumberMax, Operator::kNoProperties, 2, 0) \ 698 V(NumberMin, Operator::kNoProperties, 2, 0) \ 699 V(NumberPow, Operator::kNoProperties, 2, 0) \ 700 V(NumberRound, Operator::kNoProperties, 1, 0) \ 701 V(NumberSign, Operator::kNoProperties, 1, 0) \ 702 V(NumberSin, Operator::kNoProperties, 1, 0) \ 703 V(NumberSinh, Operator::kNoProperties, 1, 0) \ 704 V(NumberSqrt, Operator::kNoProperties, 1, 0) \ 705 V(NumberTan, Operator::kNoProperties, 1, 0) \ 706 V(NumberTanh, Operator::kNoProperties, 1, 0) \ 707 V(NumberTrunc, Operator::kNoProperties, 1, 0) \ 708 V(NumberToBoolean, Operator::kNoProperties, 1, 0) \ 709 V(NumberToInt32, Operator::kNoProperties, 1, 0) \ 710 V(NumberToString, Operator::kNoProperties, 1, 0) \ 711 V(NumberToUint32, Operator::kNoProperties, 1, 0) \ 712 V(NumberToUint8Clamped, Operator::kNoProperties, 1, 0) \ 713 V(NumberSilenceNaN, Operator::kNoProperties, 1, 0) \ 714 V(StringConcat, Operator::kNoProperties, 3, 0) \ 715 V(StringToNumber, Operator::kNoProperties, 1, 0) \ 716 V(StringFromSingleCharCode, Operator::kNoProperties, 1, 0) \ 717 V(StringIndexOf, Operator::kNoProperties, 3, 0) \ 718 V(StringLength, Operator::kNoProperties, 1, 0) \ 719 V(StringToLowerCaseIntl, Operator::kNoProperties, 1, 0) \ 720 V(StringToUpperCaseIntl, Operator::kNoProperties, 1, 0) \ 721 V(TypeOf, Operator::kNoProperties, 1, 1) \ 722 V(PlainPrimitiveToNumber, Operator::kNoProperties, 1, 0) \ 723 V(PlainPrimitiveToWord32, Operator::kNoProperties, 1, 0) \ 724 V(PlainPrimitiveToFloat64, Operator::kNoProperties, 1, 0) \ 725 V(ChangeTaggedSignedToInt32, Operator::kNoProperties, 1, 0) \ 726 V(ChangeTaggedSignedToInt64, Operator::kNoProperties, 1, 0) \ 727 V(ChangeTaggedToInt32, Operator::kNoProperties, 1, 0) \ 728 V(ChangeTaggedToInt64, Operator::kNoProperties, 1, 0) \ 729 V(ChangeTaggedToUint32, Operator::kNoProperties, 1, 0) \ 730 V(ChangeTaggedToFloat64, Operator::kNoProperties, 1, 0) \ 731 V(ChangeTaggedToTaggedSigned, Operator::kNoProperties, 1, 0) \ 732 V(ChangeFloat64ToTaggedPointer, Operator::kNoProperties, 1, 0) \ 733 V(ChangeInt31ToTaggedSigned, Operator::kNoProperties, 1, 0) \ 734 V(ChangeInt32ToTagged, Operator::kNoProperties, 1, 0) \ 735 V(ChangeInt64ToTagged, Operator::kNoProperties, 1, 0) \ 736 V(ChangeUint32ToTagged, Operator::kNoProperties, 1, 0) \ 737 V(ChangeUint64ToTagged, Operator::kNoProperties, 1, 0) \ 738 V(ChangeTaggedToBit, Operator::kNoProperties, 1, 0) \ 739 V(ChangeBitToTagged, Operator::kNoProperties, 1, 0) \ 740 V(TruncateTaggedToBit, Operator::kNoProperties, 1, 0) \ 741 V(TruncateTaggedPointerToBit, Operator::kNoProperties, 1, 0) \ 742 V(TruncateTaggedToWord32, Operator::kNoProperties, 1, 0) \ 743 V(TruncateTaggedToFloat64, Operator::kNoProperties, 1, 0) \ 744 V(ObjectIsArrayBufferView, Operator::kNoProperties, 1, 0) \ 745 V(ObjectIsBigInt, Operator::kNoProperties, 1, 0) \ 746 V(ObjectIsCallable, Operator::kNoProperties, 1, 0) \ 747 V(ObjectIsConstructor, Operator::kNoProperties, 1, 0) \ 748 V(ObjectIsDetectableCallable, Operator::kNoProperties, 1, 0) \ 749 V(ObjectIsMinusZero, Operator::kNoProperties, 1, 0) \ 750 V(NumberIsMinusZero, Operator::kNoProperties, 1, 0) \ 751 V(ObjectIsNaN, Operator::kNoProperties, 1, 0) \ 752 V(NumberIsNaN, Operator::kNoProperties, 1, 0) \ 753 V(ObjectIsNonCallable, Operator::kNoProperties, 1, 0) \ 754 V(ObjectIsNumber, Operator::kNoProperties, 1, 0) \ 755 V(ObjectIsReceiver, Operator::kNoProperties, 1, 0) \ 756 V(ObjectIsSmi, Operator::kNoProperties, 1, 0) \ 757 V(ObjectIsString, Operator::kNoProperties, 1, 0) \ 758 V(ObjectIsSymbol, Operator::kNoProperties, 1, 0) \ 759 V(ObjectIsUndetectable, Operator::kNoProperties, 1, 0) \ 760 V(NumberIsFloat64Hole, Operator::kNoProperties, 1, 0) \ 761 V(NumberIsFinite, Operator::kNoProperties, 1, 0) \ 762 V(ObjectIsFiniteNumber, Operator::kNoProperties, 1, 0) \ 763 V(NumberIsInteger, Operator::kNoProperties, 1, 0) \ 764 V(ObjectIsSafeInteger, Operator::kNoProperties, 1, 0) \ 765 V(NumberIsSafeInteger, Operator::kNoProperties, 1, 0) \ 766 V(ObjectIsInteger, Operator::kNoProperties, 1, 0) \ 767 V(ConvertTaggedHoleToUndefined, Operator::kNoProperties, 1, 0) \ 768 V(SameValue, Operator::kCommutative, 2, 0) \ 769 V(ReferenceEqual, Operator::kCommutative, 2, 0) \ 770 V(StringEqual, Operator::kCommutative, 2, 0) \ 771 V(StringLessThan, Operator::kNoProperties, 2, 0) \ 772 V(StringLessThanOrEqual, Operator::kNoProperties, 2, 0) \ 773 V(ToBoolean, Operator::kNoProperties, 1, 0) \ 774 V(NewConsString, Operator::kNoProperties, 3, 0) \ 775 V(PoisonIndex, Operator::kNoProperties, 1, 0) 777 #define EFFECT_DEPENDENT_OP_LIST(V) \ 778 V(StringCharCodeAt, Operator::kNoProperties, 2, 1) \ 779 V(StringSubstring, Operator::kNoProperties, 3, 1) \ 780 V(DateNow, Operator::kNoProperties, 0, 1) 782 #define SPECULATIVE_NUMBER_BINOP_LIST(V) \ 783 SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(V) \ 784 V(SpeculativeNumberEqual) \ 785 V(SpeculativeNumberLessThan) \ 786 V(SpeculativeNumberLessThanOrEqual) 788 #define CHECKED_OP_LIST(V) \ 789 V(CheckEqualsInternalizedString, 2, 0) \ 790 V(CheckEqualsSymbol, 2, 0) \ 791 V(CheckHeapObject, 1, 1) \ 792 V(CheckInternalizedString, 1, 1) \ 793 V(CheckNotTaggedHole, 1, 1) \ 794 V(CheckReceiver, 1, 1) \ 795 V(CheckReceiverOrNullOrUndefined, 1, 1) \ 796 V(CheckSymbol, 1, 1) \ 797 V(CheckedInt32Add, 2, 1) \ 798 V(CheckedInt32Div, 2, 1) \ 799 V(CheckedInt32Mod, 2, 1) \ 800 V(CheckedInt32Sub, 2, 1) \ 801 V(CheckedUint32Div, 2, 1) \ 802 V(CheckedUint32Mod, 2, 1) 804 #define CHECKED_WITH_FEEDBACK_OP_LIST(V) \ 805 V(CheckBounds, 2, 1) \ 806 V(CheckNumber, 1, 1) \ 808 V(CheckString, 1, 1) \ 809 V(CheckedInt32ToTaggedSigned, 1, 1) \ 810 V(CheckedInt64ToInt32, 1, 1) \ 811 V(CheckedInt64ToTaggedSigned, 1, 1) \ 812 V(CheckedTaggedSignedToInt32, 1, 1) \ 813 V(CheckedTaggedToTaggedPointer, 1, 1) \ 814 V(CheckedTaggedToTaggedSigned, 1, 1) \ 815 V(CheckedUint32Bounds, 2, 1) \ 816 V(CheckedUint32ToInt32, 1, 1) \ 817 V(CheckedUint32ToTaggedSigned, 1, 1) \ 818 V(CheckedUint64Bounds, 2, 1) \ 819 V(CheckedUint64ToInt32, 1, 1) \ 820 V(CheckedUint64ToTaggedSigned, 1, 1) 823 #define PURE(Name, properties, value_input_count, control_input_count) \ 824 struct Name##Operator final : public Operator { \ 826 : Operator(IrOpcode::k##Name, Operator::kPure | properties, #Name, \ 827 value_input_count, 0, control_input_count, 1, 0, 0) {} \ 829 Name##Operator k##Name; 833 #define EFFECT_DEPENDENT(Name, properties, value_input_count, \ 834 control_input_count) \ 835 struct Name##Operator final : public Operator { \ 837 : Operator(IrOpcode::k##Name, \ 838 Operator::kNoDeopt | Operator::kNoWrite | \ 839 Operator::kNoThrow | properties, \ 840 #Name, value_input_count, 1, control_input_count, 1, 1, \ 843 Name##Operator k##Name; 844 EFFECT_DEPENDENT_OP_LIST(EFFECT_DEPENDENT)
845 #undef EFFECT_DEPENDENT 847 #define CHECKED(Name, value_input_count, value_output_count) \ 848 struct Name##Operator final : public Operator { \ 850 : Operator(IrOpcode::k##Name, \ 851 Operator::kFoldable | Operator::kNoThrow, #Name, \ 852 value_input_count, 1, 1, value_output_count, 1, 0) {} \ 854 Name##Operator k##Name; 855 CHECKED_OP_LIST(CHECKED)
858 #define CHECKED_WITH_FEEDBACK(Name, value_input_count, value_output_count) \ 859 struct Name##Operator final : public Operator1<CheckParameters> { \ 861 : Operator1<CheckParameters>( \ 862 IrOpcode::k##Name, Operator::kFoldable | Operator::kNoThrow, \ 863 #Name, value_input_count, 1, 1, value_output_count, 1, 0, \ 864 CheckParameters(VectorSlotPair())) {} \ 866 Name##Operator k##Name; 867 CHECKED_WITH_FEEDBACK_OP_LIST(CHECKED_WITH_FEEDBACK)
868 #undef CHECKED_WITH_FEEDBACK 870 template <DeoptimizeReason kDeoptimizeReason>
874 IrOpcode::kCheckIf, Operator::kFoldable | Operator::kNoThrow,
875 "CheckIf", 1, 1, 1, 0, 1, 0,
878 #define CHECK_IF(Name, message) \ 879 CheckIfOperator<DeoptimizeReason::k##Name> kCheckIf##Name; 880 DEOPTIMIZE_REASON_LIST(CHECK_IF)
883 template <UnicodeEncoding kEncoding>
887 Operator::kFoldable | Operator::kNoThrow,
888 "StringCodePointAt", 2, 1, 1, 1, 1, 0,
892 kStringCodePointAtOperatorUTF16;
894 kStringCodePointAtOperatorUTF32;
896 template <UnicodeEncoding kEncoding>
901 IrOpcode::kStringFromSingleCodePoint, Operator::kPure,
902 "StringFromSingleCodePoint", 1, 0, 0, 1, 0, 0, kEncoding) {}
905 kStringFromSingleCodePointOperatorUTF16;
907 kStringFromSingleCodePointOperatorUTF32;
911 :
Operator(IrOpcode::kFindOrderedHashMapEntry, Operator::kEliminatable,
912 "FindOrderedHashMapEntry", 2, 1, 1, 1, 1, 0) {}
918 :
Operator(IrOpcode::kFindOrderedHashMapEntryForInt32Key,
919 Operator::kEliminatable,
920 "FindOrderedHashMapEntryForInt32Key", 2, 1, 1, 1, 1, 0) {}
923 kFindOrderedHashMapEntryForInt32Key;
927 :
Operator(IrOpcode::kArgumentsFrame, Operator::kPure,
"ArgumentsFrame",
932 template <CheckForMinusZeroMode kMode>
934 :
public Operator1<CheckForMinusZeroMode> {
937 IrOpcode::kChangeFloat64ToTagged, Operator::kPure,
938 "ChangeFloat64ToTagged", 1, 0, 0, 1, 0, 0, kMode) {}
941 kChangeFloat64ToTaggedCheckForMinusZeroOperator;
943 kChangeFloat64ToTaggedDontCheckForMinusZeroOperator;
945 template <CheckForMinusZeroMode kMode>
947 :
public Operator1<CheckForMinusZeroMode> {
950 IrOpcode::kCheckedInt32Mul,
951 Operator::kFoldable | Operator::kNoThrow,
"CheckedInt32Mul", 2, 1,
952 1, 1, 1, 0, kMode) {}
955 kCheckedInt32MulCheckForMinusZeroOperator;
957 kCheckedInt32MulDontCheckForMinusZeroOperator;
959 template <CheckForMinusZeroMode kMode>
961 :
public Operator1<CheckMinusZeroParameters> {
964 IrOpcode::kCheckedFloat64ToInt32,
965 Operator::kFoldable | Operator::kNoThrow,
"CheckedFloat64ToInt32",
970 kCheckedFloat64ToInt32CheckForMinusZeroOperator;
972 kCheckedFloat64ToInt32DontCheckForMinusZeroOperator;
974 template <CheckForMinusZeroMode kMode>
976 :
public Operator1<CheckMinusZeroParameters> {
979 IrOpcode::kCheckedFloat64ToInt64,
980 Operator::kFoldable | Operator::kNoThrow,
"CheckedFloat64ToInt64",
985 kCheckedFloat64ToInt64CheckForMinusZeroOperator;
987 kCheckedFloat64ToInt64DontCheckForMinusZeroOperator;
989 template <CheckForMinusZeroMode kMode>
991 :
public Operator1<CheckMinusZeroParameters> {
994 IrOpcode::kCheckedTaggedToInt32,
995 Operator::kFoldable | Operator::kNoThrow,
"CheckedTaggedToInt32",
1000 kCheckedTaggedToInt32CheckForMinusZeroOperator;
1002 kCheckedTaggedToInt32DontCheckForMinusZeroOperator;
1004 template <CheckForMinusZeroMode kMode>
1006 :
public Operator1<CheckMinusZeroParameters> {
1009 IrOpcode::kCheckedTaggedToInt64,
1010 Operator::kFoldable | Operator::kNoThrow,
"CheckedTaggedToInt64",
1015 kCheckedTaggedToInt64CheckForMinusZeroOperator;
1017 kCheckedTaggedToInt64DontCheckForMinusZeroOperator;
1019 template <CheckTaggedInputMode kMode>
1021 :
public Operator1<CheckTaggedInputParameters> {
1024 IrOpcode::kCheckedTaggedToFloat64,
1025 Operator::kFoldable | Operator::kNoThrow,
1026 "CheckedTaggedToFloat64", 1, 1, 1, 1, 1, 0,
1030 kCheckedTaggedToFloat64NumberOperator;
1032 kCheckedTaggedToFloat64NumberOrOddballOperator;
1034 template <CheckTaggedInputMode kMode>
1036 :
public Operator1<CheckTaggedInputParameters> {
1039 IrOpcode::kCheckedTruncateTaggedToWord32,
1040 Operator::kFoldable | Operator::kNoThrow,
1041 "CheckedTruncateTaggedToWord32", 1, 1, 1, 1, 1, 0,
1045 kCheckedTruncateTaggedToWord32NumberOperator;
1047 kCheckedTruncateTaggedToWord32NumberOrOddballOperator;
1049 template <ConvertReceiverMode kMode>
1053 IrOpcode::kConvertReceiver,
1054 Operator::kEliminatable,
1060 kConvertReceiverAnyOperator;
1062 kConvertReceiverNullOrUndefinedOperator;
1064 kConvertReceiverNotNullOrUndefinedOperator;
1066 template <CheckFloat64HoleMode kMode>
1068 :
public Operator1<CheckFloat64HoleParameters> {
1071 IrOpcode::kCheckFloat64Hole,
1072 Operator::kFoldable | Operator::kNoThrow,
"CheckFloat64Hole", 1,
1077 kCheckFloat64HoleAllowReturnHoleOperator;
1079 kCheckFloat64HoleNeverReturnHoleOperator;
1084 IrOpcode::kEnsureWritableFastElements,
1085 Operator::kNoDeopt | Operator::kNoThrow,
1086 "EnsureWritableFastElements",
1087 2, 1, 1, 1, 1, 0) {}
1091 template <GrowFastElementsMode kMode>
1093 :
public Operator1<GrowFastElementsParameters> {
1095 :
Operator1(IrOpcode::kMaybeGrowFastElements, Operator::kNoThrow,
1096 "MaybeGrowFastElements", 4, 1, 1, 1, 1, 0,
1101 kGrowFastElementsOperatorDoubleElements;
1103 kGrowFastElementsOperatorSmiOrObjectElements;
1108 IrOpcode::kLoadFieldByIndex,
1109 Operator::kEliminatable,
1111 2, 1, 1, 1, 1, 0) {}
1115 #define SPECULATIVE_NUMBER_BINOP(Name) \ 1116 template <NumberOperationHint kHint> \ 1117 struct Name##Operator final : public Operator1<NumberOperationHint> { \ 1119 : Operator1<NumberOperationHint>( \ 1120 IrOpcode::k##Name, Operator::kFoldable | Operator::kNoThrow, \ 1121 #Name, 2, 1, 1, 1, 1, 0, kHint) {} \ 1123 Name##Operator<NumberOperationHint::kSignedSmall> \ 1124 k##Name##SignedSmallOperator; \ 1125 Name##Operator<NumberOperationHint::kSignedSmallInputs> \ 1126 k##Name##SignedSmallInputsOperator; \ 1127 Name##Operator<NumberOperationHint::kSigned32> k##Name##Signed32Operator; \ 1128 Name##Operator<NumberOperationHint::kNumber> k##Name##NumberOperator; \ 1129 Name##Operator<NumberOperationHint::kNumberOrOddball> \ 1130 k##Name##NumberOrOddballOperator; 1131 SPECULATIVE_NUMBER_BINOP_LIST(SPECULATIVE_NUMBER_BINOP)
1132 #undef SPECULATIVE_NUMBER_BINOP 1134 template <NumberOperationH
int kH
int>
1136 :
public Operator1<NumberOperationParameters> {
1139 IrOpcode::kSpeculativeToNumber,
1140 Operator::kFoldable | Operator::kNoThrow,
"SpeculativeToNumber",
1145 kSpeculativeToNumberSignedSmallOperator;
1147 kSpeculativeToNumberSigned32Operator;
1149 kSpeculativeToNumberNumberOperator;
1151 kSpeculativeToNumberNumberOrOddballOperator;
1155 kSimplifiedOperatorGlobalCache = LAZY_INSTANCE_INITIALIZER;
1157 SimplifiedOperatorBuilder::SimplifiedOperatorBuilder(
Zone* zone)
1158 : cache_(kSimplifiedOperatorGlobalCache.Get()), zone_(zone) {}
1160 #define GET_FROM_CACHE(Name, ...) \ 1161 const Operator* SimplifiedOperatorBuilder::Name() { return &cache_.k##Name; } 1162 PURE_OP_LIST(GET_FROM_CACHE)
1163 EFFECT_DEPENDENT_OP_LIST(GET_FROM_CACHE)
1164 CHECKED_OP_LIST(GET_FROM_CACHE)
1165 GET_FROM_CACHE(ArgumentsFrame)
1166 GET_FROM_CACHE(FindOrderedHashMapEntry)
1167 GET_FROM_CACHE(FindOrderedHashMapEntryForInt32Key)
1168 GET_FROM_CACHE(LoadFieldByIndex)
1169 #undef GET_FROM_CACHE 1171 #define GET_FROM_CACHE_WITH_FEEDBACK(Name, value_input_count, \ 1172 value_output_count) \ 1173 const Operator* SimplifiedOperatorBuilder::Name( \ 1174 const VectorSlotPair& feedback) { \ 1175 if (!feedback.IsValid()) { \ 1176 return &cache_.k##Name; \ 1178 return new (zone()) Operator1<CheckParameters>( \ 1179 IrOpcode::k##Name, Operator::kFoldable | Operator::kNoThrow, #Name, \ 1180 value_input_count, 1, 1, value_output_count, 1, 0, \ 1181 CheckParameters(feedback)); \ 1183 CHECKED_WITH_FEEDBACK_OP_LIST(GET_FROM_CACHE_WITH_FEEDBACK)
1184 #undef GET_FROM_CACHE_WITH_FEEDBACK 1186 bool IsCheckedWithFeedback(
const Operator* op) {
1187 #define CASE(Name, ...) case IrOpcode::k##Name: 1188 switch (op->opcode()) {
1189 CHECKED_WITH_FEEDBACK_OP_LIST(CASE)
return true;
1196 const Operator* SimplifiedOperatorBuilder::RuntimeAbort(AbortReason reason) {
1197 return new (zone()) Operator1<int>(
1198 IrOpcode::kRuntimeAbort,
1199 Operator::kNoThrow | Operator::kNoDeopt,
1202 static_cast<int>(reason));
1205 const Operator* SimplifiedOperatorBuilder::CheckIf(
1206 DeoptimizeReason reason,
const VectorSlotPair& feedback) {
1207 if (!feedback.IsValid()) {
1209 #define CHECK_IF(Name, message) \ 1210 case DeoptimizeReason::k##Name: \ 1211 return &cache_.kCheckIf##Name; 1212 DEOPTIMIZE_REASON_LIST(CHECK_IF)
1216 return new (zone()) Operator1<CheckIfParameters>(
1217 IrOpcode::kCheckIf, Operator::kFoldable | Operator::kNoThrow,
"CheckIf",
1218 1, 1, 1, 0, 1, 0, CheckIfParameters(reason, feedback));
1221 const Operator* SimplifiedOperatorBuilder::ChangeFloat64ToTagged(
1222 CheckForMinusZeroMode mode) {
1224 case CheckForMinusZeroMode::kCheckForMinusZero:
1225 return &cache_.kChangeFloat64ToTaggedCheckForMinusZeroOperator;
1226 case CheckForMinusZeroMode::kDontCheckForMinusZero:
1227 return &cache_.kChangeFloat64ToTaggedDontCheckForMinusZeroOperator;
1232 const Operator* SimplifiedOperatorBuilder::CheckedInt32Mul(
1233 CheckForMinusZeroMode mode) {
1235 case CheckForMinusZeroMode::kCheckForMinusZero:
1236 return &cache_.kCheckedInt32MulCheckForMinusZeroOperator;
1237 case CheckForMinusZeroMode::kDontCheckForMinusZero:
1238 return &cache_.kCheckedInt32MulDontCheckForMinusZeroOperator;
1243 const Operator* SimplifiedOperatorBuilder::CheckedFloat64ToInt32(
1244 CheckForMinusZeroMode mode,
const VectorSlotPair& feedback) {
1245 if (!feedback.IsValid()) {
1247 case CheckForMinusZeroMode::kCheckForMinusZero:
1248 return &cache_.kCheckedFloat64ToInt32CheckForMinusZeroOperator;
1249 case CheckForMinusZeroMode::kDontCheckForMinusZero:
1250 return &cache_.kCheckedFloat64ToInt32DontCheckForMinusZeroOperator;
1253 return new (zone()) Operator1<CheckMinusZeroParameters>(
1254 IrOpcode::kCheckedFloat64ToInt32,
1255 Operator::kFoldable | Operator::kNoThrow,
"CheckedFloat64ToInt32", 1, 1,
1256 1, 1, 1, 0, CheckMinusZeroParameters(mode, feedback));
1259 const Operator* SimplifiedOperatorBuilder::CheckedFloat64ToInt64(
1260 CheckForMinusZeroMode mode,
const VectorSlotPair& feedback) {
1261 if (!feedback.IsValid()) {
1263 case CheckForMinusZeroMode::kCheckForMinusZero:
1264 return &cache_.kCheckedFloat64ToInt64CheckForMinusZeroOperator;
1265 case CheckForMinusZeroMode::kDontCheckForMinusZero:
1266 return &cache_.kCheckedFloat64ToInt64DontCheckForMinusZeroOperator;
1269 return new (zone()) Operator1<CheckMinusZeroParameters>(
1270 IrOpcode::kCheckedFloat64ToInt64,
1271 Operator::kFoldable | Operator::kNoThrow,
"CheckedFloat64ToInt64", 1, 1,
1272 1, 1, 1, 0, CheckMinusZeroParameters(mode, feedback));
1275 const Operator* SimplifiedOperatorBuilder::CheckedTaggedToInt32(
1276 CheckForMinusZeroMode mode,
const VectorSlotPair& feedback) {
1277 if (!feedback.IsValid()) {
1279 case CheckForMinusZeroMode::kCheckForMinusZero:
1280 return &cache_.kCheckedTaggedToInt32CheckForMinusZeroOperator;
1281 case CheckForMinusZeroMode::kDontCheckForMinusZero:
1282 return &cache_.kCheckedTaggedToInt32DontCheckForMinusZeroOperator;
1285 return new (zone()) Operator1<CheckMinusZeroParameters>(
1286 IrOpcode::kCheckedTaggedToInt32, Operator::kFoldable | Operator::kNoThrow,
1287 "CheckedTaggedToInt32", 1, 1, 1, 1, 1, 0,
1288 CheckMinusZeroParameters(mode, feedback));
1291 const Operator* SimplifiedOperatorBuilder::CheckedTaggedToInt64(
1292 CheckForMinusZeroMode mode,
const VectorSlotPair& feedback) {
1293 if (!feedback.IsValid()) {
1295 case CheckForMinusZeroMode::kCheckForMinusZero:
1296 return &cache_.kCheckedTaggedToInt64CheckForMinusZeroOperator;
1297 case CheckForMinusZeroMode::kDontCheckForMinusZero:
1298 return &cache_.kCheckedTaggedToInt64DontCheckForMinusZeroOperator;
1301 return new (zone()) Operator1<CheckMinusZeroParameters>(
1302 IrOpcode::kCheckedTaggedToInt64, Operator::kFoldable | Operator::kNoThrow,
1303 "CheckedTaggedToInt64", 1, 1, 1, 1, 1, 0,
1304 CheckMinusZeroParameters(mode, feedback));
1307 const Operator* SimplifiedOperatorBuilder::CheckedTaggedToFloat64(
1308 CheckTaggedInputMode mode,
const VectorSlotPair& feedback) {
1309 if (!feedback.IsValid()) {
1311 case CheckTaggedInputMode::kNumber:
1312 return &cache_.kCheckedTaggedToFloat64NumberOperator;
1313 case CheckTaggedInputMode::kNumberOrOddball:
1314 return &cache_.kCheckedTaggedToFloat64NumberOrOddballOperator;
1317 return new (zone()) Operator1<CheckTaggedInputParameters>(
1318 IrOpcode::kCheckedTaggedToFloat64,
1319 Operator::kFoldable | Operator::kNoThrow,
"CheckedTaggedToFloat64", 1, 1,
1320 1, 1, 1, 0, CheckTaggedInputParameters(mode, feedback));
1323 const Operator* SimplifiedOperatorBuilder::CheckedTruncateTaggedToWord32(
1324 CheckTaggedInputMode mode,
const VectorSlotPair& feedback) {
1325 if (!feedback.IsValid()) {
1327 case CheckTaggedInputMode::kNumber:
1328 return &cache_.kCheckedTruncateTaggedToWord32NumberOperator;
1329 case CheckTaggedInputMode::kNumberOrOddball:
1330 return &cache_.kCheckedTruncateTaggedToWord32NumberOrOddballOperator;
1333 return new (zone()) Operator1<CheckTaggedInputParameters>(
1334 IrOpcode::kCheckedTruncateTaggedToWord32,
1335 Operator::kFoldable | Operator::kNoThrow,
"CheckedTruncateTaggedToWord32",
1336 1, 1, 1, 1, 1, 0, CheckTaggedInputParameters(mode, feedback));
1339 const Operator* SimplifiedOperatorBuilder::CheckMaps(
1340 CheckMapsFlags flags, ZoneHandleSet<Map> maps,
1341 const VectorSlotPair& feedback) {
1342 CheckMapsParameters
const parameters(flags, maps, feedback);
1343 return new (zone()) Operator1<CheckMapsParameters>(
1344 IrOpcode::kCheckMaps,
1345 Operator::kNoThrow | Operator::kNoWrite,
1351 const Operator* SimplifiedOperatorBuilder::MapGuard(ZoneHandleSet<Map> maps) {
1352 return new (zone()) Operator1<MapsParameterInfo>(
1353 IrOpcode::kMapGuard, Operator::kEliminatable,
1356 MapsParameterInfo(maps));
1359 const Operator* SimplifiedOperatorBuilder::CompareMaps(
1360 ZoneHandleSet<Map> maps) {
1361 return new (zone()) Operator1<MapsParameterInfo>(
1362 IrOpcode::kCompareMaps,
1363 Operator::kEliminatable,
1366 MapsParameterInfo(maps));
1369 const Operator* SimplifiedOperatorBuilder::ConvertReceiver(
1370 ConvertReceiverMode mode) {
1372 case ConvertReceiverMode::kAny:
1373 return &cache_.kConvertReceiverAnyOperator;
1374 case ConvertReceiverMode::kNullOrUndefined:
1375 return &cache_.kConvertReceiverNullOrUndefinedOperator;
1376 case ConvertReceiverMode::kNotNullOrUndefined:
1377 return &cache_.kConvertReceiverNotNullOrUndefinedOperator;
1383 const Operator* SimplifiedOperatorBuilder::CheckFloat64Hole(
1384 CheckFloat64HoleMode mode, VectorSlotPair
const& feedback) {
1385 if (!feedback.IsValid()) {
1387 case CheckFloat64HoleMode::kAllowReturnHole:
1388 return &cache_.kCheckFloat64HoleAllowReturnHoleOperator;
1389 case CheckFloat64HoleMode::kNeverReturnHole:
1390 return &cache_.kCheckFloat64HoleNeverReturnHoleOperator;
1394 return new (zone()) Operator1<CheckFloat64HoleParameters>(
1395 IrOpcode::kCheckFloat64Hole, Operator::kFoldable | Operator::kNoThrow,
1396 "CheckFloat64Hole", 1, 1, 1, 1, 1, 0,
1397 CheckFloat64HoleParameters(mode, feedback));
1400 const Operator* SimplifiedOperatorBuilder::SpeculativeToNumber(
1401 NumberOperationHint hint,
const VectorSlotPair& feedback) {
1402 if (!feedback.IsValid()) {
1404 case NumberOperationHint::kSignedSmall:
1405 return &cache_.kSpeculativeToNumberSignedSmallOperator;
1406 case NumberOperationHint::kSignedSmallInputs:
1408 case NumberOperationHint::kSigned32:
1409 return &cache_.kSpeculativeToNumberSigned32Operator;
1410 case NumberOperationHint::kNumber:
1411 return &cache_.kSpeculativeToNumberNumberOperator;
1412 case NumberOperationHint::kNumberOrOddball:
1413 return &cache_.kSpeculativeToNumberNumberOrOddballOperator;
1416 return new (zone()) Operator1<NumberOperationParameters>(
1417 IrOpcode::kSpeculativeToNumber, Operator::kFoldable | Operator::kNoThrow,
1418 "SpeculativeToNumber", 1, 1, 1, 1, 1, 0,
1419 NumberOperationParameters(hint, feedback));
1422 const Operator* SimplifiedOperatorBuilder::EnsureWritableFastElements() {
1423 return &cache_.kEnsureWritableFastElements;
1426 const Operator* SimplifiedOperatorBuilder::MaybeGrowFastElements(
1427 GrowFastElementsMode mode,
const VectorSlotPair& feedback) {
1428 if (!feedback.IsValid()) {
1430 case GrowFastElementsMode::kDoubleElements:
1431 return &cache_.kGrowFastElementsOperatorDoubleElements;
1432 case GrowFastElementsMode::kSmiOrObjectElements:
1433 return &cache_.kGrowFastElementsOperatorSmiOrObjectElements;
1436 return new (zone()) Operator1<GrowFastElementsParameters>(
1437 IrOpcode::kMaybeGrowFastElements,
1439 "MaybeGrowFastElements",
1441 GrowFastElementsParameters(mode, feedback));
1444 const Operator* SimplifiedOperatorBuilder::TransitionElementsKind(
1445 ElementsTransition transition) {
1446 return new (zone()) Operator1<ElementsTransition>(
1447 IrOpcode::kTransitionElementsKind,
1448 Operator::kNoDeopt | Operator::kNoThrow,
1449 "TransitionElementsKind",
1456 struct ArgumentsLengthParameters {
1457 int formal_parameter_count;
1458 bool is_rest_length;
1461 bool operator==(ArgumentsLengthParameters first,
1462 ArgumentsLengthParameters second) {
1463 return first.formal_parameter_count == second.formal_parameter_count &&
1464 first.is_rest_length == second.is_rest_length;
1467 size_t hash_value(ArgumentsLengthParameters param) {
1468 return base::hash_combine(param.formal_parameter_count, param.is_rest_length);
1471 std::ostream& operator<<(std::ostream& os, ArgumentsLengthParameters param) {
1472 return os << param.formal_parameter_count <<
", " 1473 << (param.is_rest_length ?
"rest length" :
"not rest length");
1478 const Operator* SimplifiedOperatorBuilder::ArgumentsLength(
1479 int formal_parameter_count,
bool is_rest_length) {
1480 return new (zone()) Operator1<ArgumentsLengthParameters>(
1481 IrOpcode::kArgumentsLength,
1485 ArgumentsLengthParameters{formal_parameter_count,
1489 int FormalParameterCountOf(
const Operator* op) {
1490 DCHECK_EQ(IrOpcode::kArgumentsLength, op->opcode());
1491 return OpParameter<ArgumentsLengthParameters>(op).formal_parameter_count;
1494 bool IsRestLengthOf(
const Operator* op) {
1495 DCHECK_EQ(IrOpcode::kArgumentsLength, op->opcode());
1496 return OpParameter<ArgumentsLengthParameters>(op).is_rest_length;
1499 bool operator==(CheckParameters
const& lhs, CheckParameters
const& rhs) {
1500 return lhs.feedback() == rhs.feedback();
1503 size_t hash_value(CheckParameters
const& p) {
return hash_value(p.feedback()); }
1505 std::ostream& operator<<(std::ostream& os, CheckParameters
const& p) {
1506 return os << p.feedback();
1509 CheckParameters
const& CheckParametersOf(Operator
const* op) {
1510 #define MAKE_OR(name, arg2, arg3) op->opcode() == IrOpcode::k##name || 1511 CHECK((CHECKED_WITH_FEEDBACK_OP_LIST(MAKE_OR)
false));
1513 return OpParameter<CheckParameters>(op);
1516 bool operator==(CheckIfParameters
const& lhs, CheckIfParameters
const& rhs) {
1517 return lhs.reason() == rhs.reason() && lhs.feedback() == rhs.feedback();
1520 size_t hash_value(CheckIfParameters
const& p) {
1521 return base::hash_combine(p.reason(), p.feedback());
1524 std::ostream& operator<<(std::ostream& os, CheckIfParameters
const& p) {
1525 return os << p.reason() << p.feedback();
1528 CheckIfParameters
const& CheckIfParametersOf(Operator
const* op) {
1529 CHECK(op->opcode() == IrOpcode::kCheckIf);
1530 return OpParameter<CheckIfParameters>(op);
1533 const Operator* SimplifiedOperatorBuilder::NewDoubleElements(
1534 PretenureFlag pretenure) {
1535 return new (zone()) Operator1<PretenureFlag>(
1536 IrOpcode::kNewDoubleElements,
1537 Operator::kEliminatable,
1538 "NewDoubleElements",
1543 const Operator* SimplifiedOperatorBuilder::NewSmiOrObjectElements(
1544 PretenureFlag pretenure) {
1545 return new (zone()) Operator1<PretenureFlag>(
1546 IrOpcode::kNewSmiOrObjectElements,
1547 Operator::kEliminatable,
1548 "NewSmiOrObjectElements",
1553 const Operator* SimplifiedOperatorBuilder::NewArgumentsElements(
1555 return new (zone()) Operator1<int>(
1556 IrOpcode::kNewArgumentsElements,
1557 Operator::kEliminatable,
1558 "NewArgumentsElements",
1563 int NewArgumentsElementsMappedCountOf(
const Operator* op) {
1564 DCHECK_EQ(IrOpcode::kNewArgumentsElements, op->opcode());
1565 return OpParameter<int>(op);
1568 const Operator* SimplifiedOperatorBuilder::Allocate(
Type type,
1569 PretenureFlag pretenure) {
1570 return new (zone()) Operator1<AllocateParameters>(
1571 IrOpcode::kAllocate,
1572 Operator::kNoDeopt | Operator::kNoThrow | Operator::kNoWrite,
"Allocate",
1573 1, 1, 1, 1, 1, 0, AllocateParameters(type, pretenure));
1576 const Operator* SimplifiedOperatorBuilder::AllocateRaw(
1577 Type type, PretenureFlag pretenure) {
1578 return new (zone()) Operator1<AllocateParameters>(
1579 IrOpcode::kAllocateRaw,
1580 Operator::kNoDeopt | Operator::kNoThrow | Operator::kNoWrite,
1581 "AllocateRaw", 1, 1, 1, 1, 1, 1, AllocateParameters(type, pretenure));
1584 const Operator* SimplifiedOperatorBuilder::StringCodePointAt(
1585 UnicodeEncoding encoding) {
1587 case UnicodeEncoding::UTF16:
1588 return &cache_.kStringCodePointAtOperatorUTF16;
1589 case UnicodeEncoding::UTF32:
1590 return &cache_.kStringCodePointAtOperatorUTF32;
1595 const Operator* SimplifiedOperatorBuilder::StringFromSingleCodePoint(
1596 UnicodeEncoding encoding) {
1598 case UnicodeEncoding::UTF16:
1599 return &cache_.kStringFromSingleCodePointOperatorUTF16;
1600 case UnicodeEncoding::UTF32:
1601 return &cache_.kStringFromSingleCodePointOperatorUTF32;
1606 #define SPECULATIVE_NUMBER_BINOP(Name) \ 1607 const Operator* SimplifiedOperatorBuilder::Name(NumberOperationHint hint) { \ 1609 case NumberOperationHint::kSignedSmall: \ 1610 return &cache_.k##Name##SignedSmallOperator; \ 1611 case NumberOperationHint::kSignedSmallInputs: \ 1612 return &cache_.k##Name##SignedSmallInputsOperator; \ 1613 case NumberOperationHint::kSigned32: \ 1614 return &cache_.k##Name##Signed32Operator; \ 1615 case NumberOperationHint::kNumber: \ 1616 return &cache_.k##Name##NumberOperator; \ 1617 case NumberOperationHint::kNumberOrOddball: \ 1618 return &cache_.k##Name##NumberOrOddballOperator; \ 1623 SPECULATIVE_NUMBER_BINOP_LIST(SPECULATIVE_NUMBER_BINOP)
1624 #undef SPECULATIVE_NUMBER_BINOP 1626 #define ACCESS_OP_LIST(V) \ 1627 V(LoadField, FieldAccess, Operator::kNoWrite, 1, 1, 1) \ 1628 V(StoreField, FieldAccess, Operator::kNoRead, 2, 1, 0) \ 1629 V(LoadElement, ElementAccess, Operator::kNoWrite, 2, 1, 1) \ 1630 V(StoreElement, ElementAccess, Operator::kNoRead, 3, 1, 0) \ 1631 V(LoadTypedElement, ExternalArrayType, Operator::kNoWrite, 4, 1, 1) \ 1632 V(StoreTypedElement, ExternalArrayType, Operator::kNoRead, 5, 1, 0) \ 1633 V(LoadDataViewElement, ExternalArrayType, Operator::kNoWrite, 5, 1, 1) \ 1634 V(StoreDataViewElement, ExternalArrayType, Operator::kNoRead, 6, 1, 0) 1636 #define ACCESS(Name, Type, properties, value_input_count, control_input_count, \ 1638 const Operator* SimplifiedOperatorBuilder::Name(const Type& access) { \ 1639 return new (zone()) \ 1640 Operator1<Type>(IrOpcode::k##Name, \ 1641 Operator::kNoDeopt | Operator::kNoThrow | properties, \ 1642 #Name, value_input_count, 1, control_input_count, \ 1643 output_count, 1, 0, access); \ 1645 ACCESS_OP_LIST(ACCESS)
1648 const Operator* SimplifiedOperatorBuilder::TransitionAndStoreElement(
1649 Handle<Map> double_map, Handle<Map> fast_map) {
1650 TransitionAndStoreElementParameters parameters(double_map, fast_map);
1651 return new (zone()) Operator1<TransitionAndStoreElementParameters>(
1652 IrOpcode::kTransitionAndStoreElement,
1653 Operator::kNoDeopt | Operator::kNoThrow,
"TransitionAndStoreElement", 3,
1654 1, 1, 0, 1, 0, parameters);
1657 const Operator* SimplifiedOperatorBuilder::StoreSignedSmallElement() {
1658 return new (zone()) Operator(IrOpcode::kStoreSignedSmallElement,
1659 Operator::kNoDeopt | Operator::kNoThrow,
1660 "StoreSignedSmallElement", 3, 1, 1, 0, 1, 0);
1663 const Operator* SimplifiedOperatorBuilder::TransitionAndStoreNumberElement(
1664 Handle<Map> double_map) {
1665 TransitionAndStoreNumberElementParameters parameters(double_map);
1666 return new (zone()) Operator1<TransitionAndStoreNumberElementParameters>(
1667 IrOpcode::kTransitionAndStoreNumberElement,
1668 Operator::kNoDeopt | Operator::kNoThrow,
1669 "TransitionAndStoreNumberElement", 3, 1, 1, 0, 1, 0, parameters);
1672 const Operator* SimplifiedOperatorBuilder::TransitionAndStoreNonNumberElement(
1673 Handle<Map> fast_map,
Type value_type) {
1674 TransitionAndStoreNonNumberElementParameters parameters(fast_map, value_type);
1675 return new (zone()) Operator1<TransitionAndStoreNonNumberElementParameters>(
1676 IrOpcode::kTransitionAndStoreNonNumberElement,
1677 Operator::kNoDeopt | Operator::kNoThrow,
1678 "TransitionAndStoreNonNumberElement", 3, 1, 1, 0, 1, 0, parameters);
1682 #undef EFFECT_DEPENDENT_OP_LIST 1683 #undef SPECULATIVE_NUMBER_BINOP_LIST 1684 #undef CHECKED_WITH_FEEDBACK_OP_LIST 1685 #undef CHECKED_OP_LIST 1686 #undef ACCESS_OP_LIST