188fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne//===-- llvm-lto: a simple command-line program to link modules with LTO --===// 288fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne// 388fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne// The LLVM Compiler Infrastructure 488fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne// 588fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne// This file is distributed under the University of Illinois Open Source 688fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne// License. See LICENSE.TXT for details. 788fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne// 888fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne//===----------------------------------------------------------------------===// 988fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne// 1088fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne// This program takes in a list of bitcode files, links them, performs link-time 1188fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne// optimization, and outputs an object file. 1288fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne// 1388fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne//===----------------------------------------------------------------------===// 1488fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne 157e667c56cf7e27ff521ceb86518beab32bfb630dRafael Espindola#include "llvm/ADT/StringSet.h" 16c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindola#include "llvm/CodeGen/CommandFlags.h" 17cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne#include "llvm/LTO/LTOCodeGenerator.h" 18cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne#include "llvm/LTO/LTOModule.h" 1988fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne#include "llvm/Support/CommandLine.h" 20dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/Support/FileSystem.h" 2188fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne#include "llvm/Support/ManagedStatic.h" 2288fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne#include "llvm/Support/PrettyStackTrace.h" 2388fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne#include "llvm/Support/Signals.h" 24cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne#include "llvm/Support/TargetSelect.h" 2536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Support/raw_ostream.h" 2688fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne 2788fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourneusing namespace llvm; 2888fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne 294c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic cl::opt<char> 304c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga NainarOptLevel("O", 314c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] " 324c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar "(default = '-O2')"), 334c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::Prefix, 344c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::ZeroOrMore, 354c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar cl::init('2')); 3688fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne 37c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindolastatic cl::opt<bool> 38c13c9e5a9d288eac494a38f0710d34446167f940Rafael EspindolaDisableInline("disable-inlining", cl::init(false), 39c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindola cl::desc("Do not run the inliner pass")); 40c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindola 41c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindolastatic cl::opt<bool> 42c13c9e5a9d288eac494a38f0710d34446167f940Rafael EspindolaDisableGVNLoadPRE("disable-gvn-loadpre", cl::init(false), 43c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindola cl::desc("Do not run the GVN load PRE pass")); 44c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindola 4537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic cl::opt<bool> 4637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesDisableLTOVectorization("disable-lto-vectorization", cl::init(false), 4737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::desc("Do not run loop or slp vectorization during LTO")); 4837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 4937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hinesstatic cl::opt<bool> 5037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen HinesUseDiagnosticHandler("use-diagnostic-handler", cl::init(false), 5137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines cl::desc("Use a diagnostic handler to test the handler interface")); 5237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 53c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindolastatic cl::list<std::string> 54c13c9e5a9d288eac494a38f0710d34446167f940Rafael EspindolaInputFilenames(cl::Positional, cl::OneOrMore, 55c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindola cl::desc("<input bitcode files>")); 56c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindola 57c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindolastatic cl::opt<std::string> 58c13c9e5a9d288eac494a38f0710d34446167f940Rafael EspindolaOutputFilename("o", cl::init(""), 59c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindola cl::desc("Override output filename"), 60c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindola cl::value_desc("filename")); 6188fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne 62b964366a9a282dee620651611c97c80311b11a8bRafael Espindolastatic cl::list<std::string> 63b964366a9a282dee620651611c97c80311b11a8bRafael EspindolaExportedSymbols("exported-symbol", 64b964366a9a282dee620651611c97c80311b11a8bRafael Espindola cl::desc("Symbol to export from the resulting object file"), 65b964366a9a282dee620651611c97c80311b11a8bRafael Espindola cl::ZeroOrMore); 66b964366a9a282dee620651611c97c80311b11a8bRafael Espindola 67438900938c3ac9d7fac2dd5d2c85ca4b9b2e35f7Rafael Espindolastatic cl::list<std::string> 68438900938c3ac9d7fac2dd5d2c85ca4b9b2e35f7Rafael EspindolaDSOSymbols("dso-symbol", 69438900938c3ac9d7fac2dd5d2c85ca4b9b2e35f7Rafael Espindola cl::desc("Symbol to put in the symtab in the resulting dso"), 70438900938c3ac9d7fac2dd5d2c85ca4b9b2e35f7Rafael Espindola cl::ZeroOrMore); 71b964366a9a282dee620651611c97c80311b11a8bRafael Espindola 72ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic cl::opt<bool> ListSymbolsOnly( 73ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines "list-symbols-only", cl::init(false), 74ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines cl::desc("Instead of running LTO, list the symbols in each IR file")); 75ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 76ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesstatic cl::opt<bool> SetMergedModule( 77ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines "set-merged-module", cl::init(false), 78ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines cl::desc("Use the first input module as the merged module")); 79ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 807e667c56cf7e27ff521ceb86518beab32bfb630dRafael Espindolanamespace { 817e667c56cf7e27ff521ceb86518beab32bfb630dRafael Espindolastruct ModuleInfo { 827e667c56cf7e27ff521ceb86518beab32bfb630dRafael Espindola std::vector<bool> CanBeHidden; 837e667c56cf7e27ff521ceb86518beab32bfb630dRafael Espindola}; 847e667c56cf7e27ff521ceb86518beab32bfb630dRafael Espindola} 857e667c56cf7e27ff521ceb86518beab32bfb630dRafael Espindola 864c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic void handleDiagnostics(lto_codegen_diagnostic_severity_t Severity, 874c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const char *Msg, void *) { 8837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines switch (Severity) { 8937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case LTO_DS_NOTE: 9037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines errs() << "note: "; 9137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines break; 9237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case LTO_DS_REMARK: 9337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines errs() << "remark: "; 9437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines break; 9537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case LTO_DS_ERROR: 9637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines errs() << "error: "; 9737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines break; 9837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines case LTO_DS_WARNING: 9937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines errs() << "warning: "; 10037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines break; 10137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines } 10237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines errs() << Msg << "\n"; 10337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines} 10437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 1054c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic std::unique_ptr<LTOModule> 106ebe69fe11e48d322045d5949c83283927a0d790bStephen HinesgetLocalLTOModule(StringRef Path, std::unique_ptr<MemoryBuffer> &Buffer, 107ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const TargetOptions &Options, std::string &Error) { 108ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr = 109ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines MemoryBuffer::getFile(Path); 110ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (std::error_code EC = BufferOrErr.getError()) { 111ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Error = EC.message(); 112ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return nullptr; 113ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 114ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Buffer = std::move(BufferOrErr.get()); 115ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return std::unique_ptr<LTOModule>(LTOModule::createInLocalContext( 116ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines Buffer->getBufferStart(), Buffer->getBufferSize(), Options, Error, Path)); 117ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 118ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 119ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// \brief List symbols in each IR file. 120ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// 121ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// The main point here is to provide lit-testable coverage for the LTOModule 122ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// functionality that's exposed by the C API to list symbols. Moreover, this 123ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// provides testing coverage for modules that have been created in their own 124ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines/// contexts. 1254c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic int listSymbols(StringRef Command, const TargetOptions &Options) { 126ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (auto &Filename : InputFilenames) { 127ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::string Error; 128ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::unique_ptr<MemoryBuffer> Buffer; 129ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::unique_ptr<LTOModule> Module = 130ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines getLocalLTOModule(Filename, Buffer, Options, Error); 131ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (!Module) { 132ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines errs() << Command << ": error loading file '" << Filename 133ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines << "': " << Error << "\n"; 134ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return 1; 135ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 136ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 137ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // List the symbols. 138ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines outs() << Filename << ":\n"; 139ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines for (int I = 0, E = Module->getSymbolCount(); I != E; ++I) 140ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines outs() << Module->getSymbolName(I) << "\n"; 141ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 142ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return 0; 143ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 144ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 14588fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourneint main(int argc, char **argv) { 14688fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne // Print a stack trace if we signal out. 14788fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne sys::PrintStackTraceOnErrorSignal(); 14888fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne PrettyStackTraceProgram X(argc, argv); 14988fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne 15088fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. 15188fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne cl::ParseCommandLineOptions(argc, argv, "llvm LTO linker\n"); 15288fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne 1534c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (OptLevel < '0' || OptLevel > '3') { 1544c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar errs() << argv[0] << ": optimization level must be between 0 and 3\n"; 1554c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar return 1; 1564c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 1574c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 158cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne // Initialize the configured targets. 159cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne InitializeAllTargets(); 160cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne InitializeAllTargetMCs(); 161cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne InitializeAllAsmPrinters(); 162cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne InitializeAllAsmParsers(); 163cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne 164c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindola // set up the TargetOptions for the machine 16536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines TargetOptions Options = InitTargetOptionsFromCodeGenFlags(); 166c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindola 167ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (ListSymbolsOnly) 168ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return listSymbols(argv[0], Options); 169ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 17088fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne unsigned BaseArg = 0; 17188fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne 172cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne LTOCodeGenerator CodeGen; 17388fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne 17437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (UseDiagnosticHandler) 17537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines CodeGen.setDiagnosticHandler(handleDiagnostics, nullptr); 17637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 177dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines switch (RelocModel) { 178dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case Reloc::Static: 179dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines CodeGen.setCodePICModel(LTO_CODEGEN_PIC_MODEL_STATIC); 180dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines break; 181dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case Reloc::PIC_: 182dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines CodeGen.setCodePICModel(LTO_CODEGEN_PIC_MODEL_DYNAMIC); 183dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines break; 184dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines case Reloc::DynamicNoPIC: 185dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines CodeGen.setCodePICModel(LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC); 186dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines break; 187dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines default: 188dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines CodeGen.setCodePICModel(LTO_CODEGEN_PIC_MODEL_DEFAULT); 189dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 190dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 191cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne CodeGen.setDebugInfo(LTO_DEBUG_MODEL_DWARF); 192c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindola CodeGen.setTargetOptions(Options); 19388fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne 1947e667c56cf7e27ff521ceb86518beab32bfb630dRafael Espindola llvm::StringSet<llvm::MallocAllocator> DSOSymbolsSet; 1957e667c56cf7e27ff521ceb86518beab32bfb630dRafael Espindola for (unsigned i = 0; i < DSOSymbols.size(); ++i) 1967e667c56cf7e27ff521ceb86518beab32bfb630dRafael Espindola DSOSymbolsSet.insert(DSOSymbols[i]); 1977e667c56cf7e27ff521ceb86518beab32bfb630dRafael Espindola 1987e667c56cf7e27ff521ceb86518beab32bfb630dRafael Espindola std::vector<std::string> KeptDSOSyms; 1997e667c56cf7e27ff521ceb86518beab32bfb630dRafael Espindola 20088fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne for (unsigned i = BaseArg; i < InputFilenames.size(); ++i) { 201cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne std::string error; 20236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines std::unique_ptr<LTOModule> Module( 203c6a4f5e819217e1e12c458aed8e7b122e23a3a58Stephen Hines LTOModule::createFromFile(InputFilenames[i].c_str(), Options, error)); 204cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne if (!error.empty()) { 20588fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne errs() << argv[0] << ": error loading file '" << InputFilenames[i] 206cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne << "': " << error << "\n"; 20788fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne return 1; 20888fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne } 20988fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne 210ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines LTOModule *LTOMod = Module.get(); 211ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 212ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // We use the first input module as the destination module when 213ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // SetMergedModule is true. 214ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines if (SetMergedModule && i == BaseArg) { 215ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Transfer ownership to the code generator. 216ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines CodeGen.setModule(Module.release()); 217ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } else if (!CodeGen.addModule(Module.get())) 21888fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne return 1; 2197e667c56cf7e27ff521ceb86518beab32bfb630dRafael Espindola 220ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines unsigned NumSyms = LTOMod->getSymbolCount(); 2217e667c56cf7e27ff521ceb86518beab32bfb630dRafael Espindola for (unsigned I = 0; I < NumSyms; ++I) { 222ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines StringRef Name = LTOMod->getSymbolName(I); 2237e667c56cf7e27ff521ceb86518beab32bfb630dRafael Espindola if (!DSOSymbolsSet.count(Name)) 2247e667c56cf7e27ff521ceb86518beab32bfb630dRafael Espindola continue; 225ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines lto_symbol_attributes Attrs = LTOMod->getSymbolAttributes(I); 2267e667c56cf7e27ff521ceb86518beab32bfb630dRafael Espindola unsigned Scope = Attrs & LTO_SYMBOL_SCOPE_MASK; 2277e667c56cf7e27ff521ceb86518beab32bfb630dRafael Espindola if (Scope != LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN) 2287e667c56cf7e27ff521ceb86518beab32bfb630dRafael Espindola KeptDSOSyms.push_back(Name); 2297e667c56cf7e27ff521ceb86518beab32bfb630dRafael Espindola } 23088fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne } 23188fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne 232b964366a9a282dee620651611c97c80311b11a8bRafael Espindola // Add all the exported symbols to the table of symbols to preserve. 233b964366a9a282dee620651611c97c80311b11a8bRafael Espindola for (unsigned i = 0; i < ExportedSymbols.size(); ++i) 234b964366a9a282dee620651611c97c80311b11a8bRafael Espindola CodeGen.addMustPreserveSymbol(ExportedSymbols[i].c_str()); 235b964366a9a282dee620651611c97c80311b11a8bRafael Espindola 236438900938c3ac9d7fac2dd5d2c85ca4b9b2e35f7Rafael Espindola // Add all the dso symbols to the table of symbols to expose. 2377e667c56cf7e27ff521ceb86518beab32bfb630dRafael Espindola for (unsigned i = 0; i < KeptDSOSyms.size(); ++i) 2387e667c56cf7e27ff521ceb86518beab32bfb630dRafael Espindola CodeGen.addMustPreserveSymbol(KeptDSOSyms[i].c_str()); 239438900938c3ac9d7fac2dd5d2c85ca4b9b2e35f7Rafael Espindola 240ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Set cpu and attrs strings for the default target/subtarget. 241ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines CodeGen.setCpu(MCPU.c_str()); 242ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 2434c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar CodeGen.setOptLevel(OptLevel - '0'); 2444c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 245dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines std::string attrs; 246dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (unsigned i = 0; i < MAttrs.size(); ++i) { 247dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (i > 0) 248dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines attrs.append(","); 249dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines attrs.append(MAttrs[i]); 250dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 251dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 252dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!attrs.empty()) 253dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines CodeGen.setAttr(attrs.c_str()); 254dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 25588fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne if (!OutputFilename.empty()) { 25688fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne size_t len = 0; 257cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne std::string ErrorInfo; 25837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const void *Code = 2594c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar CodeGen.compile(&len, DisableInline, DisableGVNLoadPRE, 26037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines DisableLTOVectorization, ErrorInfo); 261dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (!Code) { 26288fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne errs() << argv[0] 263cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne << ": error compiling the code: " << ErrorInfo << "\n"; 26488fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne return 1; 26588fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne } 26688fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne 26737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::error_code EC; 26837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines raw_fd_ostream FileStream(OutputFilename, EC, sys::fs::F_None); 26937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines if (EC) { 27088fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne errs() << argv[0] << ": error opening the file '" << OutputFilename 27137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines << "': " << EC.message() << "\n"; 27288fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne return 1; 27388fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne } 27488fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne 27588fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne FileStream.write(reinterpret_cast<const char *>(Code), len); 27688fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne } else { 277cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne std::string ErrorInfo; 278dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const char *OutputName = nullptr; 2794c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (!CodeGen.compile_to_file(&OutputName, DisableInline, 28037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines DisableGVNLoadPRE, DisableLTOVectorization, 28137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines ErrorInfo)) { 28288fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne errs() << argv[0] 283cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne << ": error compiling the code: " << ErrorInfo 28488fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne << "\n"; 28588fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne return 1; 28688fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne } 28788fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne 28888fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne outs() << "Wrote native object file '" << OutputName << "'\n"; 28988fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne } 29088fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne 29188fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne return 0; 29288fae0edcce84920ba7c5685c36f6bd6cfb9b86dPeter Collingbourne} 293