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
No inline debug info generated for small functions when optimizing #26004
Comments
assigned to @Melamoto |
This is likely a debug location optimization problem. It would affect inlining or without inlining. If anyone wants to look into this, just watch which optimization removes the last use of the DebugLoc with the inlinedAt info. Chances are two instructions, one inside and one outside the inlined function, might get coalesced into some other operation and the outer instruction's location is chosen. Then we might split it back out (there was a bug filed recently about switch lowering doing something like this, maybe?) into multiple instructions in the backend without the extra information available anymore. I'll see if I can reduce this a bit further... |
With some changes this seemed to repro at -O1 for me. Still get an add instruction that looks like it's sufficiently similar to the add in the inlined function that it should be annotated as such. In the O1 IR, the add instruction appears to still have the right location. So I guess this is somewhere down in selection dag or other backend-y optimizations. |
Slightly simpler testcase, removing the dependency on printf int sum(int x, int y) { return x + y; } int main() { |
It's definitely a problem in the backend. define i32 @main() !dbg !3 { |
$ cat run.sh rm -rf bugopt bugopt.o echo "Result at 01" $ ./run.sh reduced.ll Result at 01 Taking this, trying to understand which backend pass destroys the information. |
I have a theory now. %add.i = add nsw i32 %inc5, %s.04, !dbg !32 where So the and the During LoopStrengthReduce the tail call void @llvm.dbg.value(metadata !2, i64 0, metadata !22, metadata !11), !dbg !23 where so, both the Stepping through with the debuggger reveals that when the Expander runs it inserts the I'm not entirely sure what's the best solution here, so I'm asking Quentin. |
It sounds like a job for the SCEVExpander at first glance. AFAICT, LSR is not playing with the debug locations and the SCEVExpander should have access to the Value, hence the debug location, related to the different expressions it expands. Right now, the expander uses the debug location of the insertion point instead of the original value, if I am not mistaken. I am not familiar with the internals of SCEV though. Sanjoy, what's your take on this? |
Is it possible to actually get to (the debug location of the) original value from within SCEVExpander? I'd think the transform that is requesting an expansion would have a better idea of what the debug location should be.
|
I'm not familiar with neither LSR or the internals of SCEV, but I spent a decent amount of time stepping in the debugger today. As a quick hack, I tried to force the debug location to be set correctly for this case and it seems to work, but I'm worried this is too specific to my case. diff --git a/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/lib/Transforms/Scalar/LoopStrengthReduce.cpp
So, I think there are two possible solutions to the problem:
Does this make sense? Ideas? |
I think we discussed this on IRC some time back, but I think the variant of (2) that changes expandCodeFor to take a DebugLoc is the right path forward. |
Agreed, #2 seems sensible to me. |
mentioned in issue #30616 |
Extended Description
For one liner functions, LLVM seems to not be emitting inlined-at information in the final binary. The inlinedAt tags are there in the bytecode, but don't show up in the final binary.
If I change the code of the inlined function to have more than one line, then the inlinedAt markers survive to the final binary.
$ clang++ -O2 -g bug.cc -o bug
$ llvm-dwarfdump --debug-dump=info bug|grep -A6 DW_TAG_inlined_subroutine
When compiled with GCC, the inlined function is marked properly:
$ g++-4.9 -O2 -g bug.cc -o gcc-bug
$ llvm-dwarfdump --debug-dump=info gcc-bug|grep -A6 DW_TAG_inlined_subroutine
0x00000476: DW_TAG_inlined_subroutine [21] *
DW_AT_abstract_origin [DW_FORM_ref4] (cu + 0x028d => {0x000003da} "_Z3sumxx")
DW_AT_low_pc [DW_FORM_addr] (0x0000000000400559)
DW_AT_high_pc [DW_FORM_data8] (0x0000000000000003)
DW_AT_call_file [DW_FORM_data1] ("./bug.cc")
DW_AT_call_line [DW_FORM_data1] (8)
DW_AT_GNU_discriminator [DW_FORM_data1] (0x02)
If I modified the inlined function to have more code, LLVM will generate a DW_TAG_inlined_subroutine tag. I did this in the no-bug.cc test case:
$ clang++ -g -O2 no-bug.cc -o no-bug
$ llvm-dwarfdump --debug-dump=info no-bug|grep -A6 DW_TAG_inlined_subroutine
0x000000b1: DW_TAG_inlined_subroutine [9] *
DW_AT_abstract_origin [DW_FORM_ref4] (cu + 0x004c => {0x0000004c} "_Z3sumxx")
DW_AT_low_pc [DW_FORM_addr] (0x000000000040063e)
DW_AT_high_pc [DW_FORM_data4] (0x00000010)
DW_AT_call_file [DW_FORM_data1] ("./no-bug.cc")
DW_AT_call_line [DW_FORM_data1] (13)
DW_AT_GNU_discriminator [DW_FORM_data1] (0x01)
The text was updated successfully, but these errors were encountered: