Commonly when an analysis uses subanalyses, we eagerly create the sub function
info when constructing the main function info. This is not always necessary and
when the subanalyses do work in their constructor, can be actively harmful if
the parent analysis is never invoked.
This utility class solves this problem by being a very easy way to perform a
delayed call to the sub-analysis to get the sub-functioninfo combined with a
cache so that after the LazyFunctionInfo is used once, we do not reuse the
DenseMap in the sub-analysis unnecessarily.
An example of where this can happen is in EpilogueARCAnalysis in combination
with PostOrderFunctionInfo. PostOrderFunctionInfo eagerly creates a new post
order. So, if we were to eagerly create the PostOrderFunctionInfo (the
sub-functioninfo) when we created an EpilogueARCFunctionInfo, we would be
creating a post order even if we never actually invoke EpilogueARCFunctionInfo.
Today, if one wants to invalidate state relative to your own function analysis,
you have to use FunctionAnalysisBase::get() to get the analysis. The problem
here is that if the analysis does not exist yet, then you are actually creating
the analysis. This is an issue when one wants to perform an action on an
analysis only if the analysis has already been built. An example of such a
situation is when one is processing a delete notification. If one does not have
an analysis for a function, one should just do nothing.
I am going to use this to fix a delete notification problem in
EpilogueARCAnalysis.
rdar://33841629
Otherwise, every time we include Analysis.h, we will try to include those other
files even if we have already included Analysis.h. This can increase compile
time.
rdar://33841629
There are now separate functions for function addition and deletion instead of InvalidationKind::Function.
Also, there is a new function for witness/vtable invalidations.
rdar://problem/29311657
Add an invalidateAnalysisForDeadFunction API. This API calls the invalidateAnalysis
by default unless overriden by analysis pass themselves. This API passes the extra
information that this function is dead and going to be removed from the module.
CallerAnalysis overrides this API and only invalidate caller/callee relations but
does not push this into the recompute list.
We also considered the possibility of keeping a computed list, instead of recompute
list but that would introduce a O(n^2) complexity as every time we try to complete
the computed list, we need to walk over all the functions that currently exist in the
module to make sure the computed list is complete.
I feel eventually we can do a handleDeleteNotification for function deletion and we
wont need the API added in this change.
The analysis can tell all the callsites which calls a function in the module.
The analysis is computed and kept up-to-date lazily.
At the core of it, it keeps a list of functions that need to be recomputed for
the Caller/Callee relation to be precise and on every query, the analysis makes
sure to recompute them and clear the list before any query.
This is NFC right now. I am going to wire it up to function signature analysis
eventually.
(Headers first)
It has been generally agreed that we need to do this reorg, and now
seems like the perfect time. Some major pass reorganization is in the
works.
This does not have to be the final word on the matter. The consensus
among those working on the code is that it's much better than what we
had and a better starting point for future bike shedding.
Note that the previous organization was designed to allow separate
analysis and optimization libraries. It turns out this is an
artificial distinction and not an important goal.