void SILPassManager::run() { const SILOptions &Options = getOptions(); (void) Options; if (SILPrintAll) { if (SILPrintOnlyFun.empty() && SILPrintOnlyFuns.empty()) { llvm::dbgs() << "*** SIL module before transformation (" << NumOptimizationIterations << ") ***\n"; Mod->dump(Options.EmitVerboseSIL); } else { for (auto &F : *Mod) { if (!SILPrintOnlyFun.empty() && F.getName().str() == SILPrintOnlyFun) { llvm::dbgs() << "*** SIL function before transformation (" << NumOptimizationIterations << ") ***\n"; F.dump(Options.EmitVerboseSIL); } if (!SILPrintOnlyFuns.empty() && F.getName().find(SILPrintOnlyFuns, 0) != StringRef::npos) { llvm::dbgs() << "*** SIL function before transformation (" << NumOptimizationIterations << ") ***\n"; F.dump(Options.EmitVerboseSIL); } } } } runOneIteration(); }
// Test the function and pass names we're given against the debug // options that force us to break prior to a given pass and/or on a // given function. static bool breakBeforeRunning(StringRef fnName, StringRef passName) { if (SILBreakOnFun.empty() && SILBreakOnPass.empty()) return false; if (SILBreakOnFun.empty() && passName == SILBreakOnPass) return true; if (SILBreakOnPass.empty() && fnName == SILBreakOnFun) return true; return fnName == SILBreakOnFun && passName == SILBreakOnPass; }
// Test the function and pass names we're given against the debug // options that force us to break prior to a given pass and/or on a // given function. static bool breakBeforeRunning(StringRef fnName, SILFunctionTransform *SFT) { if (SILBreakOnFun.empty() && SILBreakOnPass.empty()) return false; if (SILBreakOnFun.empty() && (SFT->getName() == SILBreakOnPass || SFT->getTag() == SILBreakOnPass)) return true; if (SILBreakOnPass.empty() && fnName == SILBreakOnFun) return true; return fnName == SILBreakOnFun && (SFT->getName() == SILBreakOnPass || SFT->getTag() == SILBreakOnPass); }
static void printModule(SILModule *Mod, bool EmitVerboseSIL) { if (SILPrintOnlyFun.empty() && SILPrintOnlyFuns.empty()) { Mod->dump(); return; } for (auto &F : *Mod) { if (!SILPrintOnlyFun.empty() && F.getName().str() == SILPrintOnlyFun) F.dump(EmitVerboseSIL); if (!SILPrintOnlyFuns.empty() && F.getName().find(SILPrintOnlyFuns, 0) != StringRef::npos) F.dump(EmitVerboseSIL); } }
// main function int main(int argc, char* argv[]) { llvm::llvm_shutdown_obj llvm_manager(false); cl::SetVersionPrinter(&PrintVersion); cl::ParseCommandLineOptions(argc, argv, "", true); // Handle special exiting options if (show_license) { for (std::size_t i=0; i<sizeof(license_msg)/sizeof(license_msg[0]); i++) llvm::outs() << license_msg[i] << '\n'; return EXIT_SUCCESS; } DiagnosticOptions diag_opts; diag_opts.ShowOptionNames = 1; diag_opts.ShowSourceRanges = 1; TextDiagnosticPrinter diag_printer(llvm::errs(), diag_opts); IntrusiveRefCntPtr<DiagnosticIDs> diagids(new DiagnosticIDs); DiagnosticsEngine diags(diagids, &diag_printer, false); FileSystemOptions opts; FileManager file_mgr(opts); SourceManager source_mgr(diags, file_mgr); diags.setSourceManager(&source_mgr); diag_printer.setPrefix("ygas"); for (std::vector<std::string>::const_iterator i=unknown_options.begin(), end=unknown_options.end(); i != end; ++i) { diags.Report(diag::warn_unknown_command_line_option) << *i; } // Load standard modules if (!LoadStandardPlugins()) { diags.Report(diag::fatal_standard_modules); return EXIT_FAILURE; } #ifndef BUILD_STATIC // Load plugins for (std::vector<std::string>::const_iterator i=plugin_names.begin(), end=plugin_names.end(); i != end; ++i) { if (!LoadPlugin(*i)) diags.Report(diag::warn_plugin_load) << *i; } #endif // Default to stdin if no filename specified. if (in_filename.empty()) in_filename = "-"; return do_assemble(source_mgr, diags); }
void SILFunction::viewCFG() const { /// When asserts are disabled, this should be a NoOp. #ifndef NDEBUG // If we have a target function, only print that function out. if (!TargetFunction.empty() && !(getName().str() == TargetFunction)) return; ViewGraph(const_cast<SILFunction *>(this), "cfg" + getName().str()); #endif }
static void viewCFGHelper(const SILFunction* f, bool skipBBContents) { /// When asserts are disabled, this should be a NoOp. #ifndef NDEBUG // If we have a target function, only print that function out. if (!TargetFunction.empty() && !(f->getName().str() == TargetFunction)) return; ViewGraph(const_cast<SILFunction *>(f), "cfg" + f->getName().str(), /*shortNames=*/skipBBContents); #endif }
static bool doPrintBefore(SILTransform *T, SILFunction *F) { if (!SILPrintOnlyFun.empty() && F && F->getName() != SILPrintOnlyFun) return false; if (!SILPrintOnlyFuns.empty() && F && F->getName().find(SILPrintOnlyFuns, 0) == StringRef::npos) return false; auto MatchFun = [&](const std::string &Str) -> bool { return T->getName().find(Str) != StringRef::npos; }; if (SILPrintBefore.end() != std::find_if(SILPrintBefore.begin(), SILPrintBefore.end(), MatchFun)) return true; if (SILPrintAround.end() != std::find_if(SILPrintAround.begin(), SILPrintAround.end(), MatchFun)) return true; return false; }
int main(int argc, char **argv) { // Parse the command line arguments llvm::cl::ParseCommandLineOptions(argc, argv); // Read the module file #if LLVM_VERSION_MAJOR > 3 || \ (LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 6) std::unique_ptr<llvm::Module> module; #else llvm::Module *module; #endif module = getModuleFromIRFile(BitcodeFilename); if (!module) { llvm::errs() << "Something is wrong with your bitcode file" << '\n'; return -1; } // Get the entry function llvm::Function *entry = module->getFunction(EntryFunction); if (!entry) { llvm::errs() << "Entry function " << EntryFunction << " not found" << '\n'; return -1; } if (TargetFunction.empty()) { CountInstructions stratDistance; FinalReturn stratTarget; Dijkstra s(&stratDistance, &stratTarget, &(entry->front().front())); llvm::outs() << "Minimal Instruction from " << EntryFunction << " to final return: " << s.searchForMinimalDistance() << '\n'; } else { llvm::Function *target = module->getFunction(TargetFunction); if (!target) { llvm::errs() << "Target function " << TargetFunction << " not found" << '\n'; return -1; } CountDecisions stratDistance; CallToSpecificFunction stratTarget(TargetFunction); Dijkstra s(&stratDistance, &stratTarget, &(entry->front().front())); llvm::outs() << "Minimal Decisions from " << EntryFunction << " to call of " << TargetFunction << ": " << s.searchForMinimalDistance() << '\n'; } }
void CallGraphNode::print(llvm::raw_ostream &OS) const { OS << CallGraphFileCheckPrefix << "Function #" << Ordinal << ": " << getFunction()->getName() << "\n"; OS << CallGraphFileCheckPrefix << "Demangled: " << demangle_wrappers::demangleSymbolAsString(getFunction()->getName()) << "\n"; printFlag(OS, "Trivially dead", isTriviallyDead()); printFlag(OS, "All callers known", isCallerEdgesComplete()); auto &CalleeEdges = getCalleeEdges(); if (!CalleeEdges.empty()) { OS << CallGraphFileCheckPrefix << "Call sites:\n"; llvm::SmallVector<CallGraphEdge *, 8> OrderedCalleeEdges; orderEdges(CalleeEdges, OrderedCalleeEdges); for (auto *Edge : OrderedCalleeEdges) { OS << "\n"; Edge->print(OS, /* Indent= */ 2); } OS << "\n"; } auto &CallerEdges = getCallerEdges(); if (!CallerEdges.empty()) { OS << CallGraphFileCheckPrefix << (!isCallerEdgesComplete() ? "Known " : ""); OS << "Callers:\n"; llvm::SmallVector<CallGraphEdge *, 8> OrderedCallerEdges; orderEdges(CallerEdges, OrderedCallerEdges); llvm::SetVector<SILFunction *> Callers; for (auto *Edge : OrderedCallerEdges) Callers.insert(Edge->getInstruction()->getFunction()); for (auto *Caller : Callers) { OS << "\n"; indent(OS, 2); OS << CallGraphFileCheckPrefix << "Name: " << Caller->getName() << "\n"; indent(OS, 2); OS << CallGraphFileCheckPrefix << "Demangled: " << demangle_wrappers::demangleSymbolAsString(Caller->getName()) << "\n"; } OS << "\n"; } if (!CallGraphFileCheckPrefix.empty()) getFunction()->print(OS); }
static llvm::tool_output_file * GetOutputStream() { if (OutputFilename.empty()) { OutputFilename = GetFileNameRoot(InputFilename) + ".o"; } string error; unsigned openFlags = llvm::raw_fd_ostream::F_Binary; llvm::tool_output_file * FDOut = new llvm::tool_output_file(OutputFilename.c_str(), error, openFlags); if (!error.empty()) { llvm::errs() << error << '\n'; delete FDOut; return NULL; } return FDOut; }
static void getFunctionNames(std::vector<std::string> &Names) { std::copy(CommandLineFunctionNames.begin(), CommandLineFunctionNames.end(), std::back_inserter(Names)); if (!FunctionNameFile.empty()) { llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> FileBufOrErr = llvm::MemoryBuffer::getFileOrSTDIN(FunctionNameFile); if (!FileBufOrErr) { fprintf(stderr, "Error! Failed to open file: %s\n", InputFilename.c_str()); exit(-1); } StringRef Buffer = FileBufOrErr.get()->getBuffer(); while (!Buffer.empty()) { StringRef Token, NewBuffer; std::tie(Token, NewBuffer) = llvm::getToken(Buffer, "\n"); if (Token.empty()) { break; } Names.push_back(Token); Buffer = NewBuffer; } } }
static bool verifyTransformedFiles(ArrayRef<std::string> resultFiles) { using namespace llvm; assert(!resultFiles.empty()); std::map<StringRef, StringRef> resultMap; for (ArrayRef<std::string>::iterator I = resultFiles.begin(), E = resultFiles.end(); I != E; ++I) { StringRef fname(*I); if (!fname.endswith(".result")) { errs() << "error: filename '" << fname << "' does not have '.result' extension\n"; return true; } resultMap[sys::path::stem(fname)] = fname; } ErrorOr<std::unique_ptr<MemoryBuffer>> inputBuf = std::error_code(); if (RemappingsFile.empty()) inputBuf = MemoryBuffer::getSTDIN(); else inputBuf = MemoryBuffer::getFile(RemappingsFile); if (!inputBuf) { errs() << "error: could not read remappings input\n"; return true; } SmallVector<StringRef, 8> strs; inputBuf.get()->getBuffer().split(strs, "\n", /*MaxSplit=*/-1, /*KeepEmpty=*/false); if (strs.empty()) { errs() << "error: no files to verify from stdin\n"; return true; } if (strs.size() % 2 != 0) { errs() << "error: files to verify are not original/result pairs\n"; return true; } for (unsigned i = 0, e = strs.size(); i != e; i += 2) { StringRef inputOrigFname = strs[i]; StringRef inputResultFname = strs[i+1]; std::map<StringRef, StringRef>::iterator It; It = resultMap.find(sys::path::filename(inputOrigFname)); if (It == resultMap.end()) { errs() << "error: '" << inputOrigFname << "' is not in the list of " << "transformed files to verify\n"; return true; } if (!sys::fs::exists(It->second)) { errs() << "error: '" << It->second << "' does not exist\n"; return true; } if (!sys::fs::exists(inputResultFname)) { errs() << "error: '" << inputResultFname << "' does not exist\n"; return true; } if (!filesCompareEqual(It->second, inputResultFname)) { errs() << "error: '" << It->second << "' is different than " << "'" << inputResultFname << "'\n"; return true; } resultMap.erase(It); } if (!resultMap.empty()) { for (std::map<StringRef, StringRef>::iterator I = resultMap.begin(), E = resultMap.end(); I != E; ++I) errs() << "error: '" << I->second << "' was not verified!\n"; return true; } return false; }
int main(int argc, char *argv[]) { llvm::cl::SetVersionPrinter(PrintVersion); llvm::cl::ParseCommandLineOptions(argc, argv, "CFG to LLVM"); if (InputFilename.empty() || OutputFilename.empty()) { std::cerr << "Must specify an input and output file"; return EXIT_FAILURE; } auto context = new llvm::LLVMContext; if (!InitArch(context, OS, Arch)) { std::cerr << "Cannot initialize for arch " << Arch << " and OS " << OS << std::endl; return EXIT_FAILURE; } auto M = CreateModule(context); if (!M) { return EXIT_FAILURE; } auto triple = M->getTargetTriple(); //reproduce NativeModule from CFG input argument try { auto mod = ReadProtoBuf(InputFilename); if (!mod) { std::cerr << "Unable to read module from CFG" << std::endl; return EXIT_FAILURE; } //now, convert it to an LLVM module ArchInitAttachDetach(M); if (!LiftCodeIntoModule(mod, M)) { std::cerr << "Failure to convert to LLVM module!" << std::endl; return EXIT_FAILURE; } std::set<VA> entry_point_pcs; for (const auto &entry_point_name : EntryPoints) { auto entry_pc = FindSymbolInModule(mod, entry_point_name); if (entry_pc != static_cast<VA>( -1)) { std::cerr << "Adding entry point: " << entry_point_name << std::endl << entry_point_name << " is implemented by sub_" << std::hex << entry_pc << std::endl; if ( !ArchAddEntryPointDriver(M, entry_point_name, entry_pc)) { return EXIT_FAILURE; } entry_point_pcs.insert(entry_pc); } else { std::cerr << "Could not find entry point: " << entry_point_name << "; aborting" << std::endl; return EXIT_FAILURE; } } RenameLiftedFunctions(mod, M, entry_point_pcs); // will abort if verification fails if (llvm::verifyModule( *M, &llvm::errs())) { std::cerr << "Could not verify module!" << std::endl; return EXIT_FAILURE; } std::error_code ec; llvm::tool_output_file Out(OutputFilename.c_str(), ec, llvm::sys::fs::F_None); llvm::WriteBitcodeToFile(M, Out.os()); Out.keep(); } catch (std::exception &e) { std::cerr << "error: " << std::endl << e.what() << std::endl; return EXIT_FAILURE; } return EXIT_SUCCESS; }
static void indent(llvm::raw_ostream &OS, int Indent) { if (!CallGraphFileCheckPrefix.empty()) return; std::string Blanks(Indent, ' '); OS << Blanks; }
static int DoDump(const std::string& in_filename, yasm::SourceManager& source_mgr, yasm::Diagnostic& diags) { yasm::FileManager file_mgr; // open the input file or STDIN (for filename of "-") if (in_filename == "-") { source_mgr.createMainFileIDForMemBuffer(llvm::MemoryBuffer::getSTDIN()); } else { const yasm::FileEntry* in = file_mgr.getFile(in_filename); if (!in) { diags.Report(yasm::SourceLocation(), yasm::diag::err_file_open) << in_filename; } source_mgr.createMainFileID(in, yasm::SourceLocation()); } const llvm::MemoryBuffer* in_file = source_mgr.getBuffer(source_mgr.getMainFileID()); yasm::SourceLocation sloc = source_mgr.getLocForStartOfFile(source_mgr.getMainFileID()); std::auto_ptr<yasm::ObjectFormatModule> objfmt_module(0); std::string arch_keyword, machine; if (!objfmt_keyword.empty()) { objfmt_keyword = llvm::LowercaseString(objfmt_keyword); if (!yasm::isModule<yasm::ObjectFormatModule>(objfmt_keyword)) { diags.Report(sloc, yasm::diag::err_unrecognized_object_format) << objfmt_keyword; return EXIT_FAILURE; } // Object format forced by user objfmt_module = yasm::LoadModule<yasm::ObjectFormatModule>(objfmt_keyword); if (objfmt_module.get() == 0) { diags.Report(sloc, yasm::diag::fatal_module_load) << "object format" << objfmt_keyword; return EXIT_FAILURE; } if (!objfmt_module->Taste(*in_file, &arch_keyword, &machine)) { diags.Report(sloc, yasm::diag::err_unrecognized_object_file) << objfmt_module->getKeyword(); return EXIT_FAILURE; } } else { // Need to loop through available object formats, and taste each one yasm::ModuleNames list = yasm::getModules<yasm::ObjectFormatModule>(); yasm::ModuleNames::iterator i=list.begin(), end=list.end(); for (; i != end; ++i) { objfmt_module = yasm::LoadModule<yasm::ObjectFormatModule>(*i); if (objfmt_module->Taste(*in_file, &arch_keyword, &machine)) break; } if (i == end) { diags.Report(sloc, yasm::diag::err_unrecognized_file_format); return EXIT_FAILURE; } } std::auto_ptr<yasm::ArchModule> arch_module = yasm::LoadModule<yasm::ArchModule>(arch_keyword); if (arch_module.get() == 0) { diags.Report(sloc, yasm::diag::fatal_module_load) << "architecture" << arch_keyword; return EXIT_FAILURE; } std::auto_ptr<yasm::Arch> arch = arch_module->Create(); if (!arch->setMachine(machine)) { diags.Report(sloc, yasm::diag::fatal_module_combo) << "machine" << machine << "architecture" << arch_module->getKeyword(); return EXIT_FAILURE; } yasm::Object object("", in_filename, arch.get()); if (!objfmt_module->isOkObject(object)) { diags.Report(sloc, yasm::diag::fatal_objfmt_machine_mismatch) << objfmt_module->getKeyword() << arch_module->getKeyword() << arch->getMachine(); return EXIT_FAILURE; } std::auto_ptr<yasm::ObjectFormat> objfmt = objfmt_module->Create(object); if (!objfmt->Read(source_mgr, diags)) return EXIT_FAILURE; llvm::outs() << in_filename << ": file format " << objfmt_module->getKeyword() << "\n\n"; if (show_section_headers) DumpSectionHeaders(object); if (show_symbols) DumpSymbols(object); if (show_relocs) DumpRelocs(object); if (show_contents) DumpContents(object); return EXIT_SUCCESS; }
int main(int argc, char **argv) { INITIALIZE_LLVM(argc, argv); llvm::cl::ParseCommandLineOptions(argc, argv, "Swift SIL optimizer\n"); if (PrintStats) llvm::EnableStatistics(); CompilerInvocation Invocation; Invocation.setMainExecutablePath( llvm::sys::fs::getMainExecutable(argv[0], reinterpret_cast<void *>(&anchorForGetMainExecutable))); // Give the context the list of search paths to use for modules. Invocation.setImportSearchPaths(ImportPaths); std::vector<SearchPathOptions::FrameworkSearchPath> FramePaths; for (const auto &path : FrameworkPaths) { FramePaths.push_back({path, /*isSystem=*/false}); } Invocation.setFrameworkSearchPaths(FramePaths); // Set the SDK path and target if given. if (SDKPath.getNumOccurrences() == 0) { const char *SDKROOT = getenv("SDKROOT"); if (SDKROOT) SDKPath = SDKROOT; } if (!SDKPath.empty()) Invocation.setSDKPath(SDKPath); if (!Target.empty()) Invocation.setTargetTriple(Target); if (!ResourceDir.empty()) Invocation.setRuntimeResourcePath(ResourceDir); Invocation.getFrontendOptions().EnableResilience = EnableResilience; // Set the module cache path. If not passed in we use the default swift module // cache. Invocation.getClangImporterOptions().ModuleCachePath = ModuleCachePath; Invocation.setParseStdlib(); Invocation.getLangOptions().DisableAvailabilityChecking = true; Invocation.getLangOptions().EnableAccessControl = false; Invocation.getLangOptions().EnableObjCAttrRequiresFoundation = false; Invocation.getLangOptions().EnableObjCInterop = llvm::Triple(Target).isOSDarwin(); Invocation.getLangOptions().ASTVerifierProcessCount = ASTVerifierProcessCount; Invocation.getLangOptions().ASTVerifierProcessId = ASTVerifierProcessId; Invocation.getLangOptions().EnableSILOpaqueValues = EnableSILOpaqueValues; // Setup the SIL Options. SILOptions &SILOpts = Invocation.getSILOptions(); SILOpts.InlineThreshold = SILInlineThreshold; SILOpts.VerifyAll = EnableSILVerifyAll; SILOpts.RemoveRuntimeAsserts = RemoveRuntimeAsserts; SILOpts.AssertConfig = AssertConfId; if (OptimizationGroup != OptGroup::Diagnostics) SILOpts.Optimization = SILOptions::SILOptMode::Optimize; SILOpts.EnableSILOwnership = EnableSILOwnershipOpt; SILOpts.AssumeUnqualifiedOwnershipWhenParsing = AssumeUnqualifiedOwnershipWhenParsing; switch (EnforceExclusivity) { case EnforceExclusivityMode::Unchecked: // This option is analogous to the -Ounchecked optimization setting. // It will disable dynamic checking but still diagnose statically. SILOpts.EnforceExclusivityStatic = true; SILOpts.EnforceExclusivityDynamic = false; break; case EnforceExclusivityMode::Checked: SILOpts.EnforceExclusivityStatic = true; SILOpts.EnforceExclusivityDynamic = true; break; case EnforceExclusivityMode::DynamicOnly: // This option is intended for staging purposes. The intent is that // it will eventually be removed. SILOpts.EnforceExclusivityStatic = false; SILOpts.EnforceExclusivityDynamic = true; break; case EnforceExclusivityMode::None: // This option is for staging purposes. SILOpts.EnforceExclusivityStatic = false; SILOpts.EnforceExclusivityDynamic = false; break; } // Load the input file. llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> FileBufOrErr = llvm::MemoryBuffer::getFileOrSTDIN(InputFilename); if (!FileBufOrErr) { fprintf(stderr, "Error! Failed to open file: %s\n", InputFilename.c_str()); exit(-1); } // If it looks like we have an AST, set the source file kind to SIL and the // name of the module to the file's name. Invocation.addInputBuffer(FileBufOrErr.get().get()); serialization::ExtendedValidationInfo extendedInfo; auto result = serialization::validateSerializedAST( FileBufOrErr.get()->getBuffer(), &extendedInfo); bool HasSerializedAST = result.status == serialization::Status::Valid; if (HasSerializedAST) { const StringRef Stem = ModuleName.size() ? StringRef(ModuleName) : llvm::sys::path::stem(InputFilename); Invocation.setModuleName(Stem); Invocation.setInputKind(InputFileKind::IFK_Swift_Library); } else { const StringRef Name = ModuleName.size() ? StringRef(ModuleName) : "main"; Invocation.setModuleName(Name); Invocation.setInputKind(InputFileKind::IFK_SIL); } CompilerInstance CI; PrintingDiagnosticConsumer PrintDiags; CI.addDiagnosticConsumer(&PrintDiags); if (!PerformWMO) { auto &FrontendOpts = Invocation.getFrontendOptions(); if (!InputFilename.empty() && InputFilename != "-") { FrontendOpts.PrimaryInput = SelectedInput( FrontendOpts.InputFilenames.size()); } else { FrontendOpts.PrimaryInput = SelectedInput( FrontendOpts.InputBuffers.size(), SelectedInput::InputKind::Buffer); } } if (CI.setup(Invocation)) return 1; CI.performSema(); // If parsing produced an error, don't run any passes. if (CI.getASTContext().hadError()) return 1; // Load the SIL if we have a module. We have to do this after SILParse // creating the unfortunate double if statement. if (HasSerializedAST) { assert(!CI.hasSILModule() && "performSema() should not create a SILModule."); CI.setSILModule(SILModule::createEmptyModule( CI.getMainModule(), CI.getSILOptions(), PerformWMO)); std::unique_ptr<SerializedSILLoader> SL = SerializedSILLoader::create( CI.getASTContext(), CI.getSILModule(), nullptr); if (extendedInfo.isSIB() || DisableSILLinking) SL->getAllForModule(CI.getMainModule()->getName(), nullptr); else SL->getAll(); } // If we're in verify mode, install a custom diagnostic handling for // SourceMgr. if (VerifyMode) enableDiagnosticVerifier(CI.getSourceMgr()); if (OptimizationGroup == OptGroup::Diagnostics) { runSILDiagnosticPasses(*CI.getSILModule()); } else if (OptimizationGroup == OptGroup::Performance) { runSILOptimizationPasses(*CI.getSILModule()); } else if (OptimizationGroup == OptGroup::Lowering) { runSILLoweringPasses(*CI.getSILModule()); } else { auto *SILMod = CI.getSILModule(); { auto T = irgen::createIRGenModule(SILMod, getGlobalLLVMContext()); runCommandLineSelectedPasses(SILMod, T.second); irgen::deleteIRGenModule(T); } } if (EmitSIB) { llvm::SmallString<128> OutputFile; if (OutputFilename.size()) { OutputFile = OutputFilename; } else if (ModuleName.size()) { OutputFile = ModuleName; llvm::sys::path::replace_extension(OutputFile, SIB_EXTENSION); } else { OutputFile = CI.getMainModule()->getName().str(); llvm::sys::path::replace_extension(OutputFile, SIB_EXTENSION); } SerializationOptions serializationOpts; serializationOpts.OutputPath = OutputFile.c_str(); serializationOpts.SerializeAllSIL = true; serializationOpts.IsSIB = true; serialize(CI.getMainModule(), serializationOpts, CI.getSILModule()); } else { const StringRef OutputFile = OutputFilename.size() ? StringRef(OutputFilename) : "-"; if (OutputFile == "-") { CI.getSILModule()->print(llvm::outs(), EmitVerboseSIL, CI.getMainModule(), EnableSILSortOutput, !DisableASTDump); } else { std::error_code EC; llvm::raw_fd_ostream OS(OutputFile, EC, llvm::sys::fs::F_None); if (EC) { llvm::errs() << "while opening '" << OutputFile << "': " << EC.message() << '\n'; return 1; } CI.getSILModule()->print(OS, EmitVerboseSIL, CI.getMainModule(), EnableSILSortOutput, !DisableASTDump); } } bool HadError = CI.getASTContext().hadError(); // If we're in -verify mode, we've buffered up all of the generated // diagnostics. Check now to ensure that they meet our expectations. if (VerifyMode) { HadError = verifyDiagnostics(CI.getSourceMgr(), CI.getInputBufferIDs(), /*autoApplyFixes*/false, /*ignoreUnknown*/false); DiagnosticEngine &diags = CI.getDiags(); if (diags.hasFatalErrorOccurred() && !Invocation.getDiagnosticOptions().ShowDiagnosticsAfterFatalError) { diags.resetHadAnyError(); diags.diagnose(SourceLoc(), diag::verify_encountered_fatal); HadError = true; } } return HadError; }
int main(int argc, char **argv) { INITIALIZE_LLVM(argc, argv); llvm::cl::ParseCommandLineOptions(argc, argv, "Swift LLVM IR Generator\n"); if (PrintStats) llvm::EnableStatistics(); CompilerInvocation Invocation; Invocation.setMainExecutablePath(llvm::sys::fs::getMainExecutable( argv[0], reinterpret_cast<void *>(&anchorForGetMainExecutable))); // Give the context the list of search paths to use for modules. Invocation.setImportSearchPaths(ImportPaths); Invocation.setFrameworkSearchPaths(FrameworkPaths); // Set the SDK path and target if given. if (SDKPath.getNumOccurrences() == 0) { const char *SDKROOT = getenv("SDKROOT"); if (SDKROOT) SDKPath = SDKROOT; } if (!SDKPath.empty()) Invocation.setSDKPath(SDKPath); if (!Target.empty()) Invocation.setTargetTriple(Target); if (!ResourceDir.empty()) Invocation.setRuntimeResourcePath(ResourceDir); // Set the module cache path. If not passed in we use the default swift module // cache. Invocation.getClangImporterOptions().ModuleCachePath = ModuleCachePath; Invocation.setParseStdlib(); // Setup the language options auto &LangOpts = Invocation.getLangOptions(); LangOpts.DisableAvailabilityChecking = true; LangOpts.EnableAccessControl = false; LangOpts.EnableObjCAttrRequiresFoundation = false; LangOpts.EnableObjCInterop = LangOpts.Target.isOSDarwin(); // Setup the SIL Options. SILOptions &SILOpts = Invocation.getSILOptions(); SILOpts.AssumeUnqualifiedOwnershipWhenParsing = AssumeUnqualifiedOwnershipWhenParsing; // Setup the IRGen Options. IRGenOptions &Opts = Invocation.getIRGenOptions(); Opts.MainInputFilename = InputFilename; Opts.OutputFilenames.push_back(OutputFilename); Opts.OutputKind = OutputKind; // Load the input file. llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> FileBufOrErr = llvm::MemoryBuffer::getFileOrSTDIN(InputFilename); if (!FileBufOrErr) { fprintf(stderr, "Error! Failed to open file: %s\n", InputFilename.c_str()); exit(-1); } // If it looks like we have an AST, set the source file kind to SIL and the // name of the module to the file's name. Invocation.addInputBuffer(FileBufOrErr.get().get()); serialization::ExtendedValidationInfo extendedInfo; auto result = serialization::validateSerializedAST( FileBufOrErr.get()->getBuffer(), &extendedInfo); bool HasSerializedAST = result.status == serialization::Status::Valid; if (HasSerializedAST) { const StringRef Stem = ModuleName.size() ? StringRef(ModuleName) : llvm::sys::path::stem(InputFilename); Invocation.setModuleName(Stem); Invocation.setInputKind(InputFileKind::IFK_Swift_Library); } else { const StringRef Name = ModuleName.size() ? StringRef(ModuleName) : "main"; Invocation.setModuleName(Name); Invocation.setInputKind(InputFileKind::IFK_SIL); } CompilerInstance CI; PrintingDiagnosticConsumer PrintDiags; CI.addDiagnosticConsumer(&PrintDiags); if (!PerformWMO) { auto &FrontendOpts = Invocation.getFrontendOptions(); if (!InputFilename.empty() && InputFilename != "-") { FrontendOpts.PrimaryInput = SelectedInput(FrontendOpts.InputFilenames.size()); } else { FrontendOpts.PrimaryInput = SelectedInput( FrontendOpts.InputBuffers.size(), SelectedInput::InputKind::Buffer); } } if (CI.setup(Invocation)) return 1; CI.performSema(); // If parsing produced an error, don't run any passes. if (CI.getASTContext().hadError()) return 1; // Load the SIL if we have a module. We have to do this after SILParse // creating the unfortunate double if statement. if (HasSerializedAST) { assert(!CI.hasSILModule() && "performSema() should not create a SILModule."); CI.setSILModule(SILModule::createEmptyModule( CI.getMainModule(), CI.getSILOptions(), PerformWMO)); std::unique_ptr<SerializedSILLoader> SL = SerializedSILLoader::create( CI.getASTContext(), CI.getSILModule(), nullptr); if (extendedInfo.isSIB()) SL->getAllForModule(CI.getMainModule()->getName(), nullptr); else SL->getAll(); } std::unique_ptr<llvm::Module> Mod = performIRGeneration( Opts, CI.getMainModule(), CI.takeSILModule(), CI.getMainModule()->getName().str(), getGlobalLLVMContext()); return CI.getASTContext().hadError(); }
int main(int argc, char *argv[]) { llvm::cl::SetVersionPrinter(PrintVersion); llvm::cl::ParseCommandLineOptions(argc, argv, "CFG to LLVM"); auto context = llvm::make_unique<llvm::LLVMContext>(); if (OS.empty()) { if (ListSupported || ListUnsupported) { OS = "linux"; // just need something } else { std::cerr << "-os must be specified" << std::endl; return EXIT_FAILURE; } } if (!(ListSupported || ListUnsupported || ListCFGFunctions) && EntryPoints.empty()) { std::cerr << "-entrypoint must be specified" << std::endl; return EXIT_FAILURE; } if (!InitArch(context.get(), OS, Arch)) { std::cerr << "Cannot initialize for arch " << Arch << " and OS " << OS << std::endl; return EXIT_FAILURE; } auto M = CreateModule(context.get()); if (!M) { return EXIT_FAILURE; } auto triple = M->getTargetTriple(); if (ListSupported || ListUnsupported) { ListArchSupportedInstructions(triple, llvm::outs(), ListSupported, ListUnsupported); return EXIT_SUCCESS; } if (InputFilename.empty()) { std::cerr << "Must specify an input file." << std::endl; return EXIT_FAILURE; } //reproduce NativeModule from CFG input argument try { std::unique_ptr<NativeModule> mod(ReadProtoBuf(InputFilename)); if (!mod) { std::cerr << "Unable to read module from CFG" << std::endl; return EXIT_FAILURE; } if (ListCFGFunctions) { PrintCFGFunctionList(mod.get(), Arch); return EXIT_SUCCESS; } //make sure the entry point list is correct before we start lifting the code const std::vector<NativeEntrySymbol> &module_entry_points = mod->getEntryPoints(); for (const auto &entry_point : EntryPoints) { auto it = std::find_if( module_entry_points.begin(), module_entry_points.end(), [&entry_point](const NativeEntrySymbol &symbol) -> bool { return (symbol.getName() == entry_point); } ); if (it == module_entry_points.end()) { std::cerr << "The following entry point could not be found: \"" << entry_point << "\". Aborting..." << std::endl; return EXIT_FAILURE; } } //now, convert it to an LLVM module ArchInitAttachDetach(M); if (!LiftCodeIntoModule(mod.get(), M)) { std::cerr << "Failure to convert to LLVM module!" << std::endl; return EXIT_FAILURE; } std::set<VA> entry_point_pcs; for (const auto &entry_point_name : EntryPoints) { auto entry_pc = FindSymbolInModule(mod.get(), entry_point_name); assert(entry_pc != static_cast<VA>( -1)); std::cerr << "Adding entry point: " << entry_point_name << std::endl << entry_point_name << " is implemented by sub_" << std::hex << entry_pc << std::endl; if ( !ArchAddEntryPointDriver(M, entry_point_name, entry_pc)) { return EXIT_FAILURE; } entry_point_pcs.insert(entry_pc); } RenameLiftedFunctions(mod.get(), M, entry_point_pcs); // will abort if verification fails if (llvm::verifyModule( *M, &llvm::errs())) { std::cerr << "Could not verify module!" << std::endl; return EXIT_FAILURE; } std::error_code ec; llvm::tool_output_file Out(OutputFilename.c_str(), ec, llvm::sys::fs::F_None); llvm::WriteBitcodeToFile(M, Out.os()); Out.keep(); } catch (std::exception &e) { std::cerr << "error: " << std::endl << e.what() << std::endl; return EXIT_FAILURE; } return EXIT_SUCCESS; }
int main(int argc, char **argv) { llvm::llvm_shutdown_obj shutdown; // calls llvm_shutdown() on exit llvm::cl::ParseCommandLineOptions(argc, argv, "llvm2bpl - LLVM bitcode to Boogie transformation\n"); llvm::sys::PrintStackTraceOnErrorSignal(); llvm::PrettyStackTraceProgram PSTP(argc, argv); llvm::EnableDebugBuffering = true; llvm::SMDiagnostic err; std::unique_ptr<llvm::Module> module = llvm::parseIRFile(InputFilename, err, llvm::getGlobalContext()); if (!err.getMessage().empty()) check("Problem reading input bitcode/IR: " + err.getMessage().str()); auto &L = module.get()->getDataLayoutStr(); if (L.empty()) module.get()->setDataLayout(DefaultDataLayout); /////////////////////////////// // initialise and run passes // /////////////////////////////// llvm::PassRegistry &Registry = *llvm::PassRegistry::getPassRegistry(); llvm::initializeAnalysis(Registry); llvm::legacy::PassManager pass_manager; pass_manager.add(llvm::createLowerSwitchPass()); //pass_manager.add(llvm::createCFGSimplificationPass()); pass_manager.add(llvm::createInternalizePass()); pass_manager.add(llvm::createPromoteMemoryToRegisterPass()); if (StaticUnroll) { pass_manager.add(llvm::createLoopSimplifyPass()); pass_manager.add(llvm::createLoopRotatePass()); //pass_manager.add(llvm::createIndVarSimplifyPass()); pass_manager.add(llvm::createLoopUnrollPass(32767)); } pass_manager.add(new llvm::StructRet()); pass_manager.add(new llvm::SimplifyEV()); pass_manager.add(new llvm::SimplifyIV()); pass_manager.add(new smack::ExtractContracts()); pass_manager.add(llvm::createDeadCodeEliminationPass()); pass_manager.add(new smack::CodifyStaticInits()); pass_manager.add(new smack::RemoveDeadDefs()); pass_manager.add(new llvm::MergeArrayGEP()); // pass_manager.add(new smack::SimplifyLibCalls()); pass_manager.add(new llvm::Devirtualize()); if (smack::SmackOptions::MemorySafety) { pass_manager.add(new smack::MemorySafetyChecker()); } if (SignedIntegerOverflow) pass_manager.add(new smack::SignedIntegerOverflowChecker()); std::vector<tool_output_file*> files; if (!FinalIrFilename.empty()) { std::error_code EC; auto F = new tool_output_file(FinalIrFilename.c_str(), EC, sys::fs::F_None); if (EC) check(EC.message()); F->keep(); files.push_back(F); pass_manager.add(llvm::createPrintModulePass(F->os())); } if (!OutputFilename.empty()) { std::error_code EC; auto F = new tool_output_file(OutputFilename.c_str(), EC, sys::fs::F_None); if (EC) check(EC.message()); F->keep(); files.push_back(F); pass_manager.add(new smack::SmackModuleGenerator()); pass_manager.add(new smack::BplFilePrinter(F->os())); } pass_manager.run(*module.get()); for (auto F : files) delete F; return 0; }
int main(int argc, const char **argv) { llvm::sys::PrintStackTraceOnErrorSignal(); Transforms TransformManager; ReplacementHandling ReplacementHandler; TransformManager.registerTransforms(); // Hide all options we don't define ourselves. Move pre-defined 'help', // 'help-list', and 'version' to our general category. llvm::StringMap<cl::Option*> Options; cl::getRegisteredOptions(Options); const cl::OptionCategory **CategoryEnd = VisibleCategories + llvm::array_lengthof(VisibleCategories); for (llvm::StringMap<cl::Option *>::iterator I = Options.begin(), E = Options.end(); I != E; ++I) { if (I->first() == "help" || I->first() == "version" || I->first() == "help-list") I->second->setCategory(GeneralCategory); else if (std::find(VisibleCategories, CategoryEnd, I->second->Category) == CategoryEnd) I->second->setHiddenFlag(cl::ReallyHidden); } cl::SetVersionPrinter(&printVersion); // Parse options and generate compilations. std::unique_ptr<CompilationDatabase> Compilations( FixedCompilationDatabase::loadFromCommandLine(argc, argv)); cl::ParseCommandLineOptions(argc, argv); // Populate the ModifiableFiles structure. GlobalOptions.ModifiableFiles.readListFromString(IncludePaths, ExcludePaths); GlobalOptions.ModifiableFiles.readListFromFile(IncludeFromFile, ExcludeFromFile); if (!Compilations) { std::string ErrorMessage; Compilations.reset(autoDetectCompilations(ErrorMessage)); if (!Compilations) { llvm::errs() << llvm::sys::path::filename(argv[0]) << ": " << ErrorMessage << "\n"; return 1; } } // Populate source files. std::vector<std::string> Sources; if (!SourcePaths.empty()) { // Use only files that are not explicitly excluded. std::remove_copy_if(SourcePaths.begin(), SourcePaths.end(), std::back_inserter(Sources), isFileExplicitlyExcludedPredicate); } else { if (GlobalOptions.ModifiableFiles.isIncludeListEmpty()) { llvm::errs() << llvm::sys::path::filename(argv[0]) << ": Use -include to indicate which files of " << "the compilatiion database to transform.\n"; return 1; } // Use source paths from the compilation database. // We only transform files that are explicitly included. Sources = Compilations->getAllFiles(); std::vector<std::string>::iterator E = std::remove_if( Sources.begin(), Sources.end(), isFileNotIncludedPredicate); Sources.erase(E, Sources.end()); } // check if line ranges are just applyed to single files if ( !LineRanges.empty() && Sources.size() > 1 ){ llvm::errs() << "error: -line can only be used for single file.\n"; return 1; } // add the line ranges to the sources if ( !LineRanges.empty() ){ } if (Sources.empty()) { llvm::errs() << llvm::sys::path::filename(argv[0]) << ": Could not determine sources to transform.\n"; return 1; } // Enable timming. GlobalOptions.EnableTiming = TimingDirectoryName.getNumOccurrences() > 0; bool CmdSwitchError = false; CompilerVersions RequiredVersions = handleSupportedCompilers(argv[0], CmdSwitchError); if (CmdSwitchError) return 1; TransformManager.createSelectedTransforms(GlobalOptions, RequiredVersions); if (TransformManager.begin() == TransformManager.end()) { if (SupportedCompilers.empty()) llvm::errs() << llvm::sys::path::filename(argv[0]) << ": no selected transforms\n"; else llvm::errs() << llvm::sys::path::filename(argv[0]) << ": no transforms available for specified compilers\n"; return 1; } llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> DiagOpts( new DiagnosticOptions()); DiagnosticsEngine Diagnostics( llvm::IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs()), DiagOpts.getPtr()); // FIXME: Make this DiagnosticsEngine available to all Transforms probably via // GlobalOptions. // If SerializeReplacements is requested, then code reformatting must be // turned off and only one transform should be requested. if (SerializeOnly && (std::distance(TransformManager.begin(), TransformManager.end()) > 1 || DoFormat)) { llvm::errs() << "Serialization of replacements requested for multiple " "transforms.\nChanges from only one transform can be " "serialized.\n"; return 1; } // If we're asked to apply changes to files on disk, need to locate // clang-apply-replacements. if (!SerializeOnly) { if (!ReplacementHandler.findClangApplyReplacements(argv[0])) { llvm::errs() << "Could not find clang-apply-replacements\n"; return 1; } if (DoFormat) ReplacementHandler.enableFormatting(FormatStyleOpt, FormatStyleConfig); } StringRef TempDestinationDir; if (SerializeLocation.getNumOccurrences() > 0) ReplacementHandler.setDestinationDir(SerializeLocation); else TempDestinationDir = ReplacementHandler.useTempDestinationDir(); SourcePerfData PerfData; for (Transforms::const_iterator I = TransformManager.begin(), E = TransformManager.end(); I != E; ++I) { Transform *T = *I; if (T->apply(*Compilations, Sources,LineRanges) != 0) { // FIXME: Improve ClangTool to not abort if just one file fails. return 1; } if (GlobalOptions.EnableTiming) collectSourcePerfData(*T, PerfData); if (SummaryMode) { llvm::outs() << "Transform: " << T->getName() << " - Accepted: " << T->getAcceptedChanges(); if (T->getChangesNotMade()) { llvm::outs() << " - Rejected: " << T->getRejectedChanges() << " - Deferred: " << T->getDeferredChanges(); } llvm::outs() << "\n"; } if (!ReplacementHandler.serializeReplacements(T->getAllReplacements())) return 1; if (!SerializeOnly) if (!ReplacementHandler.applyReplacements()) return 1; } // Let the user know which temporary directory the replacements got written // to. if (SerializeOnly && !TempDestinationDir.empty()) llvm::errs() << "Replacements serialized to: " << TempDestinationDir << "\n"; if (FinalSyntaxCheck) { ClangTool SyntaxTool(*Compilations, SourcePaths); if (SyntaxTool.run(newFrontendActionFactory<SyntaxOnlyAction>().get()) != 0) return 1; } // Report execution times. if (GlobalOptions.EnableTiming && !PerfData.empty()) { std::string DirectoryName = TimingDirectoryName; // Use default directory name. if (DirectoryName.empty()) DirectoryName = "./migrate_perf"; writePerfDataJSON(DirectoryName, PerfData); } return 0; }
int createStaticLibrary() { Logger::println("*** Creating static library ***"); const bool isTargetMSVC = global.params.targetTriple->isWindowsMSVCEnvironment(); #if LDC_LLVM_VER >= 309 const bool useInternalArchiver = ar.empty(); #else const bool useInternalArchiver = false; #endif // find archiver std::string tool; if (useInternalArchiver) { tool = isTargetMSVC ? "llvm-lib.exe" : "llvm-ar"; } else { #ifdef _WIN32 if (isTargetMSVC) windows::setupMsvcEnvironment(); #endif tool = getProgram(isTargetMSVC ? "lib.exe" : "ar", &ar); } // build arguments std::vector<std::string> args; // ask ar to create a new library if (!isTargetMSVC) { args.push_back("rcs"); } // ask lib to be quiet if (isTargetMSVC) { args.push_back("/NOLOGO"); } // output filename std::string libName; if (global.params.libname) { // explicit // DMD adds the default extension if there is none libName = opts::invokedByLDMD ? FileName::defaultExt(global.params.libname, global.lib_ext) : global.params.libname; } else { // infer from first object file libName = global.params.objfiles->dim ? FileName::removeExt((*global.params.objfiles)[0]) : "a.out"; libName += '.'; libName += global.lib_ext; } // DMD creates static libraries in the objects directory (unless using an // absolute output path via `-of`). if (opts::invokedByLDMD && global.params.objdir && !FileName::absolute(libName.c_str())) { libName = FileName::combine(global.params.objdir, libName.c_str()); } if (isTargetMSVC) { args.push_back("/OUT:" + libName); } else { args.push_back(libName); } appendObjectFiles(args); // create path to the library CreateDirectoryOnDisk(libName); #if LDC_LLVM_VER >= 309 if (useInternalArchiver) { std::vector<const char *> fullArgs; fullArgs.reserve(1 + args.size()); fullArgs.push_back(tool.c_str()); for (const auto &arg : args) fullArgs.push_back(arg.c_str()); if (global.params.verbose) { for (auto arg : fullArgs) { fprintf(global.stdmsg, "%s ", arg); } fprintf(global.stdmsg, "\n"); fflush(global.stdmsg); } const int exitCode = isTargetMSVC ? ldc::lib(fullArgs) : ldc::ar(fullArgs); if (exitCode) error(Loc(), "%s failed with status: %d", tool.c_str(), exitCode); return exitCode; } #endif // try to call archiver return executeToolAndWait(tool, args, global.params.verbose); }
int main(int argc, char **argv) { llvm::cl::ParseCommandLineOptions(argc, argv, "clang-wpa"); std::vector<ASTUnit*> ASTUnits; Program Prog; Indexer Idxer(Prog); if (InputFilenames.empty()) return 0; DiagnosticOptions DiagOpts; llvm::IntrusiveRefCntPtr<Diagnostic> Diags = CompilerInstance::createDiagnostics(DiagOpts, argc, argv); for (unsigned i = 0, e = InputFilenames.size(); i != e; ++i) { const std::string &InFile = InputFilenames[i]; llvm::OwningPtr<ASTUnit> AST(ASTUnit::LoadFromASTFile(InFile, Diags)); if (!AST) return 1; ASTUnits.push_back(AST.take()); } if (ViewCallGraph) { llvm::OwningPtr<CallGraph> CG; CG.reset(new CallGraph(Prog)); for (unsigned i = 0, e = ASTUnits.size(); i != e; ++i) CG->addTU(ASTUnits[i]->getASTContext()); CG->ViewCallGraph(); return 0; } if (AnalyzeFunction.empty()) return 0; // Feed all ASTUnits to the Indexer. for (unsigned i = 0, e = ASTUnits.size(); i != e; ++i) { ASTUnitTU *TU = new ASTUnitTU(ASTUnits[i]); Idxer.IndexAST(TU); } Entity Ent = Entity::get(AnalyzeFunction, Prog); FunctionDecl *FD; TranslationUnit *TU; llvm::tie(FD, TU) = Idxer.getDefinitionFor(Ent); if (!FD) return 0; // Create an analysis engine. Preprocessor &PP = TU->getPreprocessor(); // Hard code options for now. AnalysisManager AMgr(TU->getASTContext(), PP.getDiagnostics(), PP.getLangOptions(), /* PathDiagnostic */ 0, CreateRegionStoreManager, CreateRangeConstraintManager, &Idxer, /* MaxNodes */ 300000, /* MaxLoop */ 3, /* VisualizeEG */ false, /* VisualizeEGUbi */ false, /* PurgeDead */ true, /* EagerlyAssume */ false, /* TrimGraph */ false, /* InlineCall */ true, /* UseUnoptimizedCFG */ false); GRTransferFuncs* TF = MakeCFRefCountTF(AMgr.getASTContext(), /*GC*/false, AMgr.getLangOptions()); GRExprEngine Eng(AMgr, TF); Eng.ExecuteWorkList(AMgr.getStackFrame(FD, TU), AMgr.getMaxNodes()); return 0; }
int main(int argc, char **argv) { llvm::llvm_shutdown_obj shutdown; // calls llvm_shutdown() on exit llvm::cl::ParseCommandLineOptions(argc, argv, "llvm2bpl - LLVM bitcode to Boogie transformation\n"); llvm::sys::PrintStackTraceOnErrorSignal(argv[0]); llvm::PrettyStackTraceProgram PSTP(argc, argv); llvm::EnableDebugBuffering = true; llvm::SMDiagnostic err; llvm::LLVMContext Context; InitializeAllTargets(); InitializeAllTargetMCs(); InitializeAllAsmPrinters(); InitializeAllAsmParsers(); std::unique_ptr<llvm::Module> module = llvm::parseIRFile(InputFilename, err, Context); if (!err.getMessage().empty()) check("Problem reading input bitcode/IR: " + err.getMessage().str()); auto &L = module.get()->getDataLayoutStr(); if (L.empty()) module.get()->setDataLayout(DefaultDataLayout); /////////////////////////////// // initialise and run passes // /////////////////////////////// llvm::PassRegistry &Registry = *llvm::PassRegistry::getPassRegistry(); llvm::initializeAnalysis(Registry); llvm::legacy::PassManager pass_manager; pass_manager.add(llvm::createLowerSwitchPass()); //pass_manager.add(llvm::createCFGSimplificationPass()); pass_manager.add(llvm::createInternalizePass()); pass_manager.add(llvm::createPromoteMemoryToRegisterPass()); if (StaticUnroll) { pass_manager.add(llvm::createLoopSimplifyPass()); pass_manager.add(llvm::createLoopRotatePass()); //pass_manager.add(llvm::createIndVarSimplifyPass()); pass_manager.add(llvm::createLoopUnrollPass(32767)); } pass_manager.add(new llvm::StructRet()); pass_manager.add(new llvm::SimplifyEV()); pass_manager.add(new llvm::SimplifyIV()); pass_manager.add(new smack::ExtractContracts()); pass_manager.add(new smack::VerifierCodeMetadata()); pass_manager.add(llvm::createDeadCodeEliminationPass()); pass_manager.add(new smack::CodifyStaticInits()); if (!Modular) { pass_manager.add(new smack::RemoveDeadDefs()); } pass_manager.add(new llvm::MergeArrayGEP()); // pass_manager.add(new smack::SimplifyLibCalls()); pass_manager.add(new llvm::Devirtualize()); if (SplitStructs) pass_manager.add(new smack::SplitAggregateLoadStore()); if (smack::SmackOptions::MemorySafety) { pass_manager.add(new smack::MemorySafetyChecker()); } if (SignedIntegerOverflow) pass_manager.add(new smack::SignedIntegerOverflowChecker()); if(smack::SmackOptions::AddTiming){ Triple ModuleTriple(module->getTargetTriple()); assert (ModuleTriple.getArch() && "Module has no defined architecture: unable to add timing annotations"); const TargetOptions Options; /* = InitTargetOptionsFromCodeGenFlags();*/ std::string CPUStr = ""; /*getCPUStr();*/ std::string FeaturesStr = ""; /*getFeaturesStr();*/ TargetMachine *Machine = GetTargetMachine(ModuleTriple, CPUStr, FeaturesStr, Options); assert(Machine && "Module did not have a Target Machine: Cannot set up timing pass"); // Add an appropriate TargetLibraryInfo pass for the module's triple. TargetLibraryInfoImpl TLII(ModuleTriple); pass_manager.add(new TargetLibraryInfoWrapperPass(TLII)); // Add internal analysis passes from the target machine. pass_manager.add(createTargetTransformInfoWrapperPass(Machine->getTargetIRAnalysis())); pass_manager.add(new smack::AddTiming()); } std::vector<tool_output_file*> files; if (!FinalIrFilename.empty()) { std::error_code EC; auto F = new tool_output_file(FinalIrFilename.c_str(), EC, sys::fs::F_None); if (EC) check(EC.message()); F->keep(); files.push_back(F); pass_manager.add(llvm::createPrintModulePass(F->os())); } if (!OutputFilename.empty()) { std::error_code EC; auto F = new tool_output_file(OutputFilename.c_str(), EC, sys::fs::F_None); if (EC) check(EC.message()); F->keep(); files.push_back(F); pass_manager.add(new smack::SmackModuleGenerator()); pass_manager.add(new smack::BplFilePrinter(F->os())); } pass_manager.run(*module.get()); for (auto F : files) delete F; return 0; }
int main(int argc, char **argv) { llvm::llvm_shutdown_obj shutdown; // calls llvm_shutdown() on exit llvm::cl::ParseCommandLineOptions(argc, argv, "SMACK - LLVM bitcode to Boogie transformation\n"); llvm::sys::PrintStackTraceOnErrorSignal(); llvm::PrettyStackTraceProgram PSTP(argc, argv); llvm::EnableDebugBuffering = true; if (OutputFilename.empty()) { // OutputFilename = getFileName(InputFilename) + ".bpl"; OutputFilename = "a.bpl"; } std::string error_msg; llvm::SMDiagnostic err; llvm::LLVMContext &context = llvm::getGlobalContext(); std::unique_ptr<llvm::Module> module; std::unique_ptr<llvm::tool_output_file> output; module.reset(llvm::ParseIRFile(InputFilename, err, context)); if (module.get() == 0) { if (llvm::errs().has_colors()) llvm::errs().changeColor(llvm::raw_ostream::RED); llvm::errs() << "error: " << "Bitcode was not properly read; " << err.getMessage() << "\n"; if (llvm::errs().has_colors()) llvm::errs().resetColor(); return 1; } output.reset(new llvm::tool_output_file(OutputFilename.c_str(), error_msg, llvm::sys::fs::F_None)); if (!error_msg.empty()) { if (llvm::errs().has_colors()) llvm::errs().changeColor(llvm::raw_ostream::RED); llvm::errs() << "error: " << error_msg << "\n"; if (llvm::errs().has_colors()) llvm::errs().resetColor(); return 1; } /////////////////////////////// // initialise and run passes // /////////////////////////////// llvm::PassManager pass_manager; llvm::PassRegistry &Registry = *llvm::PassRegistry::getPassRegistry(); llvm::initializeAnalysis(Registry); // add an appropriate DataLayout instance for the module const llvm::DataLayout *dl = 0; const std::string &moduleDataLayout = module.get()->getDataLayoutStr(); if (!moduleDataLayout.empty()) dl = new llvm::DataLayout(moduleDataLayout); else if (!DefaultDataLayout.empty()) dl = new llvm::DataLayout(moduleDataLayout); if (dl) pass_manager.add(new llvm::DataLayoutPass(*dl)); pass_manager.add(llvm::createLowerSwitchPass()); pass_manager.add(llvm::createCFGSimplificationPass()); pass_manager.add(llvm::createInternalizePass()); pass_manager.add(llvm::createPromoteMemoryToRegisterPass()); pass_manager.add(new llvm::StructRet()); pass_manager.add(new llvm::SimplifyEV()); pass_manager.add(new llvm::SimplifyIV()); pass_manager.add(new smack::SmackModuleGenerator()); pass_manager.add(new smack::BplFilePrinter(output->os())); pass_manager.run(*module.get()); output->keep(); return 0; }
static int do_assemble(SourceManager& source_mgr, DiagnosticsEngine& diags) { // Apply warning settings ApplyWarningSettings(diags); // Determine objfmt_bits based on -32 and -64 options std::string objfmt_bits = GetBitsSetting(); FileManager& file_mgr = source_mgr.getFileManager(); Assembler assembler("x86", YGAS_OBJFMT_BASE + objfmt_bits, diags, dump_object); HeaderSearch headers(file_mgr); if (diags.hasFatalErrorOccurred()) return EXIT_FAILURE; // Set object filename if specified. if (!obj_filename.empty()) assembler.setObjectFilename(obj_filename); // Set parser. assembler.setParser("gas", diags); if (diags.hasFatalErrorOccurred()) return EXIT_FAILURE; // Set debug format to dwarf2pass if it's legal for this object format. if (assembler.isOkDebugFormat("dwarf2pass")) { assembler.setDebugFormat("dwarf2pass", diags); if (diags.hasFatalErrorOccurred()) return EXIT_FAILURE; } // open the input file or STDIN (for filename of "-") if (in_filename == "-") { OwningPtr<MemoryBuffer> my_stdin; if (llvm::error_code err = MemoryBuffer::getSTDIN(my_stdin)) { diags.Report(SourceLocation(), diag::fatal_file_open) << in_filename << err.message(); return EXIT_FAILURE; } source_mgr.createMainFileIDForMemBuffer(my_stdin.take()); } else { const FileEntry* in = file_mgr.getFile(in_filename); if (!in) { diags.Report(SourceLocation(), diag::fatal_file_open) << in_filename; return EXIT_FAILURE; } source_mgr.createMainFileID(in); } // Initialize the object. if (!assembler.InitObject(source_mgr, diags)) return EXIT_FAILURE; // Configure object per command line parameters. ConfigureObject(*assembler.getObject()); // Predefine symbols. for (std::vector<std::string>::const_iterator i=defsym.begin(), end=defsym.end(); i != end; ++i) { StringRef str(*i); size_t equalpos = str.find('='); if (equalpos == StringRef::npos) { diags.Report(diag::fatal_bad_defsym) << str; continue; } StringRef name = str.slice(0, equalpos); StringRef vstr = str.slice(equalpos+1, StringRef::npos); IntNum value; if (!vstr.empty()) { // determine radix unsigned int radix; if (vstr[0] == '0' && vstr.size() > 1 && (vstr[1] == 'x' || vstr[1] == 'X')) { vstr = vstr.substr(2); radix = 16; } else if (vstr[0] == '0') { vstr = vstr.substr(1); radix = 8; } else radix = 10; // check validity const char* ptr = vstr.begin(); const char* end = vstr.end(); if (radix == 16) { while (ptr != end && isxdigit(*ptr)) ++ptr; } else if (radix == 8) { while (ptr != end && (*ptr >= '0' && *ptr <= '7')) ++ptr; } else { while (ptr != end && isdigit(*ptr)) ++ptr; } if (ptr != end) { diags.Report(diag::fatal_bad_defsym) << name; continue; } value.setStr(vstr, radix); } // define equ assembler.getObject()->getSymbol(name)->DefineEqu(Expr(value)); } if (diags.hasFatalErrorOccurred()) return EXIT_FAILURE; // Initialize the parser. assembler.InitParser(source_mgr, diags, headers); // Assemble the input. if (!assembler.Assemble(source_mgr, diags)) { // An error occurred during assembly. return EXIT_FAILURE; } // open the object file for output std::string err; raw_fd_ostream out(assembler.getObjectFilename().str().c_str(), err, raw_fd_ostream::F_Binary); if (!err.empty()) { diags.Report(SourceLocation(), diag::err_cannot_open_file) << obj_filename << err; return EXIT_FAILURE; } if (!assembler.Output(out, diags)) { // An error occurred during output. // If we had an error at this point, we also need to delete the output // object file (to make sure it's not left newer than the source). out.close(); remove(assembler.getObjectFilename().str().c_str()); return EXIT_FAILURE; } // close object file out.close(); return EXIT_SUCCESS; }
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; }
int main(int argc, char **argv) { INITIALIZE_LLVM(argc, argv); llvm::cl::ParseCommandLineOptions(argc, argv, "Swift SIL Extractor\n"); CompilerInvocation Invocation; Invocation.setMainExecutablePath(llvm::sys::fs::getMainExecutable( argv[0], reinterpret_cast<void *>(&anchorForGetMainExecutable))); // Give the context the list of search paths to use for modules. Invocation.setImportSearchPaths(ImportPaths); // Set the SDK path and target if given. if (SDKPath.getNumOccurrences() == 0) { const char *SDKROOT = getenv("SDKROOT"); if (SDKROOT) SDKPath = SDKROOT; } if (!SDKPath.empty()) Invocation.setSDKPath(SDKPath); if (!Triple.empty()) Invocation.setTargetTriple(Triple); if (!ResourceDir.empty()) Invocation.setRuntimeResourcePath(ResourceDir); Invocation.getClangImporterOptions().ModuleCachePath = ModuleCachePath; Invocation.setParseStdlib(); Invocation.getLangOptions().DisableAvailabilityChecking = true; Invocation.getLangOptions().EnableAccessControl = false; Invocation.getLangOptions().EnableObjCAttrRequiresFoundation = false; // Load the input file. llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> FileBufOrErr = llvm::MemoryBuffer::getFileOrSTDIN(InputFilename); if (!FileBufOrErr) { fprintf(stderr, "Error! Failed to open file: %s\n", InputFilename.c_str()); exit(-1); } // If it looks like we have an AST, set the source file kind to SIL and the // name of the module to the file's name. Invocation.addInputBuffer(FileBufOrErr.get().get()); serialization::ExtendedValidationInfo extendedInfo; auto result = serialization::validateSerializedAST( FileBufOrErr.get()->getBuffer(), &extendedInfo); bool HasSerializedAST = result.status == serialization::Status::Valid; if (HasSerializedAST) { const StringRef Stem = ModuleName.size() ? StringRef(ModuleName) : llvm::sys::path::stem(InputFilename); Invocation.setModuleName(Stem); Invocation.setInputKind(InputFileKind::IFK_Swift_Library); } else { Invocation.setModuleName("main"); Invocation.setInputKind(InputFileKind::IFK_SIL); } SILOptions &SILOpts = Invocation.getSILOptions(); SILOpts.AssumeUnqualifiedOwnershipWhenParsing = AssumeUnqualifiedOwnershipWhenParsing; CompilerInstance CI; PrintingDiagnosticConsumer PrintDiags; CI.addDiagnosticConsumer(&PrintDiags); if (CI.setup(Invocation)) return 1; CI.performSema(); // If parsing produced an error, don't run any passes. if (CI.getASTContext().hadError()) return 1; // Load the SIL if we have a module. We have to do this after SILParse // creating the unfortunate double if statement. if (HasSerializedAST) { assert(!CI.hasSILModule() && "performSema() should not create a SILModule."); CI.setSILModule( SILModule::createEmptyModule(CI.getMainModule(), CI.getSILOptions())); std::unique_ptr<SerializedSILLoader> SL = SerializedSILLoader::create( CI.getASTContext(), CI.getSILModule(), nullptr); if (extendedInfo.isSIB()) SL->getAllForModule(CI.getMainModule()->getName(), nullptr); else SL->getAll(); } if (CommandLineFunctionNames.empty() && FunctionNameFile.empty()) return CI.getASTContext().hadError(); // For efficient usage, we separate our names into two separate sorted // lists, one of managled names, and one of unmangled names. std::vector<std::string> Names; getFunctionNames(Names); // First partition our function names into mangled/demangled arrays. auto FirstDemangledName = std::partition( Names.begin(), Names.end(), [](const std::string &Name) -> bool { StringRef NameRef(Name); return NameRef.startswith("_T") || NameRef.startswith(MANGLING_PREFIX_STR); }); // Then grab offsets to avoid any issues with iterator invalidation when we // sort. unsigned NumMangled = std::distance(Names.begin(), FirstDemangledName); unsigned NumNames = Names.size(); // Then sort the two partitioned arrays. std::sort(Names.begin(), FirstDemangledName); std::sort(FirstDemangledName, Names.end()); // Finally construct our ArrayRefs into the sorted std::vector for our // mangled and demangled names. ArrayRef<std::string> MangledNames(&*Names.begin(), NumMangled); ArrayRef<std::string> DemangledNames(&*std::next(Names.begin(), NumMangled), NumNames - NumMangled); DEBUG(llvm::errs() << "MangledNames to keep:\n"; std::for_each(MangledNames.begin(), MangledNames.end(), [](const std::string &str) { llvm::errs() << " " << str << '\n'; })); DEBUG(llvm::errs() << "DemangledNames to keep:\n"; std::for_each(DemangledNames.begin(), DemangledNames.end(), [](const std::string &str) { llvm::errs() << " " << str << '\n'; })); removeUnwantedFunctions(CI.getSILModule(), MangledNames, DemangledNames); if (EmitSIB) { llvm::SmallString<128> OutputFile; if (OutputFilename.size()) { OutputFile = OutputFilename; } else if (ModuleName.size()) { OutputFile = ModuleName; llvm::sys::path::replace_extension(OutputFile, SIB_EXTENSION); } else { OutputFile = CI.getMainModule()->getName().str(); llvm::sys::path::replace_extension(OutputFile, SIB_EXTENSION); } SerializationOptions serializationOpts; serializationOpts.OutputPath = OutputFile.c_str(); serializationOpts.SerializeAllSIL = true; serializationOpts.IsSIB = true; serialize(CI.getMainModule(), serializationOpts, CI.getSILModule()); } else { const StringRef OutputFile = OutputFilename.size() ? StringRef(OutputFilename) : "-"; if (OutputFile == "-") { CI.getSILModule()->print(llvm::outs(), EmitVerboseSIL, CI.getMainModule(), EnableSILSortOutput, !DisableASTDump); } else { std::error_code EC; llvm::raw_fd_ostream OS(OutputFile, EC, llvm::sys::fs::F_None); if (EC) { llvm::errs() << "while opening '" << OutputFile << "': " << EC.message() << '\n'; return 1; } CI.getSILModule()->print(OS, EmitVerboseSIL, CI.getMainModule(), EnableSILSortOutput, !DisableASTDump); } } }