For the Pass Manager to work optimally it needs to know the dependencies between the Passes. Each of the passes can itself declare its dependencies: the analysis passes that need to be executed before this pass is executed and the passes that will get invalidated after the current pass is run. To specify these dependencies, a pass needs to implement the getAnalysisUsage
method.
virtual void getAnalysisUsage(AnalysisUsage &Info) const;
Using this method the current pass can specify the required and invalidated sets by filling in the details in the AnalysisUsage
object. To fill in the information the Pass needs to call any of the following methods:
This method arranges for the execution of a Pass prior to the current Pass. One example of this is: for memory copy optimization it needs the results of an alias analysis:
void getAnalysisUsage(AnalysisUsage &AU) const override { AU.addRequired<AliasAnalysis>(); … … }
By adding the pass required to run, it is made sure that Alias Analysis Pass
is run before the MemCpyOpt
Pass. Also, this makes sure that if the Alias Analysis
has been invalidated by some other Pass, it will be run before the MemCpyOpt
Pass is run.
When an analysis chains to other analyses for results, this method should be used instead of the addRequired
method. That is, when we need to preserve the order in which the analysis passes are run we use this method. For example:
void DependenceAnalysis::getAnalysisUsage(AnalysisUsage &AU) const { … AU.addRequiredTransitive<AliasAnalysis>(); AU.addRequiredTransitive<ScalarEvolution>(); AU.addRequiredTransitive<LoopInfo>(); }
Here, DependenceAnalysis
chains to AliasAnalysis
, ScalarEvolution
and LoopInfo
Passes for the results.
By using this method a Pass can specify which analyses of other Passes it will not invalidate on running: that is, it will preserve the information already present, if any. This means that the subsequent passes that require the analysis would not need to run this again.
For example, in the case of the MemCpyOpt
Pass seen earlier, it required the AliasAnalysis
results and it also preserved them. Also:
void getAnalysisUsage(AnalysisUsage &AU) const override { …… AU.addPreserved<AliasAnalysis>(); ….. }
To get a detailed understanding of how everything is linked and works together, you can pick up any of the transformation passes and go through the source code and you will know how they are getting information from other passes and how they are using it.
18.225.234.24