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 :
12 : namespace v8 {
13 : namespace internal {
14 : namespace compiler {
15 :
16 0 : size_t hash_value(BaseTaggedness base_taggedness) {
17 0 : return static_cast<uint8_t>(base_taggedness);
18 : }
19 :
20 117852 : std::ostream& operator<<(std::ostream& os, BaseTaggedness base_taggedness) {
21 117852 : switch (base_taggedness) {
22 : case kUntaggedBase:
23 71736 : return os << "untagged base";
24 : case kTaggedBase:
25 46116 : return os << "tagged base";
26 : }
27 0 : UNREACHABLE();
28 : return os;
29 : }
30 :
31 :
32 60808 : MachineType BufferAccess::machine_type() const {
33 60808 : switch (external_array_type_) {
34 : case kExternalUint8Array:
35 : case kExternalUint8ClampedArray:
36 : return MachineType::Uint8();
37 : case kExternalInt8Array:
38 : return MachineType::Int8();
39 : case kExternalUint16Array:
40 : return MachineType::Uint16();
41 : case kExternalInt16Array:
42 : return MachineType::Int16();
43 : case kExternalUint32Array:
44 : return MachineType::Uint32();
45 : case kExternalInt32Array:
46 : return MachineType::Int32();
47 : case kExternalFloat32Array:
48 : return MachineType::Float32();
49 : case kExternalFloat64Array:
50 : return MachineType::Float64();
51 : }
52 0 : UNREACHABLE();
53 : return MachineType::None();
54 : }
55 :
56 :
57 56 : bool operator==(BufferAccess lhs, BufferAccess rhs) {
58 56 : return lhs.external_array_type() == rhs.external_array_type();
59 : }
60 :
61 :
62 0 : bool operator!=(BufferAccess lhs, BufferAccess rhs) { return !(lhs == rhs); }
63 :
64 :
65 0 : size_t hash_value(BufferAccess access) {
66 0 : return base::hash<ExternalArrayType>()(access.external_array_type());
67 : }
68 :
69 :
70 0 : std::ostream& operator<<(std::ostream& os, BufferAccess access) {
71 0 : switch (access.external_array_type()) {
72 : #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
73 : case kExternal##Type##Array: \
74 : return os << #Type;
75 0 : TYPED_ARRAYS(TYPED_ARRAY_CASE)
76 : #undef TYPED_ARRAY_CASE
77 : }
78 0 : UNREACHABLE();
79 : return os;
80 : }
81 :
82 :
83 50418 : BufferAccess const BufferAccessOf(const Operator* op) {
84 : DCHECK(op->opcode() == IrOpcode::kLoadBuffer ||
85 : op->opcode() == IrOpcode::kStoreBuffer);
86 50418 : return OpParameter<BufferAccess>(op);
87 : }
88 :
89 :
90 127 : bool operator==(FieldAccess const& lhs, FieldAccess const& rhs) {
91 : // On purpose we don't include the write barrier kind here, as this method is
92 : // really only relevant for eliminating loads and they don't care about the
93 : // write barrier mode.
94 254 : return lhs.base_is_tagged == rhs.base_is_tagged && lhs.offset == rhs.offset &&
95 254 : lhs.map.address() == rhs.map.address() &&
96 127 : lhs.machine_type == rhs.machine_type;
97 : }
98 :
99 :
100 0 : bool operator!=(FieldAccess const& lhs, FieldAccess const& rhs) {
101 0 : return !(lhs == rhs);
102 : }
103 :
104 :
105 0 : size_t hash_value(FieldAccess const& access) {
106 : // On purpose we don't include the write barrier kind here, as this method is
107 : // really only relevant for eliminating loads and they don't care about the
108 : // write barrier mode.
109 : return base::hash_combine(access.base_is_tagged, access.offset,
110 0 : access.machine_type);
111 : }
112 :
113 :
114 0 : std::ostream& operator<<(std::ostream& os, FieldAccess const& access) {
115 0 : os << "[" << access.base_is_tagged << ", " << access.offset << ", ";
116 : #ifdef OBJECT_PRINT
117 : Handle<Name> name;
118 : if (access.name.ToHandle(&name)) {
119 : name->Print(os);
120 : os << ", ";
121 : }
122 : Handle<Map> map;
123 : if (access.map.ToHandle(&map)) {
124 : os << Brief(*map) << ", ";
125 : }
126 : #endif
127 0 : access.type->PrintTo(os);
128 0 : os << ", " << access.machine_type << ", " << access.write_barrier_kind << "]";
129 0 : return os;
130 : }
131 :
132 : template <>
133 0 : void Operator1<FieldAccess>::PrintParameter(std::ostream& os,
134 : PrintVerbosity verbose) const {
135 0 : if (verbose == PrintVerbosity::kVerbose) {
136 0 : os << parameter();
137 : } else {
138 0 : os << "[+" << parameter().offset << "]";
139 : }
140 0 : }
141 :
142 70 : bool operator==(ElementAccess const& lhs, ElementAccess const& rhs) {
143 : // On purpose we don't include the write barrier kind here, as this method is
144 : // really only relevant for eliminating loads and they don't care about the
145 : // write barrier mode.
146 70 : return lhs.base_is_tagged == rhs.base_is_tagged &&
147 140 : lhs.header_size == rhs.header_size &&
148 70 : lhs.machine_type == rhs.machine_type;
149 : }
150 :
151 :
152 0 : bool operator!=(ElementAccess const& lhs, ElementAccess const& rhs) {
153 0 : return !(lhs == rhs);
154 : }
155 :
156 :
157 0 : size_t hash_value(ElementAccess const& access) {
158 : // On purpose we don't include the write barrier kind here, as this method is
159 : // really only relevant for eliminating loads and they don't care about the
160 : // write barrier mode.
161 : return base::hash_combine(access.base_is_tagged, access.header_size,
162 0 : access.machine_type);
163 : }
164 :
165 :
166 117852 : std::ostream& operator<<(std::ostream& os, ElementAccess const& access) {
167 117852 : os << access.base_is_tagged << ", " << access.header_size << ", ";
168 117852 : access.type->PrintTo(os);
169 117852 : os << ", " << access.machine_type << ", " << access.write_barrier_kind;
170 117852 : return os;
171 : }
172 :
173 :
174 13334603 : const FieldAccess& FieldAccessOf(const Operator* op) {
175 : DCHECK_NOT_NULL(op);
176 : DCHECK(op->opcode() == IrOpcode::kLoadField ||
177 : op->opcode() == IrOpcode::kStoreField);
178 13334603 : return OpParameter<FieldAccess>(op);
179 : }
180 :
181 :
182 1204866 : const ElementAccess& ElementAccessOf(const Operator* op) {
183 : DCHECK_NOT_NULL(op);
184 : DCHECK(op->opcode() == IrOpcode::kLoadElement ||
185 : op->opcode() == IrOpcode::kStoreElement);
186 1204866 : return OpParameter<ElementAccess>(op);
187 : }
188 :
189 32970 : ExternalArrayType ExternalArrayTypeOf(const Operator* op) {
190 : DCHECK(op->opcode() == IrOpcode::kLoadTypedElement ||
191 : op->opcode() == IrOpcode::kStoreTypedElement);
192 32970 : return OpParameter<ExternalArrayType>(op);
193 : }
194 :
195 0 : size_t hash_value(CheckFloat64HoleMode mode) {
196 0 : return static_cast<size_t>(mode);
197 : }
198 :
199 0 : std::ostream& operator<<(std::ostream& os, CheckFloat64HoleMode mode) {
200 0 : switch (mode) {
201 : case CheckFloat64HoleMode::kAllowReturnHole:
202 0 : return os << "allow-return-hole";
203 : case CheckFloat64HoleMode::kNeverReturnHole:
204 0 : return os << "never-return-hole";
205 : }
206 0 : UNREACHABLE();
207 : return os;
208 : }
209 :
210 2298 : CheckFloat64HoleMode CheckFloat64HoleModeOf(const Operator* op) {
211 : DCHECK_EQ(IrOpcode::kCheckFloat64Hole, op->opcode());
212 2298 : return OpParameter<CheckFloat64HoleMode>(op);
213 : }
214 :
215 62029 : CheckForMinusZeroMode CheckMinusZeroModeOf(const Operator* op) {
216 : DCHECK(op->opcode() == IrOpcode::kChangeFloat64ToTagged ||
217 : op->opcode() == IrOpcode::kCheckedInt32Mul ||
218 : op->opcode() == IrOpcode::kCheckedFloat64ToInt32 ||
219 : op->opcode() == IrOpcode::kCheckedTaggedToInt32);
220 62029 : return OpParameter<CheckForMinusZeroMode>(op);
221 : }
222 :
223 85713 : size_t hash_value(CheckForMinusZeroMode mode) {
224 85713 : return static_cast<size_t>(mode);
225 : }
226 :
227 10 : std::ostream& operator<<(std::ostream& os, CheckForMinusZeroMode mode) {
228 10 : switch (mode) {
229 : case CheckForMinusZeroMode::kCheckForMinusZero:
230 5 : return os << "check-for-minus-zero";
231 : case CheckForMinusZeroMode::kDontCheckForMinusZero:
232 5 : return os << "dont-check-for-minus-zero";
233 : }
234 0 : UNREACHABLE();
235 : return os;
236 : }
237 :
238 0 : std::ostream& operator<<(std::ostream& os, CheckMapsFlags flags) {
239 : bool empty = true;
240 0 : if (flags & CheckMapsFlag::kTryMigrateInstance) {
241 0 : os << "TryMigrateInstance";
242 : empty = false;
243 : }
244 0 : if (empty) os << "None";
245 0 : return os;
246 : }
247 :
248 0 : bool operator==(CheckMapsParameters const& lhs,
249 : CheckMapsParameters const& rhs) {
250 0 : return lhs.flags() == rhs.flags() && lhs.maps() == rhs.maps();
251 : }
252 :
253 0 : bool operator!=(CheckMapsParameters const& lhs,
254 : CheckMapsParameters const& rhs) {
255 0 : return !(lhs == rhs);
256 : }
257 :
258 0 : size_t hash_value(CheckMapsParameters const& p) {
259 0 : return base::hash_combine(p.flags(), p.maps());
260 : }
261 :
262 0 : std::ostream& operator<<(std::ostream& os, CheckMapsParameters const& p) {
263 : ZoneHandleSet<Map> const& maps = p.maps();
264 0 : os << p.flags();
265 0 : for (size_t i = 0; i < maps.size(); ++i) {
266 0 : os << ", " << Brief(*maps[i]);
267 : }
268 0 : return os;
269 : }
270 :
271 212156 : CheckMapsParameters const& CheckMapsParametersOf(Operator const* op) {
272 : DCHECK_EQ(IrOpcode::kCheckMaps, op->opcode());
273 212156 : return OpParameter<CheckMapsParameters>(op);
274 : }
275 :
276 0 : size_t hash_value(CheckTaggedInputMode mode) {
277 0 : return static_cast<size_t>(mode);
278 : }
279 :
280 0 : std::ostream& operator<<(std::ostream& os, CheckTaggedInputMode mode) {
281 0 : switch (mode) {
282 : case CheckTaggedInputMode::kNumber:
283 0 : return os << "Number";
284 : case CheckTaggedInputMode::kNumberOrOddball:
285 0 : return os << "NumberOrOddball";
286 : }
287 0 : UNREACHABLE();
288 : return os;
289 : }
290 :
291 20767 : CheckTaggedInputMode CheckTaggedInputModeOf(const Operator* op) {
292 : DCHECK_EQ(IrOpcode::kCheckedTaggedToFloat64, op->opcode());
293 20767 : return OpParameter<CheckTaggedInputMode>(op);
294 : }
295 :
296 0 : std::ostream& operator<<(std::ostream& os, GrowFastElementsFlags flags) {
297 : bool empty = true;
298 0 : if (flags & GrowFastElementsFlag::kArrayObject) {
299 0 : os << "ArrayObject";
300 : empty = false;
301 : }
302 0 : if (flags & GrowFastElementsFlag::kDoubleElements) {
303 0 : if (!empty) os << "|";
304 0 : os << "DoubleElements";
305 : empty = false;
306 : }
307 0 : if (flags & GrowFastElementsFlag::kHoleyElements) {
308 0 : if (!empty) os << "|";
309 0 : os << "HoleyElements";
310 : empty = false;
311 : }
312 0 : if (empty) os << "None";
313 0 : return os;
314 : }
315 :
316 6505 : GrowFastElementsFlags GrowFastElementsFlagsOf(const Operator* op) {
317 : DCHECK_EQ(IrOpcode::kMaybeGrowFastElements, op->opcode());
318 6505 : return OpParameter<GrowFastElementsFlags>(op);
319 : }
320 :
321 0 : bool operator==(ElementsTransition const& lhs, ElementsTransition const& rhs) {
322 0 : return lhs.mode() == rhs.mode() &&
323 0 : lhs.source().address() == rhs.source().address() &&
324 0 : lhs.target().address() == rhs.target().address();
325 : }
326 :
327 0 : bool operator!=(ElementsTransition const& lhs, ElementsTransition const& rhs) {
328 0 : return !(lhs == rhs);
329 : }
330 :
331 0 : size_t hash_value(ElementsTransition transition) {
332 0 : return base::hash_combine(static_cast<uint8_t>(transition.mode()),
333 : transition.source().address(),
334 0 : transition.target().address());
335 : }
336 :
337 0 : std::ostream& operator<<(std::ostream& os, ElementsTransition transition) {
338 0 : switch (transition.mode()) {
339 : case ElementsTransition::kFastTransition:
340 0 : return os << "fast-transition from " << Brief(*transition.source())
341 0 : << " to " << Brief(*transition.target());
342 : case ElementsTransition::kSlowTransition:
343 0 : return os << "slow-transition from " << Brief(*transition.source())
344 0 : << " to " << Brief(*transition.target());
345 : }
346 0 : UNREACHABLE();
347 : return os;
348 : }
349 :
350 1286 : ElementsTransition const& ElementsTransitionOf(const Operator* op) {
351 : DCHECK_EQ(IrOpcode::kTransitionElementsKind, op->opcode());
352 1286 : return OpParameter<ElementsTransition>(op);
353 : }
354 :
355 0 : std::ostream& operator<<(std::ostream& os, NumberOperationHint hint) {
356 0 : switch (hint) {
357 : case NumberOperationHint::kSignedSmall:
358 0 : return os << "SignedSmall";
359 : case NumberOperationHint::kSigned32:
360 0 : return os << "Signed32";
361 : case NumberOperationHint::kNumber:
362 0 : return os << "Number";
363 : case NumberOperationHint::kNumberOrOddball:
364 0 : return os << "NumberOrOddball";
365 : }
366 0 : UNREACHABLE();
367 : return os;
368 : }
369 :
370 0 : size_t hash_value(NumberOperationHint hint) {
371 0 : return static_cast<uint8_t>(hint);
372 : }
373 :
374 1097592 : NumberOperationHint NumberOperationHintOf(const Operator* op) {
375 : DCHECK(op->opcode() == IrOpcode::kSpeculativeToNumber ||
376 : op->opcode() == IrOpcode::kSpeculativeNumberAdd ||
377 : op->opcode() == IrOpcode::kSpeculativeNumberSubtract ||
378 : op->opcode() == IrOpcode::kSpeculativeNumberMultiply ||
379 : op->opcode() == IrOpcode::kSpeculativeNumberDivide ||
380 : op->opcode() == IrOpcode::kSpeculativeNumberModulus ||
381 : op->opcode() == IrOpcode::kSpeculativeNumberShiftLeft ||
382 : op->opcode() == IrOpcode::kSpeculativeNumberShiftRight ||
383 : op->opcode() == IrOpcode::kSpeculativeNumberShiftRightLogical ||
384 : op->opcode() == IrOpcode::kSpeculativeNumberBitwiseAnd ||
385 : op->opcode() == IrOpcode::kSpeculativeNumberBitwiseOr ||
386 : op->opcode() == IrOpcode::kSpeculativeNumberBitwiseXor ||
387 : op->opcode() == IrOpcode::kSpeculativeNumberEqual ||
388 : op->opcode() == IrOpcode::kSpeculativeNumberLessThan ||
389 : op->opcode() == IrOpcode::kSpeculativeNumberLessThanOrEqual);
390 1097592 : return OpParameter<NumberOperationHint>(op);
391 : }
392 :
393 0 : size_t hash_value(AllocateParameters info) {
394 0 : return base::hash_combine(info.type(), info.pretenure());
395 : }
396 :
397 0 : V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
398 : AllocateParameters info) {
399 0 : info.type()->PrintTo(os);
400 0 : return os << ", " << info.pretenure();
401 : }
402 :
403 0 : bool operator==(AllocateParameters const& lhs, AllocateParameters const& rhs) {
404 0 : return lhs.pretenure() == rhs.pretenure() && lhs.type() == rhs.type();
405 : }
406 :
407 0 : bool operator!=(AllocateParameters const& lhs, AllocateParameters const& rhs) {
408 0 : return !(lhs == rhs);
409 : }
410 :
411 166162 : PretenureFlag PretenureFlagOf(const Operator* op) {
412 : DCHECK_EQ(IrOpcode::kAllocate, op->opcode());
413 166162 : return OpParameter<AllocateParameters>(op).pretenure();
414 : }
415 :
416 112796 : Type* AllocateTypeOf(const Operator* op) {
417 : DCHECK_EQ(IrOpcode::kAllocate, op->opcode());
418 112796 : return OpParameter<AllocateParameters>(op).type();
419 : }
420 :
421 57 : UnicodeEncoding UnicodeEncodingOf(const Operator* op) {
422 : DCHECK(op->opcode() == IrOpcode::kStringFromCodePoint);
423 57 : return OpParameter<UnicodeEncoding>(op);
424 : }
425 :
426 : #define PURE_OP_LIST(V) \
427 : V(BooleanNot, Operator::kNoProperties, 1, 0) \
428 : V(NumberEqual, Operator::kCommutative, 2, 0) \
429 : V(NumberLessThan, Operator::kNoProperties, 2, 0) \
430 : V(NumberLessThanOrEqual, Operator::kNoProperties, 2, 0) \
431 : V(NumberAdd, Operator::kCommutative, 2, 0) \
432 : V(NumberSubtract, Operator::kNoProperties, 2, 0) \
433 : V(NumberMultiply, Operator::kCommutative, 2, 0) \
434 : V(NumberDivide, Operator::kNoProperties, 2, 0) \
435 : V(NumberModulus, Operator::kNoProperties, 2, 0) \
436 : V(NumberBitwiseOr, Operator::kCommutative, 2, 0) \
437 : V(NumberBitwiseXor, Operator::kCommutative, 2, 0) \
438 : V(NumberBitwiseAnd, Operator::kCommutative, 2, 0) \
439 : V(NumberShiftLeft, Operator::kNoProperties, 2, 0) \
440 : V(NumberShiftRight, Operator::kNoProperties, 2, 0) \
441 : V(NumberShiftRightLogical, Operator::kNoProperties, 2, 0) \
442 : V(NumberImul, Operator::kCommutative, 2, 0) \
443 : V(NumberAbs, Operator::kNoProperties, 1, 0) \
444 : V(NumberClz32, Operator::kNoProperties, 1, 0) \
445 : V(NumberCeil, Operator::kNoProperties, 1, 0) \
446 : V(NumberFloor, Operator::kNoProperties, 1, 0) \
447 : V(NumberFround, Operator::kNoProperties, 1, 0) \
448 : V(NumberAcos, Operator::kNoProperties, 1, 0) \
449 : V(NumberAcosh, Operator::kNoProperties, 1, 0) \
450 : V(NumberAsin, Operator::kNoProperties, 1, 0) \
451 : V(NumberAsinh, Operator::kNoProperties, 1, 0) \
452 : V(NumberAtan, Operator::kNoProperties, 1, 0) \
453 : V(NumberAtan2, Operator::kNoProperties, 2, 0) \
454 : V(NumberAtanh, Operator::kNoProperties, 1, 0) \
455 : V(NumberCbrt, Operator::kNoProperties, 1, 0) \
456 : V(NumberCos, Operator::kNoProperties, 1, 0) \
457 : V(NumberCosh, Operator::kNoProperties, 1, 0) \
458 : V(NumberExp, Operator::kNoProperties, 1, 0) \
459 : V(NumberExpm1, Operator::kNoProperties, 1, 0) \
460 : V(NumberLog, Operator::kNoProperties, 1, 0) \
461 : V(NumberLog1p, Operator::kNoProperties, 1, 0) \
462 : V(NumberLog10, Operator::kNoProperties, 1, 0) \
463 : V(NumberLog2, Operator::kNoProperties, 1, 0) \
464 : V(NumberMax, Operator::kNoProperties, 2, 0) \
465 : V(NumberMin, Operator::kNoProperties, 2, 0) \
466 : V(NumberPow, Operator::kNoProperties, 2, 0) \
467 : V(NumberRound, Operator::kNoProperties, 1, 0) \
468 : V(NumberSign, Operator::kNoProperties, 1, 0) \
469 : V(NumberSin, Operator::kNoProperties, 1, 0) \
470 : V(NumberSinh, Operator::kNoProperties, 1, 0) \
471 : V(NumberSqrt, Operator::kNoProperties, 1, 0) \
472 : V(NumberTan, Operator::kNoProperties, 1, 0) \
473 : V(NumberTanh, Operator::kNoProperties, 1, 0) \
474 : V(NumberTrunc, Operator::kNoProperties, 1, 0) \
475 : V(NumberToBoolean, Operator::kNoProperties, 1, 0) \
476 : V(NumberToInt32, Operator::kNoProperties, 1, 0) \
477 : V(NumberToUint32, Operator::kNoProperties, 1, 0) \
478 : V(NumberToUint8Clamped, Operator::kNoProperties, 1, 0) \
479 : V(NumberSilenceNaN, Operator::kNoProperties, 1, 0) \
480 : V(StringCharAt, Operator::kNoProperties, 2, 1) \
481 : V(StringCharCodeAt, Operator::kNoProperties, 2, 1) \
482 : V(StringFromCharCode, Operator::kNoProperties, 1, 0) \
483 : V(StringIndexOf, Operator::kNoProperties, 3, 0) \
484 : V(PlainPrimitiveToNumber, Operator::kNoProperties, 1, 0) \
485 : V(PlainPrimitiveToWord32, Operator::kNoProperties, 1, 0) \
486 : V(PlainPrimitiveToFloat64, Operator::kNoProperties, 1, 0) \
487 : V(ChangeTaggedSignedToInt32, Operator::kNoProperties, 1, 0) \
488 : V(ChangeTaggedToInt32, Operator::kNoProperties, 1, 0) \
489 : V(ChangeTaggedToUint32, Operator::kNoProperties, 1, 0) \
490 : V(ChangeTaggedToFloat64, Operator::kNoProperties, 1, 0) \
491 : V(ChangeTaggedToTaggedSigned, Operator::kNoProperties, 1, 0) \
492 : V(ChangeFloat64ToTaggedPointer, Operator::kNoProperties, 1, 0) \
493 : V(ChangeInt31ToTaggedSigned, Operator::kNoProperties, 1, 0) \
494 : V(ChangeInt32ToTagged, Operator::kNoProperties, 1, 0) \
495 : V(ChangeUint32ToTagged, Operator::kNoProperties, 1, 0) \
496 : V(ChangeTaggedToBit, Operator::kNoProperties, 1, 0) \
497 : V(ChangeBitToTagged, Operator::kNoProperties, 1, 0) \
498 : V(TruncateTaggedToBit, Operator::kNoProperties, 1, 0) \
499 : V(TruncateTaggedPointerToBit, Operator::kNoProperties, 1, 0) \
500 : V(TruncateTaggedToWord32, Operator::kNoProperties, 1, 0) \
501 : V(TruncateTaggedToFloat64, Operator::kNoProperties, 1, 0) \
502 : V(ObjectIsDetectableCallable, Operator::kNoProperties, 1, 0) \
503 : V(ObjectIsNaN, Operator::kNoProperties, 1, 0) \
504 : V(ObjectIsNonCallable, Operator::kNoProperties, 1, 0) \
505 : V(ObjectIsNumber, Operator::kNoProperties, 1, 0) \
506 : V(ObjectIsReceiver, Operator::kNoProperties, 1, 0) \
507 : V(ObjectIsSmi, Operator::kNoProperties, 1, 0) \
508 : V(ObjectIsString, Operator::kNoProperties, 1, 0) \
509 : V(ObjectIsSymbol, Operator::kNoProperties, 1, 0) \
510 : V(ObjectIsUndetectable, Operator::kNoProperties, 1, 0) \
511 : V(ConvertTaggedHoleToUndefined, Operator::kNoProperties, 1, 0) \
512 : V(ReferenceEqual, Operator::kCommutative, 2, 0) \
513 : V(StringEqual, Operator::kCommutative, 2, 0) \
514 : V(StringLessThan, Operator::kNoProperties, 2, 0) \
515 : V(StringLessThanOrEqual, Operator::kNoProperties, 2, 0)
516 :
517 : #define SPECULATIVE_NUMBER_BINOP_LIST(V) \
518 : SIMPLIFIED_SPECULATIVE_NUMBER_BINOP_LIST(V) \
519 : V(SpeculativeNumberEqual) \
520 : V(SpeculativeNumberLessThan) \
521 : V(SpeculativeNumberLessThanOrEqual)
522 :
523 : #define CHECKED_OP_LIST(V) \
524 : V(CheckBounds, 2, 1) \
525 : V(CheckHeapObject, 1, 1) \
526 : V(CheckIf, 1, 0) \
527 : V(CheckInternalizedString, 1, 1) \
528 : V(CheckNumber, 1, 1) \
529 : V(CheckReceiver, 1, 1) \
530 : V(CheckSmi, 1, 1) \
531 : V(CheckString, 1, 1) \
532 : V(CheckTaggedHole, 1, 1) \
533 : V(CheckedInt32Add, 2, 1) \
534 : V(CheckedInt32Sub, 2, 1) \
535 : V(CheckedInt32Div, 2, 1) \
536 : V(CheckedInt32Mod, 2, 1) \
537 : V(CheckedUint32Div, 2, 1) \
538 : V(CheckedUint32Mod, 2, 1) \
539 : V(CheckedUint32ToInt32, 1, 1) \
540 : V(CheckedUint32ToTaggedSigned, 1, 1) \
541 : V(CheckedInt32ToTaggedSigned, 1, 1) \
542 : V(CheckedTaggedSignedToInt32, 1, 1) \
543 : V(CheckedTaggedToTaggedSigned, 1, 1) \
544 : V(CheckedTaggedToTaggedPointer, 1, 1) \
545 : V(CheckedTruncateTaggedToWord32, 1, 1)
546 :
547 21918 : struct SimplifiedOperatorGlobalCache final {
548 : #define PURE(Name, properties, value_input_count, control_input_count) \
549 : struct Name##Operator final : public Operator { \
550 : Name##Operator() \
551 : : Operator(IrOpcode::k##Name, Operator::kPure | properties, #Name, \
552 : value_input_count, 0, control_input_count, 1, 0, 0) {} \
553 : }; \
554 : Name##Operator k##Name;
555 1950702 : PURE_OP_LIST(PURE)
556 : #undef PURE
557 :
558 : #define CHECKED(Name, value_input_count, value_output_count) \
559 : struct Name##Operator final : public Operator { \
560 : Name##Operator() \
561 : : Operator(IrOpcode::k##Name, \
562 : Operator::kFoldable | Operator::kNoThrow, #Name, \
563 : value_input_count, 1, 1, value_output_count, 1, 0) {} \
564 : }; \
565 : Name##Operator k##Name;
566 482196 : CHECKED_OP_LIST(CHECKED)
567 : #undef CHECKED
568 :
569 : template <UnicodeEncoding kEncoding>
570 0 : struct StringFromCodePointOperator final : public Operator1<UnicodeEncoding> {
571 43836 : StringFromCodePointOperator()
572 : : Operator1<UnicodeEncoding>(IrOpcode::kStringFromCodePoint,
573 : Operator::kPure, "StringFromCodePoint", 1,
574 43836 : 0, 0, 1, 0, 0, kEncoding) {}
575 : };
576 : StringFromCodePointOperator<UnicodeEncoding::UTF16>
577 : kStringFromCodePointOperatorUTF16;
578 : StringFromCodePointOperator<UnicodeEncoding::UTF32>
579 : kStringFromCodePointOperatorUTF32;
580 :
581 0 : struct ArrayBufferWasNeuteredOperator final : public Operator {
582 21918 : ArrayBufferWasNeuteredOperator()
583 : : Operator(IrOpcode::kArrayBufferWasNeutered, Operator::kEliminatable,
584 21918 : "ArrayBufferWasNeutered", 1, 1, 1, 1, 1, 0) {}
585 : };
586 : ArrayBufferWasNeuteredOperator kArrayBufferWasNeutered;
587 :
588 0 : struct ArgumentsFrameOperator final : public Operator {
589 21918 : ArgumentsFrameOperator()
590 : : Operator(IrOpcode::kArgumentsFrame, Operator::kPure, "ArgumentsFrame",
591 21918 : 0, 0, 0, 1, 0, 0) {}
592 : };
593 : ArgumentsFrameOperator kArgumentsFrame;
594 :
595 0 : struct NewUnmappedArgumentsElementsOperator final : public Operator {
596 21918 : NewUnmappedArgumentsElementsOperator()
597 : : Operator(IrOpcode::kNewUnmappedArgumentsElements,
598 : Operator::kEliminatable, "NewUnmappedArgumentsElements", 2,
599 21918 : 1, 0, 1, 1, 0) {}
600 : };
601 : NewUnmappedArgumentsElementsOperator kNewUnmappedArgumentsElements;
602 :
603 : template <CheckForMinusZeroMode kMode>
604 0 : struct ChangeFloat64ToTaggedOperator final
605 : : public Operator1<CheckForMinusZeroMode> {
606 43836 : ChangeFloat64ToTaggedOperator()
607 : : Operator1<CheckForMinusZeroMode>(
608 : IrOpcode::kChangeFloat64ToTagged, Operator::kPure,
609 43836 : "ChangeFloat64ToTagged", 1, 0, 0, 1, 0, 0, kMode) {}
610 : };
611 : ChangeFloat64ToTaggedOperator<CheckForMinusZeroMode::kCheckForMinusZero>
612 : kChangeFloat64ToTaggedCheckForMinusZeroOperator;
613 : ChangeFloat64ToTaggedOperator<CheckForMinusZeroMode::kDontCheckForMinusZero>
614 : kChangeFloat64ToTaggedDontCheckForMinusZeroOperator;
615 :
616 : template <CheckForMinusZeroMode kMode>
617 0 : struct CheckedInt32MulOperator final
618 : : public Operator1<CheckForMinusZeroMode> {
619 43836 : CheckedInt32MulOperator()
620 : : Operator1<CheckForMinusZeroMode>(
621 : IrOpcode::kCheckedInt32Mul,
622 : Operator::kFoldable | Operator::kNoThrow, "CheckedInt32Mul", 2, 1,
623 43836 : 1, 1, 1, 0, kMode) {}
624 : };
625 : CheckedInt32MulOperator<CheckForMinusZeroMode::kCheckForMinusZero>
626 : kCheckedInt32MulCheckForMinusZeroOperator;
627 : CheckedInt32MulOperator<CheckForMinusZeroMode::kDontCheckForMinusZero>
628 : kCheckedInt32MulDontCheckForMinusZeroOperator;
629 :
630 : template <CheckForMinusZeroMode kMode>
631 0 : struct CheckedFloat64ToInt32Operator final
632 : : public Operator1<CheckForMinusZeroMode> {
633 43836 : CheckedFloat64ToInt32Operator()
634 : : Operator1<CheckForMinusZeroMode>(
635 : IrOpcode::kCheckedFloat64ToInt32,
636 : Operator::kFoldable | Operator::kNoThrow, "CheckedFloat64ToInt32",
637 43836 : 1, 1, 1, 1, 1, 0, kMode) {}
638 : };
639 : CheckedFloat64ToInt32Operator<CheckForMinusZeroMode::kCheckForMinusZero>
640 : kCheckedFloat64ToInt32CheckForMinusZeroOperator;
641 : CheckedFloat64ToInt32Operator<CheckForMinusZeroMode::kDontCheckForMinusZero>
642 : kCheckedFloat64ToInt32DontCheckForMinusZeroOperator;
643 :
644 : template <CheckForMinusZeroMode kMode>
645 0 : struct CheckedTaggedToInt32Operator final
646 : : public Operator1<CheckForMinusZeroMode> {
647 43836 : CheckedTaggedToInt32Operator()
648 : : Operator1<CheckForMinusZeroMode>(
649 : IrOpcode::kCheckedTaggedToInt32,
650 : Operator::kFoldable | Operator::kNoThrow, "CheckedTaggedToInt32",
651 43836 : 1, 1, 1, 1, 1, 0, kMode) {}
652 : };
653 : CheckedTaggedToInt32Operator<CheckForMinusZeroMode::kCheckForMinusZero>
654 : kCheckedTaggedToInt32CheckForMinusZeroOperator;
655 : CheckedTaggedToInt32Operator<CheckForMinusZeroMode::kDontCheckForMinusZero>
656 : kCheckedTaggedToInt32DontCheckForMinusZeroOperator;
657 :
658 : template <CheckTaggedInputMode kMode>
659 0 : struct CheckedTaggedToFloat64Operator final
660 : : public Operator1<CheckTaggedInputMode> {
661 43836 : CheckedTaggedToFloat64Operator()
662 : : Operator1<CheckTaggedInputMode>(
663 : IrOpcode::kCheckedTaggedToFloat64,
664 : Operator::kFoldable | Operator::kNoThrow,
665 43836 : "CheckedTaggedToFloat64", 1, 1, 1, 1, 1, 0, kMode) {}
666 : };
667 : CheckedTaggedToFloat64Operator<CheckTaggedInputMode::kNumber>
668 : kCheckedTaggedToFloat64NumberOperator;
669 : CheckedTaggedToFloat64Operator<CheckTaggedInputMode::kNumberOrOddball>
670 : kCheckedTaggedToFloat64NumberOrOddballOperator;
671 :
672 : template <CheckFloat64HoleMode kMode>
673 0 : struct CheckFloat64HoleNaNOperator final
674 : : public Operator1<CheckFloat64HoleMode> {
675 43836 : CheckFloat64HoleNaNOperator()
676 : : Operator1<CheckFloat64HoleMode>(
677 : IrOpcode::kCheckFloat64Hole,
678 : Operator::kFoldable | Operator::kNoThrow, "CheckFloat64Hole", 1,
679 43836 : 1, 1, 1, 1, 0, kMode) {}
680 : };
681 : CheckFloat64HoleNaNOperator<CheckFloat64HoleMode::kAllowReturnHole>
682 : kCheckFloat64HoleAllowReturnHoleOperator;
683 : CheckFloat64HoleNaNOperator<CheckFloat64HoleMode::kNeverReturnHole>
684 : kCheckFloat64HoleNeverReturnHoleOperator;
685 :
686 0 : struct EnsureWritableFastElementsOperator final : public Operator {
687 21918 : EnsureWritableFastElementsOperator()
688 : : Operator( // --
689 : IrOpcode::kEnsureWritableFastElements, // opcode
690 : Operator::kNoDeopt | Operator::kNoThrow, // flags
691 : "EnsureWritableFastElements", // name
692 21918 : 2, 1, 1, 1, 1, 0) {} // counts
693 : };
694 : EnsureWritableFastElementsOperator kEnsureWritableFastElements;
695 :
696 : #define SPECULATIVE_NUMBER_BINOP(Name) \
697 : template <NumberOperationHint kHint> \
698 : struct Name##Operator final : public Operator1<NumberOperationHint> { \
699 : Name##Operator() \
700 : : Operator1<NumberOperationHint>( \
701 : IrOpcode::k##Name, Operator::kFoldable | Operator::kNoThrow, \
702 : #Name, 2, 1, 1, 1, 1, 0, kHint) {} \
703 : }; \
704 : Name##Operator<NumberOperationHint::kSignedSmall> \
705 : k##Name##SignedSmallOperator; \
706 : Name##Operator<NumberOperationHint::kSigned32> k##Name##Signed32Operator; \
707 : Name##Operator<NumberOperationHint::kNumber> k##Name##NumberOperator; \
708 : Name##Operator<NumberOperationHint::kNumberOrOddball> \
709 : k##Name##NumberOrOddballOperator;
710 2454816 : SPECULATIVE_NUMBER_BINOP_LIST(SPECULATIVE_NUMBER_BINOP)
711 : #undef SPECULATIVE_NUMBER_BINOP
712 :
713 : template <NumberOperationHint kHint>
714 0 : struct SpeculativeToNumberOperator final
715 : : public Operator1<NumberOperationHint> {
716 87672 : SpeculativeToNumberOperator()
717 : : Operator1<NumberOperationHint>(
718 : IrOpcode::kSpeculativeToNumber, // opcode
719 : Operator::kFoldable | Operator::kNoThrow, // flags
720 : "SpeculativeToNumber", // name
721 : 1, 1, 1, 1, 1, 0, // counts
722 87672 : kHint) {} // parameter
723 : };
724 : SpeculativeToNumberOperator<NumberOperationHint::kSignedSmall>
725 : kSpeculativeToNumberSignedSmallOperator;
726 : SpeculativeToNumberOperator<NumberOperationHint::kSigned32>
727 : kSpeculativeToNumberSigned32Operator;
728 : SpeculativeToNumberOperator<NumberOperationHint::kNumber>
729 : kSpeculativeToNumberNumberOperator;
730 : SpeculativeToNumberOperator<NumberOperationHint::kNumberOrOddball>
731 : kSpeculativeToNumberNumberOrOddballOperator;
732 :
733 : #define BUFFER_ACCESS(Type, type, TYPE, ctype, size) \
734 : struct LoadBuffer##Type##Operator final : public Operator1<BufferAccess> { \
735 : LoadBuffer##Type##Operator() \
736 : : Operator1<BufferAccess>( \
737 : IrOpcode::kLoadBuffer, \
738 : Operator::kNoDeopt | Operator::kNoThrow | Operator::kNoWrite, \
739 : "LoadBuffer", 3, 1, 1, 1, 1, 0, \
740 : BufferAccess(kExternal##Type##Array)) {} \
741 : }; \
742 : struct StoreBuffer##Type##Operator final : public Operator1<BufferAccess> { \
743 : StoreBuffer##Type##Operator() \
744 : : Operator1<BufferAccess>( \
745 : IrOpcode::kStoreBuffer, \
746 : Operator::kNoDeopt | Operator::kNoRead | Operator::kNoThrow, \
747 : "StoreBuffer", 4, 1, 1, 0, 1, 0, \
748 : BufferAccess(kExternal##Type##Array)) {} \
749 : }; \
750 : LoadBuffer##Type##Operator kLoadBuffer##Type; \
751 : StoreBuffer##Type##Operator kStoreBuffer##Type;
752 789048 : TYPED_ARRAYS(BUFFER_ACCESS)
753 : #undef BUFFER_ACCESS
754 : };
755 :
756 :
757 : static base::LazyInstance<SimplifiedOperatorGlobalCache>::type kCache =
758 : LAZY_INSTANCE_INITIALIZER;
759 :
760 :
761 601572 : SimplifiedOperatorBuilder::SimplifiedOperatorBuilder(Zone* zone)
762 601573 : : cache_(kCache.Get()), zone_(zone) {}
763 :
764 : #define GET_FROM_CACHE(Name, ...) \
765 : const Operator* SimplifiedOperatorBuilder::Name() { return &cache_.k##Name; }
766 1359593 : PURE_OP_LIST(GET_FROM_CACHE)
767 469970 : CHECKED_OP_LIST(GET_FROM_CACHE)
768 271 : GET_FROM_CACHE(ArrayBufferWasNeutered)
769 4410 : GET_FROM_CACHE(ArgumentsFrame)
770 4410 : GET_FROM_CACHE(NewUnmappedArgumentsElements)
771 : #undef GET_FROM_CACHE
772 :
773 79209 : const Operator* SimplifiedOperatorBuilder::ChangeFloat64ToTagged(
774 : CheckForMinusZeroMode mode) {
775 79209 : switch (mode) {
776 : case CheckForMinusZeroMode::kCheckForMinusZero:
777 30580 : return &cache_.kChangeFloat64ToTaggedCheckForMinusZeroOperator;
778 : case CheckForMinusZeroMode::kDontCheckForMinusZero:
779 48629 : return &cache_.kChangeFloat64ToTaggedDontCheckForMinusZeroOperator;
780 : }
781 0 : UNREACHABLE();
782 : return nullptr;
783 : }
784 :
785 7143 : const Operator* SimplifiedOperatorBuilder::CheckedInt32Mul(
786 : CheckForMinusZeroMode mode) {
787 7143 : switch (mode) {
788 : case CheckForMinusZeroMode::kCheckForMinusZero:
789 4315 : return &cache_.kCheckedInt32MulCheckForMinusZeroOperator;
790 : case CheckForMinusZeroMode::kDontCheckForMinusZero:
791 2828 : return &cache_.kCheckedInt32MulDontCheckForMinusZeroOperator;
792 : }
793 0 : UNREACHABLE();
794 : return nullptr;
795 : }
796 :
797 6960 : const Operator* SimplifiedOperatorBuilder::CheckedFloat64ToInt32(
798 : CheckForMinusZeroMode mode) {
799 6960 : switch (mode) {
800 : case CheckForMinusZeroMode::kCheckForMinusZero:
801 2363 : return &cache_.kCheckedFloat64ToInt32CheckForMinusZeroOperator;
802 : case CheckForMinusZeroMode::kDontCheckForMinusZero:
803 4597 : return &cache_.kCheckedFloat64ToInt32DontCheckForMinusZeroOperator;
804 : }
805 0 : UNREACHABLE();
806 : return nullptr;
807 : }
808 :
809 3072 : const Operator* SimplifiedOperatorBuilder::CheckedTaggedToInt32(
810 : CheckForMinusZeroMode mode) {
811 3072 : switch (mode) {
812 : case CheckForMinusZeroMode::kCheckForMinusZero:
813 0 : return &cache_.kCheckedTaggedToInt32CheckForMinusZeroOperator;
814 : case CheckForMinusZeroMode::kDontCheckForMinusZero:
815 3072 : return &cache_.kCheckedTaggedToInt32DontCheckForMinusZeroOperator;
816 : }
817 0 : UNREACHABLE();
818 : return nullptr;
819 : }
820 :
821 22572 : const Operator* SimplifiedOperatorBuilder::CheckedTaggedToFloat64(
822 : CheckTaggedInputMode mode) {
823 22572 : switch (mode) {
824 : case CheckTaggedInputMode::kNumber:
825 2282 : return &cache_.kCheckedTaggedToFloat64NumberOperator;
826 : case CheckTaggedInputMode::kNumberOrOddball:
827 20290 : return &cache_.kCheckedTaggedToFloat64NumberOrOddballOperator;
828 : }
829 0 : UNREACHABLE();
830 : return nullptr;
831 : }
832 :
833 68681 : const Operator* SimplifiedOperatorBuilder::CheckMaps(CheckMapsFlags flags,
834 68681 : ZoneHandleSet<Map> maps) {
835 : CheckMapsParameters const parameters(flags, maps);
836 : return new (zone()) Operator1<CheckMapsParameters>( // --
837 : IrOpcode::kCheckMaps, // opcode
838 : Operator::kNoThrow | Operator::kNoWrite, // flags
839 : "CheckMaps", // name
840 : 1, 1, 1, 0, 1, 0, // counts
841 68681 : parameters); // parameter
842 : }
843 :
844 772 : const Operator* SimplifiedOperatorBuilder::CheckFloat64Hole(
845 : CheckFloat64HoleMode mode) {
846 772 : switch (mode) {
847 : case CheckFloat64HoleMode::kAllowReturnHole:
848 710 : return &cache_.kCheckFloat64HoleAllowReturnHoleOperator;
849 : case CheckFloat64HoleMode::kNeverReturnHole:
850 62 : return &cache_.kCheckFloat64HoleNeverReturnHoleOperator;
851 : }
852 0 : UNREACHABLE();
853 : return nullptr;
854 : }
855 :
856 2219 : const Operator* SimplifiedOperatorBuilder::SpeculativeToNumber(
857 : NumberOperationHint hint) {
858 2219 : switch (hint) {
859 : case NumberOperationHint::kSignedSmall:
860 2107 : return &cache_.kSpeculativeToNumberSignedSmallOperator;
861 : case NumberOperationHint::kSigned32:
862 0 : return &cache_.kSpeculativeToNumberSigned32Operator;
863 : case NumberOperationHint::kNumber:
864 0 : return &cache_.kSpeculativeToNumberNumberOperator;
865 : case NumberOperationHint::kNumberOrOddball:
866 112 : return &cache_.kSpeculativeToNumberNumberOrOddballOperator;
867 : }
868 0 : UNREACHABLE();
869 : return nullptr;
870 : }
871 :
872 172 : const Operator* SimplifiedOperatorBuilder::EnsureWritableFastElements() {
873 172 : return &cache_.kEnsureWritableFastElements;
874 : }
875 :
876 1398 : const Operator* SimplifiedOperatorBuilder::MaybeGrowFastElements(
877 1398 : GrowFastElementsFlags flags) {
878 : return new (zone()) Operator1<GrowFastElementsFlags>( // --
879 : IrOpcode::kMaybeGrowFastElements, // opcode
880 : Operator::kNoThrow, // flags
881 : "MaybeGrowFastElements", // name
882 : 4, 1, 1, 1, 1, 0, // counts
883 2796 : flags); // parameter
884 : }
885 :
886 433 : const Operator* SimplifiedOperatorBuilder::TransitionElementsKind(
887 433 : ElementsTransition transition) {
888 : return new (zone()) Operator1<ElementsTransition>( // --
889 : IrOpcode::kTransitionElementsKind, // opcode
890 : Operator::kNoDeopt | Operator::kNoThrow, // flags
891 : "TransitionElementsKind", // name
892 : 1, 1, 1, 0, 1, 0, // counts
893 866 : transition); // parameter
894 : }
895 :
896 : namespace {
897 :
898 : struct ArgumentsLengthParameters {
899 : int formal_parameter_count;
900 : bool is_rest_length;
901 : };
902 :
903 : bool operator==(ArgumentsLengthParameters first,
904 : ArgumentsLengthParameters second) {
905 0 : return first.formal_parameter_count == second.formal_parameter_count &&
906 : first.is_rest_length == second.is_rest_length;
907 : }
908 :
909 8551 : size_t hash_value(ArgumentsLengthParameters param) {
910 8551 : return base::hash_combine(param.formal_parameter_count, param.is_rest_length);
911 : }
912 :
913 0 : std::ostream& operator<<(std::ostream& os, ArgumentsLengthParameters param) {
914 0 : return os << param.formal_parameter_count << ", "
915 0 : << (param.is_rest_length ? "rest length" : "not rest length");
916 : }
917 :
918 : } // namespace
919 :
920 4410 : const Operator* SimplifiedOperatorBuilder::ArgumentsLength(
921 4410 : int formal_parameter_count, bool is_rest_length) {
922 : return new (zone()) Operator1<ArgumentsLengthParameters>( // --
923 : IrOpcode::kArgumentsLength, // opcode
924 : Operator::kPure, // flags
925 : "ArgumentsLength", // name
926 : 1, 0, 0, 1, 0, 0, // counts
927 : ArgumentsLengthParameters{formal_parameter_count,
928 8820 : is_rest_length}); // parameter
929 : }
930 :
931 3998 : int FormalParameterCountOf(const Operator* op) {
932 : DCHECK(op->opcode() == IrOpcode::kArgumentsLength);
933 3998 : return OpParameter<ArgumentsLengthParameters>(op).formal_parameter_count;
934 : }
935 :
936 5830 : bool IsRestLengthOf(const Operator* op) {
937 : DCHECK(op->opcode() == IrOpcode::kArgumentsLength);
938 5830 : return OpParameter<ArgumentsLengthParameters>(op).is_rest_length;
939 : }
940 :
941 160255 : const Operator* SimplifiedOperatorBuilder::Allocate(Type* type,
942 160255 : PretenureFlag pretenure) {
943 : return new (zone()) Operator1<AllocateParameters>(
944 : IrOpcode::kAllocate,
945 : Operator::kNoDeopt | Operator::kNoThrow | Operator::kNoWrite, "Allocate",
946 160256 : 1, 1, 1, 1, 1, 0, AllocateParameters(type, pretenure));
947 : }
948 :
949 :
950 5829 : const Operator* SimplifiedOperatorBuilder::LoadBuffer(BufferAccess access) {
951 5829 : switch (access.external_array_type()) {
952 : #define LOAD_BUFFER(Type, type, TYPE, ctype, size) \
953 : case kExternal##Type##Array: \
954 : return &cache_.kLoadBuffer##Type;
955 285 : TYPED_ARRAYS(LOAD_BUFFER)
956 : #undef LOAD_BUFFER
957 : }
958 0 : UNREACHABLE();
959 : return nullptr;
960 : }
961 :
962 :
963 4018 : const Operator* SimplifiedOperatorBuilder::StoreBuffer(BufferAccess access) {
964 4018 : switch (access.external_array_type()) {
965 : #define STORE_BUFFER(Type, type, TYPE, ctype, size) \
966 : case kExternal##Type##Array: \
967 : return &cache_.kStoreBuffer##Type;
968 63 : TYPED_ARRAYS(STORE_BUFFER)
969 : #undef STORE_BUFFER
970 : }
971 0 : UNREACHABLE();
972 : return nullptr;
973 : }
974 :
975 45 : const Operator* SimplifiedOperatorBuilder::StringFromCodePoint(
976 : UnicodeEncoding encoding) {
977 45 : switch (encoding) {
978 : case UnicodeEncoding::UTF16:
979 45 : return &cache_.kStringFromCodePointOperatorUTF16;
980 : case UnicodeEncoding::UTF32:
981 0 : return &cache_.kStringFromCodePointOperatorUTF32;
982 : }
983 0 : UNREACHABLE();
984 : return nullptr;
985 : }
986 :
987 : #define SPECULATIVE_NUMBER_BINOP(Name) \
988 : const Operator* SimplifiedOperatorBuilder::Name(NumberOperationHint hint) { \
989 : switch (hint) { \
990 : case NumberOperationHint::kSignedSmall: \
991 : return &cache_.k##Name##SignedSmallOperator; \
992 : case NumberOperationHint::kSigned32: \
993 : return &cache_.k##Name##Signed32Operator; \
994 : case NumberOperationHint::kNumber: \
995 : return &cache_.k##Name##NumberOperator; \
996 : case NumberOperationHint::kNumberOrOddball: \
997 : return &cache_.k##Name##NumberOrOddballOperator; \
998 : } \
999 : UNREACHABLE(); \
1000 : return nullptr; \
1001 : }
1002 328591 : SPECULATIVE_NUMBER_BINOP_LIST(SPECULATIVE_NUMBER_BINOP)
1003 : #undef SPECULATIVE_NUMBER_BINOP
1004 :
1005 : #define ACCESS_OP_LIST(V) \
1006 : V(LoadField, FieldAccess, Operator::kNoWrite, 1, 1, 1) \
1007 : V(StoreField, FieldAccess, Operator::kNoRead, 2, 1, 0) \
1008 : V(LoadElement, ElementAccess, Operator::kNoWrite, 2, 1, 1) \
1009 : V(StoreElement, ElementAccess, Operator::kNoRead, 3, 1, 0) \
1010 : V(LoadTypedElement, ExternalArrayType, Operator::kNoWrite, 4, 1, 1) \
1011 : V(StoreTypedElement, ExternalArrayType, Operator::kNoRead, 5, 1, 0)
1012 :
1013 : #define ACCESS(Name, Type, properties, value_input_count, control_input_count, \
1014 : output_count) \
1015 : const Operator* SimplifiedOperatorBuilder::Name(const Type& access) { \
1016 : return new (zone()) \
1017 : Operator1<Type>(IrOpcode::k##Name, \
1018 : Operator::kNoDeopt | Operator::kNoThrow | properties, \
1019 : #Name, value_input_count, 1, control_input_count, \
1020 : output_count, 1, 0, access); \
1021 : }
1022 7026386 : ACCESS_OP_LIST(ACCESS)
1023 : #undef ACCESS
1024 :
1025 : } // namespace compiler
1026 : } // namespace internal
1027 : } // namespace v8
|