> 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. -- adrian > > -Joe _______________________________________________ swift-dev mailing list swift-dev@swift.org https://lists.swift.org/mailman/listinfo/swift-dev