Commit 818fa541 authored by Leszek Swirski's avatar Leszek Swirski Committed by V8 LUCI CQ

[maglev] Clean-up SetAccumulator

Bring back raw SetAccumulator, instead of the separate
SetAccumulatorToNew/ExistingNode. SetAccumulator (and StoreRegister) are
now expected to only ever be called on new Nodes, with some DCHECKs
tracking which nodes are new guaranteeing this.

Bug: v8:7700
Change-Id: I5657fa85dc05445bc3d6956ebcd5541ec1cedfad
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3579362
Auto-Submit: Leszek Swirski <leszeks@chromium.org>
Reviewed-by: 's avatarVictor Gomes <victorgomes@chromium.org>
Commit-Queue: Leszek Swirski <leszeks@chromium.org>
Cr-Commit-Position: refs/heads/main@{#79908}
parent 53bdb1fb
This diff is collapsed.
...@@ -113,6 +113,10 @@ class MaglevGraphBuilder { ...@@ -113,6 +113,10 @@ class MaglevGraphBuilder {
StartNewBlock(offset); StartNewBlock(offset);
} }
DCHECK_NOT_NULL(current_block_); DCHECK_NOT_NULL(current_block_);
#ifdef DEBUG
// Clear new nodes for the next VisitFoo
new_nodes_.clear();
#endif
switch (iterator_.current_bytecode()) { switch (iterator_.current_bytecode()) {
#define BYTECODE_CASE(name, ...) \ #define BYTECODE_CASE(name, ...) \
case interpreter::Bytecode::k##name: \ case interpreter::Bytecode::k##name: \
...@@ -134,6 +138,9 @@ class MaglevGraphBuilder { ...@@ -134,6 +138,9 @@ class MaglevGraphBuilder {
} }
current_block_->nodes().Add(node); current_block_->nodes().Add(node);
if (has_graph_labeller()) graph_labeller()->RegisterNode(node); if (has_graph_labeller()) graph_labeller()->RegisterNode(node);
#ifdef DEBUG
new_nodes_.insert(node);
#endif
return node; return node;
} }
...@@ -180,39 +187,30 @@ class MaglevGraphBuilder { ...@@ -180,39 +187,30 @@ class MaglevGraphBuilder {
operand_index, isolate()))); operand_index, isolate())));
} }
// For cases where we're setting the accumulator to a previously created node ValueNode* GetConstant(const compiler::ObjectRef& ref) {
// (e.g. moving an interpreter register to the accumulator). if (ref.IsSmi()) {
// TODO(leszeks): Somehow DCHECK that this isn't a new node. return AddNewNode<SmiConstant>({}, Smi::FromInt(ref.AsSmi()));
void SetAccumulatorToExistingNode(ValueNode* node) {
current_interpreter_frame_.set_accumulator(node);
}
template <typename NodeT>
void SetAccumulatorToNewNode(NodeT* node) {
DCHECK_EQ(NodeT::kProperties.can_lazy_deopt(),
node->properties().can_lazy_deopt());
if constexpr (NodeT::kProperties.can_lazy_deopt()) {
DCHECK(!node->lazy_deopt_info()->result_location.is_valid());
node->lazy_deopt_info()->result_location =
interpreter::Register::virtual_accumulator();
} }
SetAccumulatorToExistingNode(node); // TODO(leszeks): Detect roots and use RootConstant.
return AddNewNode<Constant>({}, ref.AsHeapObject());
} }
template <typename NodeT, typename... Args> // Move an existing ValueNode between two registers. You can pass
void SetAccumulatorToNewNode(std::initializer_list<ValueNode*> inputs, // virtual_accumulator as the src or dst to move in or out of the accumulator.
Args&&... args) { void MoveNodeBetweenRegisters(interpreter::Register src,
NodeT* node = AddNewNode<NodeT>(inputs, args...); interpreter::Register dst) {
SetAccumulatorToNewNode(node); // We shouldn't be moving newly created nodes between registers.
DCHECK_EQ(0, new_nodes_.count(current_interpreter_frame_.get(src)));
DCHECK_NOT_NULL(current_interpreter_frame_.get(src));
current_interpreter_frame_.set(dst, current_interpreter_frame_.get(src));
} }
void SetAccumulatorToConstant(const compiler::ObjectRef& ref) { template <typename NodeT>
if (ref.IsSmi()) { void SetAccumulator(NodeT* node) {
return SetAccumulatorToNewNode<SmiConstant>({}, // Accumulator stores are equivalent to stores to the virtual accumulator
Smi::FromInt(ref.AsSmi())); // register.
} StoreRegister(interpreter::Register::virtual_accumulator(), node);
// TODO(leszeks): Detect roots and use RootConstant.
SetAccumulatorToNewNode<Constant>({}, ref.AsHeapObject());
} }
ValueNode* GetAccumulator() const { ValueNode* GetAccumulator() const {
...@@ -224,11 +222,13 @@ class MaglevGraphBuilder { ...@@ -224,11 +222,13 @@ class MaglevGraphBuilder {
return current_interpreter_frame_.get(source); return current_interpreter_frame_.get(source);
} }
void StoreRegister(interpreter::Register target, ValueNode* value, template <typename NodeT>
const compiler::BytecodeLivenessState* liveness) { void StoreRegister(interpreter::Register target, NodeT* value) {
if (target.index() >= 0 && !liveness->RegisterIsLive(target.index())) { // We should only set register values to nodes that were newly created in
return; // this Visit. Existing nodes should be moved between registers with
} // MoveNodeBetweenRegisters.
DCHECK_NE(0, new_nodes_.count(value));
MarkAsLazyDeoptResult(value, target);
current_interpreter_frame_.set(target, value); current_interpreter_frame_.set(target, value);
} }
...@@ -249,6 +249,18 @@ class MaglevGraphBuilder { ...@@ -249,6 +249,18 @@ class MaglevGraphBuilder {
*compilation_unit_, GetOutLiveness(), current_interpreter_frame_)); *compilation_unit_, GetOutLiveness(), current_interpreter_frame_));
} }
template <typename NodeT>
void MarkAsLazyDeoptResult(NodeT* value,
interpreter::Register result_location) {
DCHECK_EQ(NodeT::kProperties.can_lazy_deopt(),
value->properties().can_lazy_deopt());
if constexpr (NodeT::kProperties.can_lazy_deopt()) {
DCHECK(result_location.is_valid());
DCHECK(!value->lazy_deopt_info()->result_location.is_valid());
value->lazy_deopt_info()->result_location = result_location;
}
}
void MarkPossibleSideEffect() { void MarkPossibleSideEffect() {
// If there was a potential side effect, invalidate the previous checkpoint. // If there was a potential side effect, invalidate the previous checkpoint.
latest_checkpointed_state_.reset(); latest_checkpointed_state_.reset();
...@@ -424,6 +436,10 @@ class MaglevGraphBuilder { ...@@ -424,6 +436,10 @@ class MaglevGraphBuilder {
// TODO(v8:7700): Clean up after all bytecodes are supported. // TODO(v8:7700): Clean up after all bytecodes are supported.
bool found_unsupported_bytecode_ = false; bool found_unsupported_bytecode_ = false;
bool this_field_will_be_unused_once_all_bytecodes_are_supported_; bool this_field_will_be_unused_once_all_bytecodes_are_supported_;
#ifdef DEBUG
std::unordered_set<Node*> new_nodes_;
#endif
}; };
} // namespace maglev } // namespace maglev
......
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