mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-05 22:02:55 +01:00
Add formatted textual IR output (#3056)
Add a textual IR format to the toolchain. The exact details of the format are somewhat arbitrary right now, and I expect them to change as we refine the semantics IR model, but at the moment they're somewhat directly following the current structure of the IR. Semantics tests currently test both the "raw" format, which shows the details of the representation, and the textual format, which is somewhat higher level. We may want to revisit that decision once the textual format is a bit more stable, and test only the textual format in most of these tests, but for now it seems prudent to keep both sets of tests. --------- Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
This commit is contained in:
co-authored by
Chandler Carruth
parent
fc5a9541ce
commit
6cbf280a68
@@ -60,3 +60,20 @@ fn F() -> i32 {
|
||||
// CHECK:STDOUT: node+10,
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: package {
|
||||
// CHECK:STDOUT: %.loc7 = fn_decl @F
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @F() -> i32 {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %n: i32 = var
|
||||
// CHECK:STDOUT: %.loc8: i32 = int_value 0
|
||||
// CHECK:STDOUT: assign %n, %.loc8
|
||||
// CHECK:STDOUT: %.loc9_13.1: type = ptr_type i32
|
||||
// CHECK:STDOUT: %.loc9_13.2: i32* = address_of %n
|
||||
// CHECK:STDOUT: %.loc9_12: i32 = dereference %.loc9_13.2
|
||||
// CHECK:STDOUT: %.loc9_11: i32* = address_of %.loc9_12
|
||||
// CHECK:STDOUT: %.loc9_10: i32 = dereference %.loc9_11
|
||||
// CHECK:STDOUT: return %.loc9_10
|
||||
// CHECK:STDOUT: }
|
||||
|
||||
@@ -239,3 +239,62 @@ fn F(param: i32) {
|
||||
// CHECK:STDOUT: node+45,
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: package {
|
||||
// CHECK:STDOUT: %.loc7 = fn_decl @F
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @F(%param: i32) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %.loc8_27: type = struct_type {.a: i32, .b: i32}
|
||||
// CHECK:STDOUT: %s: {.a: i32, .b: i32} = var
|
||||
// CHECK:STDOUT: %.loc8_37: i32 = int_value 1
|
||||
// CHECK:STDOUT: %.loc8_35: i32 = stub_reference %.loc8_37
|
||||
// CHECK:STDOUT: %.loc8_45: i32 = int_value 2
|
||||
// CHECK:STDOUT: %.loc8_43: i32 = stub_reference %.loc8_45
|
||||
// CHECK:STDOUT: %.loc8_46: {.a: i32, .b: i32} = struct_value (%.loc8_35, %.loc8_43)
|
||||
// CHECK:STDOUT: assign %s, %.loc8_46
|
||||
// CHECK:STDOUT: %.loc10_28: type = ptr_type {.a: i32, .b: i32}
|
||||
// CHECK:STDOUT: %p: {.a: i32, .b: i32}* = var
|
||||
// CHECK:STDOUT: %.loc10_32: {.a: i32, .b: i32}* = address_of %s
|
||||
// CHECK:STDOUT: assign %p, %.loc10_32
|
||||
// CHECK:STDOUT: %.loc11_13: type = ptr_type i32
|
||||
// CHECK:STDOUT: %q: i32* = var
|
||||
// CHECK:STDOUT: %.loc11_19: i32 = struct_access %s, member0
|
||||
// CHECK:STDOUT: %.loc11_17: i32* = address_of %.loc11_19
|
||||
// CHECK:STDOUT: assign %q, %.loc11_17
|
||||
// CHECK:STDOUT: %.loc12_13: type = ptr_type i32
|
||||
// CHECK:STDOUT: %r: i32* = var
|
||||
// CHECK:STDOUT: %.loc12_19: i32 = struct_access %s, member1
|
||||
// CHECK:STDOUT: %.loc12_17: i32* = address_of %.loc12_19
|
||||
// CHECK:STDOUT: assign %r, %.loc12_17
|
||||
// CHECK:STDOUT: %.loc14_11: type = stub_reference i32
|
||||
// CHECK:STDOUT: %.loc14_16: type = stub_reference i32
|
||||
// CHECK:STDOUT: %.loc14_19.1: type = tuple_type (type, type)
|
||||
// CHECK:STDOUT: %.loc14_19.2: (type, type) = tuple_value (%.loc14_11, %.loc14_16)
|
||||
// CHECK:STDOUT: %.loc14_19.3: type = tuple_type (i32, i32)
|
||||
// CHECK:STDOUT: %t: (i32, i32) = var
|
||||
// CHECK:STDOUT: %.loc14_24.1: i32 = int_value 1
|
||||
// CHECK:STDOUT: %.loc14_24.2: i32 = stub_reference %.loc14_24.1
|
||||
// CHECK:STDOUT: %.loc14_27.1: i32 = int_value 2
|
||||
// CHECK:STDOUT: %.loc14_27.2: i32 = stub_reference %.loc14_27.1
|
||||
// CHECK:STDOUT: %.loc14_28: (i32, i32) = tuple_value (%.loc14_24.2, %.loc14_27.2)
|
||||
// CHECK:STDOUT: assign %t, %.loc14_28
|
||||
// CHECK:STDOUT: %.loc15_14: type = ptr_type i32
|
||||
// CHECK:STDOUT: %t0: i32* = var
|
||||
// CHECK:STDOUT: %.loc15_21: i32 = int_value 0
|
||||
// CHECK:STDOUT: %.loc15_22: i32 = tuple_index %t, %.loc15_21
|
||||
// CHECK:STDOUT: %.loc15_18: i32* = address_of %.loc15_22
|
||||
// CHECK:STDOUT: assign %t0, %.loc15_18
|
||||
// CHECK:STDOUT: %.loc16_14: type = ptr_type i32
|
||||
// CHECK:STDOUT: %t1: i32* = var
|
||||
// CHECK:STDOUT: %.loc16_21: i32 = int_value 1
|
||||
// CHECK:STDOUT: %.loc16_22: i32 = tuple_index %t, %.loc16_21
|
||||
// CHECK:STDOUT: %.loc16_18: i32* = address_of %.loc16_22
|
||||
// CHECK:STDOUT: assign %t1, %.loc16_18
|
||||
// CHECK:STDOUT: %.loc20_22: type = ptr_type i32
|
||||
// CHECK:STDOUT: %param_addr: i32* = var
|
||||
// CHECK:STDOUT: %.loc20_26: i32* = address_of %param
|
||||
// CHECK:STDOUT: assign %param_addr, %.loc20_26
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
|
||||
@@ -65,3 +65,20 @@ fn F() -> i32 {
|
||||
// CHECK:STDOUT: node+11,
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: package {
|
||||
// CHECK:STDOUT: %.loc7 = fn_decl @F
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @F() -> i32 {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %n: i32 = var
|
||||
// CHECK:STDOUT: %.loc8: i32 = int_value 0
|
||||
// CHECK:STDOUT: assign %n, %.loc8
|
||||
// CHECK:STDOUT: %.loc9_13: type = ptr_type i32
|
||||
// CHECK:STDOUT: %p: i32* = var
|
||||
// CHECK:STDOUT: %.loc9_17: i32* = address_of %n
|
||||
// CHECK:STDOUT: assign %p, %.loc9_17
|
||||
// CHECK:STDOUT: %.loc11: i32 = dereference %p
|
||||
// CHECK:STDOUT: return %.loc11
|
||||
// CHECK:STDOUT: }
|
||||
|
||||
@@ -296,3 +296,93 @@ fn AddressOfTupleElementValue() {
|
||||
// CHECK:STDOUT: node+59,
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: package {
|
||||
// CHECK:STDOUT: %.loc7 = fn_decl @G
|
||||
// CHECK:STDOUT: %.loc9_19: type = struct_type {.a: i32}
|
||||
// CHECK:STDOUT: %.loc9_1 = fn_decl @H
|
||||
// CHECK:STDOUT: %.loc11 = fn_decl @AddressOfLiteral
|
||||
// CHECK:STDOUT: %.loc38 = fn_decl @AddressOfOperator
|
||||
// CHECK:STDOUT: %.loc53 = fn_decl @AddressOfCall
|
||||
// CHECK:STDOUT: %.loc60 = fn_decl @AddressOfType
|
||||
// CHECK:STDOUT: %.loc71 = fn_decl @AddressOfTupleElementValue
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @G() -> i32;
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @H() -> {.a: i32};
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @AddressOfLiteral() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %.loc15_4: i32 = int_value 0
|
||||
// CHECK:STDOUT: %.loc15_3.1: type = ptr_type i32
|
||||
// CHECK:STDOUT: %.loc15_3.2: i32* = address_of %.loc15_4
|
||||
// CHECK:STDOUT: %.loc19_4: bool = bool_value true
|
||||
// CHECK:STDOUT: %.loc19_3.1: type = ptr_type bool
|
||||
// CHECK:STDOUT: %.loc19_3.2: bool* = address_of %.loc19_4
|
||||
// CHECK:STDOUT: %.loc23_4: f64 = real_value 10e-1
|
||||
// CHECK:STDOUT: %.loc23_3.1: type = ptr_type f64
|
||||
// CHECK:STDOUT: %.loc23_3.2: f64* = address_of %.loc23_4
|
||||
// CHECK:STDOUT: %.loc27_4: String = string_value "Hello"
|
||||
// CHECK:STDOUT: %.loc27_3.1: type = ptr_type String
|
||||
// CHECK:STDOUT: %.loc27_3.2: String* = address_of %.loc27_4
|
||||
// CHECK:STDOUT: %.loc31_5.1: i32 = int_value 1
|
||||
// CHECK:STDOUT: %.loc31_5.2: i32 = stub_reference %.loc31_5.1
|
||||
// CHECK:STDOUT: %.loc31_8.1: i32 = int_value 2
|
||||
// CHECK:STDOUT: %.loc31_8.2: i32 = stub_reference %.loc31_8.1
|
||||
// CHECK:STDOUT: %.loc31_9.1: type = tuple_type (i32, i32)
|
||||
// CHECK:STDOUT: %.loc31_9.2: (i32, i32) = tuple_value (%.loc31_5.2, %.loc31_8.2)
|
||||
// CHECK:STDOUT: %.loc31_3.1: type = ptr_type (i32, i32)
|
||||
// CHECK:STDOUT: %.loc31_3.2: (i32, i32)* = address_of %.loc31_9.2
|
||||
// CHECK:STDOUT: %.loc35_10: i32 = int_value 5
|
||||
// CHECK:STDOUT: %.loc35_8: i32 = stub_reference %.loc35_10
|
||||
// CHECK:STDOUT: %.loc35_11: {.a: i32} = struct_value (%.loc35_8)
|
||||
// CHECK:STDOUT: %.loc35_3.1: type = ptr_type {.a: i32}
|
||||
// CHECK:STDOUT: %.loc35_3.2: {.a: i32}* = address_of %.loc35_11
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @AddressOfOperator() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %.loc42_5: i32 = int_value 1
|
||||
// CHECK:STDOUT: %.loc42_9: i32 = int_value 1
|
||||
// CHECK:STDOUT: %.loc42_7: i32 = add %.loc42_5, %.loc42_9
|
||||
// CHECK:STDOUT: %.loc42_3: i32* = address_of %.loc42_7
|
||||
// CHECK:STDOUT: %.loc46_5: {.a: i32} = call @H()
|
||||
// CHECK:STDOUT: %.loc46_7: i32 = struct_access %.loc46_5, member0
|
||||
// CHECK:STDOUT: %.loc46_3: i32* = address_of %.loc46_7
|
||||
// CHECK:STDOUT: %.loc50_9: bool = bool_value true
|
||||
// CHECK:STDOUT: %.loc50_5: bool = not %.loc50_9
|
||||
// CHECK:STDOUT: %.loc50_3: bool* = address_of %.loc50_5
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @AddressOfCall() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %.loc57_5: i32 = call @G()
|
||||
// CHECK:STDOUT: %.loc57_3: i32* = address_of %.loc57_5
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @AddressOfType() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %.loc64_3.1: type = ptr_type type
|
||||
// CHECK:STDOUT: %.loc64_3.2: type* = address_of i32
|
||||
// CHECK:STDOUT: %.loc68_5: type = const_type i32
|
||||
// CHECK:STDOUT: %.loc68_14: type = ptr_type const i32
|
||||
// CHECK:STDOUT: %.loc68_3: type* = address_of %.loc68_14
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @AddressOfTupleElementValue() {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %.loc75_6.1: i32 = int_value 1
|
||||
// CHECK:STDOUT: %.loc75_6.2: i32 = stub_reference %.loc75_6.1
|
||||
// CHECK:STDOUT: %.loc75_9.1: i32 = int_value 2
|
||||
// CHECK:STDOUT: %.loc75_9.2: i32 = stub_reference %.loc75_9.1
|
||||
// CHECK:STDOUT: %.loc75_10: (i32, i32) = tuple_value (%.loc75_6.2, %.loc75_9.2)
|
||||
// CHECK:STDOUT: %.loc75_12: i32 = int_value 0
|
||||
// CHECK:STDOUT: %.loc75_13: i32 = tuple_index %.loc75_10, %.loc75_12
|
||||
// CHECK:STDOUT: %.loc75_3: i32* = address_of %.loc75_13
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
|
||||
@@ -77,3 +77,19 @@ fn Deref(n: i32) {
|
||||
// CHECK:STDOUT: node+10,
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: package {
|
||||
// CHECK:STDOUT: %.loc7 = fn_decl @Deref
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @Deref(%n: i32) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %.loc11: <error> = dereference %n
|
||||
// CHECK:STDOUT: %.loc15_5.1: type = tuple_type ()
|
||||
// CHECK:STDOUT: %.loc15_5.2: () = tuple_value ()
|
||||
// CHECK:STDOUT: %.loc15_3: <error> = dereference %.loc15_5.2
|
||||
// CHECK:STDOUT: %.loc19_5.1: type = struct_type {}
|
||||
// CHECK:STDOUT: %.loc19_5.2: {} = struct_value ()
|
||||
// CHECK:STDOUT: %.loc19_3: <error> = dereference %.loc19_5.2
|
||||
// CHECK:STDOUT: return
|
||||
// CHECK:STDOUT: }
|
||||
|
||||
@@ -40,3 +40,8 @@ var p: *i32;
|
||||
// CHECK:STDOUT: node+2,
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: package {
|
||||
// CHECK:STDOUT: %.loc13: <error> = dereference i32
|
||||
// CHECK:STDOUT: %p: <error> = var
|
||||
// CHECK:STDOUT: }
|
||||
|
||||
@@ -69,3 +69,15 @@ fn ConstMismatch(p: const {}*) -> const ({}*) {
|
||||
// CHECK:STDOUT: node+10,
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: package {
|
||||
// CHECK:STDOUT: %.loc7_43: {} = struct_value ()
|
||||
// CHECK:STDOUT: %.loc7_44: type = ptr_type {}
|
||||
// CHECK:STDOUT: %.loc7_35: type = const_type {}*
|
||||
// CHECK:STDOUT: %.loc7_1 = fn_decl @ConstMismatch
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @ConstMismatch(%p: const {}*) -> const ({}*) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: return <error>
|
||||
// CHECK:STDOUT: }
|
||||
|
||||
@@ -70,3 +70,15 @@ fn F(p: const (const (const i32*)*)) -> const i32 {
|
||||
// CHECK:STDOUT: node+11,
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: package {
|
||||
// CHECK:STDOUT: %.loc8_41: type = const_type i32
|
||||
// CHECK:STDOUT: %.loc8_1 = fn_decl @F
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @F(%p: const (const (const i32*)*)) -> const i32 {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %.loc9_11: const (const i32*) = dereference %p
|
||||
// CHECK:STDOUT: %.loc9_10: const i32 = dereference %.loc9_11
|
||||
// CHECK:STDOUT: return %.loc9_10
|
||||
// CHECK:STDOUT: }
|
||||
|
||||
@@ -84,3 +84,21 @@ fn ConstPtr(p: const i32*) -> (const i32)* {
|
||||
// CHECK:STDOUT: node+13,
|
||||
// CHECK:STDOUT: ],
|
||||
// CHECK:STDOUT: ]
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: package {
|
||||
// CHECK:STDOUT: %.loc7_23: type = ptr_type i32
|
||||
// CHECK:STDOUT: %.loc7_1 = fn_decl @Ptr
|
||||
// CHECK:STDOUT: %.loc11_32: type = const_type i32
|
||||
// CHECK:STDOUT: %.loc11_42: type = ptr_type const i32
|
||||
// CHECK:STDOUT: %.loc11_1 = fn_decl @ConstPtr
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @Ptr(%p: i32*) -> i32* {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: return %p
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @ConstPtr(%p: const i32*) -> const i32* {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: return %p
|
||||
// CHECK:STDOUT: }
|
||||
|
||||
Reference in New Issue
Block a user