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)
MAGLEV_UNIMPLEMENTED_BYTECODE(DeletePropertyStrict)
MAGLEV_UNIMPLEMENTED_BYTECODE(DeletePropertySloppy)
MAGLEV_UNIMPLEMENTED_BYTECODE(GetSuperConstructor)
MAGLEV_UNIMPLEMENTED_BYTECODE(CallAnyReceiver)
// TODO(leszeks): For all of these:
// a) Read feedback and implement inlining
// b) Wrap in a helper.
void MaglevGraphBuilder::VisitCallProperty() {
// TODO(v8:7700): Read feedback and implement inlining
void MaglevGraphBuilder::BuildCallFromRegisterList(
ConvertReceiverMode receiver_mode) {
ValueNode* function = LoadRegister(0);
interpreter::RegisterList args = iterator_.GetRegisterListOperand(1);
ValueNode* context = GetContext();
static constexpr int kTheContextAndTheFunction = 2;
CallProperty* call_property = AddNewNode<CallProperty>(
args.register_count() + kTheContextAndTheFunction, function, context);
// TODO(leszeks): Move this for loop into the CallProperty constructor,
// pre-size the args array.
size_t input_count = args.register_count() + Call::kFixedInputCount;
if (receiver_mode == ConvertReceiverMode::kNullOrUndefined) input_count++;
Call* call = AddNewNode<Call>(input_count, receiver_mode, function, context);
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) {
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* context = GetContext();
CallProperty* call_property =
AddNewNode<CallProperty>({function, context, LoadRegister(1)});
SetAccumulator(call_property);
int argc_count_with_recv = argc_count + 1;
size_t input_count = argc_count_with_recv + Call::kFixedInputCount;
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>(
{function, context, LoadRegister(1), LoadRegister(2)});
SetAccumulator(call_property);
void MaglevGraphBuilder::VisitCallAnyReceiver() {
BuildCallFromRegisterList(ConvertReceiverMode::kAny);
}
void MaglevGraphBuilder::VisitCallProperty() {
BuildCallFromRegisterList(ConvertReceiverMode::kNotNullOrUndefined);
}
void MaglevGraphBuilder::VisitCallProperty0() {
BuildCallFromRegisters(0, ConvertReceiverMode::kNotNullOrUndefined);
}
void MaglevGraphBuilder::VisitCallProperty1() {
BuildCallFromRegisters(1, ConvertReceiverMode::kNotNullOrUndefined);
}
void MaglevGraphBuilder::VisitCallProperty2() {
ValueNode* function = LoadRegister(0);
ValueNode* context = GetContext();
CallProperty* call_property = AddNewNode<CallProperty>(
{function, context, LoadRegister(1), LoadRegister(2), LoadRegister(3)});
SetAccumulator(call_property);
BuildCallFromRegisters(2, ConvertReceiverMode::kNotNullOrUndefined);
}
void MaglevGraphBuilder::VisitCallUndefinedReceiver() {
BuildCallFromRegisterList(ConvertReceiverMode::kNullOrUndefined);
}
void MaglevGraphBuilder::VisitCallUndefinedReceiver0() {
BuildCallFromRegisters(0, ConvertReceiverMode::kNullOrUndefined);
}
MAGLEV_UNIMPLEMENTED_BYTECODE(CallUndefinedReceiver)
MAGLEV_UNIMPLEMENTED_BYTECODE(CallUndefinedReceiver0)
MAGLEV_UNIMPLEMENTED_BYTECODE(CallUndefinedReceiver1)
MAGLEV_UNIMPLEMENTED_BYTECODE(CallUndefinedReceiver2)
void MaglevGraphBuilder::VisitCallUndefinedReceiver1() {
BuildCallFromRegisters(1, ConvertReceiverMode::kNullOrUndefined);
}
void MaglevGraphBuilder::VisitCallUndefinedReceiver2() {
BuildCallFromRegisters(2, ConvertReceiverMode::kNullOrUndefined);
}
MAGLEV_UNIMPLEMENTED_BYTECODE(CallWithSpread)
MAGLEV_UNIMPLEMENTED_BYTECODE(CallRuntime)
MAGLEV_UNIMPLEMENTED_BYTECODE(CallRuntimeForPair)
......
......@@ -285,6 +285,10 @@ class MaglevGraphBuilder {
return block;
}
void BuildCallFromRegisterList(ConvertReceiverMode receiver_mode);
void BuildCallFromRegisters(int argc_count,
ConvertReceiverMode receiver_mode);
template <Operation kOperation>
void BuildGenericUnaryOperationNode();
template <Operation kOperation>
......
......@@ -719,8 +719,8 @@ void Phi::PrintParams(std::ostream& os,
os << "(" << owner().ToString() << ")";
}
void CallProperty::AllocateVreg(MaglevVregAllocationState* vreg_state,
const ProcessingState& state) {
void Call::AllocateVreg(MaglevVregAllocationState* vreg_state,
const ProcessingState& state) {
UseFixed(function(), CallTrampolineDescriptor::GetRegisterParameter(
CallTrampolineDescriptor::kFunction));
UseFixed(context(), kContextRegister);
......@@ -729,8 +729,8 @@ void CallProperty::AllocateVreg(MaglevVregAllocationState* vreg_state,
}
DefineAsFixed(vreg_state, this, kReturnRegister0);
}
void CallProperty::GenerateCode(MaglevCodeGenState* code_gen_state,
const ProcessingState& state) {
void Call::GenerateCode(MaglevCodeGenState* code_gen_state,
const ProcessingState& state) {
// TODO(leszeks): Port the nice Sparkplug CallBuiltin helper.
DCHECK_EQ(ToRegister(function()),
......@@ -749,16 +749,17 @@ void CallProperty::GenerateCode(MaglevCodeGenState* code_gen_state,
// TODO(leszeks): This doesn't collect feedback yet, either pass in the
// feedback vector by Handle.
__ CallBuiltin(Builtin::kCall_ReceiverIsNotNullOrUndefined);
}
void CallUndefinedReceiver::AllocateVreg(MaglevVregAllocationState* vreg_state,
const ProcessingState& state) {
UNREACHABLE();
}
void CallUndefinedReceiver::GenerateCode(MaglevCodeGenState* code_gen_state,
const ProcessingState& state) {
UNREACHABLE();
switch (receiver_mode_) {
case ConvertReceiverMode::kNullOrUndefined:
__ CallBuiltin(Builtin::kCall_ReceiverIsNullOrUndefined);
break;
case ConvertReceiverMode::kNotNullOrUndefined:
__ CallBuiltin(Builtin::kCall_ReceiverIsNotNullOrUndefined);
break;
case ConvertReceiverMode::kAny:
__ CallBuiltin(Builtin::kCall_ReceiverIsAny);
break;
}
}
// ---
......
......@@ -63,8 +63,7 @@ class CompactInterpreterFrameState;
V(GenericGreaterThanOrEqual)
#define VALUE_NODE_LIST(V) \
V(CallProperty) \
V(CallUndefinedReceiver) \
V(Call) \
V(Constant) \
V(InitialValue) \
V(LoadField) \
......@@ -1074,54 +1073,42 @@ class Phi : public ValueNodeT<Phi> {
friend base::ThreadedListTraits<Phi>;
};
class CallProperty : public ValueNodeT<CallProperty> {
using Base = ValueNodeT<CallProperty>;
class Call : public ValueNodeT<Call> {
using Base = ValueNodeT<Call>;
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.
// Inputs must be initialized manually.
CallProperty(size_t input_count, ValueNode* function, ValueNode* context)
: Base(input_count) {
set_input(0, function);
set_input(1, context);
Call(size_t input_count, ConvertReceiverMode mode, ValueNode* function,
ValueNode* context)
: Base(input_count), receiver_mode_(mode) {
set_input(kFunctionIndex, function);
set_input(kContextIndex, context);
}
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); }
Input& function() { return input(kFunctionIndex); }
const Input& function() const { return input(kFunctionIndex); }
Input& context() { return input(kContextIndex); }
const Input& context() const { return input(kContextIndex); }
int num_args() const { return input_count() - kFixedInputCount; }
Input& arg(int i) { return input(i + kFixedInputCount); }
void set_arg(int i, ValueNode* node) {
set_input(i + kFixedInputCount, node);
}
void AllocateVreg(MaglevVregAllocationState*, const ProcessingState&);
void GenerateCode(MaglevCodeGenState*, const ProcessingState&);
void PrintParams(std::ostream&, MaglevGraphLabeller*) const {}
};
class CallUndefinedReceiver : public ValueNodeT<CallUndefinedReceiver> {
using Base = ValueNodeT<CallUndefinedReceiver>;
public:
explicit CallUndefinedReceiver(size_t input_count) : Base(input_count) {}
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 {}
private:
ConvertReceiverMode receiver_mode_;
};
// 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