This patch adds a dedicated class to keep track of each function's
layout. It also lays the groundwork for splitting functions into
multiple fragments (as opposed to a strict hot/cold split).
Details
- Reviewers
Amir maksfb rafauler yota9 - Commits
- rG8477bc67614a: [BOLT] Add function layout class
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
bolt/include/bolt/Core/BinaryBasicBlock.h | ||
---|---|---|
683 | Hello, I didn't investigate this patch carefully for now, but why FragmentNum needs to be unsigned? It seems it is used like previously used isCold flag. |
bolt/include/bolt/Core/BinaryBasicBlock.h | ||
---|---|---|
683 | It is unsigned, because it will be used to reference the fragment in which the basic block resides. You are correct that as of this patch there is only a hot and cold fragment and FragmentNum only assumes values 0 or 1. This will change with subsequent patches, in which support for multiple fragment splitting will be introduced. For this patch, I'll change the definition of getFragmentNum() to depend on IsCold, and retain the original definition for isCold()/setIsCold(). |
Split diff to reduce noise from replacing references to function layout to
block list.
bolt/include/bolt/Core/FunctionLayout.h | ||
---|---|---|
43 | If you use an enum class, then you can get rid of the prefixes. |
bolt/include/bolt/Core/FunctionLayout.h | ||
---|---|---|
43 | This enum is to be used temporarily to pass into APIs that take a fragment number as parameter for parts of BOLT that are only hot/cold aware (so we can perform a more incremental transition from relying on .blocks() to being fully multi-fragment aware). The code using those values will be nicer if they automatically convert to unsigned. Thanks for looking over this! |
Just as a comment. Maybe down the line, you could replace the unsigned with a FragmentId, a wrapper around an unsigned, to avoid confusion.
I have a feeling that you want to deprecate FunctionLayout::blocks(). There is probably a LLVM_DEPRECATED macro.
Your intution is correct, we want to get rid of FunctionLayout::blocks(). We discussed marking it as deprecated, but we figured it'll mostly create warning noise for now, because it is used too pervasively. So we defer that for now.
I did add a type for FragmentNum. I want to avoid the term "Id" here, because it is not used as an identifier across functions and can change arbitrarily in case if fragments are inserted in the middle of a function. Thanks for the suggestion!
bolt/include/bolt/Core/BinaryFunction.h | ||
---|---|---|
1376–1377 | What do you think of making isSplit() a property of FunctionLayout? We can keep this method as it also uses isSimple() for the sake of NFC, but perhaps this check is unnecessary. | |
bolt/include/bolt/Core/FunctionLayout.h | ||
80 | ||
177 | ||
bolt/lib/Core/BinaryEmitter.cpp | ||
401 | We can take advantage of the new layout class and iterate over fragments here. | |
bolt/lib/Core/BinaryFunction.cpp | ||
3232–3233 | ||
3566 |
Add isSplit() method to FunctionLayout + fix nits
bolt/include/bolt/Core/BinaryFunction.h | ||
---|---|---|
1376–1377 | I agree. | |
bolt/lib/Core/BinaryEmitter.cpp | ||
401 | I already have considered something like this: const FunctionFragment F = BF.getLayout().getFragment( EmitColdPart ? FragmentNum::cold() : FragmentNum::hot()); for (BinaryBasicBlock *BB : F) { This change causes the AArch64 tests to fail, because this function is called (with EmitColdPart==false) even when the layout is empty. There are a few options to resolve this: separate the function into two functions, such that one deals with the constant islands and the other one emits the fragments. Then either one calls the other, or you update all callsites. The other option is to wrap the for (BinaryBasicBlock *BB... in a conditional. The last option is two return a default/null fragment from FunctionLayout::getFragment(), but I'd like to avoid adding those semantics to FunctionFragment. The first solution is probably the correct one, but adds extra noise to this diff. The second solution creates a lot of indenting. Either way, this will eventually be rewritten to support more than two fragments. Unless you think we should change it regardless, I'd suggest we keep iterating over the blocks, for now. |
bolt/lib/Core/FunctionLayout.cpp | ||
---|---|---|
105 | monotonically? unless the blocks are boring |
Hello, I didn't investigate this patch carefully for now, but why FragmentNum needs to be unsigned? It seems it is used like previously used isCold flag.