Commit 58fb7d8f authored by Victor Gomes's avatar Victor Gomes Committed by V8 LUCI CQ

[maglev] Add Float64 to ValueRepresentation

... and rename Untagged to Int32.

Bug: v8:7700
Change-Id: Ib206dba74432b3f1f70fd62006cb6a1222b40ed9
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3584114Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Commit-Queue: Victor Gomes <victorgomes@chromium.org>
Auto-Submit: Victor Gomes <victorgomes@chromium.org>
Cr-Commit-Position: refs/heads/main@{#80050}
parent 8d186bb4
......@@ -441,24 +441,47 @@ class MaglevCodeGeneratorImpl final {
deopt_info->input_locations, deopt_info->result_location);
}
void EmitDeoptStoreRegister(const compiler::AllocatedOperand& operand,
ValueRepresentation repr) {
switch (repr) {
case ValueRepresentation::kTagged:
translation_array_builder_.StoreRegister(operand.GetRegister());
break;
case ValueRepresentation::kInt32:
translation_array_builder_.StoreInt32Register(operand.GetRegister());
break;
case ValueRepresentation::kFloat64:
translation_array_builder_.StoreDoubleRegister(
operand.GetDoubleRegister());
break;
}
}
void EmitDeoptStoreStackSlot(const compiler::AllocatedOperand& operand,
ValueRepresentation repr) {
int stack_slot = DeoptStackSlotFromStackSlot(operand);
switch (repr) {
case ValueRepresentation::kTagged:
translation_array_builder_.StoreStackSlot(stack_slot);
break;
case ValueRepresentation::kInt32:
translation_array_builder_.StoreInt32StackSlot(stack_slot);
break;
case ValueRepresentation::kFloat64:
translation_array_builder_.StoreInt64StackSlot(stack_slot);
break;
}
}
void EmitDeoptFrameSingleValue(ValueNode* value,
const InputLocation& input_location) {
const compiler::AllocatedOperand& operand =
compiler::AllocatedOperand::cast(input_location.operand());
ValueRepresentation repr = value->properties().value_representation();
if (operand.IsRegister()) {
if (value->properties().is_untagged_value()) {
translation_array_builder_.StoreInt32Register(operand.GetRegister());
} else {
translation_array_builder_.StoreRegister(operand.GetRegister());
}
EmitDeoptStoreRegister(operand, repr);
} else {
if (value->properties().is_untagged_value()) {
translation_array_builder_.StoreInt32StackSlot(
DeoptStackSlotFromStackSlot(operand));
} else {
translation_array_builder_.StoreStackSlot(
DeoptStackSlotFromStackSlot(operand));
}
EmitDeoptStoreStackSlot(operand, repr);
}
}
......
......@@ -13,7 +13,7 @@ namespace v8 {
namespace internal {
namespace maglev {
enum class ValueRepresentation;
enum class ValueRepresentation : uint8_t;
class MaglevCompilationInfo;
class MaglevGraphLabeller;
class Node;
......
......@@ -143,15 +143,15 @@ using GenericNodeForOperation =
template <Operation kOperation>
void MaglevGraphBuilder::BuildGenericUnaryOperationNode() {
FeedbackSlot slot_index = GetSlotOperand(0);
ValueNode* value = GetAccumulatorTaggedValue();
ValueNode* value = GetAccumulatorTagged();
SetAccumulator(AddNewNode<GenericNodeForOperation<kOperation>>(
{value}, compiler::FeedbackSource{feedback(), slot_index}));
}
template <Operation kOperation>
void MaglevGraphBuilder::BuildGenericBinaryOperationNode() {
ValueNode* left = LoadRegisterTaggedValue(0);
ValueNode* right = GetAccumulatorTaggedValue();
ValueNode* left = LoadRegisterTagged(0);
ValueNode* right = GetAccumulatorTagged();
FeedbackSlot slot_index = GetSlotOperand(1);
SetAccumulator(AddNewNode<GenericNodeForOperation<kOperation>>(
{left, right}, compiler::FeedbackSource{feedback(), slot_index}));
......@@ -159,7 +159,7 @@ void MaglevGraphBuilder::BuildGenericBinaryOperationNode() {
template <Operation kOperation>
void MaglevGraphBuilder::BuildGenericBinarySmiOperationNode() {
ValueNode* left = GetAccumulatorTaggedValue();
ValueNode* left = GetAccumulatorTagged();
Smi constant = Smi::FromInt(iterator_.GetImmediateOperand(0));
ValueNode* right = AddNewNode<SmiConstant>({}, constant);
FeedbackSlot slot_index = GetSlotOperand(1);
......@@ -184,10 +184,10 @@ void MaglevGraphBuilder::VisitBinaryOperation() {
if (hint == BinaryOperationHint::kSignedSmall) {
ValueNode *left, *right;
if (IsRegisterEqualToAccumulator(0)) {
left = right = LoadRegisterSmiUntaggedValue(0);
left = right = LoadRegisterInt32(0);
} else {
left = LoadRegisterSmiUntaggedValue(0);
right = GetAccumulatorSmiUntaggedValue();
left = LoadRegisterInt32(0);
right = GetAccumulatorInt32();
}
if (kOperation == Operation::kAdd) {
......@@ -211,7 +211,7 @@ void MaglevGraphBuilder::VisitBinarySmiOperation() {
BinaryOperationHint hint = nexus.GetBinaryOperationFeedback();
if (hint == BinaryOperationHint::kSignedSmall) {
ValueNode* left = GetAccumulatorSmiUntaggedValue();
ValueNode* left = GetAccumulatorInt32();
int32_t constant = iterator_.GetImmediateOperand(0);
if (kOperation == Operation::kAdd) {
......@@ -396,7 +396,7 @@ MAGLEV_UNIMPLEMENTED_BYTECODE(LdaLookupGlobalSlotInsideTypeof)
MAGLEV_UNIMPLEMENTED_BYTECODE(StaLookupSlot)
void MaglevGraphBuilder::VisitGetNamedProperty() {
// GetNamedProperty <object> <name_index> <slot>
ValueNode* object = LoadRegisterTaggedValue(0);
ValueNode* object = LoadRegisterTagged(0);
compiler::NameRef name = GetRefOperand<Name>(1);
FeedbackSlot slot = GetSlotOperand(2);
compiler::FeedbackSource feedback_source{feedback(), slot};
......@@ -450,7 +450,7 @@ MAGLEV_UNIMPLEMENTED_BYTECODE(StaModuleVariable)
void MaglevGraphBuilder::VisitSetNamedProperty() {
// SetNamedProperty <object> <name_index> <slot>
ValueNode* object = LoadRegisterTaggedValue(0);
ValueNode* object = LoadRegisterTagged(0);
compiler::NameRef name = GetRefOperand<Name>(1);
FeedbackSlot slot = GetSlotOperand(2);
compiler::FeedbackSource feedback_source{feedback(), slot};
......@@ -478,7 +478,7 @@ void MaglevGraphBuilder::VisitSetNamedProperty() {
StoreHandler::Kind kind = StoreHandler::KindBits::decode(smi_handler);
if (kind == StoreHandler::Kind::kField) {
AddNewNode<CheckMaps>({object}, named_feedback.maps()[0]);
ValueNode* value = GetAccumulatorTaggedValue();
ValueNode* value = GetAccumulatorTagged();
AddNewNode<StoreField>({object, value}, smi_handler);
return;
}
......@@ -596,7 +596,7 @@ MAGLEV_UNIMPLEMENTED_BYTECODE(GetSuperConstructor)
// TODO(v8:7700): Read feedback and implement inlining
void MaglevGraphBuilder::BuildCallFromRegisterList(
ConvertReceiverMode receiver_mode) {
ValueNode* function = LoadRegisterTaggedValue(0);
ValueNode* function = LoadRegisterTagged(0);
interpreter::RegisterList args = iterator_.GetRegisterListOperand(1);
ValueNode* context = GetContext();
......@@ -626,7 +626,7 @@ void MaglevGraphBuilder::BuildCallFromRegisterList(
void MaglevGraphBuilder::BuildCallFromRegisters(
int argc_count, ConvertReceiverMode receiver_mode) {
DCHECK_LE(argc_count, 2);
ValueNode* function = LoadRegisterTaggedValue(0);
ValueNode* function = LoadRegisterTagged(0);
ValueNode* context = GetContext();
int argc_count_with_recv = argc_count + 1;
......@@ -647,7 +647,7 @@ void MaglevGraphBuilder::BuildCallFromRegisters(
call->set_arg(arg_index++, undefined_constant);
}
for (int i = 0; i < reg_count; i++) {
call->set_arg(arg_index++, LoadRegisterTaggedValue(i + 1));
call->set_arg(arg_index++, LoadRegisterTagged(i + 1));
}
SetAccumulator(call);
......@@ -808,19 +808,19 @@ void MaglevGraphBuilder::BuildBranchIfToBooleanTrue(ValueNode* node,
MergeIntoFrameState(block, iterator_.GetJumpTargetOffset());
}
void MaglevGraphBuilder::VisitJumpIfToBooleanTrue() {
BuildBranchIfToBooleanTrue(GetAccumulatorTaggedValue(),
BuildBranchIfToBooleanTrue(GetAccumulatorTagged(),
iterator_.GetJumpTargetOffset(), next_offset());
}
void MaglevGraphBuilder::VisitJumpIfToBooleanFalse() {
BuildBranchIfToBooleanTrue(GetAccumulatorTaggedValue(), next_offset(),
BuildBranchIfToBooleanTrue(GetAccumulatorTagged(), next_offset(),
iterator_.GetJumpTargetOffset());
}
void MaglevGraphBuilder::VisitJumpIfTrue() {
BuildBranchIfTrue(GetAccumulatorTaggedValue(),
iterator_.GetJumpTargetOffset(), next_offset());
BuildBranchIfTrue(GetAccumulatorTagged(), iterator_.GetJumpTargetOffset(),
next_offset());
}
void MaglevGraphBuilder::VisitJumpIfFalse() {
BuildBranchIfTrue(GetAccumulatorTaggedValue(), next_offset(),
BuildBranchIfTrue(GetAccumulatorTagged(), next_offset(),
iterator_.GetJumpTargetOffset());
}
MAGLEV_UNIMPLEMENTED_BYTECODE(JumpIfNull)
......@@ -839,7 +839,7 @@ MAGLEV_UNIMPLEMENTED_BYTECODE(SetPendingMessage)
MAGLEV_UNIMPLEMENTED_BYTECODE(Throw)
MAGLEV_UNIMPLEMENTED_BYTECODE(ReThrow)
void MaglevGraphBuilder::VisitReturn() {
FinishBlock<Return>(next_offset(), {GetAccumulatorTaggedValue()});
FinishBlock<Return>(next_offset(), {GetAccumulatorTagged()});
}
MAGLEV_UNIMPLEMENTED_BYTECODE(ThrowReferenceErrorIfHole)
MAGLEV_UNIMPLEMENTED_BYTECODE(ThrowSuperNotCalledIfHole)
......
......@@ -266,8 +266,12 @@ class MaglevGraphBuilder {
ValueNode* GetTaggedValue(interpreter::Register reg) {
// TODO(victorgomes): Add the representation (Tagged/Untagged) in the
// InterpreterFrameState, so that we don't need to derefence a node.
// TODO(victorgomes): Support Float64.
ValueNode* value = current_interpreter_frame_.get(reg);
if (!value->is_untagged_value()) return value;
if (value->properties().value_representation() ==
ValueRepresentation::kTagged) {
return value;
}
if (value->Is<CheckedSmiUntag>()) {
return value->input(0).node();
}
......@@ -277,24 +281,30 @@ class MaglevGraphBuilder {
return tagged;
}
ValueNode* GetSmiUntaggedValue(interpreter::Register reg) {
ValueNode* GetInt32(interpreter::Register reg) {
// TODO(victorgomes): Add the representation (Tagged/Untagged) in the
// InterpreterFrameState, so that we don't need to derefence a node.
// TODO(victorgomes): Support Float64.
ValueNode* value = current_interpreter_frame_.get(reg);
if (value->is_untagged_value()) return value;
if (value->properties().value_representation() ==
ValueRepresentation::kInt32) {
return value;
}
if (value->Is<CheckedSmiTag>()) return value->input(0).node();
// Untag any other value.
DCHECK_EQ(value->properties().value_representation(),
ValueRepresentation::kTagged);
ValueNode* untagged = AddNewNode<CheckedSmiUntag>({value});
current_interpreter_frame_.set(reg, untagged);
return untagged;
}
ValueNode* GetAccumulatorTaggedValue() {
ValueNode* GetAccumulatorTagged() {
return GetTaggedValue(interpreter::Register::virtual_accumulator());
}
ValueNode* GetAccumulatorSmiUntaggedValue() {
return GetSmiUntaggedValue(interpreter::Register::virtual_accumulator());
ValueNode* GetAccumulatorInt32() {
return GetInt32(interpreter::Register::virtual_accumulator());
}
bool IsRegisterEqualToAccumulator(int operand_index) {
......@@ -303,12 +313,12 @@ class MaglevGraphBuilder {
current_interpreter_frame_.accumulator();
}
ValueNode* LoadRegisterTaggedValue(int operand_index) {
ValueNode* LoadRegisterTagged(int operand_index) {
return GetTaggedValue(iterator_.GetRegisterOperand(operand_index));
}
ValueNode* LoadRegisterSmiUntaggedValue(int operand_index) {
return GetSmiUntaggedValue(iterator_.GetRegisterOperand(operand_index));
ValueNode* LoadRegisterInt32(int operand_index) {
return GetInt32(iterator_.GetRegisterOperand(operand_index));
}
template <typename NodeT>
......
......@@ -15,10 +15,13 @@ namespace maglev {
std::ostream& operator<<(std::ostream& os, const ValueRepresentation& repr) {
switch (repr) {
case ValueRepresentation::kTagged:
os << "TaggedValue";
os << "Tagged";
break;
case ValueRepresentation::kUntagged:
os << "UntaggedValue";
case ValueRepresentation::kInt32:
os << "Int32";
break;
case ValueRepresentation::kFloat64:
os << "Float64";
break;
}
return os;
......@@ -39,16 +42,17 @@ class MaglevGraphVerifier {
void PostProcessGraph(MaglevCompilationUnit*, Graph* graph) {}
void PreProcessBasicBlock(MaglevCompilationUnit*, BasicBlock* block) {}
void CheckValueInputIs(NodeBase* node, int i, ValueRepresentation repr) {
void CheckValueInputIs(NodeBase* node, int i, ValueRepresentation expected) {
ValueNode* input = node->input(i).node();
if (input->value_representation() != repr) {
ValueRepresentation got = input->properties().value_representation();
if (got != expected) {
std::ostringstream str;
str << "Type representation error: node ";
if (graph_labeller_) {
str << "#" << graph_labeller_->NodeId(node) << " : ";
}
str << node->opcode() << " (input @" << i << " = " << input->opcode()
<< ") type " << input->value_representation() << " is not " << repr;
<< ") type " << got << " is not " << expected;
FATAL("%s", str.str().c_str());
}
}
......@@ -86,7 +90,7 @@ class MaglevGraphVerifier {
break;
case Opcode::kCheckedSmiTag:
// Untagged unary operations.
CheckValueInputIs(node, 0, ValueRepresentation::kUntagged);
CheckValueInputIs(node, 0, ValueRepresentation::kInt32);
break;
case Opcode::kGenericAdd:
case Opcode::kGenericSubtract:
......@@ -119,8 +123,8 @@ class MaglevGraphVerifier {
break;
case Opcode::kInt32AddWithOverflow:
// Untagged binary operations.
CheckValueInputIs(node, 0, ValueRepresentation::kUntagged);
CheckValueInputIs(node, 1, ValueRepresentation::kUntagged);
CheckValueInputIs(node, 0, ValueRepresentation::kInt32);
CheckValueInputIs(node, 1, ValueRepresentation::kInt32);
break;
case Opcode::kCall:
case Opcode::kPhi:
......
......@@ -370,7 +370,9 @@ class MergePointInterpreterFrameState {
ValueNode* TagValue(MaglevCompilationUnit& compilation_unit,
ValueNode* value) {
DCHECK(value->is_untagged_value());
// TODO(victorgomes): Support Float64.
DCHECK_EQ(value->properties().value_representation(),
ValueRepresentation::kInt32);
if (value->Is<CheckedSmiUntag>()) {
return value->input(0).node();
}
......@@ -395,8 +397,15 @@ class MergePointInterpreterFrameState {
ValueNode* EnsureTagged(MaglevCompilationUnit& compilation_unit,
ValueNode* value) {
if (value->is_untagged_value()) return TagValue(compilation_unit, value);
return value;
switch (value->properties().value_representation()) {
case ValueRepresentation::kTagged:
return value;
case ValueRepresentation::kInt32:
return TagValue(compilation_unit, value);
case ValueRepresentation::kFloat64:
// TOOD(victorgomes): Support Float64.
UNREACHABLE();
}
}
ValueNode* MergeValue(MaglevCompilationUnit& compilation_unit,
......
......@@ -165,10 +165,7 @@ class ConditionalControlNode;
class UnconditionalControlNode;
class ValueNode;
enum class ValueRepresentation {
kTagged,
kUntagged,
};
enum class ValueRepresentation : uint8_t { kTagged, kInt32, kFloat64 };
#define DEF_FORWARD_DECLARATION(type, ...) class type;
NODE_BASE_LIST(DEF_FORWARD_DECLARATION)
......@@ -191,10 +188,9 @@ class OpProperties {
constexpr bool non_memory_side_effects() const {
return kNonMemorySideEffectsBit::decode(bitfield_);
}
constexpr bool is_untagged_value() const {
return kUntaggedValueBit::decode(bitfield_);
constexpr ValueRepresentation value_representation() const {
return kValueRepresentationBits::decode(bitfield_);
}
constexpr bool is_pure() const {
return (bitfield_ | kPureMask) == kPureValue;
}
......@@ -225,8 +221,17 @@ class OpProperties {
static constexpr OpProperties NonMemorySideEffects() {
return OpProperties(kNonMemorySideEffectsBit::encode(true));
}
static constexpr OpProperties UntaggedValue() {
return OpProperties(kUntaggedValueBit::encode(true));
static constexpr OpProperties TaggedValue() {
return OpProperties(
kValueRepresentationBits::encode(ValueRepresentation::kTagged));
}
static constexpr OpProperties Int32() {
return OpProperties(
kValueRepresentationBits::encode(ValueRepresentation::kInt32));
}
static constexpr OpProperties Float64() {
return OpProperties(
kValueRepresentationBits::encode(ValueRepresentation::kFloat64));
}
static constexpr OpProperties JSCall() {
return Call() | NonMemorySideEffects() | LazyDeopt();
......@@ -245,7 +250,8 @@ class OpProperties {
using kCanReadBit = kCanLazyDeoptBit::Next<bool, 1>;
using kCanWriteBit = kCanReadBit::Next<bool, 1>;
using kNonMemorySideEffectsBit = kCanWriteBit::Next<bool, 1>;
using kUntaggedValueBit = kNonMemorySideEffectsBit::Next<bool, 1>;
using kValueRepresentationBits =
kNonMemorySideEffectsBit::Next<ValueRepresentation, 2>;
static const uint32_t kPureMask = kCanReadBit::kMask | kCanWriteBit::kMask |
kNonMemorySideEffectsBit::kMask;
......@@ -256,7 +262,7 @@ class OpProperties {
const uint32_t bitfield_;
public:
static const size_t kSize = kUntaggedValueBit::kLastUsedBit + 1;
static const size_t kSize = kValueRepresentationBits::kLastUsedBit + 1;
};
class ValueLocation {
......@@ -436,7 +442,8 @@ class NodeBase : public ZoneObject {
}
// Overwritten by subclasses.
static constexpr OpProperties kProperties = OpProperties::Pure();
static constexpr OpProperties kProperties =
OpProperties::Pure() | OpProperties::TaggedValue();
constexpr Opcode opcode() const { return OpcodeField::decode(bit_field_); }
OpProperties properties() const {
......@@ -764,13 +771,6 @@ class ValueNode : public Node {
return compiler::AllocatedOperand::cast(spill_or_hint_);
}
bool is_untagged_value() const { return properties().is_untagged_value(); }
ValueRepresentation value_representation() const {
return is_untagged_value() ? ValueRepresentation::kUntagged
: ValueRepresentation::kTagged;
}
protected:
explicit ValueNode(uint32_t bitfield)
: Node(bitfield),
......@@ -966,7 +966,7 @@ class CheckedSmiUntag : public FixedInputValueNodeT<1, CheckedSmiUntag> {
explicit CheckedSmiUntag(uint32_t bitfield) : Base(bitfield) {}
static constexpr OpProperties kProperties =
OpProperties::EagerDeopt() | OpProperties::UntaggedValue();
OpProperties::EagerDeopt() | OpProperties::Int32();
Input& input() { return Node::input(0); }
......@@ -982,7 +982,7 @@ class Int32Constant : public FixedInputValueNodeT<0, Int32Constant> {
explicit Int32Constant(uint32_t bitfield, int32_t value)
: Base(bitfield), value_(value) {}
static constexpr OpProperties kProperties = OpProperties::UntaggedValue();
static constexpr OpProperties kProperties = OpProperties::Int32();
int32_t value() const { return value_; }
......@@ -1002,7 +1002,7 @@ class Int32AddWithOverflow
explicit Int32AddWithOverflow(uint32_t bitfield) : Base(bitfield) {}
static constexpr OpProperties kProperties =
OpProperties::EagerDeopt() | OpProperties::UntaggedValue();
OpProperties::EagerDeopt() | OpProperties::Int32();
static constexpr int kLeftIndex = 0;
static constexpr int kRightIndex = 1;
......
......@@ -668,7 +668,8 @@ void StraightForwardRegisterAllocator::SpillAndClearRegisters() {
void StraightForwardRegisterAllocator::AllocateSpillSlot(ValueNode* node) {
DCHECK(!node->is_spilled());
uint32_t free_slot;
bool is_tagged = node->value_representation() == ValueRepresentation::kTagged;
bool is_tagged = (node->properties().value_representation() ==
ValueRepresentation::kTagged);
SpillSlots& slots = is_tagged ? tagged_ : untagged_;
MachineRepresentation representation = is_tagged
? MachineRepresentation::kTagged
......
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