Skip to content

Add formatted textual IR output #3056

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 34 commits into from
Aug 10, 2023
Merged
Show file tree
Hide file tree
Changes from 28 commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
e87441a
Basic formatting.
zygoloid Jun 10, 2023
af8035d
Node and label naming.
zygoloid Jul 31, 2023
cef0ffa
Add formatting for references to builtins and for struct types.
zygoloid Jul 31, 2023
0405e2c
Fix formatting of struct member access.
zygoloid Jul 31, 2023
aabb504
Remove fallback formatting and add missing FormatArg overloads.
zygoloid Jul 31, 2023
c11bffc
Improve printing of tuples and calls.
zygoloid Jul 31, 2023
60159b9
Improve robustness.
zygoloid Aug 1, 2023
e3b4cc9
Move node name formatting up a level.
zygoloid Aug 1, 2023
9d64ff5
Add more vertical space after a forward declaration of a function.
zygoloid Aug 1, 2023
15df6f2
Fix up after rebase.
zygoloid Aug 3, 2023
6b427e6
Remove redundant "as type" printing.
zygoloid Aug 3, 2023
86a3b02
Clean up output format.
zygoloid Aug 3, 2023
4ced618
Deduplicate names, and use name qualifiers when necessary.
zygoloid Aug 3, 2023
5aa71d5
pre-commit
zygoloid Aug 3, 2023
fa5ce9f
Clean up node value kind representation.
zygoloid Aug 3, 2023
9340b93
Merge branch 'trunk' into toolchain-ir-output
zygoloid Aug 3, 2023
ba78229
Fix :semantics_ir_test.
zygoloid Aug 4, 2023
e43e822
Use source location to identify values.
zygoloid Aug 4, 2023
2e961c2
Tweak some instruction names.
zygoloid Aug 5, 2023
3a85110
pre-commit
zygoloid Aug 5, 2023
e4ea8b8
Merge branch 'trunk' into toolchain-ir-output
zygoloid Aug 8, 2023
8745782
Regenerate test expectations.
zygoloid Aug 8, 2023
cc45c58
Use `.L` prefix to introduce a line number.
zygoloid Aug 8, 2023
ce693a6
Parenthesize line and column and separate them with a colon.
zygoloid Aug 9, 2023
0838615
Switch to Chandler's preferred syntax.
zygoloid Aug 9, 2023
fc1ca6d
Address some review comments.
zygoloid Aug 9, 2023
85c0e88
Merge branch 'trunk' into toolchain-ir-output
zygoloid Aug 9, 2023
36e541d
Autoupdate after merge.
zygoloid Aug 9, 2023
332bfda
Responses to review comments.
zygoloid Aug 10, 2023
47421d6
Update toolchain/semantics/semantics_ir_formatter.cpp
zygoloid Aug 10, 2023
1c0181d
Update toolchain/semantics/semantics_ir_formatter.cpp
zygoloid Aug 10, 2023
a749bca
Merge branch 'trunk' into toolchain-ir-output
zygoloid Aug 10, 2023
24ba19e
Regenerate test expectations.
zygoloid Aug 10, 2023
ecc72e9
pre-commit
zygoloid Aug 10, 2023
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
1 change: 1 addition & 0 deletions toolchain/driver/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ cc_library(
"//toolchain/lowering:lower_to_llvm",
"//toolchain/parser:parse_tree",
"//toolchain/semantics:semantics_ir",
"//toolchain/semantics:semantics_ir_formatter",
"//toolchain/source:source_buffer",
"@llvm-project//llvm:Core",
"@llvm-project//llvm:Support",
Expand Down
25 changes: 22 additions & 3 deletions toolchain/driver/driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "toolchain/lowering/lower_to_llvm.h"
#include "toolchain/parser/parse_tree.h"
#include "toolchain/semantics/semantics_ir.h"
#include "toolchain/semantics/semantics_ir_formatter.h"
#include "toolchain/source/source_buffer.h"

namespace Carbon {
Expand Down Expand Up @@ -116,6 +117,7 @@ auto Driver::RunHelpSubcommand(DiagnosticConsumer& /*consumer*/,
enum class DumpMode {
TokenizedBuffer,
ParseTree,
RawSemanticsIR,
SemanticsIR,
LLVMIR,
Assembly,
Expand All @@ -133,6 +135,7 @@ auto Driver::RunDumpSubcommand(DiagnosticConsumer& consumer,
auto dump_mode = llvm::StringSwitch<DumpMode>(args.front())
.Case("tokens", DumpMode::TokenizedBuffer)
.Case("parse-tree", DumpMode::ParseTree)
.Case("raw-semantics-ir", DumpMode::RawSemanticsIR)
.Case("semantics-ir", DumpMode::SemanticsIR)
.Case("llvm-ir", DumpMode::LLVMIR)
.Case("assembly", DumpMode::Assembly)
Expand All @@ -152,9 +155,16 @@ auto Driver::RunDumpSubcommand(DiagnosticConsumer& consumer,
parse_tree_preorder = true;
}

bool semantics_ir_include_builtins = false;
bool semantics_ir_include_raw = false;
if (dump_mode == DumpMode::SemanticsIR && !args.empty() &&
args.front() == "--include_builtins") {
args.front() == "--include_raw") {
args = args.drop_front();
semantics_ir_include_raw = true;
}

bool semantics_ir_include_builtins = false;
if ((dump_mode == DumpMode::RawSemanticsIR || semantics_ir_include_raw) &&
!args.empty() && args.front() == "--include_builtins") {
args = args.drop_front();
semantics_ir_include_builtins = true;
}
Expand Down Expand Up @@ -239,10 +249,19 @@ auto Driver::RunDumpSubcommand(DiagnosticConsumer& consumer,
builtin_ir, tokenized_source, parse_tree, consumer, vlog_stream_);
has_errors |= semantics_ir.has_errors();
CARBON_VLOG() << "*** SemanticsIR::MakeFromParseTree done ***\n";
if (dump_mode == DumpMode::SemanticsIR) {
if (dump_mode == DumpMode::RawSemanticsIR) {
semantics_ir.Print(output_stream_, semantics_ir_include_builtins);
return !has_errors;
}
if (dump_mode == DumpMode::SemanticsIR) {
if (semantics_ir_include_raw) {
semantics_ir.Print(output_stream_, semantics_ir_include_builtins);
output_stream_ << "\n";
}
FormatSemanticsIR(tokenized_source, parse_tree, semantics_ir,
output_stream_);
return !has_errors;
}
CARBON_VLOG() << "semantics_ir: " << semantics_ir;

// Unlike previous steps, errors block further progress.
Expand Down
17 changes: 17 additions & 0 deletions toolchain/semantics/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,23 @@ cc_library(
],
)

cc_library(
name = "semantics_ir_formatter",
srcs = [
"semantics_ir_formatter.cpp",
],
hdrs = [
"semantics_ir_formatter.h",
],
deps = [
":semantics_ir",
":semantics_node_kind",
"//toolchain/lexer:tokenized_buffer",
"//toolchain/parser:parse_tree",
"@llvm-project//llvm:Support",
],
)

cc_test(
name = "semantics_ir_test",
size = "small",
Expand Down
3 changes: 2 additions & 1 deletion toolchain/semantics/semantics_file_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ class SemanticsFileTest : public DriverFileTestBase {
using DriverFileTestBase::DriverFileTestBase;

auto GetDefaultArgs() -> llvm::SmallVector<std::string> override {
return {"dump", "semantics-ir", "%s"};
// TODO: Remove the "--include_raw" once the textual IR format stabilizes.
return {"dump", "semantics-ir", "--include_raw", "%s"};
}
};

Expand Down
6 changes: 5 additions & 1 deletion toolchain/semantics/semantics_handle_function.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@ static auto BuildFunctionDeclaration(SemanticsContext& context)

// Add the callable.
auto function_id = context.semantics_ir().AddFunction(
{.name_id = name_context.unresolved_name_id,
{.name_id =
name_context.state ==
SemanticsDeclarationNameStack::Context::State::Unresolved
? name_context.unresolved_name_id
: SemanticsStringId(SemanticsStringId::InvalidIndex),
.param_refs_id = param_refs_id,
.return_type_id = return_type_id,
.body_block_ids = {}});
Expand Down
20 changes: 13 additions & 7 deletions toolchain/semantics/semantics_ir.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
#include "toolchain/semantics/semantics_ir.h"

#include "common/check.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/SaveAndRestore.h"
#include "toolchain/common/pretty_stack_trace_function.h"
#include "toolchain/parser/parse_tree_node_location_translator.h"
#include "toolchain/semantics/semantics_builtin_kind.h"
Expand Down Expand Up @@ -248,7 +251,8 @@ static auto GetTypePrecedence(SemanticsNodeKind kind) -> int {
}
}

auto SemanticsIR::StringifyType(SemanticsTypeId type_id) -> std::string {
auto SemanticsIR::StringifyType(SemanticsTypeId type_id,
bool in_type_context) const -> std::string {
std::string str;
llvm::raw_string_ostream out(str);

Expand Down Expand Up @@ -396,12 +400,14 @@ auto SemanticsIR::StringifyType(SemanticsTypeId type_id) -> std::string {
}

// For `{}` or any tuple type, we've printed a non-type expression, so add a
// conversion to type `type`.
auto outer_node = GetNode(outer_node_id);
if (outer_node.kind() == SemanticsNodeKind::TupleType ||
(outer_node.kind() == SemanticsNodeKind::StructType &&
GetNodeBlock(outer_node.GetAsStructType()).empty())) {
out << " as type";
// conversion to type `type` if it's not implied by the context.
if (!in_type_context) {
auto outer_node = GetNode(outer_node_id);
if (outer_node.kind() == SemanticsNodeKind::TupleType ||
(outer_node.kind() == SemanticsNodeKind::StructType &&
GetNodeBlock(outer_node.GetAsStructType()).empty())) {
out << " as type";
}
}

return str;
Expand Down
14 changes: 10 additions & 4 deletions toolchain/semantics/semantics_ir.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ class SemanticsIR {
}

// Returns the requested callable.
auto GetFunction(SemanticsFunctionId function_id) const -> SemanticsFunction {
auto GetFunction(SemanticsFunctionId function_id) const
-> const SemanticsFunction& {
return functions_[function_id.index];
}

Expand Down Expand Up @@ -135,7 +136,7 @@ class SemanticsIR {
}

// Returns the requested name scope.
auto GetNameScope(SemanticsNameScopeId scope_id)
auto GetNameScope(SemanticsNameScopeId scope_id) const
-> const llvm::DenseMap<SemanticsStringId, SemanticsNodeId>& {
return name_scopes_[scope_id.index];
}
Expand Down Expand Up @@ -266,11 +267,16 @@ class SemanticsIR {
return type_blocks_[block_id.index];
}

// Produces a string version of a type.
auto StringifyType(SemanticsTypeId type_id) -> std::string;
// Produces a string version of a type. If `in_type_context` is false, an
// explicit conversion to type `type` will be added in cases where the type
// expression would otherwise have a different type, such as a tuple or
// struct type.
auto StringifyType(SemanticsTypeId type_id,
bool in_type_context = false) const -> std::string;

auto functions_size() const -> int { return functions_.size(); }
auto nodes_size() const -> int { return nodes_.size(); }
auto node_blocks_size() const -> int { return node_blocks_.size(); }

auto types() const -> const llvm::SmallVector<SemanticsNodeId>& {
return types_;
Expand Down
Loading