LTO requires the debug-info-for-profiling to be a function attribute.
Details
Diff Detail
- Build Status
Buildable 3401 Build 3401: arc lint + arc unit
Event Timeline
lib/CodeGen/AsmPrinter/DwarfDebug.cpp | ||
---|---|---|
1136 | Is debug-info-for-profiling used to turn on and off debug info for profiling on a per-function basis? I'm not very familiar with this function, but it looks like HasDebugInfoForProfiling is initialized to false in the constructor and then it will always be true after beginFunction is called on a function that has attribute debug-info-for-profiling=true. |
include/llvm/IR/Attributes.td | ||
---|---|---|
182 ↗ | (On Diff #85982) | That'll be long in the IR, where there is already a long list, what about "prof-dbg-info" or something like that that would make sense? |
lib/CodeGen/AsmPrinter/DwarfDebug.cpp | ||
1136 | Yep that seems broken to me. If foo has the attribute and not bar, we'll emit the profiling debug info for bar if foo is processed first. |
lib/CodeGen/AsmPrinter/DwarfDebug.cpp | ||
---|---|---|
1136 | The issue is that I cannot check for function's attributes in DwarfUnit::applySubprogramAttributes, any suggestions on how I can pass down this attribute to that function? |
lib/CodeGen/AsmPrinter/DwarfDebug.cpp | ||
---|---|---|
1136 | Why not do here HasDebugInfoForProfiling = MF->getFunction()->debugInfoForProfiling(); ? |
Is there a reason to make this a function attribute rather than a flag carried in the metadata? Having something related to debug info as an attribute seems odd.
test/DebugInfo/Inputs/gmlt_profiling.ll | ||
---|---|---|
5 ↗ | (On Diff #85982) | f2() does not appear in any checks and is not used anywhere else in the test. Why is it here? |
7 ↗ | (On Diff #85982) | f3() and f4() do not appear in any checks, why are they here? |
14 ↗ | (On Diff #85982) | Writing checks for dwarfdump output is tricky because you're really trying to match several attribute lines within the same DWARF entry. So here you want something like this: CHECK: DW_TAG_subprogram CHECK-NOT: {{DW_TAG|NULL}} CHECK: DW_AT_name {{.*}} "f1" CHECK-NEXT: DW_AT_decl_file CHECK-NEXT: DW_AT_decl_line This assumes that name/file/line appear in that exact sequence, but there are lots of debug-info tests with that kind of assumption. Unless/until we get a fancier debug-info matcher this is the kind of thing we have to do. |
43 ↗ | (On Diff #85982) | Generally we encourage people to remove attributes that aren't relevant or necessary to the test. Here, probably only "debug-info-for-profiling" is the relevant one? Removing the others helps clarify what the test is about. |
lib/CodeGen/AsmPrinter/DwarfDebug.cpp | ||
---|---|---|
1136 | Because the llvm::DwarfDebug::beginFunction is called first before llvm::DwarfUnit::applySubprogramAttributes are called. E.g. you have f1, f2, f3 the call sequence is: The current logic is, if there is any function that has HasDebugInfoForProfiling=true, then all function will have it. |
lib/CodeGen/AsmPrinter/DwarfDebug.cpp | ||
---|---|---|
1136 | All the more reason to put it at module or CU level, rather than function level. |
lib/CodeGen/AsmPrinter/DwarfDebug.cpp | ||
---|---|---|
1136 | If the behavior you want is to have it enabled for the module, then yes like @probinson says a module level construct would make more sense. I don't enough about -gmlt to know what we would expect if we have a.cpp and b.cpp and we build with LTO one with -g and the other one with -gmlt ? |
lib/CodeGen/AsmPrinter/DwarfDebug.cpp | ||
---|---|---|
1136 | Can you clarify what is the behavior in this case:
|
lib/CodeGen/AsmPrinter/DwarfDebug.cpp | ||
---|---|---|
1136 | I am not debug info expert, Eric may have more accurate answer. My understanding is that one will have more debug info emitted, the other will only have line table emitted. What will happen in LTO? |
lib/CodeGen/AsmPrinter/DwarfDebug.cpp | ||
---|---|---|
1136 | I'm asking because I haven ming that of DebugInfoForProfiling will be enabled by -gmlt, but that may not be true? If so when/how is DebugInfoForProfiling set? |
lib/CodeGen/AsmPrinter/DwarfDebug.cpp | ||
---|---|---|
1136 | It will be set with -fdebug-info-for-profiling. A follow-up cfe patch is in: https://reviews.llvm.org/D29205 |
lib/CodeGen/AsmPrinter/DwarfDebug.cpp | ||
---|---|---|
1136 | Ok so back to my question:
|
lib/CodeGen/AsmPrinter/DwarfDebug.cpp | ||
---|---|---|
1136 | -fdebug-info-for-profiling is orthogonal with -g/-gmlt. So I guess the question should be: what we would expect if we have a.cpp and b.cpp and we build with LTO, a.cpp with -fdebug-info-for-profiling and b.cpp without the flag? How does your module flag affect that? The answer is
I guess this also applies to the cases that a.cpp is built with -g and b.cpp is built with -gmlt. |
lib/CodeGen/AsmPrinter/DwarfDebug.cpp | ||
---|---|---|
1136 | During Monolithic LTO, the two files are *merged*. There is a single CodeGen happening. I'm still trying to figure out what is the impact of If some functions are imported from b.cpp to a.cpp, it will inherit the flag from a.cpp thus have related code executed, because I don't know enough about -fdebug-info-for-profiling. I think I originally misread this comment: // Under -gmlt, skip building the subprogram if there are no inlined // subroutines inside it. But with -fdebug-info-for-profiling, the subprogram // is still needed as we need its source location. If I understand correctly, the module flag would make the debug info emission more conservative. Does it mean that adding -fdebug-info-for-profiling with -g does not have any effect on the Dwarf emission? It is only in effect with DICompileUnit::LineTablesOnly? |
lib/CodeGen/AsmPrinter/DwarfDebug.cpp | ||
---|---|---|
1136 | -fdebug-info-for-profiling has the following implication:
For #1, -g also emits these extra info, thus it only applies to -gmlt |
lib/CodeGen/AsmPrinter/DwarfDebug.cpp | ||
---|---|---|
1136 | Thanks for the explanation! If @probinson does not have any other comment that LGTM. |
Regarding the mixed-mode LTO question, my understanding is that if we have a module-level flag then it would apply to everything in the merged module. The merged module will still have debug info organized per original compilation unit. So, if we have a per-CU flag and compiled flag-on.cpp and flag-off.cpp, then functions from flag-on.cpp would get the extra info and functions from flag-off.cpp would not, with the caveat that if you inline a function across compilation units, then the flag from the CU for the caller would apply.
I believe we have a module flag here, so the entire module would be treated as if -fdebug-info-for-profiling had been turned on for all CUs.
(Did I get that right?)
test/DebugInfo/Inputs/gmlt_profiling.ll | ||
---|---|---|
14 ↗ | (On Diff #85982) | The CHECK-NOT should not match a DW_AT line. You need it to ensure that the attributes belong to the same TAG that you found. |
After a lengthy discussion with @dblaikie (Thanks David for the input), let me add some more context to this patch.
- What is the impact of adding -fdebug-info-for-profiling
- It will not affect the generated code
- It will increase the debug info size in -gmlt by ~17%
- It will not increase the debug info size in -g binary
- The compile time change should be negligible
- What we use a binary built with out -fdebug-info-for-profiling to collect profile
- The profile will be inaccurate and will yield sub-optimal performance when used to drive SamplePGO
- What is the motivating example that you want to compile some sources with -fdebug-info-for-profiling and some without
- If the debug info size is a concern for -gmlt binary, then one would want to only enable this flag for sources that is performance-critical
I think you are right. If we always emit this module flag (with value 0 or 1), when there are some CUs built with this flag, and some CUs without, in LTO, it will emit a warning and turn this flag on for all CUs.
Dehao
(Did I get that right?)
Right ;-) I think I need to raise the point before close the patch.
But my opinion is that this use cases (if any) would be rare because:
- 17% seem small, but people may have other opinions
- adding per-CU flag is manual and tedious
- per-CU flag may need to change as new source coming in/old source change that updates the hot CU distribution
That being said, I would think it's better to force this flag in LTO when mixed flag situation happens. But will let upstream decide if this would be a feature or a bug.
Thanks,
Dehao
test/DebugInfo/Inputs/gmlt_profiling.ll | ||
---|---|---|
7 ↗ | (On Diff #86117) | The CHECK-NOT needs to go before DW_AT_name. |
include/llvm/IR/DebugInfoMetadata.h | ||
---|---|---|
1140–1142 | I don't think this accessor is needed | |
lib/CodeGen/AsmPrinter/DwarfDebug.h | ||
266–268 ↗ | (On Diff #86117) | Presumably this (& the accessor below) can be removed now? |
lib/IR/Module.cpp | ||
468–475 ↗ | (On Diff #86117) | Presumably this should go away now that it's in the CU metadata. |
test/DebugInfo/Generic/gmlt.test | ||
0 | This line should probably be in gmlt_profiling.ll | |
0 | This line should probably be in gmlt.ll (both gmlt.ll and gmlt_profiling.ll would move from test/DebugInfo/Inputs to test/DebugInfo/Generic) |
include/llvm/IR/DIBuilder.h | ||
---|---|---|
107–110 | Missing doxygen for the new(er) flag(s). |
It might also be a good idea to document the purpose of the flag in SourceLevelDebugging.rst,
Could you help suggest which section I should add related doc? I think it would be good to add to the doc that introduces different debug level, but seems no such content exists in the current doc.
That document clearly needs a some love :-)
I would suggest adding a new Compile Unit section to either of the two Debugging information format sections (which should be merged) and adding a stub about global (compile-unit-wide) flags that influence the DWARF/CodeView debug info generator.
Sounds reasonable. But that seems quite some extra work that is outside the scope of this patch. Shall we start a separate thread to improve the documentation of the debug info?
Commented on bitcode test
test/Bitcode/upgrade-debug-info-for-profiling.ll | ||
---|---|---|
5 | This probably isn't necessary. | |
14 | Perhaps I'm confused about what this is testing*, but shouldn't the default be debugInfoForProfiling: false? *) I was expecting a DICompilieUnit produced by today's trunk without a bitcode record for the new flag, so we can verify that the old bitcode format is updated correctly. |
test/Bitcode/upgrade-debug-info-for-profiling.ll | ||
---|---|---|
14 | Not sure if I understand what to test in this upgrade test. What I did here:
Am I doing the right thing? |
I added one comment to the testcase, otherwise this is fine now.
test/Bitcode/upgrade-debug-info-for-profiling.ll | ||
---|---|---|
8 | Ah I didn't see the -NOT. |
test/DebugInfo/Generic/gmlt.test | ||
---|---|---|
0 | Moving this file to Generic/ means that other tests (notably, under X86/) now use files not within their Inputs, or within their parents' Inputs. Was that the intent of this comment? |
This change was addressing one of the review comments.
test/DebugInfo/X86/gmlt.test do now depends on the input file from test/DebugInfo/Generic/gmlt.ll. If this is an issue, I can send another patch to move gmlt.ll back to test/DebugInfo/Input and add test/DebugInfo/Generic/gmlt.test back.
I should have discovered the breaking x86 version of the test earlier...
Thanks for the reviews!
Missing doxygen for the new(er) flag(s).