<a href="mailto:foldr@codedgers.com">Mikhail Glushenkov</a><br />
<a href="http://llvm.org">LLVM Compiler Infrastructure</a><br />
-Last modified: $Date: 2008-12-11 11:34:48 -0600 (Thu, 11 Dec 2008) $
+Last modified: $Date$
</address></div>
</div>
</div>
<li><a href="#AU::addRequired">The <tt>AnalysisUsage::addRequired<></tt> and <tt>AnalysisUsage::addRequiredTransitive<></tt> methods</a></li>
<li><a href="#AU::addPreserved">The <tt>AnalysisUsage::addPreserved<></tt> method</a></li>
<li><a href="#AU::examples">Example implementations of <tt>getAnalysisUsage</tt></a></li>
- <li><a href="#getAnalysis">The <tt>getAnalysis<></tt> and <tt>getAnalysisToUpdate<></tt> methods</a></li>
+ <li><a href="#getAnalysis">The <tt>getAnalysis<></tt> and
+<tt>getAnalysisIfAvailable<></tt> methods</a></li>
</ul></li>
<li><a href="#analysisgroup">Implementing Analysis Groups</a>
<ul>
<!-- _______________________________________________________________________ -->
<div class="doc_subsubsection">
- <a name="getAnalysis">The <tt>getAnalysis<></tt> and <tt>getAnalysisToUpdate<></tt> methods</a>
+ <a name="getAnalysis">The <tt>getAnalysis<></tt> and
+<tt>getAnalysisIfAvailable<></tt> methods</a>
</div>
<div class="doc_text">
<p>
If your pass is capable of updating analyses if they exist (e.g.,
<tt>BreakCriticalEdges</tt>, as described above), you can use the
-<tt>getAnalysisToUpdate</tt> method, which returns a pointer to the analysis if
-it is active. For example:</p>
+<tt>getAnalysisIfAvailable</tt> method, which returns a pointer to the analysis
+if it is active. For example:</p>
<div class="doc_code"><pre>
...
- if (DominatorSet *DS = getAnalysisToUpdate<DominatorSet>()) {
+ if (DominatorSet *DS = getAnalysisIfAvailable<DominatorSet>()) {
<i>// A DominatorSet is active. This code will update it.</i>
}
...
// or null if it is not known.
static const PassInfo *lookupPassInfo(intptr_t TI);
- /// getAnalysisToUpdate<AnalysisType>() - This function is used by subclasses
- /// to get to the analysis information that might be around that needs to be
- /// updated. This is different than getAnalysis in that it can fail (ie the
- /// analysis results haven't been computed), so should only be used if you
- /// provide the capability to update an analysis that exists. This method is
- /// often used by transformation APIs to update analysis results for a pass
- /// automatically as the transform is performed.
+ /// getAnalysisIfAvailable<AnalysisType>() - Subclasses use this function to
+ /// get analysis information that might be around, for example to update it.
+ /// This is different than getAnalysis in that it can fail (if the analysis
+ /// results haven't been computed), so should only be used if you can handle
+ /// the case when the analysis is not available. This method is often used by
+ /// transformation APIs to update analysis results for a pass automatically as
+ /// the transform is performed.
///
- template<typename AnalysisType>
- AnalysisType *getAnalysisToUpdate() const; // Defined in PassAnalysisSupport.h
+ template<typename AnalysisType> AnalysisType *
+ getAnalysisIfAvailable() const; // Defined in PassAnalysisSupport.h
/// mustPreserveAnalysisID - This method serves the same function as
- /// getAnalysisToUpdate, but works if you just have an AnalysisID. This
+ /// getAnalysisIfAvailable, but works if you just have an AnalysisID. This
/// obviously cannot give you a properly typed instance of the class if you
- /// don't have the class name available (use getAnalysisToUpdate if you do),
- /// but it can tell you if you need to preserve the pass at least.
+ /// don't have the class name available (use getAnalysisIfAvailable if you
+ /// do), but it can tell you if you need to preserve the pass at least.
///
bool mustPreserveAnalysisID(const PassInfo *AnalysisID) const;
AnalysisImpls.push_back(pir);
}
- // getAnalysisToUpdate - Return an analysis result or null if it doesn't exist
- Pass *getAnalysisToUpdate(AnalysisID ID, bool Direction) const;
+ // getAnalysisIfAvailable - Return analysis result or null if it doesn't exist
+ Pass *getAnalysisIfAvailable(AnalysisID ID, bool Direction) const;
// AnalysisImpls - This keeps track of which passes implements the interfaces
// that are required by the current pass (to implement getAnalysis()).
PMDataManager &PM;
};
-/// getAnalysisToUpdate<AnalysisType>() - This function is used by subclasses
-/// to get to the analysis information that might be around that needs to be
-/// updated. This is different than getAnalysis in that it can fail (ie the
-/// analysis results haven't been computed), so should only be used if you
-/// provide the capability to update an analysis that exists. This method is
-/// often used by transformation APIs to update analysis results for a pass
-/// automatically as the transform is performed.
+/// getAnalysisIfAvailable<AnalysisType>() - Subclasses use this function to
+/// get analysis information that might be around, for example to update it.
+/// This is different than getAnalysis in that it can fail (if the analysis
+/// results haven't been computed), so should only be used if you can handle
+/// the case when the analysis is not available. This method is often used by
+/// transformation APIs to update analysis results for a pass automatically as
+/// the transform is performed.
///
template<typename AnalysisType>
-AnalysisType *Pass::getAnalysisToUpdate() const {
+AnalysisType *Pass::getAnalysisIfAvailable() const {
assert(Resolver && "Pass not resident in a PassManager object!");
const PassInfo *PI = getClassPassInfo<AnalysisType>();
if (PI == 0) return 0;
return dynamic_cast<AnalysisType*>
- (Resolver->getAnalysisToUpdate(PI, true));
+ (Resolver->getAnalysisIfAvailable(PI, true));
}
/// getAnalysis<AnalysisType>() - This function is used by subclasses to get
bool AsmPrinter::doInitialization(Module &M) {
Mang = new Mangler(M, TAI->getGlobalPrefix(), TAI->getPrivateGlobalPrefix());
- GCModuleInfo *MI = getAnalysisToUpdate<GCModuleInfo>();
+ GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>();
assert(MI && "AsmPrinter didn't require GCModuleInfo?");
if (TAI->hasSingleParameterDotFile()) {
SwitchToDataSection(""); // Reset back to no section.
- MachineModuleInfo *MMI = getAnalysisToUpdate<MachineModuleInfo>();
+ MachineModuleInfo *MMI = getAnalysisIfAvailable<MachineModuleInfo>();
if (MMI) MMI->AnalyzeModule(M);
- DW = getAnalysisToUpdate<DwarfWriter>();
+ DW = getAnalysisIfAvailable<DwarfWriter>();
return false;
}
}
}
- GCModuleInfo *MI = getAnalysisToUpdate<GCModuleInfo>();
+ GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>();
assert(MI && "AsmPrinter didn't require GCModuleInfo?");
for (GCModuleInfo::iterator I = MI->end(), E = MI->begin(); I != E; )
if (GCMetadataPrinter *MP = GetOrCreateGCPrinter(*--I))
RS = RegInfo->requiresRegisterScavenging(MF) ? new RegScavenger() : NULL;
- MMI = getAnalysisToUpdate<MachineModuleInfo>();
+ MMI = getAnalysisIfAvailable<MachineModuleInfo>();
bool MadeChangeThisIteration = true;
while (MadeChangeThisIteration) {
}
bool Deleter::doFinalization(Module &M) {
- GCModuleInfo *GMI = getAnalysisToUpdate<GCModuleInfo>();
+ GCModuleInfo *GMI = getAnalysisIfAvailable<GCModuleInfo>();
assert(GMI && "Deleter didn't require GCModuleInfo?!");
GMI->clear();
return false;
// work against the entire module. But this cannot be done at
// runFunction time (initializeCustomLowering likely needs to change
// the module).
- GCModuleInfo *MI = getAnalysisToUpdate<GCModuleInfo>();
+ GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>();
assert(MI && "LowerIntrinsics didn't require GCModuleInfo!?");
for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
if (!I->isDeclaration() && I->hasGC())
bool DebugLabelFolder::runOnMachineFunction(MachineFunction &MF) {
// Get machine module info.
- MachineModuleInfo *MMI = getAnalysisToUpdate<MachineModuleInfo>();
+ MachineModuleInfo *MMI = getAnalysisIfAvailable<MachineModuleInfo>();
if (!MMI) return false;
// Track if change is made.
}
// Update live variable information if there is any.
- LiveVariables *LV = getAnalysisToUpdate<LiveVariables>();
+ LiveVariables *LV = getAnalysisIfAvailable<LiveVariables>();
if (LV) {
MachineInstr *PHICopy = prior(AfterPHIsIt);
// Get MachineModuleInfo so that we can track the construction of the
// frame.
- if (MachineModuleInfo *MMI = getAnalysisToUpdate<MachineModuleInfo>())
+ if (MachineModuleInfo *MMI = getAnalysisIfAvailable<MachineModuleInfo>())
Fn.getFrameInfo()->setMachineModuleInfo(MMI);
// Allow the target machine to make some adjustments to the function
DOUT << "\n\n\n=== " << Fn.getName() << "\n";
FuncInfo->set(Fn, *MF, EnableFastISel);
- MachineModuleInfo *MMI = getAnalysisToUpdate<MachineModuleInfo>();
- DwarfWriter *DW = getAnalysisToUpdate<DwarfWriter>();
+ MachineModuleInfo *MMI = getAnalysisIfAvailable<MachineModuleInfo>();
+ DwarfWriter *DW = getAnalysisIfAvailable<DwarfWriter>();
CurDAG->init(*MF, MMI, DW);
SDL->init(GFI, *AA);
MRI = &MF.getRegInfo();
TII = TM.getInstrInfo();
TRI = TM.getRegisterInfo();
- LV = getAnalysisToUpdate<LiveVariables>();
+ LV = getAnalysisIfAvailable<LiveVariables>();
bool MadeChange = false;
bool UnreachableMachineBlockElim::runOnMachineFunction(MachineFunction &F) {
SmallPtrSet<MachineBasicBlock*, 8> Reachable;
- MMI = getAnalysisToUpdate<MachineModuleInfo>();
+ MMI = getAnalysisIfAvailable<MachineModuleInfo>();
// Mark all reachable blocks.
for (df_ext_iterator<MachineFunction*, SmallPtrSet<MachineBasicBlock*, 8> >
bool Result = AsmPrinter::doInitialization(M);
// Emit initial debug information.
- MMI = getAnalysisToUpdate<MachineModuleInfo>();
+ MMI = getAnalysisIfAvailable<MachineModuleInfo>();
assert(MMI);
- DW = getAnalysisToUpdate<DwarfWriter>();
+ DW = getAnalysisIfAvailable<DwarfWriter>();
assert(DW && "Dwarf Writer is not available");
DW->BeginModule(&M, MMI, O, this, TAI);
bool Result = AsmPrinter::doInitialization(M);
SwitchToTextSection("\t.text");
// Emit initial debug information.
- DW = getAnalysisToUpdate<DwarfWriter>();
+ DW = getAnalysisIfAvailable<DwarfWriter>();
assert(DW && "Dwarf Writer is not available");
- MMI = getAnalysisToUpdate<MachineModuleInfo>();
+ MMI = getAnalysisIfAvailable<MachineModuleInfo>();
DW->BeginModule(&M, MMI, O, this, TAI);
return Result;
}
bool Result = AsmPrinter::doInitialization(M);
// Emit initial debug information.
- MMI = getAnalysisToUpdate<MachineModuleInfo>();
+ MMI = getAnalysisIfAvailable<MachineModuleInfo>();
assert(MMI);
- DW = getAnalysisToUpdate<DwarfWriter>();
+ DW = getAnalysisIfAvailable<DwarfWriter>();
assert(DW && "DwarfWriter is not available");
DW->BeginModule(&M, MMI, O, this, TAI);
// Emit initial debug information.
// We need this for Personality functions.
// AsmPrinter::doInitialization should have done this analysis.
- MMI = getAnalysisToUpdate<MachineModuleInfo>();
+ MMI = getAnalysisIfAvailable<MachineModuleInfo>();
assert(MMI);
- DW = getAnalysisToUpdate<DwarfWriter>();
+ DW = getAnalysisIfAvailable<DwarfWriter>();
assert(DW && "DwarfWriter is not available");
DW->BeginModule(&M, MMI, O, this, TAI);
// Let PassManager know we need debug information and relay
// the MachineModuleInfo address on to DwarfWriter.
// AsmPrinter::doInitialization did this analysis.
- MMI = getAnalysisToUpdate<MachineModuleInfo>();
- DW = getAnalysisToUpdate<DwarfWriter>();
+ MMI = getAnalysisIfAvailable<MachineModuleInfo>();
+ DW = getAnalysisIfAvailable<DwarfWriter>();
DW->BeginModule(&M, MMI, O, this, TAI);
}
}
// Emit final debug information.
- DwarfWriter *DW = getAnalysisToUpdate<DwarfWriter>();
+ DwarfWriter *DW = getAnalysisIfAvailable<DwarfWriter>();
DW->EndModule();
// Funny Darwin hack: This flag tells the linker that no global symbols
}
// Emit final debug information.
- DwarfWriter *DW = getAnalysisToUpdate<DwarfWriter>();
+ DwarfWriter *DW = getAnalysisIfAvailable<DwarfWriter>();
DW->EndModule();
} else if (Subtarget->isTargetELF()) {
// Emit final debug information.
- DwarfWriter *DW = getAnalysisToUpdate<DwarfWriter>();
+ DwarfWriter *DW = getAnalysisIfAvailable<DwarfWriter>();
DW->EndModule();
}
}
// Emit initial debug information.
- DW = getAnalysisToUpdate<DwarfWriter>();
+ DW = getAnalysisIfAvailable<DwarfWriter>();
assert(DW && "Dwarf Writer is not available");
- DW->BeginModule(&M, getAnalysisToUpdate<MachineModuleInfo>(),
+ DW->BeginModule(&M, getAnalysisIfAvailable<MachineModuleInfo>(),
O, this, TAI);
return Result;
}
}
bool InternalizePass::runOnModule(Module &M) {
- CallGraph *CG = getAnalysisToUpdate<CallGraph>();
+ CallGraph *CG = getAnalysisIfAvailable<CallGraph>();
CallGraphNode *ExternalNode = CG ? CG->getExternalCallingNode() : 0;
if (ExternalNames.empty()) {
"Expected only one incoming value from Original PreHeader");
}
- if (DominatorTree *DT = getAnalysisToUpdate<DominatorTree>()) {
+ if (DominatorTree *DT = getAnalysisIfAvailable<DominatorTree>()) {
DT->addNewBlock(NewPreHeader, OrigPreHeader);
DT->changeImmediateDominator(L->getHeader(), NewPreHeader);
DT->changeImmediateDominator(Exit, OrigPreHeader);
DT->changeImmediateDominator(OrigHeader, OrigLatch);
}
- if (DominanceFrontier *DF = getAnalysisToUpdate<DominanceFrontier>()) {
+ if (DominanceFrontier *DF = getAnalysisIfAvailable<DominanceFrontier>()) {
// New Preheader's dominance frontier is Exit block.
DominanceFrontier::DomSetType NewPHSet;
NewPHSet.insert(Exit);
// If a loop block dominates new loop latch then its frontier is
// new header and Exit.
BasicBlock *NewLatch = L->getLoopLatch();
- DominatorTree *DT = getAnalysisToUpdate<DominatorTree>();
+ DominatorTree *DT = getAnalysisIfAvailable<DominatorTree>();
for (Loop::block_iterator BI = L->block_begin(), BE = L->block_end();
BI != BE; ++BI) {
BasicBlock *B = *BI;
return false;
// FIXME: Reconstruct dom info, because it is not preserved properly.
- DominatorTree *DT = getAnalysisToUpdate<DominatorTree>();
+ DominatorTree *DT = getAnalysisIfAvailable<DominatorTree>();
if (DT) {
DT->runOnFunction(*F);
- DominanceFrontier *DF = getAnalysisToUpdate<DominanceFrontier>();
+ DominanceFrontier *DF = getAnalysisIfAvailable<DominanceFrontier>();
if (DF)
DF->runOnFunction(*F);
}
bool LoopUnswitch::runOnLoop(Loop *L, LPPassManager &LPM_Ref) {
LI = &getAnalysis<LoopInfo>();
LPM = &LPM_Ref;
- DF = getAnalysisToUpdate<DominanceFrontier>();
- DT = getAnalysisToUpdate<DominatorTree>();
+ DF = getAnalysisIfAvailable<DominanceFrontier>();
+ DT = getAnalysisIfAvailable<DominatorTree>();
currentLoop = L;
Function *F = currentLoop->getHeader()->getParent();
bool Changed = false;
// Finally, erase the old block and update dominator info.
if (P) {
- if (DominatorTree* DT = P->getAnalysisToUpdate<DominatorTree>()) {
+ if (DominatorTree* DT = P->getAnalysisIfAvailable<DominatorTree>()) {
DomTreeNode* DTN = DT->getNode(BB);
DomTreeNode* PredDTN = DT->getNode(PredBB);
BasicBlock *New = Old->splitBasicBlock(SplitIt, Old->getName()+".split");
// The new block lives in whichever loop the old one did.
- if (LoopInfo* LI = P->getAnalysisToUpdate<LoopInfo>())
+ if (LoopInfo* LI = P->getAnalysisIfAvailable<LoopInfo>())
if (Loop *L = LI->getLoopFor(Old))
L->addBasicBlockToLoop(New, LI->getBase());
- if (DominatorTree *DT = P->getAnalysisToUpdate<DominatorTree>())
+ if (DominatorTree *DT = P->getAnalysisIfAvailable<DominatorTree>())
{
// Old dominates New. New node domiantes all other nodes dominated by Old.
DomTreeNode *OldNode = DT->getNode(Old);
DT->changeImmediateDominator(*I, NewNode);
}
- if (DominanceFrontier *DF = P->getAnalysisToUpdate<DominanceFrontier>())
+ if (DominanceFrontier *DF = P->getAnalysisIfAvailable<DominanceFrontier>())
DF->splitBlock(Old);
return New;
Preds[i]->getTerminator()->replaceUsesOfWith(BB, NewBB);
// Update dominator tree and dominator frontier if available.
- DominatorTree *DT = P ? P->getAnalysisToUpdate<DominatorTree>() : 0;
+ DominatorTree *DT = P ? P->getAnalysisIfAvailable<DominatorTree>() : 0;
if (DT)
DT->splitBlock(NewBB);
- if (DominanceFrontier *DF = P ? P->getAnalysisToUpdate<DominanceFrontier>():0)
+ if (DominanceFrontier *DF = P ? P->getAnalysisIfAvailable<DominanceFrontier>():0)
DF->splitBlock(NewBB);
- AliasAnalysis *AA = P ? P->getAnalysisToUpdate<AliasAnalysis>() : 0;
+ AliasAnalysis *AA = P ? P->getAnalysisIfAvailable<AliasAnalysis>() : 0;
// Insert a new PHI node into NewBB for every PHI node in BB and that new PHI
bool NewBBDominatesDestBB = true;
// Should we update DominatorTree information?
- if (DominatorTree *DT = P->getAnalysisToUpdate<DominatorTree>()) {
+ if (DominatorTree *DT = P->getAnalysisIfAvailable<DominatorTree>()) {
DomTreeNode *TINode = DT->getNode(TIBB);
// The new block is not the immediate dominator for any other nodes, but
}
// Should we update DominanceFrontier information?
- if (DominanceFrontier *DF = P->getAnalysisToUpdate<DominanceFrontier>()) {
+ if (DominanceFrontier *DF = P->getAnalysisIfAvailable<DominanceFrontier>()) {
// If NewBBDominatesDestBB hasn't been computed yet, do so with DF.
if (!OtherPreds.empty()) {
// FIXME: IMPLEMENT THIS!
}
// Update LoopInfo if it is around.
- if (LoopInfo *LI = P->getAnalysisToUpdate<LoopInfo>()) {
+ if (LoopInfo *LI = P->getAnalysisIfAvailable<LoopInfo>()) {
// If one or the other blocks were not in a loop, the new block is not
// either, and thus LI doesn't need to be updated.
if (Loop *TIL = LI->getLoopFor(TIBB))
DominatorTree *DT = NULL;
DominanceFrontier *DF = NULL;
if (P) {
- DT = P->getAnalysisToUpdate<DominatorTree>();
- DF = P->getAnalysisToUpdate<DominanceFrontier>();
+ DT = P->getAnalysisIfAvailable<DominatorTree>();
+ DF = P->getAnalysisIfAvailable<DominanceFrontier>();
}
SmallVector<BasicBlock *, 16> NewBlocks;
bool LoopSimplify::runOnFunction(Function &F) {
bool Changed = false;
LI = &getAnalysis<LoopInfo>();
- AA = getAnalysisToUpdate<AliasAnalysis>();
+ AA = getAnalysisIfAvailable<AliasAnalysis>();
DT = &getAnalysis<DominatorTree>();
// Check to see that no blocks (other than the header) in loops have
// Update dominator information
DT->splitBlock(BEBlock);
- if (DominanceFrontier *DF = getAnalysisToUpdate<DominanceFrontier>())
+ if (DominanceFrontier *DF = getAnalysisIfAvailable<DominanceFrontier>())
DF->splitBlock(BEBlock);
}
ModulePass::~ModulePass() { }
bool Pass::mustPreserveAnalysisID(const PassInfo *AnalysisID) const {
- return Resolver->getAnalysisToUpdate(AnalysisID, true) != 0;
+ return Resolver->getAnalysisIfAvailable(AnalysisID, true) != 0;
}
// dumpPassStructure - Implement the -debug-passes=Structure option
if (!VerifyDomInfo || !P.getResolver())
return;
- DominatorTree *DT = P.getAnalysisToUpdate<DominatorTree>();
+ DominatorTree *DT = P.getAnalysisIfAvailable<DominatorTree>();
if (!DT)
return;
assert (0 && "Invalid dominator info");
}
- DominanceFrontier *DF = P.getAnalysisToUpdate<DominanceFrontier>();
+ DominanceFrontier *DF = P.getAnalysisIfAvailable<DominanceFrontier>();
if (!DF)
return;
//===----------------------------------------------------------------------===//
// NOTE: Is this the right place to define this method ?
-// getAnalysisToUpdate - Return an analysis result or null if it doesn't exist
-Pass *AnalysisResolver::getAnalysisToUpdate(AnalysisID ID, bool dir) const {
+// getAnalysisIfAvailable - Return analysis result or null if it doesn't exist.
+Pass *AnalysisResolver::getAnalysisIfAvailable(AnalysisID ID, bool dir) const {
return PM.findAnalysisPass(ID, dir);
}