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