| Index: llvm/tools/lto/LTOCodeGenerator.cpp
|
| ===================================================================
|
| --- a/llvm/tools/lto/LTOCodeGenerator.cpp
|
| +++ b/llvm/tools/lto/LTOCodeGenerator.cpp
|
| @@ -101,6 +101,68 @@
|
| return ret;
|
| }
|
|
|
| +// @LOCALMOD-BEGIN
|
| +/// Add a module that will be merged with the final output module.
|
| +/// The merging does not happen until linkGatheredModulesAndDispose().
|
| +bool LTOCodeGenerator::gatherModuleForLinking(LTOModule* mod) {
|
| + _gatheredModules.push_back(mod);
|
| +}
|
| +
|
| +/// Merge all modules gathered from gatherModuleForLinking(), and
|
| +/// destroy the source modules in the process.
|
| +bool LTOCodeGenerator::linkGatheredModulesAndDispose(std::string& errMsg) {
|
| +
|
| + // We gather the asm undefs earlier than addModule() does,
|
| + // since we delete the modules during linking, and would not be
|
| + // able to do this after linking. The undefs vector contain lists
|
| + // of global variable names which are considered "used", which will be
|
| + // appended into the "llvm.compiler.used" list. The names must be the
|
| + // same before linking as they are after linking, since we have switched
|
| + // the order.
|
| + for (unsigned i = 0, ei = _gatheredModules.size(); i != ei; ++i) {
|
| + const std::vector<const char*> &undefs =
|
| + _gatheredModules[i]->getAsmUndefinedRefs();
|
| + for (int j = 0, ej = undefs.size(); j != ej; ++j) {
|
| + _asmUndefinedRefs[undefs[j]] = 1;
|
| + }
|
| + }
|
| +
|
| + // Tree-reduce the mods, re-using the incoming mods as scratch
|
| + // intermediate results. Module i is linked with (i + stride), with i as
|
| + // the dest. We begin with a stride of 1, and double each time. E.g.,
|
| + // after the first round, only the even-indexed modules are still available,
|
| + // and after the second, only those with index that are a multiple of 4
|
| + // are available. Eventually the Module with the content of all other modules
|
| + // will be Module 0.
|
| + // NOTE: we may be able to be smarter about linking if we did not do them
|
| + // pairwise using Linker::LinkModules. We also disregard module sizes
|
| + // and try our best to keep the modules in order (linking adjacent modules).
|
| + for (unsigned stride = 1, len = _gatheredModules.size();
|
| + stride < len;
|
| + stride *= 2) {
|
| + for (unsigned i = 0; i + stride < len; i = i + (stride * 2)) {
|
| + if (Linker::LinkModules(_gatheredModules[i]->getLLVVMModule(),
|
| + _gatheredModules[i+stride]->getLLVVMModule(),
|
| + Linker::DestroySource, &errMsg)) {
|
| + errs() << "LinkModules " << i << " w/ " << i + stride << " failed...\n";
|
| + // We leak the memory in this case...
|
| + return true;
|
| + }
|
| + delete _gatheredModules[i+stride];
|
| + }
|
| + }
|
| +
|
| + // Finally, link Node 0 with the Dest and delete Node 0.
|
| + if (_linker.LinkInModule(_gatheredModules[0]->getLLVVMModule(), &errMsg)) {
|
| + errs() << "LinkModules Dst w/ _gatheredModules[0] failed...\n";
|
| + return true;
|
| + }
|
| + delete _gatheredModules[0];
|
| +
|
| + return false;
|
| +}
|
| +// @LOCALMOD-END
|
| +
|
| bool LTOCodeGenerator::setDebugInfo(lto_debug_model debug,
|
| std::string& errMsg) {
|
| switch (debug) {
|
|
|