mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 17:31:07 +01:00
Implement thunking in terms of constant evaluation (#7332)
The bulk of this change is changing most pattern insts to be `Always` rather than `AlwaysUnique` constants, so that they can be wrapped in `SpecificConstant`s to perform substitution. That then lets thunking rely much more on `SpecificConstant` wrappers instead of deep-copying the inst tree with modified types. This approach to thunking should scale better, particularly as things like form generics make function signatures more complex, because we can leverage the existing support for constant evaluation and substitution. Unfortunately, applying this approach to binding patterns will require more work; see the TODO near the top of `thunk.cpp` for details. --------- Co-authored-by: Richard Smith <richard@metafoo.co.uk>
This commit is contained in:
co-authored by
Richard Smith
parent
40d2d8f68c
commit
e023f75254
@@ -93,10 +93,12 @@ fn F() {
|
||||
// CHECK:STDOUT: %int_16: Core.IntLiteral = int_value 16 [concrete]
|
||||
// CHECK:STDOUT: %i16: type = class_type @Int, @Int(%int_16) [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.203: type = pattern_type %i16 [concrete]
|
||||
// CHECK:STDOUT: %a.patt: %pattern_type.203 = value_binding_pattern a [concrete]
|
||||
// CHECK:STDOUT: %Enum: type = class_type @Enum [concrete]
|
||||
// CHECK:STDOUT: %int_0.822: %Enum = int_value 0 [concrete]
|
||||
// CHECK:STDOUT: %int_0.a8d: %i16 = int_value 0 [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.926: type = pattern_type %Enum [concrete]
|
||||
// CHECK:STDOUT: %b.patt: %pattern_type.926 = value_binding_pattern b [concrete]
|
||||
// CHECK:STDOUT: %int_42.20e: Core.IntLiteral = int_value 42 [concrete]
|
||||
// CHECK:STDOUT: %As.type.6f1: type = facet_type <@As, @As(%i16)> [concrete]
|
||||
// CHECK:STDOUT: %To: Core.IntLiteral = symbolic_binding To, 0 [symbolic]
|
||||
@@ -115,6 +117,7 @@ fn F() {
|
||||
// CHECK:STDOUT: %int_42.4c2: %Enum = int_value 42 [concrete]
|
||||
// CHECK:STDOUT: %Other: type = class_type @Other [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.d91: type = pattern_type %Other [concrete]
|
||||
// CHECK:STDOUT: %c.patt: %pattern_type.d91 = value_binding_pattern c [concrete]
|
||||
// CHECK:STDOUT: %int_0.10a: %Other = int_value 0 [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -139,7 +142,7 @@ fn F() {
|
||||
// CHECK:STDOUT: fn @F() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: name_binding_decl {
|
||||
// CHECK:STDOUT: %a.patt: %pattern_type.203 = value_binding_pattern a [concrete]
|
||||
// CHECK:STDOUT: %a.patt: %pattern_type.203 = value_binding_pattern a [concrete = constants.%a.patt]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Cpp.ref.loc8: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %Enum.ref.loc8: type = name_ref Enum, imports.%Enum.decl [concrete = constants.%Enum]
|
||||
@@ -150,7 +153,7 @@ fn F() {
|
||||
// CHECK:STDOUT: %i16.loc8_17: type = type_literal constants.%i16 [concrete = constants.%i16]
|
||||
// CHECK:STDOUT: %a: %i16 = value_binding a, %.loc8_34.2
|
||||
// CHECK:STDOUT: name_binding_decl {
|
||||
// CHECK:STDOUT: %b.patt: %pattern_type.926 = value_binding_pattern b [concrete]
|
||||
// CHECK:STDOUT: %b.patt: %pattern_type.926 = value_binding_pattern b [concrete = constants.%b.patt]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %int_42: Core.IntLiteral = int_value 42 [concrete = constants.%int_42.20e]
|
||||
// CHECK:STDOUT: %i16.loc9: type = type_literal constants.%i16 [concrete = constants.%i16]
|
||||
@@ -171,7 +174,7 @@ fn F() {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %b: %Enum = value_binding b, %.loc9_40.2
|
||||
// CHECK:STDOUT: name_binding_decl {
|
||||
// CHECK:STDOUT: %c.patt: %pattern_type.d91 = value_binding_pattern c [concrete]
|
||||
// CHECK:STDOUT: %c.patt: %pattern_type.d91 = value_binding_pattern c [concrete = constants.%c.patt]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Cpp.ref.loc10_29: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %a.ref.loc10: %Enum = name_ref a, imports.%int_0 [concrete = constants.%int_0.822]
|
||||
|
||||
+4
-2
@@ -36,6 +36,8 @@ fn F() {
|
||||
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %Enum: type = class_type @Enum [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.926: type = pattern_type %Enum [concrete]
|
||||
// CHECK:STDOUT: %a.patt: %pattern_type.926 = ref_binding_pattern a [concrete]
|
||||
// CHECK:STDOUT: %a.var_patt: %pattern_type.926 = var_pattern %a.patt [concrete]
|
||||
// CHECK:STDOUT: %int_0: %Enum = int_value 0 [concrete]
|
||||
// CHECK:STDOUT: %Copy.type: type = facet_type <@Copy> [concrete]
|
||||
// CHECK:STDOUT: %Enum.Op.type: type = fn_type @Enum.Op [concrete]
|
||||
@@ -68,8 +70,8 @@ fn F() {
|
||||
// CHECK:STDOUT: fn @F() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: name_binding_decl {
|
||||
// CHECK:STDOUT: %a.patt: %pattern_type.926 = ref_binding_pattern a [concrete]
|
||||
// CHECK:STDOUT: %a.var_patt: %pattern_type.926 = var_pattern %a.patt [concrete]
|
||||
// CHECK:STDOUT: %a.patt: %pattern_type.926 = ref_binding_pattern a [concrete = constants.%a.patt]
|
||||
// CHECK:STDOUT: %a.var_patt: %pattern_type.926 = var_pattern %a.patt [concrete = constants.%a.var_patt]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %a.var: ref %Enum = var %a.var_patt
|
||||
// CHECK:STDOUT: %Cpp.ref.loc8_21: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
|
||||
+4
-2
@@ -34,7 +34,9 @@ fn F() {
|
||||
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %Enum: type = class_type @Enum [concrete]
|
||||
// CHECK:STDOUT: %pattern_type: type = pattern_type %Enum [concrete]
|
||||
// CHECK:STDOUT: %a.patt: %pattern_type = value_binding_pattern a [concrete]
|
||||
// CHECK:STDOUT: %int_0: %Enum = int_value 0 [concrete]
|
||||
// CHECK:STDOUT: %b.patt: %pattern_type = value_binding_pattern b [concrete]
|
||||
// CHECK:STDOUT: %int_1: %Enum = int_value 1 [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -56,7 +58,7 @@ fn F() {
|
||||
// CHECK:STDOUT: fn @F() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: name_binding_decl {
|
||||
// CHECK:STDOUT: %a.patt: %pattern_type = value_binding_pattern a [concrete]
|
||||
// CHECK:STDOUT: %a.patt: %pattern_type = value_binding_pattern a [concrete = constants.%a.patt]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Cpp.ref.loc8_28: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %Enum.ref.loc8_31: type = name_ref Enum, imports.%Enum.decl [concrete = constants.%Enum]
|
||||
@@ -67,7 +69,7 @@ fn F() {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %a: %Enum = value_binding a, %a.ref
|
||||
// CHECK:STDOUT: name_binding_decl {
|
||||
// CHECK:STDOUT: %b.patt: %pattern_type = value_binding_pattern b [concrete]
|
||||
// CHECK:STDOUT: %b.patt: %pattern_type = value_binding_pattern b [concrete = constants.%b.patt]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Cpp.ref.loc9_28: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %b.ref: %Enum = name_ref b, imports.%int_1 [concrete = constants.%int_1]
|
||||
|
||||
@@ -62,6 +62,8 @@ fn MyF() {
|
||||
// CHECK:STDOUT: constants {
|
||||
// CHECK:STDOUT: %UnsizedEnum: type = class_type @UnsizedEnum [concrete]
|
||||
// CHECK:STDOUT: %pattern_type: type = pattern_type %UnsizedEnum [concrete]
|
||||
// CHECK:STDOUT: %e.param_patt: %pattern_type = value_param_pattern [concrete]
|
||||
// CHECK:STDOUT: %e.patt: %pattern_type = at_binding_pattern e, %e.param_patt [concrete]
|
||||
// CHECK:STDOUT: %F.type: type = fn_type @F [concrete]
|
||||
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
@@ -76,8 +78,8 @@ fn MyF() {
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: file {
|
||||
// CHECK:STDOUT: %F.decl: %F.type = fn_decl @F [concrete = constants.%F] {
|
||||
// CHECK:STDOUT: %e.param_patt: %pattern_type = value_param_pattern [concrete]
|
||||
// CHECK:STDOUT: %e.patt: %pattern_type = at_binding_pattern e, %e.param_patt [concrete]
|
||||
// CHECK:STDOUT: %e.param_patt: %pattern_type = value_param_pattern [concrete = constants.%e.param_patt]
|
||||
// CHECK:STDOUT: %e.patt: %pattern_type = at_binding_pattern e, %e.param_patt [concrete = constants.%e.patt]
|
||||
// CHECK:STDOUT: } {
|
||||
// CHECK:STDOUT: %e.param: %UnsizedEnum = value_param call_param0
|
||||
// CHECK:STDOUT: %.loc12: type = splice_block %UnsizedEnum.ref [concrete = constants.%UnsizedEnum] {
|
||||
|
||||
+4
-2
@@ -38,7 +38,9 @@ fn F() {
|
||||
// CHECK:STDOUT: %A: type = class_type @A [concrete]
|
||||
// CHECK:STDOUT: %E: type = class_type @E [concrete]
|
||||
// CHECK:STDOUT: %pattern_type: type = pattern_type %E [concrete]
|
||||
// CHECK:STDOUT: %a.patt: %pattern_type = value_binding_pattern a [concrete]
|
||||
// CHECK:STDOUT: %int_0: %E = int_value 0 [concrete]
|
||||
// CHECK:STDOUT: %b.patt: %pattern_type = value_binding_pattern b [concrete]
|
||||
// CHECK:STDOUT: %int_1: %E = int_value 1 [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -60,7 +62,7 @@ fn F() {
|
||||
// CHECK:STDOUT: fn @F() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: name_binding_decl {
|
||||
// CHECK:STDOUT: %a.patt: %pattern_type = value_binding_pattern a [concrete]
|
||||
// CHECK:STDOUT: %a.patt: %pattern_type = value_binding_pattern a [concrete = constants.%a.patt]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Cpp.ref.loc8_27: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %A.ref.loc8_30: type = name_ref A, imports.%A.decl [concrete = constants.%A]
|
||||
@@ -72,7 +74,7 @@ fn F() {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %a: %E = value_binding a, %a.ref
|
||||
// CHECK:STDOUT: name_binding_decl {
|
||||
// CHECK:STDOUT: %b.patt: %pattern_type = value_binding_pattern b [concrete]
|
||||
// CHECK:STDOUT: %b.patt: %pattern_type = value_binding_pattern b [concrete = constants.%b.patt]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Cpp.ref.loc9_27: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %A.ref.loc9_30: type = name_ref A, imports.%A.decl [concrete = constants.%A]
|
||||
|
||||
+2
-1
@@ -47,6 +47,7 @@ fn F() {
|
||||
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %Enum: type = class_type @Enum [concrete]
|
||||
// CHECK:STDOUT: %pattern_type: type = pattern_type %Enum [concrete]
|
||||
// CHECK:STDOUT: %a.patt: %pattern_type = value_binding_pattern a [concrete]
|
||||
// CHECK:STDOUT: %int_0: %Enum = int_value 0 [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -66,7 +67,7 @@ fn F() {
|
||||
// CHECK:STDOUT: fn @F() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: name_binding_decl {
|
||||
// CHECK:STDOUT: %a.patt: %pattern_type = value_binding_pattern a [concrete]
|
||||
// CHECK:STDOUT: %a.patt: %pattern_type = value_binding_pattern a [concrete = constants.%a.patt]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Cpp.ref.loc8_28: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %Enum.ref.loc8_31: type = name_ref Enum, imports.%Enum.decl [concrete = constants.%Enum]
|
||||
|
||||
@@ -76,7 +76,9 @@ fn F() {
|
||||
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %Enum: type = class_type @Enum [concrete]
|
||||
// CHECK:STDOUT: %pattern_type: type = pattern_type %Enum [concrete]
|
||||
// CHECK:STDOUT: %a.patt: %pattern_type = value_binding_pattern a [concrete]
|
||||
// CHECK:STDOUT: %int_0: %Enum = int_value 0 [concrete]
|
||||
// CHECK:STDOUT: %b.patt: %pattern_type = value_binding_pattern b [concrete]
|
||||
// CHECK:STDOUT: %int_1: %Enum = int_value 1 [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -98,7 +100,7 @@ fn F() {
|
||||
// CHECK:STDOUT: fn @F() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: name_binding_decl {
|
||||
// CHECK:STDOUT: %a.patt: %pattern_type = value_binding_pattern a [concrete]
|
||||
// CHECK:STDOUT: %a.patt: %pattern_type = value_binding_pattern a [concrete = constants.%a.patt]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Cpp.ref.loc8_28: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %Enum.ref.loc8_31: type = name_ref Enum, imports.%Enum.decl [concrete = constants.%Enum]
|
||||
@@ -109,7 +111,7 @@ fn F() {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %a: %Enum = value_binding a, %a.ref
|
||||
// CHECK:STDOUT: name_binding_decl {
|
||||
// CHECK:STDOUT: %b.patt: %pattern_type = value_binding_pattern b [concrete]
|
||||
// CHECK:STDOUT: %b.patt: %pattern_type = value_binding_pattern b [concrete = constants.%b.patt]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Cpp.ref.loc9_28: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %b.ref: %Enum = name_ref b, imports.%int_1 [concrete = constants.%int_1]
|
||||
|
||||
+8
-4
@@ -56,12 +56,16 @@ fn F() {
|
||||
// CHECK:STDOUT: %F: %F.type = struct_value () [concrete]
|
||||
// CHECK:STDOUT: %Color: type = class_type @Color [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.732: type = pattern_type %Color [concrete]
|
||||
// CHECK:STDOUT: %col.patt: %pattern_type.732 = value_binding_pattern col [concrete]
|
||||
// CHECK:STDOUT: %int_0.59e: %Color = int_value 0 [concrete]
|
||||
// CHECK:STDOUT: %colb.patt: %pattern_type.732 = value_binding_pattern colb [concrete]
|
||||
// CHECK:STDOUT: %int_1.b76: %Color = int_value 1 [concrete]
|
||||
// CHECK:STDOUT: %Zoo: type = class_type @Zoo [concrete]
|
||||
// CHECK:STDOUT: %Animal: type = class_type @Animal [concrete]
|
||||
// CHECK:STDOUT: %pattern_type.8cd: type = pattern_type %Animal [concrete]
|
||||
// CHECK:STDOUT: %pet.patt: %pattern_type.8cd = value_binding_pattern pet [concrete]
|
||||
// CHECK:STDOUT: %int_0.648: %Animal = int_value 0 [concrete]
|
||||
// CHECK:STDOUT: %pet2.patt: %pattern_type.8cd = value_binding_pattern pet2 [concrete]
|
||||
// CHECK:STDOUT: %int_1.e7b: %Animal = int_value 1 [concrete]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
@@ -89,7 +93,7 @@ fn F() {
|
||||
// CHECK:STDOUT: fn @F() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: name_binding_decl {
|
||||
// CHECK:STDOUT: %col.patt: %pattern_type.732 = value_binding_pattern col [concrete]
|
||||
// CHECK:STDOUT: %col.patt: %pattern_type.732 = value_binding_pattern col [concrete = constants.%col.patt]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Cpp.ref.loc18_32: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %Color.ref.loc18_35: type = name_ref Color, imports.%Color.decl [concrete = constants.%Color]
|
||||
@@ -100,7 +104,7 @@ fn F() {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %col: %Color = value_binding col, %Red.ref
|
||||
// CHECK:STDOUT: name_binding_decl {
|
||||
// CHECK:STDOUT: %colb.patt: %pattern_type.732 = value_binding_pattern colb [concrete]
|
||||
// CHECK:STDOUT: %colb.patt: %pattern_type.732 = value_binding_pattern colb [concrete = constants.%colb.patt]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Cpp.ref.loc19_33: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %Blue.ref: %Color = name_ref Blue, imports.%int_1.b76 [concrete = constants.%int_1.b76]
|
||||
@@ -110,7 +114,7 @@ fn F() {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %colb: %Color = value_binding colb, %Blue.ref
|
||||
// CHECK:STDOUT: name_binding_decl {
|
||||
// CHECK:STDOUT: %pet.patt: %pattern_type.8cd = value_binding_pattern pet [concrete]
|
||||
// CHECK:STDOUT: %pet.patt: %pattern_type.8cd = value_binding_pattern pet [concrete = constants.%pet.patt]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Cpp.ref.loc20_37: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %Zoo.ref.loc20_40: type = name_ref Zoo, imports.%Zoo.decl [concrete = constants.%Zoo]
|
||||
@@ -123,7 +127,7 @@ fn F() {
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %pet: %Animal = value_binding pet, %Cat.ref
|
||||
// CHECK:STDOUT: name_binding_decl {
|
||||
// CHECK:STDOUT: %pet2.patt: %pattern_type.8cd = value_binding_pattern pet2 [concrete]
|
||||
// CHECK:STDOUT: %pet2.patt: %pattern_type.8cd = value_binding_pattern pet2 [concrete = constants.%pet2.patt]
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT: %Cpp.ref.loc21_38: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %Dog.ref: %Animal = name_ref Dog, imports.%int_1.e7b [concrete = constants.%int_1.e7b]
|
||||
|
||||
Reference in New Issue
Block a user