Index: src/compiler/instruction.h |
diff --git a/src/compiler/instruction.h b/src/compiler/instruction.h |
index fab184adf8090681b2aec00dcc2cfb4964a6a8b4..502aeb0a9b64107713988e4354677203a42bd73f 100644 |
--- a/src/compiler/instruction.h |
+++ b/src/compiler/instruction.h |
@@ -31,7 +31,7 @@ class InstructionOperand { |
// TODO(dcarney): recover bit. INVALID can be represented as UNALLOCATED with |
// kInvalidVirtualRegister and some DCHECKS. |
- enum Kind { INVALID, UNALLOCATED, CONSTANT, IMMEDIATE, ALLOCATED }; |
+ enum Kind { INVALID, UNALLOCATED, CONSTANT, IMMEDIATE, EXPLICIT, ALLOCATED }; |
InstructionOperand() : InstructionOperand(INVALID) {} |
@@ -43,6 +43,7 @@ class InstructionOperand { |
INSTRUCTION_OPERAND_PREDICATE(Unallocated, UNALLOCATED) |
INSTRUCTION_OPERAND_PREDICATE(Constant, CONSTANT) |
INSTRUCTION_OPERAND_PREDICATE(Immediate, IMMEDIATE) |
+ 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
|
INSTRUCTION_OPERAND_PREDICATE(Allocated, ALLOCATED) |
#undef INSTRUCTION_OPERAND_PREDICATE |
@@ -70,18 +71,18 @@ class InstructionOperand { |
return this->value_ < that.value_; |
} |
- bool EqualsModuloType(const InstructionOperand& that) const { |
- return this->GetValueModuloType() == that.GetValueModuloType(); |
+ bool EqualsCanonicalizeType(const InstructionOperand& that) const { |
+ return this->GetValueCanonicalizeType() == that.GetValueCanonicalizeType(); |
} |
- bool CompareModuloType(const InstructionOperand& that) const { |
- return this->GetValueModuloType() < that.GetValueModuloType(); |
+ bool CompareCanonicalizeType(const InstructionOperand& that) const { |
+ return this->GetValueCanonicalizeType() < that.GetValueCanonicalizeType(); |
} |
protected: |
explicit InstructionOperand(Kind kind) : value_(KindField::encode(kind)) {} |
- inline uint64_t GetValueModuloType() const; |
+ inline uint64_t GetValueCanonicalizeType() const; |
class KindField : public BitField64<Kind, 0, 3> {}; |
@@ -353,56 +354,44 @@ class ImmediateOperand : public InstructionOperand { |
}; |
-class AllocatedOperand : public InstructionOperand { |
+class LocationOperand : 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, |
- REGISTER, |
- DOUBLE_REGISTER |
- }; |
+ enum LocationKind { REGISTER, STACK_SLOT }; |
- AllocatedOperand(AllocatedKind kind, MachineType machine_type, int index) |
- : InstructionOperand(ALLOCATED) { |
- DCHECK_IMPLIES(kind == REGISTER || kind == DOUBLE_REGISTER, index >= 0); |
+ LocationOperand(InstructionOperand::Kind operand_kind, |
+ LocationOperand::LocationKind location_kind, |
+ MachineType machine_type, int index) |
+ : InstructionOperand(operand_kind) { |
+ DCHECK_IMPLIES(location_kind == REGISTER, index >= 0); |
DCHECK(IsSupportedMachineType(machine_type)); |
- value_ |= AllocatedKindField::encode(kind); |
+ value_ |= LocationKindField::encode(location_kind); |
value_ |= MachineTypeField::encode(machine_type); |
value_ |= static_cast<int64_t>(index) << IndexField::kShift; |
} |
int index() const { |
- DCHECK(STACK_SLOT == allocated_kind() || |
- DOUBLE_STACK_SLOT == allocated_kind()); |
+ DCHECK(IsStackSlot() || IsDoubleStackSlot()); |
return static_cast<int64_t>(value_) >> IndexField::kShift; |
} |
Register GetRegister() const { |
- DCHECK(REGISTER == allocated_kind() || DOUBLE_REGISTER == allocated_kind()); |
+ DCHECK(IsRegister()); |
return Register::from_code(static_cast<int64_t>(value_) >> |
IndexField::kShift); |
} |
DoubleRegister GetDoubleRegister() const { |
- DCHECK(REGISTER == allocated_kind() || DOUBLE_REGISTER == allocated_kind()); |
+ DCHECK(IsDoubleRegister()); |
return DoubleRegister::from_code(static_cast<int64_t>(value_) >> |
IndexField::kShift); |
} |
- AllocatedKind allocated_kind() const { |
- return AllocatedKindField::decode(value_); |
+ LocationKind location_kind() const { |
+ return LocationKindField::decode(value_); |
} |
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) { |
@@ -417,71 +406,98 @@ class AllocatedOperand : public InstructionOperand { |
} |
} |
- INSTRUCTION_OPERAND_CASTS(AllocatedOperand, ALLOCATED); |
+ static LocationOperand* cast(InstructionOperand* op) { |
+ DCHECK(ALLOCATED == op->kind() || EXPLICIT == op->kind()); |
+ return static_cast<LocationOperand*>(op); |
+ } |
+ |
+ static const LocationOperand* cast(const InstructionOperand* op) { |
+ DCHECK(ALLOCATED == op->kind() || EXPLICIT == op->kind()); |
+ return static_cast<const LocationOperand*>(op); |
+ } |
+ |
+ static LocationOperand cast(const InstructionOperand& op) { |
+ DCHECK(ALLOCATED == op.kind() || EXPLICIT == op.kind()); |
+ return *static_cast<const LocationOperand*>(&op); |
+ } |
STATIC_ASSERT(KindField::kSize == 3); |
- class AllocatedKindField : public BitField64<AllocatedKind, 3, 2> {}; |
+ class LocationKindField : public BitField64<LocationKind, 3, 2> {}; |
class MachineTypeField : public BitField64<MachineType, 5, 16> {}; |
class IndexField : public BitField64<int32_t, 35, 29> {}; |
}; |
+class ExplicitOperand : public LocationOperand { |
+ public: |
+ ExplicitOperand(LocationKind kind, MachineType machine_type, int index) |
+ : LocationOperand(EXPLICIT, kind, machine_type, index) {} |
+ |
+ static ExplicitOperand* New(Zone* zone, LocationKind kind, |
+ MachineType machine_type, int index) { |
+ return InstructionOperand::New(zone, |
+ ExplicitOperand(kind, machine_type, index)); |
+ } |
+ |
+ INSTRUCTION_OPERAND_CASTS(ExplicitOperand, EXPLICIT); |
+}; |
+ |
+ |
+class AllocatedOperand : public LocationOperand { |
+ public: |
+ AllocatedOperand(LocationKind kind, MachineType machine_type, int index) |
+ : LocationOperand(ALLOCATED, kind, machine_type, index) {} |
+ |
+ static AllocatedOperand* New(Zone* zone, LocationKind kind, |
+ MachineType machine_type, int index) { |
+ return InstructionOperand::New(zone, |
+ AllocatedOperand(kind, machine_type, index)); |
+ } |
+ |
+ INSTRUCTION_OPERAND_CASTS(AllocatedOperand, ALLOCATED); |
+}; |
+ |
+ |
#undef INSTRUCTION_OPERAND_CASTS |
-#define ALLOCATED_OPERAND_LIST(V) \ |
- V(StackSlot, STACK_SLOT) \ |
- V(DoubleStackSlot, DOUBLE_STACK_SLOT) \ |
- V(Register, REGISTER) \ |
- V(DoubleRegister, DOUBLE_REGISTER) |
- |
- |
-#define ALLOCATED_OPERAND_IS(SubKind, kOperandKind) \ |
- bool InstructionOperand::Is##SubKind() const { \ |
- return IsAllocated() && \ |
- AllocatedOperand::cast(this)->allocated_kind() == \ |
- AllocatedOperand::kOperandKind; \ |
- } |
-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(MachineType machine_type, int index) \ |
- : AllocatedOperand(kOperandKind, machine_type, 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) { \ |
- DCHECK_EQ(kOperandKind, AllocatedOperand::cast(op)->allocated_kind()); \ |
- return reinterpret_cast<SubKind##Operand*>(op); \ |
- } \ |
- \ |
- static const SubKind##Operand* cast(const InstructionOperand* op) { \ |
- DCHECK_EQ(kOperandKind, AllocatedOperand::cast(op)->allocated_kind()); \ |
- return reinterpret_cast<const SubKind##Operand*>(op); \ |
- } \ |
- \ |
- static SubKind##Operand cast(const InstructionOperand& op) { \ |
- DCHECK_EQ(kOperandKind, AllocatedOperand::cast(op).allocated_kind()); \ |
- return *static_cast<const SubKind##Operand*>(&op); \ |
- } \ |
- }; |
-ALLOCATED_OPERAND_LIST(ALLOCATED_OPERAND_CLASS) |
-#undef ALLOCATED_OPERAND_CLASS |
+bool InstructionOperand::IsRegister() const { |
+ return (IsAllocated() || IsExplicit()) && |
+ LocationOperand::cast(this)->location_kind() == |
+ LocationOperand::REGISTER && |
+ !IsFloatingPoint(LocationOperand::cast(this)->machine_type()); |
+} |
+bool InstructionOperand::IsDoubleRegister() const { |
+ return (IsAllocated() || IsExplicit()) && |
+ LocationOperand::cast(this)->location_kind() == |
+ LocationOperand::REGISTER && |
+ IsFloatingPoint(LocationOperand::cast(this)->machine_type()); |
+} |
+ |
+bool InstructionOperand::IsStackSlot() const { |
+ return (IsAllocated() || IsExplicit()) && |
+ LocationOperand::cast(this)->location_kind() == |
+ LocationOperand::STACK_SLOT && |
+ !IsFloatingPoint(LocationOperand::cast(this)->machine_type()); |
+} |
+ |
+bool InstructionOperand::IsDoubleStackSlot() const { |
+ return (IsAllocated() || IsExplicit()) && |
+ LocationOperand::cast(this)->location_kind() == |
+ LocationOperand::STACK_SLOT && |
+ IsFloatingPoint(LocationOperand::cast(this)->machine_type()); |
+} |
-uint64_t InstructionOperand::GetValueModuloType() const { |
- if (IsAllocated()) { |
+uint64_t InstructionOperand::GetValueCanonicalizeType() const { |
+ if (IsAllocated() || IsExplicit()) { |
// TODO(dcarney): put machine type last and mask. |
- return AllocatedOperand::MachineTypeField::update(this->value_, kMachNone); |
+ MachineType canonicalized_machine_type = |
+ IsFloatingPoint(LocationOperand::cast(this)->machine_type()) |
+ ? kMachFloat64 |
+ : kMachNone; |
+ return LocationOperand::MachineTypeField::update( |
+ this->value_, canonicalized_machine_type); |
} |
return this->value_; |
} |
@@ -491,7 +507,7 @@ uint64_t InstructionOperand::GetValueModuloType() const { |
struct CompareOperandModuloType { |
bool operator()(const InstructionOperand& a, |
const InstructionOperand& b) const { |
- return a.CompareModuloType(b); |
+ return a.CompareCanonicalizeType(b); |
} |
}; |
@@ -523,14 +539,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().EqualsModuloType(operand); |
+ return !IsEliminated() && source().EqualsCanonicalizeType(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_.EqualsModuloType(destination_); |
+ return IsEliminated() || source_.EqualsCanonicalizeType(destination_); |
} |
// We clear both operands to indicate move that's been eliminated. |