LTOCodeGenerator.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640
  1. //===-LTOCodeGenerator.cpp - LLVM Link Time Optimizer ---------------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. //
  10. // This file implements the Link Time Optimization library. This library is
  11. // intended to be used by linker to optimize code at link time.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #include "llvm/LTO/LTOCodeGenerator.h"
  15. #include "llvm/ADT/StringExtras.h"
  16. #include "llvm/Analysis/Passes.h"
  17. #include "llvm/Analysis/TargetLibraryInfo.h"
  18. #include "llvm/Analysis/TargetTransformInfo.h"
  19. #include "llvm/Bitcode/ReaderWriter.h"
  20. #include "llvm/CodeGen/RuntimeLibcalls.h"
  21. #include "llvm/Config/config.h"
  22. #include "llvm/IR/Constants.h"
  23. #include "llvm/IR/DataLayout.h"
  24. #include "llvm/IR/DerivedTypes.h"
  25. #include "llvm/IR/DiagnosticInfo.h"
  26. #include "llvm/IR/DiagnosticPrinter.h"
  27. #include "llvm/IR/LLVMContext.h"
  28. #include "llvm/IR/LegacyPassManager.h"
  29. #include "llvm/IR/Mangler.h"
  30. #include "llvm/IR/Module.h"
  31. #include "llvm/IR/Verifier.h"
  32. #include "llvm/InitializePasses.h"
  33. #include "llvm/LTO/LTOModule.h"
  34. #include "llvm/Linker/Linker.h"
  35. #include "llvm/MC/MCAsmInfo.h"
  36. #include "llvm/MC/MCContext.h"
  37. #include "llvm/MC/SubtargetFeature.h"
  38. #include "llvm/Support/CommandLine.h"
  39. #include "llvm/Support/FileSystem.h"
  40. #include "llvm/Support/Host.h"
  41. #include "llvm/Support/MemoryBuffer.h"
  42. #include "llvm/Support/Signals.h"
  43. #include "llvm/Support/TargetRegistry.h"
  44. #include "llvm/Support/TargetSelect.h"
  45. #include "llvm/Support/ToolOutputFile.h"
  46. #include "llvm/Support/raw_ostream.h"
  47. #include "llvm/Target/TargetLowering.h"
  48. #include "llvm/Target/TargetOptions.h"
  49. #include "llvm/Target/TargetRegisterInfo.h"
  50. #include "llvm/Target/TargetSubtargetInfo.h"
  51. #include "llvm/Transforms/IPO.h"
  52. #include "llvm/Transforms/IPO/PassManagerBuilder.h"
  53. #include "llvm/Transforms/ObjCARC.h"
  54. #include <system_error>
  55. using namespace llvm;
  56. const char* LTOCodeGenerator::getVersionString() {
  57. #ifdef LLVM_VERSION_INFO
  58. return PACKAGE_NAME " version " PACKAGE_VERSION ", " LLVM_VERSION_INFO;
  59. #else
  60. return PACKAGE_NAME " version " PACKAGE_VERSION;
  61. #endif
  62. }
  63. LTOCodeGenerator::LTOCodeGenerator()
  64. : Context(getGlobalContext()), IRLinker(new Module("ld-temp.o", Context)) {
  65. initializeLTOPasses();
  66. }
  67. LTOCodeGenerator::LTOCodeGenerator(std::unique_ptr<LLVMContext> Context)
  68. : OwnedContext(std::move(Context)), Context(*OwnedContext),
  69. IRLinker(new Module("ld-temp.o", *OwnedContext)) {
  70. initializeLTOPasses();
  71. }
  72. void LTOCodeGenerator::destroyMergedModule() {
  73. if (OwnedModule) {
  74. assert(IRLinker.getModule() == &OwnedModule->getModule() &&
  75. "The linker's module should be the same as the owned module");
  76. delete OwnedModule;
  77. OwnedModule = nullptr;
  78. } else if (IRLinker.getModule())
  79. IRLinker.deleteModule();
  80. }
  81. LTOCodeGenerator::~LTOCodeGenerator() {
  82. destroyMergedModule();
  83. delete TargetMach;
  84. TargetMach = nullptr;
  85. for (std::vector<char *>::iterator I = CodegenOptions.begin(),
  86. E = CodegenOptions.end();
  87. I != E; ++I)
  88. free(*I);
  89. }
  90. // Initialize LTO passes. Please keep this funciton in sync with
  91. // PassManagerBuilder::populateLTOPassManager(), and make sure all LTO
  92. // passes are initialized.
  93. void LTOCodeGenerator::initializeLTOPasses() {
  94. PassRegistry &R = *PassRegistry::getPassRegistry();
  95. initializeInternalizePassPass(R);
  96. initializeIPSCCPPass(R);
  97. initializeGlobalOptPass(R);
  98. initializeConstantMergePass(R);
  99. initializeDAHPass(R);
  100. initializeInstructionCombiningPassPass(R);
  101. initializeSimpleInlinerPass(R);
  102. initializePruneEHPass(R);
  103. initializeGlobalDCEPass(R);
  104. initializeArgPromotionPass(R);
  105. initializeJumpThreadingPass(R);
  106. initializeSROAPass(R);
  107. initializeSROA_DTPass(R);
  108. initializeSROA_SSAUpPass(R);
  109. initializeFunctionAttrsPass(R);
  110. initializeGlobalsModRefPass(R);
  111. initializeLICMPass(R);
  112. initializeMergedLoadStoreMotionPass(R);
  113. initializeGVNPass(R);
  114. initializeMemCpyOptPass(R);
  115. initializeDCEPass(R);
  116. initializeCFGSimplifyPassPass(R);
  117. }
  118. bool LTOCodeGenerator::addModule(LTOModule *mod) {
  119. assert(&mod->getModule().getContext() == &Context &&
  120. "Expected module in same context");
  121. bool ret = IRLinker.linkInModule(&mod->getModule());
  122. const std::vector<const char*> &undefs = mod->getAsmUndefinedRefs();
  123. for (int i = 0, e = undefs.size(); i != e; ++i)
  124. AsmUndefinedRefs[undefs[i]] = 1;
  125. return !ret;
  126. }
  127. void LTOCodeGenerator::setModule(LTOModule *Mod) {
  128. assert(&Mod->getModule().getContext() == &Context &&
  129. "Expected module in same context");
  130. // Delete the old merged module.
  131. destroyMergedModule();
  132. AsmUndefinedRefs.clear();
  133. OwnedModule = Mod;
  134. IRLinker.setModule(&Mod->getModule());
  135. const std::vector<const char*> &Undefs = Mod->getAsmUndefinedRefs();
  136. for (int I = 0, E = Undefs.size(); I != E; ++I)
  137. AsmUndefinedRefs[Undefs[I]] = 1;
  138. }
  139. void LTOCodeGenerator::setTargetOptions(TargetOptions options) {
  140. Options = options;
  141. }
  142. void LTOCodeGenerator::setDebugInfo(lto_debug_model debug) {
  143. switch (debug) {
  144. case LTO_DEBUG_MODEL_NONE:
  145. EmitDwarfDebugInfo = false;
  146. return;
  147. case LTO_DEBUG_MODEL_DWARF:
  148. EmitDwarfDebugInfo = true;
  149. return;
  150. }
  151. llvm_unreachable("Unknown debug format!");
  152. }
  153. void LTOCodeGenerator::setCodePICModel(lto_codegen_model model) {
  154. switch (model) {
  155. case LTO_CODEGEN_PIC_MODEL_STATIC:
  156. case LTO_CODEGEN_PIC_MODEL_DYNAMIC:
  157. case LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC:
  158. case LTO_CODEGEN_PIC_MODEL_DEFAULT:
  159. CodeModel = model;
  160. return;
  161. }
  162. llvm_unreachable("Unknown PIC model!");
  163. }
  164. bool LTOCodeGenerator::writeMergedModules(const char *path,
  165. std::string &errMsg) {
  166. if (!determineTarget(errMsg))
  167. return false;
  168. // mark which symbols can not be internalized
  169. applyScopeRestrictions();
  170. // create output file
  171. std::error_code EC;
  172. tool_output_file Out(path, EC, sys::fs::F_None);
  173. if (EC) {
  174. errMsg = "could not open bitcode file for writing: ";
  175. errMsg += path;
  176. return false;
  177. }
  178. // write bitcode to it
  179. WriteBitcodeToFile(IRLinker.getModule(), Out.os(), ShouldEmbedUselists);
  180. Out.os().close();
  181. if (Out.os().has_error()) {
  182. errMsg = "could not write bitcode file: ";
  183. errMsg += path;
  184. Out.os().clear_error();
  185. return false;
  186. }
  187. Out.keep();
  188. return true;
  189. }
  190. bool LTOCodeGenerator::compileOptimizedToFile(const char **name,
  191. std::string &errMsg) {
  192. // make unique temp .o file to put generated object file
  193. SmallString<128> Filename;
  194. int FD;
  195. std::error_code EC =
  196. sys::fs::createTemporaryFile("lto-llvm", "o", FD, Filename);
  197. if (EC) {
  198. errMsg = EC.message();
  199. return false;
  200. }
  201. // generate object file
  202. tool_output_file objFile(Filename.c_str(), FD);
  203. bool genResult = compileOptimized(objFile.os(), errMsg);
  204. objFile.os().close();
  205. if (objFile.os().has_error()) {
  206. objFile.os().clear_error();
  207. sys::fs::remove(Twine(Filename));
  208. return false;
  209. }
  210. objFile.keep();
  211. if (!genResult) {
  212. sys::fs::remove(Twine(Filename));
  213. return false;
  214. }
  215. NativeObjectPath = Filename.c_str();
  216. *name = NativeObjectPath.c_str();
  217. return true;
  218. }
  219. std::unique_ptr<MemoryBuffer>
  220. LTOCodeGenerator::compileOptimized(std::string &errMsg) {
  221. const char *name;
  222. if (!compileOptimizedToFile(&name, errMsg))
  223. return nullptr;
  224. // read .o file into memory buffer
  225. ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
  226. MemoryBuffer::getFile(name, -1, false);
  227. if (std::error_code EC = BufferOrErr.getError()) {
  228. errMsg = EC.message();
  229. sys::fs::remove(NativeObjectPath);
  230. return nullptr;
  231. }
  232. // remove temp files
  233. sys::fs::remove(NativeObjectPath);
  234. return std::move(*BufferOrErr);
  235. }
  236. bool LTOCodeGenerator::compile_to_file(const char **name,
  237. bool disableInline,
  238. bool disableGVNLoadPRE,
  239. bool disableVectorization,
  240. std::string &errMsg) {
  241. if (!optimize(disableInline, disableGVNLoadPRE,
  242. disableVectorization, errMsg))
  243. return false;
  244. return compileOptimizedToFile(name, errMsg);
  245. }
  246. std::unique_ptr<MemoryBuffer>
  247. LTOCodeGenerator::compile(bool disableInline, bool disableGVNLoadPRE,
  248. bool disableVectorization, std::string &errMsg) {
  249. if (!optimize(disableInline, disableGVNLoadPRE,
  250. disableVectorization, errMsg))
  251. return nullptr;
  252. return compileOptimized(errMsg);
  253. }
  254. bool LTOCodeGenerator::determineTarget(std::string &errMsg) {
  255. if (TargetMach)
  256. return true;
  257. std::string TripleStr = IRLinker.getModule()->getTargetTriple();
  258. if (TripleStr.empty())
  259. TripleStr = sys::getDefaultTargetTriple();
  260. llvm::Triple Triple(TripleStr);
  261. // create target machine from info for merged modules
  262. const Target *march = TargetRegistry::lookupTarget(TripleStr, errMsg);
  263. if (!march)
  264. return false;
  265. // The relocation model is actually a static member of TargetMachine and
  266. // needs to be set before the TargetMachine is instantiated.
  267. Reloc::Model RelocModel = Reloc::Default;
  268. switch (CodeModel) {
  269. case LTO_CODEGEN_PIC_MODEL_STATIC:
  270. RelocModel = Reloc::Static;
  271. break;
  272. case LTO_CODEGEN_PIC_MODEL_DYNAMIC:
  273. RelocModel = Reloc::PIC_;
  274. break;
  275. case LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC:
  276. RelocModel = Reloc::DynamicNoPIC;
  277. break;
  278. case LTO_CODEGEN_PIC_MODEL_DEFAULT:
  279. // RelocModel is already the default, so leave it that way.
  280. break;
  281. }
  282. // Construct LTOModule, hand over ownership of module and target. Use MAttr as
  283. // the default set of features.
  284. SubtargetFeatures Features(MAttr);
  285. Features.getDefaultSubtargetFeatures(Triple);
  286. std::string FeatureStr = Features.getString();
  287. // Set a default CPU for Darwin triples.
  288. if (MCpu.empty() && Triple.isOSDarwin()) {
  289. if (Triple.getArch() == llvm::Triple::x86_64)
  290. MCpu = "core2";
  291. else if (Triple.getArch() == llvm::Triple::x86)
  292. MCpu = "yonah";
  293. else if (Triple.getArch() == llvm::Triple::aarch64)
  294. MCpu = "cyclone";
  295. }
  296. CodeGenOpt::Level CGOptLevel;
  297. switch (OptLevel) {
  298. case 0:
  299. CGOptLevel = CodeGenOpt::None;
  300. break;
  301. case 1:
  302. CGOptLevel = CodeGenOpt::Less;
  303. break;
  304. case 2:
  305. CGOptLevel = CodeGenOpt::Default;
  306. break;
  307. case 3:
  308. CGOptLevel = CodeGenOpt::Aggressive;
  309. break;
  310. }
  311. TargetMach = march->createTargetMachine(TripleStr, MCpu, FeatureStr, Options,
  312. RelocModel, CodeModel::Default,
  313. CGOptLevel);
  314. return true;
  315. }
  316. void LTOCodeGenerator::
  317. applyRestriction(GlobalValue &GV,
  318. ArrayRef<StringRef> Libcalls,
  319. std::vector<const char*> &MustPreserveList,
  320. SmallPtrSetImpl<GlobalValue*> &AsmUsed,
  321. Mangler &Mangler) {
  322. // There are no restrictions to apply to declarations.
  323. if (GV.isDeclaration())
  324. return;
  325. // There is nothing more restrictive than private linkage.
  326. if (GV.hasPrivateLinkage())
  327. return;
  328. SmallString<64> Buffer;
  329. TargetMach->getNameWithPrefix(Buffer, &GV, Mangler);
  330. if (MustPreserveSymbols.count(Buffer))
  331. MustPreserveList.push_back(GV.getName().data());
  332. if (AsmUndefinedRefs.count(Buffer))
  333. AsmUsed.insert(&GV);
  334. // Conservatively append user-supplied runtime library functions to
  335. // llvm.compiler.used. These could be internalized and deleted by
  336. // optimizations like -globalopt, causing problems when later optimizations
  337. // add new library calls (e.g., llvm.memset => memset and printf => puts).
  338. // Leave it to the linker to remove any dead code (e.g. with -dead_strip).
  339. if (isa<Function>(GV) &&
  340. std::binary_search(Libcalls.begin(), Libcalls.end(), GV.getName()))
  341. AsmUsed.insert(&GV);
  342. }
  343. static void findUsedValues(GlobalVariable *LLVMUsed,
  344. SmallPtrSetImpl<GlobalValue*> &UsedValues) {
  345. if (!LLVMUsed) return;
  346. ConstantArray *Inits = cast<ConstantArray>(LLVMUsed->getInitializer());
  347. for (unsigned i = 0, e = Inits->getNumOperands(); i != e; ++i)
  348. if (GlobalValue *GV =
  349. dyn_cast<GlobalValue>(Inits->getOperand(i)->stripPointerCasts()))
  350. UsedValues.insert(GV);
  351. }
  352. // Collect names of runtime library functions. User-defined functions with the
  353. // same names are added to llvm.compiler.used to prevent them from being
  354. // deleted by optimizations.
  355. static void accumulateAndSortLibcalls(std::vector<StringRef> &Libcalls,
  356. const TargetLibraryInfo& TLI,
  357. const Module &Mod,
  358. const TargetMachine &TM) {
  359. // TargetLibraryInfo has info on C runtime library calls on the current
  360. // target.
  361. for (unsigned I = 0, E = static_cast<unsigned>(LibFunc::NumLibFuncs);
  362. I != E; ++I) {
  363. LibFunc::Func F = static_cast<LibFunc::Func>(I);
  364. if (TLI.has(F))
  365. Libcalls.push_back(TLI.getName(F));
  366. }
  367. SmallPtrSet<const TargetLowering *, 1> TLSet;
  368. for (const Function &F : Mod) {
  369. const TargetLowering *Lowering =
  370. TM.getSubtargetImpl(F)->getTargetLowering();
  371. if (Lowering && TLSet.insert(Lowering).second)
  372. // TargetLowering has info on library calls that CodeGen expects to be
  373. // available, both from the C runtime and compiler-rt.
  374. for (unsigned I = 0, E = static_cast<unsigned>(RTLIB::UNKNOWN_LIBCALL);
  375. I != E; ++I)
  376. if (const char *Name =
  377. Lowering->getLibcallName(static_cast<RTLIB::Libcall>(I)))
  378. Libcalls.push_back(Name);
  379. }
  380. array_pod_sort(Libcalls.begin(), Libcalls.end());
  381. Libcalls.erase(std::unique(Libcalls.begin(), Libcalls.end()),
  382. Libcalls.end());
  383. }
  384. void LTOCodeGenerator::applyScopeRestrictions() {
  385. if (ScopeRestrictionsDone || !ShouldInternalize)
  386. return;
  387. Module *mergedModule = IRLinker.getModule();
  388. // Start off with a verification pass.
  389. legacy::PassManager passes;
  390. passes.add(createVerifierPass());
  391. // mark which symbols can not be internalized
  392. Mangler Mangler;
  393. std::vector<const char*> MustPreserveList;
  394. SmallPtrSet<GlobalValue*, 8> AsmUsed;
  395. std::vector<StringRef> Libcalls;
  396. TargetLibraryInfoImpl TLII(Triple(TargetMach->getTargetTriple()));
  397. TargetLibraryInfo TLI(TLII);
  398. accumulateAndSortLibcalls(Libcalls, TLI, *mergedModule, *TargetMach);
  399. for (Module::iterator f = mergedModule->begin(),
  400. e = mergedModule->end(); f != e; ++f)
  401. applyRestriction(*f, Libcalls, MustPreserveList, AsmUsed, Mangler);
  402. for (Module::global_iterator v = mergedModule->global_begin(),
  403. e = mergedModule->global_end(); v != e; ++v)
  404. applyRestriction(*v, Libcalls, MustPreserveList, AsmUsed, Mangler);
  405. for (Module::alias_iterator a = mergedModule->alias_begin(),
  406. e = mergedModule->alias_end(); a != e; ++a)
  407. applyRestriction(*a, Libcalls, MustPreserveList, AsmUsed, Mangler);
  408. GlobalVariable *LLVMCompilerUsed =
  409. mergedModule->getGlobalVariable("llvm.compiler.used");
  410. findUsedValues(LLVMCompilerUsed, AsmUsed);
  411. if (LLVMCompilerUsed)
  412. LLVMCompilerUsed->eraseFromParent();
  413. if (!AsmUsed.empty()) {
  414. llvm::Type *i8PTy = llvm::Type::getInt8PtrTy(Context);
  415. std::vector<Constant*> asmUsed2;
  416. for (auto *GV : AsmUsed) {
  417. Constant *c = ConstantExpr::getBitCast(GV, i8PTy);
  418. asmUsed2.push_back(c);
  419. }
  420. llvm::ArrayType *ATy = llvm::ArrayType::get(i8PTy, asmUsed2.size());
  421. LLVMCompilerUsed =
  422. new llvm::GlobalVariable(*mergedModule, ATy, false,
  423. llvm::GlobalValue::AppendingLinkage,
  424. llvm::ConstantArray::get(ATy, asmUsed2),
  425. "llvm.compiler.used");
  426. LLVMCompilerUsed->setSection("llvm.metadata");
  427. }
  428. passes.add(createInternalizePass(MustPreserveList));
  429. // apply scope restrictions
  430. passes.run(*mergedModule);
  431. ScopeRestrictionsDone = true;
  432. }
  433. /// Optimize merged modules using various IPO passes
  434. bool LTOCodeGenerator::optimize(bool DisableInline,
  435. bool DisableGVNLoadPRE,
  436. bool DisableVectorization,
  437. std::string &errMsg) {
  438. if (!this->determineTarget(errMsg))
  439. return false;
  440. Module *mergedModule = IRLinker.getModule();
  441. // Mark which symbols can not be internalized
  442. this->applyScopeRestrictions();
  443. // Instantiate the pass manager to organize the passes.
  444. legacy::PassManager passes;
  445. // Add an appropriate DataLayout instance for this module...
  446. mergedModule->setDataLayout(*TargetMach->getDataLayout());
  447. passes.add(
  448. createTargetTransformInfoWrapperPass(TargetMach->getTargetIRAnalysis()));
  449. Triple TargetTriple(TargetMach->getTargetTriple());
  450. PassManagerBuilder PMB;
  451. PMB.DisableGVNLoadPRE = DisableGVNLoadPRE;
  452. PMB.LoopVectorize = !DisableVectorization;
  453. PMB.SLPVectorize = !DisableVectorization;
  454. if (!DisableInline)
  455. PMB.Inliner = createFunctionInliningPass();
  456. PMB.LibraryInfo = new TargetLibraryInfoImpl(TargetTriple);
  457. PMB.OptLevel = OptLevel;
  458. PMB.VerifyInput = true;
  459. PMB.VerifyOutput = true;
  460. PMB.populateLTOPassManager(passes);
  461. // Run our queue of passes all at once now, efficiently.
  462. passes.run(*mergedModule);
  463. return true;
  464. }
  465. bool LTOCodeGenerator::compileOptimized(raw_pwrite_stream &out,
  466. std::string &errMsg) {
  467. if (!this->determineTarget(errMsg))
  468. return false;
  469. Module *mergedModule = IRLinker.getModule();
  470. legacy::PassManager codeGenPasses;
  471. // If the bitcode files contain ARC code and were compiled with optimization,
  472. // the ObjCARCContractPass must be run, so do it unconditionally here.
  473. codeGenPasses.add(createObjCARCContractPass());
  474. if (TargetMach->addPassesToEmitFile(codeGenPasses, out,
  475. TargetMachine::CGFT_ObjectFile)) {
  476. errMsg = "target file type not supported";
  477. return false;
  478. }
  479. // Run the code generator, and write assembly file
  480. codeGenPasses.run(*mergedModule);
  481. return true;
  482. }
  483. /// setCodeGenDebugOptions - Set codegen debugging options to aid in debugging
  484. /// LTO problems.
  485. void LTOCodeGenerator::setCodeGenDebugOptions(const char *options) {
  486. for (std::pair<StringRef, StringRef> o = getToken(options);
  487. !o.first.empty(); o = getToken(o.second)) {
  488. // ParseCommandLineOptions() expects argv[0] to be program name. Lazily add
  489. // that.
  490. if (CodegenOptions.empty())
  491. CodegenOptions.push_back(strdup("libLLVMLTO"));
  492. CodegenOptions.push_back(strdup(o.first.str().c_str()));
  493. }
  494. }
  495. void LTOCodeGenerator::parseCodeGenDebugOptions() {
  496. // if options were requested, set them
  497. if (!CodegenOptions.empty())
  498. cl::ParseCommandLineOptions(CodegenOptions.size(),
  499. const_cast<char **>(&CodegenOptions[0]));
  500. }
  501. void LTOCodeGenerator::DiagnosticHandler(const DiagnosticInfo &DI,
  502. void *Context) {
  503. ((LTOCodeGenerator *)Context)->DiagnosticHandler2(DI);
  504. }
  505. void LTOCodeGenerator::DiagnosticHandler2(const DiagnosticInfo &DI) {
  506. // Map the LLVM internal diagnostic severity to the LTO diagnostic severity.
  507. lto_codegen_diagnostic_severity_t Severity;
  508. switch (DI.getSeverity()) {
  509. case DS_Error:
  510. Severity = LTO_DS_ERROR;
  511. break;
  512. case DS_Warning:
  513. Severity = LTO_DS_WARNING;
  514. break;
  515. case DS_Remark:
  516. Severity = LTO_DS_REMARK;
  517. break;
  518. case DS_Note:
  519. Severity = LTO_DS_NOTE;
  520. break;
  521. }
  522. // Create the string that will be reported to the external diagnostic handler.
  523. std::string MsgStorage;
  524. raw_string_ostream Stream(MsgStorage);
  525. DiagnosticPrinterRawOStream DP(Stream);
  526. DI.print(DP);
  527. Stream.flush();
  528. // If this method has been called it means someone has set up an external
  529. // diagnostic handler. Assert on that.
  530. assert(DiagHandler && "Invalid diagnostic handler");
  531. (*DiagHandler)(Severity, MsgStorage.c_str(), DiagContext);
  532. }
  533. void
  534. LTOCodeGenerator::setDiagnosticHandler(lto_diagnostic_handler_t DiagHandler,
  535. void *Ctxt) {
  536. this->DiagHandler = DiagHandler;
  537. this->DiagContext = Ctxt;
  538. if (!DiagHandler)
  539. return Context.setDiagnosticHandler(nullptr, nullptr);
  540. // Register the LTOCodeGenerator stub in the LLVMContext to forward the
  541. // diagnostic to the external DiagHandler.
  542. Context.setDiagnosticHandler(LTOCodeGenerator::DiagnosticHandler, this,
  543. /* RespectFilters */ true);
  544. }