mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Model function calls as initializing expressions (#3089)
Start treating function calls as initializing expressions instead of as value expressions. This required adding support for expression categories. Value bindings and temporary materialization conversions are created where necessary to transition between expression categories. For a function call with a return slot, we speculatively create a materialized temporary before the call and either commit to it or replace it with something else later, once we see how the function call expression is actually used. This change follows the direction suggested in #3133 for initializing expressions: depending on the return type of a function, the return value will either be initialized in-place or returned directly. This is visible in the semantics IR, which is a little unfortunate but is probably necessary as this is part of the semantics of the program. --------- Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
This commit is contained in:
co-authored by
Chandler Carruth
parent
f790a27ace
commit
1013d1773c
+13
-10
@@ -15,7 +15,7 @@ fn Main() {
|
||||
// CHECK:STDOUT: cross_reference_irs_size: 1
|
||||
// CHECK:STDOUT: functions: [
|
||||
// CHECK:STDOUT: {name: str0, param_refs: block2, return_type: type0, body: [block4]},
|
||||
// CHECK:STDOUT: {name: str2, param_refs: block0, body: [block5]},
|
||||
// CHECK:STDOUT: {name: str3, param_refs: block0, body: [block5]},
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: integer_literals: [
|
||||
// CHECK:STDOUT: ]
|
||||
@@ -24,6 +24,7 @@ fn Main() {
|
||||
// CHECK:STDOUT: strings: [
|
||||
// CHECK:STDOUT: Echo,
|
||||
// CHECK:STDOUT: a,
|
||||
// CHECK:STDOUT: return,
|
||||
// CHECK:STDOUT: Main,
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: types: [
|
||||
@@ -36,11 +37,12 @@ fn Main() {
|
||||
// CHECK:STDOUT: {kind: StructValue, arg0: block0, type: type0},
|
||||
// CHECK:STDOUT: {kind: Parameter, arg0: str1, type: type0},
|
||||
// CHECK:STDOUT: {kind: StructValue, arg0: block0, type: type0},
|
||||
// CHECK:STDOUT: {kind: VarStorage, arg0: str2, type: type0},
|
||||
// CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function0},
|
||||
// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+2},
|
||||
// CHECK:STDOUT: {kind: Return},
|
||||
// CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function1},
|
||||
// CHECK:STDOUT: {kind: StructValue, arg0: block0, type: type0},
|
||||
// CHECK:STDOUT: {kind: StubReference, arg0: node+7, type: type0},
|
||||
// CHECK:STDOUT: {kind: StubReference, arg0: node+8, type: type0},
|
||||
// CHECK:STDOUT: {kind: Call, arg0: block6, arg1: function0, type: type0},
|
||||
// CHECK:STDOUT: {kind: Return},
|
||||
// CHECK:STDOUT: ]
|
||||
@@ -52,25 +54,26 @@ fn Main() {
|
||||
// CHECK:STDOUT: node+1,
|
||||
// CHECK:STDOUT: node+2,
|
||||
// CHECK:STDOUT: node+3,
|
||||
// CHECK:STDOUT: node+4,
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node+2,
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node+4,
|
||||
// CHECK:STDOUT: node+5,
|
||||
// CHECK:STDOUT: node+7,
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node+6,
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node+5,
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node+7,
|
||||
// CHECK:STDOUT: node+8,
|
||||
// CHECK:STDOUT: node+9,
|
||||
// CHECK:STDOUT: node+10,
|
||||
// CHECK:STDOUT: node+11,
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node+8,
|
||||
// CHECK:STDOUT: node+9,
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT:
|
||||
@@ -81,7 +84,7 @@ fn Main() {
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @Echo(%a: {}) -> {} {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: return %a
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @Main() {
|
||||
|
||||
+13
-10
@@ -15,7 +15,7 @@ fn Main() {
|
||||
// CHECK:STDOUT: cross_reference_irs_size: 1
|
||||
// CHECK:STDOUT: functions: [
|
||||
// CHECK:STDOUT: {name: str0, param_refs: block2, return_type: type0, body: [block4]},
|
||||
// CHECK:STDOUT: {name: str2, param_refs: block0, body: [block5]},
|
||||
// CHECK:STDOUT: {name: str3, param_refs: block0, body: [block5]},
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: integer_literals: [
|
||||
// CHECK:STDOUT: ]
|
||||
@@ -24,6 +24,7 @@ fn Main() {
|
||||
// CHECK:STDOUT: strings: [
|
||||
// CHECK:STDOUT: Echo,
|
||||
// CHECK:STDOUT: a,
|
||||
// CHECK:STDOUT: return,
|
||||
// CHECK:STDOUT: Main,
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: types: [
|
||||
@@ -38,11 +39,12 @@ fn Main() {
|
||||
// CHECK:STDOUT: {kind: TupleValue, arg0: block0, type: type0},
|
||||
// CHECK:STDOUT: {kind: Parameter, arg0: str1, type: type0},
|
||||
// CHECK:STDOUT: {kind: TupleValue, arg0: block0, type: type0},
|
||||
// CHECK:STDOUT: {kind: VarStorage, arg0: str2, type: type0},
|
||||
// CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function0},
|
||||
// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+2},
|
||||
// CHECK:STDOUT: {kind: Return},
|
||||
// CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function1},
|
||||
// CHECK:STDOUT: {kind: TupleValue, arg0: block0, type: type0},
|
||||
// CHECK:STDOUT: {kind: StubReference, arg0: node+7, type: type0},
|
||||
// CHECK:STDOUT: {kind: StubReference, arg0: node+8, type: type0},
|
||||
// CHECK:STDOUT: {kind: Call, arg0: block6, arg1: function0, type: type0},
|
||||
// CHECK:STDOUT: {kind: Return},
|
||||
// CHECK:STDOUT: ]
|
||||
@@ -54,25 +56,26 @@ fn Main() {
|
||||
// CHECK:STDOUT: node+1,
|
||||
// CHECK:STDOUT: node+2,
|
||||
// CHECK:STDOUT: node+3,
|
||||
// CHECK:STDOUT: node+4,
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node+2,
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node+4,
|
||||
// CHECK:STDOUT: node+5,
|
||||
// CHECK:STDOUT: node+7,
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node+6,
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node+5,
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node+7,
|
||||
// CHECK:STDOUT: node+8,
|
||||
// CHECK:STDOUT: node+9,
|
||||
// CHECK:STDOUT: node+10,
|
||||
// CHECK:STDOUT: node+11,
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node+8,
|
||||
// CHECK:STDOUT: node+9,
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT:
|
||||
@@ -83,7 +86,7 @@ fn Main() {
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @Echo(%a: ()) -> () {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: return %a
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @Main() {
|
||||
|
||||
+12
-7
@@ -15,8 +15,8 @@ fn Run() {
|
||||
|
||||
// CHECK:STDOUT: cross_reference_irs_size: 1
|
||||
// CHECK:STDOUT: functions: [
|
||||
// CHECK:STDOUT: {name: str0, param_refs: block0, return_type: type0, body: [block2]},
|
||||
// CHECK:STDOUT: {name: str1, param_refs: block0, body: [block3]},
|
||||
// CHECK:STDOUT: {name: str0, param_refs: block0, return_type: type0, body: [block3]},
|
||||
// CHECK:STDOUT: {name: str2, param_refs: block0, body: [block4]},
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: integer_literals: [
|
||||
// CHECK:STDOUT: ]
|
||||
@@ -25,6 +25,7 @@ fn Run() {
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: strings: [
|
||||
// CHECK:STDOUT: Foo,
|
||||
// CHECK:STDOUT: return,
|
||||
// CHECK:STDOUT: Run,
|
||||
// CHECK:STDOUT: x,
|
||||
// CHECK:STDOUT: ]
|
||||
@@ -35,13 +36,14 @@ fn Run() {
|
||||
// CHECK:STDOUT: type_blocks: [
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: nodes: [
|
||||
// CHECK:STDOUT: {kind: VarStorage, arg0: str1, type: type0},
|
||||
// CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function0},
|
||||
// CHECK:STDOUT: {kind: RealLiteral, arg0: real0, type: type0},
|
||||
// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+1},
|
||||
// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+2},
|
||||
// CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function1},
|
||||
// CHECK:STDOUT: {kind: VarStorage, arg0: str2, type: type1},
|
||||
// CHECK:STDOUT: {kind: VarStorage, arg0: str3, type: type1},
|
||||
// CHECK:STDOUT: {kind: Call, arg0: block0, arg1: function0, type: type0},
|
||||
// CHECK:STDOUT: {kind: Assign, arg0: node+4, arg1: nodeError},
|
||||
// CHECK:STDOUT: {kind: Assign, arg0: node+5, arg1: nodeError},
|
||||
// CHECK:STDOUT: {kind: Return},
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: node_blocks: [
|
||||
@@ -49,17 +51,20 @@ fn Run() {
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node+0,
|
||||
// CHECK:STDOUT: node+3,
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node+1,
|
||||
// CHECK:STDOUT: node+4,
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node+2,
|
||||
// CHECK:STDOUT: node+3,
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node+4,
|
||||
// CHECK:STDOUT: node+5,
|
||||
// CHECK:STDOUT: node+6,
|
||||
// CHECK:STDOUT: node+7,
|
||||
// CHECK:STDOUT: node+8,
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT:
|
||||
|
||||
+13
-10
@@ -15,7 +15,7 @@ fn Main() {
|
||||
// CHECK:STDOUT: cross_reference_irs_size: 1
|
||||
// CHECK:STDOUT: functions: [
|
||||
// CHECK:STDOUT: {name: str0, param_refs: block2, return_type: type0, body: [block4]},
|
||||
// CHECK:STDOUT: {name: str2, param_refs: block0, body: [block5]},
|
||||
// CHECK:STDOUT: {name: str3, param_refs: block0, body: [block5]},
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: integer_literals: [
|
||||
// CHECK:STDOUT: 1,
|
||||
@@ -25,6 +25,7 @@ fn Main() {
|
||||
// CHECK:STDOUT: strings: [
|
||||
// CHECK:STDOUT: Echo,
|
||||
// CHECK:STDOUT: a,
|
||||
// CHECK:STDOUT: return,
|
||||
// CHECK:STDOUT: Main,
|
||||
// CHECK:STDOUT: b,
|
||||
// CHECK:STDOUT: ]
|
||||
@@ -35,14 +36,15 @@ fn Main() {
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: nodes: [
|
||||
// CHECK:STDOUT: {kind: Parameter, arg0: str1, type: type0},
|
||||
// CHECK:STDOUT: {kind: VarStorage, arg0: str2, type: type0},
|
||||
// CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function0},
|
||||
// CHECK:STDOUT: {kind: ReturnExpression, arg0: node+0},
|
||||
// CHECK:STDOUT: {kind: FunctionDeclaration, arg0: function1},
|
||||
// CHECK:STDOUT: {kind: VarStorage, arg0: str3, type: type0},
|
||||
// CHECK:STDOUT: {kind: VarStorage, arg0: str4, type: type0},
|
||||
// CHECK:STDOUT: {kind: IntegerLiteral, arg0: int0, type: type0},
|
||||
// CHECK:STDOUT: {kind: StubReference, arg0: node+5, type: type0},
|
||||
// CHECK:STDOUT: {kind: StubReference, arg0: node+6, type: type0},
|
||||
// CHECK:STDOUT: {kind: Call, arg0: block6, arg1: function0, type: type0},
|
||||
// CHECK:STDOUT: {kind: Assign, arg0: node+4, arg1: node+7},
|
||||
// CHECK:STDOUT: {kind: Assign, arg0: node+5, arg1: node+8},
|
||||
// CHECK:STDOUT: {kind: Return},
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: node_blocks: [
|
||||
@@ -50,27 +52,28 @@ fn Main() {
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node+0,
|
||||
// CHECK:STDOUT: node+1,
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node+0,
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node+1,
|
||||
// CHECK:STDOUT: node+2,
|
||||
// CHECK:STDOUT: node+4,
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node+3,
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node+2,
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node+4,
|
||||
// CHECK:STDOUT: node+5,
|
||||
// CHECK:STDOUT: node+6,
|
||||
// CHECK:STDOUT: node+7,
|
||||
// CHECK:STDOUT: node+8,
|
||||
// CHECK:STDOUT: node+9,
|
||||
// CHECK:STDOUT: node+10,
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: [
|
||||
// CHECK:STDOUT: node+6,
|
||||
// CHECK:STDOUT: node+7,
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT:
|
||||
|
||||
@@ -40,7 +40,6 @@ fn Main() {
|
||||
// CHECK:STDOUT: {kind: TupleValue, arg0: block0, type: type0},
|
||||
// CHECK:STDOUT: {kind: VarStorage, arg0: str2, type: type0},
|
||||
// CHECK:STDOUT: {kind: Call, arg0: block0, arg1: function0, type: type0},
|
||||
// CHECK:STDOUT: {kind: Assign, arg0: node+5, arg1: node+6},
|
||||
// CHECK:STDOUT: {kind: Return},
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT: node_blocks: [
|
||||
@@ -59,7 +58,6 @@ fn Main() {
|
||||
// CHECK:STDOUT: node+5,
|
||||
// CHECK:STDOUT: node+6,
|
||||
// CHECK:STDOUT: node+7,
|
||||
// CHECK:STDOUT: node+8,
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT:
|
||||
@@ -79,6 +77,5 @@ fn Main() {
|
||||
// CHECK:STDOUT: %.loc11_11.2: () = tuple_value ()
|
||||
// CHECK:STDOUT: %b: () = var "b"
|
||||
// CHECK:STDOUT: %.loc11_37: () = call @MakeImplicitEmptyTuple()
|
||||
// CHECK:STDOUT: assign %b, %.loc11_37
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
|
||||
Reference in New Issue
Block a user