diff --git a/src/maglev/maglev-ir.h b/src/maglev/maglev-ir.h index 4c93b7e549..fad1ff10e7 100644 --- a/src/maglev/maglev-ir.h +++ b/src/maglev/maglev-ir.h @@ -318,7 +318,17 @@ NODE_BASE_LIST(DEF_OPCODE_OF) } // namespace detail class NodeBase : public ZoneObject { + private: + // Bitfield specification. + using OpcodeField = base::BitField; + STATIC_ASSERT(OpcodeField::is_valid(kLastOpcode)); + using InputCountField = OpcodeField::Next; + protected: + // Subclasses may use the remaining bitfield bits. + template + using NextBitField = InputCountField::Next; + template static constexpr Opcode opcode_of = detail::opcode_of_helper::value; @@ -350,7 +360,7 @@ class NodeBase : public ZoneObject { static constexpr OpProperties kProperties = OpProperties::Pure(); inline const OpProperties& properties() const; - constexpr Opcode opcode() const { return OpcodeField::decode(bit_field_); } + constexpr Opcode opcode() const { return OpcodeField::decode(bit_field()); } template constexpr bool Is() const; @@ -372,7 +382,7 @@ class NodeBase : public ZoneObject { constexpr bool has_inputs() const { return input_count() > 0; } constexpr uint16_t input_count() const { - return InputCountField::decode(bit_field_); + return InputCountField::decode(bit_field()); } Input& input(int index) { return *input_address(index); } @@ -427,44 +437,23 @@ class NodeBase : public ZoneObject { void Print(std::ostream& os, MaglevGraphLabeller*) const; protected: - NodeBase(Opcode opcode, size_t input_count) - : bit_field_(OpcodeField::encode(opcode) | - InputCountField::encode(input_count)) {} + NodeBase() : num_temporaries_needed_(0) {} Input* input_address(int index) { DCHECK_LT(index, input_count()); - return reinterpret_cast(this) - (index + 1); + return reinterpret_cast(bit_field_address()) - (index + 1); } const Input* input_address(int index) const { DCHECK_LT(index, input_count()); - return reinterpret_cast(this) - (index + 1); + return reinterpret_cast(bit_field_address()) - (index + 1); } void set_input(int index, ValueNode* input) { new (input_address(index)) Input(input); } - private: - template - 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(zone->Allocate(size)); - void* node_buffer = - reinterpret_cast(raw_buffer + input_count * sizeof(Input)); - Derived* node = - new (node_buffer) Derived(input_count, std::forward(args)...); - return node; - } - - protected: - // Bitfield specification. - using OpcodeField = base::BitField; - STATIC_ASSERT(OpcodeField::is_valid(kLastOpcode)); - using InputCountField = OpcodeField::Next; - // Subclasses may use the remaining bits. - template - using NextBitField = InputCountField::Next; + uint32_t bit_field() const { return *bit_field_address(); } + void set_bit_field(uint32_t value) { *bit_field_address() = value; } void set_temporaries_needed(int value) { #ifdef DEBUG @@ -474,13 +463,38 @@ class NodeBase : public ZoneObject { num_temporaries_needed_ = value; } - uint32_t bit_field_; - private: + template + 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(zone->Allocate(size)); + void* node_buffer = reinterpret_cast(raw_buffer + sizeof(uint32_t) + + input_count * sizeof(Input)); + + *reinterpret_cast(reinterpret_cast(node_buffer) - + sizeof(uint32_t)) = + OpcodeField::encode(opcode_of) | + InputCountField::encode(input_count); + + Derived* node = new (node_buffer) Derived(std::forward(args)...); + return node; + } + + uint32_t* bit_field_address() { + return reinterpret_cast(reinterpret_cast(this) - + sizeof(uint32_t)); + } + const uint32_t* bit_field_address() const { + return reinterpret_cast( + reinterpret_cast(this) - sizeof(uint32_t)); + } + NodeIdT id_ = kInvalidNodeId; union { - int num_temporaries_needed_ = 0; + int num_temporaries_needed_; RegList temporaries_; }; #ifdef DEBUG @@ -491,7 +505,6 @@ class NodeBase : public ZoneObject { } kTemporariesState = kUnset; #endif // DEBUG - NodeBase() = delete; NodeBase(const NodeBase&) = delete; NodeBase(NodeBase&&) = delete; NodeBase& operator=(const NodeBase&) = delete; @@ -524,10 +537,6 @@ class Node : public NodeBase { inline ValueLocation& result(); - protected: - explicit Node(Opcode opcode, size_t input_count) - : NodeBase(opcode, input_count) {} - private: Node** next() { return &next_; } Node* next_ = nullptr; @@ -626,9 +635,8 @@ class ValueNode : public Node { } protected: - explicit ValueNode(Opcode opcode, size_t input_count) - : Node(opcode, input_count), - last_uses_next_use_id_(&next_use_) + ValueNode() + : last_uses_next_use_id_(&next_use_) #ifdef DEBUG , state_(kLastUse) @@ -666,11 +674,8 @@ class NodeT : public Node { STATIC_ASSERT(!IsValueNode(opcode_of)); public: - constexpr Opcode opcode() const { return NodeBase::opcode_of; } + constexpr Opcode opcode() const { return opcode_of; } const OpProperties& properties() const { return Derived::kProperties; } - - protected: - explicit NodeT(size_t input_count) : Node(opcode_of, input_count) {} }; template @@ -686,10 +691,7 @@ class FixedInputNodeT : public NodeT { } protected: - explicit FixedInputNodeT(size_t input_count) : NodeT(kInputCount) { - DCHECK_EQ(input_count, kInputCount); - USE(input_count); - } + FixedInputNodeT() { DCHECK_EQ(NodeBase::input_count(), kInputCount); } }; template @@ -697,12 +699,8 @@ class ValueNodeT : public ValueNode { STATIC_ASSERT(IsValueNode(opcode_of)); public: - constexpr Opcode opcode() const { return NodeBase::opcode_of; } + constexpr Opcode opcode() const { return opcode_of; } const OpProperties& properties() const { return Derived::kProperties; } - - protected: - explicit ValueNodeT(size_t input_count) - : ValueNode(opcode_of, input_count) {} }; template @@ -718,11 +716,7 @@ class FixedInputValueNodeT : public ValueNodeT { } protected: - explicit FixedInputValueNodeT(size_t input_count) - : ValueNodeT(InputCount) { - DCHECK_EQ(input_count, InputCount); - USE(input_count); - } + FixedInputValueNodeT() { DCHECK_EQ(NodeBase::input_count(), kInputCount); } }; template @@ -738,9 +732,8 @@ class UnaryWithFeedbackNode : public FixedInputValueNodeT<1, Derived> { compiler::FeedbackSource feedback() const { return feedback_; } protected: - explicit UnaryWithFeedbackNode(size_t input_count, - const compiler::FeedbackSource& feedback) - : Base(input_count), feedback_(feedback) {} + explicit UnaryWithFeedbackNode(const compiler::FeedbackSource& feedback) + : feedback_(feedback) {} void AllocateVreg(MaglevVregAllocationState*, const ProcessingState&); void GenerateCode(MaglevCodeGenState*, const ProcessingState&); @@ -764,9 +757,8 @@ class BinaryWithFeedbackNode : public FixedInputValueNodeT<2, Derived> { compiler::FeedbackSource feedback() const { return feedback_; } protected: - BinaryWithFeedbackNode(size_t input_count, - const compiler::FeedbackSource& feedback) - : Base(input_count), feedback_(feedback) {} + explicit BinaryWithFeedbackNode(const compiler::FeedbackSource& feedback) + : feedback_(feedback) {} void AllocateVreg(MaglevVregAllocationState*, const ProcessingState&); void GenerateCode(MaglevCodeGenState*, const ProcessingState&); @@ -780,8 +772,8 @@ class BinaryWithFeedbackNode : public FixedInputValueNodeT<2, Derived> { using Base = Super; \ \ public: \ - Name(size_t input_count, const compiler::FeedbackSource& feedback) \ - : Base(input_count, feedback) {} \ + explicit Name(const compiler::FeedbackSource& feedback) \ + : Base(feedback) {} \ void AllocateVreg(MaglevVregAllocationState*, const ProcessingState&); \ void GenerateCode(MaglevCodeGenState*, const ProcessingState&); \ void PrintParams(std::ostream&, MaglevGraphLabeller*) const {} \ @@ -801,8 +793,7 @@ class InitialValue : public FixedInputValueNodeT<0, InitialValue> { using Base = FixedInputValueNodeT<0, InitialValue>; public: - explicit InitialValue(size_t input_count, interpreter::Register source) - : Base(input_count), source_(source) {} + explicit InitialValue(interpreter::Register source) : source_(source) {} interpreter::Register source() const { return source_; } @@ -818,8 +809,7 @@ class RegisterInput : public FixedInputValueNodeT<0, RegisterInput> { using Base = FixedInputValueNodeT<0, RegisterInput>; public: - explicit RegisterInput(size_t input_count, Register input) - : Base(input_count), input_(input) {} + explicit RegisterInput(Register input) : input_(input) {} Register input() const { return input_; } @@ -835,8 +825,7 @@ class SmiConstant : public FixedInputValueNodeT<0, SmiConstant> { using Base = FixedInputValueNodeT<0, SmiConstant>; public: - explicit SmiConstant(size_t input_count, Smi value) - : Base(input_count), value_(value) {} + explicit SmiConstant(Smi value) : value_(value) {} Smi value() const { return value_; } @@ -852,8 +841,7 @@ class Constant : public FixedInputValueNodeT<0, Constant> { using Base = FixedInputValueNodeT<0, Constant>; public: - explicit Constant(size_t input_count, const compiler::HeapObjectRef& object) - : Base(input_count), object_(object) {} + explicit Constant(const compiler::HeapObjectRef& object) : object_(object) {} void AllocateVreg(MaglevVregAllocationState*, const ProcessingState&); void GenerateCode(MaglevCodeGenState*, const ProcessingState&); @@ -867,8 +855,7 @@ class RootConstant : public FixedInputValueNodeT<0, RootConstant> { using Base = FixedInputValueNodeT<0, RootConstant>; public: - explicit RootConstant(size_t input_count, RootIndex index) - : Base(input_count), index_(index) {} + explicit RootConstant(RootIndex index) : index_(index) {} RootIndex index() const { return index_; } @@ -884,8 +871,7 @@ class SoftDeopt : public FixedInputNodeT<0, SoftDeopt> { using Base = FixedInputNodeT<0, SoftDeopt>; public: - explicit SoftDeopt(size_t input_count, Checkpoint* checkpoint) - : Base(input_count), checkpoint_(checkpoint) {} + explicit SoftDeopt(Checkpoint* checkpoint) : checkpoint_(checkpoint) {} static constexpr OpProperties kProperties = OpProperties::Deopt(); @@ -903,9 +889,8 @@ class CheckMaps : public FixedInputNodeT<1, CheckMaps> { using Base = FixedInputNodeT<1, CheckMaps>; public: - explicit CheckMaps(size_t input_count, const compiler::MapRef& map, - Checkpoint* checkpoint) - : Base(input_count), map_(map), checkpoint_(checkpoint) {} + explicit CheckMaps(const compiler::MapRef& map, Checkpoint* checkpoint) + : map_(map), checkpoint_(checkpoint) {} // 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 @@ -933,8 +918,7 @@ class LoadField : public FixedInputValueNodeT<1, LoadField> { using Base = FixedInputValueNodeT<1, LoadField>; public: - explicit LoadField(size_t input_count, int handler) - : Base(input_count), handler_(handler) {} + explicit LoadField(int handler) : handler_(handler) {} static constexpr OpProperties kProperties = OpProperties::Reading(); @@ -955,8 +939,7 @@ class StoreField : public FixedInputNodeT<2, StoreField> { using Base = FixedInputNodeT<2, StoreField>; public: - explicit StoreField(size_t input_count, int handler) - : Base(input_count), handler_(handler) {} + explicit StoreField(int handler) : handler_(handler) {} static constexpr OpProperties kProperties = OpProperties::Writing(); @@ -979,8 +962,7 @@ class LoadGlobal : public FixedInputValueNodeT<1, LoadGlobal> { using Base = FixedInputValueNodeT<1, LoadGlobal>; public: - explicit LoadGlobal(size_t input_count, const compiler::NameRef& name) - : Base(input_count), name_(name) {} + explicit LoadGlobal(const compiler::NameRef& name) : name_(name) {} // The implementation currently calls runtime. static constexpr OpProperties kProperties = OpProperties::JSCall(); @@ -1000,8 +982,7 @@ class LoadNamedGeneric : public FixedInputValueNodeT<2, LoadNamedGeneric> { using Base = FixedInputValueNodeT<2, LoadNamedGeneric>; public: - explicit LoadNamedGeneric(size_t input_count, const compiler::NameRef& name) - : Base(input_count), name_(name) {} + explicit LoadNamedGeneric(const compiler::NameRef& name) : name_(name) {} // The implementation currently calls runtime. static constexpr OpProperties kProperties = OpProperties::JSCall(); @@ -1025,9 +1006,8 @@ class GapMove : public FixedInputNodeT<0, GapMove> { using Base = FixedInputNodeT<0, GapMove>; public: - GapMove(size_t input_count, compiler::AllocatedOperand source, - compiler::AllocatedOperand target) - : Base(input_count), source_(source), target_(target) {} + GapMove(compiler::AllocatedOperand source, compiler::AllocatedOperand target) + : source_(source), target_(target) {} compiler::AllocatedOperand source() const { return source_; } compiler::AllocatedOperand target() const { return target_; } @@ -1051,8 +1031,8 @@ class Phi : public ValueNodeT { using List = base::ThreadedList; // TODO(jgruber): More intuitive constructors, if possible. - Phi(size_t input_count, interpreter::Register owner, int merge_offset) - : Base(input_count), owner_(owner), merge_offset_(merge_offset) {} + Phi(interpreter::Register owner, int merge_offset) + : owner_(owner), merge_offset_(merge_offset) {} interpreter::Register owner() const { return owner_; } int merge_offset() const { return merge_offset_; } @@ -1078,12 +1058,11 @@ class CallProperty : public ValueNodeT { using Base = ValueNodeT; public: - explicit CallProperty(size_t input_count) : Base(input_count) {} + CallProperty() = default; // This ctor is used when for variable input counts. // Inputs must be initialized manually. - CallProperty(size_t input_count, ValueNode* function, ValueNode* context) - : Base(input_count) { + CallProperty(ValueNode* function, ValueNode* context) { set_input(0, function); set_input(1, context); } @@ -1107,8 +1086,6 @@ class CallUndefinedReceiver : public ValueNodeT { using Base = ValueNodeT; public: - explicit CallUndefinedReceiver(size_t input_count) : Base(input_count) {} - static constexpr OpProperties kProperties = OpProperties::JSCall(); Input& function() { return input(0); } @@ -1234,10 +1211,6 @@ class ControlNode : public NodeBase { next_post_dominating_hole_ = node; } - protected: - explicit ControlNode(Opcode opcode, size_t input_count) - : NodeBase(opcode, input_count) {} - private: ControlNode* next_post_dominating_hole_ = nullptr; }; @@ -1249,12 +1222,9 @@ class UnconditionalControlNode : public ControlNode { void set_predecessor_id(int id) { predecessor_id_ = id; } protected: - explicit UnconditionalControlNode(Opcode opcode, size_t input_count, - BasicBlockRef* target_refs) - : ControlNode(opcode, input_count), target_(target_refs) {} - explicit UnconditionalControlNode(Opcode opcode, size_t input_count, - BasicBlock* target) - : ControlNode(opcode, input_count), target_(target) {} + explicit UnconditionalControlNode(BasicBlockRef* target_refs) + : target_(target_refs) {} + explicit UnconditionalControlNode(BasicBlock* target) : target_(target) {} private: const BasicBlockRef target_; @@ -1268,7 +1238,7 @@ class UnconditionalControlNodeT : public UnconditionalControlNode { public: // Shadowing for static knowledge. - constexpr Opcode opcode() const { return NodeBase::opcode_of; } + constexpr Opcode opcode() const { return opcode_of; } constexpr bool has_inputs() const { return input_count() > 0; } constexpr uint16_t input_count() const { return kInputCount; } auto end() { @@ -1276,27 +1246,21 @@ class UnconditionalControlNodeT : public UnconditionalControlNode { } protected: - explicit UnconditionalControlNodeT(size_t input_count, - BasicBlockRef* target_refs) - : UnconditionalControlNode(opcode_of, kInputCount, target_refs) { - DCHECK_EQ(input_count, kInputCount); - USE(input_count); + explicit UnconditionalControlNodeT(BasicBlockRef* target_refs) + : UnconditionalControlNode(target_refs) { + DCHECK_EQ(NodeBase::input_count(), kInputCount); } - explicit UnconditionalControlNodeT(size_t input_count, BasicBlock* target) - : UnconditionalControlNode(opcode_of, kInputCount, target) { - DCHECK_EQ(input_count, kInputCount); - USE(input_count); + explicit UnconditionalControlNodeT(BasicBlock* target) + : UnconditionalControlNode(target) { + DCHECK_EQ(NodeBase::input_count(), kInputCount); } }; class ConditionalControlNode : public ControlNode { public: - ConditionalControlNode(Opcode opcode, size_t input_count, - BasicBlockRef* if_true_refs, + ConditionalControlNode(BasicBlockRef* if_true_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_false() const { return if_false_.block_ptr(); } @@ -1313,7 +1277,7 @@ class ConditionalControlNodeT : public ConditionalControlNode { public: // Shadowing for static knowledge. - constexpr Opcode opcode() const { return NodeBase::opcode_of; } + constexpr Opcode opcode() const { return opcode_of; } constexpr bool has_inputs() const { return input_count() > 0; } constexpr uint16_t input_count() const { return kInputCount; } auto end() { @@ -1321,13 +1285,10 @@ class ConditionalControlNodeT : public ConditionalControlNode { } protected: - explicit ConditionalControlNodeT(size_t input_count, - BasicBlockRef* if_true_refs, + explicit ConditionalControlNodeT(BasicBlockRef* if_true_refs, BasicBlockRef* if_false_refs) - : ConditionalControlNode(opcode_of, kInputCount, if_true_refs, - if_false_refs) { - DCHECK_EQ(input_count, kInputCount); - USE(input_count); + : ConditionalControlNode(if_true_refs, if_false_refs) { + DCHECK_EQ(NodeBase::input_count(), kInputCount); } }; @@ -1335,8 +1296,7 @@ class Jump : public UnconditionalControlNodeT { using Base = UnconditionalControlNodeT; public: - explicit Jump(size_t input_count, BasicBlockRef* target_refs) - : Base(input_count, target_refs) {} + explicit Jump(BasicBlockRef* target_refs) : Base(target_refs) {} void AllocateVreg(MaglevVregAllocationState*, const ProcessingState&); void GenerateCode(MaglevCodeGenState*, const ProcessingState&); @@ -1347,11 +1307,9 @@ class JumpLoop : public UnconditionalControlNodeT { using Base = UnconditionalControlNodeT; public: - explicit JumpLoop(size_t input_count, BasicBlock* target) - : Base(input_count, target) {} + explicit JumpLoop(BasicBlock* target) : Base(target) {} - explicit JumpLoop(size_t input_count, BasicBlockRef* ref) - : Base(input_count, ref) {} + explicit JumpLoop(BasicBlockRef* ref) : Base(ref) {} void AllocateVreg(MaglevVregAllocationState*, const ProcessingState&); void GenerateCode(MaglevCodeGenState*, const ProcessingState&); @@ -1360,9 +1318,6 @@ class JumpLoop : public UnconditionalControlNodeT { class Return : public ControlNode { public: - explicit Return(size_t input_count) - : ControlNode(opcode_of, input_count) {} - Input& value_input() { return input(0); } void AllocateVreg(MaglevVregAllocationState*, const ProcessingState&); @@ -1374,9 +1329,9 @@ class BranchIfTrue : public ConditionalControlNodeT<1, BranchIfTrue> { using Base = ConditionalControlNodeT<1, BranchIfTrue>; public: - explicit BranchIfTrue(size_t input_count, BasicBlockRef* if_true_refs, + explicit BranchIfTrue(BasicBlockRef* if_true_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); } @@ -1390,10 +1345,9 @@ class BranchIfToBooleanTrue using Base = ConditionalControlNodeT<1, BranchIfToBooleanTrue>; public: - explicit BranchIfToBooleanTrue(size_t input_count, - BasicBlockRef* if_true_refs, + explicit BranchIfToBooleanTrue(BasicBlockRef* if_true_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(); @@ -1414,10 +1368,9 @@ class BranchIfCompare Input& left_input() { return NodeBase::input(kLeftIndex); } Input& right_input() { return NodeBase::input(kRightIndex); } - explicit BranchIfCompare(size_t input_count, Operation operation, - BasicBlockRef* if_true_refs, + explicit BranchIfCompare(Operation operation, BasicBlockRef* if_true_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 GenerateCode(MaglevCodeGenState*, const ProcessingState&);