| Index: src/compiler/common-operator.cc
|
| diff --git a/src/compiler/common-operator.cc b/src/compiler/common-operator.cc
|
| index a9ff0bd778fc086917c8019d5b98d238481d0308..d45c6b484d6d1af05dd094e7e3202e9edd6d0760 100644
|
| --- a/src/compiler/common-operator.cc
|
| +++ b/src/compiler/common-operator.cc
|
| @@ -7,6 +7,7 @@
|
| #include "src/assembler.h"
|
| #include "src/base/lazy-instance.h"
|
| #include "src/compiler/linkage.h"
|
| +#include "src/compiler/node.h"
|
| #include "src/compiler/opcodes.h"
|
| #include "src/compiler/operator.h"
|
| #include "src/handles-inl.h"
|
| @@ -171,6 +172,106 @@ std::ostream& operator<<(std::ostream& os,
|
| return os << p.value() << "|" << p.rmode() << "|" << p.type();
|
| }
|
|
|
| +SparseInputMask::InputIterator::InputIterator(
|
| + SparseInputMask::BitMaskType bit_mask, Node* parent)
|
| + : bit_mask_(bit_mask), parent_(parent), real_index_(0) {
|
| +#if DEBUG
|
| + if (bit_mask_ != SparseInputMask::kDenseBitMask) {
|
| + DCHECK_EQ(base::bits::CountPopulation(bit_mask_) -
|
| + base::bits::CountPopulation(kEndMarker),
|
| + parent->InputCount());
|
| + }
|
| +#endif
|
| +}
|
| +
|
| +void SparseInputMask::InputIterator::Advance() {
|
| + DCHECK(!IsEnd());
|
| +
|
| + if (IsReal()) {
|
| + ++real_index_;
|
| + }
|
| + bit_mask_ >>= 1;
|
| +}
|
| +
|
| +Node* SparseInputMask::InputIterator::GetReal() const {
|
| + DCHECK(IsReal());
|
| + return parent_->InputAt(real_index_);
|
| +}
|
| +
|
| +bool SparseInputMask::InputIterator::IsReal() const {
|
| + return bit_mask_ == SparseInputMask::kDenseBitMask ||
|
| + (bit_mask_ & kEntryMask);
|
| +}
|
| +
|
| +bool SparseInputMask::InputIterator::IsEnd() const {
|
| + return (bit_mask_ == kEndMarker) ||
|
| + (bit_mask_ == SparseInputMask::kDenseBitMask &&
|
| + real_index_ >= parent_->InputCount());
|
| +}
|
| +
|
| +int SparseInputMask::CountReal() const {
|
| + DCHECK(!IsDense());
|
| + return base::bits::CountPopulation(bit_mask_) -
|
| + base::bits::CountPopulation(kEndMarker);
|
| +}
|
| +
|
| +SparseInputMask::InputIterator SparseInputMask::IterateOverInputs(Node* node) {
|
| + DCHECK(IsDense() || CountReal() == node->InputCount());
|
| + return InputIterator(bit_mask_, node);
|
| +}
|
| +
|
| +bool operator==(SparseInputMask const& lhs, SparseInputMask const& rhs) {
|
| + return lhs.mask() == rhs.mask();
|
| +}
|
| +
|
| +bool operator!=(SparseInputMask const& lhs, SparseInputMask const& rhs) {
|
| + return !(lhs == rhs);
|
| +}
|
| +
|
| +size_t hash_value(SparseInputMask const& p) {
|
| + return base::hash_value(p.mask());
|
| +}
|
| +
|
| +std::ostream& operator<<(std::ostream& os, SparseInputMask const& p) {
|
| + if (p.IsDense()) {
|
| + return os << "dense";
|
| + } else {
|
| + SparseInputMask::BitMaskType mask = p.mask();
|
| + DCHECK_NE(mask, SparseInputMask::kDenseBitMask);
|
| +
|
| + os << "sparse:";
|
| +
|
| + while (mask != SparseInputMask::kEndMarker) {
|
| + if (mask & SparseInputMask::kEntryMask) {
|
| + os << "^";
|
| + } else {
|
| + os << ".";
|
| + }
|
| + mask >>= 1;
|
| + }
|
| + return os;
|
| + }
|
| +}
|
| +
|
| +bool operator==(TypedStateValueInfo const& lhs,
|
| + TypedStateValueInfo const& rhs) {
|
| + return lhs.machine_types() == rhs.machine_types() &&
|
| + lhs.sparse_input_mask() == rhs.sparse_input_mask();
|
| +}
|
| +
|
| +bool operator!=(TypedStateValueInfo const& lhs,
|
| + TypedStateValueInfo const& rhs) {
|
| + return !(lhs == rhs);
|
| +}
|
| +
|
| +size_t hash_value(TypedStateValueInfo const& p) {
|
| + return base::hash_combine(p.machine_types(), p.sparse_input_mask());
|
| +}
|
| +
|
| +std::ostream& operator<<(std::ostream& os, TypedStateValueInfo const& p) {
|
| + return os << p.machine_types() << "|" << p.sparse_input_mask();
|
| +}
|
| +
|
| size_t hash_value(RegionObservability observability) {
|
| return static_cast<size_t>(observability);
|
| }
|
| @@ -235,9 +336,23 @@ OsrGuardType OsrGuardTypeOf(Operator const* op) {
|
| return OpParameter<OsrGuardType>(op);
|
| }
|
|
|
| +SparseInputMask SparseInputMaskOf(Operator const* op) {
|
| + DCHECK(op->opcode() == IrOpcode::kStateValues ||
|
| + op->opcode() == IrOpcode::kTypedStateValues);
|
| +
|
| + if (op->opcode() == IrOpcode::kTypedStateValues) {
|
| + return OpParameter<TypedStateValueInfo>(op).sparse_input_mask();
|
| + }
|
| + return OpParameter<SparseInputMask>(op);
|
| +}
|
| +
|
| ZoneVector<MachineType> const* MachineTypesOf(Operator const* op) {
|
| DCHECK(op->opcode() == IrOpcode::kTypedObjectState ||
|
| op->opcode() == IrOpcode::kTypedStateValues);
|
| +
|
| + if (op->opcode() == IrOpcode::kTypedStateValues) {
|
| + return OpParameter<TypedStateValueInfo>(op).machine_types();
|
| + }
|
| return OpParameter<const ZoneVector<MachineType>*>(op);
|
| }
|
|
|
| @@ -588,13 +703,14 @@ struct CommonOperatorGlobalCache final {
|
| #undef CACHED_PROJECTION
|
|
|
| template <int kInputCount>
|
| - struct StateValuesOperator final : public Operator {
|
| + struct StateValuesOperator final : public Operator1<SparseInputMask> {
|
| StateValuesOperator()
|
| - : Operator( // --
|
| - IrOpcode::kStateValues, // opcode
|
| - Operator::kPure, // flags
|
| - "StateValues", // name
|
| - kInputCount, 0, 0, 1, 0, 0) {} // counts
|
| + : Operator1<SparseInputMask>( // --
|
| + IrOpcode::kStateValues, // opcode
|
| + Operator::kPure, // flags
|
| + "StateValues", // name
|
| + kInputCount, 0, 0, 1, 0, 0, // counts
|
| + SparseInputMask::Dense()) {} // parameter
|
| };
|
| #define CACHED_STATE_VALUES(input_count) \
|
| StateValuesOperator<input_count> kStateValues##input_count##Operator;
|
| @@ -1000,30 +1116,44 @@ const Operator* CommonOperatorBuilder::BeginRegion(
|
| return nullptr;
|
| }
|
|
|
| -const Operator* CommonOperatorBuilder::StateValues(int arguments) {
|
| - switch (arguments) {
|
| +const Operator* CommonOperatorBuilder::StateValues(int arguments,
|
| + SparseInputMask bitmask) {
|
| + if (bitmask.IsDense()) {
|
| + switch (arguments) {
|
| #define CACHED_STATE_VALUES(arguments) \
|
| case arguments: \
|
| return &cache_.kStateValues##arguments##Operator;
|
| - CACHED_STATE_VALUES_LIST(CACHED_STATE_VALUES)
|
| + CACHED_STATE_VALUES_LIST(CACHED_STATE_VALUES)
|
| #undef CACHED_STATE_VALUES
|
| - default:
|
| - break;
|
| + default:
|
| + break;
|
| + }
|
| }
|
| +
|
| +#if DEBUG
|
| + DCHECK(bitmask.IsDense() || bitmask.CountReal() == arguments);
|
| +#endif
|
| +
|
| // Uncached.
|
| - return new (zone()) Operator( // --
|
| - IrOpcode::kStateValues, Operator::kPure, // opcode
|
| - "StateValues", // name
|
| - arguments, 0, 0, 1, 0, 0); // counts
|
| + return new (zone()) Operator1<SparseInputMask>( // --
|
| + IrOpcode::kStateValues, Operator::kPure, // opcode
|
| + "StateValues", // name
|
| + arguments, 0, 0, 1, 0, 0, // counts
|
| + bitmask); // parameter
|
| }
|
|
|
| const Operator* CommonOperatorBuilder::TypedStateValues(
|
| - const ZoneVector<MachineType>* types) {
|
| - return new (zone()) Operator1<const ZoneVector<MachineType>*>( // --
|
| - IrOpcode::kTypedStateValues, Operator::kPure, // opcode
|
| - "TypedStateValues", // name
|
| - static_cast<int>(types->size()), 0, 0, 1, 0, 0, // counts
|
| - types); // parameter
|
| + const ZoneVector<MachineType>* types, SparseInputMask bitmask) {
|
| +#if DEBUG
|
| + DCHECK(bitmask.IsDense() ||
|
| + bitmask.CountReal() == static_cast<int>(types->size()));
|
| +#endif
|
| +
|
| + return new (zone()) Operator1<TypedStateValueInfo>( // --
|
| + IrOpcode::kTypedStateValues, Operator::kPure, // opcode
|
| + "TypedStateValues", // name
|
| + static_cast<int>(types->size()), 0, 0, 1, 0, 0, // counts
|
| + TypedStateValueInfo(types, bitmask)); // parameters
|
| }
|
|
|
| const Operator* CommonOperatorBuilder::ObjectState(int pointer_slots) {
|
|
|