Line data Source code
1 : // Copyright 2012 the V8 project authors. All rights reserved.
2 : // Use of this source code is governed by a BSD-style license that can be
3 : // found in the LICENSE file.
4 :
5 : #ifndef V8_CRANKSHAFT_X64_LITHIUM_X64_H_
6 : #define V8_CRANKSHAFT_X64_LITHIUM_X64_H_
7 :
8 : #include "src/crankshaft/hydrogen.h"
9 : #include "src/crankshaft/lithium.h"
10 : #include "src/crankshaft/lithium-allocator.h"
11 : #include "src/safepoint-table.h"
12 : #include "src/utils.h"
13 :
14 : namespace v8 {
15 : namespace internal {
16 :
17 : // Forward declarations.
18 : class LCodeGen;
19 :
20 : #define LITHIUM_CONCRETE_INSTRUCTION_LIST(V) \
21 : V(AccessArgumentsAt) \
22 : V(AddI) \
23 : V(Allocate) \
24 : V(ApplyArguments) \
25 : V(ArgumentsElements) \
26 : V(ArgumentsLength) \
27 : V(ArithmeticD) \
28 : V(ArithmeticT) \
29 : V(BitI) \
30 : V(BoundsCheck) \
31 : V(Branch) \
32 : V(CallWithDescriptor) \
33 : V(CallNewArray) \
34 : V(CallRuntime) \
35 : V(CheckArrayBufferNotNeutered) \
36 : V(CheckInstanceType) \
37 : V(CheckMaps) \
38 : V(CheckMapValue) \
39 : V(CheckNonSmi) \
40 : V(CheckSmi) \
41 : V(CheckValue) \
42 : V(ClampDToUint8) \
43 : V(ClampIToUint8) \
44 : V(ClampTToUint8) \
45 : V(ClassOfTestAndBranch) \
46 : V(CompareNumericAndBranch) \
47 : V(CmpObjectEqAndBranch) \
48 : V(CmpHoleAndBranch) \
49 : V(CmpMapAndBranch) \
50 : V(CmpT) \
51 : V(ConstantD) \
52 : V(ConstantE) \
53 : V(ConstantI) \
54 : V(ConstantS) \
55 : V(ConstantT) \
56 : V(Context) \
57 : V(DebugBreak) \
58 : V(DeclareGlobals) \
59 : V(Deoptimize) \
60 : V(DivByConstI) \
61 : V(DivByPowerOf2I) \
62 : V(DivI) \
63 : V(DoubleToI) \
64 : V(DoubleToSmi) \
65 : V(Drop) \
66 : V(DummyUse) \
67 : V(Dummy) \
68 : V(FastAllocate) \
69 : V(FlooringDivByConstI) \
70 : V(FlooringDivByPowerOf2I) \
71 : V(FlooringDivI) \
72 : V(ForInCacheArray) \
73 : V(ForInPrepareMap) \
74 : V(Goto) \
75 : V(HasInPrototypeChainAndBranch) \
76 : V(HasInstanceTypeAndBranch) \
77 : V(InnerAllocatedObject) \
78 : V(InstructionGap) \
79 : V(Integer32ToDouble) \
80 : V(InvokeFunction) \
81 : V(IsStringAndBranch) \
82 : V(IsSmiAndBranch) \
83 : V(IsUndetectableAndBranch) \
84 : V(Label) \
85 : V(LazyBailout) \
86 : V(LoadContextSlot) \
87 : V(LoadRoot) \
88 : V(LoadFieldByIndex) \
89 : V(LoadFunctionPrototype) \
90 : V(LoadKeyed) \
91 : V(LoadNamedField) \
92 : V(MathAbs) \
93 : V(MathClz32) \
94 : V(MathCos) \
95 : V(MathExp) \
96 : V(MathFloorD) \
97 : V(MathFloorI) \
98 : V(MathFround) \
99 : V(MathLog) \
100 : V(MathMinMax) \
101 : V(MathPowHalf) \
102 : V(MathRoundD) \
103 : V(MathRoundI) \
104 : V(MathSin) \
105 : V(MathSqrt) \
106 : V(MaybeGrowElements) \
107 : V(ModByConstI) \
108 : V(ModByPowerOf2I) \
109 : V(ModI) \
110 : V(MulI) \
111 : V(NumberTagD) \
112 : V(NumberTagI) \
113 : V(NumberTagU) \
114 : V(NumberUntagD) \
115 : V(OsrEntry) \
116 : V(Parameter) \
117 : V(Power) \
118 : V(Prologue) \
119 : V(PushArgument) \
120 : V(Return) \
121 : V(SeqStringGetChar) \
122 : V(SeqStringSetChar) \
123 : V(ShiftI) \
124 : V(SmiTag) \
125 : V(SmiUntag) \
126 : V(StackCheck) \
127 : V(StoreCodeEntry) \
128 : V(StoreContextSlot) \
129 : V(StoreKeyed) \
130 : V(StoreNamedField) \
131 : V(StringAdd) \
132 : V(StringCharCodeAt) \
133 : V(StringCharFromCode) \
134 : V(StringCompareAndBranch) \
135 : V(SubI) \
136 : V(TaggedToI) \
137 : V(ThisFunction) \
138 : V(TransitionElementsKind) \
139 : V(TrapAllocationMemento) \
140 : V(Typeof) \
141 : V(TypeofIsAndBranch) \
142 : V(Uint32ToDouble) \
143 : V(UnknownOSRValue) \
144 : V(WrapReceiver)
145 :
146 : #define DECLARE_CONCRETE_INSTRUCTION(type, mnemonic) \
147 : Opcode opcode() const final { return LInstruction::k##type; } \
148 : void CompileToNative(LCodeGen* generator) final; \
149 : const char* Mnemonic() const final { return mnemonic; } \
150 : static L##type* cast(LInstruction* instr) { \
151 : DCHECK(instr->Is##type()); \
152 : return reinterpret_cast<L##type*>(instr); \
153 : }
154 :
155 :
156 : #define DECLARE_HYDROGEN_ACCESSOR(type) \
157 : H##type* hydrogen() const { \
158 : return H##type::cast(hydrogen_value()); \
159 : }
160 :
161 :
162 : class LInstruction : public ZoneObject {
163 : public:
164 : LInstruction()
165 : : environment_(NULL),
166 : hydrogen_value_(NULL),
167 88975911 : bit_field_(IsCallBits::encode(false)) {
168 : }
169 :
170 0 : virtual ~LInstruction() {}
171 :
172 : virtual void CompileToNative(LCodeGen* generator) = 0;
173 : virtual const char* Mnemonic() const = 0;
174 : virtual void PrintTo(StringStream* stream);
175 : virtual void PrintDataTo(StringStream* stream);
176 : virtual void PrintOutputOperandTo(StringStream* stream);
177 :
178 : enum Opcode {
179 : // Declare a unique enum value for each instruction.
180 : #define DECLARE_OPCODE(type) k##type,
181 : LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_OPCODE)
182 : kNumberOfInstructions
183 : #undef DECLARE_OPCODE
184 : };
185 :
186 : virtual Opcode opcode() const = 0;
187 :
188 : // Declare non-virtual type testers for all leaf IR classes.
189 : #define DECLARE_PREDICATE(type) \
190 : bool Is##type() const { return opcode() == k##type; }
191 79285480 : LITHIUM_CONCRETE_INSTRUCTION_LIST(DECLARE_PREDICATE)
192 : #undef DECLARE_PREDICATE
193 :
194 : // Declare virtual predicates for instructions that don't have
195 : // an opcode.
196 48925717 : virtual bool IsGap() const { return false; }
197 :
198 18178652 : virtual bool IsControl() const { return false; }
199 :
200 : // Try deleting this instruction if possible.
201 0 : virtual bool TryDelete() { return false; }
202 :
203 2934432 : void set_environment(LEnvironment* env) { environment_ = env; }
204 : LEnvironment* environment() const { return environment_; }
205 : bool HasEnvironment() const { return environment_ != NULL; }
206 :
207 : void set_pointer_map(LPointerMap* p) { pointer_map_.set(p); }
208 : LPointerMap* pointer_map() const { return pointer_map_.get(); }
209 : bool HasPointerMap() const { return pointer_map_.is_set(); }
210 :
211 44616838 : void set_hydrogen_value(HValue* value) { hydrogen_value_ = value; }
212 : HValue* hydrogen_value() const { return hydrogen_value_; }
213 :
214 3390220 : void MarkAsCall() { bit_field_ = IsCallBits::update(bit_field_, true); }
215 85929183 : bool IsCall() const { return IsCallBits::decode(bit_field_); }
216 :
217 : void MarkAsSyntacticTailCall() {
218 428 : bit_field_ = IsSyntacticTailCallBits::update(bit_field_, true);
219 : }
220 : bool IsSyntacticTailCall() const {
221 : return IsSyntacticTailCallBits::decode(bit_field_);
222 : }
223 :
224 : // Interface to the register allocator and iterators.
225 198385 : bool ClobbersTemps() const { return IsCall(); }
226 17797385 : bool ClobbersRegisters() const { return IsCall(); }
227 17690038 : virtual bool ClobbersDoubleRegisters(Isolate* isolate) const {
228 17690038 : return IsCall();
229 : }
230 :
231 : // Interface to the register allocator and iterators.
232 : bool IsMarkedAsCall() const { return IsCall(); }
233 :
234 : virtual bool HasResult() const = 0;
235 : virtual LOperand* result() const = 0;
236 :
237 350140 : LOperand* FirstInput() { return InputAt(0); }
238 82072428 : LOperand* Output() { return HasResult() ? result() : NULL; }
239 :
240 0 : virtual bool HasInterestingComment(LCodeGen* gen) const { return true; }
241 :
242 0 : virtual bool MustSignExtendResult(LPlatformChunk* chunk) const {
243 0 : return false;
244 : }
245 :
246 : #ifdef DEBUG
247 : void VerifyCall();
248 : #endif
249 :
250 : virtual int InputCount() = 0;
251 : virtual LOperand* InputAt(int i) = 0;
252 :
253 : private:
254 : // Iterator support.
255 : friend class InputIterator;
256 :
257 : friend class TempIterator;
258 : virtual int TempCount() = 0;
259 : virtual LOperand* TempAt(int i) = 0;
260 :
261 : class IsCallBits: public BitField<bool, 0, 1> {};
262 : class IsSyntacticTailCallBits : public BitField<bool, IsCallBits::kNext, 1> {
263 : };
264 :
265 : LEnvironment* environment_;
266 : SetOncePointer<LPointerMap> pointer_map_;
267 : HValue* hydrogen_value_;
268 : int bit_field_;
269 : };
270 :
271 :
272 : // R = number of result operands (0 or 1).
273 : template<int R>
274 44618051 : class LTemplateResultInstruction : public LInstruction {
275 : public:
276 : // Allow 0 or 1 output operands.
277 : STATIC_ASSERT(R == 0 || R == 1);
278 112909619 : bool HasResult() const final { return R != 0 && result() != NULL; }
279 7776693 : void set_result(LOperand* operand) { results_[0] = operand; }
280 93995398 : LOperand* result() const override { return results_[0]; }
281 :
282 : bool MustSignExtendResult(LPlatformChunk* chunk) const final;
283 :
284 : protected:
285 : EmbeddedContainer<LOperand*, R> results_;
286 : };
287 :
288 :
289 : // R = number of result operands (0 or 1).
290 : // I = number of input operands.
291 : // T = number of temporary operands.
292 : template<int R, int I, int T>
293 51791643 : class LTemplateInstruction : public LTemplateResultInstruction<R> {
294 : protected:
295 : EmbeddedContainer<LOperand*, I> inputs_;
296 : EmbeddedContainer<LOperand*, T> temps_;
297 :
298 : private:
299 : // Iterator support.
300 42515344 : int InputCount() final { return I; }
301 33231121 : LOperand* InputAt(int i) final { return inputs_[i]; }
302 :
303 38401103 : int TempCount() final { return T; }
304 1182417 : LOperand* TempAt(int i) final { return temps_[i]; }
305 : };
306 :
307 :
308 0 : class LGap : public LTemplateInstruction<0, 0, 0> {
309 : public:
310 : explicit LGap(HBasicBlock* block)
311 26820108 : : block_(block) {
312 26820108 : parallel_moves_[BEFORE] = NULL;
313 26820108 : parallel_moves_[START] = NULL;
314 26820108 : parallel_moves_[END] = NULL;
315 26820108 : parallel_moves_[AFTER] = NULL;
316 : }
317 :
318 : // Can't use the DECLARE-macro here because of sub-classes.
319 78809399 : bool IsGap() const final { return true; }
320 : void PrintDataTo(StringStream* stream) override;
321 : static LGap* cast(LInstruction* instr) {
322 : DCHECK(instr->IsGap());
323 : return reinterpret_cast<LGap*>(instr);
324 : }
325 :
326 : bool IsRedundant() const;
327 :
328 : HBasicBlock* block() const { return block_; }
329 :
330 : enum InnerPosition {
331 : BEFORE,
332 : START,
333 : END,
334 : AFTER,
335 : FIRST_INNER_POSITION = BEFORE,
336 : LAST_INNER_POSITION = AFTER
337 : };
338 :
339 44394684 : LParallelMove* GetOrCreateParallelMove(InnerPosition pos,
340 : Zone* zone) {
341 44394684 : if (parallel_moves_[pos] == NULL) {
342 34590875 : parallel_moves_[pos] = new(zone) LParallelMove(zone);
343 : }
344 44394120 : return parallel_moves_[pos];
345 : }
346 :
347 : LParallelMove* GetParallelMove(InnerPosition pos) {
348 69749321 : return parallel_moves_[pos];
349 : }
350 :
351 : private:
352 : LParallelMove* parallel_moves_[LAST_INNER_POSITION + 1];
353 : HBasicBlock* block_;
354 : };
355 :
356 :
357 0 : class LInstructionGap final : public LGap {
358 : public:
359 22308532 : explicit LInstructionGap(HBasicBlock* block) : LGap(block) { }
360 :
361 0 : bool HasInterestingComment(LCodeGen* gen) const override {
362 0 : return !IsRedundant();
363 : }
364 :
365 37796554 : DECLARE_CONCRETE_INSTRUCTION(InstructionGap, "gap")
366 : };
367 :
368 :
369 0 : class LGoto final : public LTemplateInstruction<0, 0, 0> {
370 : public:
371 3139526 : explicit LGoto(HBasicBlock* block) : block_(block) { }
372 :
373 : bool HasInterestingComment(LCodeGen* gen) const override;
374 7195777 : DECLARE_CONCRETE_INSTRUCTION(Goto, "goto")
375 : void PrintDataTo(StringStream* stream) override;
376 3139557 : bool IsControl() const override { return true; }
377 :
378 3002288 : int block_id() const { return block_->block_id(); }
379 :
380 : private:
381 : HBasicBlock* block_;
382 : };
383 :
384 :
385 260191 : class LPrologue final : public LTemplateInstruction<0, 0, 0> {
386 : public:
387 511104 : DECLARE_CONCRETE_INSTRUCTION(Prologue, "prologue")
388 : };
389 :
390 :
391 0 : class LLazyBailout final : public LTemplateInstruction<0, 0, 0> {
392 : public:
393 1695113 : LLazyBailout() : gap_instructions_size_(0) { }
394 :
395 3356290 : DECLARE_CONCRETE_INSTRUCTION(LazyBailout, "lazy-bailout")
396 :
397 : void set_gap_instructions_size(int gap_instructions_size) {
398 : gap_instructions_size_ = gap_instructions_size;
399 : }
400 : int gap_instructions_size() { return gap_instructions_size_; }
401 :
402 : private:
403 : int gap_instructions_size_;
404 : };
405 :
406 :
407 0 : class LDummy final : public LTemplateInstruction<1, 0, 0> {
408 : public:
409 6761 : LDummy() {}
410 9799 : DECLARE_CONCRETE_INSTRUCTION(Dummy, "dummy")
411 : };
412 :
413 :
414 0 : class LDummyUse final : public LTemplateInstruction<1, 1, 0> {
415 : public:
416 1771756 : explicit LDummyUse(LOperand* value) {
417 1771755 : inputs_[0] = value;
418 : }
419 1736518 : DECLARE_CONCRETE_INSTRUCTION(DummyUse, "dummy-use")
420 : };
421 :
422 :
423 188914 : class LDeoptimize final : public LTemplateInstruction<0, 0, 0> {
424 : public:
425 188916 : bool IsControl() const override { return true; }
426 399846 : DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize")
427 32377 : DECLARE_HYDROGEN_ACCESSOR(Deoptimize)
428 : };
429 :
430 :
431 0 : class LLabel final : public LGap {
432 : public:
433 : explicit LLabel(HBasicBlock* block)
434 9023152 : : LGap(block), replacement_(NULL) { }
435 :
436 0 : bool HasInterestingComment(LCodeGen* gen) const override { return false; }
437 6489897 : DECLARE_CONCRETE_INSTRUCTION(Label, "label")
438 :
439 : void PrintDataTo(StringStream* stream) override;
440 :
441 6710349 : int block_id() const { return block()->block_id(); }
442 5085985 : bool is_loop_header() const { return block()->IsLoopHeader(); }
443 : bool is_osr_entry() const { return block()->is_osr_entry(); }
444 : Label* label() { return &label_; }
445 : LLabel* replacement() const { return replacement_; }
446 1994887 : void set_replacement(LLabel* label) { replacement_ = label; }
447 : bool HasReplacement() const { return replacement_ != NULL; }
448 :
449 : private:
450 : Label label_;
451 : LLabel* replacement_;
452 : };
453 :
454 :
455 459990 : class LParameter final : public LTemplateInstruction<1, 0, 0> {
456 : public:
457 0 : bool HasInterestingComment(LCodeGen* gen) const override { return false; }
458 901154 : DECLARE_CONCRETE_INSTRUCTION(Parameter, "parameter")
459 : };
460 :
461 :
462 14103 : class LUnknownOSRValue final : public LTemplateInstruction<1, 0, 0> {
463 : public:
464 0 : bool HasInterestingComment(LCodeGen* gen) const override { return false; }
465 28206 : DECLARE_CONCRETE_INSTRUCTION(UnknownOSRValue, "unknown-osr-value")
466 : };
467 :
468 :
469 : template<int I, int T>
470 0 : class LControlInstruction : public LTemplateInstruction<0, I, T> {
471 : public:
472 801663 : LControlInstruction() : false_label_(NULL), true_label_(NULL) { }
473 :
474 801659 : bool IsControl() const final { return true; }
475 :
476 : int SuccessorCount() { return hydrogen()->SuccessorCount(); }
477 1432325 : HBasicBlock* SuccessorAt(int i) { return hydrogen()->SuccessorAt(i); }
478 :
479 701771 : int TrueDestination(LChunk* chunk) {
480 701771 : return chunk->LookupDestination(true_block_id());
481 : }
482 730554 : int FalseDestination(LChunk* chunk) {
483 730554 : return chunk->LookupDestination(false_block_id());
484 : }
485 :
486 516618 : Label* TrueLabel(LChunk* chunk) {
487 516618 : if (true_label_ == NULL) {
488 167310 : true_label_ = chunk->GetAssemblyLabel(TrueDestination(chunk));
489 : }
490 516618 : return true_label_;
491 : }
492 612478 : Label* FalseLabel(LChunk* chunk) {
493 612478 : if (false_label_ == NULL) {
494 188435 : false_label_ = chunk->GetAssemblyLabel(FalseDestination(chunk));
495 : }
496 612478 : return false_label_;
497 : }
498 :
499 : protected:
500 701771 : int true_block_id() { return SuccessorAt(0)->block_id(); }
501 730554 : int false_block_id() { return SuccessorAt(1)->block_id(); }
502 :
503 : private:
504 : HControlInstruction* hydrogen() {
505 1432325 : return HControlInstruction::cast(this->hydrogen_value());
506 : }
507 :
508 : Label* false_label_;
509 : Label* true_label_;
510 : };
511 :
512 :
513 0 : class LWrapReceiver final : public LTemplateInstruction<1, 2, 0> {
514 : public:
515 4495 : LWrapReceiver(LOperand* receiver, LOperand* function) {
516 4495 : inputs_[0] = receiver;
517 4495 : inputs_[1] = function;
518 : }
519 :
520 4467 : LOperand* receiver() { return inputs_[0]; }
521 4467 : LOperand* function() { return inputs_[1]; }
522 :
523 8934 : DECLARE_CONCRETE_INSTRUCTION(WrapReceiver, "wrap-receiver")
524 4467 : DECLARE_HYDROGEN_ACCESSOR(WrapReceiver)
525 : };
526 :
527 :
528 0 : class LApplyArguments final : public LTemplateInstruction<1, 4, 0> {
529 : public:
530 : LApplyArguments(LOperand* function,
531 : LOperand* receiver,
532 : LOperand* length,
533 136 : LOperand* elements) {
534 136 : inputs_[0] = function;
535 136 : inputs_[1] = receiver;
536 136 : inputs_[2] = length;
537 136 : inputs_[3] = elements;
538 : }
539 :
540 136 : LOperand* function() { return inputs_[0]; }
541 136 : LOperand* receiver() { return inputs_[1]; }
542 136 : LOperand* length() { return inputs_[2]; }
543 136 : LOperand* elements() { return inputs_[3]; }
544 :
545 272 : DECLARE_CONCRETE_INSTRUCTION(ApplyArguments, "apply-arguments")
546 136 : DECLARE_HYDROGEN_ACCESSOR(ApplyArguments)
547 : };
548 :
549 :
550 0 : class LAccessArgumentsAt final : public LTemplateInstruction<1, 3, 0> {
551 : public:
552 636 : LAccessArgumentsAt(LOperand* arguments, LOperand* length, LOperand* index) {
553 636 : inputs_[0] = arguments;
554 636 : inputs_[1] = length;
555 636 : inputs_[2] = index;
556 : }
557 :
558 594 : LOperand* arguments() { return inputs_[0]; }
559 778 : LOperand* length() { return inputs_[1]; }
560 778 : LOperand* index() { return inputs_[2]; }
561 :
562 1188 : DECLARE_CONCRETE_INSTRUCTION(AccessArgumentsAt, "access-arguments-at")
563 :
564 : void PrintDataTo(StringStream* stream) override;
565 : };
566 :
567 :
568 0 : class LArgumentsLength final : public LTemplateInstruction<1, 1, 0> {
569 : public:
570 574 : explicit LArgumentsLength(LOperand* elements) {
571 574 : inputs_[0] = elements;
572 : }
573 :
574 533 : LOperand* elements() { return inputs_[0]; }
575 :
576 1066 : DECLARE_CONCRETE_INSTRUCTION(ArgumentsLength, "arguments-length")
577 : };
578 :
579 :
580 760 : class LArgumentsElements final : public LTemplateInstruction<1, 0, 0> {
581 : public:
582 1434 : DECLARE_CONCRETE_INSTRUCTION(ArgumentsElements, "arguments-elements")
583 717 : DECLARE_HYDROGEN_ACCESSOR(ArgumentsElements)
584 : };
585 :
586 :
587 0 : class LModByPowerOf2I final : public LTemplateInstruction<1, 1, 0> {
588 : public:
589 1083 : LModByPowerOf2I(LOperand* dividend, int32_t divisor) {
590 1083 : inputs_[0] = dividend;
591 1083 : divisor_ = divisor;
592 : }
593 :
594 1064 : LOperand* dividend() { return inputs_[0]; }
595 : int32_t divisor() const { return divisor_; }
596 :
597 2128 : DECLARE_CONCRETE_INSTRUCTION(ModByPowerOf2I, "mod-by-power-of-2-i")
598 1064 : DECLARE_HYDROGEN_ACCESSOR(Mod)
599 :
600 : private:
601 : int32_t divisor_;
602 : };
603 :
604 :
605 0 : class LModByConstI final : public LTemplateInstruction<1, 1, 2> {
606 : public:
607 : LModByConstI(LOperand* dividend,
608 : int32_t divisor,
609 : LOperand* temp1,
610 1623 : LOperand* temp2) {
611 1623 : inputs_[0] = dividend;
612 1623 : divisor_ = divisor;
613 1623 : temps_[0] = temp1;
614 1623 : temps_[1] = temp2;
615 : }
616 :
617 1567 : LOperand* dividend() { return inputs_[0]; }
618 : int32_t divisor() const { return divisor_; }
619 : LOperand* temp1() { return temps_[0]; }
620 : LOperand* temp2() { return temps_[1]; }
621 :
622 3134 : DECLARE_CONCRETE_INSTRUCTION(ModByConstI, "mod-by-const-i")
623 1566 : DECLARE_HYDROGEN_ACCESSOR(Mod)
624 :
625 : private:
626 : int32_t divisor_;
627 : };
628 :
629 :
630 0 : class LModI final : public LTemplateInstruction<1, 2, 1> {
631 : public:
632 403 : LModI(LOperand* left, LOperand* right, LOperand* temp) {
633 403 : inputs_[0] = left;
634 403 : inputs_[1] = right;
635 403 : temps_[0] = temp;
636 : }
637 :
638 403 : LOperand* left() { return inputs_[0]; }
639 403 : LOperand* right() { return inputs_[1]; }
640 : LOperand* temp() { return temps_[0]; }
641 :
642 806 : DECLARE_CONCRETE_INSTRUCTION(ModI, "mod-i")
643 403 : DECLARE_HYDROGEN_ACCESSOR(Mod)
644 : };
645 :
646 :
647 0 : class LDivByPowerOf2I final : public LTemplateInstruction<1, 1, 0> {
648 : public:
649 564 : LDivByPowerOf2I(LOperand* dividend, int32_t divisor) {
650 564 : inputs_[0] = dividend;
651 564 : divisor_ = divisor;
652 : }
653 :
654 537 : LOperand* dividend() { return inputs_[0]; }
655 : int32_t divisor() const { return divisor_; }
656 :
657 1074 : DECLARE_CONCRETE_INSTRUCTION(DivByPowerOf2I, "div-by-power-of-2-i")
658 537 : DECLARE_HYDROGEN_ACCESSOR(Div)
659 :
660 : private:
661 : int32_t divisor_;
662 : };
663 :
664 :
665 0 : class LDivByConstI final : public LTemplateInstruction<1, 1, 2> {
666 : public:
667 : LDivByConstI(LOperand* dividend,
668 : int32_t divisor,
669 : LOperand* temp1,
670 1497 : LOperand* temp2) {
671 1497 : inputs_[0] = dividend;
672 1497 : divisor_ = divisor;
673 1497 : temps_[0] = temp1;
674 1497 : temps_[1] = temp2;
675 : }
676 :
677 1417 : LOperand* dividend() { return inputs_[0]; }
678 : int32_t divisor() const { return divisor_; }
679 : LOperand* temp1() { return temps_[0]; }
680 : LOperand* temp2() { return temps_[1]; }
681 :
682 2834 : DECLARE_CONCRETE_INSTRUCTION(DivByConstI, "div-by-const-i")
683 1417 : DECLARE_HYDROGEN_ACCESSOR(Div)
684 :
685 : private:
686 : int32_t divisor_;
687 : };
688 :
689 :
690 0 : class LDivI final : public LTemplateInstruction<1, 2, 1> {
691 : public:
692 453 : LDivI(LOperand* dividend, LOperand* divisor, LOperand* temp) {
693 453 : inputs_[0] = dividend;
694 453 : inputs_[1] = divisor;
695 453 : temps_[0] = temp;
696 : }
697 :
698 453 : LOperand* dividend() { return inputs_[0]; }
699 453 : LOperand* divisor() { return inputs_[1]; }
700 453 : LOperand* temp() { return temps_[0]; }
701 :
702 906 : DECLARE_CONCRETE_INSTRUCTION(DivI, "div-i")
703 453 : DECLARE_HYDROGEN_ACCESSOR(BinaryOperation)
704 : };
705 :
706 :
707 0 : class LFlooringDivByPowerOf2I final : public LTemplateInstruction<1, 1, 0> {
708 : public:
709 519 : LFlooringDivByPowerOf2I(LOperand* dividend, int32_t divisor) {
710 519 : inputs_[0] = dividend;
711 519 : divisor_ = divisor;
712 : }
713 :
714 503 : LOperand* dividend() { return inputs_[0]; }
715 : int32_t divisor() const { return divisor_; }
716 :
717 1006 : DECLARE_CONCRETE_INSTRUCTION(FlooringDivByPowerOf2I,
718 : "flooring-div-by-power-of-2-i")
719 542 : DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv)
720 :
721 : private:
722 : int32_t divisor_;
723 : };
724 :
725 :
726 0 : class LFlooringDivByConstI final : public LTemplateInstruction<1, 1, 3> {
727 : public:
728 : LFlooringDivByConstI(LOperand* dividend,
729 : int32_t divisor,
730 : LOperand* temp1,
731 : LOperand* temp2,
732 2010 : LOperand* temp3) {
733 2010 : inputs_[0] = dividend;
734 2010 : divisor_ = divisor;
735 2010 : temps_[0] = temp1;
736 2010 : temps_[1] = temp2;
737 2010 : temps_[2] = temp3;
738 : }
739 :
740 1944 : LOperand* dividend() { return inputs_[0]; }
741 : int32_t divisor() const { return divisor_; }
742 : LOperand* temp1() { return temps_[0]; }
743 : LOperand* temp2() { return temps_[1]; }
744 1937 : LOperand* temp3() { return temps_[2]; }
745 :
746 3888 : DECLARE_CONCRETE_INSTRUCTION(FlooringDivByConstI, "flooring-div-by-const-i")
747 1937 : DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv)
748 :
749 : private:
750 : int32_t divisor_;
751 : };
752 :
753 :
754 0 : class LFlooringDivI final : public LTemplateInstruction<1, 2, 1> {
755 : public:
756 71 : LFlooringDivI(LOperand* dividend, LOperand* divisor, LOperand* temp) {
757 71 : inputs_[0] = dividend;
758 71 : inputs_[1] = divisor;
759 71 : temps_[0] = temp;
760 : }
761 :
762 71 : LOperand* dividend() { return inputs_[0]; }
763 71 : LOperand* divisor() { return inputs_[1]; }
764 71 : LOperand* temp() { return temps_[0]; }
765 :
766 142 : DECLARE_CONCRETE_INSTRUCTION(FlooringDivI, "flooring-div-i")
767 71 : DECLARE_HYDROGEN_ACCESSOR(MathFloorOfDiv)
768 : };
769 :
770 :
771 0 : class LMulI final : public LTemplateInstruction<1, 2, 0> {
772 : public:
773 7622 : LMulI(LOperand* left, LOperand* right) {
774 7622 : inputs_[0] = left;
775 7622 : inputs_[1] = right;
776 : }
777 :
778 7271 : LOperand* left() { return inputs_[0]; }
779 7271 : LOperand* right() { return inputs_[1]; }
780 :
781 14542 : DECLARE_CONCRETE_INSTRUCTION(MulI, "mul-i")
782 21813 : DECLARE_HYDROGEN_ACCESSOR(Mul)
783 : };
784 :
785 :
786 0 : class LCompareNumericAndBranch final : public LControlInstruction<2, 0> {
787 : public:
788 166018 : LCompareNumericAndBranch(LOperand* left, LOperand* right) {
789 166018 : inputs_[0] = left;
790 166018 : inputs_[1] = right;
791 : }
792 :
793 160751 : LOperand* left() { return inputs_[0]; }
794 160751 : LOperand* right() { return inputs_[1]; }
795 :
796 490737 : DECLARE_CONCRETE_INSTRUCTION(CompareNumericAndBranch,
797 : "compare-numeric-and-branch")
798 474680 : DECLARE_HYDROGEN_ACCESSOR(CompareNumericAndBranch)
799 :
800 169896 : Token::Value op() const { return hydrogen()->token(); }
801 : bool is_double() const {
802 : return hydrogen()->representation().IsDouble();
803 : }
804 :
805 : void PrintDataTo(StringStream* stream) override;
806 : };
807 :
808 : // Math.floor with a double result.
809 0 : class LMathFloorD final : public LTemplateInstruction<1, 1, 0> {
810 : public:
811 4661 : explicit LMathFloorD(LOperand* value) { inputs_[0] = value; }
812 :
813 4495 : LOperand* value() { return inputs_[0]; }
814 :
815 8990 : DECLARE_CONCRETE_INSTRUCTION(MathFloorD, "math-floor-d")
816 : DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation)
817 : };
818 :
819 : // Math.floor with an integer result.
820 0 : class LMathFloorI final : public LTemplateInstruction<1, 1, 0> {
821 : public:
822 18771 : explicit LMathFloorI(LOperand* value) { inputs_[0] = value; }
823 :
824 18289 : LOperand* value() { return inputs_[0]; }
825 :
826 36578 : DECLARE_CONCRETE_INSTRUCTION(MathFloorI, "math-floor-i")
827 18289 : DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation)
828 : };
829 :
830 : // Math.round with a double result.
831 0 : class LMathRoundD final : public LTemplateInstruction<1, 1, 0> {
832 : public:
833 662 : explicit LMathRoundD(LOperand* value) { inputs_[0] = value; }
834 :
835 627 : LOperand* value() { return inputs_[0]; }
836 :
837 1254 : DECLARE_CONCRETE_INSTRUCTION(MathRoundD, "math-round-d")
838 : DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation)
839 : };
840 :
841 : // Math.round with an integer result.
842 0 : class LMathRoundI final : public LTemplateInstruction<1, 1, 1> {
843 : public:
844 726 : LMathRoundI(LOperand* value, LOperand* temp) {
845 726 : inputs_[0] = value;
846 726 : temps_[0] = temp;
847 : }
848 :
849 695 : LOperand* value() { return inputs_[0]; }
850 695 : LOperand* temp() { return temps_[0]; }
851 :
852 1390 : DECLARE_CONCRETE_INSTRUCTION(MathRoundI, "math-round-i")
853 695 : DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation)
854 : };
855 :
856 :
857 0 : class LMathFround final : public LTemplateInstruction<1, 1, 0> {
858 : public:
859 628 : explicit LMathFround(LOperand* value) { inputs_[0] = value; }
860 :
861 628 : LOperand* value() { return inputs_[0]; }
862 :
863 1256 : DECLARE_CONCRETE_INSTRUCTION(MathFround, "math-fround")
864 : };
865 :
866 :
867 0 : class LMathAbs final : public LTemplateInstruction<1, 2, 0> {
868 : public:
869 384 : explicit LMathAbs(LOperand* context, LOperand* value) {
870 384 : inputs_[1] = context;
871 384 : inputs_[0] = value;
872 : }
873 :
874 158 : LOperand* context() { return inputs_[1]; }
875 461 : LOperand* value() { return inputs_[0]; }
876 :
877 685 : DECLARE_CONCRETE_INSTRUCTION(MathAbs, "math-abs")
878 303 : DECLARE_HYDROGEN_ACCESSOR(UnaryMathOperation)
879 : };
880 :
881 :
882 0 : class LMathLog final : public LTemplateInstruction<1, 1, 0> {
883 : public:
884 291 : explicit LMathLog(LOperand* value) {
885 291 : inputs_[0] = value;
886 : }
887 :
888 : LOperand* value() { return inputs_[0]; }
889 :
890 582 : DECLARE_CONCRETE_INSTRUCTION(MathLog, "math-log")
891 : };
892 :
893 :
894 0 : class LMathClz32 final : public LTemplateInstruction<1, 1, 0> {
895 : public:
896 42 : explicit LMathClz32(LOperand* value) {
897 42 : inputs_[0] = value;
898 : }
899 :
900 42 : LOperand* value() { return inputs_[0]; }
901 :
902 84 : DECLARE_CONCRETE_INSTRUCTION(MathClz32, "math-clz32")
903 : };
904 :
905 0 : class LMathCos final : public LTemplateInstruction<1, 1, 0> {
906 : public:
907 60 : explicit LMathCos(LOperand* value) { inputs_[0] = value; }
908 :
909 : LOperand* value() { return inputs_[0]; }
910 :
911 120 : DECLARE_CONCRETE_INSTRUCTION(MathCos, "math-cos")
912 : };
913 :
914 0 : class LMathExp final : public LTemplateInstruction<1, 1, 0> {
915 : public:
916 58 : explicit LMathExp(LOperand* value) { inputs_[0] = value; }
917 :
918 : LOperand* value() { return inputs_[0]; }
919 :
920 116 : DECLARE_CONCRETE_INSTRUCTION(MathExp, "math-exp")
921 : };
922 :
923 0 : class LMathSin final : public LTemplateInstruction<1, 1, 0> {
924 : public:
925 90 : explicit LMathSin(LOperand* value) { inputs_[0] = value; }
926 :
927 : LOperand* value() { return inputs_[0]; }
928 :
929 180 : DECLARE_CONCRETE_INSTRUCTION(MathSin, "math-sin")
930 : };
931 :
932 0 : class LMathSqrt final : public LTemplateInstruction<1, 1, 0> {
933 : public:
934 61 : explicit LMathSqrt(LOperand* value) {
935 61 : inputs_[0] = value;
936 : }
937 :
938 61 : LOperand* value() { return inputs_[0]; }
939 :
940 122 : DECLARE_CONCRETE_INSTRUCTION(MathSqrt, "math-sqrt")
941 : };
942 :
943 :
944 0 : class LMathPowHalf final : public LTemplateInstruction<1, 1, 0> {
945 : public:
946 41 : explicit LMathPowHalf(LOperand* value) {
947 41 : inputs_[0] = value;
948 : }
949 :
950 41 : LOperand* value() { return inputs_[0]; }
951 :
952 82 : DECLARE_CONCRETE_INSTRUCTION(MathPowHalf, "math-pow-half")
953 : };
954 :
955 :
956 0 : class LCmpObjectEqAndBranch final : public LControlInstruction<2, 0> {
957 : public:
958 43374 : LCmpObjectEqAndBranch(LOperand* left, LOperand* right) {
959 43374 : inputs_[0] = left;
960 43374 : inputs_[1] = right;
961 : }
962 :
963 41466 : LOperand* left() { return inputs_[0]; }
964 41466 : LOperand* right() { return inputs_[1]; }
965 :
966 125532 : DECLARE_CONCRETE_INSTRUCTION(CmpObjectEqAndBranch, "cmp-object-eq-and-branch")
967 : };
968 :
969 :
970 0 : class LCmpHoleAndBranch final : public LControlInstruction<1, 0> {
971 : public:
972 33 : explicit LCmpHoleAndBranch(LOperand* object) {
973 33 : inputs_[0] = object;
974 : }
975 :
976 33 : LOperand* object() { return inputs_[0]; }
977 :
978 99 : DECLARE_CONCRETE_INSTRUCTION(CmpHoleAndBranch, "cmp-hole-and-branch")
979 33 : DECLARE_HYDROGEN_ACCESSOR(CompareHoleAndBranch)
980 : };
981 :
982 :
983 0 : class LIsStringAndBranch final : public LControlInstruction<1, 1> {
984 : public:
985 446 : explicit LIsStringAndBranch(LOperand* value, LOperand* temp) {
986 446 : inputs_[0] = value;
987 446 : temps_[0] = temp;
988 : }
989 :
990 426 : LOperand* value() { return inputs_[0]; }
991 426 : LOperand* temp() { return temps_[0]; }
992 :
993 1318 : DECLARE_CONCRETE_INSTRUCTION(IsStringAndBranch, "is-string-and-branch")
994 426 : DECLARE_HYDROGEN_ACCESSOR(IsStringAndBranch)
995 :
996 : void PrintDataTo(StringStream* stream) override;
997 : };
998 :
999 :
1000 0 : class LIsSmiAndBranch final : public LControlInstruction<1, 0> {
1001 : public:
1002 9194 : explicit LIsSmiAndBranch(LOperand* value) {
1003 9194 : inputs_[0] = value;
1004 : }
1005 :
1006 8832 : LOperand* value() { return inputs_[0]; }
1007 :
1008 26800 : DECLARE_CONCRETE_INSTRUCTION(IsSmiAndBranch, "is-smi-and-branch")
1009 : DECLARE_HYDROGEN_ACCESSOR(IsSmiAndBranch)
1010 :
1011 : void PrintDataTo(StringStream* stream) override;
1012 : };
1013 :
1014 :
1015 0 : class LIsUndetectableAndBranch final : public LControlInstruction<1, 1> {
1016 : public:
1017 1257 : explicit LIsUndetectableAndBranch(LOperand* value, LOperand* temp) {
1018 1257 : inputs_[0] = value;
1019 1257 : temps_[0] = temp;
1020 : }
1021 :
1022 1183 : LOperand* value() { return inputs_[0]; }
1023 1183 : LOperand* temp() { return temps_[0]; }
1024 :
1025 3627 : DECLARE_CONCRETE_INSTRUCTION(IsUndetectableAndBranch,
1026 : "is-undetectable-and-branch")
1027 1183 : DECLARE_HYDROGEN_ACCESSOR(IsUndetectableAndBranch)
1028 :
1029 : void PrintDataTo(StringStream* stream) override;
1030 : };
1031 :
1032 :
1033 0 : class LStringCompareAndBranch final : public LControlInstruction<3, 0> {
1034 : public:
1035 : explicit LStringCompareAndBranch(LOperand* context,
1036 : LOperand* left,
1037 15235 : LOperand* right) {
1038 15235 : inputs_[0] = context;
1039 15235 : inputs_[1] = left;
1040 15235 : inputs_[2] = right;
1041 : }
1042 :
1043 : LOperand* context() { return inputs_[0]; }
1044 0 : LOperand* left() { return inputs_[1]; }
1045 0 : LOperand* right() { return inputs_[2]; }
1046 :
1047 28056 : DECLARE_CONCRETE_INSTRUCTION(StringCompareAndBranch,
1048 : "string-compare-and-branch")
1049 13249 : DECLARE_HYDROGEN_ACCESSOR(StringCompareAndBranch)
1050 :
1051 : void PrintDataTo(StringStream* stream) override;
1052 :
1053 13249 : Token::Value op() const { return hydrogen()->token(); }
1054 : };
1055 :
1056 :
1057 0 : class LHasInstanceTypeAndBranch final : public LControlInstruction<1, 0> {
1058 : public:
1059 1966 : explicit LHasInstanceTypeAndBranch(LOperand* value) {
1060 1966 : inputs_[0] = value;
1061 : }
1062 :
1063 1882 : LOperand* value() { return inputs_[0]; }
1064 :
1065 5646 : DECLARE_CONCRETE_INSTRUCTION(HasInstanceTypeAndBranch,
1066 : "has-instance-type-and-branch")
1067 5646 : DECLARE_HYDROGEN_ACCESSOR(HasInstanceTypeAndBranch)
1068 :
1069 : void PrintDataTo(StringStream* stream) override;
1070 : };
1071 :
1072 0 : class LClassOfTestAndBranch final : public LControlInstruction<1, 2> {
1073 : public:
1074 7697 : LClassOfTestAndBranch(LOperand* value, LOperand* temp, LOperand* temp2) {
1075 7697 : inputs_[0] = value;
1076 7697 : temps_[0] = temp;
1077 7697 : temps_[1] = temp2;
1078 : }
1079 :
1080 7327 : LOperand* value() { return inputs_[0]; }
1081 7327 : LOperand* temp() { return temps_[0]; }
1082 7327 : LOperand* temp2() { return temps_[1]; }
1083 :
1084 21981 : DECLARE_CONCRETE_INSTRUCTION(ClassOfTestAndBranch, "class-of-test-and-branch")
1085 7327 : DECLARE_HYDROGEN_ACCESSOR(ClassOfTestAndBranch)
1086 :
1087 : void PrintDataTo(StringStream* stream) override;
1088 : };
1089 :
1090 0 : class LCmpT final : public LTemplateInstruction<1, 3, 0> {
1091 : public:
1092 201242 : LCmpT(LOperand* context, LOperand* left, LOperand* right) {
1093 201242 : inputs_[0] = context;
1094 201242 : inputs_[1] = left;
1095 201242 : inputs_[2] = right;
1096 : }
1097 :
1098 : LOperand* context() { return inputs_[0]; }
1099 : LOperand* left() { return inputs_[1]; }
1100 : LOperand* right() { return inputs_[2]; }
1101 :
1102 399996 : DECLARE_CONCRETE_INSTRUCTION(CmpT, "cmp-t")
1103 199998 : DECLARE_HYDROGEN_ACCESSOR(CompareGeneric)
1104 :
1105 199998 : Token::Value op() const { return hydrogen()->token(); }
1106 : };
1107 :
1108 :
1109 0 : class LHasInPrototypeChainAndBranch final : public LControlInstruction<2, 0> {
1110 : public:
1111 319 : LHasInPrototypeChainAndBranch(LOperand* object, LOperand* prototype) {
1112 319 : inputs_[0] = object;
1113 319 : inputs_[1] = prototype;
1114 : }
1115 :
1116 319 : LOperand* object() const { return inputs_[0]; }
1117 319 : LOperand* prototype() const { return inputs_[1]; }
1118 :
1119 957 : DECLARE_CONCRETE_INSTRUCTION(HasInPrototypeChainAndBranch,
1120 : "has-in-prototype-chain-and-branch")
1121 319 : DECLARE_HYDROGEN_ACCESSOR(HasInPrototypeChainAndBranch)
1122 : };
1123 :
1124 :
1125 0 : class LBoundsCheck final : public LTemplateInstruction<0, 2, 0> {
1126 : public:
1127 31784 : LBoundsCheck(LOperand* index, LOperand* length) {
1128 31784 : inputs_[0] = index;
1129 31784 : inputs_[1] = length;
1130 : }
1131 :
1132 30937 : LOperand* index() { return inputs_[0]; }
1133 35299 : LOperand* length() { return inputs_[1]; }
1134 :
1135 61874 : DECLARE_CONCRETE_INSTRUCTION(BoundsCheck, "bounds-check")
1136 30948 : DECLARE_HYDROGEN_ACCESSOR(BoundsCheck)
1137 : };
1138 :
1139 :
1140 0 : class LBitI final : public LTemplateInstruction<1, 2, 0> {
1141 : public:
1142 89864 : LBitI(LOperand* left, LOperand* right) {
1143 89864 : inputs_[0] = left;
1144 89864 : inputs_[1] = right;
1145 : }
1146 :
1147 88975 : LOperand* left() { return inputs_[0]; }
1148 88975 : LOperand* right() { return inputs_[1]; }
1149 :
1150 88975 : Token::Value op() const { return hydrogen()->op(); }
1151 : bool IsInteger32() const {
1152 : return hydrogen()->representation().IsInteger32();
1153 : }
1154 :
1155 177950 : DECLARE_CONCRETE_INSTRUCTION(BitI, "bit-i")
1156 145513 : DECLARE_HYDROGEN_ACCESSOR(Bitwise)
1157 : };
1158 :
1159 :
1160 0 : class LShiftI final : public LTemplateInstruction<1, 2, 0> {
1161 : public:
1162 : LShiftI(Token::Value op, LOperand* left, LOperand* right, bool can_deopt)
1163 36897 : : op_(op), can_deopt_(can_deopt) {
1164 36897 : inputs_[0] = left;
1165 36897 : inputs_[1] = right;
1166 : }
1167 :
1168 : Token::Value op() const { return op_; }
1169 36218 : LOperand* left() { return inputs_[0]; }
1170 36218 : LOperand* right() { return inputs_[1]; }
1171 : bool can_deopt() const { return can_deopt_; }
1172 :
1173 72436 : DECLARE_CONCRETE_INSTRUCTION(ShiftI, "shift-i")
1174 :
1175 : private:
1176 : Token::Value op_;
1177 : bool can_deopt_;
1178 : };
1179 :
1180 :
1181 0 : class LSubI final : public LTemplateInstruction<1, 2, 0> {
1182 : public:
1183 13540 : LSubI(LOperand* left, LOperand* right) {
1184 13540 : inputs_[0] = left;
1185 13540 : inputs_[1] = right;
1186 : }
1187 :
1188 13202 : LOperand* left() { return inputs_[0]; }
1189 13202 : LOperand* right() { return inputs_[1]; }
1190 :
1191 26404 : DECLARE_CONCRETE_INSTRUCTION(SubI, "sub-i")
1192 24657 : DECLARE_HYDROGEN_ACCESSOR(Sub)
1193 : };
1194 :
1195 :
1196 510638 : class LConstantI final : public LTemplateInstruction<1, 0, 0> {
1197 : public:
1198 1015499 : DECLARE_CONCRETE_INSTRUCTION(ConstantI, "constant-i")
1199 507746 : DECLARE_HYDROGEN_ACCESSOR(Constant)
1200 :
1201 507746 : int32_t value() const { return hydrogen()->Integer32Value(); }
1202 : };
1203 :
1204 :
1205 414557 : class LConstantS final : public LTemplateInstruction<1, 0, 0> {
1206 : public:
1207 826239 : DECLARE_CONCRETE_INSTRUCTION(ConstantS, "constant-s")
1208 413115 : DECLARE_HYDROGEN_ACCESSOR(Constant)
1209 :
1210 413115 : Smi* value() const { return Smi::FromInt(hydrogen()->Integer32Value()); }
1211 : };
1212 :
1213 :
1214 43739 : class LConstantD final : public LTemplateInstruction<1, 0, 0> {
1215 : public:
1216 85992 : DECLARE_CONCRETE_INSTRUCTION(ConstantD, "constant-d")
1217 42996 : DECLARE_HYDROGEN_ACCESSOR(Constant)
1218 :
1219 : uint64_t bits() const { return hydrogen()->DoubleValueAsBits(); }
1220 : };
1221 :
1222 :
1223 8083 : class LConstantE final : public LTemplateInstruction<1, 0, 0> {
1224 : public:
1225 15176 : DECLARE_CONCRETE_INSTRUCTION(ConstantE, "constant-e")
1226 7588 : DECLARE_HYDROGEN_ACCESSOR(Constant)
1227 :
1228 : ExternalReference value() const {
1229 : return hydrogen()->ExternalReferenceValue();
1230 : }
1231 : };
1232 :
1233 :
1234 2620194 : class LConstantT final : public LTemplateInstruction<1, 0, 0> {
1235 : public:
1236 5201240 : DECLARE_CONCRETE_INSTRUCTION(ConstantT, "constant-t")
1237 2597750 : DECLARE_HYDROGEN_ACCESSOR(Constant)
1238 :
1239 : Handle<Object> value(Isolate* isolate) const {
1240 2597750 : return hydrogen()->handle(isolate);
1241 : }
1242 : };
1243 :
1244 :
1245 0 : class LBranch final : public LControlInstruction<1, 0> {
1246 : public:
1247 480810 : explicit LBranch(LOperand* value) {
1248 480810 : inputs_[0] = value;
1249 : }
1250 :
1251 326114 : LOperand* value() { return inputs_[0]; }
1252 :
1253 1274804 : DECLARE_CONCRETE_INSTRUCTION(Branch, "branch")
1254 772431 : DECLARE_HYDROGEN_ACCESSOR(Branch)
1255 :
1256 : void PrintDataTo(StringStream* stream) override;
1257 : };
1258 :
1259 :
1260 0 : class LDebugBreak final : public LTemplateInstruction<0, 0, 0> {
1261 : public:
1262 0 : DECLARE_CONCRETE_INSTRUCTION(DebugBreak, "break")
1263 : };
1264 :
1265 :
1266 0 : class LCmpMapAndBranch final : public LControlInstruction<1, 0> {
1267 : public:
1268 19103 : explicit LCmpMapAndBranch(LOperand* value) {
1269 19103 : inputs_[0] = value;
1270 : }
1271 :
1272 17544 : LOperand* value() { return inputs_[0]; }
1273 :
1274 53438 : DECLARE_CONCRETE_INSTRUCTION(CmpMapAndBranch, "cmp-map-and-branch")
1275 17544 : DECLARE_HYDROGEN_ACCESSOR(CompareMap)
1276 :
1277 : Handle<Map> map() const { return hydrogen()->map().handle(); }
1278 : };
1279 :
1280 :
1281 0 : class LSeqStringGetChar final : public LTemplateInstruction<1, 2, 0> {
1282 : public:
1283 14320 : LSeqStringGetChar(LOperand* string, LOperand* index) {
1284 14320 : inputs_[0] = string;
1285 14320 : inputs_[1] = index;
1286 : }
1287 :
1288 14320 : LOperand* string() const { return inputs_[0]; }
1289 14320 : LOperand* index() const { return inputs_[1]; }
1290 :
1291 28640 : DECLARE_CONCRETE_INSTRUCTION(SeqStringGetChar, "seq-string-get-char")
1292 14320 : DECLARE_HYDROGEN_ACCESSOR(SeqStringGetChar)
1293 : };
1294 :
1295 :
1296 0 : class LSeqStringSetChar final : public LTemplateInstruction<1, 4, 0> {
1297 : public:
1298 : LSeqStringSetChar(LOperand* context,
1299 : LOperand* string,
1300 : LOperand* index,
1301 14320 : LOperand* value) {
1302 14320 : inputs_[0] = context;
1303 14320 : inputs_[1] = string;
1304 14320 : inputs_[2] = index;
1305 14320 : inputs_[3] = value;
1306 : }
1307 :
1308 14320 : LOperand* string() { return inputs_[1]; }
1309 14320 : LOperand* index() { return inputs_[2]; }
1310 14320 : LOperand* value() { return inputs_[3]; }
1311 :
1312 28640 : DECLARE_CONCRETE_INSTRUCTION(SeqStringSetChar, "seq-string-set-char")
1313 14320 : DECLARE_HYDROGEN_ACCESSOR(SeqStringSetChar)
1314 : };
1315 :
1316 :
1317 0 : class LAddI final : public LTemplateInstruction<1, 2, 0> {
1318 : public:
1319 148546 : LAddI(LOperand* left, LOperand* right) {
1320 148546 : inputs_[0] = left;
1321 148546 : inputs_[1] = right;
1322 : }
1323 :
1324 147627 : LOperand* left() { return inputs_[0]; }
1325 147627 : LOperand* right() { return inputs_[1]; }
1326 :
1327 296173 : static bool UseLea(HAdd* add) {
1328 762978 : return !add->CheckFlag(HValue::kCanOverflow) &&
1329 637437 : add->BetterLeftOperand()->UseCount() > 1;
1330 : }
1331 :
1332 295254 : DECLARE_CONCRETE_INSTRUCTION(AddI, "add-i")
1333 381076 : DECLARE_HYDROGEN_ACCESSOR(Add)
1334 : };
1335 :
1336 :
1337 0 : class LMathMinMax final : public LTemplateInstruction<1, 2, 0> {
1338 : public:
1339 1581 : LMathMinMax(LOperand* left, LOperand* right) {
1340 1581 : inputs_[0] = left;
1341 1581 : inputs_[1] = right;
1342 : }
1343 :
1344 1582 : LOperand* left() { return inputs_[0]; }
1345 1582 : LOperand* right() { return inputs_[1]; }
1346 :
1347 3164 : DECLARE_CONCRETE_INSTRUCTION(MathMinMax, "math-min-max")
1348 1582 : DECLARE_HYDROGEN_ACCESSOR(MathMinMax)
1349 : };
1350 :
1351 :
1352 0 : class LPower final : public LTemplateInstruction<1, 2, 0> {
1353 : public:
1354 827 : LPower(LOperand* left, LOperand* right) {
1355 827 : inputs_[0] = left;
1356 827 : inputs_[1] = right;
1357 : }
1358 :
1359 : LOperand* left() { return inputs_[0]; }
1360 : LOperand* right() { return inputs_[1]; }
1361 :
1362 1654 : DECLARE_CONCRETE_INSTRUCTION(Power, "power")
1363 827 : DECLARE_HYDROGEN_ACCESSOR(Power)
1364 : };
1365 :
1366 :
1367 0 : class LArithmeticD final : public LTemplateInstruction<1, 2, 0> {
1368 : public:
1369 : LArithmeticD(Token::Value op, LOperand* left, LOperand* right)
1370 83800 : : op_(op) {
1371 83800 : inputs_[0] = left;
1372 83800 : inputs_[1] = right;
1373 : }
1374 :
1375 : Token::Value op() const { return op_; }
1376 82952 : LOperand* left() { return inputs_[0]; }
1377 82952 : LOperand* right() { return inputs_[1]; }
1378 :
1379 165904 : Opcode opcode() const override { return LInstruction::kArithmeticD; }
1380 : void CompileToNative(LCodeGen* generator) override;
1381 : const char* Mnemonic() const override;
1382 :
1383 : private:
1384 : Token::Value op_;
1385 : };
1386 :
1387 :
1388 0 : class LArithmeticT final : public LTemplateInstruction<1, 3, 0> {
1389 : public:
1390 : LArithmeticT(Token::Value op,
1391 : LOperand* context,
1392 : LOperand* left,
1393 : LOperand* right)
1394 47577 : : op_(op) {
1395 47577 : inputs_[0] = context;
1396 47577 : inputs_[1] = left;
1397 47577 : inputs_[2] = right;
1398 : }
1399 :
1400 : Token::Value op() const { return op_; }
1401 : LOperand* context() { return inputs_[0]; }
1402 : LOperand* left() { return inputs_[1]; }
1403 : LOperand* right() { return inputs_[2]; }
1404 :
1405 95096 : Opcode opcode() const override { return LInstruction::kArithmeticT; }
1406 : void CompileToNative(LCodeGen* generator) override;
1407 : const char* Mnemonic() const override;
1408 :
1409 : DECLARE_HYDROGEN_ACCESSOR(BinaryOperation)
1410 :
1411 : private:
1412 : Token::Value op_;
1413 : };
1414 :
1415 :
1416 0 : class LReturn final : public LTemplateInstruction<0, 3, 0> {
1417 : public:
1418 : explicit LReturn(LOperand* value,
1419 : LOperand* context,
1420 365863 : LOperand* parameter_count) {
1421 365863 : inputs_[0] = value;
1422 365863 : inputs_[1] = context;
1423 365863 : inputs_[2] = parameter_count;
1424 : }
1425 :
1426 : LOperand* value() { return inputs_[0]; }
1427 : LOperand* context() { return inputs_[1]; }
1428 :
1429 : bool has_constant_parameter_count() {
1430 : return parameter_count()->IsConstantOperand();
1431 : }
1432 : LConstantOperand* constant_parameter_count() {
1433 : DCHECK(has_constant_parameter_count());
1434 : return LConstantOperand::cast(parameter_count());
1435 : }
1436 353697 : LOperand* parameter_count() { return inputs_[2]; }
1437 :
1438 713276 : DECLARE_CONCRETE_INSTRUCTION(Return, "return")
1439 : DECLARE_HYDROGEN_ACCESSOR(Return)
1440 : };
1441 :
1442 :
1443 0 : class LLoadNamedField final : public LTemplateInstruction<1, 1, 0> {
1444 : public:
1445 246761 : explicit LLoadNamedField(LOperand* object) {
1446 246761 : inputs_[0] = object;
1447 : }
1448 :
1449 240928 : LOperand* object() { return inputs_[0]; }
1450 :
1451 481856 : DECLARE_CONCRETE_INSTRUCTION(LoadNamedField, "load-named-field")
1452 320356 : DECLARE_HYDROGEN_ACCESSOR(LoadNamedField)
1453 : };
1454 :
1455 :
1456 0 : class LLoadFunctionPrototype final : public LTemplateInstruction<1, 1, 0> {
1457 : public:
1458 5770 : explicit LLoadFunctionPrototype(LOperand* function) {
1459 5770 : inputs_[0] = function;
1460 : }
1461 :
1462 11540 : DECLARE_CONCRETE_INSTRUCTION(LoadFunctionPrototype, "load-function-prototype")
1463 : DECLARE_HYDROGEN_ACCESSOR(LoadFunctionPrototype)
1464 :
1465 5770 : LOperand* function() { return inputs_[0]; }
1466 : };
1467 :
1468 :
1469 5298 : class LLoadRoot final : public LTemplateInstruction<1, 0, 0> {
1470 : public:
1471 10404 : DECLARE_CONCRETE_INSTRUCTION(LoadRoot, "load-root")
1472 5202 : DECLARE_HYDROGEN_ACCESSOR(LoadRoot)
1473 :
1474 5202 : Heap::RootListIndex index() const { return hydrogen()->index(); }
1475 : };
1476 :
1477 :
1478 : inline static bool ExternalArrayOpRequiresTemp(
1479 : Representation key_representation,
1480 : ElementsKind elements_kind) {
1481 : // Operations that require the key to be divided by two to be converted into
1482 : // an index cannot fold the scale operation into a load and need an extra
1483 : // temp register to do the work.
1484 : return SmiValuesAre31Bits() && key_representation.IsSmi() &&
1485 : (elements_kind == UINT8_ELEMENTS || elements_kind == INT8_ELEMENTS ||
1486 : elements_kind == UINT8_CLAMPED_ELEMENTS);
1487 : }
1488 :
1489 :
1490 0 : class LLoadKeyed final : public LTemplateInstruction<1, 3, 0> {
1491 : public:
1492 50531 : LLoadKeyed(LOperand* elements, LOperand* key, LOperand* backing_store_owner) {
1493 50530 : inputs_[0] = elements;
1494 50530 : inputs_[1] = key;
1495 50530 : inputs_[2] = backing_store_owner;
1496 : }
1497 :
1498 98300 : DECLARE_CONCRETE_INSTRUCTION(LoadKeyed, "load-keyed")
1499 187396 : DECLARE_HYDROGEN_ACCESSOR(LoadKeyed)
1500 :
1501 : bool is_fixed_typed_array() const {
1502 49150 : return hydrogen()->is_fixed_typed_array();
1503 : }
1504 49588 : LOperand* elements() { return inputs_[0]; }
1505 49150 : LOperand* key() { return inputs_[1]; }
1506 : LOperand* backing_store_owner() { return inputs_[2]; }
1507 : void PrintDataTo(StringStream* stream) override;
1508 47562 : uint32_t base_offset() const { return hydrogen()->base_offset(); }
1509 : ElementsKind elements_kind() const {
1510 : return hydrogen()->elements_kind();
1511 : }
1512 : };
1513 :
1514 :
1515 0 : class LLoadContextSlot final : public LTemplateInstruction<1, 1, 0> {
1516 : public:
1517 304607 : explicit LLoadContextSlot(LOperand* context) {
1518 304607 : inputs_[0] = context;
1519 : }
1520 :
1521 299284 : LOperand* context() { return inputs_[0]; }
1522 :
1523 598568 : DECLARE_CONCRETE_INSTRUCTION(LoadContextSlot, "load-context-slot")
1524 611276 : DECLARE_HYDROGEN_ACCESSOR(LoadContextSlot)
1525 :
1526 299284 : int slot_index() { return hydrogen()->slot_index(); }
1527 :
1528 : void PrintDataTo(StringStream* stream) override;
1529 : };
1530 :
1531 :
1532 0 : class LStoreContextSlot final : public LTemplateInstruction<0, 2, 1> {
1533 : public:
1534 70171 : LStoreContextSlot(LOperand* context, LOperand* value, LOperand* temp) {
1535 70171 : inputs_[0] = context;
1536 70171 : inputs_[1] = value;
1537 70171 : temps_[0] = temp;
1538 : }
1539 :
1540 69884 : LOperand* context() { return inputs_[0]; }
1541 69884 : LOperand* value() { return inputs_[1]; }
1542 38371 : LOperand* temp() { return temps_[0]; }
1543 :
1544 139768 : DECLARE_CONCRETE_INSTRUCTION(StoreContextSlot, "store-context-slot")
1545 248631 : DECLARE_HYDROGEN_ACCESSOR(StoreContextSlot)
1546 :
1547 108255 : int slot_index() { return hydrogen()->slot_index(); }
1548 :
1549 : void PrintDataTo(StringStream* stream) override;
1550 : };
1551 :
1552 :
1553 0 : class LPushArgument final : public LTemplateInstruction<0, 1, 0> {
1554 : public:
1555 1361281 : explicit LPushArgument(LOperand* value) {
1556 1361281 : inputs_[0] = value;
1557 : }
1558 :
1559 1346240 : LOperand* value() { return inputs_[0]; }
1560 :
1561 2692480 : DECLARE_CONCRETE_INSTRUCTION(PushArgument, "push-argument")
1562 : };
1563 :
1564 :
1565 0 : class LDrop final : public LTemplateInstruction<0, 0, 0> {
1566 : public:
1567 247 : explicit LDrop(int count) : count_(count) { }
1568 :
1569 : int count() const { return count_; }
1570 :
1571 445 : DECLARE_CONCRETE_INSTRUCTION(Drop, "drop")
1572 :
1573 : private:
1574 : int count_;
1575 : };
1576 :
1577 :
1578 0 : class LStoreCodeEntry final : public LTemplateInstruction<0, 2, 0> {
1579 : public:
1580 0 : LStoreCodeEntry(LOperand* function, LOperand* code_object) {
1581 0 : inputs_[0] = function;
1582 0 : inputs_[1] = code_object;
1583 : }
1584 :
1585 0 : LOperand* function() { return inputs_[0]; }
1586 0 : LOperand* code_object() { return inputs_[1]; }
1587 :
1588 : void PrintDataTo(StringStream* stream) override;
1589 :
1590 0 : DECLARE_CONCRETE_INSTRUCTION(StoreCodeEntry, "store-code-entry")
1591 : DECLARE_HYDROGEN_ACCESSOR(StoreCodeEntry)
1592 : };
1593 :
1594 :
1595 0 : class LInnerAllocatedObject final : public LTemplateInstruction<1, 2, 0> {
1596 : public:
1597 7160 : LInnerAllocatedObject(LOperand* base_object, LOperand* offset) {
1598 7160 : inputs_[0] = base_object;
1599 7160 : inputs_[1] = offset;
1600 : }
1601 :
1602 7160 : LOperand* base_object() const { return inputs_[0]; }
1603 7160 : LOperand* offset() const { return inputs_[1]; }
1604 :
1605 : void PrintDataTo(StringStream* stream) override;
1606 :
1607 14320 : DECLARE_CONCRETE_INSTRUCTION(InnerAllocatedObject, "inner-allocated-object")
1608 : };
1609 :
1610 :
1611 21991 : class LThisFunction final : public LTemplateInstruction<1, 0, 0> {
1612 : public:
1613 43866 : DECLARE_CONCRETE_INSTRUCTION(ThisFunction, "this-function")
1614 : DECLARE_HYDROGEN_ACCESSOR(ThisFunction)
1615 : };
1616 :
1617 :
1618 286095 : class LContext final : public LTemplateInstruction<1, 0, 0> {
1619 : public:
1620 562908 : DECLARE_CONCRETE_INSTRUCTION(Context, "context")
1621 : DECLARE_HYDROGEN_ACCESSOR(Context)
1622 : };
1623 :
1624 :
1625 0 : class LDeclareGlobals final : public LTemplateInstruction<0, 1, 0> {
1626 : public:
1627 12333 : explicit LDeclareGlobals(LOperand* context) {
1628 12333 : inputs_[0] = context;
1629 : }
1630 :
1631 : LOperand* context() { return inputs_[0]; }
1632 :
1633 24666 : DECLARE_CONCRETE_INSTRUCTION(DeclareGlobals, "declare-globals")
1634 36999 : DECLARE_HYDROGEN_ACCESSOR(DeclareGlobals)
1635 : };
1636 :
1637 :
1638 0 : class LCallWithDescriptor final : public LTemplateResultInstruction<1> {
1639 : public:
1640 852958 : LCallWithDescriptor(CallInterfaceDescriptor descriptor,
1641 : const ZoneList<LOperand*>& operands, Zone* zone)
1642 : : inputs_(descriptor.GetRegisterParameterCount() +
1643 : kImplicitRegisterParameterCount,
1644 1705916 : zone) {
1645 : DCHECK(descriptor.GetRegisterParameterCount() +
1646 : kImplicitRegisterParameterCount ==
1647 : operands.length());
1648 : inputs_.AddAll(operands, zone);
1649 852957 : }
1650 :
1651 848446 : LOperand* target() const { return inputs_[0]; }
1652 :
1653 848446 : DECLARE_HYDROGEN_ACCESSOR(CallWithDescriptor)
1654 :
1655 : // The target and context are passed as implicit parameters that are not
1656 : // explicitly listed in the descriptor.
1657 : static const int kImplicitRegisterParameterCount = 2;
1658 :
1659 : private:
1660 1696892 : DECLARE_CONCRETE_INSTRUCTION(CallWithDescriptor, "call-with-descriptor")
1661 :
1662 : void PrintDataTo(StringStream* stream) override;
1663 :
1664 0 : int arity() const { return hydrogen()->argument_count() - 1; }
1665 :
1666 : ZoneList<LOperand*> inputs_;
1667 :
1668 : // Iterator support.
1669 1705913 : int InputCount() final { return inputs_.length(); }
1670 34858928 : LOperand* InputAt(int i) final { return inputs_[i]; }
1671 :
1672 1705909 : int TempCount() final { return 0; }
1673 0 : LOperand* TempAt(int i) final { return NULL; }
1674 : };
1675 :
1676 :
1677 0 : class LInvokeFunction final : public LTemplateInstruction<1, 2, 0> {
1678 : public:
1679 129298 : LInvokeFunction(LOperand* context, LOperand* function) {
1680 129297 : inputs_[0] = context;
1681 129297 : inputs_[1] = function;
1682 : }
1683 :
1684 : LOperand* context() { return inputs_[0]; }
1685 0 : LOperand* function() { return inputs_[1]; }
1686 :
1687 252166 : DECLARE_CONCRETE_INSTRUCTION(InvokeFunction, "invoke-function")
1688 252166 : DECLARE_HYDROGEN_ACCESSOR(InvokeFunction)
1689 :
1690 : void PrintDataTo(StringStream* stream) override;
1691 :
1692 126119 : int arity() const { return hydrogen()->argument_count() - 1; }
1693 : };
1694 :
1695 :
1696 0 : class LCallNewArray final : public LTemplateInstruction<1, 2, 0> {
1697 : public:
1698 404 : LCallNewArray(LOperand* context, LOperand* constructor) {
1699 404 : inputs_[0] = context;
1700 404 : inputs_[1] = constructor;
1701 : }
1702 :
1703 : LOperand* context() { return inputs_[0]; }
1704 0 : LOperand* constructor() { return inputs_[1]; }
1705 :
1706 804 : DECLARE_CONCRETE_INSTRUCTION(CallNewArray, "call-new-array")
1707 1608 : DECLARE_HYDROGEN_ACCESSOR(CallNewArray)
1708 :
1709 : void PrintDataTo(StringStream* stream) override;
1710 :
1711 1206 : int arity() const { return hydrogen()->argument_count() - 1; }
1712 : };
1713 :
1714 :
1715 0 : class LCallRuntime final : public LTemplateInstruction<1, 1, 0> {
1716 : public:
1717 104667 : explicit LCallRuntime(LOperand* context) {
1718 104667 : inputs_[0] = context;
1719 : }
1720 :
1721 : LOperand* context() { return inputs_[0]; }
1722 :
1723 206440 : DECLARE_CONCRETE_INSTRUCTION(CallRuntime, "call-runtime")
1724 311106 : DECLARE_HYDROGEN_ACCESSOR(CallRuntime)
1725 :
1726 104666 : bool ClobbersDoubleRegisters(Isolate* isolate) const override {
1727 104666 : return save_doubles() == kDontSaveFPRegs;
1728 : }
1729 :
1730 103220 : const Runtime::Function* function() const { return hydrogen()->function(); }
1731 103220 : int arity() const { return hydrogen()->argument_count(); }
1732 207886 : SaveFPRegsMode save_doubles() const { return hydrogen()->save_doubles(); }
1733 : };
1734 :
1735 :
1736 0 : class LInteger32ToDouble final : public LTemplateInstruction<1, 1, 0> {
1737 : public:
1738 22484 : explicit LInteger32ToDouble(LOperand* value) {
1739 22484 : inputs_[0] = value;
1740 : }
1741 :
1742 22389 : LOperand* value() { return inputs_[0]; }
1743 :
1744 44778 : DECLARE_CONCRETE_INSTRUCTION(Integer32ToDouble, "int32-to-double")
1745 : };
1746 :
1747 :
1748 0 : class LUint32ToDouble final : public LTemplateInstruction<1, 1, 0> {
1749 : public:
1750 650 : explicit LUint32ToDouble(LOperand* value) {
1751 650 : inputs_[0] = value;
1752 : }
1753 :
1754 650 : LOperand* value() { return inputs_[0]; }
1755 :
1756 1300 : DECLARE_CONCRETE_INSTRUCTION(Uint32ToDouble, "uint32-to-double")
1757 : };
1758 :
1759 :
1760 0 : class LNumberTagI final : public LTemplateInstruction<1, 1, 2> {
1761 : public:
1762 0 : LNumberTagI(LOperand* value, LOperand* temp1, LOperand* temp2) {
1763 0 : inputs_[0] = value;
1764 0 : temps_[0] = temp1;
1765 0 : temps_[1] = temp2;
1766 : }
1767 :
1768 0 : LOperand* value() { return inputs_[0]; }
1769 0 : LOperand* temp1() { return temps_[0]; }
1770 0 : LOperand* temp2() { return temps_[1]; }
1771 :
1772 0 : DECLARE_CONCRETE_INSTRUCTION(NumberTagI, "number-tag-i")
1773 : };
1774 :
1775 :
1776 0 : class LNumberTagU final : public LTemplateInstruction<1, 1, 2> {
1777 : public:
1778 776 : LNumberTagU(LOperand* value, LOperand* temp1, LOperand* temp2) {
1779 776 : inputs_[0] = value;
1780 776 : temps_[0] = temp1;
1781 776 : temps_[1] = temp2;
1782 : }
1783 :
1784 1552 : LOperand* value() { return inputs_[0]; }
1785 776 : LOperand* temp1() { return temps_[0]; }
1786 776 : LOperand* temp2() { return temps_[1]; }
1787 :
1788 2328 : DECLARE_CONCRETE_INSTRUCTION(NumberTagU, "number-tag-u")
1789 : };
1790 :
1791 :
1792 0 : class LNumberTagD final : public LTemplateInstruction<1, 1, 1> {
1793 : public:
1794 27004 : explicit LNumberTagD(LOperand* value, LOperand* temp) {
1795 27005 : inputs_[0] = value;
1796 27005 : temps_[0] = temp;
1797 : }
1798 :
1799 26492 : LOperand* value() { return inputs_[0]; }
1800 26492 : LOperand* temp() { return temps_[0]; }
1801 :
1802 79476 : DECLARE_CONCRETE_INSTRUCTION(NumberTagD, "number-tag-d")
1803 : DECLARE_HYDROGEN_ACCESSOR(Change)
1804 : };
1805 :
1806 :
1807 : // Sometimes truncating conversion from a tagged value to an int32.
1808 0 : class LDoubleToI final : public LTemplateInstruction<1, 1, 0> {
1809 : public:
1810 8980 : explicit LDoubleToI(LOperand* value) {
1811 8980 : inputs_[0] = value;
1812 : }
1813 :
1814 8815 : LOperand* value() { return inputs_[0]; }
1815 :
1816 17630 : DECLARE_CONCRETE_INSTRUCTION(DoubleToI, "double-to-i")
1817 8815 : DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)
1818 :
1819 : bool truncating() { return hydrogen()->CanTruncateToInt32(); }
1820 : };
1821 :
1822 :
1823 0 : class LDoubleToSmi final : public LTemplateInstruction<1, 1, 0> {
1824 : public:
1825 82 : explicit LDoubleToSmi(LOperand* value) {
1826 82 : inputs_[0] = value;
1827 : }
1828 :
1829 82 : LOperand* value() { return inputs_[0]; }
1830 :
1831 164 : DECLARE_CONCRETE_INSTRUCTION(DoubleToSmi, "double-to-smi")
1832 82 : DECLARE_HYDROGEN_ACCESSOR(UnaryOperation)
1833 : };
1834 :
1835 :
1836 : // Truncating conversion from a tagged value to an int32.
1837 0 : class LTaggedToI final : public LTemplateInstruction<1, 1, 1> {
1838 : public:
1839 71568 : LTaggedToI(LOperand* value, LOperand* temp) {
1840 71568 : inputs_[0] = value;
1841 71568 : temps_[0] = temp;
1842 : }
1843 :
1844 139130 : LOperand* value() { return inputs_[0]; }
1845 53184 : LOperand* temp() { return temps_[0]; }
1846 :
1847 208697 : DECLARE_CONCRETE_INSTRUCTION(TaggedToI, "tagged-to-i")
1848 192314 : DECLARE_HYDROGEN_ACCESSOR(Change)
1849 :
1850 : bool truncating() { return hydrogen()->CanTruncateToInt32(); }
1851 : };
1852 :
1853 :
1854 0 : class LSmiTag final : public LTemplateInstruction<1, 1, 0> {
1855 : public:
1856 125503 : explicit LSmiTag(LOperand* value) {
1857 125503 : inputs_[0] = value;
1858 : }
1859 :
1860 123017 : LOperand* value() { return inputs_[0]; }
1861 :
1862 246034 : DECLARE_CONCRETE_INSTRUCTION(SmiTag, "smi-tag")
1863 123017 : DECLARE_HYDROGEN_ACCESSOR(Change)
1864 : };
1865 :
1866 :
1867 0 : class LNumberUntagD final : public LTemplateInstruction<1, 1, 0> {
1868 : public:
1869 54125 : explicit LNumberUntagD(LOperand* value) {
1870 54125 : inputs_[0] = value;
1871 : }
1872 :
1873 52946 : LOperand* value() { return inputs_[0]; }
1874 :
1875 105892 : DECLARE_CONCRETE_INSTRUCTION(NumberUntagD, "double-untag")
1876 105892 : DECLARE_HYDROGEN_ACCESSOR(Change);
1877 :
1878 : bool truncating() { return hydrogen()->CanTruncateToNumber(); }
1879 : };
1880 :
1881 :
1882 0 : class LSmiUntag final : public LTemplateInstruction<1, 1, 0> {
1883 : public:
1884 : LSmiUntag(LOperand* value, bool needs_check)
1885 4422 : : needs_check_(needs_check) {
1886 4422 : inputs_[0] = value;
1887 : }
1888 :
1889 4374 : LOperand* value() { return inputs_[0]; }
1890 : bool needs_check() const { return needs_check_; }
1891 :
1892 8748 : DECLARE_CONCRETE_INSTRUCTION(SmiUntag, "smi-untag")
1893 :
1894 : private:
1895 : bool needs_check_;
1896 : };
1897 :
1898 :
1899 0 : class LStoreNamedField final : public LTemplateInstruction<0, 2, 1> {
1900 : public:
1901 181292 : LStoreNamedField(LOperand* object, LOperand* value, LOperand* temp) {
1902 181292 : inputs_[0] = object;
1903 181292 : inputs_[1] = value;
1904 181292 : temps_[0] = temp;
1905 : }
1906 :
1907 176411 : LOperand* object() { return inputs_[0]; }
1908 191213 : LOperand* value() { return inputs_[1]; }
1909 23657 : LOperand* temp() { return temps_[0]; }
1910 :
1911 352822 : DECLARE_CONCRETE_INSTRUCTION(StoreNamedField, "store-named-field")
1912 176411 : DECLARE_HYDROGEN_ACCESSOR(StoreNamedField)
1913 :
1914 : void PrintDataTo(StringStream* stream) override;
1915 :
1916 : Representation representation() const {
1917 : return hydrogen()->field_representation();
1918 : }
1919 : };
1920 :
1921 :
1922 0 : class LStoreKeyed final : public LTemplateInstruction<0, 4, 0> {
1923 : public:
1924 : LStoreKeyed(LOperand* object, LOperand* key, LOperand* value,
1925 27953 : LOperand* backing_store_owner) {
1926 27953 : inputs_[0] = object;
1927 27953 : inputs_[1] = key;
1928 27953 : inputs_[2] = value;
1929 27953 : inputs_[3] = backing_store_owner;
1930 : }
1931 :
1932 : bool is_fixed_typed_array() const {
1933 27752 : return hydrogen()->is_fixed_typed_array();
1934 : }
1935 34282 : LOperand* elements() { return inputs_[0]; }
1936 27752 : LOperand* key() { return inputs_[1]; }
1937 34282 : LOperand* value() { return inputs_[2]; }
1938 : LOperand* backing_store_owner() { return inputs_[3]; }
1939 : ElementsKind elements_kind() const { return hydrogen()->elements_kind(); }
1940 :
1941 55504 : DECLARE_CONCRETE_INSTRUCTION(StoreKeyed, "store-keyed")
1942 81461 : DECLARE_HYDROGEN_ACCESSOR(StoreKeyed)
1943 :
1944 : void PrintDataTo(StringStream* stream) override;
1945 5963 : bool NeedsCanonicalization() { return hydrogen()->NeedsCanonicalization(); }
1946 27752 : uint32_t base_offset() const { return hydrogen()->base_offset(); }
1947 : };
1948 :
1949 :
1950 0 : class LTransitionElementsKind final : public LTemplateInstruction<0, 2, 2> {
1951 : public:
1952 : LTransitionElementsKind(LOperand* object,
1953 : LOperand* context,
1954 : LOperand* new_map_temp,
1955 754 : LOperand* temp) {
1956 754 : inputs_[0] = object;
1957 754 : inputs_[1] = context;
1958 754 : temps_[0] = new_map_temp;
1959 754 : temps_[1] = temp;
1960 : }
1961 :
1962 754 : LOperand* object() { return inputs_[0]; }
1963 : LOperand* context() { return inputs_[1]; }
1964 352 : LOperand* new_map_temp() { return temps_[0]; }
1965 352 : LOperand* temp() { return temps_[1]; }
1966 :
1967 1508 : DECLARE_CONCRETE_INSTRUCTION(TransitionElementsKind,
1968 : "transition-elements-kind")
1969 754 : DECLARE_HYDROGEN_ACCESSOR(TransitionElementsKind)
1970 :
1971 : void PrintDataTo(StringStream* stream) override;
1972 :
1973 : Handle<Map> original_map() { return hydrogen()->original_map().handle(); }
1974 : Handle<Map> transitioned_map() {
1975 : return hydrogen()->transitioned_map().handle();
1976 : }
1977 754 : ElementsKind from_kind() { return hydrogen()->from_kind(); }
1978 : ElementsKind to_kind() { return hydrogen()->to_kind(); }
1979 : };
1980 :
1981 :
1982 0 : class LTrapAllocationMemento final : public LTemplateInstruction<0, 1, 1> {
1983 : public:
1984 : LTrapAllocationMemento(LOperand* object,
1985 37 : LOperand* temp) {
1986 37 : inputs_[0] = object;
1987 37 : temps_[0] = temp;
1988 : }
1989 :
1990 37 : LOperand* object() { return inputs_[0]; }
1991 37 : LOperand* temp() { return temps_[0]; }
1992 :
1993 74 : DECLARE_CONCRETE_INSTRUCTION(TrapAllocationMemento,
1994 : "trap-allocation-memento")
1995 : };
1996 :
1997 :
1998 0 : class LMaybeGrowElements final : public LTemplateInstruction<1, 5, 0> {
1999 : public:
2000 : LMaybeGrowElements(LOperand* context, LOperand* object, LOperand* elements,
2001 2584 : LOperand* key, LOperand* current_capacity) {
2002 2584 : inputs_[0] = context;
2003 2584 : inputs_[1] = object;
2004 2584 : inputs_[2] = elements;
2005 2584 : inputs_[3] = key;
2006 2584 : inputs_[4] = current_capacity;
2007 : }
2008 :
2009 : LOperand* context() { return inputs_[0]; }
2010 2539 : LOperand* object() { return inputs_[1]; }
2011 2543 : LOperand* elements() { return inputs_[2]; }
2012 5082 : LOperand* key() { return inputs_[3]; }
2013 2543 : LOperand* current_capacity() { return inputs_[4]; }
2014 :
2015 2584 : bool ClobbersDoubleRegisters(Isolate* isolate) const override { return true; }
2016 :
2017 2539 : DECLARE_HYDROGEN_ACCESSOR(MaybeGrowElements)
2018 7672 : DECLARE_CONCRETE_INSTRUCTION(MaybeGrowElements, "maybe-grow-elements")
2019 : };
2020 :
2021 :
2022 0 : class LStringAdd final : public LTemplateInstruction<1, 3, 0> {
2023 : public:
2024 21242 : LStringAdd(LOperand* context, LOperand* left, LOperand* right) {
2025 21242 : inputs_[0] = context;
2026 21242 : inputs_[1] = left;
2027 21242 : inputs_[2] = right;
2028 : }
2029 :
2030 : LOperand* context() { return inputs_[0]; }
2031 : LOperand* left() { return inputs_[1]; }
2032 : LOperand* right() { return inputs_[2]; }
2033 :
2034 42192 : DECLARE_CONCRETE_INSTRUCTION(StringAdd, "string-add")
2035 21096 : DECLARE_HYDROGEN_ACCESSOR(StringAdd)
2036 : };
2037 :
2038 :
2039 0 : class LStringCharCodeAt final : public LTemplateInstruction<1, 3, 0> {
2040 : public:
2041 377 : LStringCharCodeAt(LOperand* context, LOperand* string, LOperand* index) {
2042 377 : inputs_[0] = context;
2043 377 : inputs_[1] = string;
2044 377 : inputs_[2] = index;
2045 : }
2046 :
2047 374 : LOperand* context() { return inputs_[0]; }
2048 748 : LOperand* string() { return inputs_[1]; }
2049 748 : LOperand* index() { return inputs_[2]; }
2050 :
2051 1122 : DECLARE_CONCRETE_INSTRUCTION(StringCharCodeAt, "string-char-code-at")
2052 : DECLARE_HYDROGEN_ACCESSOR(StringCharCodeAt)
2053 : };
2054 :
2055 :
2056 0 : class LStringCharFromCode final : public LTemplateInstruction<1, 2, 0> {
2057 : public:
2058 477 : explicit LStringCharFromCode(LOperand* context, LOperand* char_code) {
2059 477 : inputs_[0] = context;
2060 477 : inputs_[1] = char_code;
2061 : }
2062 :
2063 471 : LOperand* context() { return inputs_[0]; }
2064 942 : LOperand* char_code() { return inputs_[1]; }
2065 :
2066 1413 : DECLARE_CONCRETE_INSTRUCTION(StringCharFromCode, "string-char-from-code")
2067 : DECLARE_HYDROGEN_ACCESSOR(StringCharFromCode)
2068 : };
2069 :
2070 :
2071 0 : class LCheckValue final : public LTemplateInstruction<0, 1, 0> {
2072 : public:
2073 36259 : explicit LCheckValue(LOperand* value) {
2074 36259 : inputs_[0] = value;
2075 : }
2076 :
2077 35054 : LOperand* value() { return inputs_[0]; }
2078 :
2079 70108 : DECLARE_CONCRETE_INSTRUCTION(CheckValue, "check-value")
2080 35054 : DECLARE_HYDROGEN_ACCESSOR(CheckValue)
2081 : };
2082 :
2083 :
2084 0 : class LCheckArrayBufferNotNeutered final
2085 : : public LTemplateInstruction<0, 1, 0> {
2086 : public:
2087 2361 : explicit LCheckArrayBufferNotNeutered(LOperand* view) { inputs_[0] = view; }
2088 :
2089 2360 : LOperand* view() { return inputs_[0]; }
2090 :
2091 4720 : DECLARE_CONCRETE_INSTRUCTION(CheckArrayBufferNotNeutered,
2092 : "check-array-buffer-not-neutered")
2093 : DECLARE_HYDROGEN_ACCESSOR(CheckArrayBufferNotNeutered)
2094 : };
2095 :
2096 :
2097 0 : class LCheckInstanceType final : public LTemplateInstruction<0, 1, 0> {
2098 : public:
2099 43198 : explicit LCheckInstanceType(LOperand* value) {
2100 43198 : inputs_[0] = value;
2101 : }
2102 :
2103 42686 : LOperand* value() { return inputs_[0]; }
2104 :
2105 85372 : DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType, "check-instance-type")
2106 42686 : DECLARE_HYDROGEN_ACCESSOR(CheckInstanceType)
2107 : };
2108 :
2109 :
2110 0 : class LCheckMaps final : public LTemplateInstruction<0, 1, 0> {
2111 : public:
2112 195493 : explicit LCheckMaps(LOperand* value = NULL) {
2113 195493 : inputs_[0] = value;
2114 : }
2115 :
2116 71180 : LOperand* value() { return inputs_[0]; }
2117 :
2118 364324 : DECLARE_CONCRETE_INSTRUCTION(CheckMaps, "check-maps")
2119 323751 : DECLARE_HYDROGEN_ACCESSOR(CheckMaps)
2120 : };
2121 :
2122 :
2123 0 : class LCheckSmi final : public LTemplateInstruction<1, 1, 0> {
2124 : public:
2125 21979 : explicit LCheckSmi(LOperand* value) {
2126 21979 : inputs_[0] = value;
2127 : }
2128 :
2129 21426 : LOperand* value() { return inputs_[0]; }
2130 :
2131 42852 : DECLARE_CONCRETE_INSTRUCTION(CheckSmi, "check-smi")
2132 : };
2133 :
2134 :
2135 0 : class LClampDToUint8 final : public LTemplateInstruction<1, 1, 0> {
2136 : public:
2137 223 : explicit LClampDToUint8(LOperand* unclamped) {
2138 223 : inputs_[0] = unclamped;
2139 : }
2140 :
2141 223 : LOperand* unclamped() { return inputs_[0]; }
2142 :
2143 446 : DECLARE_CONCRETE_INSTRUCTION(ClampDToUint8, "clamp-d-to-uint8")
2144 : };
2145 :
2146 :
2147 0 : class LClampIToUint8 final : public LTemplateInstruction<1, 1, 0> {
2148 : public:
2149 84 : explicit LClampIToUint8(LOperand* unclamped) {
2150 84 : inputs_[0] = unclamped;
2151 : }
2152 :
2153 : LOperand* unclamped() { return inputs_[0]; }
2154 :
2155 168 : DECLARE_CONCRETE_INSTRUCTION(ClampIToUint8, "clamp-i-to-uint8")
2156 : };
2157 :
2158 :
2159 0 : class LClampTToUint8 final : public LTemplateInstruction<1, 1, 1> {
2160 : public:
2161 : LClampTToUint8(LOperand* unclamped,
2162 21 : LOperand* temp_xmm) {
2163 21 : inputs_[0] = unclamped;
2164 21 : temps_[0] = temp_xmm;
2165 : }
2166 :
2167 21 : LOperand* unclamped() { return inputs_[0]; }
2168 21 : LOperand* temp_xmm() { return temps_[0]; }
2169 :
2170 42 : DECLARE_CONCRETE_INSTRUCTION(ClampTToUint8, "clamp-t-to-uint8")
2171 : };
2172 :
2173 :
2174 0 : class LCheckNonSmi final : public LTemplateInstruction<0, 1, 0> {
2175 : public:
2176 91628 : explicit LCheckNonSmi(LOperand* value) {
2177 91628 : inputs_[0] = value;
2178 : }
2179 :
2180 86332 : LOperand* value() { return inputs_[0]; }
2181 :
2182 172664 : DECLARE_CONCRETE_INSTRUCTION(CheckNonSmi, "check-non-smi")
2183 86332 : DECLARE_HYDROGEN_ACCESSOR(CheckHeapObject)
2184 : };
2185 :
2186 :
2187 0 : class LAllocate final : public LTemplateInstruction<1, 2, 1> {
2188 : public:
2189 20845 : LAllocate(LOperand* context, LOperand* size, LOperand* temp) {
2190 20845 : inputs_[0] = context;
2191 20845 : inputs_[1] = size;
2192 20845 : temps_[0] = temp;
2193 : }
2194 :
2195 20528 : LOperand* context() { return inputs_[0]; }
2196 41185 : LOperand* size() { return inputs_[1]; }
2197 20528 : LOperand* temp() { return temps_[0]; }
2198 :
2199 61584 : DECLARE_CONCRETE_INSTRUCTION(Allocate, "allocate")
2200 82112 : DECLARE_HYDROGEN_ACCESSOR(Allocate)
2201 : };
2202 :
2203 0 : class LFastAllocate final : public LTemplateInstruction<1, 1, 1> {
2204 : public:
2205 4903 : LFastAllocate(LOperand* size, LOperand* temp) {
2206 4903 : inputs_[0] = size;
2207 4903 : temps_[0] = temp;
2208 : }
2209 :
2210 4821 : LOperand* size() const { return inputs_[0]; }
2211 4821 : LOperand* temp() { return temps_[0]; }
2212 :
2213 9642 : DECLARE_CONCRETE_INSTRUCTION(FastAllocate, "fast-allocate")
2214 4821 : DECLARE_HYDROGEN_ACCESSOR(Allocate)
2215 : };
2216 :
2217 0 : class LTypeof final : public LTemplateInstruction<1, 2, 0> {
2218 : public:
2219 38635 : LTypeof(LOperand* context, LOperand* value) {
2220 38635 : inputs_[0] = context;
2221 38635 : inputs_[1] = value;
2222 : }
2223 :
2224 : LOperand* context() { return inputs_[0]; }
2225 38130 : LOperand* value() { return inputs_[1]; }
2226 :
2227 76260 : DECLARE_CONCRETE_INSTRUCTION(Typeof, "typeof")
2228 : };
2229 :
2230 :
2231 0 : class LTypeofIsAndBranch final : public LControlInstruction<1, 0> {
2232 : public:
2233 56211 : explicit LTypeofIsAndBranch(LOperand* value) {
2234 56211 : inputs_[0] = value;
2235 : }
2236 :
2237 42191 : LOperand* value() { return inputs_[0]; }
2238 :
2239 152972 : DECLARE_CONCRETE_INSTRUCTION(TypeofIsAndBranch, "typeof-is-and-branch")
2240 42191 : DECLARE_HYDROGEN_ACCESSOR(TypeofIsAndBranch)
2241 :
2242 : Handle<String> type_literal() { return hydrogen()->type_literal(); }
2243 :
2244 : void PrintDataTo(StringStream* stream) override;
2245 : };
2246 :
2247 :
2248 0 : class LOsrEntry final : public LTemplateInstruction<0, 0, 0> {
2249 : public:
2250 2369 : LOsrEntry() {}
2251 :
2252 0 : bool HasInterestingComment(LCodeGen* gen) const override { return false; }
2253 4738 : DECLARE_CONCRETE_INSTRUCTION(OsrEntry, "osr-entry")
2254 : };
2255 :
2256 :
2257 0 : class LStackCheck final : public LTemplateInstruction<0, 1, 0> {
2258 : public:
2259 291516 : explicit LStackCheck(LOperand* context) {
2260 291516 : inputs_[0] = context;
2261 : }
2262 :
2263 : LOperand* context() { return inputs_[0]; }
2264 :
2265 604716 : DECLARE_CONCRETE_INSTRUCTION(StackCheck, "stack-check")
2266 286755 : DECLARE_HYDROGEN_ACCESSOR(StackCheck)
2267 :
2268 : Label* done_label() { return &done_label_; }
2269 :
2270 : private:
2271 : Label done_label_;
2272 : };
2273 :
2274 :
2275 0 : class LForInPrepareMap final : public LTemplateInstruction<1, 2, 0> {
2276 : public:
2277 754 : LForInPrepareMap(LOperand* context, LOperand* object) {
2278 754 : inputs_[0] = context;
2279 754 : inputs_[1] = object;
2280 : }
2281 :
2282 : LOperand* context() { return inputs_[0]; }
2283 : LOperand* object() { return inputs_[1]; }
2284 :
2285 1504 : DECLARE_CONCRETE_INSTRUCTION(ForInPrepareMap, "for-in-prepare-map")
2286 : };
2287 :
2288 :
2289 0 : class LForInCacheArray final : public LTemplateInstruction<1, 1, 0> {
2290 : public:
2291 1732 : explicit LForInCacheArray(LOperand* map) {
2292 1732 : inputs_[0] = map;
2293 : }
2294 :
2295 1728 : LOperand* map() { return inputs_[0]; }
2296 :
2297 3456 : DECLARE_CONCRETE_INSTRUCTION(ForInCacheArray, "for-in-cache-array")
2298 :
2299 : int idx() {
2300 1728 : return HForInCacheArray::cast(this->hydrogen_value())->idx();
2301 : }
2302 : };
2303 :
2304 :
2305 0 : class LCheckMapValue final : public LTemplateInstruction<0, 2, 0> {
2306 : public:
2307 1209 : LCheckMapValue(LOperand* value, LOperand* map) {
2308 1209 : inputs_[0] = value;
2309 1209 : inputs_[1] = map;
2310 : }
2311 :
2312 1206 : LOperand* value() { return inputs_[0]; }
2313 1206 : LOperand* map() { return inputs_[1]; }
2314 :
2315 2412 : DECLARE_CONCRETE_INSTRUCTION(CheckMapValue, "check-map-value")
2316 : };
2317 :
2318 :
2319 0 : class LLoadFieldByIndex final : public LTemplateInstruction<1, 2, 0> {
2320 : public:
2321 589 : LLoadFieldByIndex(LOperand* object, LOperand* index) {
2322 589 : inputs_[0] = object;
2323 589 : inputs_[1] = index;
2324 : }
2325 :
2326 588 : LOperand* object() { return inputs_[0]; }
2327 588 : LOperand* index() { return inputs_[1]; }
2328 :
2329 1764 : DECLARE_CONCRETE_INSTRUCTION(LoadFieldByIndex, "load-field-by-index")
2330 : };
2331 :
2332 :
2333 : class LChunkBuilder;
2334 : class LPlatformChunk final : public LChunk {
2335 : public:
2336 567453 : LPlatformChunk(CompilationInfo* info, HGraph* graph)
2337 : : LChunk(info, graph),
2338 567453 : dehoisted_key_ids_(graph->GetMaximumValueID(), graph->zone()) { }
2339 :
2340 : int GetNextSpillIndex(RegisterKind kind);
2341 : LOperand* GetNextSpillSlot(RegisterKind kind);
2342 : BitVector* GetDehoistedKeyIds() { return &dehoisted_key_ids_; }
2343 29333 : bool IsDehoistedKey(HValue* value) {
2344 29333 : return dehoisted_key_ids_.Contains(value->id());
2345 : }
2346 :
2347 : private:
2348 : BitVector dehoisted_key_ids_;
2349 : };
2350 :
2351 :
2352 283728 : class LChunkBuilder final : public LChunkBuilderBase {
2353 : public:
2354 : LChunkBuilder(CompilationInfo* info, HGraph* graph, LAllocator* allocator)
2355 : : LChunkBuilderBase(info, graph),
2356 : current_instruction_(NULL),
2357 : current_block_(NULL),
2358 : next_block_(NULL),
2359 283730 : allocator_(allocator) {}
2360 :
2361 : // Build the sequence for the graph.
2362 : LPlatformChunk* Build();
2363 :
2364 : // Declare methods that deal with the individual node types.
2365 : #define DECLARE_DO(type) LInstruction* Do##type(H##type* node);
2366 : HYDROGEN_CONCRETE_INSTRUCTION_LIST(DECLARE_DO)
2367 : #undef DECLARE_DO
2368 :
2369 : LInstruction* DoMathFloor(HUnaryMathOperation* instr);
2370 : LInstruction* DoMathRound(HUnaryMathOperation* instr);
2371 : LInstruction* DoMathFround(HUnaryMathOperation* instr);
2372 : LInstruction* DoMathAbs(HUnaryMathOperation* instr);
2373 : LInstruction* DoMathCos(HUnaryMathOperation* instr);
2374 : LInstruction* DoMathLog(HUnaryMathOperation* instr);
2375 : LInstruction* DoMathExp(HUnaryMathOperation* instr);
2376 : LInstruction* DoMathSin(HUnaryMathOperation* instr);
2377 : LInstruction* DoMathSqrt(HUnaryMathOperation* instr);
2378 : LInstruction* DoMathPowHalf(HUnaryMathOperation* instr);
2379 : LInstruction* DoMathClz32(HUnaryMathOperation* instr);
2380 : LInstruction* DoDivByPowerOf2I(HDiv* instr);
2381 : LInstruction* DoDivByConstI(HDiv* instr);
2382 : LInstruction* DoDivI(HDiv* instr);
2383 : LInstruction* DoModByPowerOf2I(HMod* instr);
2384 : LInstruction* DoModByConstI(HMod* instr);
2385 : LInstruction* DoModI(HMod* instr);
2386 : LInstruction* DoFlooringDivByPowerOf2I(HMathFloorOfDiv* instr);
2387 : LInstruction* DoFlooringDivByConstI(HMathFloorOfDiv* instr);
2388 : LInstruction* DoFlooringDivI(HMathFloorOfDiv* instr);
2389 :
2390 : private:
2391 : // Methods for getting operands for Use / Define / Temp.
2392 : LUnallocated* ToUnallocated(Register reg);
2393 : LUnallocated* ToUnallocated(XMMRegister reg);
2394 :
2395 : // Methods for setting up define-use relationships.
2396 : MUST_USE_RESULT LOperand* Use(HValue* value, LUnallocated* operand);
2397 : MUST_USE_RESULT LOperand* UseFixed(HValue* value, Register fixed_register);
2398 : MUST_USE_RESULT LOperand* UseFixedDouble(HValue* value,
2399 : XMMRegister fixed_register);
2400 :
2401 : // A value that is guaranteed to be allocated to a register.
2402 : // Operand created by UseRegister is guaranteed to be live until the end of
2403 : // instruction. This means that register allocator will not reuse it's
2404 : // register for any other operand inside instruction.
2405 : // Operand created by UseRegisterAtStart is guaranteed to be live only at
2406 : // instruction start. Register allocator is free to assign the same register
2407 : // to some other operand used inside instruction (i.e. temporary or
2408 : // output).
2409 : MUST_USE_RESULT LOperand* UseRegister(HValue* value);
2410 : MUST_USE_RESULT LOperand* UseRegisterAtStart(HValue* value);
2411 :
2412 : // An input operand in a register that may be trashed.
2413 : MUST_USE_RESULT LOperand* UseTempRegister(HValue* value);
2414 :
2415 : // An input operand in a register that may be trashed or a constant operand.
2416 : MUST_USE_RESULT LOperand* UseTempRegisterOrConstant(HValue* value);
2417 :
2418 : // An input operand in a register or stack slot.
2419 : MUST_USE_RESULT LOperand* Use(HValue* value);
2420 : MUST_USE_RESULT LOperand* UseAtStart(HValue* value);
2421 :
2422 : // An input operand in a register, stack slot or a constant operand.
2423 : MUST_USE_RESULT LOperand* UseOrConstant(HValue* value);
2424 : MUST_USE_RESULT LOperand* UseOrConstantAtStart(HValue* value);
2425 :
2426 : // An input operand in a register or a constant operand.
2427 : MUST_USE_RESULT LOperand* UseRegisterOrConstant(HValue* value);
2428 : MUST_USE_RESULT LOperand* UseRegisterOrConstantAtStart(HValue* value);
2429 :
2430 : // An input operand in a constant operand.
2431 : MUST_USE_RESULT LOperand* UseConstant(HValue* value);
2432 :
2433 : // An input operand in register, stack slot or a constant operand.
2434 : // Will not be moved to a register even if one is freely available.
2435 : MUST_USE_RESULT LOperand* UseAny(HValue* value) override;
2436 :
2437 : // Temporary operand that must be in a register.
2438 : MUST_USE_RESULT LUnallocated* TempRegister();
2439 : MUST_USE_RESULT LOperand* FixedTemp(Register reg);
2440 : MUST_USE_RESULT LOperand* FixedTemp(XMMRegister reg);
2441 :
2442 : // Methods for setting up define-use relationships.
2443 : // Return the same instruction that they are passed.
2444 : LInstruction* Define(LTemplateResultInstruction<1>* instr,
2445 : LUnallocated* result);
2446 : LInstruction* DefineAsRegister(LTemplateResultInstruction<1>* instr);
2447 : LInstruction* DefineAsSpilled(LTemplateResultInstruction<1>* instr,
2448 : int index);
2449 : LInstruction* DefineSameAsFirst(LTemplateResultInstruction<1>* instr);
2450 : LInstruction* DefineFixed(LTemplateResultInstruction<1>* instr,
2451 : Register reg);
2452 : LInstruction* DefineFixedDouble(LTemplateResultInstruction<1>* instr,
2453 : XMMRegister reg);
2454 : // Assigns an environment to an instruction. An instruction which can
2455 : // deoptimize must have an environment.
2456 : LInstruction* AssignEnvironment(LInstruction* instr);
2457 : // Assigns a pointer map to an instruction. An instruction which can
2458 : // trigger a GC or a lazy deoptimization must have a pointer map.
2459 : LInstruction* AssignPointerMap(LInstruction* instr);
2460 :
2461 : enum CanDeoptimize { CAN_DEOPTIMIZE_EAGERLY, CANNOT_DEOPTIMIZE_EAGERLY };
2462 :
2463 : // Marks a call for the register allocator. Assigns a pointer map to
2464 : // support GC and lazy deoptimization. Assigns an environment to support
2465 : // eager deoptimization if CAN_DEOPTIMIZE_EAGERLY.
2466 : LInstruction* MarkAsCall(
2467 : LInstruction* instr,
2468 : HInstruction* hinstr,
2469 : CanDeoptimize can_deoptimize = CANNOT_DEOPTIMIZE_EAGERLY);
2470 :
2471 : void VisitInstruction(HInstruction* current);
2472 : void AddInstruction(LInstruction* instr, HInstruction* current);
2473 :
2474 : void DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block);
2475 : LInstruction* DoShift(Token::Value op, HBitwiseBinaryOperation* instr);
2476 : LInstruction* DoArithmeticD(Token::Value op,
2477 : HArithmeticBinaryOperation* instr);
2478 : LInstruction* DoArithmeticT(Token::Value op,
2479 : HBinaryOperation* instr);
2480 : void FindDehoistedKeyDefinitions(HValue* candidate);
2481 :
2482 : HInstruction* current_instruction_;
2483 : HBasicBlock* current_block_;
2484 : HBasicBlock* next_block_;
2485 : LAllocator* allocator_;
2486 :
2487 : DISALLOW_COPY_AND_ASSIGN(LChunkBuilder);
2488 : };
2489 :
2490 : #undef DECLARE_HYDROGEN_ACCESSOR
2491 : #undef DECLARE_CONCRETE_INSTRUCTION
2492 :
2493 : } // namespace internal
2494 : } // namespace v8
2495 :
2496 : #endif // V8_CRANKSHAFT_X64_LITHIUM_X64_H_
|