In lite mode, include split function fragments to the list of functions to
process even if a fragment has no samples. This is required to properly
detect and update split jump tables (jump tables that contain pointers to code
in the main and cold fragments).
Details
- Reviewers
rafauler maksfb - Group Reviewers
Restricted Project - Commits
- rGc49941bd0d7f: [BOLT] Process fragment siblings in lite mode, keep lite mode on
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
If the function is local, it will have a /<N> suffix inserted after the main fragment name and after .cold. Will this change cover such case? Please add a test for it.
bolt/lib/Rewrite/RewriteInstance.cpp | ||
---|---|---|
1525–1526 |
What do you think about preliminary matching fragments while reading the symbol table for non-stripped binaries? It's almost exactly what you are doing in this diff, right?
bolt/test/X86/fragment-lite-reverse.s | ||
---|---|---|
48 | How is foo different from main for the purpose of this test? From what I've seen, cold fragments typically have local visibility (but we shouldn't rely on it), while main fragments could be of any type. |
Let me look into that. I thought that selectFunctionsToProcess is the appropriate place since at that point we know which functions we want to skip and it's the earliest place to override that.
bolt/test/X86/fragment-lite-reverse.s | ||
---|---|---|
48 | Fixed. |
Sorry, I wasn't clear. I mean to match fragments early and then use the fragment dependency info in selectFunctionsToProcess(). It's still the right place to set functions as ignored.
Thanks for refactoring the code.
What happens to stripped binaries? Should we disable lite mode for them?
bolt/lib/Core/BinaryContext.cpp | ||
---|---|---|
504 | Do we have to check isFragment() before checking isParentFragment()? BTW, what do you think about renaming the latter to isChildOf()? | |
bolt/lib/Rewrite/RewriteInstance.cpp | ||
737 | Add the call to the end of discoverFileObjects(). That's where we register functions, data objects, etc. | |
1347 | ||
1351 | What if you have global foo+foo.cold.1 and local foo/1+foo.cold.1/1? What will foo.cold.1/1 match to? |
Actually, I don't know what happens to stripped binaries. For them, the more functions we process, the higher the risk that we miss a fragment or incorrectly update the jump table. Disabling lite mode doesn't fix processing stripped binaries with split functions. BTW, lite mode wasn't even disabled for such binaries since the determination is based on symbol names.
bolt/test/X86/fragment-lite.s | ||
---|---|---|
29 | IIRC, FileCheck will pass this check even for Parent : baz/1. |
Do we have to check isFragment() before checking isParentFragment()? BTW, what do you think about renaming the latter to isChildOf()?