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