| 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 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 385 class ValueField : public BitField64<int32_t, 32, 32> {}; | 385 class ValueField : public BitField64<int32_t, 32, 32> {}; |
| 386 }; | 386 }; |
| 387 | 387 |
| 388 | 388 |
| 389 class LocationOperand : public InstructionOperand { | 389 class LocationOperand : public InstructionOperand { |
| 390 public: | 390 public: |
| 391 enum LocationKind { REGISTER, STACK_SLOT }; | 391 enum LocationKind { REGISTER, STACK_SLOT }; |
| 392 | 392 |
| 393 LocationOperand(InstructionOperand::Kind operand_kind, | 393 LocationOperand(InstructionOperand::Kind operand_kind, |
| 394 LocationOperand::LocationKind location_kind, | 394 LocationOperand::LocationKind location_kind, |
| 395 MachineType machine_type, int index) | 395 MachineRepresentation rep, int index) |
| 396 : InstructionOperand(operand_kind) { | 396 : InstructionOperand(operand_kind) { |
| 397 DCHECK_IMPLIES(location_kind == REGISTER, index >= 0); | 397 DCHECK_IMPLIES(location_kind == REGISTER, index >= 0); |
| 398 DCHECK(IsSupportedMachineType(machine_type)); | 398 DCHECK(IsSupportedRepresentation(rep)); |
| 399 value_ |= LocationKindField::encode(location_kind); | 399 value_ |= LocationKindField::encode(location_kind); |
| 400 value_ |= MachineTypeField::encode(machine_type); | 400 value_ |= RepresentationField::encode(rep); |
| 401 value_ |= static_cast<int64_t>(index) << IndexField::kShift; | 401 value_ |= static_cast<int64_t>(index) << IndexField::kShift; |
| 402 } | 402 } |
| 403 | 403 |
| 404 int index() const { | 404 int index() const { |
| 405 DCHECK(IsStackSlot() || IsDoubleStackSlot()); | 405 DCHECK(IsStackSlot() || IsDoubleStackSlot()); |
| 406 return static_cast<int64_t>(value_) >> IndexField::kShift; | 406 return static_cast<int64_t>(value_) >> IndexField::kShift; |
| 407 } | 407 } |
| 408 | 408 |
| 409 Register GetRegister() const { | 409 Register GetRegister() const { |
| 410 DCHECK(IsRegister()); | 410 DCHECK(IsRegister()); |
| 411 return Register::from_code(static_cast<int64_t>(value_) >> | 411 return Register::from_code(static_cast<int64_t>(value_) >> |
| 412 IndexField::kShift); | 412 IndexField::kShift); |
| 413 } | 413 } |
| 414 | 414 |
| 415 DoubleRegister GetDoubleRegister() const { | 415 DoubleRegister GetDoubleRegister() const { |
| 416 DCHECK(IsDoubleRegister()); | 416 DCHECK(IsDoubleRegister()); |
| 417 return DoubleRegister::from_code(static_cast<int64_t>(value_) >> | 417 return DoubleRegister::from_code(static_cast<int64_t>(value_) >> |
| 418 IndexField::kShift); | 418 IndexField::kShift); |
| 419 } | 419 } |
| 420 | 420 |
| 421 LocationKind location_kind() const { | 421 LocationKind location_kind() const { |
| 422 return LocationKindField::decode(value_); | 422 return LocationKindField::decode(value_); |
| 423 } | 423 } |
| 424 | 424 |
| 425 MachineType machine_type() const { return MachineTypeField::decode(value_); } | 425 MachineRepresentation representation() const { |
| 426 return RepresentationField::decode(value_); |
| 427 } |
| 426 | 428 |
| 427 static bool IsSupportedMachineType(MachineType machine_type) { | 429 static bool IsSupportedRepresentation(MachineRepresentation rep) { |
| 428 if (RepresentationOf(machine_type) != machine_type) return false; | 430 switch (rep) { |
| 429 switch (machine_type) { | 431 case MachineRepresentation::kWord32: |
| 430 case kRepWord32: | 432 case MachineRepresentation::kWord64: |
| 431 case kRepWord64: | 433 case MachineRepresentation::kFloat32: |
| 432 case kRepFloat32: | 434 case MachineRepresentation::kFloat64: |
| 433 case kRepFloat64: | 435 case MachineRepresentation::kTagged: |
| 434 case kRepTagged: | |
| 435 return true; | 436 return true; |
| 436 default: | 437 default: |
| 437 return false; | 438 return false; |
| 438 } | 439 } |
| 439 } | 440 } |
| 440 | 441 |
| 441 static LocationOperand* cast(InstructionOperand* op) { | 442 static LocationOperand* cast(InstructionOperand* op) { |
| 442 DCHECK(ALLOCATED == op->kind() || EXPLICIT == op->kind()); | 443 DCHECK(ALLOCATED == op->kind() || EXPLICIT == op->kind()); |
| 443 return static_cast<LocationOperand*>(op); | 444 return static_cast<LocationOperand*>(op); |
| 444 } | 445 } |
| 445 | 446 |
| 446 static const LocationOperand* cast(const InstructionOperand* op) { | 447 static const LocationOperand* cast(const InstructionOperand* op) { |
| 447 DCHECK(ALLOCATED == op->kind() || EXPLICIT == op->kind()); | 448 DCHECK(ALLOCATED == op->kind() || EXPLICIT == op->kind()); |
| 448 return static_cast<const LocationOperand*>(op); | 449 return static_cast<const LocationOperand*>(op); |
| 449 } | 450 } |
| 450 | 451 |
| 451 static LocationOperand cast(const InstructionOperand& op) { | 452 static LocationOperand cast(const InstructionOperand& op) { |
| 452 DCHECK(ALLOCATED == op.kind() || EXPLICIT == op.kind()); | 453 DCHECK(ALLOCATED == op.kind() || EXPLICIT == op.kind()); |
| 453 return *static_cast<const LocationOperand*>(&op); | 454 return *static_cast<const LocationOperand*>(&op); |
| 454 } | 455 } |
| 455 | 456 |
| 456 STATIC_ASSERT(KindField::kSize == 3); | 457 STATIC_ASSERT(KindField::kSize == 3); |
| 457 class LocationKindField : public BitField64<LocationKind, 3, 2> {}; | 458 class LocationKindField : public BitField64<LocationKind, 3, 2> {}; |
| 458 class MachineTypeField : public BitField64<MachineType, 5, 16> {}; | 459 class RepresentationField : public BitField64<MachineRepresentation, 5, 8> {}; |
| 459 class IndexField : public BitField64<int32_t, 35, 29> {}; | 460 class IndexField : public BitField64<int32_t, 35, 29> {}; |
| 460 }; | 461 }; |
| 461 | 462 |
| 462 | 463 |
| 463 class ExplicitOperand : public LocationOperand { | 464 class ExplicitOperand : public LocationOperand { |
| 464 public: | 465 public: |
| 465 ExplicitOperand(LocationKind kind, MachineType machine_type, int index); | 466 ExplicitOperand(LocationKind kind, MachineRepresentation rep, int index); |
| 466 | 467 |
| 467 static ExplicitOperand* New(Zone* zone, LocationKind kind, | 468 static ExplicitOperand* New(Zone* zone, LocationKind kind, |
| 468 MachineType machine_type, int index) { | 469 MachineRepresentation rep, int index) { |
| 469 return InstructionOperand::New(zone, | 470 return InstructionOperand::New(zone, ExplicitOperand(kind, rep, index)); |
| 470 ExplicitOperand(kind, machine_type, index)); | |
| 471 } | 471 } |
| 472 | 472 |
| 473 INSTRUCTION_OPERAND_CASTS(ExplicitOperand, EXPLICIT); | 473 INSTRUCTION_OPERAND_CASTS(ExplicitOperand, EXPLICIT); |
| 474 }; | 474 }; |
| 475 | 475 |
| 476 | 476 |
| 477 class AllocatedOperand : public LocationOperand { | 477 class AllocatedOperand : public LocationOperand { |
| 478 public: | 478 public: |
| 479 AllocatedOperand(LocationKind kind, MachineType machine_type, int index) | 479 AllocatedOperand(LocationKind kind, MachineRepresentation rep, int index) |
| 480 : LocationOperand(ALLOCATED, kind, machine_type, index) {} | 480 : LocationOperand(ALLOCATED, kind, rep, index) {} |
| 481 | 481 |
| 482 static AllocatedOperand* New(Zone* zone, LocationKind kind, | 482 static AllocatedOperand* New(Zone* zone, LocationKind kind, |
| 483 MachineType machine_type, int index) { | 483 MachineRepresentation rep, int index) { |
| 484 return InstructionOperand::New(zone, | 484 return InstructionOperand::New(zone, AllocatedOperand(kind, rep, index)); |
| 485 AllocatedOperand(kind, machine_type, index)); | |
| 486 } | 485 } |
| 487 | 486 |
| 488 INSTRUCTION_OPERAND_CASTS(AllocatedOperand, ALLOCATED); | 487 INSTRUCTION_OPERAND_CASTS(AllocatedOperand, ALLOCATED); |
| 489 }; | 488 }; |
| 490 | 489 |
| 491 | 490 |
| 492 #undef INSTRUCTION_OPERAND_CASTS | 491 #undef INSTRUCTION_OPERAND_CASTS |
| 493 | 492 |
| 494 | 493 |
| 495 bool InstructionOperand::IsRegister() const { | 494 bool InstructionOperand::IsRegister() const { |
| 496 return (IsAllocated() || IsExplicit()) && | 495 return (IsAllocated() || IsExplicit()) && |
| 497 LocationOperand::cast(this)->location_kind() == | 496 LocationOperand::cast(this)->location_kind() == |
| 498 LocationOperand::REGISTER && | 497 LocationOperand::REGISTER && |
| 499 !IsFloatingPoint(LocationOperand::cast(this)->machine_type()); | 498 !IsFloatingPoint(LocationOperand::cast(this)->representation()); |
| 500 } | 499 } |
| 501 | 500 |
| 502 bool InstructionOperand::IsDoubleRegister() const { | 501 bool InstructionOperand::IsDoubleRegister() const { |
| 503 return (IsAllocated() || IsExplicit()) && | 502 return (IsAllocated() || IsExplicit()) && |
| 504 LocationOperand::cast(this)->location_kind() == | 503 LocationOperand::cast(this)->location_kind() == |
| 505 LocationOperand::REGISTER && | 504 LocationOperand::REGISTER && |
| 506 IsFloatingPoint(LocationOperand::cast(this)->machine_type()); | 505 IsFloatingPoint(LocationOperand::cast(this)->representation()); |
| 507 } | 506 } |
| 508 | 507 |
| 509 bool InstructionOperand::IsStackSlot() const { | 508 bool InstructionOperand::IsStackSlot() const { |
| 510 return (IsAllocated() || IsExplicit()) && | 509 return (IsAllocated() || IsExplicit()) && |
| 511 LocationOperand::cast(this)->location_kind() == | 510 LocationOperand::cast(this)->location_kind() == |
| 512 LocationOperand::STACK_SLOT && | 511 LocationOperand::STACK_SLOT && |
| 513 !IsFloatingPoint(LocationOperand::cast(this)->machine_type()); | 512 !IsFloatingPoint(LocationOperand::cast(this)->representation()); |
| 514 } | 513 } |
| 515 | 514 |
| 516 bool InstructionOperand::IsDoubleStackSlot() const { | 515 bool InstructionOperand::IsDoubleStackSlot() const { |
| 517 return (IsAllocated() || IsExplicit()) && | 516 return (IsAllocated() || IsExplicit()) && |
| 518 LocationOperand::cast(this)->location_kind() == | 517 LocationOperand::cast(this)->location_kind() == |
| 519 LocationOperand::STACK_SLOT && | 518 LocationOperand::STACK_SLOT && |
| 520 IsFloatingPoint(LocationOperand::cast(this)->machine_type()); | 519 IsFloatingPoint(LocationOperand::cast(this)->representation()); |
| 521 } | 520 } |
| 522 | 521 |
| 523 uint64_t InstructionOperand::GetCanonicalizedValue() const { | 522 uint64_t InstructionOperand::GetCanonicalizedValue() const { |
| 524 if (IsAllocated() || IsExplicit()) { | 523 if (IsAllocated() || IsExplicit()) { |
| 525 // TODO(dcarney): put machine type last and mask. | 524 // TODO(dcarney): put machine type last and mask. |
| 526 MachineType canonicalized_machine_type = | 525 MachineRepresentation canonicalized_representation = |
| 527 IsFloatingPoint(LocationOperand::cast(this)->machine_type()) | 526 IsFloatingPoint(LocationOperand::cast(this)->representation()) |
| 528 ? kMachFloat64 | 527 ? MachineRepresentation::kFloat64 |
| 529 : kMachNone; | 528 : MachineRepresentation::kNone; |
| 530 return InstructionOperand::KindField::update( | 529 return InstructionOperand::KindField::update( |
| 531 LocationOperand::MachineTypeField::update(this->value_, | 530 LocationOperand::RepresentationField::update( |
| 532 canonicalized_machine_type), | 531 this->value_, canonicalized_representation), |
| 533 LocationOperand::EXPLICIT); | 532 LocationOperand::EXPLICIT); |
| 534 } | 533 } |
| 535 return this->value_; | 534 return this->value_; |
| 536 } | 535 } |
| 537 | 536 |
| 538 | 537 |
| 539 // Required for maps that don't care about machine type. | 538 // Required for maps that don't care about machine type. |
| 540 struct CompareOperandModuloType { | 539 struct CompareOperandModuloType { |
| 541 bool operator()(const InstructionOperand& a, | 540 bool operator()(const InstructionOperand& a, |
| 542 const InstructionOperand& b) const { | 541 const InstructionOperand& b) const { |
| (...skipping 581 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1124 return instruction_blocks_->at(block->loop_end().ToSize() - 1) | 1123 return instruction_blocks_->at(block->loop_end().ToSize() - 1) |
| 1125 ->last_instruction_index(); | 1124 ->last_instruction_index(); |
| 1126 } | 1125 } |
| 1127 | 1126 |
| 1128 const InstructionBlock* InstructionBlockAt(RpoNumber rpo_number) const { | 1127 const InstructionBlock* InstructionBlockAt(RpoNumber rpo_number) const { |
| 1129 return instruction_blocks_->at(rpo_number.ToSize()); | 1128 return instruction_blocks_->at(rpo_number.ToSize()); |
| 1130 } | 1129 } |
| 1131 | 1130 |
| 1132 InstructionBlock* GetInstructionBlock(int instruction_index) const; | 1131 InstructionBlock* GetInstructionBlock(int instruction_index) const; |
| 1133 | 1132 |
| 1134 static MachineType DefaultRepresentation() { | 1133 static MachineRepresentation DefaultRepresentation() { |
| 1135 return kPointerSize == 8 ? kRepWord64 : kRepWord32; | 1134 return MachineType::PointerRepresentation(); |
| 1136 } | 1135 } |
| 1137 MachineType GetRepresentation(int virtual_register) const; | 1136 MachineRepresentation GetRepresentation(int virtual_register) const; |
| 1138 void MarkAsRepresentation(MachineType machine_type, int virtual_register); | 1137 void MarkAsRepresentation(MachineRepresentation rep, int virtual_register); |
| 1139 | 1138 |
| 1140 bool IsReference(int virtual_register) const { | 1139 bool IsReference(int virtual_register) const { |
| 1141 return GetRepresentation(virtual_register) == kRepTagged; | 1140 return GetRepresentation(virtual_register) == |
| 1141 MachineRepresentation::kTagged; |
| 1142 } | 1142 } |
| 1143 bool IsFloat(int virtual_register) const { | 1143 bool IsFloat(int virtual_register) const { |
| 1144 switch (GetRepresentation(virtual_register)) { | 1144 switch (GetRepresentation(virtual_register)) { |
| 1145 case kRepFloat32: | 1145 case MachineRepresentation::kFloat32: |
| 1146 case kRepFloat64: | 1146 case MachineRepresentation::kFloat64: |
| 1147 return true; | 1147 return true; |
| 1148 default: | 1148 default: |
| 1149 return false; | 1149 return false; |
| 1150 } | 1150 } |
| 1151 } | 1151 } |
| 1152 | 1152 |
| 1153 Instruction* GetBlockStart(RpoNumber rpo) const; | 1153 Instruction* GetBlockStart(RpoNumber rpo) const; |
| 1154 | 1154 |
| 1155 typedef InstructionDeque::const_iterator const_iterator; | 1155 typedef InstructionDeque::const_iterator const_iterator; |
| 1156 const_iterator begin() const { return instructions_.begin(); } | 1156 const_iterator begin() const { return instructions_.begin(); } |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1256 Isolate* isolate_; | 1256 Isolate* isolate_; |
| 1257 Zone* const zone_; | 1257 Zone* const zone_; |
| 1258 InstructionBlocks* const instruction_blocks_; | 1258 InstructionBlocks* const instruction_blocks_; |
| 1259 SourcePositionMap source_positions_; | 1259 SourcePositionMap source_positions_; |
| 1260 IntVector block_starts_; | 1260 IntVector block_starts_; |
| 1261 ConstantMap constants_; | 1261 ConstantMap constants_; |
| 1262 Immediates immediates_; | 1262 Immediates immediates_; |
| 1263 InstructionDeque instructions_; | 1263 InstructionDeque instructions_; |
| 1264 int next_virtual_register_; | 1264 int next_virtual_register_; |
| 1265 ReferenceMapDeque reference_maps_; | 1265 ReferenceMapDeque reference_maps_; |
| 1266 ZoneVector<MachineType> representations_; | 1266 ZoneVector<MachineRepresentation> representations_; |
| 1267 DeoptimizationVector deoptimization_entries_; | 1267 DeoptimizationVector deoptimization_entries_; |
| 1268 | 1268 |
| 1269 DISALLOW_COPY_AND_ASSIGN(InstructionSequence); | 1269 DISALLOW_COPY_AND_ASSIGN(InstructionSequence); |
| 1270 }; | 1270 }; |
| 1271 | 1271 |
| 1272 | 1272 |
| 1273 struct PrintableInstructionSequence { | 1273 struct PrintableInstructionSequence { |
| 1274 const RegisterConfiguration* register_configuration_; | 1274 const RegisterConfiguration* register_configuration_; |
| 1275 const InstructionSequence* sequence_; | 1275 const InstructionSequence* sequence_; |
| 1276 }; | 1276 }; |
| 1277 | 1277 |
| 1278 | 1278 |
| 1279 std::ostream& operator<<(std::ostream& os, | 1279 std::ostream& operator<<(std::ostream& os, |
| 1280 const PrintableInstructionSequence& code); | 1280 const PrintableInstructionSequence& code); |
| 1281 | 1281 |
| 1282 } // namespace compiler | 1282 } // namespace compiler |
| 1283 } // namespace internal | 1283 } // namespace internal |
| 1284 } // namespace v8 | 1284 } // namespace v8 |
| 1285 | 1285 |
| 1286 #endif // V8_COMPILER_INSTRUCTION_H_ | 1286 #endif // V8_COMPILER_INSTRUCTION_H_ |
| OLD | NEW |