|
|
@@ -333,22 +333,15 @@ class CompilationUnit {
|
|
|
// Parses tokens. Returns true on success.
|
|
|
auto RunParse() -> void;
|
|
|
|
|
|
- // Prepares per-IR lazy fetch functions which may come up in cross-IR
|
|
|
- // diagnostics.
|
|
|
- auto PreCheck() -> Parse::GetTreeAndSubtreesFn;
|
|
|
-
|
|
|
// Returns information needed to check this unit.
|
|
|
- auto GetCheckUnit(
|
|
|
- SemIR::CheckIRId check_ir_id,
|
|
|
- llvm::ArrayRef<Parse::GetTreeAndSubtreesFn> all_trees_and_subtrees)
|
|
|
- -> Check::Unit;
|
|
|
+ auto GetCheckUnit(SemIR::CheckIRId check_ir_id) -> Check::Unit;
|
|
|
|
|
|
// Runs post-check logic. Returns true if checking succeeded for the IR.
|
|
|
auto PostCheck() -> void;
|
|
|
|
|
|
// Lower SemIR to LLVM IR.
|
|
|
auto RunLower(std::optional<llvm::ArrayRef<Parse::GetTreeAndSubtreesFn>>
|
|
|
- all_trees_and_subtrees_for_debug_info) -> void;
|
|
|
+ tree_and_subtrees_getters_for_debug_info) -> void;
|
|
|
|
|
|
auto RunCodeGen() -> void;
|
|
|
|
|
|
@@ -363,6 +356,9 @@ class CompilationUnit {
|
|
|
auto input_filename() -> llvm::StringRef { return input_filename_; }
|
|
|
auto success() -> bool { return success_; }
|
|
|
auto has_source() -> bool { return source_.has_value(); }
|
|
|
+ auto get_trees_and_subtrees() -> Parse::GetTreeAndSubtreesFn {
|
|
|
+ return *tree_and_subtrees_getter_;
|
|
|
+ }
|
|
|
|
|
|
private:
|
|
|
// Do codegen. Returns true on success.
|
|
|
@@ -414,8 +410,7 @@ class CompilationUnit {
|
|
|
std::optional<Parse::Tree> parse_tree_;
|
|
|
std::optional<Parse::TreeAndSubtrees> parse_tree_and_subtrees_;
|
|
|
std::optional<std::function<const Parse::TreeAndSubtrees&()>>
|
|
|
- get_parse_tree_and_subtrees_;
|
|
|
- std::optional<Check::SemIRDiagnosticConverter> sem_ir_converter_;
|
|
|
+ tree_and_subtrees_getter_;
|
|
|
std::optional<SemIR::File> sem_ir_;
|
|
|
std::unique_ptr<llvm::LLVMContext> llvm_context_;
|
|
|
std::unique_ptr<llvm::Module> module_;
|
|
|
@@ -500,36 +495,25 @@ auto CompilationUnit::RunParse() -> void {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-auto CompilationUnit::PreCheck() -> Parse::GetTreeAndSubtreesFn {
|
|
|
+auto CompilationUnit::GetCheckUnit(SemIR::CheckIRId check_ir_id)
|
|
|
+ -> Check::Unit {
|
|
|
CARBON_CHECK(parse_tree_, "Must call RunParse first");
|
|
|
- CARBON_CHECK(!get_parse_tree_and_subtrees_, "Called PreCheck twice");
|
|
|
+ CARBON_CHECK(!sem_ir_, "Called GetCheckUnit twice");
|
|
|
|
|
|
- get_parse_tree_and_subtrees_ = [this]() -> const Parse::TreeAndSubtrees& {
|
|
|
+ tree_and_subtrees_getter_ = [this]() -> const Parse::TreeAndSubtrees& {
|
|
|
return this->GetParseTreeAndSubtrees();
|
|
|
};
|
|
|
- return *get_parse_tree_and_subtrees_;
|
|
|
-}
|
|
|
-
|
|
|
-auto CompilationUnit::GetCheckUnit(
|
|
|
- SemIR::CheckIRId check_ir_id,
|
|
|
- llvm::ArrayRef<Parse::GetTreeAndSubtreesFn> all_trees_and_subtrees)
|
|
|
- -> Check::Unit {
|
|
|
- CARBON_CHECK(get_parse_tree_and_subtrees_, "Must call PreCheck first");
|
|
|
- CARBON_CHECK(!sem_ir_converter_, "Called GetCheckUnit twice");
|
|
|
-
|
|
|
sem_ir_.emplace(&*parse_tree_, check_ir_id, parse_tree_->packaging_decl(),
|
|
|
value_stores_, input_filename_);
|
|
|
- sem_ir_converter_.emplace(all_trees_and_subtrees, &*sem_ir_);
|
|
|
return {.consumer = consumer_,
|
|
|
.value_stores = &value_stores_,
|
|
|
.timings = timings_ ? &*timings_ : nullptr,
|
|
|
- .get_parse_tree_and_subtrees = *get_parse_tree_and_subtrees_,
|
|
|
- .sem_ir = &*sem_ir_,
|
|
|
- .sem_ir_converter = &*sem_ir_converter_};
|
|
|
+ .tree_and_subtrees_getter = *tree_and_subtrees_getter_,
|
|
|
+ .sem_ir = &*sem_ir_};
|
|
|
}
|
|
|
|
|
|
auto CompilationUnit::PostCheck() -> void {
|
|
|
- CARBON_CHECK(sem_ir_converter_, "Must call GetCheckUnit first");
|
|
|
+ CARBON_CHECK(sem_ir_, "Must call GetCheckUnit first");
|
|
|
|
|
|
// We've finished all steps that can produce diagnostics. Emit the
|
|
|
// diagnostics now, so that the developer sees them sooner and doesn't need
|
|
|
@@ -589,15 +573,15 @@ auto CompilationUnit::PostCheck() -> void {
|
|
|
|
|
|
auto CompilationUnit::RunLower(
|
|
|
std::optional<llvm::ArrayRef<Parse::GetTreeAndSubtreesFn>>
|
|
|
- all_trees_and_subtrees_for_debug_info) -> void {
|
|
|
+ tree_and_subtrees_getters_for_debug_info) -> void {
|
|
|
LogCall("Lower::LowerToLLVM", "lower", [&] {
|
|
|
llvm_context_ = std::make_unique<llvm::LLVMContext>();
|
|
|
// TODO: Consider disabling instruction naming by default if we're not
|
|
|
// producing textual LLVM IR.
|
|
|
SemIR::InstNamer inst_namer(&*sem_ir_);
|
|
|
module_ = Lower::LowerToLLVM(
|
|
|
- *llvm_context_, all_trees_and_subtrees_for_debug_info, input_filename_,
|
|
|
- *sem_ir_, &inst_namer, vlog_stream_);
|
|
|
+ *llvm_context_, tree_and_subtrees_getters_for_debug_info,
|
|
|
+ input_filename_, *sem_ir_, &inst_namer, vlog_stream_);
|
|
|
});
|
|
|
if (vlog_stream_) {
|
|
|
CARBON_VLOG("*** llvm::Module ***\n");
|
|
|
@@ -843,25 +827,13 @@ auto CompileSubcommand::Run(DriverEnv& driver_env) -> DriverResult {
|
|
|
return make_result();
|
|
|
}
|
|
|
|
|
|
- // Pre-check assigns IR IDs and constructs node converters.
|
|
|
- llvm::SmallVector<Parse::GetTreeAndSubtreesFn> all_trees_and_subtrees;
|
|
|
- // This size may not match due to units that are missing source, but that's an
|
|
|
- // error case and not worth extra work.
|
|
|
- all_trees_and_subtrees.reserve(units.size());
|
|
|
- for (auto& unit : units) {
|
|
|
- if (unit->has_source()) {
|
|
|
- all_trees_and_subtrees.push_back(unit->PreCheck());
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
// Gather Check::Units.
|
|
|
llvm::SmallVector<Check::Unit> check_units;
|
|
|
- check_units.reserve(all_trees_and_subtrees.size());
|
|
|
+ check_units.reserve(units.size());
|
|
|
for (auto& unit : units) {
|
|
|
if (unit->has_source()) {
|
|
|
SemIR::CheckIRId check_ir_id(check_units.size());
|
|
|
- check_units.push_back(
|
|
|
- unit->GetCheckUnit(check_ir_id, all_trees_and_subtrees));
|
|
|
+ check_units.push_back(unit->GetCheckUnit(check_ir_id));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
@@ -888,13 +860,23 @@ auto CompileSubcommand::Run(DriverEnv& driver_env) -> DriverResult {
|
|
|
}
|
|
|
|
|
|
// Lower.
|
|
|
+ llvm::SmallVector<Parse::GetTreeAndSubtreesFn> tree_and_subtrees_getters;
|
|
|
std::optional<llvm::ArrayRef<Parse::GetTreeAndSubtreesFn>>
|
|
|
- all_trees_and_subtrees_for_debug_info;
|
|
|
+ tree_and_subtrees_getters_for_debug_info;
|
|
|
if (options_.include_debug_info) {
|
|
|
- all_trees_and_subtrees_for_debug_info = all_trees_and_subtrees;
|
|
|
+ // This size may not match due to units that are missing source, but that's
|
|
|
+ // an error case and not worth extra work.
|
|
|
+ tree_and_subtrees_getters.reserve(units.size());
|
|
|
+ for (auto& unit : units) {
|
|
|
+ if (unit->has_source()) {
|
|
|
+ tree_and_subtrees_getters.push_back(unit->get_trees_and_subtrees());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ tree_and_subtrees_getters_for_debug_info = {};
|
|
|
+ tree_and_subtrees_getters_for_debug_info = tree_and_subtrees_getters;
|
|
|
}
|
|
|
for (const auto& unit : units) {
|
|
|
- unit->RunLower(all_trees_and_subtrees_for_debug_info);
|
|
|
+ unit->RunLower(tree_and_subtrees_getters_for_debug_info);
|
|
|
}
|
|
|
if (options_.phase == CompileOptions::Phase::Lower) {
|
|
|
return make_result();
|