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 {
StartNewBlock(offset);
}
DCHECK_NOT_NULL(current_block_);
#ifdef DEBUG
// Clear new nodes for the next VisitFoo
new_nodes_.clear();
#endif
switch (iterator_.current_bytecode()) {
#define BYTECODE_CASE(name, ...) \
case interpreter::Bytecode::k##name: \
......@@ -134,6 +138,9 @@ class MaglevGraphBuilder {
}
current_block_->nodes().Add(node);
if (has_graph_labeller()) graph_labeller()->RegisterNode(node);
#ifdef DEBUG
new_nodes_.insert(node);
#endif
return node;
}
......@@ -180,39 +187,30 @@ class MaglevGraphBuilder {
operand_index, isolate())));
}
// For cases where we're setting the accumulator to a previously created node
// (e.g. moving an interpreter register to the accumulator).
// TODO(leszeks): Somehow DCHECK that this isn't a new node.
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();
ValueNode* GetConstant(const compiler::ObjectRef& ref) {
if (ref.IsSmi()) {
return AddNewNode<SmiConstant>({}, Smi::FromInt(ref.AsSmi()));
}
SetAccumulatorToExistingNode(node);
// TODO(leszeks): Detect roots and use RootConstant.
return AddNewNode<Constant>({}, ref.AsHeapObject());
}
template <typename NodeT, typename... Args>
void SetAccumulatorToNewNode(std::initializer_list<ValueNode*> inputs,
Args&&... args) {
NodeT* node = AddNewNode<NodeT>(inputs, args...);
SetAccumulatorToNewNode(node);
}
// Move an existing ValueNode between two registers. You can pass
// virtual_accumulator as the src or dst to move in or out of the accumulator.
void MoveNodeBetweenRegisters(interpreter::Register src,
interpreter::Register dst) {
// 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));
void SetAccumulatorToConstant(const compiler::ObjectRef& ref) {
if (ref.IsSmi()) {
return SetAccumulatorToNewNode<SmiConstant>({},
Smi::FromInt(ref.AsSmi()));
current_interpreter_frame_.set(dst, current_interpreter_frame_.get(src));
}
// TODO(leszeks): Detect roots and use RootConstant.
SetAccumulatorToNewNode<Constant>({}, ref.AsHeapObject());
template <typename NodeT>
void SetAccumulator(NodeT* node) {
// Accumulator stores are equivalent to stores to the virtual accumulator
// register.
StoreRegister(interpreter::Register::virtual_accumulator(), node);
}
ValueNode* GetAccumulator() const {
......@@ -224,11 +222,13 @@ class MaglevGraphBuilder {
return current_interpreter_frame_.get(source);
}
void StoreRegister(interpreter::Register target, ValueNode* value,
const compiler::BytecodeLivenessState* liveness) {
if (target.index() >= 0 && !liveness->RegisterIsLive(target.index())) {
return;
}
template <typename NodeT>
void StoreRegister(interpreter::Register target, NodeT* value) {
// We should only set register values to nodes that were newly created in
// 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);
}
......@@ -249,6 +249,18 @@ class MaglevGraphBuilder {
*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() {
// If there was a potential side effect, invalidate the previous checkpoint.
latest_checkpointed_state_.reset();
......@@ -424,6 +436,10 @@ class MaglevGraphBuilder {
// TODO(v8:7700): Clean up after all bytecodes are supported.
bool found_unsupported_bytecode_ = false;
bool this_field_will_be_unused_once_all_bytecodes_are_supported_;
#ifdef DEBUG
std::unordered_set<Node*> new_nodes_;
#endif
};
} // 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