%PDF- %PDF-
| Direktori : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/deps/v8/src/compiler/turboshaft/ |
| Current File : /home/vacivi36/vittasync.vacivitta.com.br/vittasync/node/deps/v8/src/compiler/turboshaft/use-map.cc |
// Copyright 2023 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/compiler/turboshaft/use-map.h"
#include "src/compiler/turboshaft/graph.h"
namespace v8::internal::compiler::turboshaft {
UseMap::UseMap(const Graph& graph, Zone* zone)
: table_(graph.op_id_count(), zone), uses_(zone), saturated_uses_(zone) {
std::vector<std::pair<OpIndex, OpIndex>> delayed_phi_uses;
// We preallocate for 2 uses per operation.
uses_.reserve(graph.op_id_count() * 2);
// We skip {offset:0} to use {offset == 0} as uninitialized.
uint32_t offset = 1;
for (uint32_t index = 0; index < graph.block_count(); ++index) {
BlockIndex block_index(index);
const Block& block = graph.Get(block_index);
auto block_ops = graph.OperationIndices(block);
for (OpIndex op_index : block_ops) {
const Operation& op = graph.Get(op_index);
// When we see a definition, we allocate space in the {uses_}.
DCHECK_EQ(table_[op_index].offset, 0);
DCHECK_EQ(table_[op_index].count, 0);
if (op.saturated_use_count.IsSaturated()) {
table_[op_index].offset =
-static_cast<int32_t>(saturated_uses_.size()) - 1;
saturated_uses_.emplace_back(zone);
saturated_uses_.back().reserve(std::numeric_limits<uint8_t>::max());
} else {
table_[op_index].offset = offset;
offset += op.saturated_use_count.Get();
uses_.resize(offset);
}
if (block.IsLoop()) {
if (op.Is<PhiOp>()) {
DCHECK_EQ(op.input_count, 2);
DCHECK_EQ(PhiOp::kLoopPhiBackEdgeIndex, 1);
AddUse(&graph, op.input(0), op_index);
// Delay back edge of loop Phis.
delayed_phi_uses.emplace_back(op.input(1), op_index);
continue;
}
}
// Add uses.
for (OpIndex input_index : op.inputs()) {
AddUse(&graph, input_index, op_index);
}
}
}
for (auto [input_index, op_index] : delayed_phi_uses) {
AddUse(&graph, input_index, op_index);
}
}
base::Vector<const OpIndex> UseMap::uses(OpIndex index) const {
DCHECK(index.valid());
int32_t offset = table_[index].offset;
uint32_t count = table_[index].count;
DCHECK_NE(offset, 0);
if (V8_LIKELY(offset > 0)) {
return base::Vector<const OpIndex>(uses_.data() + offset, count);
} else {
DCHECK_EQ(count, saturated_uses_[-offset - 1].size());
return base::Vector<const OpIndex>(saturated_uses_[-offset - 1].data(),
count);
}
}
void UseMap::AddUse(const Graph* graph, OpIndex node, OpIndex use) {
int32_t input_offset = table_[node].offset;
uint32_t& input_count = table_[node].count;
DCHECK_NE(input_offset, 0);
if (V8_LIKELY(input_offset > 0)) {
DCHECK_LT(input_count, graph->Get(node).saturated_use_count.Get());
DCHECK(!uses_[input_offset + input_count].valid());
uses_[input_offset + input_count] = use;
} else {
ZoneVector<OpIndex>& uses = saturated_uses_[-input_offset - 1];
DCHECK_EQ(uses.size(), input_count);
uses.emplace_back(use);
}
++input_count;
}
} // namespace v8::internal::compiler::turboshaft