Chromium Code Reviews| 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 13 matching lines...) Expand all Loading... | |
| 24 namespace compiler { | 24 namespace compiler { |
| 25 | 25 |
| 26 class Schedule; | 26 class Schedule; |
| 27 | 27 |
| 28 class InstructionOperand { | 28 class InstructionOperand { |
| 29 public: | 29 public: |
| 30 static const int kInvalidVirtualRegister = -1; | 30 static const int kInvalidVirtualRegister = -1; |
| 31 | 31 |
| 32 // TODO(dcarney): recover bit. INVALID can be represented as UNALLOCATED with | 32 // TODO(dcarney): recover bit. INVALID can be represented as UNALLOCATED with |
| 33 // kInvalidVirtualRegister and some DCHECKS. | 33 // kInvalidVirtualRegister and some DCHECKS. |
| 34 enum Kind { INVALID, UNALLOCATED, CONSTANT, IMMEDIATE, ALLOCATED }; | 34 enum Kind { INVALID, UNALLOCATED, CONSTANT, IMMEDIATE, EXPLICIT, ALLOCATED }; |
| 35 | 35 |
| 36 InstructionOperand() : InstructionOperand(INVALID) {} | 36 InstructionOperand() : InstructionOperand(INVALID) {} |
| 37 | 37 |
| 38 Kind kind() const { return KindField::decode(value_); } | 38 Kind kind() const { return KindField::decode(value_); } |
| 39 | 39 |
| 40 #define INSTRUCTION_OPERAND_PREDICATE(name, type) \ | 40 #define INSTRUCTION_OPERAND_PREDICATE(name, type) \ |
| 41 bool Is##name() const { return kind() == type; } | 41 bool Is##name() const { return kind() == type; } |
| 42 INSTRUCTION_OPERAND_PREDICATE(Invalid, INVALID) | 42 INSTRUCTION_OPERAND_PREDICATE(Invalid, INVALID) |
| 43 INSTRUCTION_OPERAND_PREDICATE(Unallocated, UNALLOCATED) | 43 INSTRUCTION_OPERAND_PREDICATE(Unallocated, UNALLOCATED) |
| 44 INSTRUCTION_OPERAND_PREDICATE(Constant, CONSTANT) | 44 INSTRUCTION_OPERAND_PREDICATE(Constant, CONSTANT) |
| 45 INSTRUCTION_OPERAND_PREDICATE(Immediate, IMMEDIATE) | 45 INSTRUCTION_OPERAND_PREDICATE(Immediate, IMMEDIATE) |
| 46 INSTRUCTION_OPERAND_PREDICATE(Explicit, EXPLICIT) | |
|
Mircea Trofin
2015/10/15 15:05:38
Maybe this would be a good time to add a short des
danno
2015/10/23 08:07:49
Done
| |
| 46 INSTRUCTION_OPERAND_PREDICATE(Allocated, ALLOCATED) | 47 INSTRUCTION_OPERAND_PREDICATE(Allocated, ALLOCATED) |
| 47 #undef INSTRUCTION_OPERAND_PREDICATE | 48 #undef INSTRUCTION_OPERAND_PREDICATE |
| 48 | 49 |
| 49 inline bool IsRegister() const; | 50 inline bool IsRegister() const; |
| 50 inline bool IsDoubleRegister() const; | 51 inline bool IsDoubleRegister() const; |
| 51 inline bool IsStackSlot() const; | 52 inline bool IsStackSlot() const; |
| 52 inline bool IsDoubleStackSlot() const; | 53 inline bool IsDoubleStackSlot() const; |
| 53 | 54 |
| 54 template <typename SubKindOperand> | 55 template <typename SubKindOperand> |
| 55 static SubKindOperand* New(Zone* zone, const SubKindOperand& op) { | 56 static SubKindOperand* New(Zone* zone, const SubKindOperand& op) { |
| 56 void* buffer = zone->New(sizeof(op)); | 57 void* buffer = zone->New(sizeof(op)); |
| 57 return new (buffer) SubKindOperand(op); | 58 return new (buffer) SubKindOperand(op); |
| 58 } | 59 } |
| 59 | 60 |
| 60 static void ReplaceWith(InstructionOperand* dest, | 61 static void ReplaceWith(InstructionOperand* dest, |
| 61 const InstructionOperand* src) { | 62 const InstructionOperand* src) { |
| 62 *dest = *src; | 63 *dest = *src; |
| 63 } | 64 } |
| 64 | 65 |
| 65 bool Equals(const InstructionOperand& that) const { | 66 bool Equals(const InstructionOperand& that) const { |
| 66 return this->value_ == that.value_; | 67 return this->value_ == that.value_; |
| 67 } | 68 } |
| 68 | 69 |
| 69 bool Compare(const InstructionOperand& that) const { | 70 bool Compare(const InstructionOperand& that) const { |
| 70 return this->value_ < that.value_; | 71 return this->value_ < that.value_; |
| 71 } | 72 } |
| 72 | 73 |
| 73 bool EqualsModuloType(const InstructionOperand& that) const { | 74 bool EqualsCanonicalizeType(const InstructionOperand& that) const { |
| 74 return this->GetValueModuloType() == that.GetValueModuloType(); | 75 return this->GetValueCanonicalizeType() == that.GetValueCanonicalizeType(); |
| 75 } | 76 } |
| 76 | 77 |
| 77 bool CompareModuloType(const InstructionOperand& that) const { | 78 bool CompareCanonicalizeType(const InstructionOperand& that) const { |
| 78 return this->GetValueModuloType() < that.GetValueModuloType(); | 79 return this->GetValueCanonicalizeType() < that.GetValueCanonicalizeType(); |
| 79 } | 80 } |
| 80 | 81 |
| 81 protected: | 82 protected: |
| 82 explicit InstructionOperand(Kind kind) : value_(KindField::encode(kind)) {} | 83 explicit InstructionOperand(Kind kind) : value_(KindField::encode(kind)) {} |
| 83 | 84 |
| 84 inline uint64_t GetValueModuloType() const; | 85 inline uint64_t GetValueCanonicalizeType() const; |
| 85 | 86 |
| 86 class KindField : public BitField64<Kind, 0, 3> {}; | 87 class KindField : public BitField64<Kind, 0, 3> {}; |
| 87 | 88 |
| 88 uint64_t value_; | 89 uint64_t value_; |
| 89 }; | 90 }; |
| 90 | 91 |
| 91 | 92 |
| 92 struct PrintableInstructionOperand { | 93 struct PrintableInstructionOperand { |
| 93 const RegisterConfiguration* register_configuration_; | 94 const RegisterConfiguration* register_configuration_; |
| 94 InstructionOperand op_; | 95 InstructionOperand op_; |
| (...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 346 } | 347 } |
| 347 | 348 |
| 348 INSTRUCTION_OPERAND_CASTS(ImmediateOperand, IMMEDIATE); | 349 INSTRUCTION_OPERAND_CASTS(ImmediateOperand, IMMEDIATE); |
| 349 | 350 |
| 350 STATIC_ASSERT(KindField::kSize == 3); | 351 STATIC_ASSERT(KindField::kSize == 3); |
| 351 class TypeField : public BitField64<ImmediateType, 3, 1> {}; | 352 class TypeField : public BitField64<ImmediateType, 3, 1> {}; |
| 352 class ValueField : public BitField64<int32_t, 32, 32> {}; | 353 class ValueField : public BitField64<int32_t, 32, 32> {}; |
| 353 }; | 354 }; |
| 354 | 355 |
| 355 | 356 |
| 356 class AllocatedOperand : public InstructionOperand { | 357 class LocationOperand : public InstructionOperand { |
| 357 public: | 358 public: |
| 358 // TODO(dcarney): machine_type makes this now redundant. Just need to know is | 359 enum LocationKind { REGISTER, STACK_SLOT }; |
| 359 // the operand is a slot or a register. | |
| 360 enum AllocatedKind { | |
| 361 STACK_SLOT, | |
| 362 DOUBLE_STACK_SLOT, | |
| 363 REGISTER, | |
| 364 DOUBLE_REGISTER | |
| 365 }; | |
| 366 | 360 |
| 367 AllocatedOperand(AllocatedKind kind, MachineType machine_type, int index) | 361 LocationOperand(InstructionOperand::Kind operand_kind, |
| 368 : InstructionOperand(ALLOCATED) { | 362 LocationOperand::LocationKind location_kind, |
| 369 DCHECK_IMPLIES(kind == REGISTER || kind == DOUBLE_REGISTER, index >= 0); | 363 MachineType machine_type, int index) |
| 364 : InstructionOperand(operand_kind) { | |
| 365 DCHECK_IMPLIES(location_kind == REGISTER, index >= 0); | |
| 370 DCHECK(IsSupportedMachineType(machine_type)); | 366 DCHECK(IsSupportedMachineType(machine_type)); |
| 371 value_ |= AllocatedKindField::encode(kind); | 367 value_ |= LocationKindField::encode(location_kind); |
| 372 value_ |= MachineTypeField::encode(machine_type); | 368 value_ |= MachineTypeField::encode(machine_type); |
| 373 value_ |= static_cast<int64_t>(index) << IndexField::kShift; | 369 value_ |= static_cast<int64_t>(index) << IndexField::kShift; |
| 374 } | 370 } |
| 375 | 371 |
| 376 int index() const { | 372 int index() const { |
| 377 DCHECK(STACK_SLOT == allocated_kind() || | 373 DCHECK(IsStackSlot() || IsDoubleStackSlot()); |
| 378 DOUBLE_STACK_SLOT == allocated_kind()); | |
| 379 return static_cast<int64_t>(value_) >> IndexField::kShift; | 374 return static_cast<int64_t>(value_) >> IndexField::kShift; |
| 380 } | 375 } |
| 381 | 376 |
| 382 Register GetRegister() const { | 377 Register GetRegister() const { |
| 383 DCHECK(REGISTER == allocated_kind() || DOUBLE_REGISTER == allocated_kind()); | 378 DCHECK(IsRegister()); |
| 384 return Register::from_code(static_cast<int64_t>(value_) >> | 379 return Register::from_code(static_cast<int64_t>(value_) >> |
| 385 IndexField::kShift); | 380 IndexField::kShift); |
| 386 } | 381 } |
| 387 | 382 |
| 388 DoubleRegister GetDoubleRegister() const { | 383 DoubleRegister GetDoubleRegister() const { |
| 389 DCHECK(REGISTER == allocated_kind() || DOUBLE_REGISTER == allocated_kind()); | 384 DCHECK(IsDoubleRegister()); |
| 390 return DoubleRegister::from_code(static_cast<int64_t>(value_) >> | 385 return DoubleRegister::from_code(static_cast<int64_t>(value_) >> |
| 391 IndexField::kShift); | 386 IndexField::kShift); |
| 392 } | 387 } |
| 393 | 388 |
| 394 AllocatedKind allocated_kind() const { | 389 LocationKind location_kind() const { |
| 395 return AllocatedKindField::decode(value_); | 390 return LocationKindField::decode(value_); |
| 396 } | 391 } |
| 397 | 392 |
| 398 MachineType machine_type() const { return MachineTypeField::decode(value_); } | 393 MachineType machine_type() const { return MachineTypeField::decode(value_); } |
| 399 | 394 |
| 400 static AllocatedOperand* New(Zone* zone, AllocatedKind kind, | |
| 401 MachineType machine_type, int index) { | |
| 402 return InstructionOperand::New(zone, | |
| 403 AllocatedOperand(kind, machine_type, index)); | |
| 404 } | |
| 405 | |
| 406 static bool IsSupportedMachineType(MachineType machine_type) { | 395 static bool IsSupportedMachineType(MachineType machine_type) { |
| 407 if (RepresentationOf(machine_type) != machine_type) return false; | 396 if (RepresentationOf(machine_type) != machine_type) return false; |
| 408 switch (machine_type) { | 397 switch (machine_type) { |
| 409 case kRepWord32: | 398 case kRepWord32: |
| 410 case kRepWord64: | 399 case kRepWord64: |
| 411 case kRepFloat32: | 400 case kRepFloat32: |
| 412 case kRepFloat64: | 401 case kRepFloat64: |
| 413 case kRepTagged: | 402 case kRepTagged: |
| 414 return true; | 403 return true; |
| 415 default: | 404 default: |
| 416 return false; | 405 return false; |
| 417 } | 406 } |
| 418 } | 407 } |
| 419 | 408 |
| 420 INSTRUCTION_OPERAND_CASTS(AllocatedOperand, ALLOCATED); | 409 static LocationOperand* cast(InstructionOperand* op) { |
| 410 DCHECK(ALLOCATED == op->kind() || EXPLICIT == op->kind()); | |
| 411 return static_cast<LocationOperand*>(op); | |
| 412 } | |
| 413 | |
| 414 static const LocationOperand* cast(const InstructionOperand* op) { | |
| 415 DCHECK(ALLOCATED == op->kind() || EXPLICIT == op->kind()); | |
| 416 return static_cast<const LocationOperand*>(op); | |
| 417 } | |
| 418 | |
| 419 static LocationOperand cast(const InstructionOperand& op) { | |
| 420 DCHECK(ALLOCATED == op.kind() || EXPLICIT == op.kind()); | |
| 421 return *static_cast<const LocationOperand*>(&op); | |
| 422 } | |
| 421 | 423 |
| 422 STATIC_ASSERT(KindField::kSize == 3); | 424 STATIC_ASSERT(KindField::kSize == 3); |
| 423 class AllocatedKindField : public BitField64<AllocatedKind, 3, 2> {}; | 425 class LocationKindField : public BitField64<LocationKind, 3, 2> {}; |
| 424 class MachineTypeField : public BitField64<MachineType, 5, 16> {}; | 426 class MachineTypeField : public BitField64<MachineType, 5, 16> {}; |
| 425 class IndexField : public BitField64<int32_t, 35, 29> {}; | 427 class IndexField : public BitField64<int32_t, 35, 29> {}; |
| 426 }; | 428 }; |
| 427 | 429 |
| 428 | 430 |
| 431 class ExplicitOperand : public LocationOperand { | |
| 432 public: | |
| 433 ExplicitOperand(LocationKind kind, MachineType machine_type, int index) | |
| 434 : LocationOperand(EXPLICIT, kind, machine_type, index) {} | |
| 435 | |
| 436 static ExplicitOperand* New(Zone* zone, LocationKind kind, | |
| 437 MachineType machine_type, int index) { | |
| 438 return InstructionOperand::New(zone, | |
| 439 ExplicitOperand(kind, machine_type, index)); | |
| 440 } | |
| 441 | |
| 442 INSTRUCTION_OPERAND_CASTS(ExplicitOperand, EXPLICIT); | |
| 443 }; | |
| 444 | |
| 445 | |
| 446 class AllocatedOperand : public LocationOperand { | |
| 447 public: | |
| 448 AllocatedOperand(LocationKind kind, MachineType machine_type, int index) | |
| 449 : LocationOperand(ALLOCATED, kind, machine_type, index) {} | |
| 450 | |
| 451 static AllocatedOperand* New(Zone* zone, LocationKind kind, | |
| 452 MachineType machine_type, int index) { | |
| 453 return InstructionOperand::New(zone, | |
| 454 AllocatedOperand(kind, machine_type, index)); | |
| 455 } | |
| 456 | |
| 457 INSTRUCTION_OPERAND_CASTS(AllocatedOperand, ALLOCATED); | |
| 458 }; | |
| 459 | |
| 460 | |
| 429 #undef INSTRUCTION_OPERAND_CASTS | 461 #undef INSTRUCTION_OPERAND_CASTS |
| 430 | 462 |
| 431 | 463 |
| 432 #define ALLOCATED_OPERAND_LIST(V) \ | 464 bool InstructionOperand::IsRegister() const { |
| 433 V(StackSlot, STACK_SLOT) \ | 465 return (IsAllocated() || IsExplicit()) && |
| 434 V(DoubleStackSlot, DOUBLE_STACK_SLOT) \ | 466 LocationOperand::cast(this)->location_kind() == |
| 435 V(Register, REGISTER) \ | 467 LocationOperand::REGISTER && |
| 436 V(DoubleRegister, DOUBLE_REGISTER) | 468 !IsFloatingPoint(LocationOperand::cast(this)->machine_type()); |
| 469 } | |
| 437 | 470 |
| 471 bool InstructionOperand::IsDoubleRegister() const { | |
| 472 return (IsAllocated() || IsExplicit()) && | |
| 473 LocationOperand::cast(this)->location_kind() == | |
| 474 LocationOperand::REGISTER && | |
| 475 IsFloatingPoint(LocationOperand::cast(this)->machine_type()); | |
| 476 } | |
| 438 | 477 |
| 439 #define ALLOCATED_OPERAND_IS(SubKind, kOperandKind) \ | 478 bool InstructionOperand::IsStackSlot() const { |
| 440 bool InstructionOperand::Is##SubKind() const { \ | 479 return (IsAllocated() || IsExplicit()) && |
| 441 return IsAllocated() && \ | 480 LocationOperand::cast(this)->location_kind() == |
| 442 AllocatedOperand::cast(this)->allocated_kind() == \ | 481 LocationOperand::STACK_SLOT && |
| 443 AllocatedOperand::kOperandKind; \ | 482 !IsFloatingPoint(LocationOperand::cast(this)->machine_type()); |
| 444 } | 483 } |
| 445 ALLOCATED_OPERAND_LIST(ALLOCATED_OPERAND_IS) | |
| 446 #undef ALLOCATED_OPERAND_IS | |
| 447 | 484 |
| 485 bool InstructionOperand::IsDoubleStackSlot() const { | |
| 486 return (IsAllocated() || IsExplicit()) && | |
| 487 LocationOperand::cast(this)->location_kind() == | |
| 488 LocationOperand::STACK_SLOT && | |
| 489 IsFloatingPoint(LocationOperand::cast(this)->machine_type()); | |
| 490 } | |
| 448 | 491 |
| 449 // TODO(dcarney): these subkinds are now pretty useless, nuke. | 492 uint64_t InstructionOperand::GetValueCanonicalizeType() const { |
| 450 #define ALLOCATED_OPERAND_CLASS(SubKind, kOperandKind) \ | 493 if (IsAllocated() || IsExplicit()) { |
| 451 class SubKind##Operand final : public AllocatedOperand { \ | |
| 452 public: \ | |
| 453 explicit SubKind##Operand(MachineType machine_type, int index) \ | |
| 454 : AllocatedOperand(kOperandKind, machine_type, index) {} \ | |
| 455 \ | |
| 456 static SubKind##Operand* New(Zone* zone, MachineType machine_type, \ | |
| 457 int index) { \ | |
| 458 return InstructionOperand::New(zone, \ | |
| 459 SubKind##Operand(machine_type, index)); \ | |
| 460 } \ | |
| 461 \ | |
| 462 static SubKind##Operand* cast(InstructionOperand* op) { \ | |
| 463 DCHECK_EQ(kOperandKind, AllocatedOperand::cast(op)->allocated_kind()); \ | |
| 464 return reinterpret_cast<SubKind##Operand*>(op); \ | |
| 465 } \ | |
| 466 \ | |
| 467 static const SubKind##Operand* cast(const InstructionOperand* op) { \ | |
| 468 DCHECK_EQ(kOperandKind, AllocatedOperand::cast(op)->allocated_kind()); \ | |
| 469 return reinterpret_cast<const SubKind##Operand*>(op); \ | |
| 470 } \ | |
| 471 \ | |
| 472 static SubKind##Operand cast(const InstructionOperand& op) { \ | |
| 473 DCHECK_EQ(kOperandKind, AllocatedOperand::cast(op).allocated_kind()); \ | |
| 474 return *static_cast<const SubKind##Operand*>(&op); \ | |
| 475 } \ | |
| 476 }; | |
| 477 ALLOCATED_OPERAND_LIST(ALLOCATED_OPERAND_CLASS) | |
| 478 #undef ALLOCATED_OPERAND_CLASS | |
| 479 | |
| 480 | |
| 481 uint64_t InstructionOperand::GetValueModuloType() const { | |
| 482 if (IsAllocated()) { | |
| 483 // TODO(dcarney): put machine type last and mask. | 494 // TODO(dcarney): put machine type last and mask. |
| 484 return AllocatedOperand::MachineTypeField::update(this->value_, kMachNone); | 495 MachineType canonicalized_machine_type = |
| 496 IsFloatingPoint(LocationOperand::cast(this)->machine_type()) | |
| 497 ? kMachFloat64 | |
| 498 : kMachNone; | |
| 499 return LocationOperand::MachineTypeField::update( | |
| 500 this->value_, canonicalized_machine_type); | |
| 485 } | 501 } |
| 486 return this->value_; | 502 return this->value_; |
| 487 } | 503 } |
| 488 | 504 |
| 489 | 505 |
| 490 // Required for maps that don't care about machine type. | 506 // Required for maps that don't care about machine type. |
| 491 struct CompareOperandModuloType { | 507 struct CompareOperandModuloType { |
| 492 bool operator()(const InstructionOperand& a, | 508 bool operator()(const InstructionOperand& a, |
| 493 const InstructionOperand& b) const { | 509 const InstructionOperand& b) const { |
| 494 return a.CompareModuloType(b); | 510 return a.CompareCanonicalizeType(b); |
| 495 } | 511 } |
| 496 }; | 512 }; |
| 497 | 513 |
| 498 | 514 |
| 499 class MoveOperands final : public ZoneObject { | 515 class MoveOperands final : public ZoneObject { |
| 500 public: | 516 public: |
| 501 MoveOperands(const InstructionOperand& source, | 517 MoveOperands(const InstructionOperand& source, |
| 502 const InstructionOperand& destination) | 518 const InstructionOperand& destination) |
| 503 : source_(source), destination_(destination) { | 519 : source_(source), destination_(destination) { |
| 504 DCHECK(!source.IsInvalid() && !destination.IsInvalid()); | 520 DCHECK(!source.IsInvalid() && !destination.IsInvalid()); |
| (...skipping 11 matching lines...) Expand all Loading... | |
| 516 | 532 |
| 517 // The gap resolver marks moves as "in-progress" by clearing the | 533 // The gap resolver marks moves as "in-progress" by clearing the |
| 518 // destination (but not the source). | 534 // destination (but not the source). |
| 519 bool IsPending() const { | 535 bool IsPending() const { |
| 520 return destination_.IsInvalid() && !source_.IsInvalid(); | 536 return destination_.IsInvalid() && !source_.IsInvalid(); |
| 521 } | 537 } |
| 522 void SetPending() { destination_ = InstructionOperand(); } | 538 void SetPending() { destination_ = InstructionOperand(); } |
| 523 | 539 |
| 524 // True if this move a move into the given destination operand. | 540 // True if this move a move into the given destination operand. |
| 525 bool Blocks(const InstructionOperand& operand) const { | 541 bool Blocks(const InstructionOperand& operand) const { |
| 526 return !IsEliminated() && source().EqualsModuloType(operand); | 542 return !IsEliminated() && source().EqualsCanonicalizeType(operand); |
| 527 } | 543 } |
| 528 | 544 |
| 529 // A move is redundant if it's been eliminated or if its source and | 545 // A move is redundant if it's been eliminated or if its source and |
| 530 // destination are the same. | 546 // destination are the same. |
| 531 bool IsRedundant() const { | 547 bool IsRedundant() const { |
| 532 DCHECK_IMPLIES(!destination_.IsInvalid(), !destination_.IsConstant()); | 548 DCHECK_IMPLIES(!destination_.IsInvalid(), !destination_.IsConstant()); |
| 533 return IsEliminated() || source_.EqualsModuloType(destination_); | 549 return IsEliminated() || source_.EqualsCanonicalizeType(destination_); |
| 534 } | 550 } |
| 535 | 551 |
| 536 // We clear both operands to indicate move that's been eliminated. | 552 // We clear both operands to indicate move that's been eliminated. |
| 537 void Eliminate() { source_ = destination_ = InstructionOperand(); } | 553 void Eliminate() { source_ = destination_ = InstructionOperand(); } |
| 538 bool IsEliminated() const { | 554 bool IsEliminated() const { |
| 539 DCHECK_IMPLIES(source_.IsInvalid(), destination_.IsInvalid()); | 555 DCHECK_IMPLIES(source_.IsInvalid(), destination_.IsInvalid()); |
| 540 return source_.IsInvalid(); | 556 return source_.IsInvalid(); |
| 541 } | 557 } |
| 542 | 558 |
| 543 private: | 559 private: |
| (...skipping 684 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1228 | 1244 |
| 1229 | 1245 |
| 1230 std::ostream& operator<<(std::ostream& os, | 1246 std::ostream& operator<<(std::ostream& os, |
| 1231 const PrintableInstructionSequence& code); | 1247 const PrintableInstructionSequence& code); |
| 1232 | 1248 |
| 1233 } // namespace compiler | 1249 } // namespace compiler |
| 1234 } // namespace internal | 1250 } // namespace internal |
| 1235 } // namespace v8 | 1251 } // namespace v8 |
| 1236 | 1252 |
| 1237 #endif // V8_COMPILER_INSTRUCTION_H_ | 1253 #endif // V8_COMPILER_INSTRUCTION_H_ |
| OLD | NEW |