//===----------------------------------------------------------------------===// // main for opt // int main(int argc, char **argv) { sys::PrintStackTraceOnErrorSignal(argv[0]); llvm::PrettyStackTraceProgram X(argc, argv); // Enable debug stream buffering. EnableDebugBuffering = true; llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. LLVMContext Context; InitializeAllTargets(); InitializeAllTargetMCs(); InitializeAllAsmPrinters(); InitializeAllAsmParsers(); // Initialize passes PassRegistry &Registry = *PassRegistry::getPassRegistry(); initializeCore(Registry); initializeCoroutines(Registry); initializeScalarOpts(Registry); initializeObjCARCOpts(Registry); initializeVectorization(Registry); initializeIPO(Registry); initializeAnalysis(Registry); initializeTransformUtils(Registry); initializeInstCombine(Registry); initializeInstrumentation(Registry); initializeTarget(Registry); // For codegen passes, only passes that do IR to IR transformation are // supported. initializeScalarizeMaskedMemIntrinPass(Registry); initializeCodeGenPreparePass(Registry); initializeAtomicExpandPass(Registry); initializeRewriteSymbolsLegacyPassPass(Registry); initializeWinEHPreparePass(Registry); initializeDwarfEHPreparePass(Registry); initializeSafeStackLegacyPassPass(Registry); initializeSjLjEHPreparePass(Registry); initializePreISelIntrinsicLoweringLegacyPassPass(Registry); initializeGlobalMergePass(Registry); initializeInterleavedAccessPass(Registry); initializeCountingFunctionInserterPass(Registry); initializeUnreachableBlockElimLegacyPassPass(Registry); initializeExpandReductionsPass(Registry); #ifdef LINK_POLLY_INTO_TOOLS polly::initializePollyPasses(Registry); #endif cl::ParseCommandLineOptions(argc, argv, "llvm .bc -> .bc modular optimizer and analysis printer\n"); if (AnalyzeOnly && NoOutput) { errs() << argv[0] << ": analyze mode conflicts with no-output mode.\n"; return 1; } SMDiagnostic Err; Context.setDiscardValueNames(DiscardValueNames); if (!DisableDITypeMap) Context.enableDebugTypeODRUniquing(); if (PassRemarksWithHotness) Context.setDiagnosticsHotnessRequested(true); if (PassRemarksHotnessThreshold) Context.setDiagnosticsHotnessThreshold(PassRemarksHotnessThreshold); std::unique_ptr<ToolOutputFile> OptRemarkFile; if (RemarksFilename != "") { std::error_code EC; OptRemarkFile = llvm::make_unique<ToolOutputFile>(RemarksFilename, EC, sys::fs::F_None); if (EC) { errs() << EC.message() << '\n'; return 1; } Context.setDiagnosticsOutputFile( llvm::make_unique<yaml::Output>(OptRemarkFile->os())); } // Load the input module... std::unique_ptr<Module> M = parseIRFile(InputFilename, Err, Context, !NoVerify); if (!M) { Err.print(argv[0], errs()); return 1; } // Strip debug info before running the verifier. if (StripDebug) StripDebugInfo(*M); // Immediately run the verifier to catch any problems before starting up the // pass pipelines. Otherwise we can crash on broken code during // doInitialization(). if (!NoVerify && verifyModule(*M, &errs())) { errs() << argv[0] << ": " << InputFilename << ": error: input module is broken!\n"; return 1; } // If we are supposed to override the target triple or data layout, do so now. if (!TargetTriple.empty()) M->setTargetTriple(Triple::normalize(TargetTriple)); if (!ClDataLayout.empty()) M->setDataLayout(ClDataLayout); // Figure out what stream we are supposed to write to... std::unique_ptr<ToolOutputFile> Out; std::unique_ptr<ToolOutputFile> ThinLinkOut; if (NoOutput) { if (!OutputFilename.empty()) errs() << "WARNING: The -o (output filename) option is ignored when\n" "the --disable-output option is used.\n"; } else { // Default to standard output. if (OutputFilename.empty()) OutputFilename = "-"; std::error_code EC; Out.reset(new ToolOutputFile(OutputFilename, EC, sys::fs::F_None)); if (EC) { errs() << EC.message() << '\n'; return 1; } if (!ThinLinkBitcodeFile.empty()) { ThinLinkOut.reset( new ToolOutputFile(ThinLinkBitcodeFile, EC, sys::fs::F_None)); if (EC) { errs() << EC.message() << '\n'; return 1; } } } 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); } std::unique_ptr<TargetMachine> TM(Machine); // Override function attributes based on CPUStr, FeaturesStr, and command line // flags. setFunctionAttributes(CPUStr, FeaturesStr, *M); // If the output is set to be emitted to standard out, and standard out is a // console, print out a warning message and refuse to do it. We don't // impress anyone by spewing tons of binary goo to a terminal. if (!Force && !NoOutput && !AnalyzeOnly && !OutputAssembly) if (CheckBitcodeOutputToConsole(Out->os(), !Quiet)) NoOutput = true; 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; else if (VerifyEach) VK = VK_VerifyEachPass; // The user has asked to use the new pass manager and provided a pipeline // string. Hand off the rest of the functionality to the new code for that // layer. return runPassPipeline(argv[0], *M, TM.get(), Out.get(), ThinLinkOut.get(), OptRemarkFile.get(), PassPipeline, OK, VK, PreserveAssemblyUseListOrder, PreserveBitcodeUseListOrder, EmitSummaryIndex, EmitModuleHash) ? 0 : 1; } // Create a PassManager to hold and optimize the collection of passes we are // about to build. // legacy::PassManager Passes; // Add an appropriate TargetLibraryInfo pass for the module's triple. TargetLibraryInfoImpl TLII(ModuleTriple); // The -disable-simplify-libcalls flag actually disables all builtin optzns. if (DisableSimplifyLibCalls) TLII.disableAllFunctions(); Passes.add(new TargetLibraryInfoWrapperPass(TLII)); // Add internal analysis passes from the target machine. Passes.add(createTargetTransformInfoWrapperPass(TM ? TM->getTargetIRAnalysis() : TargetIRAnalysis())); std::unique_ptr<legacy::FunctionPassManager> FPasses; if (OptLevelO0 || OptLevelO1 || OptLevelO2 || OptLevelOs || OptLevelOz || OptLevelO3) { FPasses.reset(new legacy::FunctionPassManager(M.get())); FPasses->add(createTargetTransformInfoWrapperPass( TM ? TM->getTargetIRAnalysis() : TargetIRAnalysis())); } if (PrintBreakpoints) { // Default to standard output. if (!Out) { if (OutputFilename.empty()) OutputFilename = "-"; std::error_code EC; Out = llvm::make_unique<ToolOutputFile>(OutputFilename, EC, sys::fs::F_None); if (EC) { errs() << EC.message() << '\n'; return 1; } } Passes.add(createBreakpointPrinter(Out->os())); NoOutput = true; } if (TM) { // FIXME: We should dyn_cast this when supported. auto <M = static_cast<LLVMTargetMachine &>(*TM); Pass *TPC = LTM.createPassConfig(Passes); Passes.add(TPC); } // Create a new optimization pass for each one specified on the command line for (unsigned i = 0; i < PassList.size(); ++i) { if (StandardLinkOpts && StandardLinkOpts.getPosition() < PassList.getPosition(i)) { AddStandardLinkPasses(Passes); StandardLinkOpts = false; } if (OptLevelO0 && OptLevelO0.getPosition() < PassList.getPosition(i)) { AddOptimizationPasses(Passes, *FPasses, TM.get(), 0, 0); OptLevelO0 = false; } if (OptLevelO1 && OptLevelO1.getPosition() < PassList.getPosition(i)) { AddOptimizationPasses(Passes, *FPasses, TM.get(), 1, 0); OptLevelO1 = false; } if (OptLevelO2 && OptLevelO2.getPosition() < PassList.getPosition(i)) { AddOptimizationPasses(Passes, *FPasses, TM.get(), 2, 0); OptLevelO2 = false; } if (OptLevelOs && OptLevelOs.getPosition() < PassList.getPosition(i)) { AddOptimizationPasses(Passes, *FPasses, TM.get(), 2, 1); OptLevelOs = false; } if (OptLevelOz && OptLevelOz.getPosition() < PassList.getPosition(i)) { AddOptimizationPasses(Passes, *FPasses, TM.get(), 2, 2); OptLevelOz = false; } if (OptLevelO3 && OptLevelO3.getPosition() < PassList.getPosition(i)) { AddOptimizationPasses(Passes, *FPasses, TM.get(), 3, 0); OptLevelO3 = false; } const PassInfo *PassInf = PassList[i]; Pass *P = nullptr; if (PassInf->getNormalCtor()) P = PassInf->getNormalCtor()(); else errs() << argv[0] << ": cannot create pass: "******"\n"; if (P) { PassKind Kind = P->getPassKind(); addPass(Passes, P); if (AnalyzeOnly) { switch (Kind) { case PT_BasicBlock: Passes.add(createBasicBlockPassPrinter(PassInf, Out->os(), Quiet)); break; case PT_Region: Passes.add(createRegionPassPrinter(PassInf, Out->os(), Quiet)); break; case PT_Loop: Passes.add(createLoopPassPrinter(PassInf, Out->os(), Quiet)); break; case PT_Function: Passes.add(createFunctionPassPrinter(PassInf, Out->os(), Quiet)); break; case PT_CallGraphSCC: Passes.add(createCallGraphPassPrinter(PassInf, Out->os(), Quiet)); break; default: Passes.add(createModulePassPrinter(PassInf, Out->os(), Quiet)); break; } } } if (PrintEachXForm) Passes.add( createPrintModulePass(errs(), "", PreserveAssemblyUseListOrder)); } if (StandardLinkOpts) { AddStandardLinkPasses(Passes); StandardLinkOpts = false; } if (OptLevelO0) AddOptimizationPasses(Passes, *FPasses, TM.get(), 0, 0); if (OptLevelO1) AddOptimizationPasses(Passes, *FPasses, TM.get(), 1, 0); if (OptLevelO2) AddOptimizationPasses(Passes, *FPasses, TM.get(), 2, 0); if (OptLevelOs) AddOptimizationPasses(Passes, *FPasses, TM.get(), 2, 1); if (OptLevelOz) AddOptimizationPasses(Passes, *FPasses, TM.get(), 2, 2); if (OptLevelO3) AddOptimizationPasses(Passes, *FPasses, TM.get(), 3, 0); if (FPasses) { FPasses->doInitialization(); for (Function &F : *M) FPasses->run(F); FPasses->doFinalization(); } // Check that the module is well formed on completion of optimization if (!NoVerify && !VerifyEach) Passes.add(createVerifierPass()); // In run twice mode, we want to make sure the output is bit-by-bit // equivalent if we run the pass manager again, so setup two buffers and // a stream to write to them. Note that llc does something similar and it // may be worth to abstract this out in the future. SmallVector<char, 0> Buffer; SmallVector<char, 0> CompileTwiceBuffer; std::unique_ptr<raw_svector_ostream> BOS; raw_ostream *OS = nullptr; // Write bitcode or assembly to the output as the last step... if (!NoOutput && !AnalyzeOnly) { assert(Out); OS = &Out->os(); if (RunTwice) { BOS = make_unique<raw_svector_ostream>(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) Passes.add(createWriteThinLTOBitcodePass( *OS, ThinLinkOut ? &ThinLinkOut->os() : nullptr)); else Passes.add(createBitcodeWriterPass(*OS, PreserveBitcodeUseListOrder, EmitSummaryIndex, EmitModuleHash)); } // Before executing passes, print the final values of the LLVM options. cl::PrintOptionValues(); // If requested, run all passes again with the same pass manager to catch // bugs caused by persistent state in the passes if (RunTwice) { std::unique_ptr<Module> M2(CloneModule(M.get())); Passes.run(*M2); CompileTwiceBuffer = Buffer; Buffer.clear(); } // Now that we have all of the passes ready, run them. Passes.run(*M); // Compare the two outputs and make sure they're the same if (RunTwice) { assert(Out); if (Buffer.size() != CompileTwiceBuffer.size() || (memcmp(Buffer.data(), CompileTwiceBuffer.data(), Buffer.size()) != 0)) { 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"; Out->os() << BOS->str(); Out->keep(); if (OptRemarkFile) OptRemarkFile->keep(); return 1; } Out->os() << BOS->str(); } // Declare success. if (!NoOutput || PrintBreakpoints) Out->keep(); if (OptRemarkFile) OptRemarkFile->keep(); if (ThinLinkOut) ThinLinkOut->keep(); return 0; }
// main - Entry point for the llc compiler. // int main(int argc, char **argv) { sys::PrintStackTraceOnErrorSignal(argv[0]); PrettyStackTraceProgram X(argc, argv); // Enable debug stream buffering. EnableDebugBuffering = true; LLVMContext Context; llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. // Initialize targets first, so that --version shows registered targets. InitializeAllTargets(); InitializeAllTargetMCs(); InitializeAllAsmPrinters(); InitializeAllAsmParsers(); // Initialize codegen and IR passes used by llc so that the -print-after, // -print-before, and -stop-after options work. PassRegistry *Registry = PassRegistry::getPassRegistry(); initializeCore(*Registry); initializeCodeGen(*Registry); initializeLoopStrengthReducePass(*Registry); initializeLowerIntrinsicsPass(*Registry); initializeCountingFunctionInserterPass(*Registry); initializeUnreachableBlockElimLegacyPassPass(*Registry); initializeConstantHoistingLegacyPassPass(*Registry); initializeScalarOpts(*Registry); initializeVectorization(*Registry); initializeScalarizeMaskedMemIntrinPass(*Registry); initializeExpandReductionsPass(*Registry); // Initialize debugging passes. initializeScavengerTestPass(*Registry); // Register the target printer for --version. cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion); cl::ParseCommandLineOptions(argc, argv, "llvm system compiler\n"); Context.setDiscardValueNames(DiscardValueNames); // Set a diagnostic handler that doesn't exit on the first error bool HasError = false; Context.setDiagnosticHandler(DiagnosticHandler, &HasError); Context.setInlineAsmDiagnosticHandler(InlineAsmDiagHandler, &HasError); if (PassRemarksWithHotness) Context.setDiagnosticsHotnessRequested(true); if (PassRemarksHotnessThreshold) Context.setDiagnosticsHotnessThreshold(PassRemarksHotnessThreshold); std::unique_ptr<tool_output_file> YamlFile; if (RemarksFilename != "") { std::error_code EC; YamlFile = llvm::make_unique<tool_output_file>(RemarksFilename, EC, sys::fs::F_None); if (EC) { errs() << EC.message() << '\n'; return 1; } Context.setDiagnosticsOutputFile( llvm::make_unique<yaml::Output>(YamlFile->os())); } if (InputLanguage != "" && InputLanguage != "ir" && InputLanguage != "mir") { errs() << argv[0] << "Input language must be '', 'IR' or 'MIR'\n"; return 1; } // Compile the module TimeCompilations times to give better compile time // metrics. for (unsigned I = TimeCompilations; I; --I) if (int RetVal = compileModule(argv, Context)) return RetVal; if (YamlFile) YamlFile->keep(); return 0; }