V8 API Reference, 7.2.502.16 (for Deno 0.2.4)
simplified-operator.cc
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 
20 size_t hash_value(BaseTaggedness base_taggedness) {
21  return static_cast<uint8_t>(base_taggedness);
22 }
23 
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 
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 
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 
51 size_t hash_value(LoadSensitivity load_sensitivity) {
52  return static_cast<size_t>(load_sensitivity);
53 }
54 
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 
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) {
83  os << ", " << access.load_sensitivity;
84  }
85  os << "]";
86  return os;
87 }
88 
89 template <>
90 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 
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 
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 
117 std::ostream& operator<<(std::ostream& os, ElementAccess const& access) {
118  os << access.base_is_tagged << ", " << access.header_size << ", "
119  << access.type << ", " << access.machine_type << ", "
120  << access.write_barrier_kind;
121  if (FLAG_untrusted_code_mitigations) {
122  os << ", " << access.load_sensitivity;
123  }
124  return os;
125 }
126 
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 
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 
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 
150 ConvertReceiverMode ConvertReceiverModeOf(Operator const* op) {
151  DCHECK_EQ(IrOpcode::kConvertReceiver, op->opcode());
152  return OpParameter<ConvertReceiverMode>(op);
153 }
154 
155 size_t hash_value(CheckFloat64HoleMode mode) {
156  return static_cast<size_t>(mode);
157 }
158 
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 
169 CheckFloat64HoleParameters const& CheckFloat64HoleParametersOf(
170  Operator const* op) {
171  DCHECK_EQ(IrOpcode::kCheckFloat64Hole, op->opcode());
172  return OpParameter<CheckFloat64HoleParameters>(op);
173 }
174 
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 
182 size_t hash_value(const CheckFloat64HoleParameters& params) {
183  return base::hash_combine(params.mode(), params.feedback());
184 }
185 
186 bool operator==(CheckFloat64HoleParameters const& lhs,
187  CheckFloat64HoleParameters const& rhs) {
188  return lhs.mode() == rhs.mode() && lhs.feedback() == rhs.feedback();
189 }
190 
191 bool operator!=(CheckFloat64HoleParameters const& lhs,
192  CheckFloat64HoleParameters const& rhs) {
193  return !(lhs == rhs);
194 }
195 
196 CheckForMinusZeroMode CheckMinusZeroModeOf(const Operator* op) {
197  DCHECK(op->opcode() == IrOpcode::kChangeFloat64ToTagged ||
198  op->opcode() == IrOpcode::kCheckedInt32Mul);
199  return OpParameter<CheckForMinusZeroMode>(op);
200 }
201 
202 size_t hash_value(CheckForMinusZeroMode mode) {
203  return static_cast<size_t>(mode);
204 }
205 
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 
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 
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 
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 
250 bool operator==(MapsParameterInfo const& lhs, MapsParameterInfo const& rhs) {
251  return lhs.maps() == rhs.maps();
252 }
253 
254 bool operator!=(MapsParameterInfo const& lhs, MapsParameterInfo const& rhs) {
255  return !(lhs == rhs);
256 }
257 
258 size_t hash_value(MapsParameterInfo const& p) { return hash_value(p.maps()); }
259 
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 
266 size_t hash_value(CheckMapsParameters const& p) {
267  return base::hash_combine(p.flags(), p.maps(), p.feedback());
268 }
269 
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 
278 CheckMapsParameters const& CheckMapsParametersOf(Operator const* op) {
279  DCHECK_EQ(IrOpcode::kCheckMaps, op->opcode());
280  return OpParameter<CheckMapsParameters>(op);
281 }
282 
283 MapsParameterInfo const& CompareMapsParametersOf(Operator const* op) {
284  DCHECK_EQ(IrOpcode::kCompareMaps, op->opcode());
285  return OpParameter<MapsParameterInfo>(op);
286 }
287 
288 MapsParameterInfo const& MapGuardMapsOf(Operator const* op) {
289  DCHECK_EQ(IrOpcode::kMapGuard, op->opcode());
290  return OpParameter<MapsParameterInfo>(op);
291 }
292 
293 size_t hash_value(CheckTaggedInputMode mode) {
294  return static_cast<size_t>(mode);
295 }
296 
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 
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 
317 bool operator==(const GrowFastElementsParameters& lhs,
318  const GrowFastElementsParameters& rhs) {
319  return lhs.mode() == rhs.mode() && lhs.feedback() == rhs.feedback();
320 }
321 
322 inline size_t hash_value(const GrowFastElementsParameters& params) {
323  return base::hash_combine(params.mode(), params.feedback());
324 }
325 
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 
335 const GrowFastElementsParameters& GrowFastElementsParametersOf(
336  const Operator* op) {
337  DCHECK_EQ(IrOpcode::kMaybeGrowFastElements, op->opcode());
338  return OpParameter<GrowFastElementsParameters>(op);
339 }
340 
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 
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 
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 
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 
378  Handle<Map> double_map() const { return double_map_; }
379  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 
386 TransitionAndStoreElementParameters::TransitionAndStoreElementParameters(
387  Handle<Map> double_map, Handle<Map> fast_map)
388  : double_map_(double_map), fast_map_(fast_map) {}
389 
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 
396 size_t hash_value(TransitionAndStoreElementParameters parameters) {
397  return base::hash_combine(parameters.fast_map().address(),
398  parameters.double_map().address());
399 }
400 
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 
417  Handle<Map> fast_map() const { return fast_map_; }
418  Type value_type() const { return value_type_; }
419 
420  private:
421  Handle<Map> const fast_map_;
422  Type value_type_;
423 };
424 
425 TransitionAndStoreNonNumberElementParameters::
426  TransitionAndStoreNonNumberElementParameters(Handle<Map> fast_map,
427  Type value_type)
428  : fast_map_(fast_map), value_type_(value_type) {}
429 
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 
436 size_t hash_value(TransitionAndStoreNonNumberElementParameters parameters) {
437  return base::hash_combine(parameters.fast_map().address(),
438  parameters.value_type());
439 }
440 
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 
456  Handle<Map> double_map() const { return double_map_; }
457 
458  private:
459  Handle<Map> const double_map_;
460 };
461 
462 TransitionAndStoreNumberElementParameters::
463  TransitionAndStoreNumberElementParameters(Handle<Map> double_map)
464  : double_map_(double_map) {}
465 
466 bool operator==(TransitionAndStoreNumberElementParameters const& lhs,
467  TransitionAndStoreNumberElementParameters const& rhs) {
468  return lhs.double_map().address() == rhs.double_map().address();
469 }
470 
471 size_t hash_value(TransitionAndStoreNumberElementParameters parameters) {
472  return base::hash_combine(parameters.double_map().address());
473 }
474 
475 std::ostream& operator<<(std::ostream& os,
476  TransitionAndStoreNumberElementParameters parameters) {
477  return os << "double-map" << Brief(*parameters.double_map());
478 }
479 
480 } // namespace
481 
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 
493 Type ValueTypeParameterOf(const Operator* op) {
494  DCHECK_EQ(IrOpcode::kTransitionAndStoreNonNumberElement, op->opcode());
495  return OpParameter<TransitionAndStoreNonNumberElementParameters>(op)
496  .value_type();
497 }
498 
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 
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 
526 size_t hash_value(NumberOperationHint hint) {
527  return static_cast<uint8_t>(hint);
528 }
529 
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 
550 bool operator==(NumberOperationParameters const& lhs,
551  NumberOperationParameters const& rhs) {
552  return lhs.hint() == rhs.hint() && lhs.feedback() == rhs.feedback();
553 }
554 
555 size_t hash_value(NumberOperationParameters const& p) {
556  return base::hash_combine(p.hint(), p.feedback());
557 }
558 
559 std::ostream& operator<<(std::ostream& os, NumberOperationParameters const& p) {
560  return os << p.hint() << " " << p.feedback();
561 }
562 
563 NumberOperationParameters const& NumberOperationParametersOf(
564  Operator const* op) {
565  DCHECK_EQ(IrOpcode::kSpeculativeToNumber, op->opcode());
566  return OpParameter<NumberOperationParameters>(op);
567 }
568 
569 size_t hash_value(AllocateParameters info) {
570  return base::hash_combine(info.type(), info.pretenure());
571 }
572 
573 V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
574  AllocateParameters info) {
575  return os << info.type() << ", " << info.pretenure();
576 }
577 
578 bool operator==(AllocateParameters const& lhs, AllocateParameters const& rhs) {
579  return lhs.pretenure() == rhs.pretenure() && lhs.type() == rhs.type();
580 }
581 
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 
592 Type AllocateTypeOf(const Operator* op) {
593  DCHECK_EQ(IrOpcode::kAllocate, op->opcode());
594  return OpParameter<AllocateParameters>(op).type();
595 }
596 
597 UnicodeEncoding UnicodeEncodingOf(const Operator* op) {
598  DCHECK(op->opcode() == IrOpcode::kStringFromSingleCodePoint ||
599  op->opcode() == IrOpcode::kStringCodePointAt);
600  return OpParameter<UnicodeEncoding>(op);
601 }
602 
603 AbortReason AbortReasonOf(const Operator* op) {
604  DCHECK_EQ(IrOpcode::kRuntimeAbort, op->opcode());
605  return static_cast<AbortReason>(OpParameter<int>(op));
606 }
607 
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 
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 
624 size_t hash_value(const CheckTaggedInputParameters& params) {
625  return base::hash_combine(params.mode(), params.feedback());
626 }
627 
628 bool operator==(CheckTaggedInputParameters const& lhs,
629  CheckTaggedInputParameters const& rhs) {
630  return lhs.mode() == rhs.mode() && lhs.feedback() == rhs.feedback();
631 }
632 
633 const CheckMinusZeroParameters& CheckMinusZeroParametersOf(const Operator* op) {
634  DCHECK(op->opcode() == IrOpcode::kCheckedTaggedToInt32 ||
635  op->opcode() == IrOpcode::kCheckedTaggedToInt64 ||
636  op->opcode() == IrOpcode::kCheckedFloat64ToInt32 ||
637  op->opcode() == IrOpcode::kCheckedFloat64ToInt64);
638  return OpParameter<CheckMinusZeroParameters>(op);
639 }
640 
641 std::ostream& operator<<(std::ostream& os,
642  const CheckMinusZeroParameters& params) {
643  os << params.mode();
644  if (params.feedback().IsValid()) {
645  os << "; " << params.feedback();
646  }
647  return os;
648 }
649 
650 size_t hash_value(const CheckMinusZeroParameters& params) {
651  return base::hash_combine(params.mode(), params.feedback());
652 }
653 
654 bool operator==(CheckMinusZeroParameters const& lhs,
655  CheckMinusZeroParameters const& rhs) {
656  return lhs.mode() == rhs.mode() && lhs.feedback() == rhs.feedback();
657 }
658 
659 #define PURE_OP_LIST(V) \
660  V(BooleanNot, Operator::kNoProperties, 1, 0) \
661  V(NumberEqual, Operator::kCommutative, 2, 0) \
662  V(NumberLessThan, Operator::kNoProperties, 2, 0) \
663  V(NumberLessThanOrEqual, Operator::kNoProperties, 2, 0) \
664  V(NumberAdd, Operator::kCommutative, 2, 0) \
665  V(NumberSubtract, Operator::kNoProperties, 2, 0) \
666  V(NumberMultiply, Operator::kCommutative, 2, 0) \
667  V(NumberDivide, Operator::kNoProperties, 2, 0) \
668  V(NumberModulus, Operator::kNoProperties, 2, 0) \
669  V(NumberBitwiseOr, Operator::kCommutative, 2, 0) \
670  V(NumberBitwiseXor, Operator::kCommutative, 2, 0) \
671  V(NumberBitwiseAnd, Operator::kCommutative, 2, 0) \
672  V(NumberShiftLeft, Operator::kNoProperties, 2, 0) \
673  V(NumberShiftRight, Operator::kNoProperties, 2, 0) \
674  V(NumberShiftRightLogical, Operator::kNoProperties, 2, 0) \
675  V(NumberImul, Operator::kCommutative, 2, 0) \
676  V(NumberAbs, Operator::kNoProperties, 1, 0) \
677  V(NumberClz32, Operator::kNoProperties, 1, 0) \
678  V(NumberCeil, Operator::kNoProperties, 1, 0) \
679  V(NumberFloor, Operator::kNoProperties, 1, 0) \
680  V(NumberFround, Operator::kNoProperties, 1, 0) \
681  V(NumberAcos, Operator::kNoProperties, 1, 0) \
682  V(NumberAcosh, Operator::kNoProperties, 1, 0) \
683  V(NumberAsin, Operator::kNoProperties, 1, 0) \
684  V(NumberAsinh, Operator::kNoProperties, 1, 0) \
685  V(NumberAtan, Operator::kNoProperties, 1, 0) \
686  V(NumberAtan2, Operator::kNoProperties, 2, 0) \
687  V(NumberAtanh, Operator::kNoProperties, 1, 0) \
688  V(NumberCbrt, Operator::kNoProperties, 1, 0) \
689  V(NumberCos, Operator::kNoProperties, 1, 0) \
690  V(NumberCosh, Operator::kNoProperties, 1, 0) \
691  V(NumberExp, Operator::kNoProperties, 1, 0) \
692  V(NumberExpm1, Operator::kNoProperties, 1, 0) \
693  V(NumberLog, Operator::kNoProperties, 1, 0) \
694  V(NumberLog1p, Operator::kNoProperties, 1, 0) \
695  V(NumberLog10, Operator::kNoProperties, 1, 0) \
696  V(NumberLog2, Operator::kNoProperties, 1, 0) \
697  V(NumberMax, Operator::kNoProperties, 2, 0) \
698  V(NumberMin, Operator::kNoProperties, 2, 0) \
699  V(NumberPow, Operator::kNoProperties, 2, 0) \
700  V(NumberRound, Operator::kNoProperties, 1, 0) \
701  V(NumberSign, Operator::kNoProperties, 1, 0) \
702  V(NumberSin, Operator::kNoProperties, 1, 0) \
703  V(NumberSinh, Operator::kNoProperties, 1, 0) \
704  V(NumberSqrt, Operator::kNoProperties, 1, 0) \
705  V(NumberTan, Operator::kNoProperties, 1, 0) \
706  V(NumberTanh, Operator::kNoProperties, 1, 0) \
707  V(NumberTrunc, Operator::kNoProperties, 1, 0) \
708  V(NumberToBoolean, Operator::kNoProperties, 1, 0) \
709  V(NumberToInt32, Operator::kNoProperties, 1, 0) \
710  V(NumberToString, Operator::kNoProperties, 1, 0) \
711  V(NumberToUint32, Operator::kNoProperties, 1, 0) \
712  V(NumberToUint8Clamped, Operator::kNoProperties, 1, 0) \
713  V(NumberSilenceNaN, Operator::kNoProperties, 1, 0) \
714  V(StringConcat, Operator::kNoProperties, 3, 0) \
715  V(StringToNumber, Operator::kNoProperties, 1, 0) \
716  V(StringFromSingleCharCode, Operator::kNoProperties, 1, 0) \
717  V(StringIndexOf, Operator::kNoProperties, 3, 0) \
718  V(StringLength, Operator::kNoProperties, 1, 0) \
719  V(StringToLowerCaseIntl, Operator::kNoProperties, 1, 0) \
720  V(StringToUpperCaseIntl, Operator::kNoProperties, 1, 0) \
721  V(TypeOf, Operator::kNoProperties, 1, 1) \
722  V(PlainPrimitiveToNumber, Operator::kNoProperties, 1, 0) \
723  V(PlainPrimitiveToWord32, Operator::kNoProperties, 1, 0) \
724  V(PlainPrimitiveToFloat64, Operator::kNoProperties, 1, 0) \
725  V(ChangeTaggedSignedToInt32, Operator::kNoProperties, 1, 0) \
726  V(ChangeTaggedSignedToInt64, Operator::kNoProperties, 1, 0) \
727  V(ChangeTaggedToInt32, Operator::kNoProperties, 1, 0) \
728  V(ChangeTaggedToInt64, Operator::kNoProperties, 1, 0) \
729  V(ChangeTaggedToUint32, Operator::kNoProperties, 1, 0) \
730  V(ChangeTaggedToFloat64, Operator::kNoProperties, 1, 0) \
731  V(ChangeTaggedToTaggedSigned, Operator::kNoProperties, 1, 0) \
732  V(ChangeFloat64ToTaggedPointer, Operator::kNoProperties, 1, 0) \
733  V(ChangeInt31ToTaggedSigned, Operator::kNoProperties, 1, 0) \
734  V(ChangeInt32ToTagged, Operator::kNoProperties, 1, 0) \
735  V(ChangeInt64ToTagged, Operator::kNoProperties, 1, 0) \
736  V(ChangeUint32ToTagged, Operator::kNoProperties, 1, 0) \
737  V(ChangeUint64ToTagged, Operator::kNoProperties, 1, 0) \
738  V(ChangeTaggedToBit, Operator::kNoProperties, 1, 0) \
739  V(ChangeBitToTagged, Operator::kNoProperties, 1, 0) \
740  V(TruncateTaggedToBit, Operator::kNoProperties, 1, 0) \
741  V(TruncateTaggedPointerToBit, Operator::kNoProperties, 1, 0) \
742  V(TruncateTaggedToWord32, Operator::kNoProperties, 1, 0) \
743  V(TruncateTaggedToFloat64, Operator::kNoProperties, 1, 0) \
744  V(ObjectIsArrayBufferView, Operator::kNoProperties, 1, 0) \
745  V(ObjectIsBigInt, Operator::kNoProperties, 1, 0) \
746  V(ObjectIsCallable, Operator::kNoProperties, 1, 0) \
747  V(ObjectIsConstructor, Operator::kNoProperties, 1, 0) \
748  V(ObjectIsDetectableCallable, Operator::kNoProperties, 1, 0) \
749  V(ObjectIsMinusZero, Operator::kNoProperties, 1, 0) \
750  V(NumberIsMinusZero, Operator::kNoProperties, 1, 0) \
751  V(ObjectIsNaN, Operator::kNoProperties, 1, 0) \
752  V(NumberIsNaN, Operator::kNoProperties, 1, 0) \
753  V(ObjectIsNonCallable, Operator::kNoProperties, 1, 0) \
754  V(ObjectIsNumber, Operator::kNoProperties, 1, 0) \
755  V(ObjectIsReceiver, Operator::kNoProperties, 1, 0) \
756  V(ObjectIsSmi, Operator::kNoProperties, 1, 0) \
757  V(ObjectIsString, Operator::kNoProperties, 1, 0) \
758  V(ObjectIsSymbol, Operator::kNoProperties, 1, 0) \
759  V(ObjectIsUndetectable, Operator::kNoProperties, 1, 0) \
760  V(NumberIsFloat64Hole, Operator::kNoProperties, 1, 0) \
761  V(NumberIsFinite, Operator::kNoProperties, 1, 0) \
762  V(ObjectIsFiniteNumber, Operator::kNoProperties, 1, 0) \
763  V(NumberIsInteger, Operator::kNoProperties, 1, 0) \
764  V(ObjectIsSafeInteger, Operator::kNoProperties, 1, 0) \
765  V(NumberIsSafeInteger, Operator::kNoProperties, 1, 0) \
766  V(ObjectIsInteger, Operator::kNoProperties, 1, 0) \
767  V(ConvertTaggedHoleToUndefined, Operator::kNoProperties, 1, 0) \
768  V(SameValue, Operator::kCommutative, 2, 0) \
769  V(ReferenceEqual, Operator::kCommutative, 2, 0) \
770  V(StringEqual, Operator::kCommutative, 2, 0) \
771  V(StringLessThan, Operator::kNoProperties, 2, 0) \
772  V(StringLessThanOrEqual, Operator::kNoProperties, 2, 0) \
773  V(ToBoolean, Operator::kNoProperties, 1, 0) \
774  V(NewConsString, Operator::kNoProperties, 3, 0) \
775  V(PoisonIndex, Operator::kNoProperties, 1, 0)
776 
777 #define EFFECT_DEPENDENT_OP_LIST(V) \
778  V(StringCharCodeAt, Operator::kNoProperties, 2, 1) \
779  V(StringSubstring, Operator::kNoProperties, 3, 1) \
780  V(DateNow, Operator::kNoProperties, 0, 1)
781 
782 #define SPECULATIVE_NUMBER_BINOP_LIST(V) \
783  SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(V) \
784  V(SpeculativeNumberEqual) \
785  V(SpeculativeNumberLessThan) \
786  V(SpeculativeNumberLessThanOrEqual)
787 
788 #define CHECKED_OP_LIST(V) \
789  V(CheckEqualsInternalizedString, 2, 0) \
790  V(CheckEqualsSymbol, 2, 0) \
791  V(CheckHeapObject, 1, 1) \
792  V(CheckInternalizedString, 1, 1) \
793  V(CheckNotTaggedHole, 1, 1) \
794  V(CheckReceiver, 1, 1) \
795  V(CheckReceiverOrNullOrUndefined, 1, 1) \
796  V(CheckSymbol, 1, 1) \
797  V(CheckedInt32Add, 2, 1) \
798  V(CheckedInt32Div, 2, 1) \
799  V(CheckedInt32Mod, 2, 1) \
800  V(CheckedInt32Sub, 2, 1) \
801  V(CheckedUint32Div, 2, 1) \
802  V(CheckedUint32Mod, 2, 1)
803 
804 #define CHECKED_WITH_FEEDBACK_OP_LIST(V) \
805  V(CheckBounds, 2, 1) \
806  V(CheckNumber, 1, 1) \
807  V(CheckSmi, 1, 1) \
808  V(CheckString, 1, 1) \
809  V(CheckedInt32ToTaggedSigned, 1, 1) \
810  V(CheckedInt64ToInt32, 1, 1) \
811  V(CheckedInt64ToTaggedSigned, 1, 1) \
812  V(CheckedTaggedSignedToInt32, 1, 1) \
813  V(CheckedTaggedToTaggedPointer, 1, 1) \
814  V(CheckedTaggedToTaggedSigned, 1, 1) \
815  V(CheckedUint32Bounds, 2, 1) \
816  V(CheckedUint32ToInt32, 1, 1) \
817  V(CheckedUint32ToTaggedSigned, 1, 1) \
818  V(CheckedUint64Bounds, 2, 1) \
819  V(CheckedUint64ToInt32, 1, 1) \
820  V(CheckedUint64ToTaggedSigned, 1, 1)
821 
823 #define PURE(Name, properties, value_input_count, control_input_count) \
824  struct Name##Operator final : public Operator { \
825  Name##Operator() \
826  : Operator(IrOpcode::k##Name, Operator::kPure | properties, #Name, \
827  value_input_count, 0, control_input_count, 1, 0, 0) {} \
828  }; \
829  Name##Operator k##Name;
830  PURE_OP_LIST(PURE)
831 #undef PURE
832 
833 #define EFFECT_DEPENDENT(Name, properties, value_input_count, \
834  control_input_count) \
835  struct Name##Operator final : public Operator { \
836  Name##Operator() \
837  : Operator(IrOpcode::k##Name, \
838  Operator::kNoDeopt | Operator::kNoWrite | \
839  Operator::kNoThrow | properties, \
840  #Name, value_input_count, 1, control_input_count, 1, 1, \
841  0) {} \
842  }; \
843  Name##Operator k##Name;
844  EFFECT_DEPENDENT_OP_LIST(EFFECT_DEPENDENT)
845 #undef EFFECT_DEPENDENT
846 
847 #define CHECKED(Name, value_input_count, value_output_count) \
848  struct Name##Operator final : public Operator { \
849  Name##Operator() \
850  : Operator(IrOpcode::k##Name, \
851  Operator::kFoldable | Operator::kNoThrow, #Name, \
852  value_input_count, 1, 1, value_output_count, 1, 0) {} \
853  }; \
854  Name##Operator k##Name;
855  CHECKED_OP_LIST(CHECKED)
856 #undef CHECKED
857 
858 #define CHECKED_WITH_FEEDBACK(Name, value_input_count, value_output_count) \
859  struct Name##Operator final : public Operator1<CheckParameters> { \
860  Name##Operator() \
861  : Operator1<CheckParameters>( \
862  IrOpcode::k##Name, Operator::kFoldable | Operator::kNoThrow, \
863  #Name, value_input_count, 1, 1, value_output_count, 1, 0, \
864  CheckParameters(VectorSlotPair())) {} \
865  }; \
866  Name##Operator k##Name;
867  CHECKED_WITH_FEEDBACK_OP_LIST(CHECKED_WITH_FEEDBACK)
868 #undef CHECKED_WITH_FEEDBACK
869 
870  template <DeoptimizeReason kDeoptimizeReason>
871  struct CheckIfOperator final : public Operator1<CheckIfParameters> {
874  IrOpcode::kCheckIf, Operator::kFoldable | Operator::kNoThrow,
875  "CheckIf", 1, 1, 1, 0, 1, 0,
876  CheckIfParameters(kDeoptimizeReason, VectorSlotPair())) {}
877  };
878 #define CHECK_IF(Name, message) \
879  CheckIfOperator<DeoptimizeReason::k##Name> kCheckIf##Name;
880  DEOPTIMIZE_REASON_LIST(CHECK_IF)
881 #undef CHECK_IF
882 
883  template <UnicodeEncoding kEncoding>
884  struct StringCodePointAtOperator final : public Operator1<UnicodeEncoding> {
886  : Operator1<UnicodeEncoding>(IrOpcode::kStringCodePointAt,
887  Operator::kFoldable | Operator::kNoThrow,
888  "StringCodePointAt", 2, 1, 1, 1, 1, 0,
889  kEncoding) {}
890  };
892  kStringCodePointAtOperatorUTF16;
894  kStringCodePointAtOperatorUTF32;
895 
896  template <UnicodeEncoding kEncoding>
898  : public Operator1<UnicodeEncoding> {
901  IrOpcode::kStringFromSingleCodePoint, Operator::kPure,
902  "StringFromSingleCodePoint", 1, 0, 0, 1, 0, 0, kEncoding) {}
903  };
905  kStringFromSingleCodePointOperatorUTF16;
907  kStringFromSingleCodePointOperatorUTF32;
908 
911  : Operator(IrOpcode::kFindOrderedHashMapEntry, Operator::kEliminatable,
912  "FindOrderedHashMapEntry", 2, 1, 1, 1, 1, 0) {}
913  };
914  FindOrderedHashMapEntryOperator kFindOrderedHashMapEntry;
915 
918  : Operator(IrOpcode::kFindOrderedHashMapEntryForInt32Key,
919  Operator::kEliminatable,
920  "FindOrderedHashMapEntryForInt32Key", 2, 1, 1, 1, 1, 0) {}
921  };
923  kFindOrderedHashMapEntryForInt32Key;
924 
925  struct ArgumentsFrameOperator final : public Operator {
927  : Operator(IrOpcode::kArgumentsFrame, Operator::kPure, "ArgumentsFrame",
928  0, 0, 0, 1, 0, 0) {}
929  };
930  ArgumentsFrameOperator kArgumentsFrame;
931 
932  template <CheckForMinusZeroMode kMode>
934  : public Operator1<CheckForMinusZeroMode> {
937  IrOpcode::kChangeFloat64ToTagged, Operator::kPure,
938  "ChangeFloat64ToTagged", 1, 0, 0, 1, 0, 0, kMode) {}
939  };
941  kChangeFloat64ToTaggedCheckForMinusZeroOperator;
943  kChangeFloat64ToTaggedDontCheckForMinusZeroOperator;
944 
945  template <CheckForMinusZeroMode kMode>
947  : public Operator1<CheckForMinusZeroMode> {
950  IrOpcode::kCheckedInt32Mul,
951  Operator::kFoldable | Operator::kNoThrow, "CheckedInt32Mul", 2, 1,
952  1, 1, 1, 0, kMode) {}
953  };
955  kCheckedInt32MulCheckForMinusZeroOperator;
957  kCheckedInt32MulDontCheckForMinusZeroOperator;
958 
959  template <CheckForMinusZeroMode kMode>
961  : public Operator1<CheckMinusZeroParameters> {
964  IrOpcode::kCheckedFloat64ToInt32,
965  Operator::kFoldable | Operator::kNoThrow, "CheckedFloat64ToInt32",
966  1, 1, 1, 1, 1, 0,
968  };
970  kCheckedFloat64ToInt32CheckForMinusZeroOperator;
972  kCheckedFloat64ToInt32DontCheckForMinusZeroOperator;
973 
974  template <CheckForMinusZeroMode kMode>
976  : public Operator1<CheckMinusZeroParameters> {
979  IrOpcode::kCheckedFloat64ToInt64,
980  Operator::kFoldable | Operator::kNoThrow, "CheckedFloat64ToInt64",
981  1, 1, 1, 1, 1, 0,
983  };
985  kCheckedFloat64ToInt64CheckForMinusZeroOperator;
987  kCheckedFloat64ToInt64DontCheckForMinusZeroOperator;
988 
989  template <CheckForMinusZeroMode kMode>
991  : public Operator1<CheckMinusZeroParameters> {
994  IrOpcode::kCheckedTaggedToInt32,
995  Operator::kFoldable | Operator::kNoThrow, "CheckedTaggedToInt32",
996  1, 1, 1, 1, 1, 0,
998  };
1000  kCheckedTaggedToInt32CheckForMinusZeroOperator;
1002  kCheckedTaggedToInt32DontCheckForMinusZeroOperator;
1003 
1004  template <CheckForMinusZeroMode kMode>
1006  : public Operator1<CheckMinusZeroParameters> {
1009  IrOpcode::kCheckedTaggedToInt64,
1010  Operator::kFoldable | Operator::kNoThrow, "CheckedTaggedToInt64",
1011  1, 1, 1, 1, 1, 0,
1013  };
1015  kCheckedTaggedToInt64CheckForMinusZeroOperator;
1017  kCheckedTaggedToInt64DontCheckForMinusZeroOperator;
1018 
1019  template <CheckTaggedInputMode kMode>
1021  : public Operator1<CheckTaggedInputParameters> {
1024  IrOpcode::kCheckedTaggedToFloat64,
1025  Operator::kFoldable | Operator::kNoThrow,
1026  "CheckedTaggedToFloat64", 1, 1, 1, 1, 1, 0,
1028  };
1030  kCheckedTaggedToFloat64NumberOperator;
1032  kCheckedTaggedToFloat64NumberOrOddballOperator;
1033 
1034  template <CheckTaggedInputMode kMode>
1036  : public Operator1<CheckTaggedInputParameters> {
1039  IrOpcode::kCheckedTruncateTaggedToWord32,
1040  Operator::kFoldable | Operator::kNoThrow,
1041  "CheckedTruncateTaggedToWord32", 1, 1, 1, 1, 1, 0,
1043  };
1045  kCheckedTruncateTaggedToWord32NumberOperator;
1047  kCheckedTruncateTaggedToWord32NumberOrOddballOperator;
1048 
1049  template <ConvertReceiverMode kMode>
1050  struct ConvertReceiverOperator final : public Operator1<ConvertReceiverMode> {
1053  IrOpcode::kConvertReceiver, // opcode
1054  Operator::kEliminatable, // flags
1055  "ConvertReceiver", // name
1056  2, 1, 1, 1, 1, 0, // counts
1057  kMode) {} // param
1058  };
1060  kConvertReceiverAnyOperator;
1062  kConvertReceiverNullOrUndefinedOperator;
1064  kConvertReceiverNotNullOrUndefinedOperator;
1065 
1066  template <CheckFloat64HoleMode kMode>
1068  : public Operator1<CheckFloat64HoleParameters> {
1071  IrOpcode::kCheckFloat64Hole,
1072  Operator::kFoldable | Operator::kNoThrow, "CheckFloat64Hole", 1,
1073  1, 1, 1, 1, 0,
1075  };
1077  kCheckFloat64HoleAllowReturnHoleOperator;
1079  kCheckFloat64HoleNeverReturnHoleOperator;
1080 
1083  : Operator( // --
1084  IrOpcode::kEnsureWritableFastElements, // opcode
1085  Operator::kNoDeopt | Operator::kNoThrow, // flags
1086  "EnsureWritableFastElements", // name
1087  2, 1, 1, 1, 1, 0) {} // counts
1088  };
1089  EnsureWritableFastElementsOperator kEnsureWritableFastElements;
1090 
1091  template <GrowFastElementsMode kMode>
1093  : public Operator1<GrowFastElementsParameters> {
1095  : Operator1(IrOpcode::kMaybeGrowFastElements, Operator::kNoThrow,
1096  "MaybeGrowFastElements", 4, 1, 1, 1, 1, 0,
1098  };
1099 
1101  kGrowFastElementsOperatorDoubleElements;
1103  kGrowFastElementsOperatorSmiOrObjectElements;
1104 
1105  struct LoadFieldByIndexOperator final : public Operator {
1107  : Operator( // --
1108  IrOpcode::kLoadFieldByIndex, // opcode
1109  Operator::kEliminatable, // flags,
1110  "LoadFieldByIndex", // name
1111  2, 1, 1, 1, 1, 0) {} // counts;
1112  };
1113  LoadFieldByIndexOperator kLoadFieldByIndex;
1114 
1115 #define SPECULATIVE_NUMBER_BINOP(Name) \
1116  template <NumberOperationHint kHint> \
1117  struct Name##Operator final : public Operator1<NumberOperationHint> { \
1118  Name##Operator() \
1119  : Operator1<NumberOperationHint>( \
1120  IrOpcode::k##Name, Operator::kFoldable | Operator::kNoThrow, \
1121  #Name, 2, 1, 1, 1, 1, 0, kHint) {} \
1122  }; \
1123  Name##Operator<NumberOperationHint::kSignedSmall> \
1124  k##Name##SignedSmallOperator; \
1125  Name##Operator<NumberOperationHint::kSignedSmallInputs> \
1126  k##Name##SignedSmallInputsOperator; \
1127  Name##Operator<NumberOperationHint::kSigned32> k##Name##Signed32Operator; \
1128  Name##Operator<NumberOperationHint::kNumber> k##Name##NumberOperator; \
1129  Name##Operator<NumberOperationHint::kNumberOrOddball> \
1130  k##Name##NumberOrOddballOperator;
1131  SPECULATIVE_NUMBER_BINOP_LIST(SPECULATIVE_NUMBER_BINOP)
1132 #undef SPECULATIVE_NUMBER_BINOP
1133 
1134  template <NumberOperationHint kHint>
1136  : public Operator1<NumberOperationParameters> {
1139  IrOpcode::kSpeculativeToNumber,
1140  Operator::kFoldable | Operator::kNoThrow, "SpeculativeToNumber",
1141  1, 1, 1, 1, 1, 0,
1143  };
1145  kSpeculativeToNumberSignedSmallOperator;
1147  kSpeculativeToNumberSigned32Operator;
1149  kSpeculativeToNumberNumberOperator;
1151  kSpeculativeToNumberNumberOrOddballOperator;
1152 };
1153 
1155  kSimplifiedOperatorGlobalCache = LAZY_INSTANCE_INITIALIZER;
1156 
1157 SimplifiedOperatorBuilder::SimplifiedOperatorBuilder(Zone* zone)
1158  : cache_(kSimplifiedOperatorGlobalCache.Get()), zone_(zone) {}
1159 
1160 #define GET_FROM_CACHE(Name, ...) \
1161  const Operator* SimplifiedOperatorBuilder::Name() { return &cache_.k##Name; }
1162 PURE_OP_LIST(GET_FROM_CACHE)
1163 EFFECT_DEPENDENT_OP_LIST(GET_FROM_CACHE)
1164 CHECKED_OP_LIST(GET_FROM_CACHE)
1165 GET_FROM_CACHE(ArgumentsFrame)
1166 GET_FROM_CACHE(FindOrderedHashMapEntry)
1167 GET_FROM_CACHE(FindOrderedHashMapEntryForInt32Key)
1168 GET_FROM_CACHE(LoadFieldByIndex)
1169 #undef GET_FROM_CACHE
1170 
1171 #define GET_FROM_CACHE_WITH_FEEDBACK(Name, value_input_count, \
1172  value_output_count) \
1173  const Operator* SimplifiedOperatorBuilder::Name( \
1174  const VectorSlotPair& feedback) { \
1175  if (!feedback.IsValid()) { \
1176  return &cache_.k##Name; \
1177  } \
1178  return new (zone()) Operator1<CheckParameters>( \
1179  IrOpcode::k##Name, Operator::kFoldable | Operator::kNoThrow, #Name, \
1180  value_input_count, 1, 1, value_output_count, 1, 0, \
1181  CheckParameters(feedback)); \
1182  }
1183 CHECKED_WITH_FEEDBACK_OP_LIST(GET_FROM_CACHE_WITH_FEEDBACK)
1184 #undef GET_FROM_CACHE_WITH_FEEDBACK
1185 
1186 bool IsCheckedWithFeedback(const Operator* op) {
1187 #define CASE(Name, ...) case IrOpcode::k##Name:
1188  switch (op->opcode()) {
1189  CHECKED_WITH_FEEDBACK_OP_LIST(CASE) return true;
1190  default:
1191  return false;
1192  }
1193 #undef CASE
1194 }
1195 
1196 const Operator* SimplifiedOperatorBuilder::RuntimeAbort(AbortReason reason) {
1197  return new (zone()) Operator1<int>( // --
1198  IrOpcode::kRuntimeAbort, // opcode
1199  Operator::kNoThrow | Operator::kNoDeopt, // flags
1200  "RuntimeAbort", // name
1201  0, 1, 1, 0, 1, 0, // counts
1202  static_cast<int>(reason)); // parameter
1203 }
1204 
1205 const Operator* SimplifiedOperatorBuilder::CheckIf(
1206  DeoptimizeReason reason, const VectorSlotPair& feedback) {
1207  if (!feedback.IsValid()) {
1208  switch (reason) {
1209 #define CHECK_IF(Name, message) \
1210  case DeoptimizeReason::k##Name: \
1211  return &cache_.kCheckIf##Name;
1212  DEOPTIMIZE_REASON_LIST(CHECK_IF)
1213 #undef CHECK_IF
1214  }
1215  }
1216  return new (zone()) Operator1<CheckIfParameters>(
1217  IrOpcode::kCheckIf, Operator::kFoldable | Operator::kNoThrow, "CheckIf",
1218  1, 1, 1, 0, 1, 0, CheckIfParameters(reason, feedback));
1219 }
1220 
1221 const Operator* SimplifiedOperatorBuilder::ChangeFloat64ToTagged(
1222  CheckForMinusZeroMode mode) {
1223  switch (mode) {
1224  case CheckForMinusZeroMode::kCheckForMinusZero:
1225  return &cache_.kChangeFloat64ToTaggedCheckForMinusZeroOperator;
1226  case CheckForMinusZeroMode::kDontCheckForMinusZero:
1227  return &cache_.kChangeFloat64ToTaggedDontCheckForMinusZeroOperator;
1228  }
1229  UNREACHABLE();
1230 }
1231 
1232 const Operator* SimplifiedOperatorBuilder::CheckedInt32Mul(
1233  CheckForMinusZeroMode mode) {
1234  switch (mode) {
1235  case CheckForMinusZeroMode::kCheckForMinusZero:
1236  return &cache_.kCheckedInt32MulCheckForMinusZeroOperator;
1237  case CheckForMinusZeroMode::kDontCheckForMinusZero:
1238  return &cache_.kCheckedInt32MulDontCheckForMinusZeroOperator;
1239  }
1240  UNREACHABLE();
1241 }
1242 
1243 const Operator* SimplifiedOperatorBuilder::CheckedFloat64ToInt32(
1244  CheckForMinusZeroMode mode, const VectorSlotPair& feedback) {
1245  if (!feedback.IsValid()) {
1246  switch (mode) {
1247  case CheckForMinusZeroMode::kCheckForMinusZero:
1248  return &cache_.kCheckedFloat64ToInt32CheckForMinusZeroOperator;
1249  case CheckForMinusZeroMode::kDontCheckForMinusZero:
1250  return &cache_.kCheckedFloat64ToInt32DontCheckForMinusZeroOperator;
1251  }
1252  }
1253  return new (zone()) Operator1<CheckMinusZeroParameters>(
1254  IrOpcode::kCheckedFloat64ToInt32,
1255  Operator::kFoldable | Operator::kNoThrow, "CheckedFloat64ToInt32", 1, 1,
1256  1, 1, 1, 0, CheckMinusZeroParameters(mode, feedback));
1257 }
1258 
1259 const Operator* SimplifiedOperatorBuilder::CheckedFloat64ToInt64(
1260  CheckForMinusZeroMode mode, const VectorSlotPair& feedback) {
1261  if (!feedback.IsValid()) {
1262  switch (mode) {
1263  case CheckForMinusZeroMode::kCheckForMinusZero:
1264  return &cache_.kCheckedFloat64ToInt64CheckForMinusZeroOperator;
1265  case CheckForMinusZeroMode::kDontCheckForMinusZero:
1266  return &cache_.kCheckedFloat64ToInt64DontCheckForMinusZeroOperator;
1267  }
1268  }
1269  return new (zone()) Operator1<CheckMinusZeroParameters>(
1270  IrOpcode::kCheckedFloat64ToInt64,
1271  Operator::kFoldable | Operator::kNoThrow, "CheckedFloat64ToInt64", 1, 1,
1272  1, 1, 1, 0, CheckMinusZeroParameters(mode, feedback));
1273 }
1274 
1275 const Operator* SimplifiedOperatorBuilder::CheckedTaggedToInt32(
1276  CheckForMinusZeroMode mode, const VectorSlotPair& feedback) {
1277  if (!feedback.IsValid()) {
1278  switch (mode) {
1279  case CheckForMinusZeroMode::kCheckForMinusZero:
1280  return &cache_.kCheckedTaggedToInt32CheckForMinusZeroOperator;
1281  case CheckForMinusZeroMode::kDontCheckForMinusZero:
1282  return &cache_.kCheckedTaggedToInt32DontCheckForMinusZeroOperator;
1283  }
1284  }
1285  return new (zone()) Operator1<CheckMinusZeroParameters>(
1286  IrOpcode::kCheckedTaggedToInt32, Operator::kFoldable | Operator::kNoThrow,
1287  "CheckedTaggedToInt32", 1, 1, 1, 1, 1, 0,
1288  CheckMinusZeroParameters(mode, feedback));
1289 }
1290 
1291 const Operator* SimplifiedOperatorBuilder::CheckedTaggedToInt64(
1292  CheckForMinusZeroMode mode, const VectorSlotPair& feedback) {
1293  if (!feedback.IsValid()) {
1294  switch (mode) {
1295  case CheckForMinusZeroMode::kCheckForMinusZero:
1296  return &cache_.kCheckedTaggedToInt64CheckForMinusZeroOperator;
1297  case CheckForMinusZeroMode::kDontCheckForMinusZero:
1298  return &cache_.kCheckedTaggedToInt64DontCheckForMinusZeroOperator;
1299  }
1300  }
1301  return new (zone()) Operator1<CheckMinusZeroParameters>(
1302  IrOpcode::kCheckedTaggedToInt64, Operator::kFoldable | Operator::kNoThrow,
1303  "CheckedTaggedToInt64", 1, 1, 1, 1, 1, 0,
1304  CheckMinusZeroParameters(mode, feedback));
1305 }
1306 
1307 const Operator* SimplifiedOperatorBuilder::CheckedTaggedToFloat64(
1308  CheckTaggedInputMode mode, const VectorSlotPair& feedback) {
1309  if (!feedback.IsValid()) {
1310  switch (mode) {
1311  case CheckTaggedInputMode::kNumber:
1312  return &cache_.kCheckedTaggedToFloat64NumberOperator;
1313  case CheckTaggedInputMode::kNumberOrOddball:
1314  return &cache_.kCheckedTaggedToFloat64NumberOrOddballOperator;
1315  }
1316  }
1317  return new (zone()) Operator1<CheckTaggedInputParameters>(
1318  IrOpcode::kCheckedTaggedToFloat64,
1319  Operator::kFoldable | Operator::kNoThrow, "CheckedTaggedToFloat64", 1, 1,
1320  1, 1, 1, 0, CheckTaggedInputParameters(mode, feedback));
1321 }
1322 
1323 const Operator* SimplifiedOperatorBuilder::CheckedTruncateTaggedToWord32(
1324  CheckTaggedInputMode mode, const VectorSlotPair& feedback) {
1325  if (!feedback.IsValid()) {
1326  switch (mode) {
1327  case CheckTaggedInputMode::kNumber:
1328  return &cache_.kCheckedTruncateTaggedToWord32NumberOperator;
1329  case CheckTaggedInputMode::kNumberOrOddball:
1330  return &cache_.kCheckedTruncateTaggedToWord32NumberOrOddballOperator;
1331  }
1332  }
1333  return new (zone()) Operator1<CheckTaggedInputParameters>(
1334  IrOpcode::kCheckedTruncateTaggedToWord32,
1335  Operator::kFoldable | Operator::kNoThrow, "CheckedTruncateTaggedToWord32",
1336  1, 1, 1, 1, 1, 0, CheckTaggedInputParameters(mode, feedback));
1337 }
1338 
1339 const Operator* SimplifiedOperatorBuilder::CheckMaps(
1340  CheckMapsFlags flags, ZoneHandleSet<Map> maps,
1341  const VectorSlotPair& feedback) {
1342  CheckMapsParameters const parameters(flags, maps, feedback);
1343  return new (zone()) Operator1<CheckMapsParameters>( // --
1344  IrOpcode::kCheckMaps, // opcode
1345  Operator::kNoThrow | Operator::kNoWrite, // flags
1346  "CheckMaps", // name
1347  1, 1, 1, 0, 1, 0, // counts
1348  parameters); // parameter
1349 }
1350 
1351 const Operator* SimplifiedOperatorBuilder::MapGuard(ZoneHandleSet<Map> maps) {
1352  return new (zone()) Operator1<MapsParameterInfo>( // --
1353  IrOpcode::kMapGuard, Operator::kEliminatable, // opcode
1354  "MapGuard", // name
1355  1, 1, 1, 0, 1, 0, // counts
1356  MapsParameterInfo(maps)); // parameter
1357 }
1358 
1359 const Operator* SimplifiedOperatorBuilder::CompareMaps(
1360  ZoneHandleSet<Map> maps) {
1361  return new (zone()) Operator1<MapsParameterInfo>( // --
1362  IrOpcode::kCompareMaps, // opcode
1363  Operator::kEliminatable, // flags
1364  "CompareMaps", // name
1365  1, 1, 1, 1, 1, 0, // counts
1366  MapsParameterInfo(maps)); // parameter
1367 }
1368 
1369 const Operator* SimplifiedOperatorBuilder::ConvertReceiver(
1370  ConvertReceiverMode mode) {
1371  switch (mode) {
1372  case ConvertReceiverMode::kAny:
1373  return &cache_.kConvertReceiverAnyOperator;
1374  case ConvertReceiverMode::kNullOrUndefined:
1375  return &cache_.kConvertReceiverNullOrUndefinedOperator;
1376  case ConvertReceiverMode::kNotNullOrUndefined:
1377  return &cache_.kConvertReceiverNotNullOrUndefinedOperator;
1378  }
1379  UNREACHABLE();
1380  return nullptr;
1381 }
1382 
1383 const Operator* SimplifiedOperatorBuilder::CheckFloat64Hole(
1384  CheckFloat64HoleMode mode, VectorSlotPair const& feedback) {
1385  if (!feedback.IsValid()) {
1386  switch (mode) {
1387  case CheckFloat64HoleMode::kAllowReturnHole:
1388  return &cache_.kCheckFloat64HoleAllowReturnHoleOperator;
1389  case CheckFloat64HoleMode::kNeverReturnHole:
1390  return &cache_.kCheckFloat64HoleNeverReturnHoleOperator;
1391  }
1392  UNREACHABLE();
1393  }
1394  return new (zone()) Operator1<CheckFloat64HoleParameters>(
1395  IrOpcode::kCheckFloat64Hole, Operator::kFoldable | Operator::kNoThrow,
1396  "CheckFloat64Hole", 1, 1, 1, 1, 1, 0,
1397  CheckFloat64HoleParameters(mode, feedback));
1398 }
1399 
1400 const Operator* SimplifiedOperatorBuilder::SpeculativeToNumber(
1401  NumberOperationHint hint, const VectorSlotPair& feedback) {
1402  if (!feedback.IsValid()) {
1403  switch (hint) {
1404  case NumberOperationHint::kSignedSmall:
1405  return &cache_.kSpeculativeToNumberSignedSmallOperator;
1406  case NumberOperationHint::kSignedSmallInputs:
1407  break;
1408  case NumberOperationHint::kSigned32:
1409  return &cache_.kSpeculativeToNumberSigned32Operator;
1410  case NumberOperationHint::kNumber:
1411  return &cache_.kSpeculativeToNumberNumberOperator;
1412  case NumberOperationHint::kNumberOrOddball:
1413  return &cache_.kSpeculativeToNumberNumberOrOddballOperator;
1414  }
1415  }
1416  return new (zone()) Operator1<NumberOperationParameters>(
1417  IrOpcode::kSpeculativeToNumber, Operator::kFoldable | Operator::kNoThrow,
1418  "SpeculativeToNumber", 1, 1, 1, 1, 1, 0,
1419  NumberOperationParameters(hint, feedback));
1420 }
1421 
1422 const Operator* SimplifiedOperatorBuilder::EnsureWritableFastElements() {
1423  return &cache_.kEnsureWritableFastElements;
1424 }
1425 
1426 const Operator* SimplifiedOperatorBuilder::MaybeGrowFastElements(
1427  GrowFastElementsMode mode, const VectorSlotPair& feedback) {
1428  if (!feedback.IsValid()) {
1429  switch (mode) {
1430  case GrowFastElementsMode::kDoubleElements:
1431  return &cache_.kGrowFastElementsOperatorDoubleElements;
1432  case GrowFastElementsMode::kSmiOrObjectElements:
1433  return &cache_.kGrowFastElementsOperatorSmiOrObjectElements;
1434  }
1435  }
1436  return new (zone()) Operator1<GrowFastElementsParameters>( // --
1437  IrOpcode::kMaybeGrowFastElements, // opcode
1438  Operator::kNoThrow, // flags
1439  "MaybeGrowFastElements", // name
1440  4, 1, 1, 1, 1, 0, // counts
1441  GrowFastElementsParameters(mode, feedback)); // parameter
1442 }
1443 
1444 const Operator* SimplifiedOperatorBuilder::TransitionElementsKind(
1445  ElementsTransition transition) {
1446  return new (zone()) Operator1<ElementsTransition>( // --
1447  IrOpcode::kTransitionElementsKind, // opcode
1448  Operator::kNoDeopt | Operator::kNoThrow, // flags
1449  "TransitionElementsKind", // name
1450  1, 1, 1, 0, 1, 0, // counts
1451  transition); // parameter
1452 }
1453 
1454 namespace {
1455 
1456 struct ArgumentsLengthParameters {
1457  int formal_parameter_count;
1458  bool is_rest_length;
1459 };
1460 
1461 bool operator==(ArgumentsLengthParameters first,
1462  ArgumentsLengthParameters second) {
1463  return first.formal_parameter_count == second.formal_parameter_count &&
1464  first.is_rest_length == second.is_rest_length;
1465 }
1466 
1467 size_t hash_value(ArgumentsLengthParameters param) {
1468  return base::hash_combine(param.formal_parameter_count, param.is_rest_length);
1469 }
1470 
1471 std::ostream& operator<<(std::ostream& os, ArgumentsLengthParameters param) {
1472  return os << param.formal_parameter_count << ", "
1473  << (param.is_rest_length ? "rest length" : "not rest length");
1474 }
1475 
1476 } // namespace
1477 
1478 const Operator* SimplifiedOperatorBuilder::ArgumentsLength(
1479  int formal_parameter_count, bool is_rest_length) {
1480  return new (zone()) Operator1<ArgumentsLengthParameters>( // --
1481  IrOpcode::kArgumentsLength, // opcode
1482  Operator::kPure, // flags
1483  "ArgumentsLength", // name
1484  1, 0, 0, 1, 0, 0, // counts
1485  ArgumentsLengthParameters{formal_parameter_count,
1486  is_rest_length}); // parameter
1487 }
1488 
1489 int FormalParameterCountOf(const Operator* op) {
1490  DCHECK_EQ(IrOpcode::kArgumentsLength, op->opcode());
1491  return OpParameter<ArgumentsLengthParameters>(op).formal_parameter_count;
1492 }
1493 
1494 bool IsRestLengthOf(const Operator* op) {
1495  DCHECK_EQ(IrOpcode::kArgumentsLength, op->opcode());
1496  return OpParameter<ArgumentsLengthParameters>(op).is_rest_length;
1497 }
1498 
1499 bool operator==(CheckParameters const& lhs, CheckParameters const& rhs) {
1500  return lhs.feedback() == rhs.feedback();
1501 }
1502 
1503 size_t hash_value(CheckParameters const& p) { return hash_value(p.feedback()); }
1504 
1505 std::ostream& operator<<(std::ostream& os, CheckParameters const& p) {
1506  return os << p.feedback();
1507 }
1508 
1509 CheckParameters const& CheckParametersOf(Operator const* op) {
1510 #define MAKE_OR(name, arg2, arg3) op->opcode() == IrOpcode::k##name ||
1511  CHECK((CHECKED_WITH_FEEDBACK_OP_LIST(MAKE_OR) false));
1512 #undef MAKE_OR
1513  return OpParameter<CheckParameters>(op);
1514 }
1515 
1516 bool operator==(CheckIfParameters const& lhs, CheckIfParameters const& rhs) {
1517  return lhs.reason() == rhs.reason() && lhs.feedback() == rhs.feedback();
1518 }
1519 
1520 size_t hash_value(CheckIfParameters const& p) {
1521  return base::hash_combine(p.reason(), p.feedback());
1522 }
1523 
1524 std::ostream& operator<<(std::ostream& os, CheckIfParameters const& p) {
1525  return os << p.reason() << p.feedback();
1526 }
1527 
1528 CheckIfParameters const& CheckIfParametersOf(Operator const* op) {
1529  CHECK(op->opcode() == IrOpcode::kCheckIf);
1530  return OpParameter<CheckIfParameters>(op);
1531 }
1532 
1533 const Operator* SimplifiedOperatorBuilder::NewDoubleElements(
1534  PretenureFlag pretenure) {
1535  return new (zone()) Operator1<PretenureFlag>( // --
1536  IrOpcode::kNewDoubleElements, // opcode
1537  Operator::kEliminatable, // flags
1538  "NewDoubleElements", // name
1539  1, 1, 1, 1, 1, 0, // counts
1540  pretenure); // parameter
1541 }
1542 
1543 const Operator* SimplifiedOperatorBuilder::NewSmiOrObjectElements(
1544  PretenureFlag pretenure) {
1545  return new (zone()) Operator1<PretenureFlag>( // --
1546  IrOpcode::kNewSmiOrObjectElements, // opcode
1547  Operator::kEliminatable, // flags
1548  "NewSmiOrObjectElements", // name
1549  1, 1, 1, 1, 1, 0, // counts
1550  pretenure); // parameter
1551 }
1552 
1553 const Operator* SimplifiedOperatorBuilder::NewArgumentsElements(
1554  int mapped_count) {
1555  return new (zone()) Operator1<int>( // --
1556  IrOpcode::kNewArgumentsElements, // opcode
1557  Operator::kEliminatable, // flags
1558  "NewArgumentsElements", // name
1559  2, 1, 0, 1, 1, 0, // counts
1560  mapped_count); // parameter
1561 }
1562 
1563 int NewArgumentsElementsMappedCountOf(const Operator* op) {
1564  DCHECK_EQ(IrOpcode::kNewArgumentsElements, op->opcode());
1565  return OpParameter<int>(op);
1566 }
1567 
1568 const Operator* SimplifiedOperatorBuilder::Allocate(Type type,
1569  PretenureFlag pretenure) {
1570  return new (zone()) Operator1<AllocateParameters>(
1571  IrOpcode::kAllocate,
1572  Operator::kNoDeopt | Operator::kNoThrow | Operator::kNoWrite, "Allocate",
1573  1, 1, 1, 1, 1, 0, AllocateParameters(type, pretenure));
1574 }
1575 
1576 const Operator* SimplifiedOperatorBuilder::AllocateRaw(
1577  Type type, PretenureFlag pretenure) {
1578  return new (zone()) Operator1<AllocateParameters>(
1579  IrOpcode::kAllocateRaw,
1580  Operator::kNoDeopt | Operator::kNoThrow | Operator::kNoWrite,
1581  "AllocateRaw", 1, 1, 1, 1, 1, 1, AllocateParameters(type, pretenure));
1582 }
1583 
1584 const Operator* SimplifiedOperatorBuilder::StringCodePointAt(
1585  UnicodeEncoding encoding) {
1586  switch (encoding) {
1587  case UnicodeEncoding::UTF16:
1588  return &cache_.kStringCodePointAtOperatorUTF16;
1589  case UnicodeEncoding::UTF32:
1590  return &cache_.kStringCodePointAtOperatorUTF32;
1591  }
1592  UNREACHABLE();
1593 }
1594 
1595 const Operator* SimplifiedOperatorBuilder::StringFromSingleCodePoint(
1596  UnicodeEncoding encoding) {
1597  switch (encoding) {
1598  case UnicodeEncoding::UTF16:
1599  return &cache_.kStringFromSingleCodePointOperatorUTF16;
1600  case UnicodeEncoding::UTF32:
1601  return &cache_.kStringFromSingleCodePointOperatorUTF32;
1602  }
1603  UNREACHABLE();
1604 }
1605 
1606 #define SPECULATIVE_NUMBER_BINOP(Name) \
1607  const Operator* SimplifiedOperatorBuilder::Name(NumberOperationHint hint) { \
1608  switch (hint) { \
1609  case NumberOperationHint::kSignedSmall: \
1610  return &cache_.k##Name##SignedSmallOperator; \
1611  case NumberOperationHint::kSignedSmallInputs: \
1612  return &cache_.k##Name##SignedSmallInputsOperator; \
1613  case NumberOperationHint::kSigned32: \
1614  return &cache_.k##Name##Signed32Operator; \
1615  case NumberOperationHint::kNumber: \
1616  return &cache_.k##Name##NumberOperator; \
1617  case NumberOperationHint::kNumberOrOddball: \
1618  return &cache_.k##Name##NumberOrOddballOperator; \
1619  } \
1620  UNREACHABLE(); \
1621  return nullptr; \
1622  }
1623 SPECULATIVE_NUMBER_BINOP_LIST(SPECULATIVE_NUMBER_BINOP)
1624 #undef SPECULATIVE_NUMBER_BINOP
1625 
1626 #define ACCESS_OP_LIST(V) \
1627  V(LoadField, FieldAccess, Operator::kNoWrite, 1, 1, 1) \
1628  V(StoreField, FieldAccess, Operator::kNoRead, 2, 1, 0) \
1629  V(LoadElement, ElementAccess, Operator::kNoWrite, 2, 1, 1) \
1630  V(StoreElement, ElementAccess, Operator::kNoRead, 3, 1, 0) \
1631  V(LoadTypedElement, ExternalArrayType, Operator::kNoWrite, 4, 1, 1) \
1632  V(StoreTypedElement, ExternalArrayType, Operator::kNoRead, 5, 1, 0) \
1633  V(LoadDataViewElement, ExternalArrayType, Operator::kNoWrite, 5, 1, 1) \
1634  V(StoreDataViewElement, ExternalArrayType, Operator::kNoRead, 6, 1, 0)
1635 
1636 #define ACCESS(Name, Type, properties, value_input_count, control_input_count, \
1637  output_count) \
1638  const Operator* SimplifiedOperatorBuilder::Name(const Type& access) { \
1639  return new (zone()) \
1640  Operator1<Type>(IrOpcode::k##Name, \
1641  Operator::kNoDeopt | Operator::kNoThrow | properties, \
1642  #Name, value_input_count, 1, control_input_count, \
1643  output_count, 1, 0, access); \
1644  }
1645 ACCESS_OP_LIST(ACCESS)
1646 #undef ACCESS
1647 
1648 const Operator* SimplifiedOperatorBuilder::TransitionAndStoreElement(
1649  Handle<Map> double_map, Handle<Map> fast_map) {
1650  TransitionAndStoreElementParameters parameters(double_map, fast_map);
1651  return new (zone()) Operator1<TransitionAndStoreElementParameters>(
1652  IrOpcode::kTransitionAndStoreElement,
1653  Operator::kNoDeopt | Operator::kNoThrow, "TransitionAndStoreElement", 3,
1654  1, 1, 0, 1, 0, parameters);
1655 }
1656 
1657 const Operator* SimplifiedOperatorBuilder::StoreSignedSmallElement() {
1658  return new (zone()) Operator(IrOpcode::kStoreSignedSmallElement,
1659  Operator::kNoDeopt | Operator::kNoThrow,
1660  "StoreSignedSmallElement", 3, 1, 1, 0, 1, 0);
1661 }
1662 
1663 const Operator* SimplifiedOperatorBuilder::TransitionAndStoreNumberElement(
1664  Handle<Map> double_map) {
1665  TransitionAndStoreNumberElementParameters parameters(double_map);
1666  return new (zone()) Operator1<TransitionAndStoreNumberElementParameters>(
1667  IrOpcode::kTransitionAndStoreNumberElement,
1668  Operator::kNoDeopt | Operator::kNoThrow,
1669  "TransitionAndStoreNumberElement", 3, 1, 1, 0, 1, 0, parameters);
1670 }
1671 
1672 const Operator* SimplifiedOperatorBuilder::TransitionAndStoreNonNumberElement(
1673  Handle<Map> fast_map, Type value_type) {
1674  TransitionAndStoreNonNumberElementParameters parameters(fast_map, value_type);
1675  return new (zone()) Operator1<TransitionAndStoreNonNumberElementParameters>(
1676  IrOpcode::kTransitionAndStoreNonNumberElement,
1677  Operator::kNoDeopt | Operator::kNoThrow,
1678  "TransitionAndStoreNonNumberElement", 3, 1, 1, 0, 1, 0, parameters);
1679 }
1680 
1681 #undef PURE_OP_LIST
1682 #undef EFFECT_DEPENDENT_OP_LIST
1683 #undef SPECULATIVE_NUMBER_BINOP_LIST
1684 #undef CHECKED_WITH_FEEDBACK_OP_LIST
1685 #undef CHECKED_OP_LIST
1686 #undef ACCESS_OP_LIST
1687 
1688 } // namespace compiler
1689 } // namespace internal
1690 } // namespace v8
Definition: libplatform.h:13