1 // Copyright 2014 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/common-operator.h"
6
7 #include "src/assembler.h"
8 #include "src/base/lazy-instance.h"
9 #include "src/compiler/linkage.h"
10 #include "src/compiler/node.h"
11 #include "src/compiler/opcodes.h"
12 #include "src/compiler/operator.h"
13 #include "src/handles-inl.h"
14 #include "src/objects-inl.h"
15 #include "src/zone/zone.h"
16
17 namespace v8 {
18 namespace internal {
19 namespace compiler {
20
operator <<(std::ostream & os,BranchHint hint)21 std::ostream& operator<<(std::ostream& os, BranchHint hint) {
22 switch (hint) {
23 case BranchHint::kNone:
24 return os << "None";
25 case BranchHint::kTrue:
26 return os << "True";
27 case BranchHint::kFalse:
28 return os << "False";
29 }
30 UNREACHABLE();
31 return os;
32 }
33
34
BranchHintOf(const Operator * const op)35 BranchHint BranchHintOf(const Operator* const op) {
36 DCHECK_EQ(IrOpcode::kBranch, op->opcode());
37 return OpParameter<BranchHint>(op);
38 }
39
ValueInputCountOfReturn(Operator const * const op)40 int ValueInputCountOfReturn(Operator const* const op) {
41 DCHECK(op->opcode() == IrOpcode::kReturn);
42 // Return nodes have a hidden input at index 0 which we ignore in the value
43 // input count.
44 return op->ValueInputCount() - 1;
45 }
46
operator ==(DeoptimizeParameters lhs,DeoptimizeParameters rhs)47 bool operator==(DeoptimizeParameters lhs, DeoptimizeParameters rhs) {
48 return lhs.kind() == rhs.kind() && lhs.reason() == rhs.reason();
49 }
50
operator !=(DeoptimizeParameters lhs,DeoptimizeParameters rhs)51 bool operator!=(DeoptimizeParameters lhs, DeoptimizeParameters rhs) {
52 return !(lhs == rhs);
53 }
54
hash_value(DeoptimizeParameters p)55 size_t hash_value(DeoptimizeParameters p) {
56 return base::hash_combine(p.kind(), p.reason());
57 }
58
operator <<(std::ostream & os,DeoptimizeParameters p)59 std::ostream& operator<<(std::ostream& os, DeoptimizeParameters p) {
60 return os << p.kind() << ":" << p.reason();
61 }
62
DeoptimizeParametersOf(Operator const * const op)63 DeoptimizeParameters const& DeoptimizeParametersOf(Operator const* const op) {
64 DCHECK(op->opcode() == IrOpcode::kDeoptimize ||
65 op->opcode() == IrOpcode::kDeoptimizeIf ||
66 op->opcode() == IrOpcode::kDeoptimizeUnless);
67 return OpParameter<DeoptimizeParameters>(op);
68 }
69
70
operator ==(SelectParameters const & lhs,SelectParameters const & rhs)71 bool operator==(SelectParameters const& lhs, SelectParameters const& rhs) {
72 return lhs.representation() == rhs.representation() &&
73 lhs.hint() == rhs.hint();
74 }
75
76
operator !=(SelectParameters const & lhs,SelectParameters const & rhs)77 bool operator!=(SelectParameters const& lhs, SelectParameters const& rhs) {
78 return !(lhs == rhs);
79 }
80
81
hash_value(SelectParameters const & p)82 size_t hash_value(SelectParameters const& p) {
83 return base::hash_combine(p.representation(), p.hint());
84 }
85
86
operator <<(std::ostream & os,SelectParameters const & p)87 std::ostream& operator<<(std::ostream& os, SelectParameters const& p) {
88 return os << p.representation() << "|" << p.hint();
89 }
90
91
SelectParametersOf(const Operator * const op)92 SelectParameters const& SelectParametersOf(const Operator* const op) {
93 DCHECK_EQ(IrOpcode::kSelect, op->opcode());
94 return OpParameter<SelectParameters>(op);
95 }
96
CallDescriptorOf(const Operator * const op)97 CallDescriptor const* CallDescriptorOf(const Operator* const op) {
98 DCHECK(op->opcode() == IrOpcode::kCall ||
99 op->opcode() == IrOpcode::kTailCall);
100 return OpParameter<CallDescriptor const*>(op);
101 }
102
ProjectionIndexOf(const Operator * const op)103 size_t ProjectionIndexOf(const Operator* const op) {
104 DCHECK_EQ(IrOpcode::kProjection, op->opcode());
105 return OpParameter<size_t>(op);
106 }
107
108
PhiRepresentationOf(const Operator * const op)109 MachineRepresentation PhiRepresentationOf(const Operator* const op) {
110 DCHECK_EQ(IrOpcode::kPhi, op->opcode());
111 return OpParameter<MachineRepresentation>(op);
112 }
113
114
ParameterIndexOf(const Operator * const op)115 int ParameterIndexOf(const Operator* const op) {
116 DCHECK_EQ(IrOpcode::kParameter, op->opcode());
117 return OpParameter<ParameterInfo>(op).index();
118 }
119
120
ParameterInfoOf(const Operator * const op)121 const ParameterInfo& ParameterInfoOf(const Operator* const op) {
122 DCHECK_EQ(IrOpcode::kParameter, op->opcode());
123 return OpParameter<ParameterInfo>(op);
124 }
125
126
operator ==(ParameterInfo const & lhs,ParameterInfo const & rhs)127 bool operator==(ParameterInfo const& lhs, ParameterInfo const& rhs) {
128 return lhs.index() == rhs.index();
129 }
130
131
operator !=(ParameterInfo const & lhs,ParameterInfo const & rhs)132 bool operator!=(ParameterInfo const& lhs, ParameterInfo const& rhs) {
133 return !(lhs == rhs);
134 }
135
136
hash_value(ParameterInfo const & p)137 size_t hash_value(ParameterInfo const& p) { return p.index(); }
138
139
operator <<(std::ostream & os,ParameterInfo const & i)140 std::ostream& operator<<(std::ostream& os, ParameterInfo const& i) {
141 if (i.debug_name()) os << i.debug_name() << '#';
142 os << i.index();
143 return os;
144 }
145
operator ==(RelocatablePtrConstantInfo const & lhs,RelocatablePtrConstantInfo const & rhs)146 bool operator==(RelocatablePtrConstantInfo const& lhs,
147 RelocatablePtrConstantInfo const& rhs) {
148 return lhs.rmode() == rhs.rmode() && lhs.value() == rhs.value() &&
149 lhs.type() == rhs.type();
150 }
151
operator !=(RelocatablePtrConstantInfo const & lhs,RelocatablePtrConstantInfo const & rhs)152 bool operator!=(RelocatablePtrConstantInfo const& lhs,
153 RelocatablePtrConstantInfo const& rhs) {
154 return !(lhs == rhs);
155 }
156
hash_value(RelocatablePtrConstantInfo const & p)157 size_t hash_value(RelocatablePtrConstantInfo const& p) {
158 return base::hash_combine(p.value(), p.rmode(), p.type());
159 }
160
operator <<(std::ostream & os,RelocatablePtrConstantInfo const & p)161 std::ostream& operator<<(std::ostream& os,
162 RelocatablePtrConstantInfo const& p) {
163 return os << p.value() << "|" << p.rmode() << "|" << p.type();
164 }
165
InputIterator(SparseInputMask::BitMaskType bit_mask,Node * parent)166 SparseInputMask::InputIterator::InputIterator(
167 SparseInputMask::BitMaskType bit_mask, Node* parent)
168 : bit_mask_(bit_mask), parent_(parent), real_index_(0) {
169 #if DEBUG
170 if (bit_mask_ != SparseInputMask::kDenseBitMask) {
171 DCHECK_EQ(base::bits::CountPopulation(bit_mask_) -
172 base::bits::CountPopulation(kEndMarker),
173 parent->InputCount());
174 }
175 #endif
176 }
177
Advance()178 void SparseInputMask::InputIterator::Advance() {
179 DCHECK(!IsEnd());
180
181 if (IsReal()) {
182 ++real_index_;
183 }
184 bit_mask_ >>= 1;
185 }
186
GetReal() const187 Node* SparseInputMask::InputIterator::GetReal() const {
188 DCHECK(IsReal());
189 return parent_->InputAt(real_index_);
190 }
191
IsReal() const192 bool SparseInputMask::InputIterator::IsReal() const {
193 return bit_mask_ == SparseInputMask::kDenseBitMask ||
194 (bit_mask_ & kEntryMask);
195 }
196
IsEnd() const197 bool SparseInputMask::InputIterator::IsEnd() const {
198 return (bit_mask_ == kEndMarker) ||
199 (bit_mask_ == SparseInputMask::kDenseBitMask &&
200 real_index_ >= parent_->InputCount());
201 }
202
CountReal() const203 int SparseInputMask::CountReal() const {
204 DCHECK(!IsDense());
205 return base::bits::CountPopulation(bit_mask_) -
206 base::bits::CountPopulation(kEndMarker);
207 }
208
IterateOverInputs(Node * node)209 SparseInputMask::InputIterator SparseInputMask::IterateOverInputs(Node* node) {
210 DCHECK(IsDense() || CountReal() == node->InputCount());
211 return InputIterator(bit_mask_, node);
212 }
213
operator ==(SparseInputMask const & lhs,SparseInputMask const & rhs)214 bool operator==(SparseInputMask const& lhs, SparseInputMask const& rhs) {
215 return lhs.mask() == rhs.mask();
216 }
217
operator !=(SparseInputMask const & lhs,SparseInputMask const & rhs)218 bool operator!=(SparseInputMask const& lhs, SparseInputMask const& rhs) {
219 return !(lhs == rhs);
220 }
221
hash_value(SparseInputMask const & p)222 size_t hash_value(SparseInputMask const& p) {
223 return base::hash_value(p.mask());
224 }
225
operator <<(std::ostream & os,SparseInputMask const & p)226 std::ostream& operator<<(std::ostream& os, SparseInputMask const& p) {
227 if (p.IsDense()) {
228 return os << "dense";
229 } else {
230 SparseInputMask::BitMaskType mask = p.mask();
231 DCHECK_NE(mask, SparseInputMask::kDenseBitMask);
232
233 os << "sparse:";
234
235 while (mask != SparseInputMask::kEndMarker) {
236 if (mask & SparseInputMask::kEntryMask) {
237 os << "^";
238 } else {
239 os << ".";
240 }
241 mask >>= 1;
242 }
243 return os;
244 }
245 }
246
operator ==(TypedStateValueInfo const & lhs,TypedStateValueInfo const & rhs)247 bool operator==(TypedStateValueInfo const& lhs,
248 TypedStateValueInfo const& rhs) {
249 return lhs.machine_types() == rhs.machine_types() &&
250 lhs.sparse_input_mask() == rhs.sparse_input_mask();
251 }
252
operator !=(TypedStateValueInfo const & lhs,TypedStateValueInfo const & rhs)253 bool operator!=(TypedStateValueInfo const& lhs,
254 TypedStateValueInfo const& rhs) {
255 return !(lhs == rhs);
256 }
257
hash_value(TypedStateValueInfo const & p)258 size_t hash_value(TypedStateValueInfo const& p) {
259 return base::hash_combine(p.machine_types(), p.sparse_input_mask());
260 }
261
operator <<(std::ostream & os,TypedStateValueInfo const & p)262 std::ostream& operator<<(std::ostream& os, TypedStateValueInfo const& p) {
263 return os << p.machine_types() << "|" << p.sparse_input_mask();
264 }
265
hash_value(RegionObservability observability)266 size_t hash_value(RegionObservability observability) {
267 return static_cast<size_t>(observability);
268 }
269
operator <<(std::ostream & os,RegionObservability observability)270 std::ostream& operator<<(std::ostream& os, RegionObservability observability) {
271 switch (observability) {
272 case RegionObservability::kObservable:
273 return os << "observable";
274 case RegionObservability::kNotObservable:
275 return os << "not-observable";
276 }
277 UNREACHABLE();
278 return os;
279 }
280
RegionObservabilityOf(Operator const * op)281 RegionObservability RegionObservabilityOf(Operator const* op) {
282 DCHECK_EQ(IrOpcode::kBeginRegion, op->opcode());
283 return OpParameter<RegionObservability>(op);
284 }
285
TypeGuardTypeOf(Operator const * op)286 Type* TypeGuardTypeOf(Operator const* op) {
287 DCHECK_EQ(IrOpcode::kTypeGuard, op->opcode());
288 return OpParameter<Type*>(op);
289 }
290
operator <<(std::ostream & os,const ZoneVector<MachineType> * types)291 std::ostream& operator<<(std::ostream& os,
292 const ZoneVector<MachineType>* types) {
293 // Print all the MachineTypes, separated by commas.
294 bool first = true;
295 for (MachineType elem : *types) {
296 if (!first) {
297 os << ", ";
298 }
299 first = false;
300 os << elem;
301 }
302 return os;
303 }
304
OsrValueIndexOf(Operator const * op)305 int OsrValueIndexOf(Operator const* op) {
306 DCHECK_EQ(IrOpcode::kOsrValue, op->opcode());
307 return OpParameter<int>(op);
308 }
309
hash_value(OsrGuardType type)310 size_t hash_value(OsrGuardType type) { return static_cast<size_t>(type); }
311
operator <<(std::ostream & os,OsrGuardType type)312 std::ostream& operator<<(std::ostream& os, OsrGuardType type) {
313 switch (type) {
314 case OsrGuardType::kUninitialized:
315 return os << "Uninitialized";
316 case OsrGuardType::kSignedSmall:
317 return os << "SignedSmall";
318 case OsrGuardType::kAny:
319 return os << "Any";
320 }
321 UNREACHABLE();
322 return os;
323 }
324
OsrGuardTypeOf(Operator const * op)325 OsrGuardType OsrGuardTypeOf(Operator const* op) {
326 DCHECK_EQ(IrOpcode::kOsrGuard, op->opcode());
327 return OpParameter<OsrGuardType>(op);
328 }
329
SparseInputMaskOf(Operator const * op)330 SparseInputMask SparseInputMaskOf(Operator const* op) {
331 DCHECK(op->opcode() == IrOpcode::kStateValues ||
332 op->opcode() == IrOpcode::kTypedStateValues);
333
334 if (op->opcode() == IrOpcode::kTypedStateValues) {
335 return OpParameter<TypedStateValueInfo>(op).sparse_input_mask();
336 }
337 return OpParameter<SparseInputMask>(op);
338 }
339
MachineTypesOf(Operator const * op)340 ZoneVector<MachineType> const* MachineTypesOf(Operator const* op) {
341 DCHECK(op->opcode() == IrOpcode::kTypedObjectState ||
342 op->opcode() == IrOpcode::kTypedStateValues);
343
344 if (op->opcode() == IrOpcode::kTypedStateValues) {
345 return OpParameter<TypedStateValueInfo>(op).machine_types();
346 }
347 return OpParameter<const ZoneVector<MachineType>*>(op);
348 }
349
350 #define CACHED_OP_LIST(V) \
351 V(Dead, Operator::kFoldable, 0, 0, 0, 1, 1, 1) \
352 V(IfTrue, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \
353 V(IfFalse, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \
354 V(IfSuccess, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \
355 V(IfException, Operator::kKontrol, 0, 1, 1, 1, 1, 1) \
356 V(IfDefault, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \
357 V(Throw, Operator::kKontrol, 1, 1, 1, 0, 0, 1) \
358 V(Terminate, Operator::kKontrol, 0, 1, 1, 0, 0, 1) \
359 V(OsrNormalEntry, Operator::kFoldable, 0, 1, 1, 0, 1, 1) \
360 V(OsrLoopEntry, Operator::kFoldable | Operator::kNoThrow, 0, 1, 1, 0, 1, 1) \
361 V(LoopExit, Operator::kKontrol, 0, 0, 2, 0, 0, 1) \
362 V(LoopExitValue, Operator::kPure, 1, 0, 1, 1, 0, 0) \
363 V(LoopExitEffect, Operator::kNoThrow, 0, 1, 1, 0, 1, 0) \
364 V(Checkpoint, Operator::kKontrol, 0, 1, 1, 0, 1, 0) \
365 V(FinishRegion, Operator::kKontrol, 1, 1, 0, 1, 1, 0) \
366 V(Retain, Operator::kKontrol, 1, 1, 0, 0, 1, 0)
367
368 #define CACHED_RETURN_LIST(V) \
369 V(1) \
370 V(2) \
371 V(3) \
372 V(4)
373
374 #define CACHED_END_LIST(V) \
375 V(1) \
376 V(2) \
377 V(3) \
378 V(4) \
379 V(5) \
380 V(6) \
381 V(7) \
382 V(8)
383
384
385 #define CACHED_EFFECT_PHI_LIST(V) \
386 V(1) \
387 V(2) \
388 V(3) \
389 V(4) \
390 V(5) \
391 V(6)
392
393 #define CACHED_INDUCTION_VARIABLE_PHI_LIST(V) \
394 V(4) \
395 V(5) \
396 V(6) \
397 V(7)
398
399 #define CACHED_LOOP_LIST(V) \
400 V(1) \
401 V(2)
402
403
404 #define CACHED_MERGE_LIST(V) \
405 V(1) \
406 V(2) \
407 V(3) \
408 V(4) \
409 V(5) \
410 V(6) \
411 V(7) \
412 V(8)
413
414 #define CACHED_DEOPTIMIZE_LIST(V) \
415 V(Eager, MinusZero) \
416 V(Eager, NoReason) \
417 V(Eager, WrongMap) \
418 V(Soft, InsufficientTypeFeedbackForGenericKeyedAccess) \
419 V(Soft, InsufficientTypeFeedbackForGenericNamedAccess)
420
421 #define CACHED_DEOPTIMIZE_IF_LIST(V) \
422 V(Eager, DivisionByZero) \
423 V(Eager, Hole) \
424 V(Eager, MinusZero) \
425 V(Eager, Overflow) \
426 V(Eager, Smi)
427
428 #define CACHED_DEOPTIMIZE_UNLESS_LIST(V) \
429 V(Eager, LostPrecision) \
430 V(Eager, LostPrecisionOrNaN) \
431 V(Eager, NoReason) \
432 V(Eager, NotAHeapNumber) \
433 V(Eager, NotANumberOrOddball) \
434 V(Eager, NotASmi) \
435 V(Eager, OutOfBounds) \
436 V(Eager, WrongInstanceType) \
437 V(Eager, WrongMap)
438
439 #define CACHED_TRAP_IF_LIST(V) \
440 V(TrapDivUnrepresentable) \
441 V(TrapFloatUnrepresentable)
442
443 // The reason for a trap.
444 #define CACHED_TRAP_UNLESS_LIST(V) \
445 V(TrapUnreachable) \
446 V(TrapMemOutOfBounds) \
447 V(TrapDivByZero) \
448 V(TrapDivUnrepresentable) \
449 V(TrapRemByZero) \
450 V(TrapFloatUnrepresentable) \
451 V(TrapFuncInvalid) \
452 V(TrapFuncSigMismatch)
453
454 #define CACHED_PARAMETER_LIST(V) \
455 V(0) \
456 V(1) \
457 V(2) \
458 V(3) \
459 V(4) \
460 V(5) \
461 V(6)
462
463
464 #define CACHED_PHI_LIST(V) \
465 V(kTagged, 1) \
466 V(kTagged, 2) \
467 V(kTagged, 3) \
468 V(kTagged, 4) \
469 V(kTagged, 5) \
470 V(kTagged, 6) \
471 V(kBit, 2) \
472 V(kFloat64, 2) \
473 V(kWord32, 2)
474
475
476 #define CACHED_PROJECTION_LIST(V) \
477 V(0) \
478 V(1)
479
480
481 #define CACHED_STATE_VALUES_LIST(V) \
482 V(0) \
483 V(1) \
484 V(2) \
485 V(3) \
486 V(4) \
487 V(5) \
488 V(6) \
489 V(7) \
490 V(8) \
491 V(10) \
492 V(11) \
493 V(12) \
494 V(13) \
495 V(14)
496
497
498 struct CommonOperatorGlobalCache final {
499 #define CACHED(Name, properties, value_input_count, effect_input_count, \
500 control_input_count, value_output_count, effect_output_count, \
501 control_output_count) \
502 struct Name##Operator final : public Operator { \
503 Name##Operator() \
504 : Operator(IrOpcode::k##Name, properties, #Name, value_input_count, \
505 effect_input_count, control_input_count, \
506 value_output_count, effect_output_count, \
507 control_output_count) {} \
508 }; \
509 Name##Operator k##Name##Operator;
510 CACHED_OP_LIST(CACHED)
511 #undef CACHED
512
513 template <size_t kInputCount>
514 struct EndOperator final : public Operator {
EndOperatorv8::internal::compiler::CommonOperatorGlobalCache::EndOperator515 EndOperator()
516 : Operator( // --
517 IrOpcode::kEnd, Operator::kKontrol, // opcode
518 "End", // name
519 0, 0, kInputCount, 0, 0, 0) {} // counts
520 };
521 #define CACHED_END(input_count) \
522 EndOperator<input_count> kEnd##input_count##Operator;
523 CACHED_END_LIST(CACHED_END)
524 #undef CACHED_END
525
526 template <size_t kValueInputCount>
527 struct ReturnOperator final : public Operator {
ReturnOperatorv8::internal::compiler::CommonOperatorGlobalCache::ReturnOperator528 ReturnOperator()
529 : Operator( // --
530 IrOpcode::kReturn, Operator::kNoThrow, // opcode
531 "Return", // name
532 kValueInputCount + 1, 1, 1, 0, 0, 1) {} // counts
533 };
534 #define CACHED_RETURN(value_input_count) \
535 ReturnOperator<value_input_count> kReturn##value_input_count##Operator;
536 CACHED_RETURN_LIST(CACHED_RETURN)
537 #undef CACHED_RETURN
538
539 template <BranchHint kBranchHint>
540 struct BranchOperator final : public Operator1<BranchHint> {
BranchOperatorv8::internal::compiler::CommonOperatorGlobalCache::BranchOperator541 BranchOperator()
542 : Operator1<BranchHint>( // --
543 IrOpcode::kBranch, Operator::kKontrol, // opcode
544 "Branch", // name
545 1, 0, 1, 0, 0, 2, // counts
546 kBranchHint) {} // parameter
547 };
548 BranchOperator<BranchHint::kNone> kBranchNoneOperator;
549 BranchOperator<BranchHint::kTrue> kBranchTrueOperator;
550 BranchOperator<BranchHint::kFalse> kBranchFalseOperator;
551
552 template <int kEffectInputCount>
553 struct EffectPhiOperator final : public Operator {
EffectPhiOperatorv8::internal::compiler::CommonOperatorGlobalCache::EffectPhiOperator554 EffectPhiOperator()
555 : Operator( // --
556 IrOpcode::kEffectPhi, Operator::kKontrol, // opcode
557 "EffectPhi", // name
558 0, kEffectInputCount, 1, 0, 1, 0) {} // counts
559 };
560 #define CACHED_EFFECT_PHI(input_count) \
561 EffectPhiOperator<input_count> kEffectPhi##input_count##Operator;
562 CACHED_EFFECT_PHI_LIST(CACHED_EFFECT_PHI)
563 #undef CACHED_EFFECT_PHI
564
565 template <RegionObservability kRegionObservability>
566 struct BeginRegionOperator final : public Operator1<RegionObservability> {
BeginRegionOperatorv8::internal::compiler::CommonOperatorGlobalCache::BeginRegionOperator567 BeginRegionOperator()
568 : Operator1<RegionObservability>( // --
569 IrOpcode::kBeginRegion, Operator::kKontrol, // opcode
570 "BeginRegion", // name
571 0, 1, 0, 0, 1, 0, // counts
572 kRegionObservability) {} // parameter
573 };
574 BeginRegionOperator<RegionObservability::kObservable>
575 kBeginRegionObservableOperator;
576 BeginRegionOperator<RegionObservability::kNotObservable>
577 kBeginRegionNotObservableOperator;
578
579 template <size_t kInputCount>
580 struct LoopOperator final : public Operator {
LoopOperatorv8::internal::compiler::CommonOperatorGlobalCache::LoopOperator581 LoopOperator()
582 : Operator( // --
583 IrOpcode::kLoop, Operator::kKontrol, // opcode
584 "Loop", // name
585 0, 0, kInputCount, 0, 0, 1) {} // counts
586 };
587 #define CACHED_LOOP(input_count) \
588 LoopOperator<input_count> kLoop##input_count##Operator;
589 CACHED_LOOP_LIST(CACHED_LOOP)
590 #undef CACHED_LOOP
591
592 template <size_t kInputCount>
593 struct MergeOperator final : public Operator {
MergeOperatorv8::internal::compiler::CommonOperatorGlobalCache::MergeOperator594 MergeOperator()
595 : Operator( // --
596 IrOpcode::kMerge, Operator::kKontrol, // opcode
597 "Merge", // name
598 0, 0, kInputCount, 0, 0, 1) {} // counts
599 };
600 #define CACHED_MERGE(input_count) \
601 MergeOperator<input_count> kMerge##input_count##Operator;
602 CACHED_MERGE_LIST(CACHED_MERGE)
603 #undef CACHED_MERGE
604
605 template <DeoptimizeKind kKind, DeoptimizeReason kReason>
606 struct DeoptimizeOperator final : public Operator1<DeoptimizeParameters> {
DeoptimizeOperatorv8::internal::compiler::CommonOperatorGlobalCache::DeoptimizeOperator607 DeoptimizeOperator()
608 : Operator1<DeoptimizeParameters>( // --
609 IrOpcode::kDeoptimize, // opcode
610 Operator::kFoldable | Operator::kNoThrow, // properties
611 "Deoptimize", // name
612 1, 1, 1, 0, 0, 1, // counts
613 DeoptimizeParameters(kKind, kReason)) {} // parameter
614 };
615 #define CACHED_DEOPTIMIZE(Kind, Reason) \
616 DeoptimizeOperator<DeoptimizeKind::k##Kind, DeoptimizeReason::k##Reason> \
617 kDeoptimize##Kind##Reason##Operator;
618 CACHED_DEOPTIMIZE_LIST(CACHED_DEOPTIMIZE)
619 #undef CACHED_DEOPTIMIZE
620
621 template <DeoptimizeKind kKind, DeoptimizeReason kReason>
622 struct DeoptimizeIfOperator final : public Operator1<DeoptimizeParameters> {
DeoptimizeIfOperatorv8::internal::compiler::CommonOperatorGlobalCache::DeoptimizeIfOperator623 DeoptimizeIfOperator()
624 : Operator1<DeoptimizeParameters>( // --
625 IrOpcode::kDeoptimizeIf, // opcode
626 Operator::kFoldable | Operator::kNoThrow, // properties
627 "DeoptimizeIf", // name
628 2, 1, 1, 0, 1, 1, // counts
629 DeoptimizeParameters(kKind, kReason)) {} // parameter
630 };
631 #define CACHED_DEOPTIMIZE_IF(Kind, Reason) \
632 DeoptimizeIfOperator<DeoptimizeKind::k##Kind, DeoptimizeReason::k##Reason> \
633 kDeoptimizeIf##Kind##Reason##Operator;
634 CACHED_DEOPTIMIZE_IF_LIST(CACHED_DEOPTIMIZE_IF)
635 #undef CACHED_DEOPTIMIZE_IF
636
637 template <DeoptimizeKind kKind, DeoptimizeReason kReason>
638 struct DeoptimizeUnlessOperator final
639 : public Operator1<DeoptimizeParameters> {
DeoptimizeUnlessOperatorv8::internal::compiler::CommonOperatorGlobalCache::DeoptimizeUnlessOperator640 DeoptimizeUnlessOperator()
641 : Operator1<DeoptimizeParameters>( // --
642 IrOpcode::kDeoptimizeUnless, // opcode
643 Operator::kFoldable | Operator::kNoThrow, // properties
644 "DeoptimizeUnless", // name
645 2, 1, 1, 0, 1, 1, // counts
646 DeoptimizeParameters(kKind, kReason)) {} // parameter
647 };
648 #define CACHED_DEOPTIMIZE_UNLESS(Kind, Reason) \
649 DeoptimizeUnlessOperator<DeoptimizeKind::k##Kind, \
650 DeoptimizeReason::k##Reason> \
651 kDeoptimizeUnless##Kind##Reason##Operator;
652 CACHED_DEOPTIMIZE_UNLESS_LIST(CACHED_DEOPTIMIZE_UNLESS)
653 #undef CACHED_DEOPTIMIZE_UNLESS
654
655 template <int32_t trap_id>
656 struct TrapIfOperator final : public Operator1<int32_t> {
TrapIfOperatorv8::internal::compiler::CommonOperatorGlobalCache::TrapIfOperator657 TrapIfOperator()
658 : Operator1<int32_t>( // --
659 IrOpcode::kTrapIf, // opcode
660 Operator::kFoldable | Operator::kNoThrow, // properties
661 "TrapIf", // name
662 1, 1, 1, 0, 0, 1, // counts
663 trap_id) {} // parameter
664 };
665 #define CACHED_TRAP_IF(Trap) \
666 TrapIfOperator<static_cast<int32_t>(Builtins::kThrowWasm##Trap)> \
667 kTrapIf##Trap##Operator;
668 CACHED_TRAP_IF_LIST(CACHED_TRAP_IF)
669 #undef CACHED_TRAP_IF
670
671 template <int32_t trap_id>
672 struct TrapUnlessOperator final : public Operator1<int32_t> {
TrapUnlessOperatorv8::internal::compiler::CommonOperatorGlobalCache::TrapUnlessOperator673 TrapUnlessOperator()
674 : Operator1<int32_t>( // --
675 IrOpcode::kTrapUnless, // opcode
676 Operator::kFoldable | Operator::kNoThrow, // properties
677 "TrapUnless", // name
678 1, 1, 1, 0, 0, 1, // counts
679 trap_id) {} // parameter
680 };
681 #define CACHED_TRAP_UNLESS(Trap) \
682 TrapUnlessOperator<static_cast<int32_t>(Builtins::kThrowWasm##Trap)> \
683 kTrapUnless##Trap##Operator;
684 CACHED_TRAP_UNLESS_LIST(CACHED_TRAP_UNLESS)
685 #undef CACHED_TRAP_UNLESS
686
687 template <MachineRepresentation kRep, int kInputCount>
688 struct PhiOperator final : public Operator1<MachineRepresentation> {
PhiOperatorv8::internal::compiler::CommonOperatorGlobalCache::PhiOperator689 PhiOperator()
690 : Operator1<MachineRepresentation>( //--
691 IrOpcode::kPhi, Operator::kPure, // opcode
692 "Phi", // name
693 kInputCount, 0, 1, 1, 0, 0, // counts
694 kRep) {} // parameter
695 };
696 #define CACHED_PHI(rep, input_count) \
697 PhiOperator<MachineRepresentation::rep, input_count> \
698 kPhi##rep##input_count##Operator;
699 CACHED_PHI_LIST(CACHED_PHI)
700 #undef CACHED_PHI
701
702 template <int kInputCount>
703 struct InductionVariablePhiOperator final : public Operator {
InductionVariablePhiOperatorv8::internal::compiler::CommonOperatorGlobalCache::InductionVariablePhiOperator704 InductionVariablePhiOperator()
705 : Operator( //--
706 IrOpcode::kInductionVariablePhi, Operator::kPure, // opcode
707 "InductionVariablePhi", // name
708 kInputCount, 0, 1, 1, 0, 0) {} // counts
709 };
710 #define CACHED_INDUCTION_VARIABLE_PHI(input_count) \
711 InductionVariablePhiOperator<input_count> \
712 kInductionVariablePhi##input_count##Operator;
713 CACHED_INDUCTION_VARIABLE_PHI_LIST(CACHED_INDUCTION_VARIABLE_PHI)
714 #undef CACHED_INDUCTION_VARIABLE_PHI
715
716 template <int kIndex>
717 struct ParameterOperator final : public Operator1<ParameterInfo> {
ParameterOperatorv8::internal::compiler::CommonOperatorGlobalCache::ParameterOperator718 ParameterOperator()
719 : Operator1<ParameterInfo>( // --
720 IrOpcode::kParameter, Operator::kPure, // opcode
721 "Parameter", // name
722 1, 0, 0, 1, 0, 0, // counts,
723 ParameterInfo(kIndex, nullptr)) {} // parameter and name
724 };
725 #define CACHED_PARAMETER(index) \
726 ParameterOperator<index> kParameter##index##Operator;
727 CACHED_PARAMETER_LIST(CACHED_PARAMETER)
728 #undef CACHED_PARAMETER
729
730 template <size_t kIndex>
731 struct ProjectionOperator final : public Operator1<size_t> {
ProjectionOperatorv8::internal::compiler::CommonOperatorGlobalCache::ProjectionOperator732 ProjectionOperator()
733 : Operator1<size_t>( // --
734 IrOpcode::kProjection, // opcode
735 Operator::kPure, // flags
736 "Projection", // name
737 1, 0, 1, 1, 0, 0, // counts,
738 kIndex) {} // parameter
739 };
740 #define CACHED_PROJECTION(index) \
741 ProjectionOperator<index> kProjection##index##Operator;
742 CACHED_PROJECTION_LIST(CACHED_PROJECTION)
743 #undef CACHED_PROJECTION
744
745 template <int kInputCount>
746 struct StateValuesOperator final : public Operator1<SparseInputMask> {
StateValuesOperatorv8::internal::compiler::CommonOperatorGlobalCache::StateValuesOperator747 StateValuesOperator()
748 : Operator1<SparseInputMask>( // --
749 IrOpcode::kStateValues, // opcode
750 Operator::kPure, // flags
751 "StateValues", // name
752 kInputCount, 0, 0, 1, 0, 0, // counts
753 SparseInputMask::Dense()) {} // parameter
754 };
755 #define CACHED_STATE_VALUES(input_count) \
756 StateValuesOperator<input_count> kStateValues##input_count##Operator;
757 CACHED_STATE_VALUES_LIST(CACHED_STATE_VALUES)
758 #undef CACHED_STATE_VALUES
759 };
760
761
762 static base::LazyInstance<CommonOperatorGlobalCache>::type kCache =
763 LAZY_INSTANCE_INITIALIZER;
764
765
CommonOperatorBuilder(Zone * zone)766 CommonOperatorBuilder::CommonOperatorBuilder(Zone* zone)
767 : cache_(kCache.Get()), zone_(zone) {}
768
769
770 #define CACHED(Name, properties, value_input_count, effect_input_count, \
771 control_input_count, value_output_count, effect_output_count, \
772 control_output_count) \
773 const Operator* CommonOperatorBuilder::Name() { \
774 return &cache_.k##Name##Operator; \
775 }
CACHED_OP_LIST(CACHED) const776 CACHED_OP_LIST(CACHED)
777 #undef CACHED
778
779
780 const Operator* CommonOperatorBuilder::End(size_t control_input_count) {
781 switch (control_input_count) {
782 #define CACHED_END(input_count) \
783 case input_count: \
784 return &cache_.kEnd##input_count##Operator;
785 CACHED_END_LIST(CACHED_END)
786 #undef CACHED_END
787 default:
788 break;
789 }
790 // Uncached.
791 return new (zone()) Operator( //--
792 IrOpcode::kEnd, Operator::kKontrol, // opcode
793 "End", // name
794 0, 0, control_input_count, 0, 0, 0); // counts
795 }
796
Return(int value_input_count)797 const Operator* CommonOperatorBuilder::Return(int value_input_count) {
798 switch (value_input_count) {
799 #define CACHED_RETURN(input_count) \
800 case input_count: \
801 return &cache_.kReturn##input_count##Operator;
802 CACHED_RETURN_LIST(CACHED_RETURN)
803 #undef CACHED_RETURN
804 default:
805 break;
806 }
807 // Uncached.
808 return new (zone()) Operator( //--
809 IrOpcode::kReturn, Operator::kNoThrow, // opcode
810 "Return", // name
811 value_input_count + 1, 1, 1, 0, 0, 1); // counts
812 }
813
814
Branch(BranchHint hint)815 const Operator* CommonOperatorBuilder::Branch(BranchHint hint) {
816 switch (hint) {
817 case BranchHint::kNone:
818 return &cache_.kBranchNoneOperator;
819 case BranchHint::kTrue:
820 return &cache_.kBranchTrueOperator;
821 case BranchHint::kFalse:
822 return &cache_.kBranchFalseOperator;
823 }
824 UNREACHABLE();
825 return nullptr;
826 }
827
Deoptimize(DeoptimizeKind kind,DeoptimizeReason reason)828 const Operator* CommonOperatorBuilder::Deoptimize(DeoptimizeKind kind,
829 DeoptimizeReason reason) {
830 #define CACHED_DEOPTIMIZE(Kind, Reason) \
831 if (kind == DeoptimizeKind::k##Kind && \
832 reason == DeoptimizeReason::k##Reason) { \
833 return &cache_.kDeoptimize##Kind##Reason##Operator; \
834 }
835 CACHED_DEOPTIMIZE_LIST(CACHED_DEOPTIMIZE)
836 #undef CACHED_DEOPTIMIZE
837 // Uncached
838 DeoptimizeParameters parameter(kind, reason);
839 return new (zone()) Operator1<DeoptimizeParameters>( // --
840 IrOpcode::kDeoptimize, // opcodes
841 Operator::kFoldable | Operator::kNoThrow, // properties
842 "Deoptimize", // name
843 1, 1, 1, 0, 0, 1, // counts
844 parameter); // parameter
845 }
846
DeoptimizeIf(DeoptimizeKind kind,DeoptimizeReason reason)847 const Operator* CommonOperatorBuilder::DeoptimizeIf(DeoptimizeKind kind,
848 DeoptimizeReason reason) {
849 #define CACHED_DEOPTIMIZE_IF(Kind, Reason) \
850 if (kind == DeoptimizeKind::k##Kind && \
851 reason == DeoptimizeReason::k##Reason) { \
852 return &cache_.kDeoptimizeIf##Kind##Reason##Operator; \
853 }
854 CACHED_DEOPTIMIZE_IF_LIST(CACHED_DEOPTIMIZE_IF)
855 #undef CACHED_DEOPTIMIZE_IF
856 // Uncached
857 DeoptimizeParameters parameter(kind, reason);
858 return new (zone()) Operator1<DeoptimizeParameters>( // --
859 IrOpcode::kDeoptimizeIf, // opcode
860 Operator::kFoldable | Operator::kNoThrow, // properties
861 "DeoptimizeIf", // name
862 2, 1, 1, 0, 1, 1, // counts
863 parameter); // parameter
864 }
865
DeoptimizeUnless(DeoptimizeKind kind,DeoptimizeReason reason)866 const Operator* CommonOperatorBuilder::DeoptimizeUnless(
867 DeoptimizeKind kind, DeoptimizeReason reason) {
868 #define CACHED_DEOPTIMIZE_UNLESS(Kind, Reason) \
869 if (kind == DeoptimizeKind::k##Kind && \
870 reason == DeoptimizeReason::k##Reason) { \
871 return &cache_.kDeoptimizeUnless##Kind##Reason##Operator; \
872 }
873 CACHED_DEOPTIMIZE_UNLESS_LIST(CACHED_DEOPTIMIZE_UNLESS)
874 #undef CACHED_DEOPTIMIZE_UNLESS
875 // Uncached
876 DeoptimizeParameters parameter(kind, reason);
877 return new (zone()) Operator1<DeoptimizeParameters>( // --
878 IrOpcode::kDeoptimizeUnless, // opcode
879 Operator::kFoldable | Operator::kNoThrow, // properties
880 "DeoptimizeUnless", // name
881 2, 1, 1, 0, 1, 1, // counts
882 parameter); // parameter
883 }
884
TrapIf(int32_t trap_id)885 const Operator* CommonOperatorBuilder::TrapIf(int32_t trap_id) {
886 switch (trap_id) {
887 #define CACHED_TRAP_IF(Trap) \
888 case Builtins::kThrowWasm##Trap: \
889 return &cache_.kTrapIf##Trap##Operator;
890 CACHED_TRAP_IF_LIST(CACHED_TRAP_IF)
891 #undef CACHED_TRAP_IF
892 default:
893 break;
894 }
895 // Uncached
896 return new (zone()) Operator1<int>( // --
897 IrOpcode::kTrapIf, // opcode
898 Operator::kFoldable | Operator::kNoThrow, // properties
899 "TrapIf", // name
900 1, 1, 1, 0, 0, 1, // counts
901 trap_id); // parameter
902 }
903
TrapUnless(int32_t trap_id)904 const Operator* CommonOperatorBuilder::TrapUnless(int32_t trap_id) {
905 switch (trap_id) {
906 #define CACHED_TRAP_UNLESS(Trap) \
907 case Builtins::kThrowWasm##Trap: \
908 return &cache_.kTrapUnless##Trap##Operator;
909 CACHED_TRAP_UNLESS_LIST(CACHED_TRAP_UNLESS)
910 #undef CACHED_TRAP_UNLESS
911 default:
912 break;
913 }
914 // Uncached
915 return new (zone()) Operator1<int>( // --
916 IrOpcode::kTrapUnless, // opcode
917 Operator::kFoldable | Operator::kNoThrow, // properties
918 "TrapUnless", // name
919 1, 1, 1, 0, 0, 1, // counts
920 trap_id); // parameter
921 }
922
Switch(size_t control_output_count)923 const Operator* CommonOperatorBuilder::Switch(size_t control_output_count) {
924 return new (zone()) Operator( // --
925 IrOpcode::kSwitch, Operator::kKontrol, // opcode
926 "Switch", // name
927 1, 0, 1, 0, 0, control_output_count); // counts
928 }
929
930
IfValue(int32_t index)931 const Operator* CommonOperatorBuilder::IfValue(int32_t index) {
932 return new (zone()) Operator1<int32_t>( // --
933 IrOpcode::kIfValue, Operator::kKontrol, // opcode
934 "IfValue", // name
935 0, 0, 1, 0, 0, 1, // counts
936 index); // parameter
937 }
938
939
Start(int value_output_count)940 const Operator* CommonOperatorBuilder::Start(int value_output_count) {
941 return new (zone()) Operator( // --
942 IrOpcode::kStart, Operator::kFoldable | Operator::kNoThrow, // opcode
943 "Start", // name
944 0, 0, 0, value_output_count, 1, 1); // counts
945 }
946
947
Loop(int control_input_count)948 const Operator* CommonOperatorBuilder::Loop(int control_input_count) {
949 switch (control_input_count) {
950 #define CACHED_LOOP(input_count) \
951 case input_count: \
952 return &cache_.kLoop##input_count##Operator;
953 CACHED_LOOP_LIST(CACHED_LOOP)
954 #undef CACHED_LOOP
955 default:
956 break;
957 }
958 // Uncached.
959 return new (zone()) Operator( // --
960 IrOpcode::kLoop, Operator::kKontrol, // opcode
961 "Loop", // name
962 0, 0, control_input_count, 0, 0, 1); // counts
963 }
964
965
Merge(int control_input_count)966 const Operator* CommonOperatorBuilder::Merge(int control_input_count) {
967 switch (control_input_count) {
968 #define CACHED_MERGE(input_count) \
969 case input_count: \
970 return &cache_.kMerge##input_count##Operator;
971 CACHED_MERGE_LIST(CACHED_MERGE)
972 #undef CACHED_MERGE
973 default:
974 break;
975 }
976 // Uncached.
977 return new (zone()) Operator( // --
978 IrOpcode::kMerge, Operator::kKontrol, // opcode
979 "Merge", // name
980 0, 0, control_input_count, 0, 0, 1); // counts
981 }
982
983
Parameter(int index,const char * debug_name)984 const Operator* CommonOperatorBuilder::Parameter(int index,
985 const char* debug_name) {
986 if (!debug_name) {
987 switch (index) {
988 #define CACHED_PARAMETER(index) \
989 case index: \
990 return &cache_.kParameter##index##Operator;
991 CACHED_PARAMETER_LIST(CACHED_PARAMETER)
992 #undef CACHED_PARAMETER
993 default:
994 break;
995 }
996 }
997 // Uncached.
998 return new (zone()) Operator1<ParameterInfo>( // --
999 IrOpcode::kParameter, Operator::kPure, // opcode
1000 "Parameter", // name
1001 1, 0, 0, 1, 0, 0, // counts
1002 ParameterInfo(index, debug_name)); // parameter info
1003 }
1004
OsrValue(int index)1005 const Operator* CommonOperatorBuilder::OsrValue(int index) {
1006 return new (zone()) Operator1<int>( // --
1007 IrOpcode::kOsrValue, Operator::kNoProperties, // opcode
1008 "OsrValue", // name
1009 0, 0, 1, 1, 0, 0, // counts
1010 index); // parameter
1011 }
1012
OsrGuard(OsrGuardType type)1013 const Operator* CommonOperatorBuilder::OsrGuard(OsrGuardType type) {
1014 return new (zone()) Operator1<OsrGuardType>( // --
1015 IrOpcode::kOsrGuard, Operator::kNoThrow, // opcode
1016 "OsrGuard", // name
1017 1, 1, 1, 1, 1, 0, // counts
1018 type); // parameter
1019 }
1020
Int32Constant(int32_t value)1021 const Operator* CommonOperatorBuilder::Int32Constant(int32_t value) {
1022 return new (zone()) Operator1<int32_t>( // --
1023 IrOpcode::kInt32Constant, Operator::kPure, // opcode
1024 "Int32Constant", // name
1025 0, 0, 0, 1, 0, 0, // counts
1026 value); // parameter
1027 }
1028
1029
Int64Constant(int64_t value)1030 const Operator* CommonOperatorBuilder::Int64Constant(int64_t value) {
1031 return new (zone()) Operator1<int64_t>( // --
1032 IrOpcode::kInt64Constant, Operator::kPure, // opcode
1033 "Int64Constant", // name
1034 0, 0, 0, 1, 0, 0, // counts
1035 value); // parameter
1036 }
1037
1038
Float32Constant(volatile float value)1039 const Operator* CommonOperatorBuilder::Float32Constant(volatile float value) {
1040 return new (zone()) Operator1<float>( // --
1041 IrOpcode::kFloat32Constant, Operator::kPure, // opcode
1042 "Float32Constant", // name
1043 0, 0, 0, 1, 0, 0, // counts
1044 value); // parameter
1045 }
1046
1047
Float64Constant(volatile double value)1048 const Operator* CommonOperatorBuilder::Float64Constant(volatile double value) {
1049 return new (zone()) Operator1<double>( // --
1050 IrOpcode::kFloat64Constant, Operator::kPure, // opcode
1051 "Float64Constant", // name
1052 0, 0, 0, 1, 0, 0, // counts
1053 value); // parameter
1054 }
1055
1056
ExternalConstant(const ExternalReference & value)1057 const Operator* CommonOperatorBuilder::ExternalConstant(
1058 const ExternalReference& value) {
1059 return new (zone()) Operator1<ExternalReference>( // --
1060 IrOpcode::kExternalConstant, Operator::kPure, // opcode
1061 "ExternalConstant", // name
1062 0, 0, 0, 1, 0, 0, // counts
1063 value); // parameter
1064 }
1065
1066
NumberConstant(volatile double value)1067 const Operator* CommonOperatorBuilder::NumberConstant(volatile double value) {
1068 return new (zone()) Operator1<double>( // --
1069 IrOpcode::kNumberConstant, Operator::kPure, // opcode
1070 "NumberConstant", // name
1071 0, 0, 0, 1, 0, 0, // counts
1072 value); // parameter
1073 }
1074
PointerConstant(intptr_t value)1075 const Operator* CommonOperatorBuilder::PointerConstant(intptr_t value) {
1076 return new (zone()) Operator1<intptr_t>( // --
1077 IrOpcode::kPointerConstant, Operator::kPure, // opcode
1078 "PointerConstant", // name
1079 0, 0, 0, 1, 0, 0, // counts
1080 value); // parameter
1081 }
1082
HeapConstant(const Handle<HeapObject> & value)1083 const Operator* CommonOperatorBuilder::HeapConstant(
1084 const Handle<HeapObject>& value) {
1085 return new (zone()) Operator1<Handle<HeapObject>>( // --
1086 IrOpcode::kHeapConstant, Operator::kPure, // opcode
1087 "HeapConstant", // name
1088 0, 0, 0, 1, 0, 0, // counts
1089 value); // parameter
1090 }
1091
RelocatableInt32Constant(int32_t value,RelocInfo::Mode rmode)1092 const Operator* CommonOperatorBuilder::RelocatableInt32Constant(
1093 int32_t value, RelocInfo::Mode rmode) {
1094 return new (zone()) Operator1<RelocatablePtrConstantInfo>( // --
1095 IrOpcode::kRelocatableInt32Constant, Operator::kPure, // opcode
1096 "RelocatableInt32Constant", // name
1097 0, 0, 0, 1, 0, 0, // counts
1098 RelocatablePtrConstantInfo(value, rmode)); // parameter
1099 }
1100
RelocatableInt64Constant(int64_t value,RelocInfo::Mode rmode)1101 const Operator* CommonOperatorBuilder::RelocatableInt64Constant(
1102 int64_t value, RelocInfo::Mode rmode) {
1103 return new (zone()) Operator1<RelocatablePtrConstantInfo>( // --
1104 IrOpcode::kRelocatableInt64Constant, Operator::kPure, // opcode
1105 "RelocatableInt64Constant", // name
1106 0, 0, 0, 1, 0, 0, // counts
1107 RelocatablePtrConstantInfo(value, rmode)); // parameter
1108 }
1109
Select(MachineRepresentation rep,BranchHint hint)1110 const Operator* CommonOperatorBuilder::Select(MachineRepresentation rep,
1111 BranchHint hint) {
1112 return new (zone()) Operator1<SelectParameters>( // --
1113 IrOpcode::kSelect, Operator::kPure, // opcode
1114 "Select", // name
1115 3, 0, 0, 1, 0, 0, // counts
1116 SelectParameters(rep, hint)); // parameter
1117 }
1118
1119
Phi(MachineRepresentation rep,int value_input_count)1120 const Operator* CommonOperatorBuilder::Phi(MachineRepresentation rep,
1121 int value_input_count) {
1122 DCHECK(value_input_count > 0); // Disallow empty phis.
1123 #define CACHED_PHI(kRep, kValueInputCount) \
1124 if (MachineRepresentation::kRep == rep && \
1125 kValueInputCount == value_input_count) { \
1126 return &cache_.kPhi##kRep##kValueInputCount##Operator; \
1127 }
1128 CACHED_PHI_LIST(CACHED_PHI)
1129 #undef CACHED_PHI
1130 // Uncached.
1131 return new (zone()) Operator1<MachineRepresentation>( // --
1132 IrOpcode::kPhi, Operator::kPure, // opcode
1133 "Phi", // name
1134 value_input_count, 0, 1, 1, 0, 0, // counts
1135 rep); // parameter
1136 }
1137
TypeGuard(Type * type)1138 const Operator* CommonOperatorBuilder::TypeGuard(Type* type) {
1139 return new (zone()) Operator1<Type*>( // --
1140 IrOpcode::kTypeGuard, Operator::kPure, // opcode
1141 "TypeGuard", // name
1142 1, 0, 1, 1, 0, 0, // counts
1143 type); // parameter
1144 }
1145
EffectPhi(int effect_input_count)1146 const Operator* CommonOperatorBuilder::EffectPhi(int effect_input_count) {
1147 DCHECK(effect_input_count > 0); // Disallow empty effect phis.
1148 switch (effect_input_count) {
1149 #define CACHED_EFFECT_PHI(input_count) \
1150 case input_count: \
1151 return &cache_.kEffectPhi##input_count##Operator;
1152 CACHED_EFFECT_PHI_LIST(CACHED_EFFECT_PHI)
1153 #undef CACHED_EFFECT_PHI
1154 default:
1155 break;
1156 }
1157 // Uncached.
1158 return new (zone()) Operator( // --
1159 IrOpcode::kEffectPhi, Operator::kKontrol, // opcode
1160 "EffectPhi", // name
1161 0, effect_input_count, 1, 0, 1, 0); // counts
1162 }
1163
InductionVariablePhi(int input_count)1164 const Operator* CommonOperatorBuilder::InductionVariablePhi(int input_count) {
1165 DCHECK(input_count >= 4); // There must be always the entry, backedge,
1166 // increment and at least one bound.
1167 switch (input_count) {
1168 #define CACHED_INDUCTION_VARIABLE_PHI(input_count) \
1169 case input_count: \
1170 return &cache_.kInductionVariablePhi##input_count##Operator;
1171 CACHED_INDUCTION_VARIABLE_PHI_LIST(CACHED_INDUCTION_VARIABLE_PHI)
1172 #undef CACHED_INDUCTION_VARIABLE_PHI
1173 default:
1174 break;
1175 }
1176 // Uncached.
1177 return new (zone()) Operator( // --
1178 IrOpcode::kInductionVariablePhi, Operator::kPure, // opcode
1179 "InductionVariablePhi", // name
1180 input_count, 0, 1, 1, 0, 0); // counts
1181 }
1182
BeginRegion(RegionObservability region_observability)1183 const Operator* CommonOperatorBuilder::BeginRegion(
1184 RegionObservability region_observability) {
1185 switch (region_observability) {
1186 case RegionObservability::kObservable:
1187 return &cache_.kBeginRegionObservableOperator;
1188 case RegionObservability::kNotObservable:
1189 return &cache_.kBeginRegionNotObservableOperator;
1190 }
1191 UNREACHABLE();
1192 return nullptr;
1193 }
1194
StateValues(int arguments,SparseInputMask bitmask)1195 const Operator* CommonOperatorBuilder::StateValues(int arguments,
1196 SparseInputMask bitmask) {
1197 if (bitmask.IsDense()) {
1198 switch (arguments) {
1199 #define CACHED_STATE_VALUES(arguments) \
1200 case arguments: \
1201 return &cache_.kStateValues##arguments##Operator;
1202 CACHED_STATE_VALUES_LIST(CACHED_STATE_VALUES)
1203 #undef CACHED_STATE_VALUES
1204 default:
1205 break;
1206 }
1207 }
1208
1209 #if DEBUG
1210 DCHECK(bitmask.IsDense() || bitmask.CountReal() == arguments);
1211 #endif
1212
1213 // Uncached.
1214 return new (zone()) Operator1<SparseInputMask>( // --
1215 IrOpcode::kStateValues, Operator::kPure, // opcode
1216 "StateValues", // name
1217 arguments, 0, 0, 1, 0, 0, // counts
1218 bitmask); // parameter
1219 }
1220
TypedStateValues(const ZoneVector<MachineType> * types,SparseInputMask bitmask)1221 const Operator* CommonOperatorBuilder::TypedStateValues(
1222 const ZoneVector<MachineType>* types, SparseInputMask bitmask) {
1223 #if DEBUG
1224 DCHECK(bitmask.IsDense() ||
1225 bitmask.CountReal() == static_cast<int>(types->size()));
1226 #endif
1227
1228 return new (zone()) Operator1<TypedStateValueInfo>( // --
1229 IrOpcode::kTypedStateValues, Operator::kPure, // opcode
1230 "TypedStateValues", // name
1231 static_cast<int>(types->size()), 0, 0, 1, 0, 0, // counts
1232 TypedStateValueInfo(types, bitmask)); // parameters
1233 }
1234
ArgumentsObjectState()1235 const Operator* CommonOperatorBuilder::ArgumentsObjectState() {
1236 return new (zone()) Operator( // --
1237 IrOpcode::kArgumentsObjectState, Operator::kPure, // opcode
1238 "ArgumentsObjectState", // name
1239 0, 0, 0, 1, 0, 0); // counts
1240 }
1241
ObjectState(int pointer_slots)1242 const Operator* CommonOperatorBuilder::ObjectState(int pointer_slots) {
1243 return new (zone()) Operator1<int>( // --
1244 IrOpcode::kObjectState, Operator::kPure, // opcode
1245 "ObjectState", // name
1246 pointer_slots, 0, 0, 1, 0, 0, // counts
1247 pointer_slots); // parameter
1248 }
1249
TypedObjectState(const ZoneVector<MachineType> * types)1250 const Operator* CommonOperatorBuilder::TypedObjectState(
1251 const ZoneVector<MachineType>* types) {
1252 return new (zone()) Operator1<const ZoneVector<MachineType>*>( // --
1253 IrOpcode::kTypedObjectState, Operator::kPure, // opcode
1254 "TypedObjectState", // name
1255 static_cast<int>(types->size()), 0, 0, 1, 0, 0, // counts
1256 types); // parameter
1257 }
1258
FrameState(BailoutId bailout_id,OutputFrameStateCombine state_combine,const FrameStateFunctionInfo * function_info)1259 const Operator* CommonOperatorBuilder::FrameState(
1260 BailoutId bailout_id, OutputFrameStateCombine state_combine,
1261 const FrameStateFunctionInfo* function_info) {
1262 FrameStateInfo state_info(bailout_id, state_combine, function_info);
1263 return new (zone()) Operator1<FrameStateInfo>( // --
1264 IrOpcode::kFrameState, Operator::kPure, // opcode
1265 "FrameState", // name
1266 5, 0, 0, 1, 0, 0, // counts
1267 state_info); // parameter
1268 }
1269
1270
Call(const CallDescriptor * descriptor)1271 const Operator* CommonOperatorBuilder::Call(const CallDescriptor* descriptor) {
1272 class CallOperator final : public Operator1<const CallDescriptor*> {
1273 public:
1274 explicit CallOperator(const CallDescriptor* descriptor)
1275 : Operator1<const CallDescriptor*>(
1276 IrOpcode::kCall, descriptor->properties(), "Call",
1277 descriptor->InputCount() + descriptor->FrameStateCount(),
1278 Operator::ZeroIfPure(descriptor->properties()),
1279 Operator::ZeroIfEliminatable(descriptor->properties()),
1280 descriptor->ReturnCount(),
1281 Operator::ZeroIfPure(descriptor->properties()),
1282 Operator::ZeroIfNoThrow(descriptor->properties()), descriptor) {}
1283
1284 void PrintParameter(std::ostream& os, PrintVerbosity verbose) const {
1285 os << "[" << *parameter() << "]";
1286 }
1287 };
1288 return new (zone()) CallOperator(descriptor);
1289 }
1290
1291
TailCall(const CallDescriptor * descriptor)1292 const Operator* CommonOperatorBuilder::TailCall(
1293 const CallDescriptor* descriptor) {
1294 class TailCallOperator final : public Operator1<const CallDescriptor*> {
1295 public:
1296 explicit TailCallOperator(const CallDescriptor* descriptor)
1297 : Operator1<const CallDescriptor*>(
1298 IrOpcode::kTailCall,
1299 descriptor->properties() | Operator::kNoThrow, "TailCall",
1300 descriptor->InputCount() + descriptor->FrameStateCount(), 1, 1, 0,
1301 0, 1, descriptor) {}
1302
1303 void PrintParameter(std::ostream& os, PrintVerbosity verbose) const {
1304 os << "[" << *parameter() << "]";
1305 }
1306 };
1307 return new (zone()) TailCallOperator(descriptor);
1308 }
1309
1310
Projection(size_t index)1311 const Operator* CommonOperatorBuilder::Projection(size_t index) {
1312 switch (index) {
1313 #define CACHED_PROJECTION(index) \
1314 case index: \
1315 return &cache_.kProjection##index##Operator;
1316 CACHED_PROJECTION_LIST(CACHED_PROJECTION)
1317 #undef CACHED_PROJECTION
1318 default:
1319 break;
1320 }
1321 // Uncached.
1322 return new (zone()) Operator1<size_t>( // --
1323 IrOpcode::kProjection, // opcode
1324 Operator::kPure, // flags
1325 "Projection", // name
1326 1, 0, 1, 1, 0, 0, // counts
1327 index); // parameter
1328 }
1329
1330
ResizeMergeOrPhi(const Operator * op,int size)1331 const Operator* CommonOperatorBuilder::ResizeMergeOrPhi(const Operator* op,
1332 int size) {
1333 if (op->opcode() == IrOpcode::kPhi) {
1334 return Phi(PhiRepresentationOf(op), size);
1335 } else if (op->opcode() == IrOpcode::kEffectPhi) {
1336 return EffectPhi(size);
1337 } else if (op->opcode() == IrOpcode::kMerge) {
1338 return Merge(size);
1339 } else if (op->opcode() == IrOpcode::kLoop) {
1340 return Loop(size);
1341 } else {
1342 UNREACHABLE();
1343 return nullptr;
1344 }
1345 }
1346
1347 const FrameStateFunctionInfo*
CreateFrameStateFunctionInfo(FrameStateType type,int parameter_count,int local_count,Handle<SharedFunctionInfo> shared_info)1348 CommonOperatorBuilder::CreateFrameStateFunctionInfo(
1349 FrameStateType type, int parameter_count, int local_count,
1350 Handle<SharedFunctionInfo> shared_info) {
1351 return new (zone()->New(sizeof(FrameStateFunctionInfo)))
1352 FrameStateFunctionInfo(type, parameter_count, local_count, shared_info);
1353 }
1354
1355 } // namespace compiler
1356 } // namespace internal
1357 } // namespace v8
1358