Index: src/compiler/instruction.h |
diff --git a/src/compiler/instruction.h b/src/compiler/instruction.h |
index f05542e6ff4016ca2d1677c815bff93616099b0f..f7d240a9deb72d6ef39562aa12525131a340eb96 100644 |
--- a/src/compiler/instruction.h |
+++ b/src/compiler/instruction.h |
@@ -50,10 +50,6 @@ class InstructionOperand { |
inline bool IsStackSlot() const; |
inline bool IsDoubleStackSlot() const; |
- bool Equals(const InstructionOperand* other) const { |
- return value_ == other->value_; |
- } |
- |
// Useful for map/set keys. |
bool operator<(const InstructionOperand& op) const { |
return value_ < op.value_; |
@@ -63,6 +59,10 @@ class InstructionOperand { |
return value_ == op.value_; |
} |
+ bool operator!=(const InstructionOperand& op) const { |
+ return value_ != op.value_; |
+ } |
+ |
template <typename SubKindOperand> |
static SubKindOperand* New(Zone* zone, const SubKindOperand& op) { |
void* buffer = zone->New(sizeof(op)); |
@@ -84,7 +84,7 @@ class InstructionOperand { |
struct PrintableInstructionOperand { |
const RegisterConfiguration* register_configuration_; |
- const InstructionOperand* op_; |
+ InstructionOperand op_; |
}; |
std::ostream& operator<<(std::ostream& os, |
@@ -167,12 +167,6 @@ class UnallocatedOperand : public InstructionOperand { |
value_ |= LifetimeField::encode(lifetime); |
} |
- UnallocatedOperand* Copy(Zone* zone) { return New(zone, *this); } |
- |
- UnallocatedOperand* CopyUnconstrained(Zone* zone) { |
- return New(zone, UnallocatedOperand(ANY, virtual_register())); |
- } |
- |
// Predicates for the operand policy. |
bool HasAnyPolicy() const { |
return basic_policy() == EXTENDED_POLICY && extended_policy() == ANY; |
@@ -435,43 +429,55 @@ ALLOCATED_OPERAND_LIST(ALLOCATED_OPERAND_CLASS) |
#undef ALLOCATED_OPERAND_CLASS |
-class MoveOperands FINAL { |
+class MoveOperands FINAL : public ZoneObject { |
public: |
- MoveOperands(InstructionOperand* source, InstructionOperand* destination) |
- : source_(source), destination_(destination) {} |
+ MoveOperands(const InstructionOperand& source, |
+ const InstructionOperand& destination) |
+ : source_(source), destination_(destination) { |
+ DCHECK(!source.IsInvalid() && !destination.IsInvalid()); |
+ } |
- InstructionOperand* source() const { return source_; } |
- void set_source(InstructionOperand* operand) { source_ = operand; } |
+ const InstructionOperand& source() const { return source_; } |
+ InstructionOperand& source() { return source_; } |
+ void set_source(const InstructionOperand& operand) { source_ = operand; } |
- InstructionOperand* destination() const { return destination_; } |
- void set_destination(InstructionOperand* operand) { destination_ = operand; } |
+ const InstructionOperand& destination() const { return destination_; } |
+ InstructionOperand& destination() { return destination_; } |
+ void set_destination(const InstructionOperand& operand) { |
+ destination_ = operand; |
+ } |
// The gap resolver marks moves as "in-progress" by clearing the |
// destination (but not the source). |
- bool IsPending() const { return destination_ == NULL && source_ != NULL; } |
+ bool IsPending() const { |
+ return destination_.IsInvalid() && !source_.IsInvalid(); |
+ } |
+ void SetPending() { destination_ = InstructionOperand(); } |
// True if this move a move into the given destination operand. |
- bool Blocks(InstructionOperand* operand) const { |
- return !IsEliminated() && source()->Equals(operand); |
+ bool Blocks(const InstructionOperand& operand) const { |
+ return !IsEliminated() && source() == operand; |
} |
// A move is redundant if it's been eliminated or if its source and |
// destination are the same. |
bool IsRedundant() const { |
- DCHECK_IMPLIES(destination_ != nullptr, !destination_->IsConstant()); |
- return IsEliminated() || source_->Equals(destination_); |
+ DCHECK_IMPLIES(!destination_.IsInvalid(), !destination_.IsConstant()); |
+ return IsEliminated() || source_ == destination_; |
} |
// We clear both operands to indicate move that's been eliminated. |
- void Eliminate() { source_ = destination_ = NULL; } |
+ void Eliminate() { source_ = destination_ = InstructionOperand(); } |
bool IsEliminated() const { |
- DCHECK(source_ != NULL || destination_ == NULL); |
- return source_ == NULL; |
+ DCHECK_IMPLIES(source_.IsInvalid(), destination_.IsInvalid()); |
+ return source_.IsInvalid(); |
} |
private: |
- InstructionOperand* source_; |
- InstructionOperand* destination_; |
+ InstructionOperand source_; |
+ InstructionOperand destination_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(MoveOperands); |
}; |
@@ -484,29 +490,29 @@ struct PrintableMoveOperands { |
std::ostream& operator<<(std::ostream& os, const PrintableMoveOperands& mo); |
-class ParallelMove FINAL : public ZoneObject { |
+class ParallelMove FINAL : public ZoneVector<MoveOperands*>, public ZoneObject { |
public: |
- explicit ParallelMove(Zone* zone) : move_operands_(4, zone) {} |
+ explicit ParallelMove(Zone* zone) : ZoneVector<MoveOperands*>(zone) { |
+ reserve(4); |
+ } |
- void AddMove(InstructionOperand* from, InstructionOperand* to, Zone* zone) { |
- move_operands_.Add(MoveOperands(from, to), zone); |
+ MoveOperands* AddMove(const InstructionOperand& from, |
+ const InstructionOperand& to) { |
+ auto zone = get_allocator().zone(); |
+ auto move = new (zone) MoveOperands(from, to); |
+ push_back(move); |
+ return move; |
} |
bool IsRedundant() const; |
- ZoneList<MoveOperands>* move_operands() { return &move_operands_; } |
- const ZoneList<MoveOperands>* move_operands() const { |
- return &move_operands_; |
- } |
- |
// Prepare this ParallelMove to insert move as if it happened in a subsequent |
// ParallelMove. move->source() may be changed. The MoveOperand returned |
- // must be Eliminated and, as it points directly into move_operands_, it must |
- // be Eliminated before any further mutation. |
+ // must be Eliminated. |
MoveOperands* PrepareInsertAfter(MoveOperands* move) const; |
private: |
- ZoneList<MoveOperands> move_operands_; |
+ DISALLOW_COPY_AND_ASSIGN(ParallelMove); |
}; |
@@ -856,18 +862,15 @@ class PhiInstruction FINAL : public ZoneObject { |
int virtual_register() const { return virtual_register_; } |
const IntVector& operands() const { return operands_; } |
+ // TODO(dcarney): this has no real business being here, since it's internal to |
+ // the register allocator, but putting it here was convenient. |
const InstructionOperand& output() const { return output_; } |
InstructionOperand& output() { return output_; } |
- const Inputs& inputs() const { return inputs_; } |
- Inputs& inputs() { return inputs_; } |
private: |
- // TODO(dcarney): some of these fields are only for verification, move them to |
- // verifier. |
const int virtual_register_; |
InstructionOperand output_; |
IntVector operands_; |
- Inputs inputs_; |
}; |