| 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 |