> On Dec 15, 2015, at 2:37 PM, Joe Groff <[email protected]> wrote:
>
>>
>> On Dec 15, 2015, at 2:34 PM, Adrian Prantl <[email protected]> wrote:
>>
>>>
>>> On Dec 15, 2015, at 2:27 PM, Joe Groff <[email protected]> wrote:
>>>
>>>>
>>>> On Dec 15, 2015, at 1:25 PM, Adrian Prantl <[email protected]> wrote:
>>>>
>>>>>
>>>>> On Dec 10, 2015, at 10:19 AM, John McCall <[email protected]> wrote:
>>>>>
>>>>>> On Dec 10, 2015, at 8:31 AM, Joe Groff via swift-dev
>>>>>> <[email protected]> wrote:
>>>>>>> On Dec 9, 2015, at 4:15 PM, Adrian Prantl via swift-dev
>>>>>>> <[email protected]> wrote:
>>>>>>>
>>>>>>> In order to write textual SIL -> SIL testcases that exercise the
>>>>>>> handling of debug information by SIL passes, we need to make a couple
>>>>>>> of additions to the textual SIL language. In memory, the debug
>>>>>>> information attached to SIL instructions references information from
>>>>>>> the AST. If we want to create debug info from parsing a textual .sil
>>>>>>> file, these bits need to be made explicit.
>>>>>>>
>>>>>>> Let me illustrate this with an example. The function
>>>>>>>
>>>>>>>> func foo(x : Int) -> Int {
>>>>>>>> return bar(x)
>>>>>>>> }
>>>>>>>
>>>>>>> is compiled to SIL as
>>>>>>>
>>>>>>>> // main.foo (Swift.Int) -> Swift.Int
>>>>>>>> sil hidden @_TF4main3fooFSiSi : $@convention(thin) (Int) -> Int {
>>>>>>>> // %0 // users: %1, %2, %4
>>>>>>>> bb0(%0 : $Int):
>>>>>>>> debug_value %0 : $Int // let x, argno: 1 // id: %1
>>>>>>>> line:1:10:in_prologue
>>>>>>>> return %4 : $Int // id: %5
>>>>>>>> line:2:3:return
>>>>>>>> }
>>>>>>>
>>>>>>> Note that there is a bunch of information available in comments that
>>>>>>> will be lost once we parse that textual SIL again. I’d like to add
>>>>>>> syntax to SIL for the information in the comments. This proposal deals
>>>>>>> with lifting the debug variable information (the first comment) into
>>>>>>> actual SIL syntax. A similar proposal for locations will be coming soon.
>>>>>>> With the proposed syntax, this could like like:
>>>>>>>
>>>>>>>> sil hidden @_TF4main3fooFSiSi : $@convention(thin) (Int) -> Int {
>>>>>>>> bb0(%0 : $Int):
>>>>>>>> debug_value %0 : $Int, !dbg_var(name: "x", type: "_TTSi", argno: 1)
>>>>>>>> return %4 : $Int
>>>>>>>> }
>>>>>>>
>>>>>>> More formally, debug variable info may be attached to debug_value,
>>>>>>> debug_value_addr, alloc_box, and alloc_stack instructions.
>>>>>>>
>>>>>>> sil-instruction ::= 'alloc_stack' sil-type dbg-var
>>>>>>> sil-instruction ::= 'alloc_stack' sil-type dbg-var
>>>>>>> sil-instruction ::= debug_value sil-operand dbg-var
>>>>>>> sil-instruction ::= debug_value_addr sil-operand dbg-var
>>>>>>> dbg-var ::= ‘!dbg_var’ ‘(‘ var-attr (',' var-attr)*) ‘)'
>>>>>>> var-attr ::= ‘name:’ string-literal
>>>>>>> var-attr ::= ’type:’ string-literal
>>>>>>> var-attr ::= ‘argno:’ integer-literal
>>>>>>>
>>>>>>> This syntax for `dbg-var` is borrowed straight from LLVM IR and thus
>>>>>>> invokes a familiar feeling. Since the primary use-case of it will be in
>>>>>>> test cases, the verbose dictionary-like syntax is really helpful.
>>>>>>>
>>>>>>> Syntax alternatives I’ve considered and rejected include:
>>>>>>> 1. debug_value %0 : $Int, “x”, “_TtSi”, 1
>>>>>>> Why: Hard to read, potentially ambiguous because some fields are
>>>>>>> optional.
>>>>>>>
>>>>>>> 2. debug_value [name “x”] [type “_TtSi”] [argno 1] %0 : $Int
>>>>>>> Why: Attributes in square brackets don’t typically have arguments and
>>>>>>> come before the entity they are modifying.
>>>>>>>
>>>>>>> 3. debug_value @var(name: “x”, type: “_TtSi”, argno: 1) %0 : $Int
>>>>>>> Why: The ‘@‘ sigil is used not just for attributes but also for global
>>>>>>> symbols and thus creates an ambiguity.
>>>>>>
>>>>>> Thanks for working on this, Adrian! My thoughts:
>>>>>>
>>>>>> - I don't see a reason to mangle the type name at SIL time. You should
>>>>>> reference the formal AST type directly in the instruction, and print and
>>>>>> parse it using the normal (Swift) type parser.
>>>>>
>>>>> In addition to all the other good reasons to do this, this means that
>>>>> archetypes in the type will be (1) sensibly bound in the context and (2)
>>>>> actually substituted by inlining and generic specialization.
>>>>
>>>> By deferring the type mangling to IRGen time I’m hitting an interesting
>>>> problem:
>>>>
>>>> Let’s say we have the function
>>>> func id<T>(x : T) -> T { return x }
>>>>
>>>> which is translated to SIL as
>>>>
>>>>> func id<T>(x: T) -> T // FuncDecl
>>>>>
>>>>> // declcontext.id <A> (A) -> A
>>>>> sil hidden @_TF11declcontext2idurFxx : $@convention(thin) <T> (@out T,
>>>>> @in T) -> () {
>>>>> bb0(%0 : $*T, %1 : $*T):
>>>>> debug_value_addr %1 : $*T, let, name "x", argno 1
>>>>> copy_addr [take] %1 to [initialization] %0 : $*T
>>>>> %4 = tuple ()
>>>>> return %4 : $()
>>>>> }
>>>>
>>>> When emitting debug info for “x” we need to determine the mangled name of
>>>> “T”. Since T is an archetype, the Mangler needs its DeclContext. In a
>>>> compilation from source the DeclContext is readily available and the
>>>> FuncDecl itself.
>>>> However, when parsing this from SIL it is unclear how to match up the
>>>> SILFunction with the FuncDecl to establish the DeclContext for the
>>>> Mangler. It would be possible to demangle the SILFunction’s name and then
>>>> look up the FuncDecl by name in the SwiftModule and then filter the lookup
>>>> results by type. But this filtering would not work after function
>>>> signature optimizations.
>>>> Another option is to explicitly call out the DeclContext by adding a
>>>> sil-decl-ref attribute, like this:
>>>>
>>>>> debug_value_addr %1 : $*T, let, name "x", argno 1, declctx #id!1
>>>>
>>>>
>>>> But it looks like sil-decl-refs also aren’t expressive enough to
>>>> distinguish between foo() / foo(x:Int) / foo<T>(x:T).
>>>>
>>>> Am I missing something obvious?
>>>>
>>>
>>> Don't SILFunctions already reference a context ValueDecl for debug purposes?
>>
>> If you’re refering to SILFunction::getDeclContext() this field is only
>> populated by the regular SILGen path. ParseSIL does not (yet) do this. I ran
>> into the above problem while trying to set the DeclContext of SILFunctions
>> that are created by ParseSIL.cpp.
>
> We could add some syntax to the sil function syntax to reference the debug
> DeclContext. I wouldn't try to demangle the name to guess what it's supposed
> to be.
>
Here are a couple of horrible ideas how this could be done:
1. Extend sil-decl-ref to allow specifying a type:
Grammar:
sil-function ::= 'sil' sil-linkage? sil-function-name ':' sil-type
‘declcontext’ sil-decl-ref
'{' sil-basic-block+ '}'
Example:
// Decl
func foo<T>(i : Int) -> T
// SIL function + DeclContextRef
sil @_TF4test3foo... : $@convention(thin) <T> (@out T, @in T) -> ()
declcontext test.foo$<T>(Int) -> (T) {
2. Extend ValueDecls in .sil files with a unique id
Example:
// Decl + ID
func foo() #1
// SIL function + DeclContextRef
sil @_TF4test3foo... : $... declcontext #1 {
3. Extend ValueDecls with a unique id that happens to be its mangled/silgen name
Example:
// Decl + ID
@_silgen_name("@_TF4test3foo...”) func foo()
// SIL function + DeclContextRef
sil @_TF4test3foo... : $... declcontext @_TF4test3foo... {
I personally lean towards something along the lines of option 1. What do you
think?
-- adrian
_______________________________________________
swift-dev mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-dev