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 142048 : std::ostream& operator<<(std::ostream& os, BaseTaggedness base_taggedness) {
25 142048 : switch (base_taggedness) {
26 : case kUntaggedBase:
27 86464 : return os << "untagged base";
28 : case kTaggedBase:
29 55584 : 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 142048 : std::ostream& operator<<(std::ostream& os, ElementAccess const& access) {
118 284096 : os << access.base_is_tagged << ", " << access.header_size << ", "
119 284096 : << access.type << ", " << access.machine_type << ", "
120 284096 : << access.write_barrier_kind;
121 142048 : if (FLAG_untrusted_code_mitigations) {
122 0 : os << ", " << access.load_sensitivity;
123 : }
124 142048 : return os;
125 : }
126 :
127 29336132 : const FieldAccess& FieldAccessOf(const Operator* op) {
128 : DCHECK_NOT_NULL(op);
129 : DCHECK(op->opcode() == IrOpcode::kLoadField ||
130 : op->opcode() == IrOpcode::kStoreField);
131 29336132 : return OpParameter<FieldAccess>(op);
132 : }
133 :
134 :
135 404052 : const ElementAccess& ElementAccessOf(const Operator* op) {
136 : DCHECK_NOT_NULL(op);
137 : DCHECK(op->opcode() == IrOpcode::kLoadElement ||
138 : op->opcode() == IrOpcode::kStoreElement);
139 404052 : return OpParameter<ElementAccess>(op);
140 : }
141 :
142 48714 : 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 48714 : return OpParameter<ExternalArrayType>(op);
148 : }
149 :
150 876 : ConvertReceiverMode ConvertReceiverModeOf(Operator const* op) {
151 : DCHECK_EQ(IrOpcode::kConvertReceiver, op->opcode());
152 876 : 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 2365 : CheckFloat64HoleParameters const& CheckFloat64HoleParametersOf(
170 : Operator const* op) {
171 : DCHECK_EQ(IrOpcode::kCheckFloat64Hole, op->opcode());
172 2365 : return OpParameter<CheckFloat64HoleParameters>(op);
173 : }
174 :
175 0 : std::ostream& operator<<(std::ostream& os,
176 : 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 : 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 59293 : CheckForMinusZeroMode CheckMinusZeroModeOf(const Operator* op) {
197 : DCHECK(op->opcode() == IrOpcode::kChangeFloat64ToTagged ||
198 : op->opcode() == IrOpcode::kCheckedInt32Mul);
199 59293 : return OpParameter<CheckForMinusZeroMode>(op);
200 : }
201 :
202 0 : size_t hash_value(CheckForMinusZeroMode mode) {
203 73400 : 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 0 : bool operator==(CheckMapsParameters const& lhs,
227 : CheckMapsParameters const& rhs) {
228 0 : return lhs.flags() == rhs.flags() && lhs.maps() == rhs.maps() &&
229 0 : lhs.feedback() == rhs.feedback();
230 : }
231 :
232 0 : size_t hash_value(CheckMapsParameters const& p) {
233 0 : return base::hash_combine(p.flags(), p.maps(), p.feedback());
234 : }
235 :
236 0 : std::ostream& operator<<(std::ostream& os, CheckMapsParameters const& p) {
237 0 : os << p.flags() << p.maps();
238 0 : if (p.feedback().IsValid()) {
239 0 : os << "; " << p.feedback();
240 : }
241 0 : return os;
242 : }
243 :
244 388515 : CheckMapsParameters const& CheckMapsParametersOf(Operator const* op) {
245 : DCHECK_EQ(IrOpcode::kCheckMaps, op->opcode());
246 388515 : return OpParameter<CheckMapsParameters>(op);
247 : }
248 :
249 23300 : ZoneHandleSet<Map> const& CompareMapsParametersOf(Operator const* op) {
250 : DCHECK_EQ(IrOpcode::kCompareMaps, op->opcode());
251 23300 : return OpParameter<ZoneHandleSet<Map>>(op);
252 : }
253 :
254 15454 : ZoneHandleSet<Map> const& MapGuardMapsOf(Operator const* op) {
255 : DCHECK_EQ(IrOpcode::kMapGuard, op->opcode());
256 15454 : return OpParameter<ZoneHandleSet<Map>>(op);
257 : }
258 :
259 0 : size_t hash_value(CheckTaggedInputMode mode) {
260 0 : return static_cast<size_t>(mode);
261 : }
262 :
263 36 : std::ostream& operator<<(std::ostream& os, CheckTaggedInputMode mode) {
264 36 : switch (mode) {
265 : case CheckTaggedInputMode::kNumber:
266 18 : return os << "Number";
267 : case CheckTaggedInputMode::kNumberOrOddball:
268 18 : return os << "NumberOrOddball";
269 : }
270 0 : UNREACHABLE();
271 : }
272 :
273 0 : std::ostream& operator<<(std::ostream& os, GrowFastElementsMode mode) {
274 0 : switch (mode) {
275 : case GrowFastElementsMode::kDoubleElements:
276 0 : return os << "DoubleElements";
277 : case GrowFastElementsMode::kSmiOrObjectElements:
278 0 : return os << "SmiOrObjectElements";
279 : }
280 0 : UNREACHABLE();
281 : }
282 :
283 0 : bool operator==(const GrowFastElementsParameters& lhs,
284 : const GrowFastElementsParameters& rhs) {
285 0 : return lhs.mode() == rhs.mode() && lhs.feedback() == rhs.feedback();
286 : }
287 :
288 0 : inline size_t hash_value(const GrowFastElementsParameters& params) {
289 0 : return base::hash_combine(params.mode(), params.feedback());
290 : }
291 :
292 0 : std::ostream& operator<<(std::ostream& os,
293 : const GrowFastElementsParameters& params) {
294 0 : os << params.mode();
295 0 : if (params.feedback().IsValid()) {
296 0 : os << params.feedback();
297 : }
298 0 : return os;
299 : }
300 :
301 13431 : const GrowFastElementsParameters& GrowFastElementsParametersOf(
302 : const Operator* op) {
303 : DCHECK_EQ(IrOpcode::kMaybeGrowFastElements, op->opcode());
304 13431 : return OpParameter<GrowFastElementsParameters>(op);
305 : }
306 :
307 0 : bool operator==(ElementsTransition const& lhs, ElementsTransition const& rhs) {
308 0 : return lhs.mode() == rhs.mode() &&
309 0 : lhs.source().address() == rhs.source().address() &&
310 0 : lhs.target().address() == rhs.target().address();
311 : }
312 :
313 0 : size_t hash_value(ElementsTransition transition) {
314 : return base::hash_combine(static_cast<uint8_t>(transition.mode()),
315 0 : transition.source().address(),
316 0 : transition.target().address());
317 : }
318 :
319 0 : std::ostream& operator<<(std::ostream& os, ElementsTransition transition) {
320 0 : switch (transition.mode()) {
321 : case ElementsTransition::kFastTransition:
322 0 : return os << "fast-transition from " << Brief(*transition.source())
323 0 : << " to " << Brief(*transition.target());
324 : case ElementsTransition::kSlowTransition:
325 0 : return os << "slow-transition from " << Brief(*transition.source())
326 0 : << " to " << Brief(*transition.target());
327 : }
328 0 : UNREACHABLE();
329 : }
330 :
331 1782 : ElementsTransition const& ElementsTransitionOf(const Operator* op) {
332 : DCHECK_EQ(IrOpcode::kTransitionElementsKind, op->opcode());
333 1782 : return OpParameter<ElementsTransition>(op);
334 : }
335 :
336 : namespace {
337 :
338 : // Parameters for the TransitionAndStoreElement opcode.
339 : class TransitionAndStoreElementParameters final {
340 : public:
341 : TransitionAndStoreElementParameters(Handle<Map> double_map,
342 : Handle<Map> fast_map);
343 :
344 : Handle<Map> double_map() const { return double_map_; }
345 : Handle<Map> fast_map() const { return fast_map_; }
346 :
347 : private:
348 : Handle<Map> const double_map_;
349 : Handle<Map> const fast_map_;
350 : };
351 :
352 : TransitionAndStoreElementParameters::TransitionAndStoreElementParameters(
353 : Handle<Map> double_map, Handle<Map> fast_map)
354 : : double_map_(double_map), fast_map_(fast_map) {}
355 :
356 : bool operator==(TransitionAndStoreElementParameters const& lhs,
357 : TransitionAndStoreElementParameters const& rhs) {
358 0 : return lhs.fast_map().address() == rhs.fast_map().address() &&
359 0 : lhs.double_map().address() == rhs.double_map().address();
360 : }
361 :
362 : size_t hash_value(TransitionAndStoreElementParameters parameters) {
363 0 : return base::hash_combine(parameters.fast_map().address(),
364 0 : parameters.double_map().address());
365 : }
366 :
367 0 : std::ostream& operator<<(std::ostream& os,
368 : TransitionAndStoreElementParameters parameters) {
369 0 : return os << "fast-map" << Brief(*parameters.fast_map()) << " double-map"
370 0 : << Brief(*parameters.double_map());
371 : }
372 :
373 : } // namespace
374 :
375 : namespace {
376 :
377 : // Parameters for the TransitionAndStoreNonNumberElement opcode.
378 : class TransitionAndStoreNonNumberElementParameters final {
379 : public:
380 : TransitionAndStoreNonNumberElementParameters(Handle<Map> fast_map,
381 : Type value_type);
382 :
383 : Handle<Map> fast_map() const { return fast_map_; }
384 : Type value_type() const { return value_type_; }
385 :
386 : private:
387 : Handle<Map> const fast_map_;
388 : Type value_type_;
389 : };
390 :
391 : TransitionAndStoreNonNumberElementParameters::
392 : TransitionAndStoreNonNumberElementParameters(Handle<Map> fast_map,
393 : Type value_type)
394 : : fast_map_(fast_map), value_type_(value_type) {}
395 :
396 : bool operator==(TransitionAndStoreNonNumberElementParameters const& lhs,
397 : TransitionAndStoreNonNumberElementParameters const& rhs) {
398 0 : return lhs.fast_map().address() == rhs.fast_map().address() &&
399 : lhs.value_type() == rhs.value_type();
400 : }
401 :
402 0 : size_t hash_value(TransitionAndStoreNonNumberElementParameters parameters) {
403 0 : return base::hash_combine(parameters.fast_map().address(),
404 0 : parameters.value_type());
405 : }
406 :
407 0 : std::ostream& operator<<(
408 : std::ostream& os, TransitionAndStoreNonNumberElementParameters parameters) {
409 0 : return os << parameters.value_type() << ", fast-map"
410 0 : << Brief(*parameters.fast_map());
411 : }
412 :
413 : } // namespace
414 :
415 : namespace {
416 :
417 : // Parameters for the TransitionAndStoreNumberElement opcode.
418 : class TransitionAndStoreNumberElementParameters final {
419 : public:
420 : explicit TransitionAndStoreNumberElementParameters(Handle<Map> double_map);
421 :
422 28 : Handle<Map> double_map() const { return double_map_; }
423 :
424 : private:
425 : Handle<Map> const double_map_;
426 : };
427 :
428 : TransitionAndStoreNumberElementParameters::
429 : TransitionAndStoreNumberElementParameters(Handle<Map> double_map)
430 : : double_map_(double_map) {}
431 :
432 : bool operator==(TransitionAndStoreNumberElementParameters const& lhs,
433 : TransitionAndStoreNumberElementParameters const& rhs) {
434 0 : return lhs.double_map().address() == rhs.double_map().address();
435 : }
436 :
437 : size_t hash_value(TransitionAndStoreNumberElementParameters parameters) {
438 0 : return base::hash_combine(parameters.double_map().address());
439 : }
440 :
441 0 : std::ostream& operator<<(std::ostream& os,
442 : TransitionAndStoreNumberElementParameters parameters) {
443 0 : return os << "double-map" << Brief(*parameters.double_map());
444 : }
445 :
446 : } // namespace
447 :
448 688 : Handle<Map> DoubleMapParameterOf(const Operator* op) {
449 688 : if (op->opcode() == IrOpcode::kTransitionAndStoreElement) {
450 : return OpParameter<TransitionAndStoreElementParameters>(op).double_map();
451 28 : } else if (op->opcode() == IrOpcode::kTransitionAndStoreNumberElement) {
452 : return OpParameter<TransitionAndStoreNumberElementParameters>(op)
453 : .double_map();
454 : }
455 0 : UNREACHABLE();
456 : return Handle<Map>::null();
457 : }
458 :
459 20 : Type ValueTypeParameterOf(const Operator* op) {
460 : DCHECK_EQ(IrOpcode::kTransitionAndStoreNonNumberElement, op->opcode());
461 : return OpParameter<TransitionAndStoreNonNumberElementParameters>(op)
462 20 : .value_type();
463 : }
464 :
465 778 : Handle<Map> FastMapParameterOf(const Operator* op) {
466 778 : if (op->opcode() == IrOpcode::kTransitionAndStoreElement) {
467 : return OpParameter<TransitionAndStoreElementParameters>(op).fast_map();
468 40 : } else if (op->opcode() == IrOpcode::kTransitionAndStoreNonNumberElement) {
469 : return OpParameter<TransitionAndStoreNonNumberElementParameters>(op)
470 : .fast_map();
471 : }
472 0 : UNREACHABLE();
473 : return Handle<Map>::null();
474 : }
475 :
476 234 : std::ostream& operator<<(std::ostream& os, NumberOperationHint hint) {
477 234 : switch (hint) {
478 : case NumberOperationHint::kSignedSmall:
479 66 : return os << "SignedSmall";
480 : case NumberOperationHint::kSignedSmallInputs:
481 42 : return os << "SignedSmallInputs";
482 : case NumberOperationHint::kSigned32:
483 42 : return os << "Signed32";
484 : case NumberOperationHint::kNumber:
485 42 : return os << "Number";
486 : case NumberOperationHint::kNumberOrOddball:
487 42 : return os << "NumberOrOddball";
488 : }
489 0 : UNREACHABLE();
490 : }
491 :
492 0 : size_t hash_value(NumberOperationHint hint) {
493 0 : return static_cast<uint8_t>(hint);
494 : }
495 :
496 1140469 : NumberOperationHint NumberOperationHintOf(const Operator* op) {
497 : DCHECK(op->opcode() == IrOpcode::kSpeculativeNumberAdd ||
498 : op->opcode() == IrOpcode::kSpeculativeNumberSubtract ||
499 : op->opcode() == IrOpcode::kSpeculativeNumberMultiply ||
500 : op->opcode() == IrOpcode::kSpeculativeNumberDivide ||
501 : op->opcode() == IrOpcode::kSpeculativeNumberModulus ||
502 : op->opcode() == IrOpcode::kSpeculativeNumberShiftLeft ||
503 : op->opcode() == IrOpcode::kSpeculativeNumberShiftRight ||
504 : op->opcode() == IrOpcode::kSpeculativeNumberShiftRightLogical ||
505 : op->opcode() == IrOpcode::kSpeculativeNumberBitwiseAnd ||
506 : op->opcode() == IrOpcode::kSpeculativeNumberBitwiseOr ||
507 : op->opcode() == IrOpcode::kSpeculativeNumberBitwiseXor ||
508 : op->opcode() == IrOpcode::kSpeculativeNumberEqual ||
509 : op->opcode() == IrOpcode::kSpeculativeNumberLessThan ||
510 : op->opcode() == IrOpcode::kSpeculativeNumberLessThanOrEqual ||
511 : op->opcode() == IrOpcode::kSpeculativeSafeIntegerAdd ||
512 : op->opcode() == IrOpcode::kSpeculativeSafeIntegerSubtract);
513 1140469 : return OpParameter<NumberOperationHint>(op);
514 : }
515 :
516 0 : bool operator==(NumberOperationParameters const& lhs,
517 : NumberOperationParameters const& rhs) {
518 0 : return lhs.hint() == rhs.hint() && lhs.feedback() == rhs.feedback();
519 : }
520 :
521 0 : size_t hash_value(NumberOperationParameters const& p) {
522 0 : return base::hash_combine(p.hint(), p.feedback());
523 : }
524 :
525 0 : std::ostream& operator<<(std::ostream& os, NumberOperationParameters const& p) {
526 0 : return os << p.hint() << " " << p.feedback();
527 : }
528 :
529 133199 : NumberOperationParameters const& NumberOperationParametersOf(
530 : Operator const* op) {
531 : DCHECK_EQ(IrOpcode::kSpeculativeToNumber, op->opcode());
532 133199 : return OpParameter<NumberOperationParameters>(op);
533 : }
534 :
535 0 : size_t hash_value(AllocateParameters info) {
536 : return base::hash_combine(info.type(),
537 0 : static_cast<int>(info.allocation_type()));
538 : }
539 :
540 0 : V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
541 : AllocateParameters info) {
542 0 : return os << info.type() << ", " << info.allocation_type();
543 : }
544 :
545 0 : bool operator==(AllocateParameters const& lhs, AllocateParameters const& rhs) {
546 0 : return lhs.allocation_type() == rhs.allocation_type() &&
547 0 : lhs.type() == rhs.type();
548 : }
549 :
550 393905 : AllocationType AllocationTypeOf(const Operator* op) {
551 393905 : if (op->opcode() == IrOpcode::kNewDoubleElements ||
552 : op->opcode() == IrOpcode::kNewSmiOrObjectElements) {
553 492 : return OpParameter<AllocationType>(op);
554 : }
555 : DCHECK(op->opcode() == IrOpcode::kAllocate ||
556 : op->opcode() == IrOpcode::kAllocateRaw);
557 393413 : return OpParameter<AllocateParameters>(op).allocation_type();
558 : }
559 :
560 141419 : Type AllocateTypeOf(const Operator* op) {
561 : DCHECK_EQ(IrOpcode::kAllocate, op->opcode());
562 141419 : return OpParameter<AllocateParameters>(op).type();
563 : }
564 :
565 430 : UnicodeEncoding UnicodeEncodingOf(const Operator* op) {
566 : DCHECK(op->opcode() == IrOpcode::kStringFromSingleCodePoint ||
567 : op->opcode() == IrOpcode::kStringCodePointAt);
568 430 : return OpParameter<UnicodeEncoding>(op);
569 : }
570 :
571 2557 : AbortReason AbortReasonOf(const Operator* op) {
572 : DCHECK_EQ(IrOpcode::kRuntimeAbort, op->opcode());
573 2557 : return static_cast<AbortReason>(OpParameter<int>(op));
574 : }
575 :
576 67861 : const CheckTaggedInputParameters& CheckTaggedInputParametersOf(
577 : const Operator* op) {
578 : DCHECK(op->opcode() == IrOpcode::kCheckedTruncateTaggedToWord32 ||
579 : op->opcode() == IrOpcode::kCheckedTaggedToFloat64);
580 67861 : return OpParameter<CheckTaggedInputParameters>(op);
581 : }
582 :
583 0 : std::ostream& operator<<(std::ostream& os,
584 : const CheckTaggedInputParameters& params) {
585 0 : os << params.mode();
586 0 : if (params.feedback().IsValid()) {
587 0 : os << "; " << params.feedback();
588 : }
589 0 : return os;
590 : }
591 :
592 0 : size_t hash_value(const CheckTaggedInputParameters& params) {
593 0 : return base::hash_combine(params.mode(), params.feedback());
594 : }
595 :
596 0 : bool operator==(CheckTaggedInputParameters const& lhs,
597 : CheckTaggedInputParameters const& rhs) {
598 0 : return lhs.mode() == rhs.mode() && lhs.feedback() == rhs.feedback();
599 : }
600 :
601 4930 : const CheckMinusZeroParameters& CheckMinusZeroParametersOf(const Operator* op) {
602 : DCHECK(op->opcode() == IrOpcode::kCheckedTaggedToInt32 ||
603 : op->opcode() == IrOpcode::kCheckedTaggedToInt64 ||
604 : op->opcode() == IrOpcode::kCheckedFloat64ToInt32 ||
605 : op->opcode() == IrOpcode::kCheckedFloat64ToInt64);
606 4930 : return OpParameter<CheckMinusZeroParameters>(op);
607 : }
608 :
609 0 : std::ostream& operator<<(std::ostream& os,
610 : const CheckMinusZeroParameters& params) {
611 0 : os << params.mode();
612 0 : if (params.feedback().IsValid()) {
613 0 : os << "; " << params.feedback();
614 : }
615 0 : return os;
616 : }
617 :
618 0 : size_t hash_value(const CheckMinusZeroParameters& params) {
619 0 : return base::hash_combine(params.mode(), params.feedback());
620 : }
621 :
622 0 : bool operator==(CheckMinusZeroParameters const& lhs,
623 : CheckMinusZeroParameters const& rhs) {
624 0 : return lhs.mode() == rhs.mode() && lhs.feedback() == rhs.feedback();
625 : }
626 :
627 : #define PURE_OP_LIST(V) \
628 : V(BooleanNot, Operator::kNoProperties, 1, 0) \
629 : V(NumberEqual, Operator::kCommutative, 2, 0) \
630 : V(NumberLessThan, Operator::kNoProperties, 2, 0) \
631 : V(NumberLessThanOrEqual, Operator::kNoProperties, 2, 0) \
632 : V(NumberAdd, Operator::kCommutative, 2, 0) \
633 : V(NumberSubtract, Operator::kNoProperties, 2, 0) \
634 : V(NumberMultiply, Operator::kCommutative, 2, 0) \
635 : V(NumberDivide, Operator::kNoProperties, 2, 0) \
636 : V(NumberModulus, Operator::kNoProperties, 2, 0) \
637 : V(NumberBitwiseOr, Operator::kCommutative, 2, 0) \
638 : V(NumberBitwiseXor, Operator::kCommutative, 2, 0) \
639 : V(NumberBitwiseAnd, Operator::kCommutative, 2, 0) \
640 : V(NumberShiftLeft, Operator::kNoProperties, 2, 0) \
641 : V(NumberShiftRight, Operator::kNoProperties, 2, 0) \
642 : V(NumberShiftRightLogical, Operator::kNoProperties, 2, 0) \
643 : V(NumberImul, Operator::kCommutative, 2, 0) \
644 : V(NumberAbs, Operator::kNoProperties, 1, 0) \
645 : V(NumberClz32, Operator::kNoProperties, 1, 0) \
646 : V(NumberCeil, Operator::kNoProperties, 1, 0) \
647 : V(NumberFloor, Operator::kNoProperties, 1, 0) \
648 : V(NumberFround, Operator::kNoProperties, 1, 0) \
649 : V(NumberAcos, Operator::kNoProperties, 1, 0) \
650 : V(NumberAcosh, Operator::kNoProperties, 1, 0) \
651 : V(NumberAsin, Operator::kNoProperties, 1, 0) \
652 : V(NumberAsinh, Operator::kNoProperties, 1, 0) \
653 : V(NumberAtan, Operator::kNoProperties, 1, 0) \
654 : V(NumberAtan2, Operator::kNoProperties, 2, 0) \
655 : V(NumberAtanh, Operator::kNoProperties, 1, 0) \
656 : V(NumberCbrt, Operator::kNoProperties, 1, 0) \
657 : V(NumberCos, Operator::kNoProperties, 1, 0) \
658 : V(NumberCosh, Operator::kNoProperties, 1, 0) \
659 : V(NumberExp, Operator::kNoProperties, 1, 0) \
660 : V(NumberExpm1, Operator::kNoProperties, 1, 0) \
661 : V(NumberLog, Operator::kNoProperties, 1, 0) \
662 : V(NumberLog1p, Operator::kNoProperties, 1, 0) \
663 : V(NumberLog10, Operator::kNoProperties, 1, 0) \
664 : V(NumberLog2, Operator::kNoProperties, 1, 0) \
665 : V(NumberMax, Operator::kNoProperties, 2, 0) \
666 : V(NumberMin, Operator::kNoProperties, 2, 0) \
667 : V(NumberPow, Operator::kNoProperties, 2, 0) \
668 : V(NumberRound, Operator::kNoProperties, 1, 0) \
669 : V(NumberSign, Operator::kNoProperties, 1, 0) \
670 : V(NumberSin, Operator::kNoProperties, 1, 0) \
671 : V(NumberSinh, Operator::kNoProperties, 1, 0) \
672 : V(NumberSqrt, Operator::kNoProperties, 1, 0) \
673 : V(NumberTan, Operator::kNoProperties, 1, 0) \
674 : V(NumberTanh, Operator::kNoProperties, 1, 0) \
675 : V(NumberTrunc, Operator::kNoProperties, 1, 0) \
676 : V(NumberToBoolean, Operator::kNoProperties, 1, 0) \
677 : V(NumberToInt32, Operator::kNoProperties, 1, 0) \
678 : V(NumberToString, Operator::kNoProperties, 1, 0) \
679 : V(NumberToUint32, Operator::kNoProperties, 1, 0) \
680 : V(NumberToUint8Clamped, Operator::kNoProperties, 1, 0) \
681 : V(NumberSilenceNaN, Operator::kNoProperties, 1, 0) \
682 : V(StringConcat, Operator::kNoProperties, 3, 0) \
683 : V(StringToNumber, Operator::kNoProperties, 1, 0) \
684 : V(StringFromSingleCharCode, Operator::kNoProperties, 1, 0) \
685 : V(StringIndexOf, Operator::kNoProperties, 3, 0) \
686 : V(StringLength, Operator::kNoProperties, 1, 0) \
687 : V(StringToLowerCaseIntl, Operator::kNoProperties, 1, 0) \
688 : V(StringToUpperCaseIntl, Operator::kNoProperties, 1, 0) \
689 : V(TypeOf, Operator::kNoProperties, 1, 1) \
690 : V(PlainPrimitiveToNumber, Operator::kNoProperties, 1, 0) \
691 : V(PlainPrimitiveToWord32, Operator::kNoProperties, 1, 0) \
692 : V(PlainPrimitiveToFloat64, Operator::kNoProperties, 1, 0) \
693 : V(ChangeTaggedSignedToInt32, Operator::kNoProperties, 1, 0) \
694 : V(ChangeTaggedSignedToInt64, Operator::kNoProperties, 1, 0) \
695 : V(ChangeTaggedToInt32, Operator::kNoProperties, 1, 0) \
696 : V(ChangeTaggedToInt64, Operator::kNoProperties, 1, 0) \
697 : V(ChangeTaggedToUint32, Operator::kNoProperties, 1, 0) \
698 : V(ChangeTaggedToFloat64, Operator::kNoProperties, 1, 0) \
699 : V(ChangeTaggedToTaggedSigned, Operator::kNoProperties, 1, 0) \
700 : V(ChangeCompressedToTaggedSigned, Operator::kNoProperties, 1, 0) \
701 : V(ChangeTaggedToCompressedSigned, Operator::kNoProperties, 1, 0) \
702 : V(ChangeFloat64ToTaggedPointer, Operator::kNoProperties, 1, 0) \
703 : V(ChangeInt31ToTaggedSigned, Operator::kNoProperties, 1, 0) \
704 : V(ChangeInt32ToTagged, Operator::kNoProperties, 1, 0) \
705 : V(ChangeInt64ToTagged, Operator::kNoProperties, 1, 0) \
706 : V(ChangeUint32ToTagged, Operator::kNoProperties, 1, 0) \
707 : V(ChangeUint64ToTagged, Operator::kNoProperties, 1, 0) \
708 : V(ChangeTaggedToBit, Operator::kNoProperties, 1, 0) \
709 : V(ChangeBitToTagged, Operator::kNoProperties, 1, 0) \
710 : V(TruncateTaggedToBit, Operator::kNoProperties, 1, 0) \
711 : V(TruncateTaggedPointerToBit, Operator::kNoProperties, 1, 0) \
712 : V(TruncateTaggedToWord32, Operator::kNoProperties, 1, 0) \
713 : V(TruncateTaggedToFloat64, Operator::kNoProperties, 1, 0) \
714 : V(ObjectIsArrayBufferView, Operator::kNoProperties, 1, 0) \
715 : V(ObjectIsBigInt, Operator::kNoProperties, 1, 0) \
716 : V(ObjectIsCallable, Operator::kNoProperties, 1, 0) \
717 : V(ObjectIsConstructor, Operator::kNoProperties, 1, 0) \
718 : V(ObjectIsDetectableCallable, Operator::kNoProperties, 1, 0) \
719 : V(ObjectIsMinusZero, Operator::kNoProperties, 1, 0) \
720 : V(NumberIsMinusZero, Operator::kNoProperties, 1, 0) \
721 : V(ObjectIsNaN, Operator::kNoProperties, 1, 0) \
722 : V(NumberIsNaN, Operator::kNoProperties, 1, 0) \
723 : V(ObjectIsNonCallable, Operator::kNoProperties, 1, 0) \
724 : V(ObjectIsNumber, Operator::kNoProperties, 1, 0) \
725 : V(ObjectIsReceiver, Operator::kNoProperties, 1, 0) \
726 : V(ObjectIsSmi, Operator::kNoProperties, 1, 0) \
727 : V(ObjectIsString, Operator::kNoProperties, 1, 0) \
728 : V(ObjectIsSymbol, Operator::kNoProperties, 1, 0) \
729 : V(ObjectIsUndetectable, Operator::kNoProperties, 1, 0) \
730 : V(NumberIsFloat64Hole, Operator::kNoProperties, 1, 0) \
731 : V(NumberIsFinite, Operator::kNoProperties, 1, 0) \
732 : V(ObjectIsFiniteNumber, Operator::kNoProperties, 1, 0) \
733 : V(NumberIsInteger, Operator::kNoProperties, 1, 0) \
734 : V(ObjectIsSafeInteger, Operator::kNoProperties, 1, 0) \
735 : V(NumberIsSafeInteger, Operator::kNoProperties, 1, 0) \
736 : V(ObjectIsInteger, Operator::kNoProperties, 1, 0) \
737 : V(ConvertTaggedHoleToUndefined, Operator::kNoProperties, 1, 0) \
738 : V(SameValue, Operator::kCommutative, 2, 0) \
739 : V(NumberSameValue, Operator::kCommutative, 2, 0) \
740 : V(ReferenceEqual, Operator::kCommutative, 2, 0) \
741 : V(StringEqual, Operator::kCommutative, 2, 0) \
742 : V(StringLessThan, Operator::kNoProperties, 2, 0) \
743 : V(StringLessThanOrEqual, Operator::kNoProperties, 2, 0) \
744 : V(ToBoolean, Operator::kNoProperties, 1, 0) \
745 : V(NewConsOneByteString, Operator::kNoProperties, 3, 0) \
746 : V(NewConsTwoByteString, Operator::kNoProperties, 3, 0) \
747 : V(NewConsString, Operator::kNoProperties, 3, 0) \
748 : V(PoisonIndex, Operator::kNoProperties, 1, 0)
749 :
750 : #define EFFECT_DEPENDENT_OP_LIST(V) \
751 : V(StringCharCodeAt, Operator::kNoProperties, 2, 1) \
752 : V(StringSubstring, Operator::kNoProperties, 3, 1) \
753 : V(DateNow, Operator::kNoProperties, 0, 1)
754 :
755 : #define SPECULATIVE_NUMBER_BINOP_LIST(V) \
756 : SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(V) \
757 : V(SpeculativeNumberEqual) \
758 : V(SpeculativeNumberLessThan) \
759 : V(SpeculativeNumberLessThanOrEqual)
760 :
761 : #define CHECKED_OP_LIST(V) \
762 : V(CheckEqualsInternalizedString, 2, 0) \
763 : V(CheckEqualsSymbol, 2, 0) \
764 : V(CheckHeapObject, 1, 1) \
765 : V(CheckNonEmptyString, 1, 1) \
766 : V(CheckNonEmptyOneByteString, 1, 1) \
767 : V(CheckNonEmptyTwoByteString, 1, 1) \
768 : V(CheckInternalizedString, 1, 1) \
769 : V(CheckNotTaggedHole, 1, 1) \
770 : V(CheckReceiver, 1, 1) \
771 : V(CheckReceiverOrNullOrUndefined, 1, 1) \
772 : V(CheckSymbol, 1, 1) \
773 : V(CheckedInt32Add, 2, 1) \
774 : V(CheckedInt32Div, 2, 1) \
775 : V(CheckedInt32Mod, 2, 1) \
776 : V(CheckedInt32Sub, 2, 1) \
777 : V(CheckedUint32Div, 2, 1) \
778 : V(CheckedUint32Mod, 2, 1)
779 :
780 : #define CHECKED_WITH_FEEDBACK_OP_LIST(V) \
781 : V(CheckBounds, 2, 1) \
782 : V(CheckNumber, 1, 1) \
783 : V(CheckSmi, 1, 1) \
784 : V(CheckString, 1, 1) \
785 : V(CheckedInt32ToTaggedSigned, 1, 1) \
786 : V(CheckedInt64ToInt32, 1, 1) \
787 : V(CheckedInt64ToTaggedSigned, 1, 1) \
788 : V(CheckedTaggedSignedToInt32, 1, 1) \
789 : V(CheckedTaggedToTaggedPointer, 1, 1) \
790 : V(CheckedTaggedToTaggedSigned, 1, 1) \
791 : V(CheckedCompressedToTaggedPointer, 1, 1) \
792 : V(CheckedCompressedToTaggedSigned, 1, 1) \
793 : V(CheckedTaggedToCompressedPointer, 1, 1) \
794 : V(CheckedTaggedToCompressedSigned, 1, 1) \
795 : V(CheckedUint32ToInt32, 1, 1) \
796 : V(CheckedUint32ToTaggedSigned, 1, 1) \
797 : V(CheckedUint64Bounds, 2, 1) \
798 : V(CheckedUint64ToInt32, 1, 1) \
799 : V(CheckedUint64ToTaggedSigned, 1, 1)
800 :
801 : #define CHECKED_BOUNDS_OP_LIST(V) V(CheckedUint32Bounds)
802 :
803 28913 : struct SimplifiedOperatorGlobalCache final {
804 : #define PURE(Name, properties, value_input_count, control_input_count) \
805 : struct Name##Operator final : public Operator { \
806 : Name##Operator() \
807 : : Operator(IrOpcode::k##Name, Operator::kPure | properties, #Name, \
808 : value_input_count, 0, control_input_count, 1, 0, 0) {} \
809 : }; \
810 : Name##Operator k##Name;
811 3498473 : PURE_OP_LIST(PURE)
812 : #undef PURE
813 :
814 : #define EFFECT_DEPENDENT(Name, properties, value_input_count, \
815 : control_input_count) \
816 : struct Name##Operator final : public Operator { \
817 : Name##Operator() \
818 : : Operator(IrOpcode::k##Name, \
819 : Operator::kNoDeopt | Operator::kNoWrite | \
820 : Operator::kNoThrow | properties, \
821 : #Name, value_input_count, 1, control_input_count, 1, 1, \
822 : 0) {} \
823 : }; \
824 : Name##Operator k##Name;
825 86739 : EFFECT_DEPENDENT_OP_LIST(EFFECT_DEPENDENT)
826 : #undef EFFECT_DEPENDENT
827 :
828 : #define CHECKED(Name, value_input_count, value_output_count) \
829 : struct Name##Operator final : public Operator { \
830 : Name##Operator() \
831 : : Operator(IrOpcode::k##Name, \
832 : Operator::kFoldable | Operator::kNoThrow, #Name, \
833 : value_input_count, 1, 1, value_output_count, 1, 0) {} \
834 : }; \
835 : Name##Operator k##Name;
836 491521 : CHECKED_OP_LIST(CHECKED)
837 : #undef CHECKED
838 :
839 : #define CHECKED_WITH_FEEDBACK(Name, value_input_count, value_output_count) \
840 : struct Name##Operator final : public Operator1<CheckParameters> { \
841 : Name##Operator() \
842 : : Operator1<CheckParameters>( \
843 : IrOpcode::k##Name, Operator::kFoldable | Operator::kNoThrow, \
844 : #Name, value_input_count, 1, 1, value_output_count, 1, 0, \
845 : CheckParameters(VectorSlotPair())) {} \
846 : }; \
847 : Name##Operator k##Name;
848 1098694 : CHECKED_WITH_FEEDBACK_OP_LIST(CHECKED_WITH_FEEDBACK)
849 : #undef CHECKED_WITH_FEEDBACK
850 :
851 : #define CHECKED_BOUNDS(Name) \
852 : struct Name##Operator final : public Operator1<CheckBoundsParameters> { \
853 : Name##Operator(VectorSlotPair feedback, CheckBoundsParameters::Mode mode) \
854 : : Operator1<CheckBoundsParameters>( \
855 : IrOpcode::k##Name, Operator::kFoldable | Operator::kNoThrow, \
856 : #Name, 2, 1, 1, 1, 1, 0, \
857 : CheckBoundsParameters(feedback, mode)) {} \
858 : }; \
859 : Name##Operator k##Name##Deopting = { \
860 : VectorSlotPair(), CheckBoundsParameters::kDeoptOnOutOfBounds}; \
861 : Name##Operator k##Name##Aborting = { \
862 : VectorSlotPair(), CheckBoundsParameters::kAbortOnOutOfBounds};
863 124564 : CHECKED_BOUNDS_OP_LIST(CHECKED_BOUNDS)
864 : #undef CHECKED_BOUNDS
865 :
866 : template <DeoptimizeReason kDeoptimizeReason>
867 0 : struct CheckIfOperator final : public Operator1<CheckIfParameters> {
868 1185433 : CheckIfOperator()
869 : : Operator1<CheckIfParameters>(
870 : IrOpcode::kCheckIf, Operator::kFoldable | Operator::kNoThrow,
871 : "CheckIf", 1, 1, 1, 0, 1, 0,
872 2370866 : CheckIfParameters(kDeoptimizeReason, VectorSlotPair())) {}
873 : };
874 : #define CHECK_IF(Name, message) \
875 : CheckIfOperator<DeoptimizeReason::k##Name> kCheckIf##Name;
876 : DEOPTIMIZE_REASON_LIST(CHECK_IF)
877 : #undef CHECK_IF
878 :
879 : template <UnicodeEncoding kEncoding>
880 0 : struct StringCodePointAtOperator final : public Operator1<UnicodeEncoding> {
881 57826 : StringCodePointAtOperator()
882 : : Operator1<UnicodeEncoding>(IrOpcode::kStringCodePointAt,
883 : Operator::kFoldable | Operator::kNoThrow,
884 : "StringCodePointAt", 2, 1, 1, 1, 1, 0,
885 57826 : kEncoding) {}
886 : };
887 : StringCodePointAtOperator<UnicodeEncoding::UTF16>
888 : kStringCodePointAtOperatorUTF16;
889 : StringCodePointAtOperator<UnicodeEncoding::UTF32>
890 : kStringCodePointAtOperatorUTF32;
891 :
892 : template <UnicodeEncoding kEncoding>
893 0 : struct StringFromSingleCodePointOperator final
894 : : public Operator1<UnicodeEncoding> {
895 57826 : StringFromSingleCodePointOperator()
896 : : Operator1<UnicodeEncoding>(
897 : IrOpcode::kStringFromSingleCodePoint, Operator::kPure,
898 57826 : "StringFromSingleCodePoint", 1, 0, 0, 1, 0, 0, kEncoding) {}
899 : };
900 : StringFromSingleCodePointOperator<UnicodeEncoding::UTF16>
901 : kStringFromSingleCodePointOperatorUTF16;
902 : StringFromSingleCodePointOperator<UnicodeEncoding::UTF32>
903 : kStringFromSingleCodePointOperatorUTF32;
904 :
905 0 : struct FindOrderedHashMapEntryOperator final : public Operator {
906 28913 : FindOrderedHashMapEntryOperator()
907 : : Operator(IrOpcode::kFindOrderedHashMapEntry, Operator::kEliminatable,
908 28913 : "FindOrderedHashMapEntry", 2, 1, 1, 1, 1, 0) {}
909 : };
910 : FindOrderedHashMapEntryOperator kFindOrderedHashMapEntry;
911 :
912 0 : struct FindOrderedHashMapEntryForInt32KeyOperator final : public Operator {
913 28913 : FindOrderedHashMapEntryForInt32KeyOperator()
914 : : Operator(IrOpcode::kFindOrderedHashMapEntryForInt32Key,
915 : Operator::kEliminatable,
916 28913 : "FindOrderedHashMapEntryForInt32Key", 2, 1, 1, 1, 1, 0) {}
917 : };
918 : FindOrderedHashMapEntryForInt32KeyOperator
919 : kFindOrderedHashMapEntryForInt32Key;
920 :
921 0 : struct ArgumentsFrameOperator final : public Operator {
922 28913 : ArgumentsFrameOperator()
923 : : Operator(IrOpcode::kArgumentsFrame, Operator::kPure, "ArgumentsFrame",
924 28913 : 0, 0, 0, 1, 0, 0) {}
925 : };
926 : ArgumentsFrameOperator kArgumentsFrame;
927 :
928 : template <CheckForMinusZeroMode kMode>
929 0 : struct ChangeFloat64ToTaggedOperator final
930 : : public Operator1<CheckForMinusZeroMode> {
931 57826 : ChangeFloat64ToTaggedOperator()
932 : : Operator1<CheckForMinusZeroMode>(
933 : IrOpcode::kChangeFloat64ToTagged, Operator::kPure,
934 57826 : "ChangeFloat64ToTagged", 1, 0, 0, 1, 0, 0, kMode) {}
935 : };
936 : ChangeFloat64ToTaggedOperator<CheckForMinusZeroMode::kCheckForMinusZero>
937 : kChangeFloat64ToTaggedCheckForMinusZeroOperator;
938 : ChangeFloat64ToTaggedOperator<CheckForMinusZeroMode::kDontCheckForMinusZero>
939 : kChangeFloat64ToTaggedDontCheckForMinusZeroOperator;
940 :
941 : template <CheckForMinusZeroMode kMode>
942 0 : struct CheckedInt32MulOperator final
943 : : public Operator1<CheckForMinusZeroMode> {
944 57826 : CheckedInt32MulOperator()
945 : : Operator1<CheckForMinusZeroMode>(
946 : IrOpcode::kCheckedInt32Mul,
947 : Operator::kFoldable | Operator::kNoThrow, "CheckedInt32Mul", 2, 1,
948 57826 : 1, 1, 1, 0, kMode) {}
949 : };
950 : CheckedInt32MulOperator<CheckForMinusZeroMode::kCheckForMinusZero>
951 : kCheckedInt32MulCheckForMinusZeroOperator;
952 : CheckedInt32MulOperator<CheckForMinusZeroMode::kDontCheckForMinusZero>
953 : kCheckedInt32MulDontCheckForMinusZeroOperator;
954 :
955 : template <CheckForMinusZeroMode kMode>
956 0 : struct CheckedFloat64ToInt32Operator final
957 : : public Operator1<CheckMinusZeroParameters> {
958 57826 : CheckedFloat64ToInt32Operator()
959 : : Operator1<CheckMinusZeroParameters>(
960 : IrOpcode::kCheckedFloat64ToInt32,
961 : Operator::kFoldable | Operator::kNoThrow, "CheckedFloat64ToInt32",
962 : 1, 1, 1, 1, 1, 0,
963 115652 : CheckMinusZeroParameters(kMode, VectorSlotPair())) {}
964 : };
965 : CheckedFloat64ToInt32Operator<CheckForMinusZeroMode::kCheckForMinusZero>
966 : kCheckedFloat64ToInt32CheckForMinusZeroOperator;
967 : CheckedFloat64ToInt32Operator<CheckForMinusZeroMode::kDontCheckForMinusZero>
968 : kCheckedFloat64ToInt32DontCheckForMinusZeroOperator;
969 :
970 : template <CheckForMinusZeroMode kMode>
971 0 : struct CheckedFloat64ToInt64Operator final
972 : : public Operator1<CheckMinusZeroParameters> {
973 57826 : CheckedFloat64ToInt64Operator()
974 : : Operator1<CheckMinusZeroParameters>(
975 : IrOpcode::kCheckedFloat64ToInt64,
976 : Operator::kFoldable | Operator::kNoThrow, "CheckedFloat64ToInt64",
977 : 1, 1, 1, 1, 1, 0,
978 115652 : CheckMinusZeroParameters(kMode, VectorSlotPair())) {}
979 : };
980 : CheckedFloat64ToInt64Operator<CheckForMinusZeroMode::kCheckForMinusZero>
981 : kCheckedFloat64ToInt64CheckForMinusZeroOperator;
982 : CheckedFloat64ToInt64Operator<CheckForMinusZeroMode::kDontCheckForMinusZero>
983 : kCheckedFloat64ToInt64DontCheckForMinusZeroOperator;
984 :
985 : template <CheckForMinusZeroMode kMode>
986 0 : struct CheckedTaggedToInt32Operator final
987 : : public Operator1<CheckMinusZeroParameters> {
988 57826 : CheckedTaggedToInt32Operator()
989 : : Operator1<CheckMinusZeroParameters>(
990 : IrOpcode::kCheckedTaggedToInt32,
991 : Operator::kFoldable | Operator::kNoThrow, "CheckedTaggedToInt32",
992 : 1, 1, 1, 1, 1, 0,
993 115652 : CheckMinusZeroParameters(kMode, VectorSlotPair())) {}
994 : };
995 : CheckedTaggedToInt32Operator<CheckForMinusZeroMode::kCheckForMinusZero>
996 : kCheckedTaggedToInt32CheckForMinusZeroOperator;
997 : CheckedTaggedToInt32Operator<CheckForMinusZeroMode::kDontCheckForMinusZero>
998 : kCheckedTaggedToInt32DontCheckForMinusZeroOperator;
999 :
1000 : template <CheckForMinusZeroMode kMode>
1001 0 : struct CheckedTaggedToInt64Operator final
1002 : : public Operator1<CheckMinusZeroParameters> {
1003 57826 : CheckedTaggedToInt64Operator()
1004 : : Operator1<CheckMinusZeroParameters>(
1005 : IrOpcode::kCheckedTaggedToInt64,
1006 : Operator::kFoldable | Operator::kNoThrow, "CheckedTaggedToInt64",
1007 : 1, 1, 1, 1, 1, 0,
1008 115652 : CheckMinusZeroParameters(kMode, VectorSlotPair())) {}
1009 : };
1010 : CheckedTaggedToInt64Operator<CheckForMinusZeroMode::kCheckForMinusZero>
1011 : kCheckedTaggedToInt64CheckForMinusZeroOperator;
1012 : CheckedTaggedToInt64Operator<CheckForMinusZeroMode::kDontCheckForMinusZero>
1013 : kCheckedTaggedToInt64DontCheckForMinusZeroOperator;
1014 :
1015 : template <CheckTaggedInputMode kMode>
1016 0 : struct CheckedTaggedToFloat64Operator final
1017 : : public Operator1<CheckTaggedInputParameters> {
1018 57826 : CheckedTaggedToFloat64Operator()
1019 : : Operator1<CheckTaggedInputParameters>(
1020 : IrOpcode::kCheckedTaggedToFloat64,
1021 : Operator::kFoldable | Operator::kNoThrow,
1022 : "CheckedTaggedToFloat64", 1, 1, 1, 1, 1, 0,
1023 115652 : CheckTaggedInputParameters(kMode, VectorSlotPair())) {}
1024 : };
1025 : CheckedTaggedToFloat64Operator<CheckTaggedInputMode::kNumber>
1026 : kCheckedTaggedToFloat64NumberOperator;
1027 : CheckedTaggedToFloat64Operator<CheckTaggedInputMode::kNumberOrOddball>
1028 : kCheckedTaggedToFloat64NumberOrOddballOperator;
1029 :
1030 : template <CheckTaggedInputMode kMode>
1031 0 : struct CheckedTruncateTaggedToWord32Operator final
1032 : : public Operator1<CheckTaggedInputParameters> {
1033 57826 : CheckedTruncateTaggedToWord32Operator()
1034 : : Operator1<CheckTaggedInputParameters>(
1035 : IrOpcode::kCheckedTruncateTaggedToWord32,
1036 : Operator::kFoldable | Operator::kNoThrow,
1037 : "CheckedTruncateTaggedToWord32", 1, 1, 1, 1, 1, 0,
1038 115652 : CheckTaggedInputParameters(kMode, VectorSlotPair())) {}
1039 : };
1040 : CheckedTruncateTaggedToWord32Operator<CheckTaggedInputMode::kNumber>
1041 : kCheckedTruncateTaggedToWord32NumberOperator;
1042 : CheckedTruncateTaggedToWord32Operator<CheckTaggedInputMode::kNumberOrOddball>
1043 : kCheckedTruncateTaggedToWord32NumberOrOddballOperator;
1044 :
1045 : template <ConvertReceiverMode kMode>
1046 0 : struct ConvertReceiverOperator final : public Operator1<ConvertReceiverMode> {
1047 86739 : ConvertReceiverOperator()
1048 : : Operator1<ConvertReceiverMode>( // --
1049 : IrOpcode::kConvertReceiver, // opcode
1050 : Operator::kEliminatable, // flags
1051 : "ConvertReceiver", // name
1052 : 2, 1, 1, 1, 1, 0, // counts
1053 86739 : kMode) {} // param
1054 : };
1055 : ConvertReceiverOperator<ConvertReceiverMode::kAny>
1056 : kConvertReceiverAnyOperator;
1057 : ConvertReceiverOperator<ConvertReceiverMode::kNullOrUndefined>
1058 : kConvertReceiverNullOrUndefinedOperator;
1059 : ConvertReceiverOperator<ConvertReceiverMode::kNotNullOrUndefined>
1060 : kConvertReceiverNotNullOrUndefinedOperator;
1061 :
1062 : template <CheckFloat64HoleMode kMode>
1063 0 : struct CheckFloat64HoleNaNOperator final
1064 : : public Operator1<CheckFloat64HoleParameters> {
1065 57826 : CheckFloat64HoleNaNOperator()
1066 : : Operator1<CheckFloat64HoleParameters>(
1067 : IrOpcode::kCheckFloat64Hole,
1068 : Operator::kFoldable | Operator::kNoThrow, "CheckFloat64Hole", 1,
1069 : 1, 1, 1, 1, 0,
1070 115652 : CheckFloat64HoleParameters(kMode, VectorSlotPair())) {}
1071 : };
1072 : CheckFloat64HoleNaNOperator<CheckFloat64HoleMode::kAllowReturnHole>
1073 : kCheckFloat64HoleAllowReturnHoleOperator;
1074 : CheckFloat64HoleNaNOperator<CheckFloat64HoleMode::kNeverReturnHole>
1075 : kCheckFloat64HoleNeverReturnHoleOperator;
1076 :
1077 0 : struct EnsureWritableFastElementsOperator final : public Operator {
1078 28913 : EnsureWritableFastElementsOperator()
1079 : : Operator( // --
1080 : IrOpcode::kEnsureWritableFastElements, // opcode
1081 : Operator::kNoDeopt | Operator::kNoThrow, // flags
1082 : "EnsureWritableFastElements", // name
1083 28913 : 2, 1, 1, 1, 1, 0) {} // counts
1084 : };
1085 : EnsureWritableFastElementsOperator kEnsureWritableFastElements;
1086 :
1087 : template <GrowFastElementsMode kMode>
1088 0 : struct GrowFastElementsOperator final
1089 : : public Operator1<GrowFastElementsParameters> {
1090 57826 : GrowFastElementsOperator()
1091 : : Operator1(IrOpcode::kMaybeGrowFastElements, Operator::kNoThrow,
1092 : "MaybeGrowFastElements", 4, 1, 1, 1, 1, 0,
1093 115652 : GrowFastElementsParameters(kMode, VectorSlotPair())) {}
1094 : };
1095 :
1096 : GrowFastElementsOperator<GrowFastElementsMode::kDoubleElements>
1097 : kGrowFastElementsOperatorDoubleElements;
1098 : GrowFastElementsOperator<GrowFastElementsMode::kSmiOrObjectElements>
1099 : kGrowFastElementsOperatorSmiOrObjectElements;
1100 :
1101 0 : struct LoadFieldByIndexOperator final : public Operator {
1102 28913 : LoadFieldByIndexOperator()
1103 : : Operator( // --
1104 : IrOpcode::kLoadFieldByIndex, // opcode
1105 : Operator::kEliminatable, // flags,
1106 : "LoadFieldByIndex", // name
1107 28913 : 2, 1, 1, 1, 1, 0) {} // counts;
1108 : };
1109 : LoadFieldByIndexOperator kLoadFieldByIndex;
1110 :
1111 0 : struct LoadStackArgumentOperator final : public Operator {
1112 28913 : LoadStackArgumentOperator()
1113 : : Operator( // --
1114 : IrOpcode::kLoadStackArgument, // opcode
1115 : Operator::kNoDeopt | Operator::kNoThrow |
1116 : Operator::kNoWrite, // flags
1117 : "LoadStackArgument", // name
1118 28913 : 2, 1, 1, 1, 1, 0) {} // counts
1119 : };
1120 : LoadStackArgumentOperator kLoadStackArgument;
1121 :
1122 0 : struct LoadMessageOperator final : public Operator {
1123 28913 : LoadMessageOperator()
1124 : : Operator( // --
1125 : IrOpcode::kLoadMessage, // opcode
1126 : Operator::kNoDeopt | Operator::kNoThrow |
1127 : Operator::kNoWrite, // flags
1128 : "LoadMessage", // name
1129 28913 : 1, 1, 1, 1, 1, 0) {} // counts
1130 : };
1131 : LoadMessageOperator kLoadMessage;
1132 :
1133 0 : struct StoreMessageOperator final : public Operator {
1134 28913 : StoreMessageOperator()
1135 : : Operator( // --
1136 : IrOpcode::kStoreMessage, // opcode
1137 : Operator::kNoDeopt | Operator::kNoThrow |
1138 : Operator::kNoRead, // flags
1139 : "StoreMessage", // name
1140 28913 : 2, 1, 1, 0, 1, 0) {} // counts
1141 : };
1142 : StoreMessageOperator kStoreMessage;
1143 :
1144 : #define SPECULATIVE_NUMBER_BINOP(Name) \
1145 : template <NumberOperationHint kHint> \
1146 : struct Name##Operator final : public Operator1<NumberOperationHint> { \
1147 : Name##Operator() \
1148 : : Operator1<NumberOperationHint>( \
1149 : IrOpcode::k##Name, Operator::kFoldable | Operator::kNoThrow, \
1150 : #Name, 2, 1, 1, 1, 1, 0, kHint) {} \
1151 : }; \
1152 : Name##Operator<NumberOperationHint::kSignedSmall> \
1153 : k##Name##SignedSmallOperator; \
1154 : Name##Operator<NumberOperationHint::kSignedSmallInputs> \
1155 : k##Name##SignedSmallInputsOperator; \
1156 : Name##Operator<NumberOperationHint::kSigned32> k##Name##Signed32Operator; \
1157 : Name##Operator<NumberOperationHint::kNumber> k##Name##NumberOperator; \
1158 : Name##Operator<NumberOperationHint::kNumberOrOddball> \
1159 : k##Name##NumberOrOddballOperator;
1160 4626080 : SPECULATIVE_NUMBER_BINOP_LIST(SPECULATIVE_NUMBER_BINOP)
1161 : #undef SPECULATIVE_NUMBER_BINOP
1162 :
1163 : template <NumberOperationHint kHint>
1164 0 : struct SpeculativeToNumberOperator final
1165 : : public Operator1<NumberOperationParameters> {
1166 115652 : SpeculativeToNumberOperator()
1167 : : Operator1<NumberOperationParameters>(
1168 : IrOpcode::kSpeculativeToNumber,
1169 : Operator::kFoldable | Operator::kNoThrow, "SpeculativeToNumber",
1170 : 1, 1, 1, 1, 1, 0,
1171 231304 : NumberOperationParameters(kHint, VectorSlotPair())) {}
1172 : };
1173 : SpeculativeToNumberOperator<NumberOperationHint::kSignedSmall>
1174 : kSpeculativeToNumberSignedSmallOperator;
1175 : SpeculativeToNumberOperator<NumberOperationHint::kSigned32>
1176 : kSpeculativeToNumberSigned32Operator;
1177 : SpeculativeToNumberOperator<NumberOperationHint::kNumber>
1178 : kSpeculativeToNumberNumberOperator;
1179 : SpeculativeToNumberOperator<NumberOperationHint::kNumberOrOddball>
1180 : kSpeculativeToNumberNumberOrOddballOperator;
1181 : };
1182 :
1183 : namespace {
1184 4164503 : DEFINE_LAZY_LEAKY_OBJECT_GETTER(SimplifiedOperatorGlobalCache,
1185 : GetSimplifiedOperatorGlobalCache)
1186 : }
1187 :
1188 4135590 : SimplifiedOperatorBuilder::SimplifiedOperatorBuilder(Zone* zone)
1189 4135590 : : cache_(*GetSimplifiedOperatorGlobalCache()), zone_(zone) {}
1190 :
1191 : #define GET_FROM_CACHE(Name, ...) \
1192 : const Operator* SimplifiedOperatorBuilder::Name() { return &cache_.k##Name; }
1193 1271339 : PURE_OP_LIST(GET_FROM_CACHE)
1194 4135 : EFFECT_DEPENDENT_OP_LIST(GET_FROM_CACHE)
1195 206409 : CHECKED_OP_LIST(GET_FROM_CACHE)
1196 17729 : GET_FROM_CACHE(ArgumentsFrame)
1197 195 : GET_FROM_CACHE(FindOrderedHashMapEntry)
1198 16 : GET_FROM_CACHE(FindOrderedHashMapEntryForInt32Key)
1199 311 : GET_FROM_CACHE(LoadFieldByIndex)
1200 : #undef GET_FROM_CACHE
1201 :
1202 : #define GET_FROM_CACHE_WITH_FEEDBACK(Name, value_input_count, \
1203 : value_output_count) \
1204 : const Operator* SimplifiedOperatorBuilder::Name( \
1205 : const VectorSlotPair& feedback) { \
1206 : if (!feedback.IsValid()) { \
1207 : return &cache_.k##Name; \
1208 : } \
1209 : return new (zone()) Operator1<CheckParameters>( \
1210 : IrOpcode::k##Name, Operator::kFoldable | Operator::kNoThrow, #Name, \
1211 : value_input_count, 1, 1, value_output_count, 1, 0, \
1212 : CheckParameters(feedback)); \
1213 : }
1214 648906 : CHECKED_WITH_FEEDBACK_OP_LIST(GET_FROM_CACHE_WITH_FEEDBACK)
1215 : #undef GET_FROM_CACHE_WITH_FEEDBACK
1216 :
1217 : #define GET_FROM_CACHE_WITH_FEEDBACK(Name) \
1218 : const Operator* SimplifiedOperatorBuilder::Name( \
1219 : const VectorSlotPair& feedback, CheckBoundsParameters::Mode mode) { \
1220 : if (!feedback.IsValid()) { \
1221 : switch (mode) { \
1222 : case CheckBoundsParameters::kDeoptOnOutOfBounds: \
1223 : return &cache_.k##Name##Deopting; \
1224 : case CheckBoundsParameters::kAbortOnOutOfBounds: \
1225 : return &cache_.k##Name##Aborting; \
1226 : } \
1227 : } \
1228 : return new (zone()) \
1229 : SimplifiedOperatorGlobalCache::Name##Operator(feedback, mode); \
1230 : }
1231 113694 : CHECKED_BOUNDS_OP_LIST(GET_FROM_CACHE_WITH_FEEDBACK)
1232 : #undef GET_FROM_CACHE_WITH_FEEDBACK
1233 :
1234 0 : bool IsCheckedWithFeedback(const Operator* op) {
1235 : #define CASE(Name, ...) case IrOpcode::k##Name:
1236 0 : switch (op->opcode()) {
1237 : CHECKED_WITH_FEEDBACK_OP_LIST(CASE) return true;
1238 : default:
1239 0 : return false;
1240 : }
1241 : #undef CASE
1242 : }
1243 :
1244 2756 : const Operator* SimplifiedOperatorBuilder::RuntimeAbort(AbortReason reason) {
1245 : return new (zone()) Operator1<int>( // --
1246 : IrOpcode::kRuntimeAbort, // opcode
1247 : Operator::kNoThrow | Operator::kNoDeopt, // flags
1248 : "RuntimeAbort", // name
1249 : 0, 1, 1, 0, 1, 0, // counts
1250 5512 : static_cast<int>(reason)); // parameter
1251 : }
1252 :
1253 17978 : const Operator* SimplifiedOperatorBuilder::CheckIf(
1254 : DeoptimizeReason reason, const VectorSlotPair& feedback) {
1255 17978 : if (!feedback.IsValid()) {
1256 17392 : switch (reason) {
1257 : #define CHECK_IF(Name, message) \
1258 : case DeoptimizeReason::k##Name: \
1259 : return &cache_.kCheckIf##Name;
1260 142 : DEOPTIMIZE_REASON_LIST(CHECK_IF)
1261 : #undef CHECK_IF
1262 : }
1263 : }
1264 : return new (zone()) Operator1<CheckIfParameters>(
1265 : IrOpcode::kCheckIf, Operator::kFoldable | Operator::kNoThrow, "CheckIf",
1266 : 1, 1, 1, 0, 1, 0, CheckIfParameters(reason, feedback));
1267 : }
1268 :
1269 71502 : const Operator* SimplifiedOperatorBuilder::ChangeFloat64ToTagged(
1270 : CheckForMinusZeroMode mode) {
1271 71502 : switch (mode) {
1272 : case CheckForMinusZeroMode::kCheckForMinusZero:
1273 41878 : return &cache_.kChangeFloat64ToTaggedCheckForMinusZeroOperator;
1274 : case CheckForMinusZeroMode::kDontCheckForMinusZero:
1275 29624 : return &cache_.kChangeFloat64ToTaggedDontCheckForMinusZeroOperator;
1276 : }
1277 0 : UNREACHABLE();
1278 : }
1279 :
1280 6206 : const Operator* SimplifiedOperatorBuilder::CheckedInt32Mul(
1281 : CheckForMinusZeroMode mode) {
1282 6206 : switch (mode) {
1283 : case CheckForMinusZeroMode::kCheckForMinusZero:
1284 4017 : return &cache_.kCheckedInt32MulCheckForMinusZeroOperator;
1285 : case CheckForMinusZeroMode::kDontCheckForMinusZero:
1286 2189 : return &cache_.kCheckedInt32MulDontCheckForMinusZeroOperator;
1287 : }
1288 0 : UNREACHABLE();
1289 : }
1290 :
1291 2586 : const Operator* SimplifiedOperatorBuilder::CheckedFloat64ToInt32(
1292 : CheckForMinusZeroMode mode, const VectorSlotPair& feedback) {
1293 2586 : if (!feedback.IsValid()) {
1294 2561 : switch (mode) {
1295 : case CheckForMinusZeroMode::kCheckForMinusZero:
1296 2177 : return &cache_.kCheckedFloat64ToInt32CheckForMinusZeroOperator;
1297 : case CheckForMinusZeroMode::kDontCheckForMinusZero:
1298 384 : return &cache_.kCheckedFloat64ToInt32DontCheckForMinusZeroOperator;
1299 : }
1300 : }
1301 : return new (zone()) Operator1<CheckMinusZeroParameters>(
1302 : IrOpcode::kCheckedFloat64ToInt32,
1303 : Operator::kFoldable | Operator::kNoThrow, "CheckedFloat64ToInt32", 1, 1,
1304 : 1, 1, 1, 0, CheckMinusZeroParameters(mode, feedback));
1305 : }
1306 :
1307 62 : const Operator* SimplifiedOperatorBuilder::CheckedFloat64ToInt64(
1308 : CheckForMinusZeroMode mode, const VectorSlotPair& feedback) {
1309 62 : if (!feedback.IsValid()) {
1310 22 : switch (mode) {
1311 : case CheckForMinusZeroMode::kCheckForMinusZero:
1312 6 : return &cache_.kCheckedFloat64ToInt64CheckForMinusZeroOperator;
1313 : case CheckForMinusZeroMode::kDontCheckForMinusZero:
1314 16 : return &cache_.kCheckedFloat64ToInt64DontCheckForMinusZeroOperator;
1315 : }
1316 : }
1317 : return new (zone()) Operator1<CheckMinusZeroParameters>(
1318 : IrOpcode::kCheckedFloat64ToInt64,
1319 : Operator::kFoldable | Operator::kNoThrow, "CheckedFloat64ToInt64", 1, 1,
1320 : 1, 1, 1, 0, CheckMinusZeroParameters(mode, feedback));
1321 : }
1322 :
1323 2574 : const Operator* SimplifiedOperatorBuilder::CheckedTaggedToInt32(
1324 : CheckForMinusZeroMode mode, const VectorSlotPair& feedback) {
1325 2574 : if (!feedback.IsValid()) {
1326 2222 : switch (mode) {
1327 : case CheckForMinusZeroMode::kCheckForMinusZero:
1328 9 : return &cache_.kCheckedTaggedToInt32CheckForMinusZeroOperator;
1329 : case CheckForMinusZeroMode::kDontCheckForMinusZero:
1330 2213 : return &cache_.kCheckedTaggedToInt32DontCheckForMinusZeroOperator;
1331 : }
1332 : }
1333 : return new (zone()) Operator1<CheckMinusZeroParameters>(
1334 : IrOpcode::kCheckedTaggedToInt32, Operator::kFoldable | Operator::kNoThrow,
1335 : "CheckedTaggedToInt32", 1, 1, 1, 1, 1, 0,
1336 : CheckMinusZeroParameters(mode, feedback));
1337 : }
1338 :
1339 133 : const Operator* SimplifiedOperatorBuilder::CheckedTaggedToInt64(
1340 : CheckForMinusZeroMode mode, const VectorSlotPair& feedback) {
1341 133 : if (!feedback.IsValid()) {
1342 22 : switch (mode) {
1343 : case CheckForMinusZeroMode::kCheckForMinusZero:
1344 6 : return &cache_.kCheckedTaggedToInt64CheckForMinusZeroOperator;
1345 : case CheckForMinusZeroMode::kDontCheckForMinusZero:
1346 16 : return &cache_.kCheckedTaggedToInt64DontCheckForMinusZeroOperator;
1347 : }
1348 : }
1349 : return new (zone()) Operator1<CheckMinusZeroParameters>(
1350 : IrOpcode::kCheckedTaggedToInt64, Operator::kFoldable | Operator::kNoThrow,
1351 : "CheckedTaggedToInt64", 1, 1, 1, 1, 1, 0,
1352 : CheckMinusZeroParameters(mode, feedback));
1353 : }
1354 :
1355 54384 : const Operator* SimplifiedOperatorBuilder::CheckedTaggedToFloat64(
1356 : CheckTaggedInputMode mode, const VectorSlotPair& feedback) {
1357 54384 : if (!feedback.IsValid()) {
1358 22504 : switch (mode) {
1359 : case CheckTaggedInputMode::kNumber:
1360 8090 : return &cache_.kCheckedTaggedToFloat64NumberOperator;
1361 : case CheckTaggedInputMode::kNumberOrOddball:
1362 14414 : return &cache_.kCheckedTaggedToFloat64NumberOrOddballOperator;
1363 : }
1364 : }
1365 : return new (zone()) Operator1<CheckTaggedInputParameters>(
1366 : IrOpcode::kCheckedTaggedToFloat64,
1367 : Operator::kFoldable | Operator::kNoThrow, "CheckedTaggedToFloat64", 1, 1,
1368 : 1, 1, 1, 0, CheckTaggedInputParameters(mode, feedback));
1369 : }
1370 :
1371 1386 : const Operator* SimplifiedOperatorBuilder::CheckedTruncateTaggedToWord32(
1372 : CheckTaggedInputMode mode, const VectorSlotPair& feedback) {
1373 1386 : if (!feedback.IsValid()) {
1374 1350 : switch (mode) {
1375 : case CheckTaggedInputMode::kNumber:
1376 874 : return &cache_.kCheckedTruncateTaggedToWord32NumberOperator;
1377 : case CheckTaggedInputMode::kNumberOrOddball:
1378 476 : return &cache_.kCheckedTruncateTaggedToWord32NumberOrOddballOperator;
1379 : }
1380 : }
1381 : return new (zone()) Operator1<CheckTaggedInputParameters>(
1382 : IrOpcode::kCheckedTruncateTaggedToWord32,
1383 : Operator::kFoldable | Operator::kNoThrow, "CheckedTruncateTaggedToWord32",
1384 : 1, 1, 1, 1, 1, 0, CheckTaggedInputParameters(mode, feedback));
1385 : }
1386 :
1387 91070 : const Operator* SimplifiedOperatorBuilder::CheckMaps(
1388 : CheckMapsFlags flags, ZoneHandleSet<Map> maps,
1389 : const VectorSlotPair& feedback) {
1390 : CheckMapsParameters const parameters(flags, maps, feedback);
1391 : return new (zone()) Operator1<CheckMapsParameters>( // --
1392 : IrOpcode::kCheckMaps, // opcode
1393 : Operator::kNoThrow | Operator::kNoWrite, // flags
1394 : "CheckMaps", // name
1395 : 1, 1, 1, 0, 1, 0, // counts
1396 91070 : parameters); // parameter
1397 : }
1398 :
1399 6749 : const Operator* SimplifiedOperatorBuilder::MapGuard(ZoneHandleSet<Map> maps) {
1400 : DCHECK_LT(0, maps.size());
1401 : return new (zone()) Operator1<ZoneHandleSet<Map>>( // --
1402 : IrOpcode::kMapGuard, Operator::kEliminatable, // opcode
1403 : "MapGuard", // name
1404 : 1, 1, 1, 0, 1, 0, // counts
1405 13498 : maps); // parameter
1406 : }
1407 :
1408 7015 : const Operator* SimplifiedOperatorBuilder::CompareMaps(
1409 : ZoneHandleSet<Map> maps) {
1410 : DCHECK_LT(0, maps.size());
1411 : return new (zone()) Operator1<ZoneHandleSet<Map>>( // --
1412 : IrOpcode::kCompareMaps, // opcode
1413 : Operator::kEliminatable, // flags
1414 : "CompareMaps", // name
1415 : 1, 1, 1, 1, 1, 0, // counts
1416 14030 : maps); // parameter
1417 : }
1418 :
1419 73977 : const Operator* SimplifiedOperatorBuilder::ConvertReceiver(
1420 : ConvertReceiverMode mode) {
1421 73977 : switch (mode) {
1422 : case ConvertReceiverMode::kAny:
1423 1180 : return &cache_.kConvertReceiverAnyOperator;
1424 : case ConvertReceiverMode::kNullOrUndefined:
1425 71959 : return &cache_.kConvertReceiverNullOrUndefinedOperator;
1426 : case ConvertReceiverMode::kNotNullOrUndefined:
1427 838 : return &cache_.kConvertReceiverNotNullOrUndefinedOperator;
1428 : }
1429 0 : UNREACHABLE();
1430 : return nullptr;
1431 : }
1432 :
1433 618 : const Operator* SimplifiedOperatorBuilder::CheckFloat64Hole(
1434 : CheckFloat64HoleMode mode, VectorSlotPair const& feedback) {
1435 618 : if (!feedback.IsValid()) {
1436 603 : switch (mode) {
1437 : case CheckFloat64HoleMode::kAllowReturnHole:
1438 428 : return &cache_.kCheckFloat64HoleAllowReturnHoleOperator;
1439 : case CheckFloat64HoleMode::kNeverReturnHole:
1440 175 : return &cache_.kCheckFloat64HoleNeverReturnHoleOperator;
1441 : }
1442 0 : UNREACHABLE();
1443 : }
1444 : return new (zone()) Operator1<CheckFloat64HoleParameters>(
1445 : IrOpcode::kCheckFloat64Hole, Operator::kFoldable | Operator::kNoThrow,
1446 : "CheckFloat64Hole", 1, 1, 1, 1, 1, 0,
1447 : CheckFloat64HoleParameters(mode, feedback));
1448 : }
1449 :
1450 75102 : const Operator* SimplifiedOperatorBuilder::SpeculativeToNumber(
1451 : NumberOperationHint hint, const VectorSlotPair& feedback) {
1452 75102 : if (!feedback.IsValid()) {
1453 17417 : switch (hint) {
1454 : case NumberOperationHint::kSignedSmall:
1455 7590 : return &cache_.kSpeculativeToNumberSignedSmallOperator;
1456 : case NumberOperationHint::kSignedSmallInputs:
1457 : break;
1458 : case NumberOperationHint::kSigned32:
1459 6 : return &cache_.kSpeculativeToNumberSigned32Operator;
1460 : case NumberOperationHint::kNumber:
1461 6435 : return &cache_.kSpeculativeToNumberNumberOperator;
1462 : case NumberOperationHint::kNumberOrOddball:
1463 3380 : return &cache_.kSpeculativeToNumberNumberOrOddballOperator;
1464 : }
1465 : }
1466 : return new (zone()) Operator1<NumberOperationParameters>(
1467 : IrOpcode::kSpeculativeToNumber, Operator::kFoldable | Operator::kNoThrow,
1468 : "SpeculativeToNumber", 1, 1, 1, 1, 1, 0,
1469 : NumberOperationParameters(hint, feedback));
1470 : }
1471 :
1472 1342 : const Operator* SimplifiedOperatorBuilder::EnsureWritableFastElements() {
1473 1342 : return &cache_.kEnsureWritableFastElements;
1474 : }
1475 :
1476 2852 : const Operator* SimplifiedOperatorBuilder::MaybeGrowFastElements(
1477 : GrowFastElementsMode mode, const VectorSlotPair& feedback) {
1478 2852 : if (!feedback.IsValid()) {
1479 1072 : switch (mode) {
1480 : case GrowFastElementsMode::kDoubleElements:
1481 142 : return &cache_.kGrowFastElementsOperatorDoubleElements;
1482 : case GrowFastElementsMode::kSmiOrObjectElements:
1483 930 : return &cache_.kGrowFastElementsOperatorSmiOrObjectElements;
1484 : }
1485 : }
1486 : return new (zone()) Operator1<GrowFastElementsParameters>( // --
1487 : IrOpcode::kMaybeGrowFastElements, // opcode
1488 : Operator::kNoThrow, // flags
1489 : "MaybeGrowFastElements", // name
1490 : 4, 1, 1, 1, 1, 0, // counts
1491 : GrowFastElementsParameters(mode, feedback)); // parameter
1492 : }
1493 :
1494 550 : const Operator* SimplifiedOperatorBuilder::TransitionElementsKind(
1495 : ElementsTransition transition) {
1496 : return new (zone()) Operator1<ElementsTransition>( // --
1497 : IrOpcode::kTransitionElementsKind, // opcode
1498 : Operator::kNoDeopt | Operator::kNoThrow, // flags
1499 : "TransitionElementsKind", // name
1500 : 1, 1, 1, 0, 1, 0, // counts
1501 1100 : transition); // parameter
1502 : }
1503 :
1504 : namespace {
1505 :
1506 : struct ArgumentsLengthParameters {
1507 : int formal_parameter_count;
1508 : bool is_rest_length;
1509 : };
1510 :
1511 : bool operator==(ArgumentsLengthParameters first,
1512 : ArgumentsLengthParameters second) {
1513 0 : return first.formal_parameter_count == second.formal_parameter_count &&
1514 : first.is_rest_length == second.is_rest_length;
1515 : }
1516 :
1517 41270 : size_t hash_value(ArgumentsLengthParameters param) {
1518 41270 : return base::hash_combine(param.formal_parameter_count, param.is_rest_length);
1519 : }
1520 :
1521 0 : std::ostream& operator<<(std::ostream& os, ArgumentsLengthParameters param) {
1522 0 : return os << param.formal_parameter_count << ", "
1523 0 : << (param.is_rest_length ? "rest length" : "not rest length");
1524 : }
1525 :
1526 : } // namespace
1527 :
1528 17729 : const Operator* SimplifiedOperatorBuilder::ArgumentsLength(
1529 : int formal_parameter_count, bool is_rest_length) {
1530 : return new (zone()) Operator1<ArgumentsLengthParameters>( // --
1531 : IrOpcode::kArgumentsLength, // opcode
1532 : Operator::kPure, // flags
1533 : "ArgumentsLength", // name
1534 : 1, 0, 0, 1, 0, 0, // counts
1535 : ArgumentsLengthParameters{formal_parameter_count,
1536 35458 : is_rest_length}); // parameter
1537 : }
1538 :
1539 16921 : int FormalParameterCountOf(const Operator* op) {
1540 : DCHECK_EQ(IrOpcode::kArgumentsLength, op->opcode());
1541 16921 : return OpParameter<ArgumentsLengthParameters>(op).formal_parameter_count;
1542 : }
1543 :
1544 35965 : bool IsRestLengthOf(const Operator* op) {
1545 : DCHECK_EQ(IrOpcode::kArgumentsLength, op->opcode());
1546 35965 : return OpParameter<ArgumentsLengthParameters>(op).is_rest_length;
1547 : }
1548 :
1549 0 : bool operator==(CheckParameters const& lhs, CheckParameters const& rhs) {
1550 0 : return lhs.feedback() == rhs.feedback();
1551 : }
1552 :
1553 0 : size_t hash_value(CheckParameters const& p) { return hash_value(p.feedback()); }
1554 :
1555 0 : std::ostream& operator<<(std::ostream& os, CheckParameters const& p) {
1556 26 : return os << p.feedback();
1557 : }
1558 :
1559 385552 : CheckParameters const& CheckParametersOf(Operator const* op) {
1560 385552 : if (op->opcode() == IrOpcode::kCheckedUint32Bounds) {
1561 0 : return OpParameter<CheckBoundsParameters>(op).check_parameters();
1562 : }
1563 : #define MAKE_OR(name, arg2, arg3) op->opcode() == IrOpcode::k##name ||
1564 385552 : CHECK((CHECKED_WITH_FEEDBACK_OP_LIST(MAKE_OR) false));
1565 : #undef MAKE_OR
1566 385552 : return OpParameter<CheckParameters>(op);
1567 : }
1568 :
1569 0 : bool operator==(CheckBoundsParameters const& lhs,
1570 : CheckBoundsParameters const& rhs) {
1571 0 : return lhs.check_parameters() == rhs.check_parameters() &&
1572 0 : lhs.mode() == rhs.mode();
1573 : }
1574 :
1575 0 : size_t hash_value(CheckBoundsParameters const& p) {
1576 0 : return base::hash_combine(hash_value(p.check_parameters()), p.mode());
1577 : }
1578 :
1579 0 : std::ostream& operator<<(std::ostream& os, CheckBoundsParameters const& p) {
1580 0 : os << p.check_parameters() << ",";
1581 0 : switch (p.mode()) {
1582 : case CheckBoundsParameters::kDeoptOnOutOfBounds:
1583 0 : os << "deopt";
1584 0 : break;
1585 : case CheckBoundsParameters::kAbortOnOutOfBounds:
1586 0 : os << "abort";
1587 0 : break;
1588 : }
1589 0 : return os;
1590 : }
1591 :
1592 52339 : CheckBoundsParameters const& CheckBoundsParametersOf(Operator const* op) {
1593 52339 : CHECK_EQ(op->opcode(), IrOpcode::kCheckedUint32Bounds);
1594 52339 : return OpParameter<CheckBoundsParameters>(op);
1595 : }
1596 :
1597 0 : bool operator==(CheckIfParameters const& lhs, CheckIfParameters const& rhs) {
1598 0 : return lhs.reason() == rhs.reason() && lhs.feedback() == rhs.feedback();
1599 : }
1600 :
1601 0 : size_t hash_value(CheckIfParameters const& p) {
1602 0 : return base::hash_combine(p.reason(), p.feedback());
1603 : }
1604 :
1605 0 : std::ostream& operator<<(std::ostream& os, CheckIfParameters const& p) {
1606 0 : return os << p.reason() << p.feedback();
1607 : }
1608 :
1609 16409 : CheckIfParameters const& CheckIfParametersOf(Operator const* op) {
1610 16409 : CHECK(op->opcode() == IrOpcode::kCheckIf);
1611 16409 : return OpParameter<CheckIfParameters>(op);
1612 : }
1613 :
1614 28 : const Operator* SimplifiedOperatorBuilder::NewDoubleElements(
1615 : AllocationType allocation) {
1616 : return new (zone()) Operator1<AllocationType>( // --
1617 : IrOpcode::kNewDoubleElements, // opcode
1618 : Operator::kEliminatable, // flags
1619 : "NewDoubleElements", // name
1620 : 1, 1, 1, 1, 1, 0, // counts
1621 28 : allocation); // parameter
1622 : }
1623 :
1624 448 : const Operator* SimplifiedOperatorBuilder::NewSmiOrObjectElements(
1625 : AllocationType allocation) {
1626 : return new (zone()) Operator1<AllocationType>( // --
1627 : IrOpcode::kNewSmiOrObjectElements, // opcode
1628 : Operator::kEliminatable, // flags
1629 : "NewSmiOrObjectElements", // name
1630 : 1, 1, 1, 1, 1, 0, // counts
1631 448 : allocation); // parameter
1632 : }
1633 :
1634 17729 : const Operator* SimplifiedOperatorBuilder::NewArgumentsElements(
1635 : int mapped_count) {
1636 : return new (zone()) Operator1<int>( // --
1637 : IrOpcode::kNewArgumentsElements, // opcode
1638 : Operator::kEliminatable, // flags
1639 : "NewArgumentsElements", // name
1640 : 2, 1, 0, 1, 1, 0, // counts
1641 17729 : mapped_count); // parameter
1642 : }
1643 :
1644 35462 : int NewArgumentsElementsMappedCountOf(const Operator* op) {
1645 : DCHECK_EQ(IrOpcode::kNewArgumentsElements, op->opcode());
1646 35462 : return OpParameter<int>(op);
1647 : }
1648 :
1649 139017 : const Operator* SimplifiedOperatorBuilder::Allocate(Type type,
1650 : AllocationType allocation) {
1651 : return new (zone()) Operator1<AllocateParameters>(
1652 : IrOpcode::kAllocate,
1653 : Operator::kNoDeopt | Operator::kNoThrow | Operator::kNoWrite, "Allocate",
1654 139017 : 1, 1, 1, 1, 1, 0, AllocateParameters(type, allocation));
1655 : }
1656 :
1657 234828 : const Operator* SimplifiedOperatorBuilder::AllocateRaw(
1658 : Type type, AllocationType allocation) {
1659 : return new (zone()) Operator1<AllocateParameters>(
1660 : IrOpcode::kAllocateRaw,
1661 : Operator::kNoDeopt | Operator::kNoThrow | Operator::kNoWrite,
1662 234828 : "AllocateRaw", 1, 1, 1, 1, 1, 1, AllocateParameters(type, allocation));
1663 : }
1664 :
1665 548 : const Operator* SimplifiedOperatorBuilder::StringCodePointAt(
1666 : UnicodeEncoding encoding) {
1667 548 : switch (encoding) {
1668 : case UnicodeEncoding::UTF16:
1669 87 : return &cache_.kStringCodePointAtOperatorUTF16;
1670 : case UnicodeEncoding::UTF32:
1671 461 : return &cache_.kStringCodePointAtOperatorUTF32;
1672 : }
1673 0 : UNREACHABLE();
1674 : }
1675 :
1676 215 : const Operator* SimplifiedOperatorBuilder::StringFromSingleCodePoint(
1677 : UnicodeEncoding encoding) {
1678 215 : switch (encoding) {
1679 : case UnicodeEncoding::UTF16:
1680 87 : return &cache_.kStringFromSingleCodePointOperatorUTF16;
1681 : case UnicodeEncoding::UTF32:
1682 128 : return &cache_.kStringFromSingleCodePointOperatorUTF32;
1683 : }
1684 0 : UNREACHABLE();
1685 : }
1686 :
1687 : #define SPECULATIVE_NUMBER_BINOP(Name) \
1688 : const Operator* SimplifiedOperatorBuilder::Name(NumberOperationHint hint) { \
1689 : switch (hint) { \
1690 : case NumberOperationHint::kSignedSmall: \
1691 : return &cache_.k##Name##SignedSmallOperator; \
1692 : case NumberOperationHint::kSignedSmallInputs: \
1693 : return &cache_.k##Name##SignedSmallInputsOperator; \
1694 : case NumberOperationHint::kSigned32: \
1695 : return &cache_.k##Name##Signed32Operator; \
1696 : case NumberOperationHint::kNumber: \
1697 : return &cache_.k##Name##NumberOperator; \
1698 : case NumberOperationHint::kNumberOrOddball: \
1699 : return &cache_.k##Name##NumberOrOddballOperator; \
1700 : } \
1701 : UNREACHABLE(); \
1702 : return nullptr; \
1703 : }
1704 324163 : SPECULATIVE_NUMBER_BINOP_LIST(SPECULATIVE_NUMBER_BINOP)
1705 : #undef SPECULATIVE_NUMBER_BINOP
1706 :
1707 : #define ACCESS_OP_LIST(V) \
1708 : V(LoadField, FieldAccess, Operator::kNoWrite, 1, 1, 1) \
1709 : V(StoreField, FieldAccess, Operator::kNoRead, 2, 1, 0) \
1710 : V(LoadElement, ElementAccess, Operator::kNoWrite, 2, 1, 1) \
1711 : V(StoreElement, ElementAccess, Operator::kNoRead, 3, 1, 0) \
1712 : V(LoadTypedElement, ExternalArrayType, Operator::kNoWrite, 4, 1, 1) \
1713 : V(StoreTypedElement, ExternalArrayType, Operator::kNoRead, 5, 1, 0) \
1714 : V(LoadDataViewElement, ExternalArrayType, Operator::kNoWrite, 5, 1, 1) \
1715 : V(StoreDataViewElement, ExternalArrayType, Operator::kNoRead, 6, 1, 0)
1716 :
1717 : #define ACCESS(Name, Type, properties, value_input_count, control_input_count, \
1718 : output_count) \
1719 : const Operator* SimplifiedOperatorBuilder::Name(const Type& access) { \
1720 : return new (zone()) \
1721 : Operator1<Type>(IrOpcode::k##Name, \
1722 : Operator::kNoDeopt | Operator::kNoThrow | properties, \
1723 : #Name, value_input_count, 1, control_input_count, \
1724 : output_count, 1, 0, access); \
1725 : }
1726 10924087 : ACCESS_OP_LIST(ACCESS)
1727 : #undef ACCESS
1728 :
1729 29802 : const Operator* SimplifiedOperatorBuilder::LoadMessage() {
1730 29802 : return &cache_.kLoadMessage;
1731 : }
1732 :
1733 29804 : const Operator* SimplifiedOperatorBuilder::StoreMessage() {
1734 29804 : return &cache_.kStoreMessage;
1735 : }
1736 :
1737 585 : const Operator* SimplifiedOperatorBuilder::LoadStackArgument() {
1738 585 : return &cache_.kLoadStackArgument;
1739 : }
1740 :
1741 336 : const Operator* SimplifiedOperatorBuilder::TransitionAndStoreElement(
1742 : Handle<Map> double_map, Handle<Map> fast_map) {
1743 : TransitionAndStoreElementParameters parameters(double_map, fast_map);
1744 : return new (zone()) Operator1<TransitionAndStoreElementParameters>(
1745 : IrOpcode::kTransitionAndStoreElement,
1746 : Operator::kNoDeopt | Operator::kNoThrow, "TransitionAndStoreElement", 3,
1747 336 : 1, 1, 0, 1, 0, parameters);
1748 : }
1749 :
1750 70 : const Operator* SimplifiedOperatorBuilder::StoreSignedSmallElement() {
1751 : return new (zone()) Operator(IrOpcode::kStoreSignedSmallElement,
1752 140 : Operator::kNoDeopt | Operator::kNoThrow,
1753 140 : "StoreSignedSmallElement", 3, 1, 1, 0, 1, 0);
1754 : }
1755 :
1756 28 : const Operator* SimplifiedOperatorBuilder::TransitionAndStoreNumberElement(
1757 : Handle<Map> double_map) {
1758 : TransitionAndStoreNumberElementParameters parameters(double_map);
1759 : return new (zone()) Operator1<TransitionAndStoreNumberElementParameters>(
1760 : IrOpcode::kTransitionAndStoreNumberElement,
1761 : Operator::kNoDeopt | Operator::kNoThrow,
1762 28 : "TransitionAndStoreNumberElement", 3, 1, 1, 0, 1, 0, parameters);
1763 : }
1764 :
1765 20 : const Operator* SimplifiedOperatorBuilder::TransitionAndStoreNonNumberElement(
1766 : Handle<Map> fast_map, Type value_type) {
1767 : TransitionAndStoreNonNumberElementParameters parameters(fast_map, value_type);
1768 : return new (zone()) Operator1<TransitionAndStoreNonNumberElementParameters>(
1769 : IrOpcode::kTransitionAndStoreNonNumberElement,
1770 : Operator::kNoDeopt | Operator::kNoThrow,
1771 20 : "TransitionAndStoreNonNumberElement", 3, 1, 1, 0, 1, 0, parameters);
1772 : }
1773 :
1774 : #undef PURE_OP_LIST
1775 : #undef EFFECT_DEPENDENT_OP_LIST
1776 : #undef SPECULATIVE_NUMBER_BINOP_LIST
1777 : #undef CHECKED_WITH_FEEDBACK_OP_LIST
1778 : #undef CHECKED_BOUNDS_OP_LIST
1779 : #undef CHECKED_OP_LIST
1780 : #undef ACCESS_OP_LIST
1781 :
1782 : } // namespace compiler
1783 : } // namespace internal
1784 121996 : } // namespace v8
|