Yeah, option 1 seems reasonable to me. I might give it attribute-like spelling, though, to help bracket it and keep it separate from the real name and declaration:
sil [debug_decl_context test.foo : <T> (T) -> ()] @_Tfoo : $... { } -Joe > On Dec 15, 2015, at 4:30 PM, Adrian Prantl <apra...@apple.com> wrote: > >> >> On Dec 15, 2015, at 2:37 PM, Joe Groff <jgr...@apple.com> wrote: >> >>> >>> On Dec 15, 2015, at 2:34 PM, Adrian Prantl <apra...@apple.com> wrote: >>> >>>> >>>> On Dec 15, 2015, at 2:27 PM, Joe Groff <jgr...@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. >>>>> 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 swift-dev@swift.org https://lists.swift.org/mailman/listinfo/swift-dev