Index: llvm/tools/llvm-reduce/ReducerWorkItem.h =================================================================== --- llvm/tools/llvm-reduce/ReducerWorkItem.h +++ llvm/tools/llvm-reduce/ReducerWorkItem.h @@ -15,6 +15,7 @@ namespace llvm { class LLVMContext; class MachineModuleInfo; +class MemoryBufferRef; class raw_ostream; class TargetMachine; class TestRunner; @@ -26,6 +27,11 @@ std::unique_ptr LTOInfo; std::unique_ptr MMI; + ReducerWorkItem(); + ~ReducerWorkItem(); + ReducerWorkItem(ReducerWorkItem &) = delete; + ReducerWorkItem(ReducerWorkItem &&) = default; + bool isMIR() const { return MMI != nullptr; } LLVMContext &getContext() { @@ -34,36 +40,29 @@ Module &getModule() { return *M; } const Module &getModule() const { return *M; } + operator Module &() const { return *M; } void print(raw_ostream &ROS, void *p = nullptr) const; - operator Module &() const { return *M; } + bool verify(raw_fd_ostream *OS) const; + std::unique_ptr clone(const TargetMachine *TM) const; /// Return a number to indicate whether there was any reduction progress. uint64_t getComplexityScore() const { return isMIR() ? computeMIRComplexityScore() : computeIRComplexityScore(); } - ReducerWorkItem(); - ~ReducerWorkItem(); - ReducerWorkItem(ReducerWorkItem&) = delete; - ReducerWorkItem(ReducerWorkItem&&) = default; + void writeOutput(raw_ostream &OS, bool EmitBitcode) const; + void readBitcode(MemoryBufferRef Data, LLVMContext &Ctx, StringRef ToolName); + void writeBitcode(raw_ostream &OutStream) const; private: uint64_t computeIRComplexityScore() const; uint64_t computeMIRComplexityScore() const; }; -} // namespace llvm - -std::pair, bool> -parseReducerWorkItem(llvm::StringRef ToolName, llvm::StringRef Filename, - llvm::LLVMContext &Ctxt, - std::unique_ptr &TM, bool IsMIR); -std::unique_ptr -cloneReducerWorkItem(const llvm::ReducerWorkItem &MMM, - const llvm::TargetMachine *TM); - -bool verifyReducerWorkItem(const llvm::ReducerWorkItem &MMM, - llvm::raw_fd_ostream *OS); +std::pair, bool> +parseReducerWorkItem(StringRef ToolName, StringRef Filename, LLVMContext &Ctxt, + std::unique_ptr &TM, bool IsMIR); +} // namespace llvm #endif Index: llvm/tools/llvm-reduce/ReducerWorkItem.cpp =================================================================== --- llvm/tools/llvm-reduce/ReducerWorkItem.cpp +++ llvm/tools/llvm-reduce/ReducerWorkItem.cpp @@ -7,7 +7,11 @@ //===----------------------------------------------------------------------===// #include "ReducerWorkItem.h" +#include "TestRunner.h" +#include "llvm/Analysis/ModuleSummaryAnalysis.h" +#include "llvm/Analysis/ProfileSummaryInfo.h" #include "llvm/Bitcode/BitcodeReader.h" +#include "llvm/Bitcode/BitcodeWriter.h" #include "llvm/CodeGen/CommandFlags.h" #include "llvm/CodeGen/MIRParser/MIRParser.h" #include "llvm/CodeGen/MIRPrinter.h" @@ -25,12 +29,14 @@ #include "llvm/IR/Verifier.h" #include "llvm/IRReader/IRReader.h" #include "llvm/MC/TargetRegistry.h" +#include "llvm/Passes/PassBuilder.h" #include "llvm/Support/Host.h" #include "llvm/Support/MemoryBufferRef.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Support/WithColor.h" #include "llvm/Target/TargetMachine.h" +#include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h" #include "llvm/Transforms/Utils/Cloning.h" #include @@ -43,10 +49,6 @@ static cl::opt TargetTriple("mtriple", cl::desc("Set the target triple"), cl::cat(LLVMReduceOptions)); - -void readBitcode(ReducerWorkItem &M, MemoryBufferRef Data, LLVMContext &Ctx, - StringRef ToolName); - static void cloneFrameInfo( MachineFrameInfo &DstMFI, const MachineFrameInfo &SrcMFI, const DenseMap &Src2DstMBB) { @@ -392,102 +394,43 @@ InitializeAllAsmParsers(); } -std::pair, bool> -parseReducerWorkItem(StringRef ToolName, StringRef Filename, LLVMContext &Ctxt, - std::unique_ptr &TM, bool IsMIR) { - bool IsBitcode = false; - Triple TheTriple; - - auto MMM = std::make_unique(); - - if (IsMIR) { - initializeTargetInfo(); - - auto FileOrErr = MemoryBuffer::getFileOrSTDIN(Filename, /*IsText=*/true); - if (std::error_code EC = FileOrErr.getError()) { - WithColor::error(errs(), ToolName) << EC.message() << '\n'; - return {nullptr, false}; +void ReducerWorkItem::print(raw_ostream &ROS, void *p) const { + if (MMI) { + printMIR(ROS, *M); + for (Function &F : *M) { + if (auto *MF = MMI->getMachineFunction(F)) + printMIR(ROS, *MF); } - - std::unique_ptr MParser = - createMIRParser(std::move(FileOrErr.get()), Ctxt); - - auto SetDataLayout = [&](StringRef DataLayoutTargetTriple, - StringRef OldDLStr) -> std::optional { - // If we are supposed to override the target triple, do so now. - std::string IRTargetTriple = DataLayoutTargetTriple.str(); - if (!TargetTriple.empty()) - IRTargetTriple = Triple::normalize(TargetTriple); - TheTriple = Triple(IRTargetTriple); - if (TheTriple.getTriple().empty()) - TheTriple.setTriple(sys::getDefaultTargetTriple()); - - std::string Error; - const Target *TheTarget = - TargetRegistry::lookupTarget(codegen::getMArch(), TheTriple, Error); - if (!TheTarget) { - WithColor::error(errs(), ToolName) << Error; - exit(1); - } - - // Hopefully the MIR parsing doesn't depend on any options. - TargetOptions Options; - std::optional RM = codegen::getExplicitRelocModel(); - std::string CPUStr = codegen::getCPUStr(); - std::string FeaturesStr = codegen::getFeaturesStr(); - TM = std::unique_ptr(TheTarget->createTargetMachine( - TheTriple.getTriple(), CPUStr, FeaturesStr, Options, RM, - codegen::getExplicitCodeModel(), CodeGenOpt::Default)); - assert(TM && "Could not allocate target machine!"); - - return TM->createDataLayout().getStringRepresentation(); - }; - - std::unique_ptr M = MParser->parseIRModule(SetDataLayout); - LLVMTargetMachine *LLVMTM = static_cast(TM.get()); - - MMM->MMI = std::make_unique(LLVMTM); - MParser->parseMachineFunctions(*M, *MMM->MMI); - MMM->M = std::move(M); } else { - SMDiagnostic Err; - ErrorOr> MB = MemoryBuffer::getFileOrSTDIN(Filename); - if (std::error_code EC = MB.getError()) { - WithColor::error(errs(), ToolName) << Filename << ": " << EC.message() << "\n"; - return {nullptr, false}; - } + M->print(ROS, /*AssemblyAnnotationWriter=*/nullptr, + /*ShouldPreserveUseListOrder=*/true); + } +} - if (!isBitcode((const unsigned char *)(*MB)->getBufferStart(), - (const unsigned char *)(*MB)->getBufferEnd())) { - std::unique_ptr Result = parseIRFile(Filename, Err, Ctxt); - if (!Result) { - Err.print(ToolName.data(), errs()); - return {nullptr, false}; - } - MMM->M = std::move(Result); - } else { - IsBitcode = true; - readBitcode(*MMM, MemoryBufferRef(**MB), Ctxt, ToolName); +bool ReducerWorkItem::verify(raw_fd_ostream *OS) const { + if (verifyModule(*M, OS)) + return true; - if (MMM->LTOInfo->IsThinLTO && MMM->LTOInfo->EnableSplitLTOUnit) - initializeTargetInfo(); + if (!MMI) + return false; + + for (const Function &F : getModule()) { + if (const MachineFunction *MF = MMI->getMachineFunction(F)) { + if (!MF->verify(nullptr, "", /*AbortOnError=*/false)) + return true; } } - if (verifyReducerWorkItem(*MMM, &errs())) { - WithColor::error(errs(), ToolName) - << Filename << " - input module is broken!\n"; - return {nullptr, false}; - } - return {std::move(MMM), IsBitcode}; + + return false; } std::unique_ptr -cloneReducerWorkItem(const ReducerWorkItem &MMM, const TargetMachine *TM) { +ReducerWorkItem::clone(const TargetMachine *TM) const { auto CloneMMM = std::make_unique(); if (TM) { // We're assuming the Module IR contents are always unchanged by MIR // reductions, and can share it as a constant. - CloneMMM->M = MMM.M; + CloneMMM->M = M; // MachineModuleInfo contains a lot of other state used during codegen which // we won't be using here, but we should be able to ignore it (although this @@ -496,46 +439,16 @@ static_cast(TM); CloneMMM->MMI = std::make_unique(LLVMTM); - for (const Function &F : MMM.getModule()) { - if (auto *MF = MMM.MMI->getMachineFunction(F)) + for (const Function &F : getModule()) { + if (auto *MF = MMI->getMachineFunction(F)) CloneMMM->MMI->insertFunction(F, cloneMF(MF, *CloneMMM->MMI)); } } else { - CloneMMM->M = CloneModule(*MMM.M); + CloneMMM->M = CloneModule(*M); } return CloneMMM; } -bool verifyReducerWorkItem(const ReducerWorkItem &MMM, raw_fd_ostream *OS) { - if (verifyModule(*MMM.M, OS)) - return true; - - if (!MMM.MMI) - return false; - - for (const Function &F : MMM.getModule()) { - if (const MachineFunction *MF = MMM.MMI->getMachineFunction(F)) { - if (!MF->verify(nullptr, "", /*AbortOnError=*/false)) - return true; - } - } - - return false; -} - -void ReducerWorkItem::print(raw_ostream &ROS, void *p) const { - if (MMI) { - printMIR(ROS, *M); - for (Function &F : *M) { - if (auto *MF = MMI->getMachineFunction(F)) - printMIR(ROS, *MF); - } - } else { - M->print(ROS, /*AssemblyAnnotationWriter=*/nullptr, - /*ShouldPreserveUseListOrder=*/true); - } -} - /// Try to produce some number that indicates a function is getting smaller / /// simpler. static uint64_t computeMIRComplexityScoreImpl(const MachineFunction &MF) { @@ -731,3 +644,147 @@ return Score; } + +void ReducerWorkItem::writeOutput(raw_ostream &OS, bool EmitBitcode) const { + // Requesting bitcode emission with mir is nonsense, so just ignore it. + if (EmitBitcode && !isMIR()) + writeBitcode(OS); + else + print(OS, /*AnnotationWriter=*/nullptr); +} + +void ReducerWorkItem::readBitcode(MemoryBufferRef Data, LLVMContext &Ctx, + StringRef ToolName) { + Expected IF = llvm::getBitcodeFileContents(Data); + if (!IF) { + WithColor::error(errs(), ToolName) << IF.takeError(); + exit(1); + } + BitcodeModule BM = IF->Mods[0]; + Expected LI = BM.getLTOInfo(); + Expected> MOrErr = BM.parseModule(Ctx); + if (!LI || !MOrErr) { + WithColor::error(errs(), ToolName) << IF.takeError(); + exit(1); + } + LTOInfo = std::make_unique(*LI); + M = std::move(MOrErr.get()); +} + +void ReducerWorkItem::writeBitcode(raw_ostream &OutStream) const { + if (LTOInfo && LTOInfo->IsThinLTO && LTOInfo->EnableSplitLTOUnit) { + PassBuilder PB; + LoopAnalysisManager LAM; + FunctionAnalysisManager FAM; + CGSCCAnalysisManager CGAM; + ModuleAnalysisManager MAM; + PB.registerModuleAnalyses(MAM); + PB.registerCGSCCAnalyses(CGAM); + PB.registerFunctionAnalyses(FAM); + PB.registerLoopAnalyses(LAM); + PB.crossRegisterProxies(LAM, FAM, CGAM, MAM); + ModulePassManager MPM; + MPM.addPass(ThinLTOBitcodeWriterPass(OutStream, nullptr)); + MPM.run(*M, MAM); + } else { + std::unique_ptr Index; + if (LTOInfo && LTOInfo->HasSummary) { + ProfileSummaryInfo PSI(*M); + Index = std::make_unique( + buildModuleSummaryIndex(*M, nullptr, &PSI)); + } + WriteBitcodeToFile(getModule(), OutStream, Index.get()); + } +} + +std::pair, bool> +llvm::parseReducerWorkItem(StringRef ToolName, StringRef Filename, + LLVMContext &Ctxt, + std::unique_ptr &TM, bool IsMIR) { + bool IsBitcode = false; + Triple TheTriple; + + auto MMM = std::make_unique(); + + if (IsMIR) { + initializeTargetInfo(); + + auto FileOrErr = MemoryBuffer::getFileOrSTDIN(Filename, /*IsText=*/true); + if (std::error_code EC = FileOrErr.getError()) { + WithColor::error(errs(), ToolName) << EC.message() << '\n'; + return {nullptr, false}; + } + + std::unique_ptr MParser = + createMIRParser(std::move(FileOrErr.get()), Ctxt); + + auto SetDataLayout = [&](StringRef DataLayoutTargetTriple, + StringRef OldDLStr) -> std::optional { + // If we are supposed to override the target triple, do so now. + std::string IRTargetTriple = DataLayoutTargetTriple.str(); + if (!TargetTriple.empty()) + IRTargetTriple = Triple::normalize(TargetTriple); + TheTriple = Triple(IRTargetTriple); + if (TheTriple.getTriple().empty()) + TheTriple.setTriple(sys::getDefaultTargetTriple()); + + std::string Error; + const Target *TheTarget = + TargetRegistry::lookupTarget(codegen::getMArch(), TheTriple, Error); + if (!TheTarget) { + WithColor::error(errs(), ToolName) << Error; + exit(1); + } + + // Hopefully the MIR parsing doesn't depend on any options. + TargetOptions Options; + std::optional RM = codegen::getExplicitRelocModel(); + std::string CPUStr = codegen::getCPUStr(); + std::string FeaturesStr = codegen::getFeaturesStr(); + TM = std::unique_ptr(TheTarget->createTargetMachine( + TheTriple.getTriple(), CPUStr, FeaturesStr, Options, RM, + codegen::getExplicitCodeModel(), CodeGenOpt::Default)); + assert(TM && "Could not allocate target machine!"); + + return TM->createDataLayout().getStringRepresentation(); + }; + + std::unique_ptr M = MParser->parseIRModule(SetDataLayout); + LLVMTargetMachine *LLVMTM = static_cast(TM.get()); + + MMM->MMI = std::make_unique(LLVMTM); + MParser->parseMachineFunctions(*M, *MMM->MMI); + MMM->M = std::move(M); + } else { + SMDiagnostic Err; + ErrorOr> MB = + MemoryBuffer::getFileOrSTDIN(Filename); + if (std::error_code EC = MB.getError()) { + WithColor::error(errs(), ToolName) + << Filename << ": " << EC.message() << "\n"; + return {nullptr, false}; + } + + if (!isBitcode((const unsigned char *)(*MB)->getBufferStart(), + (const unsigned char *)(*MB)->getBufferEnd())) { + std::unique_ptr Result = parseIRFile(Filename, Err, Ctxt); + if (!Result) { + Err.print(ToolName.data(), errs()); + return {nullptr, false}; + } + MMM->M = std::move(Result); + } else { + IsBitcode = true; + MMM->readBitcode(MemoryBufferRef(**MB), Ctxt, ToolName); + + if (MMM->LTOInfo->IsThinLTO && MMM->LTOInfo->EnableSplitLTOUnit) + initializeTargetInfo(); + } + } + if (MMM->verify(&errs())) { + WithColor::error(errs(), ToolName) + << Filename << " - input module is broken!\n"; + return {nullptr, false}; + } + return {std::move(MMM), IsBitcode}; +} Index: llvm/tools/llvm-reduce/TestRunner.h =================================================================== --- llvm/tools/llvm-reduce/TestRunner.h +++ llvm/tools/llvm-reduce/TestRunner.h @@ -38,7 +38,10 @@ /// Returns the most reduced version of the original testcase ReducerWorkItem &getProgram() const { return *Program; } - void setProgram(std::unique_ptr P); + void setProgram(std::unique_ptr &&P) { + assert(P && "Setting null program?"); + Program = std::move(P); + } const TargetMachine *getTargetMachine() const { return TM.get(); } Index: llvm/tools/llvm-reduce/TestRunner.cpp =================================================================== --- llvm/tools/llvm-reduce/TestRunner.cpp +++ llvm/tools/llvm-reduce/TestRunner.cpp @@ -9,13 +9,7 @@ #include "TestRunner.h" #include "ReducerWorkItem.h" #include "deltas/Utils.h" -#include "llvm/Analysis/ModuleSummaryAnalysis.h" -#include "llvm/Analysis/ProfileSummaryInfo.h" -#include "llvm/Bitcode/BitcodeReader.h" -#include "llvm/Bitcode/BitcodeWriter.h" -#include "llvm/Passes/PassBuilder.h" #include "llvm/Support/WithColor.h" -#include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h" using namespace llvm; @@ -65,37 +59,6 @@ return !Result; } -void TestRunner::setProgram(std::unique_ptr P) { - assert(P && "Setting null program?"); - Program = std::move(P); -} - -void writeBitcode(const ReducerWorkItem &M, raw_ostream &OutStream) { - if (M.LTOInfo && M.LTOInfo->IsThinLTO && M.LTOInfo->EnableSplitLTOUnit) { - PassBuilder PB; - LoopAnalysisManager LAM; - FunctionAnalysisManager FAM; - CGSCCAnalysisManager CGAM; - ModuleAnalysisManager MAM; - PB.registerModuleAnalyses(MAM); - PB.registerCGSCCAnalyses(CGAM); - PB.registerFunctionAnalyses(FAM); - PB.registerLoopAnalyses(LAM); - PB.crossRegisterProxies(LAM, FAM, CGAM, MAM); - ModulePassManager MPM; - MPM.addPass(ThinLTOBitcodeWriterPass(OutStream, nullptr)); - MPM.run(*M.M, MAM); - } else { - std::unique_ptr Index; - if (M.LTOInfo && M.LTOInfo->HasSummary) { - ProfileSummaryInfo PSI(M); - Index = std::make_unique( - buildModuleSummaryIndex(M, nullptr, &PSI)); - } - WriteBitcodeToFile(M.getModule(), OutStream, Index.get()); - } -} - void TestRunner::writeOutput(StringRef Message) { std::error_code EC; raw_fd_ostream Out(OutputFilename, EC, @@ -106,11 +69,6 @@ exit(1); } - // Requesting bitcode emission with mir is nonsense, so just ignore it. - if (EmitBitcode && !Program->isMIR()) - writeBitcode(*Program, Out); - else - Program->print(Out, /*AnnotationWriter=*/nullptr); - + Program->writeOutput(Out, EmitBitcode); errs() << Message << OutputFilename << '\n'; } Index: llvm/tools/llvm-reduce/deltas/Delta.cpp =================================================================== --- llvm/tools/llvm-reduce/deltas/Delta.cpp +++ llvm/tools/llvm-reduce/deltas/Delta.cpp @@ -60,11 +60,6 @@ unsigned NumJobs = 1; #endif -void writeBitcode(const ReducerWorkItem &M, raw_ostream &OutStream); - -void readBitcode(ReducerWorkItem &M, MemoryBufferRef Data, LLVMContext &Ctx, - StringRef ToolName); - bool isReduced(const ReducerWorkItem &M, const TestRunner &Test) { const bool UseBitcode = Test.inputIsBitcode() || TmpFilesAsBitcode; @@ -84,7 +79,7 @@ ToolOutputFile Out(CurrentFilepath, FD); if (TmpFilesAsBitcode) - writeBitcode(M, Out.os()); + M.writeBitcode(Out.os()); else M.print(Out.os(), /*AnnotationWriter=*/nullptr); @@ -157,7 +152,7 @@ ExtractChunksFromModule(O, *Clone); // Some reductions may result in invalid IR. Skip such reductions. - if (verifyReducerWorkItem(*Clone, &errs())) { + if (Clone->verify(&errs())) { if (AbortOnInvalidReduction) { errs() << "Invalid reduction, aborting.\n"; Clone->print(errs()); @@ -196,7 +191,7 @@ LLVMContext Ctx; auto CloneMMM = std::make_unique(); MemoryBufferRef Data(OriginalBC, ""); - readBitcode(*CloneMMM, Data, Ctx, Test.getToolName()); + CloneMMM->readBitcode(Data, Ctx, Test.getToolName()); SmallString<0> Result; if (std::unique_ptr ChunkResult = @@ -204,7 +199,7 @@ Test, ExtractChunksFromModule, UninterestingChunks, ChunksStillConsideredInteresting)) { raw_svector_ostream BCOS(Result); - writeBitcode(*ChunkResult, BCOS); + ChunkResult->writeBitcode(BCOS); // Communicate that the task reduced a chunk. AnyReduced = true; } @@ -227,7 +222,7 @@ /// reduction pass where no change must be made to the module. void llvm::runDeltaPass(TestRunner &Test, ReductionFunc ExtractChunksFromModule, StringRef Message) { - assert(!verifyReducerWorkItem(Test.getProgram(), &errs()) && + assert(!Test.getProgram().verify(&errs()) && "input module is broken before making changes"); errs() << "*** " << Message << "...\n"; @@ -241,7 +236,7 @@ ExtractChunksFromModule(Counter, Test.getProgram()); Targets = Counter.count(); - assert(!verifyReducerWorkItem(Test.getProgram(), &errs()) && + assert(!Test.getProgram().verify(&errs()) && "input module is broken after counting chunks"); assert(isReduced(Test.getProgram(), Test) && "input module no longer interesting after counting chunks"); @@ -252,7 +247,7 @@ std::vector NoChunks = {{0, INT_MAX}}; Oracle NoChunksCounter(NoChunks); std::unique_ptr Clone = - cloneReducerWorkItem(Test.getProgram(), Test.getTargetMachine()); + Test.getProgram().clone(Test.getTargetMachine()); ExtractChunksFromModule(NoChunksCounter, *Clone); assert(Targets == NoChunksCounter.count() && "number of chunks changes when reducing"); @@ -290,7 +285,7 @@ SmallString<0> OriginalBC; if (NumJobs > 1) { raw_svector_ostream BCOS(OriginalBC); - writeBitcode(Test.getProgram(), BCOS); + Test.getProgram().writeBitcode(BCOS); } SharedTaskQueue TaskQueue; @@ -353,8 +348,8 @@ Result = std::make_unique(); MemoryBufferRef Data(StringRef(Res), ""); - readBitcode(*Result, Data, Test.getProgram().M->getContext(), - Test.getToolName()); + Result->readBitcode(Data, Test.getProgram().M->getContext(), + Test.getToolName()); break; } @@ -368,11 +363,10 @@ // Forward I to the last chunk processed in parallel. I += NumChunksProcessed - 1; } else { - Result = CheckChunk( - *I, - cloneReducerWorkItem(Test.getProgram(), Test.getTargetMachine()), - Test, ExtractChunksFromModule, UninterestingChunks, - ChunksStillConsideredInteresting); + Result = + CheckChunk(*I, Test.getProgram().clone(Test.getTargetMachine()), + Test, ExtractChunksFromModule, UninterestingChunks, + ChunksStillConsideredInteresting); } if (!Result) Index: llvm/tools/llvm-reduce/llvm-reduce.cpp =================================================================== --- llvm/tools/llvm-reduce/llvm-reduce.cpp +++ llvm/tools/llvm-reduce/llvm-reduce.cpp @@ -139,24 +139,6 @@ return {OutputFilename, OutputBitcode}; } -void readBitcode(ReducerWorkItem &M, MemoryBufferRef Data, LLVMContext &Ctx, - StringRef ToolName) { - Expected IF = llvm::getBitcodeFileContents(Data); - if (!IF) { - WithColor::error(errs(), ToolName) << IF.takeError(); - exit(1); - } - BitcodeModule BM = IF->Mods[0]; - Expected LI = BM.getLTOInfo(); - Expected> MOrErr = BM.parseModule(Ctx); - if (!LI || !MOrErr) { - WithColor::error(errs(), ToolName) << IF.takeError(); - exit(1); - } - M.LTOInfo = std::make_unique(*LI); - M.M = std::move(MOrErr.get()); -} - int main(int Argc, char **Argv) { InitLLVM X(Argc, Argv); const StringRef ToolName(Argv[0]);