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
3 // found in the LICENSE file.
4
5 #include "src/compiler/simplified-operator.h"
6
7 #include "include/v8-fast-api-calls.h"
8 #include "src/base/lazy-instance.h"
9 #include "src/compiler/opcodes.h"
10 #include "src/compiler/operator.h"
11 #include "src/compiler/types.h"
12 #include "src/handles/handles-inl.h"
13 #include "src/objects/feedback-cell.h"
14 #include "src/objects/map.h"
15 #include "src/objects/name.h"
16 #include "src/objects/objects-inl.h"
17
18 namespace v8 {
19 namespace internal {
20 namespace compiler {
21
hash_value(BaseTaggedness base_taggedness)22 size_t hash_value(BaseTaggedness base_taggedness) {
23 return static_cast<uint8_t>(base_taggedness);
24 }
25
operator <<(std::ostream & os,BaseTaggedness base_taggedness)26 std::ostream& operator<<(std::ostream& os, BaseTaggedness base_taggedness) {
27 switch (base_taggedness) {
28 case kUntaggedBase:
29 return os << "untagged base";
30 case kTaggedBase:
31 return os << "tagged base";
32 }
33 UNREACHABLE();
34 }
35
operator <<(std::ostream & os,ConstFieldInfo const & const_field_info)36 std::ostream& operator<<(std::ostream& os,
37 ConstFieldInfo const& const_field_info) {
38 if (const_field_info.IsConst()) {
39 return os << "const (field owner: " << const_field_info.owner_map.address()
40 << ")";
41 } else {
42 return os << "mutable";
43 }
44 UNREACHABLE();
45 }
46
operator ==(ConstFieldInfo const & lhs,ConstFieldInfo const & rhs)47 bool operator==(ConstFieldInfo const& lhs, ConstFieldInfo const& rhs) {
48 return lhs.owner_map.address() == rhs.owner_map.address();
49 }
50
hash_value(ConstFieldInfo const & const_field_info)51 size_t hash_value(ConstFieldInfo const& const_field_info) {
52 return (size_t)const_field_info.owner_map.address();
53 }
54
operator ==(FieldAccess const & lhs,FieldAccess const & rhs)55 bool operator==(FieldAccess const& lhs, FieldAccess const& rhs) {
56 // On purpose we don't include the write barrier kind here, as this method is
57 // really only relevant for eliminating loads and they don't care about the
58 // write barrier mode.
59 return lhs.base_is_tagged == rhs.base_is_tagged && lhs.offset == rhs.offset &&
60 lhs.map.address() == rhs.map.address() &&
61 lhs.machine_type == rhs.machine_type &&
62 lhs.const_field_info == rhs.const_field_info &&
63 lhs.is_store_in_literal == rhs.is_store_in_literal;
64 }
65
hash_value(FieldAccess const & access)66 size_t hash_value(FieldAccess const& access) {
67 // On purpose we don't include the write barrier kind here, as this method is
68 // really only relevant for eliminating loads and they don't care about the
69 // write barrier mode.
70 return base::hash_combine(access.base_is_tagged, access.offset,
71 access.machine_type, access.const_field_info,
72 access.is_store_in_literal);
73 }
74
hash_value(LoadSensitivity load_sensitivity)75 size_t hash_value(LoadSensitivity load_sensitivity) {
76 return static_cast<size_t>(load_sensitivity);
77 }
78
operator <<(std::ostream & os,LoadSensitivity load_sensitivity)79 std::ostream& operator<<(std::ostream& os, LoadSensitivity load_sensitivity) {
80 switch (load_sensitivity) {
81 case LoadSensitivity::kCritical:
82 return os << "Critical";
83 case LoadSensitivity::kSafe:
84 return os << "Safe";
85 case LoadSensitivity::kUnsafe:
86 return os << "Unsafe";
87 }
88 UNREACHABLE();
89 }
90
operator <<(std::ostream & os,FieldAccess const & access)91 std::ostream& operator<<(std::ostream& os, FieldAccess const& access) {
92 os << "[" << access.base_is_tagged << ", " << access.offset << ", ";
93 #ifdef OBJECT_PRINT
94 Handle<Name> name;
95 if (access.name.ToHandle(&name)) {
96 name->NamePrint(os);
97 os << ", ";
98 }
99 Handle<Map> map;
100 if (access.map.ToHandle(&map)) {
101 os << Brief(*map) << ", ";
102 }
103 #endif
104 os << access.type << ", " << access.machine_type << ", "
105 << access.write_barrier_kind << ", " << access.const_field_info;
106 if (access.is_store_in_literal) {
107 os << " (store in literal)";
108 }
109 if (FLAG_untrusted_code_mitigations) {
110 os << ", " << access.load_sensitivity;
111 }
112 os << "]";
113 return os;
114 }
115
116 template <>
PrintParameter(std::ostream & os,PrintVerbosity verbose) const117 void Operator1<FieldAccess>::PrintParameter(std::ostream& os,
118 PrintVerbosity verbose) const {
119 if (verbose == PrintVerbosity::kVerbose) {
120 os << parameter();
121 } else {
122 os << "[+" << parameter().offset << "]";
123 }
124 }
125
operator ==(ElementAccess const & lhs,ElementAccess const & rhs)126 bool operator==(ElementAccess const& lhs, ElementAccess const& rhs) {
127 // On purpose we don't include the write barrier kind here, as this method is
128 // really only relevant for eliminating loads and they don't care about the
129 // write barrier mode.
130 return lhs.base_is_tagged == rhs.base_is_tagged &&
131 lhs.header_size == rhs.header_size &&
132 lhs.machine_type == rhs.machine_type;
133 }
134
hash_value(ElementAccess const & access)135 size_t hash_value(ElementAccess const& access) {
136 // On purpose we don't include the write barrier kind here, as this method is
137 // really only relevant for eliminating loads and they don't care about the
138 // write barrier mode.
139 return base::hash_combine(access.base_is_tagged, access.header_size,
140 access.machine_type);
141 }
142
operator <<(std::ostream & os,ElementAccess const & access)143 std::ostream& operator<<(std::ostream& os, ElementAccess const& access) {
144 os << access.base_is_tagged << ", " << access.header_size << ", "
145 << access.type << ", " << access.machine_type << ", "
146 << access.write_barrier_kind;
147 if (FLAG_untrusted_code_mitigations) {
148 os << ", " << access.load_sensitivity;
149 }
150 return os;
151 }
152
operator ==(ObjectAccess const & lhs,ObjectAccess const & rhs)153 bool operator==(ObjectAccess const& lhs, ObjectAccess const& rhs) {
154 return lhs.machine_type == rhs.machine_type &&
155 lhs.write_barrier_kind == rhs.write_barrier_kind;
156 }
157
hash_value(ObjectAccess const & access)158 size_t hash_value(ObjectAccess const& access) {
159 return base::hash_combine(access.machine_type, access.write_barrier_kind);
160 }
161
operator <<(std::ostream & os,ObjectAccess const & access)162 std::ostream& operator<<(std::ostream& os, ObjectAccess const& access) {
163 os << access.machine_type << ", " << access.write_barrier_kind;
164 return os;
165 }
166
FieldAccessOf(const Operator * op)167 const FieldAccess& FieldAccessOf(const Operator* op) {
168 DCHECK_NOT_NULL(op);
169 DCHECK(op->opcode() == IrOpcode::kLoadField ||
170 op->opcode() == IrOpcode::kStoreField);
171 return OpParameter<FieldAccess>(op);
172 }
173
ElementAccessOf(const Operator * op)174 const ElementAccess& ElementAccessOf(const Operator* op) {
175 DCHECK_NOT_NULL(op);
176 DCHECK(op->opcode() == IrOpcode::kLoadElement ||
177 op->opcode() == IrOpcode::kStoreElement);
178 return OpParameter<ElementAccess>(op);
179 }
180
ObjectAccessOf(const Operator * op)181 const ObjectAccess& ObjectAccessOf(const Operator* op) {
182 DCHECK_NOT_NULL(op);
183 DCHECK(op->opcode() == IrOpcode::kLoadFromObject ||
184 op->opcode() == IrOpcode::kStoreToObject);
185 return OpParameter<ObjectAccess>(op);
186 }
187
ExternalArrayTypeOf(const Operator * op)188 ExternalArrayType ExternalArrayTypeOf(const Operator* op) {
189 DCHECK(op->opcode() == IrOpcode::kLoadTypedElement ||
190 op->opcode() == IrOpcode::kLoadDataViewElement ||
191 op->opcode() == IrOpcode::kStoreTypedElement ||
192 op->opcode() == IrOpcode::kStoreDataViewElement);
193 return OpParameter<ExternalArrayType>(op);
194 }
195
ConvertReceiverModeOf(Operator const * op)196 ConvertReceiverMode ConvertReceiverModeOf(Operator const* op) {
197 DCHECK_EQ(IrOpcode::kConvertReceiver, op->opcode());
198 return OpParameter<ConvertReceiverMode>(op);
199 }
200
hash_value(CheckFloat64HoleMode mode)201 size_t hash_value(CheckFloat64HoleMode mode) {
202 return static_cast<size_t>(mode);
203 }
204
operator <<(std::ostream & os,CheckFloat64HoleMode mode)205 std::ostream& operator<<(std::ostream& os, CheckFloat64HoleMode mode) {
206 switch (mode) {
207 case CheckFloat64HoleMode::kAllowReturnHole:
208 return os << "allow-return-hole";
209 case CheckFloat64HoleMode::kNeverReturnHole:
210 return os << "never-return-hole";
211 }
212 UNREACHABLE();
213 }
214
CheckFloat64HoleParametersOf(Operator const * op)215 CheckFloat64HoleParameters const& CheckFloat64HoleParametersOf(
216 Operator const* op) {
217 DCHECK_EQ(IrOpcode::kCheckFloat64Hole, op->opcode());
218 return OpParameter<CheckFloat64HoleParameters>(op);
219 }
220
operator <<(std::ostream & os,CheckFloat64HoleParameters const & params)221 std::ostream& operator<<(std::ostream& os,
222 CheckFloat64HoleParameters const& params) {
223 return os << params.mode() << ", " << params.feedback();
224 }
225
hash_value(const CheckFloat64HoleParameters & params)226 size_t hash_value(const CheckFloat64HoleParameters& params) {
227 FeedbackSource::Hash feedback_hash;
228 return base::hash_combine(params.mode(), feedback_hash(params.feedback()));
229 }
230
operator ==(CheckFloat64HoleParameters const & lhs,CheckFloat64HoleParameters const & rhs)231 bool operator==(CheckFloat64HoleParameters const& lhs,
232 CheckFloat64HoleParameters const& rhs) {
233 return lhs.mode() == rhs.mode() && lhs.feedback() == rhs.feedback();
234 }
235
operator !=(CheckFloat64HoleParameters const & lhs,CheckFloat64HoleParameters const & rhs)236 bool operator!=(CheckFloat64HoleParameters const& lhs,
237 CheckFloat64HoleParameters const& rhs) {
238 return !(lhs == rhs);
239 }
240
CheckMinusZeroModeOf(const Operator * op)241 CheckForMinusZeroMode CheckMinusZeroModeOf(const Operator* op) {
242 DCHECK(op->opcode() == IrOpcode::kChangeFloat64ToTagged ||
243 op->opcode() == IrOpcode::kCheckedInt32Mul);
244 return OpParameter<CheckForMinusZeroMode>(op);
245 }
246
hash_value(CheckForMinusZeroMode mode)247 size_t hash_value(CheckForMinusZeroMode mode) {
248 return static_cast<size_t>(mode);
249 }
250
operator <<(std::ostream & os,CheckForMinusZeroMode mode)251 std::ostream& operator<<(std::ostream& os, CheckForMinusZeroMode mode) {
252 switch (mode) {
253 case CheckForMinusZeroMode::kCheckForMinusZero:
254 return os << "check-for-minus-zero";
255 case CheckForMinusZeroMode::kDontCheckForMinusZero:
256 return os << "dont-check-for-minus-zero";
257 }
258 UNREACHABLE();
259 }
260
operator <<(std::ostream & os,CheckMapsFlags flags)261 std::ostream& operator<<(std::ostream& os, CheckMapsFlags flags) {
262 if (flags & CheckMapsFlag::kTryMigrateInstance) {
263 return os << "TryMigrateInstance";
264 } else {
265 return os << "None";
266 }
267 }
268
operator ==(CheckMapsParameters const & lhs,CheckMapsParameters const & rhs)269 bool operator==(CheckMapsParameters const& lhs,
270 CheckMapsParameters const& rhs) {
271 return lhs.flags() == rhs.flags() && lhs.maps() == rhs.maps() &&
272 lhs.feedback() == rhs.feedback();
273 }
274
hash_value(CheckMapsParameters const & p)275 size_t hash_value(CheckMapsParameters const& p) {
276 FeedbackSource::Hash feedback_hash;
277 return base::hash_combine(p.flags(), p.maps(), feedback_hash(p.feedback()));
278 }
279
operator <<(std::ostream & os,CheckMapsParameters const & p)280 std::ostream& operator<<(std::ostream& os, CheckMapsParameters const& p) {
281 return os << p.flags() << ", " << p.maps() << ", " << p.feedback();
282 }
283
CheckMapsParametersOf(Operator const * op)284 CheckMapsParameters const& CheckMapsParametersOf(Operator const* op) {
285 DCHECK_EQ(IrOpcode::kCheckMaps, op->opcode());
286 return OpParameter<CheckMapsParameters>(op);
287 }
288
CompareMapsParametersOf(Operator const * op)289 ZoneHandleSet<Map> const& CompareMapsParametersOf(Operator const* op) {
290 DCHECK_EQ(IrOpcode::kCompareMaps, op->opcode());
291 return OpParameter<ZoneHandleSet<Map>>(op);
292 }
293
MapGuardMapsOf(Operator const * op)294 ZoneHandleSet<Map> const& MapGuardMapsOf(Operator const* op) {
295 DCHECK_EQ(IrOpcode::kMapGuard, op->opcode());
296 return OpParameter<ZoneHandleSet<Map>>(op);
297 }
298
hash_value(CheckTaggedInputMode mode)299 size_t hash_value(CheckTaggedInputMode mode) {
300 return static_cast<size_t>(mode);
301 }
302
operator <<(std::ostream & os,CheckTaggedInputMode mode)303 std::ostream& operator<<(std::ostream& os, CheckTaggedInputMode mode) {
304 switch (mode) {
305 case CheckTaggedInputMode::kNumber:
306 return os << "Number";
307 case CheckTaggedInputMode::kNumberOrOddball:
308 return os << "NumberOrOddball";
309 }
310 UNREACHABLE();
311 }
312
operator <<(std::ostream & os,GrowFastElementsMode mode)313 std::ostream& operator<<(std::ostream& os, GrowFastElementsMode mode) {
314 switch (mode) {
315 case GrowFastElementsMode::kDoubleElements:
316 return os << "DoubleElements";
317 case GrowFastElementsMode::kSmiOrObjectElements:
318 return os << "SmiOrObjectElements";
319 }
320 UNREACHABLE();
321 }
322
operator ==(const GrowFastElementsParameters & lhs,const GrowFastElementsParameters & rhs)323 bool operator==(const GrowFastElementsParameters& lhs,
324 const GrowFastElementsParameters& rhs) {
325 return lhs.mode() == rhs.mode() && lhs.feedback() == rhs.feedback();
326 }
327
hash_value(const GrowFastElementsParameters & params)328 inline size_t hash_value(const GrowFastElementsParameters& params) {
329 FeedbackSource::Hash feedback_hash;
330 return base::hash_combine(params.mode(), feedback_hash(params.feedback()));
331 }
332
operator <<(std::ostream & os,const GrowFastElementsParameters & params)333 std::ostream& operator<<(std::ostream& os,
334 const GrowFastElementsParameters& params) {
335 return os << params.mode() << ", " << params.feedback();
336 }
337
GrowFastElementsParametersOf(const Operator * op)338 const GrowFastElementsParameters& GrowFastElementsParametersOf(
339 const Operator* op) {
340 DCHECK_EQ(IrOpcode::kMaybeGrowFastElements, op->opcode());
341 return OpParameter<GrowFastElementsParameters>(op);
342 }
343
operator ==(ElementsTransition const & lhs,ElementsTransition const & rhs)344 bool operator==(ElementsTransition const& lhs, ElementsTransition const& rhs) {
345 return lhs.mode() == rhs.mode() &&
346 lhs.source().address() == rhs.source().address() &&
347 lhs.target().address() == rhs.target().address();
348 }
349
hash_value(ElementsTransition transition)350 size_t hash_value(ElementsTransition transition) {
351 return base::hash_combine(static_cast<uint8_t>(transition.mode()),
352 transition.source().address(),
353 transition.target().address());
354 }
355
operator <<(std::ostream & os,ElementsTransition transition)356 std::ostream& operator<<(std::ostream& os, ElementsTransition transition) {
357 switch (transition.mode()) {
358 case ElementsTransition::kFastTransition:
359 return os << "fast-transition from " << Brief(*transition.source())
360 << " to " << Brief(*transition.target());
361 case ElementsTransition::kSlowTransition:
362 return os << "slow-transition from " << Brief(*transition.source())
363 << " to " << Brief(*transition.target());
364 }
365 UNREACHABLE();
366 }
367
ElementsTransitionOf(const Operator * op)368 ElementsTransition const& ElementsTransitionOf(const Operator* op) {
369 DCHECK_EQ(IrOpcode::kTransitionElementsKind, op->opcode());
370 return OpParameter<ElementsTransition>(op);
371 }
372
373 namespace {
374
375 // Parameters for the TransitionAndStoreElement opcode.
376 class TransitionAndStoreElementParameters final {
377 public:
378 TransitionAndStoreElementParameters(Handle<Map> double_map,
379 Handle<Map> fast_map);
380
double_map() const381 Handle<Map> double_map() const { return double_map_; }
fast_map() const382 Handle<Map> fast_map() const { return fast_map_; }
383
384 private:
385 Handle<Map> const double_map_;
386 Handle<Map> const fast_map_;
387 };
388
TransitionAndStoreElementParameters(Handle<Map> double_map,Handle<Map> fast_map)389 TransitionAndStoreElementParameters::TransitionAndStoreElementParameters(
390 Handle<Map> double_map, Handle<Map> fast_map)
391 : double_map_(double_map), fast_map_(fast_map) {}
392
operator ==(TransitionAndStoreElementParameters const & lhs,TransitionAndStoreElementParameters const & rhs)393 bool operator==(TransitionAndStoreElementParameters const& lhs,
394 TransitionAndStoreElementParameters const& rhs) {
395 return lhs.fast_map().address() == rhs.fast_map().address() &&
396 lhs.double_map().address() == rhs.double_map().address();
397 }
398
hash_value(TransitionAndStoreElementParameters parameters)399 size_t hash_value(TransitionAndStoreElementParameters parameters) {
400 return base::hash_combine(parameters.fast_map().address(),
401 parameters.double_map().address());
402 }
403
operator <<(std::ostream & os,TransitionAndStoreElementParameters parameters)404 std::ostream& operator<<(std::ostream& os,
405 TransitionAndStoreElementParameters parameters) {
406 return os << "fast-map" << Brief(*parameters.fast_map()) << " double-map"
407 << Brief(*parameters.double_map());
408 }
409
410 } // namespace
411
412 namespace {
413
414 // Parameters for the TransitionAndStoreNonNumberElement opcode.
415 class TransitionAndStoreNonNumberElementParameters final {
416 public:
417 TransitionAndStoreNonNumberElementParameters(Handle<Map> fast_map,
418 Type value_type);
419
fast_map() const420 Handle<Map> fast_map() const { return fast_map_; }
value_type() const421 Type value_type() const { return value_type_; }
422
423 private:
424 Handle<Map> const fast_map_;
425 Type value_type_;
426 };
427
428 TransitionAndStoreNonNumberElementParameters::
TransitionAndStoreNonNumberElementParameters(Handle<Map> fast_map,Type value_type)429 TransitionAndStoreNonNumberElementParameters(Handle<Map> fast_map,
430 Type value_type)
431 : fast_map_(fast_map), value_type_(value_type) {}
432
operator ==(TransitionAndStoreNonNumberElementParameters const & lhs,TransitionAndStoreNonNumberElementParameters const & rhs)433 bool operator==(TransitionAndStoreNonNumberElementParameters const& lhs,
434 TransitionAndStoreNonNumberElementParameters const& rhs) {
435 return lhs.fast_map().address() == rhs.fast_map().address() &&
436 lhs.value_type() == rhs.value_type();
437 }
438
hash_value(TransitionAndStoreNonNumberElementParameters parameters)439 size_t hash_value(TransitionAndStoreNonNumberElementParameters parameters) {
440 return base::hash_combine(parameters.fast_map().address(),
441 parameters.value_type());
442 }
443
operator <<(std::ostream & os,TransitionAndStoreNonNumberElementParameters parameters)444 std::ostream& operator<<(
445 std::ostream& os, TransitionAndStoreNonNumberElementParameters parameters) {
446 return os << parameters.value_type() << ", fast-map"
447 << Brief(*parameters.fast_map());
448 }
449
450 } // namespace
451
452 namespace {
453
454 // Parameters for the TransitionAndStoreNumberElement opcode.
455 class TransitionAndStoreNumberElementParameters final {
456 public:
457 explicit TransitionAndStoreNumberElementParameters(Handle<Map> double_map);
458
double_map() const459 Handle<Map> double_map() const { return double_map_; }
460
461 private:
462 Handle<Map> const double_map_;
463 };
464
465 TransitionAndStoreNumberElementParameters::
TransitionAndStoreNumberElementParameters(Handle<Map> double_map)466 TransitionAndStoreNumberElementParameters(Handle<Map> double_map)
467 : double_map_(double_map) {}
468
operator ==(TransitionAndStoreNumberElementParameters const & lhs,TransitionAndStoreNumberElementParameters const & rhs)469 bool operator==(TransitionAndStoreNumberElementParameters const& lhs,
470 TransitionAndStoreNumberElementParameters const& rhs) {
471 return lhs.double_map().address() == rhs.double_map().address();
472 }
473
hash_value(TransitionAndStoreNumberElementParameters parameters)474 size_t hash_value(TransitionAndStoreNumberElementParameters parameters) {
475 return base::hash_combine(parameters.double_map().address());
476 }
477
operator <<(std::ostream & os,TransitionAndStoreNumberElementParameters parameters)478 std::ostream& operator<<(std::ostream& os,
479 TransitionAndStoreNumberElementParameters parameters) {
480 return os << "double-map" << Brief(*parameters.double_map());
481 }
482
483 } // namespace
484
DoubleMapParameterOf(const Operator * op)485 Handle<Map> DoubleMapParameterOf(const Operator* op) {
486 if (op->opcode() == IrOpcode::kTransitionAndStoreElement) {
487 return OpParameter<TransitionAndStoreElementParameters>(op).double_map();
488 } else if (op->opcode() == IrOpcode::kTransitionAndStoreNumberElement) {
489 return OpParameter<TransitionAndStoreNumberElementParameters>(op)
490 .double_map();
491 }
492 UNREACHABLE();
493 return Handle<Map>::null();
494 }
495
ValueTypeParameterOf(const Operator * op)496 Type ValueTypeParameterOf(const Operator* op) {
497 DCHECK_EQ(IrOpcode::kTransitionAndStoreNonNumberElement, op->opcode());
498 return OpParameter<TransitionAndStoreNonNumberElementParameters>(op)
499 .value_type();
500 }
501
FastMapParameterOf(const Operator * op)502 Handle<Map> FastMapParameterOf(const Operator* op) {
503 if (op->opcode() == IrOpcode::kTransitionAndStoreElement) {
504 return OpParameter<TransitionAndStoreElementParameters>(op).fast_map();
505 } else if (op->opcode() == IrOpcode::kTransitionAndStoreNonNumberElement) {
506 return OpParameter<TransitionAndStoreNonNumberElementParameters>(op)
507 .fast_map();
508 }
509 UNREACHABLE();
510 return Handle<Map>::null();
511 }
512
operator <<(std::ostream & os,BigIntOperationHint hint)513 std::ostream& operator<<(std::ostream& os, BigIntOperationHint hint) {
514 switch (hint) {
515 case BigIntOperationHint::kBigInt:
516 return os << "BigInt";
517 }
518 UNREACHABLE();
519 }
520
hash_value(BigIntOperationHint hint)521 size_t hash_value(BigIntOperationHint hint) {
522 return static_cast<uint8_t>(hint);
523 }
524
operator <<(std::ostream & os,NumberOperationHint hint)525 std::ostream& operator<<(std::ostream& os, NumberOperationHint hint) {
526 switch (hint) {
527 case NumberOperationHint::kSignedSmall:
528 return os << "SignedSmall";
529 case NumberOperationHint::kSignedSmallInputs:
530 return os << "SignedSmallInputs";
531 case NumberOperationHint::kSigned32:
532 return os << "Signed32";
533 case NumberOperationHint::kNumber:
534 return os << "Number";
535 case NumberOperationHint::kNumberOrOddball:
536 return os << "NumberOrOddball";
537 }
538 UNREACHABLE();
539 }
540
hash_value(NumberOperationHint hint)541 size_t hash_value(NumberOperationHint hint) {
542 return static_cast<uint8_t>(hint);
543 }
544
NumberOperationHintOf(const Operator * op)545 NumberOperationHint NumberOperationHintOf(const Operator* op) {
546 DCHECK(op->opcode() == IrOpcode::kSpeculativeNumberAdd ||
547 op->opcode() == IrOpcode::kSpeculativeNumberSubtract ||
548 op->opcode() == IrOpcode::kSpeculativeNumberMultiply ||
549 op->opcode() == IrOpcode::kSpeculativeNumberDivide ||
550 op->opcode() == IrOpcode::kSpeculativeNumberModulus ||
551 op->opcode() == IrOpcode::kSpeculativeNumberShiftLeft ||
552 op->opcode() == IrOpcode::kSpeculativeNumberShiftRight ||
553 op->opcode() == IrOpcode::kSpeculativeNumberShiftRightLogical ||
554 op->opcode() == IrOpcode::kSpeculativeNumberBitwiseAnd ||
555 op->opcode() == IrOpcode::kSpeculativeNumberBitwiseOr ||
556 op->opcode() == IrOpcode::kSpeculativeNumberBitwiseXor ||
557 op->opcode() == IrOpcode::kSpeculativeNumberEqual ||
558 op->opcode() == IrOpcode::kSpeculativeNumberLessThan ||
559 op->opcode() == IrOpcode::kSpeculativeNumberLessThanOrEqual ||
560 op->opcode() == IrOpcode::kSpeculativeSafeIntegerAdd ||
561 op->opcode() == IrOpcode::kSpeculativeSafeIntegerSubtract);
562 return OpParameter<NumberOperationHint>(op);
563 }
564
operator ==(NumberOperationParameters const & lhs,NumberOperationParameters const & rhs)565 bool operator==(NumberOperationParameters const& lhs,
566 NumberOperationParameters const& rhs) {
567 return lhs.hint() == rhs.hint() && lhs.feedback() == rhs.feedback();
568 }
569
hash_value(NumberOperationParameters const & p)570 size_t hash_value(NumberOperationParameters const& p) {
571 FeedbackSource::Hash feedback_hash;
572 return base::hash_combine(p.hint(), feedback_hash(p.feedback()));
573 }
574
operator <<(std::ostream & os,NumberOperationParameters const & p)575 std::ostream& operator<<(std::ostream& os, NumberOperationParameters const& p) {
576 return os << p.hint() << ", " << p.feedback();
577 }
578
NumberOperationParametersOf(Operator const * op)579 NumberOperationParameters const& NumberOperationParametersOf(
580 Operator const* op) {
581 DCHECK_EQ(IrOpcode::kSpeculativeToNumber, op->opcode());
582 return OpParameter<NumberOperationParameters>(op);
583 }
584
hash_value(AllocateParameters info)585 size_t hash_value(AllocateParameters info) {
586 return base::hash_combine(info.type(),
587 static_cast<int>(info.allocation_type()));
588 }
589
operator <<(std::ostream & os,AllocateParameters info)590 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
591 AllocateParameters info) {
592 return os << info.type() << ", " << info.allocation_type();
593 }
594
operator ==(AllocateParameters const & lhs,AllocateParameters const & rhs)595 bool operator==(AllocateParameters const& lhs, AllocateParameters const& rhs) {
596 return lhs.allocation_type() == rhs.allocation_type() &&
597 lhs.type() == rhs.type();
598 }
599
AllocateParametersOf(const Operator * op)600 const AllocateParameters& AllocateParametersOf(const Operator* op) {
601 DCHECK(op->opcode() == IrOpcode::kAllocate ||
602 op->opcode() == IrOpcode::kAllocateRaw);
603 return OpParameter<AllocateParameters>(op);
604 }
605
AllocationTypeOf(const Operator * op)606 AllocationType AllocationTypeOf(const Operator* op) {
607 if (op->opcode() == IrOpcode::kNewDoubleElements ||
608 op->opcode() == IrOpcode::kNewSmiOrObjectElements) {
609 return OpParameter<AllocationType>(op);
610 }
611 return AllocateParametersOf(op).allocation_type();
612 }
613
AllocateTypeOf(const Operator * op)614 Type AllocateTypeOf(const Operator* op) {
615 DCHECK_EQ(IrOpcode::kAllocate, op->opcode());
616 return AllocateParametersOf(op).type();
617 }
618
AbortReasonOf(const Operator * op)619 AbortReason AbortReasonOf(const Operator* op) {
620 DCHECK_EQ(IrOpcode::kRuntimeAbort, op->opcode());
621 return static_cast<AbortReason>(OpParameter<int>(op));
622 }
623
CheckTaggedInputParametersOf(const Operator * op)624 const CheckTaggedInputParameters& CheckTaggedInputParametersOf(
625 const Operator* op) {
626 DCHECK(op->opcode() == IrOpcode::kCheckedTruncateTaggedToWord32 ||
627 op->opcode() == IrOpcode::kCheckedTaggedToFloat64);
628 return OpParameter<CheckTaggedInputParameters>(op);
629 }
630
operator <<(std::ostream & os,const CheckTaggedInputParameters & params)631 std::ostream& operator<<(std::ostream& os,
632 const CheckTaggedInputParameters& params) {
633 return os << params.mode() << ", " << params.feedback();
634 }
635
hash_value(const CheckTaggedInputParameters & params)636 size_t hash_value(const CheckTaggedInputParameters& params) {
637 FeedbackSource::Hash feedback_hash;
638 return base::hash_combine(params.mode(), feedback_hash(params.feedback()));
639 }
640
operator ==(CheckTaggedInputParameters const & lhs,CheckTaggedInputParameters const & rhs)641 bool operator==(CheckTaggedInputParameters const& lhs,
642 CheckTaggedInputParameters const& rhs) {
643 return lhs.mode() == rhs.mode() && lhs.feedback() == rhs.feedback();
644 }
645
CheckMinusZeroParametersOf(const Operator * op)646 const CheckMinusZeroParameters& CheckMinusZeroParametersOf(const Operator* op) {
647 DCHECK(op->opcode() == IrOpcode::kCheckedTaggedToInt32 ||
648 op->opcode() == IrOpcode::kCheckedTaggedToInt64 ||
649 op->opcode() == IrOpcode::kCheckedFloat64ToInt32 ||
650 op->opcode() == IrOpcode::kCheckedFloat64ToInt64);
651 return OpParameter<CheckMinusZeroParameters>(op);
652 }
653
operator <<(std::ostream & os,const CheckMinusZeroParameters & params)654 std::ostream& operator<<(std::ostream& os,
655 const CheckMinusZeroParameters& params) {
656 return os << params.mode() << ", " << params.feedback();
657 }
658
hash_value(const CheckMinusZeroParameters & params)659 size_t hash_value(const CheckMinusZeroParameters& params) {
660 FeedbackSource::Hash feedback_hash;
661 return base::hash_combine(params.mode(), feedback_hash(params.feedback()));
662 }
663
operator ==(CheckMinusZeroParameters const & lhs,CheckMinusZeroParameters const & rhs)664 bool operator==(CheckMinusZeroParameters const& lhs,
665 CheckMinusZeroParameters const& rhs) {
666 return lhs.mode() == rhs.mode() && lhs.feedback() == rhs.feedback();
667 }
668
669 #define PURE_OP_LIST(V) \
670 V(BooleanNot, Operator::kNoProperties, 1, 0) \
671 V(NumberEqual, Operator::kCommutative, 2, 0) \
672 V(NumberLessThan, Operator::kNoProperties, 2, 0) \
673 V(NumberLessThanOrEqual, Operator::kNoProperties, 2, 0) \
674 V(NumberAdd, Operator::kCommutative, 2, 0) \
675 V(NumberSubtract, Operator::kNoProperties, 2, 0) \
676 V(NumberMultiply, Operator::kCommutative, 2, 0) \
677 V(NumberDivide, Operator::kNoProperties, 2, 0) \
678 V(NumberModulus, Operator::kNoProperties, 2, 0) \
679 V(NumberBitwiseOr, Operator::kCommutative, 2, 0) \
680 V(NumberBitwiseXor, Operator::kCommutative, 2, 0) \
681 V(NumberBitwiseAnd, Operator::kCommutative, 2, 0) \
682 V(NumberShiftLeft, Operator::kNoProperties, 2, 0) \
683 V(NumberShiftRight, Operator::kNoProperties, 2, 0) \
684 V(NumberShiftRightLogical, Operator::kNoProperties, 2, 0) \
685 V(NumberImul, Operator::kCommutative, 2, 0) \
686 V(NumberAbs, Operator::kNoProperties, 1, 0) \
687 V(NumberClz32, Operator::kNoProperties, 1, 0) \
688 V(NumberCeil, Operator::kNoProperties, 1, 0) \
689 V(NumberFloor, Operator::kNoProperties, 1, 0) \
690 V(NumberFround, Operator::kNoProperties, 1, 0) \
691 V(NumberAcos, Operator::kNoProperties, 1, 0) \
692 V(NumberAcosh, Operator::kNoProperties, 1, 0) \
693 V(NumberAsin, Operator::kNoProperties, 1, 0) \
694 V(NumberAsinh, Operator::kNoProperties, 1, 0) \
695 V(NumberAtan, Operator::kNoProperties, 1, 0) \
696 V(NumberAtan2, Operator::kNoProperties, 2, 0) \
697 V(NumberAtanh, Operator::kNoProperties, 1, 0) \
698 V(NumberCbrt, Operator::kNoProperties, 1, 0) \
699 V(NumberCos, Operator::kNoProperties, 1, 0) \
700 V(NumberCosh, Operator::kNoProperties, 1, 0) \
701 V(NumberExp, Operator::kNoProperties, 1, 0) \
702 V(NumberExpm1, Operator::kNoProperties, 1, 0) \
703 V(NumberLog, Operator::kNoProperties, 1, 0) \
704 V(NumberLog1p, Operator::kNoProperties, 1, 0) \
705 V(NumberLog10, Operator::kNoProperties, 1, 0) \
706 V(NumberLog2, Operator::kNoProperties, 1, 0) \
707 V(NumberMax, Operator::kNoProperties, 2, 0) \
708 V(NumberMin, Operator::kNoProperties, 2, 0) \
709 V(NumberPow, Operator::kNoProperties, 2, 0) \
710 V(NumberRound, Operator::kNoProperties, 1, 0) \
711 V(NumberSign, Operator::kNoProperties, 1, 0) \
712 V(NumberSin, Operator::kNoProperties, 1, 0) \
713 V(NumberSinh, Operator::kNoProperties, 1, 0) \
714 V(NumberSqrt, Operator::kNoProperties, 1, 0) \
715 V(NumberTan, Operator::kNoProperties, 1, 0) \
716 V(NumberTanh, Operator::kNoProperties, 1, 0) \
717 V(NumberTrunc, Operator::kNoProperties, 1, 0) \
718 V(NumberToBoolean, Operator::kNoProperties, 1, 0) \
719 V(NumberToInt32, Operator::kNoProperties, 1, 0) \
720 V(NumberToString, Operator::kNoProperties, 1, 0) \
721 V(NumberToUint32, Operator::kNoProperties, 1, 0) \
722 V(NumberToUint8Clamped, Operator::kNoProperties, 1, 0) \
723 V(NumberSilenceNaN, Operator::kNoProperties, 1, 0) \
724 V(BigIntNegate, Operator::kNoProperties, 1, 0) \
725 V(StringConcat, Operator::kNoProperties, 3, 0) \
726 V(StringToNumber, Operator::kNoProperties, 1, 0) \
727 V(StringFromSingleCharCode, Operator::kNoProperties, 1, 0) \
728 V(StringFromSingleCodePoint, Operator::kNoProperties, 1, 0) \
729 V(StringIndexOf, Operator::kNoProperties, 3, 0) \
730 V(StringLength, Operator::kNoProperties, 1, 0) \
731 V(StringToLowerCaseIntl, Operator::kNoProperties, 1, 0) \
732 V(StringToUpperCaseIntl, Operator::kNoProperties, 1, 0) \
733 V(TypeOf, Operator::kNoProperties, 1, 1) \
734 V(PlainPrimitiveToNumber, Operator::kNoProperties, 1, 0) \
735 V(PlainPrimitiveToWord32, Operator::kNoProperties, 1, 0) \
736 V(PlainPrimitiveToFloat64, Operator::kNoProperties, 1, 0) \
737 V(ChangeTaggedSignedToInt32, Operator::kNoProperties, 1, 0) \
738 V(ChangeTaggedSignedToInt64, Operator::kNoProperties, 1, 0) \
739 V(ChangeTaggedToInt32, Operator::kNoProperties, 1, 0) \
740 V(ChangeTaggedToInt64, Operator::kNoProperties, 1, 0) \
741 V(ChangeTaggedToUint32, Operator::kNoProperties, 1, 0) \
742 V(ChangeTaggedToFloat64, Operator::kNoProperties, 1, 0) \
743 V(ChangeTaggedToTaggedSigned, Operator::kNoProperties, 1, 0) \
744 V(ChangeFloat64ToTaggedPointer, Operator::kNoProperties, 1, 0) \
745 V(ChangeInt31ToTaggedSigned, Operator::kNoProperties, 1, 0) \
746 V(ChangeInt32ToTagged, Operator::kNoProperties, 1, 0) \
747 V(ChangeInt64ToTagged, Operator::kNoProperties, 1, 0) \
748 V(ChangeUint32ToTagged, Operator::kNoProperties, 1, 0) \
749 V(ChangeUint64ToTagged, Operator::kNoProperties, 1, 0) \
750 V(ChangeTaggedToBit, Operator::kNoProperties, 1, 0) \
751 V(ChangeBitToTagged, Operator::kNoProperties, 1, 0) \
752 V(TruncateBigIntToUint64, Operator::kNoProperties, 1, 0) \
753 V(ChangeUint64ToBigInt, Operator::kNoProperties, 1, 0) \
754 V(TruncateTaggedToBit, Operator::kNoProperties, 1, 0) \
755 V(TruncateTaggedPointerToBit, Operator::kNoProperties, 1, 0) \
756 V(TruncateTaggedToWord32, Operator::kNoProperties, 1, 0) \
757 V(TruncateTaggedToFloat64, Operator::kNoProperties, 1, 0) \
758 V(ObjectIsArrayBufferView, Operator::kNoProperties, 1, 0) \
759 V(ObjectIsBigInt, Operator::kNoProperties, 1, 0) \
760 V(ObjectIsCallable, Operator::kNoProperties, 1, 0) \
761 V(ObjectIsConstructor, Operator::kNoProperties, 1, 0) \
762 V(ObjectIsDetectableCallable, Operator::kNoProperties, 1, 0) \
763 V(ObjectIsMinusZero, Operator::kNoProperties, 1, 0) \
764 V(NumberIsMinusZero, Operator::kNoProperties, 1, 0) \
765 V(ObjectIsNaN, Operator::kNoProperties, 1, 0) \
766 V(NumberIsNaN, Operator::kNoProperties, 1, 0) \
767 V(ObjectIsNonCallable, Operator::kNoProperties, 1, 0) \
768 V(ObjectIsNumber, Operator::kNoProperties, 1, 0) \
769 V(ObjectIsReceiver, Operator::kNoProperties, 1, 0) \
770 V(ObjectIsSmi, Operator::kNoProperties, 1, 0) \
771 V(ObjectIsString, Operator::kNoProperties, 1, 0) \
772 V(ObjectIsSymbol, Operator::kNoProperties, 1, 0) \
773 V(ObjectIsUndetectable, Operator::kNoProperties, 1, 0) \
774 V(NumberIsFloat64Hole, Operator::kNoProperties, 1, 0) \
775 V(NumberIsFinite, Operator::kNoProperties, 1, 0) \
776 V(ObjectIsFiniteNumber, Operator::kNoProperties, 1, 0) \
777 V(NumberIsInteger, Operator::kNoProperties, 1, 0) \
778 V(ObjectIsSafeInteger, Operator::kNoProperties, 1, 0) \
779 V(NumberIsSafeInteger, Operator::kNoProperties, 1, 0) \
780 V(ObjectIsInteger, Operator::kNoProperties, 1, 0) \
781 V(ConvertTaggedHoleToUndefined, Operator::kNoProperties, 1, 0) \
782 V(SameValue, Operator::kCommutative, 2, 0) \
783 V(SameValueNumbersOnly, Operator::kCommutative, 2, 0) \
784 V(NumberSameValue, Operator::kCommutative, 2, 0) \
785 V(ReferenceEqual, Operator::kCommutative, 2, 0) \
786 V(StringEqual, Operator::kCommutative, 2, 0) \
787 V(StringLessThan, Operator::kNoProperties, 2, 0) \
788 V(StringLessThanOrEqual, Operator::kNoProperties, 2, 0) \
789 V(ToBoolean, Operator::kNoProperties, 1, 0) \
790 V(NewConsString, Operator::kNoProperties, 3, 0) \
791 V(PoisonIndex, Operator::kNoProperties, 1, 0)
792
793 #define EFFECT_DEPENDENT_OP_LIST(V) \
794 V(BigIntAdd, Operator::kNoProperties, 2, 1) \
795 V(BigIntSubtract, Operator::kNoProperties, 2, 1) \
796 V(StringCharCodeAt, Operator::kNoProperties, 2, 1) \
797 V(StringCodePointAt, Operator::kNoProperties, 2, 1) \
798 V(StringFromCodePointAt, Operator::kNoProperties, 2, 1) \
799 V(StringSubstring, Operator::kNoProperties, 3, 1) \
800 V(DateNow, Operator::kNoProperties, 0, 1)
801
802 #define SPECULATIVE_NUMBER_BINOP_LIST(V) \
803 SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(V) \
804 V(SpeculativeNumberEqual) \
805 V(SpeculativeNumberLessThan) \
806 V(SpeculativeNumberLessThanOrEqual)
807
808 #define CHECKED_OP_LIST(V) \
809 V(CheckEqualsInternalizedString, 2, 0) \
810 V(CheckEqualsSymbol, 2, 0) \
811 V(CheckHeapObject, 1, 1) \
812 V(CheckInternalizedString, 1, 1) \
813 V(CheckNotTaggedHole, 1, 1) \
814 V(CheckReceiver, 1, 1) \
815 V(CheckReceiverOrNullOrUndefined, 1, 1) \
816 V(CheckSymbol, 1, 1) \
817 V(CheckedInt32Add, 2, 1) \
818 V(CheckedInt32Div, 2, 1) \
819 V(CheckedInt32Mod, 2, 1) \
820 V(CheckedInt32Sub, 2, 1) \
821 V(CheckedUint32Div, 2, 1) \
822 V(CheckedUint32Mod, 2, 1)
823
824 #define CHECKED_WITH_FEEDBACK_OP_LIST(V) \
825 V(CheckNumber, 1, 1) \
826 V(CheckSmi, 1, 1) \
827 V(CheckString, 1, 1) \
828 V(CheckBigInt, 1, 1) \
829 V(CheckedInt32ToTaggedSigned, 1, 1) \
830 V(CheckedInt64ToInt32, 1, 1) \
831 V(CheckedInt64ToTaggedSigned, 1, 1) \
832 V(CheckedTaggedToArrayIndex, 1, 1) \
833 V(CheckedTaggedSignedToInt32, 1, 1) \
834 V(CheckedTaggedToTaggedPointer, 1, 1) \
835 V(CheckedTaggedToTaggedSigned, 1, 1) \
836 V(CheckedUint32ToInt32, 1, 1) \
837 V(CheckedUint32ToTaggedSigned, 1, 1) \
838 V(CheckedUint64ToInt32, 1, 1) \
839 V(CheckedUint64ToTaggedSigned, 1, 1)
840
841 #define CHECKED_BOUNDS_OP_LIST(V) \
842 V(CheckBounds) \
843 V(CheckedUint32Bounds) \
844 V(CheckedUint64Bounds)
845
846 struct SimplifiedOperatorGlobalCache final {
847 #define PURE(Name, properties, value_input_count, control_input_count) \
848 struct Name##Operator final : public Operator { \
849 Name##Operator() \
850 : Operator(IrOpcode::k##Name, Operator::kPure | properties, #Name, \
851 value_input_count, 0, control_input_count, 1, 0, 0) {} \
852 }; \
853 Name##Operator k##Name;
854 PURE_OP_LIST(PURE)
855 #undef PURE
856
857 #define EFFECT_DEPENDENT(Name, properties, value_input_count, \
858 control_input_count) \
859 struct Name##Operator final : public Operator { \
860 Name##Operator() \
861 : Operator(IrOpcode::k##Name, Operator::kEliminatable | properties, \
862 #Name, value_input_count, 1, control_input_count, 1, 1, \
863 0) {} \
864 }; \
865 Name##Operator k##Name;
866 EFFECT_DEPENDENT_OP_LIST(EFFECT_DEPENDENT)
867 #undef EFFECT_DEPENDENT
868
869 #define CHECKED(Name, value_input_count, value_output_count) \
870 struct Name##Operator final : public Operator { \
871 Name##Operator() \
872 : Operator(IrOpcode::k##Name, \
873 Operator::kFoldable | Operator::kNoThrow, #Name, \
874 value_input_count, 1, 1, value_output_count, 1, 0) {} \
875 }; \
876 Name##Operator k##Name;
877 CHECKED_OP_LIST(CHECKED)
878 #undef CHECKED
879
880 #define CHECKED_WITH_FEEDBACK(Name, value_input_count, value_output_count) \
881 struct Name##Operator final : public Operator1<CheckParameters> { \
882 Name##Operator() \
883 : Operator1<CheckParameters>( \
884 IrOpcode::k##Name, Operator::kFoldable | Operator::kNoThrow, \
885 #Name, value_input_count, 1, 1, value_output_count, 1, 0, \
886 CheckParameters(FeedbackSource())) {} \
887 }; \
888 Name##Operator k##Name;
889 CHECKED_WITH_FEEDBACK_OP_LIST(CHECKED_WITH_FEEDBACK)
890 #undef CHECKED_WITH_FEEDBACK
891
892 #define CHECKED_BOUNDS(Name) \
893 struct Name##Operator final : public Operator1<CheckBoundsParameters> { \
894 Name##Operator(FeedbackSource feedback, CheckBoundsParameters::Mode mode) \
895 : Operator1<CheckBoundsParameters>( \
896 IrOpcode::k##Name, Operator::kFoldable | Operator::kNoThrow, \
897 #Name, 2, 1, 1, 1, 1, 0, \
898 CheckBoundsParameters(feedback, mode)) {} \
899 }; \
900 Name##Operator k##Name##Deopting = { \
901 FeedbackSource(), CheckBoundsParameters::kDeoptOnOutOfBounds}; \
902 Name##Operator k##Name##Aborting = { \
903 FeedbackSource(), CheckBoundsParameters::kAbortOnOutOfBounds};
904 CHECKED_BOUNDS_OP_LIST(CHECKED_BOUNDS)
905 #undef CHECKED_BOUNDS
906
907 template <DeoptimizeReason kDeoptimizeReason>
908 struct CheckIfOperator final : public Operator1<CheckIfParameters> {
CheckIfOperatorv8::internal::compiler::SimplifiedOperatorGlobalCache::CheckIfOperator909 CheckIfOperator()
910 : Operator1<CheckIfParameters>(
911 IrOpcode::kCheckIf, Operator::kFoldable | Operator::kNoThrow,
912 "CheckIf", 1, 1, 1, 0, 1, 0,
913 CheckIfParameters(kDeoptimizeReason, FeedbackSource())) {}
914 };
915 #define CHECK_IF(Name, message) \
916 CheckIfOperator<DeoptimizeReason::k##Name> kCheckIf##Name;
917 DEOPTIMIZE_REASON_LIST(CHECK_IF)
918 #undef CHECK_IF
919
920 struct FindOrderedHashMapEntryOperator final : public Operator {
FindOrderedHashMapEntryOperatorv8::internal::compiler::SimplifiedOperatorGlobalCache::FindOrderedHashMapEntryOperator921 FindOrderedHashMapEntryOperator()
922 : Operator(IrOpcode::kFindOrderedHashMapEntry, Operator::kEliminatable,
923 "FindOrderedHashMapEntry", 2, 1, 1, 1, 1, 0) {}
924 };
925 FindOrderedHashMapEntryOperator kFindOrderedHashMapEntry;
926
927 struct FindOrderedHashMapEntryForInt32KeyOperator final : public Operator {
FindOrderedHashMapEntryForInt32KeyOperatorv8::internal::compiler::SimplifiedOperatorGlobalCache::FindOrderedHashMapEntryForInt32KeyOperator928 FindOrderedHashMapEntryForInt32KeyOperator()
929 : Operator(IrOpcode::kFindOrderedHashMapEntryForInt32Key,
930 Operator::kEliminatable,
931 "FindOrderedHashMapEntryForInt32Key", 2, 1, 1, 1, 1, 0) {}
932 };
933 FindOrderedHashMapEntryForInt32KeyOperator
934 kFindOrderedHashMapEntryForInt32Key;
935
936 struct ArgumentsFrameOperator final : public Operator {
ArgumentsFrameOperatorv8::internal::compiler::SimplifiedOperatorGlobalCache::ArgumentsFrameOperator937 ArgumentsFrameOperator()
938 : Operator(IrOpcode::kArgumentsFrame, Operator::kPure, "ArgumentsFrame",
939 0, 0, 0, 1, 0, 0) {}
940 };
941 ArgumentsFrameOperator kArgumentsFrame;
942
943 template <CheckForMinusZeroMode kMode>
944 struct ChangeFloat64ToTaggedOperator final
945 : public Operator1<CheckForMinusZeroMode> {
ChangeFloat64ToTaggedOperatorv8::internal::compiler::SimplifiedOperatorGlobalCache::ChangeFloat64ToTaggedOperator946 ChangeFloat64ToTaggedOperator()
947 : Operator1<CheckForMinusZeroMode>(
948 IrOpcode::kChangeFloat64ToTagged, Operator::kPure,
949 "ChangeFloat64ToTagged", 1, 0, 0, 1, 0, 0, kMode) {}
950 };
951 ChangeFloat64ToTaggedOperator<CheckForMinusZeroMode::kCheckForMinusZero>
952 kChangeFloat64ToTaggedCheckForMinusZeroOperator;
953 ChangeFloat64ToTaggedOperator<CheckForMinusZeroMode::kDontCheckForMinusZero>
954 kChangeFloat64ToTaggedDontCheckForMinusZeroOperator;
955
956 template <CheckForMinusZeroMode kMode>
957 struct CheckedInt32MulOperator final
958 : public Operator1<CheckForMinusZeroMode> {
CheckedInt32MulOperatorv8::internal::compiler::SimplifiedOperatorGlobalCache::CheckedInt32MulOperator959 CheckedInt32MulOperator()
960 : Operator1<CheckForMinusZeroMode>(
961 IrOpcode::kCheckedInt32Mul,
962 Operator::kFoldable | Operator::kNoThrow, "CheckedInt32Mul", 2, 1,
963 1, 1, 1, 0, kMode) {}
964 };
965 CheckedInt32MulOperator<CheckForMinusZeroMode::kCheckForMinusZero>
966 kCheckedInt32MulCheckForMinusZeroOperator;
967 CheckedInt32MulOperator<CheckForMinusZeroMode::kDontCheckForMinusZero>
968 kCheckedInt32MulDontCheckForMinusZeroOperator;
969
970 template <CheckForMinusZeroMode kMode>
971 struct CheckedFloat64ToInt32Operator final
972 : public Operator1<CheckMinusZeroParameters> {
CheckedFloat64ToInt32Operatorv8::internal::compiler::SimplifiedOperatorGlobalCache::CheckedFloat64ToInt32Operator973 CheckedFloat64ToInt32Operator()
974 : Operator1<CheckMinusZeroParameters>(
975 IrOpcode::kCheckedFloat64ToInt32,
976 Operator::kFoldable | Operator::kNoThrow, "CheckedFloat64ToInt32",
977 1, 1, 1, 1, 1, 0,
978 CheckMinusZeroParameters(kMode, FeedbackSource())) {}
979 };
980 CheckedFloat64ToInt32Operator<CheckForMinusZeroMode::kCheckForMinusZero>
981 kCheckedFloat64ToInt32CheckForMinusZeroOperator;
982 CheckedFloat64ToInt32Operator<CheckForMinusZeroMode::kDontCheckForMinusZero>
983 kCheckedFloat64ToInt32DontCheckForMinusZeroOperator;
984
985 template <CheckForMinusZeroMode kMode>
986 struct CheckedFloat64ToInt64Operator final
987 : public Operator1<CheckMinusZeroParameters> {
CheckedFloat64ToInt64Operatorv8::internal::compiler::SimplifiedOperatorGlobalCache::CheckedFloat64ToInt64Operator988 CheckedFloat64ToInt64Operator()
989 : Operator1<CheckMinusZeroParameters>(
990 IrOpcode::kCheckedFloat64ToInt64,
991 Operator::kFoldable | Operator::kNoThrow, "CheckedFloat64ToInt64",
992 1, 1, 1, 1, 1, 0,
993 CheckMinusZeroParameters(kMode, FeedbackSource())) {}
994 };
995 CheckedFloat64ToInt64Operator<CheckForMinusZeroMode::kCheckForMinusZero>
996 kCheckedFloat64ToInt64CheckForMinusZeroOperator;
997 CheckedFloat64ToInt64Operator<CheckForMinusZeroMode::kDontCheckForMinusZero>
998 kCheckedFloat64ToInt64DontCheckForMinusZeroOperator;
999
1000 template <CheckForMinusZeroMode kMode>
1001 struct CheckedTaggedToInt32Operator final
1002 : public Operator1<CheckMinusZeroParameters> {
CheckedTaggedToInt32Operatorv8::internal::compiler::SimplifiedOperatorGlobalCache::CheckedTaggedToInt32Operator1003 CheckedTaggedToInt32Operator()
1004 : Operator1<CheckMinusZeroParameters>(
1005 IrOpcode::kCheckedTaggedToInt32,
1006 Operator::kFoldable | Operator::kNoThrow, "CheckedTaggedToInt32",
1007 1, 1, 1, 1, 1, 0,
1008 CheckMinusZeroParameters(kMode, FeedbackSource())) {}
1009 };
1010 CheckedTaggedToInt32Operator<CheckForMinusZeroMode::kCheckForMinusZero>
1011 kCheckedTaggedToInt32CheckForMinusZeroOperator;
1012 CheckedTaggedToInt32Operator<CheckForMinusZeroMode::kDontCheckForMinusZero>
1013 kCheckedTaggedToInt32DontCheckForMinusZeroOperator;
1014
1015 template <CheckForMinusZeroMode kMode>
1016 struct CheckedTaggedToInt64Operator final
1017 : public Operator1<CheckMinusZeroParameters> {
CheckedTaggedToInt64Operatorv8::internal::compiler::SimplifiedOperatorGlobalCache::CheckedTaggedToInt64Operator1018 CheckedTaggedToInt64Operator()
1019 : Operator1<CheckMinusZeroParameters>(
1020 IrOpcode::kCheckedTaggedToInt64,
1021 Operator::kFoldable | Operator::kNoThrow, "CheckedTaggedToInt64",
1022 1, 1, 1, 1, 1, 0,
1023 CheckMinusZeroParameters(kMode, FeedbackSource())) {}
1024 };
1025 CheckedTaggedToInt64Operator<CheckForMinusZeroMode::kCheckForMinusZero>
1026 kCheckedTaggedToInt64CheckForMinusZeroOperator;
1027 CheckedTaggedToInt64Operator<CheckForMinusZeroMode::kDontCheckForMinusZero>
1028 kCheckedTaggedToInt64DontCheckForMinusZeroOperator;
1029
1030 template <CheckTaggedInputMode kMode>
1031 struct CheckedTaggedToFloat64Operator final
1032 : public Operator1<CheckTaggedInputParameters> {
CheckedTaggedToFloat64Operatorv8::internal::compiler::SimplifiedOperatorGlobalCache::CheckedTaggedToFloat64Operator1033 CheckedTaggedToFloat64Operator()
1034 : Operator1<CheckTaggedInputParameters>(
1035 IrOpcode::kCheckedTaggedToFloat64,
1036 Operator::kFoldable | Operator::kNoThrow,
1037 "CheckedTaggedToFloat64", 1, 1, 1, 1, 1, 0,
1038 CheckTaggedInputParameters(kMode, FeedbackSource())) {}
1039 };
1040 CheckedTaggedToFloat64Operator<CheckTaggedInputMode::kNumber>
1041 kCheckedTaggedToFloat64NumberOperator;
1042 CheckedTaggedToFloat64Operator<CheckTaggedInputMode::kNumberOrOddball>
1043 kCheckedTaggedToFloat64NumberOrOddballOperator;
1044
1045 template <CheckTaggedInputMode kMode>
1046 struct CheckedTruncateTaggedToWord32Operator final
1047 : public Operator1<CheckTaggedInputParameters> {
CheckedTruncateTaggedToWord32Operatorv8::internal::compiler::SimplifiedOperatorGlobalCache::CheckedTruncateTaggedToWord32Operator1048 CheckedTruncateTaggedToWord32Operator()
1049 : Operator1<CheckTaggedInputParameters>(
1050 IrOpcode::kCheckedTruncateTaggedToWord32,
1051 Operator::kFoldable | Operator::kNoThrow,
1052 "CheckedTruncateTaggedToWord32", 1, 1, 1, 1, 1, 0,
1053 CheckTaggedInputParameters(kMode, FeedbackSource())) {}
1054 };
1055 CheckedTruncateTaggedToWord32Operator<CheckTaggedInputMode::kNumber>
1056 kCheckedTruncateTaggedToWord32NumberOperator;
1057 CheckedTruncateTaggedToWord32Operator<CheckTaggedInputMode::kNumberOrOddball>
1058 kCheckedTruncateTaggedToWord32NumberOrOddballOperator;
1059
1060 template <ConvertReceiverMode kMode>
1061 struct ConvertReceiverOperator final : public Operator1<ConvertReceiverMode> {
ConvertReceiverOperatorv8::internal::compiler::SimplifiedOperatorGlobalCache::ConvertReceiverOperator1062 ConvertReceiverOperator()
1063 : Operator1<ConvertReceiverMode>( // --
1064 IrOpcode::kConvertReceiver, // opcode
1065 Operator::kEliminatable, // flags
1066 "ConvertReceiver", // name
1067 2, 1, 1, 1, 1, 0, // counts
1068 kMode) {} // param
1069 };
1070 ConvertReceiverOperator<ConvertReceiverMode::kAny>
1071 kConvertReceiverAnyOperator;
1072 ConvertReceiverOperator<ConvertReceiverMode::kNullOrUndefined>
1073 kConvertReceiverNullOrUndefinedOperator;
1074 ConvertReceiverOperator<ConvertReceiverMode::kNotNullOrUndefined>
1075 kConvertReceiverNotNullOrUndefinedOperator;
1076
1077 template <CheckFloat64HoleMode kMode>
1078 struct CheckFloat64HoleNaNOperator final
1079 : public Operator1<CheckFloat64HoleParameters> {
CheckFloat64HoleNaNOperatorv8::internal::compiler::SimplifiedOperatorGlobalCache::CheckFloat64HoleNaNOperator1080 CheckFloat64HoleNaNOperator()
1081 : Operator1<CheckFloat64HoleParameters>(
1082 IrOpcode::kCheckFloat64Hole,
1083 Operator::kFoldable | Operator::kNoThrow, "CheckFloat64Hole", 1,
1084 1, 1, 1, 1, 0,
1085 CheckFloat64HoleParameters(kMode, FeedbackSource())) {}
1086 };
1087 CheckFloat64HoleNaNOperator<CheckFloat64HoleMode::kAllowReturnHole>
1088 kCheckFloat64HoleAllowReturnHoleOperator;
1089 CheckFloat64HoleNaNOperator<CheckFloat64HoleMode::kNeverReturnHole>
1090 kCheckFloat64HoleNeverReturnHoleOperator;
1091
1092 struct EnsureWritableFastElementsOperator final : public Operator {
EnsureWritableFastElementsOperatorv8::internal::compiler::SimplifiedOperatorGlobalCache::EnsureWritableFastElementsOperator1093 EnsureWritableFastElementsOperator()
1094 : Operator( // --
1095 IrOpcode::kEnsureWritableFastElements, // opcode
1096 Operator::kNoDeopt | Operator::kNoThrow, // flags
1097 "EnsureWritableFastElements", // name
1098 2, 1, 1, 1, 1, 0) {} // counts
1099 };
1100 EnsureWritableFastElementsOperator kEnsureWritableFastElements;
1101
1102 template <GrowFastElementsMode kMode>
1103 struct GrowFastElementsOperator final
1104 : public Operator1<GrowFastElementsParameters> {
GrowFastElementsOperatorv8::internal::compiler::SimplifiedOperatorGlobalCache::GrowFastElementsOperator1105 GrowFastElementsOperator()
1106 : Operator1(IrOpcode::kMaybeGrowFastElements, Operator::kNoThrow,
1107 "MaybeGrowFastElements", 4, 1, 1, 1, 1, 0,
1108 GrowFastElementsParameters(kMode, FeedbackSource())) {}
1109 };
1110
1111 GrowFastElementsOperator<GrowFastElementsMode::kDoubleElements>
1112 kGrowFastElementsOperatorDoubleElements;
1113 GrowFastElementsOperator<GrowFastElementsMode::kSmiOrObjectElements>
1114 kGrowFastElementsOperatorSmiOrObjectElements;
1115
1116 struct LoadFieldByIndexOperator final : public Operator {
LoadFieldByIndexOperatorv8::internal::compiler::SimplifiedOperatorGlobalCache::LoadFieldByIndexOperator1117 LoadFieldByIndexOperator()
1118 : Operator( // --
1119 IrOpcode::kLoadFieldByIndex, // opcode
1120 Operator::kEliminatable, // flags,
1121 "LoadFieldByIndex", // name
1122 2, 1, 1, 1, 1, 0) {} // counts;
1123 };
1124 LoadFieldByIndexOperator kLoadFieldByIndex;
1125
1126 struct LoadStackArgumentOperator final : public Operator {
LoadStackArgumentOperatorv8::internal::compiler::SimplifiedOperatorGlobalCache::LoadStackArgumentOperator1127 LoadStackArgumentOperator()
1128 : Operator( // --
1129 IrOpcode::kLoadStackArgument, // opcode
1130 Operator::kEliminatable, // flags
1131 "LoadStackArgument", // name
1132 2, 1, 1, 1, 1, 0) {} // counts
1133 };
1134 LoadStackArgumentOperator kLoadStackArgument;
1135
1136 #define SPECULATIVE_NUMBER_BINOP(Name) \
1137 template <NumberOperationHint kHint> \
1138 struct Name##Operator final : public Operator1<NumberOperationHint> { \
1139 Name##Operator() \
1140 : Operator1<NumberOperationHint>( \
1141 IrOpcode::k##Name, Operator::kFoldable | Operator::kNoThrow, \
1142 #Name, 2, 1, 1, 1, 1, 0, kHint) {} \
1143 }; \
1144 Name##Operator<NumberOperationHint::kSignedSmall> \
1145 k##Name##SignedSmallOperator; \
1146 Name##Operator<NumberOperationHint::kSignedSmallInputs> \
1147 k##Name##SignedSmallInputsOperator; \
1148 Name##Operator<NumberOperationHint::kSigned32> k##Name##Signed32Operator; \
1149 Name##Operator<NumberOperationHint::kNumber> k##Name##NumberOperator; \
1150 Name##Operator<NumberOperationHint::kNumberOrOddball> \
1151 k##Name##NumberOrOddballOperator;
1152 SPECULATIVE_NUMBER_BINOP_LIST(SPECULATIVE_NUMBER_BINOP)
1153 #undef SPECULATIVE_NUMBER_BINOP
1154
1155 template <NumberOperationHint kHint>
1156 struct SpeculativeToNumberOperator final
1157 : public Operator1<NumberOperationParameters> {
SpeculativeToNumberOperatorv8::internal::compiler::SimplifiedOperatorGlobalCache::SpeculativeToNumberOperator1158 SpeculativeToNumberOperator()
1159 : Operator1<NumberOperationParameters>(
1160 IrOpcode::kSpeculativeToNumber,
1161 Operator::kFoldable | Operator::kNoThrow, "SpeculativeToNumber",
1162 1, 1, 1, 1, 1, 0,
1163 NumberOperationParameters(kHint, FeedbackSource())) {}
1164 };
1165 SpeculativeToNumberOperator<NumberOperationHint::kSignedSmall>
1166 kSpeculativeToNumberSignedSmallOperator;
1167 SpeculativeToNumberOperator<NumberOperationHint::kSigned32>
1168 kSpeculativeToNumberSigned32Operator;
1169 SpeculativeToNumberOperator<NumberOperationHint::kNumber>
1170 kSpeculativeToNumberNumberOperator;
1171 SpeculativeToNumberOperator<NumberOperationHint::kNumberOrOddball>
1172 kSpeculativeToNumberNumberOrOddballOperator;
1173 };
1174
1175 namespace {
1176 DEFINE_LAZY_LEAKY_OBJECT_GETTER(SimplifiedOperatorGlobalCache,
1177 GetSimplifiedOperatorGlobalCache)
1178 }
1179
SimplifiedOperatorBuilder(Zone * zone)1180 SimplifiedOperatorBuilder::SimplifiedOperatorBuilder(Zone* zone)
1181 : cache_(*GetSimplifiedOperatorGlobalCache()), zone_(zone) {}
1182
1183 #define GET_FROM_CACHE(Name, ...) \
1184 const Operator* SimplifiedOperatorBuilder::Name() { return &cache_.k##Name; }
1185 PURE_OP_LIST(GET_FROM_CACHE)
EFFECT_DEPENDENT_OP_LIST(GET_FROM_CACHE)1186 EFFECT_DEPENDENT_OP_LIST(GET_FROM_CACHE)
1187 CHECKED_OP_LIST(GET_FROM_CACHE)
1188 GET_FROM_CACHE(ArgumentsFrame)
1189 GET_FROM_CACHE(FindOrderedHashMapEntry)
1190 GET_FROM_CACHE(FindOrderedHashMapEntryForInt32Key)
1191 GET_FROM_CACHE(LoadFieldByIndex)
1192 #undef GET_FROM_CACHE
1193
1194 #define GET_FROM_CACHE_WITH_FEEDBACK(Name, value_input_count, \
1195 value_output_count) \
1196 const Operator* SimplifiedOperatorBuilder::Name( \
1197 const FeedbackSource& feedback) { \
1198 if (!feedback.IsValid()) { \
1199 return &cache_.k##Name; \
1200 } \
1201 return new (zone()) Operator1<CheckParameters>( \
1202 IrOpcode::k##Name, Operator::kFoldable | Operator::kNoThrow, #Name, \
1203 value_input_count, 1, 1, value_output_count, 1, 0, \
1204 CheckParameters(feedback)); \
1205 }
1206 CHECKED_WITH_FEEDBACK_OP_LIST(GET_FROM_CACHE_WITH_FEEDBACK)
1207 #undef GET_FROM_CACHE_WITH_FEEDBACK
1208
1209 #define GET_FROM_CACHE_WITH_FEEDBACK(Name) \
1210 const Operator* SimplifiedOperatorBuilder::Name( \
1211 const FeedbackSource& feedback, CheckBoundsParameters::Mode mode) { \
1212 if (!feedback.IsValid()) { \
1213 switch (mode) { \
1214 case CheckBoundsParameters::kDeoptOnOutOfBounds: \
1215 return &cache_.k##Name##Deopting; \
1216 case CheckBoundsParameters::kAbortOnOutOfBounds: \
1217 return &cache_.k##Name##Aborting; \
1218 } \
1219 } \
1220 return new (zone()) \
1221 SimplifiedOperatorGlobalCache::Name##Operator(feedback, mode); \
1222 }
1223 CHECKED_BOUNDS_OP_LIST(GET_FROM_CACHE_WITH_FEEDBACK)
1224 #undef GET_FROM_CACHE_WITH_FEEDBACK
1225
1226 bool IsCheckedWithFeedback(const Operator* op) {
1227 #define CASE(Name, ...) case IrOpcode::k##Name:
1228 switch (op->opcode()) {
1229 CHECKED_WITH_FEEDBACK_OP_LIST(CASE) return true;
1230 default:
1231 return false;
1232 }
1233 #undef CASE
1234 }
1235
RuntimeAbort(AbortReason reason)1236 const Operator* SimplifiedOperatorBuilder::RuntimeAbort(AbortReason reason) {
1237 return new (zone()) Operator1<int>( // --
1238 IrOpcode::kRuntimeAbort, // opcode
1239 Operator::kNoThrow | Operator::kNoDeopt, // flags
1240 "RuntimeAbort", // name
1241 0, 1, 1, 0, 1, 0, // counts
1242 static_cast<int>(reason)); // parameter
1243 }
1244
BigIntAsUintN(int bits)1245 const Operator* SimplifiedOperatorBuilder::BigIntAsUintN(int bits) {
1246 CHECK(0 <= bits && bits <= 64);
1247
1248 return new (zone()) Operator1<int>(IrOpcode::kBigIntAsUintN, Operator::kPure,
1249 "BigIntAsUintN", 1, 0, 0, 1, 0, 0, bits);
1250 }
1251
AssertType(Type type)1252 const Operator* SimplifiedOperatorBuilder::AssertType(Type type) {
1253 DCHECK(type.IsRange());
1254 return new (zone()) Operator1<Type>(IrOpcode::kAssertType,
1255 Operator::kNoThrow | Operator::kNoDeopt,
1256 "AssertType", 1, 0, 0, 1, 0, 0, type);
1257 }
1258
FastApiCall(const CFunctionInfo * signature,FeedbackSource const & feedback)1259 const Operator* SimplifiedOperatorBuilder::FastApiCall(
1260 const CFunctionInfo* signature, FeedbackSource const& feedback) {
1261 // function, c args
1262 int value_input_count = signature->ArgumentCount() + 1;
1263 return new (zone()) Operator1<FastApiCallParameters>(
1264 IrOpcode::kFastApiCall, Operator::kNoThrow, "FastApiCall",
1265 value_input_count, 1, 1, 1, 1, 0,
1266 FastApiCallParameters(signature, feedback));
1267 }
1268
CheckIf(DeoptimizeReason reason,const FeedbackSource & feedback)1269 const Operator* SimplifiedOperatorBuilder::CheckIf(
1270 DeoptimizeReason reason, const FeedbackSource& feedback) {
1271 if (!feedback.IsValid()) {
1272 switch (reason) {
1273 #define CHECK_IF(Name, message) \
1274 case DeoptimizeReason::k##Name: \
1275 return &cache_.kCheckIf##Name;
1276 DEOPTIMIZE_REASON_LIST(CHECK_IF)
1277 #undef CHECK_IF
1278 }
1279 }
1280 return new (zone()) Operator1<CheckIfParameters>(
1281 IrOpcode::kCheckIf, Operator::kFoldable | Operator::kNoThrow, "CheckIf",
1282 1, 1, 1, 0, 1, 0, CheckIfParameters(reason, feedback));
1283 }
1284
ChangeFloat64ToTagged(CheckForMinusZeroMode mode)1285 const Operator* SimplifiedOperatorBuilder::ChangeFloat64ToTagged(
1286 CheckForMinusZeroMode mode) {
1287 switch (mode) {
1288 case CheckForMinusZeroMode::kCheckForMinusZero:
1289 return &cache_.kChangeFloat64ToTaggedCheckForMinusZeroOperator;
1290 case CheckForMinusZeroMode::kDontCheckForMinusZero:
1291 return &cache_.kChangeFloat64ToTaggedDontCheckForMinusZeroOperator;
1292 }
1293 UNREACHABLE();
1294 }
1295
CheckedInt32Mul(CheckForMinusZeroMode mode)1296 const Operator* SimplifiedOperatorBuilder::CheckedInt32Mul(
1297 CheckForMinusZeroMode mode) {
1298 switch (mode) {
1299 case CheckForMinusZeroMode::kCheckForMinusZero:
1300 return &cache_.kCheckedInt32MulCheckForMinusZeroOperator;
1301 case CheckForMinusZeroMode::kDontCheckForMinusZero:
1302 return &cache_.kCheckedInt32MulDontCheckForMinusZeroOperator;
1303 }
1304 UNREACHABLE();
1305 }
1306
CheckedFloat64ToInt32(CheckForMinusZeroMode mode,const FeedbackSource & feedback)1307 const Operator* SimplifiedOperatorBuilder::CheckedFloat64ToInt32(
1308 CheckForMinusZeroMode mode, const FeedbackSource& feedback) {
1309 if (!feedback.IsValid()) {
1310 switch (mode) {
1311 case CheckForMinusZeroMode::kCheckForMinusZero:
1312 return &cache_.kCheckedFloat64ToInt32CheckForMinusZeroOperator;
1313 case CheckForMinusZeroMode::kDontCheckForMinusZero:
1314 return &cache_.kCheckedFloat64ToInt32DontCheckForMinusZeroOperator;
1315 }
1316 }
1317 return new (zone()) Operator1<CheckMinusZeroParameters>(
1318 IrOpcode::kCheckedFloat64ToInt32,
1319 Operator::kFoldable | Operator::kNoThrow, "CheckedFloat64ToInt32", 1, 1,
1320 1, 1, 1, 0, CheckMinusZeroParameters(mode, feedback));
1321 }
1322
CheckedFloat64ToInt64(CheckForMinusZeroMode mode,const FeedbackSource & feedback)1323 const Operator* SimplifiedOperatorBuilder::CheckedFloat64ToInt64(
1324 CheckForMinusZeroMode mode, const FeedbackSource& feedback) {
1325 if (!feedback.IsValid()) {
1326 switch (mode) {
1327 case CheckForMinusZeroMode::kCheckForMinusZero:
1328 return &cache_.kCheckedFloat64ToInt64CheckForMinusZeroOperator;
1329 case CheckForMinusZeroMode::kDontCheckForMinusZero:
1330 return &cache_.kCheckedFloat64ToInt64DontCheckForMinusZeroOperator;
1331 }
1332 }
1333 return new (zone()) Operator1<CheckMinusZeroParameters>(
1334 IrOpcode::kCheckedFloat64ToInt64,
1335 Operator::kFoldable | Operator::kNoThrow, "CheckedFloat64ToInt64", 1, 1,
1336 1, 1, 1, 0, CheckMinusZeroParameters(mode, feedback));
1337 }
1338
CheckedTaggedToInt32(CheckForMinusZeroMode mode,const FeedbackSource & feedback)1339 const Operator* SimplifiedOperatorBuilder::CheckedTaggedToInt32(
1340 CheckForMinusZeroMode mode, const FeedbackSource& feedback) {
1341 if (!feedback.IsValid()) {
1342 switch (mode) {
1343 case CheckForMinusZeroMode::kCheckForMinusZero:
1344 return &cache_.kCheckedTaggedToInt32CheckForMinusZeroOperator;
1345 case CheckForMinusZeroMode::kDontCheckForMinusZero:
1346 return &cache_.kCheckedTaggedToInt32DontCheckForMinusZeroOperator;
1347 }
1348 }
1349 return new (zone()) Operator1<CheckMinusZeroParameters>(
1350 IrOpcode::kCheckedTaggedToInt32, Operator::kFoldable | Operator::kNoThrow,
1351 "CheckedTaggedToInt32", 1, 1, 1, 1, 1, 0,
1352 CheckMinusZeroParameters(mode, feedback));
1353 }
1354
CheckedTaggedToInt64(CheckForMinusZeroMode mode,const FeedbackSource & feedback)1355 const Operator* SimplifiedOperatorBuilder::CheckedTaggedToInt64(
1356 CheckForMinusZeroMode mode, const FeedbackSource& feedback) {
1357 if (!feedback.IsValid()) {
1358 switch (mode) {
1359 case CheckForMinusZeroMode::kCheckForMinusZero:
1360 return &cache_.kCheckedTaggedToInt64CheckForMinusZeroOperator;
1361 case CheckForMinusZeroMode::kDontCheckForMinusZero:
1362 return &cache_.kCheckedTaggedToInt64DontCheckForMinusZeroOperator;
1363 }
1364 }
1365 return new (zone()) Operator1<CheckMinusZeroParameters>(
1366 IrOpcode::kCheckedTaggedToInt64, Operator::kFoldable | Operator::kNoThrow,
1367 "CheckedTaggedToInt64", 1, 1, 1, 1, 1, 0,
1368 CheckMinusZeroParameters(mode, feedback));
1369 }
1370
CheckedTaggedToFloat64(CheckTaggedInputMode mode,const FeedbackSource & feedback)1371 const Operator* SimplifiedOperatorBuilder::CheckedTaggedToFloat64(
1372 CheckTaggedInputMode mode, const FeedbackSource& feedback) {
1373 if (!feedback.IsValid()) {
1374 switch (mode) {
1375 case CheckTaggedInputMode::kNumber:
1376 return &cache_.kCheckedTaggedToFloat64NumberOperator;
1377 case CheckTaggedInputMode::kNumberOrOddball:
1378 return &cache_.kCheckedTaggedToFloat64NumberOrOddballOperator;
1379 }
1380 }
1381 return new (zone()) Operator1<CheckTaggedInputParameters>(
1382 IrOpcode::kCheckedTaggedToFloat64,
1383 Operator::kFoldable | Operator::kNoThrow, "CheckedTaggedToFloat64", 1, 1,
1384 1, 1, 1, 0, CheckTaggedInputParameters(mode, feedback));
1385 }
1386
CheckedTruncateTaggedToWord32(CheckTaggedInputMode mode,const FeedbackSource & feedback)1387 const Operator* SimplifiedOperatorBuilder::CheckedTruncateTaggedToWord32(
1388 CheckTaggedInputMode mode, const FeedbackSource& feedback) {
1389 if (!feedback.IsValid()) {
1390 switch (mode) {
1391 case CheckTaggedInputMode::kNumber:
1392 return &cache_.kCheckedTruncateTaggedToWord32NumberOperator;
1393 case CheckTaggedInputMode::kNumberOrOddball:
1394 return &cache_.kCheckedTruncateTaggedToWord32NumberOrOddballOperator;
1395 }
1396 }
1397 return new (zone()) Operator1<CheckTaggedInputParameters>(
1398 IrOpcode::kCheckedTruncateTaggedToWord32,
1399 Operator::kFoldable | Operator::kNoThrow, "CheckedTruncateTaggedToWord32",
1400 1, 1, 1, 1, 1, 0, CheckTaggedInputParameters(mode, feedback));
1401 }
1402
CheckMaps(CheckMapsFlags flags,ZoneHandleSet<Map> maps,const FeedbackSource & feedback)1403 const Operator* SimplifiedOperatorBuilder::CheckMaps(
1404 CheckMapsFlags flags, ZoneHandleSet<Map> maps,
1405 const FeedbackSource& feedback) {
1406 CheckMapsParameters const parameters(flags, maps, feedback);
1407 return new (zone()) Operator1<CheckMapsParameters>( // --
1408 IrOpcode::kCheckMaps, // opcode
1409 Operator::kNoThrow | Operator::kNoWrite, // flags
1410 "CheckMaps", // name
1411 1, 1, 1, 0, 1, 0, // counts
1412 parameters); // parameter
1413 }
1414
MapGuard(ZoneHandleSet<Map> maps)1415 const Operator* SimplifiedOperatorBuilder::MapGuard(ZoneHandleSet<Map> maps) {
1416 DCHECK_LT(0, maps.size());
1417 return new (zone()) Operator1<ZoneHandleSet<Map>>( // --
1418 IrOpcode::kMapGuard, Operator::kEliminatable, // opcode
1419 "MapGuard", // name
1420 1, 1, 1, 0, 1, 0, // counts
1421 maps); // parameter
1422 }
1423
CompareMaps(ZoneHandleSet<Map> maps)1424 const Operator* SimplifiedOperatorBuilder::CompareMaps(
1425 ZoneHandleSet<Map> maps) {
1426 DCHECK_LT(0, maps.size());
1427 return new (zone()) Operator1<ZoneHandleSet<Map>>( // --
1428 IrOpcode::kCompareMaps, // opcode
1429 Operator::kNoThrow | Operator::kNoWrite, // flags
1430 "CompareMaps", // name
1431 1, 1, 1, 1, 1, 0, // counts
1432 maps); // parameter
1433 }
1434
ConvertReceiver(ConvertReceiverMode mode)1435 const Operator* SimplifiedOperatorBuilder::ConvertReceiver(
1436 ConvertReceiverMode mode) {
1437 switch (mode) {
1438 case ConvertReceiverMode::kAny:
1439 return &cache_.kConvertReceiverAnyOperator;
1440 case ConvertReceiverMode::kNullOrUndefined:
1441 return &cache_.kConvertReceiverNullOrUndefinedOperator;
1442 case ConvertReceiverMode::kNotNullOrUndefined:
1443 return &cache_.kConvertReceiverNotNullOrUndefinedOperator;
1444 }
1445 UNREACHABLE();
1446 return nullptr;
1447 }
1448
CheckFloat64Hole(CheckFloat64HoleMode mode,FeedbackSource const & feedback)1449 const Operator* SimplifiedOperatorBuilder::CheckFloat64Hole(
1450 CheckFloat64HoleMode mode, FeedbackSource const& feedback) {
1451 if (!feedback.IsValid()) {
1452 switch (mode) {
1453 case CheckFloat64HoleMode::kAllowReturnHole:
1454 return &cache_.kCheckFloat64HoleAllowReturnHoleOperator;
1455 case CheckFloat64HoleMode::kNeverReturnHole:
1456 return &cache_.kCheckFloat64HoleNeverReturnHoleOperator;
1457 }
1458 UNREACHABLE();
1459 }
1460 return new (zone()) Operator1<CheckFloat64HoleParameters>(
1461 IrOpcode::kCheckFloat64Hole, Operator::kFoldable | Operator::kNoThrow,
1462 "CheckFloat64Hole", 1, 1, 1, 1, 1, 0,
1463 CheckFloat64HoleParameters(mode, feedback));
1464 }
1465
SpeculativeBigIntAdd(BigIntOperationHint hint)1466 const Operator* SimplifiedOperatorBuilder::SpeculativeBigIntAdd(
1467 BigIntOperationHint hint) {
1468 return new (zone()) Operator1<BigIntOperationHint>(
1469 IrOpcode::kSpeculativeBigIntAdd, Operator::kFoldable | Operator::kNoThrow,
1470 "SpeculativeBigIntAdd", 2, 1, 1, 1, 1, 0, hint);
1471 }
1472
SpeculativeBigIntSubtract(BigIntOperationHint hint)1473 const Operator* SimplifiedOperatorBuilder::SpeculativeBigIntSubtract(
1474 BigIntOperationHint hint) {
1475 return new (zone()) Operator1<BigIntOperationHint>(
1476 IrOpcode::kSpeculativeBigIntSubtract,
1477 Operator::kFoldable | Operator::kNoThrow, "SpeculativeBigIntSubtract", 2,
1478 1, 1, 1, 1, 0, hint);
1479 }
1480
SpeculativeBigIntNegate(BigIntOperationHint hint)1481 const Operator* SimplifiedOperatorBuilder::SpeculativeBigIntNegate(
1482 BigIntOperationHint hint) {
1483 return new (zone()) Operator1<BigIntOperationHint>(
1484 IrOpcode::kSpeculativeBigIntNegate,
1485 Operator::kFoldable | Operator::kNoThrow, "SpeculativeBigIntNegate", 1, 1,
1486 1, 1, 1, 0, hint);
1487 }
1488
CheckClosure(const Handle<FeedbackCell> & feedback_cell)1489 const Operator* SimplifiedOperatorBuilder::CheckClosure(
1490 const Handle<FeedbackCell>& feedback_cell) {
1491 return new (zone()) Operator1<Handle<FeedbackCell>>( // --
1492 IrOpcode::kCheckClosure, // opcode
1493 Operator::kNoThrow | Operator::kNoWrite, // flags
1494 "CheckClosure", // name
1495 1, 1, 1, 1, 1, 0, // counts
1496 feedback_cell); // parameter
1497 }
1498
FeedbackCellOf(const Operator * op)1499 Handle<FeedbackCell> FeedbackCellOf(const Operator* op) {
1500 DCHECK(IrOpcode::kCheckClosure == op->opcode());
1501 return OpParameter<Handle<FeedbackCell>>(op);
1502 }
1503
SpeculativeToNumber(NumberOperationHint hint,const FeedbackSource & feedback)1504 const Operator* SimplifiedOperatorBuilder::SpeculativeToNumber(
1505 NumberOperationHint hint, const FeedbackSource& feedback) {
1506 if (!feedback.IsValid()) {
1507 switch (hint) {
1508 case NumberOperationHint::kSignedSmall:
1509 return &cache_.kSpeculativeToNumberSignedSmallOperator;
1510 case NumberOperationHint::kSignedSmallInputs:
1511 break;
1512 case NumberOperationHint::kSigned32:
1513 return &cache_.kSpeculativeToNumberSigned32Operator;
1514 case NumberOperationHint::kNumber:
1515 return &cache_.kSpeculativeToNumberNumberOperator;
1516 case NumberOperationHint::kNumberOrOddball:
1517 return &cache_.kSpeculativeToNumberNumberOrOddballOperator;
1518 }
1519 }
1520 return new (zone()) Operator1<NumberOperationParameters>(
1521 IrOpcode::kSpeculativeToNumber, Operator::kFoldable | Operator::kNoThrow,
1522 "SpeculativeToNumber", 1, 1, 1, 1, 1, 0,
1523 NumberOperationParameters(hint, feedback));
1524 }
1525
EnsureWritableFastElements()1526 const Operator* SimplifiedOperatorBuilder::EnsureWritableFastElements() {
1527 return &cache_.kEnsureWritableFastElements;
1528 }
1529
MaybeGrowFastElements(GrowFastElementsMode mode,const FeedbackSource & feedback)1530 const Operator* SimplifiedOperatorBuilder::MaybeGrowFastElements(
1531 GrowFastElementsMode mode, const FeedbackSource& feedback) {
1532 if (!feedback.IsValid()) {
1533 switch (mode) {
1534 case GrowFastElementsMode::kDoubleElements:
1535 return &cache_.kGrowFastElementsOperatorDoubleElements;
1536 case GrowFastElementsMode::kSmiOrObjectElements:
1537 return &cache_.kGrowFastElementsOperatorSmiOrObjectElements;
1538 }
1539 }
1540 return new (zone()) Operator1<GrowFastElementsParameters>( // --
1541 IrOpcode::kMaybeGrowFastElements, // opcode
1542 Operator::kNoThrow, // flags
1543 "MaybeGrowFastElements", // name
1544 4, 1, 1, 1, 1, 0, // counts
1545 GrowFastElementsParameters(mode, feedback)); // parameter
1546 }
1547
TransitionElementsKind(ElementsTransition transition)1548 const Operator* SimplifiedOperatorBuilder::TransitionElementsKind(
1549 ElementsTransition transition) {
1550 return new (zone()) Operator1<ElementsTransition>( // --
1551 IrOpcode::kTransitionElementsKind, // opcode
1552 Operator::kNoThrow, // flags
1553 "TransitionElementsKind", // name
1554 1, 1, 1, 0, 1, 0, // counts
1555 transition); // parameter
1556 }
1557
1558 namespace {
1559
1560 struct ArgumentsLengthParameters {
1561 int formal_parameter_count;
1562 bool is_rest_length;
1563 };
1564
operator ==(ArgumentsLengthParameters first,ArgumentsLengthParameters second)1565 bool operator==(ArgumentsLengthParameters first,
1566 ArgumentsLengthParameters second) {
1567 return first.formal_parameter_count == second.formal_parameter_count &&
1568 first.is_rest_length == second.is_rest_length;
1569 }
1570
hash_value(ArgumentsLengthParameters param)1571 size_t hash_value(ArgumentsLengthParameters param) {
1572 return base::hash_combine(param.formal_parameter_count, param.is_rest_length);
1573 }
1574
operator <<(std::ostream & os,ArgumentsLengthParameters param)1575 std::ostream& operator<<(std::ostream& os, ArgumentsLengthParameters param) {
1576 return os << param.formal_parameter_count << ", "
1577 << (param.is_rest_length ? "rest length" : "not rest length");
1578 }
1579
1580 } // namespace
1581
ArgumentsLength(int formal_parameter_count,bool is_rest_length)1582 const Operator* SimplifiedOperatorBuilder::ArgumentsLength(
1583 int formal_parameter_count, bool is_rest_length) {
1584 return new (zone()) Operator1<ArgumentsLengthParameters>( // --
1585 IrOpcode::kArgumentsLength, // opcode
1586 Operator::kPure, // flags
1587 "ArgumentsLength", // name
1588 1, 0, 0, 1, 0, 0, // counts
1589 ArgumentsLengthParameters{formal_parameter_count,
1590 is_rest_length}); // parameter
1591 }
1592
FormalParameterCountOf(const Operator * op)1593 int FormalParameterCountOf(const Operator* op) {
1594 DCHECK_EQ(IrOpcode::kArgumentsLength, op->opcode());
1595 return OpParameter<ArgumentsLengthParameters>(op).formal_parameter_count;
1596 }
1597
IsRestLengthOf(const Operator * op)1598 bool IsRestLengthOf(const Operator* op) {
1599 DCHECK_EQ(IrOpcode::kArgumentsLength, op->opcode());
1600 return OpParameter<ArgumentsLengthParameters>(op).is_rest_length;
1601 }
1602
operator ==(CheckParameters const & lhs,CheckParameters const & rhs)1603 bool operator==(CheckParameters const& lhs, CheckParameters const& rhs) {
1604 return lhs.feedback() == rhs.feedback();
1605 }
1606
hash_value(CheckParameters const & p)1607 size_t hash_value(CheckParameters const& p) {
1608 FeedbackSource::Hash feedback_hash;
1609 return feedback_hash(p.feedback());
1610 }
1611
operator <<(std::ostream & os,CheckParameters const & p)1612 std::ostream& operator<<(std::ostream& os, CheckParameters const& p) {
1613 return os << p.feedback();
1614 }
1615
CheckParametersOf(Operator const * op)1616 CheckParameters const& CheckParametersOf(Operator const* op) {
1617 if (op->opcode() == IrOpcode::kCheckBounds ||
1618 op->opcode() == IrOpcode::kCheckedUint32Bounds ||
1619 op->opcode() == IrOpcode::kCheckedUint64Bounds) {
1620 return OpParameter<CheckBoundsParameters>(op).check_parameters();
1621 }
1622 #define MAKE_OR(name, arg2, arg3) op->opcode() == IrOpcode::k##name ||
1623 CHECK((CHECKED_WITH_FEEDBACK_OP_LIST(MAKE_OR) false));
1624 #undef MAKE_OR
1625 return OpParameter<CheckParameters>(op);
1626 }
1627
operator ==(CheckBoundsParameters const & lhs,CheckBoundsParameters const & rhs)1628 bool operator==(CheckBoundsParameters const& lhs,
1629 CheckBoundsParameters const& rhs) {
1630 return lhs.check_parameters() == rhs.check_parameters() &&
1631 lhs.mode() == rhs.mode();
1632 }
1633
hash_value(CheckBoundsParameters const & p)1634 size_t hash_value(CheckBoundsParameters const& p) {
1635 return base::hash_combine(hash_value(p.check_parameters()), p.mode());
1636 }
1637
operator <<(std::ostream & os,CheckBoundsParameters const & p)1638 std::ostream& operator<<(std::ostream& os, CheckBoundsParameters const& p) {
1639 os << p.check_parameters() << ", ";
1640 switch (p.mode()) {
1641 case CheckBoundsParameters::kDeoptOnOutOfBounds:
1642 os << "deopt";
1643 break;
1644 case CheckBoundsParameters::kAbortOnOutOfBounds:
1645 os << "abort";
1646 break;
1647 }
1648 return os;
1649 }
1650
CheckBoundsParametersOf(Operator const * op)1651 CheckBoundsParameters const& CheckBoundsParametersOf(Operator const* op) {
1652 DCHECK(op->opcode() == IrOpcode::kCheckBounds ||
1653 op->opcode() == IrOpcode::kCheckedUint32Bounds ||
1654 op->opcode() == IrOpcode::kCheckedUint64Bounds);
1655 return OpParameter<CheckBoundsParameters>(op);
1656 }
1657
operator ==(CheckIfParameters const & lhs,CheckIfParameters const & rhs)1658 bool operator==(CheckIfParameters const& lhs, CheckIfParameters const& rhs) {
1659 return lhs.reason() == rhs.reason() && lhs.feedback() == rhs.feedback();
1660 }
1661
hash_value(CheckIfParameters const & p)1662 size_t hash_value(CheckIfParameters const& p) {
1663 FeedbackSource::Hash feedback_hash;
1664 return base::hash_combine(p.reason(), feedback_hash(p.feedback()));
1665 }
1666
operator <<(std::ostream & os,CheckIfParameters const & p)1667 std::ostream& operator<<(std::ostream& os, CheckIfParameters const& p) {
1668 return os << p.reason() << ", " << p.feedback();
1669 }
1670
CheckIfParametersOf(Operator const * op)1671 CheckIfParameters const& CheckIfParametersOf(Operator const* op) {
1672 CHECK(op->opcode() == IrOpcode::kCheckIf);
1673 return OpParameter<CheckIfParameters>(op);
1674 }
1675
NewDoubleElements(AllocationType allocation)1676 const Operator* SimplifiedOperatorBuilder::NewDoubleElements(
1677 AllocationType allocation) {
1678 return new (zone()) Operator1<AllocationType>( // --
1679 IrOpcode::kNewDoubleElements, // opcode
1680 Operator::kEliminatable, // flags
1681 "NewDoubleElements", // name
1682 1, 1, 1, 1, 1, 0, // counts
1683 allocation); // parameter
1684 }
1685
NewSmiOrObjectElements(AllocationType allocation)1686 const Operator* SimplifiedOperatorBuilder::NewSmiOrObjectElements(
1687 AllocationType allocation) {
1688 return new (zone()) Operator1<AllocationType>( // --
1689 IrOpcode::kNewSmiOrObjectElements, // opcode
1690 Operator::kEliminatable, // flags
1691 "NewSmiOrObjectElements", // name
1692 1, 1, 1, 1, 1, 0, // counts
1693 allocation); // parameter
1694 }
1695
NewArgumentsElements(int mapped_count)1696 const Operator* SimplifiedOperatorBuilder::NewArgumentsElements(
1697 int mapped_count) {
1698 return new (zone()) Operator1<int>( // --
1699 IrOpcode::kNewArgumentsElements, // opcode
1700 Operator::kEliminatable, // flags
1701 "NewArgumentsElements", // name
1702 2, 1, 0, 1, 1, 0, // counts
1703 mapped_count); // parameter
1704 }
1705
NewArgumentsElementsMappedCountOf(const Operator * op)1706 int NewArgumentsElementsMappedCountOf(const Operator* op) {
1707 DCHECK_EQ(IrOpcode::kNewArgumentsElements, op->opcode());
1708 return OpParameter<int>(op);
1709 }
1710
FastApiCallParametersOf(const Operator * op)1711 FastApiCallParameters const& FastApiCallParametersOf(const Operator* op) {
1712 DCHECK_EQ(IrOpcode::kFastApiCall, op->opcode());
1713 return OpParameter<FastApiCallParameters>(op);
1714 }
1715
operator <<(std::ostream & os,FastApiCallParameters const & p)1716 std::ostream& operator<<(std::ostream& os, FastApiCallParameters const& p) {
1717 return os << p.signature() << ", " << p.feedback();
1718 }
1719
hash_value(FastApiCallParameters const & p)1720 size_t hash_value(FastApiCallParameters const& p) {
1721 return base::hash_combine(p.signature(),
1722 FeedbackSource::Hash()(p.feedback()));
1723 }
1724
operator ==(FastApiCallParameters const & lhs,FastApiCallParameters const & rhs)1725 bool operator==(FastApiCallParameters const& lhs,
1726 FastApiCallParameters const& rhs) {
1727 return lhs.signature() == rhs.signature() && lhs.feedback() == rhs.feedback();
1728 }
1729
Allocate(Type type,AllocationType allocation)1730 const Operator* SimplifiedOperatorBuilder::Allocate(Type type,
1731 AllocationType allocation) {
1732 return new (zone()) Operator1<AllocateParameters>(
1733 IrOpcode::kAllocate, Operator::kEliminatable, "Allocate", 1, 1, 1, 1, 1,
1734 0, AllocateParameters(type, allocation));
1735 }
1736
AllocateRaw(Type type,AllocationType allocation,AllowLargeObjects allow_large_objects)1737 const Operator* SimplifiedOperatorBuilder::AllocateRaw(
1738 Type type, AllocationType allocation,
1739 AllowLargeObjects allow_large_objects) {
1740 // We forbid optimized allocations to allocate in a different generation than
1741 // requested.
1742 DCHECK(!(allow_large_objects == AllowLargeObjects::kTrue &&
1743 allocation == AllocationType::kYoung &&
1744 !FLAG_young_generation_large_objects));
1745 return new (zone()) Operator1<AllocateParameters>(
1746 IrOpcode::kAllocateRaw, Operator::kEliminatable, "AllocateRaw", 1, 1, 1,
1747 1, 1, 1, AllocateParameters(type, allocation, allow_large_objects));
1748 }
1749
1750 #define SPECULATIVE_NUMBER_BINOP(Name) \
1751 const Operator* SimplifiedOperatorBuilder::Name(NumberOperationHint hint) { \
1752 switch (hint) { \
1753 case NumberOperationHint::kSignedSmall: \
1754 return &cache_.k##Name##SignedSmallOperator; \
1755 case NumberOperationHint::kSignedSmallInputs: \
1756 return &cache_.k##Name##SignedSmallInputsOperator; \
1757 case NumberOperationHint::kSigned32: \
1758 return &cache_.k##Name##Signed32Operator; \
1759 case NumberOperationHint::kNumber: \
1760 return &cache_.k##Name##NumberOperator; \
1761 case NumberOperationHint::kNumberOrOddball: \
1762 return &cache_.k##Name##NumberOrOddballOperator; \
1763 } \
1764 UNREACHABLE(); \
1765 return nullptr; \
1766 }
1767 SPECULATIVE_NUMBER_BINOP_LIST(SPECULATIVE_NUMBER_BINOP)
1768 #undef SPECULATIVE_NUMBER_BINOP
1769
1770 #define ACCESS_OP_LIST(V) \
1771 V(LoadField, FieldAccess, Operator::kNoWrite, 1, 1, 1) \
1772 V(StoreField, FieldAccess, Operator::kNoRead, 2, 1, 0) \
1773 V(LoadElement, ElementAccess, Operator::kNoWrite, 2, 1, 1) \
1774 V(StoreElement, ElementAccess, Operator::kNoRead, 3, 1, 0) \
1775 V(LoadTypedElement, ExternalArrayType, Operator::kNoWrite, 4, 1, 1) \
1776 V(LoadFromObject, ObjectAccess, Operator::kNoWrite, 2, 1, 1) \
1777 V(StoreTypedElement, ExternalArrayType, Operator::kNoRead, 5, 1, 0) \
1778 V(StoreToObject, ObjectAccess, Operator::kNoRead, 3, 1, 0) \
1779 V(LoadDataViewElement, ExternalArrayType, Operator::kNoWrite, 4, 1, 1) \
1780 V(StoreDataViewElement, ExternalArrayType, Operator::kNoRead, 5, 1, 0)
1781
1782 #define ACCESS(Name, Type, properties, value_input_count, control_input_count, \
1783 output_count) \
1784 const Operator* SimplifiedOperatorBuilder::Name(const Type& access) { \
1785 return new (zone()) \
1786 Operator1<Type>(IrOpcode::k##Name, \
1787 Operator::kNoDeopt | Operator::kNoThrow | properties, \
1788 #Name, value_input_count, 1, control_input_count, \
1789 output_count, 1, 0, access); \
1790 }
ACCESS_OP_LIST(ACCESS) const1791 ACCESS_OP_LIST(ACCESS)
1792 #undef ACCESS
1793
1794 const Operator* SimplifiedOperatorBuilder::LoadMessage() {
1795 return new (zone()) Operator(IrOpcode::kLoadMessage, Operator::kEliminatable,
1796 "LoadMessage", 1, 1, 1, 1, 1, 0);
1797 }
1798
StoreMessage()1799 const Operator* SimplifiedOperatorBuilder::StoreMessage() {
1800 return new (zone())
1801 Operator(IrOpcode::kStoreMessage,
1802 Operator::kNoDeopt | Operator::kNoThrow | Operator::kNoRead,
1803 "StoreMessage", 2, 1, 1, 0, 1, 0);
1804 }
1805
LoadStackArgument()1806 const Operator* SimplifiedOperatorBuilder::LoadStackArgument() {
1807 return &cache_.kLoadStackArgument;
1808 }
1809
TransitionAndStoreElement(Handle<Map> double_map,Handle<Map> fast_map)1810 const Operator* SimplifiedOperatorBuilder::TransitionAndStoreElement(
1811 Handle<Map> double_map, Handle<Map> fast_map) {
1812 TransitionAndStoreElementParameters parameters(double_map, fast_map);
1813 return new (zone()) Operator1<TransitionAndStoreElementParameters>(
1814 IrOpcode::kTransitionAndStoreElement,
1815 Operator::kNoDeopt | Operator::kNoThrow, "TransitionAndStoreElement", 3,
1816 1, 1, 0, 1, 0, parameters);
1817 }
1818
StoreSignedSmallElement()1819 const Operator* SimplifiedOperatorBuilder::StoreSignedSmallElement() {
1820 return new (zone()) Operator(IrOpcode::kStoreSignedSmallElement,
1821 Operator::kNoDeopt | Operator::kNoThrow,
1822 "StoreSignedSmallElement", 3, 1, 1, 0, 1, 0);
1823 }
1824
TransitionAndStoreNumberElement(Handle<Map> double_map)1825 const Operator* SimplifiedOperatorBuilder::TransitionAndStoreNumberElement(
1826 Handle<Map> double_map) {
1827 TransitionAndStoreNumberElementParameters parameters(double_map);
1828 return new (zone()) Operator1<TransitionAndStoreNumberElementParameters>(
1829 IrOpcode::kTransitionAndStoreNumberElement,
1830 Operator::kNoDeopt | Operator::kNoThrow,
1831 "TransitionAndStoreNumberElement", 3, 1, 1, 0, 1, 0, parameters);
1832 }
1833
TransitionAndStoreNonNumberElement(Handle<Map> fast_map,Type value_type)1834 const Operator* SimplifiedOperatorBuilder::TransitionAndStoreNonNumberElement(
1835 Handle<Map> fast_map, Type value_type) {
1836 TransitionAndStoreNonNumberElementParameters parameters(fast_map, value_type);
1837 return new (zone()) Operator1<TransitionAndStoreNonNumberElementParameters>(
1838 IrOpcode::kTransitionAndStoreNonNumberElement,
1839 Operator::kNoDeopt | Operator::kNoThrow,
1840 "TransitionAndStoreNonNumberElement", 3, 1, 1, 0, 1, 0, parameters);
1841 }
1842
1843 #undef PURE_OP_LIST
1844 #undef EFFECT_DEPENDENT_OP_LIST
1845 #undef SPECULATIVE_NUMBER_BINOP_LIST
1846 #undef CHECKED_WITH_FEEDBACK_OP_LIST
1847 #undef CHECKED_BOUNDS_OP_LIST
1848 #undef CHECKED_OP_LIST
1849 #undef ACCESS_OP_LIST
1850
1851 } // namespace compiler
1852 } // namespace internal
1853 } // namespace v8
1854