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