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 |