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