github.com/johnnyeven/libtools@v0.0.0-20191126065708-61829c1adf46/third_party/mlir/lib/Pass/PassRegistry.cpp (about) 1 //===- PassRegistry.cpp - Pass Registration Utilities ---------------------===// 2 // 3 // Copyright 2019 The MLIR Authors. 4 // 5 // Licensed under the Apache License, Version 2.0 (the "License"); 6 // you may not use this file except in compliance with the License. 7 // You may obtain a copy of the License at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, software 12 // distributed under the License is distributed on an "AS IS" BASIS, 13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 // See the License for the specific language governing permissions and 15 // limitations under the License. 16 // ============================================================================= 17 18 #include "mlir/Pass/PassRegistry.h" 19 #include "mlir/Pass/Pass.h" 20 #include "mlir/Pass/PassManager.h" 21 #include "llvm/ADT/DenseMap.h" 22 #include "llvm/Support/ManagedStatic.h" 23 24 using namespace mlir; 25 26 /// Static mapping of all of the registered passes. 27 static llvm::ManagedStatic<llvm::DenseMap<const PassID *, PassInfo>> 28 passRegistry; 29 30 /// Static mapping of all of the registered pass pipelines. 31 static llvm::ManagedStatic<llvm::StringMap<PassPipelineInfo>> 32 passPipelineRegistry; 33 34 /// Utility to create a default registry function from a pass instance. 35 static PassRegistryFunction 36 buildDefaultRegistryFn(PassAllocatorFunction allocator) { 37 return [=](PassManager &pm) { pm.addPass(allocator()); }; 38 } 39 40 //===----------------------------------------------------------------------===// 41 // PassPipelineInfo 42 //===----------------------------------------------------------------------===// 43 44 /// Constructor that accepts a pass allocator function instead of the standard 45 /// registry function. This is useful for registering specializations of 46 /// existing passes. 47 PassPipelineRegistration::PassPipelineRegistration( 48 StringRef arg, StringRef description, PassAllocatorFunction allocator) { 49 registerPassPipeline(arg, description, buildDefaultRegistryFn(allocator)); 50 } 51 52 void mlir::registerPassPipeline(StringRef arg, StringRef description, 53 const PassRegistryFunction &function) { 54 PassPipelineInfo pipelineInfo(arg, description, function); 55 bool inserted = passPipelineRegistry->try_emplace(arg, pipelineInfo).second; 56 assert(inserted && "Pass pipeline registered multiple times"); 57 (void)inserted; 58 } 59 60 //===----------------------------------------------------------------------===// 61 // PassInfo 62 //===----------------------------------------------------------------------===// 63 64 PassInfo::PassInfo(StringRef arg, StringRef description, const PassID *passID, 65 PassAllocatorFunction allocator) 66 : PassRegistryEntry(arg, description, buildDefaultRegistryFn(allocator)) {} 67 68 void mlir::registerPass(StringRef arg, StringRef description, 69 const PassID *passID, 70 const PassAllocatorFunction &function) { 71 PassInfo passInfo(arg, description, passID, function); 72 bool inserted = passRegistry->try_emplace(passID, passInfo).second; 73 assert(inserted && "Pass registered multiple times"); 74 (void)inserted; 75 } 76 77 /// Returns the pass info for the specified pass class or null if unknown. 78 const PassInfo *mlir::Pass::lookupPassInfo(const PassID *passID) { 79 auto it = passRegistry->find(passID); 80 if (it == passRegistry->end()) 81 return nullptr; 82 return &it->getSecond(); 83 } 84 85 //===----------------------------------------------------------------------===// 86 // PassNameParser 87 //===----------------------------------------------------------------------===// 88 89 PassNameParser::PassNameParser(llvm::cl::Option &opt) 90 : llvm::cl::parser<const PassRegistryEntry *>(opt) {} 91 92 void PassNameParser::initialize() { 93 llvm::cl::parser<const PassRegistryEntry *>::initialize(); 94 95 /// Add the pass entries. 96 for (const auto &kv : *passRegistry) { 97 addLiteralOption(kv.second.getPassArgument(), &kv.second, 98 kv.second.getPassDescription()); 99 } 100 /// Add the pass pipeline entries. 101 for (const auto &kv : *passPipelineRegistry) { 102 addLiteralOption(kv.second.getPassArgument(), &kv.second, 103 kv.second.getPassDescription()); 104 } 105 } 106 107 void PassNameParser::printOptionInfo(const llvm::cl::Option &O, 108 size_t GlobalWidth) const { 109 PassNameParser *TP = const_cast<PassNameParser *>(this); 110 llvm::array_pod_sort(TP->Values.begin(), TP->Values.end(), 111 [](const PassNameParser::OptionInfo *VT1, 112 const PassNameParser::OptionInfo *VT2) { 113 return VT1->Name.compare(VT2->Name); 114 }); 115 using llvm::cl::parser; 116 parser<const PassRegistryEntry *>::printOptionInfo(O, GlobalWidth); 117 }