Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 //===-- gold-plugin.cpp - Plugin to gold for Link Time Optimization ------===// | 1 //===-- gold-plugin.cpp - Plugin to gold for Link Time Optimization ------===// |
| 2 // | 2 // |
| 3 // The LLVM Compiler Infrastructure | 3 // The LLVM Compiler Infrastructure |
| 4 // | 4 // |
| 5 // This file is distributed under the University of Illinois Open Source | 5 // This file is distributed under the University of Illinois Open Source |
| 6 // License. See LICENSE.TXT for details. | 6 // License. See LICENSE.TXT for details. |
| 7 // | 7 // |
| 8 //===----------------------------------------------------------------------===// | 8 //===----------------------------------------------------------------------===// |
| 9 // | 9 // |
| 10 // This is a gold plugin for LLVM. It provides an LLVM implementation of the | 10 // This is a gold plugin for LLVM. It provides an LLVM implementation of the |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 92 std::vector<std::string> DepLibs; | 92 std::vector<std::string> DepLibs; |
| 93 // @LOCALMOD-END | 93 // @LOCALMOD-END |
| 94 | 94 |
| 95 std::vector<sys::Path> Cleanup; | 95 std::vector<sys::Path> Cleanup; |
| 96 lto_code_gen_t code_gen = NULL; | 96 lto_code_gen_t code_gen = NULL; |
| 97 } | 97 } |
| 98 | 98 |
| 99 namespace options { | 99 namespace options { |
| 100 enum generate_bc { BC_NO, BC_ALSO, BC_ONLY }; | 100 enum generate_bc { BC_NO, BC_ALSO, BC_ONLY }; |
| 101 static bool generate_api_file = false; | 101 static bool generate_api_file = false; |
| 102 static bool gather_then_link = true; // @LOCALMOD | |
| 102 static generate_bc generate_bc_file = BC_NO; | 103 static generate_bc generate_bc_file = BC_NO; |
| 103 static std::string bc_path; | 104 static std::string bc_path; |
| 104 static std::string obj_path; | 105 static std::string obj_path; |
| 105 static std::string extra_library_path; | 106 static std::string extra_library_path; |
| 106 static std::string triple; | 107 static std::string triple; |
| 107 static std::string mcpu; | 108 static std::string mcpu; |
| 108 // Additional options to pass into the code generator. | 109 // Additional options to pass into the code generator. |
| 109 // Note: This array will contain all plugin options which are not claimed | 110 // Note: This array will contain all plugin options which are not claimed |
| 110 // as plugin exclusive to pass to the code generator. | 111 // as plugin exclusive to pass to the code generator. |
| 111 // For example, "generate-api-file" and "as"options are for the plugin | 112 // For example, "generate-api-file" and "as"options are for the plugin |
| 112 // use only and will not be passed. | 113 // use only and will not be passed. |
| 113 static std::vector<std::string> extra; | 114 static std::vector<std::string> extra; |
| 114 | 115 |
| 115 static void process_plugin_option(const char* opt_) | 116 static void process_plugin_option(const char* opt_) |
| 116 { | 117 { |
| 117 if (opt_ == NULL) | 118 if (opt_ == NULL) |
| 118 return; | 119 return; |
| 119 llvm::StringRef opt = opt_; | 120 llvm::StringRef opt = opt_; |
| 120 | 121 |
| 121 if (opt == "generate-api-file") { | 122 if (opt == "generate-api-file") { |
| 122 generate_api_file = true; | 123 generate_api_file = true; |
| 123 } else if (opt.startswith("mcpu=")) { | 124 } else if (opt.startswith("mcpu=")) { |
| 124 mcpu = opt.substr(strlen("mcpu=")); | 125 mcpu = opt.substr(strlen("mcpu=")); |
| 125 } else if (opt.startswith("extra-library-path=")) { | 126 } else if (opt.startswith("extra-library-path=")) { |
| 126 extra_library_path = opt.substr(strlen("extra_library_path=")); | 127 extra_library_path = opt.substr(strlen("extra_library_path=")); |
| 127 } else if (opt.startswith("mtriple=")) { | 128 } else if (opt.startswith("mtriple=")) { |
| 128 triple = opt.substr(strlen("mtriple=")); | 129 triple = opt.substr(strlen("mtriple=")); |
| 129 } else if (opt.startswith("obj-path=")) { | 130 } else if (opt.startswith("obj-path=")) { |
| 130 obj_path = opt.substr(strlen("obj-path=")); | 131 obj_path = opt.substr(strlen("obj-path=")); |
| 132 // @LOCALMOD-BEGIN | |
| 133 } else if (opt == "no-gather-then-link") { | |
| 134 gather_then_link = false; | |
|
jvoung (off chromium)
2012/08/01 17:11:01
changed this flag to be "no-gather-..." so that on
| |
| 135 // @LOCALMOD-END | |
| 131 } else if (opt == "emit-llvm") { | 136 } else if (opt == "emit-llvm") { |
| 132 generate_bc_file = BC_ONLY; | 137 generate_bc_file = BC_ONLY; |
| 133 } else if (opt == "also-emit-llvm") { | 138 } else if (opt == "also-emit-llvm") { |
| 134 generate_bc_file = BC_ALSO; | 139 generate_bc_file = BC_ALSO; |
| 135 } else if (opt.startswith("also-emit-llvm=")) { | 140 } else if (opt.startswith("also-emit-llvm=")) { |
| 136 llvm::StringRef path = opt.substr(strlen("also-emit-llvm=")); | 141 llvm::StringRef path = opt.substr(strlen("also-emit-llvm=")); |
| 137 generate_bc_file = BC_ALSO; | 142 generate_bc_file = BC_ALSO; |
| 138 if (!bc_path.empty()) { | 143 if (!bc_path.empty()) { |
| 139 (*message)(LDPL_WARNING, "Path to the output IL file specified twice. " | 144 (*message)(LDPL_WARNING, "Path to the output IL file specified twice. " |
| 140 "Discarding %s", opt_); | 145 "Discarding %s", opt_); |
| (...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 454 // @LOCALMOD-BEGIN | 459 // @LOCALMOD-BEGIN |
| 455 // Do not merge the module if it's a PSO. | 460 // Do not merge the module if it's a PSO. |
| 456 // If the PSO's soname is set, add it to DepLibs. | 461 // If the PSO's soname is set, add it to DepLibs. |
| 457 cf.is_linked_in = false; | 462 cf.is_linked_in = false; |
| 458 if (code_gen) { | 463 if (code_gen) { |
| 459 if (is_shared) { | 464 if (is_shared) { |
| 460 if (soname && strlen(soname) > 0) { | 465 if (soname && strlen(soname) > 0) { |
| 461 DepLibs.push_back(soname); | 466 DepLibs.push_back(soname); |
| 462 } | 467 } |
| 463 } else { | 468 } else { |
| 464 lto_codegen_add_module(code_gen, M); | 469 if (options::gather_then_link) { |
| 470 lto_codegen_gather_module_for_link(code_gen, M); | |
| 471 } else { | |
| 472 lto_codegen_add_module(code_gen, M); | |
| 473 } | |
| 465 cf.is_linked_in = true; | 474 cf.is_linked_in = true; |
| 466 } | 475 } |
| 467 } | 476 } |
| 477 | |
| 478 // With gather_then_link, the modules are disposed when linking. | |
| 479 if (!options::gather_then_link) | |
| 480 lto_module_dispose(M); | |
| 468 // @LOCALMOD-END | 481 // @LOCALMOD-END |
| 469 | 482 |
| 470 lto_module_dispose(M); | |
| 471 | |
| 472 return LDPS_OK; | 483 return LDPS_OK; |
| 473 } | 484 } |
| 474 | 485 |
| 475 /// all_symbols_read_hook - gold informs us that all symbols have been read. | 486 /// all_symbols_read_hook - gold informs us that all symbols have been read. |
| 476 /// At this point, we use get_symbols to see if any of our definitions have | 487 /// At this point, we use get_symbols to see if any of our definitions have |
| 477 /// been overridden by a native object file. Then, perform optimization and | 488 /// been overridden by a native object file. Then, perform optimization and |
| 478 /// codegen. | 489 /// codegen. |
| 479 static ld_plugin_status all_symbols_read_hook(void) { | 490 static ld_plugin_status all_symbols_read_hook(void) { |
| 480 std::ofstream api_file; | 491 std::ofstream api_file; |
| 481 assert(code_gen); | 492 assert(code_gen); |
| 482 | 493 |
| 494 // @LOCALMOD-BEGIN | |
| 495 if (options::gather_then_link) { | |
| 496 lto_codegen_link_gathered_modules_and_dispose(code_gen); | |
| 497 } | |
| 498 // @LOCALMOD-END | |
| 499 | |
| 483 if (options::generate_api_file) { | 500 if (options::generate_api_file) { |
| 484 api_file.open("apifile.txt", std::ofstream::out | std::ofstream::trunc); | 501 api_file.open("apifile.txt", std::ofstream::out | std::ofstream::trunc); |
| 485 if (!api_file.is_open()) { | 502 if (!api_file.is_open()) { |
| 486 (*message)(LDPL_FATAL, "Unable to open apifile.txt for writing."); | 503 (*message)(LDPL_FATAL, "Unable to open apifile.txt for writing."); |
| 487 abort(); | 504 abort(); |
| 488 } | 505 } |
| 489 } | 506 } |
| 490 | 507 |
| 491 // If we don't preserve any symbols, libLTO will assume that all symbols are | 508 // If we don't preserve any symbols, libLTO will assume that all symbols are |
| 492 // needed. Keep all symbols unless we're producing a final executable. | 509 // needed. Keep all symbols unless we're producing a final executable. |
| (...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 667 static ld_plugin_status cleanup_hook(void) { | 684 static ld_plugin_status cleanup_hook(void) { |
| 668 std::string ErrMsg; | 685 std::string ErrMsg; |
| 669 | 686 |
| 670 for (int i = 0, e = Cleanup.size(); i != e; ++i) | 687 for (int i = 0, e = Cleanup.size(); i != e; ++i) |
| 671 if (Cleanup[i].eraseFromDisk(false, &ErrMsg)) | 688 if (Cleanup[i].eraseFromDisk(false, &ErrMsg)) |
| 672 (*message)(LDPL_ERROR, "Failed to delete '%s': %s", Cleanup[i].c_str(), | 689 (*message)(LDPL_ERROR, "Failed to delete '%s': %s", Cleanup[i].c_str(), |
| 673 ErrMsg.c_str()); | 690 ErrMsg.c_str()); |
| 674 | 691 |
| 675 return LDPS_OK; | 692 return LDPS_OK; |
| 676 } | 693 } |
| OLD | NEW |