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