Line data Source code
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 0 : size_t hash_value(BaseTaggedness base_taggedness) {
21 0 : return static_cast<uint8_t>(base_taggedness);
22 : }
23 :
24 139150 : std::ostream& operator<<(std::ostream& os, BaseTaggedness base_taggedness) {
25 139150 : switch (base_taggedness) {
26 : case kUntaggedBase:
27 84700 : return os << "untagged base";
28 : case kTaggedBase:
29 54450 : return os << "tagged base";
30 : }
31 0 : UNREACHABLE();
32 : }
33 :
34 126 : 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 252 : return lhs.base_is_tagged == rhs.base_is_tagged && lhs.offset == rhs.offset &&
39 252 : lhs.map.address() == rhs.map.address() &&
40 126 : lhs.machine_type == rhs.machine_type;
41 : }
42 :
43 0 : 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 0 : access.machine_type);
49 : }
50 :
51 0 : size_t hash_value(LoadSensitivity load_sensitivity) {
52 0 : return static_cast<size_t>(load_sensitivity);
53 : }
54 :
55 0 : std::ostream& operator<<(std::ostream& os, LoadSensitivity load_sensitivity) {
56 0 : switch (load_sensitivity) {
57 : case LoadSensitivity::kCritical:
58 0 : return os << "Critical";
59 : case LoadSensitivity::kSafe:
60 0 : return os << "Safe";
61 : case LoadSensitivity::kUnsafe:
62 0 : return os << "Unsafe";
63 : }
64 0 : UNREACHABLE();
65 : }
66 :
67 0 : std::ostream& operator<<(std::ostream& os, FieldAccess const& access) {
68 0 : 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 0 : os << access.type << ", " << access.machine_type << ", "
81 0 : << access.write_barrier_kind;
82 0 : if (FLAG_untrusted_code_mitigations) {
83 0 : os << ", " << access.load_sensitivity;
84 : }
85 0 : os << "]";
86 0 : return os;
87 : }
88 :
89 : template <>
90 0 : void Operator1<FieldAccess>::PrintParameter(std::ostream& os,
91 : PrintVerbosity verbose) const {
92 0 : if (verbose == PrintVerbosity::kVerbose) {
93 0 : os << parameter();
94 : } else {
95 0 : os << "[+" << parameter().offset << "]";
96 : }
97 0 : }
98 :
99 46 : 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 46 : return lhs.base_is_tagged == rhs.base_is_tagged &&
104 92 : lhs.header_size == rhs.header_size &&
105 46 : lhs.machine_type == rhs.machine_type;
106 : }
107 :
108 0 : 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 0 : access.machine_type);
114 : }
115 :
116 :
117 139150 : std::ostream& operator<<(std::ostream& os, ElementAccess const& access) {
118 139150 : os << access.base_is_tagged << ", " << access.header_size << ", "
119 139150 : << access.type << ", " << access.machine_type << ", "
120 278300 : << access.write_barrier_kind;
121 139150 : if (FLAG_untrusted_code_mitigations) {
122 0 : os << ", " << access.load_sensitivity;
123 : }
124 139150 : return os;
125 : }
126 :
127 19464364 : const FieldAccess& FieldAccessOf(const Operator* op) {
128 : DCHECK_NOT_NULL(op);
129 : DCHECK(op->opcode() == IrOpcode::kLoadField ||
130 : op->opcode() == IrOpcode::kStoreField);
131 19464364 : return OpParameter<FieldAccess>(op);
132 : }
133 :
134 :
135 425507 : const ElementAccess& ElementAccessOf(const Operator* op) {
136 : DCHECK_NOT_NULL(op);
137 : DCHECK(op->opcode() == IrOpcode::kLoadElement ||
138 : op->opcode() == IrOpcode::kStoreElement);
139 425507 : return OpParameter<ElementAccess>(op);
140 : }
141 :
142 48548 : 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 48548 : return OpParameter<ExternalArrayType>(op);
148 : }
149 :
150 892 : ConvertReceiverMode ConvertReceiverModeOf(Operator const* op) {
151 : DCHECK_EQ(IrOpcode::kConvertReceiver, op->opcode());
152 892 : return OpParameter<ConvertReceiverMode>(op);
153 : }
154 :
155 0 : size_t hash_value(CheckFloat64HoleMode mode) {
156 0 : return static_cast<size_t>(mode);
157 : }
158 :
159 0 : std::ostream& operator<<(std::ostream& os, CheckFloat64HoleMode mode) {
160 0 : switch (mode) {
161 : case CheckFloat64HoleMode::kAllowReturnHole:
162 0 : return os << "allow-return-hole";
163 : case CheckFloat64HoleMode::kNeverReturnHole:
164 0 : return os << "never-return-hole";
165 : }
166 0 : UNREACHABLE();
167 : }
168 :
169 2349 : CheckFloat64HoleParameters const& CheckFloat64HoleParametersOf(
170 : Operator const* op) {
171 : DCHECK_EQ(IrOpcode::kCheckFloat64Hole, op->opcode());
172 2349 : return OpParameter<CheckFloat64HoleParameters>(op);
173 : }
174 :
175 0 : std::ostream& operator<<(std::ostream& os,
176 0 : CheckFloat64HoleParameters const& params) {
177 0 : os << params.mode();
178 0 : if (params.feedback().IsValid()) os << "; " << params.feedback();
179 0 : return os;
180 : }
181 :
182 0 : size_t hash_value(const CheckFloat64HoleParameters& params) {
183 0 : return base::hash_combine(params.mode(), params.feedback());
184 : }
185 :
186 0 : bool operator==(CheckFloat64HoleParameters const& lhs,
187 0 : CheckFloat64HoleParameters const& rhs) {
188 0 : return lhs.mode() == rhs.mode() && lhs.feedback() == rhs.feedback();
189 : }
190 :
191 0 : bool operator!=(CheckFloat64HoleParameters const& lhs,
192 : CheckFloat64HoleParameters const& rhs) {
193 0 : return !(lhs == rhs);
194 : }
195 :
196 58658 : CheckForMinusZeroMode CheckMinusZeroModeOf(const Operator* op) {
197 : DCHECK(op->opcode() == IrOpcode::kChangeFloat64ToTagged ||
198 : op->opcode() == IrOpcode::kCheckedInt32Mul);
199 58658 : return OpParameter<CheckForMinusZeroMode>(op);
200 : }
201 :
202 72356 : size_t hash_value(CheckForMinusZeroMode mode) {
203 72356 : return static_cast<size_t>(mode);
204 : }
205 :
206 100 : std::ostream& operator<<(std::ostream& os, CheckForMinusZeroMode mode) {
207 100 : switch (mode) {
208 : case CheckForMinusZeroMode::kCheckForMinusZero:
209 50 : return os << "check-for-minus-zero";
210 : case CheckForMinusZeroMode::kDontCheckForMinusZero:
211 50 : return os << "dont-check-for-minus-zero";
212 : }
213 0 : UNREACHABLE();
214 : }
215 :
216 0 : std::ostream& operator<<(std::ostream& os, CheckMapsFlags flags) {
217 : bool empty = true;
218 0 : if (flags & CheckMapsFlag::kTryMigrateInstance) {
219 0 : os << "TryMigrateInstance";
220 : empty = false;
221 : }
222 0 : if (empty) os << "None";
223 0 : return os;
224 : }
225 :
226 104329 : MapsParameterInfo::MapsParameterInfo(ZoneHandleSet<Map> const& maps)
227 104329 : : maps_(maps), instance_type_(Nothing<InstanceType>()) {
228 : DCHECK_LT(0, maps.size());
229 208658 : instance_type_ = Just(maps.at(0)->instance_type());
230 223948 : for (size_t i = 1; i < maps.size(); ++i) {
231 15408 : if (instance_type_.FromJust() != maps.at(i)->instance_type()) {
232 59 : instance_type_ = Nothing<InstanceType>();
233 59 : break;
234 : }
235 : }
236 104329 : }
237 :
238 0 : std::ostream& operator<<(std::ostream& os, MapsParameterInfo const& p) {
239 0 : ZoneHandleSet<Map> const& maps = p.maps();
240 : InstanceType instance_type;
241 0 : if (p.instance_type().To(&instance_type)) {
242 0 : os << ", " << instance_type;
243 : }
244 0 : for (size_t i = 0; i < maps.size(); ++i) {
245 0 : os << ", " << Brief(*maps[i]);
246 : }
247 0 : return os;
248 : }
249 :
250 0 : bool operator==(MapsParameterInfo const& lhs, MapsParameterInfo const& rhs) {
251 0 : return lhs.maps() == rhs.maps();
252 : }
253 :
254 0 : bool operator!=(MapsParameterInfo const& lhs, MapsParameterInfo const& rhs) {
255 0 : return !(lhs == rhs);
256 : }
257 :
258 0 : size_t hash_value(MapsParameterInfo const& p) { return hash_value(p.maps()); }
259 :
260 0 : bool operator==(CheckMapsParameters const& lhs,
261 : CheckMapsParameters const& rhs) {
262 0 : return lhs.flags() == rhs.flags() && lhs.maps() == rhs.maps() &&
263 0 : lhs.feedback() == rhs.feedback();
264 : }
265 :
266 0 : size_t hash_value(CheckMapsParameters const& p) {
267 0 : return base::hash_combine(p.flags(), p.maps(), p.feedback());
268 : }
269 :
270 0 : std::ostream& operator<<(std::ostream& os, CheckMapsParameters const& p) {
271 0 : os << p.flags() << p.maps_info();
272 0 : if (p.feedback().IsValid()) {
273 0 : os << "; " << p.feedback();
274 : }
275 0 : return os;
276 : }
277 :
278 454298 : CheckMapsParameters const& CheckMapsParametersOf(Operator const* op) {
279 : DCHECK_EQ(IrOpcode::kCheckMaps, op->opcode());
280 454298 : return OpParameter<CheckMapsParameters>(op);
281 : }
282 :
283 17961 : MapsParameterInfo const& CompareMapsParametersOf(Operator const* op) {
284 : DCHECK_EQ(IrOpcode::kCompareMaps, op->opcode());
285 17961 : return OpParameter<MapsParameterInfo>(op);
286 : }
287 :
288 11834 : MapsParameterInfo const& MapGuardMapsOf(Operator const* op) {
289 : DCHECK_EQ(IrOpcode::kMapGuard, op->opcode());
290 11834 : return OpParameter<MapsParameterInfo>(op);
291 : }
292 :
293 0 : size_t hash_value(CheckTaggedInputMode mode) {
294 0 : return static_cast<size_t>(mode);
295 : }
296 :
297 36 : std::ostream& operator<<(std::ostream& os, CheckTaggedInputMode mode) {
298 36 : switch (mode) {
299 : case CheckTaggedInputMode::kNumber:
300 18 : return os << "Number";
301 : case CheckTaggedInputMode::kNumberOrOddball:
302 18 : return os << "NumberOrOddball";
303 : }
304 0 : UNREACHABLE();
305 : }
306 :
307 0 : std::ostream& operator<<(std::ostream& os, GrowFastElementsMode mode) {
308 0 : switch (mode) {
309 : case GrowFastElementsMode::kDoubleElements:
310 0 : return os << "DoubleElements";
311 : case GrowFastElementsMode::kSmiOrObjectElements:
312 0 : return os << "SmiOrObjectElements";
313 : }
314 0 : UNREACHABLE();
315 : }
316 :
317 0 : bool operator==(const GrowFastElementsParameters& lhs,
318 0 : const GrowFastElementsParameters& rhs) {
319 0 : return lhs.mode() == rhs.mode() && lhs.feedback() == rhs.feedback();
320 : }
321 :
322 0 : inline size_t hash_value(const GrowFastElementsParameters& params) {
323 0 : return base::hash_combine(params.mode(), params.feedback());
324 : }
325 :
326 0 : std::ostream& operator<<(std::ostream& os,
327 0 : const GrowFastElementsParameters& params) {
328 0 : os << params.mode();
329 0 : if (params.feedback().IsValid()) {
330 0 : os << params.feedback();
331 : }
332 0 : return os;
333 : }
334 :
335 16705 : const GrowFastElementsParameters& GrowFastElementsParametersOf(
336 : const Operator* op) {
337 : DCHECK_EQ(IrOpcode::kMaybeGrowFastElements, op->opcode());
338 16705 : return OpParameter<GrowFastElementsParameters>(op);
339 : }
340 :
341 0 : bool operator==(ElementsTransition const& lhs, ElementsTransition const& rhs) {
342 0 : return lhs.mode() == rhs.mode() &&
343 0 : lhs.source().address() == rhs.source().address() &&
344 0 : lhs.target().address() == rhs.target().address();
345 : }
346 :
347 0 : size_t hash_value(ElementsTransition transition) {
348 0 : return base::hash_combine(static_cast<uint8_t>(transition.mode()),
349 0 : transition.source().address(),
350 0 : transition.target().address());
351 : }
352 :
353 0 : std::ostream& operator<<(std::ostream& os, ElementsTransition transition) {
354 0 : switch (transition.mode()) {
355 : case ElementsTransition::kFastTransition:
356 0 : return os << "fast-transition from " << Brief(*transition.source())
357 0 : << " to " << Brief(*transition.target());
358 : case ElementsTransition::kSlowTransition:
359 0 : return os << "slow-transition from " << Brief(*transition.source())
360 0 : << " to " << Brief(*transition.target());
361 : }
362 0 : UNREACHABLE();
363 : }
364 :
365 1770 : ElementsTransition const& ElementsTransitionOf(const Operator* op) {
366 : DCHECK_EQ(IrOpcode::kTransitionElementsKind, op->opcode());
367 1770 : 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 0 : return lhs.fast_map().address() == rhs.fast_map().address() &&
393 0 : lhs.double_map().address() == rhs.double_map().address();
394 : }
395 :
396 0 : size_t hash_value(TransitionAndStoreElementParameters parameters) {
397 : return base::hash_combine(parameters.fast_map().address(),
398 0 : parameters.double_map().address());
399 : }
400 :
401 0 : std::ostream& operator<<(std::ostream& os,
402 : TransitionAndStoreElementParameters parameters) {
403 0 : return os << "fast-map" << Brief(*parameters.fast_map()) << " double-map"
404 0 : << 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 0 : return lhs.fast_map().address() == rhs.fast_map().address() &&
433 : lhs.value_type() == rhs.value_type();
434 : }
435 :
436 0 : size_t hash_value(TransitionAndStoreNonNumberElementParameters parameters) {
437 0 : return base::hash_combine(parameters.fast_map().address(),
438 0 : parameters.value_type());
439 : }
440 :
441 0 : std::ostream& operator<<(
442 : std::ostream& os, TransitionAndStoreNonNumberElementParameters parameters) {
443 0 : return os << parameters.value_type() << ", fast-map"
444 0 : << 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 22 : 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 0 : return lhs.double_map().address() == rhs.double_map().address();
469 : }
470 :
471 0 : size_t hash_value(TransitionAndStoreNumberElementParameters parameters) {
472 0 : return base::hash_combine(parameters.double_map().address());
473 : }
474 :
475 0 : std::ostream& operator<<(std::ostream& os,
476 : TransitionAndStoreNumberElementParameters parameters) {
477 0 : return os << "double-map" << Brief(*parameters.double_map());
478 : }
479 :
480 : } // namespace
481 :
482 704 : Handle<Map> DoubleMapParameterOf(const Operator* op) {
483 704 : if (op->opcode() == IrOpcode::kTransitionAndStoreElement) {
484 : return OpParameter<TransitionAndStoreElementParameters>(op).double_map();
485 22 : } else if (op->opcode() == IrOpcode::kTransitionAndStoreNumberElement) {
486 : return OpParameter<TransitionAndStoreNumberElementParameters>(op)
487 : .double_map();
488 : }
489 0 : UNREACHABLE();
490 : return Handle<Map>::null();
491 : }
492 :
493 21 : Type ValueTypeParameterOf(const Operator* op) {
494 : DCHECK_EQ(IrOpcode::kTransitionAndStoreNonNumberElement, op->opcode());
495 : return OpParameter<TransitionAndStoreNonNumberElementParameters>(op)
496 21 : .value_type();
497 : }
498 :
499 804 : Handle<Map> FastMapParameterOf(const Operator* op) {
500 804 : if (op->opcode() == IrOpcode::kTransitionAndStoreElement) {
501 : return OpParameter<TransitionAndStoreElementParameters>(op).fast_map();
502 42 : } else if (op->opcode() == IrOpcode::kTransitionAndStoreNonNumberElement) {
503 : return OpParameter<TransitionAndStoreNonNumberElementParameters>(op)
504 : .fast_map();
505 : }
506 0 : UNREACHABLE();
507 : return Handle<Map>::null();
508 : }
509 :
510 234 : std::ostream& operator<<(std::ostream& os, NumberOperationHint hint) {
511 234 : switch (hint) {
512 : case NumberOperationHint::kSignedSmall:
513 66 : return os << "SignedSmall";
514 : case NumberOperationHint::kSignedSmallInputs:
515 42 : return os << "SignedSmallInputs";
516 : case NumberOperationHint::kSigned32:
517 42 : return os << "Signed32";
518 : case NumberOperationHint::kNumber:
519 42 : return os << "Number";
520 : case NumberOperationHint::kNumberOrOddball:
521 42 : return os << "NumberOrOddball";
522 : }
523 0 : UNREACHABLE();
524 : }
525 :
526 0 : size_t hash_value(NumberOperationHint hint) {
527 0 : return static_cast<uint8_t>(hint);
528 : }
529 :
530 1161958 : 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 1161958 : return OpParameter<NumberOperationHint>(op);
548 : }
549 :
550 0 : bool operator==(NumberOperationParameters const& lhs,
551 0 : NumberOperationParameters const& rhs) {
552 0 : return lhs.hint() == rhs.hint() && lhs.feedback() == rhs.feedback();
553 : }
554 :
555 0 : size_t hash_value(NumberOperationParameters const& p) {
556 0 : return base::hash_combine(p.hint(), p.feedback());
557 : }
558 :
559 0 : std::ostream& operator<<(std::ostream& os, NumberOperationParameters const& p) {
560 0 : return os << p.hint() << " " << p.feedback();
561 : }
562 :
563 154930 : NumberOperationParameters const& NumberOperationParametersOf(
564 : Operator const* op) {
565 : DCHECK_EQ(IrOpcode::kSpeculativeToNumber, op->opcode());
566 154930 : return OpParameter<NumberOperationParameters>(op);
567 : }
568 :
569 0 : size_t hash_value(AllocateParameters info) {
570 0 : return base::hash_combine(info.type(), info.pretenure());
571 : }
572 :
573 0 : V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
574 : AllocateParameters info) {
575 0 : return os << info.type() << ", " << info.pretenure();
576 : }
577 :
578 0 : bool operator==(AllocateParameters const& lhs, AllocateParameters const& rhs) {
579 0 : return lhs.pretenure() == rhs.pretenure() && lhs.type() == rhs.type();
580 : }
581 :
582 393929 : PretenureFlag PretenureFlagOf(const Operator* op) {
583 393929 : if (op->opcode() == IrOpcode::kNewDoubleElements ||
584 : op->opcode() == IrOpcode::kNewSmiOrObjectElements) {
585 535 : return OpParameter<PretenureFlag>(op);
586 : }
587 : DCHECK(op->opcode() == IrOpcode::kAllocate ||
588 : op->opcode() == IrOpcode::kAllocateRaw);
589 393394 : return OpParameter<AllocateParameters>(op).pretenure();
590 : }
591 :
592 139372 : Type AllocateTypeOf(const Operator* op) {
593 : DCHECK_EQ(IrOpcode::kAllocate, op->opcode());
594 139372 : return OpParameter<AllocateParameters>(op).type();
595 : }
596 :
597 471 : UnicodeEncoding UnicodeEncodingOf(const Operator* op) {
598 : DCHECK(op->opcode() == IrOpcode::kStringFromSingleCodePoint ||
599 : op->opcode() == IrOpcode::kStringCodePointAt);
600 471 : return OpParameter<UnicodeEncoding>(op);
601 : }
602 :
603 2463 : AbortReason AbortReasonOf(const Operator* op) {
604 : DCHECK_EQ(IrOpcode::kRuntimeAbort, op->opcode());
605 2463 : return static_cast<AbortReason>(OpParameter<int>(op));
606 : }
607 :
608 84150 : const CheckTaggedInputParameters& CheckTaggedInputParametersOf(
609 : const Operator* op) {
610 : DCHECK(op->opcode() == IrOpcode::kCheckedTruncateTaggedToWord32 ||
611 : op->opcode() == IrOpcode::kCheckedTaggedToFloat64);
612 84150 : return OpParameter<CheckTaggedInputParameters>(op);
613 : }
614 :
615 0 : std::ostream& operator<<(std::ostream& os,
616 0 : const CheckTaggedInputParameters& params) {
617 0 : os << params.mode();
618 0 : if (params.feedback().IsValid()) {
619 0 : os << "; " << params.feedback();
620 : }
621 0 : return os;
622 : }
623 :
624 0 : size_t hash_value(const CheckTaggedInputParameters& params) {
625 0 : return base::hash_combine(params.mode(), params.feedback());
626 : }
627 :
628 0 : bool operator==(CheckTaggedInputParameters const& lhs,
629 0 : CheckTaggedInputParameters const& rhs) {
630 0 : return lhs.mode() == rhs.mode() && lhs.feedback() == rhs.feedback();
631 : }
632 :
633 5072 : 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 5072 : return OpParameter<CheckMinusZeroParameters>(op);
639 : }
640 :
641 0 : std::ostream& operator<<(std::ostream& os,
642 0 : const CheckMinusZeroParameters& params) {
643 0 : os << params.mode();
644 0 : if (params.feedback().IsValid()) {
645 0 : os << "; " << params.feedback();
646 : }
647 0 : return os;
648 : }
649 :
650 0 : size_t hash_value(const CheckMinusZeroParameters& params) {
651 0 : return base::hash_combine(params.mode(), params.feedback());
652 : }
653 :
654 0 : bool operator==(CheckMinusZeroParameters const& lhs,
655 0 : CheckMinusZeroParameters const& rhs) {
656 0 : 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 :
822 30868 : struct SimplifiedOperatorGlobalCache final {
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 3580688 : 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 92604 : 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 432152 : 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 987776 : CHECKED_WITH_FEEDBACK_OP_LIST(CHECKED_WITH_FEEDBACK)
868 : #undef CHECKED_WITH_FEEDBACK
869 :
870 : template <DeoptimizeReason kDeoptimizeReason>
871 0 : struct CheckIfOperator final : public Operator1<CheckIfParameters> {
872 1234720 : CheckIfOperator()
873 : : Operator1<CheckIfParameters>(
874 : IrOpcode::kCheckIf, Operator::kFoldable | Operator::kNoThrow,
875 : "CheckIf", 1, 1, 1, 0, 1, 0,
876 2469440 : 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 0 : struct StringCodePointAtOperator final : public Operator1<UnicodeEncoding> {
885 61736 : StringCodePointAtOperator()
886 : : Operator1<UnicodeEncoding>(IrOpcode::kStringCodePointAt,
887 : Operator::kFoldable | Operator::kNoThrow,
888 : "StringCodePointAt", 2, 1, 1, 1, 1, 0,
889 61736 : kEncoding) {}
890 : };
891 : StringCodePointAtOperator<UnicodeEncoding::UTF16>
892 : kStringCodePointAtOperatorUTF16;
893 : StringCodePointAtOperator<UnicodeEncoding::UTF32>
894 : kStringCodePointAtOperatorUTF32;
895 :
896 : template <UnicodeEncoding kEncoding>
897 0 : struct StringFromSingleCodePointOperator final
898 : : public Operator1<UnicodeEncoding> {
899 61736 : StringFromSingleCodePointOperator()
900 : : Operator1<UnicodeEncoding>(
901 : IrOpcode::kStringFromSingleCodePoint, Operator::kPure,
902 61736 : "StringFromSingleCodePoint", 1, 0, 0, 1, 0, 0, kEncoding) {}
903 : };
904 : StringFromSingleCodePointOperator<UnicodeEncoding::UTF16>
905 : kStringFromSingleCodePointOperatorUTF16;
906 : StringFromSingleCodePointOperator<UnicodeEncoding::UTF32>
907 : kStringFromSingleCodePointOperatorUTF32;
908 :
909 0 : struct FindOrderedHashMapEntryOperator final : public Operator {
910 30868 : FindOrderedHashMapEntryOperator()
911 : : Operator(IrOpcode::kFindOrderedHashMapEntry, Operator::kEliminatable,
912 30868 : "FindOrderedHashMapEntry", 2, 1, 1, 1, 1, 0) {}
913 : };
914 : FindOrderedHashMapEntryOperator kFindOrderedHashMapEntry;
915 :
916 0 : struct FindOrderedHashMapEntryForInt32KeyOperator final : public Operator {
917 30868 : FindOrderedHashMapEntryForInt32KeyOperator()
918 : : Operator(IrOpcode::kFindOrderedHashMapEntryForInt32Key,
919 : Operator::kEliminatable,
920 30868 : "FindOrderedHashMapEntryForInt32Key", 2, 1, 1, 1, 1, 0) {}
921 : };
922 : FindOrderedHashMapEntryForInt32KeyOperator
923 : kFindOrderedHashMapEntryForInt32Key;
924 :
925 0 : struct ArgumentsFrameOperator final : public Operator {
926 30868 : ArgumentsFrameOperator()
927 : : Operator(IrOpcode::kArgumentsFrame, Operator::kPure, "ArgumentsFrame",
928 30868 : 0, 0, 0, 1, 0, 0) {}
929 : };
930 : ArgumentsFrameOperator kArgumentsFrame;
931 :
932 : template <CheckForMinusZeroMode kMode>
933 0 : struct ChangeFloat64ToTaggedOperator final
934 : : public Operator1<CheckForMinusZeroMode> {
935 61736 : ChangeFloat64ToTaggedOperator()
936 : : Operator1<CheckForMinusZeroMode>(
937 : IrOpcode::kChangeFloat64ToTagged, Operator::kPure,
938 61736 : "ChangeFloat64ToTagged", 1, 0, 0, 1, 0, 0, kMode) {}
939 : };
940 : ChangeFloat64ToTaggedOperator<CheckForMinusZeroMode::kCheckForMinusZero>
941 : kChangeFloat64ToTaggedCheckForMinusZeroOperator;
942 : ChangeFloat64ToTaggedOperator<CheckForMinusZeroMode::kDontCheckForMinusZero>
943 : kChangeFloat64ToTaggedDontCheckForMinusZeroOperator;
944 :
945 : template <CheckForMinusZeroMode kMode>
946 0 : struct CheckedInt32MulOperator final
947 : : public Operator1<CheckForMinusZeroMode> {
948 61736 : CheckedInt32MulOperator()
949 : : Operator1<CheckForMinusZeroMode>(
950 : IrOpcode::kCheckedInt32Mul,
951 : Operator::kFoldable | Operator::kNoThrow, "CheckedInt32Mul", 2, 1,
952 61736 : 1, 1, 1, 0, kMode) {}
953 : };
954 : CheckedInt32MulOperator<CheckForMinusZeroMode::kCheckForMinusZero>
955 : kCheckedInt32MulCheckForMinusZeroOperator;
956 : CheckedInt32MulOperator<CheckForMinusZeroMode::kDontCheckForMinusZero>
957 : kCheckedInt32MulDontCheckForMinusZeroOperator;
958 :
959 : template <CheckForMinusZeroMode kMode>
960 0 : struct CheckedFloat64ToInt32Operator final
961 : : public Operator1<CheckMinusZeroParameters> {
962 61736 : CheckedFloat64ToInt32Operator()
963 : : Operator1<CheckMinusZeroParameters>(
964 : IrOpcode::kCheckedFloat64ToInt32,
965 : Operator::kFoldable | Operator::kNoThrow, "CheckedFloat64ToInt32",
966 : 1, 1, 1, 1, 1, 0,
967 123472 : CheckMinusZeroParameters(kMode, VectorSlotPair())) {}
968 : };
969 : CheckedFloat64ToInt32Operator<CheckForMinusZeroMode::kCheckForMinusZero>
970 : kCheckedFloat64ToInt32CheckForMinusZeroOperator;
971 : CheckedFloat64ToInt32Operator<CheckForMinusZeroMode::kDontCheckForMinusZero>
972 : kCheckedFloat64ToInt32DontCheckForMinusZeroOperator;
973 :
974 : template <CheckForMinusZeroMode kMode>
975 0 : struct CheckedFloat64ToInt64Operator final
976 : : public Operator1<CheckMinusZeroParameters> {
977 61736 : CheckedFloat64ToInt64Operator()
978 : : Operator1<CheckMinusZeroParameters>(
979 : IrOpcode::kCheckedFloat64ToInt64,
980 : Operator::kFoldable | Operator::kNoThrow, "CheckedFloat64ToInt64",
981 : 1, 1, 1, 1, 1, 0,
982 123472 : CheckMinusZeroParameters(kMode, VectorSlotPair())) {}
983 : };
984 : CheckedFloat64ToInt64Operator<CheckForMinusZeroMode::kCheckForMinusZero>
985 : kCheckedFloat64ToInt64CheckForMinusZeroOperator;
986 : CheckedFloat64ToInt64Operator<CheckForMinusZeroMode::kDontCheckForMinusZero>
987 : kCheckedFloat64ToInt64DontCheckForMinusZeroOperator;
988 :
989 : template <CheckForMinusZeroMode kMode>
990 0 : struct CheckedTaggedToInt32Operator final
991 : : public Operator1<CheckMinusZeroParameters> {
992 61736 : CheckedTaggedToInt32Operator()
993 : : Operator1<CheckMinusZeroParameters>(
994 : IrOpcode::kCheckedTaggedToInt32,
995 : Operator::kFoldable | Operator::kNoThrow, "CheckedTaggedToInt32",
996 : 1, 1, 1, 1, 1, 0,
997 123472 : CheckMinusZeroParameters(kMode, VectorSlotPair())) {}
998 : };
999 : CheckedTaggedToInt32Operator<CheckForMinusZeroMode::kCheckForMinusZero>
1000 : kCheckedTaggedToInt32CheckForMinusZeroOperator;
1001 : CheckedTaggedToInt32Operator<CheckForMinusZeroMode::kDontCheckForMinusZero>
1002 : kCheckedTaggedToInt32DontCheckForMinusZeroOperator;
1003 :
1004 : template <CheckForMinusZeroMode kMode>
1005 0 : struct CheckedTaggedToInt64Operator final
1006 : : public Operator1<CheckMinusZeroParameters> {
1007 61736 : CheckedTaggedToInt64Operator()
1008 : : Operator1<CheckMinusZeroParameters>(
1009 : IrOpcode::kCheckedTaggedToInt64,
1010 : Operator::kFoldable | Operator::kNoThrow, "CheckedTaggedToInt64",
1011 : 1, 1, 1, 1, 1, 0,
1012 123472 : CheckMinusZeroParameters(kMode, VectorSlotPair())) {}
1013 : };
1014 : CheckedTaggedToInt64Operator<CheckForMinusZeroMode::kCheckForMinusZero>
1015 : kCheckedTaggedToInt64CheckForMinusZeroOperator;
1016 : CheckedTaggedToInt64Operator<CheckForMinusZeroMode::kDontCheckForMinusZero>
1017 : kCheckedTaggedToInt64DontCheckForMinusZeroOperator;
1018 :
1019 : template <CheckTaggedInputMode kMode>
1020 0 : struct CheckedTaggedToFloat64Operator final
1021 : : public Operator1<CheckTaggedInputParameters> {
1022 61736 : CheckedTaggedToFloat64Operator()
1023 : : Operator1<CheckTaggedInputParameters>(
1024 : IrOpcode::kCheckedTaggedToFloat64,
1025 : Operator::kFoldable | Operator::kNoThrow,
1026 : "CheckedTaggedToFloat64", 1, 1, 1, 1, 1, 0,
1027 123472 : CheckTaggedInputParameters(kMode, VectorSlotPair())) {}
1028 : };
1029 : CheckedTaggedToFloat64Operator<CheckTaggedInputMode::kNumber>
1030 : kCheckedTaggedToFloat64NumberOperator;
1031 : CheckedTaggedToFloat64Operator<CheckTaggedInputMode::kNumberOrOddball>
1032 : kCheckedTaggedToFloat64NumberOrOddballOperator;
1033 :
1034 : template <CheckTaggedInputMode kMode>
1035 0 : struct CheckedTruncateTaggedToWord32Operator final
1036 : : public Operator1<CheckTaggedInputParameters> {
1037 61736 : CheckedTruncateTaggedToWord32Operator()
1038 : : Operator1<CheckTaggedInputParameters>(
1039 : IrOpcode::kCheckedTruncateTaggedToWord32,
1040 : Operator::kFoldable | Operator::kNoThrow,
1041 : "CheckedTruncateTaggedToWord32", 1, 1, 1, 1, 1, 0,
1042 123472 : CheckTaggedInputParameters(kMode, VectorSlotPair())) {}
1043 : };
1044 : CheckedTruncateTaggedToWord32Operator<CheckTaggedInputMode::kNumber>
1045 : kCheckedTruncateTaggedToWord32NumberOperator;
1046 : CheckedTruncateTaggedToWord32Operator<CheckTaggedInputMode::kNumberOrOddball>
1047 : kCheckedTruncateTaggedToWord32NumberOrOddballOperator;
1048 :
1049 : template <ConvertReceiverMode kMode>
1050 0 : struct ConvertReceiverOperator final : public Operator1<ConvertReceiverMode> {
1051 92604 : ConvertReceiverOperator()
1052 : : Operator1<ConvertReceiverMode>( // --
1053 : IrOpcode::kConvertReceiver, // opcode
1054 : Operator::kEliminatable, // flags
1055 : "ConvertReceiver", // name
1056 : 2, 1, 1, 1, 1, 0, // counts
1057 92604 : kMode) {} // param
1058 : };
1059 : ConvertReceiverOperator<ConvertReceiverMode::kAny>
1060 : kConvertReceiverAnyOperator;
1061 : ConvertReceiverOperator<ConvertReceiverMode::kNullOrUndefined>
1062 : kConvertReceiverNullOrUndefinedOperator;
1063 : ConvertReceiverOperator<ConvertReceiverMode::kNotNullOrUndefined>
1064 : kConvertReceiverNotNullOrUndefinedOperator;
1065 :
1066 : template <CheckFloat64HoleMode kMode>
1067 0 : struct CheckFloat64HoleNaNOperator final
1068 : : public Operator1<CheckFloat64HoleParameters> {
1069 61736 : CheckFloat64HoleNaNOperator()
1070 : : Operator1<CheckFloat64HoleParameters>(
1071 : IrOpcode::kCheckFloat64Hole,
1072 : Operator::kFoldable | Operator::kNoThrow, "CheckFloat64Hole", 1,
1073 : 1, 1, 1, 1, 0,
1074 123472 : CheckFloat64HoleParameters(kMode, VectorSlotPair())) {}
1075 : };
1076 : CheckFloat64HoleNaNOperator<CheckFloat64HoleMode::kAllowReturnHole>
1077 : kCheckFloat64HoleAllowReturnHoleOperator;
1078 : CheckFloat64HoleNaNOperator<CheckFloat64HoleMode::kNeverReturnHole>
1079 : kCheckFloat64HoleNeverReturnHoleOperator;
1080 :
1081 0 : struct EnsureWritableFastElementsOperator final : public Operator {
1082 30868 : EnsureWritableFastElementsOperator()
1083 : : Operator( // --
1084 : IrOpcode::kEnsureWritableFastElements, // opcode
1085 : Operator::kNoDeopt | Operator::kNoThrow, // flags
1086 : "EnsureWritableFastElements", // name
1087 30868 : 2, 1, 1, 1, 1, 0) {} // counts
1088 : };
1089 : EnsureWritableFastElementsOperator kEnsureWritableFastElements;
1090 :
1091 : template <GrowFastElementsMode kMode>
1092 0 : struct GrowFastElementsOperator final
1093 : : public Operator1<GrowFastElementsParameters> {
1094 61736 : GrowFastElementsOperator()
1095 : : Operator1(IrOpcode::kMaybeGrowFastElements, Operator::kNoThrow,
1096 : "MaybeGrowFastElements", 4, 1, 1, 1, 1, 0,
1097 123472 : GrowFastElementsParameters(kMode, VectorSlotPair())) {}
1098 : };
1099 :
1100 : GrowFastElementsOperator<GrowFastElementsMode::kDoubleElements>
1101 : kGrowFastElementsOperatorDoubleElements;
1102 : GrowFastElementsOperator<GrowFastElementsMode::kSmiOrObjectElements>
1103 : kGrowFastElementsOperatorSmiOrObjectElements;
1104 :
1105 0 : struct LoadFieldByIndexOperator final : public Operator {
1106 30868 : LoadFieldByIndexOperator()
1107 : : Operator( // --
1108 : IrOpcode::kLoadFieldByIndex, // opcode
1109 : Operator::kEliminatable, // flags,
1110 : "LoadFieldByIndex", // name
1111 30868 : 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 4938880 : SPECULATIVE_NUMBER_BINOP_LIST(SPECULATIVE_NUMBER_BINOP)
1132 : #undef SPECULATIVE_NUMBER_BINOP
1133 :
1134 : template <NumberOperationHint kHint>
1135 0 : struct SpeculativeToNumberOperator final
1136 : : public Operator1<NumberOperationParameters> {
1137 123472 : SpeculativeToNumberOperator()
1138 : : Operator1<NumberOperationParameters>(
1139 : IrOpcode::kSpeculativeToNumber,
1140 : Operator::kFoldable | Operator::kNoThrow, "SpeculativeToNumber",
1141 : 1, 1, 1, 1, 1, 0,
1142 246944 : NumberOperationParameters(kHint, VectorSlotPair())) {}
1143 : };
1144 : SpeculativeToNumberOperator<NumberOperationHint::kSignedSmall>
1145 : kSpeculativeToNumberSignedSmallOperator;
1146 : SpeculativeToNumberOperator<NumberOperationHint::kSigned32>
1147 : kSpeculativeToNumberSigned32Operator;
1148 : SpeculativeToNumberOperator<NumberOperationHint::kNumber>
1149 : kSpeculativeToNumberNumberOperator;
1150 : SpeculativeToNumberOperator<NumberOperationHint::kNumberOrOddball>
1151 : kSpeculativeToNumberNumberOrOddballOperator;
1152 : };
1153 :
1154 : namespace {
1155 4964604 : DEFINE_LAZY_LEAKY_OBJECT_GETTER(SimplifiedOperatorGlobalCache,
1156 : GetSimplifiedOperatorGlobalCache);
1157 : }
1158 :
1159 4964604 : SimplifiedOperatorBuilder::SimplifiedOperatorBuilder(Zone* zone)
1160 4964604 : : cache_(*GetSimplifiedOperatorGlobalCache()), zone_(zone) {}
1161 :
1162 : #define GET_FROM_CACHE(Name, ...) \
1163 : const Operator* SimplifiedOperatorBuilder::Name() { return &cache_.k##Name; }
1164 1279983 : PURE_OP_LIST(GET_FROM_CACHE)
1165 4310 : EFFECT_DEPENDENT_OP_LIST(GET_FROM_CACHE)
1166 206889 : CHECKED_OP_LIST(GET_FROM_CACHE)
1167 17702 : GET_FROM_CACHE(ArgumentsFrame)
1168 211 : GET_FROM_CACHE(FindOrderedHashMapEntry)
1169 15 : GET_FROM_CACHE(FindOrderedHashMapEntryForInt32Key)
1170 543 : GET_FROM_CACHE(LoadFieldByIndex)
1171 : #undef GET_FROM_CACHE
1172 :
1173 : #define GET_FROM_CACHE_WITH_FEEDBACK(Name, value_input_count, \
1174 : value_output_count) \
1175 : const Operator* SimplifiedOperatorBuilder::Name( \
1176 : const VectorSlotPair& feedback) { \
1177 : if (!feedback.IsValid()) { \
1178 : return &cache_.k##Name; \
1179 : } \
1180 : return new (zone()) Operator1<CheckParameters>( \
1181 : IrOpcode::k##Name, Operator::kFoldable | Operator::kNoThrow, #Name, \
1182 : value_input_count, 1, 1, value_output_count, 1, 0, \
1183 : CheckParameters(feedback)); \
1184 : }
1185 765124 : CHECKED_WITH_FEEDBACK_OP_LIST(GET_FROM_CACHE_WITH_FEEDBACK)
1186 : #undef GET_FROM_CACHE_WITH_FEEDBACK
1187 :
1188 0 : bool IsCheckedWithFeedback(const Operator* op) {
1189 : #define CASE(Name, ...) case IrOpcode::k##Name:
1190 0 : switch (op->opcode()) {
1191 : CHECKED_WITH_FEEDBACK_OP_LIST(CASE) return true;
1192 : default:
1193 0 : return false;
1194 : }
1195 : #undef CASE
1196 : }
1197 :
1198 2655 : const Operator* SimplifiedOperatorBuilder::RuntimeAbort(AbortReason reason) {
1199 : return new (zone()) Operator1<int>( // --
1200 : IrOpcode::kRuntimeAbort, // opcode
1201 : Operator::kNoThrow | Operator::kNoDeopt, // flags
1202 : "RuntimeAbort", // name
1203 : 0, 1, 1, 0, 1, 0, // counts
1204 5310 : static_cast<int>(reason)); // parameter
1205 : }
1206 :
1207 16395 : const Operator* SimplifiedOperatorBuilder::CheckIf(
1208 625 : DeoptimizeReason reason, const VectorSlotPair& feedback) {
1209 16395 : if (!feedback.IsValid()) {
1210 15770 : switch (reason) {
1211 : #define CHECK_IF(Name, message) \
1212 : case DeoptimizeReason::k##Name: \
1213 : return &cache_.kCheckIf##Name;
1214 250 : DEOPTIMIZE_REASON_LIST(CHECK_IF)
1215 : #undef CHECK_IF
1216 : }
1217 : }
1218 : return new (zone()) Operator1<CheckIfParameters>(
1219 : IrOpcode::kCheckIf, Operator::kFoldable | Operator::kNoThrow, "CheckIf",
1220 : 1, 1, 1, 0, 1, 0, CheckIfParameters(reason, feedback));
1221 : }
1222 :
1223 72770 : const Operator* SimplifiedOperatorBuilder::ChangeFloat64ToTagged(
1224 : CheckForMinusZeroMode mode) {
1225 72770 : switch (mode) {
1226 : case CheckForMinusZeroMode::kCheckForMinusZero:
1227 43121 : return &cache_.kChangeFloat64ToTaggedCheckForMinusZeroOperator;
1228 : case CheckForMinusZeroMode::kDontCheckForMinusZero:
1229 29649 : return &cache_.kChangeFloat64ToTaggedDontCheckForMinusZeroOperator;
1230 : }
1231 0 : UNREACHABLE();
1232 : }
1233 :
1234 5975 : const Operator* SimplifiedOperatorBuilder::CheckedInt32Mul(
1235 : CheckForMinusZeroMode mode) {
1236 5975 : switch (mode) {
1237 : case CheckForMinusZeroMode::kCheckForMinusZero:
1238 4012 : return &cache_.kCheckedInt32MulCheckForMinusZeroOperator;
1239 : case CheckForMinusZeroMode::kDontCheckForMinusZero:
1240 1963 : return &cache_.kCheckedInt32MulDontCheckForMinusZeroOperator;
1241 : }
1242 0 : UNREACHABLE();
1243 : }
1244 :
1245 2644 : const Operator* SimplifiedOperatorBuilder::CheckedFloat64ToInt32(
1246 25 : CheckForMinusZeroMode mode, const VectorSlotPair& feedback) {
1247 2644 : if (!feedback.IsValid()) {
1248 2619 : switch (mode) {
1249 : case CheckForMinusZeroMode::kCheckForMinusZero:
1250 2179 : return &cache_.kCheckedFloat64ToInt32CheckForMinusZeroOperator;
1251 : case CheckForMinusZeroMode::kDontCheckForMinusZero:
1252 440 : return &cache_.kCheckedFloat64ToInt32DontCheckForMinusZeroOperator;
1253 : }
1254 : }
1255 : return new (zone()) Operator1<CheckMinusZeroParameters>(
1256 : IrOpcode::kCheckedFloat64ToInt32,
1257 : Operator::kFoldable | Operator::kNoThrow, "CheckedFloat64ToInt32", 1, 1,
1258 : 1, 1, 1, 0, CheckMinusZeroParameters(mode, feedback));
1259 : }
1260 :
1261 60 : const Operator* SimplifiedOperatorBuilder::CheckedFloat64ToInt64(
1262 38 : CheckForMinusZeroMode mode, const VectorSlotPair& feedback) {
1263 60 : if (!feedback.IsValid()) {
1264 22 : switch (mode) {
1265 : case CheckForMinusZeroMode::kCheckForMinusZero:
1266 6 : return &cache_.kCheckedFloat64ToInt64CheckForMinusZeroOperator;
1267 : case CheckForMinusZeroMode::kDontCheckForMinusZero:
1268 16 : return &cache_.kCheckedFloat64ToInt64DontCheckForMinusZeroOperator;
1269 : }
1270 : }
1271 : return new (zone()) Operator1<CheckMinusZeroParameters>(
1272 : IrOpcode::kCheckedFloat64ToInt64,
1273 : Operator::kFoldable | Operator::kNoThrow, "CheckedFloat64ToInt64", 1, 1,
1274 : 1, 1, 1, 0, CheckMinusZeroParameters(mode, feedback));
1275 : }
1276 :
1277 2759 : const Operator* SimplifiedOperatorBuilder::CheckedTaggedToInt32(
1278 397 : CheckForMinusZeroMode mode, const VectorSlotPair& feedback) {
1279 2759 : if (!feedback.IsValid()) {
1280 2362 : switch (mode) {
1281 : case CheckForMinusZeroMode::kCheckForMinusZero:
1282 9 : return &cache_.kCheckedTaggedToInt32CheckForMinusZeroOperator;
1283 : case CheckForMinusZeroMode::kDontCheckForMinusZero:
1284 2353 : return &cache_.kCheckedTaggedToInt32DontCheckForMinusZeroOperator;
1285 : }
1286 : }
1287 : return new (zone()) Operator1<CheckMinusZeroParameters>(
1288 : IrOpcode::kCheckedTaggedToInt32, Operator::kFoldable | Operator::kNoThrow,
1289 : "CheckedTaggedToInt32", 1, 1, 1, 1, 1, 0,
1290 : CheckMinusZeroParameters(mode, feedback));
1291 : }
1292 :
1293 116 : const Operator* SimplifiedOperatorBuilder::CheckedTaggedToInt64(
1294 94 : CheckForMinusZeroMode mode, const VectorSlotPair& feedback) {
1295 116 : if (!feedback.IsValid()) {
1296 22 : switch (mode) {
1297 : case CheckForMinusZeroMode::kCheckForMinusZero:
1298 6 : return &cache_.kCheckedTaggedToInt64CheckForMinusZeroOperator;
1299 : case CheckForMinusZeroMode::kDontCheckForMinusZero:
1300 16 : return &cache_.kCheckedTaggedToInt64DontCheckForMinusZeroOperator;
1301 : }
1302 : }
1303 : return new (zone()) Operator1<CheckMinusZeroParameters>(
1304 : IrOpcode::kCheckedTaggedToInt64, Operator::kFoldable | Operator::kNoThrow,
1305 : "CheckedTaggedToInt64", 1, 1, 1, 1, 1, 0,
1306 : CheckMinusZeroParameters(mode, feedback));
1307 : }
1308 :
1309 62064 : const Operator* SimplifiedOperatorBuilder::CheckedTaggedToFloat64(
1310 38995 : CheckTaggedInputMode mode, const VectorSlotPair& feedback) {
1311 62064 : if (!feedback.IsValid()) {
1312 23069 : switch (mode) {
1313 : case CheckTaggedInputMode::kNumber:
1314 8789 : return &cache_.kCheckedTaggedToFloat64NumberOperator;
1315 : case CheckTaggedInputMode::kNumberOrOddball:
1316 14280 : return &cache_.kCheckedTaggedToFloat64NumberOrOddballOperator;
1317 : }
1318 : }
1319 : return new (zone()) Operator1<CheckTaggedInputParameters>(
1320 : IrOpcode::kCheckedTaggedToFloat64,
1321 : Operator::kFoldable | Operator::kNoThrow, "CheckedTaggedToFloat64", 1, 1,
1322 : 1, 1, 1, 0, CheckTaggedInputParameters(mode, feedback));
1323 : }
1324 :
1325 1607 : const Operator* SimplifiedOperatorBuilder::CheckedTruncateTaggedToWord32(
1326 36 : CheckTaggedInputMode mode, const VectorSlotPair& feedback) {
1327 1607 : if (!feedback.IsValid()) {
1328 1571 : switch (mode) {
1329 : case CheckTaggedInputMode::kNumber:
1330 874 : return &cache_.kCheckedTruncateTaggedToWord32NumberOperator;
1331 : case CheckTaggedInputMode::kNumberOrOddball:
1332 697 : return &cache_.kCheckedTruncateTaggedToWord32NumberOrOddballOperator;
1333 : }
1334 : }
1335 : return new (zone()) Operator1<CheckTaggedInputParameters>(
1336 : IrOpcode::kCheckedTruncateTaggedToWord32,
1337 : Operator::kFoldable | Operator::kNoThrow, "CheckedTruncateTaggedToWord32",
1338 : 1, 1, 1, 1, 1, 0, CheckTaggedInputParameters(mode, feedback));
1339 : }
1340 :
1341 94303 : const Operator* SimplifiedOperatorBuilder::CheckMaps(
1342 : CheckMapsFlags flags, ZoneHandleSet<Map> maps,
1343 94303 : const VectorSlotPair& feedback) {
1344 : CheckMapsParameters const parameters(flags, maps, feedback);
1345 : return new (zone()) Operator1<CheckMapsParameters>( // --
1346 : IrOpcode::kCheckMaps, // opcode
1347 : Operator::kNoThrow | Operator::kNoWrite, // flags
1348 : "CheckMaps", // name
1349 : 1, 1, 1, 0, 1, 0, // counts
1350 188607 : parameters); // parameter
1351 : }
1352 :
1353 9730 : const Operator* SimplifiedOperatorBuilder::MapGuard(ZoneHandleSet<Map> maps) {
1354 : return new (zone()) Operator1<MapsParameterInfo>( // --
1355 : IrOpcode::kMapGuard, Operator::kEliminatable, // opcode
1356 : "MapGuard", // name
1357 : 1, 1, 1, 0, 1, 0, // counts
1358 9730 : MapsParameterInfo(maps)); // parameter
1359 : }
1360 :
1361 5161 : const Operator* SimplifiedOperatorBuilder::CompareMaps(
1362 5161 : ZoneHandleSet<Map> maps) {
1363 : return new (zone()) Operator1<MapsParameterInfo>( // --
1364 : IrOpcode::kCompareMaps, // opcode
1365 : Operator::kEliminatable, // flags
1366 : "CompareMaps", // name
1367 : 1, 1, 1, 1, 1, 0, // counts
1368 10322 : MapsParameterInfo(maps)); // parameter
1369 : }
1370 :
1371 168771 : const Operator* SimplifiedOperatorBuilder::ConvertReceiver(
1372 : ConvertReceiverMode mode) {
1373 168771 : switch (mode) {
1374 : case ConvertReceiverMode::kAny:
1375 1257 : return &cache_.kConvertReceiverAnyOperator;
1376 : case ConvertReceiverMode::kNullOrUndefined:
1377 166665 : return &cache_.kConvertReceiverNullOrUndefinedOperator;
1378 : case ConvertReceiverMode::kNotNullOrUndefined:
1379 849 : return &cache_.kConvertReceiverNotNullOrUndefinedOperator;
1380 : }
1381 0 : UNREACHABLE();
1382 : return nullptr;
1383 : }
1384 :
1385 612 : const Operator* SimplifiedOperatorBuilder::CheckFloat64Hole(
1386 17 : CheckFloat64HoleMode mode, VectorSlotPair const& feedback) {
1387 612 : if (!feedback.IsValid()) {
1388 595 : switch (mode) {
1389 : case CheckFloat64HoleMode::kAllowReturnHole:
1390 419 : return &cache_.kCheckFloat64HoleAllowReturnHoleOperator;
1391 : case CheckFloat64HoleMode::kNeverReturnHole:
1392 176 : return &cache_.kCheckFloat64HoleNeverReturnHoleOperator;
1393 : }
1394 0 : UNREACHABLE();
1395 : }
1396 : return new (zone()) Operator1<CheckFloat64HoleParameters>(
1397 : IrOpcode::kCheckFloat64Hole, Operator::kFoldable | Operator::kNoThrow,
1398 : "CheckFloat64Hole", 1, 1, 1, 1, 1, 0,
1399 : CheckFloat64HoleParameters(mode, feedback));
1400 : }
1401 :
1402 82507 : const Operator* SimplifiedOperatorBuilder::SpeculativeToNumber(
1403 65519 : NumberOperationHint hint, const VectorSlotPair& feedback) {
1404 82507 : if (!feedback.IsValid()) {
1405 16994 : switch (hint) {
1406 : case NumberOperationHint::kSignedSmall:
1407 7402 : return &cache_.kSpeculativeToNumberSignedSmallOperator;
1408 : case NumberOperationHint::kSignedSmallInputs:
1409 : break;
1410 : case NumberOperationHint::kSigned32:
1411 6 : return &cache_.kSpeculativeToNumberSigned32Operator;
1412 : case NumberOperationHint::kNumber:
1413 6374 : return &cache_.kSpeculativeToNumberNumberOperator;
1414 : case NumberOperationHint::kNumberOrOddball:
1415 3206 : return &cache_.kSpeculativeToNumberNumberOrOddballOperator;
1416 : }
1417 : }
1418 : return new (zone()) Operator1<NumberOperationParameters>(
1419 : IrOpcode::kSpeculativeToNumber, Operator::kFoldable | Operator::kNoThrow,
1420 : "SpeculativeToNumber", 1, 1, 1, 1, 1, 0,
1421 : NumberOperationParameters(hint, feedback));
1422 : }
1423 :
1424 1401 : const Operator* SimplifiedOperatorBuilder::EnsureWritableFastElements() {
1425 1401 : return &cache_.kEnsureWritableFastElements;
1426 : }
1427 :
1428 3000 : const Operator* SimplifiedOperatorBuilder::MaybeGrowFastElements(
1429 1896 : GrowFastElementsMode mode, const VectorSlotPair& feedback) {
1430 3000 : if (!feedback.IsValid()) {
1431 1104 : switch (mode) {
1432 : case GrowFastElementsMode::kDoubleElements:
1433 157 : return &cache_.kGrowFastElementsOperatorDoubleElements;
1434 : case GrowFastElementsMode::kSmiOrObjectElements:
1435 947 : return &cache_.kGrowFastElementsOperatorSmiOrObjectElements;
1436 : }
1437 : }
1438 : return new (zone()) Operator1<GrowFastElementsParameters>( // --
1439 : IrOpcode::kMaybeGrowFastElements, // opcode
1440 : Operator::kNoThrow, // flags
1441 : "MaybeGrowFastElements", // name
1442 : 4, 1, 1, 1, 1, 0, // counts
1443 : GrowFastElementsParameters(mode, feedback)); // parameter
1444 : }
1445 :
1446 538 : const Operator* SimplifiedOperatorBuilder::TransitionElementsKind(
1447 538 : ElementsTransition transition) {
1448 : return new (zone()) Operator1<ElementsTransition>( // --
1449 : IrOpcode::kTransitionElementsKind, // opcode
1450 : Operator::kNoDeopt | Operator::kNoThrow, // flags
1451 : "TransitionElementsKind", // name
1452 : 1, 1, 1, 0, 1, 0, // counts
1453 1076 : transition); // parameter
1454 : }
1455 :
1456 : namespace {
1457 :
1458 : struct ArgumentsLengthParameters {
1459 : int formal_parameter_count;
1460 : bool is_rest_length;
1461 : };
1462 :
1463 : bool operator==(ArgumentsLengthParameters first,
1464 : ArgumentsLengthParameters second) {
1465 0 : return first.formal_parameter_count == second.formal_parameter_count &&
1466 : first.is_rest_length == second.is_rest_length;
1467 : }
1468 :
1469 40599 : size_t hash_value(ArgumentsLengthParameters param) {
1470 40599 : return base::hash_combine(param.formal_parameter_count, param.is_rest_length);
1471 : }
1472 :
1473 0 : std::ostream& operator<<(std::ostream& os, ArgumentsLengthParameters param) {
1474 0 : return os << param.formal_parameter_count << ", "
1475 0 : << (param.is_rest_length ? "rest length" : "not rest length");
1476 : }
1477 :
1478 : } // namespace
1479 :
1480 17702 : const Operator* SimplifiedOperatorBuilder::ArgumentsLength(
1481 17702 : int formal_parameter_count, bool is_rest_length) {
1482 : return new (zone()) Operator1<ArgumentsLengthParameters>( // --
1483 : IrOpcode::kArgumentsLength, // opcode
1484 : Operator::kPure, // flags
1485 : "ArgumentsLength", // name
1486 : 1, 0, 0, 1, 0, 0, // counts
1487 : ArgumentsLengthParameters{formal_parameter_count,
1488 35404 : is_rest_length}); // parameter
1489 : }
1490 :
1491 16668 : int FormalParameterCountOf(const Operator* op) {
1492 : DCHECK_EQ(IrOpcode::kArgumentsLength, op->opcode());
1493 16668 : return OpParameter<ArgumentsLengthParameters>(op).formal_parameter_count;
1494 : }
1495 :
1496 35921 : bool IsRestLengthOf(const Operator* op) {
1497 : DCHECK_EQ(IrOpcode::kArgumentsLength, op->opcode());
1498 35921 : return OpParameter<ArgumentsLengthParameters>(op).is_rest_length;
1499 : }
1500 :
1501 0 : bool operator==(CheckParameters const& lhs, CheckParameters const& rhs) {
1502 0 : return lhs.feedback() == rhs.feedback();
1503 : }
1504 :
1505 0 : size_t hash_value(CheckParameters const& p) { return hash_value(p.feedback()); }
1506 :
1507 0 : std::ostream& operator<<(std::ostream& os, CheckParameters const& p) {
1508 26 : return os << p.feedback();
1509 : }
1510 :
1511 413170 : CheckParameters const& CheckParametersOf(Operator const* op) {
1512 : #define MAKE_OR(name, arg2, arg3) op->opcode() == IrOpcode::k##name ||
1513 413170 : CHECK((CHECKED_WITH_FEEDBACK_OP_LIST(MAKE_OR) false));
1514 : #undef MAKE_OR
1515 413170 : return OpParameter<CheckParameters>(op);
1516 : }
1517 :
1518 0 : bool operator==(CheckIfParameters const& lhs, CheckIfParameters const& rhs) {
1519 0 : return lhs.reason() == rhs.reason() && lhs.feedback() == rhs.feedback();
1520 : }
1521 :
1522 0 : size_t hash_value(CheckIfParameters const& p) {
1523 0 : return base::hash_combine(p.reason(), p.feedback());
1524 : }
1525 :
1526 0 : std::ostream& operator<<(std::ostream& os, CheckIfParameters const& p) {
1527 0 : return os << p.reason() << p.feedback();
1528 : }
1529 :
1530 15244 : CheckIfParameters const& CheckIfParametersOf(Operator const* op) {
1531 15244 : CHECK(op->opcode() == IrOpcode::kCheckIf);
1532 15244 : return OpParameter<CheckIfParameters>(op);
1533 : }
1534 :
1535 28 : const Operator* SimplifiedOperatorBuilder::NewDoubleElements(
1536 28 : PretenureFlag pretenure) {
1537 : return new (zone()) Operator1<PretenureFlag>( // --
1538 : IrOpcode::kNewDoubleElements, // opcode
1539 : Operator::kEliminatable, // flags
1540 : "NewDoubleElements", // name
1541 : 1, 1, 1, 1, 1, 0, // counts
1542 28 : pretenure); // parameter
1543 : }
1544 :
1545 487 : const Operator* SimplifiedOperatorBuilder::NewSmiOrObjectElements(
1546 487 : PretenureFlag pretenure) {
1547 : return new (zone()) Operator1<PretenureFlag>( // --
1548 : IrOpcode::kNewSmiOrObjectElements, // opcode
1549 : Operator::kEliminatable, // flags
1550 : "NewSmiOrObjectElements", // name
1551 : 1, 1, 1, 1, 1, 0, // counts
1552 487 : pretenure); // parameter
1553 : }
1554 :
1555 17702 : const Operator* SimplifiedOperatorBuilder::NewArgumentsElements(
1556 17702 : int mapped_count) {
1557 : return new (zone()) Operator1<int>( // --
1558 : IrOpcode::kNewArgumentsElements, // opcode
1559 : Operator::kEliminatable, // flags
1560 : "NewArgumentsElements", // name
1561 : 2, 1, 0, 1, 1, 0, // counts
1562 17702 : mapped_count); // parameter
1563 : }
1564 :
1565 35408 : int NewArgumentsElementsMappedCountOf(const Operator* op) {
1566 : DCHECK_EQ(IrOpcode::kNewArgumentsElements, op->opcode());
1567 35408 : return OpParameter<int>(op);
1568 : }
1569 :
1570 136675 : const Operator* SimplifiedOperatorBuilder::Allocate(Type type,
1571 136675 : PretenureFlag pretenure) {
1572 : return new (zone()) Operator1<AllocateParameters>(
1573 : IrOpcode::kAllocate,
1574 : Operator::kNoDeopt | Operator::kNoThrow | Operator::kNoWrite, "Allocate",
1575 136675 : 1, 1, 1, 1, 1, 0, AllocateParameters(type, pretenure));
1576 : }
1577 :
1578 236522 : const Operator* SimplifiedOperatorBuilder::AllocateRaw(
1579 236522 : Type type, PretenureFlag pretenure) {
1580 : return new (zone()) Operator1<AllocateParameters>(
1581 : IrOpcode::kAllocateRaw,
1582 : Operator::kNoDeopt | Operator::kNoThrow | Operator::kNoWrite,
1583 236523 : "AllocateRaw", 1, 1, 1, 1, 1, 1, AllocateParameters(type, pretenure));
1584 : }
1585 :
1586 693 : const Operator* SimplifiedOperatorBuilder::StringCodePointAt(
1587 : UnicodeEncoding encoding) {
1588 693 : switch (encoding) {
1589 : case UnicodeEncoding::UTF16:
1590 95 : return &cache_.kStringCodePointAtOperatorUTF16;
1591 : case UnicodeEncoding::UTF32:
1592 598 : return &cache_.kStringCodePointAtOperatorUTF32;
1593 : }
1594 0 : UNREACHABLE();
1595 : }
1596 :
1597 242 : const Operator* SimplifiedOperatorBuilder::StringFromSingleCodePoint(
1598 : UnicodeEncoding encoding) {
1599 242 : switch (encoding) {
1600 : case UnicodeEncoding::UTF16:
1601 95 : return &cache_.kStringFromSingleCodePointOperatorUTF16;
1602 : case UnicodeEncoding::UTF32:
1603 147 : return &cache_.kStringFromSingleCodePointOperatorUTF32;
1604 : }
1605 0 : UNREACHABLE();
1606 : }
1607 :
1608 : #define SPECULATIVE_NUMBER_BINOP(Name) \
1609 : const Operator* SimplifiedOperatorBuilder::Name(NumberOperationHint hint) { \
1610 : switch (hint) { \
1611 : case NumberOperationHint::kSignedSmall: \
1612 : return &cache_.k##Name##SignedSmallOperator; \
1613 : case NumberOperationHint::kSignedSmallInputs: \
1614 : return &cache_.k##Name##SignedSmallInputsOperator; \
1615 : case NumberOperationHint::kSigned32: \
1616 : return &cache_.k##Name##Signed32Operator; \
1617 : case NumberOperationHint::kNumber: \
1618 : return &cache_.k##Name##NumberOperator; \
1619 : case NumberOperationHint::kNumberOrOddball: \
1620 : return &cache_.k##Name##NumberOrOddballOperator; \
1621 : } \
1622 : UNREACHABLE(); \
1623 : return nullptr; \
1624 : }
1625 328155 : SPECULATIVE_NUMBER_BINOP_LIST(SPECULATIVE_NUMBER_BINOP)
1626 : #undef SPECULATIVE_NUMBER_BINOP
1627 :
1628 : #define ACCESS_OP_LIST(V) \
1629 : V(LoadField, FieldAccess, Operator::kNoWrite, 1, 1, 1) \
1630 : V(StoreField, FieldAccess, Operator::kNoRead, 2, 1, 0) \
1631 : V(LoadElement, ElementAccess, Operator::kNoWrite, 2, 1, 1) \
1632 : V(StoreElement, ElementAccess, Operator::kNoRead, 3, 1, 0) \
1633 : V(LoadTypedElement, ExternalArrayType, Operator::kNoWrite, 4, 1, 1) \
1634 : V(StoreTypedElement, ExternalArrayType, Operator::kNoRead, 5, 1, 0) \
1635 : V(LoadDataViewElement, ExternalArrayType, Operator::kNoWrite, 5, 1, 1) \
1636 : V(StoreDataViewElement, ExternalArrayType, Operator::kNoRead, 6, 1, 0)
1637 :
1638 : #define ACCESS(Name, Type, properties, value_input_count, control_input_count, \
1639 : output_count) \
1640 : const Operator* SimplifiedOperatorBuilder::Name(const Type& access) { \
1641 : return new (zone()) \
1642 : Operator1<Type>(IrOpcode::k##Name, \
1643 : Operator::kNoDeopt | Operator::kNoThrow | properties, \
1644 : #Name, value_input_count, 1, control_input_count, \
1645 : output_count, 1, 0, access); \
1646 : }
1647 8444782 : ACCESS_OP_LIST(ACCESS)
1648 : #undef ACCESS
1649 :
1650 326 : const Operator* SimplifiedOperatorBuilder::TransitionAndStoreElement(
1651 326 : Handle<Map> double_map, Handle<Map> fast_map) {
1652 : TransitionAndStoreElementParameters parameters(double_map, fast_map);
1653 : return new (zone()) Operator1<TransitionAndStoreElementParameters>(
1654 : IrOpcode::kTransitionAndStoreElement,
1655 : Operator::kNoDeopt | Operator::kNoThrow, "TransitionAndStoreElement", 3,
1656 326 : 1, 1, 0, 1, 0, parameters);
1657 : }
1658 :
1659 156 : const Operator* SimplifiedOperatorBuilder::StoreSignedSmallElement() {
1660 : return new (zone()) Operator(IrOpcode::kStoreSignedSmallElement,
1661 156 : Operator::kNoDeopt | Operator::kNoThrow,
1662 156 : "StoreSignedSmallElement", 3, 1, 1, 0, 1, 0);
1663 : }
1664 :
1665 22 : const Operator* SimplifiedOperatorBuilder::TransitionAndStoreNumberElement(
1666 22 : Handle<Map> double_map) {
1667 : TransitionAndStoreNumberElementParameters parameters(double_map);
1668 : return new (zone()) Operator1<TransitionAndStoreNumberElementParameters>(
1669 : IrOpcode::kTransitionAndStoreNumberElement,
1670 : Operator::kNoDeopt | Operator::kNoThrow,
1671 22 : "TransitionAndStoreNumberElement", 3, 1, 1, 0, 1, 0, parameters);
1672 : }
1673 :
1674 21 : const Operator* SimplifiedOperatorBuilder::TransitionAndStoreNonNumberElement(
1675 21 : Handle<Map> fast_map, Type value_type) {
1676 : TransitionAndStoreNonNumberElementParameters parameters(fast_map, value_type);
1677 : return new (zone()) Operator1<TransitionAndStoreNonNumberElementParameters>(
1678 : IrOpcode::kTransitionAndStoreNonNumberElement,
1679 : Operator::kNoDeopt | Operator::kNoThrow,
1680 21 : "TransitionAndStoreNonNumberElement", 3, 1, 1, 0, 1, 0, parameters);
1681 : }
1682 :
1683 : #undef PURE_OP_LIST
1684 : #undef EFFECT_DEPENDENT_OP_LIST
1685 : #undef SPECULATIVE_NUMBER_BINOP_LIST
1686 : #undef CHECKED_WITH_FEEDBACK_OP_LIST
1687 : #undef CHECKED_OP_LIST
1688 : #undef ACCESS_OP_LIST
1689 :
1690 : } // namespace compiler
1691 : } // namespace internal
1692 183867 : } // namespace v8
|