mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 20:01:14 +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
93 lines
2.9 KiB
C++
93 lines
2.9 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
|
|
|
|
#ifndef CARBON_TOOLCHAIN_SEM_IR_IMPORT_IR_H_
|
|
#define CARBON_TOOLCHAIN_SEM_IR_IMPORT_IR_H_
|
|
|
|
#include "llvm/ADT/FoldingSet.h"
|
|
#include "toolchain/base/value_store.h"
|
|
#include "toolchain/sem_ir/ids.h"
|
|
#include "toolchain/sem_ir/inst.h"
|
|
|
|
namespace Carbon::SemIR {
|
|
|
|
// A reference to an imported IR.
|
|
struct ImportIR : public Printable<ImportIR> {
|
|
auto Print(llvm::raw_ostream& out) const -> void;
|
|
|
|
// The `import` declaration.
|
|
InstId decl_id;
|
|
// True if this is part of an `export import`.
|
|
bool is_export;
|
|
// The imported IR.
|
|
const File* sem_ir;
|
|
};
|
|
|
|
static_assert(sizeof(ImportIR) == 8 + sizeof(uintptr_t), "Unexpected size");
|
|
|
|
using ImportIRStore = ValueStore<ImportIRId, ImportIR, Tag<CheckIRId>>;
|
|
|
|
// A reference to an instruction in an imported IR. Used for diagnostics with
|
|
// LocId. For a `Cpp` import, points to a Clang source location.
|
|
class ImportIRInst : public Printable<ImportIRInst> {
|
|
public:
|
|
// Constructor for a non-`Cpp` import.
|
|
explicit ImportIRInst(ImportIRId ir_id, InstId inst_id)
|
|
: ir_id_(ir_id), inst_id_(inst_id) {
|
|
CARBON_CHECK(ir_id != ImportIRId::Cpp);
|
|
}
|
|
|
|
// Constructor for a `Cpp` import.
|
|
explicit ImportIRInst(ClangSourceLocId clang_source_loc_id)
|
|
: ir_id_(ImportIRId::Cpp), clang_source_loc_id_(clang_source_loc_id) {}
|
|
|
|
auto Print(llvm::raw_ostream& out) const -> void;
|
|
|
|
friend auto operator==(const ImportIRInst& lhs, const ImportIRInst& rhs)
|
|
-> bool {
|
|
return lhs.ir_id() == rhs.ir_id() &&
|
|
(lhs.ir_id() == ImportIRId::Cpp
|
|
? lhs.clang_source_loc_id() == rhs.clang_source_loc_id()
|
|
: lhs.inst_id() == rhs.inst_id());
|
|
}
|
|
|
|
auto ir_id() const -> ImportIRId { return ir_id_; }
|
|
auto inst_id() const -> InstId {
|
|
CARBON_CHECK(ir_id() != ImportIRId::Cpp);
|
|
return inst_id_;
|
|
}
|
|
auto clang_source_loc_id() const -> ClangSourceLocId {
|
|
CARBON_CHECK(ir_id() == ImportIRId::Cpp);
|
|
return clang_source_loc_id_;
|
|
}
|
|
|
|
private:
|
|
ImportIRId ir_id_;
|
|
union {
|
|
// Set iff `ir_id != ImportIRId::Cpp`.
|
|
InstId inst_id_;
|
|
|
|
// Set iff `ir_id == ImportIRId::Cpp`.
|
|
ClangSourceLocId clang_source_loc_id_;
|
|
};
|
|
};
|
|
|
|
using ImportIRInstStore = ValueStore<ImportIRInstId, ImportIRInst>;
|
|
|
|
// Returns the canonical `File` and `InstId` for an entity, tracing imported
|
|
// instructions. Note the returned `File` might not be directly imported by the
|
|
// input `sem_ir`.
|
|
auto GetCanonicalFileAndInstId(const File* sem_ir, InstId inst_id)
|
|
-> std::pair<const File*, InstId>;
|
|
|
|
} // namespace Carbon::SemIR
|
|
|
|
namespace Carbon {
|
|
extern template class ValueStore<SemIR::ImportIRId, SemIR::ImportIR,
|
|
Tag<SemIR::CheckIRId>>;
|
|
extern template class ValueStore<SemIR::ImportIRInstId, SemIR::ImportIRInst>;
|
|
} // namespace Carbon
|
|
|
|
#endif // CARBON_TOOLCHAIN_SEM_IR_IMPORT_IR_H_
|