Skip to content

[DebugInfo] Adding DIExpression into SIL #38378

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 22, 2021

Conversation

mshockwave
Copy link
Contributor

@mshockwave mshockwave commented Jul 13, 2021

This PR adds DIExpression infrastructure into SIL.

Previously, we can not use debug_value to mark the updated (SIL) SSA of a sub-field inside an aggregate-type source variable. For example:

struct MyStruct {
    var x : Int
}
%2 = alloc_stack $MyStruct, name "my_struct", loc "file.swift":3:4, scope 3
...
%5 = struct_element_addr %2 : $*MyStruct, #MyStruct.x, loc ...

In this snippet we are not able to generate a correct LLVM debug info for %5 using debug_value or debug_value_addr. Because the current SIL debug infrastructure lacks the equivalent feature of LLVM's !DIExpression. More specifically, the DW_OP_fragment operator.

This is not a problem in -Onone, but an outstanding one in optimized build where optimizations -- SROA for example -- might break an aggregate-type object apart or even eliminate the original aggregate type. In which case the debug info quality for variable values will degrade.

This PR (when it's finished) essentially adds functionalities similar to !DIExpression at the SIL level. Take the code above as the example, we're now able to generate the following SIL:

struct MyStruct {
    var x : Int
}
%2 = alloc_stack $MyStruct, name "my_struct", loc "file.swift":3:4, scope 3
...
%5 = struct_element_addr %2 : $*MyStruct, #MyStruct.x, loc ...
debug_value_addr %5 : $*Int, var, (name "my_struct", loc "file.swift":3:4, scope 3), type $MyStruct, expr op_fragment:#MyStruct.x, loc "file.swift":10:11, scope 3

Here are the new parameters / features added to debug_value / debug_value_addr:

  • The debug variable can have (optional) SILLocation and/or SILDebugScope attached (the loc and scope directives inside the parens enclosing name), which represents the source location where it was originally declared. If this extra info is absent, the instruction's source location will be used.
  • The type directive can be used to indicate the type where the debug variable was originally declared. If this info is absent, the type of the SSA value (i.e. %5 in this case) will be used.
  • Finally, the expr directive is used to carry the DIExpression that basically has a one-to-one mapping to LLVM's !DIExpression. Currently we only have op_fragment and op_deref operator, corresponding to DW_OP_LLVM_fragment and DW_OP_deref, respectively.

The part that is slightly controversial is probably how we carry these extra information on in-memory representation for the affected SIL instructions. This change will make SILDebugVariable, the class that represents debug variable and used by all debug-info-carrying instructions (including the alloc_* family), more expensive. Luckily most of the time SILDebugVariable is generated on-demand (it is actually not stored inside aforementioned SIL instructions) so hopefully it won't affect conventional SIL instruction transformations (like copying or moving SIL instructions).

I'm splitting this PR into two commits: The first commit add DIExpression support into SIL instructions classes (e.g. DebugValueInst) and changes regarding SILParser / SILPrinter; The second one add IRGen support.

@mshockwave
Copy link
Contributor Author

I'll add test cases shortly

@mshockwave mshockwave marked this pull request as ready for review July 14, 2021 21:30
@mshockwave
Copy link
Contributor Author

I'll squash all the commits into one right before it's ready to merge (or I can do it right now if you prefer)

@mshockwave
Copy link
Contributor Author

mshockwave commented Jul 14, 2021

@swift-ci test

@mshockwave mshockwave changed the title [WIP][DebugInfo] Adding DIExpression into SIL [DebugInfo] Adding DIExpression into SIL Jul 14, 2021
@mshockwave
Copy link
Contributor Author

@swift-ci please test

@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - 045a0ae249842a6c3313de7cb6bd08b983879498

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - 045a0ae249842a6c3313de7cb6bd08b983879498

@mshockwave mshockwave force-pushed the dev-sil-diexpression branch from 045a0ae to d8eef9e Compare July 15, 2021 21:42
@mshockwave
Copy link
Contributor Author

@swift-ci please test

@mshockwave mshockwave force-pushed the dev-sil-diexpression branch 2 times, most recently from 6e7f798 to bff2c61 Compare July 16, 2021 17:01
@mshockwave
Copy link
Contributor Author

Add documentations
@swift-ci please test

@adrian-prantl
Copy link
Contributor

Thanks, this is looking great! It would be good to also have test cases for the Verifier assertions that are added by this patch.

@adrian-prantl
Copy link
Contributor

@jckarter Do you have any opinion on the proposed SIL syntax extension?

Currently the debug info infrastructure inside SIL can only associate a
source variable with a single (simple) SSA value. Which is insufficient
to preserve (correct) debug info across SIL-level optimizations -- for
example, SROA that decompose or even eliminate aggregate-type obejcts.

By adding DIExpression into SIL, we are able to reconstruct the
connection between a source variable and its SSA value counterpart, even
across optimizations. This patch adds such support into in-memory
representation for SIL instructions and the SILParser/Printer. The
following patch will add changes for the IRGen part.
This patch is primarily doing two things:
 - Teach IRGen for some of the instructions to generate debug info based
   on SILDebugVariable rather than AST node, which is not always
   available when reading from SIL.
 - Generate corresponding `llvm.dbg.*` intrinsics and `!DIExpression`
   from the newly added SIL DIExpression.
@mshockwave mshockwave force-pushed the dev-sil-diexpression branch from bff2c61 to b363bbd Compare July 21, 2021 16:29
@mshockwave
Copy link
Contributor Author

Thanks, this is looking great! It would be good to also have test cases for the Verifier assertions that are added by this patch.

Sorry I almost missed this comment.
And hopefully the windows build bot is back to work 😛

@swift-ci please test

Copy link
Contributor

@adrian-prantl adrian-prantl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@mshockwave mshockwave merged commit 5a42c27 into swiftlang:main Jul 22, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants