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/opcodes.h"
11 #include "src/compiler/operator.h"
12 #include "src/handles-inl.h"
13 #include "src/zone.h"
14
15 namespace v8 {
16 namespace internal {
17 namespace compiler {
18
operator <<(std::ostream & os,BranchHint hint)19 std::ostream& operator<<(std::ostream& os, BranchHint hint) {
20 switch (hint) {
21 case BranchHint::kNone:
22 return os << "None";
23 case BranchHint::kTrue:
24 return os << "True";
25 case BranchHint::kFalse:
26 return os << "False";
27 }
28 UNREACHABLE();
29 return os;
30 }
31
32
BranchHintOf(const Operator * const op)33 BranchHint BranchHintOf(const Operator* const op) {
34 DCHECK_EQ(IrOpcode::kBranch, op->opcode());
35 return OpParameter<BranchHint>(op);
36 }
37
38
hash_value(DeoptimizeKind kind)39 size_t hash_value(DeoptimizeKind kind) { return static_cast<size_t>(kind); }
40
41
operator <<(std::ostream & os,DeoptimizeKind kind)42 std::ostream& operator<<(std::ostream& os, DeoptimizeKind kind) {
43 switch (kind) {
44 case DeoptimizeKind::kEager:
45 return os << "Eager";
46 case DeoptimizeKind::kSoft:
47 return os << "Soft";
48 }
49 UNREACHABLE();
50 return os;
51 }
52
53
DeoptimizeKindOf(const Operator * const op)54 DeoptimizeKind DeoptimizeKindOf(const Operator* const op) {
55 DCHECK_EQ(IrOpcode::kDeoptimize, op->opcode());
56 return OpParameter<DeoptimizeKind>(op);
57 }
58
59
hash_value(IfExceptionHint hint)60 size_t hash_value(IfExceptionHint hint) { return static_cast<size_t>(hint); }
61
62
operator <<(std::ostream & os,IfExceptionHint hint)63 std::ostream& operator<<(std::ostream& os, IfExceptionHint hint) {
64 switch (hint) {
65 case IfExceptionHint::kLocallyCaught:
66 return os << "Caught";
67 case IfExceptionHint::kLocallyUncaught:
68 return os << "Uncaught";
69 }
70 UNREACHABLE();
71 return os;
72 }
73
74
operator ==(SelectParameters const & lhs,SelectParameters const & rhs)75 bool operator==(SelectParameters const& lhs, SelectParameters const& rhs) {
76 return lhs.representation() == rhs.representation() &&
77 lhs.hint() == rhs.hint();
78 }
79
80
operator !=(SelectParameters const & lhs,SelectParameters const & rhs)81 bool operator!=(SelectParameters const& lhs, SelectParameters const& rhs) {
82 return !(lhs == rhs);
83 }
84
85
hash_value(SelectParameters const & p)86 size_t hash_value(SelectParameters const& p) {
87 return base::hash_combine(p.representation(), p.hint());
88 }
89
90
operator <<(std::ostream & os,SelectParameters const & p)91 std::ostream& operator<<(std::ostream& os, SelectParameters const& p) {
92 return os << p.representation() << "|" << p.hint();
93 }
94
95
SelectParametersOf(const Operator * const op)96 SelectParameters const& SelectParametersOf(const Operator* const op) {
97 DCHECK_EQ(IrOpcode::kSelect, op->opcode());
98 return OpParameter<SelectParameters>(op);
99 }
100
101
ProjectionIndexOf(const Operator * const op)102 size_t ProjectionIndexOf(const Operator* const op) {
103 DCHECK_EQ(IrOpcode::kProjection, op->opcode());
104 return OpParameter<size_t>(op);
105 }
106
107
PhiRepresentationOf(const Operator * const op)108 MachineRepresentation PhiRepresentationOf(const Operator* const op) {
109 DCHECK_EQ(IrOpcode::kPhi, op->opcode());
110 return OpParameter<MachineRepresentation>(op);
111 }
112
113
ParameterIndexOf(const Operator * const op)114 int ParameterIndexOf(const Operator* const op) {
115 DCHECK_EQ(IrOpcode::kParameter, op->opcode());
116 return OpParameter<ParameterInfo>(op).index();
117 }
118
119
ParameterInfoOf(const Operator * const op)120 const ParameterInfo& ParameterInfoOf(const Operator* const op) {
121 DCHECK_EQ(IrOpcode::kParameter, op->opcode());
122 return OpParameter<ParameterInfo>(op);
123 }
124
125
operator ==(ParameterInfo const & lhs,ParameterInfo const & rhs)126 bool operator==(ParameterInfo const& lhs, ParameterInfo const& rhs) {
127 return lhs.index() == rhs.index();
128 }
129
130
operator !=(ParameterInfo const & lhs,ParameterInfo const & rhs)131 bool operator!=(ParameterInfo const& lhs, ParameterInfo const& rhs) {
132 return !(lhs == rhs);
133 }
134
135
hash_value(ParameterInfo const & p)136 size_t hash_value(ParameterInfo const& p) { return p.index(); }
137
138
operator <<(std::ostream & os,ParameterInfo const & i)139 std::ostream& operator<<(std::ostream& os, ParameterInfo const& i) {
140 if (i.debug_name()) os << i.debug_name() << '#';
141 os << i.index();
142 return os;
143 }
144
145
146 #define CACHED_OP_LIST(V) \
147 V(Dead, Operator::kFoldable, 0, 0, 0, 1, 1, 1) \
148 V(IfTrue, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \
149 V(IfFalse, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \
150 V(IfSuccess, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \
151 V(IfDefault, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \
152 V(Throw, Operator::kKontrol, 1, 1, 1, 0, 0, 1) \
153 V(Terminate, Operator::kKontrol, 0, 1, 1, 0, 0, 1) \
154 V(OsrNormalEntry, Operator::kFoldable, 0, 1, 1, 0, 1, 1) \
155 V(OsrLoopEntry, Operator::kFoldable, 0, 1, 1, 0, 1, 1) \
156 V(BeginRegion, Operator::kNoThrow, 0, 1, 0, 0, 1, 0) \
157 V(FinishRegion, Operator::kNoThrow, 1, 1, 0, 1, 1, 0)
158
159
160 #define CACHED_RETURN_LIST(V) \
161 V(1) \
162 V(2) \
163 V(3)
164
165
166 #define CACHED_END_LIST(V) \
167 V(1) \
168 V(2) \
169 V(3) \
170 V(4) \
171 V(5) \
172 V(6) \
173 V(7) \
174 V(8)
175
176
177 #define CACHED_EFFECT_PHI_LIST(V) \
178 V(1) \
179 V(2) \
180 V(3) \
181 V(4) \
182 V(5) \
183 V(6)
184
185
186 #define CACHED_LOOP_LIST(V) \
187 V(1) \
188 V(2)
189
190
191 #define CACHED_MERGE_LIST(V) \
192 V(1) \
193 V(2) \
194 V(3) \
195 V(4) \
196 V(5) \
197 V(6) \
198 V(7) \
199 V(8)
200
201
202 #define CACHED_PARAMETER_LIST(V) \
203 V(0) \
204 V(1) \
205 V(2) \
206 V(3) \
207 V(4) \
208 V(5) \
209 V(6)
210
211
212 #define CACHED_PHI_LIST(V) \
213 V(kTagged, 1) \
214 V(kTagged, 2) \
215 V(kTagged, 3) \
216 V(kTagged, 4) \
217 V(kTagged, 5) \
218 V(kTagged, 6) \
219 V(kBit, 2) \
220 V(kFloat64, 2) \
221 V(kWord32, 2)
222
223
224 #define CACHED_PROJECTION_LIST(V) \
225 V(0) \
226 V(1)
227
228
229 #define CACHED_STATE_VALUES_LIST(V) \
230 V(0) \
231 V(1) \
232 V(2) \
233 V(3) \
234 V(4) \
235 V(5) \
236 V(6) \
237 V(7) \
238 V(8) \
239 V(10) \
240 V(11) \
241 V(12) \
242 V(13) \
243 V(14)
244
245
246 struct CommonOperatorGlobalCache final {
247 #define CACHED(Name, properties, value_input_count, effect_input_count, \
248 control_input_count, value_output_count, effect_output_count, \
249 control_output_count) \
250 struct Name##Operator final : public Operator { \
251 Name##Operator() \
252 : Operator(IrOpcode::k##Name, properties, #Name, value_input_count, \
253 effect_input_count, control_input_count, \
254 value_output_count, effect_output_count, \
255 control_output_count) {} \
256 }; \
257 Name##Operator k##Name##Operator;
258 CACHED_OP_LIST(CACHED)
259 #undef CACHED
260
261 template <DeoptimizeKind kKind>
262 struct DeoptimizeOperator final : public Operator1<DeoptimizeKind> {
DeoptimizeOperatorv8::internal::compiler::CommonOperatorGlobalCache::DeoptimizeOperator263 DeoptimizeOperator()
264 : Operator1<DeoptimizeKind>( // --
265 IrOpcode::kDeoptimize, Operator::kNoThrow, // opcode
266 "Deoptimize", // name
267 1, 1, 1, 0, 0, 1, // counts
268 kKind) {} // parameter
269 };
270 DeoptimizeOperator<DeoptimizeKind::kEager> kDeoptimizeEagerOperator;
271 DeoptimizeOperator<DeoptimizeKind::kSoft> kDeoptimizeSoftOperator;
272
273 template <IfExceptionHint kCaughtLocally>
274 struct IfExceptionOperator final : public Operator1<IfExceptionHint> {
IfExceptionOperatorv8::internal::compiler::CommonOperatorGlobalCache::IfExceptionOperator275 IfExceptionOperator()
276 : Operator1<IfExceptionHint>( // --
277 IrOpcode::kIfException, Operator::kKontrol, // opcode
278 "IfException", // name
279 0, 1, 1, 1, 1, 1, // counts
280 kCaughtLocally) {} // parameter
281 };
282 IfExceptionOperator<IfExceptionHint::kLocallyCaught> kIfExceptionCOperator;
283 IfExceptionOperator<IfExceptionHint::kLocallyUncaught> kIfExceptionUOperator;
284
285 template <size_t kInputCount>
286 struct EndOperator final : public Operator {
EndOperatorv8::internal::compiler::CommonOperatorGlobalCache::EndOperator287 EndOperator()
288 : Operator( // --
289 IrOpcode::kEnd, Operator::kKontrol, // opcode
290 "End", // name
291 0, 0, kInputCount, 0, 0, 0) {} // counts
292 };
293 #define CACHED_END(input_count) \
294 EndOperator<input_count> kEnd##input_count##Operator;
295 CACHED_END_LIST(CACHED_END)
296 #undef CACHED_END
297
298 template <size_t kInputCount>
299 struct ReturnOperator final : public Operator {
ReturnOperatorv8::internal::compiler::CommonOperatorGlobalCache::ReturnOperator300 ReturnOperator()
301 : Operator( // --
302 IrOpcode::kReturn, Operator::kNoThrow, // opcode
303 "Return", // name
304 kInputCount, 1, 1, 0, 0, 1) {} // counts
305 };
306 #define CACHED_RETURN(input_count) \
307 ReturnOperator<input_count> kReturn##input_count##Operator;
308 CACHED_RETURN_LIST(CACHED_RETURN)
309 #undef CACHED_RETURN
310
311 template <BranchHint kBranchHint>
312 struct BranchOperator final : public Operator1<BranchHint> {
BranchOperatorv8::internal::compiler::CommonOperatorGlobalCache::BranchOperator313 BranchOperator()
314 : Operator1<BranchHint>( // --
315 IrOpcode::kBranch, Operator::kKontrol, // opcode
316 "Branch", // name
317 1, 0, 1, 0, 0, 2, // counts
318 kBranchHint) {} // parameter
319 };
320 BranchOperator<BranchHint::kNone> kBranchNoneOperator;
321 BranchOperator<BranchHint::kTrue> kBranchTrueOperator;
322 BranchOperator<BranchHint::kFalse> kBranchFalseOperator;
323
324 template <int kEffectInputCount>
325 struct EffectPhiOperator final : public Operator {
EffectPhiOperatorv8::internal::compiler::CommonOperatorGlobalCache::EffectPhiOperator326 EffectPhiOperator()
327 : Operator( // --
328 IrOpcode::kEffectPhi, Operator::kPure, // opcode
329 "EffectPhi", // name
330 0, kEffectInputCount, 1, 0, 1, 0) {} // counts
331 };
332 #define CACHED_EFFECT_PHI(input_count) \
333 EffectPhiOperator<input_count> kEffectPhi##input_count##Operator;
334 CACHED_EFFECT_PHI_LIST(CACHED_EFFECT_PHI)
335 #undef CACHED_EFFECT_PHI
336
337 template <size_t kInputCount>
338 struct LoopOperator final : public Operator {
LoopOperatorv8::internal::compiler::CommonOperatorGlobalCache::LoopOperator339 LoopOperator()
340 : Operator( // --
341 IrOpcode::kLoop, Operator::kKontrol, // opcode
342 "Loop", // name
343 0, 0, kInputCount, 0, 0, 1) {} // counts
344 };
345 #define CACHED_LOOP(input_count) \
346 LoopOperator<input_count> kLoop##input_count##Operator;
347 CACHED_LOOP_LIST(CACHED_LOOP)
348 #undef CACHED_LOOP
349
350 template <size_t kInputCount>
351 struct MergeOperator final : public Operator {
MergeOperatorv8::internal::compiler::CommonOperatorGlobalCache::MergeOperator352 MergeOperator()
353 : Operator( // --
354 IrOpcode::kMerge, Operator::kKontrol, // opcode
355 "Merge", // name
356 0, 0, kInputCount, 0, 0, 1) {} // counts
357 };
358 #define CACHED_MERGE(input_count) \
359 MergeOperator<input_count> kMerge##input_count##Operator;
360 CACHED_MERGE_LIST(CACHED_MERGE)
361 #undef CACHED_MERGE
362
363 template <MachineRepresentation kRep, int kInputCount>
364 struct PhiOperator final : public Operator1<MachineRepresentation> {
PhiOperatorv8::internal::compiler::CommonOperatorGlobalCache::PhiOperator365 PhiOperator()
366 : Operator1<MachineRepresentation>( //--
367 IrOpcode::kPhi, Operator::kPure, // opcode
368 "Phi", // name
369 kInputCount, 0, 1, 1, 0, 0, // counts
370 kRep) {} // parameter
371 };
372 #define CACHED_PHI(rep, input_count) \
373 PhiOperator<MachineRepresentation::rep, input_count> \
374 kPhi##rep##input_count##Operator;
375 CACHED_PHI_LIST(CACHED_PHI)
376 #undef CACHED_PHI
377
378 template <int kIndex>
379 struct ParameterOperator final : public Operator1<ParameterInfo> {
ParameterOperatorv8::internal::compiler::CommonOperatorGlobalCache::ParameterOperator380 ParameterOperator()
381 : Operator1<ParameterInfo>( // --
382 IrOpcode::kParameter, Operator::kPure, // opcode
383 "Parameter", // name
384 1, 0, 0, 1, 0, 0, // counts,
385 ParameterInfo(kIndex, nullptr)) {} // parameter and name
386 };
387 #define CACHED_PARAMETER(index) \
388 ParameterOperator<index> kParameter##index##Operator;
389 CACHED_PARAMETER_LIST(CACHED_PARAMETER)
390 #undef CACHED_PARAMETER
391
392 template <size_t kIndex>
393 struct ProjectionOperator final : public Operator1<size_t> {
ProjectionOperatorv8::internal::compiler::CommonOperatorGlobalCache::ProjectionOperator394 ProjectionOperator()
395 : Operator1<size_t>( // --
396 IrOpcode::kProjection, // opcode
397 Operator::kPure, // flags
398 "Projection", // name
399 1, 0, 0, 1, 0, 0, // counts,
400 kIndex) {} // parameter
401 };
402 #define CACHED_PROJECTION(index) \
403 ProjectionOperator<index> kProjection##index##Operator;
404 CACHED_PROJECTION_LIST(CACHED_PROJECTION)
405 #undef CACHED_PROJECTION
406
407 template <int kInputCount>
408 struct StateValuesOperator final : public Operator {
StateValuesOperatorv8::internal::compiler::CommonOperatorGlobalCache::StateValuesOperator409 StateValuesOperator()
410 : Operator( // --
411 IrOpcode::kStateValues, // opcode
412 Operator::kPure, // flags
413 "StateValues", // name
414 kInputCount, 0, 0, 1, 0, 0) {} // counts
415 };
416 #define CACHED_STATE_VALUES(input_count) \
417 StateValuesOperator<input_count> kStateValues##input_count##Operator;
418 CACHED_STATE_VALUES_LIST(CACHED_STATE_VALUES)
419 #undef CACHED_STATE_VALUES
420 };
421
422
423 static base::LazyInstance<CommonOperatorGlobalCache>::type kCache =
424 LAZY_INSTANCE_INITIALIZER;
425
426
CommonOperatorBuilder(Zone * zone)427 CommonOperatorBuilder::CommonOperatorBuilder(Zone* zone)
428 : cache_(kCache.Get()), zone_(zone) {}
429
430
431 #define CACHED(Name, properties, value_input_count, effect_input_count, \
432 control_input_count, value_output_count, effect_output_count, \
433 control_output_count) \
434 const Operator* CommonOperatorBuilder::Name() { \
435 return &cache_.k##Name##Operator; \
436 }
CACHED_OP_LIST(CACHED) const437 CACHED_OP_LIST(CACHED)
438 #undef CACHED
439
440
441 const Operator* CommonOperatorBuilder::End(size_t control_input_count) {
442 switch (control_input_count) {
443 #define CACHED_END(input_count) \
444 case input_count: \
445 return &cache_.kEnd##input_count##Operator;
446 CACHED_END_LIST(CACHED_END)
447 #undef CACHED_END
448 default:
449 break;
450 }
451 // Uncached.
452 return new (zone()) Operator( //--
453 IrOpcode::kEnd, Operator::kKontrol, // opcode
454 "End", // name
455 0, 0, control_input_count, 0, 0, 0); // counts
456 }
457
458
Return(int value_input_count)459 const Operator* CommonOperatorBuilder::Return(int value_input_count) {
460 switch (value_input_count) {
461 #define CACHED_RETURN(input_count) \
462 case input_count: \
463 return &cache_.kReturn##input_count##Operator;
464 CACHED_RETURN_LIST(CACHED_RETURN)
465 #undef CACHED_RETURN
466 default:
467 break;
468 }
469 // Uncached.
470 return new (zone()) Operator( //--
471 IrOpcode::kReturn, Operator::kNoThrow, // opcode
472 "Return", // name
473 value_input_count, 1, 1, 0, 0, 1); // counts
474 }
475
476
Branch(BranchHint hint)477 const Operator* CommonOperatorBuilder::Branch(BranchHint hint) {
478 switch (hint) {
479 case BranchHint::kNone:
480 return &cache_.kBranchNoneOperator;
481 case BranchHint::kTrue:
482 return &cache_.kBranchTrueOperator;
483 case BranchHint::kFalse:
484 return &cache_.kBranchFalseOperator;
485 }
486 UNREACHABLE();
487 return nullptr;
488 }
489
490
Deoptimize(DeoptimizeKind kind)491 const Operator* CommonOperatorBuilder::Deoptimize(DeoptimizeKind kind) {
492 switch (kind) {
493 case DeoptimizeKind::kEager:
494 return &cache_.kDeoptimizeEagerOperator;
495 case DeoptimizeKind::kSoft:
496 return &cache_.kDeoptimizeSoftOperator;
497 }
498 UNREACHABLE();
499 return nullptr;
500 }
501
502
IfException(IfExceptionHint hint)503 const Operator* CommonOperatorBuilder::IfException(IfExceptionHint hint) {
504 switch (hint) {
505 case IfExceptionHint::kLocallyCaught:
506 return &cache_.kIfExceptionCOperator;
507 case IfExceptionHint::kLocallyUncaught:
508 return &cache_.kIfExceptionUOperator;
509 }
510 UNREACHABLE();
511 return nullptr;
512 }
513
514
Switch(size_t control_output_count)515 const Operator* CommonOperatorBuilder::Switch(size_t control_output_count) {
516 return new (zone()) Operator( // --
517 IrOpcode::kSwitch, Operator::kKontrol, // opcode
518 "Switch", // name
519 1, 0, 1, 0, 0, control_output_count); // counts
520 }
521
522
IfValue(int32_t index)523 const Operator* CommonOperatorBuilder::IfValue(int32_t index) {
524 return new (zone()) Operator1<int32_t>( // --
525 IrOpcode::kIfValue, Operator::kKontrol, // opcode
526 "IfValue", // name
527 0, 0, 1, 0, 0, 1, // counts
528 index); // parameter
529 }
530
531
Start(int value_output_count)532 const Operator* CommonOperatorBuilder::Start(int value_output_count) {
533 return new (zone()) Operator( // --
534 IrOpcode::kStart, Operator::kFoldable, // opcode
535 "Start", // name
536 0, 0, 0, value_output_count, 1, 1); // counts
537 }
538
539
Loop(int control_input_count)540 const Operator* CommonOperatorBuilder::Loop(int control_input_count) {
541 switch (control_input_count) {
542 #define CACHED_LOOP(input_count) \
543 case input_count: \
544 return &cache_.kLoop##input_count##Operator;
545 CACHED_LOOP_LIST(CACHED_LOOP)
546 #undef CACHED_LOOP
547 default:
548 break;
549 }
550 // Uncached.
551 return new (zone()) Operator( // --
552 IrOpcode::kLoop, Operator::kKontrol, // opcode
553 "Loop", // name
554 0, 0, control_input_count, 0, 0, 1); // counts
555 }
556
557
Merge(int control_input_count)558 const Operator* CommonOperatorBuilder::Merge(int control_input_count) {
559 switch (control_input_count) {
560 #define CACHED_MERGE(input_count) \
561 case input_count: \
562 return &cache_.kMerge##input_count##Operator;
563 CACHED_MERGE_LIST(CACHED_MERGE)
564 #undef CACHED_MERGE
565 default:
566 break;
567 }
568 // Uncached.
569 return new (zone()) Operator( // --
570 IrOpcode::kMerge, Operator::kKontrol, // opcode
571 "Merge", // name
572 0, 0, control_input_count, 0, 0, 1); // counts
573 }
574
575
Parameter(int index,const char * debug_name)576 const Operator* CommonOperatorBuilder::Parameter(int index,
577 const char* debug_name) {
578 if (!debug_name) {
579 switch (index) {
580 #define CACHED_PARAMETER(index) \
581 case index: \
582 return &cache_.kParameter##index##Operator;
583 CACHED_PARAMETER_LIST(CACHED_PARAMETER)
584 #undef CACHED_PARAMETER
585 default:
586 break;
587 }
588 }
589 // Uncached.
590 return new (zone()) Operator1<ParameterInfo>( // --
591 IrOpcode::kParameter, Operator::kPure, // opcode
592 "Parameter", // name
593 1, 0, 0, 1, 0, 0, // counts
594 ParameterInfo(index, debug_name)); // parameter info
595 }
596
597
OsrValue(int index)598 const Operator* CommonOperatorBuilder::OsrValue(int index) {
599 return new (zone()) Operator1<int>( // --
600 IrOpcode::kOsrValue, Operator::kNoProperties, // opcode
601 "OsrValue", // name
602 0, 0, 1, 1, 0, 0, // counts
603 index); // parameter
604 }
605
606
Int32Constant(int32_t value)607 const Operator* CommonOperatorBuilder::Int32Constant(int32_t value) {
608 return new (zone()) Operator1<int32_t>( // --
609 IrOpcode::kInt32Constant, Operator::kPure, // opcode
610 "Int32Constant", // name
611 0, 0, 0, 1, 0, 0, // counts
612 value); // parameter
613 }
614
615
Int64Constant(int64_t value)616 const Operator* CommonOperatorBuilder::Int64Constant(int64_t value) {
617 return new (zone()) Operator1<int64_t>( // --
618 IrOpcode::kInt64Constant, Operator::kPure, // opcode
619 "Int64Constant", // name
620 0, 0, 0, 1, 0, 0, // counts
621 value); // parameter
622 }
623
624
Float32Constant(volatile float value)625 const Operator* CommonOperatorBuilder::Float32Constant(volatile float value) {
626 return new (zone()) Operator1<float>( // --
627 IrOpcode::kFloat32Constant, Operator::kPure, // opcode
628 "Float32Constant", // name
629 0, 0, 0, 1, 0, 0, // counts
630 value); // parameter
631 }
632
633
Float64Constant(volatile double value)634 const Operator* CommonOperatorBuilder::Float64Constant(volatile double value) {
635 return new (zone()) Operator1<double>( // --
636 IrOpcode::kFloat64Constant, Operator::kPure, // opcode
637 "Float64Constant", // name
638 0, 0, 0, 1, 0, 0, // counts
639 value); // parameter
640 }
641
642
ExternalConstant(const ExternalReference & value)643 const Operator* CommonOperatorBuilder::ExternalConstant(
644 const ExternalReference& value) {
645 return new (zone()) Operator1<ExternalReference>( // --
646 IrOpcode::kExternalConstant, Operator::kPure, // opcode
647 "ExternalConstant", // name
648 0, 0, 0, 1, 0, 0, // counts
649 value); // parameter
650 }
651
652
NumberConstant(volatile double value)653 const Operator* CommonOperatorBuilder::NumberConstant(volatile double value) {
654 return new (zone()) Operator1<double>( // --
655 IrOpcode::kNumberConstant, Operator::kPure, // opcode
656 "NumberConstant", // name
657 0, 0, 0, 1, 0, 0, // counts
658 value); // parameter
659 }
660
661
HeapConstant(const Handle<HeapObject> & value)662 const Operator* CommonOperatorBuilder::HeapConstant(
663 const Handle<HeapObject>& value) {
664 return new (zone()) Operator1<Handle<HeapObject>>( // --
665 IrOpcode::kHeapConstant, Operator::kPure, // opcode
666 "HeapConstant", // name
667 0, 0, 0, 1, 0, 0, // counts
668 value); // parameter
669 }
670
671
Select(MachineRepresentation rep,BranchHint hint)672 const Operator* CommonOperatorBuilder::Select(MachineRepresentation rep,
673 BranchHint hint) {
674 return new (zone()) Operator1<SelectParameters>( // --
675 IrOpcode::kSelect, Operator::kPure, // opcode
676 "Select", // name
677 3, 0, 0, 1, 0, 0, // counts
678 SelectParameters(rep, hint)); // parameter
679 }
680
681
Phi(MachineRepresentation rep,int value_input_count)682 const Operator* CommonOperatorBuilder::Phi(MachineRepresentation rep,
683 int value_input_count) {
684 DCHECK(value_input_count > 0); // Disallow empty phis.
685 #define CACHED_PHI(kRep, kValueInputCount) \
686 if (MachineRepresentation::kRep == rep && \
687 kValueInputCount == value_input_count) { \
688 return &cache_.kPhi##kRep##kValueInputCount##Operator; \
689 }
690 CACHED_PHI_LIST(CACHED_PHI)
691 #undef CACHED_PHI
692 // Uncached.
693 return new (zone()) Operator1<MachineRepresentation>( // --
694 IrOpcode::kPhi, Operator::kPure, // opcode
695 "Phi", // name
696 value_input_count, 0, 1, 1, 0, 0, // counts
697 rep); // parameter
698 }
699
700
EffectPhi(int effect_input_count)701 const Operator* CommonOperatorBuilder::EffectPhi(int effect_input_count) {
702 DCHECK(effect_input_count > 0); // Disallow empty effect phis.
703 switch (effect_input_count) {
704 #define CACHED_EFFECT_PHI(input_count) \
705 case input_count: \
706 return &cache_.kEffectPhi##input_count##Operator;
707 CACHED_EFFECT_PHI_LIST(CACHED_EFFECT_PHI)
708 #undef CACHED_EFFECT_PHI
709 default:
710 break;
711 }
712 // Uncached.
713 return new (zone()) Operator( // --
714 IrOpcode::kEffectPhi, Operator::kPure, // opcode
715 "EffectPhi", // name
716 0, effect_input_count, 1, 0, 1, 0); // counts
717 }
718
719
Guard(Type * type)720 const Operator* CommonOperatorBuilder::Guard(Type* type) {
721 return new (zone()) Operator1<Type*>( // --
722 IrOpcode::kGuard, Operator::kKontrol, // opcode
723 "Guard", // name
724 1, 0, 1, 1, 0, 0, // counts
725 type); // parameter
726 }
727
728
EffectSet(int arguments)729 const Operator* CommonOperatorBuilder::EffectSet(int arguments) {
730 DCHECK(arguments > 1); // Disallow empty/singleton sets.
731 return new (zone()) Operator( // --
732 IrOpcode::kEffectSet, Operator::kPure, // opcode
733 "EffectSet", // name
734 0, arguments, 0, 0, 1, 0); // counts
735 }
736
737
StateValues(int arguments)738 const Operator* CommonOperatorBuilder::StateValues(int arguments) {
739 switch (arguments) {
740 #define CACHED_STATE_VALUES(arguments) \
741 case arguments: \
742 return &cache_.kStateValues##arguments##Operator;
743 CACHED_STATE_VALUES_LIST(CACHED_STATE_VALUES)
744 #undef CACHED_STATE_VALUES
745 default:
746 break;
747 }
748 // Uncached.
749 return new (zone()) Operator( // --
750 IrOpcode::kStateValues, Operator::kPure, // opcode
751 "StateValues", // name
752 arguments, 0, 0, 1, 0, 0); // counts
753 }
754
755
ObjectState(int pointer_slots,int id)756 const Operator* CommonOperatorBuilder::ObjectState(int pointer_slots, int id) {
757 return new (zone()) Operator1<int>( // --
758 IrOpcode::kObjectState, Operator::kPure, // opcode
759 "ObjectState", // name
760 pointer_slots, 0, 0, 1, 0, 0, id); // counts
761 }
762
763
TypedStateValues(const ZoneVector<MachineType> * types)764 const Operator* CommonOperatorBuilder::TypedStateValues(
765 const ZoneVector<MachineType>* types) {
766 return new (zone()) Operator1<const ZoneVector<MachineType>*>( // --
767 IrOpcode::kTypedStateValues, Operator::kPure, // opcode
768 "TypedStateValues", // name
769 static_cast<int>(types->size()), 0, 0, 1, 0, 0, types); // counts
770 }
771
772
FrameState(BailoutId bailout_id,OutputFrameStateCombine state_combine,const FrameStateFunctionInfo * function_info)773 const Operator* CommonOperatorBuilder::FrameState(
774 BailoutId bailout_id, OutputFrameStateCombine state_combine,
775 const FrameStateFunctionInfo* function_info) {
776 FrameStateInfo state_info(bailout_id, state_combine, function_info);
777 return new (zone()) Operator1<FrameStateInfo>( // --
778 IrOpcode::kFrameState, Operator::kPure, // opcode
779 "FrameState", // name
780 5, 0, 0, 1, 0, 0, // counts
781 state_info); // parameter
782 }
783
784
Call(const CallDescriptor * descriptor)785 const Operator* CommonOperatorBuilder::Call(const CallDescriptor* descriptor) {
786 class CallOperator final : public Operator1<const CallDescriptor*> {
787 public:
788 explicit CallOperator(const CallDescriptor* descriptor)
789 : Operator1<const CallDescriptor*>(
790 IrOpcode::kCall, descriptor->properties(), "Call",
791 descriptor->InputCount() + descriptor->FrameStateCount(),
792 Operator::ZeroIfPure(descriptor->properties()),
793 Operator::ZeroIfEliminatable(descriptor->properties()),
794 descriptor->ReturnCount(),
795 Operator::ZeroIfPure(descriptor->properties()),
796 Operator::ZeroIfNoThrow(descriptor->properties()), descriptor) {}
797
798 void PrintParameter(std::ostream& os) const override {
799 os << "[" << *parameter() << "]";
800 }
801 };
802 return new (zone()) CallOperator(descriptor);
803 }
804
805
LazyBailout()806 const Operator* CommonOperatorBuilder::LazyBailout() {
807 return Call(Linkage::GetLazyBailoutDescriptor(zone()));
808 }
809
810
TailCall(const CallDescriptor * descriptor)811 const Operator* CommonOperatorBuilder::TailCall(
812 const CallDescriptor* descriptor) {
813 class TailCallOperator final : public Operator1<const CallDescriptor*> {
814 public:
815 explicit TailCallOperator(const CallDescriptor* descriptor)
816 : Operator1<const CallDescriptor*>(
817 IrOpcode::kTailCall, descriptor->properties(), "TailCall",
818 descriptor->InputCount() + descriptor->FrameStateCount(), 1, 1, 0,
819 0, 1, descriptor) {}
820
821 void PrintParameter(std::ostream& os) const override {
822 os << "[" << *parameter() << "]";
823 }
824 };
825 return new (zone()) TailCallOperator(descriptor);
826 }
827
828
Projection(size_t index)829 const Operator* CommonOperatorBuilder::Projection(size_t index) {
830 switch (index) {
831 #define CACHED_PROJECTION(index) \
832 case index: \
833 return &cache_.kProjection##index##Operator;
834 CACHED_PROJECTION_LIST(CACHED_PROJECTION)
835 #undef CACHED_PROJECTION
836 default:
837 break;
838 }
839 // Uncached.
840 return new (zone()) Operator1<size_t>( // --
841 IrOpcode::kProjection, // opcode
842 Operator::kFoldable | Operator::kNoThrow, // flags
843 "Projection", // name
844 1, 0, 0, 1, 0, 0, // counts
845 index); // parameter
846 }
847
848
ResizeMergeOrPhi(const Operator * op,int size)849 const Operator* CommonOperatorBuilder::ResizeMergeOrPhi(const Operator* op,
850 int size) {
851 if (op->opcode() == IrOpcode::kPhi) {
852 return Phi(PhiRepresentationOf(op), size);
853 } else if (op->opcode() == IrOpcode::kEffectPhi) {
854 return EffectPhi(size);
855 } else if (op->opcode() == IrOpcode::kMerge) {
856 return Merge(size);
857 } else if (op->opcode() == IrOpcode::kLoop) {
858 return Loop(size);
859 } else {
860 UNREACHABLE();
861 return nullptr;
862 }
863 }
864
865
866 const FrameStateFunctionInfo*
CreateFrameStateFunctionInfo(FrameStateType type,int parameter_count,int local_count,Handle<SharedFunctionInfo> shared_info,ContextCallingMode context_calling_mode)867 CommonOperatorBuilder::CreateFrameStateFunctionInfo(
868 FrameStateType type, int parameter_count, int local_count,
869 Handle<SharedFunctionInfo> shared_info,
870 ContextCallingMode context_calling_mode) {
871 return new (zone()->New(sizeof(FrameStateFunctionInfo)))
872 FrameStateFunctionInfo(type, parameter_count, local_count, shared_info,
873 context_calling_mode);
874 }
875
876 } // namespace compiler
877 } // namespace internal
878 } // namespace v8
879