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 |