Skip to content
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

Simplify interface for getting an instruction from a type. #3455

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
Prev Previous commit
Next Next commit
Move type functions from File onto the type value store.
  • Loading branch information
zygoloid committed Dec 8, 2023
commit bc2779194ef38e1e8240bab41720833a465ccfda
16 changes: 8 additions & 8 deletions toolchain/check/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -542,7 +542,7 @@ class TypeCompleter {
private:
// Adds `type_id` to the work list, if it's not already complete.
auto Push(SemIR::TypeId type_id) -> void {
if (!context_.sem_ir().IsTypeComplete(type_id)) {
if (!context_.types().IsComplete(type_id)) {
work_list_.push_back({type_id, Phase::AddNestedIncompleteTypes});
}
}
Expand All @@ -553,12 +553,12 @@ class TypeCompleter {

// We might have enqueued the same type more than once. Just skip the
// type if it's already complete.
if (context_.sem_ir().IsTypeComplete(type_id)) {
if (context_.types().IsComplete(type_id)) {
work_list_.pop_back();
return true;
}

auto inst = context_.sem_ir().GetType(type_id);
auto inst = context_.types().GetAsInst(type_id);
auto old_work_list_size = work_list_.size();

switch (phase) {
Expand All @@ -581,14 +581,14 @@ class TypeCompleter {
// Also complete the value representation type, if necessary. This
// should never fail: the value representation shouldn't require any
// additional nested types to be complete.
if (!context_.sem_ir().IsTypeComplete(value_rep.type_id)) {
if (!context_.types().IsComplete(value_rep.type_id)) {
work_list_.push_back({value_rep.type_id, Phase::BuildValueRepr});
}
// For a pointer representation, the pointee also needs to be complete.
if (value_rep.kind == SemIR::ValueRepr::Pointer) {
auto pointee_type_id =
context_.sem_ir().GetPointeeType(value_rep.type_id);
if (!context_.sem_ir().IsTypeComplete(pointee_type_id)) {
if (!context_.types().IsComplete(pointee_type_id)) {
work_list_.push_back({pointee_type_id, Phase::BuildValueRepr});
}
}
Expand Down Expand Up @@ -682,9 +682,9 @@ class TypeCompleter {
// Gets the value representation of a nested type, which should already be
// complete.
auto GetNestedValueRepr(SemIR::TypeId nested_type_id) const {
CARBON_CHECK(context_.sem_ir().IsTypeComplete(nested_type_id))
CARBON_CHECK(context_.types().IsComplete(nested_type_id))
<< "Nested type should already be complete";
auto value_rep = context_.sem_ir().GetValueRepr(nested_type_id);
auto value_rep = context_.types().GetValueRepr(nested_type_id);
CARBON_CHECK(value_rep.kind != SemIR::ValueRepr::Unknown)
<< "Complete type should have a value representation";
return value_rep;
Expand Down Expand Up @@ -1125,7 +1125,7 @@ auto Context::GetPointerType(Parse::NodeId parse_node,
}

auto Context::GetUnqualifiedType(SemIR::TypeId type_id) -> SemIR::TypeId {
if (auto const_type = sem_ir_->TryGetTypeAs<SemIR::ConstType>(type_id)) {
if (auto const_type = types().TryGetAs<SemIR::ConstType>(type_id)) {
return const_type->inner_id;
}
return type_id;
Expand Down
16 changes: 8 additions & 8 deletions toolchain/check/convert.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -547,7 +547,7 @@ static auto ConvertStructToClass(Context& context, SemIR::StructType src_type,
return SemIR::InstId::BuiltinError;
}
auto dest_struct_type =
context.sem_ir().GetTypeAs<SemIR::StructType>(class_info.object_repr_id);
context.types().GetAs<SemIR::StructType>(class_info.object_repr_id);

// If we're trying to create a class value, form a temporary for the value to
// point to.
Expand Down Expand Up @@ -599,7 +599,7 @@ static auto PerformBuiltinConversion(Context& context, Parse::NodeId parse_node,
auto& sem_ir = context.sem_ir();
auto value = sem_ir.insts().Get(value_id);
auto value_type_id = value.type_id();
auto target_type_inst = sem_ir.GetType(target.type_id);
auto target_type_inst = sem_ir.types().GetAsInst(target.type_id);

// Various forms of implicit conversion are supported as builtin conversions,
// either in addition to or instead of `impl`s of `ImplicitAs` in the Carbon
Expand Down Expand Up @@ -660,7 +660,7 @@ static auto PerformBuiltinConversion(Context& context, Parse::NodeId parse_node,
// converts to Ui.
if (auto target_tuple_type = target_type_inst.TryAs<SemIR::TupleType>()) {
if (auto src_tuple_type =
sem_ir.TryGetTypeAs<SemIR::TupleType>(value_type_id)) {
sem_ir.types().TryGetAs<SemIR::TupleType>(value_type_id)) {
return ConvertTupleToTuple(context, *src_tuple_type, *target_tuple_type,
value_id, target);
}
Expand All @@ -672,7 +672,7 @@ static auto PerformBuiltinConversion(Context& context, Parse::NodeId parse_node,
// to Ui.
if (auto target_struct_type = target_type_inst.TryAs<SemIR::StructType>()) {
if (auto src_struct_type =
sem_ir.TryGetTypeAs<SemIR::StructType>(value_type_id)) {
sem_ir.types().TryGetAs<SemIR::StructType>(value_type_id)) {
return ConvertStructToStruct(context, *src_struct_type,
*target_struct_type, value_id, target);
}
Expand All @@ -681,7 +681,7 @@ static auto PerformBuiltinConversion(Context& context, Parse::NodeId parse_node,
// A tuple (T1, T2, ..., Tn) converts to [T; n] if each Ti converts to T.
if (auto target_array_type = target_type_inst.TryAs<SemIR::ArrayType>()) {
if (auto src_tuple_type =
sem_ir.TryGetTypeAs<SemIR::TupleType>(value_type_id)) {
sem_ir.types().TryGetAs<SemIR::TupleType>(value_type_id)) {
return ConvertTupleToArray(context, *src_tuple_type, *target_array_type,
value_id, target);
}
Expand All @@ -693,7 +693,7 @@ static auto PerformBuiltinConversion(Context& context, Parse::NodeId parse_node,
// relevant).
if (auto target_class_type = target_type_inst.TryAs<SemIR::ClassType>()) {
if (auto src_struct_type =
sem_ir.TryGetTypeAs<SemIR::StructType>(value_type_id)) {
sem_ir.types().TryGetAs<SemIR::StructType>(value_type_id)) {
return ConvertStructToClass(context, *src_struct_type, *target_class_type,
value_id, target);
}
Expand All @@ -711,7 +711,7 @@ static auto PerformBuiltinConversion(Context& context, Parse::NodeId parse_node,
type_ids.push_back(ExprAsType(context, parse_node, tuple_inst_id));
}
auto tuple_type_id = context.CanonicalizeTupleType(parse_node, type_ids);
return sem_ir.GetTypeInstId(tuple_type_id);
return sem_ir.types().GetInstId(tuple_type_id);
}

// `{}` converts to `{} as type`.
Expand All @@ -720,7 +720,7 @@ static auto PerformBuiltinConversion(Context& context, Parse::NodeId parse_node,
if (auto struct_literal = value.TryAs<SemIR::StructLiteral>();
struct_literal &&
struct_literal->elements_id == SemIR::InstBlockId::Empty) {
value_id = sem_ir.GetTypeInstId(value_type_id);
value_id = sem_ir.types().GetInstId(value_type_id);
}
}

Expand Down
8 changes: 3 additions & 5 deletions toolchain/check/handle_class.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,8 @@ auto HandleClassDefinitionStart(Context& context, Parse::NodeId parse_node)
context.PushScope(class_decl_id, class_info.scope_id);

// Introduce `Self`.
context.AddNameToLookup(
parse_node, SemIR::NameId::SelfType,
context.sem_ir().GetTypeInstId(class_info.self_type_id));
context.AddNameToLookup(parse_node, SemIR::NameId::SelfType,
context.types().GetInstId(class_info.self_type_id));

context.inst_block_stack().Push();
context.node_stack().Push(parse_node, class_id);
Expand Down Expand Up @@ -227,8 +226,7 @@ auto HandleBaseDecl(Context& context, Parse::NodeId parse_node) -> bool {
// declaration as being final classes.
// TODO: Once we have a better idea of which types are considered to be
// classes, produce a better diagnostic for deriving from a non-class type.
auto base_class =
context.sem_ir().TryGetTypeAs<SemIR::ClassType>(base_type_id);
auto base_class = context.types().TryGetAs<SemIR::ClassType>(base_type_id);
if (!base_class ||
context.classes().Get(base_class->class_id).inheritance_kind ==
SemIR::Class::Final) {
Expand Down
2 changes: 1 addition & 1 deletion toolchain/check/handle_index.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ auto HandleIndexExpr(Context& context, Parse::NodeId parse_node) -> bool {
operand_inst_id = ConvertToValueOrRefExpr(context, operand_inst_id);
auto operand_inst = context.insts().Get(operand_inst_id);
auto operand_type_id = operand_inst.type_id();
auto operand_type_inst = context.sem_ir().GetType(operand_type_id);
auto operand_type_inst = context.types().GetAsInst(operand_type_id);

switch (operand_type_inst.kind()) {
case SemIR::ArrayType::Kind: {
Expand Down
6 changes: 3 additions & 3 deletions toolchain/check/handle_name.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ static auto GetExprValueForLookupResult(Context& context,
// If lookup finds a class declaration, the value is its `Self` type.
auto lookup_result = context.insts().Get(lookup_result_id);
if (auto class_decl = lookup_result.TryAs<SemIR::ClassDecl>()) {
return context.sem_ir().GetTypeInstId(
return context.types().GetInstId(
context.classes().Get(class_decl->class_id).self_type_id);
}

Expand Down Expand Up @@ -108,7 +108,7 @@ auto HandleMemberAccessExpr(Context& context, Parse::NodeId parse_node)
base_id = ConvertToValueOrRefExpr(context, base_id);
base_type_id = context.insts().Get(base_id).type_id();

switch (auto base_type = context.sem_ir().GetType(base_type_id);
switch (auto base_type = context.types().GetAsInst(base_type_id);
base_type.kind()) {
case SemIR::ClassType::Kind: {
// Perform lookup for the name in the class scope.
Expand All @@ -122,7 +122,7 @@ auto HandleMemberAccessExpr(Context& context, Parse::NodeId parse_node)
// Perform instance binding if we found an instance member.
auto member_type_id = context.insts().Get(member_id).type_id();
if (auto unbound_element_type =
context.sem_ir().TryGetTypeAs<SemIR::UnboundElementType>(
context.types().TryGetAs<SemIR::UnboundElementType>(
member_type_id)) {
// TODO: Check that the unbound element type describes a member of this
// class. Perform a conversion of the base if necessary.
Expand Down
2 changes: 1 addition & 1 deletion toolchain/check/handle_operator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ auto HandlePrefixOperator(Context& context, Parse::NodeId parse_node) -> bool {
context.GetUnqualifiedType(context.insts().Get(value_id).type_id());
auto result_type_id = SemIR::TypeId::Error;
if (auto pointer_type =
context.sem_ir().TryGetTypeAs<SemIR::PointerType>(type_id)) {
context.types().TryGetAs<SemIR::PointerType>(type_id)) {
result_type_id = pointer_type->pointee_id;
} else if (type_id != SemIR::TypeId::Error) {
CARBON_DIAGNOSTIC(
Expand Down
2 changes: 1 addition & 1 deletion toolchain/lower/handle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ auto HandleIntLiteral(FunctionContext& context, SemIR::InstId inst_id,

auto HandleNameRef(FunctionContext& context, SemIR::InstId inst_id,
SemIR::NameRef inst) -> void {
auto type_inst_id = context.sem_ir().GetTypeInstId(inst.type_id);
auto type_inst_id = context.sem_ir().types().GetInstId(inst.type_id);
if (type_inst_id == SemIR::InstId::BuiltinNamespaceType) {
return;
}
Expand Down
7 changes: 5 additions & 2 deletions toolchain/lower/handle_aggregates.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,10 @@ static auto GetStructFieldName(FunctionContext& context,
SemIR::TypeId struct_type_id,
SemIR::ElementIndex index) -> llvm::StringRef {
auto fields = context.sem_ir().inst_blocks().Get(
context.sem_ir().GetTypeAs<SemIR::StructType>(struct_type_id).fields_id);
context.sem_ir()
.types()
.GetAs<SemIR::StructType>(struct_type_id)
.fields_id);
auto field = context.sem_ir().insts().GetAs<SemIR::StructTypeField>(
fields[index.index]);
return context.sem_ir().names().GetIRBaseName(field.name_id);
Expand All @@ -101,7 +104,7 @@ auto HandleClassElementAccess(FunctionContext& context, SemIR::InstId inst_id,
// Find the class that we're performing access into.
auto class_type_id = context.sem_ir().insts().Get(inst.base_id).type_id();
auto class_id =
context.sem_ir().GetTypeAs<SemIR::ClassType>(class_type_id).class_id;
context.sem_ir().types().GetAs<SemIR::ClassType>(class_type_id).class_id;
const auto& class_info = context.sem_ir().classes().Get(class_id);

// Translate the class field access into a struct access on the object
Expand Down
14 changes: 7 additions & 7 deletions toolchain/sem_ir/file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ static auto GetTypePrecedence(InstKind kind) -> int {
}

auto File::StringifyType(TypeId type_id) const -> std::string {
return StringifyTypeExpr(GetTypeInstId(type_id));
return StringifyTypeExpr(types().GetInstId(type_id));
}

auto File::StringifyTypeExpr(InstId outer_inst_id) const -> std::string {
Expand Down Expand Up @@ -278,7 +278,7 @@ auto File::StringifyTypeExpr(InstId outer_inst_id) const -> std::string {
if (step.index == 0) {
out << "[";
steps.push_back(step.Next());
steps.push_back({.inst_id = GetTypeInstId(array.element_type_id)});
steps.push_back({.inst_id = types().GetInstId(array.element_type_id)});
} else if (step.index == 1) {
out << "; " << GetArrayBoundValue(array.bound_id) << "]";
}
Expand All @@ -296,7 +296,7 @@ auto File::StringifyTypeExpr(InstId outer_inst_id) const -> std::string {

// Add parentheses if required.
auto inner_type_inst_id =
GetTypeInstId(inst.As<ConstType>().inner_id);
types().GetInstId(inst.As<ConstType>().inner_id);
if (GetTypePrecedence(insts().Get(inner_type_inst_id).kind()) <
GetTypePrecedence(inst.kind())) {
out << "(";
Expand All @@ -317,7 +317,7 @@ auto File::StringifyTypeExpr(InstId outer_inst_id) const -> std::string {
if (step.index == 0) {
steps.push_back(step.Next());
steps.push_back(
{.inst_id = GetTypeInstId(inst.As<PointerType>().pointee_id)});
{.inst_id = types().GetInstId(inst.As<PointerType>().pointee_id)});
} else if (step.index == 1) {
out << "*";
}
Expand All @@ -344,7 +344,7 @@ auto File::StringifyTypeExpr(InstId outer_inst_id) const -> std::string {
case StructTypeField::Kind: {
auto field = inst.As<StructTypeField>();
out << "." << names().GetFormatted(field.name_id) << ": ";
steps.push_back({.inst_id = GetTypeInstId(field.field_type_id)});
steps.push_back({.inst_id = types().GetInstId(field.field_type_id)});
break;
}
case TupleType::Kind: {
Expand All @@ -366,14 +366,14 @@ auto File::StringifyTypeExpr(InstId outer_inst_id) const -> std::string {
break;
}
steps.push_back(step.Next());
steps.push_back({.inst_id = GetTypeInstId(refs[step.index])});
steps.push_back({.inst_id = types().GetInstId(refs[step.index])});
break;
}
case UnboundElementType::Kind: {
if (step.index == 0) {
out << "<unbound element of class ";
steps.push_back(step.Next());
steps.push_back({.inst_id = GetTypeInstId(
steps.push_back({.inst_id = types().GetInstId(
inst.As<UnboundElementType>().class_type_id)});
} else {
out << ">";
Expand Down
55 changes: 1 addition & 54 deletions toolchain/sem_ir/file.h
Original file line number Diff line number Diff line change
Expand Up @@ -164,59 +164,6 @@ class File : public Printable<File> {
complete_types_.push_back(object_type_id);
}

// Returns the ID of the instruction used to define the specified type.
auto GetTypeInstId(TypeId type_id) const -> InstId {
if (type_id == TypeId::TypeType) {
return InstId::BuiltinTypeType;
} else if (type_id == TypeId::Error) {
return InstId::BuiltinError;
} else if (type_id == TypeId::Invalid) {
return InstId::Invalid;
} else {
return types().Get(type_id).inst_id;
}
}

// Returns the instruction used to define the specified type.
auto GetType(TypeId type_id) const -> Inst {
return insts().Get(GetTypeInstId(type_id));
}

// Returns the instruction used to define the specified type, which is known
// to be a particular kind of instruction.
template <typename InstKind>
auto GetTypeAs(TypeId type_id) const -> InstKind {
if constexpr (std::is_same_v<InstKind, Builtin>) {
return GetType(type_id).As<InstKind>();
} else {
// The type is not a builtin, so no need to check for special values.
return insts().Get(types().Get(type_id).inst_id).As<InstKind>();
}
}

// Returns the instruction used to define the specified type, if it is of a
// particular kind.
template <typename InstKind>
auto TryGetTypeAs(TypeId type_id) const -> std::optional<InstKind> {
return GetType(type_id).TryAs<InstKind>();
}

// Gets the value representation to use for a type. This returns an
// invalid type if the given type is not complete.
auto GetValueRepr(TypeId type_id) const -> ValueRepr {
if (type_id.index < 0) {
// TypeType and InvalidType are their own value representation.
return {.kind = ValueRepr::Copy, .type_id = type_id};
}
return types().Get(type_id).value_repr;
}

// Determines whether the given type is known to be complete. This does not
// determine whether the type could be completed, only whether it has been.
auto IsTypeComplete(TypeId type_id) const -> bool {
return GetValueRepr(type_id).kind != ValueRepr::Unknown;
}

// Gets the pointee type of the given type, which must be a pointer type.
auto GetPointeeType(TypeId pointer_id) const -> TypeId {
return insts()
Expand Down Expand Up @@ -384,7 +331,7 @@ auto GetExprCategory(const File& file, InstId inst_id) -> ExprCategory;

// Returns information about the value representation to use for a type.
inline auto GetValueRepr(const File& file, TypeId type_id) -> ValueRepr {
return file.GetValueRepr(type_id);
return file.types().GetValueRepr(type_id);
}

// The initializing representation to use when returning by value.
Expand Down