Commit 0bfd4cc1 authored by Victor Gomes's avatar Victor Gomes Committed by V8 LUCI CQ

[maglev] Build Call IR nodes

Bug: v8:7700
Change-Id: I60b47808360430ecfde528cf6429fcc24e84fc31
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3555766Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Auto-Submit: Victor Gomes <victorgomes@chromium.org>
Commit-Queue: Victor Gomes <victorgomes@chromium.org>
Cr-Commit-Position: refs/heads/main@{#79653}
parent 54bb4b2e
...@@ -361,55 +361,83 @@ MAGLEV_UNIMPLEMENTED_BYTECODE(TypeOf) ...@@ -361,55 +361,83 @@ MAGLEV_UNIMPLEMENTED_BYTECODE(TypeOf)
MAGLEV_UNIMPLEMENTED_BYTECODE(DeletePropertyStrict) MAGLEV_UNIMPLEMENTED_BYTECODE(DeletePropertyStrict)
MAGLEV_UNIMPLEMENTED_BYTECODE(DeletePropertySloppy) MAGLEV_UNIMPLEMENTED_BYTECODE(DeletePropertySloppy)
MAGLEV_UNIMPLEMENTED_BYTECODE(GetSuperConstructor) MAGLEV_UNIMPLEMENTED_BYTECODE(GetSuperConstructor)
MAGLEV_UNIMPLEMENTED_BYTECODE(CallAnyReceiver)
// TODO(leszeks): For all of these: // TODO(v8:7700): Read feedback and implement inlining
// a) Read feedback and implement inlining void MaglevGraphBuilder::BuildCallFromRegisterList(
// b) Wrap in a helper. ConvertReceiverMode receiver_mode) {
void MaglevGraphBuilder::VisitCallProperty() {
ValueNode* function = LoadRegister(0); ValueNode* function = LoadRegister(0);
interpreter::RegisterList args = iterator_.GetRegisterListOperand(1); interpreter::RegisterList args = iterator_.GetRegisterListOperand(1);
ValueNode* context = GetContext(); ValueNode* context = GetContext();
static constexpr int kTheContextAndTheFunction = 2; size_t input_count = args.register_count() + Call::kFixedInputCount;
CallProperty* call_property = AddNewNode<CallProperty>( if (receiver_mode == ConvertReceiverMode::kNullOrUndefined) input_count++;
args.register_count() + kTheContextAndTheFunction, function, context);
// TODO(leszeks): Move this for loop into the CallProperty constructor, Call* call = AddNewNode<Call>(input_count, receiver_mode, function, context);
// pre-size the args array. int arg_index = 0;
if (receiver_mode == ConvertReceiverMode::kNullOrUndefined) {
call->set_arg(arg_index++,
AddNewNode<RootConstant>({}, RootIndex::kUndefinedValue));
}
for (int i = 0; i < args.register_count(); ++i) { for (int i = 0; i < args.register_count(); ++i) {
call_property->set_arg(i, current_interpreter_frame_.get(args[i])); call->set_arg(arg_index++, current_interpreter_frame_.get(args[i]));
} }
SetAccumulator(call_property);
SetAccumulator(call);
} }
void MaglevGraphBuilder::VisitCallProperty0() {
void MaglevGraphBuilder::BuildCallFromRegisters(
int argc_count, ConvertReceiverMode receiver_mode) {
DCHECK_LE(argc_count, 2);
ValueNode* function = LoadRegister(0); ValueNode* function = LoadRegister(0);
ValueNode* context = GetContext(); ValueNode* context = GetContext();
CallProperty* call_property = int argc_count_with_recv = argc_count + 1;
AddNewNode<CallProperty>({function, context, LoadRegister(1)}); size_t input_count = argc_count_with_recv + Call::kFixedInputCount;
SetAccumulator(call_property);
Call* call = AddNewNode<Call>(input_count, receiver_mode, function, context);
int arg_index = 0;
int reg_count = argc_count_with_recv;
if (receiver_mode == ConvertReceiverMode::kNullOrUndefined) {
reg_count = argc_count;
call->set_arg(arg_index++,
AddNewNode<RootConstant>({}, RootIndex::kUndefinedValue));
}
for (int i = 0; i < reg_count; i++) {
call->set_arg(arg_index++, LoadRegister(i + 1));
}
SetAccumulator(call);
} }
void MaglevGraphBuilder::VisitCallProperty1() {
ValueNode* function = LoadRegister(0);
ValueNode* context = GetContext();
CallProperty* call_property = AddNewNode<CallProperty>( void MaglevGraphBuilder::VisitCallAnyReceiver() {
{function, context, LoadRegister(1), LoadRegister(2)}); BuildCallFromRegisterList(ConvertReceiverMode::kAny);
SetAccumulator(call_property); }
void MaglevGraphBuilder::VisitCallProperty() {
BuildCallFromRegisterList(ConvertReceiverMode::kNotNullOrUndefined);
}
void MaglevGraphBuilder::VisitCallProperty0() {
BuildCallFromRegisters(0, ConvertReceiverMode::kNotNullOrUndefined);
}
void MaglevGraphBuilder::VisitCallProperty1() {
BuildCallFromRegisters(1, ConvertReceiverMode::kNotNullOrUndefined);
} }
void MaglevGraphBuilder::VisitCallProperty2() { void MaglevGraphBuilder::VisitCallProperty2() {
ValueNode* function = LoadRegister(0); BuildCallFromRegisters(2, ConvertReceiverMode::kNotNullOrUndefined);
ValueNode* context = GetContext(); }
void MaglevGraphBuilder::VisitCallUndefinedReceiver() {
CallProperty* call_property = AddNewNode<CallProperty>( BuildCallFromRegisterList(ConvertReceiverMode::kNullOrUndefined);
{function, context, LoadRegister(1), LoadRegister(2), LoadRegister(3)}); }
SetAccumulator(call_property); void MaglevGraphBuilder::VisitCallUndefinedReceiver0() {
BuildCallFromRegisters(0, ConvertReceiverMode::kNullOrUndefined);
} }
MAGLEV_UNIMPLEMENTED_BYTECODE(CallUndefinedReceiver) void MaglevGraphBuilder::VisitCallUndefinedReceiver1() {
MAGLEV_UNIMPLEMENTED_BYTECODE(CallUndefinedReceiver0) BuildCallFromRegisters(1, ConvertReceiverMode::kNullOrUndefined);
MAGLEV_UNIMPLEMENTED_BYTECODE(CallUndefinedReceiver1) }
MAGLEV_UNIMPLEMENTED_BYTECODE(CallUndefinedReceiver2) void MaglevGraphBuilder::VisitCallUndefinedReceiver2() {
BuildCallFromRegisters(2, ConvertReceiverMode::kNullOrUndefined);
}
MAGLEV_UNIMPLEMENTED_BYTECODE(CallWithSpread) MAGLEV_UNIMPLEMENTED_BYTECODE(CallWithSpread)
MAGLEV_UNIMPLEMENTED_BYTECODE(CallRuntime) MAGLEV_UNIMPLEMENTED_BYTECODE(CallRuntime)
MAGLEV_UNIMPLEMENTED_BYTECODE(CallRuntimeForPair) MAGLEV_UNIMPLEMENTED_BYTECODE(CallRuntimeForPair)
......
...@@ -285,6 +285,10 @@ class MaglevGraphBuilder { ...@@ -285,6 +285,10 @@ class MaglevGraphBuilder {
return block; return block;
} }
void BuildCallFromRegisterList(ConvertReceiverMode receiver_mode);
void BuildCallFromRegisters(int argc_count,
ConvertReceiverMode receiver_mode);
template <Operation kOperation> template <Operation kOperation>
void BuildGenericUnaryOperationNode(); void BuildGenericUnaryOperationNode();
template <Operation kOperation> template <Operation kOperation>
......
...@@ -719,8 +719,8 @@ void Phi::PrintParams(std::ostream& os, ...@@ -719,8 +719,8 @@ void Phi::PrintParams(std::ostream& os,
os << "(" << owner().ToString() << ")"; os << "(" << owner().ToString() << ")";
} }
void CallProperty::AllocateVreg(MaglevVregAllocationState* vreg_state, void Call::AllocateVreg(MaglevVregAllocationState* vreg_state,
const ProcessingState& state) { const ProcessingState& state) {
UseFixed(function(), CallTrampolineDescriptor::GetRegisterParameter( UseFixed(function(), CallTrampolineDescriptor::GetRegisterParameter(
CallTrampolineDescriptor::kFunction)); CallTrampolineDescriptor::kFunction));
UseFixed(context(), kContextRegister); UseFixed(context(), kContextRegister);
...@@ -729,8 +729,8 @@ void CallProperty::AllocateVreg(MaglevVregAllocationState* vreg_state, ...@@ -729,8 +729,8 @@ void CallProperty::AllocateVreg(MaglevVregAllocationState* vreg_state,
} }
DefineAsFixed(vreg_state, this, kReturnRegister0); DefineAsFixed(vreg_state, this, kReturnRegister0);
} }
void CallProperty::GenerateCode(MaglevCodeGenState* code_gen_state, void Call::GenerateCode(MaglevCodeGenState* code_gen_state,
const ProcessingState& state) { const ProcessingState& state) {
// TODO(leszeks): Port the nice Sparkplug CallBuiltin helper. // TODO(leszeks): Port the nice Sparkplug CallBuiltin helper.
DCHECK_EQ(ToRegister(function()), DCHECK_EQ(ToRegister(function()),
...@@ -749,16 +749,17 @@ void CallProperty::GenerateCode(MaglevCodeGenState* code_gen_state, ...@@ -749,16 +749,17 @@ void CallProperty::GenerateCode(MaglevCodeGenState* code_gen_state,
// TODO(leszeks): This doesn't collect feedback yet, either pass in the // TODO(leszeks): This doesn't collect feedback yet, either pass in the
// feedback vector by Handle. // feedback vector by Handle.
__ CallBuiltin(Builtin::kCall_ReceiverIsNotNullOrUndefined); switch (receiver_mode_) {
} case ConvertReceiverMode::kNullOrUndefined:
__ CallBuiltin(Builtin::kCall_ReceiverIsNullOrUndefined);
void CallUndefinedReceiver::AllocateVreg(MaglevVregAllocationState* vreg_state, break;
const ProcessingState& state) { case ConvertReceiverMode::kNotNullOrUndefined:
UNREACHABLE(); __ CallBuiltin(Builtin::kCall_ReceiverIsNotNullOrUndefined);
} break;
void CallUndefinedReceiver::GenerateCode(MaglevCodeGenState* code_gen_state, case ConvertReceiverMode::kAny:
const ProcessingState& state) { __ CallBuiltin(Builtin::kCall_ReceiverIsAny);
UNREACHABLE(); break;
}
} }
// --- // ---
......
...@@ -63,8 +63,7 @@ class CompactInterpreterFrameState; ...@@ -63,8 +63,7 @@ class CompactInterpreterFrameState;
V(GenericGreaterThanOrEqual) V(GenericGreaterThanOrEqual)
#define VALUE_NODE_LIST(V) \ #define VALUE_NODE_LIST(V) \
V(CallProperty) \ V(Call) \
V(CallUndefinedReceiver) \
V(Constant) \ V(Constant) \
V(InitialValue) \ V(InitialValue) \
V(LoadField) \ V(LoadField) \
...@@ -1074,54 +1073,42 @@ class Phi : public ValueNodeT<Phi> { ...@@ -1074,54 +1073,42 @@ class Phi : public ValueNodeT<Phi> {
friend base::ThreadedListTraits<Phi>; friend base::ThreadedListTraits<Phi>;
}; };
class CallProperty : public ValueNodeT<CallProperty> { class Call : public ValueNodeT<Call> {
using Base = ValueNodeT<CallProperty>; using Base = ValueNodeT<Call>;
public: public:
explicit CallProperty(size_t input_count) : Base(input_count) {} // We assume function and context as fixed inputs.
static constexpr int kFunctionIndex = 0;
static constexpr int kContextIndex = 1;
static constexpr int kFixedInputCount = 2;
// 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) Call(size_t input_count, ConvertReceiverMode mode, ValueNode* function,
: Base(input_count) { ValueNode* context)
set_input(0, function); : Base(input_count), receiver_mode_(mode) {
set_input(1, context); set_input(kFunctionIndex, function);
set_input(kContextIndex, context);
} }
static constexpr OpProperties kProperties = OpProperties::JSCall(); static constexpr OpProperties kProperties = OpProperties::JSCall();
Input& function() { return input(0); } Input& function() { return input(kFunctionIndex); }
const Input& function() const { return input(0); } const Input& function() const { return input(kFunctionIndex); }
Input& context() { return input(1); } Input& context() { return input(kContextIndex); }
const Input& context() const { return input(1); } const Input& context() const { return input(kContextIndex); }
int num_args() const { return input_count() - 2; } int num_args() const { return input_count() - kFixedInputCount; }
Input& arg(int i) { return input(i + 2); } Input& arg(int i) { return input(i + kFixedInputCount); }
void set_arg(int i, ValueNode* node) { set_input(i + 2, node); } void set_arg(int i, ValueNode* node) {
set_input(i + kFixedInputCount, node);
}
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 {}
};
class CallUndefinedReceiver : public ValueNodeT<CallUndefinedReceiver> {
using Base = ValueNodeT<CallUndefinedReceiver>;
public: private:
explicit CallUndefinedReceiver(size_t input_count) : Base(input_count) {} ConvertReceiverMode receiver_mode_;
static constexpr OpProperties kProperties = OpProperties::JSCall();
Input& function() { return input(0); }
const Input& function() const { return input(0); }
Input& context() { return input(1); }
const Input& context() const { return input(1); }
int num_args() const { return input_count() - 2; }
Input& arg(int i) { return input(i + 2); }
void set_arg(int i, ValueNode* node) { set_input(i + 2, node); }
void AllocateVreg(MaglevVregAllocationState*, const ProcessingState&);
void GenerateCode(MaglevCodeGenState*, const ProcessingState&);
void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
}; };
// Represents either a direct BasicBlock pointer, or an entry in a list of // Represents either a direct BasicBlock pointer, or an entry in a list of
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment