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