From 2118b9d39b91e93c0146611235072cd6ca0f27b1 Mon Sep 17 00:00:00 2001 From: Arthur Eubanks Date: Tue, 20 Dec 2022 12:55:05 -0800 Subject: [PATCH] [llvm-extract] Use new pass manager instead of legacy pass manager Removes some legacy passes specific to llvm-extract --- llvm/include/llvm/InitializePasses.h | 1 - llvm/include/llvm/Transforms/IPO.h | 12 -- llvm/include/llvm/Transforms/IPO/BlockExtractor.h | 11 ++ llvm/include/llvm/Transforms/IPO/ExtractGV.h | 30 ++++ llvm/lib/Passes/PassRegistry.def | 2 +- llvm/lib/Transforms/IPO/BlockExtractor.cpp | 73 ++------- llvm/lib/Transforms/IPO/ExtractGV.cpp | 174 +++++++++------------ llvm/lib/Transforms/IPO/IPO.cpp | 1 - llvm/lib/Transforms/IPO/StripSymbols.cpp | 1 + llvm/tools/llvm-extract/CMakeLists.txt | 1 + llvm/tools/llvm-extract/llvm-extract.cpp | 80 +++++++--- .../gn/secondary/llvm/tools/llvm-extract/BUILD.gn | 1 + 12 files changed, 192 insertions(+), 195 deletions(-) create mode 100644 llvm/include/llvm/Transforms/IPO/ExtractGV.h diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h index b507490..2d6d43d 100644 --- a/llvm/include/llvm/InitializePasses.h +++ b/llvm/include/llvm/InitializePasses.h @@ -67,7 +67,6 @@ void initializeBasicBlockSectionsPass(PassRegistry &); void initializeBDCELegacyPassPass(PassRegistry&); void initializeBarrierNoopPass(PassRegistry&); void initializeBasicAAWrapperPassPass(PassRegistry&); -void initializeBlockExtractorLegacyPassPass(PassRegistry &); void initializeBlockFrequencyInfoWrapperPassPass(PassRegistry&); void initializeBranchFolderPassPass(PassRegistry&); void initializeBranchProbabilityInfoWrapperPassPass(PassRegistry&); diff --git a/llvm/include/llvm/Transforms/IPO.h b/llvm/include/llvm/Transforms/IPO.h index fe1e4d6..9b1a2fb 100644 --- a/llvm/include/llvm/Transforms/IPO.h +++ b/llvm/include/llvm/Transforms/IPO.h @@ -158,18 +158,6 @@ Pass *createLoopExtractorPass(); /// Pass *createSingleLoopExtractorPass(); -/// createBlockExtractorPass - This pass extracts all the specified blocks -/// from the functions in the module. -/// -ModulePass *createBlockExtractorPass(); -ModulePass * -createBlockExtractorPass(const SmallVectorImpl &BlocksToExtract, - bool EraseFunctions); -ModulePass * -createBlockExtractorPass(const SmallVectorImpl> - &GroupsOfBlocksToExtract, - bool EraseFunctions); - /// createStripDeadPrototypesPass - This pass removes any function declarations /// (prototypes) that are not used. ModulePass *createStripDeadPrototypesPass(); diff --git a/llvm/include/llvm/Transforms/IPO/BlockExtractor.h b/llvm/include/llvm/Transforms/IPO/BlockExtractor.h index deeb5eb..6211027 100644 --- a/llvm/include/llvm/Transforms/IPO/BlockExtractor.h +++ b/llvm/include/llvm/Transforms/IPO/BlockExtractor.h @@ -14,11 +14,22 @@ #ifndef LLVM_TRANSFORMS_IPO_BLOCKEXTRACTOR_H #define LLVM_TRANSFORMS_IPO_BLOCKEXTRACTOR_H +#include + +#include "llvm/ADT/SmallVector.h" #include "llvm/IR/PassManager.h" namespace llvm { +class BasicBlock; + struct BlockExtractorPass : PassInfoMixin { + BlockExtractorPass(std::vector> &&GroupsOfBlocks, + bool EraseFunctions); PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM); + +private: + std::vector> GroupsOfBlocks; + bool EraseFunctions; }; } // namespace llvm diff --git a/llvm/include/llvm/Transforms/IPO/ExtractGV.h b/llvm/include/llvm/Transforms/IPO/ExtractGV.h new file mode 100644 index 0000000..45e29ba --- /dev/null +++ b/llvm/include/llvm/Transforms/IPO/ExtractGV.h @@ -0,0 +1,30 @@ +//===-- ExtractGV.h -------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TRANSFORMS_IPO_EXTRACTGV_H +#define LLVM_TRANSFORMS_IPO_EXTRACTGV_H + +#include "llvm/ADT/SetVector.h" +#include "llvm/IR/PassManager.h" + +namespace llvm { + +class ExtractGVPass : public PassInfoMixin { +private: + SetVector Named; + bool deleteStuff; + bool keepConstInit; + +public: + ExtractGVPass(std::vector &GVs, bool deleteS = true, + bool keepConstInit = false); + PreservedAnalyses run(Module &M, ModuleAnalysisManager &); +}; +} // namespace llvm + +#endif // LLVM_TRANSFORMS_IPO_EXTRACTGV_H diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def index ee41084..4aec1b8 100644 --- a/llvm/lib/Passes/PassRegistry.def +++ b/llvm/lib/Passes/PassRegistry.def @@ -56,7 +56,7 @@ MODULE_PASS("deadargelim", DeadArgumentEliminationPass()) MODULE_PASS("debugify", NewPMDebugifyPass()) MODULE_PASS("dot-callgraph", CallGraphDOTPrinterPass()) MODULE_PASS("elim-avail-extern", EliminateAvailableExternallyPass()) -MODULE_PASS("extract-blocks", BlockExtractorPass()) +MODULE_PASS("extract-blocks", BlockExtractorPass({}, false)) MODULE_PASS("forceattrs", ForceFunctionAttrsPass()) MODULE_PASS("function-import", FunctionImportPass()) MODULE_PASS("globaldce", GlobalDCEPass()) diff --git a/llvm/lib/Transforms/IPO/BlockExtractor.cpp b/llvm/lib/Transforms/IPO/BlockExtractor.cpp index dfadfdd..a68cf7d 100644 --- a/llvm/lib/Transforms/IPO/BlockExtractor.cpp +++ b/llvm/lib/Transforms/IPO/BlockExtractor.cpp @@ -45,20 +45,15 @@ class BlockExtractor { public: BlockExtractor(bool EraseFunctions) : EraseFunctions(EraseFunctions) {} bool runOnModule(Module &M); - void init(const SmallVectorImpl> - &GroupsOfBlocksToExtract) { - for (const SmallVectorImpl &GroupOfBlocks : - GroupsOfBlocksToExtract) { - SmallVector NewGroup; - NewGroup.append(GroupOfBlocks.begin(), GroupOfBlocks.end()); - GroupsOfBlocks.emplace_back(NewGroup); - } + void + init(const std::vector> &GroupsOfBlocksToExtract) { + GroupsOfBlocks = GroupsOfBlocksToExtract; if (!BlockExtractorFile.empty()) loadFile(); } private: - SmallVector, 4> GroupsOfBlocks; + std::vector> GroupsOfBlocks; bool EraseFunctions; /// Map a function name to groups of blocks. SmallVector>, 4> @@ -68,56 +63,8 @@ private: void splitLandingPadPreds(Function &F); }; -class BlockExtractorLegacyPass : public ModulePass { - BlockExtractor BE; - bool runOnModule(Module &M) override; - -public: - static char ID; - BlockExtractorLegacyPass(const SmallVectorImpl &BlocksToExtract, - bool EraseFunctions) - : ModulePass(ID), BE(EraseFunctions) { - // We want one group per element of the input list. - SmallVector, 4> MassagedGroupsOfBlocks; - for (BasicBlock *BB : BlocksToExtract) { - SmallVector NewGroup; - NewGroup.push_back(BB); - MassagedGroupsOfBlocks.push_back(NewGroup); - } - BE.init(MassagedGroupsOfBlocks); - } - - BlockExtractorLegacyPass(const SmallVectorImpl> - &GroupsOfBlocksToExtract, - bool EraseFunctions) - : ModulePass(ID), BE(EraseFunctions) { - BE.init(GroupsOfBlocksToExtract); - } - - BlockExtractorLegacyPass() - : BlockExtractorLegacyPass(SmallVector(), false) {} -}; - } // end anonymous namespace -char BlockExtractorLegacyPass::ID = 0; -INITIALIZE_PASS(BlockExtractorLegacyPass, "extract-blocks", - "Extract basic blocks from module", false, false) - -ModulePass *llvm::createBlockExtractorPass() { - return new BlockExtractorLegacyPass(); -} -ModulePass *llvm::createBlockExtractorPass( - const SmallVectorImpl &BlocksToExtract, bool EraseFunctions) { - return new BlockExtractorLegacyPass(BlocksToExtract, EraseFunctions); -} -ModulePass *llvm::createBlockExtractorPass( - const SmallVectorImpl> - &GroupsOfBlocksToExtract, - bool EraseFunctions) { - return new BlockExtractorLegacyPass(GroupsOfBlocksToExtract, EraseFunctions); -} - /// Gets all of the blocks specified in the input file. void BlockExtractor::loadFile() { auto ErrOrBuf = MemoryBuffer::getFile(BlockExtractorFile); @@ -179,7 +126,6 @@ void BlockExtractor::splitLandingPadPreds(Function &F) { } bool BlockExtractor::runOnModule(Module &M) { - bool Changed = false; // Get all the functions. @@ -251,14 +197,15 @@ bool BlockExtractor::runOnModule(Module &M) { return Changed; } -bool BlockExtractorLegacyPass::runOnModule(Module &M) { - return BE.runOnModule(M); -} +BlockExtractorPass::BlockExtractorPass( + std::vector> &&GroupsOfBlocks, + bool EraseFunctions) + : GroupsOfBlocks(GroupsOfBlocks), EraseFunctions(EraseFunctions) {} PreservedAnalyses BlockExtractorPass::run(Module &M, ModuleAnalysisManager &AM) { - BlockExtractor BE(false); - BE.init(SmallVector, 0>()); + BlockExtractor BE(EraseFunctions); + BE.init(GroupsOfBlocks); return BE.runOnModule(M) ? PreservedAnalyses::none() : PreservedAnalyses::all(); } diff --git a/llvm/lib/Transforms/IPO/ExtractGV.cpp b/llvm/lib/Transforms/IPO/ExtractGV.cpp index 8428078..d5073ee 100644 --- a/llvm/lib/Transforms/IPO/ExtractGV.cpp +++ b/llvm/lib/Transforms/IPO/ExtractGV.cpp @@ -10,11 +10,11 @@ // //===----------------------------------------------------------------------===// -#include "llvm/ADT/SetVector.h" +#include "llvm/Transforms/IPO/ExtractGV.h" #include "llvm/IR/Module.h" -#include "llvm/Pass.h" -#include "llvm/Transforms/IPO.h" +#include "llvm/IR/PassManager.h" #include + using namespace llvm; /// Make sure GV is visible from both modules. Delete is true if it is @@ -48,110 +48,86 @@ static void makeVisible(GlobalValue &GV, bool Delete) { } } -namespace { - /// A pass to extract specific global values and their dependencies. - class GVExtractorPass : public ModulePass { - SetVector Named; - bool deleteStuff; - bool keepConstInit; - public: - static char ID; // Pass identification, replacement for typeid /// If deleteS is true, this pass deletes the specified global values. /// Otherwise, it deletes as much of the module as possible, except for the /// global values specified. - explicit GVExtractorPass(std::vector &GVs, - bool deleteS = true, bool keepConstInit = false) - : ModulePass(ID), Named(GVs.begin(), GVs.end()), deleteStuff(deleteS), - keepConstInit(keepConstInit) {} - - bool runOnModule(Module &M) override { - if (skipModule(M)) - return false; - - // Visit the global inline asm. - if (!deleteStuff) - M.setModuleInlineAsm(""); - - // For simplicity, just give all GlobalValues ExternalLinkage. A trickier - // implementation could figure out which GlobalValues are actually - // referenced by the Named set, and which GlobalValues in the rest of - // the module are referenced by the NamedSet, and get away with leaving - // more internal and private things internal and private. But for now, - // be conservative and simple. - - // Visit the GlobalVariables. - for (GlobalVariable &GV : M.globals()) { - bool Delete = deleteStuff == (bool)Named.count(&GV) && - !GV.isDeclaration() && - (!GV.isConstant() || !keepConstInit); - if (!Delete) { - if (GV.hasAvailableExternallyLinkage()) - continue; - if (GV.getName() == "llvm.global_ctors") - continue; - } - - makeVisible(GV, Delete); - - if (Delete) { - // Make this a declaration and drop it's comdat. - GV.setInitializer(nullptr); - GV.setComdat(nullptr); - } - } +ExtractGVPass::ExtractGVPass(std::vector &GVs, bool deleteS, + bool keepConstInit) + : Named(GVs.begin(), GVs.end()), deleteStuff(deleteS), + keepConstInit(keepConstInit) {} + +PreservedAnalyses ExtractGVPass::run(Module &M, ModuleAnalysisManager &) { + // Visit the global inline asm. + if (!deleteStuff) + M.setModuleInlineAsm(""); + + // For simplicity, just give all GlobalValues ExternalLinkage. A trickier + // implementation could figure out which GlobalValues are actually + // referenced by the Named set, and which GlobalValues in the rest of + // the module are referenced by the NamedSet, and get away with leaving + // more internal and private things internal and private. But for now, + // be conservative and simple. + + // Visit the GlobalVariables. + for (GlobalVariable &GV : M.globals()) { + bool Delete = deleteStuff == (bool)Named.count(&GV) && + !GV.isDeclaration() && (!GV.isConstant() || !keepConstInit); + if (!Delete) { + if (GV.hasAvailableExternallyLinkage()) + continue; + if (GV.getName() == "llvm.global_ctors") + continue; + } - // Visit the Functions. - for (Function &F : M) { - bool Delete = - deleteStuff == (bool)Named.count(&F) && !F.isDeclaration(); - if (!Delete) { - if (F.hasAvailableExternallyLinkage()) - continue; - } - - makeVisible(F, Delete); - - if (Delete) { - // Make this a declaration and drop it's comdat. - F.deleteBody(); - F.setComdat(nullptr); - } - } + makeVisible(GV, Delete); - // Visit the Aliases. - for (GlobalAlias &GA : llvm::make_early_inc_range(M.aliases())) { - bool Delete = deleteStuff == (bool)Named.count(&GA); - makeVisible(GA, Delete); - - if (Delete) { - Type *Ty = GA.getValueType(); - - GA.removeFromParent(); - llvm::Value *Declaration; - if (FunctionType *FTy = dyn_cast(Ty)) { - Declaration = - Function::Create(FTy, GlobalValue::ExternalLinkage, - GA.getAddressSpace(), GA.getName(), &M); - - } else { - Declaration = - new GlobalVariable(M, Ty, false, GlobalValue::ExternalLinkage, - nullptr, GA.getName()); - } - GA.replaceAllUsesWith(Declaration); - delete &GA; - } - } + if (Delete) { + // Make this a declaration and drop it's comdat. + GV.setInitializer(nullptr); + GV.setComdat(nullptr); + } + } - return true; + // Visit the Functions. + for (Function &F : M) { + bool Delete = deleteStuff == (bool)Named.count(&F) && !F.isDeclaration(); + if (!Delete) { + if (F.hasAvailableExternallyLinkage()) + continue; } - }; - char GVExtractorPass::ID = 0; -} + makeVisible(F, Delete); + + if (Delete) { + // Make this a declaration and drop it's comdat. + F.deleteBody(); + F.setComdat(nullptr); + } + } + + // Visit the Aliases. + for (GlobalAlias &GA : llvm::make_early_inc_range(M.aliases())) { + bool Delete = deleteStuff == (bool)Named.count(&GA); + makeVisible(GA, Delete); + + if (Delete) { + Type *Ty = GA.getValueType(); + + GA.removeFromParent(); + llvm::Value *Declaration; + if (FunctionType *FTy = dyn_cast(Ty)) { + Declaration = Function::Create(FTy, GlobalValue::ExternalLinkage, + GA.getAddressSpace(), GA.getName(), &M); + + } else { + Declaration = new GlobalVariable( + M, Ty, false, GlobalValue::ExternalLinkage, nullptr, GA.getName()); + } + GA.replaceAllUsesWith(Declaration); + delete &GA; + } + } -ModulePass *llvm::createGVExtractionPass(std::vector &GVs, - bool deleteFn, bool keepConstInit) { - return new GVExtractorPass(GVs, deleteFn, keepConstInit); + return PreservedAnalyses::none(); } diff --git a/llvm/lib/Transforms/IPO/IPO.cpp b/llvm/lib/Transforms/IPO/IPO.cpp index 8bd92b5..4163c44 100644 --- a/llvm/lib/Transforms/IPO/IPO.cpp +++ b/llvm/lib/Transforms/IPO/IPO.cpp @@ -40,7 +40,6 @@ void llvm::initializeIPO(PassRegistry &Registry) { initializeInferFunctionAttrsLegacyPassPass(Registry); initializeInternalizeLegacyPassPass(Registry); initializeLoopExtractorLegacyPassPass(Registry); - initializeBlockExtractorLegacyPassPass(Registry); initializeSingleLoopExtractorPass(Registry); initializeMergeFunctionsLegacyPassPass(Registry); initializePartialInlinerLegacyPassPass(Registry); diff --git a/llvm/lib/Transforms/IPO/StripSymbols.cpp b/llvm/lib/Transforms/IPO/StripSymbols.cpp index 159f0b2..34f8c43 100644 --- a/llvm/lib/Transforms/IPO/StripSymbols.cpp +++ b/llvm/lib/Transforms/IPO/StripSymbols.cpp @@ -33,6 +33,7 @@ #include "llvm/InitializePasses.h" #include "llvm/Pass.h" #include "llvm/Transforms/IPO.h" +#include "llvm/Transforms/IPO/StripSymbols.h" #include "llvm/Transforms/Utils/Local.h" using namespace llvm; diff --git a/llvm/tools/llvm-extract/CMakeLists.txt b/llvm/tools/llvm-extract/CMakeLists.txt index ce2a78d..dcd4c89 100644 --- a/llvm/tools/llvm-extract/CMakeLists.txt +++ b/llvm/tools/llvm-extract/CMakeLists.txt @@ -3,6 +3,7 @@ set(LLVM_LINK_COMPONENTS Core IPO IRReader + Passes Support ) diff --git a/llvm/tools/llvm-extract/llvm-extract.cpp b/llvm/tools/llvm-extract/llvm-extract.cpp index ffd2a39..a879c203 100644 --- a/llvm/tools/llvm-extract/llvm-extract.cpp +++ b/llvm/tools/llvm-extract/llvm-extract.cpp @@ -18,10 +18,10 @@ #include "llvm/IR/IRPrintingPasses.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/LLVMContext.h" -#include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/Module.h" +#include "llvm/IRPrinter/IRPrintingPasses.h" #include "llvm/IRReader/IRReader.h" -#include "llvm/Pass.h" +#include "llvm/Passes/PassBuilder.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/Error.h" #include "llvm/Support/FileSystem.h" @@ -31,8 +31,14 @@ #include "llvm/Support/SystemUtils.h" #include "llvm/Support/ToolOutputFile.h" #include "llvm/Transforms/IPO.h" +#include "llvm/Transforms/IPO/BlockExtractor.h" +#include "llvm/Transforms/IPO/ExtractGV.h" +#include "llvm/Transforms/IPO/GlobalDCE.h" +#include "llvm/Transforms/IPO/StripDeadPrototypes.h" +#include "llvm/Transforms/IPO/StripSymbols.h" #include #include + using namespace llvm; cl::OptionCategory ExtractCat("llvm-extract Options"); @@ -317,9 +323,22 @@ int main(int argc, char **argv) { { std::vector Gvs(GVs.begin(), GVs.end()); - legacy::PassManager Extract; - Extract.add(createGVExtractionPass(Gvs, DeleteFn, KeepConstInit)); - Extract.run(*M); + LoopAnalysisManager LAM; + FunctionAnalysisManager FAM; + CGSCCAnalysisManager CGAM; + ModuleAnalysisManager MAM; + + PassBuilder PB; + + PB.registerModuleAnalyses(MAM); + PB.registerCGSCCAnalyses(CGAM); + PB.registerFunctionAnalyses(FAM); + PB.registerLoopAnalyses(LAM); + PB.crossRegisterProxies(LAM, FAM, CGAM, MAM); + + ModulePassManager PM; + PM.addPass(ExtractGVPass(Gvs, DeleteFn, KeepConstInit)); + PM.run(*M, MAM); // Now that we have all the GVs we want, mark the module as fully // materialized. @@ -331,9 +350,9 @@ int main(int argc, char **argv) { // functions. if (!ExtractBlocks.empty()) { // Figure out which BasicBlocks we should extract. - SmallVector, 4> GroupOfBBs; + std::vector> GroupOfBBs; for (auto &P : BBMap) { - SmallVector BBs; + std::vector BBs; for (StringRef BBName : P.second) { // The function has been materialized, so add its matching basic blocks // to the block extractor list, or fail if a name is not found. @@ -351,19 +370,45 @@ int main(int argc, char **argv) { GroupOfBBs.push_back(BBs); } - legacy::PassManager PM; - PM.add(createBlockExtractorPass(GroupOfBBs, true)); - PM.run(*M); + LoopAnalysisManager LAM; + FunctionAnalysisManager FAM; + CGSCCAnalysisManager CGAM; + ModuleAnalysisManager MAM; + + PassBuilder PB; + + PB.registerModuleAnalyses(MAM); + PB.registerCGSCCAnalyses(CGAM); + PB.registerFunctionAnalyses(FAM); + PB.registerLoopAnalyses(LAM); + PB.crossRegisterProxies(LAM, FAM, CGAM, MAM); + + ModulePassManager PM; + PM.addPass(BlockExtractorPass(std::move(GroupOfBBs), true)); + PM.run(*M, MAM); } // In addition to deleting all other functions, we also want to spiff it // up a little bit. Do this now. - legacy::PassManager Passes; + LoopAnalysisManager LAM; + FunctionAnalysisManager FAM; + CGSCCAnalysisManager CGAM; + ModuleAnalysisManager MAM; + + PassBuilder PB; + + PB.registerModuleAnalyses(MAM); + PB.registerCGSCCAnalyses(CGAM); + PB.registerFunctionAnalyses(FAM); + PB.registerLoopAnalyses(LAM); + PB.crossRegisterProxies(LAM, FAM, CGAM, MAM); + + ModulePassManager PM; if (!DeleteFn) - Passes.add(createGlobalDCEPass()); // Delete unreachable globals - Passes.add(createStripDeadDebugInfoPass()); // Remove dead debug info - Passes.add(createStripDeadPrototypesPass()); // Remove dead func decls + PM.addPass(GlobalDCEPass()); + PM.addPass(StripDeadDebugInfoPass()); + PM.addPass(StripDeadPrototypesPass()); std::error_code EC; ToolOutputFile Out(OutputFilename, EC, sys::fs::OF_None); @@ -373,12 +418,11 @@ int main(int argc, char **argv) { } if (OutputAssembly) - Passes.add( - createPrintModulePass(Out.os(), "", PreserveAssemblyUseListOrder)); + PM.addPass(PrintModulePass(Out.os(), "", PreserveAssemblyUseListOrder)); else if (Force || !CheckBitcodeOutputToConsole(Out.os())) - Passes.add(createBitcodeWriterPass(Out.os(), PreserveBitcodeUseListOrder)); + PM.addPass(BitcodeWriterPass(Out.os(), PreserveBitcodeUseListOrder)); - Passes.run(*M.get()); + PM.run(*M, MAM); // Declare success. Out.keep(); diff --git a/llvm/utils/gn/secondary/llvm/tools/llvm-extract/BUILD.gn b/llvm/utils/gn/secondary/llvm/tools/llvm-extract/BUILD.gn index b486cf0..38be9f7 100644 --- a/llvm/utils/gn/secondary/llvm/tools/llvm-extract/BUILD.gn +++ b/llvm/utils/gn/secondary/llvm/tools/llvm-extract/BUILD.gn @@ -4,6 +4,7 @@ executable("llvm-extract") { "//llvm/lib/IR", "//llvm/lib/IRReader", "//llvm/lib/Support", + "//llvm/lib/Passes", "//llvm/lib/Transforms/IPO", ] sources = [ "llvm-extract.cpp" ] -- 2.7.4