> On Dec 15, 2015, at 3:01 PM, Adrian Prantl <apra...@apple.com> wrote:
>> On Dec 15, 2015, at 2:35 PM, John McCall <rjmcc...@apple.com> wrote:
>> 
>>> 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.
>> 
>> Well, right now the in-memory representation uses a single DeclContext for 
>> the entire SILFunction.  If that choice makes sense — and I’m willing to 
>> accept that it does — then it seems to me that the assembly representation 
>> should be consistent with that choice.  That is, you should find a way to 
>> write the DeclContext for the entire function in the parsed representation 
>> instead of writing it out for individual instructions.
> 
> The only complication is that a debug_value that was inlined from another 
> function will need to refer to that function as its DeclContext. Once we have 
> a syntax for locations and inline information (this is next up on my list) we 
> could determine an inlined instruction’s context via the location (which will 
> point to the original function) and don’t need to store it in the instruction.
> So, yes, attaching the DeclContext to a function would be totally adequate :-)
> 
>> 
>> Now, for the specific case of archetypes and mangling, the answer is 
>> probably that you don’t really need a DeclContext, you need a 
>> GenericParamList.
> 
> That would be great, as the GenericParamList is already stored in the 
> SILFunction. Alas, for debug info (only) the mangling for an archetype is 
> 
>  qualified-archetype ::= 'Qq' index context
> 
> and contains the DeclContext.

Well, as a reminder, you made this mangling up for debug-info’s purposes, so 
it’s up to you. :)

> It looks like both for locations DeclContexts it would be useful if there was 
> a way to uniquely refer to an earlier ValueDecl in the same SIL file. I’m 
> unsure what the best solution for this would be syntax-wise.

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

Reply via email to