-
Notifications
You must be signed in to change notification settings - Fork 14.9k
[ICF] Add a NOP after branch in ICF thunk to improve debugability #154986
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
base: main
Are you sure you want to change the base?
Conversation
Signed-off-by: Peter Rong <PeterRong@meta.com>
Signed-off-by: Peter Rong <PeterRong@meta.com>
Signed-off-by: Peter Rong <PeterRong@meta.com>
@@ -1913,7 +1913,6 @@ void AsmPrinter::emitFunctionBody() { | |||
|
|||
// Print out code for the function. | |||
bool HasAnyRealCode = false; | |||
int NumInstsInFunction = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
NumInstsInFunction
was already calculated for debugging purposes. We just promote them as a class member to help us determine if DW_AT_LLVM_stmt_sequence
should be emitted.
So far as I know, one instruction sequences are fine - /zero/ instruction sequences are problematic. Is this about one instruction, or zero instruction? Could you say more about what problems one instruction sequences have? I had trouble following info on the linked PR #154851 - it says things like "LowPC == HighPC" - but that shouldn't be the case for a single instruction sequence, right? (I'd have expected: LowPC + sizeof(instruction) + 1 == HighPC) |
@dwblaikie Thanks for taking a look, here's more explanation, hopefully it helps:
One instruction and one instruction only.
Ideally, it shouldn't. But this is the case right now. HighPC is the last row's address, which means for one-instruction sequences, the last row is the first row, and thus HighPC and LowPC are the same.
This is what #154851 trying to achieve/fix by setting
As mentioned above, one-instruction won't be its own sequence. But normally that's fine. The problem is specific to safe-thunk ICF and DW_AT_LLVM_stmt_sequence:
Combining 1 and 2 creates a new problem: when one-instruction is not its own sequence, we can't correctly insert such offset. |
Ranges are half open - so the last row's address should be one past the last instruction, see here for example: https://godbolt.org/z/ffP17MPaP A single instruction function (containts a single x86 ret instruction) has two entries in the line table:
|
Thanks for pointing that out! But if you have three consecutive one-instruction functions (which would be a common case if you enable ICF safe thunks), they will be concat into one sequence: https://godbolt.org/z/GhrYP8njv
The problem we have here is, for ICF thunks to be probably symbolicated, each function needs to be its own sequence when we enable
In this case, we cannot just advance PC, or it will go into other thunks. |
I'm pretty sure this table is incorrect/buggy - it contains duplicate entries for the same offset. It describes zero-length, not one-length sequences. 3 single-instruction functions with separate sequences should be emitted like this:
|
(if the functions have padding to force 0x10 alignment, then their ranges can be [0, 1) or [0, 2) up to [0, 10) - any of those values would be OK, doesn't matter if the padding is included in the function or not) In reality, if you build this example and actually link it (not sure how to then dwarfdump that on godbolt, so you'll have to do this locally):
|
I agree, if the last row's address is not considered as part of the Sequence, it shouldn't bother with symbolication. If we agree that its
|
FYI: @dwblaikie Seems you guys had a similar discussion a year ago |
Thanks for dredging up the history, perhaps it's informative to you/your work now.
That still sounds like a bit of a dodgy workaround for some more fundamental problem - we know how long the instruction is, we can produce a sequence that properly describes it (as can be seen in other single-instruction examples, with |
One-instruction functions are not considered as a
Sequence
of instructions in the eye of DebugInfo, this has made the debugability of an ICF'ed function really poor. Both verification #152807 and relocation #149618 of debug info are hard because of it.We have two options moving forward:
For design discussions / more context please move to #154851