Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion xls/contrib/xlscc/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,7 @@ cc_library(
"//xls/common/status:ret_check",
"//xls/common/status:status_macros",
"//xls/data_structures:leaf_type_tree",
"//xls/dev_tools:link_to_source",
"//xls/interpreter:ir_interpreter",
"//xls/ir",
"//xls/ir:bits",
Expand All @@ -257,7 +258,6 @@ cc_library(
"//xls/passes:inlining_pass",
"//xls/passes:node_source_analysis",
"//xls/passes:optimization_pass",
"//xls/passes:optimization_pass_pipeline",
"//xls/passes:partial_info_query_engine",
"//xls/passes:pass_base",
"//xls/solvers:z3_ir_translator",
Expand Down
50 changes: 35 additions & 15 deletions xls/contrib/xlscc/continuations.cc
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@
#include "xls/contrib/xlscc/translator_types.h"
#include "xls/contrib/xlscc/xlscc_logging.h"
#include "xls/data_structures/leaf_type_tree.h"
#include "xls/dev_tools/link_to_source.h"
#include "xls/ir/bits.h"
#include "xls/ir/function_builder.h"
#include "xls/ir/nodes.h"
Expand Down Expand Up @@ -2466,7 +2467,21 @@ absl::Status Translator::MarkDirectIns(GeneratedFunction& func,
return absl::OkStatus();
}

std::string Debug_GenerateSliceGraph(const GeneratedFunction& func) {
namespace {
std::string LinkifyLocation(const IOOp* op, const xls::Package* package) {
if (!op || op->op_location.locations.empty() || package == nullptr) {
return "";
}
auto link = LinkToSource(op->op_location.locations.back(), package);
if (!link) {
return "";
}
return absl::StrFormat("href=\"%s\"", *link);
}
} // namespace

std::string Debug_GenerateSliceGraph(const GeneratedFunction& func,
const xls::Package* package) {
const bool show_choose_in_states = false;
const bool show_input_debug_info = false;

Expand Down Expand Up @@ -2513,27 +2528,32 @@ std::string Debug_GenerateSliceGraph(const GeneratedFunction& func) {
}
}

const std::string rank_full_name =
GraphvizEscape(absl::StrFormat("%p_rank", &slice));
const std::string rank_input_name =
GraphvizEscape(absl::StrFormat("%p_inputs", &slice));
absl::StrFormat("%s:input", rank_full_name);
const std::string rank_output_name =
GraphvizEscape(absl::StrFormat("%p_outputs", &slice));

rank_orders.push_back(
absl::StrFormat(" %s -> %s", rank_input_name, rank_output_name));
absl::StrFormat("%s:output", rank_full_name);
const std::string link =
slice_index != 0 ? LinkifyLocation(slice.after_op, package) : "";
const std::string link_label =
link.empty()
? ""
: absl::StrFormat(" [line:%d] [link]",
slice.after_op->op_location.locations.back()
.lineno()
.value());
const std::string rank_label = absl::StrFormat(
"{ <input> inputs | <id> [%d] %s%s | "
"<output> outputs }",
slice_index, new_rank, link_label);
node_names.push_back(absl::StrFormat(" %s [shape=record label=\"%s\" %s];",
rank_full_name, rank_label, link));
if (!last_rank_name.empty()) {
rank_orders.push_back(
absl::StrFormat(" %s -> %s", last_rank_name, rank_input_name));
}

node_names.push_back(
absl::StrFormat(" %s [label=%s style=rounded];", rank_input_name,
GraphvizEscape(absl::StrFormat(
"[%i] %s inputs", slice_index, new_rank))));
node_names.push_back(
absl::StrFormat(" %s [label=%s];", rank_output_name,
GraphvizEscape(absl::StrFormat(
"[%i] %s outputs", slice_index, new_rank))));

last_rank_name = rank_output_name;

std::vector<std::string> nodes_in_input_rank = {rank_input_name};
Expand Down
17 changes: 9 additions & 8 deletions xls/contrib/xlscc/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -282,16 +282,17 @@ static absl::Status Run(std::string_view cpp_path) {
std::filesystem::path debug_write_function_slice_graph_path(
absl::GetFlag(FLAGS_debug_write_function_slice_graph_path));

auto write_to_output =
[&](std::string_view output,
const GeneratedFunction* top_function) -> absl::Status {
auto write_to_output = [&](std::string_view output,
const GeneratedFunction* top_function,
const xls::Package* package) -> absl::Status {
if (output_file.empty()) {
std::cout << output;
} else {
XLS_RETURN_IF_ERROR(xls::SetFileContents(output_file, output));
}
if (!debug_write_function_slice_graph_path.empty()) {
const std::string graph = Debug_GenerateSliceGraph(*top_function);
const std::string graph =
Debug_GenerateSliceGraph(*top_function, package);
XLS_RETURN_IF_ERROR(
xls::SetFileContents(debug_write_function_slice_graph_path, graph));
}
Expand All @@ -311,8 +312,8 @@ static absl::Status Run(std::string_view cpp_path) {
translator.AddSourceInfoToPackage(package);

std::cerr << "Saving Package IR..." << '\n';
XLS_RETURN_IF_ERROR(
write_to_output(absl::StrCat(package.DumpIr(), "\n"), top_function));
XLS_RETURN_IF_ERROR(write_to_output(absl::StrCat(package.DumpIr(), "\n"),
top_function, &package));
} else {
xls::Proc* proc = nullptr;

Expand Down Expand Up @@ -342,8 +343,8 @@ static absl::Status Run(std::string_view cpp_path) {
const GeneratedFunction* top_function =
translator.GetGeneratedFunction(top_function_decl);

XLS_RETURN_IF_ERROR(
write_to_output(absl::StrCat(package.DumpIr(), "\n"), top_function));
XLS_RETURN_IF_ERROR(write_to_output(absl::StrCat(package.DumpIr(), "\n"),
top_function, &package));
}

const std::string metadata_out_path = absl::GetFlag(FLAGS_meta_out);
Expand Down
3 changes: 2 additions & 1 deletion xls/contrib/xlscc/translator.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ class Translator;
class NewFSMGenerator;

std::string Debug_GenerateReadableTypeName(xls::Type* type);
std::string Debug_GenerateSliceGraph(const GeneratedFunction& func);
std::string Debug_GenerateSliceGraph(const GeneratedFunction& func,
const xls::Package* package);

struct TranslationContext;

Expand Down
4 changes: 2 additions & 2 deletions xls/contrib/xlscc/unit_tests/continuations_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ class ContinuationsTest : public XlsccTestBase {
LOG(INFO) << package_->DumpIr();

LogContinuations(*func);
testing::Test::RecordProperty("GraphViz file",
Debug_GenerateSliceGraph(*func));
testing::Test::RecordProperty(
"GraphViz file", Debug_GenerateSliceGraph(*func, package_.get()));

return func;
}
Expand Down
12 changes: 6 additions & 6 deletions xls/contrib/xlscc/unit_tests/unit_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -387,8 +387,8 @@ absl::StatusOr<std::string> XlsccTestBase::SourceToIr(
translator_->GenerateIR_Top_Function(
package_.get(), top_channel_injections));

testing::Test::RecordProperty("GraphViz file",
Debug_GenerateSliceGraph(*func));
testing::Test::RecordProperty(
"GraphViz file", Debug_GenerateSliceGraph(*func, package_.get()));

XLS_RETURN_IF_ERROR(package_->SetTopByName(func->xls_func->name()));
if (pfunc != nullptr) {
Expand Down Expand Up @@ -484,8 +484,8 @@ void XlsccTestBase::BuildTestIR(
const xlscc::GeneratedFunction* top_func =
translator_->GetGeneratedFunction(top_decl);

testing::Test::RecordProperty("GraphViz file",
Debug_GenerateSliceGraph(*top_func));
testing::Test::RecordProperty(
"GraphViz file", Debug_GenerateSliceGraph(*top_func, package_.get()));

for (const xlscc::HLSChannel& ch : block_spec_.channels()) {
if (ch.type() == xlscc::CHANNEL_TYPE_DIRECT_IN) {
Expand Down Expand Up @@ -1022,8 +1022,8 @@ void XlsccTestBase::IOTest(std::string_view content, std::list<IOOpTest> inputs,
const xlscc::GeneratedFunction* top_func =
translator_->GetGeneratedFunction(top_decl);

testing::Test::RecordProperty("GraphViz file",
Debug_GenerateSliceGraph(*top_func));
testing::Test::RecordProperty(
"GraphViz file", Debug_GenerateSliceGraph(*top_func, package_.get()));

XLS_ASSERT_OK_AND_ASSIGN(package_, ParsePackage(ir_src));

Expand Down
13 changes: 13 additions & 0 deletions xls/dev_tools/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -976,3 +976,16 @@ pytype_strict_contrib_test(
"@abseil-py//absl/testing:absltest",
],
)

cc_library(
name = "link_to_source",
srcs = [
"link_to_source.cc",
],
hdrs = ["link_to_source.h"],
deps = [
"//xls/ir",
"//xls/ir:source_location",
"@com_google_absl//absl/strings:str_format",
],
)
35 changes: 35 additions & 0 deletions xls/dev_tools/link_to_source.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright 2026 The XLS Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "xls/dev_tools/link_to_source.h"

#include <optional>
#include <string>

#include "absl/strings/str_format.h"
#include "xls/ir/package.h"
#include "xls/ir/source_location.h"

namespace xls {

std::optional<std::string> LinkToSource(const SourceLocation& loc,
const Package* package) {
auto it = package->fileno_to_name().find(loc.fileno());
if (it == package->fileno_to_name().end()) {
return std::nullopt;
}
return absl::StrFormat("file://%s", it->second);
}

} // namespace xls
34 changes: 34 additions & 0 deletions xls/dev_tools/link_to_source.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright 2026 The XLS Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef XLS_DEV_TOOLS_LINK_TO_SOURCE_H_
#define XLS_DEV_TOOLS_LINK_TO_SOURCE_H_

#include <optional>
#include <string>

#include "xls/ir/package.h"
#include "xls/ir/source_location.h"

namespace xls {

// Get a link to the source code associated with the given source location.
//
// TODO(allight): Let the link format be configurable with a flag.
std::optional<std::string> LinkToSource(const SourceLocation& loc,
const Package* package);

} // namespace xls

#endif // XLS_DEV_TOOLS_LINK_TO_SOURCE_H_
Loading