In D36351, Call-Chain Clustering (C3) heuristic is implemented with
option --call-graph-ordering-file <file>.
This patch adds a flag --print-symbol-order=<file> to LLD, and when specified,
it prints out the symbols ordered by the heuristics to the file.
The symbols printout is helpful to those who want to understand the
heuristics and want to reproduce the ordering with --symbol-ordering-file
in later pass.
Details
- Reviewers
ruiu george.burgess.iv pcc • espindola Bigcheese - Commits
- rG432030e843bf: [ELF] Dump symbols ordered by profiled guided section layout to file.
rL357133: [ELF] Dump symbols ordered by profiled guided section layout to file.
rLLD357133: [ELF] Dump symbols ordered by profiled guided section layout to file.
Diff Detail
- Repository
- rG LLVM Github Monorepo
- Build Status
Buildable 29112 Build 29111: arc lint + arc unit
Event Timeline
lld/ELF/CallGraphSort.cpp | ||
---|---|---|
230 | This is obvious, no need to explain by comment. | |
231 | This looks too fancy compared to other messages such as one in MapFile.cpp. Let's make it less fancy. I'd make the first line "Symbols ordered by call-chain clustering:\n", followed by a list of symbols, terminated by a blank line. | |
236 | Are you sure that all input sections have a name? | |
lld/test/ELF/cgprofile-print.s | ||
9 | This does not seem to test the feature that you want to use. Don't you want to print out the sorting order as a result of parsing .llvm.call-graph-profile sections, do you? |
Thank you so much for the comments! Do you care to elaborate more on the test? I am not sure what I should test? Thanks!
lld/ELF/CallGraphSort.cpp | ||
---|---|---|
236 | Not sure... But if the section doesn't, should I print an empty line, or just skip it? | |
lld/test/ELF/cgprofile-print.s | ||
9 | I am sorry that I think I am not sure I understand the comment completely. I was trying to add --verbose to LLD while passing in a call graph file and check the standard print with the expected ordering. (And I have removed the checks in the object file, since this check should be done in another test already.) Should I test something else instead? |
lld/ELF/CallGraphSort.cpp | ||
---|---|---|
235 | Should this go to a file with a user-specified name (without the header) instead of stdout? I'd expect the output of this to be consumed by a script, and sending it to a file would probably make it easier for said script to consume. Also, should this be listing the symbols instead of the sections if the intent is to pass this to --symbol-ordering-file? |
lld/ELF/CallGraphSort.cpp | ||
---|---|---|
236 | I don't think printing out a blank line is useful, but what I wanted to ask is if it is ever possible to be unnamed. We shouldn't guard it against an empty name "just in case". | |
lld/test/ELF/cgprofile-print.s | ||
9 | I thought that you wanted to print a result of a compiler-generated callgraph data stored into .llvm.call-graph-profile sections (there's such feature in lld and LLVM). If that's not the case, never mind. |
Thanks again for the comments!
lld/ELF/CallGraphSort.cpp | ||
---|---|---|
235 | I strongly agree that these suggestions would improve our lives if we want to use the outputs to feed --symbol-ordering-file in later pass. (Actually, right now I have to use a separate script to process the standard output and removing the headers to generate order file.) I'd love to improve this part, if it is OK to add a flag to support it. (And do you have any suggestions on the name of the flag?) Also, do you have some suggestions how to remove the headers cleanly? I don't see there's an option to remove the added prefix in the Name field of InputSectionBase? I don't think I should just try to remove ".text" (or ".text.hot" in some cases). Thank you! | |
236 | I do see empty Name when testing against some programs. Maybe we should check empty Name before printing to avoid empty lines? | |
lld/test/ELF/cgprofile-print.s | ||
9 | I think this option --call-graph-ordering-file is consuming the call graph and directly generate a map of sections with order. I think I only need to print out the ordering in the map for this purpose. So that's why I test it against. |
lld/ELF/CallGraphSort.cpp | ||
---|---|---|
235 | OK, that's fine. If that's the case, print out only symbol names to the file (without the header line). As to the option name, --print-symbol-order=FILENAME? |
Add a flag to save the output. Also printing out the symbol names of the ordering, instead of
the section names.
lld/ELF/CallGraphSort.cpp | ||
---|---|---|
235 | Thanks! |
lld/ELF/CallGraphSort.cpp | ||
---|---|---|
243 | We do not use auto unless its type is obvious from right-hand side. auto* Foo -> auto *Foo | |
246–247 | You don't need to cast -- I think you can directly compare Sections[SecIndex] == D->Section. | |
lld/ELF/Driver.cpp | ||
831 | Config members has the same name as their corresponding command line options, so please name it PrintSymbolOrder. |
Fix comments. Add one more test to test the outputs of the flag can be used to
reproduce the order with --symbol-ordering-file
lld/ELF/CallGraphSort.cpp | ||
---|---|---|
243 | Let's avoid using the same name for a variable and a class. I believe you have shadowed class Symbol by a variable Symbol. That's confusing. A common variable name is Sym. |
lld/ELF/CallGraphSort.cpp | ||
---|---|---|
243 | Oh, right. I'll fix it. |
lld/ELF/Options.td | ||
---|---|---|
278 | --call-graph-ordering file |
lld/ELF/Options.td | ||
---|---|---|
278 | Thanks! |
Ping. I think I have addressed all the comments here. Please let me know if there are more concerns to address. Thanks!
lld/ELF/CallGraphSort.cpp | ||
---|---|---|
244 | So I think that checking name is fragile. What do you actually want to skip by doing this? | |
lld/ELF/Driver.cpp | ||
1477 | 80 cols. | |
lld/ELF/Options.td | ||
278 | This help message seem a little bit foreign compared to other help messages. A more natural help message would be probably something this: Print a symbol order specified by --call-graph-ordering-file into to the specified file Be careful not to put a full stop at the end of a help message. | |
lld/test/ELF/cgprofile-print.s | ||
36–38 | Remove trailing extra newlines. |
lld/ELF/CallGraphSort.cpp | ||
---|---|---|
244 | Because without this checking, I can get two symbols in the file that both match section. One of them is empty name. I wanted to use this filter out that symbol. Plus the goal of this part is to find out a symbol name from the file that is in the section. So empty-named symbols should be ignored? |
lld/ELF/CallGraphSort.cpp | ||
---|---|---|
244 | Change the empty name check to symbol type check. If a symbol is section, no need to do the matching below. |
lld/ELF/CallGraphSort.cpp | ||
---|---|---|
243 | So the cost of this code is O(n*m) where n is there number of the sorted sections and n is the number of the symbols in each file. I don't think this code needs to be super fast, as this is not in the usual code path. If the performance becomes a problem, let's revisit to optimize. I'm ok with this code for now. | |
lld/ELF/Driver.cpp | ||
1475 | I don't think we need this guard, as this is a minor feature. Can you remove this code? |
lld/ELF/Driver.cpp | ||
---|---|---|
1475 | Why not be consistent here? |
lld/ELF/Driver.cpp | ||
---|---|---|
1475 | We could have many more features that writes something to a file, but I don't want to add two lines of code every time we add such feature. I'd remove MapFile rather than adding all files here if it needs to be consistent. |
This is obvious, no need to explain by comment.