| 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> |
| 11 #include <set> | 11 #include <set> |
| 12 | 12 |
| 13 #include "src/compiler/common-operator.h" | 13 #include "src/compiler/common-operator.h" |
| 14 #include "src/compiler/frame.h" | 14 #include "src/compiler/frame.h" |
| 15 #include "src/compiler/instruction-codes.h" | 15 #include "src/compiler/instruction-codes.h" |
| 16 #include "src/compiler/opcodes.h" | 16 #include "src/compiler/opcodes.h" |
| 17 #include "src/compiler/register-configuration.h" |
| 17 #include "src/compiler/schedule.h" | 18 #include "src/compiler/schedule.h" |
| 18 #include "src/compiler/source-position.h" | 19 #include "src/compiler/source-position.h" |
| 19 #include "src/zone-allocator.h" | 20 #include "src/zone-allocator.h" |
| 20 | 21 |
| 21 namespace v8 { | 22 namespace v8 { |
| 22 namespace internal { | 23 namespace internal { |
| 23 namespace compiler { | 24 namespace compiler { |
| 24 | 25 |
| 25 // A couple of reserved opcodes are used for internal use. | 26 // A couple of reserved opcodes are used for internal use. |
| 26 const InstructionCode kGapInstruction = -1; | 27 const InstructionCode kGapInstruction = -1; |
| 27 const InstructionCode kBlockStartInstruction = -2; | 28 const InstructionCode kBlockStartInstruction = -2; |
| 28 const InstructionCode kSourcePositionInstruction = -3; | 29 const InstructionCode kSourcePositionInstruction = -3; |
| 29 | 30 |
| 30 // Platform independent maxes. | 31 #define INSTRUCTION_OPERAND_LIST(V) \ |
| 31 static const int kMaxGeneralRegisters = 32; | 32 V(Constant, CONSTANT, 0) \ |
| 32 static const int kMaxDoubleRegisters = 32; | 33 V(Immediate, IMMEDIATE, 0) \ |
| 33 | 34 V(StackSlot, STACK_SLOT, 128) \ |
| 34 | 35 V(DoubleStackSlot, DOUBLE_STACK_SLOT, 128) \ |
| 35 #define INSTRUCTION_OPERAND_LIST(V) \ | 36 V(Register, REGISTER, RegisterConfiguration::kMaxGeneralRegisters) \ |
| 36 V(Constant, CONSTANT, 0) \ | 37 V(DoubleRegister, DOUBLE_REGISTER, RegisterConfiguration::kMaxDoubleRegisters) |
| 37 V(Immediate, IMMEDIATE, 0) \ | |
| 38 V(StackSlot, STACK_SLOT, 128) \ | |
| 39 V(DoubleStackSlot, DOUBLE_STACK_SLOT, 128) \ | |
| 40 V(Register, REGISTER, kMaxGeneralRegisters) \ | |
| 41 V(DoubleRegister, DOUBLE_REGISTER, kMaxDoubleRegisters) | |
| 42 | 38 |
| 43 class InstructionOperand : public ZoneObject { | 39 class InstructionOperand : public ZoneObject { |
| 44 public: | 40 public: |
| 45 enum Kind { | 41 enum Kind { |
| 46 INVALID, | 42 INVALID, |
| 47 UNALLOCATED, | 43 UNALLOCATED, |
| 48 CONSTANT, | 44 CONSTANT, |
| 49 IMMEDIATE, | 45 IMMEDIATE, |
| 50 STACK_SLOT, | 46 STACK_SLOT, |
| 51 DOUBLE_STACK_SLOT, | 47 DOUBLE_STACK_SLOT, |
| (...skipping 28 matching lines...) Expand all Loading... |
| 80 static void TearDownCaches(); | 76 static void TearDownCaches(); |
| 81 | 77 |
| 82 protected: | 78 protected: |
| 83 typedef BitField<Kind, 0, 3> KindField; | 79 typedef BitField<Kind, 0, 3> KindField; |
| 84 | 80 |
| 85 unsigned value_; | 81 unsigned value_; |
| 86 }; | 82 }; |
| 87 | 83 |
| 88 typedef ZoneVector<InstructionOperand*> InstructionOperandVector; | 84 typedef ZoneVector<InstructionOperand*> InstructionOperandVector; |
| 89 | 85 |
| 90 std::ostream& operator<<(std::ostream& os, const InstructionOperand& op); | 86 struct PrintableInstructionOperand { |
| 87 const RegisterConfiguration* register_configuration_; |
| 88 const InstructionOperand* op_; |
| 89 }; |
| 90 |
| 91 std::ostream& operator<<(std::ostream& os, |
| 92 const PrintableInstructionOperand& op); |
| 91 | 93 |
| 92 class UnallocatedOperand : public InstructionOperand { | 94 class UnallocatedOperand : public InstructionOperand { |
| 93 public: | 95 public: |
| 94 enum BasicPolicy { FIXED_SLOT, EXTENDED_POLICY }; | 96 enum BasicPolicy { FIXED_SLOT, EXTENDED_POLICY }; |
| 95 | 97 |
| 96 enum ExtendedPolicy { | 98 enum ExtendedPolicy { |
| 97 NONE, | 99 NONE, |
| 98 ANY, | 100 ANY, |
| 99 FIXED_REGISTER, | 101 FIXED_REGISTER, |
| 100 FIXED_DOUBLE_REGISTER, | 102 FIXED_DOUBLE_REGISTER, |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 299 bool IsEliminated() const { | 301 bool IsEliminated() const { |
| 300 DCHECK(source_ != NULL || destination_ == NULL); | 302 DCHECK(source_ != NULL || destination_ == NULL); |
| 301 return source_ == NULL; | 303 return source_ == NULL; |
| 302 } | 304 } |
| 303 | 305 |
| 304 private: | 306 private: |
| 305 InstructionOperand* source_; | 307 InstructionOperand* source_; |
| 306 InstructionOperand* destination_; | 308 InstructionOperand* destination_; |
| 307 }; | 309 }; |
| 308 | 310 |
| 309 std::ostream& operator<<(std::ostream& os, const MoveOperands& mo); | 311 |
| 312 struct PrintableMoveOperands { |
| 313 const RegisterConfiguration* register_configuration_; |
| 314 const MoveOperands* move_operands_; |
| 315 }; |
| 316 |
| 317 |
| 318 std::ostream& operator<<(std::ostream& os, const PrintableMoveOperands& mo); |
| 319 |
| 310 | 320 |
| 311 template <InstructionOperand::Kind kOperandKind, int kNumCachedOperands> | 321 template <InstructionOperand::Kind kOperandKind, int kNumCachedOperands> |
| 312 class SubKindOperand FINAL : public InstructionOperand { | 322 class SubKindOperand FINAL : public InstructionOperand { |
| 313 public: | 323 public: |
| 314 static SubKindOperand* Create(int index, Zone* zone) { | 324 static SubKindOperand* Create(int index, Zone* zone) { |
| 315 DCHECK(index >= 0); | 325 DCHECK(index >= 0); |
| 316 if (index < kNumCachedOperands) return &cache[index]; | 326 if (index < kNumCachedOperands) return &cache[index]; |
| 317 return new (zone) SubKindOperand(index); | 327 return new (zone) SubKindOperand(index); |
| 318 } | 328 } |
| 319 | 329 |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 352 | 362 |
| 353 ZoneList<MoveOperands>* move_operands() { return &move_operands_; } | 363 ZoneList<MoveOperands>* move_operands() { return &move_operands_; } |
| 354 const ZoneList<MoveOperands>* move_operands() const { | 364 const ZoneList<MoveOperands>* move_operands() const { |
| 355 return &move_operands_; | 365 return &move_operands_; |
| 356 } | 366 } |
| 357 | 367 |
| 358 private: | 368 private: |
| 359 ZoneList<MoveOperands> move_operands_; | 369 ZoneList<MoveOperands> move_operands_; |
| 360 }; | 370 }; |
| 361 | 371 |
| 362 std::ostream& operator<<(std::ostream& os, const ParallelMove& pm); | 372 |
| 373 struct PrintableParallelMove { |
| 374 const RegisterConfiguration* register_configuration_; |
| 375 const ParallelMove* parallel_move_; |
| 376 }; |
| 377 |
| 378 |
| 379 std::ostream& operator<<(std::ostream& os, const PrintableParallelMove& pm); |
| 380 |
| 363 | 381 |
| 364 class PointerMap FINAL : public ZoneObject { | 382 class PointerMap FINAL : public ZoneObject { |
| 365 public: | 383 public: |
| 366 explicit PointerMap(Zone* zone) | 384 explicit PointerMap(Zone* zone) |
| 367 : pointer_operands_(8, zone), | 385 : pointer_operands_(8, zone), |
| 368 untagged_operands_(0, zone), | 386 untagged_operands_(0, zone), |
| 369 instruction_position_(-1) {} | 387 instruction_position_(-1) {} |
| 370 | 388 |
| 371 const ZoneList<InstructionOperand*>* GetNormalizedOperands() { | 389 const ZoneList<InstructionOperand*>* GetNormalizedOperands() { |
| 372 for (int i = 0; i < untagged_operands_.length(); ++i) { | 390 for (int i = 0; i < untagged_operands_.length(); ++i) { |
| (...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 527 typedef BitField<size_t, 24, 6> TempCountField; | 545 typedef BitField<size_t, 24, 6> TempCountField; |
| 528 typedef BitField<bool, 30, 1> IsCallField; | 546 typedef BitField<bool, 30, 1> IsCallField; |
| 529 typedef BitField<bool, 31, 1> IsControlField; | 547 typedef BitField<bool, 31, 1> IsControlField; |
| 530 | 548 |
| 531 InstructionCode opcode_; | 549 InstructionCode opcode_; |
| 532 uint32_t bit_field_; | 550 uint32_t bit_field_; |
| 533 PointerMap* pointer_map_; | 551 PointerMap* pointer_map_; |
| 534 InstructionOperand* operands_[1]; | 552 InstructionOperand* operands_[1]; |
| 535 }; | 553 }; |
| 536 | 554 |
| 537 std::ostream& operator<<(std::ostream& os, const Instruction& instr); | 555 |
| 556 struct PrintableInstruction { |
| 557 const RegisterConfiguration* register_configuration_; |
| 558 const Instruction* instr_; |
| 559 }; |
| 560 std::ostream& operator<<(std::ostream& os, const PrintableInstruction& instr); |
| 561 |
| 538 | 562 |
| 539 // Represents moves inserted before an instruction due to register allocation. | 563 // Represents moves inserted before an instruction due to register allocation. |
| 540 // TODO(titzer): squash GapInstruction back into Instruction, since essentially | 564 // TODO(titzer): squash GapInstruction back into Instruction, since essentially |
| 541 // every instruction can possibly have moves inserted before it. | 565 // every instruction can possibly have moves inserted before it. |
| 542 class GapInstruction : public Instruction { | 566 class GapInstruction : public Instruction { |
| 543 public: | 567 public: |
| 544 enum InnerPosition { | 568 enum InnerPosition { |
| 545 BEFORE, | 569 BEFORE, |
| 546 START, | 570 START, |
| 547 END, | 571 END, |
| (...skipping 30 matching lines...) Expand all Loading... |
| 578 | 602 |
| 579 protected: | 603 protected: |
| 580 explicit GapInstruction(InstructionCode opcode) : Instruction(opcode) { | 604 explicit GapInstruction(InstructionCode opcode) : Instruction(opcode) { |
| 581 parallel_moves_[BEFORE] = NULL; | 605 parallel_moves_[BEFORE] = NULL; |
| 582 parallel_moves_[START] = NULL; | 606 parallel_moves_[START] = NULL; |
| 583 parallel_moves_[END] = NULL; | 607 parallel_moves_[END] = NULL; |
| 584 parallel_moves_[AFTER] = NULL; | 608 parallel_moves_[AFTER] = NULL; |
| 585 } | 609 } |
| 586 | 610 |
| 587 private: | 611 private: |
| 588 friend std::ostream& operator<<(std::ostream& os, const Instruction& instr); | 612 friend std::ostream& operator<<(std::ostream& os, |
| 613 const PrintableInstruction& instr); |
| 589 ParallelMove* parallel_moves_[LAST_INNER_POSITION + 1]; | 614 ParallelMove* parallel_moves_[LAST_INNER_POSITION + 1]; |
| 590 }; | 615 }; |
| 591 | 616 |
| 592 | 617 |
| 593 // This special kind of gap move instruction represents the beginning of a | 618 // This special kind of gap move instruction represents the beginning of a |
| 594 // block of code. | 619 // block of code. |
| 595 // TODO(titzer): move code_start and code_end from BasicBlock to here. | 620 // TODO(titzer): move code_start and code_end from BasicBlock to here. |
| 596 class BlockStartInstruction FINAL : public GapInstruction { | 621 class BlockStartInstruction FINAL : public GapInstruction { |
| 597 public: | 622 public: |
| 598 Label* label() { return &label_; } | 623 Label* label() { return &label_; } |
| (...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 840 | 865 |
| 841 typedef ZoneDeque<Constant> ConstantDeque; | 866 typedef ZoneDeque<Constant> ConstantDeque; |
| 842 typedef std::map<int, Constant, std::less<int>, | 867 typedef std::map<int, Constant, std::less<int>, |
| 843 zone_allocator<std::pair<int, Constant> > > ConstantMap; | 868 zone_allocator<std::pair<int, Constant> > > ConstantMap; |
| 844 | 869 |
| 845 typedef ZoneDeque<Instruction*> InstructionDeque; | 870 typedef ZoneDeque<Instruction*> InstructionDeque; |
| 846 typedef ZoneDeque<PointerMap*> PointerMapDeque; | 871 typedef ZoneDeque<PointerMap*> PointerMapDeque; |
| 847 typedef ZoneVector<FrameStateDescriptor*> DeoptimizationVector; | 872 typedef ZoneVector<FrameStateDescriptor*> DeoptimizationVector; |
| 848 typedef ZoneVector<InstructionBlock*> InstructionBlocks; | 873 typedef ZoneVector<InstructionBlock*> InstructionBlocks; |
| 849 | 874 |
| 875 struct PrintableInstructionSequence; |
| 876 |
| 877 |
| 850 // Represents architecture-specific generated code before, during, and after | 878 // Represents architecture-specific generated code before, during, and after |
| 851 // register allocation. | 879 // register allocation. |
| 852 // TODO(titzer): s/IsDouble/IsFloat64/ | 880 // TODO(titzer): s/IsDouble/IsFloat64/ |
| 853 class InstructionSequence FINAL { | 881 class InstructionSequence FINAL { |
| 854 public: | 882 public: |
| 855 static InstructionBlocks* InstructionBlocksFor(Zone* zone, | 883 static InstructionBlocks* InstructionBlocksFor(Zone* zone, |
| 856 const Schedule* schedule); | 884 const Schedule* schedule); |
| 857 | 885 |
| 858 InstructionSequence(Zone* zone, InstructionBlocks* instruction_blocks); | 886 InstructionSequence(Zone* zone, InstructionBlocks* instruction_blocks); |
| 859 | 887 |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 954 explicit StateId(int id) : id_(id) {} | 982 explicit StateId(int id) : id_(id) {} |
| 955 int id_; | 983 int id_; |
| 956 }; | 984 }; |
| 957 | 985 |
| 958 StateId AddFrameStateDescriptor(FrameStateDescriptor* descriptor); | 986 StateId AddFrameStateDescriptor(FrameStateDescriptor* descriptor); |
| 959 FrameStateDescriptor* GetFrameStateDescriptor(StateId deoptimization_id); | 987 FrameStateDescriptor* GetFrameStateDescriptor(StateId deoptimization_id); |
| 960 int GetFrameStateDescriptorCount(); | 988 int GetFrameStateDescriptorCount(); |
| 961 | 989 |
| 962 private: | 990 private: |
| 963 friend std::ostream& operator<<(std::ostream& os, | 991 friend std::ostream& operator<<(std::ostream& os, |
| 964 const InstructionSequence& code); | 992 const PrintableInstructionSequence& code); |
| 965 | 993 |
| 966 typedef std::set<int, std::less<int>, ZoneIntAllocator> VirtualRegisterSet; | 994 typedef std::set<int, std::less<int>, ZoneIntAllocator> VirtualRegisterSet; |
| 967 | 995 |
| 968 Zone* const zone_; | 996 Zone* const zone_; |
| 969 InstructionBlocks* const instruction_blocks_; | 997 InstructionBlocks* const instruction_blocks_; |
| 970 ConstantMap constants_; | 998 ConstantMap constants_; |
| 971 ConstantDeque immediates_; | 999 ConstantDeque immediates_; |
| 972 InstructionDeque instructions_; | 1000 InstructionDeque instructions_; |
| 973 int next_virtual_register_; | 1001 int next_virtual_register_; |
| 974 PointerMapDeque pointer_maps_; | 1002 PointerMapDeque pointer_maps_; |
| 975 VirtualRegisterSet doubles_; | 1003 VirtualRegisterSet doubles_; |
| 976 VirtualRegisterSet references_; | 1004 VirtualRegisterSet references_; |
| 977 DeoptimizationVector deoptimization_entries_; | 1005 DeoptimizationVector deoptimization_entries_; |
| 978 }; | 1006 }; |
| 979 | 1007 |
| 980 std::ostream& operator<<(std::ostream& os, const InstructionSequence& code); | 1008 |
| 1009 struct PrintableInstructionSequence { |
| 1010 const RegisterConfiguration* register_configuration_; |
| 1011 const InstructionSequence* sequence_; |
| 1012 }; |
| 1013 |
| 1014 |
| 1015 std::ostream& operator<<(std::ostream& os, |
| 1016 const PrintableInstructionSequence& code); |
| 981 | 1017 |
| 982 } // namespace compiler | 1018 } // namespace compiler |
| 983 } // namespace internal | 1019 } // namespace internal |
| 984 } // namespace v8 | 1020 } // namespace v8 |
| 985 | 1021 |
| 986 #endif // V8_COMPILER_INSTRUCTION_H_ | 1022 #endif // V8_COMPILER_INSTRUCTION_H_ |
| OLD | NEW |