X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FPassManagerT.h;h=95e0f563c947bc3ca2c79a17dd06c0a5f65741ad;hb=e59eaf407a675845e278c2769e3dbed9f1daae8c;hp=315d9d67e4d8a9a9aaa03d5aa1216b9abc66f7ff;hpb=a3183be835b09ad0a5bb94fbac6756ff4ba956ed;p=oota-llvm.git diff --git a/lib/VMCore/PassManagerT.h b/lib/VMCore/PassManagerT.h index 315d9d67e4d..95e0f563c94 100644 --- a/lib/VMCore/PassManagerT.h +++ b/lib/VMCore/PassManagerT.h @@ -1,4 +1,11 @@ -//===- PassManagerT.h - Container for Passes ---------------------*- C++ -*--=// +//===- PassManagerT.h - Container for Passes --------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file was developed by the LLVM research group and is distributed under +// the University of Illinois Open Source License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// // // This file defines the PassManagerT class. This class is used to hold, // maintain, and optimize execution of Pass's. The PassManager class ensures @@ -16,12 +23,13 @@ #define LLVM_PASSMANAGER_T_H #include "llvm/Pass.h" -#include "Support/CommandLine.h" -#include "Support/LeakDetector.h" -#include "Support/Timer.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/LeakDetector.h" +#include "llvm/Support/Timer.h" #include #include -class Annotable; + +namespace llvm { //===----------------------------------------------------------------------===// // Pass debugging information. Often it is useful to find out what pass is @@ -44,7 +52,7 @@ PassDebugging("debug-pass", cl::Hidden, clEnumVal(Structure , "print pass structure before run()"), clEnumVal(Executions, "print pass name before it is executed"), clEnumVal(Details , "print pass details when it is executed"), - 0)); + clEnumValEnd)); //===----------------------------------------------------------------------===// // PMDebug class - a set of debugging functions, that are not to be @@ -65,7 +73,9 @@ struct PMDebug { } static void PrintArgumentInformation(const Pass *P); - static void PrintPassInformation(unsigned,const char*,Pass *, Annotable *); + static void PrintPassInformation(unsigned,const char*,Pass *, Module *); + static void PrintPassInformation(unsigned,const char*,Pass *, Function *); + static void PrintPassInformation(unsigned,const char*,Pass *, BasicBlock *); static void PrintAnalysisSetInfo(unsigned,const char*,Pass *P, const std::vector &); }; @@ -84,11 +94,6 @@ class TimingInfo { // Private ctor, must use 'create' member TimingInfo() : TG("... Pass execution timing report ...") {} public: - // Create method. If Timing is enabled, this creates and returns a new timing - // object, otherwise it returns null. - // - static TimingInfo *create(); - // TimingDtor - Print out information about timing information ~TimingInfo() { // Delete all of the timers... @@ -96,6 +101,11 @@ public: // TimerGroup is deleted next, printing the report. } + // createTheTimeInfo - This method either initializes the TheTimeInfo pointer + // to a non null value (if the -time-passes option is enabled) or it leaves it + // null. It may be called multiple times. + static void createTheTimeInfo(); + void passStarted(Pass *P) { if (dynamic_cast(P)) return; std::map::iterator I = TimingData.find(P); @@ -111,6 +121,8 @@ public: } }; +static TimingInfo *TheTimeInfo; + //===----------------------------------------------------------------------===// // Declare the PassManagerTraits which will be specialized... // @@ -130,9 +142,14 @@ class PassManagerT : public PassManagerTraits,public AnalysisResolver{ typedef typename Traits::BatcherClass BatcherClass; typedef typename Traits::ParentClass ParentClass; - friend typename Traits::PassClass; - friend typename Traits::SubPassClass; - friend class Traits; +#ifndef _MSC_VER + friend class PassManagerTraits::PassClass; + friend class PassManagerTraits::SubPassClass; +#else + friend PassClass; + friend SubPassClass; +#endif + friend class PassManagerTraits; friend class ImmutablePass; std::vector Passes; // List of passes to run @@ -176,6 +193,8 @@ public: closeBatcher(); CurrentAnalyses.clear(); + TimingInfo::createTheTimeInfo(); + // Add any immutable passes to the CurrentAnalyses set... for (unsigned i = 0, e = ImmutablePasses.size(); i != e; ++i) { ImmutablePass *IPass = ImmutablePasses[i]; @@ -194,7 +213,6 @@ public: E = LastUseOf.end(); I != E; ++I) LastUserOf[I->second].push_back(I->first); - // Output debug information... if (Parent == 0) PMDebug::PerformPassStartupStuff(this); @@ -202,8 +220,7 @@ public: for (unsigned i = 0, e = Passes.size(); i < e; ++i) { PassClass *P = Passes[i]; - PMDebug::PrintPassInformation(getDepth(), "Executing Pass", P, - (Annotable*)M); + PMDebug::PrintPassInformation(getDepth(), "Executing Pass", P, M); // Get information about what analyses the pass uses... AnalysisUsage AnUsage; @@ -235,9 +252,9 @@ public: } // Run the sub pass! - startPass(P); + if (TheTimeInfo) TheTimeInfo->passStarted(P); bool Changed = runPass(P, M); - endPass(P); + if (TheTimeInfo) TheTimeInfo->passEnded(P); MadeChanges |= Changed; // Check for memory leaks by the pass... @@ -245,8 +262,7 @@ public: P->getPassName() + "'"); if (Changed) - PMDebug::PrintPassInformation(getDepth()+1, "Made Modification", P, - (Annotable*)M); + PMDebug::PrintPassInformation(getDepth()+1, "Made Modification", P, M); PMDebug::PrintAnalysisSetInfo(getDepth(), "Preserved", P, AnUsage.getPreservedSet()); @@ -287,8 +303,7 @@ public: std::vector &DeadPass = LastUserOf[P]; for (std::vector::iterator I = DeadPass.begin(),E = DeadPass.end(); I != E; ++I) { - PMDebug::PrintPassInformation(getDepth()+1, "Freeing Pass", *I, - (Annotable*)M); + PMDebug::PrintPassInformation(getDepth()+1, "Freeing Pass", *I, M); (*I)->releaseMemory(); } @@ -305,6 +320,7 @@ public: } } } + return MadeChanges; } @@ -332,12 +348,32 @@ public: } } + Pass *getImmutablePassOrNull(const PassInfo *ID) const { + for (unsigned i = 0, e = ImmutablePasses.size(); i != e; ++i) { + const PassInfo *IPID = ImmutablePasses[i]->getPassInfo(); + if (IPID == ID) + return ImmutablePasses[i]; + + // This pass is the current implementation of all of the interfaces it + // implements as well. + // + const std::vector &II = + IPID->getInterfacesImplemented(); + for (unsigned j = 0, e = II.size(); j != e; ++j) + if (II[j] == ID) return ImmutablePasses[i]; + } + return 0; + } + Pass *getAnalysisOrNullDown(const PassInfo *ID) const { std::map::const_iterator I = CurrentAnalyses.find(ID); if (I != CurrentAnalyses.end()) return I->second; // Found it. + if (Pass *P = getImmutablePassOrNull(ID)) + return P; + if (Batcher) return ((AnalysisResolver*)Batcher)->getAnalysisOrNullDown(ID); return 0; @@ -350,23 +386,11 @@ public: if (Parent) // Try scanning... return Parent->getAnalysisOrNullUp(ID); + else if (!ImmutablePasses.empty()) + return getImmutablePassOrNull(ID); return 0; } - // {start/end}Pass - Called when a pass is started, it just propagates - // information up to the top level PassManagerT object to tell it that a pass - // has started or ended. This is used to gather timing information about - // passes. - // - void startPass(Pass *P) { - if (Parent) Parent->startPass(P); - else PassStarted(P); - } - void endPass(Pass *P) { - if (Parent) Parent->endPass(P); - else PassEnded(P); - } - // markPassUsed - Inform higher level pass managers (and ourselves) // that these analyses are being used by this pass. This is used to // make sure that analyses are not free'd before we have to use @@ -377,6 +401,16 @@ public: if (I != CurrentAnalyses.end()) { LastUseOf[I->second] = User; // Local pass, extend the lifetime + + // Prolong live range of analyses that are needed after an analysis pass + // is destroyed, for querying by subsequent passes + AnalysisUsage AnUsage; + I->second->getAnalysisUsage(AnUsage); + const std::vector &IDs = AnUsage.getRequiredTransitiveSet(); + for (std::vector::const_iterator i = IDs.begin(), + e = IDs.end(); i != e; ++i) + markPassUsed(*i, User); + } else { // Pass not in current available set, must be a higher level pass // available to us, propagate to parent pass manager... We tell the @@ -386,7 +420,9 @@ public: if (Parent) { Parent->markPassUsed(P, this); } else { - assert(0 && "Pass available but not found! " + assert(getAnalysisOrNullUp(P) && + dynamic_cast(getAnalysisOrNullUp(P)) && + "Pass available but not found! " "Perhaps this is a module pass requiring a function pass?"); } } @@ -418,8 +454,12 @@ public: // Loop over all of the analyses used by this pass, for (std::vector::const_iterator I = Required.begin(), E = Required.end(); I != E; ++I) { - if (getAnalysisOrNullDown(*I) == 0) - add((PassClass*)(*I)->createPass()); + if (getAnalysisOrNullDown(*I) == 0) { + Pass *AP = (*I)->createPass(); + if (ImmutablePass *IP = dynamic_cast (AP)) { add(IP); } + else if (PassClass *RP = dynamic_cast (AP)) { add(RP); } + else { assert (0 && "Wrong kind of pass for this PassManager"); } + } } // Tell the pass to add itself to this PassManager... the way it does so @@ -429,8 +469,31 @@ public: P->addToPassManager(this, AnUsage); } -private: + // add - H4x0r an ImmutablePass into a PassManager that might not be + // expecting one. + // + void add(ImmutablePass *P) { + // Get information about what analyses the pass uses... + AnalysisUsage AnUsage; + P->getAnalysisUsage(AnUsage); + const std::vector &Required = AnUsage.getRequiredSet(); + + // Loop over all of the analyses used by this pass, + for (std::vector::const_iterator I = Required.begin(), + E = Required.end(); I != E; ++I) { + if (getAnalysisOrNullDown(*I) == 0) { + Pass *AP = (*I)->createPass(); + if (ImmutablePass *IP = dynamic_cast (AP)) add(IP); + else if (PassClass *RP = dynamic_cast (AP)) add(RP); + else assert (0 && "Wrong kind of pass for this PassManager"); + } + } + + // Add the ImmutablePass to this PassManager. + addPass(P, AnUsage); + } +private: // addPass - These functions are used to implement the subclass specific // behaviors present in PassManager. Basically the add(Pass*) method ends up // reflecting its behavior into a Pass::addToPassManager call. Subclasses of @@ -530,18 +593,32 @@ public: // setAnalysisResolver(IP, this); ImmutablePasses.push_back(IP); - - // Add this pass to the currently available set... - if (const PassInfo *PI = IP->getPassInfo()) { - CurrentAnalyses[PI] = IP; - // This pass is the current implementation of all of the interfaces it - // implements as well. - // - const std::vector &II = PI->getInterfacesImplemented(); - for (unsigned i = 0, e = II.size(); i != e; ++i) - CurrentAnalyses[II[i]] = IP; + // All Required analyses should be available to the pass as it initializes! + // Here we fill in the AnalysisImpls member of the pass so that it can + // successfully use the getAnalysis() method to retrieve the implementations + // it needs. + // + IP->AnalysisImpls.clear(); + IP->AnalysisImpls.reserve(AU.getRequiredSet().size()); + for (std::vector::const_iterator + I = AU.getRequiredSet().begin(), + E = AU.getRequiredSet().end(); I != E; ++I) { + Pass *Impl = getAnalysisOrNullUp(*I); + if (Impl == 0) { + std::cerr << "Analysis '" << (*I)->getPassName() + << "' used but not available!"; + assert(0 && "Analysis used but not available!"); + } else if (PassDebugging == Details) { + if ((*I)->getPassName() != std::string(Impl->getPassName())) + std::cerr << " Interface '" << (*I)->getPassName() + << "' implemented by '" << Impl->getPassName() << "'\n"; + } + IP->AnalysisImpls.push_back(std::make_pair(*I, Impl)); } + + // Initialize the immutable pass... + IP->initializePass(); } }; @@ -581,10 +658,6 @@ template<> struct PassManagerTraits : public BasicBlockPass { return P->runOnBasicBlock(*M); } - // Dummy implementation of PassStarted/PassEnded - static void PassStarted(Pass *P) {} - static void PassEnded(Pass *P) {} - // getPMName() - Return the name of the unit the PassManager operates on for // debugging. const char *getPMName() const { return "BasicBlock"; } @@ -631,10 +704,6 @@ template<> struct PassManagerTraits : public FunctionPass { return P->runOnFunction(*F); } - // Dummy implementation of PassStarted/PassEnded - static void PassStarted(Pass *P) {} - static void PassEnded(Pass *P) {} - // getPMName() - Return the name of the unit the PassManager operates on for // debugging. const char *getPMName() const { return "Function"; } @@ -678,37 +747,10 @@ template<> struct PassManagerTraits : public Pass { const char *getPMName() const { return "Module"; } virtual const char *getPassName() const { return "Module Pass Manager"; } - // TimingInformation - This data member maintains timing information for each - // of the passes that is executed. - // - TimingInfo *TimeInfo; - - // PassStarted/Ended - This callback is notified any time a pass is started - // or stops. This is used to collect timing information about the different - // passes being executed. - // - void PassStarted(Pass *P) { - if (TimeInfo) TimeInfo->passStarted(P); - } - void PassEnded(Pass *P) { - if (TimeInfo) TimeInfo->passEnded(P); - } - // run - Implement the PassManager interface... bool run(Module &M) { - TimeInfo = TimingInfo::create(); - bool Result = ((PassManagerT*)this)->runOnUnit(&M); - if (TimeInfo) { - delete TimeInfo; - TimeInfo = 0; - } - return Result; + return ((PassManagerT*)this)->runOnUnit(&M); } - - // PassManagerTraits constructor - Create a timing info object if the user - // specified timing info should be collected on the command line. - // - PassManagerTraits() : TimeInfo(0) {} }; @@ -772,4 +814,6 @@ inline bool PassManagerTraits::doFinalization(Module &M) { return Changed; } +} // End llvm namespace + #endif