> On Dec 15, 2015, at 1:25 PM, Adrian Prantl <apra...@apple.com> wrote:
> 
>> 
>> On Dec 10, 2015, at 10:19 AM, John McCall <rjmcc...@apple.com> wrote:
>> 
>>> On Dec 10, 2015, at 8:31 AM, Joe Groff via swift-dev <swift-dev@swift.org> 
>>> wrote:
>>>> On Dec 9, 2015, at 4:15 PM, Adrian Prantl via swift-dev 
>>>> <swift-dev@swift.org> 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?

-Joe

_______________________________________________
swift-dev mailing list
swift-dev@swift.org
https://lists.swift.org/mailman/listinfo/swift-dev

Reply via email to