Commit 5f8ce57d authored by Tobias Tebbi's avatar Tobias Tebbi Committed by V8 LUCI CQ

[turbofan] preserve node origins and emit them with --trace-turbo

Bug: v8:12783, v8:7327

Change-Id: I7c4280b94abc8103472cbef0cf7bb226b918ae32
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3805886Reviewed-by: 's avatarNico Hartmann <nicohartmann@chromium.org>
Commit-Queue: Tobias Tebbi <tebbi@chromium.org>
Cr-Commit-Position: refs/heads/main@{#82229}
parent 0dcb488c
...@@ -45,6 +45,9 @@ void SourcePositionTable::RemoveDecorator() { ...@@ -45,6 +45,9 @@ void SourcePositionTable::RemoveDecorator() {
SourcePosition SourcePositionTable::GetSourcePosition(Node* node) const { SourcePosition SourcePositionTable::GetSourcePosition(Node* node) const {
return table_.Get(node); return table_.Get(node);
} }
SourcePosition SourcePositionTable::GetSourcePosition(NodeId id) const {
return table_.Get(id);
}
void SourcePositionTable::SetSourcePosition(Node* node, void SourcePositionTable::SetSourcePosition(Node* node,
SourcePosition position) { SourcePosition position) {
......
...@@ -49,6 +49,7 @@ class V8_EXPORT_PRIVATE SourcePositionTable final ...@@ -49,6 +49,7 @@ class V8_EXPORT_PRIVATE SourcePositionTable final
void RemoveDecorator(); void RemoveDecorator();
SourcePosition GetSourcePosition(Node* node) const; SourcePosition GetSourcePosition(Node* node) const;
SourcePosition GetSourcePosition(NodeId id) const;
void SetSourcePosition(Node* node, SourcePosition position); void SetSourcePosition(Node* node, SourcePosition position);
void SetCurrentPosition(const SourcePosition& pos) { void SetCurrentPosition(const SourcePosition& pos) {
......
...@@ -69,6 +69,7 @@ V8_INLINE V8_EXPORT_PRIVATE NodeOriginAsJSON AsJSON(const NodeOrigin& no) { ...@@ -69,6 +69,7 @@ V8_INLINE V8_EXPORT_PRIVATE NodeOriginAsJSON AsJSON(const NodeOrigin& no) {
} }
std::ostream& operator<<(std::ostream& out, const SourcePositionAsJSON& pos); std::ostream& operator<<(std::ostream& out, const SourcePositionAsJSON& pos);
std::ostream& operator<<(std::ostream& out, const NodeOriginAsJSON& asJSON);
// Small helper that deduplicates SharedFunctionInfos. // Small helper that deduplicates SharedFunctionInfos.
class V8_EXPORT_PRIVATE SourceIdAssigner { class V8_EXPORT_PRIVATE SourceIdAssigner {
......
...@@ -34,7 +34,11 @@ class NodeAuxData { ...@@ -34,7 +34,11 @@ class NodeAuxData {
// Update entry. Returns true iff entry was changed. // Update entry. Returns true iff entry was changed.
bool Set(Node* node, T const& data) { bool Set(Node* node, T const& data) {
size_t const id = node->id(); NodeId const id = node->id();
return Set(id, data);
}
bool Set(NodeId id, T const& data) {
if (id >= aux_data_.size()) aux_data_.resize(id + 1, def(zone_)); if (id >= aux_data_.size()) aux_data_.resize(id + 1, def(zone_));
if (aux_data_[id] != data) { if (aux_data_[id] != data) {
aux_data_[id] = data; aux_data_[id] = data;
...@@ -43,8 +47,9 @@ class NodeAuxData { ...@@ -43,8 +47,9 @@ class NodeAuxData {
return false; return false;
} }
T Get(Node* node) const { T Get(Node* node) const { return Get(node->id()); }
size_t const id = node->id();
T Get(NodeId id) const {
return (id < aux_data_.size()) ? aux_data_[id] : def(zone_); return (id < aux_data_.size()) ? aux_data_[id] : def(zone_);
} }
......
...@@ -60,10 +60,16 @@ void NodeOriginTable::RemoveDecorator() { ...@@ -60,10 +60,16 @@ void NodeOriginTable::RemoveDecorator() {
NodeOrigin NodeOriginTable::GetNodeOrigin(Node* node) const { NodeOrigin NodeOriginTable::GetNodeOrigin(Node* node) const {
return table_.Get(node); return table_.Get(node);
} }
NodeOrigin NodeOriginTable::GetNodeOrigin(NodeId id) const {
return table_.Get(id);
}
void NodeOriginTable::SetNodeOrigin(Node* node, const NodeOrigin& no) { void NodeOriginTable::SetNodeOrigin(Node* node, const NodeOrigin& no) {
table_.Set(node, no); table_.Set(node, no);
} }
void NodeOriginTable::SetNodeOrigin(NodeId id, NodeId origin) {
table_.Set(id, NodeOrigin(current_phase_name_, "", origin));
}
void NodeOriginTable::PrintJson(std::ostream& os) const { void NodeOriginTable::PrintJson(std::ostream& os) const {
os << "{"; os << "{";
......
...@@ -120,7 +120,9 @@ class V8_EXPORT_PRIVATE NodeOriginTable final ...@@ -120,7 +120,9 @@ class V8_EXPORT_PRIVATE NodeOriginTable final
void RemoveDecorator(); void RemoveDecorator();
NodeOrigin GetNodeOrigin(Node* node) const; NodeOrigin GetNodeOrigin(Node* node) const;
NodeOrigin GetNodeOrigin(NodeId id) const;
void SetNodeOrigin(Node* node, const NodeOrigin& no); void SetNodeOrigin(Node* node, const NodeOrigin& no);
void SetNodeOrigin(NodeId id, NodeId origin);
void SetCurrentPosition(const NodeOrigin& no) { current_origin_ = no; } void SetCurrentPosition(const NodeOrigin& no) { current_origin_ = no; }
......
...@@ -2036,9 +2036,9 @@ struct BuildTurboshaftPhase { ...@@ -2036,9 +2036,9 @@ struct BuildTurboshaftPhase {
Schedule* schedule = data->schedule(); Schedule* schedule = data->schedule();
data->reset_schedule(); data->reset_schedule();
data->CreateTurboshaftGraph(); data->CreateTurboshaftGraph();
return turboshaft::BuildGraph(schedule, data->graph_zone(), temp_zone, return turboshaft::BuildGraph(
&data->turboshaft_graph(), schedule, data->graph_zone(), temp_zone, &data->turboshaft_graph(),
data->source_positions()); data->source_positions(), data->node_origins());
} }
}; };
...@@ -2048,7 +2048,7 @@ struct OptimizeTurboshaftPhase { ...@@ -2048,7 +2048,7 @@ struct OptimizeTurboshaftPhase {
void Run(PipelineData* data, Zone* temp_zone) { void Run(PipelineData* data, Zone* temp_zone) {
turboshaft::OptimizationPhase<turboshaft::LivenessAnalyzer, turboshaft::OptimizationPhase<turboshaft::LivenessAnalyzer,
turboshaft::ValueNumberingAssembler>:: turboshaft::ValueNumberingAssembler>::
Run(&data->turboshaft_graph(), temp_zone, Run(&data->turboshaft_graph(), temp_zone, data->node_origins(),
turboshaft::VisitOrder::kDominator); turboshaft::VisitOrder::kDominator);
} }
}; };
...@@ -2059,7 +2059,8 @@ struct TurboshaftRecreateSchedulePhase { ...@@ -2059,7 +2059,8 @@ struct TurboshaftRecreateSchedulePhase {
void Run(PipelineData* data, Zone* temp_zone, Linkage* linkage) { void Run(PipelineData* data, Zone* temp_zone, Linkage* linkage) {
auto result = turboshaft::RecreateSchedule( auto result = turboshaft::RecreateSchedule(
data->turboshaft_graph(), linkage->GetIncomingDescriptor(), data->turboshaft_graph(), linkage->GetIncomingDescriptor(),
data->graph_zone(), temp_zone, data->source_positions()); data->graph_zone(), temp_zone, data->source_positions(),
data->node_origins());
data->set_graph(result.graph); data->set_graph(result.graph);
data->set_schedule(result.schedule); data->set_schedule(result.schedule);
} }
...@@ -2596,7 +2597,9 @@ struct PrintTurboshaftGraphPhase { ...@@ -2596,7 +2597,9 @@ struct PrintTurboshaftGraphPhase {
TurboJsonFile json_of(data->info(), std::ios_base::app); TurboJsonFile json_of(data->info(), std::ios_base::app);
json_of << "{\"name\":\"" << phase json_of << "{\"name\":\"" << phase
<< "\",\"type\":\"turboshaft_graph\",\"data\":" << "\",\"type\":\"turboshaft_graph\",\"data\":"
<< AsJSON(data->turboshaft_graph(), temp_zone) << "},\n"; << AsJSON(data->turboshaft_graph(), data->node_origins(),
temp_zone)
<< "},\n";
} }
if (data->info()->trace_turbo_graph()) { if (data->info()->trace_turbo_graph()) {
......
...@@ -218,8 +218,8 @@ class Assembler ...@@ -218,8 +218,8 @@ class Assembler
return true; return true;
} }
void SetCurrentSourcePosition(SourcePosition position) { void SetCurrentOrigin(OpIndex operation_origin) {
current_source_position_ = position; current_operation_origin_ = operation_origin;
} }
OpIndex Phi(base::Vector<const OpIndex> inputs, MachineRepresentation rep) { OpIndex Phi(base::Vector<const OpIndex> inputs, MachineRepresentation rep) {
...@@ -283,16 +283,14 @@ class Assembler ...@@ -283,16 +283,14 @@ class Assembler
static_assert(!(std::is_same<Op, Operation>::value)); static_assert(!(std::is_same<Op, Operation>::value));
DCHECK_NOT_NULL(current_block_); DCHECK_NOT_NULL(current_block_);
OpIndex result = graph().Add<Op>(args...); OpIndex result = graph().Add<Op>(args...);
if (current_source_position_.IsKnown()) { graph().operation_origins()[result] = current_operation_origin_;
graph().source_positions()[result] = current_source_position_;
}
if (Op::properties.is_block_terminator) FinalizeBlock(); if (Op::properties.is_block_terminator) FinalizeBlock();
return result; return result;
} }
Block* current_block_ = nullptr; Block* current_block_ = nullptr;
Graph& graph_; Graph& graph_;
SourcePosition current_source_position_ = SourcePosition::Unknown(); OpIndex current_operation_origin_ = OpIndex::Invalid();
Zone* const phase_zone_; Zone* const phase_zone_;
}; };
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "src/compiler/compiler-source-position-table.h" #include "src/compiler/compiler-source-position-table.h"
#include "src/compiler/machine-operator.h" #include "src/compiler/machine-operator.h"
#include "src/compiler/node-aux-data.h" #include "src/compiler/node-aux-data.h"
#include "src/compiler/node-origin-table.h"
#include "src/compiler/node-properties.h" #include "src/compiler/node-properties.h"
#include "src/compiler/opcodes.h" #include "src/compiler/opcodes.h"
#include "src/compiler/operator.h" #include "src/compiler/operator.h"
...@@ -38,6 +39,7 @@ struct GraphBuilder { ...@@ -38,6 +39,7 @@ struct GraphBuilder {
Schedule& schedule; Schedule& schedule;
Assembler assembler; Assembler assembler;
SourcePositionTable* source_positions; SourcePositionTable* source_positions;
NodeOriginTable* origins;
NodeAuxData<OpIndex> op_mapping{phase_zone}; NodeAuxData<OpIndex> op_mapping{phase_zone};
ZoneVector<Block*> block_mapping{schedule.RpoBlockCount(), phase_zone}; ZoneVector<Block*> block_mapping{schedule.RpoBlockCount(), phase_zone};
...@@ -217,16 +219,30 @@ base::Optional<BailoutReason> GraphBuilder::Run() { ...@@ -217,16 +219,30 @@ base::Optional<BailoutReason> GraphBuilder::Run() {
} }
DCHECK_NULL(assembler.current_block()); DCHECK_NULL(assembler.current_block());
} }
if (source_positions) {
for (OpIndex index : assembler.graph().AllOperationIndices()) {
compiler::NodeId origin =
assembler.graph().operation_origins()[index].DecodeTurbofanNodeId();
assembler.graph().source_positions()[index] =
source_positions->GetSourcePosition(origin);
}
}
if (origins) {
for (OpIndex index : assembler.graph().AllOperationIndices()) {
OpIndex origin = assembler.graph().operation_origins()[index];
origins->SetNodeOrigin(index.id(), origin.DecodeTurbofanNodeId());
}
}
return base::nullopt; return base::nullopt;
} }
OpIndex GraphBuilder::Process( OpIndex GraphBuilder::Process(
Node* node, BasicBlock* block, Node* node, BasicBlock* block,
const base::SmallVector<int, 16>& predecessor_permutation) { const base::SmallVector<int, 16>& predecessor_permutation) {
if (source_positions) { assembler.SetCurrentOrigin(OpIndex::EncodeTurbofanNodeId(node->id()));
assembler.SetCurrentSourcePosition(
source_positions->GetSourcePosition(node));
}
const Operator* op = node->op(); const Operator* op = node->op();
Operator::Opcode opcode = op->opcode(); Operator::Opcode opcode = op->opcode();
switch (opcode) { switch (opcode) {
...@@ -990,11 +1006,13 @@ OpIndex GraphBuilder::Process( ...@@ -990,11 +1006,13 @@ OpIndex GraphBuilder::Process(
} // namespace } // namespace
base::Optional<BailoutReason> BuildGraph( base::Optional<BailoutReason> BuildGraph(Schedule* schedule, Zone* graph_zone,
Schedule* schedule, Zone* graph_zone, Zone* phase_zone, Graph* graph, Zone* phase_zone, Graph* graph,
SourcePositionTable* source_positions) { SourcePositionTable* source_positions,
GraphBuilder builder{graph_zone, phase_zone, *schedule, NodeOriginTable* origins) {
Assembler(graph, phase_zone), source_positions}; GraphBuilder builder{graph_zone, phase_zone,
*schedule, Assembler(graph, phase_zone),
source_positions, origins};
return builder.Run(); return builder.Run();
} }
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#define V8_COMPILER_TURBOSHAFT_GRAPH_BUILDER_H_ #define V8_COMPILER_TURBOSHAFT_GRAPH_BUILDER_H_
#include "src/codegen/bailout-reason.h" #include "src/codegen/bailout-reason.h"
#include "src/compiler/node-origin-table.h"
#include "src/compiler/turboshaft/graph.h" #include "src/compiler/turboshaft/graph.h"
namespace v8::internal::compiler { namespace v8::internal::compiler {
...@@ -15,7 +16,8 @@ class SourcePositionTable; ...@@ -15,7 +16,8 @@ class SourcePositionTable;
namespace v8::internal::compiler::turboshaft { namespace v8::internal::compiler::turboshaft {
base::Optional<BailoutReason> BuildGraph(Schedule* schedule, Zone* graph_zone, base::Optional<BailoutReason> BuildGraph(Schedule* schedule, Zone* graph_zone,
Zone* phase_zone, Graph* graph, Zone* phase_zone, Graph* graph,
SourcePositionTable* source_positions); SourcePositionTable* source_positions,
NodeOriginTable* origins);
} }
#endif // V8_COMPILER_TURBOSHAFT_GRAPH_BUILDER_H_ #endif // V8_COMPILER_TURBOSHAFT_GRAPH_BUILDER_H_
...@@ -2,16 +2,20 @@ ...@@ -2,16 +2,20 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "src/compiler/graph-visualizer.h"
#include "src/compiler/node-origin-table.h"
#include "src/compiler/turboshaft/graph-visualizer.h" #include "src/compiler/turboshaft/graph-visualizer.h"
namespace v8::internal::compiler::turboshaft { namespace v8::internal::compiler::turboshaft {
JSONTurboshaftGraphWriter::JSONTurboshaftGraphWriter(std::ostream& os, JSONTurboshaftGraphWriter::JSONTurboshaftGraphWriter(
const Graph& turboshaft_graph, std::ostream& os, const Graph& turboshaft_graph, NodeOriginTable* origins,
Zone* zone) Zone* zone)
: os_(os), : os_(os),
zone_(zone), zone_(zone),
turboshaft_graph_(turboshaft_graph) {} turboshaft_graph_(turboshaft_graph),
origins_(origins) {}
void JSONTurboshaftGraphWriter::Print() { void JSONTurboshaftGraphWriter::Print() {
os_ << "{\n\"nodes\":["; os_ << "{\n\"nodes\":[";
...@@ -27,6 +31,7 @@ void JSONTurboshaftGraphWriter::PrintNodes() { ...@@ -27,6 +31,7 @@ void JSONTurboshaftGraphWriter::PrintNodes() {
bool first = true; bool first = true;
for (const Block& block : turboshaft_graph_.blocks()) { for (const Block& block : turboshaft_graph_.blocks()) {
for (const Operation& op : turboshaft_graph_.operations(block)) { for (const Operation& op : turboshaft_graph_.operations(block)) {
OpIndex index = turboshaft_graph_.Index(op);
if (!first) os_ << ",\n"; if (!first) os_ << ",\n";
first = false; first = false;
os_ << "{\"id\":" << turboshaft_graph_.Index(op).id() << ","; os_ << "{\"id\":" << turboshaft_graph_.Index(op).id() << ",";
...@@ -35,7 +40,18 @@ void JSONTurboshaftGraphWriter::PrintNodes() { ...@@ -35,7 +40,18 @@ void JSONTurboshaftGraphWriter::PrintNodes() {
os_ << "\"op_properties_type\":\"" << op.properties() << "\","; os_ << "\"op_properties_type\":\"" << op.properties() << "\",";
os_ << "\"properties\":\""; os_ << "\"properties\":\"";
op.PrintOptions(os_); op.PrintOptions(os_);
os_ << "\"}"; os_ << "\"";
if (origins_) {
NodeOrigin origin = origins_->GetNodeOrigin(index.id());
if (origin.IsKnown()) {
os_ << ", \"origin\":" << AsJSON(origin);
}
}
SourcePosition position = turboshaft_graph_.source_positions()[index];
if (position.IsKnown()) {
os_ << ", \"sourcePosition\":" << compiler::AsJSON(position);
}
os_ << "}";
} }
} }
} }
...@@ -75,7 +91,8 @@ void JSONTurboshaftGraphWriter::PrintBlocks() { ...@@ -75,7 +91,8 @@ void JSONTurboshaftGraphWriter::PrintBlocks() {
} }
std::ostream& operator<<(std::ostream& os, const TurboshaftGraphAsJSON& ad) { std::ostream& operator<<(std::ostream& os, const TurboshaftGraphAsJSON& ad) {
JSONTurboshaftGraphWriter writer(os, ad.turboshaft_graph, ad.temp_zone); JSONTurboshaftGraphWriter writer(os, ad.turboshaft_graph, ad.origins,
ad.temp_zone);
writer.Print(); writer.Print();
return os; return os;
} }
......
...@@ -5,23 +5,22 @@ ...@@ -5,23 +5,22 @@
#ifndef V8_COMPILER_TURBOSHAFT_GRAPH_VISUALIZER_H_ #ifndef V8_COMPILER_TURBOSHAFT_GRAPH_VISUALIZER_H_
#define V8_COMPILER_TURBOSHAFT_GRAPH_VISUALIZER_H_ #define V8_COMPILER_TURBOSHAFT_GRAPH_VISUALIZER_H_
#include "src/compiler/turboshaft/graph.h"
#include "src/common/globals.h" #include "src/common/globals.h"
#include "src/compiler/node-origin-table.h"
#include "src/compiler/turboshaft/graph.h"
#include "src/handles/handles.h" #include "src/handles/handles.h"
namespace v8::internal::compiler::turboshaft { namespace v8::internal::compiler::turboshaft {
struct TurboshaftGraphAsJSON { struct TurboshaftGraphAsJSON {
TurboshaftGraphAsJSON(const Graph& tg, Zone* z): turboshaft_graph(tg),
temp_zone(z){}
const Graph& turboshaft_graph; const Graph& turboshaft_graph;
NodeOriginTable* origins;
Zone* temp_zone; Zone* temp_zone;
}; };
V8_INLINE V8_EXPORT_PRIVATE TurboshaftGraphAsJSON AsJSON(const Graph& tg, V8_INLINE V8_EXPORT_PRIVATE TurboshaftGraphAsJSON
Zone* z) { AsJSON(const Graph& graph, NodeOriginTable* origins, Zone* temp_zone) {
return TurboshaftGraphAsJSON(tg, z); return TurboshaftGraphAsJSON{graph, origins, temp_zone};
} }
V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
...@@ -30,7 +29,7 @@ V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os, ...@@ -30,7 +29,7 @@ V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
class JSONTurboshaftGraphWriter { class JSONTurboshaftGraphWriter {
public: public:
JSONTurboshaftGraphWriter(std::ostream& os, const Graph& turboshaft_graph, JSONTurboshaftGraphWriter(std::ostream& os, const Graph& turboshaft_graph,
Zone* zone); NodeOriginTable* origins, Zone* zone);
JSONTurboshaftGraphWriter(const JSONTurboshaftGraphWriter&) = delete; JSONTurboshaftGraphWriter(const JSONTurboshaftGraphWriter&) = delete;
JSONTurboshaftGraphWriter& operator=(const JSONTurboshaftGraphWriter&) = delete; JSONTurboshaftGraphWriter& operator=(const JSONTurboshaftGraphWriter&) = delete;
...@@ -46,6 +45,7 @@ class JSONTurboshaftGraphWriter { ...@@ -46,6 +45,7 @@ class JSONTurboshaftGraphWriter {
std::ostream& os_; std::ostream& os_;
Zone* zone_; Zone* zone_;
const Graph& turboshaft_graph_; const Graph& turboshaft_graph_;
NodeOriginTable* origins_;
}; };
} // namespace v8::internal::compiler::turboshaft } // namespace v8::internal::compiler::turboshaft
......
...@@ -351,13 +351,15 @@ class Graph { ...@@ -351,13 +351,15 @@ class Graph {
bound_blocks_(graph_zone), bound_blocks_(graph_zone),
all_blocks_(graph_zone), all_blocks_(graph_zone),
graph_zone_(graph_zone), graph_zone_(graph_zone),
source_positions_(graph_zone) {} source_positions_(graph_zone),
operation_origins_(graph_zone) {}
// Reset the graph to recycle its memory. // Reset the graph to recycle its memory.
void Reset() { void Reset() {
operations_.Reset(); operations_.Reset();
bound_blocks_.clear(); bound_blocks_.clear();
source_positions_.Reset(); source_positions_.Reset();
operation_origins_.Reset();
next_block_ = 0; next_block_ = 0;
} }
...@@ -483,6 +485,33 @@ class Graph { ...@@ -483,6 +485,33 @@ class Graph {
return operations_.capacity() / kSlotsPerId; return operations_.capacity() / kSlotsPerId;
} }
class OpIndexIterator
: public base::iterator<std::bidirectional_iterator_tag, OpIndex> {
public:
using value_type = OpIndex;
explicit OpIndexIterator(OpIndex index, const Graph* graph)
: index_(index), graph_(graph) {}
value_type& operator*() { return index_; }
OpIndexIterator& operator++() {
index_ = graph_->operations_.Next(index_);
return *this;
}
OpIndexIterator& operator--() {
index_ = graph_->operations_.Previous(index_);
return *this;
}
bool operator!=(OpIndexIterator other) const {
DCHECK_EQ(graph_, other.graph_);
return index_ != other.index_;
}
bool operator==(OpIndexIterator other) const { return !(*this != other); }
private:
OpIndex index_;
const Graph* const graph_;
};
template <class OperationT, typename GraphT> template <class OperationT, typename GraphT>
class OperationIterator class OperationIterator
: public base::iterator<std::bidirectional_iterator_tag, OperationT> { : public base::iterator<std::bidirectional_iterator_tag, OperationT> {
...@@ -508,8 +537,6 @@ class Graph { ...@@ -508,8 +537,6 @@ class Graph {
} }
bool operator==(OperationIterator other) const { return !(*this != other); } bool operator==(OperationIterator other) const { return !(*this != other); }
OpIndex Index() const { return index_; }
private: private:
OpIndex index_; OpIndex index_;
GraphT* const graph_; GraphT* const graph_;
...@@ -522,11 +549,14 @@ class Graph { ...@@ -522,11 +549,14 @@ class Graph {
base::iterator_range<MutableOperationIterator> AllOperations() { base::iterator_range<MutableOperationIterator> AllOperations() {
return operations(operations_.BeginIndex(), operations_.EndIndex()); return operations(operations_.BeginIndex(), operations_.EndIndex());
} }
base::iterator_range<ConstOperationIterator> AllOperations() const { base::iterator_range<ConstOperationIterator> AllOperations() const {
return operations(operations_.BeginIndex(), operations_.EndIndex()); return operations(operations_.BeginIndex(), operations_.EndIndex());
} }
base::iterator_range<OpIndexIterator> AllOperationIndices() const {
return OperationIndices(operations_.BeginIndex(), operations_.EndIndex());
}
base::iterator_range<MutableOperationIterator> operations( base::iterator_range<MutableOperationIterator> operations(
const Block& block) { const Block& block) {
return operations(block.begin_, block.end_); return operations(block.begin_, block.end_);
...@@ -536,6 +566,11 @@ class Graph { ...@@ -536,6 +566,11 @@ class Graph {
return operations(block.begin_, block.end_); return operations(block.begin_, block.end_);
} }
base::iterator_range<OpIndexIterator> OperationIndices(
const Block& block) const {
return OperationIndices(block.begin_, block.end_);
}
base::iterator_range<ConstOperationIterator> operations(OpIndex begin, base::iterator_range<ConstOperationIterator> operations(OpIndex begin,
OpIndex end) const { OpIndex end) const {
DCHECK(begin.valid()); DCHECK(begin.valid());
...@@ -543,7 +578,6 @@ class Graph { ...@@ -543,7 +578,6 @@ class Graph {
return {ConstOperationIterator(begin, this), return {ConstOperationIterator(begin, this),
ConstOperationIterator(end, this)}; ConstOperationIterator(end, this)};
} }
base::iterator_range<MutableOperationIterator> operations(OpIndex begin, base::iterator_range<MutableOperationIterator> operations(OpIndex begin,
OpIndex end) { OpIndex end) {
DCHECK(begin.valid()); DCHECK(begin.valid());
...@@ -552,6 +586,13 @@ class Graph { ...@@ -552,6 +586,13 @@ class Graph {
MutableOperationIterator(end, this)}; MutableOperationIterator(end, this)};
} }
base::iterator_range<OpIndexIterator> OperationIndices(OpIndex begin,
OpIndex end) const {
DCHECK(begin.valid());
DCHECK(end.valid());
return {OpIndexIterator(begin, this), OpIndexIterator(end, this)};
}
base::iterator_range<base::DerefPtrIterator<Block>> blocks() { base::iterator_range<base::DerefPtrIterator<Block>> blocks() {
return {base::DerefPtrIterator<Block>(bound_blocks_.data()), return {base::DerefPtrIterator<Block>(bound_blocks_.data()),
base::DerefPtrIterator<Block>(bound_blocks_.data() + base::DerefPtrIterator<Block>(bound_blocks_.data() +
...@@ -572,6 +613,11 @@ class Graph { ...@@ -572,6 +613,11 @@ class Graph {
return source_positions_; return source_positions_;
} }
const GrowingSidetable<OpIndex>& operation_origins() const {
return operation_origins_;
}
GrowingSidetable<OpIndex>& operation_origins() { return operation_origins_; }
Graph& GetOrCreateCompanion() { Graph& GetOrCreateCompanion() {
if (!companion_) { if (!companion_) {
companion_ = std::make_unique<Graph>(graph_zone_, operations_.size()); companion_ = std::make_unique<Graph>(graph_zone_, operations_.size());
...@@ -592,6 +638,7 @@ class Graph { ...@@ -592,6 +638,7 @@ class Graph {
std::swap(next_block_, companion.next_block_); std::swap(next_block_, companion.next_block_);
std::swap(graph_zone_, companion.graph_zone_); std::swap(graph_zone_, companion.graph_zone_);
std::swap(source_positions_, companion.source_positions_); std::swap(source_positions_, companion.source_positions_);
std::swap(operation_origins_, companion.operation_origins_);
#ifdef DEBUG #ifdef DEBUG
// Update generation index. // Update generation index.
DCHECK_EQ(generation_ + 1, companion.generation_); DCHECK_EQ(generation_ + 1, companion.generation_);
...@@ -613,6 +660,7 @@ class Graph { ...@@ -613,6 +660,7 @@ class Graph {
size_t next_block_ = 0; size_t next_block_ = 0;
Zone* graph_zone_; Zone* graph_zone_;
GrowingSidetable<SourcePosition> source_positions_; GrowingSidetable<SourcePosition> source_positions_;
GrowingSidetable<OpIndex> operation_origins_;
std::unique_ptr<Graph> companion_ = {}; std::unique_ptr<Graph> companion_ = {};
#ifdef DEBUG #ifdef DEBUG
......
...@@ -136,12 +136,30 @@ class OpIndex { ...@@ -136,12 +136,30 @@ class OpIndex {
DCHECK_EQ(offset_ % sizeof(OperationStorageSlot), 0); DCHECK_EQ(offset_ % sizeof(OperationStorageSlot), 0);
return offset_ / sizeof(OperationStorageSlot) / kSlotsPerId; return offset_ / sizeof(OperationStorageSlot) / kSlotsPerId;
} }
uint32_t offset() const { return offset_; } uint32_t offset() const {
DCHECK_EQ(offset_ % sizeof(OperationStorageSlot), 0);
return offset_;
}
bool valid() const { return *this != Invalid(); } bool valid() const { return *this != Invalid(); }
static constexpr OpIndex Invalid() { return OpIndex(); } static constexpr OpIndex Invalid() { return OpIndex(); }
// Encode a sea-of-nodes node id in the `OpIndex` type.
// Only used for node origins that actually point to sea-of-nodes graph nodes.
static OpIndex EncodeTurbofanNodeId(uint32_t id) {
OpIndex result = OpIndex(id * sizeof(OperationStorageSlot));
result.offset_ += kTurbofanNodeIdFlag;
return result;
}
uint32_t DecodeTurbofanNodeId() const {
DCHECK(IsTurbofanNodeId());
return offset_ / sizeof(OperationStorageSlot);
}
bool IsTurbofanNodeId() const {
return offset_ % sizeof(OperationStorageSlot) == kTurbofanNodeIdFlag;
}
bool operator==(OpIndex other) const { return offset_ == other.offset_; } bool operator==(OpIndex other) const { return offset_ == other.offset_; }
bool operator!=(OpIndex other) const { return offset_ != other.offset_; } bool operator!=(OpIndex other) const { return offset_ != other.offset_; }
bool operator<(OpIndex other) const { return offset_ < other.offset_; } bool operator<(OpIndex other) const { return offset_ < other.offset_; }
...@@ -151,6 +169,8 @@ class OpIndex { ...@@ -151,6 +169,8 @@ class OpIndex {
private: private:
uint32_t offset_; uint32_t offset_;
static constexpr uint32_t kTurbofanNodeIdFlag = 1;
}; };
V8_INLINE size_t hash_value(OpIndex op) { return op.id(); } V8_INLINE size_t hash_value(OpIndex op) { return op.id(); }
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "src/base/logging.h" #include "src/base/logging.h"
#include "src/base/small-vector.h" #include "src/base/small-vector.h"
#include "src/base/vector.h" #include "src/base/vector.h"
#include "src/compiler/node-origin-table.h"
#include "src/compiler/turboshaft/graph.h" #include "src/compiler/turboshaft/graph.h"
#include "src/compiler/turboshaft/operations.h" #include "src/compiler/turboshaft/operations.h"
...@@ -64,11 +65,11 @@ struct LivenessAnalyzer : AnalyzerBase { ...@@ -64,11 +65,11 @@ struct LivenessAnalyzer : AnalyzerBase {
template <bool is_loop> template <bool is_loop>
void ProcessBlock(const Block& block, uint32_t* unprocessed_count) { void ProcessBlock(const Block& block, uint32_t* unprocessed_count) {
auto op_range = graph.operations(block); auto op_range = graph.OperationIndices(block);
for (auto it = op_range.end(); it != op_range.begin();) { for (auto it = op_range.end(); it != op_range.begin();) {
--it; --it;
OpIndex index = it.Index(); OpIndex index = *it;
const Operation& op = *it; const Operation& op = graph.Get(index);
if (op.properties().is_required_when_unused) { if (op.properties().is_required_when_unused) {
op_used[index.id()] = true; op_used[index.id()] = true;
} else if (!OpIsUsed(index)) { } else if (!OpIsUsed(index)) {
...@@ -103,9 +104,9 @@ class OptimizationPhase { ...@@ -103,9 +104,9 @@ class OptimizationPhase {
struct Impl; struct Impl;
public: public:
static void Run(Graph* input, Zone* phase_zone, static void Run(Graph* input, Zone* phase_zone, NodeOriginTable* origins,
VisitOrder visit_order = VisitOrder::kAsEmitted) { VisitOrder visit_order = VisitOrder::kAsEmitted) {
Impl phase{*input, phase_zone, visit_order}; Impl phase{*input, phase_zone, origins, visit_order};
if (FLAG_turboshaft_trace_reduction) { if (FLAG_turboshaft_trace_reduction) {
phase.template Run<true>(); phase.template Run<true>();
} else { } else {
...@@ -124,6 +125,7 @@ template <class Analyzer, class Assembler> ...@@ -124,6 +125,7 @@ template <class Analyzer, class Assembler>
struct OptimizationPhase<Analyzer, Assembler>::Impl { struct OptimizationPhase<Analyzer, Assembler>::Impl {
Graph& input_graph; Graph& input_graph;
Zone* phase_zone; Zone* phase_zone;
compiler::NodeOriginTable* origins;
VisitOrder visit_order; VisitOrder visit_order;
Analyzer analyzer{input_graph, phase_zone}; Analyzer analyzer{input_graph, phase_zone};
...@@ -151,6 +153,20 @@ struct OptimizationPhase<Analyzer, Assembler>::Impl { ...@@ -151,6 +153,20 @@ struct OptimizationPhase<Analyzer, Assembler>::Impl {
RunAsEmittedOrder<trace_reduction>(); RunAsEmittedOrder<trace_reduction>();
} }
if (!input_graph.source_positions().empty()) {
for (OpIndex index : assembler.graph().AllOperationIndices()) {
OpIndex origin = assembler.graph().operation_origins()[index];
assembler.graph().source_positions()[index] =
input_graph.source_positions()[origin];
}
}
if (origins) {
for (OpIndex index : assembler.graph().AllOperationIndices()) {
OpIndex origin = assembler.graph().operation_origins()[index];
origins->SetNodeOrigin(index.id(), origin.id());
}
}
input_graph.SwapWithCompanion(); input_graph.SwapWithCompanion();
} }
...@@ -192,14 +208,8 @@ struct OptimizationPhase<Analyzer, Assembler>::Impl { ...@@ -192,14 +208,8 @@ struct OptimizationPhase<Analyzer, Assembler>::Impl {
return; return;
} }
assembler.current_block()->SetDeferred(input_block.IsDeferred()); assembler.current_block()->SetDeferred(input_block.IsDeferred());
auto op_range = input_graph.operations(input_block); for (OpIndex index : input_graph.OperationIndices(input_block)) {
for (auto it = op_range.begin(); it != op_range.end(); ++it) { assembler.SetCurrentOrigin(index);
const Operation& op = *it;
OpIndex index = it.Index();
if (V8_UNLIKELY(!input_graph.source_positions().empty())) {
assembler.SetCurrentSourcePosition(
input_graph.source_positions()[index]);
}
OpIndex first_output_index = assembler.graph().next_operation_index(); OpIndex first_output_index = assembler.graph().next_operation_index();
USE(first_output_index); USE(first_output_index);
if constexpr (trace_reduction) TraceReductionStart(index); if constexpr (trace_reduction) TraceReductionStart(index);
...@@ -207,6 +217,7 @@ struct OptimizationPhase<Analyzer, Assembler>::Impl { ...@@ -207,6 +217,7 @@ struct OptimizationPhase<Analyzer, Assembler>::Impl {
if constexpr (trace_reduction) TraceOperationUnused(); if constexpr (trace_reduction) TraceOperationUnused();
continue; continue;
} }
const Operation& op = input_graph.Get(index);
OpIndex new_index; OpIndex new_index;
if (input_block.IsLoop() && op.Is<PhiOp>()) { if (input_block.IsLoop() && op.Is<PhiOp>()) {
const PhiOp& phi = op.Cast<PhiOp>(); const PhiOp& phi = op.Cast<PhiOp>();
......
...@@ -18,6 +18,7 @@ ...@@ -18,6 +18,7 @@
#include "src/compiler/graph.h" #include "src/compiler/graph.h"
#include "src/compiler/linkage.h" #include "src/compiler/linkage.h"
#include "src/compiler/machine-operator.h" #include "src/compiler/machine-operator.h"
#include "src/compiler/node-origin-table.h"
#include "src/compiler/schedule.h" #include "src/compiler/schedule.h"
#include "src/compiler/scheduler.h" #include "src/compiler/scheduler.h"
#include "src/compiler/simplified-operator.h" #include "src/compiler/simplified-operator.h"
...@@ -38,6 +39,7 @@ struct ScheduleBuilder { ...@@ -38,6 +39,7 @@ struct ScheduleBuilder {
Zone* graph_zone; Zone* graph_zone;
Zone* phase_zone; Zone* phase_zone;
SourcePositionTable* source_positions; SourcePositionTable* source_positions;
NodeOriginTable* origins;
const size_t node_count_estimate = const size_t node_count_estimate =
static_cast<size_t>(1.1 * input_graph.op_id_count()); static_cast<size_t>(1.1 * input_graph.op_id_count());
...@@ -158,6 +160,9 @@ void ScheduleBuilder::ProcessOperation(const Operation& op) { ...@@ -158,6 +160,9 @@ void ScheduleBuilder::ProcessOperation(const Operation& op) {
source_positions->SetSourcePosition(node, source_positions->SetSourcePosition(node,
input_graph.source_positions()[index]); input_graph.source_positions()[index]);
} }
if (origins && node) {
origins->SetNodeOrigin(node->id(), index.id());
}
} }
Node* ScheduleBuilder::ProcessOperation(const BinopOp& op) { Node* ScheduleBuilder::ProcessOperation(const BinopOp& op) {
...@@ -1149,9 +1154,10 @@ Node* ScheduleBuilder::ProcessOperation(const SwitchOp& op) { ...@@ -1149,9 +1154,10 @@ Node* ScheduleBuilder::ProcessOperation(const SwitchOp& op) {
RecreateScheduleResult RecreateSchedule(const Graph& graph, RecreateScheduleResult RecreateSchedule(const Graph& graph,
CallDescriptor* call_descriptor, CallDescriptor* call_descriptor,
Zone* graph_zone, Zone* phase_zone, Zone* graph_zone, Zone* phase_zone,
SourcePositionTable* source_positions) { SourcePositionTable* source_positions,
ScheduleBuilder builder{graph, call_descriptor, graph_zone, phase_zone, NodeOriginTable* origins) {
source_positions}; ScheduleBuilder builder{graph, call_descriptor, graph_zone,
phase_zone, source_positions, origins};
return builder.Run(); return builder.Run();
} }
......
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
#define V8_COMPILER_TURBOSHAFT_RECREATE_SCHEDULE_H_ #define V8_COMPILER_TURBOSHAFT_RECREATE_SCHEDULE_H_
#include "src/compiler/compiler-source-position-table.h" #include "src/compiler/compiler-source-position-table.h"
#include "src/compiler/node-origin-table.h"
#include "src/compiler/node.h"
namespace v8::internal { namespace v8::internal {
class Zone; class Zone;
} }
...@@ -25,7 +27,8 @@ struct RecreateScheduleResult { ...@@ -25,7 +27,8 @@ struct RecreateScheduleResult {
RecreateScheduleResult RecreateSchedule(const Graph& graph, RecreateScheduleResult RecreateSchedule(const Graph& graph,
CallDescriptor* call_descriptor, CallDescriptor* call_descriptor,
Zone* graph_zone, Zone* phase_zone, Zone* graph_zone, Zone* phase_zone,
SourcePositionTable* source_positions); SourcePositionTable* source_positions,
NodeOriginTable* origins);
} // namespace v8::internal::compiler::turboshaft } // namespace v8::internal::compiler::turboshaft
......
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