Index: src/compiler/instruction.h |
diff --git a/src/compiler/instruction.h b/src/compiler/instruction.h |
index 9b9728224ce35e8a78c8c89481cf230311c5aea6..7d5105b93a8435de4c0c7b0b52e46594e9bbc0e2 100644 |
--- a/src/compiler/instruction.h |
+++ b/src/compiler/instruction.h |
@@ -50,19 +50,6 @@ class InstructionOperand { |
inline bool IsStackSlot() const; |
inline bool IsDoubleStackSlot() const; |
- // Useful for map/set keys. |
- bool operator<(const InstructionOperand& op) const { |
- return value_ < op.value_; |
- } |
- |
- bool operator==(const InstructionOperand& op) const { |
- 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)); |
@@ -74,22 +61,43 @@ class InstructionOperand { |
*dest = *src; |
} |
+ bool Equals(const InstructionOperand& that) const { |
+ return this->value_ == that.value_; |
+ } |
+ |
+ bool Compare(const InstructionOperand& that) const { |
+ return this->value_ < that.value_; |
+ } |
+ |
+ bool EqualsModuloType(const InstructionOperand& that) const { |
+ return this->GetValueModuloType() == that.GetValueModuloType(); |
+ } |
+ |
+ bool CompareModuloType(const InstructionOperand& that) const { |
+ return this->GetValueModuloType() < that.GetValueModuloType(); |
+ } |
+ |
protected: |
explicit InstructionOperand(Kind kind) : value_(KindField::encode(kind)) {} |
+ inline uint64_t GetValueModuloType() const; |
+ |
class KindField : public BitField64<Kind, 0, 3> {}; |
uint64_t value_; |
}; |
+ |
struct PrintableInstructionOperand { |
const RegisterConfiguration* register_configuration_; |
InstructionOperand op_; |
}; |
+ |
std::ostream& operator<<(std::ostream& os, |
const PrintableInstructionOperand& op); |
+ |
#define INSTRUCTION_OPERAND_CASTS(OperandType, OperandKind) \ |
\ |
static OperandType* cast(InstructionOperand* op) { \ |
@@ -346,6 +354,8 @@ class ImmediateOperand : public InstructionOperand { |
class AllocatedOperand : public InstructionOperand { |
public: |
+ // TODO(dcarney): machine_type makes this now redundant. Just need to know is |
+ // the operand is a slot or a register. |
enum AllocatedKind { |
STACK_SLOT, |
DOUBLE_STACK_SLOT, |
@@ -353,10 +363,12 @@ class AllocatedOperand : public InstructionOperand { |
DOUBLE_REGISTER |
}; |
- AllocatedOperand(AllocatedKind kind, int index) |
+ AllocatedOperand(AllocatedKind kind, MachineType machine_type, int index) |
: InstructionOperand(ALLOCATED) { |
DCHECK_IMPLIES(kind == REGISTER || kind == DOUBLE_REGISTER, index >= 0); |
+ DCHECK(IsSupportedMachineType(machine_type)); |
value_ |= AllocatedKindField::encode(kind); |
+ value_ |= MachineTypeField::encode(machine_type); |
value_ |= static_cast<int64_t>(index) << IndexField::kShift; |
} |
@@ -368,14 +380,33 @@ class AllocatedOperand : public InstructionOperand { |
return AllocatedKindField::decode(value_); |
} |
- static AllocatedOperand* New(Zone* zone, AllocatedKind kind, int index) { |
- return InstructionOperand::New(zone, AllocatedOperand(kind, index)); |
+ MachineType machine_type() const { return MachineTypeField::decode(value_); } |
+ |
+ static AllocatedOperand* New(Zone* zone, AllocatedKind kind, |
+ MachineType machine_type, int index) { |
+ return InstructionOperand::New(zone, |
+ AllocatedOperand(kind, machine_type, index)); |
+ } |
+ |
+ static bool IsSupportedMachineType(MachineType machine_type) { |
+ if (RepresentationOf(machine_type) != machine_type) return false; |
+ switch (machine_type) { |
+ case kRepWord32: |
+ case kRepWord64: |
+ case kRepFloat32: |
+ case kRepFloat64: |
+ case kRepTagged: |
+ return true; |
+ default: |
+ return false; |
+ } |
} |
INSTRUCTION_OPERAND_CASTS(AllocatedOperand, ALLOCATED); |
STATIC_ASSERT(KindField::kSize == 3); |
class AllocatedKindField : public BitField64<AllocatedKind, 3, 2> {}; |
+ class MachineTypeField : public BitField64<MachineType, 5, 16> {}; |
class IndexField : public BitField64<int32_t, 35, 29> {}; |
}; |
@@ -400,14 +431,17 @@ ALLOCATED_OPERAND_LIST(ALLOCATED_OPERAND_IS) |
#undef ALLOCATED_OPERAND_IS |
+// TODO(dcarney): these subkinds are now pretty useless, nuke. |
#define ALLOCATED_OPERAND_CLASS(SubKind, kOperandKind) \ |
class SubKind##Operand final : public AllocatedOperand { \ |
public: \ |
- explicit SubKind##Operand(int index) \ |
- : AllocatedOperand(kOperandKind, index) {} \ |
+ explicit SubKind##Operand(MachineType machine_type, int index) \ |
+ : AllocatedOperand(kOperandKind, machine_type, index) {} \ |
\ |
- static SubKind##Operand* New(Zone* zone, int index) { \ |
- return InstructionOperand::New(zone, SubKind##Operand(index)); \ |
+ static SubKind##Operand* New(Zone* zone, MachineType machine_type, \ |
+ int index) { \ |
+ return InstructionOperand::New(zone, \ |
+ SubKind##Operand(machine_type, index)); \ |
} \ |
\ |
static SubKind##Operand* cast(InstructionOperand* op) { \ |
@@ -429,6 +463,24 @@ ALLOCATED_OPERAND_LIST(ALLOCATED_OPERAND_CLASS) |
#undef ALLOCATED_OPERAND_CLASS |
+uint64_t InstructionOperand::GetValueModuloType() const { |
+ if (IsAllocated()) { |
+ // TODO(dcarney): put machine type last and mask. |
+ return AllocatedOperand::MachineTypeField::update(this->value_, kMachNone); |
+ } |
+ return this->value_; |
+} |
+ |
+ |
+// Required for maps that don't care about machine type. |
+struct CompareOperandModuloType { |
+ bool operator()(const InstructionOperand& a, |
+ const InstructionOperand& b) const { |
+ return a.CompareModuloType(b); |
+ } |
+}; |
+ |
+ |
class MoveOperands final : public ZoneObject { |
public: |
MoveOperands(const InstructionOperand& source, |
@@ -456,14 +508,14 @@ class MoveOperands final : public ZoneObject { |
// True if this move a move into the given destination operand. |
bool Blocks(const InstructionOperand& operand) const { |
- return !IsEliminated() && source() == operand; |
+ return !IsEliminated() && source().EqualsModuloType(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_.IsInvalid(), !destination_.IsConstant()); |
- return IsEliminated() || source_ == destination_; |
+ return IsEliminated() || source_.EqualsModuloType(destination_); |
} |
// We clear both operands to indicate move that's been eliminated. |
@@ -551,7 +603,7 @@ class ReferenceMap final : public ZoneObject { |
std::ostream& operator<<(std::ostream& os, const ReferenceMap& pm); |
-class Instruction { |
+class Instruction final { |
public: |
size_t OutputCount() const { return OutputCountField::decode(bit_field_); } |
const InstructionOperand* OutputAt(size_t i) const { |
@@ -676,10 +728,9 @@ class Instruction { |
ParallelMove* const* parallel_moves() const { return ¶llel_moves_[0]; } |
ParallelMove** parallel_moves() { return ¶llel_moves_[0]; } |
- protected: |
+ private: |
explicit Instruction(InstructionCode opcode); |
- private: |
Instruction(InstructionCode opcode, size_t output_count, |
InstructionOperand* outputs, size_t input_count, |
InstructionOperand* inputs, size_t temp_count, |
@@ -696,7 +747,6 @@ class Instruction { |
ReferenceMap* reference_map_; |
InstructionOperand operands_[1]; |
- private: |
DISALLOW_COPY_AND_ASSIGN(Instruction); |
}; |
@@ -1004,11 +1054,24 @@ class InstructionSequence final : public ZoneObject { |
const InstructionBlock* GetInstructionBlock(int instruction_index) const; |
- bool IsReference(int virtual_register) const; |
- bool IsDouble(int virtual_register) const; |
+ static MachineType DefaultRepresentation() { |
+ return kPointerSize == 8 ? kRepWord64 : kRepWord32; |
+ } |
+ MachineType GetRepresentation(int virtual_register) const; |
+ void MarkAsRepresentation(MachineType machine_type, int virtual_register); |
- void MarkAsReference(int virtual_register); |
- void MarkAsDouble(int virtual_register); |
+ bool IsReference(int virtual_register) const { |
+ return GetRepresentation(virtual_register) == kRepTagged; |
+ } |
+ bool IsFloat(int virtual_register) const { |
+ switch (GetRepresentation(virtual_register)) { |
+ case kRepFloat32: |
+ case kRepFloat64: |
+ return true; |
+ default: |
+ return false; |
+ } |
+ } |
Instruction* GetBlockStart(RpoNumber rpo) const; |
@@ -1111,8 +1174,7 @@ class InstructionSequence final : public ZoneObject { |
InstructionDeque instructions_; |
int next_virtual_register_; |
ReferenceMapDeque reference_maps_; |
- VirtualRegisterSet doubles_; |
- VirtualRegisterSet references_; |
+ ZoneVector<MachineType> representations_; |
DeoptimizationVector deoptimization_entries_; |
DISALLOW_COPY_AND_ASSIGN(InstructionSequence); |