[maglev] Remove input_count from Node constructors
Change the NodeBase bitfield to be out-of-line, and initialised by NodeBase::Allocate. This means that we don't have to thread the input_count through the Derived constructor just to pass it back into the NodeBase constructor, and so we can remove those arguments (plus the opcode ones while we're at it). Bug: v8:7700 Change-Id: I0c96db8cdd05ef106b3cfeb31c5e0d4770d13cc9 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3553103 Reviewed-by: Toon Verwaest <verwaest@chromium.org> Commit-Queue: Leszek Swirski <leszeks@chromium.org> Cr-Commit-Position: refs/heads/main@{#79627}
This commit is contained in:
parent
1d96641ff7
commit
2ee36e4cf5
@ -318,7 +318,17 @@ NODE_BASE_LIST(DEF_OPCODE_OF)
|
|||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
class NodeBase : public ZoneObject {
|
class NodeBase : public ZoneObject {
|
||||||
|
private:
|
||||||
|
// Bitfield specification.
|
||||||
|
using OpcodeField = base::BitField<Opcode, 0, 6>;
|
||||||
|
STATIC_ASSERT(OpcodeField::is_valid(kLastOpcode));
|
||||||
|
using InputCountField = OpcodeField::Next<uint16_t, 16>;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
// Subclasses may use the remaining bitfield bits.
|
||||||
|
template <class T, int size>
|
||||||
|
using NextBitField = InputCountField::Next<T, size>;
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
static constexpr Opcode opcode_of = detail::opcode_of_helper<T>::value;
|
static constexpr Opcode opcode_of = detail::opcode_of_helper<T>::value;
|
||||||
|
|
||||||
@ -350,7 +360,7 @@ class NodeBase : public ZoneObject {
|
|||||||
static constexpr OpProperties kProperties = OpProperties::Pure();
|
static constexpr OpProperties kProperties = OpProperties::Pure();
|
||||||
inline const OpProperties& properties() const;
|
inline const OpProperties& properties() const;
|
||||||
|
|
||||||
constexpr Opcode opcode() const { return OpcodeField::decode(bit_field_); }
|
constexpr Opcode opcode() const { return OpcodeField::decode(bit_field()); }
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
constexpr bool Is() const;
|
constexpr bool Is() const;
|
||||||
@ -372,7 +382,7 @@ class NodeBase : public ZoneObject {
|
|||||||
|
|
||||||
constexpr bool has_inputs() const { return input_count() > 0; }
|
constexpr bool has_inputs() const { return input_count() > 0; }
|
||||||
constexpr uint16_t input_count() const {
|
constexpr uint16_t input_count() const {
|
||||||
return InputCountField::decode(bit_field_);
|
return InputCountField::decode(bit_field());
|
||||||
}
|
}
|
||||||
|
|
||||||
Input& input(int index) { return *input_address(index); }
|
Input& input(int index) { return *input_address(index); }
|
||||||
@ -427,44 +437,23 @@ class NodeBase : public ZoneObject {
|
|||||||
void Print(std::ostream& os, MaglevGraphLabeller*) const;
|
void Print(std::ostream& os, MaglevGraphLabeller*) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
NodeBase(Opcode opcode, size_t input_count)
|
NodeBase() : num_temporaries_needed_(0) {}
|
||||||
: bit_field_(OpcodeField::encode(opcode) |
|
|
||||||
InputCountField::encode(input_count)) {}
|
|
||||||
|
|
||||||
Input* input_address(int index) {
|
Input* input_address(int index) {
|
||||||
DCHECK_LT(index, input_count());
|
DCHECK_LT(index, input_count());
|
||||||
return reinterpret_cast<Input*>(this) - (index + 1);
|
return reinterpret_cast<Input*>(bit_field_address()) - (index + 1);
|
||||||
}
|
}
|
||||||
const Input* input_address(int index) const {
|
const Input* input_address(int index) const {
|
||||||
DCHECK_LT(index, input_count());
|
DCHECK_LT(index, input_count());
|
||||||
return reinterpret_cast<const Input*>(this) - (index + 1);
|
return reinterpret_cast<const Input*>(bit_field_address()) - (index + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_input(int index, ValueNode* input) {
|
void set_input(int index, ValueNode* input) {
|
||||||
new (input_address(index)) Input(input);
|
new (input_address(index)) Input(input);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
uint32_t bit_field() const { return *bit_field_address(); }
|
||||||
template <class Derived, typename... Args>
|
void set_bit_field(uint32_t value) { *bit_field_address() = value; }
|
||||||
static Derived* Allocate(Zone* zone, size_t input_count, Args&&... args) {
|
|
||||||
const size_t size = sizeof(Derived) + input_count * sizeof(Input);
|
|
||||||
intptr_t raw_buffer =
|
|
||||||
reinterpret_cast<intptr_t>(zone->Allocate<NodeWithInlineInputs>(size));
|
|
||||||
void* node_buffer =
|
|
||||||
reinterpret_cast<void*>(raw_buffer + input_count * sizeof(Input));
|
|
||||||
Derived* node =
|
|
||||||
new (node_buffer) Derived(input_count, std::forward<Args>(args)...);
|
|
||||||
return node;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// Bitfield specification.
|
|
||||||
using OpcodeField = base::BitField<Opcode, 0, 6>;
|
|
||||||
STATIC_ASSERT(OpcodeField::is_valid(kLastOpcode));
|
|
||||||
using InputCountField = OpcodeField::Next<uint16_t, 16>;
|
|
||||||
// Subclasses may use the remaining bits.
|
|
||||||
template <class T, int size>
|
|
||||||
using NextBitField = InputCountField::Next<T, size>;
|
|
||||||
|
|
||||||
void set_temporaries_needed(int value) {
|
void set_temporaries_needed(int value) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
@ -474,13 +463,38 @@ class NodeBase : public ZoneObject {
|
|||||||
num_temporaries_needed_ = value;
|
num_temporaries_needed_ = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t bit_field_;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
template <class Derived, typename... Args>
|
||||||
|
static Derived* Allocate(Zone* zone, size_t input_count, Args&&... args) {
|
||||||
|
const size_t size =
|
||||||
|
sizeof(Derived) + sizeof(uint32_t) + input_count * sizeof(Input);
|
||||||
|
intptr_t raw_buffer =
|
||||||
|
reinterpret_cast<intptr_t>(zone->Allocate<NodeWithInlineInputs>(size));
|
||||||
|
void* node_buffer = reinterpret_cast<void*>(raw_buffer + sizeof(uint32_t) +
|
||||||
|
input_count * sizeof(Input));
|
||||||
|
|
||||||
|
*reinterpret_cast<uint32_t*>(reinterpret_cast<char*>(node_buffer) -
|
||||||
|
sizeof(uint32_t)) =
|
||||||
|
OpcodeField::encode(opcode_of<Derived>) |
|
||||||
|
InputCountField::encode(input_count);
|
||||||
|
|
||||||
|
Derived* node = new (node_buffer) Derived(std::forward<Args>(args)...);
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t* bit_field_address() {
|
||||||
|
return reinterpret_cast<uint32_t*>(reinterpret_cast<char*>(this) -
|
||||||
|
sizeof(uint32_t));
|
||||||
|
}
|
||||||
|
const uint32_t* bit_field_address() const {
|
||||||
|
return reinterpret_cast<const uint32_t*>(
|
||||||
|
reinterpret_cast<const char*>(this) - sizeof(uint32_t));
|
||||||
|
}
|
||||||
|
|
||||||
NodeIdT id_ = kInvalidNodeId;
|
NodeIdT id_ = kInvalidNodeId;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
int num_temporaries_needed_ = 0;
|
int num_temporaries_needed_;
|
||||||
RegList temporaries_;
|
RegList temporaries_;
|
||||||
};
|
};
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
@ -491,7 +505,6 @@ class NodeBase : public ZoneObject {
|
|||||||
} kTemporariesState = kUnset;
|
} kTemporariesState = kUnset;
|
||||||
#endif // DEBUG
|
#endif // DEBUG
|
||||||
|
|
||||||
NodeBase() = delete;
|
|
||||||
NodeBase(const NodeBase&) = delete;
|
NodeBase(const NodeBase&) = delete;
|
||||||
NodeBase(NodeBase&&) = delete;
|
NodeBase(NodeBase&&) = delete;
|
||||||
NodeBase& operator=(const NodeBase&) = delete;
|
NodeBase& operator=(const NodeBase&) = delete;
|
||||||
@ -524,10 +537,6 @@ class Node : public NodeBase {
|
|||||||
|
|
||||||
inline ValueLocation& result();
|
inline ValueLocation& result();
|
||||||
|
|
||||||
protected:
|
|
||||||
explicit Node(Opcode opcode, size_t input_count)
|
|
||||||
: NodeBase(opcode, input_count) {}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Node** next() { return &next_; }
|
Node** next() { return &next_; }
|
||||||
Node* next_ = nullptr;
|
Node* next_ = nullptr;
|
||||||
@ -626,9 +635,8 @@ class ValueNode : public Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit ValueNode(Opcode opcode, size_t input_count)
|
ValueNode()
|
||||||
: Node(opcode, input_count),
|
: last_uses_next_use_id_(&next_use_)
|
||||||
last_uses_next_use_id_(&next_use_)
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
,
|
,
|
||||||
state_(kLastUse)
|
state_(kLastUse)
|
||||||
@ -666,11 +674,8 @@ class NodeT : public Node {
|
|||||||
STATIC_ASSERT(!IsValueNode(opcode_of<Derived>));
|
STATIC_ASSERT(!IsValueNode(opcode_of<Derived>));
|
||||||
|
|
||||||
public:
|
public:
|
||||||
constexpr Opcode opcode() const { return NodeBase::opcode_of<Derived>; }
|
constexpr Opcode opcode() const { return opcode_of<Derived>; }
|
||||||
const OpProperties& properties() const { return Derived::kProperties; }
|
const OpProperties& properties() const { return Derived::kProperties; }
|
||||||
|
|
||||||
protected:
|
|
||||||
explicit NodeT(size_t input_count) : Node(opcode_of<Derived>, input_count) {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <size_t InputCount, class Derived>
|
template <size_t InputCount, class Derived>
|
||||||
@ -686,10 +691,7 @@ class FixedInputNodeT : public NodeT<Derived> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit FixedInputNodeT(size_t input_count) : NodeT<Derived>(kInputCount) {
|
FixedInputNodeT() { DCHECK_EQ(NodeBase::input_count(), kInputCount); }
|
||||||
DCHECK_EQ(input_count, kInputCount);
|
|
||||||
USE(input_count);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class Derived>
|
template <class Derived>
|
||||||
@ -697,12 +699,8 @@ class ValueNodeT : public ValueNode {
|
|||||||
STATIC_ASSERT(IsValueNode(opcode_of<Derived>));
|
STATIC_ASSERT(IsValueNode(opcode_of<Derived>));
|
||||||
|
|
||||||
public:
|
public:
|
||||||
constexpr Opcode opcode() const { return NodeBase::opcode_of<Derived>; }
|
constexpr Opcode opcode() const { return opcode_of<Derived>; }
|
||||||
const OpProperties& properties() const { return Derived::kProperties; }
|
const OpProperties& properties() const { return Derived::kProperties; }
|
||||||
|
|
||||||
protected:
|
|
||||||
explicit ValueNodeT(size_t input_count)
|
|
||||||
: ValueNode(opcode_of<Derived>, input_count) {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <size_t InputCount, class Derived>
|
template <size_t InputCount, class Derived>
|
||||||
@ -718,11 +716,7 @@ class FixedInputValueNodeT : public ValueNodeT<Derived> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit FixedInputValueNodeT(size_t input_count)
|
FixedInputValueNodeT() { DCHECK_EQ(NodeBase::input_count(), kInputCount); }
|
||||||
: ValueNodeT<Derived>(InputCount) {
|
|
||||||
DCHECK_EQ(input_count, InputCount);
|
|
||||||
USE(input_count);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class Derived, Operation kOperation>
|
template <class Derived, Operation kOperation>
|
||||||
@ -738,9 +732,8 @@ class UnaryWithFeedbackNode : public FixedInputValueNodeT<1, Derived> {
|
|||||||
compiler::FeedbackSource feedback() const { return feedback_; }
|
compiler::FeedbackSource feedback() const { return feedback_; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit UnaryWithFeedbackNode(size_t input_count,
|
explicit UnaryWithFeedbackNode(const compiler::FeedbackSource& feedback)
|
||||||
const compiler::FeedbackSource& feedback)
|
: feedback_(feedback) {}
|
||||||
: Base(input_count), feedback_(feedback) {}
|
|
||||||
|
|
||||||
void AllocateVreg(MaglevVregAllocationState*, const ProcessingState&);
|
void AllocateVreg(MaglevVregAllocationState*, const ProcessingState&);
|
||||||
void GenerateCode(MaglevCodeGenState*, const ProcessingState&);
|
void GenerateCode(MaglevCodeGenState*, const ProcessingState&);
|
||||||
@ -764,9 +757,8 @@ class BinaryWithFeedbackNode : public FixedInputValueNodeT<2, Derived> {
|
|||||||
compiler::FeedbackSource feedback() const { return feedback_; }
|
compiler::FeedbackSource feedback() const { return feedback_; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
BinaryWithFeedbackNode(size_t input_count,
|
explicit BinaryWithFeedbackNode(const compiler::FeedbackSource& feedback)
|
||||||
const compiler::FeedbackSource& feedback)
|
: feedback_(feedback) {}
|
||||||
: Base(input_count), feedback_(feedback) {}
|
|
||||||
|
|
||||||
void AllocateVreg(MaglevVregAllocationState*, const ProcessingState&);
|
void AllocateVreg(MaglevVregAllocationState*, const ProcessingState&);
|
||||||
void GenerateCode(MaglevCodeGenState*, const ProcessingState&);
|
void GenerateCode(MaglevCodeGenState*, const ProcessingState&);
|
||||||
@ -780,8 +772,8 @@ class BinaryWithFeedbackNode : public FixedInputValueNodeT<2, Derived> {
|
|||||||
using Base = Super<Name, Operation::k##OpName>; \
|
using Base = Super<Name, Operation::k##OpName>; \
|
||||||
\
|
\
|
||||||
public: \
|
public: \
|
||||||
Name(size_t input_count, const compiler::FeedbackSource& feedback) \
|
explicit Name(const compiler::FeedbackSource& feedback) \
|
||||||
: Base(input_count, feedback) {} \
|
: Base(feedback) {} \
|
||||||
void AllocateVreg(MaglevVregAllocationState*, const ProcessingState&); \
|
void AllocateVreg(MaglevVregAllocationState*, const ProcessingState&); \
|
||||||
void GenerateCode(MaglevCodeGenState*, const ProcessingState&); \
|
void GenerateCode(MaglevCodeGenState*, const ProcessingState&); \
|
||||||
void PrintParams(std::ostream&, MaglevGraphLabeller*) const {} \
|
void PrintParams(std::ostream&, MaglevGraphLabeller*) const {} \
|
||||||
@ -801,8 +793,7 @@ class InitialValue : public FixedInputValueNodeT<0, InitialValue> {
|
|||||||
using Base = FixedInputValueNodeT<0, InitialValue>;
|
using Base = FixedInputValueNodeT<0, InitialValue>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit InitialValue(size_t input_count, interpreter::Register source)
|
explicit InitialValue(interpreter::Register source) : source_(source) {}
|
||||||
: Base(input_count), source_(source) {}
|
|
||||||
|
|
||||||
interpreter::Register source() const { return source_; }
|
interpreter::Register source() const { return source_; }
|
||||||
|
|
||||||
@ -818,8 +809,7 @@ class RegisterInput : public FixedInputValueNodeT<0, RegisterInput> {
|
|||||||
using Base = FixedInputValueNodeT<0, RegisterInput>;
|
using Base = FixedInputValueNodeT<0, RegisterInput>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit RegisterInput(size_t input_count, Register input)
|
explicit RegisterInput(Register input) : input_(input) {}
|
||||||
: Base(input_count), input_(input) {}
|
|
||||||
|
|
||||||
Register input() const { return input_; }
|
Register input() const { return input_; }
|
||||||
|
|
||||||
@ -835,8 +825,7 @@ class SmiConstant : public FixedInputValueNodeT<0, SmiConstant> {
|
|||||||
using Base = FixedInputValueNodeT<0, SmiConstant>;
|
using Base = FixedInputValueNodeT<0, SmiConstant>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit SmiConstant(size_t input_count, Smi value)
|
explicit SmiConstant(Smi value) : value_(value) {}
|
||||||
: Base(input_count), value_(value) {}
|
|
||||||
|
|
||||||
Smi value() const { return value_; }
|
Smi value() const { return value_; }
|
||||||
|
|
||||||
@ -852,8 +841,7 @@ class Constant : public FixedInputValueNodeT<0, Constant> {
|
|||||||
using Base = FixedInputValueNodeT<0, Constant>;
|
using Base = FixedInputValueNodeT<0, Constant>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Constant(size_t input_count, const compiler::HeapObjectRef& object)
|
explicit Constant(const compiler::HeapObjectRef& object) : object_(object) {}
|
||||||
: Base(input_count), object_(object) {}
|
|
||||||
|
|
||||||
void AllocateVreg(MaglevVregAllocationState*, const ProcessingState&);
|
void AllocateVreg(MaglevVregAllocationState*, const ProcessingState&);
|
||||||
void GenerateCode(MaglevCodeGenState*, const ProcessingState&);
|
void GenerateCode(MaglevCodeGenState*, const ProcessingState&);
|
||||||
@ -867,8 +855,7 @@ class RootConstant : public FixedInputValueNodeT<0, RootConstant> {
|
|||||||
using Base = FixedInputValueNodeT<0, RootConstant>;
|
using Base = FixedInputValueNodeT<0, RootConstant>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit RootConstant(size_t input_count, RootIndex index)
|
explicit RootConstant(RootIndex index) : index_(index) {}
|
||||||
: Base(input_count), index_(index) {}
|
|
||||||
|
|
||||||
RootIndex index() const { return index_; }
|
RootIndex index() const { return index_; }
|
||||||
|
|
||||||
@ -884,8 +871,7 @@ class SoftDeopt : public FixedInputNodeT<0, SoftDeopt> {
|
|||||||
using Base = FixedInputNodeT<0, SoftDeopt>;
|
using Base = FixedInputNodeT<0, SoftDeopt>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit SoftDeopt(size_t input_count, Checkpoint* checkpoint)
|
explicit SoftDeopt(Checkpoint* checkpoint) : checkpoint_(checkpoint) {}
|
||||||
: Base(input_count), checkpoint_(checkpoint) {}
|
|
||||||
|
|
||||||
static constexpr OpProperties kProperties = OpProperties::Deopt();
|
static constexpr OpProperties kProperties = OpProperties::Deopt();
|
||||||
|
|
||||||
@ -903,9 +889,8 @@ class CheckMaps : public FixedInputNodeT<1, CheckMaps> {
|
|||||||
using Base = FixedInputNodeT<1, CheckMaps>;
|
using Base = FixedInputNodeT<1, CheckMaps>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit CheckMaps(size_t input_count, const compiler::MapRef& map,
|
explicit CheckMaps(const compiler::MapRef& map, Checkpoint* checkpoint)
|
||||||
Checkpoint* checkpoint)
|
: map_(map), checkpoint_(checkpoint) {}
|
||||||
: Base(input_count), map_(map), checkpoint_(checkpoint) {}
|
|
||||||
|
|
||||||
// TODO(verwaest): This just calls in deferred code, so probably we'll need to
|
// TODO(verwaest): This just calls in deferred code, so probably we'll need to
|
||||||
// mark that to generate stack maps. Mark as call so we at least clear the
|
// mark that to generate stack maps. Mark as call so we at least clear the
|
||||||
@ -933,8 +918,7 @@ class LoadField : public FixedInputValueNodeT<1, LoadField> {
|
|||||||
using Base = FixedInputValueNodeT<1, LoadField>;
|
using Base = FixedInputValueNodeT<1, LoadField>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit LoadField(size_t input_count, int handler)
|
explicit LoadField(int handler) : handler_(handler) {}
|
||||||
: Base(input_count), handler_(handler) {}
|
|
||||||
|
|
||||||
static constexpr OpProperties kProperties = OpProperties::Reading();
|
static constexpr OpProperties kProperties = OpProperties::Reading();
|
||||||
|
|
||||||
@ -955,8 +939,7 @@ class StoreField : public FixedInputNodeT<2, StoreField> {
|
|||||||
using Base = FixedInputNodeT<2, StoreField>;
|
using Base = FixedInputNodeT<2, StoreField>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit StoreField(size_t input_count, int handler)
|
explicit StoreField(int handler) : handler_(handler) {}
|
||||||
: Base(input_count), handler_(handler) {}
|
|
||||||
|
|
||||||
static constexpr OpProperties kProperties = OpProperties::Writing();
|
static constexpr OpProperties kProperties = OpProperties::Writing();
|
||||||
|
|
||||||
@ -979,8 +962,7 @@ class LoadGlobal : public FixedInputValueNodeT<1, LoadGlobal> {
|
|||||||
using Base = FixedInputValueNodeT<1, LoadGlobal>;
|
using Base = FixedInputValueNodeT<1, LoadGlobal>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit LoadGlobal(size_t input_count, const compiler::NameRef& name)
|
explicit LoadGlobal(const compiler::NameRef& name) : name_(name) {}
|
||||||
: Base(input_count), name_(name) {}
|
|
||||||
|
|
||||||
// The implementation currently calls runtime.
|
// The implementation currently calls runtime.
|
||||||
static constexpr OpProperties kProperties = OpProperties::JSCall();
|
static constexpr OpProperties kProperties = OpProperties::JSCall();
|
||||||
@ -1000,8 +982,7 @@ class LoadNamedGeneric : public FixedInputValueNodeT<2, LoadNamedGeneric> {
|
|||||||
using Base = FixedInputValueNodeT<2, LoadNamedGeneric>;
|
using Base = FixedInputValueNodeT<2, LoadNamedGeneric>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit LoadNamedGeneric(size_t input_count, const compiler::NameRef& name)
|
explicit LoadNamedGeneric(const compiler::NameRef& name) : name_(name) {}
|
||||||
: Base(input_count), name_(name) {}
|
|
||||||
|
|
||||||
// The implementation currently calls runtime.
|
// The implementation currently calls runtime.
|
||||||
static constexpr OpProperties kProperties = OpProperties::JSCall();
|
static constexpr OpProperties kProperties = OpProperties::JSCall();
|
||||||
@ -1025,9 +1006,8 @@ class GapMove : public FixedInputNodeT<0, GapMove> {
|
|||||||
using Base = FixedInputNodeT<0, GapMove>;
|
using Base = FixedInputNodeT<0, GapMove>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GapMove(size_t input_count, compiler::AllocatedOperand source,
|
GapMove(compiler::AllocatedOperand source, compiler::AllocatedOperand target)
|
||||||
compiler::AllocatedOperand target)
|
: source_(source), target_(target) {}
|
||||||
: Base(input_count), source_(source), target_(target) {}
|
|
||||||
|
|
||||||
compiler::AllocatedOperand source() const { return source_; }
|
compiler::AllocatedOperand source() const { return source_; }
|
||||||
compiler::AllocatedOperand target() const { return target_; }
|
compiler::AllocatedOperand target() const { return target_; }
|
||||||
@ -1051,8 +1031,8 @@ class Phi : public ValueNodeT<Phi> {
|
|||||||
using List = base::ThreadedList<Phi>;
|
using List = base::ThreadedList<Phi>;
|
||||||
|
|
||||||
// TODO(jgruber): More intuitive constructors, if possible.
|
// TODO(jgruber): More intuitive constructors, if possible.
|
||||||
Phi(size_t input_count, interpreter::Register owner, int merge_offset)
|
Phi(interpreter::Register owner, int merge_offset)
|
||||||
: Base(input_count), owner_(owner), merge_offset_(merge_offset) {}
|
: owner_(owner), merge_offset_(merge_offset) {}
|
||||||
|
|
||||||
interpreter::Register owner() const { return owner_; }
|
interpreter::Register owner() const { return owner_; }
|
||||||
int merge_offset() const { return merge_offset_; }
|
int merge_offset() const { return merge_offset_; }
|
||||||
@ -1078,12 +1058,11 @@ class CallProperty : public ValueNodeT<CallProperty> {
|
|||||||
using Base = ValueNodeT<CallProperty>;
|
using Base = ValueNodeT<CallProperty>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit CallProperty(size_t input_count) : Base(input_count) {}
|
CallProperty() = default;
|
||||||
|
|
||||||
// This ctor is used when for variable input counts.
|
// This ctor is used when for variable input counts.
|
||||||
// Inputs must be initialized manually.
|
// Inputs must be initialized manually.
|
||||||
CallProperty(size_t input_count, ValueNode* function, ValueNode* context)
|
CallProperty(ValueNode* function, ValueNode* context) {
|
||||||
: Base(input_count) {
|
|
||||||
set_input(0, function);
|
set_input(0, function);
|
||||||
set_input(1, context);
|
set_input(1, context);
|
||||||
}
|
}
|
||||||
@ -1107,8 +1086,6 @@ class CallUndefinedReceiver : public ValueNodeT<CallUndefinedReceiver> {
|
|||||||
using Base = ValueNodeT<CallUndefinedReceiver>;
|
using Base = ValueNodeT<CallUndefinedReceiver>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit CallUndefinedReceiver(size_t input_count) : Base(input_count) {}
|
|
||||||
|
|
||||||
static constexpr OpProperties kProperties = OpProperties::JSCall();
|
static constexpr OpProperties kProperties = OpProperties::JSCall();
|
||||||
|
|
||||||
Input& function() { return input(0); }
|
Input& function() { return input(0); }
|
||||||
@ -1234,10 +1211,6 @@ class ControlNode : public NodeBase {
|
|||||||
next_post_dominating_hole_ = node;
|
next_post_dominating_hole_ = node;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
|
||||||
explicit ControlNode(Opcode opcode, size_t input_count)
|
|
||||||
: NodeBase(opcode, input_count) {}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ControlNode* next_post_dominating_hole_ = nullptr;
|
ControlNode* next_post_dominating_hole_ = nullptr;
|
||||||
};
|
};
|
||||||
@ -1249,12 +1222,9 @@ class UnconditionalControlNode : public ControlNode {
|
|||||||
void set_predecessor_id(int id) { predecessor_id_ = id; }
|
void set_predecessor_id(int id) { predecessor_id_ = id; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit UnconditionalControlNode(Opcode opcode, size_t input_count,
|
explicit UnconditionalControlNode(BasicBlockRef* target_refs)
|
||||||
BasicBlockRef* target_refs)
|
: target_(target_refs) {}
|
||||||
: ControlNode(opcode, input_count), target_(target_refs) {}
|
explicit UnconditionalControlNode(BasicBlock* target) : target_(target) {}
|
||||||
explicit UnconditionalControlNode(Opcode opcode, size_t input_count,
|
|
||||||
BasicBlock* target)
|
|
||||||
: ControlNode(opcode, input_count), target_(target) {}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const BasicBlockRef target_;
|
const BasicBlockRef target_;
|
||||||
@ -1268,7 +1238,7 @@ class UnconditionalControlNodeT : public UnconditionalControlNode {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
// Shadowing for static knowledge.
|
// Shadowing for static knowledge.
|
||||||
constexpr Opcode opcode() const { return NodeBase::opcode_of<Derived>; }
|
constexpr Opcode opcode() const { return opcode_of<Derived>; }
|
||||||
constexpr bool has_inputs() const { return input_count() > 0; }
|
constexpr bool has_inputs() const { return input_count() > 0; }
|
||||||
constexpr uint16_t input_count() const { return kInputCount; }
|
constexpr uint16_t input_count() const { return kInputCount; }
|
||||||
auto end() {
|
auto end() {
|
||||||
@ -1276,27 +1246,21 @@ class UnconditionalControlNodeT : public UnconditionalControlNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit UnconditionalControlNodeT(size_t input_count,
|
explicit UnconditionalControlNodeT(BasicBlockRef* target_refs)
|
||||||
BasicBlockRef* target_refs)
|
: UnconditionalControlNode(target_refs) {
|
||||||
: UnconditionalControlNode(opcode_of<Derived>, kInputCount, target_refs) {
|
DCHECK_EQ(NodeBase::input_count(), kInputCount);
|
||||||
DCHECK_EQ(input_count, kInputCount);
|
|
||||||
USE(input_count);
|
|
||||||
}
|
}
|
||||||
explicit UnconditionalControlNodeT(size_t input_count, BasicBlock* target)
|
explicit UnconditionalControlNodeT(BasicBlock* target)
|
||||||
: UnconditionalControlNode(opcode_of<Derived>, kInputCount, target) {
|
: UnconditionalControlNode(target) {
|
||||||
DCHECK_EQ(input_count, kInputCount);
|
DCHECK_EQ(NodeBase::input_count(), kInputCount);
|
||||||
USE(input_count);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class ConditionalControlNode : public ControlNode {
|
class ConditionalControlNode : public ControlNode {
|
||||||
public:
|
public:
|
||||||
ConditionalControlNode(Opcode opcode, size_t input_count,
|
ConditionalControlNode(BasicBlockRef* if_true_refs,
|
||||||
BasicBlockRef* if_true_refs,
|
|
||||||
BasicBlockRef* if_false_refs)
|
BasicBlockRef* if_false_refs)
|
||||||
: ControlNode(opcode, input_count),
|
: if_true_(if_true_refs), if_false_(if_false_refs) {}
|
||||||
if_true_(if_true_refs),
|
|
||||||
if_false_(if_false_refs) {}
|
|
||||||
|
|
||||||
BasicBlock* if_true() const { return if_true_.block_ptr(); }
|
BasicBlock* if_true() const { return if_true_.block_ptr(); }
|
||||||
BasicBlock* if_false() const { return if_false_.block_ptr(); }
|
BasicBlock* if_false() const { return if_false_.block_ptr(); }
|
||||||
@ -1313,7 +1277,7 @@ class ConditionalControlNodeT : public ConditionalControlNode {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
// Shadowing for static knowledge.
|
// Shadowing for static knowledge.
|
||||||
constexpr Opcode opcode() const { return NodeBase::opcode_of<Derived>; }
|
constexpr Opcode opcode() const { return opcode_of<Derived>; }
|
||||||
constexpr bool has_inputs() const { return input_count() > 0; }
|
constexpr bool has_inputs() const { return input_count() > 0; }
|
||||||
constexpr uint16_t input_count() const { return kInputCount; }
|
constexpr uint16_t input_count() const { return kInputCount; }
|
||||||
auto end() {
|
auto end() {
|
||||||
@ -1321,13 +1285,10 @@ class ConditionalControlNodeT : public ConditionalControlNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit ConditionalControlNodeT(size_t input_count,
|
explicit ConditionalControlNodeT(BasicBlockRef* if_true_refs,
|
||||||
BasicBlockRef* if_true_refs,
|
|
||||||
BasicBlockRef* if_false_refs)
|
BasicBlockRef* if_false_refs)
|
||||||
: ConditionalControlNode(opcode_of<Derived>, kInputCount, if_true_refs,
|
: ConditionalControlNode(if_true_refs, if_false_refs) {
|
||||||
if_false_refs) {
|
DCHECK_EQ(NodeBase::input_count(), kInputCount);
|
||||||
DCHECK_EQ(input_count, kInputCount);
|
|
||||||
USE(input_count);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1335,8 +1296,7 @@ class Jump : public UnconditionalControlNodeT<Jump> {
|
|||||||
using Base = UnconditionalControlNodeT<Jump>;
|
using Base = UnconditionalControlNodeT<Jump>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Jump(size_t input_count, BasicBlockRef* target_refs)
|
explicit Jump(BasicBlockRef* target_refs) : Base(target_refs) {}
|
||||||
: Base(input_count, target_refs) {}
|
|
||||||
|
|
||||||
void AllocateVreg(MaglevVregAllocationState*, const ProcessingState&);
|
void AllocateVreg(MaglevVregAllocationState*, const ProcessingState&);
|
||||||
void GenerateCode(MaglevCodeGenState*, const ProcessingState&);
|
void GenerateCode(MaglevCodeGenState*, const ProcessingState&);
|
||||||
@ -1347,11 +1307,9 @@ class JumpLoop : public UnconditionalControlNodeT<JumpLoop> {
|
|||||||
using Base = UnconditionalControlNodeT<JumpLoop>;
|
using Base = UnconditionalControlNodeT<JumpLoop>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit JumpLoop(size_t input_count, BasicBlock* target)
|
explicit JumpLoop(BasicBlock* target) : Base(target) {}
|
||||||
: Base(input_count, target) {}
|
|
||||||
|
|
||||||
explicit JumpLoop(size_t input_count, BasicBlockRef* ref)
|
explicit JumpLoop(BasicBlockRef* ref) : Base(ref) {}
|
||||||
: Base(input_count, ref) {}
|
|
||||||
|
|
||||||
void AllocateVreg(MaglevVregAllocationState*, const ProcessingState&);
|
void AllocateVreg(MaglevVregAllocationState*, const ProcessingState&);
|
||||||
void GenerateCode(MaglevCodeGenState*, const ProcessingState&);
|
void GenerateCode(MaglevCodeGenState*, const ProcessingState&);
|
||||||
@ -1360,9 +1318,6 @@ class JumpLoop : public UnconditionalControlNodeT<JumpLoop> {
|
|||||||
|
|
||||||
class Return : public ControlNode {
|
class Return : public ControlNode {
|
||||||
public:
|
public:
|
||||||
explicit Return(size_t input_count)
|
|
||||||
: ControlNode(opcode_of<Return>, input_count) {}
|
|
||||||
|
|
||||||
Input& value_input() { return input(0); }
|
Input& value_input() { return input(0); }
|
||||||
|
|
||||||
void AllocateVreg(MaglevVregAllocationState*, const ProcessingState&);
|
void AllocateVreg(MaglevVregAllocationState*, const ProcessingState&);
|
||||||
@ -1374,9 +1329,9 @@ class BranchIfTrue : public ConditionalControlNodeT<1, BranchIfTrue> {
|
|||||||
using Base = ConditionalControlNodeT<1, BranchIfTrue>;
|
using Base = ConditionalControlNodeT<1, BranchIfTrue>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit BranchIfTrue(size_t input_count, BasicBlockRef* if_true_refs,
|
explicit BranchIfTrue(BasicBlockRef* if_true_refs,
|
||||||
BasicBlockRef* if_false_refs)
|
BasicBlockRef* if_false_refs)
|
||||||
: Base(input_count, if_true_refs, if_false_refs) {}
|
: Base(if_true_refs, if_false_refs) {}
|
||||||
|
|
||||||
Input& condition_input() { return input(0); }
|
Input& condition_input() { return input(0); }
|
||||||
|
|
||||||
@ -1390,10 +1345,9 @@ class BranchIfToBooleanTrue
|
|||||||
using Base = ConditionalControlNodeT<1, BranchIfToBooleanTrue>;
|
using Base = ConditionalControlNodeT<1, BranchIfToBooleanTrue>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit BranchIfToBooleanTrue(size_t input_count,
|
explicit BranchIfToBooleanTrue(BasicBlockRef* if_true_refs,
|
||||||
BasicBlockRef* if_true_refs,
|
|
||||||
BasicBlockRef* if_false_refs)
|
BasicBlockRef* if_false_refs)
|
||||||
: Base(input_count, if_true_refs, if_false_refs) {}
|
: Base(if_true_refs, if_false_refs) {}
|
||||||
|
|
||||||
static constexpr OpProperties kProperties = OpProperties::Call();
|
static constexpr OpProperties kProperties = OpProperties::Call();
|
||||||
|
|
||||||
@ -1414,10 +1368,9 @@ class BranchIfCompare
|
|||||||
Input& left_input() { return NodeBase::input(kLeftIndex); }
|
Input& left_input() { return NodeBase::input(kLeftIndex); }
|
||||||
Input& right_input() { return NodeBase::input(kRightIndex); }
|
Input& right_input() { return NodeBase::input(kRightIndex); }
|
||||||
|
|
||||||
explicit BranchIfCompare(size_t input_count, Operation operation,
|
explicit BranchIfCompare(Operation operation, BasicBlockRef* if_true_refs,
|
||||||
BasicBlockRef* if_true_refs,
|
|
||||||
BasicBlockRef* if_false_refs)
|
BasicBlockRef* if_false_refs)
|
||||||
: Base(input_count, if_true_refs, if_false_refs), operation_(operation) {}
|
: Base(if_true_refs, if_false_refs), operation_(operation) {}
|
||||||
|
|
||||||
void AllocateVreg(MaglevVregAllocationState*, const ProcessingState&);
|
void AllocateVreg(MaglevVregAllocationState*, const ProcessingState&);
|
||||||
void GenerateCode(MaglevCodeGenState*, const ProcessingState&);
|
void GenerateCode(MaglevCodeGenState*, const ProcessingState&);
|
||||||
|
Loading…
Reference in New Issue
Block a user