blob: d3f697256c6dfeb56f34667e136a3b55c30f61c1 [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// 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"
Emily Bernierd0a1eb72015-03-24 16:35:39 -040010#include "src/compiler/opcodes.h"
11#include "src/compiler/operator.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000012#include "src/handles-inl.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000013#include "src/zone.h"
14
15namespace v8 {
16namespace internal {
17namespace compiler {
18
Emily Bernierd0a1eb72015-03-24 16:35:39 -040019std::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";
Ben Murdochb8a8cc12014-11-26 15:28:44 +000027 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -040028 UNREACHABLE();
29 return os;
30}
31
32
33BranchHint BranchHintOf(const Operator* const op) {
34 DCHECK_EQ(IrOpcode::kBranch, op->opcode());
35 return OpParameter<BranchHint>(op);
36}
37
38
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000039size_t hash_value(DeoptimizeKind kind) { return static_cast<size_t>(kind); }
40
41
42std::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
54DeoptimizeKind DeoptimizeKindOf(const Operator* const op) {
55 DCHECK_EQ(IrOpcode::kDeoptimize, op->opcode());
56 return OpParameter<DeoptimizeKind>(op);
57}
58
59
60size_t hash_value(IfExceptionHint hint) { return static_cast<size_t>(hint); }
61
62
63std::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
Emily Bernierd0a1eb72015-03-24 16:35:39 -040075bool operator==(SelectParameters const& lhs, SelectParameters const& rhs) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000076 return lhs.representation() == rhs.representation() &&
77 lhs.hint() == rhs.hint();
Emily Bernierd0a1eb72015-03-24 16:35:39 -040078}
79
80
81bool operator!=(SelectParameters const& lhs, SelectParameters const& rhs) {
82 return !(lhs == rhs);
83}
84
85
86size_t hash_value(SelectParameters const& p) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000087 return base::hash_combine(p.representation(), p.hint());
Emily Bernierd0a1eb72015-03-24 16:35:39 -040088}
89
90
91std::ostream& operator<<(std::ostream& os, SelectParameters const& p) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000092 return os << p.representation() << "|" << p.hint();
Emily Bernierd0a1eb72015-03-24 16:35:39 -040093}
94
95
96SelectParameters const& SelectParametersOf(const Operator* const op) {
97 DCHECK_EQ(IrOpcode::kSelect, op->opcode());
98 return OpParameter<SelectParameters>(op);
99}
100
Ben Murdochc5610432016-08-08 18:44:38 +0100101CallDescriptor const* CallDescriptorOf(const Operator* const op) {
102 DCHECK(op->opcode() == IrOpcode::kCall ||
103 op->opcode() == IrOpcode::kTailCall);
104 return OpParameter<CallDescriptor const*>(op);
105}
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400106
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000107size_t ProjectionIndexOf(const Operator* const op) {
108 DCHECK_EQ(IrOpcode::kProjection, op->opcode());
109 return OpParameter<size_t>(op);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400110}
111
112
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000113MachineRepresentation PhiRepresentationOf(const Operator* const op) {
114 DCHECK_EQ(IrOpcode::kPhi, op->opcode());
115 return OpParameter<MachineRepresentation>(op);
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400116}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000117
118
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000119int ParameterIndexOf(const Operator* const op) {
120 DCHECK_EQ(IrOpcode::kParameter, op->opcode());
121 return OpParameter<ParameterInfo>(op).index();
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400122}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000123
124
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000125const ParameterInfo& ParameterInfoOf(const Operator* const op) {
126 DCHECK_EQ(IrOpcode::kParameter, op->opcode());
127 return OpParameter<ParameterInfo>(op);
128}
129
130
131bool operator==(ParameterInfo const& lhs, ParameterInfo const& rhs) {
132 return lhs.index() == rhs.index();
133}
134
135
136bool operator!=(ParameterInfo const& lhs, ParameterInfo const& rhs) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400137 return !(lhs == rhs);
138}
139
140
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000141size_t hash_value(ParameterInfo const& p) { return p.index(); }
142
143
144std::ostream& operator<<(std::ostream& os, ParameterInfo const& i) {
145 if (i.debug_name()) os << i.debug_name() << '#';
146 os << i.index();
147 return os;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400148}
149
Ben Murdochc5610432016-08-08 18:44:38 +0100150bool operator==(RelocatablePtrConstantInfo const& lhs,
151 RelocatablePtrConstantInfo const& rhs) {
152 return lhs.rmode() == rhs.rmode() && lhs.value() == rhs.value() &&
153 lhs.type() == rhs.type();
154}
155
156bool operator!=(RelocatablePtrConstantInfo const& lhs,
157 RelocatablePtrConstantInfo const& rhs) {
158 return !(lhs == rhs);
159}
160
161size_t hash_value(RelocatablePtrConstantInfo const& p) {
162 return base::hash_combine(p.value(), p.rmode(), p.type());
163}
164
165std::ostream& operator<<(std::ostream& os,
166 RelocatablePtrConstantInfo const& p) {
167 return os << p.value() << "|" << p.rmode() << "|" << p.type();
168}
169
Ben Murdochda12d292016-06-02 14:46:10 +0100170#define CACHED_OP_LIST(V) \
171 V(Dead, Operator::kFoldable, 0, 0, 0, 1, 1, 1) \
172 V(DeoptimizeIf, Operator::kFoldable, 2, 1, 1, 0, 0, 1) \
173 V(DeoptimizeUnless, Operator::kFoldable, 2, 1, 1, 0, 0, 1) \
174 V(IfTrue, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \
175 V(IfFalse, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \
176 V(IfSuccess, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \
177 V(IfDefault, Operator::kKontrol, 0, 0, 1, 0, 0, 1) \
178 V(Throw, Operator::kKontrol, 1, 1, 1, 0, 0, 1) \
179 V(Terminate, Operator::kKontrol, 0, 1, 1, 0, 0, 1) \
180 V(OsrNormalEntry, Operator::kFoldable, 0, 1, 1, 0, 1, 1) \
181 V(OsrLoopEntry, Operator::kFoldable, 0, 1, 1, 0, 1, 1) \
Ben Murdochc5610432016-08-08 18:44:38 +0100182 V(CheckPoint, Operator::kKontrol, 1, 1, 1, 0, 1, 0) \
Ben Murdochda12d292016-06-02 14:46:10 +0100183 V(BeginRegion, Operator::kNoThrow, 0, 1, 0, 0, 1, 0) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000184 V(FinishRegion, Operator::kNoThrow, 1, 1, 0, 1, 1, 0)
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400185
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000186#define CACHED_RETURN_LIST(V) \
187 V(1) \
188 V(2) \
189 V(3)
190
191
192#define CACHED_END_LIST(V) \
193 V(1) \
194 V(2) \
195 V(3) \
196 V(4) \
197 V(5) \
198 V(6) \
199 V(7) \
200 V(8)
201
202
203#define CACHED_EFFECT_PHI_LIST(V) \
204 V(1) \
205 V(2) \
206 V(3) \
207 V(4) \
208 V(5) \
209 V(6)
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400210
211
212#define CACHED_LOOP_LIST(V) \
213 V(1) \
214 V(2)
215
216
217#define CACHED_MERGE_LIST(V) \
218 V(1) \
219 V(2) \
220 V(3) \
221 V(4) \
222 V(5) \
223 V(6) \
224 V(7) \
225 V(8)
226
227
228#define CACHED_PARAMETER_LIST(V) \
229 V(0) \
230 V(1) \
231 V(2) \
232 V(3) \
233 V(4) \
234 V(5) \
235 V(6)
236
237
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000238#define CACHED_PHI_LIST(V) \
239 V(kTagged, 1) \
240 V(kTagged, 2) \
241 V(kTagged, 3) \
242 V(kTagged, 4) \
243 V(kTagged, 5) \
244 V(kTagged, 6) \
245 V(kBit, 2) \
246 V(kFloat64, 2) \
247 V(kWord32, 2)
248
249
250#define CACHED_PROJECTION_LIST(V) \
251 V(0) \
252 V(1)
253
254
255#define CACHED_STATE_VALUES_LIST(V) \
256 V(0) \
257 V(1) \
258 V(2) \
259 V(3) \
260 V(4) \
261 V(5) \
262 V(6) \
263 V(7) \
264 V(8) \
265 V(10) \
266 V(11) \
267 V(12) \
268 V(13) \
269 V(14)
270
271
272struct CommonOperatorGlobalCache final {
273#define CACHED(Name, properties, value_input_count, effect_input_count, \
274 control_input_count, value_output_count, effect_output_count, \
275 control_output_count) \
276 struct Name##Operator final : public Operator { \
277 Name##Operator() \
278 : Operator(IrOpcode::k##Name, properties, #Name, value_input_count, \
279 effect_input_count, control_input_count, \
280 value_output_count, effect_output_count, \
281 control_output_count) {} \
282 }; \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000283 Name##Operator k##Name##Operator;
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400284 CACHED_OP_LIST(CACHED)
285#undef CACHED
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000286
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000287 template <DeoptimizeKind kKind>
288 struct DeoptimizeOperator final : public Operator1<DeoptimizeKind> {
289 DeoptimizeOperator()
290 : Operator1<DeoptimizeKind>( // --
291 IrOpcode::kDeoptimize, Operator::kNoThrow, // opcode
292 "Deoptimize", // name
293 1, 1, 1, 0, 0, 1, // counts
294 kKind) {} // parameter
295 };
296 DeoptimizeOperator<DeoptimizeKind::kEager> kDeoptimizeEagerOperator;
297 DeoptimizeOperator<DeoptimizeKind::kSoft> kDeoptimizeSoftOperator;
298
299 template <IfExceptionHint kCaughtLocally>
300 struct IfExceptionOperator final : public Operator1<IfExceptionHint> {
301 IfExceptionOperator()
302 : Operator1<IfExceptionHint>( // --
303 IrOpcode::kIfException, Operator::kKontrol, // opcode
304 "IfException", // name
305 0, 1, 1, 1, 1, 1, // counts
306 kCaughtLocally) {} // parameter
307 };
308 IfExceptionOperator<IfExceptionHint::kLocallyCaught> kIfExceptionCOperator;
309 IfExceptionOperator<IfExceptionHint::kLocallyUncaught> kIfExceptionUOperator;
310
311 template <size_t kInputCount>
312 struct EndOperator final : public Operator {
313 EndOperator()
314 : Operator( // --
315 IrOpcode::kEnd, Operator::kKontrol, // opcode
316 "End", // name
317 0, 0, kInputCount, 0, 0, 0) {} // counts
318 };
319#define CACHED_END(input_count) \
320 EndOperator<input_count> kEnd##input_count##Operator;
321 CACHED_END_LIST(CACHED_END)
322#undef CACHED_END
323
324 template <size_t kInputCount>
325 struct ReturnOperator final : public Operator {
326 ReturnOperator()
327 : Operator( // --
328 IrOpcode::kReturn, Operator::kNoThrow, // opcode
329 "Return", // name
330 kInputCount, 1, 1, 0, 0, 1) {} // counts
331 };
332#define CACHED_RETURN(input_count) \
333 ReturnOperator<input_count> kReturn##input_count##Operator;
334 CACHED_RETURN_LIST(CACHED_RETURN)
335#undef CACHED_RETURN
336
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400337 template <BranchHint kBranchHint>
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000338 struct BranchOperator final : public Operator1<BranchHint> {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400339 BranchOperator()
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000340 : Operator1<BranchHint>( // --
341 IrOpcode::kBranch, Operator::kKontrol, // opcode
342 "Branch", // name
343 1, 0, 1, 0, 0, 2, // counts
344 kBranchHint) {} // parameter
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000345 };
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400346 BranchOperator<BranchHint::kNone> kBranchNoneOperator;
347 BranchOperator<BranchHint::kTrue> kBranchTrueOperator;
348 BranchOperator<BranchHint::kFalse> kBranchFalseOperator;
349
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000350 template <int kEffectInputCount>
351 struct EffectPhiOperator final : public Operator {
352 EffectPhiOperator()
353 : Operator( // --
354 IrOpcode::kEffectPhi, Operator::kPure, // opcode
355 "EffectPhi", // name
356 0, kEffectInputCount, 1, 0, 1, 0) {} // counts
357 };
358#define CACHED_EFFECT_PHI(input_count) \
359 EffectPhiOperator<input_count> kEffectPhi##input_count##Operator;
360 CACHED_EFFECT_PHI_LIST(CACHED_EFFECT_PHI)
361#undef CACHED_EFFECT_PHI
362
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400363 template <size_t kInputCount>
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000364 struct LoopOperator final : public Operator {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400365 LoopOperator()
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000366 : Operator( // --
367 IrOpcode::kLoop, Operator::kKontrol, // opcode
368 "Loop", // name
369 0, 0, kInputCount, 0, 0, 1) {} // counts
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400370 };
371#define CACHED_LOOP(input_count) \
372 LoopOperator<input_count> kLoop##input_count##Operator;
373 CACHED_LOOP_LIST(CACHED_LOOP)
374#undef CACHED_LOOP
375
376 template <size_t kInputCount>
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000377 struct MergeOperator final : public Operator {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400378 MergeOperator()
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000379 : Operator( // --
380 IrOpcode::kMerge, Operator::kKontrol, // opcode
381 "Merge", // name
382 0, 0, kInputCount, 0, 0, 1) {} // counts
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400383 };
384#define CACHED_MERGE(input_count) \
385 MergeOperator<input_count> kMerge##input_count##Operator;
386 CACHED_MERGE_LIST(CACHED_MERGE)
387#undef CACHED_MERGE
388
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000389 template <MachineRepresentation kRep, int kInputCount>
390 struct PhiOperator final : public Operator1<MachineRepresentation> {
391 PhiOperator()
392 : Operator1<MachineRepresentation>( //--
393 IrOpcode::kPhi, Operator::kPure, // opcode
394 "Phi", // name
395 kInputCount, 0, 1, 1, 0, 0, // counts
396 kRep) {} // parameter
397 };
398#define CACHED_PHI(rep, input_count) \
399 PhiOperator<MachineRepresentation::rep, input_count> \
400 kPhi##rep##input_count##Operator;
401 CACHED_PHI_LIST(CACHED_PHI)
402#undef CACHED_PHI
403
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400404 template <int kIndex>
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000405 struct ParameterOperator final : public Operator1<ParameterInfo> {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400406 ParameterOperator()
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000407 : Operator1<ParameterInfo>( // --
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400408 IrOpcode::kParameter, Operator::kPure, // opcode
409 "Parameter", // name
410 1, 0, 0, 1, 0, 0, // counts,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000411 ParameterInfo(kIndex, nullptr)) {} // parameter and name
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400412 };
413#define CACHED_PARAMETER(index) \
414 ParameterOperator<index> kParameter##index##Operator;
415 CACHED_PARAMETER_LIST(CACHED_PARAMETER)
416#undef CACHED_PARAMETER
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000417
418 template <size_t kIndex>
419 struct ProjectionOperator final : public Operator1<size_t> {
420 ProjectionOperator()
421 : Operator1<size_t>( // --
422 IrOpcode::kProjection, // opcode
423 Operator::kPure, // flags
424 "Projection", // name
425 1, 0, 0, 1, 0, 0, // counts,
426 kIndex) {} // parameter
427 };
428#define CACHED_PROJECTION(index) \
429 ProjectionOperator<index> kProjection##index##Operator;
430 CACHED_PROJECTION_LIST(CACHED_PROJECTION)
431#undef CACHED_PROJECTION
432
433 template <int kInputCount>
434 struct StateValuesOperator final : public Operator {
435 StateValuesOperator()
436 : Operator( // --
437 IrOpcode::kStateValues, // opcode
438 Operator::kPure, // flags
439 "StateValues", // name
440 kInputCount, 0, 0, 1, 0, 0) {} // counts
441 };
442#define CACHED_STATE_VALUES(input_count) \
443 StateValuesOperator<input_count> kStateValues##input_count##Operator;
444 CACHED_STATE_VALUES_LIST(CACHED_STATE_VALUES)
445#undef CACHED_STATE_VALUES
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000446};
447
448
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400449static base::LazyInstance<CommonOperatorGlobalCache>::type kCache =
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000450 LAZY_INSTANCE_INITIALIZER;
451
452
453CommonOperatorBuilder::CommonOperatorBuilder(Zone* zone)
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400454 : cache_(kCache.Get()), zone_(zone) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000455
456
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000457#define CACHED(Name, properties, value_input_count, effect_input_count, \
458 control_input_count, value_output_count, effect_output_count, \
459 control_output_count) \
460 const Operator* CommonOperatorBuilder::Name() { \
461 return &cache_.k##Name##Operator; \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000462 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400463CACHED_OP_LIST(CACHED)
464#undef CACHED
465
466
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000467const Operator* CommonOperatorBuilder::End(size_t control_input_count) {
468 switch (control_input_count) {
469#define CACHED_END(input_count) \
470 case input_count: \
471 return &cache_.kEnd##input_count##Operator;
472 CACHED_END_LIST(CACHED_END)
473#undef CACHED_END
474 default:
475 break;
476 }
477 // Uncached.
478 return new (zone()) Operator( //--
479 IrOpcode::kEnd, Operator::kKontrol, // opcode
480 "End", // name
481 0, 0, control_input_count, 0, 0, 0); // counts
482}
483
484
485const Operator* CommonOperatorBuilder::Return(int value_input_count) {
486 switch (value_input_count) {
487#define CACHED_RETURN(input_count) \
488 case input_count: \
489 return &cache_.kReturn##input_count##Operator;
490 CACHED_RETURN_LIST(CACHED_RETURN)
491#undef CACHED_RETURN
492 default:
493 break;
494 }
495 // Uncached.
496 return new (zone()) Operator( //--
497 IrOpcode::kReturn, Operator::kNoThrow, // opcode
498 "Return", // name
499 value_input_count, 1, 1, 0, 0, 1); // counts
500}
501
502
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400503const Operator* CommonOperatorBuilder::Branch(BranchHint hint) {
504 switch (hint) {
505 case BranchHint::kNone:
506 return &cache_.kBranchNoneOperator;
507 case BranchHint::kTrue:
508 return &cache_.kBranchTrueOperator;
509 case BranchHint::kFalse:
510 return &cache_.kBranchFalseOperator;
511 }
512 UNREACHABLE();
513 return nullptr;
514}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000515
516
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000517const Operator* CommonOperatorBuilder::Deoptimize(DeoptimizeKind kind) {
518 switch (kind) {
519 case DeoptimizeKind::kEager:
520 return &cache_.kDeoptimizeEagerOperator;
521 case DeoptimizeKind::kSoft:
522 return &cache_.kDeoptimizeSoftOperator;
523 }
524 UNREACHABLE();
525 return nullptr;
526}
527
528
529const Operator* CommonOperatorBuilder::IfException(IfExceptionHint hint) {
530 switch (hint) {
531 case IfExceptionHint::kLocallyCaught:
532 return &cache_.kIfExceptionCOperator;
533 case IfExceptionHint::kLocallyUncaught:
534 return &cache_.kIfExceptionUOperator;
535 }
536 UNREACHABLE();
537 return nullptr;
538}
539
540
541const Operator* CommonOperatorBuilder::Switch(size_t control_output_count) {
542 return new (zone()) Operator( // --
543 IrOpcode::kSwitch, Operator::kKontrol, // opcode
544 "Switch", // name
545 1, 0, 1, 0, 0, control_output_count); // counts
546}
547
548
549const Operator* CommonOperatorBuilder::IfValue(int32_t index) {
550 return new (zone()) Operator1<int32_t>( // --
551 IrOpcode::kIfValue, Operator::kKontrol, // opcode
552 "IfValue", // name
553 0, 0, 1, 0, 0, 1, // counts
554 index); // parameter
555}
556
557
558const Operator* CommonOperatorBuilder::Start(int value_output_count) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400559 return new (zone()) Operator( // --
560 IrOpcode::kStart, Operator::kFoldable, // opcode
561 "Start", // name
562 0, 0, 0, value_output_count, 1, 1); // counts
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000563}
564
565
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400566const Operator* CommonOperatorBuilder::Loop(int control_input_count) {
567 switch (control_input_count) {
568#define CACHED_LOOP(input_count) \
569 case input_count: \
570 return &cache_.kLoop##input_count##Operator;
571 CACHED_LOOP_LIST(CACHED_LOOP)
572#undef CACHED_LOOP
573 default:
574 break;
575 }
576 // Uncached.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000577 return new (zone()) Operator( // --
578 IrOpcode::kLoop, Operator::kKontrol, // opcode
579 "Loop", // name
580 0, 0, control_input_count, 0, 0, 1); // counts
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000581}
582
583
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400584const Operator* CommonOperatorBuilder::Merge(int control_input_count) {
585 switch (control_input_count) {
586#define CACHED_MERGE(input_count) \
587 case input_count: \
588 return &cache_.kMerge##input_count##Operator;
589 CACHED_MERGE_LIST(CACHED_MERGE)
590#undef CACHED_MERGE
591 default:
592 break;
593 }
594 // Uncached.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000595 return new (zone()) Operator( // --
596 IrOpcode::kMerge, Operator::kKontrol, // opcode
597 "Merge", // name
598 0, 0, control_input_count, 0, 0, 1); // counts
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400599}
600
601
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000602const Operator* CommonOperatorBuilder::Parameter(int index,
603 const char* debug_name) {
604 if (!debug_name) {
605 switch (index) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400606#define CACHED_PARAMETER(index) \
607 case index: \
608 return &cache_.kParameter##index##Operator;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000609 CACHED_PARAMETER_LIST(CACHED_PARAMETER)
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400610#undef CACHED_PARAMETER
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000611 default:
612 break;
613 }
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400614 }
615 // Uncached.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000616 return new (zone()) Operator1<ParameterInfo>( // --
617 IrOpcode::kParameter, Operator::kPure, // opcode
618 "Parameter", // name
619 1, 0, 0, 1, 0, 0, // counts
620 ParameterInfo(index, debug_name)); // parameter info
621}
622
623
624const Operator* CommonOperatorBuilder::OsrValue(int index) {
625 return new (zone()) Operator1<int>( // --
626 IrOpcode::kOsrValue, Operator::kNoProperties, // opcode
627 "OsrValue", // name
628 0, 0, 1, 1, 0, 0, // counts
629 index); // parameter
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000630}
631
632
633const Operator* CommonOperatorBuilder::Int32Constant(int32_t value) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400634 return new (zone()) Operator1<int32_t>( // --
635 IrOpcode::kInt32Constant, Operator::kPure, // opcode
636 "Int32Constant", // name
637 0, 0, 0, 1, 0, 0, // counts
638 value); // parameter
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000639}
640
641
642const Operator* CommonOperatorBuilder::Int64Constant(int64_t value) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400643 return new (zone()) Operator1<int64_t>( // --
644 IrOpcode::kInt64Constant, Operator::kPure, // opcode
645 "Int64Constant", // name
646 0, 0, 0, 1, 0, 0, // counts
647 value); // parameter
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000648}
649
650
651const Operator* CommonOperatorBuilder::Float32Constant(volatile float value) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000652 return new (zone()) Operator1<float>( // --
653 IrOpcode::kFloat32Constant, Operator::kPure, // opcode
654 "Float32Constant", // name
655 0, 0, 0, 1, 0, 0, // counts
656 value); // parameter
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000657}
658
659
660const Operator* CommonOperatorBuilder::Float64Constant(volatile double value) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000661 return new (zone()) Operator1<double>( // --
662 IrOpcode::kFloat64Constant, Operator::kPure, // opcode
663 "Float64Constant", // name
664 0, 0, 0, 1, 0, 0, // counts
665 value); // parameter
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000666}
667
668
669const Operator* CommonOperatorBuilder::ExternalConstant(
670 const ExternalReference& value) {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400671 return new (zone()) Operator1<ExternalReference>( // --
672 IrOpcode::kExternalConstant, Operator::kPure, // opcode
673 "ExternalConstant", // name
674 0, 0, 0, 1, 0, 0, // counts
675 value); // parameter
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000676}
677
678
679const Operator* CommonOperatorBuilder::NumberConstant(volatile double value) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000680 return new (zone()) Operator1<double>( // --
681 IrOpcode::kNumberConstant, Operator::kPure, // opcode
682 "NumberConstant", // name
683 0, 0, 0, 1, 0, 0, // counts
684 value); // parameter
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000685}
686
687
688const Operator* CommonOperatorBuilder::HeapConstant(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000689 const Handle<HeapObject>& value) {
690 return new (zone()) Operator1<Handle<HeapObject>>( // --
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400691 IrOpcode::kHeapConstant, Operator::kPure, // opcode
692 "HeapConstant", // name
693 0, 0, 0, 1, 0, 0, // counts
694 value); // parameter
695}
696
Ben Murdochc5610432016-08-08 18:44:38 +0100697const Operator* CommonOperatorBuilder::RelocatableInt32Constant(
698 int32_t value, RelocInfo::Mode rmode) {
699 return new (zone()) Operator1<RelocatablePtrConstantInfo>( // --
700 IrOpcode::kRelocatableInt32Constant, Operator::kPure, // opcode
701 "RelocatableInt32Constant", // name
702 0, 0, 0, 1, 0, 0, // counts
703 RelocatablePtrConstantInfo(value, rmode)); // parameter
704}
705
706const Operator* CommonOperatorBuilder::RelocatableInt64Constant(
707 int64_t value, RelocInfo::Mode rmode) {
708 return new (zone()) Operator1<RelocatablePtrConstantInfo>( // --
709 IrOpcode::kRelocatableInt64Constant, Operator::kPure, // opcode
710 "RelocatableInt64Constant", // name
711 0, 0, 0, 1, 0, 0, // counts
712 RelocatablePtrConstantInfo(value, rmode)); // parameter
713}
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400714
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000715const Operator* CommonOperatorBuilder::Select(MachineRepresentation rep,
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400716 BranchHint hint) {
717 return new (zone()) Operator1<SelectParameters>( // --
718 IrOpcode::kSelect, Operator::kPure, // opcode
719 "Select", // name
720 3, 0, 0, 1, 0, 0, // counts
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000721 SelectParameters(rep, hint)); // parameter
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000722}
723
724
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000725const Operator* CommonOperatorBuilder::Phi(MachineRepresentation rep,
726 int value_input_count) {
727 DCHECK(value_input_count > 0); // Disallow empty phis.
728#define CACHED_PHI(kRep, kValueInputCount) \
729 if (MachineRepresentation::kRep == rep && \
730 kValueInputCount == value_input_count) { \
731 return &cache_.kPhi##kRep##kValueInputCount##Operator; \
732 }
733 CACHED_PHI_LIST(CACHED_PHI)
734#undef CACHED_PHI
735 // Uncached.
736 return new (zone()) Operator1<MachineRepresentation>( // --
737 IrOpcode::kPhi, Operator::kPure, // opcode
738 "Phi", // name
739 value_input_count, 0, 1, 1, 0, 0, // counts
740 rep); // parameter
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000741}
742
743
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000744const Operator* CommonOperatorBuilder::EffectPhi(int effect_input_count) {
745 DCHECK(effect_input_count > 0); // Disallow empty effect phis.
746 switch (effect_input_count) {
747#define CACHED_EFFECT_PHI(input_count) \
748 case input_count: \
749 return &cache_.kEffectPhi##input_count##Operator;
750 CACHED_EFFECT_PHI_LIST(CACHED_EFFECT_PHI)
751#undef CACHED_EFFECT_PHI
752 default:
753 break;
754 }
755 // Uncached.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400756 return new (zone()) Operator( // --
757 IrOpcode::kEffectPhi, Operator::kPure, // opcode
758 "EffectPhi", // name
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000759 0, effect_input_count, 1, 0, 1, 0); // counts
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000760}
761
762
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000763const Operator* CommonOperatorBuilder::StateValues(int arguments) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000764 switch (arguments) {
765#define CACHED_STATE_VALUES(arguments) \
766 case arguments: \
767 return &cache_.kStateValues##arguments##Operator;
768 CACHED_STATE_VALUES_LIST(CACHED_STATE_VALUES)
769#undef CACHED_STATE_VALUES
770 default:
771 break;
772 }
773 // Uncached.
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400774 return new (zone()) Operator( // --
775 IrOpcode::kStateValues, Operator::kPure, // opcode
776 "StateValues", // name
777 arguments, 0, 0, 1, 0, 0); // counts
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000778}
779
780
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000781const Operator* CommonOperatorBuilder::ObjectState(int pointer_slots, int id) {
782 return new (zone()) Operator1<int>( // --
783 IrOpcode::kObjectState, Operator::kPure, // opcode
784 "ObjectState", // name
785 pointer_slots, 0, 0, 1, 0, 0, id); // counts
786}
787
788
789const Operator* CommonOperatorBuilder::TypedStateValues(
790 const ZoneVector<MachineType>* types) {
791 return new (zone()) Operator1<const ZoneVector<MachineType>*>( // --
792 IrOpcode::kTypedStateValues, Operator::kPure, // opcode
793 "TypedStateValues", // name
794 static_cast<int>(types->size()), 0, 0, 1, 0, 0, types); // counts
795}
796
797
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000798const Operator* CommonOperatorBuilder::FrameState(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000799 BailoutId bailout_id, OutputFrameStateCombine state_combine,
800 const FrameStateFunctionInfo* function_info) {
801 FrameStateInfo state_info(bailout_id, state_combine, function_info);
802 return new (zone()) Operator1<FrameStateInfo>( // --
803 IrOpcode::kFrameState, Operator::kPure, // opcode
804 "FrameState", // name
805 5, 0, 0, 1, 0, 0, // counts
806 state_info); // parameter
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000807}
808
809
810const Operator* CommonOperatorBuilder::Call(const CallDescriptor* descriptor) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000811 class CallOperator final : public Operator1<const CallDescriptor*> {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000812 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000813 explicit CallOperator(const CallDescriptor* descriptor)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000814 : Operator1<const CallDescriptor*>(
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000815 IrOpcode::kCall, descriptor->properties(), "Call",
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400816 descriptor->InputCount() + descriptor->FrameStateCount(),
817 Operator::ZeroIfPure(descriptor->properties()),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000818 Operator::ZeroIfEliminatable(descriptor->properties()),
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400819 descriptor->ReturnCount(),
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000820 Operator::ZeroIfPure(descriptor->properties()),
821 Operator::ZeroIfNoThrow(descriptor->properties()), descriptor) {}
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000822
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000823 void PrintParameter(std::ostream& os) const override {
Emily Bernierd0a1eb72015-03-24 16:35:39 -0400824 os << "[" << *parameter() << "]";
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000825 }
826 };
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000827 return new (zone()) CallOperator(descriptor);
828}
829
830
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000831const Operator* CommonOperatorBuilder::TailCall(
832 const CallDescriptor* descriptor) {
833 class TailCallOperator final : public Operator1<const CallDescriptor*> {
834 public:
835 explicit TailCallOperator(const CallDescriptor* descriptor)
836 : Operator1<const CallDescriptor*>(
837 IrOpcode::kTailCall, descriptor->properties(), "TailCall",
838 descriptor->InputCount() + descriptor->FrameStateCount(), 1, 1, 0,
839 0, 1, descriptor) {}
840
841 void PrintParameter(std::ostream& os) const override {
842 os << "[" << *parameter() << "]";
843 }
844 };
845 return new (zone()) TailCallOperator(descriptor);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000846}
847
848
849const Operator* CommonOperatorBuilder::Projection(size_t index) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000850 switch (index) {
851#define CACHED_PROJECTION(index) \
852 case index: \
853 return &cache_.kProjection##index##Operator;
854 CACHED_PROJECTION_LIST(CACHED_PROJECTION)
855#undef CACHED_PROJECTION
856 default:
857 break;
858 }
859 // Uncached.
860 return new (zone()) Operator1<size_t>( // --
861 IrOpcode::kProjection, // opcode
862 Operator::kFoldable | Operator::kNoThrow, // flags
863 "Projection", // name
864 1, 0, 0, 1, 0, 0, // counts
865 index); // parameter
866}
867
868
869const Operator* CommonOperatorBuilder::ResizeMergeOrPhi(const Operator* op,
870 int size) {
871 if (op->opcode() == IrOpcode::kPhi) {
872 return Phi(PhiRepresentationOf(op), size);
873 } else if (op->opcode() == IrOpcode::kEffectPhi) {
874 return EffectPhi(size);
875 } else if (op->opcode() == IrOpcode::kMerge) {
876 return Merge(size);
877 } else if (op->opcode() == IrOpcode::kLoop) {
878 return Loop(size);
879 } else {
880 UNREACHABLE();
881 return nullptr;
882 }
883}
884
885
886const FrameStateFunctionInfo*
887CommonOperatorBuilder::CreateFrameStateFunctionInfo(
888 FrameStateType type, int parameter_count, int local_count,
Ben Murdoch097c5b22016-05-18 11:27:45 +0100889 Handle<SharedFunctionInfo> shared_info) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000890 return new (zone()->New(sizeof(FrameStateFunctionInfo)))
Ben Murdoch097c5b22016-05-18 11:27:45 +0100891 FrameStateFunctionInfo(type, parameter_count, local_count, shared_info);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000892}
893
894} // namespace compiler
895} // namespace internal
896} // namespace v8