Index: llvm/tools/llc/llc.cpp =================================================================== --- llvm/tools/llc/llc.cpp +++ llvm/tools/llc/llc.cpp @@ -609,9 +609,7 @@ // Compare the two outputs and make sure they're the same if (CompileTwice) { - if (Buffer.size() != CompileTwiceBuffer.size() || - (memcmp(Buffer.data(), CompileTwiceBuffer.data(), Buffer.size()) != - 0)) { + if (Buffer != CompileTwiceBuffer) { errs() << "Running the pass manager twice changed the output.\n" "Writing the result of the second run to the specified output\n" Index: llvm/tools/opt/opt.cpp =================================================================== --- llvm/tools/opt/opt.cpp +++ llvm/tools/opt/opt.cpp @@ -466,9 +466,9 @@ } // Returns the TargetMachine instance or zero if no triple is provided. -static TargetMachine* GetTargetMachine(Triple TheTriple, StringRef CPUStr, - StringRef FeaturesStr, - const TargetOptions &Options) { +static std::unique_ptr +GetTargetMachine(Triple TheTriple, StringRef CPUStr, StringRef FeaturesStr, + const TargetOptions &Options) { std::string Error; const Target *TheTarget = TargetRegistry::lookupTarget(MArch, TheTriple, Error); @@ -477,9 +477,22 @@ return nullptr; } - return TheTarget->createTargetMachine(TheTriple.getTriple(), CPUStr, - FeaturesStr, Options, getRelocModel(), - getCodeModel(), GetCodeGenOptLevel()); + return std::unique_ptr(TheTarget->createTargetMachine( + TheTriple.getTriple(), CPUStr, FeaturesStr, Options, getRelocModel(), + getCodeModel(), GetCodeGenOptLevel())); +} + +static OutputKind GetOutputKind() { + if (NoOutput) + return OK_NoOutput; + + if (OutputAssembly) + return OK_OutputAssembly; + + if (OutputThinLTOBC) + return OK_OutputThinLTOBitcode; + + return OK_OutputBitcode; } #ifdef LINK_POLLY_INTO_TOOLS @@ -509,22 +522,7 @@ } } -//===----------------------------------------------------------------------===// -// main for opt -// -int main(int argc, char **argv) { - InitLLVM X(argc, argv); - - // Enable debug stream buffering. - EnableDebugBuffering = true; - - LLVMContext Context; - - InitializeAllTargets(); - InitializeAllTargetMCs(); - InitializeAllAsmPrinters(); - InitializeAllAsmParsers(); - +static void InitializetDefaultPasses() { // Initialize passes PassRegistry &Registry = *PassRegistry::getPassRegistry(); initializeCore(Registry); @@ -567,6 +565,25 @@ #ifdef LINK_POLLY_INTO_TOOLS polly::initializePollyPasses(Registry); #endif +} + +//===----------------------------------------------------------------------===// +// main for opt +// +int main(int argc, char **argv) { + InitLLVM X(argc, argv); + + // Enable debug st0ream buffering. + EnableDebugBuffering = true; + + LLVMContext Context; + + InitializeAllTargets(); + InitializeAllTargetMCs(); + InitializeAllAsmPrinters(); + InitializeAllAsmParsers(); + + InitializetDefaultPasses(); cl::ParseCommandLineOptions(argc, argv, "llvm .bc -> .bc modular optimizer and analysis printer\n"); @@ -591,6 +608,20 @@ return 1; } std::unique_ptr RemarksFile = std::move(*RemarksFileOrErr); + if (RemarksFile) + RemarksFile->keep(); + + if (OutputAssembly) { + if (EmitSummaryIndex) { + errs() << argv[0] + << ": Text output is incompatible with -module-summary\n"; + return 1; + } + if (EmitModuleHash) { + errs() << argv[0] << ": Text output is incompatible with -module-hash\n"; + return 1; + } + } // Load the input module... std::unique_ptr M = @@ -650,6 +681,7 @@ if (!ThinLinkBitcodeFile.empty()) { ThinLinkOut.reset( new ToolOutputFile(ThinLinkBitcodeFile, EC, sys::fs::OF_None)); + ThinLinkOut->keep(); if (EC) { errs() << EC.message() << '\n'; return 1; @@ -658,22 +690,20 @@ } Triple ModuleTriple(M->getTargetTriple()); - std::string CPUStr, FeaturesStr; - TargetMachine *Machine = nullptr; - const TargetOptions Options = InitTargetOptionsFromCodeGenFlags(); - if (ModuleTriple.getArch()) { - CPUStr = getCPUStr(); - FeaturesStr = getFeaturesStr(); - Machine = GetTargetMachine(ModuleTriple, CPUStr, FeaturesStr, Options); - } else if (ModuleTriple.getArchName() != "unknown" && - ModuleTriple.getArchName() != "") { + if (!ModuleTriple.getArch() && ModuleTriple.getArchName() != "unknown" && + ModuleTriple.getArchName() != "") { errs() << argv[0] << ": unrecognized architecture '" << ModuleTriple.getArchName() << "' provided.\n"; return 1; } - std::unique_ptr TM(Machine); + std::string CPUStr = getCPUStr(); + std::string FeaturesStr = getFeaturesStr(); + const TargetOptions Options = InitTargetOptionsFromCodeGenFlags(); + + std::unique_ptr TM = + GetTargetMachine(ModuleTriple, CPUStr, FeaturesStr, Options); // Override function attributes based on CPUStr, FeaturesStr, and command line // flags. @@ -686,16 +716,12 @@ if (CheckBitcodeOutputToConsole(Out->os(), !Quiet)) NoOutput = true; + OutputKind OK = GetOutputKind(); + if (OutputThinLTOBC) M->addModuleFlag(Module::Error, "EnableSplitLTOUnit", SplitLTOUnit); if (PassPipeline.getNumOccurrences() > 0) { - OutputKind OK = OK_NoOutput; - if (!NoOutput) - OK = OutputAssembly - ? OK_OutputAssembly - : (OutputThinLTOBC ? OK_OutputThinLTOBitcode : OK_OutputBitcode); - VerifierKind VK = VK_VerifyInAndOut; if (NoVerify) VK = VK_NoVerifier; @@ -771,6 +797,7 @@ } Passes.add(createBreakpointPrinter(Out->os())); NoOutput = true; + Out->keep(); } if (TM) { @@ -911,53 +938,57 @@ BOS = std::make_unique(Buffer); OS = BOS.get(); } - if (OutputAssembly) { - if (EmitSummaryIndex) - report_fatal_error("Text output is incompatible with -module-summary"); - if (EmitModuleHash) - report_fatal_error("Text output is incompatible with -module-hash"); - Passes.add(createPrintModulePass(*OS, "", PreserveAssemblyUseListOrder)); - } else if (OutputThinLTOBC) + + switch (OK) { + case OK_NoOutput: + assert(false); + break; + case OK_OutputThinLTOBitcode: Passes.add(createWriteThinLTOBitcodePass( *OS, ThinLinkOut ? &ThinLinkOut->os() : nullptr)); - else + break; + case OK_OutputBitcode: Passes.add(createBitcodeWriterPass(*OS, PreserveBitcodeUseListOrder, EmitSummaryIndex, EmitModuleHash)); + break; + case OK_OutputAssembly: + Passes.add(createPrintModulePass(*OS, "", PreserveAssemblyUseListOrder)); + break; + } + Out->keep(); } // Before executing passes, print the final values of the LLVM options. cl::PrintOptionValues(); - if (!RunTwice) { - // Now that we have all of the passes ready, run them. - Passes.run(*M); - } else { + std::unique_ptr ModuleCopy; + if (RunTwice) { + ModuleCopy = CloneModule(*M); + } + + // Now that we have all of the passes ready, run them. + Passes.run(*M); + + if (RunTwice) { // If requested, run all passes twice with the same pass manager to catch // bugs caused by persistent state in the passes. - std::unique_ptr M2(CloneModule(*M)); - // Run all passes on the original module first, so the second run processes - // the clone to catch CloneModule bugs. - Passes.run(*M); + // Run all passes on the second run processes the clone to catch CloneModule + // bugs. FirstRunBuffer = Buffer; Buffer.clear(); - Passes.run(*M2); + Passes.run(*ModuleCopy); // Compare the two outputs and make sure they're the same assert(Out); - if (Buffer.size() != FirstRunBuffer.size() || - (memcmp(Buffer.data(), FirstRunBuffer.data(), Buffer.size()) != 0)) { + if (Buffer != FirstRunBuffer) { errs() << "Running the pass manager twice changed the output.\n" "Writing the result of the second run to the specified output.\n" "To generate the one-run comparison binary, just run without\n" "the compile-twice option\n"; - if (ShouldEmitOutput) { + if (ShouldEmitOutput) Out->os() << BOS->str(); - Out->keep(); - } - if (RemarksFile) - RemarksFile->keep(); return 1; } if (ShouldEmitOutput) @@ -967,15 +998,6 @@ if (DebugifyEach && !DebugifyExport.empty()) exportDebugifyStats(DebugifyExport, Passes.getDebugifyStatsMap()); - // Declare success. - if (!NoOutput || PrintBreakpoints) - Out->keep(); - - if (RemarksFile) - RemarksFile->keep(); - - if (ThinLinkOut) - ThinLinkOut->keep(); return 0; }