Add --dump-sem-ir-ranges for controlling dump output (#5450)

Right now, a lot of tests have started setting `--no-dump-sem-ir`. My
thought is that we can look at:

1. Put ranges in a bunch more files.
2. Shift more towards `--dump-sem-ir-ranges=only` instead of
`--no-dump-sem-ir`, because it allows mixing fail-tests with no IR
alongside tests that contain IR.
3. Evaluate switching the default to `--dump-sem-ir-ranges=only`, and
instead set `--dump-sem-ir-ranges=if-present` only in files that want to
typically show all IR (particularly import-related tests, where ranges
don't work well).

In real-world use, my thought is also that it'd be helpful to be able to
add the dump range comments to files, see the output (i.e., the default
behavior of `if-present`) but then also be able to pass `ignore` in
order to see the full IR without modifying the file (possibly also
useful in tests). That model is why I went for tri-state handling.

Note `only` can also have an interesting side-effect. Because core files
(including min_prelude versions) typically won't have ranges, they'd be
implicitly excluded.
This commit is contained in:
Jon Ross-Perkins
2025-05-12 14:51:10 +00:00
committed by GitHub
parent b6a55c0818
commit 937caaecce
7 changed files with 194 additions and 22 deletions
+54 -14
View File
@@ -180,10 +180,32 @@ Dump the raw JSON structure of SemIR to stdout when built.
{
.name = "dump-sem-ir",
.help = R"""(
Dump the SemIR to stdout when built.
Dump the full SemIR to stdout when built.
)""",
},
[&](auto& arg_b) { arg_b.Set(&dump_sem_ir); });
b.AddOneOfOption(
{
.name = "dump-sem-ir-ranges",
.help = R"""(
Selects handling of `//@dump-sem-ir-[begin|end]` markers when dumping SemIR.
By default, `if-present` prints ranges for files that have them, and full SemIR
for files that don't. `only` skips files with no ranges, and `ignore` always
prints full SemIR.
)""",
},
[&](auto& arg_b) {
arg_b.SetOneOf(
{
arg_b.OneOfValue("if-present", DumpSemIRRanges::IfPresent)
.Default(true),
arg_b.OneOfValue("only", DumpSemIRRanges::Only),
arg_b.OneOfValue("ignore", DumpSemIRRanges::Ignore),
},
&dump_sem_ir_ranges);
});
b.AddFlag(
{
.name = "builtin-sem-ir",
@@ -399,6 +421,9 @@ class CompilationUnit {
// significant overhead. Avoid constructing it when unused.
auto GetParseTreeAndSubtrees() -> const Parse::TreeAndSubtrees&;
// Handles printing of formatted SemIR.
auto MaybePrintFormattedSemIR() -> void;
// Wraps a call with log statements to indicate start and end. Typically logs
// with the actual function name, but marks timings with the appropriate
// phase.
@@ -624,6 +649,33 @@ auto CompilationUnit::GetCheckUnit() -> Check::Unit {
.cpp_ast = &cpp_ast_};
}
auto CompilationUnit::MaybePrintFormattedSemIR() -> void {
bool print = options_->dump_sem_ir && IncludeInDumps();
if (!vlog_stream_ && !print) {
return;
}
if (options_->dump_sem_ir_ranges == CompileOptions::DumpSemIRRanges::Only &&
!tokens_->has_dump_sem_ir_ranges()) {
return;
}
bool use_dump_sem_ir_ranges =
options_->dump_sem_ir_ranges != CompileOptions::DumpSemIRRanges::Ignore &&
tokens_->has_dump_sem_ir_ranges();
SemIR::Formatter formatter(&*sem_ir_, *tree_and_subtrees_getter_,
cache_->include_in_dumps(),
use_dump_sem_ir_ranges);
formatter.Format();
if (vlog_stream_) {
CARBON_VLOG("*** SemIR::File ***\n");
formatter.Write(*vlog_stream_);
}
if (print) {
formatter.Write(*driver_env_->output_stream);
}
}
auto CompilationUnit::PostCheck() -> void {
CARBON_CHECK(sem_ir_, "Must call GetCheckUnit first");
@@ -644,19 +696,7 @@ auto CompilationUnit::PostCheck() -> void {
}
}
bool print = options_->dump_sem_ir && IncludeInDumps();
if (vlog_stream_ || print) {
SemIR::Formatter formatter(&*sem_ir_, *tree_and_subtrees_getter_,
cache_->include_in_dumps());
formatter.Format();
if (vlog_stream_) {
CARBON_VLOG("*** SemIR::File ***\n");
formatter.Write(*vlog_stream_);
}
if (print) {
formatter.Write(*driver_env_->output_stream);
}
}
MaybePrintFormattedSemIR();
if (sem_ir_->has_errors()) {
success_ = false;
}