| 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 21 matching lines...) Expand all Loading... |
| 32 V(Constant, CONSTANT, 0) \ | 32 V(Constant, CONSTANT, 0) \ |
| 33 V(Immediate, IMMEDIATE, 0) \ | 33 V(Immediate, IMMEDIATE, 0) \ |
| 34 V(StackSlot, STACK_SLOT, 128) \ | 34 V(StackSlot, STACK_SLOT, 128) \ |
| 35 V(DoubleStackSlot, DOUBLE_STACK_SLOT, 128) \ | 35 V(DoubleStackSlot, DOUBLE_STACK_SLOT, 128) \ |
| 36 V(Register, REGISTER, RegisterConfiguration::kMaxGeneralRegisters) \ | 36 V(Register, REGISTER, RegisterConfiguration::kMaxGeneralRegisters) \ |
| 37 V(DoubleRegister, DOUBLE_REGISTER, RegisterConfiguration::kMaxDoubleRegisters) | 37 V(DoubleRegister, DOUBLE_REGISTER, RegisterConfiguration::kMaxDoubleRegisters) |
| 38 | 38 |
| 39 class InstructionOperand : public ZoneObject { | 39 class InstructionOperand : public ZoneObject { |
| 40 public: | 40 public: |
| 41 enum Kind { | 41 enum Kind { |
| 42 INVALID, | |
| 43 UNALLOCATED, | 42 UNALLOCATED, |
| 44 CONSTANT, | 43 CONSTANT, |
| 45 IMMEDIATE, | 44 IMMEDIATE, |
| 46 STACK_SLOT, | 45 STACK_SLOT, |
| 47 DOUBLE_STACK_SLOT, | 46 DOUBLE_STACK_SLOT, |
| 48 REGISTER, | 47 REGISTER, |
| 49 DOUBLE_REGISTER | 48 DOUBLE_REGISTER |
| 50 }; | 49 }; |
| 51 | 50 |
| 52 InstructionOperand() : value_(KindField::encode(INVALID)) {} | |
| 53 InstructionOperand(Kind kind, int index) { ConvertTo(kind, index); } | 51 InstructionOperand(Kind kind, int index) { ConvertTo(kind, index); } |
| 54 | 52 |
| 55 Kind kind() const { return KindField::decode(value_); } | 53 Kind kind() const { return KindField::decode(value_); } |
| 56 int index() const { return static_cast<int>(value_) >> KindField::kSize; } | 54 int index() const { return static_cast<int>(value_) >> KindField::kSize; } |
| 57 #define INSTRUCTION_OPERAND_PREDICATE(name, type, number) \ | 55 #define INSTRUCTION_OPERAND_PREDICATE(name, type, number) \ |
| 58 bool Is##name() const { return kind() == type; } | 56 bool Is##name() const { return kind() == type; } |
| 59 INSTRUCTION_OPERAND_LIST(INSTRUCTION_OPERAND_PREDICATE) | 57 INSTRUCTION_OPERAND_LIST(INSTRUCTION_OPERAND_PREDICATE) |
| 60 INSTRUCTION_OPERAND_PREDICATE(Unallocated, UNALLOCATED, 0) | 58 INSTRUCTION_OPERAND_PREDICATE(Unallocated, UNALLOCATED, 0) |
| 61 INSTRUCTION_OPERAND_PREDICATE(Ignored, INVALID, 0) | |
| 62 #undef INSTRUCTION_OPERAND_PREDICATE | 59 #undef INSTRUCTION_OPERAND_PREDICATE |
| 63 bool Equals(const InstructionOperand* other) const { | 60 bool Equals(const InstructionOperand* other) const { |
| 64 return value_ == other->value_; | 61 return value_ == other->value_; |
| 65 } | 62 } |
| 66 | 63 |
| 67 void ConvertTo(Kind kind, int index) { | 64 void ConvertTo(Kind kind, int index) { |
| 68 if (kind == REGISTER || kind == DOUBLE_REGISTER) DCHECK(index >= 0); | 65 if (kind == REGISTER || kind == DOUBLE_REGISTER) DCHECK(index >= 0); |
| 69 value_ = KindField::encode(kind); | 66 value_ = KindField::encode(kind); |
| 70 value_ |= index << KindField::kSize; | 67 value_ |= index << KindField::kSize; |
| 71 DCHECK(this->index() == index); | 68 DCHECK(this->index() == index); |
| (...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 284 // The gap resolver marks moves as "in-progress" by clearing the | 281 // The gap resolver marks moves as "in-progress" by clearing the |
| 285 // destination (but not the source). | 282 // destination (but not the source). |
| 286 bool IsPending() const { return destination_ == NULL && source_ != NULL; } | 283 bool IsPending() const { return destination_ == NULL && source_ != NULL; } |
| 287 | 284 |
| 288 // True if this move a move into the given destination operand. | 285 // True if this move a move into the given destination operand. |
| 289 bool Blocks(InstructionOperand* operand) const { | 286 bool Blocks(InstructionOperand* operand) const { |
| 290 return !IsEliminated() && source()->Equals(operand); | 287 return !IsEliminated() && source()->Equals(operand); |
| 291 } | 288 } |
| 292 | 289 |
| 293 // A move is redundant if it's been eliminated, if its source and | 290 // A move is redundant if it's been eliminated, if its source and |
| 294 // destination are the same, or if its destination is unneeded or constant. | 291 // destination are the same, or if its destination is constant. |
| 295 bool IsRedundant() const { | 292 bool IsRedundant() const { |
| 296 return IsEliminated() || source_->Equals(destination_) || IsIgnored() || | 293 return IsEliminated() || source_->Equals(destination_) || |
| 297 (destination_ != NULL && destination_->IsConstant()); | 294 (destination_ != NULL && destination_->IsConstant()); |
| 298 } | 295 } |
| 299 | 296 |
| 300 bool IsIgnored() const { | |
| 301 return destination_ != NULL && destination_->IsIgnored(); | |
| 302 } | |
| 303 | |
| 304 // We clear both operands to indicate move that's been eliminated. | 297 // We clear both operands to indicate move that's been eliminated. |
| 305 void Eliminate() { source_ = destination_ = NULL; } | 298 void Eliminate() { source_ = destination_ = NULL; } |
| 306 bool IsEliminated() const { | 299 bool IsEliminated() const { |
| 307 DCHECK(source_ != NULL || destination_ == NULL); | 300 DCHECK(source_ != NULL || destination_ == NULL); |
| 308 return source_ == NULL; | 301 return source_ == NULL; |
| 309 } | 302 } |
| 310 | 303 |
| 311 private: | 304 private: |
| 312 InstructionOperand* source_; | 305 InstructionOperand* source_; |
| 313 InstructionOperand* destination_; | 306 InstructionOperand* destination_; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 341 DCHECK(op->kind() == kOperandKind); | 334 DCHECK(op->kind() == kOperandKind); |
| 342 return reinterpret_cast<const SubKindOperand*>(op); | 335 return reinterpret_cast<const SubKindOperand*>(op); |
| 343 } | 336 } |
| 344 | 337 |
| 345 static void SetUpCache(); | 338 static void SetUpCache(); |
| 346 static void TearDownCache(); | 339 static void TearDownCache(); |
| 347 | 340 |
| 348 private: | 341 private: |
| 349 static SubKindOperand* cache; | 342 static SubKindOperand* cache; |
| 350 | 343 |
| 351 SubKindOperand() : InstructionOperand() {} | 344 SubKindOperand() : InstructionOperand(kOperandKind, 0) {} // For the caches. |
| 352 explicit SubKindOperand(int index) | 345 explicit SubKindOperand(int index) |
| 353 : InstructionOperand(kOperandKind, index) {} | 346 : InstructionOperand(kOperandKind, index) {} |
| 354 }; | 347 }; |
| 355 | 348 |
| 356 | 349 |
| 357 #define INSTRUCTION_TYPEDEF_SUBKIND_OPERAND_CLASS(name, type, number) \ | 350 #define INSTRUCTION_TYPEDEF_SUBKIND_OPERAND_CLASS(name, type, number) \ |
| 358 typedef SubKindOperand<InstructionOperand::type, number> name##Operand; | 351 typedef SubKindOperand<InstructionOperand::type, number> name##Operand; |
| 359 INSTRUCTION_OPERAND_LIST(INSTRUCTION_TYPEDEF_SUBKIND_OPERAND_CLASS) | 352 INSTRUCTION_OPERAND_LIST(INSTRUCTION_TYPEDEF_SUBKIND_OPERAND_CLASS) |
| 360 #undef INSTRUCTION_TYPEDEF_SUBKIND_OPERAND_CLASS | 353 #undef INSTRUCTION_TYPEDEF_SUBKIND_OPERAND_CLASS |
| 361 | 354 |
| (...skipping 730 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1092 | 1085 |
| 1093 | 1086 |
| 1094 std::ostream& operator<<(std::ostream& os, | 1087 std::ostream& operator<<(std::ostream& os, |
| 1095 const PrintableInstructionSequence& code); | 1088 const PrintableInstructionSequence& code); |
| 1096 | 1089 |
| 1097 } // namespace compiler | 1090 } // namespace compiler |
| 1098 } // namespace internal | 1091 } // namespace internal |
| 1099 } // namespace v8 | 1092 } // namespace v8 |
| 1100 | 1093 |
| 1101 #endif // V8_COMPILER_INSTRUCTION_H_ | 1094 #endif // V8_COMPILER_INSTRUCTION_H_ |
| OLD | NEW |