Skip to content

Skip meta instructions for Builder.init with automatic location #73864

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
May 30, 2024

Conversation

Snowy1803
Copy link
Member

Following discussion under #73387, this PR fixes the Builder in SwiftCompilerSources to do the same as SILBuilderWithScope. Inserting an instruction at the beginning of a block will use the first non-meta instruction's location and scope, instead of potentially inheriting it from a debug_value.

@Snowy1803
Copy link
Member Author

@swift-ci please test

Copy link
Contributor

@eeckstein eeckstein left a comment

Choose a reason for hiding this comment

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

Thanks for putting up this PR!
I'm a bit picky with my comments, because I think it's important to get such a basic API right.
I know you just translated the C++ code into swift, but we should take the opportunity to fix the deficiencies of the C++ design.

@@ -429,6 +429,33 @@ extension Type {
// Builder initialization
//===----------------------------------------------------------------------===//

extension Instruction {
/// Returns self, unless self is a meta instruction, in which case the next
Copy link
Contributor

Choose a reason for hiding this comment

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

We need a good definition of the term "meta instruction" - and also a better name. The term is not used anywhere else in SIL (I just figured out now that it's borrowed from LLVM's machine instructions).
In SILInstruction::isMetaInstruction() we define it as: "Every instruction that doesn't generate code should be in this list."
But this is not even true for alloc_stack: if the allocated type is generic, alloc_stack can generate code (metadata instantiation). On the other hand, there are a lot of instructions which really don't generate code, like dealloc_stack, begin_borrow, etc. and are not considered as "meta instructions".
So, what makes alloc_stack special in terms of debug info?

Copy link
Contributor

Choose a reason for hiding this comment

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

We need a good definition of the term "meta instruction" - and also a better name.

Yes we copied this term of art from MIR: https://www.llvm.org/doxygen/classllvm_1_1MachineInstr.html#aeffeb27bd92437aa2fd7b7567b01d078

Return true if this instruction doesn't produce any output in the form of executable instructions.

I think the definition we really mean in SIL is: Should a new SIL instruction inserted after this instruction inherit this instruction's SILLocation and scope?

Since alloc_stack instructions are often hoisted to the beginning of a function, they can have a scope and location that is out-of-order. You are correct that alloc_stack instruction generate code in the form of an LLVM alloca but these instructions are part of the function prologue and don't have any scope or location.

In modern SIL alloc_stack instructions can actually have two SIL location/scope pairs, one for the instruction, and one for the variable. We could side-step the problem by setting the location of the alloc_stack instruction to a compiler-generated (or prologue?) location and relying on the variable carrying its own scope and location. Then we don't need an IsMetaInstruction helper.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, but that would still not solve the problem of what scope an alloc_stack should have. If we don't skip alloc_stacks in SILBuilderWithScope, then we'd need to reparent an alloc_stack every time it's moved. So I think we may still want to be able to skip them in SILBuilderWithScope.

So back to finding a better name for the function:
Since meta instruction is already a term of art in LLVM, I'd want to keep it.
The fact that dealloc_stack and begin_borrow are not classified as meta instructions is probably more a bug than a significant difference.

Copy link
Member Author

Choose a reason for hiding this comment

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

Writing this in the doc comment:
"A meta instruction is an instruction whose location is not interesting as it is impossible to set a breakpoint on it. That could be because the instruction does not generate code (such as debug_value), or because the generated code would be in the prologue (alloc_stack). Other instructions should not inherit this instruction's location."

We could add other instructions to the list, but we would have to do it on both the C++ and the Swift side, so I think it should be in a separate PR.

@eeckstein eeckstein requested a review from atrick May 24, 2024 08:07
@Snowy1803 Snowy1803 force-pushed the scs-builder-skip-meta branch 2 times, most recently from d954c72 to fbed1c1 Compare May 24, 2024 23:00
@Snowy1803 Snowy1803 force-pushed the scs-builder-skip-meta branch from fbed1c1 to d39d838 Compare May 24, 2024 23:01
@Snowy1803
Copy link
Member Author

@swift-ci please smoke test

@adrian-prantl adrian-prantl self-requested a review May 29, 2024 23:43
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.

Based on an offline conversation with Erik we can go ahead and merge this, though there might be future improvements to the API that we might want to make.

@Snowy1803 Snowy1803 merged commit 531469f into swiftlang:main May 30, 2024
3 checks passed
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