//=========-- StandardPasses.cpp - Standard pass lists -----*- C++ -*-=======// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file defines utility functions for creating a "standard" set of // optimization passes, so that compilers and tools which use optimization // passes use the same set of standard passes. // //===----------------------------------------------------------------------===// #include "llvm/PassManager.h" #include "llvm/Analysis/Passes.h" #include "llvm/Analysis/Verifier.h" #include "llvm/Analysis/Verifier.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/Mutex.h" #include "llvm/Support/DynamicLibrary.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/IPO.h" using namespace llvm::DefaultStandardPasses; using namespace llvm; namespace { /// Entry in the standard passes list. struct StandardPassEntry { /// Function called to create the pass PassInfo::NormalCtor_t createPass; /// Unique identifier for this pass unsigned char *passID; /// Flags specifying when this pass should be run unsigned flags; StandardPassEntry(PassInfo::NormalCtor_t constructor, unsigned char *ID, unsigned f) : createPass(constructor), passID(ID), flags(f) {}; }; /// Standard alias analysis passes static llvm::SmallVector AAPasses; /// Standard function passes static llvm::SmallVector FunctionPasses; /// Standard module passes static llvm::SmallVector ModulePasses; /// Standard link-time optimization passes static llvm::SmallVector LTOPasses; /// Entry in the unresolved standard pass list. IF a pass is inserted in front /// of a pass that is not yet registered in the standard pass list then it is /// stored in a separate list and resolved later. struct UnresolvedStandardPass : public StandardPassEntry { /// The set into which this is stored StandardPass::StandardSet set; /// The unique ID of the pass that should follow this one in the sequence unsigned char *next; UnresolvedStandardPass(PassInfo::NormalCtor_t constructor, unsigned char *newPass, unsigned char *oldPass, StandardPass::StandardSet s, unsigned f) : StandardPassEntry(constructor, newPass, f), set(s), next(oldPass) {} }; /// The passes that can not be inserted into the correct lists yet because of /// their place in the sequence. static llvm::SmallVector UnresolvedPasses; /// Returns a reference to the pass list for the corresponding set of /// optimisations. llvm::SmallVectorImpl& PassList(StandardPass::StandardSet set) { switch (set) { case StandardPass::AliasAnalysis: return AAPasses; case StandardPass::Function: return FunctionPasses; case StandardPass::Module: return ModulePasses; case StandardPass::LTO: return LTOPasses; } // We could use a map of standard pass lists to allow definition of new // default sets llvm_unreachable("Invalid standard optimization set requested"); } static ManagedStatic > Lock; /// Registers the default set of standard passes. This is called lazily when /// an attempt is made to read or modify the standard pass list void RegisterDefaultStandardPasses(void(*doRegister)(void)) { // Only initialize the standard passes once static bool initialized = false; if (initialized) return; llvm::sys::SmartScopedLock Guard(*Lock); if (initialized) return; if (doRegister) { // We must set initialized to true before calling this function, because // the doRegister() function will probably call RegisterDefaultPasses(), // which will call this function, and we'd end up with infinite recursion // and breakage if we didn't. initialized = true; doRegister(); } } } // Anonymous namespace void (*StandardPass::RegisterDefaultPasses)(void); void StandardPass::RegisterDefaultPass(PassInfo::NormalCtor_t constructor, unsigned char *newPass, unsigned char *oldPass, StandardPass::StandardSet set, unsigned flags) { // Make sure that the standard sets are already regstered RegisterDefaultStandardPasses(RegisterDefaultPasses); // Get the correct list to modify llvm::SmallVectorImpl &passList = PassList(set); // If there is no old pass specified, then we are adding a new final pass, so // just push it onto the end. if (!oldPass) { StandardPassEntry pass(constructor, newPass, flags); passList.push_back(pass); return; } // Find the correct place to insert the pass. This is a linear search, but // this shouldn't be too slow since the SmallVector will store the values in // a contiguous block of memory. Each entry is just three words of memory, so // in most cases we are only going to be looking in one or two cache lines. // The extra memory accesses from a more complex search structure would // offset any performance gain (unless someone decides to for (SmallVectorImpl::iterator i = passList.begin(), e=passList.end(); i != e; ++i) { if (i->passID == oldPass) { StandardPassEntry pass(constructor, newPass, flags); passList.insert(i, pass); // If we've added a new pass, then there may have gained the ability to // insert one of the previously unresolved ones. If so, insert the new // one. for (SmallVectorImpl::iterator u = UnresolvedPasses.begin(), eu = UnresolvedPasses.end(); u!=eu; ++u){ if (u->next == newPass && u->set == set) { UnresolvedStandardPass p = *u; UnresolvedPasses.erase(u); RegisterDefaultPass(p.createPass, p.passID, p.next, p.set, p.flags); } } return; } } // If we get to here, then we didn't find the correct place to insert the new // pass UnresolvedStandardPass pass(constructor, newPass, oldPass, set, flags); UnresolvedPasses.push_back(pass); } void StandardPass::AddPassesFromSet(PassManagerBase *PM, StandardSet set, unsigned flags, bool VerifyEach, Pass *inliner) { RegisterDefaultStandardPasses(RegisterDefaultPasses); unsigned level = OptimizationLevel(flags); flags = RequiredFlags(flags); llvm::SmallVectorImpl& passList = PassList(set); // Add all of the passes from this set for (SmallVectorImpl::iterator i = passList.begin(), e=passList.end(); i != e ; ++i) { // Skip passes that don't have conditions that match the ones specified // here. For a pass to match: // - Its minimum optimisation level must be less than or equal to the // specified level. // - Its maximum optimisation level must be greater than or equal to the // specified level // - All of its required flags must be set // - None of its disallowed flags may be set if ((level >= OptimizationLevel(i->flags)) && ((level <= MaxOptimizationLevel(i->flags)) || MaxOptimizationLevel(i->flags) == 0) && ((RequiredFlags(i->flags) & flags) == RequiredFlags(i->flags)) && ((DisallowedFlags(i->flags) & flags) == 0)) { // This is quite an ugly way of allowing us to specify an inliner pass to // insert. Ideally, we'd replace this with a general mechanism allowing // callers to replace arbitrary passes in the list. Pass *p = inliner; if ((&InlinerPlaceholderID != i->passID) && i->createPass) p = i->createPass(); if (p) { PM->add(p); if (VerifyEach) PM->add(createVerifierPass()); } } } } unsigned char DefaultStandardPasses::AggressiveDCEID; unsigned char DefaultStandardPasses::ArgumentPromotionID; unsigned char DefaultStandardPasses::BasicAliasAnalysisID; unsigned char DefaultStandardPasses::CFGSimplificationID; unsigned char DefaultStandardPasses::ConstantMergeID; unsigned char DefaultStandardPasses::CorrelatedValuePropagationID; unsigned char DefaultStandardPasses::DeadArgEliminationID; unsigned char DefaultStandardPasses::DeadStoreEliminationID; unsigned char DefaultStandardPasses::DeadTypeEliminationID; unsigned char DefaultStandardPasses::EarlyCSEID; unsigned char DefaultStandardPasses::FunctionAttrsID; unsigned char DefaultStandardPasses::FunctionInliningID; unsigned char DefaultStandardPasses::GVNID; unsigned char DefaultStandardPasses::GlobalDCEID; unsigned char DefaultStandardPasses::GlobalOptimizerID; unsigned char DefaultStandardPasses::GlobalsModRefID; unsigned char DefaultStandardPasses::IPSCCPID; unsigned char DefaultStandardPasses::IndVarSimplifyID; unsigned char DefaultStandardPasses::InlinerPlaceholderID; unsigned char DefaultStandardPasses::InstructionCombiningID; unsigned char DefaultStandardPasses::JumpThreadingID; unsigned char DefaultStandardPasses::LICMID; unsigned char DefaultStandardPasses::LoopDeletionID; unsigned char DefaultStandardPasses::LoopIdiomID; unsigned char DefaultStandardPasses::LoopRotateID; unsigned char DefaultStandardPasses::LoopUnrollID; unsigned char DefaultStandardPasses::LoopUnswitchID; unsigned char DefaultStandardPasses::MemCpyOptID; unsigned char DefaultStandardPasses::PruneEHID; unsigned char DefaultStandardPasses::ReassociateID; unsigned char DefaultStandardPasses::SCCPID; unsigned char DefaultStandardPasses::ScalarReplAggregatesID; unsigned char DefaultStandardPasses::SimplifyLibCallsID; unsigned char DefaultStandardPasses::StripDeadPrototypesID; unsigned char DefaultStandardPasses::TailCallEliminationID; unsigned char DefaultStandardPasses::TypeBasedAliasAnalysisID;