summaryrefslogtreecommitdiff
path: root/deps/v8/src/compiler/instruction.h
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/compiler/instruction.h')
-rw-r--r--deps/v8/src/compiler/instruction.h223
1 files changed, 158 insertions, 65 deletions
diff --git a/deps/v8/src/compiler/instruction.h b/deps/v8/src/compiler/instruction.h
index 7ab2b90778..8a6a0ae92a 100644
--- a/deps/v8/src/compiler/instruction.h
+++ b/deps/v8/src/compiler/instruction.h
@@ -23,8 +23,10 @@ namespace v8 {
namespace internal {
namespace compiler {
+// Forward declarations.
class Schedule;
+
class InstructionOperand {
public:
static const int kInvalidVirtualRegister = -1;
@@ -62,6 +64,7 @@ class InstructionOperand {
INSTRUCTION_OPERAND_PREDICATE(Allocated, ALLOCATED)
#undef INSTRUCTION_OPERAND_PREDICATE
+ inline bool IsAnyRegister() const;
inline bool IsRegister() const;
inline bool IsDoubleRegister() const;
inline bool IsStackSlot() const;
@@ -94,6 +97,9 @@ class InstructionOperand {
return this->GetCanonicalizedValue() < that.GetCanonicalizedValue();
}
+ void Print(const RegisterConfiguration* config) const;
+ void Print() const;
+
protected:
explicit InstructionOperand(Kind kind) : value_(KindField::encode(kind)) {}
@@ -105,6 +111,9 @@ class InstructionOperand {
};
+typedef ZoneVector<InstructionOperand> InstructionOperandVector;
+
+
struct PrintableInstructionOperand {
const RegisterConfiguration* register_configuration_;
InstructionOperand op_;
@@ -192,6 +201,12 @@ class UnallocatedOperand : public InstructionOperand {
value_ |= LifetimeField::encode(lifetime);
}
+ UnallocatedOperand(int reg_id, int slot_id, int virtual_register)
+ : UnallocatedOperand(FIXED_REGISTER, reg_id, virtual_register) {
+ value_ |= HasSecondaryStorageField::encode(true);
+ value_ |= SecondaryStorageField::encode(slot_id);
+ }
+
// Predicates for the operand policy.
bool HasAnyPolicy() const {
return basic_policy() == EXTENDED_POLICY && extended_policy() == ANY;
@@ -222,6 +237,15 @@ class UnallocatedOperand : public InstructionOperand {
return basic_policy() == EXTENDED_POLICY &&
extended_policy() == FIXED_DOUBLE_REGISTER;
}
+ bool HasSecondaryStorage() const {
+ return basic_policy() == EXTENDED_POLICY &&
+ extended_policy() == FIXED_REGISTER &&
+ HasSecondaryStorageField::decode(value_);
+ }
+ int GetSecondaryStorage() const {
+ DCHECK(HasSecondaryStorage());
+ return SecondaryStorageField::decode(value_);
+ }
// [basic_policy]: Distinguish between FIXED_SLOT and all other policies.
BasicPolicy basic_policy() const {
@@ -301,7 +325,9 @@ class UnallocatedOperand : public InstructionOperand {
// BitFields specific to BasicPolicy::EXTENDED_POLICY.
class ExtendedPolicyField : public BitField64<ExtendedPolicy, 36, 3> {};
class LifetimeField : public BitField64<Lifetime, 39, 1> {};
- class FixedRegisterField : public BitField64<int, 40, 6> {};
+ class HasSecondaryStorageField : public BitField64<bool, 40, 1> {};
+ class FixedRegisterField : public BitField64<int, 41, 6> {};
+ class SecondaryStorageField : public BitField64<int, 47, 3> {};
private:
explicit UnallocatedOperand(int virtual_register)
@@ -375,12 +401,12 @@ class LocationOperand : public InstructionOperand {
LocationOperand(InstructionOperand::Kind operand_kind,
LocationOperand::LocationKind location_kind,
- MachineType machine_type, int index)
+ MachineRepresentation rep, int index)
: InstructionOperand(operand_kind) {
DCHECK_IMPLIES(location_kind == REGISTER, index >= 0);
- DCHECK(IsSupportedMachineType(machine_type));
+ DCHECK(IsSupportedRepresentation(rep));
value_ |= LocationKindField::encode(location_kind);
- value_ |= MachineTypeField::encode(machine_type);
+ value_ |= RepresentationField::encode(rep);
value_ |= static_cast<int64_t>(index) << IndexField::kShift;
}
@@ -405,20 +431,26 @@ class LocationOperand : public InstructionOperand {
return LocationKindField::decode(value_);
}
- MachineType machine_type() const { return MachineTypeField::decode(value_); }
+ MachineRepresentation representation() const {
+ return RepresentationField::decode(value_);
+ }
- 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:
+ static bool IsSupportedRepresentation(MachineRepresentation rep) {
+ switch (rep) {
+ case MachineRepresentation::kWord32:
+ case MachineRepresentation::kWord64:
+ case MachineRepresentation::kFloat32:
+ case MachineRepresentation::kFloat64:
+ case MachineRepresentation::kTagged:
return true;
- default:
+ case MachineRepresentation::kBit:
+ case MachineRepresentation::kWord8:
+ case MachineRepresentation::kWord16:
+ case MachineRepresentation::kNone:
return false;
}
+ UNREACHABLE();
+ return false;
}
static LocationOperand* cast(InstructionOperand* op) {
@@ -438,19 +470,18 @@ class LocationOperand : public InstructionOperand {
STATIC_ASSERT(KindField::kSize == 3);
class LocationKindField : public BitField64<LocationKind, 3, 2> {};
- class MachineTypeField : public BitField64<MachineType, 5, 16> {};
+ class RepresentationField : public BitField64<MachineRepresentation, 5, 8> {};
class IndexField : public BitField64<int32_t, 35, 29> {};
};
class ExplicitOperand : public LocationOperand {
public:
- ExplicitOperand(LocationKind kind, MachineType machine_type, int index);
+ ExplicitOperand(LocationKind kind, MachineRepresentation rep, int index);
static ExplicitOperand* New(Zone* zone, LocationKind kind,
- MachineType machine_type, int index) {
- return InstructionOperand::New(zone,
- ExplicitOperand(kind, machine_type, index));
+ MachineRepresentation rep, int index) {
+ return InstructionOperand::New(zone, ExplicitOperand(kind, rep, index));
}
INSTRUCTION_OPERAND_CASTS(ExplicitOperand, EXPLICIT);
@@ -459,13 +490,12 @@ class ExplicitOperand : public LocationOperand {
class AllocatedOperand : public LocationOperand {
public:
- AllocatedOperand(LocationKind kind, MachineType machine_type, int index)
- : LocationOperand(ALLOCATED, kind, machine_type, index) {}
+ AllocatedOperand(LocationKind kind, MachineRepresentation rep, int index)
+ : LocationOperand(ALLOCATED, kind, rep, index) {}
static AllocatedOperand* New(Zone* zone, LocationKind kind,
- MachineType machine_type, int index) {
- return InstructionOperand::New(zone,
- AllocatedOperand(kind, machine_type, index));
+ MachineRepresentation rep, int index) {
+ return InstructionOperand::New(zone, AllocatedOperand(kind, rep, index));
}
INSTRUCTION_OPERAND_CASTS(AllocatedOperand, ALLOCATED);
@@ -475,44 +505,47 @@ class AllocatedOperand : public LocationOperand {
#undef INSTRUCTION_OPERAND_CASTS
-bool InstructionOperand::IsRegister() const {
+bool InstructionOperand::IsAnyRegister() const {
return (IsAllocated() || IsExplicit()) &&
LocationOperand::cast(this)->location_kind() ==
- LocationOperand::REGISTER &&
- !IsFloatingPoint(LocationOperand::cast(this)->machine_type());
+ LocationOperand::REGISTER;
+}
+
+
+bool InstructionOperand::IsRegister() const {
+ return IsAnyRegister() &&
+ !IsFloatingPoint(LocationOperand::cast(this)->representation());
}
bool InstructionOperand::IsDoubleRegister() const {
- return (IsAllocated() || IsExplicit()) &&
- LocationOperand::cast(this)->location_kind() ==
- LocationOperand::REGISTER &&
- IsFloatingPoint(LocationOperand::cast(this)->machine_type());
+ return IsAnyRegister() &&
+ IsFloatingPoint(LocationOperand::cast(this)->representation());
}
bool InstructionOperand::IsStackSlot() const {
return (IsAllocated() || IsExplicit()) &&
LocationOperand::cast(this)->location_kind() ==
LocationOperand::STACK_SLOT &&
- !IsFloatingPoint(LocationOperand::cast(this)->machine_type());
+ !IsFloatingPoint(LocationOperand::cast(this)->representation());
}
bool InstructionOperand::IsDoubleStackSlot() const {
return (IsAllocated() || IsExplicit()) &&
LocationOperand::cast(this)->location_kind() ==
LocationOperand::STACK_SLOT &&
- IsFloatingPoint(LocationOperand::cast(this)->machine_type());
+ IsFloatingPoint(LocationOperand::cast(this)->representation());
}
uint64_t InstructionOperand::GetCanonicalizedValue() const {
if (IsAllocated() || IsExplicit()) {
// TODO(dcarney): put machine type last and mask.
- MachineType canonicalized_machine_type =
- IsFloatingPoint(LocationOperand::cast(this)->machine_type())
- ? kMachFloat64
- : kMachNone;
+ MachineRepresentation canonicalized_representation =
+ IsFloatingPoint(LocationOperand::cast(this)->representation())
+ ? MachineRepresentation::kFloat64
+ : MachineRepresentation::kNone;
return InstructionOperand::KindField::update(
- LocationOperand::MachineTypeField::update(this->value_,
- canonicalized_machine_type),
+ LocationOperand::RepresentationField::update(
+ this->value_, canonicalized_representation),
LocationOperand::EXPLICIT);
}
return this->value_;
@@ -572,6 +605,9 @@ class MoveOperands final : public ZoneObject {
return source_.IsInvalid();
}
+ void Print(const RegisterConfiguration* config) const;
+ void Print() const;
+
private:
InstructionOperand source_;
InstructionOperand destination_;
@@ -698,7 +734,7 @@ class Instruction final {
// TODO(titzer): make call into a flags.
static Instruction* New(Zone* zone, InstructionCode opcode) {
- return New(zone, opcode, 0, NULL, 0, NULL, 0, NULL);
+ return New(zone, opcode, 0, nullptr, 0, nullptr, 0, nullptr);
}
static Instruction* New(Zone* zone, InstructionCode opcode,
@@ -706,9 +742,9 @@ class Instruction final {
size_t input_count, InstructionOperand* inputs,
size_t temp_count, InstructionOperand* temps) {
DCHECK(opcode >= 0);
- DCHECK(output_count == 0 || outputs != NULL);
- DCHECK(input_count == 0 || inputs != NULL);
- DCHECK(temp_count == 0 || temps != NULL);
+ DCHECK(output_count == 0 || outputs != nullptr);
+ DCHECK(input_count == 0 || inputs != nullptr);
+ DCHECK(temp_count == 0 || temps != nullptr);
size_t total_extra_ops = output_count + input_count + temp_count;
if (total_extra_ops != 0) total_extra_ops--;
int size = static_cast<int>(
@@ -724,7 +760,7 @@ class Instruction final {
}
bool IsCall() const { return IsCallField::decode(bit_field_); }
bool NeedsReferenceMap() const { return IsCall(); }
- bool HasReferenceMap() const { return reference_map_ != NULL; }
+ bool HasReferenceMap() const { return reference_map_ != nullptr; }
bool ClobbersRegisters() const { return IsCall(); }
bool ClobbersTemps() const { return IsCall(); }
@@ -740,7 +776,7 @@ class Instruction final {
void OverwriteWithNop() {
opcode_ = ArchOpcodeField::encode(kArchNop);
bit_field_ = 0;
- reference_map_ = NULL;
+ reference_map_ = nullptr;
}
bool IsNop() const {
@@ -775,6 +811,9 @@ class Instruction final {
ParallelMove* const* parallel_moves() const { return &parallel_moves_[0]; }
ParallelMove** parallel_moves() { return &parallel_moves_[0]; }
+ void Print(const RegisterConfiguration* config) const;
+ void Print() const;
+
private:
explicit Instruction(InstructionCode opcode);
@@ -911,6 +950,59 @@ class Constant final {
};
+std::ostream& operator<<(std::ostream& os, const Constant& constant);
+
+
+// Forward declarations.
+class FrameStateDescriptor;
+
+
+enum class StateValueKind { kPlain, kNested, kDuplicate };
+
+
+class StateValueDescriptor {
+ public:
+ explicit StateValueDescriptor(Zone* zone)
+ : kind_(StateValueKind::kPlain),
+ type_(MachineType::AnyTagged()),
+ id_(0),
+ fields_(zone) {}
+
+ static StateValueDescriptor Plain(Zone* zone, MachineType type) {
+ return StateValueDescriptor(StateValueKind::kPlain, zone, type, 0);
+ }
+ static StateValueDescriptor Recursive(Zone* zone, size_t id) {
+ return StateValueDescriptor(StateValueKind::kNested, zone,
+ MachineType::AnyTagged(), id);
+ }
+ static StateValueDescriptor Duplicate(Zone* zone, size_t id) {
+ return StateValueDescriptor(StateValueKind::kDuplicate, zone,
+ MachineType::AnyTagged(), id);
+ }
+
+ size_t size() { return fields_.size(); }
+ ZoneVector<StateValueDescriptor>& fields() { return fields_; }
+ int IsPlain() { return kind_ == StateValueKind::kPlain; }
+ int IsNested() { return kind_ == StateValueKind::kNested; }
+ int IsDuplicate() { return kind_ == StateValueKind::kDuplicate; }
+ MachineType type() const { return type_; }
+ MachineType GetOperandType(size_t index) const {
+ return fields_[index].type_;
+ }
+ size_t id() const { return id_; }
+
+ private:
+ StateValueDescriptor(StateValueKind kind, Zone* zone, MachineType type,
+ size_t id)
+ : kind_(kind), type_(type), id_(id), fields_(zone) {}
+
+ StateValueKind kind_;
+ MachineType type_;
+ size_t id_;
+ ZoneVector<StateValueDescriptor> fields_;
+};
+
+
class FrameStateDescriptor : public ZoneObject {
public:
FrameStateDescriptor(Zone* zone, FrameStateType type, BailoutId bailout_id,
@@ -929,7 +1021,7 @@ class FrameStateDescriptor : public ZoneObject {
MaybeHandle<SharedFunctionInfo> shared_info() const { return shared_info_; }
FrameStateDescriptor* outer_state() const { return outer_state_; }
bool HasContext() const {
- return type_ == FrameStateType::kJavaScriptFunction;
+ return FrameStateFunctionInfo::IsJSFunctionType(type_);
}
size_t GetSize(OutputFrameStateCombine combine =
@@ -938,8 +1030,10 @@ class FrameStateDescriptor : public ZoneObject {
size_t GetFrameCount() const;
size_t GetJSFrameCount() const;
- MachineType GetType(size_t index) const;
- void SetType(size_t index, MachineType type);
+ MachineType GetType(size_t index) const {
+ return values_.GetOperandType(index);
+ }
+ StateValueDescriptor* GetStateValueDescriptor() { return &values_; }
private:
FrameStateType type_;
@@ -948,12 +1042,13 @@ class FrameStateDescriptor : public ZoneObject {
size_t parameters_count_;
size_t locals_count_;
size_t stack_count_;
- ZoneVector<MachineType> types_;
+ StateValueDescriptor values_;
MaybeHandle<SharedFunctionInfo> const shared_info_;
FrameStateDescriptor* outer_state_;
};
-std::ostream& operator<<(std::ostream& os, const Constant& constant);
+
+typedef ZoneVector<FrameStateDescriptor*> DeoptimizationVector;
class PhiInstruction final : public ZoneObject {
@@ -1066,13 +1161,14 @@ class InstructionBlock final : public ZoneObject {
typedef ZoneDeque<Constant> ConstantDeque;
typedef std::map<int, Constant, std::less<int>,
- zone_allocator<std::pair<int, Constant> > > ConstantMap;
+ zone_allocator<std::pair<const int, Constant> > > ConstantMap;
typedef ZoneDeque<Instruction*> InstructionDeque;
typedef ZoneDeque<ReferenceMap*> ReferenceMapDeque;
-typedef ZoneVector<FrameStateDescriptor*> DeoptimizationVector;
typedef ZoneVector<InstructionBlock*> InstructionBlocks;
+
+// Forward declarations.
struct PrintableInstructionSequence;
@@ -1114,23 +1210,18 @@ class InstructionSequence final : public ZoneObject {
InstructionBlock* GetInstructionBlock(int instruction_index) const;
- static MachineType DefaultRepresentation() {
- return kPointerSize == 8 ? kRepWord64 : kRepWord32;
+ static MachineRepresentation DefaultRepresentation() {
+ return MachineType::PointerRepresentation();
}
- MachineType GetRepresentation(int virtual_register) const;
- void MarkAsRepresentation(MachineType machine_type, int virtual_register);
+ MachineRepresentation GetRepresentation(int virtual_register) const;
+ void MarkAsRepresentation(MachineRepresentation rep, int virtual_register);
bool IsReference(int virtual_register) const {
- return GetRepresentation(virtual_register) == kRepTagged;
+ return GetRepresentation(virtual_register) ==
+ MachineRepresentation::kTagged;
}
bool IsFloat(int virtual_register) const {
- switch (GetRepresentation(virtual_register)) {
- case kRepFloat32:
- case kRepFloat64:
- return true;
- default:
- return false;
- }
+ return IsFloatingPoint(GetRepresentation(virtual_register));
}
Instruction* GetBlockStart(RpoNumber rpo) const;
@@ -1229,6 +1320,8 @@ class InstructionSequence final : public ZoneObject {
}
return false;
}
+ void Print(const RegisterConfiguration* config) const;
+ void Print() const;
private:
friend std::ostream& operator<<(std::ostream& os,
@@ -1246,7 +1339,7 @@ class InstructionSequence final : public ZoneObject {
InstructionDeque instructions_;
int next_virtual_register_;
ReferenceMapDeque reference_maps_;
- ZoneVector<MachineType> representations_;
+ ZoneVector<MachineRepresentation> representations_;
DeoptimizationVector deoptimization_entries_;
DISALLOW_COPY_AND_ASSIGN(InstructionSequence);