// Convert the subtarget features into a string to pass to LTOCodeGenerator. static void lto_add_attrs(lto_code_gen_t cg) { LTOCodeGenerator *CG = unwrap(cg); if (MAttrs.size()) { std::string attrs; for (unsigned i = 0; i < MAttrs.size(); ++i) { if (i > 0) attrs.append(","); attrs.append(MAttrs[i]); } CG->setAttr(attrs.c_str()); } }
// Convert the subtarget features into a string to pass to LTOCodeGenerator. static void lto_add_attrs(lto_code_gen_t cg) { LTOCodeGenerator *CG = unwrap(cg); if (MAttrs.size()) { std::string attrs; for (unsigned i = 0; i < MAttrs.size(); ++i) { if (i > 0) attrs.append(","); attrs.append(MAttrs[i]); } CG->setAttr(attrs.c_str()); } if (OptLevel < '0' || OptLevel > '3') report_fatal_error("Optimization level must be between 0 and 3"); CG->setOptLevel(OptLevel - '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. cl::ParseCommandLineOptions(argc, argv, "llvm LTO linker\n"); if (OptLevel < '0' || OptLevel > '3') { errs() << argv[0] << ": optimization level must be between 0 and 3\n"; return 1; } // Initialize the configured targets. InitializeAllTargets(); InitializeAllTargetMCs(); InitializeAllAsmPrinters(); InitializeAllAsmParsers(); // set up the TargetOptions for the machine TargetOptions Options = InitTargetOptionsFromCodeGenFlags(); if (ListSymbolsOnly) return listSymbols(argv[0], Options); if (ThinLTO) return createCombinedFunctionIndex(argv[0]); unsigned BaseArg = 0; LTOCodeGenerator CodeGen; if (UseDiagnosticHandler) CodeGen.setDiagnosticHandler(handleDiagnostics, nullptr); CodeGen.setCodePICModel(RelocModel); CodeGen.setDebugInfo(LTO_DEBUG_MODEL_DWARF); CodeGen.setTargetOptions(Options); llvm::StringSet<llvm::MallocAllocator> DSOSymbolsSet; for (unsigned i = 0; i < DSOSymbols.size(); ++i) DSOSymbolsSet.insert(DSOSymbols[i]); std::vector<std::string> KeptDSOSyms; for (unsigned i = BaseArg; i < InputFilenames.size(); ++i) { std::string error; std::unique_ptr<LTOModule> Module( LTOModule::createFromFile(InputFilenames[i].c_str(), Options, error)); if (!error.empty()) { errs() << argv[0] << ": error loading file '" << InputFilenames[i] << "': " << error << "\n"; return 1; } unsigned NumSyms = Module->getSymbolCount(); for (unsigned I = 0; I < NumSyms; ++I) { StringRef Name = Module->getSymbolName(I); if (!DSOSymbolsSet.count(Name)) continue; lto_symbol_attributes Attrs = Module->getSymbolAttributes(I); unsigned Scope = Attrs & LTO_SYMBOL_SCOPE_MASK; if (Scope != LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN) KeptDSOSyms.push_back(Name); } // We use the first input module as the destination module when // SetMergedModule is true. if (SetMergedModule && i == BaseArg) { // Transfer ownership to the code generator. CodeGen.setModule(std::move(Module)); } else if (!CodeGen.addModule(Module.get())) { // Print a message here so that we know addModule() did not abort. errs() << argv[0] << ": error adding file '" << InputFilenames[i] << "'\n"; return 1; } } // Add all the exported symbols to the table of symbols to preserve. for (unsigned i = 0; i < ExportedSymbols.size(); ++i) CodeGen.addMustPreserveSymbol(ExportedSymbols[i].c_str()); // Add all the dso symbols to the table of symbols to expose. for (unsigned i = 0; i < KeptDSOSyms.size(); ++i) CodeGen.addMustPreserveSymbol(KeptDSOSyms[i].c_str()); // Set cpu and attrs strings for the default target/subtarget. CodeGen.setCpu(MCPU.c_str()); CodeGen.setOptLevel(OptLevel - '0'); std::string attrs; for (unsigned i = 0; i < MAttrs.size(); ++i) { if (i > 0) attrs.append(","); attrs.append(MAttrs[i]); } if (!attrs.empty()) CodeGen.setAttr(attrs.c_str()); if (!OutputFilename.empty()) { std::string ErrorInfo; if (!CodeGen.optimize(DisableVerify, DisableInline, DisableGVNLoadPRE, DisableLTOVectorization, ErrorInfo)) { errs() << argv[0] << ": error optimizing the code: " << ErrorInfo << "\n"; return 1; } std::list<tool_output_file> OSs; std::vector<raw_pwrite_stream *> OSPtrs; for (unsigned I = 0; I != Parallelism; ++I) { std::string PartFilename = OutputFilename; if (Parallelism != 1) PartFilename += "." + utostr(I); std::error_code EC; OSs.emplace_back(PartFilename, EC, sys::fs::F_None); if (EC) { errs() << argv[0] << ": error opening the file '" << PartFilename << "': " << EC.message() << "\n"; return 1; } OSPtrs.push_back(&OSs.back().os()); } if (!CodeGen.compileOptimized(OSPtrs, ErrorInfo)) { errs() << argv[0] << ": error compiling the code: " << ErrorInfo << "\n"; return 1; } for (tool_output_file &OS : OSs) OS.keep(); } else { if (Parallelism != 1) { errs() << argv[0] << ": -j must be specified together with -o\n"; return 1; } std::string ErrorInfo; const char *OutputName = nullptr; if (!CodeGen.compile_to_file(&OutputName, DisableVerify, DisableInline, DisableGVNLoadPRE, DisableLTOVectorization, ErrorInfo)) { errs() << argv[0] << ": error compiling the code: " << ErrorInfo << "\n"; return 1; } outs() << "Wrote native object file '" << OutputName << "'\n"; } 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. cl::ParseCommandLineOptions(argc, argv, "llvm LTO linker\n"); // Initialize the configured targets. InitializeAllTargets(); InitializeAllTargetMCs(); InitializeAllAsmPrinters(); InitializeAllAsmParsers(); // set up the TargetOptions for the machine TargetOptions Options = InitTargetOptionsFromCodeGenFlags(); if (ListSymbolsOnly) return listSymbols(argv[0], Options); unsigned BaseArg = 0; LTOCodeGenerator CodeGen; if (UseDiagnosticHandler) CodeGen.setDiagnosticHandler(handleDiagnostics, nullptr); switch (RelocModel) { case Reloc::Static: CodeGen.setCodePICModel(LTO_CODEGEN_PIC_MODEL_STATIC); break; case Reloc::PIC_: CodeGen.setCodePICModel(LTO_CODEGEN_PIC_MODEL_DYNAMIC); break; case Reloc::DynamicNoPIC: CodeGen.setCodePICModel(LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC); break; default: CodeGen.setCodePICModel(LTO_CODEGEN_PIC_MODEL_DEFAULT); } CodeGen.setDebugInfo(LTO_DEBUG_MODEL_DWARF); CodeGen.setTargetOptions(Options); llvm::StringSet<llvm::MallocAllocator> DSOSymbolsSet; for (unsigned i = 0; i < DSOSymbols.size(); ++i) DSOSymbolsSet.insert(DSOSymbols[i]); std::vector<std::string> KeptDSOSyms; for (unsigned i = BaseArg; i < InputFilenames.size(); ++i) { std::string error; std::unique_ptr<LTOModule> Module( LTOModule::createFromFile(InputFilenames[i].c_str(), Options, error)); if (!error.empty()) { errs() << argv[0] << ": error loading file '" << InputFilenames[i] << "': " << error << "\n"; return 1; } if (!CodeGen.addModule(Module.get())) return 1; unsigned NumSyms = Module->getSymbolCount(); for (unsigned I = 0; I < NumSyms; ++I) { StringRef Name = Module->getSymbolName(I); if (!DSOSymbolsSet.count(Name)) continue; lto_symbol_attributes Attrs = Module->getSymbolAttributes(I); unsigned Scope = Attrs & LTO_SYMBOL_SCOPE_MASK; if (Scope != LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN) KeptDSOSyms.push_back(Name); } } // Add all the exported symbols to the table of symbols to preserve. for (unsigned i = 0; i < ExportedSymbols.size(); ++i) CodeGen.addMustPreserveSymbol(ExportedSymbols[i].c_str()); // Add all the dso symbols to the table of symbols to expose. for (unsigned i = 0; i < KeptDSOSyms.size(); ++i) CodeGen.addMustPreserveSymbol(KeptDSOSyms[i].c_str()); // Set cpu and attrs strings for the default target/subtarget. CodeGen.setCpu(MCPU.c_str()); std::string attrs; for (unsigned i = 0; i < MAttrs.size(); ++i) { if (i > 0) attrs.append(","); attrs.append(MAttrs[i]); } if (!attrs.empty()) CodeGen.setAttr(attrs.c_str()); if (!OutputFilename.empty()) { size_t len = 0; std::string ErrorInfo; const void *Code = CodeGen.compile(&len, DisableOpt, DisableInline, DisableGVNLoadPRE, DisableLTOVectorization, ErrorInfo); if (!Code) { errs() << argv[0] << ": error compiling the code: " << ErrorInfo << "\n"; return 1; } std::error_code EC; raw_fd_ostream FileStream(OutputFilename, EC, sys::fs::F_None); if (EC) { errs() << argv[0] << ": error opening the file '" << OutputFilename << "': " << EC.message() << "\n"; return 1; } FileStream.write(reinterpret_cast<const char *>(Code), len); } else { std::string ErrorInfo; const char *OutputName = nullptr; if (!CodeGen.compile_to_file(&OutputName, DisableOpt, DisableInline, DisableGVNLoadPRE, DisableLTOVectorization, ErrorInfo)) { errs() << argv[0] << ": error compiling the code: " << ErrorInfo << "\n"; return 1; } outs() << "Wrote native object file '" << OutputName << "'\n"; } return 0; }