/// Add the complete set of target-independent postISel code generator passes. /// /// This can be read as the standard order of major LLVM CodeGen stages. Stages /// with nontrivial configuration or multiple passes are broken out below in /// add%Stage routines. /// /// Any TargetPassConfig::addXX routine may be overriden by the Target. The /// addPre/Post methods with empty header implementations allow injecting /// target-specific fixups just before or after major stages. Additionally, /// targets have the flexibility to change pass order within a stage by /// overriding default implementation of add%Stage routines below. Each /// technique has maintainability tradeoffs because alternate pass orders are /// not well supported. addPre/Post works better if the target pass is easily /// tied to a common pass. But if it has subtle dependencies on multiple passes, /// the target should override the stage instead. /// /// TODO: We could use a single addPre/Post(ID) hook to allow pass injection /// before/after any target-independent pass. But it's currently overkill. void TargetPassConfig::addMachinePasses() { AddingMachinePasses = true; // Insert a machine instr printer pass after the specified pass. if (!StringRef(PrintMachineInstrs.getValue()).equals("") && !StringRef(PrintMachineInstrs.getValue()).equals("option-unspecified")) { const PassRegistry *PR = PassRegistry::getPassRegistry(); const PassInfo *TPI = PR->getPassInfo(PrintMachineInstrs.getValue()); const PassInfo *IPI = PR->getPassInfo(StringRef("machineinstr-printer")); assert (TPI && IPI && "Pass ID not registered!"); const char *TID = (const char *)(TPI->getTypeInfo()); const char *IID = (const char *)(IPI->getTypeInfo()); insertPass(TID, IID); } // Print the instruction selected machine code... printAndVerify("After Instruction Selection"); if (TM->Options.EnableIPRA) addPass(createRegUsageInfoPropPass()); // Expand pseudo-instructions emitted by ISel. addPass(&ExpandISelPseudosID); // Add passes that optimize machine instructions in SSA form. if (getOptLevel() != CodeGenOpt::None) { addMachineSSAOptimization(); } else { // If the target requests it, assign local variables to stack slots relative // to one another and simplify frame index references where possible. addPass(&LocalStackSlotAllocationID, false); } // Run pre-ra passes. addPreRegAlloc(); // Run register allocation and passes that are tightly coupled with it, // including phi elimination and scheduling. if (getOptimizeRegAlloc()) addOptimizedRegAlloc(createRegAllocPass(true)); else addFastRegAlloc(createRegAllocPass(false)); // Run post-ra passes. addPostRegAlloc(); // Insert prolog/epilog code. Eliminate abstract frame index references... if (getOptLevel() != CodeGenOpt::None) addPass(&ShrinkWrapID); // Prolog/Epilog inserter needs a TargetMachine to instantiate. But only // do so if it hasn't been disabled, substituted, or overridden. if (!isPassSubstitutedOrOverridden(&PrologEpilogCodeInserterID)) addPass(createPrologEpilogInserterPass(TM)); /// Add passes that optimize machine instructions after register allocation. if (getOptLevel() != CodeGenOpt::None) addMachineLateOptimization(); // Expand pseudo instructions before second scheduling pass. addPass(&ExpandPostRAPseudosID); // Run pre-sched2 passes. addPreSched2(); if (EnableImplicitNullChecks) addPass(&ImplicitNullChecksID); // Second pass scheduler. // Let Target optionally insert this pass by itself at some other // point. if (getOptLevel() != CodeGenOpt::None && !TM->targetSchedulesPostRAScheduling()) { if (MISchedPostRA) addPass(&PostMachineSchedulerID); else addPass(&PostRASchedulerID); } // GC if (addGCPasses()) { if (PrintGCInfo) addPass(createGCInfoPrinter(dbgs()), false, false); } // Basic block placement. if (getOptLevel() != CodeGenOpt::None) addBlockPlacement(); addPreEmitPass(); if (TM->Options.EnableIPRA) // Collect register usage information and produce a register mask of // clobbered registers, to be used to optimize call sites. addPass(createRegUsageInfoCollector()); addPass(&FuncletLayoutID, false); addPass(&StackMapLivenessID, false); addPass(&LiveDebugValuesID, false); addPass(&XRayInstrumentationID, false); addPass(&PatchableFunctionID, false); AddingMachinePasses = false; }
int main(int argc, char **argv) { #ifndef DEBUG_BUGPOINT llvm::sys::PrintStackTraceOnErrorSignal(); llvm::PrettyStackTraceProgram X(argc, argv); llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. #endif // Initialize passes PassRegistry &Registry = *PassRegistry::getPassRegistry(); initializeCore(Registry); initializeScalarOpts(Registry); initializeObjCARCOpts(Registry); initializeVectorization(Registry); initializeIPO(Registry); initializeAnalysis(Registry); initializeIPA(Registry); initializeTransformUtils(Registry); initializeInstCombine(Registry); initializeInstrumentation(Registry); initializeTarget(Registry); #ifdef LINK_POLLY_INTO_TOOLS polly::initializePollyPasses(Registry); #endif cl::ParseCommandLineOptions(argc, argv, "LLVM automatic testcase reducer. See\nhttp://" "llvm.org/cmds/bugpoint.html" " for more information.\n"); #ifndef DEBUG_BUGPOINT sys::SetInterruptFunction(BugpointInterruptFunction); #endif LLVMContext& Context = getGlobalContext(); // If we have an override, set it and then track the triple we want Modules // to use. if (!OverrideTriple.empty()) { TargetTriple.setTriple(Triple::normalize(OverrideTriple)); outs() << "Override triple set to '" << TargetTriple.getTriple() << "'\n"; } if (MemoryLimit < 0) { // Set the default MemoryLimit. Be sure to update the flag's description if // you change this. if (sys::RunningOnValgrind() || UseValgrind) MemoryLimit = 800; else MemoryLimit = 300; } BugDriver D(argv[0], FindBugs, TimeoutValue, MemoryLimit, UseValgrind, Context); if (D.addSources(InputFilenames)) return 1; AddToDriver PM(D); if (StandardLinkOpts) { PassManagerBuilder Builder; Builder.Inliner = createFunctionInliningPass(); Builder.populateLTOPassManager(PM); } if (OptLevelO1 || OptLevelO2 || OptLevelO3) { PassManagerBuilder Builder; if (OptLevelO1) Builder.Inliner = createAlwaysInlinerPass(); else if (OptLevelO2) Builder.Inliner = createFunctionInliningPass(225); else Builder.Inliner = createFunctionInliningPass(275); // Note that although clang/llvm-gcc use two separate passmanagers // here, it shouldn't normally make a difference. Builder.populateFunctionPassManager(PM); Builder.populateModulePassManager(PM); } for (std::vector<const PassInfo*>::iterator I = PassList.begin(), E = PassList.end(); I != E; ++I) { const PassInfo* PI = *I; D.addPass(PI->getPassArgument()); } // Bugpoint has the ability of generating a plethora of core files, so to // avoid filling up the disk, we prevent it #ifndef DEBUG_BUGPOINT sys::Process::PreventCoreFiles(); #endif std::string Error; bool Failure = D.run(Error); if (!Error.empty()) { errs() << Error; return 1; } return Failure; }
int main(int argc_, const char **argv_) { llvm::sys::PrintStackTraceOnErrorSignal(); llvm::PrettyStackTraceProgram X(argc_, argv_); if (llvm::sys::Process::FixupStandardFileDescriptors()) return 1; SmallVector<const char *, 256> argv; llvm::SpecificBumpPtrAllocator<char> ArgAllocator; std::error_code EC = llvm::sys::Process::GetArgumentVector( argv, llvm::makeArrayRef(argv_, argc_), ArgAllocator); if (EC) { llvm::errs() << "error: couldn't get arguments: " << EC.message() << '\n'; return 1; } std::string ProgName = normalizeProgramName(argv[0]); const DriverSuffix *DS = parseDriverSuffix(ProgName); llvm::BumpPtrAllocator A; llvm::StringSaver Saver(A); // Parse response files using the GNU syntax, unless we're in CL mode. There // are two ways to put clang in CL compatibility mode: argv[0] is either // clang-cl or cl, or --driver-mode=cl is on the command line. The normal // command line parsing can't happen until after response file parsing, so we // have to manually search for a --driver-mode=cl argument the hard way. // Finally, our -cc1 tools don't care which tokenization mode we use because // response files written by clang will tokenize the same way in either mode. llvm::cl::TokenizerCallback Tokenizer = &llvm::cl::TokenizeGNUCommandLine; if ((DS && DS->ModeFlag && strcmp(DS->ModeFlag, "--driver-mode=cl") == 0) || std::find_if(argv.begin(), argv.end(), [](const char *F) { return F && strcmp(F, "--driver-mode=cl") == 0; }) != argv.end()) { Tokenizer = &llvm::cl::TokenizeWindowsCommandLine; } // Determines whether we want nullptr markers in argv to indicate response // files end-of-lines. We only use this for the /LINK driver argument. bool MarkEOLs = true; if (argv.size() > 1 && StringRef(argv[1]).startswith("-cc1")) MarkEOLs = false; llvm::cl::ExpandResponseFiles(Saver, Tokenizer, argv, MarkEOLs); // Separate out templight and clang flags. templight flags are "-Xtemplight <templight_flag>" SmallVector<const char *, 256> templight_argv, clang_argv; templight_argv.push_back(argv[0]); clang_argv.push_back(argv[0]); for (int i = 1, size = argv.size(); i < size; /* in loop */ ) { if ((argv[i] != nullptr) && (strcmp(argv[i], "-Xtemplight") == 0)) { while( i < size - 1 && argv[++i] == nullptr ) /* skip EOLs */ ; templight_argv.push_back(argv[i]); // the word after -Xtemplight if( i == size - 1 ) // was this the last argument? break; while( i < size - 1 && argv[++i] == nullptr ) /* skip EOLs */ ; } else { if ((argv[i] != nullptr) && ((strcmp(argv[i], "-help") == 0) || (strcmp(argv[i], "--help") == 0))) { // Print the help for the templight options: PrintTemplightHelp(); } clang_argv.push_back(argv[i++]); // also leave -help to driver (to print its help info too) } } cl::ParseCommandLineOptions( templight_argv.size(), &templight_argv[0], "A tool to profile template instantiations in C++ code.\n"); bool CanonicalPrefixes = true; for (int i = 1, size = clang_argv.size(); i < size; ++i) { // Skip end-of-line response file markers if (clang_argv[i] == nullptr) continue; if (StringRef(clang_argv[i]) == "-no-canonical-prefixes") { CanonicalPrefixes = false; break; } } std::string Path = GetExecutablePath(clang_argv[0], CanonicalPrefixes); IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = CreateAndPopulateDiagOpts(clang_argv); TextDiagnosticPrinter *DiagClient = new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts); FixupDiagPrefixExeName(DiagClient, Path); IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs()); DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagClient); if (!DiagOpts->DiagnosticSerializationFile.empty()) { auto SerializedConsumer = clang::serialized_diags::create(DiagOpts->DiagnosticSerializationFile, &*DiagOpts, /*MergeChildRecords=*/true); Diags.setClient(new ChainedDiagnosticConsumer( Diags.takeClient(), std::move(SerializedConsumer))); } ProcessWarningOptions(Diags, *DiagOpts, /*ReportDiags=*/false); // Prepare a variable for the return value: int Res = 0; void *GetExecutablePathVP = (void *)(intptr_t) GetExecutablePath; llvm::InitializeAllTargets(); llvm::InitializeAllTargetMCs(); llvm::InitializeAllAsmPrinters(); llvm::InitializeAllAsmParsers(); #ifdef LINK_POLLY_INTO_TOOLS llvm::PassRegistry &Registry = *llvm::PassRegistry::getPassRegistry(); polly::initializePollyPasses(Registry); #endif // Handle -cc1 integrated tools, even if -cc1 was expanded from a response // file. auto FirstArg = std::find_if(clang_argv.begin() + 1, clang_argv.end(), [](const char *A) { return A != nullptr; }); bool invokeCC1 = (FirstArg != clang_argv.end() && StringRef(*FirstArg).startswith("-cc1")); if (invokeCC1) { // If -cc1 came from a response file, remove the EOL sentinels. if (MarkEOLs) { auto newEnd = std::remove(clang_argv.begin(), clang_argv.end(), nullptr); clang_argv.resize(newEnd - clang_argv.begin()); } std::unique_ptr<CompilerInstance> Clang(new CompilerInstance()); Res = !CompilerInvocation::CreateFromArgs( Clang->getInvocation(), clang_argv.begin() + 2, clang_argv.end(), Diags); // Infer the builtin include path if unspecified. if (Clang->getHeaderSearchOpts().UseBuiltinIncludes && Clang->getHeaderSearchOpts().ResourceDir.empty()) Clang->getHeaderSearchOpts().ResourceDir = CompilerInvocation::GetResourcesPath(clang_argv[0], GetExecutablePathVP); // Create the compilers actual diagnostics engine. Clang->createDiagnostics(); if (!Clang->hasDiagnostics()) { Res = 1; goto cleanup; } LocalOutputFilename = OutputFilename; // Execute the frontend actions. Res = ExecuteTemplightInvocation(Clang.get()); // When running with -disable-free, don't do any destruction or shutdown. if (Clang->getFrontendOpts().DisableFree) { if (llvm::AreStatisticsEnabled() || Clang->getFrontendOpts().ShowStats) llvm::PrintStatistics(); BuryPointer(std::move(Clang)); } } else { Driver TheDriver(Path, llvm::sys::getDefaultTargetTriple(), Diags); TheDriver.setTitle("templight"); SetInstallDir(clang_argv, TheDriver); std::set<std::string> SavedStrings; insertArgsFromProgramName(ProgName, DS, clang_argv, SavedStrings); SetBackdoorDriverOutputsFromEnvVars(TheDriver); std::unique_ptr<Compilation> C(TheDriver.BuildCompilation(clang_argv)); if(!C.get()) { Res = 1; goto cleanup; } SmallVector<std::pair<int, const Command *>, 4> FailingCommands; for (auto &J : C->getJobs()) ExecuteTemplightCommand(TheDriver, Diags, *C, J, clang_argv[0], FailingCommands); // Merge all the temp files into a single output file: if ( ! TempOutputFiles.empty() ) { if ( OutputFilename.empty() ) OutputFilename = "a"; std::string FinalOutputFilename = TemplightAction::CreateOutputFilename( nullptr, OutputFilename, InstProfiler, OutputToStdOut, MemoryProfile); if ( ( !FinalOutputFilename.empty() ) && ( FinalOutputFilename != "-" ) ) { std::error_code error; llvm::raw_fd_ostream TraceOS(FinalOutputFilename, error, llvm::sys::fs::F_None); if ( error ) { llvm::errs() << "Error: [Templight] Can not open file to write trace of template instantiations: " << FinalOutputFilename << " Error: " << error.message(); } else { for ( SmallVector< std::string, 32 >::iterator it = TempOutputFiles.begin(), it_end = TempOutputFiles.end(); it != it_end; ++it) { llvm::ErrorOr< std::unique_ptr<llvm::MemoryBuffer> > file_epbuf = llvm::MemoryBuffer::getFile(llvm::Twine(*it)); if(file_epbuf && file_epbuf.get()) { TraceOS << StringRef(file_epbuf.get()->getBufferStart(), file_epbuf.get()->getBufferEnd() - file_epbuf.get()->getBufferStart()) << '\n'; } } } } } // Remove temp files. C->CleanupFileList(C->getTempFiles()); // If the command succeeded, the number of failing commands should zero: Res = FailingCommands.size(); // Otherwise, remove result files and print extra information about abnormal // failures. for (SmallVectorImpl< std::pair<int, const Command *> >::iterator it = FailingCommands.begin(), ie = FailingCommands.end(); it != ie; ++it) { int FailRes = it->first; const Command *FailingCommand = it->second; // Remove result files if we're not saving temps. if (!C->getArgs().hasArg(options::OPT_save_temps)) { const JobAction *JA = cast<JobAction>(&FailingCommand->getSource()); C->CleanupFileMap(C->getResultFiles(), JA, true); // Failure result files are valid unless we crashed. if (FailRes < 0) C->CleanupFileMap(C->getFailureResultFiles(), JA, true); } // Print extra information about abnormal failures, if possible. const Tool &FailingTool = FailingCommand->getCreator(); if (!FailingCommand->getCreator().hasGoodDiagnostics() || FailRes != 1) { if (FailRes < 0) Diags.Report(clang::diag::err_drv_command_signalled) << FailingTool.getShortName(); else Diags.Report(clang::diag::err_drv_command_failed) << FailingTool.getShortName() << FailRes; } } } cleanup: // If any timers were active but haven't been destroyed yet, print their // results now. This happens in -disable-free mode. llvm::TimerGroup::printAll(llvm::errs()); llvm::llvm_shutdown(); #ifdef LLVM_ON_WIN32 // Exit status should not be negative on Win32, unless abnormal termination. // Once abnormal termiation was caught, negative status should not be // propagated. if (Res < 0) Res = 1; #endif // If we have multiple failing commands, we return the result of the first // failing command. return Res; }
int main(int argc, char **argv, char **envp) { // Print a stack trace if we signal out. sys::PrintStackTraceOnErrorSignal(); PrettyStackTraceProgram X(argc, argv); LLVMContext &Context = getGlobalContext(); llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. // Initialize passes PassRegistry &Registry = *PassRegistry::getPassRegistry(); initializeCore(Registry); initializeScalarOpts(Registry); initializeIPO(Registry); initializeAnalysis(Registry); initializeIPA(Registry); initializeTransformUtils(Registry); initializeInstCombine(Registry); initializeTarget(Registry); // Initial global variable above for convenience printing of program name. progname = sys::path::stem(argv[0]); // Parse the command line options cl::ParseCommandLineOptions(argc, argv, "llvm linker\n"); #if defined(_WIN32) || defined(__CYGWIN__) if (!LinkAsLibrary) { // Default to "a.exe" instead of "a.out". if (OutputFilename.getNumOccurrences() == 0) OutputFilename = "a.exe"; // If there is no suffix add an "exe" one. if (sys::path::extension(OutputFilename).empty()) OutputFilename.append(".exe"); } #endif // Generate the bitcode for the optimized module. // If -b wasn't specified, use the name specified // with -o to construct BitcodeOutputFilename. if (BitcodeOutputFilename.empty()) { BitcodeOutputFilename = OutputFilename; if (!LinkAsLibrary) BitcodeOutputFilename += ".bc"; } // Arrange for the bitcode output file to be deleted on any errors. BitcodeOutputRemover.setFile(BitcodeOutputFilename); sys::RemoveFileOnSignal(sys::Path(BitcodeOutputFilename)); // Arrange for the output file to be deleted on any errors. if (!LinkAsLibrary) { OutputRemover.setFile(OutputFilename); sys::RemoveFileOnSignal(sys::Path(OutputFilename)); } // Construct a Linker (now that Verbose is set) Linker TheLinker(progname, OutputFilename, Context, Verbose); // Keep track of the native link items (versus the bitcode items) Linker::ItemList NativeLinkItems; // Add library paths to the linker TheLinker.addPaths(LibPaths); TheLinker.addSystemPaths(); // Remove any consecutive duplicates of the same library... Libraries.erase(std::unique(Libraries.begin(), Libraries.end()), Libraries.end()); if (LinkAsLibrary) { std::vector<sys::Path> Files; for (unsigned i = 0; i < InputFilenames.size(); ++i ) Files.push_back(sys::Path(InputFilenames[i])); if (TheLinker.LinkInFiles(Files)) return 1; // Error already printed // The libraries aren't linked in but are noted as "dependent" in the // module. for (cl::list<std::string>::const_iterator I = Libraries.begin(), E = Libraries.end(); I != E ; ++I) { TheLinker.getModule()->addLibrary(*I); } } else { // Build a list of the items from our command line Linker::ItemList Items; BuildLinkItems(Items, InputFilenames, Libraries); // Link all the items together if (TheLinker.LinkInItems(Items, NativeLinkItems) ) return 1; // Error already printed } std::auto_ptr<Module> Composite(TheLinker.releaseModule()); // Optimize the module Optimize(Composite.get()); // Generate the bitcode output. GenerateBitcode(Composite.get(), BitcodeOutputFilename); // If we are not linking a library, generate either a native executable // or a JIT shell script, depending upon what the user wants. if (!LinkAsLibrary) { // If the user wants to run a post-link optimization, run it now. if (!PostLinkOpts.empty()) { std::vector<std::string> opts = PostLinkOpts; for (std::vector<std::string>::iterator I = opts.begin(), E = opts.end(); I != E; ++I) { sys::Path prog(*I); if (!prog.canExecute()) { prog = sys::Program::FindProgramByName(*I); if (prog.isEmpty()) PrintAndExit(std::string("Optimization program '") + *I + "' is not found or not executable.", Composite.get()); } // Get the program arguments sys::Path tmp_output("opt_result"); std::string ErrMsg; if (tmp_output.createTemporaryFileOnDisk(true, &ErrMsg)) PrintAndExit(ErrMsg, Composite.get()); const char* args[4]; args[0] = I->c_str(); args[1] = BitcodeOutputFilename.c_str(); args[2] = tmp_output.c_str(); args[3] = 0; if (0 == sys::Program::ExecuteAndWait(prog, args, 0,0,0,0, &ErrMsg)) { if (tmp_output.isBitcodeFile()) { sys::Path target(BitcodeOutputFilename); target.eraseFromDisk(); if (tmp_output.renamePathOnDisk(target, &ErrMsg)) PrintAndExit(ErrMsg, Composite.get(), 2); } else PrintAndExit("Post-link optimization output is not bitcode", Composite.get()); } else { PrintAndExit(ErrMsg, Composite.get()); } } } // If the user wants to generate a native executable, compile it from the // bitcode file. // // Otherwise, create a script that will run the bitcode through the JIT. if (Native) { // Name of the Assembly Language output file sys::Path AssemblyFile ( OutputFilename); AssemblyFile.appendSuffix("s"); // Mark the output files for removal. FileRemover AssemblyFileRemover(AssemblyFile.str()); sys::RemoveFileOnSignal(AssemblyFile); // Determine the locations of the llc and gcc programs. sys::Path llc = PrependMainExecutablePath("llc", argv[0], (void *)(intptr_t)&Optimize); if (llc.isEmpty()) PrintAndExit("Failed to find llc", Composite.get()); sys::Path gcc = sys::Program::FindProgramByName("gcc"); if (gcc.isEmpty()) PrintAndExit("Failed to find gcc", Composite.get()); // Generate an assembly language file for the bitcode. std::string ErrMsg; if (0 != GenerateAssembly(AssemblyFile.str(), BitcodeOutputFilename, llc, ErrMsg)) PrintAndExit(ErrMsg, Composite.get()); if (0 != GenerateNative(OutputFilename, AssemblyFile.str(), NativeLinkItems, gcc, envp, ErrMsg)) PrintAndExit(ErrMsg, Composite.get()); } else if (NativeCBE) { sys::Path CFile (OutputFilename); CFile.appendSuffix("cbe.c"); // Mark the output files for removal. FileRemover CFileRemover(CFile.str()); sys::RemoveFileOnSignal(CFile); // Determine the locations of the llc and gcc programs. sys::Path llc = PrependMainExecutablePath("llc", argv[0], (void *)(intptr_t)&Optimize); if (llc.isEmpty()) PrintAndExit("Failed to find llc", Composite.get()); sys::Path gcc = sys::Program::FindProgramByName("gcc"); if (gcc.isEmpty()) PrintAndExit("Failed to find gcc", Composite.get()); // Generate an assembly language file for the bitcode. std::string ErrMsg; if (GenerateCFile(CFile.str(), BitcodeOutputFilename, llc, ErrMsg)) PrintAndExit(ErrMsg, Composite.get()); if (GenerateNative(OutputFilename, CFile.str(), NativeLinkItems, gcc, envp, ErrMsg)) PrintAndExit(ErrMsg, Composite.get()); } else { EmitShellScript(argv, Composite.get()); } // Make the script executable... std::string ErrMsg; if (sys::Path(OutputFilename).makeExecutableOnDisk(&ErrMsg)) PrintAndExit(ErrMsg, Composite.get()); // Make the bitcode file readable and directly executable in LLEE as well if (sys::Path(BitcodeOutputFilename).makeExecutableOnDisk(&ErrMsg)) PrintAndExit(ErrMsg, Composite.get()); if (sys::Path(BitcodeOutputFilename).makeReadableOnDisk(&ErrMsg)) PrintAndExit(ErrMsg, Composite.get()); } // Operations which may fail are now complete. BitcodeOutputRemover.releaseFile(); if (!LinkAsLibrary) OutputRemover.releaseFile(); // Graceful exit return 0; }
int main(int argc, char **argv) { sys::PrintStackTraceOnErrorSignal(argv[0]); llvm::PrettyStackTraceProgram X(argc, argv); llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. LLVMContext Context; //InitializeAllTargets(); //InitializeAllTargetMCs(); // Initialize passes PassRegistry &Registry = *PassRegistry::getPassRegistry(); initializeCore(Registry); initializeScalarOpts(Registry); initializeObjCARCOpts(Registry); initializeVectorization(Registry); initializeIPO(Registry); initializeAnalysis(Registry); //initializeIPA(Registry); initializeTransformUtils(Registry); initializeInstCombine(Registry); initializeInstrumentation(Registry); initializeTarget(Registry); initializeSoaapPass(Registry); cl::ParseCommandLineOptions(argc, argv, "llvm .bc -> .bc modular optimizer and analysis printer\n"); SMDiagnostic Err; // Load the input module... std::unique_ptr<Module> M = parseIRFile(InputFilename, Err, Context); if (!M.get()) { Err.print(argv[0], errs()); return 1; } // Warn if M doesn't have debug info if (M->getNamedMetadata("llvm.dbg.cu") == NULL) { errs() << "**********************************************************\n"; errs() << "WARNING: Input IR file does not contain debug information\n"; errs() << "**********************************************************\n"; } // Figure out what stream we are supposed to write to... std::unique_ptr<tool_output_file> Out; if (!OutputFilename.empty()) { std::error_code EC; Out.reset(new tool_output_file(OutputFilename, EC, sys::fs::F_None)); if (EC) { errs() << EC.message() << '\n'; return 1; } } // Create a PassManager to hold and optimize the collection of passes we are // about to build. // legacy::PassManager Passes; Passes.add(new soaap::Soaap); // Check that the module is well formed on completion of optimization if (!OutputFilename.empty()) { if (Verify) Passes.add(createVerifierPass()); // Pass to create output if (OutputAssembly) Passes.add(createPrintModulePass(Out->os())); else Passes.add(createBitcodeWriterPass(Out->os())); } // Now that we have all of the passes ready, run them. Passes.run(*M.get()); // Declare success. if (!OutputFilename.empty()) { Out->keep(); } return 0; }
int main(int argc, char* argv[]) { std::string programName = argv[0]; try { cl::ParseCommandLineOptions( argc, argv ); SMDiagnostic Err; // Load the input module. std::auto_ptr<Module> M(ParseAssemblyFile(InputFilename, Err, Context)); if (M.get() == 0) { Err.Print(argv[0], errs()); return (1); } if (!DisableVerify) { std::string Err; if (verifyModule(*M.get(), ReturnStatusAction, &Err)) { errs() << argv[0] << ": assembly parsed, but does not verify as correct!\n"; errs() << Err; return (1); } } std::ostream *Out = new std::ofstream(OutputFilename.c_str(), std::ios::out | std::ios::trunc | std::ios::binary); if (!Out->good()) { std::cerr << programName << ": Error opening " << OutputFilename << "!\n"; return (1); } if (DumpAsm) errs() << "Here's the assembly:\n" << *M.get(); PassManager Passes; raw_os_ostream L(*Out); // Add an appropriate TargetData instance for this module. Passes.add(new TargetData("onfuscator")); Passes.add(new MakeDispatcherPass()); // Passes.add(new WriteBytecodePass(Out, true)); Passes.add(createPrintModulePass(&L)); Passes.run( *M.get() ); } catch( std::exception e ) { std::cerr << programName << ": " << e.what() << "\n"; return (1); } catch( const std::string& msg ) { std::cerr << programName << ": " << msg << "\n"; return (1); } catch( ... ) { std::cerr << programName << ": Unexpected exception occurred.\n"; return (1); } return (0); }
int LLVMFuzzerInitialize(int *argc, char ***argv) { // The command line is unusual compared to other fuzzers due to the need to // specify the target. Options like -triple, -mcpu, and -mattr work like // their counterparts in llvm-mc, while -fuzzer-args collects options for the // fuzzer itself. // // Examples: // // Fuzz the big-endian MIPS32R6 disassembler using 100,000 inputs of up to // 4-bytes each and use the contents of ./corpus as the test corpus: // llvm-mc-fuzzer -triple mips-linux-gnu -mcpu=mips32r6 -disassemble \ // -fuzzer-args -max_len=4 -runs=100000 ./corpus // // Infinitely fuzz the little-endian MIPS64R2 disassembler with the MSA // feature enabled using up to 64-byte inputs: // llvm-mc-fuzzer -triple mipsel-linux-gnu -mcpu=mips64r2 -mattr=msa \ // -disassemble -fuzzer-args ./corpus // // If your aim is to find instructions that are not tested, then it is // advisable to constrain the maximum input size to a single instruction // using -max_len as in the first example. This results in a test corpus of // individual instructions that test unique paths. Without this constraint, // there will be considerable redundancy in the corpus. char **OriginalArgv = *argv; LLVMInitializeAllTargetInfos(); LLVMInitializeAllTargetMCs(); LLVMInitializeAllAsmParsers(); cl::ParseCommandLineOptions(*argc, OriginalArgv); // Rebuild the argv without the arguments llvm-mc-fuzzer consumed so that // the driver can parse its arguments. // // FuzzerArgs cannot provide the non-const pointer that OriginalArgv needs. // Re-use the strings from OriginalArgv instead of copying FuzzerArg to a // non-const buffer to avoid the need to clean up when the fuzzer terminates. ModifiedArgv.push_back(OriginalArgv[0]); for (const auto &FuzzerArg : FuzzerArgs) { for (int i = 1; i < *argc; ++i) { if (FuzzerArg == OriginalArgv[i]) ModifiedArgv.push_back(OriginalArgv[i]); } } *argc = ModifiedArgv.size(); *argv = ModifiedArgv.data(); // Package up features to be passed to target/subtarget // We have to pass it via a global since the callback doesn't // permit any user data. if (MAttrs.size()) { SubtargetFeatures Features; for (unsigned i = 0; i != MAttrs.size(); ++i) Features.AddFeature(MAttrs[i]); FeaturesStr = Features.getString(); } if (TripleName.empty()) TripleName = sys::getDefaultTargetTriple(); return 0; }
//===----------------------------------------------------------------------===// // main for instrument // int main(int argc, char **argv) { llvm_shutdown_obj X; // Call llvm_shutdown() on exit. LLVMContext &Context = getGlobalContext(); try { cl::ParseCommandLineOptions(argc, argv, "zoltar .bc -> .bc instrumenter and mutator\n"); sys::PrintStackTraceOnErrorSignal(); // Allocate a full target machine description only if necessary. // FIXME: The choice of target should be controllable on the command line. std::auto_ptr<TargetMachine> target; std::string ErrorMessage; // Load the input module... std::auto_ptr<Module> M; if (MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(InputFilename, &ErrorMessage)) { M.reset(ParseBitcodeFile(Buffer, Context, &ErrorMessage)); delete Buffer; } if (M.get() == 0) { errs() << argv[0] << ": "; if (ErrorMessage.size()) errs() << ErrorMessage << "\n"; else errs() << "bitcode didn't read correctly.\n"; return 1; } // Figure out what stream we are supposed to write to... // FIXME: outs() is not binary! raw_ostream *Out = &outs(); // Default to printing to stdout... if (OutputFilename != "-") { std::string ErrorInfo; /*TODO: solve this problem */ //Out = new raw_fd_ostream(OutputFilename.c_str(), /*Binary=*/true, // Force, ErrorInfo); Out = new raw_fd_ostream(OutputFilename.c_str(),ErrorInfo,0); if (!ErrorInfo.empty()) { errs() << ErrorInfo << '\n'; if (!Force) errs() << "Use -f command line argument to force output\n"; delete Out; return 1; } // Make sure that the Output file gets unlinked from the disk if we get a // SIGINT sys::RemoveFileOnSignal(sys::Path(OutputFilename)); } // 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 && CheckBitcodeOutputToConsole(*Out,!Quiet)) { NoOutput = true; } // Create a PassManager to hold and optimize the collection of passes we are // about to build... // PassManager Passes; // Add an appropriate TargetData instance for this module... Passes.add(new TargetData(M.get())); // Create a new instrumentation pass for each one specified on the command line for (unsigned i = 0; i < PassList.size(); ++i) { const PassInfo *PassInf = PassList[i]; Pass *P = 0; if (PassInf->getNormalCtor()) P = PassInf->getNormalCtor()(); else errs() << argv[0] << ": cannot create pass: "******"\n"; if (P) { Passes.add(P); } } // Enable the specified mutation operators if (!MutOps) { OperatorManager* OM = OperatorManager::getInstance(); OperatorInfoList::iterator oit; for (oit = OM->getRegistered().begin(); oit != OM->getRegistered().end(); oit++) { (*oit)->setEnabled(true); } } else { for (unsigned i = 0; i < OperatorList.size(); ++i) { OperatorInfo *OInf = OperatorList[i]; OInf->setEnabled(true); } } //Passes.add(createPrintModulePass(&errs())); // Check that the module is well formed on completion of optimization Passes.add(createVerifierPass()); // Write bitcode out to disk or outs() as the last step... if (!NoOutput) Passes.add(createBitcodeWriterPass(*Out)); // Now that we have all of the passes ready, run them. Passes.run(*M.get()); // Delete the raw_fd_ostream. if (Out != &outs()) delete Out; // Write the context.dat file of zoltar ContextManager::print(); return 0; } catch (const std::string& msg) { errs() << argv[0] << ": " << msg << "\n"; } catch (...) { errs() << argv[0] << ": Unexpected unknown exception occurred.\n"; } llvm_shutdown(); return 1; }
void WorklessInstrument::InstrumentWorkless0Star1(Module * pModule, Loop * pLoop) { Function * pMain = NULL; if(strMainName != "" ) { pMain = pModule->getFunction(strMainName.c_str()); } else { pMain = pModule->getFunction("main"); } LoadInst * pLoad; BinaryOperator* pAdd = NULL; StoreInst * pStore = NULL; for (Function::iterator BB = pMain->begin(); BB != pMain->end(); ++BB) { if(BB->getName().equals("entry")) { CallInst * pCall; StoreInst * pStore; Instruction * II = BB->begin(); pCall = CallInst::Create(this->InitHooks, "", II); pCall->setCallingConv(CallingConv::C); pCall->setTailCall(false); AttributeSet emptySet; pCall->setAttributes(emptySet); pCall = CallInst::Create(this->getenv, this->SAMPLE_RATE_ptr, "", II); pCall->setCallingConv(CallingConv::C); pCall->setTailCall(false); AttributeSet AS; { SmallVector<AttributeSet, 4> Attrs; AttributeSet PAS; { AttrBuilder B; B.addAttribute(Attribute::NoUnwind); PAS = AttributeSet::get(pModule->getContext(), ~0U, B); } Attrs.push_back(PAS); AS = AttributeSet::get(pModule->getContext(), Attrs); } pCall->setAttributes(AS); pCall = CallInst::Create(this->function_atoi, pCall, "", II); pCall->setCallingConv(CallingConv::C); pCall->setTailCall(false); { SmallVector<AttributeSet, 4> Attrs; AttributeSet PAS; { AttrBuilder B; B.addAttribute(Attribute::NoUnwind); B.addAttribute(Attribute::ReadOnly); PAS = AttributeSet::get(pModule->getContext(), ~0U, B); } Attrs.push_back(PAS); AS = AttributeSet::get(pModule->getContext(), Attrs); } pCall->setAttributes(AS); pStore = new StoreInst(pCall, this->SAMPLE_RATE, false, II); pStore->setAlignment(4); pCall = CallInst::Create(this->geo, pCall, "", II); pCall->setCallingConv(CallingConv::C); pCall->setTailCall(false); pCall->setAttributes(emptySet); CastInst * pCast = CastInst::CreateIntegerCast(pCall, this->LongType, true, "", II); pStore = new StoreInst(pCast, this->CURRENT_SAMPLE, false, II); pStore->setAlignment(8); vector<Value *> vecParam; vecParam.push_back(this->Output_Format_String); vecParam.push_back(pCall); pCall = CallInst::Create(this->printf, vecParam, "", II); pCall->setCallingConv(CallingConv::C); pCall->setTailCall(false); pCall->setAttributes(emptySet); break; } } for (Function::iterator BB = pMain->begin(); BB != pMain->end(); ++BB) { for (BasicBlock::iterator Ins = BB->begin(); Ins != BB->end(); ++Ins) { if (isa<ReturnInst>(Ins) || isa<ResumeInst>(Ins)) { vector<Value*> vecParams; pLoad = new LoadInst(numIterations, "", false, Ins); pLoad->setAlignment(8); vecParams.push_back(pLoad); pLoad = new LoadInst(numInstances, "", false, Ins); pLoad->setAlignment(8); vecParams.push_back(pLoad); CallInst* pCall = CallInst::Create(this->PrintLoopInfo, vecParams, "", Ins); pCall->setCallingConv(CallingConv::C); pCall->setTailCall(false); AttributeSet aSet; pCall->setAttributes(aSet); } else if(isa<CallInst>(Ins) || isa<InvokeInst>(Ins)) { CallSite cs(Ins); Function * pCalled = cs.getCalledFunction(); if(pCalled == NULL) { continue; } if(pCalled->getName() == "exit" || pCalled->getName() == "_ZL9mysql_endi") { vector<Value*> vecParams; pLoad = new LoadInst(numIterations, "", false, Ins); pLoad->setAlignment(8); vecParams.push_back(pLoad); pLoad = new LoadInst(numInstances, "", false, Ins); pLoad->setAlignment(8); vecParams.push_back(pLoad); CallInst* pCall = CallInst::Create(this->PrintLoopInfo, vecParams, "", Ins); pCall->setCallingConv(CallingConv::C); pCall->setTailCall(false); AttributeSet aSet; pCall->setAttributes(aSet); } } } } BasicBlock * pHeader = pLoop->getHeader(); set<BasicBlock *> setExitBlock; CollectExitBlock(pLoop, setExitBlock); vector<BasicBlock *> vecAdded; CreateIfElseBlock(pLoop, vecAdded); ValueToValueMapTy VMap; set<BasicBlock *> setCloned; CloneInnerLoop(pLoop, vecAdded, VMap, setCloned); BasicBlock * pPreHeader = vecAdded[1]; pLoad = new LoadInst(this->numIterations, "", false, pPreHeader->getTerminator()); pLoad->setAlignment(8); BasicBlock * pClonedHeader = cast<BasicBlock>(VMap[pHeader]); set<BasicBlock *> setPredBlocks; for(pred_iterator PI = pred_begin(pClonedHeader), E = pred_end(pClonedHeader); PI != E; ++PI) { setPredBlocks.insert(*PI); } PHINode * pNew = PHINode::Create(pLoad->getType(), setPredBlocks.size(), "numIterations", pClonedHeader->getFirstInsertionPt()); pAdd = BinaryOperator::Create(Instruction::Add, pNew, this->ConstantLong1, "add", pClonedHeader->getFirstInsertionPt()); set<BasicBlock *>::iterator itSetBegin = setPredBlocks.begin(); set<BasicBlock *>::iterator itSetEnd = setPredBlocks.end(); for(; itSetBegin != itSetEnd; itSetBegin ++ ) { if((*itSetBegin) == pPreHeader) { pNew->addIncoming(pLoad, pPreHeader); } else { pNew->addIncoming(pAdd, *itSetBegin); } } itSetBegin = setExitBlock.begin(); itSetEnd = setExitBlock.end(); for(; itSetBegin != itSetEnd; itSetBegin ++ ) { SmallVector<BasicBlock*, 8> LoopBlocks; for(pred_iterator PI = pred_begin(*itSetBegin), E = pred_end(*itSetBegin); PI != E; ++PI) { if(setCloned.find(*PI) != setCloned.end()) { LoopBlocks.push_back(*PI); } } BasicBlock * NewExitBB = SplitBlockPredecessors(*itSetBegin, LoopBlocks, ".WL.loopexit", this); pStore = new StoreInst(pAdd, this->numIterations, false, NewExitBB->getFirstInsertionPt()); pStore->setAlignment(8); } pPreHeader->getParent()->dump(); }
int ObjectGenerator::process(Module *module) { cerr << "Starting object generation" << endl; cerr.flush(); // if (false) { // // Initialize targets first, so that --version shows registered targets. // InitializeAllTargets(); InitializeAllAsmPrinters(); // // Load the module to be compiled... // SMDiagnostic Err; Module &mod = *module; // // If we are supposed to override the target triple, do so now. // if (! TargetTriple.empty()) mod.setTargetTriple(TargetTriple); Triple TheTriple(mod.getTargetTriple()); if (TheTriple.getTriple().empty()) TheTriple.setTriple(sys::getHostTriple()); // // Allocate target machine. First, check whether the user has explicitly // specified an architecture to compile for. If so we have to look it up by // name, because it might be a backend that has no mapping to a target triple. // const Target *TheTarget = 0; if (! MArch.empty()) { for (TargetRegistry::iterator it = TargetRegistry::begin(), ie = TargetRegistry::end(); it != ie; ++it) { if (MArch == it -> getName()) { TheTarget = &*it; break; } } if (! TheTarget) { errs() << "RoseToLLVM" /*argv[0]*/ << ": error: invalid target '" << MArch << "'.\n"; return 1; } // // Adjust the triple to match (if known), otherwise stick with the // module/host triple. // Triple::ArchType Type = Triple::getArchTypeForLLVMName(MArch); if (Type != Triple::UnknownArch) TheTriple.setArch(Type); } else { std::string Err; TheTarget = TargetRegistry::lookupTarget(TheTriple.getTriple(), Err); if (TheTarget == 0) { errs() << "RoseToLLVM" /*argv[0]*/ << ": error auto-selecting target for module '" << Err << "'. Please use the -march option to explicitly " << "pick a target.\n"; return 1; } } // // Package up features to be passed to target/subtarget // std::string FeaturesStr; if (MCPU.size() || MAttrs.size()) { SubtargetFeatures Features; Features.setCPU(MCPU); for (unsigned i = 0; i != MAttrs.size(); ++i) Features.AddFeature(MAttrs[i]); FeaturesStr = Features.getString(); } std::auto_ptr<TargetMachine> target(TheTarget->createTargetMachine(TheTriple.getTriple(), FeaturesStr)); assert(target.get() && "Could not allocate target machine!"); TargetMachine &Target = *target.get(); // // Figure out where we are going to send the output... // formatted_raw_ostream *Out = GetOutputStream(TheTarget -> getName(), "RoseToLLVM"/*argv[0]*/); if (Out == 0) return 1; CodeGenOpt::Level OLvl = CodeGenOpt::Default; switch (OptLevel) { default: cerr << "The optimization level is " << OptLevel << endl; cerr.flush(); errs() << "RoseToLLVM" /*argv[0]*/ << ": invalid optimization level.\n"; return 1; case ' ': break; case '0': OLvl = CodeGenOpt::None; break; case '1': OLvl = CodeGenOpt::Less; break; case '2': OLvl = CodeGenOpt::Default; break; case '3': OLvl = CodeGenOpt::Aggressive; break; } // // Request that addPassesToEmitFile run the Verifier after running // passes which modify the IR. // #ifndef NDEBUG bool DisableVerify = false; #else bool DisableVerify = true; #endif // // If this target requires addPassesToEmitWholeFile, do it now. This is // used by strange things like the C backend. // if (Target.WantsWholeFile()) { PassManager PM; // // Add the target data from the target machine, if it exists, or the module. // if (const TargetData *TD = Target.getTargetData()) PM.add(new TargetData(*TD)); else PM.add(new TargetData(&mod)); if (! NoVerify) PM.add(createVerifierPass()); // // Ask the target to add backend passes as necessary. // // if (Target.addPassesToEmitWholeFile(PM, *Out, FileType, OLvl, DisableVerify)) { if (Target.addPassesToEmitWholeFile(PM, *Out, FileType, OLvl)) { errs() << "RoseToLLVM" /*argv[0]*/ << ": target does not support generation of this" << " file type!\n"; if (Out != &fouts()) delete Out; // And the Out file is empty and useless, so remove it now. sys::Path(OutputFilename).eraseFromDisk(); return 1; } PM.run(mod); } else { // // Build up all of the passes that we want to do to the module. // FunctionPassManager Passes(module); // // Add the target data from the target machine, if it exists, or the module. // if (const TargetData *TD = Target.getTargetData()) Passes.add(new TargetData(*TD)); else Passes.add(new TargetData(&mod)); #ifndef NDEBUG if (! NoVerify) Passes.add(createVerifierPass()); #endif // // Override default to generate verbose assembly. // Target.setAsmVerbosityDefault(true); cerr << "The file type is " << FileType << endl; cerr.flush(); // if (Target.addPassesToEmitFile(Passes, *Out, FileType, OLvl, DisableVerify)) { if (Target.addPassesToEmitFile(Passes, *Out, FileType, OLvl)) { errs() << "RoseToLLVM" /*argv[0]*/ << ": target does not support generation of this" << " file type!\n"; if (Out != &fouts()) delete Out; // And the Out file is empty and useless, so remove it now. sys::Path(OutputFilename).eraseFromDisk(); return 1; } Passes.doInitialization(); // // Run our queue of passes all at once now, efficiently. // TODO: this could lazily stream functions out of the module. // for (Module::iterator I = mod.begin(), E = mod.end(); I != E; ++I) if (! I -> isDeclaration()) { if (DisableRedZone) I -> addFnAttr(Attribute::NoRedZone); if (NoImplicitFloats) I -> addFnAttr(Attribute::NoImplicitFloat); Passes.run(*I); } Passes.doFinalization(); } // // Delete the ostream if it's not a stdout stream // if (Out != &fouts()) delete Out; // } cerr << "Done with object generation" << endl; cerr.flush(); }
formatted_raw_ostream *ObjectGenerator::GetOutputStream(const char *TargetName, const char *ProgName) { if (OutputFilename != "") { if (OutputFilename == "-") return &fouts(); // // Make sure that the Out file gets unlinked from the disk if we get a // SIGINT // sys::RemoveFileOnSignal(sys::Path(OutputFilename)); std::string error; raw_fd_ostream *FDOut = new raw_fd_ostream(OutputFilename.c_str(), error, raw_fd_ostream::F_Binary); if (! error.empty()) { errs() << error << '\n'; delete FDOut; return 0; } formatted_raw_ostream *Out = new formatted_raw_ostream(*FDOut, formatted_raw_ostream::DELETE_STREAM); return Out; } if (InputFilename == "-") { OutputFilename = "-"; return &fouts(); } OutputFilename = GetFileNameRoot(InputFilename); bool Binary = false; switch (FileType) { default: assert(0 && "Unknown file type"); case TargetMachine::CGFT_AssemblyFile: if (TargetName[0] == 'c') { if (TargetName[1] == 0) OutputFilename += ".cbe.c"; else if (TargetName[1] == 'p' && TargetName[2] == 'p') OutputFilename += ".cpp"; else OutputFilename += ".s"; } else OutputFilename += ".s"; break; case TargetMachine::CGFT_ObjectFile: OutputFilename += ".o"; Binary = true; break; // case TargetMachine::CGFT_Null: // OutputFilename += ".null"; // Binary = true; // break; } // // Make sure that the Out file gets unlinked from the disk if we get a // SIGINT // sys::RemoveFileOnSignal(sys::Path(OutputFilename)); std::string error; unsigned OpenFlags = 0; if (Binary) OpenFlags |= raw_fd_ostream::F_Binary; raw_fd_ostream *FDOut = new raw_fd_ostream(OutputFilename.c_str(), error, OpenFlags); if (!error.empty()) { errs() << error << '\n'; delete FDOut; return 0; } formatted_raw_ostream *Out = new formatted_raw_ostream(*FDOut, formatted_raw_ostream::DELETE_STREAM); return Out; }
int main(int argc, char **argv) { // Print a stack trace if we signal out. sys::PrintStackTraceOnErrorSignal(); PrettyStackTraceProgram X(argc, argv); LLVMContext &Context = getGlobalContext(); llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. cl::ParseCommandLineOptions(argc, argv, "llvm .bc -> .ll disassembler\n"); std::string ErrorMessage; std::auto_ptr<Module> M; { OwningPtr<MemoryBuffer> BufferPtr; if (error_code ec = MemoryBuffer::getFileOrSTDIN(InputFilename, BufferPtr)) ErrorMessage = ec.message(); else M.reset(ParseBitcodeFile(BufferPtr.get(), Context, &ErrorMessage)); } if (M.get() == 0) { errs() << argv[0] << ": "; if (ErrorMessage.size()) errs() << ErrorMessage << "\n"; else errs() << "bitcode didn't read correctly.\n"; return 1; } // Just use stdout. We won't actually print anything on it. if (DontPrint) OutputFilename = "-"; if (OutputFilename.empty()) { // Unspecified output, infer it. if (InputFilename == "-") { OutputFilename = "-"; } else { const std::string &IFN = InputFilename; int Len = IFN.length(); // If the source ends in .bc, strip it off. if (IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c') OutputFilename = std::string(IFN.begin(), IFN.end()-3)+".ll"; else OutputFilename = IFN+".ll"; } } std::string ErrorInfo; OwningPtr<tool_output_file> Out(new tool_output_file(OutputFilename.c_str(), ErrorInfo, raw_fd_ostream::F_Binary)); if (!ErrorInfo.empty()) { errs() << ErrorInfo << '\n'; return 1; } OwningPtr<AssemblyAnnotationWriter> Annotator; if (ShowAnnotations) Annotator.reset(new CommentWriter()); // All that llvm-dis does is write the assembly to a file. if (!DontPrint) M->print(Out->os(), Annotator.get()); // Declare success. Out->keep(); return 0; }
int main(int argc, char **argv) { // Print a stack trace if we signal out. sys::PrintStackTraceOnErrorSignal(); PrettyStackTraceProgram X(argc, argv); llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. try { cl::ParseCommandLineOptions(argc, argv, "llvm .bc -> .ll disassembler\n"); std::ostream *Out = &std::cout; // Default to printing to stdout. std::string ErrorMessage; std::auto_ptr<Module> M; if (MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(InputFilename, &ErrorMessage)) { M.reset(ParseBitcodeFile(Buffer, &ErrorMessage)); delete Buffer; } if (M.get() == 0) { cerr << argv[0] << ": "; if (ErrorMessage.size()) cerr << ErrorMessage << "\n"; else cerr << "bitcode didn't read correctly.\n"; return 1; } if (DontPrint) { // Just use stdout. We won't actually print anything on it. } else if (OutputFilename != "") { // Specified an output filename? if (OutputFilename != "-") { // Not stdout? if (!Force && std::ifstream(OutputFilename.c_str())) { // If force is not specified, make sure not to overwrite a file! cerr << argv[0] << ": error opening '" << OutputFilename << "': file exists! Sending to standard output.\n"; } else { Out = new std::ofstream(OutputFilename.c_str()); } } } else { if (InputFilename == "-") { OutputFilename = "-"; } else { std::string IFN = InputFilename; int Len = IFN.length(); if (IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c') { // Source ends in .bc OutputFilename = std::string(IFN.begin(), IFN.end()-3)+".ll"; } else { OutputFilename = IFN+".ll"; } if (!Force && std::ifstream(OutputFilename.c_str())) { // If force is not specified, make sure not to overwrite a file! cerr << argv[0] << ": error opening '" << OutputFilename << "': file exists! Sending to standard output.\n"; } else { Out = new std::ofstream(OutputFilename.c_str()); // Make sure that the Out file gets unlinked from the disk if we get a // SIGINT sys::RemoveFileOnSignal(sys::Path(OutputFilename)); } } } if (!Out->good()) { cerr << argv[0] << ": error opening " << OutputFilename << ": sending to stdout instead!\n"; Out = &std::cout; } // All that llvm-dis does is write the assembly to a file. if (!DontPrint) { PassManager Passes; raw_os_ostream L(*Out); Passes.add(createPrintModulePass(&L)); Passes.run(*M.get()); } if (Out != &std::cout) { ((std::ofstream*)Out)->close(); delete Out; } return 0; } catch (const std::string& msg) { cerr << argv[0] << ": " << msg << "\n"; } catch (...) { cerr << argv[0] << ": Unexpected unknown exception occurred.\n"; } return 1; }
/// Return true if the default global register allocator is in use and /// has not be overriden on the command line with '-regalloc=...' bool TargetPassConfig::usingDefaultRegAlloc() const { return RegAlloc.getNumOccurrences() == 0; }
//Command line decoder control void startCmdLine(){ LLVMContext &Context = getGlobalContext(); for (unsigned int i =0 ; i < PassList.size(); i++ ){ cout << "Pass added: "<< PassList[i]->getPassName() << endl; cout << "Argument name :" << PassList[i]->getPassArgument() << endl; } clock_t timer = clock(); //Parsing XDF file std::cout << "Parsing file " << XDFFile.getValue() << "." << endl; XDFParser xdfParser(Verbose); Network* network = xdfParser.parseFile(XDFFile, Context); cout << "Network parsed in : "<< (clock() - timer) * 1000 / CLOCKS_PER_SEC << " ms, start engine" << endl; //Parsing XCF file if needed if(XCFFile != "") { std::cout << "Parsing file " << XCFFile.getValue() << "." << endl; XCFParser xcfParser(Verbose); map<string, string>* mapping = xcfParser.parseFile(XCFFile); network->setMapping(mapping); } if (enableTrace){ setTraces(network); } //Load network engine->load(network); // Optimizing decoder if (optLevel > 0){ engine->optimize(network, optLevel); } // Verify the given decoder if needed if (Verify){ engine->verify(network, "error.txt"); } // Set input file input_file = (char*)VidFile.c_str(); // Print the given decoder if needed if (OutputDir != ""){ engine->print(network); } //Run network engine->run(network); cout << "End of Jade" << endl; cout << "Total time: " << (clock() - timer) * 1000 / CLOCKS_PER_SEC << " ms" << endl; if(XCFFile != "") { cout << "Note: This execution time is calculated from CPU clock. When more than 1 thread were run, " "the value displayed is higher than the real execution time." << endl; } }
void WorklessInstrument::InstrumentWorkless0Or1Star(Module * pModule, Loop * pLoop, set<string> & setWorkingBlocks) { LoadInst * pLoad0 = NULL; LoadInst * pLoad1 = NULL; //BinaryOperator* pAdd = NULL; StoreInst * pStore = NULL; CallInst * pCall = NULL; Function * pMain = NULL; if(strMainName != "" ) { pMain = pModule->getFunction(strMainName.c_str()); } else { pMain = pModule->getFunction("main"); } for (Function::iterator BB = pMain->begin(); BB != pMain->end(); ++BB) { if(BB->getName().equals("entry")) { CallInst * pCall; StoreInst * pStore; Instruction * II = BB->begin(); pCall = CallInst::Create(this->InitHooks, "", II); pCall->setCallingConv(CallingConv::C); pCall->setTailCall(false); AttributeSet emptySet; pCall->setAttributes(emptySet); pCall = CallInst::Create(this->getenv, this->SAMPLE_RATE_ptr, "", II); pCall->setCallingConv(CallingConv::C); pCall->setTailCall(false); AttributeSet AS; { SmallVector<AttributeSet, 4> Attrs; AttributeSet PAS; { AttrBuilder B; B.addAttribute(Attribute::NoUnwind); PAS = AttributeSet::get(pModule->getContext(), ~0U, B); } Attrs.push_back(PAS); AS = AttributeSet::get(pModule->getContext(), Attrs); } pCall->setAttributes(AS); pCall = CallInst::Create(this->function_atoi, pCall, "", II); pCall->setCallingConv(CallingConv::C); pCall->setTailCall(false); { SmallVector<AttributeSet, 4> Attrs; AttributeSet PAS; { AttrBuilder B; B.addAttribute(Attribute::NoUnwind); B.addAttribute(Attribute::ReadOnly); PAS = AttributeSet::get(pModule->getContext(), ~0U, B); } Attrs.push_back(PAS); AS = AttributeSet::get(pModule->getContext(), Attrs); } pCall->setAttributes(AS); pStore = new StoreInst(pCall, this->SAMPLE_RATE, false, II); pStore->setAlignment(4); pCall = CallInst::Create(this->geo, pCall, "", II); pCall->setCallingConv(CallingConv::C); pCall->setTailCall(false); pCall->setAttributes(emptySet); CastInst * pCast = CastInst::CreateIntegerCast(pCall, this->LongType, true, "", II); pStore = new StoreInst(pCast, this->CURRENT_SAMPLE, false, II); pStore->setAlignment(8); vector<Value *> vecParam; vecParam.push_back(this->Output_Format_String); vecParam.push_back(pCall); pCall = CallInst::Create(this->printf, vecParam, "", II); pCall->setCallingConv(CallingConv::C); pCall->setTailCall(false); pCall->setAttributes(emptySet); break; } } for (Function::iterator BB = pMain->begin(); BB != pMain->end(); ++BB) { for (BasicBlock::iterator Ins = BB->begin(); Ins != BB->end(); ++Ins) { if (isa<ReturnInst>(Ins) || isa<ResumeInst>(Ins)) { vector<Value*> vecParams; pLoad0 = new LoadInst(numIterations, "", false, Ins); pLoad0->setAlignment(8); vecParams.push_back(pLoad0); pLoad1 = new LoadInst(numInstances, "", false, Ins); pLoad1->setAlignment(8); vecParams.push_back(pLoad1); pCall = CallInst::Create(this->PrintLoopInfo, vecParams, "", Ins); pCall->setCallingConv(CallingConv::C); pCall->setTailCall(false); AttributeSet aSet; pCall->setAttributes(aSet); vecParams.clear(); pLoad0 = new LoadInst(numIterations, "", false, Ins); pLoad0->setAlignment(8); vecParams.push_back(pLoad0); pLoad1 = new LoadInst(numWorkingIterations, "", false, Ins); pLoad1->setAlignment(8); vecParams.push_back(pLoad1); pCall = CallInst::Create(PrintWorkingRatio, vecParams, "", Ins); pCall->setCallingConv(CallingConv::C); pCall->setTailCall(false); pCall->setAttributes(aSet); } else if(isa<CallInst>(Ins) || isa<InvokeInst>(Ins)) { CallSite cs(Ins); Function * pCalled = cs.getCalledFunction(); if(pCalled == NULL) { continue; } if(pCalled->getName() == "exit" || pCalled->getName() == "_ZL9mysql_endi") { vector<Value*> vecParams; pLoad0 = new LoadInst(numIterations, "", false, Ins); pLoad0->setAlignment(8); vecParams.push_back(pLoad0); pLoad1 = new LoadInst(numInstances, "", false, Ins); pLoad1->setAlignment(8); vecParams.push_back(pLoad1); pCall = CallInst::Create(this->PrintLoopInfo, vecParams, "", Ins); pCall->setCallingConv(CallingConv::C); pCall->setTailCall(false); AttributeSet aSet; pCall->setAttributes(aSet); vecParams.clear(); pLoad0 = new LoadInst(numIterations, "", false, Ins); pLoad0->setAlignment(8); vecParams.push_back(pLoad0); pLoad1 = new LoadInst(numWorkingIterations, "", false, Ins); pLoad1->setAlignment(8); vecParams.push_back(pLoad1); pCall = CallInst::Create(PrintWorkingRatio, vecParams, "", Ins); pCall->setCallingConv(CallingConv::C); pCall->setTailCall(false); pCall->setAttributes(aSet); } } } } Function * pFunction = pLoop->getHeader()->getParent(); BasicBlock * pEntry = &(pFunction->getEntryBlock()); AllocaInst * pAlloc = new AllocaInst(this->LongType, "bWorkingIteration.local", pEntry->getFirstInsertionPt()); vector<BasicBlock *> vecWorkingBlock; for(Function::iterator BB = pFunction->begin(); BB != pFunction->end(); ++ BB) { if(setWorkingBlocks.find(BB->getName()) != setWorkingBlocks.end() ) { vecWorkingBlock.push_back(BB); } } errs() << "working block number: " << vecWorkingBlock.size() << "\n"; BasicBlock * pHeader = pLoop->getHeader(); set<BasicBlock *> setExitBlock; CollectExitBlock(pLoop, setExitBlock); vector<BasicBlock *> vecAdded; CreateIfElseBlock(pLoop, vecAdded); ValueToValueMapTy VMap; set<BasicBlock *> setCloned; CloneInnerLoop(pLoop, vecAdded, VMap, setCloned); //BasicBlock * pPreHeader = vecAdded[0]; BasicBlock * pElseBody = vecAdded[1]; vector<BasicBlock *>::iterator itVecBegin = vecWorkingBlock.begin(); vector<BasicBlock *>::iterator itVecEnd = vecWorkingBlock.end(); for(; itVecBegin != itVecEnd; itVecBegin++ ) { BasicBlock * pClonedBlock = cast<BasicBlock>(VMap[*itVecBegin]); pStore = new StoreInst(this->ConstantLong1, pAlloc, false, pClonedBlock->getFirstInsertionPt()); pStore->setAlignment(8); pClonedBlock->dump(); } pStore = new StoreInst(this->ConstantLong0, pAlloc, false, pElseBody->getTerminator()); pStore->setAlignment(8); pLoad0 = new LoadInst(this->numIterations, "", false, pElseBody->getTerminator()); pLoad0->setAlignment(8); pLoad1 = new LoadInst(this->numWorkingIterations, "", false, pElseBody->getTerminator()); pLoad1->setAlignment(8); BasicBlock * pClonedHeader = cast<BasicBlock>(VMap[pHeader]); set<BasicBlock *> setPredBlocks; for(pred_iterator PI = pred_begin(pClonedHeader), E = pred_end(pClonedHeader); PI != E; ++PI) { setPredBlocks.insert(*PI); } BasicBlock::iterator itInsert = pClonedHeader->getFirstInsertionPt(); PHINode * pNewIterations = PHINode::Create(pLoad0->getType(), setPredBlocks.size(), "numIterations.2", itInsert); PHINode * pNewWorkingIterations = PHINode::Create(pLoad1->getType(), setPredBlocks.size(), "WorkingIterations.2", itInsert); BinaryOperator * pIterationAdd = BinaryOperator::Create(Instruction::Add, pNewIterations, this->ConstantLong1, "Iterations.add.2", itInsert); set<BasicBlock *>::iterator itSetBegin = setPredBlocks.begin(); set<BasicBlock *>::iterator itSetEnd = setPredBlocks.end(); for(; itSetBegin != itSetEnd; itSetBegin ++ ) { if((*itSetBegin) == pElseBody) { pNewIterations->addIncoming(pLoad0, pElseBody); } else { pNewIterations->addIncoming(pIterationAdd, *itSetBegin); } } pLoad0 = new LoadInst(pAlloc, "", false, itInsert); BinaryOperator * pWorkingAdd = BinaryOperator::Create(Instruction::Add, pNewWorkingIterations, pLoad0, "Working.add.2", itInsert); itSetBegin = setPredBlocks.begin(); itSetEnd = setPredBlocks.end(); for(; itSetBegin != itSetEnd; itSetBegin ++ ) { if((*itSetBegin) == pElseBody) { pNewWorkingIterations->addIncoming(pLoad1, pElseBody); } else { pNewWorkingIterations->addIncoming(pWorkingAdd, *itSetBegin); } } pStore = new StoreInst(this->ConstantLong0, pAlloc, false, itInsert); pStore->setAlignment(8); itSetBegin = setExitBlock.begin(); itSetEnd = setExitBlock.end(); for(; itSetBegin != itSetEnd; itSetBegin ++ ) { SmallVector<BasicBlock*, 8> LoopBlocks; for(pred_iterator PI = pred_begin(*itSetBegin), E = pred_end(*itSetBegin); PI != E; ++PI) { if(setCloned.find(*PI) != setCloned.end()) { LoopBlocks.push_back(*PI); } } BasicBlock * NewExitBB = SplitBlockPredecessors(*itSetBegin, LoopBlocks, ".WL.loopexit", this); pStore = new StoreInst(pIterationAdd, this->numIterations, false, NewExitBB->getFirstInsertionPt()); pStore->setAlignment(8); pStore = new StoreInst(pWorkingAdd, this->numWorkingIterations, false, NewExitBB->getFirstInsertionPt()); pStore->setAlignment(8); } //pFunction->dump(); DominatorTree * DT = &(getAnalysis<DominatorTree>(*pFunction)); vector<AllocaInst *> vecAlloc; vecAlloc.push_back(pAlloc); PromoteMemToReg(vecAlloc, *DT); pFunction->dump(); }
// Scatter sections in all directions! // Remaps section addresses for -verify mode. The following command line options // can be used to customize the layout of the memory within the phony target's // address space: // -target-addr-start <s> -- Specify where the phony target addres range starts. // -target-addr-end <e> -- Specify where the phony target address range ends. // -target-section-sep <d> -- Specify how big a gap should be left between the // end of one section and the start of the next. // Defaults to zero. Set to something big // (e.g. 1 << 32) to stress-test stubs, GOTs, etc. // static void remapSectionsAndSymbols(const llvm::Triple &TargetTriple, TrivialMemoryManager &MemMgr, RuntimeDyldChecker &Checker) { // Set up a work list (section addr/size pairs). typedef std::list<std::pair<void*, uint64_t>> WorklistT; WorklistT Worklist; for (const auto& CodeSection : MemMgr.FunctionMemory) Worklist.push_back(std::make_pair(CodeSection.base(), CodeSection.size())); for (const auto& DataSection : MemMgr.DataMemory) Worklist.push_back(std::make_pair(DataSection.base(), DataSection.size())); // Apply any section-specific mappings that were requested on the command // line. typedef std::map<void*, uint64_t> AppliedMappingsT; AppliedMappingsT AppliedMappings = applySpecificSectionMappings(Checker); // Keep an "already allocated" mapping of section target addresses to sizes. // Sections whose address mappings aren't specified on the command line will // allocated around the explicitly mapped sections while maintaining the // minimum separation. std::map<uint64_t, uint64_t> AlreadyAllocated; // Move the previously applied mappings into the already-allocated map. for (WorklistT::iterator I = Worklist.begin(), E = Worklist.end(); I != E;) { WorklistT::iterator Tmp = I; ++I; AppliedMappingsT::iterator AI = AppliedMappings.find(Tmp->first); if (AI != AppliedMappings.end()) { AlreadyAllocated[AI->second] = Tmp->second; Worklist.erase(Tmp); } } // If the -target-addr-end option wasn't explicitly passed, then set it to a // sensible default based on the target triple. if (TargetAddrEnd.getNumOccurrences() == 0) { if (TargetTriple.isArch16Bit()) TargetAddrEnd = (1ULL << 16) - 1; else if (TargetTriple.isArch32Bit()) TargetAddrEnd = (1ULL << 32) - 1; // TargetAddrEnd already has a sensible default for 64-bit systems, so // there's nothing to do in the 64-bit case. } // Process any elements remaining in the worklist. while (!Worklist.empty()) { std::pair<void*, uint64_t> CurEntry = Worklist.front(); Worklist.pop_front(); uint64_t NextSectionAddr = TargetAddrStart; for (const auto &Alloc : AlreadyAllocated) if (NextSectionAddr + CurEntry.second + TargetSectionSep <= Alloc.first) break; else NextSectionAddr = Alloc.first + Alloc.second + TargetSectionSep; AlreadyAllocated[NextSectionAddr] = CurEntry.second; Checker.getRTDyld().mapSectionAddress(CurEntry.first, NextSectionAddr); } // Add dummy symbols to the memory manager. for (const auto &Mapping : DummySymbolMappings) { size_t EqualsIdx = Mapping.find_first_of("="); if (EqualsIdx == StringRef::npos) report_fatal_error("Invalid dummy symbol specification '" + Mapping + "'. Should be '<symbol name>=<addr>'"); std::string Symbol = Mapping.substr(0, EqualsIdx); std::string AddrStr = Mapping.substr(EqualsIdx + 1); uint64_t Addr; if (StringRef(AddrStr).getAsInteger(0, Addr)) report_fatal_error("Invalid symbol mapping '" + Mapping + "'."); MemMgr.addDummySymbol(Symbol, Addr); } }
/// Determine if it is profitable to duplicate this block. bool TailDuplicatePass::shouldTailDuplicate(const MachineFunction &MF, bool IsSimple, MachineBasicBlock &TailBB) { // Only duplicate blocks that end with unconditional branches. if (TailBB.canFallThrough()) return false; // Don't try to tail-duplicate single-block loops. if (TailBB.isSuccessor(&TailBB)) return false; // Set the limit on the cost to duplicate. When optimizing for size, // duplicate only one, because one branch instruction can be eliminated to // compensate for the duplication. unsigned MaxDuplicateCount; if (TailDuplicateSize.getNumOccurrences() == 0 && // FIXME: Use Function::optForSize(). MF.getFunction()->hasFnAttribute(Attribute::OptimizeForSize)) MaxDuplicateCount = 1; else MaxDuplicateCount = TailDuplicateSize; // If the target has hardware branch prediction that can handle indirect // branches, duplicating them can often make them predictable when there // are common paths through the code. The limit needs to be high enough // to allow undoing the effects of tail merging and other optimizations // that rearrange the predecessors of the indirect branch. bool HasIndirectbr = false; if (!TailBB.empty()) HasIndirectbr = TailBB.back().isIndirectBranch(); if (HasIndirectbr && PreRegAlloc) MaxDuplicateCount = 20; // Check the instructions in the block to determine whether tail-duplication // is invalid or unlikely to be profitable. unsigned InstrCount = 0; for (MachineInstr &MI : TailBB) { // Non-duplicable things shouldn't be tail-duplicated. if (MI.isNotDuplicable()) return false; // Do not duplicate 'return' instructions if this is a pre-regalloc run. // A return may expand into a lot more instructions (e.g. reload of callee // saved registers) after PEI. if (PreRegAlloc && MI.isReturn()) return false; // Avoid duplicating calls before register allocation. Calls presents a // barrier to register allocation so duplicating them may end up increasing // spills. if (PreRegAlloc && MI.isCall()) return false; if (!MI.isPHI() && !MI.isDebugValue()) InstrCount += 1; if (InstrCount > MaxDuplicateCount) return false; } if (HasIndirectbr && PreRegAlloc) return true; if (IsSimple) return true; if (!PreRegAlloc) return true; return canCompletelyDuplicateBB(TailBB); }
/// runOnMachineFunction - Insert prolog/epilog code and replace abstract /// frame indexes with appropriate references. /// bool PEI::runOnMachineFunction(MachineFunction &Fn) { const Function* F = Fn.getFunction(); const TargetRegisterInfo *TRI = Fn.getSubtarget().getRegisterInfo(); const TargetFrameLowering *TFI = Fn.getSubtarget().getFrameLowering(); assert(!Fn.getRegInfo().getNumVirtRegs() && "Regalloc must assign all vregs"); RS = TRI->requiresRegisterScavenging(Fn) ? new RegScavenger() : nullptr; FrameIndexVirtualScavenging = TRI->requiresFrameIndexScavenging(Fn); // Calculate the MaxCallFrameSize and AdjustsStack variables for the // function's frame information. Also eliminates call frame pseudo // instructions. calculateCallsInformation(Fn); // Determine which of the registers in the callee save list should be saved. BitVector SavedRegs; TFI->determineCalleeSaves(Fn, SavedRegs, RS); // Insert spill code for any callee saved registers that are modified. assignCalleeSavedSpillSlots(Fn, SavedRegs); // Determine placement of CSR spill/restore code: // place all spills in the entry block, all restores in return blocks. calculateSets(Fn); // Add the code to save and restore the callee saved registers. if (!F->hasFnAttribute(Attribute::Naked)) insertCSRSpillsAndRestores(Fn); // Allow the target machine to make final modifications to the function // before the frame layout is finalized. TFI->processFunctionBeforeFrameFinalized(Fn, RS); // Calculate actual frame offsets for all abstract stack objects... calculateFrameObjectOffsets(Fn); // Add prolog and epilog code to the function. This function is required // to align the stack frame as necessary for any stack variables or // called functions. Because of this, calculateCalleeSavedRegisters() // must be called before this function in order to set the AdjustsStack // and MaxCallFrameSize variables. if (!F->hasFnAttribute(Attribute::Naked)) insertPrologEpilogCode(Fn); // Replace all MO_FrameIndex operands with physical register references // and actual offsets. // replaceFrameIndices(Fn); // If register scavenging is needed, as we've enabled doing it as a // post-pass, scavenge the virtual registers that frame index elimination // inserted. if (TRI->requiresRegisterScavenging(Fn) && FrameIndexVirtualScavenging) scavengeFrameVirtualRegs(Fn); // Clear any vregs created by virtual scavenging. Fn.getRegInfo().clearVirtRegs(); // Warn on stack size when we exceeds the given limit. MachineFrameInfo *MFI = Fn.getFrameInfo(); uint64_t StackSize = MFI->getStackSize(); if (WarnStackSize.getNumOccurrences() > 0 && WarnStackSize < StackSize) { DiagnosticInfoStackSize DiagStackSize(*F, StackSize); F->getContext().diagnose(DiagStackSize); } delete RS; SaveBlocks.clear(); RestoreBlocks.clear(); MFI->setSavePoint(nullptr); MFI->setRestorePoint(nullptr); return true; }
int main(int argc, char **argv) { // Print a stack trace if we signal out. sys::PrintStackTraceOnErrorSignal(); PrettyStackTraceProgram X(argc, argv); LLVMContext &Context = getGlobalContext(); llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. cl::ParseCommandLineOptions(argc, argv, "llvm .bc -> .ll disassembler\n"); std::string ErrorMessage; OwningPtr<Module> M; // Use the bitcode streaming interface DataStreamer *streamer = getDataFileStreamer(InputFilename, &ErrorMessage); if (streamer) { std::string DisplayFilename; if (InputFilename == "-") DisplayFilename = "<stdin>"; else DisplayFilename = InputFilename; // @LOCALMOD-BEGIN switch (InputFileFormat) { case LLVMFormat: M.reset(getStreamedBitcodeModule(DisplayFilename, streamer, Context, &ErrorMessage)); break; case PNaClFormat: M.reset(getNaClStreamedBitcodeModule(DisplayFilename, streamer, Context, &ErrorMessage)); break; default: ErrorMessage = "Don't understand specified bitcode format"; break; } // @LOCALMOD-END if(M.get() != 0 && M->MaterializeAllPermanently(&ErrorMessage)) { M.reset(); } } if (M.get() == 0) { errs() << argv[0] << ": "; if (ErrorMessage.size()) errs() << ErrorMessage << "\n"; else errs() << "bitcode didn't read correctly.\n"; return 1; } // Just use stdout. We won't actually print anything on it. if (DontPrint) OutputFilename = "-"; if (OutputFilename.empty()) { // Unspecified output, infer it. if (InputFilename == "-" || DumpMetadata) { // @LOCALMOD OutputFilename = "-"; } else { const std::string &IFN = InputFilename; int Len = IFN.length(); // If the source ends in .bc, strip it off. if (IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c') OutputFilename = std::string(IFN.begin(), IFN.end()-3)+".ll"; else OutputFilename = IFN+".ll"; } } std::string ErrorInfo; OwningPtr<tool_output_file> Out(new tool_output_file(OutputFilename.c_str(), ErrorInfo, raw_fd_ostream::F_Binary)); if (!ErrorInfo.empty()) { errs() << ErrorInfo << '\n'; return 1; } // @LOCALMOD-BEGIN if (DumpMetadata) { M->dumpMeta(Out->os()); Out->keep(); return 0; } // @LOCALMOD-END OwningPtr<AssemblyAnnotationWriter> Annotator; if (ShowAnnotations) Annotator.reset(new CommentWriter()); // All that llvm-dis does is write the assembly to a file. if (!DontPrint) M->print(Out->os(), Annotator.get()); // Declare success. Out->keep(); return 0; }
/// EmitShellScript - Output the wrapper file that invokes the JIT on the LLVM /// bitcode file for the program. static void EmitShellScript(char **argv, Module *M) { if (Verbose) errs() << "Emitting Shell Script\n"; #if defined(_WIN32) // Windows doesn't support #!/bin/sh style shell scripts in .exe files. To // support windows systems, we copy the llvm-stub.exe executable from the // build tree to the destination file. std::string ErrMsg; sys::Path llvmstub = PrependMainExecutablePath("llvm-stub", argv[0], (void *)(intptr_t)&Optimize); if (llvmstub.isEmpty()) PrintAndExit("Could not find llvm-stub.exe executable!", M); if (0 != sys::CopyFile(sys::Path(OutputFilename), llvmstub, &ErrMsg)) PrintAndExit(ErrMsg, M); return; #endif // Output the script to start the program... std::string ErrorInfo; tool_output_file Out2(OutputFilename.c_str(), ErrorInfo); if (!ErrorInfo.empty()) PrintAndExit(ErrorInfo, M); Out2.os() << "#!/bin/sh\n"; // Allow user to setenv LLVMINTERP if lli is not in their PATH. Out2.os() << "lli=${LLVMINTERP-lli}\n"; Out2.os() << "exec $lli \\\n"; // gcc accepts -l<lib> and implicitly searches /lib and /usr/lib. LibPaths.push_back("/lib"); LibPaths.push_back("/usr/lib"); LibPaths.push_back("/usr/X11R6/lib"); // We don't need to link in libc! In fact, /usr/lib/libc.so may not be a // shared object at all! See RH 8: plain text. std::vector<std::string>::iterator libc = std::find(Libraries.begin(), Libraries.end(), "c"); if (libc != Libraries.end()) Libraries.erase(libc); // List all the shared object (native) libraries this executable will need // on the command line, so that we don't have to do this manually! for (std::vector<std::string>::iterator i = Libraries.begin(), e = Libraries.end(); i != e; ++i) { // try explicit -L arguments first: sys::Path FullLibraryPath; for (cl::list<std::string>::const_iterator P = LibPaths.begin(), E = LibPaths.end(); P != E; ++P) { FullLibraryPath = *P; FullLibraryPath.appendComponent("lib" + *i); FullLibraryPath.appendSuffix(sys::Path::GetDLLSuffix()); if (!FullLibraryPath.isEmpty()) { if (!FullLibraryPath.isDynamicLibrary()) { // Not a native shared library; mark as invalid FullLibraryPath = sys::Path(); } else break; } } if (FullLibraryPath.isEmpty()) FullLibraryPath = sys::Path::FindLibrary(*i); if (!FullLibraryPath.isEmpty()) Out2.os() << " -load=" << FullLibraryPath.str() << " \\\n"; } Out2.os() << " " << BitcodeOutputFilename << " ${1+\"$@\"}\n"; Out2.keep(); }
// parseCommandLine - Parse the command line options as presented and return the // operation specified. Process all modifiers and check to make sure that // constraints on modifier/operation pairs have not been violated. ArchiveOperation parseCommandLine() { // Keep track of number of operations. We can only specify one // per execution. unsigned NumOperations = 0; // Keep track of the number of positional modifiers (a,b,i). Only // one can be specified. unsigned NumPositional = 0; // Keep track of which operation was requested ArchiveOperation Operation = NoOperation; for(unsigned i=0; i<Options.size(); ++i) { switch(Options[i]) { case 'd': ++NumOperations; Operation = Delete; break; case 'm': ++NumOperations; Operation = Move ; break; case 'p': ++NumOperations; Operation = Print; break; case 'q': ++NumOperations; Operation = QuickAppend; break; case 'r': ++NumOperations; Operation = ReplaceOrInsert; break; case 't': ++NumOperations; Operation = DisplayTable; break; case 'x': ++NumOperations; Operation = Extract; break; case 'c': Create = true; break; case 'f': TruncateNames = true; break; case 'k': DontSkipBitcode = true; break; case 'l': /* accepted but unused */ break; case 'o': OriginalDates = true; break; case 'P': FullPath = true; break; case 'R': RecurseDirectories = true; break; case 's': SymTable = true; break; case 'S': SymTable = false; break; case 'u': OnlyUpdate = true; break; case 'v': Verbose = true; break; case 'V': Verbose = ReallyVerbose = true; break; case 'a': getRelPos(); AddAfter = true; NumPositional++; break; case 'b': getRelPos(); AddBefore = true; NumPositional++; break; case 'i': getRelPos(); InsertBefore = true; NumPositional++; break; case 'N': getCount(); UseCount = true; break; default: cl::PrintHelpMessage(); } } // At this point, the next thing on the command line must be // the archive name. getArchive(); // Everything on the command line at this point is a member. getMembers(); // Perform various checks on the operation/modifier specification // to make sure we are dealing with a legal request. if (NumOperations == 0) throw "You must specify at least one of the operations"; if (NumOperations > 1) throw "Only one operation may be specified"; if (NumPositional > 1) throw "You may only specify one of a, b, and i modifiers"; if (AddAfter || AddBefore || InsertBefore) if (Operation != Move && Operation != ReplaceOrInsert) throw "The 'a', 'b' and 'i' modifiers can only be specified with " "the 'm' or 'r' operations"; if (RecurseDirectories && Operation != ReplaceOrInsert) throw "The 'R' modifiers is only applicabe to the 'r' operation"; if (OriginalDates && Operation != Extract) throw "The 'o' modifier is only applicable to the 'x' operation"; if (TruncateNames && Operation!=QuickAppend && Operation!=ReplaceOrInsert) throw "The 'f' modifier is only applicable to the 'q' and 'r' operations"; if (OnlyUpdate && Operation != ReplaceOrInsert) throw "The 'u' modifier is only applicable to the 'r' operation"; if (Count > 1 && Members.size() > 1) throw "Only one member name may be specified with the 'N' modifier"; // Return the parsed operation to the caller return Operation; }
int main(int argc, char **argv) { #ifndef DEBUG_BUGPOINT llvm::sys::PrintStackTraceOnErrorSignal(); llvm::PrettyStackTraceProgram X(argc, argv); llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. #endif // Initialize passes PassRegistry &Registry = *PassRegistry::getPassRegistry(); initializeCore(Registry); initializeScalarOpts(Registry); initializeObjCARCOpts(Registry); initializeVectorization(Registry); initializeIPO(Registry); initializeAnalysis(Registry); initializeIPA(Registry); initializeTransformUtils(Registry); initializeInstCombine(Registry); initializeInstrumentation(Registry); initializeTarget(Registry); #ifdef LINK_POLLY_INTO_TOOLS polly::initializePollyPasses(Registry); #endif // @LOCALMOD-BEGIN initializeAddPNaClExternalDeclsPass(Registry); initializeAllocateDataSegmentPass(Registry); initializeBackendCanonicalizePass(Registry); initializeCanonicalizeMemIntrinsicsPass(Registry); initializeCleanupUsedGlobalsMetadataPass(Registry); initializeConstantInsertExtractElementIndexPass(Registry); initializeExpandAllocasPass(Registry); initializeExpandArithWithOverflowPass(Registry); initializeExpandByValPass(Registry); initializeExpandConstantExprPass(Registry); initializeExpandCtorsPass(Registry); initializeExpandGetElementPtrPass(Registry); initializeExpandIndirectBrPass(Registry); initializeExpandLargeIntegersPass(Registry); initializeExpandShuffleVectorPass(Registry); initializeExpandSmallArgumentsPass(Registry); initializeExpandStructRegsPass(Registry); initializeExpandTlsConstantExprPass(Registry); initializeExpandTlsPass(Registry); initializeExpandVarArgsPass(Registry); initializeFixVectorLoadStoreAlignmentPass(Registry); initializeFlattenGlobalsPass(Registry); initializeGlobalCleanupPass(Registry); initializeGlobalizeConstantVectorsPass(Registry); initializeInsertDivideCheckPass(Registry); initializeInternalizeUsedGlobalsPass(Registry); initializeNormalizeAlignmentPass(Registry); initializePNaClABIVerifyFunctionsPass(Registry); initializePNaClABIVerifyModulePass(Registry); initializePNaClSjLjEHPass(Registry); initializePromoteI1OpsPass(Registry); initializePromoteIntegersPass(Registry); initializeRemoveAsmMemoryPass(Registry); initializeRenameEntryPointPass(Registry); initializeReplacePtrsWithIntsPass(Registry); initializeResolveAliasesPass(Registry); initializeResolvePNaClIntrinsicsPass(Registry); initializeRewriteAtomicsPass(Registry); initializeRewriteLLVMIntrinsicsPass(Registry); initializeRewritePNaClLibraryCallsPass(Registry); initializeSandboxIndirectCallsPass(Registry); initializeSandboxMemoryAccessesPass(Registry); initializeSimplifyAllocasPass(Registry); initializeSimplifyStructRegSignaturesPass(Registry); initializeStripAttributesPass(Registry); initializeStripMetadataPass(Registry); initializeStripModuleFlagsPass(Registry); initializeStripTlsPass(Registry); initializeSubstituteUndefsPass(Registry); // Emscripten passes: initializeExpandI64Pass(Registry); initializeExpandInsertExtractElementPass(Registry); initializeLowerEmAsyncifyPass(Registry); initializeLowerEmExceptionsPass(Registry); initializeLowerEmSetjmpPass(Registry); initializeNoExitRuntimePass(Registry); // Emscripten passes end. // @LOCALMOD-END cl::ParseCommandLineOptions(argc, argv, "LLVM automatic testcase reducer. See\nhttp://" "llvm.org/cmds/bugpoint.html" " for more information.\n"); #ifndef DEBUG_BUGPOINT sys::SetInterruptFunction(BugpointInterruptFunction); #endif LLVMContext& Context = getGlobalContext(); // If we have an override, set it and then track the triple we want Modules // to use. if (!OverrideTriple.empty()) { TargetTriple.setTriple(Triple::normalize(OverrideTriple)); outs() << "Override triple set to '" << TargetTriple.getTriple() << "'\n"; } if (MemoryLimit < 0) { // Set the default MemoryLimit. Be sure to update the flag's description if // you change this. if (sys::RunningOnValgrind() || UseValgrind) MemoryLimit = 800; else MemoryLimit = 300; } BugDriver D(argv[0], FindBugs, TimeoutValue, MemoryLimit, UseValgrind, Context); if (D.addSources(InputFilenames)) return 1; AddToDriver PM(D); if (StandardLinkOpts) { PassManagerBuilder Builder; Builder.Inliner = createFunctionInliningPass(); Builder.populateLTOPassManager(PM); } if (OptLevelO1 || OptLevelO2 || OptLevelO3) { PassManagerBuilder Builder; if (OptLevelO1) Builder.Inliner = createAlwaysInlinerPass(); else if (OptLevelO2) Builder.Inliner = createFunctionInliningPass(225); else Builder.Inliner = createFunctionInliningPass(275); // Note that although clang/llvm-gcc use two separate passmanagers // here, it shouldn't normally make a difference. Builder.populateFunctionPassManager(PM); Builder.populateModulePassManager(PM); } for (std::vector<const PassInfo*>::iterator I = PassList.begin(), E = PassList.end(); I != E; ++I) { const PassInfo* PI = *I; D.addPass(PI->getPassArgument()); } // Bugpoint has the ability of generating a plethora of core files, so to // avoid filling up the disk, we prevent it #ifndef DEBUG_BUGPOINT sys::Process::PreventCoreFiles(); #endif std::string Error; bool Failure = D.run(Error); if (!Error.empty()) { errs() << Error; return 1; } return Failure; }
bool TargetSubtargetInfo::useMachineScheduler() const { if (BenchMachineSched.getNumOccurrences()) return BenchMachineSched; return enableMachineScheduler(); }
int main(int argc, char **argv) { // Print a stack trace if we signal out. sys::PrintStackTraceOnErrorSignal(); PrettyStackTraceProgram X(argc, argv); llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. // Initialize targets and assembly printers/parsers. llvm::InitializeAllTargetInfos(); llvm::InitializeAllTargetMCs(); llvm::InitializeAllAsmParsers(); llvm::InitializeAllDisassemblers(); // Register the target printer for --version. cl::AddExtraVersionPrinter(TargetRegistry::printRegisteredTargetsForVersion); cl::ParseCommandLineOptions(argc, argv, "llvm machine code playground\n"); MCTargetOptions MCOptions = InitMCTargetOptionsFromFlags(); TripleName = Triple::normalize(TripleName); setDwarfDebugFlags(argc, argv); setDwarfDebugProducer(); const char *ProgName = argv[0]; const Target *TheTarget = GetTarget(ProgName); if (!TheTarget) return 1; // Now that GetTarget() has (potentially) replaced TripleName, it's safe to // construct the Triple object. Triple TheTriple(TripleName); ErrorOr<std::unique_ptr<MemoryBuffer>> BufferPtr = MemoryBuffer::getFileOrSTDIN(InputFilename); if (std::error_code EC = BufferPtr.getError()) { errs() << InputFilename << ": " << EC.message() << '\n'; return 1; } MemoryBuffer *Buffer = BufferPtr->get(); SourceMgr SrcMgr; // Tell SrcMgr about this buffer, which is what the parser will pick up. SrcMgr.AddNewSourceBuffer(std::move(*BufferPtr), SMLoc()); // Record the location of the include directories so that the lexer can find // it later. SrcMgr.setIncludeDirs(IncludeDirs); std::unique_ptr<MCRegisterInfo> MRI(TheTarget->createMCRegInfo(TripleName)); assert(MRI && "Unable to create target register info!"); std::unique_ptr<MCAsmInfo> MAI(TheTarget->createMCAsmInfo(*MRI, TripleName)); assert(MAI && "Unable to create target asm info!"); MAI->setRelaxELFRelocations(RelaxELFRel); if (CompressDebugSections != DebugCompressionType::DCT_None) { if (!zlib::isAvailable()) { errs() << ProgName << ": build tools with zlib to enable -compress-debug-sections"; return 1; } MAI->setCompressDebugSections(CompressDebugSections); } // FIXME: This is not pretty. MCContext has a ptr to MCObjectFileInfo and // MCObjectFileInfo needs a MCContext reference in order to initialize itself. MCObjectFileInfo MOFI; MCContext Ctx(MAI.get(), MRI.get(), &MOFI, &SrcMgr); MOFI.InitMCObjectFileInfo(TheTriple, PIC, CMModel, Ctx); if (SaveTempLabels) Ctx.setAllowTemporaryLabels(false); Ctx.setGenDwarfForAssembly(GenDwarfForAssembly); // Default to 4 for dwarf version. unsigned DwarfVersion = MCOptions.DwarfVersion ? MCOptions.DwarfVersion : 4; if (DwarfVersion < 2 || DwarfVersion > 4) { errs() << ProgName << ": Dwarf version " << DwarfVersion << " is not supported." << '\n'; return 1; } Ctx.setDwarfVersion(DwarfVersion); if (!DwarfDebugFlags.empty()) Ctx.setDwarfDebugFlags(StringRef(DwarfDebugFlags)); if (!DwarfDebugProducer.empty()) Ctx.setDwarfDebugProducer(StringRef(DwarfDebugProducer)); if (!DebugCompilationDir.empty()) Ctx.setCompilationDir(DebugCompilationDir); else { // If no compilation dir is set, try to use the current directory. SmallString<128> CWD; if (!sys::fs::current_path(CWD)) Ctx.setCompilationDir(CWD); } if (!MainFileName.empty()) Ctx.setMainFileName(MainFileName); // Package up features to be passed to target/subtarget std::string FeaturesStr; if (MAttrs.size()) { SubtargetFeatures Features; for (unsigned i = 0; i != MAttrs.size(); ++i) Features.AddFeature(MAttrs[i]); FeaturesStr = Features.getString(); } std::unique_ptr<tool_output_file> Out = GetOutputStream(); if (!Out) return 1; std::unique_ptr<buffer_ostream> BOS; raw_pwrite_stream *OS = &Out->os(); std::unique_ptr<MCStreamer> Str; std::unique_ptr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo()); std::unique_ptr<MCSubtargetInfo> STI( TheTarget->createMCSubtargetInfo(TripleName, MCPU, FeaturesStr)); MCInstPrinter *IP = nullptr; if (FileType == OFT_AssemblyFile) { IP = TheTarget->createMCInstPrinter(Triple(TripleName), OutputAsmVariant, *MAI, *MCII, *MRI); // Set the display preference for hex vs. decimal immediates. IP->setPrintImmHex(PrintImmHex); // Set up the AsmStreamer. MCCodeEmitter *CE = nullptr; MCAsmBackend *MAB = nullptr; if (ShowEncoding) { CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx); MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, MCPU); } auto FOut = llvm::make_unique<formatted_raw_ostream>(*OS); Str.reset(TheTarget->createAsmStreamer( Ctx, std::move(FOut), /*asmverbose*/ true, /*useDwarfDirectory*/ true, IP, CE, MAB, ShowInst)); } else if (FileType == OFT_Null) { Str.reset(TheTarget->createNullStreamer(Ctx)); } else { assert(FileType == OFT_ObjectFile && "Invalid file type!"); // Don't waste memory on names of temp labels. Ctx.setUseNamesOnTempLabels(false); if (!Out->os().supportsSeeking()) { BOS = make_unique<buffer_ostream>(Out->os()); OS = BOS.get(); } MCCodeEmitter *CE = TheTarget->createMCCodeEmitter(*MCII, *MRI, Ctx); MCAsmBackend *MAB = TheTarget->createMCAsmBackend(*MRI, TripleName, MCPU); Str.reset(TheTarget->createMCObjectStreamer( TheTriple, Ctx, *MAB, *OS, CE, *STI, MCOptions.MCRelaxAll, MCOptions.MCIncrementalLinkerCompatible, /*DWARFMustBeAtTheEnd*/ false)); if (NoExecStack) Str->InitSections(true); } int Res = 1; bool disassemble = false; switch (Action) { case AC_AsLex: Res = AsLexInput(SrcMgr, *MAI, Out->os()); break; case AC_Assemble: Res = AssembleInput(ProgName, TheTarget, SrcMgr, Ctx, *Str, *MAI, *STI, *MCII, MCOptions); break; case AC_MDisassemble: assert(IP && "Expected assembly output"); IP->setUseMarkup(1); disassemble = true; break; case AC_Disassemble: disassemble = true; break; } if (disassemble) Res = Disassembler::disassemble(*TheTarget, TripleName, *STI, *Str, *Buffer, SrcMgr, Out->os()); // Keep output if no errors. if (Res == 0) Out->keep(); return Res; }
//===----------------------------------------------------------------------===// // main for opt // int main(int argc, char **argv) { sys::PrintStackTraceOnErrorSignal(); llvm::PrettyStackTraceProgram X(argc, argv); // Enable debug stream buffering. EnableDebugBuffering = true; llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. LLVMContext &Context = getGlobalContext(); InitializeAllTargets(); InitializeAllTargetMCs(); // Initialize passes PassRegistry &Registry = *PassRegistry::getPassRegistry(); initializeCore(Registry); initializeDebugIRPass(Registry); initializeScalarOpts(Registry); initializeObjCARCOpts(Registry); initializeVectorization(Registry); initializeIPO(Registry); initializeAnalysis(Registry); initializeIPA(Registry); initializeTransformUtils(Registry); initializeInstCombine(Registry); initializeInstrumentation(Registry); initializeTarget(Registry); 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; // Load the input module... OwningPtr<Module> M; M.reset(ParseIRFile(InputFilename, Err, Context)); if (M.get() == 0) { Err.print(argv[0], errs()); return 1; } // If we are supposed to override the target triple, do so now. if (!TargetTriple.empty()) M->setTargetTriple(Triple::normalize(TargetTriple)); // Figure out what stream we are supposed to write to... OwningPtr<tool_output_file> Out; 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::string ErrorInfo; Out.reset(new tool_output_file(OutputFilename.c_str(), ErrorInfo, sys::fs::F_Binary)); if (!ErrorInfo.empty()) { errs() << ErrorInfo << '\n'; return 1; } } // 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; // Create a PassManager to hold and optimize the collection of passes we are // about to build. // PassManager Passes; // Add an appropriate TargetLibraryInfo pass for the module's triple. TargetLibraryInfo *TLI = new TargetLibraryInfo(Triple(M->getTargetTriple())); // The -disable-simplify-libcalls flag actually disables all builtin optzns. if (DisableSimplifyLibCalls) TLI->disableAllFunctions(); Passes.add(TLI); // Add an appropriate DataLayout instance for this module. DataLayout *TD = 0; const std::string &ModuleDataLayout = M.get()->getDataLayout(); if (!ModuleDataLayout.empty()) TD = new DataLayout(ModuleDataLayout); else if (!DefaultDataLayout.empty()) TD = new DataLayout(DefaultDataLayout); if (TD) Passes.add(TD); Triple ModuleTriple(M->getTargetTriple()); TargetMachine *Machine = 0; if (ModuleTriple.getArch()) Machine = GetTargetMachine(Triple(ModuleTriple)); OwningPtr<TargetMachine> TM(Machine); // Add internal analysis passes from the target machine. if (TM.get()) TM->addAnalysisPasses(Passes); OwningPtr<FunctionPassManager> FPasses; if (OptLevelO1 || OptLevelO2 || OptLevelOs || OptLevelOz || OptLevelO3) { FPasses.reset(new FunctionPassManager(M.get())); if (TD) FPasses->add(new DataLayout(*TD)); if (TM.get()) TM->addAnalysisPasses(*FPasses); } if (PrintBreakpoints) { // Default to standard output. if (!Out) { if (OutputFilename.empty()) OutputFilename = "-"; std::string ErrorInfo; Out.reset(new tool_output_file(OutputFilename.c_str(), ErrorInfo, sys::fs::F_Binary)); if (!ErrorInfo.empty()) { errs() << ErrorInfo << '\n'; return 1; } } Passes.add(new BreakpointPrinter(Out->os())); NoOutput = true; } // If the -strip-debug command line option was specified, add it. If // -std-compile-opts was also specified, it will handle StripDebug. if (StripDebug && !StandardCompileOpts) addPass(Passes, createStripSymbolsPass(true)); // Create a new optimization pass for each one specified on the command line for (unsigned i = 0; i < PassList.size(); ++i) { // Check to see if -std-compile-opts was specified before this option. If // so, handle it. if (StandardCompileOpts && StandardCompileOpts.getPosition() < PassList.getPosition(i)) { AddStandardCompilePasses(Passes); StandardCompileOpts = false; } if (StandardLinkOpts && StandardLinkOpts.getPosition() < PassList.getPosition(i)) { AddStandardLinkPasses(Passes); StandardLinkOpts = false; } if (OptLevelO1 && OptLevelO1.getPosition() < PassList.getPosition(i)) { AddOptimizationPasses(Passes, *FPasses, 1, 0); OptLevelO1 = false; } if (OptLevelO2 && OptLevelO2.getPosition() < PassList.getPosition(i)) { AddOptimizationPasses(Passes, *FPasses, 2, 0); OptLevelO2 = false; } if (OptLevelOs && OptLevelOs.getPosition() < PassList.getPosition(i)) { AddOptimizationPasses(Passes, *FPasses, 2, 1); OptLevelOs = false; } if (OptLevelOz && OptLevelOz.getPosition() < PassList.getPosition(i)) { AddOptimizationPasses(Passes, *FPasses, 2, 2); OptLevelOz = false; } if (OptLevelO3 && OptLevelO3.getPosition() < PassList.getPosition(i)) { AddOptimizationPasses(Passes, *FPasses, 3, 0); OptLevelO3 = false; } const PassInfo *PassInf = PassList[i]; Pass *P = 0; 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(new BasicBlockPassPrinter(PassInf, Out->os())); break; case PT_Region: Passes.add(new RegionPassPrinter(PassInf, Out->os())); break; case PT_Loop: Passes.add(new LoopPassPrinter(PassInf, Out->os())); break; case PT_Function: Passes.add(new FunctionPassPrinter(PassInf, Out->os())); break; case PT_CallGraphSCC: Passes.add(new CallGraphSCCPassPrinter(PassInf, Out->os())); break; default: Passes.add(new ModulePassPrinter(PassInf, Out->os())); break; } } } if (PrintEachXForm) Passes.add(createPrintModulePass(&errs())); } // If -std-compile-opts was specified at the end of the pass list, add them. if (StandardCompileOpts) { AddStandardCompilePasses(Passes); StandardCompileOpts = false; } if (StandardLinkOpts) { AddStandardLinkPasses(Passes); StandardLinkOpts = false; } if (OptLevelO1) AddOptimizationPasses(Passes, *FPasses, 1, 0); if (OptLevelO2) AddOptimizationPasses(Passes, *FPasses, 2, 0); if (OptLevelOs) AddOptimizationPasses(Passes, *FPasses, 2, 1); if (OptLevelOz) AddOptimizationPasses(Passes, *FPasses, 2, 2); if (OptLevelO3) AddOptimizationPasses(Passes, *FPasses, 3, 0); if (OptLevelO1 || OptLevelO2 || OptLevelOs || OptLevelOz || OptLevelO3) { FPasses->doInitialization(); for (Module::iterator F = M->begin(), E = M->end(); F != E; ++F) FPasses->run(*F); FPasses->doFinalization(); } // Check that the module is well formed on completion of optimization if (!NoVerify && !VerifyEach) Passes.add(createVerifierPass()); // Write bitcode or assembly to the output as the last step... if (!NoOutput && !AnalyzeOnly) { if (OutputAssembly) Passes.add(createPrintModulePass(&Out->os())); else Passes.add(createBitcodeWriterPass(Out->os())); } // Before executing passes, print the final values of the LLVM options. cl::PrintOptionValues(); // Now that we have all of the passes ready, run them. Passes.run(*M.get()); // Declare success. if (!NoOutput || PrintBreakpoints) Out->keep(); return 0; }
int main(int argc, char **argv) { INITIALIZE_LLVM(argc, argv); // Initialize passes PassRegistry &Registry = *PassRegistry::getPassRegistry(); initializeCore(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. initializeCodeGenPreparePass(Registry); initializeAtomicExpandPass(Registry); initializeRewriteSymbolsPass(Registry); initializeWinEHPreparePass(Registry); initializeDwarfEHPreparePass(Registry); initializeSjLjEHPreparePass(Registry); // Register Swift Only Passes. initializeSwiftAAWrapperPassPass(Registry); initializeSwiftRCIdentityPass(Registry); initializeSwiftARCOptPass(Registry); initializeSwiftARCContractPass(Registry); initializeSwiftStackPromotionPass(Registry); initializeInlineTreePrinterPass(Registry); llvm::cl::ParseCommandLineOptions(argc, argv, "Swift LLVM optimizer\n"); if (PrintStats) llvm::EnableStatistics(); llvm::SMDiagnostic Err; // Load the input module... std::unique_ptr<Module> M = parseIRFile(InputFilename, Err, getGlobalContext()); if (!M) { Err.print(argv[0], errs()); return 1; } if (verifyModule(*M, &errs())) { errs() << argv[0] << ": " << InputFilename << ": error: input module is broken!\n"; return 1; } // If we are supposed to override the target triple, do so now. if (!TargetTriple.empty()) M->setTargetTriple(llvm::Triple::normalize(TargetTriple)); // Figure out what stream we are supposed to write to... std::unique_ptr<llvm::tool_output_file> Out; // Default to standard output. if (OutputFilename.empty()) OutputFilename = "-"; std::error_code EC; Out.reset( new llvm::tool_output_file(OutputFilename, EC, llvm::sys::fs::F_None)); if (EC) { errs() << EC.message() << '\n'; return 1; } llvm::Triple ModuleTriple(M->getTargetTriple()); std::string CPUStr, FeaturesStr; llvm::TargetMachine *Machine = nullptr; const llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags(); if (ModuleTriple.getArch()) { CPUStr = getCPUStr(); FeaturesStr = getFeaturesStr(); Machine = getTargetMachine(ModuleTriple, CPUStr, FeaturesStr, Options); } std::unique_ptr<llvm::TargetMachine> TM(Machine); // Override function attributes based on CPUStr, FeaturesStr, and command line // flags. setFunctionAttributes(CPUStr, FeaturesStr, *M); if (Optimized) { IRGenOptions Opts; Opts.Optimize = true; // Then perform the optimizations. performLLVMOptimizations(Opts, M.get(), TM.get()); } else { runSpecificPasses(argv[0], M.get(), TM.get(), ModuleTriple); } // Finally dump the output. dumpOutput(*M, Out->os()); return 0; }
/// AnalyzeBitcode - Analyze the bitcode file specified by InputFilename. static int AnalyzeBitcode() { // Read the input file. error_code ec; MemoryBuffer *MemBuf = MemoryBuffer::getFileOrSTDIN(InputFilename.c_str(), ec); if (MemBuf == 0) return Error("Error reading '" + InputFilename + "': " + ec.message()); if (MemBuf->getBufferSize() & 3) return Error("Bitcode stream should be a multiple of 4 bytes in length"); unsigned char *BufPtr = (unsigned char *)MemBuf->getBufferStart(); unsigned char *EndBufPtr = BufPtr+MemBuf->getBufferSize(); // If we have a wrapper header, parse it and ignore the non-bc file contents. // The magic number is 0x0B17C0DE stored in little endian. if (isBitcodeWrapper(BufPtr, EndBufPtr)) if (SkipBitcodeWrapperHeader(BufPtr, EndBufPtr)) return Error("Invalid bitcode wrapper header"); BitstreamReader StreamFile(BufPtr, EndBufPtr); BitstreamCursor Stream(StreamFile); StreamFile.CollectBlockInfoNames(); // Read the stream signature. char Signature[6]; Signature[0] = Stream.Read(8); Signature[1] = Stream.Read(8); Signature[2] = Stream.Read(4); Signature[3] = Stream.Read(4); Signature[4] = Stream.Read(4); Signature[5] = Stream.Read(4); // Autodetect the file contents, if it is one we know. CurStreamType = UnknownBitstream; if (Signature[0] == 'B' && Signature[1] == 'C' && Signature[2] == 0x0 && Signature[3] == 0xC && Signature[4] == 0xE && Signature[5] == 0xD) CurStreamType = LLVMIRBitstream; unsigned NumTopBlocks = 0; // Parse the top-level structure. We only allow blocks at the top-level. while (!Stream.AtEndOfStream()) { unsigned Code = Stream.ReadCode(); if (Code != bitc::ENTER_SUBBLOCK) return Error("Invalid record at top-level"); if (ParseBlock(Stream, 0)) return true; ++NumTopBlocks; } if (Dump) errs() << "\n\n"; uint64_t BufferSizeBits = (EndBufPtr-BufPtr)*CHAR_BIT; // Print a summary of the read file. errs() << "Summary of " << InputFilename << ":\n"; errs() << " Total size: "; PrintSize(BufferSizeBits); errs() << "\n"; errs() << " Stream type: "; switch (CurStreamType) { default: assert(0 && "Unknown bitstream type"); case UnknownBitstream: errs() << "unknown\n"; break; case LLVMIRBitstream: errs() << "LLVM IR\n"; break; } errs() << " # Toplevel Blocks: " << NumTopBlocks << "\n"; errs() << "\n"; // Emit per-block stats. errs() << "Per-block Summary:\n"; for (std::map<unsigned, PerBlockIDStats>::iterator I = BlockIDStats.begin(), E = BlockIDStats.end(); I != E; ++I) { errs() << " Block ID #" << I->first; if (const char *BlockName = GetBlockName(I->first, StreamFile)) errs() << " (" << BlockName << ")"; errs() << ":\n"; const PerBlockIDStats &Stats = I->second; errs() << " Num Instances: " << Stats.NumInstances << "\n"; errs() << " Total Size: "; PrintSize(Stats.NumBits); errs() << "\n"; double pct = (Stats.NumBits * 100.0) / BufferSizeBits; errs() << " Percent of file: " << format("%2.4f%%", pct) << "\n"; if (Stats.NumInstances > 1) { errs() << " Average Size: "; PrintSize(Stats.NumBits/(double)Stats.NumInstances); errs() << "\n"; errs() << " Tot/Avg SubBlocks: " << Stats.NumSubBlocks << "/" << Stats.NumSubBlocks/(double)Stats.NumInstances << "\n"; errs() << " Tot/Avg Abbrevs: " << Stats.NumAbbrevs << "/" << Stats.NumAbbrevs/(double)Stats.NumInstances << "\n"; errs() << " Tot/Avg Records: " << Stats.NumRecords << "/" << Stats.NumRecords/(double)Stats.NumInstances << "\n"; } else { errs() << " Num SubBlocks: " << Stats.NumSubBlocks << "\n"; errs() << " Num Abbrevs: " << Stats.NumAbbrevs << "\n"; errs() << " Num Records: " << Stats.NumRecords << "\n"; } if (Stats.NumRecords) { double pct = (Stats.NumAbbreviatedRecords * 100.0) / Stats.NumRecords; errs() << " Percent Abbrevs: " << format("%2.4f%%", pct) << "\n"; } errs() << "\n"; // Print a histogram of the codes we see. if (!NoHistogram && !Stats.CodeFreq.empty()) { std::vector<std::pair<unsigned, unsigned> > FreqPairs; // <freq,code> for (unsigned i = 0, e = Stats.CodeFreq.size(); i != e; ++i) if (unsigned Freq = Stats.CodeFreq[i].NumInstances) FreqPairs.push_back(std::make_pair(Freq, i)); std::stable_sort(FreqPairs.begin(), FreqPairs.end()); std::reverse(FreqPairs.begin(), FreqPairs.end()); errs() << "\tRecord Histogram:\n"; fprintf(stderr, "\t\t Count # Bits %% Abv Record Kind\n"); for (unsigned i = 0, e = FreqPairs.size(); i != e; ++i) { const PerRecordStats &RecStats = Stats.CodeFreq[FreqPairs[i].second]; fprintf(stderr, "\t\t%7d %9llu ", RecStats.NumInstances, (unsigned long long)RecStats.TotalBits); if (RecStats.NumAbbrev) fprintf(stderr, "%7.2f ", (double)RecStats.NumAbbrev/RecStats.NumInstances*100); else fprintf(stderr, " "); if (const char *CodeName = GetCodeName(FreqPairs[i].second, I->first, StreamFile)) fprintf(stderr, "%s\n", CodeName); else fprintf(stderr, "UnknownCode%d\n", FreqPairs[i].second); } errs() << "\n"; } } return 0; }
CommonOptionsParser::CommonOptionsParser( int &argc, const char **argv, cl::OptionCategory &Category, llvm::cl::NumOccurrencesFlag OccurrencesFlag, const char *Overview) { static cl::opt<bool> Help("h", cl::desc("Alias for -help"), cl::Hidden, cl::sub(*cl::AllSubCommands)); static cl::opt<std::string> BuildPath("p", cl::desc("Build path"), cl::Optional, cl::cat(Category), cl::sub(*cl::AllSubCommands)); static cl::list<std::string> SourcePaths( cl::Positional, cl::desc("<source0> [... <sourceN>]"), OccurrencesFlag, cl::cat(Category), cl::sub(*cl::AllSubCommands)); static cl::list<std::string> ArgsAfter( "extra-arg", cl::desc("Additional argument to append to the compiler command line"), cl::cat(Category), cl::sub(*cl::AllSubCommands)); static cl::list<std::string> ArgsBefore( "extra-arg-before", cl::desc("Additional argument to prepend to the compiler command line"), cl::cat(Category), cl::sub(*cl::AllSubCommands)); cl::HideUnrelatedOptions(Category); std::string ErrorMessage; Compilations = FixedCompilationDatabase::loadFromCommandLine(argc, argv, ErrorMessage); if (!Compilations && !ErrorMessage.empty()) llvm::errs() << ErrorMessage; cl::ParseCommandLineOptions(argc, argv, Overview); cl::PrintOptionValues(); SourcePathList = SourcePaths; if ((OccurrencesFlag == cl::ZeroOrMore || OccurrencesFlag == cl::Optional) && SourcePathList.empty()) return; if (!Compilations) { if (!BuildPath.empty()) { Compilations = CompilationDatabase::autoDetectFromDirectory(BuildPath, ErrorMessage); } else { Compilations = CompilationDatabase::autoDetectFromSource(SourcePaths[0], ErrorMessage); } if (!Compilations) { llvm::errs() << "Error while trying to load a compilation database:\n" << ErrorMessage << "Running without flags.\n"; Compilations.reset( new FixedCompilationDatabase(".", std::vector<std::string>())); } } auto AdjustingCompilations = llvm::make_unique<ArgumentsAdjustingCompilations>( std::move(Compilations)); AdjustingCompilations->appendArgumentsAdjuster( getInsertArgumentAdjuster(ArgsBefore, ArgumentInsertPosition::BEGIN)); AdjustingCompilations->appendArgumentsAdjuster( getInsertArgumentAdjuster(ArgsAfter, ArgumentInsertPosition::END)); Compilations = std::move(AdjustingCompilations); }
// Returns true if unroll count was set explicitly. // Calculates unroll count and writes it to UP.Count. static bool computeUnrollCount( Loop *L, const TargetTransformInfo &TTI, DominatorTree &DT, LoopInfo *LI, ScalarEvolution *SE, OptimizationRemarkEmitter *ORE, unsigned &TripCount, unsigned MaxTripCount, unsigned &TripMultiple, unsigned LoopSize, TargetTransformInfo::UnrollingPreferences &UP, bool &UseUpperBound) { // Check for explicit Count. // 1st priority is unroll count set by "unroll-count" option. bool UserUnrollCount = UnrollCount.getNumOccurrences() > 0; if (UserUnrollCount) { UP.Count = UnrollCount; UP.AllowExpensiveTripCount = true; UP.Force = true; if (UP.AllowRemainder && getUnrolledLoopSize(LoopSize, UP) < UP.Threshold) return true; } // 2nd priority is unroll count set by pragma. unsigned PragmaCount = UnrollCountPragmaValue(L); if (PragmaCount > 0) { UP.Count = PragmaCount; UP.Runtime = true; UP.AllowExpensiveTripCount = true; UP.Force = true; if (UP.AllowRemainder && getUnrolledLoopSize(LoopSize, UP) < PragmaUnrollThreshold) return true; } bool PragmaFullUnroll = HasUnrollFullPragma(L); if (PragmaFullUnroll && TripCount != 0) { UP.Count = TripCount; if (getUnrolledLoopSize(LoopSize, UP) < PragmaUnrollThreshold) return false; } bool PragmaEnableUnroll = HasUnrollEnablePragma(L); bool ExplicitUnroll = PragmaCount > 0 || PragmaFullUnroll || PragmaEnableUnroll || UserUnrollCount; if (ExplicitUnroll && TripCount != 0) { // If the loop has an unrolling pragma, we want to be more aggressive with // unrolling limits. Set thresholds to at least the PragmaThreshold value // which is larger than the default limits. UP.Threshold = std::max<unsigned>(UP.Threshold, PragmaUnrollThreshold); UP.PartialThreshold = std::max<unsigned>(UP.PartialThreshold, PragmaUnrollThreshold); } // 3rd priority is full unroll count. // Full unroll makes sense only when TripCount or its upper bound could be // statically calculated. // Also we need to check if we exceed FullUnrollMaxCount. // If using the upper bound to unroll, TripMultiple should be set to 1 because // we do not know when loop may exit. // MaxTripCount and ExactTripCount cannot both be non zero since we only // compute the former when the latter is zero. unsigned ExactTripCount = TripCount; assert((ExactTripCount == 0 || MaxTripCount == 0) && "ExtractTripCound and MaxTripCount cannot both be non zero."); unsigned FullUnrollTripCount = ExactTripCount ? ExactTripCount : MaxTripCount; UP.Count = FullUnrollTripCount; if (FullUnrollTripCount && FullUnrollTripCount <= UP.FullUnrollMaxCount) { // When computing the unrolled size, note that BEInsns are not replicated // like the rest of the loop body. if (getUnrolledLoopSize(LoopSize, UP) < UP.Threshold) { UseUpperBound = (MaxTripCount == FullUnrollTripCount); TripCount = FullUnrollTripCount; TripMultiple = UP.UpperBound ? 1 : TripMultiple; return ExplicitUnroll; } else { // The loop isn't that small, but we still can fully unroll it if that // helps to remove a significant number of instructions. // To check that, run additional analysis on the loop. if (Optional<EstimatedUnrollCost> Cost = analyzeLoopUnrollCost( L, FullUnrollTripCount, DT, *SE, TTI, UP.Threshold * UP.MaxPercentThresholdBoost / 100)) { unsigned Boost = getFullUnrollBoostingFactor(*Cost, UP.MaxPercentThresholdBoost); if (Cost->UnrolledCost < UP.Threshold * Boost / 100) { UseUpperBound = (MaxTripCount == FullUnrollTripCount); TripCount = FullUnrollTripCount; TripMultiple = UP.UpperBound ? 1 : TripMultiple; return ExplicitUnroll; } } } } // 4rd priority is partial unrolling. // Try partial unroll only when TripCount could be staticaly calculated. if (TripCount) { UP.Partial |= ExplicitUnroll; if (!UP.Partial) { DEBUG(dbgs() << " will not try to unroll partially because " << "-unroll-allow-partial not given\n"); UP.Count = 0; return false; } if (UP.Count == 0) UP.Count = TripCount; if (UP.PartialThreshold != NoThreshold) { // Reduce unroll count to be modulo of TripCount for partial unrolling. if (getUnrolledLoopSize(LoopSize, UP) > UP.PartialThreshold) UP.Count = (std::max(UP.PartialThreshold, UP.BEInsns + 1) - UP.BEInsns) / (LoopSize - UP.BEInsns); if (UP.Count > UP.MaxCount) UP.Count = UP.MaxCount; while (UP.Count != 0 && TripCount % UP.Count != 0) UP.Count--; if (UP.AllowRemainder && UP.Count <= 1) { // If there is no Count that is modulo of TripCount, set Count to // largest power-of-two factor that satisfies the threshold limit. // As we'll create fixup loop, do the type of unrolling only if // remainder loop is allowed. UP.Count = UP.DefaultUnrollRuntimeCount; while (UP.Count != 0 && getUnrolledLoopSize(LoopSize, UP) > UP.PartialThreshold) UP.Count >>= 1; } if (UP.Count < 2) { if (PragmaEnableUnroll) ORE->emit( OptimizationRemarkMissed(DEBUG_TYPE, "UnrollAsDirectedTooLarge", L->getStartLoc(), L->getHeader()) << "Unable to unroll loop as directed by unroll(enable) pragma " "because unrolled size is too large."); UP.Count = 0; } } else {