[swift-dev] [RFC] SIL syntax for debug information Part 2: Scopes and Locations
Adrian Prantl
aprantl at apple.com
Wed Feb 10 13:34:42 CST 2016
Hi Everybody,
I’d like to solicit comments on extending the textual .sil assembler
language with even more debug information.
At the moment it is only possible to test the effects that SIL
optimization passes have on debug information by observing the
effects of a full .swift -> LLVM IR compilation. To enable us
writing targeted testcases for single SIL optimization passes,
I'd like to propose a serialization format for scope and location
information for textual SIL.
The format is inspired by LLVM IR's metadata representation, but
with a couple of improvements that reduce the amount of
individual metadata records and improve the overall readability
by moving the metadata definition closer to their (first) use.
Each SIL instruction is extended by a location and scope reference.
sil-instruction-def ::= (sil-value-name '=')? sil-instruction, sil-loc, sil-scope
sil-loc ::= 'loc' md-name
sil-scope ::= 'scope' md-name
md-name ::= '!' [0-9]+
The individual metadata nodes are defined in a global context, as
they may be shared between individual SIL functions.
decl ::= md-def
md-def ::= md-name '=' md-node
md-node ::= 'loc' ',' 'line' [0-9]+ ',' 'column' [0-9]+ ',' 'file' string-literal
md-node ::= 'scope' ',' 'loc' md-name ',' 'parent' scope-parent (',' 'inlinedCallSite' md-name )?
scope-parent ::= sil-function-name
scope-parent ::= md-name
Let me know what you think!
-- adrian
PS:
Below is an example of what this would look like in practice for the following program:
Swift source code
-----------------
#line 100 "abc.swift"
@inline(__always)
public func h(k : Int) -> Int { // 101
return k // 102
}
#line 200 "abc.swift"
@inline(__always)
public func g(j : Int) -> Int { // 201
return h(j) // 202
}
#line 301 "abc.swift"
public func f(i : Int) -> Int { // 301
return g(i) // 302
}
Verbose SIL output
------------------
Note that metadata is defined before its first use:
!1 = loc, line 0, column 0
!2 = scope, loc !1, parent @main
[...]
!3 = loc, line 101, column 15, file "abc.swift"
!4 = loc, line 101, column 13, file "abc.swift"
!5 = scope, loc !4, parent @_TF9inlinedAt1hFSiSi
!6 = loc, line 102, column 3, file "abc.swift"
!7 = loc, line 103, column 1, file "abc.swift"
!8 = scope, loc !7, parent !5
// h(Int) -> Int
sil [always_inline] @_TF9inlinedAt1hFSiSi : $@convention(thin) (Int) -> Int {
// %0 // users: %1, %2
bb0(%0 : $Int):
debug_value %0 : $Int, let, name "k", argno 1, loc !3, scope !5 // id: %1 line:101:15:in_prologue
return %0 : $Int, loc !6, scope !8 // id: %2 line:102:3:return
}
!9 = loc, line 201, column 15, file "abc.swift"
!10 = loc, line 201, column 13, file "abc.swift"
!11 = scope, loc !10, parent @_TF9inlinedAt1gFSiSi
!12 = loc, line 203, column 1, file "abc.swift"
!13 = scope, loc !12, parent !11
!14 = loc, line 202, column 13, file "abc.swift"
!15 = scope, loc !14, parent !13
!16 = scope, loc !4, parent !5, inlinedCallSite !15
!17 = loc, line 202, column 3, file "abc.swift"
// g(Int) -> Int
sil [always_inline] @_TF9inlinedAt1gFSiSi : $@convention(thin) (Int) -> Int {
// %0 // users: %1, %2, %3
bb0(%0 : $Int):
debug_value %0 : $Int, let, name "j", argno 1, loc !9, scope !11 // id: %1 line:201:15:in_prologue
debug_value %0 : $Int, let, name "k", argno 1, loc !3, scope !16 // id: %2 line:101:15:in_prologue: h(Int) -> Int perf_inlined_at /Volumes/Data/swift/swift/test/DebugInfo/inlinedAt.swift:202:10
return %0 : $Int, loc !17, scope !13 // id: %3 line:202:3:return
}
!18 = loc, line 301, column 15, file "abc.swift"
!19 = loc, line 301, column 13, file "abc.swift"
!20 = scope, loc !19, parent @_TF9inlinedAt1fFSiSi
!21 = loc, line 303, column 1, file "abc.swift"
!22 = scope, loc !21, parent !20
!23 = loc, line 302, column 13, file "abc.swift"
!24 = scope, loc !23, parent !22
!25 = scope, loc !10, parent !11, inlinedCallSite !24
!26 = scope, loc !4, parent !16, inlinedCallSite !24
!27 = loc, line 302, column 3, file "abc.swift"
More information about the swift-dev
mailing list