> 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