xref: /freebsd-src/contrib/llvm-project/llvm/lib/IR/Pass.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
10b57cec5SDimitry Andric //===- Pass.cpp - LLVM Pass Infrastructure Implementation -----------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements the LLVM Pass infrastructure.  It is primarily
100b57cec5SDimitry Andric // responsible with ensuring that passes are executed and batched together
110b57cec5SDimitry Andric // optimally.
120b57cec5SDimitry Andric //
130b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
140b57cec5SDimitry Andric 
150b57cec5SDimitry Andric #include "llvm/Pass.h"
160b57cec5SDimitry Andric #include "llvm/Config/llvm-config.h"
170b57cec5SDimitry Andric #include "llvm/IR/Function.h"
180b57cec5SDimitry Andric #include "llvm/IR/IRPrintingPasses.h"
190b57cec5SDimitry Andric #include "llvm/IR/LLVMContext.h"
200b57cec5SDimitry Andric #include "llvm/IR/LegacyPassNameParser.h"
210b57cec5SDimitry Andric #include "llvm/IR/Module.h"
220b57cec5SDimitry Andric #include "llvm/IR/OptBisect.h"
230b57cec5SDimitry Andric #include "llvm/PassInfo.h"
240b57cec5SDimitry Andric #include "llvm/PassRegistry.h"
250b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
260b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
270b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
280b57cec5SDimitry Andric #include <cassert>
290b57cec5SDimitry Andric 
3081ad6265SDimitry Andric #ifdef EXPENSIVE_CHECKS
3181ad6265SDimitry Andric #include "llvm/IR/StructuralHash.h"
3281ad6265SDimitry Andric #endif
3381ad6265SDimitry Andric 
340b57cec5SDimitry Andric using namespace llvm;
350b57cec5SDimitry Andric 
360b57cec5SDimitry Andric #define DEBUG_TYPE "ir"
370b57cec5SDimitry Andric 
380b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
390b57cec5SDimitry Andric // Pass Implementation
400b57cec5SDimitry Andric //
410b57cec5SDimitry Andric 
420b57cec5SDimitry Andric // Force out-of-line virtual method.
~Pass()430b57cec5SDimitry Andric Pass::~Pass() {
440b57cec5SDimitry Andric   delete Resolver;
450b57cec5SDimitry Andric }
460b57cec5SDimitry Andric 
470b57cec5SDimitry Andric // Force out-of-line virtual method.
480b57cec5SDimitry Andric ModulePass::~ModulePass() = default;
490b57cec5SDimitry Andric 
createPrinterPass(raw_ostream & OS,const std::string & Banner) const500b57cec5SDimitry Andric Pass *ModulePass::createPrinterPass(raw_ostream &OS,
510b57cec5SDimitry Andric                                     const std::string &Banner) const {
520b57cec5SDimitry Andric   return createPrintModulePass(OS, Banner);
530b57cec5SDimitry Andric }
540b57cec5SDimitry Andric 
getPotentialPassManagerType() const550b57cec5SDimitry Andric PassManagerType ModulePass::getPotentialPassManagerType() const {
560b57cec5SDimitry Andric   return PMT_ModulePassManager;
570b57cec5SDimitry Andric }
580b57cec5SDimitry Andric 
getDescription(const Module & M)590b57cec5SDimitry Andric static std::string getDescription(const Module &M) {
600b57cec5SDimitry Andric   return "module (" + M.getName().str() + ")";
610b57cec5SDimitry Andric }
620b57cec5SDimitry Andric 
skipModule(Module & M) const630b57cec5SDimitry Andric bool ModulePass::skipModule(Module &M) const {
640b57cec5SDimitry Andric   OptPassGate &Gate = M.getContext().getOptPassGate();
65bdd1243dSDimitry Andric   return Gate.isEnabled() &&
66bdd1243dSDimitry Andric          !Gate.shouldRunPass(this->getPassName(), getDescription(M));
670b57cec5SDimitry Andric }
680b57cec5SDimitry Andric 
mustPreserveAnalysisID(char & AID) const690b57cec5SDimitry Andric bool Pass::mustPreserveAnalysisID(char &AID) const {
70e8d8bef9SDimitry Andric   return Resolver->getAnalysisIfAvailable(&AID) != nullptr;
710b57cec5SDimitry Andric }
720b57cec5SDimitry Andric 
730b57cec5SDimitry Andric // dumpPassStructure - Implement the -debug-pass=Structure option
dumpPassStructure(unsigned Offset)740b57cec5SDimitry Andric void Pass::dumpPassStructure(unsigned Offset) {
750b57cec5SDimitry Andric   dbgs().indent(Offset*2) << getPassName() << "\n";
760b57cec5SDimitry Andric }
770b57cec5SDimitry Andric 
780b57cec5SDimitry Andric /// getPassName - Return a nice clean name for a pass.  This usually
790b57cec5SDimitry Andric /// implemented in terms of the name that is registered by one of the
800b57cec5SDimitry Andric /// Registration templates, but can be overloaded directly.
getPassName() const810b57cec5SDimitry Andric StringRef Pass::getPassName() const {
820b57cec5SDimitry Andric   AnalysisID AID =  getPassID();
830b57cec5SDimitry Andric   const PassInfo *PI = PassRegistry::getPassRegistry()->getPassInfo(AID);
840b57cec5SDimitry Andric   if (PI)
850b57cec5SDimitry Andric     return PI->getPassName();
860b57cec5SDimitry Andric   return "Unnamed pass: implement Pass::getPassName()";
870b57cec5SDimitry Andric }
880b57cec5SDimitry Andric 
preparePassManager(PMStack &)890b57cec5SDimitry Andric void Pass::preparePassManager(PMStack &) {
900b57cec5SDimitry Andric   // By default, don't do anything.
910b57cec5SDimitry Andric }
920b57cec5SDimitry Andric 
getPotentialPassManagerType() const930b57cec5SDimitry Andric PassManagerType Pass::getPotentialPassManagerType() const {
940b57cec5SDimitry Andric   // Default implementation.
950b57cec5SDimitry Andric   return PMT_Unknown;
960b57cec5SDimitry Andric }
970b57cec5SDimitry Andric 
getAnalysisUsage(AnalysisUsage &) const980b57cec5SDimitry Andric void Pass::getAnalysisUsage(AnalysisUsage &) const {
990b57cec5SDimitry Andric   // By default, no analysis results are used, all are invalidated.
1000b57cec5SDimitry Andric }
1010b57cec5SDimitry Andric 
releaseMemory()1020b57cec5SDimitry Andric void Pass::releaseMemory() {
1030b57cec5SDimitry Andric   // By default, don't do anything.
1040b57cec5SDimitry Andric }
1050b57cec5SDimitry Andric 
verifyAnalysis() const1060b57cec5SDimitry Andric void Pass::verifyAnalysis() const {
1070b57cec5SDimitry Andric   // By default, don't do anything.
1080b57cec5SDimitry Andric }
1090b57cec5SDimitry Andric 
getAdjustedAnalysisPointer(AnalysisID AID)1100b57cec5SDimitry Andric void *Pass::getAdjustedAnalysisPointer(AnalysisID AID) {
1110b57cec5SDimitry Andric   return this;
1120b57cec5SDimitry Andric }
1130b57cec5SDimitry Andric 
getAsImmutablePass()1140b57cec5SDimitry Andric ImmutablePass *Pass::getAsImmutablePass() {
1150b57cec5SDimitry Andric   return nullptr;
1160b57cec5SDimitry Andric }
1170b57cec5SDimitry Andric 
getAsPMDataManager()1180b57cec5SDimitry Andric PMDataManager *Pass::getAsPMDataManager() {
1190b57cec5SDimitry Andric   return nullptr;
1200b57cec5SDimitry Andric }
1210b57cec5SDimitry Andric 
setResolver(AnalysisResolver * AR)1220b57cec5SDimitry Andric void Pass::setResolver(AnalysisResolver *AR) {
1230b57cec5SDimitry Andric   assert(!Resolver && "Resolver is already set");
1240b57cec5SDimitry Andric   Resolver = AR;
1250b57cec5SDimitry Andric }
1260b57cec5SDimitry Andric 
1270b57cec5SDimitry Andric // print - Print out the internal state of the pass.  This is called by Analyze
1280b57cec5SDimitry Andric // to print out the contents of an analysis.  Otherwise it is not necessary to
1290b57cec5SDimitry Andric // implement this method.
print(raw_ostream & OS,const Module *) const1300b57cec5SDimitry Andric void Pass::print(raw_ostream &OS, const Module *) const {
1310b57cec5SDimitry Andric   OS << "Pass::print not implemented for pass: '" << getPassName() << "'!\n";
1320b57cec5SDimitry Andric }
1330b57cec5SDimitry Andric 
1340b57cec5SDimitry Andric #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1350b57cec5SDimitry Andric // dump - call print(cerr);
dump() const1360b57cec5SDimitry Andric LLVM_DUMP_METHOD void Pass::dump() const {
1370b57cec5SDimitry Andric   print(dbgs(), nullptr);
1380b57cec5SDimitry Andric }
1390b57cec5SDimitry Andric #endif
1400b57cec5SDimitry Andric 
14181ad6265SDimitry Andric #ifdef EXPENSIVE_CHECKS
structuralHash(Module & M) const142*5f757f3fSDimitry Andric uint64_t Pass::structuralHash(Module &M) const {
143*5f757f3fSDimitry Andric   return StructuralHash(M, true);
144*5f757f3fSDimitry Andric }
14581ad6265SDimitry Andric 
structuralHash(Function & F) const146*5f757f3fSDimitry Andric uint64_t Pass::structuralHash(Function &F) const {
147*5f757f3fSDimitry Andric   return StructuralHash(F, true);
148*5f757f3fSDimitry Andric }
14981ad6265SDimitry Andric #endif
15081ad6265SDimitry Andric 
1510b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1520b57cec5SDimitry Andric // ImmutablePass Implementation
1530b57cec5SDimitry Andric //
1540b57cec5SDimitry Andric // Force out-of-line virtual method.
1550b57cec5SDimitry Andric ImmutablePass::~ImmutablePass() = default;
1560b57cec5SDimitry Andric 
initializePass()1570b57cec5SDimitry Andric void ImmutablePass::initializePass() {
1580b57cec5SDimitry Andric   // By default, don't do anything.
1590b57cec5SDimitry Andric }
1600b57cec5SDimitry Andric 
1610b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1620b57cec5SDimitry Andric // FunctionPass Implementation
1630b57cec5SDimitry Andric //
1640b57cec5SDimitry Andric 
createPrinterPass(raw_ostream & OS,const std::string & Banner) const1650b57cec5SDimitry Andric Pass *FunctionPass::createPrinterPass(raw_ostream &OS,
1660b57cec5SDimitry Andric                                       const std::string &Banner) const {
1670b57cec5SDimitry Andric   return createPrintFunctionPass(OS, Banner);
1680b57cec5SDimitry Andric }
1690b57cec5SDimitry Andric 
getPotentialPassManagerType() const1700b57cec5SDimitry Andric PassManagerType FunctionPass::getPotentialPassManagerType() const {
1710b57cec5SDimitry Andric   return PMT_FunctionPassManager;
1720b57cec5SDimitry Andric }
1730b57cec5SDimitry Andric 
getDescription(const Function & F)1740b57cec5SDimitry Andric static std::string getDescription(const Function &F) {
1750b57cec5SDimitry Andric   return "function (" + F.getName().str() + ")";
1760b57cec5SDimitry Andric }
1770b57cec5SDimitry Andric 
skipFunction(const Function & F) const1780b57cec5SDimitry Andric bool FunctionPass::skipFunction(const Function &F) const {
1790b57cec5SDimitry Andric   OptPassGate &Gate = F.getContext().getOptPassGate();
180bdd1243dSDimitry Andric   if (Gate.isEnabled() &&
181bdd1243dSDimitry Andric       !Gate.shouldRunPass(this->getPassName(), getDescription(F)))
1820b57cec5SDimitry Andric     return true;
1830b57cec5SDimitry Andric 
1840b57cec5SDimitry Andric   if (F.hasOptNone()) {
1850b57cec5SDimitry Andric     LLVM_DEBUG(dbgs() << "Skipping pass '" << getPassName() << "' on function "
1860b57cec5SDimitry Andric                       << F.getName() << "\n");
1870b57cec5SDimitry Andric     return true;
1880b57cec5SDimitry Andric   }
1890b57cec5SDimitry Andric   return false;
1900b57cec5SDimitry Andric }
1910b57cec5SDimitry Andric 
lookupPassInfo(const void * TI)1920b57cec5SDimitry Andric const PassInfo *Pass::lookupPassInfo(const void *TI) {
1930b57cec5SDimitry Andric   return PassRegistry::getPassRegistry()->getPassInfo(TI);
1940b57cec5SDimitry Andric }
1950b57cec5SDimitry Andric 
lookupPassInfo(StringRef Arg)1960b57cec5SDimitry Andric const PassInfo *Pass::lookupPassInfo(StringRef Arg) {
1970b57cec5SDimitry Andric   return PassRegistry::getPassRegistry()->getPassInfo(Arg);
1980b57cec5SDimitry Andric }
1990b57cec5SDimitry Andric 
createPass(AnalysisID ID)2000b57cec5SDimitry Andric Pass *Pass::createPass(AnalysisID ID) {
2010b57cec5SDimitry Andric   const PassInfo *PI = PassRegistry::getPassRegistry()->getPassInfo(ID);
2020b57cec5SDimitry Andric   if (!PI)
2030b57cec5SDimitry Andric     return nullptr;
2040b57cec5SDimitry Andric   return PI->createPass();
2050b57cec5SDimitry Andric }
2060b57cec5SDimitry Andric 
2070b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
2080b57cec5SDimitry Andric //                  Analysis Group Implementation Code
2090b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
2100b57cec5SDimitry Andric 
2110b57cec5SDimitry Andric // RegisterAGBase implementation
2120b57cec5SDimitry Andric 
RegisterAGBase(StringRef Name,const void * InterfaceID,const void * PassID,bool isDefault)2130b57cec5SDimitry Andric RegisterAGBase::RegisterAGBase(StringRef Name, const void *InterfaceID,
2140b57cec5SDimitry Andric                                const void *PassID, bool isDefault)
2150b57cec5SDimitry Andric     : PassInfo(Name, InterfaceID) {
2160b57cec5SDimitry Andric   PassRegistry::getPassRegistry()->registerAnalysisGroup(InterfaceID, PassID,
2170b57cec5SDimitry Andric                                                          *this, isDefault);
2180b57cec5SDimitry Andric }
2190b57cec5SDimitry Andric 
2200b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
2210b57cec5SDimitry Andric // PassRegistrationListener implementation
2220b57cec5SDimitry Andric //
2230b57cec5SDimitry Andric 
2240b57cec5SDimitry Andric // enumeratePasses - Iterate over the registered passes, calling the
2250b57cec5SDimitry Andric // passEnumerate callback on each PassInfo object.
enumeratePasses()2260b57cec5SDimitry Andric void PassRegistrationListener::enumeratePasses() {
2270b57cec5SDimitry Andric   PassRegistry::getPassRegistry()->enumerateWith(this);
2280b57cec5SDimitry Andric }
2290b57cec5SDimitry Andric 
PassNameParser(cl::Option & O)2300b57cec5SDimitry Andric PassNameParser::PassNameParser(cl::Option &O)
2310b57cec5SDimitry Andric     : cl::parser<const PassInfo *>(O) {
2320b57cec5SDimitry Andric   PassRegistry::getPassRegistry()->addRegistrationListener(this);
2330b57cec5SDimitry Andric }
2340b57cec5SDimitry Andric 
2350b57cec5SDimitry Andric // This only gets called during static destruction, in which case the
2360b57cec5SDimitry Andric // PassRegistry will have already been destroyed by llvm_shutdown().  So
2370b57cec5SDimitry Andric // attempting to remove the registration listener is an error.
2380b57cec5SDimitry Andric PassNameParser::~PassNameParser() = default;
2390b57cec5SDimitry Andric 
2400b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
2410b57cec5SDimitry Andric //   AnalysisUsage Class Implementation
2420b57cec5SDimitry Andric //
2430b57cec5SDimitry Andric 
2440b57cec5SDimitry Andric namespace {
2450b57cec5SDimitry Andric 
2460b57cec5SDimitry Andric struct GetCFGOnlyPasses : public PassRegistrationListener {
2470b57cec5SDimitry Andric   using VectorType = AnalysisUsage::VectorType;
2480b57cec5SDimitry Andric 
2490b57cec5SDimitry Andric   VectorType &CFGOnlyList;
2500b57cec5SDimitry Andric 
GetCFGOnlyPasses__anonc1982da30111::GetCFGOnlyPasses2510b57cec5SDimitry Andric   GetCFGOnlyPasses(VectorType &L) : CFGOnlyList(L) {}
2520b57cec5SDimitry Andric 
passEnumerate__anonc1982da30111::GetCFGOnlyPasses2530b57cec5SDimitry Andric   void passEnumerate(const PassInfo *P) override {
2540b57cec5SDimitry Andric     if (P->isCFGOnlyPass())
2550b57cec5SDimitry Andric       CFGOnlyList.push_back(P->getTypeInfo());
2560b57cec5SDimitry Andric   }
2570b57cec5SDimitry Andric };
2580b57cec5SDimitry Andric 
2590b57cec5SDimitry Andric } // end anonymous namespace
2600b57cec5SDimitry Andric 
2610b57cec5SDimitry Andric // setPreservesCFG - This function should be called to by the pass, iff they do
2620b57cec5SDimitry Andric // not:
2630b57cec5SDimitry Andric //
2640b57cec5SDimitry Andric //  1. Add or remove basic blocks from the function
2650b57cec5SDimitry Andric //  2. Modify terminator instructions in any way.
2660b57cec5SDimitry Andric //
2670b57cec5SDimitry Andric // This function annotates the AnalysisUsage info object to say that analyses
2680b57cec5SDimitry Andric // that only depend on the CFG are preserved by this pass.
setPreservesCFG()2690b57cec5SDimitry Andric void AnalysisUsage::setPreservesCFG() {
2700b57cec5SDimitry Andric   // Since this transformation doesn't modify the CFG, it preserves all analyses
2710b57cec5SDimitry Andric   // that only depend on the CFG (like dominators, loop info, etc...)
2720b57cec5SDimitry Andric   GetCFGOnlyPasses(Preserved).enumeratePasses();
2730b57cec5SDimitry Andric }
2740b57cec5SDimitry Andric 
addPreserved(StringRef Arg)2750b57cec5SDimitry Andric AnalysisUsage &AnalysisUsage::addPreserved(StringRef Arg) {
2760b57cec5SDimitry Andric   const PassInfo *PI = Pass::lookupPassInfo(Arg);
2770b57cec5SDimitry Andric   // If the pass exists, preserve it. Otherwise silently do nothing.
278e8d8bef9SDimitry Andric   if (PI)
279e8d8bef9SDimitry Andric     pushUnique(Preserved, PI->getTypeInfo());
2800b57cec5SDimitry Andric   return *this;
2810b57cec5SDimitry Andric }
2820b57cec5SDimitry Andric 
addRequiredID(const void * ID)2830b57cec5SDimitry Andric AnalysisUsage &AnalysisUsage::addRequiredID(const void *ID) {
284e8d8bef9SDimitry Andric   pushUnique(Required, ID);
2850b57cec5SDimitry Andric   return *this;
2860b57cec5SDimitry Andric }
2870b57cec5SDimitry Andric 
addRequiredID(char & ID)2880b57cec5SDimitry Andric AnalysisUsage &AnalysisUsage::addRequiredID(char &ID) {
289e8d8bef9SDimitry Andric   pushUnique(Required, &ID);
2900b57cec5SDimitry Andric   return *this;
2910b57cec5SDimitry Andric }
2920b57cec5SDimitry Andric 
addRequiredTransitiveID(char & ID)2930b57cec5SDimitry Andric AnalysisUsage &AnalysisUsage::addRequiredTransitiveID(char &ID) {
294e8d8bef9SDimitry Andric   pushUnique(Required, &ID);
295e8d8bef9SDimitry Andric   pushUnique(RequiredTransitive, &ID);
2960b57cec5SDimitry Andric   return *this;
2970b57cec5SDimitry Andric }
298