mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-29 21:15:26 +01:00
As part of this, move functions that seem reasonable to make out-of-line to a separate `_impl.h` header file that is only included where the explicit instantiation _definition_ is provided. By using explicit instantiation we can make these templates behave more like non-template classes in terms of supporting out-of-line definitions that don't need to be compiled by every translation unit. The set of eventual instantiations here is fundamentally known, and there tend to be headers that define a canonical "leaf" type where it makes sense to trigger the explicit instantiation. Where we already had a `.cpp` file to put the explicit instantiation definition, use it. But in some places we didn't have such a `.cpp` file so this PR adds those. This also requires that we have precise constraints on APIs that _can't_ be instantiated for specific argument types, as now we don't do this lazily. Combined, this appears to reduce the sum of object file sizes in the `check` directory by almost 40% (122mb -> 74mb) in my measurement. My actual goal was to improve compile times, but so far I don't have a great methodology for measuring these... But the object file size reduction seems to confirm this is a net win and likely represents a non-trivial improvement in compile time. Assisted-by: Antigravity with Gemini
66 lines
2.0 KiB
C++
66 lines
2.0 KiB
C++
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
|
// Exceptions. See /LICENSE for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
|
|
#include "toolchain/sem_ir/import_ir.h"
|
|
|
|
#include <utility>
|
|
|
|
#include "toolchain/base/value_store_impl.h"
|
|
#include "toolchain/sem_ir/file.h"
|
|
|
|
namespace Carbon::SemIR {
|
|
|
|
auto ImportIR::Print(llvm::raw_ostream& out) const -> void {
|
|
out << "{decl_id: " << decl_id
|
|
<< ", is_export: " << (is_export ? "true" : "false") << "}";
|
|
}
|
|
|
|
auto ImportIRInst::Print(llvm::raw_ostream& out) const -> void {
|
|
out << "{ir_id: " << ir_id() << ", ";
|
|
if (ir_id() == ImportIRId::Cpp) {
|
|
out << "clang_source_loc_id: " << clang_source_loc_id();
|
|
} else {
|
|
out << "inst_id: " << inst_id();
|
|
}
|
|
out << "}";
|
|
}
|
|
|
|
auto GetCanonicalFileAndInstId(const File* sem_ir, InstId inst_id)
|
|
-> std::pair<const File*, InstId> {
|
|
while (true) {
|
|
// Step through an imported instruction to the instruction it was imported
|
|
// from.
|
|
if (auto import_ir_inst_id = sem_ir->insts().GetImportSource(inst_id);
|
|
import_ir_inst_id.has_value()) {
|
|
auto import_ir_inst = sem_ir->import_ir_insts().Get(import_ir_inst_id);
|
|
// TODO: For imports from C++, we return the importing instruction, which
|
|
// isn't necessarily canonical.
|
|
if (import_ir_inst.ir_id() != ImportIRId::Cpp) {
|
|
sem_ir = sem_ir->import_irs().Get(import_ir_inst.ir_id()).sem_ir;
|
|
inst_id = import_ir_inst.inst_id();
|
|
continue;
|
|
}
|
|
}
|
|
|
|
// Step through export declarations to their exported value.
|
|
if (auto export_decl = sem_ir->insts().TryGetAs<ExportDecl>(inst_id)) {
|
|
inst_id = export_decl->value_id;
|
|
continue;
|
|
}
|
|
|
|
// Reached a non-imported entity.
|
|
break;
|
|
}
|
|
|
|
return std::make_pair(sem_ir, inst_id);
|
|
}
|
|
|
|
} // namespace Carbon::SemIR
|
|
|
|
namespace Carbon {
|
|
template class ValueStore<SemIR::ImportIRId, SemIR::ImportIR,
|
|
Tag<SemIR::CheckIRId>>;
|
|
template class ValueStore<SemIR::ImportIRInstId, SemIR::ImportIRInst>;
|
|
} // namespace Carbon
|