Allow skipping children in the module visitor and use that to speed up
decl-chain loading.
Details
Diff Detail
Event Timeline
On my tests this is a 40% speedup for a TU using ~1000 transitive modules. I didn't include the number in the description because it is misleading; we are still merging too much, and we have merging-heavy TUs.
Essentially this seems fine. It'd be better if visitDepthFirst didn't actually walk the the entire module graph in the case where it's been told to SkipChildren, but we can leave that improvement for a later change.
include/clang/Serialization/ModuleManager.h | ||
---|---|---|
297–300 | These parameters seem backwards to me (on each node, we'll call the preorder visitor before the postorder one, so it would seem more natural for the preorder one to be written first in a call to this function). | |
lib/Serialization/ASTReaderDecl.cpp | ||
3374 | Children here is ambiguous, and entirely backwards from the way I think of the imports graph (where the roots import nothing and the leaves are not imported by anything). Calling this Imports would remove the ambiguity (likewise in the DFSPreorderControl enum). | |
3387–3389 | A comment explaining what's going on here ("we don't need to visit a module or any of its imports if we've already deserialized the redecls from this module") would help. |
I'm not sure how that would be possible due to imports building a DAG.
The trade-off seems to be: either we remember the knowledge that all transitive deps do not need to be visited, or we might have to re-calculate that information when we come in via a different edge. My experiments indicate that the latter is common enough to offset the cost of the former.
include/clang/Serialization/ModuleManager.h | ||
---|---|---|
297–300 | ... says the person whose trees grow upside-down ;) Done. | |
lib/Serialization/ASTReaderDecl.cpp | ||
3374 | Note that there is precedence in the ModuleManager.h of calling the imports "children" :P | |
3387–3389 | Done. |
These parameters seem backwards to me (on each node, we'll call the preorder visitor before the postorder one, so it would seem more natural for the preorder one to be written first in a call to this function).