mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Canonicalize generated functions for Core witnesses (#7729)
Use a single `SemIR::Function` per `Core` interface method, whether it's generated locally or imported. This prevents generating duplicate functions, which lead to different types when the witness appears in a `FacetValue` as part of a specific for a class. We use a `CanonicalValueStore` of `GeneratedFunction` objects that allow finding an existing FunctionId for a `Generated` special function before (re-)generating it. Mangling for `Generated` functions is also moved to use the values from the `GeneratedFunction`'s canonicalization key, so that we have a consistent source of truth for the unique ID of a `Generated` function across all files. New tests are in `toolchain/check/testdata/impl/custom_witness/destroy.carbon`.
This commit is contained in:
@@ -110,9 +110,9 @@ fn F() {
|
||||
// CHECK:STDOUT: %initializer_list.initializer_list.0db5f6.2: %initializer_list.initializer_list.type.0fbcd7.2 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %initializer_list.cpp_destructor.type: type = fn_type @initializer_list.cpp_destructor [concrete]
|
||||
// CHECK:STDOUT: %initializer_list.cpp_destructor: %initializer_list.cpp_destructor.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %Destroy.Op.type.1d8f74.4: type = fn_type @Destroy.Op.loc10_23.3 [concrete]
|
||||
// CHECK:STDOUT: %Destroy.Op.1a2547.4: %Destroy.Op.type.1d8f74.4 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %Destroy.Op.bound: <bound method> = bound_method %.981, %Destroy.Op.1a2547.4 [concrete]
|
||||
// CHECK:STDOUT: %Destroy.WithSelf.Op.type.ef016f.4: type = fn_type @Destroy.WithSelf.Op.loc10_23.3 [concrete]
|
||||
// CHECK:STDOUT: %Destroy.WithSelf.Op.403171.4: %Destroy.WithSelf.Op.type.ef016f.4 = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %Destroy.WithSelf.Op.bound: <bound method> = bound_method %.981, %Destroy.WithSelf.Op.403171.4 [concrete]
|
||||
// CHECK:STDOUT: %InitListConstructor: type = class_type @InitListConstructor [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.ed6: type = pattern_type %InitListConstructor [concrete]
|
||||
// CHECK:STDOUT: %_.patt.100: %pattern_type.ed6 = value_binding_pattern _ [concrete]
|
||||
@@ -298,7 +298,7 @@ fn F() {
|
||||
// CHECK:STDOUT: %Consume__carbon_thunk.call: init %empty_tuple.type = call imports.%Consume__carbon_thunk.decl(%addr.loc10)
|
||||
// CHECK:STDOUT: %initializer_list.cpp_destructor.bound.loc10: <bound method> = bound_method %.loc10_23.19, constants.%initializer_list.cpp_destructor
|
||||
// CHECK:STDOUT: %initializer_list.cpp_destructor.call.loc10: init %empty_tuple.type = call %initializer_list.cpp_destructor.bound.loc10(%.loc10_23.19)
|
||||
// CHECK:STDOUT: %Destroy.Op.call.loc10: init %empty_tuple.type = call constants.%Destroy.Op.bound(constants.%.981)
|
||||
// CHECK:STDOUT: %Destroy.WithSelf.Op.call.loc10: init %empty_tuple.type = call constants.%Destroy.WithSelf.Op.bound(constants.%.981)
|
||||
// CHECK:STDOUT: %int_1.loc12_37: Core.IntLiteral = int_value 1 [concrete = constants.%int_1.5b8]
|
||||
// CHECK:STDOUT: %int_2.loc12_40: Core.IntLiteral = int_value 2 [concrete = constants.%int_2.ecc]
|
||||
// CHECK:STDOUT: %int_3.loc12_43: Core.IntLiteral = int_value 3 [concrete = constants.%int_3.1ba]
|
||||
@@ -365,10 +365,10 @@ fn F() {
|
||||
// CHECK:STDOUT: %InitListConstructor.cpp_destructor.call: init %empty_tuple.type = call %InitListConstructor.cpp_destructor.bound(%.loc12_44.25)
|
||||
// CHECK:STDOUT: %initializer_list.cpp_destructor.bound.loc12: <bound method> = bound_method %.loc12_44.20, constants.%initializer_list.cpp_destructor
|
||||
// CHECK:STDOUT: %initializer_list.cpp_destructor.call.loc12: init %empty_tuple.type = call %initializer_list.cpp_destructor.bound.loc12(%.loc12_44.20)
|
||||
// CHECK:STDOUT: %Destroy.Op.call.loc12: init %empty_tuple.type = call constants.%Destroy.Op.bound(constants.%.981)
|
||||
// CHECK:STDOUT: %Destroy.WithSelf.Op.call.loc12: init %empty_tuple.type = call constants.%Destroy.WithSelf.Op.bound(constants.%.981)
|
||||
// CHECK:STDOUT: %initializer_list.cpp_destructor.bound.loc8: <bound method> = bound_method %.loc8_50.19, constants.%initializer_list.cpp_destructor
|
||||
// CHECK:STDOUT: %initializer_list.cpp_destructor.call.loc8: init %empty_tuple.type = call %initializer_list.cpp_destructor.bound.loc8(%.loc8_50.19)
|
||||
// CHECK:STDOUT: %Destroy.Op.call.loc8: init %empty_tuple.type = call constants.%Destroy.Op.bound(constants.%.981)
|
||||
// CHECK:STDOUT: %Destroy.WithSelf.Op.call.loc8: init %empty_tuple.type = call constants.%Destroy.WithSelf.Op.bound(constants.%.981)
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -376,14 +376,14 @@ fn F() {
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @initializer_list.initializer_list.loc10(%_.param: %array_type) -> out %return.param: %initializer_list = "cpp.std.initializer_list.make";
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @Destroy.Op.loc10_23.1(%self.param: ref %i32.builtin) = "no_op";
|
||||
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc10_23.1(%self.param: ref %i32.builtin) = "no_op";
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @Destroy.Op.loc10_23.2(%self.param: ref %i32) {
|
||||
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc10_23.2(%self.param: ref %i32) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @Destroy.Op.loc10_23.3(%self.param: ref %array_type) {
|
||||
// CHECK:STDOUT: fn @Destroy.WithSelf.Op.loc10_23.3(%self.param: ref %array_type) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
|
||||
Reference in New Issue
Block a user