OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef V8_COMPILER_INSTRUCTION_H_ | 5 #ifndef V8_COMPILER_INSTRUCTION_H_ |
6 #define V8_COMPILER_INSTRUCTION_H_ | 6 #define V8_COMPILER_INSTRUCTION_H_ |
7 | 7 |
8 #include <deque> | 8 #include <deque> |
9 #include <iosfwd> | 9 #include <iosfwd> |
10 #include <map> | 10 #include <map> |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
43 INSTRUCTION_OPERAND_PREDICATE(Constant, CONSTANT) | 43 INSTRUCTION_OPERAND_PREDICATE(Constant, CONSTANT) |
44 INSTRUCTION_OPERAND_PREDICATE(Immediate, IMMEDIATE) | 44 INSTRUCTION_OPERAND_PREDICATE(Immediate, IMMEDIATE) |
45 INSTRUCTION_OPERAND_PREDICATE(Allocated, ALLOCATED) | 45 INSTRUCTION_OPERAND_PREDICATE(Allocated, ALLOCATED) |
46 #undef INSTRUCTION_OPERAND_PREDICATE | 46 #undef INSTRUCTION_OPERAND_PREDICATE |
47 | 47 |
48 inline bool IsRegister() const; | 48 inline bool IsRegister() const; |
49 inline bool IsDoubleRegister() const; | 49 inline bool IsDoubleRegister() const; |
50 inline bool IsStackSlot() const; | 50 inline bool IsStackSlot() const; |
51 inline bool IsDoubleStackSlot() const; | 51 inline bool IsDoubleStackSlot() const; |
52 | 52 |
| 53 // Useful for map/set keys. |
| 54 bool operator<(const InstructionOperand& op) const { |
| 55 return value_ < op.value_; |
| 56 } |
| 57 |
| 58 bool operator==(const InstructionOperand& op) const { |
| 59 return value_ == op.value_; |
| 60 } |
| 61 |
| 62 bool operator!=(const InstructionOperand& op) const { |
| 63 return value_ != op.value_; |
| 64 } |
| 65 |
53 template <typename SubKindOperand> | 66 template <typename SubKindOperand> |
54 static SubKindOperand* New(Zone* zone, const SubKindOperand& op) { | 67 static SubKindOperand* New(Zone* zone, const SubKindOperand& op) { |
55 void* buffer = zone->New(sizeof(op)); | 68 void* buffer = zone->New(sizeof(op)); |
56 return new (buffer) SubKindOperand(op); | 69 return new (buffer) SubKindOperand(op); |
57 } | 70 } |
58 | 71 |
59 static void ReplaceWith(InstructionOperand* dest, | 72 static void ReplaceWith(InstructionOperand* dest, |
60 const InstructionOperand* src) { | 73 const InstructionOperand* src) { |
61 *dest = *src; | 74 *dest = *src; |
62 } | 75 } |
63 | 76 |
64 bool Equals(const InstructionOperand& that) const { | |
65 return this->value_ == that.value_; | |
66 } | |
67 | |
68 bool Compare(const InstructionOperand& that) const { | |
69 return this->value_ < that.value_; | |
70 } | |
71 | |
72 bool EqualsModuloType(const InstructionOperand& that) const { | |
73 return this->GetValueModuloType() == that.GetValueModuloType(); | |
74 } | |
75 | |
76 bool CompareModuloType(const InstructionOperand& that) const { | |
77 return this->GetValueModuloType() < that.GetValueModuloType(); | |
78 } | |
79 | |
80 protected: | 77 protected: |
81 explicit InstructionOperand(Kind kind) : value_(KindField::encode(kind)) {} | 78 explicit InstructionOperand(Kind kind) : value_(KindField::encode(kind)) {} |
82 | 79 |
83 inline uint64_t GetValueModuloType() const; | |
84 | |
85 class KindField : public BitField64<Kind, 0, 3> {}; | 80 class KindField : public BitField64<Kind, 0, 3> {}; |
86 | 81 |
87 uint64_t value_; | 82 uint64_t value_; |
88 }; | 83 }; |
89 | 84 |
90 | |
91 struct PrintableInstructionOperand { | 85 struct PrintableInstructionOperand { |
92 const RegisterConfiguration* register_configuration_; | 86 const RegisterConfiguration* register_configuration_; |
93 InstructionOperand op_; | 87 InstructionOperand op_; |
94 }; | 88 }; |
95 | 89 |
96 | |
97 std::ostream& operator<<(std::ostream& os, | 90 std::ostream& operator<<(std::ostream& os, |
98 const PrintableInstructionOperand& op); | 91 const PrintableInstructionOperand& op); |
99 | 92 |
100 | |
101 #define INSTRUCTION_OPERAND_CASTS(OperandType, OperandKind) \ | 93 #define INSTRUCTION_OPERAND_CASTS(OperandType, OperandKind) \ |
102 \ | 94 \ |
103 static OperandType* cast(InstructionOperand* op) { \ | 95 static OperandType* cast(InstructionOperand* op) { \ |
104 DCHECK_EQ(OperandKind, op->kind()); \ | 96 DCHECK_EQ(OperandKind, op->kind()); \ |
105 return static_cast<OperandType*>(op); \ | 97 return static_cast<OperandType*>(op); \ |
106 } \ | 98 } \ |
107 \ | 99 \ |
108 static const OperandType* cast(const InstructionOperand* op) { \ | 100 static const OperandType* cast(const InstructionOperand* op) { \ |
109 DCHECK_EQ(OperandKind, op->kind()); \ | 101 DCHECK_EQ(OperandKind, op->kind()); \ |
110 return static_cast<const OperandType*>(op); \ | 102 return static_cast<const OperandType*>(op); \ |
(...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
347 INSTRUCTION_OPERAND_CASTS(ImmediateOperand, IMMEDIATE); | 339 INSTRUCTION_OPERAND_CASTS(ImmediateOperand, IMMEDIATE); |
348 | 340 |
349 STATIC_ASSERT(KindField::kSize == 3); | 341 STATIC_ASSERT(KindField::kSize == 3); |
350 class TypeField : public BitField64<ImmediateType, 3, 1> {}; | 342 class TypeField : public BitField64<ImmediateType, 3, 1> {}; |
351 class ValueField : public BitField64<int32_t, 32, 32> {}; | 343 class ValueField : public BitField64<int32_t, 32, 32> {}; |
352 }; | 344 }; |
353 | 345 |
354 | 346 |
355 class AllocatedOperand : public InstructionOperand { | 347 class AllocatedOperand : public InstructionOperand { |
356 public: | 348 public: |
357 // TODO(dcarney): machine_type makes this now redundant. Just need to know is | |
358 // the operand is a slot or a register. | |
359 enum AllocatedKind { | 349 enum AllocatedKind { |
360 STACK_SLOT, | 350 STACK_SLOT, |
361 DOUBLE_STACK_SLOT, | 351 DOUBLE_STACK_SLOT, |
362 REGISTER, | 352 REGISTER, |
363 DOUBLE_REGISTER | 353 DOUBLE_REGISTER |
364 }; | 354 }; |
365 | 355 |
366 AllocatedOperand(AllocatedKind kind, MachineType machine_type, int index) | 356 AllocatedOperand(AllocatedKind kind, int index) |
367 : InstructionOperand(ALLOCATED) { | 357 : InstructionOperand(ALLOCATED) { |
368 DCHECK_IMPLIES(kind == REGISTER || kind == DOUBLE_REGISTER, index >= 0); | 358 DCHECK_IMPLIES(kind == REGISTER || kind == DOUBLE_REGISTER, index >= 0); |
369 DCHECK(IsSupportedMachineType(machine_type)); | |
370 value_ |= AllocatedKindField::encode(kind); | 359 value_ |= AllocatedKindField::encode(kind); |
371 value_ |= MachineTypeField::encode(machine_type); | |
372 value_ |= static_cast<int64_t>(index) << IndexField::kShift; | 360 value_ |= static_cast<int64_t>(index) << IndexField::kShift; |
373 } | 361 } |
374 | 362 |
375 int index() const { | 363 int index() const { |
376 return static_cast<int64_t>(value_) >> IndexField::kShift; | 364 return static_cast<int64_t>(value_) >> IndexField::kShift; |
377 } | 365 } |
378 | 366 |
379 AllocatedKind allocated_kind() const { | 367 AllocatedKind allocated_kind() const { |
380 return AllocatedKindField::decode(value_); | 368 return AllocatedKindField::decode(value_); |
381 } | 369 } |
382 | 370 |
383 MachineType machine_type() const { return MachineTypeField::decode(value_); } | 371 static AllocatedOperand* New(Zone* zone, AllocatedKind kind, int index) { |
384 | 372 return InstructionOperand::New(zone, AllocatedOperand(kind, index)); |
385 static AllocatedOperand* New(Zone* zone, AllocatedKind kind, | |
386 MachineType machine_type, int index) { | |
387 return InstructionOperand::New(zone, | |
388 AllocatedOperand(kind, machine_type, index)); | |
389 } | |
390 | |
391 static bool IsSupportedMachineType(MachineType machine_type) { | |
392 if (RepresentationOf(machine_type) != machine_type) return false; | |
393 switch (machine_type) { | |
394 case kRepWord32: | |
395 case kRepWord64: | |
396 case kRepFloat32: | |
397 case kRepFloat64: | |
398 case kRepTagged: | |
399 return true; | |
400 default: | |
401 return false; | |
402 } | |
403 } | 373 } |
404 | 374 |
405 INSTRUCTION_OPERAND_CASTS(AllocatedOperand, ALLOCATED); | 375 INSTRUCTION_OPERAND_CASTS(AllocatedOperand, ALLOCATED); |
406 | 376 |
407 STATIC_ASSERT(KindField::kSize == 3); | 377 STATIC_ASSERT(KindField::kSize == 3); |
408 class AllocatedKindField : public BitField64<AllocatedKind, 3, 2> {}; | 378 class AllocatedKindField : public BitField64<AllocatedKind, 3, 2> {}; |
409 class MachineTypeField : public BitField64<MachineType, 5, 16> {}; | |
410 class IndexField : public BitField64<int32_t, 35, 29> {}; | 379 class IndexField : public BitField64<int32_t, 35, 29> {}; |
411 }; | 380 }; |
412 | 381 |
413 | 382 |
414 #undef INSTRUCTION_OPERAND_CASTS | 383 #undef INSTRUCTION_OPERAND_CASTS |
415 | 384 |
416 | 385 |
417 #define ALLOCATED_OPERAND_LIST(V) \ | 386 #define ALLOCATED_OPERAND_LIST(V) \ |
418 V(StackSlot, STACK_SLOT) \ | 387 V(StackSlot, STACK_SLOT) \ |
419 V(DoubleStackSlot, DOUBLE_STACK_SLOT) \ | 388 V(DoubleStackSlot, DOUBLE_STACK_SLOT) \ |
420 V(Register, REGISTER) \ | 389 V(Register, REGISTER) \ |
421 V(DoubleRegister, DOUBLE_REGISTER) | 390 V(DoubleRegister, DOUBLE_REGISTER) |
422 | 391 |
423 | 392 |
424 #define ALLOCATED_OPERAND_IS(SubKind, kOperandKind) \ | 393 #define ALLOCATED_OPERAND_IS(SubKind, kOperandKind) \ |
425 bool InstructionOperand::Is##SubKind() const { \ | 394 bool InstructionOperand::Is##SubKind() const { \ |
426 return IsAllocated() && \ | 395 return IsAllocated() && \ |
427 AllocatedOperand::cast(this)->allocated_kind() == \ | 396 AllocatedOperand::cast(this)->allocated_kind() == \ |
428 AllocatedOperand::kOperandKind; \ | 397 AllocatedOperand::kOperandKind; \ |
429 } | 398 } |
430 ALLOCATED_OPERAND_LIST(ALLOCATED_OPERAND_IS) | 399 ALLOCATED_OPERAND_LIST(ALLOCATED_OPERAND_IS) |
431 #undef ALLOCATED_OPERAND_IS | 400 #undef ALLOCATED_OPERAND_IS |
432 | 401 |
433 | 402 |
434 // TODO(dcarney): these subkinds are now pretty useless, nuke. | |
435 #define ALLOCATED_OPERAND_CLASS(SubKind, kOperandKind) \ | 403 #define ALLOCATED_OPERAND_CLASS(SubKind, kOperandKind) \ |
436 class SubKind##Operand final : public AllocatedOperand { \ | 404 class SubKind##Operand final : public AllocatedOperand { \ |
437 public: \ | 405 public: \ |
438 explicit SubKind##Operand(MachineType machine_type, int index) \ | 406 explicit SubKind##Operand(int index) \ |
439 : AllocatedOperand(kOperandKind, machine_type, index) {} \ | 407 : AllocatedOperand(kOperandKind, index) {} \ |
440 \ | 408 \ |
441 static SubKind##Operand* New(Zone* zone, MachineType machine_type, \ | 409 static SubKind##Operand* New(Zone* zone, int index) { \ |
442 int index) { \ | 410 return InstructionOperand::New(zone, SubKind##Operand(index)); \ |
443 return InstructionOperand::New(zone, \ | |
444 SubKind##Operand(machine_type, index)); \ | |
445 } \ | 411 } \ |
446 \ | 412 \ |
447 static SubKind##Operand* cast(InstructionOperand* op) { \ | 413 static SubKind##Operand* cast(InstructionOperand* op) { \ |
448 DCHECK_EQ(kOperandKind, AllocatedOperand::cast(op)->allocated_kind()); \ | 414 DCHECK_EQ(kOperandKind, AllocatedOperand::cast(op)->allocated_kind()); \ |
449 return reinterpret_cast<SubKind##Operand*>(op); \ | 415 return reinterpret_cast<SubKind##Operand*>(op); \ |
450 } \ | 416 } \ |
451 \ | 417 \ |
452 static const SubKind##Operand* cast(const InstructionOperand* op) { \ | 418 static const SubKind##Operand* cast(const InstructionOperand* op) { \ |
453 DCHECK_EQ(kOperandKind, AllocatedOperand::cast(op)->allocated_kind()); \ | 419 DCHECK_EQ(kOperandKind, AllocatedOperand::cast(op)->allocated_kind()); \ |
454 return reinterpret_cast<const SubKind##Operand*>(op); \ | 420 return reinterpret_cast<const SubKind##Operand*>(op); \ |
455 } \ | 421 } \ |
456 \ | 422 \ |
457 static SubKind##Operand cast(const InstructionOperand& op) { \ | 423 static SubKind##Operand cast(const InstructionOperand& op) { \ |
458 DCHECK_EQ(kOperandKind, AllocatedOperand::cast(op).allocated_kind()); \ | 424 DCHECK_EQ(kOperandKind, AllocatedOperand::cast(op).allocated_kind()); \ |
459 return *static_cast<const SubKind##Operand*>(&op); \ | 425 return *static_cast<const SubKind##Operand*>(&op); \ |
460 } \ | 426 } \ |
461 }; | 427 }; |
462 ALLOCATED_OPERAND_LIST(ALLOCATED_OPERAND_CLASS) | 428 ALLOCATED_OPERAND_LIST(ALLOCATED_OPERAND_CLASS) |
463 #undef ALLOCATED_OPERAND_CLASS | 429 #undef ALLOCATED_OPERAND_CLASS |
464 | 430 |
465 | 431 |
466 uint64_t InstructionOperand::GetValueModuloType() const { | |
467 if (IsAllocated()) { | |
468 // TODO(dcarney): put machine type last and mask. | |
469 return AllocatedOperand::MachineTypeField::update(this->value_, kMachNone); | |
470 } | |
471 return this->value_; | |
472 } | |
473 | |
474 | |
475 // Required for maps that don't care about machine type. | |
476 struct CompareOperandModuloType { | |
477 bool operator()(const InstructionOperand& a, | |
478 const InstructionOperand& b) const { | |
479 return a.CompareModuloType(b); | |
480 } | |
481 }; | |
482 | |
483 | |
484 class MoveOperands final : public ZoneObject { | 432 class MoveOperands final : public ZoneObject { |
485 public: | 433 public: |
486 MoveOperands(const InstructionOperand& source, | 434 MoveOperands(const InstructionOperand& source, |
487 const InstructionOperand& destination) | 435 const InstructionOperand& destination) |
488 : source_(source), destination_(destination) { | 436 : source_(source), destination_(destination) { |
489 DCHECK(!source.IsInvalid() && !destination.IsInvalid()); | 437 DCHECK(!source.IsInvalid() && !destination.IsInvalid()); |
490 } | 438 } |
491 | 439 |
492 const InstructionOperand& source() const { return source_; } | 440 const InstructionOperand& source() const { return source_; } |
493 InstructionOperand& source() { return source_; } | 441 InstructionOperand& source() { return source_; } |
494 void set_source(const InstructionOperand& operand) { source_ = operand; } | 442 void set_source(const InstructionOperand& operand) { source_ = operand; } |
495 | 443 |
496 const InstructionOperand& destination() const { return destination_; } | 444 const InstructionOperand& destination() const { return destination_; } |
497 InstructionOperand& destination() { return destination_; } | 445 InstructionOperand& destination() { return destination_; } |
498 void set_destination(const InstructionOperand& operand) { | 446 void set_destination(const InstructionOperand& operand) { |
499 destination_ = operand; | 447 destination_ = operand; |
500 } | 448 } |
501 | 449 |
502 // The gap resolver marks moves as "in-progress" by clearing the | 450 // The gap resolver marks moves as "in-progress" by clearing the |
503 // destination (but not the source). | 451 // destination (but not the source). |
504 bool IsPending() const { | 452 bool IsPending() const { |
505 return destination_.IsInvalid() && !source_.IsInvalid(); | 453 return destination_.IsInvalid() && !source_.IsInvalid(); |
506 } | 454 } |
507 void SetPending() { destination_ = InstructionOperand(); } | 455 void SetPending() { destination_ = InstructionOperand(); } |
508 | 456 |
509 // True if this move a move into the given destination operand. | 457 // True if this move a move into the given destination operand. |
510 bool Blocks(const InstructionOperand& operand) const { | 458 bool Blocks(const InstructionOperand& operand) const { |
511 return !IsEliminated() && source().EqualsModuloType(operand); | 459 return !IsEliminated() && source() == operand; |
512 } | 460 } |
513 | 461 |
514 // A move is redundant if it's been eliminated or if its source and | 462 // A move is redundant if it's been eliminated or if its source and |
515 // destination are the same. | 463 // destination are the same. |
516 bool IsRedundant() const { | 464 bool IsRedundant() const { |
517 DCHECK_IMPLIES(!destination_.IsInvalid(), !destination_.IsConstant()); | 465 DCHECK_IMPLIES(!destination_.IsInvalid(), !destination_.IsConstant()); |
518 return IsEliminated() || source_.EqualsModuloType(destination_); | 466 return IsEliminated() || source_ == destination_; |
519 } | 467 } |
520 | 468 |
521 // We clear both operands to indicate move that's been eliminated. | 469 // We clear both operands to indicate move that's been eliminated. |
522 void Eliminate() { source_ = destination_ = InstructionOperand(); } | 470 void Eliminate() { source_ = destination_ = InstructionOperand(); } |
523 bool IsEliminated() const { | 471 bool IsEliminated() const { |
524 DCHECK_IMPLIES(source_.IsInvalid(), destination_.IsInvalid()); | 472 DCHECK_IMPLIES(source_.IsInvalid(), destination_.IsInvalid()); |
525 return source_.IsInvalid(); | 473 return source_.IsInvalid(); |
526 } | 474 } |
527 | 475 |
528 private: | 476 private: |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
596 | 544 |
597 private: | 545 private: |
598 friend std::ostream& operator<<(std::ostream& os, const ReferenceMap& pm); | 546 friend std::ostream& operator<<(std::ostream& os, const ReferenceMap& pm); |
599 | 547 |
600 ZoneVector<InstructionOperand> reference_operands_; | 548 ZoneVector<InstructionOperand> reference_operands_; |
601 int instruction_position_; | 549 int instruction_position_; |
602 }; | 550 }; |
603 | 551 |
604 std::ostream& operator<<(std::ostream& os, const ReferenceMap& pm); | 552 std::ostream& operator<<(std::ostream& os, const ReferenceMap& pm); |
605 | 553 |
606 class Instruction final { | 554 class Instruction { |
607 public: | 555 public: |
608 size_t OutputCount() const { return OutputCountField::decode(bit_field_); } | 556 size_t OutputCount() const { return OutputCountField::decode(bit_field_); } |
609 const InstructionOperand* OutputAt(size_t i) const { | 557 const InstructionOperand* OutputAt(size_t i) const { |
610 DCHECK(i < OutputCount()); | 558 DCHECK(i < OutputCount()); |
611 return &operands_[i]; | 559 return &operands_[i]; |
612 } | 560 } |
613 InstructionOperand* OutputAt(size_t i) { | 561 InstructionOperand* OutputAt(size_t i) { |
614 DCHECK(i < OutputCount()); | 562 DCHECK(i < OutputCount()); |
615 return &operands_[i]; | 563 return &operands_[i]; |
616 } | 564 } |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
721 | 669 |
722 const ParallelMove* GetParallelMove(GapPosition pos) const { | 670 const ParallelMove* GetParallelMove(GapPosition pos) const { |
723 return parallel_moves_[pos]; | 671 return parallel_moves_[pos]; |
724 } | 672 } |
725 | 673 |
726 bool AreMovesRedundant() const; | 674 bool AreMovesRedundant() const; |
727 | 675 |
728 ParallelMove* const* parallel_moves() const { return ¶llel_moves_[0]; } | 676 ParallelMove* const* parallel_moves() const { return ¶llel_moves_[0]; } |
729 ParallelMove** parallel_moves() { return ¶llel_moves_[0]; } | 677 ParallelMove** parallel_moves() { return ¶llel_moves_[0]; } |
730 | 678 |
731 private: | 679 protected: |
732 explicit Instruction(InstructionCode opcode); | 680 explicit Instruction(InstructionCode opcode); |
733 | 681 |
| 682 private: |
734 Instruction(InstructionCode opcode, size_t output_count, | 683 Instruction(InstructionCode opcode, size_t output_count, |
735 InstructionOperand* outputs, size_t input_count, | 684 InstructionOperand* outputs, size_t input_count, |
736 InstructionOperand* inputs, size_t temp_count, | 685 InstructionOperand* inputs, size_t temp_count, |
737 InstructionOperand* temps); | 686 InstructionOperand* temps); |
738 | 687 |
739 typedef BitField<size_t, 0, 8> OutputCountField; | 688 typedef BitField<size_t, 0, 8> OutputCountField; |
740 typedef BitField<size_t, 8, 16> InputCountField; | 689 typedef BitField<size_t, 8, 16> InputCountField; |
741 typedef BitField<size_t, 24, 6> TempCountField; | 690 typedef BitField<size_t, 24, 6> TempCountField; |
742 typedef BitField<bool, 30, 1> IsCallField; | 691 typedef BitField<bool, 30, 1> IsCallField; |
743 | 692 |
744 InstructionCode opcode_; | 693 InstructionCode opcode_; |
745 uint32_t bit_field_; | 694 uint32_t bit_field_; |
746 ParallelMove* parallel_moves_[2]; | 695 ParallelMove* parallel_moves_[2]; |
747 ReferenceMap* reference_map_; | 696 ReferenceMap* reference_map_; |
748 InstructionOperand operands_[1]; | 697 InstructionOperand operands_[1]; |
749 | 698 |
| 699 private: |
750 DISALLOW_COPY_AND_ASSIGN(Instruction); | 700 DISALLOW_COPY_AND_ASSIGN(Instruction); |
751 }; | 701 }; |
752 | 702 |
753 | 703 |
754 struct PrintableInstruction { | 704 struct PrintableInstruction { |
755 const RegisterConfiguration* register_configuration_; | 705 const RegisterConfiguration* register_configuration_; |
756 const Instruction* instr_; | 706 const Instruction* instr_; |
757 }; | 707 }; |
758 std::ostream& operator<<(std::ostream& os, const PrintableInstruction& instr); | 708 std::ostream& operator<<(std::ostream& os, const PrintableInstruction& instr); |
759 | 709 |
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1047 return instruction_blocks_->at(block->loop_end().ToSize() - 1) | 997 return instruction_blocks_->at(block->loop_end().ToSize() - 1) |
1048 ->last_instruction_index(); | 998 ->last_instruction_index(); |
1049 } | 999 } |
1050 | 1000 |
1051 const InstructionBlock* InstructionBlockAt(RpoNumber rpo_number) const { | 1001 const InstructionBlock* InstructionBlockAt(RpoNumber rpo_number) const { |
1052 return instruction_blocks_->at(rpo_number.ToSize()); | 1002 return instruction_blocks_->at(rpo_number.ToSize()); |
1053 } | 1003 } |
1054 | 1004 |
1055 const InstructionBlock* GetInstructionBlock(int instruction_index) const; | 1005 const InstructionBlock* GetInstructionBlock(int instruction_index) const; |
1056 | 1006 |
1057 static MachineType DefaultRepresentation() { | 1007 bool IsReference(int virtual_register) const; |
1058 return kPointerSize == 8 ? kRepWord64 : kRepWord32; | 1008 bool IsDouble(int virtual_register) const; |
1059 } | |
1060 MachineType GetRepresentation(int virtual_register) const; | |
1061 void MarkAsRepresentation(MachineType machine_type, int virtual_register); | |
1062 | 1009 |
1063 bool IsReference(int virtual_register) const { | 1010 void MarkAsReference(int virtual_register); |
1064 return GetRepresentation(virtual_register) == kRepTagged; | 1011 void MarkAsDouble(int virtual_register); |
1065 } | |
1066 bool IsFloat(int virtual_register) const { | |
1067 switch (GetRepresentation(virtual_register)) { | |
1068 case kRepFloat32: | |
1069 case kRepFloat64: | |
1070 return true; | |
1071 default: | |
1072 return false; | |
1073 } | |
1074 } | |
1075 | 1012 |
1076 Instruction* GetBlockStart(RpoNumber rpo) const; | 1013 Instruction* GetBlockStart(RpoNumber rpo) const; |
1077 | 1014 |
1078 typedef InstructionDeque::const_iterator const_iterator; | 1015 typedef InstructionDeque::const_iterator const_iterator; |
1079 const_iterator begin() const { return instructions_.begin(); } | 1016 const_iterator begin() const { return instructions_.begin(); } |
1080 const_iterator end() const { return instructions_.end(); } | 1017 const_iterator end() const { return instructions_.end(); } |
1081 const InstructionDeque& instructions() const { return instructions_; } | 1018 const InstructionDeque& instructions() const { return instructions_; } |
1082 | 1019 |
1083 Instruction* InstructionAt(int index) const { | 1020 Instruction* InstructionAt(int index) const { |
1084 DCHECK(index >= 0); | 1021 DCHECK(index >= 0); |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1167 Isolate* isolate_; | 1104 Isolate* isolate_; |
1168 Zone* const zone_; | 1105 Zone* const zone_; |
1169 InstructionBlocks* const instruction_blocks_; | 1106 InstructionBlocks* const instruction_blocks_; |
1170 SourcePositionMap source_positions_; | 1107 SourcePositionMap source_positions_; |
1171 IntVector block_starts_; | 1108 IntVector block_starts_; |
1172 ConstantMap constants_; | 1109 ConstantMap constants_; |
1173 Immediates immediates_; | 1110 Immediates immediates_; |
1174 InstructionDeque instructions_; | 1111 InstructionDeque instructions_; |
1175 int next_virtual_register_; | 1112 int next_virtual_register_; |
1176 ReferenceMapDeque reference_maps_; | 1113 ReferenceMapDeque reference_maps_; |
1177 ZoneVector<MachineType> representations_; | 1114 VirtualRegisterSet doubles_; |
| 1115 VirtualRegisterSet references_; |
1178 DeoptimizationVector deoptimization_entries_; | 1116 DeoptimizationVector deoptimization_entries_; |
1179 | 1117 |
1180 DISALLOW_COPY_AND_ASSIGN(InstructionSequence); | 1118 DISALLOW_COPY_AND_ASSIGN(InstructionSequence); |
1181 }; | 1119 }; |
1182 | 1120 |
1183 | 1121 |
1184 struct PrintableInstructionSequence { | 1122 struct PrintableInstructionSequence { |
1185 const RegisterConfiguration* register_configuration_; | 1123 const RegisterConfiguration* register_configuration_; |
1186 const InstructionSequence* sequence_; | 1124 const InstructionSequence* sequence_; |
1187 }; | 1125 }; |
1188 | 1126 |
1189 | 1127 |
1190 std::ostream& operator<<(std::ostream& os, | 1128 std::ostream& operator<<(std::ostream& os, |
1191 const PrintableInstructionSequence& code); | 1129 const PrintableInstructionSequence& code); |
1192 | 1130 |
1193 } // namespace compiler | 1131 } // namespace compiler |
1194 } // namespace internal | 1132 } // namespace internal |
1195 } // namespace v8 | 1133 } // namespace v8 |
1196 | 1134 |
1197 #endif // V8_COMPILER_INSTRUCTION_H_ | 1135 #endif // V8_COMPILER_INSTRUCTION_H_ |
OLD | NEW |