summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/llvm-c/lto.h7
-rw-r--r--tools/gold/gold-plugin.cpp32
-rw-r--r--tools/lto/LTOCodeGenerator.cpp95
-rw-r--r--tools/lto/LTOCodeGenerator.h2
-rw-r--r--tools/lto/lto.cpp6
-rw-r--r--tools/lto/lto.exports1
6 files changed, 70 insertions, 73 deletions
diff --git a/include/llvm-c/lto.h b/include/llvm-c/lto.h
index be08c4eb19..e4ede9cc6d 100644
--- a/include/llvm-c/lto.h
+++ b/include/llvm-c/lto.h
@@ -272,6 +272,13 @@ lto_codegen_write_merged_modules(lto_code_gen_t cg, const char* path);
extern const void*
lto_codegen_compile(lto_code_gen_t cg, size_t* length);
+/**
+ * Generates code for all added modules into one native object file.
+ * The name of the file is written to name. Returns true on error.
+ */
+extern bool
+lto_codegen_compile_to_file(lto_code_gen_t cg, const char** name);
+
/**
* Sets options to help debug codegen bugs.
diff --git a/tools/gold/gold-plugin.cpp b/tools/gold/gold-plugin.cpp
index 7aa8c9109f..ce857894d6 100644
--- a/tools/gold/gold-plugin.cpp
+++ b/tools/gold/gold-plugin.cpp
@@ -398,38 +398,10 @@ static ld_plugin_status all_symbols_read_hook(void) {
exit(0);
}
size_t bufsize = 0;
- const char *buffer = static_cast<const char *>(lto_codegen_compile(code_gen,
- &bufsize));
-
- std::string ErrMsg;
-
const char *objPath;
- sys::Path uniqueObjPath("/tmp/llvmgold.o");
- if (!options::obj_path.empty()) {
- objPath = options::obj_path.c_str();
- } else {
- if (uniqueObjPath.createTemporaryFileOnDisk(true, &ErrMsg)) {
- (*message)(LDPL_ERROR, "%s", ErrMsg.c_str());
- return LDPS_ERR;
- }
- objPath = uniqueObjPath.c_str();
- }
- tool_output_file objFile(objPath, ErrMsg,
- raw_fd_ostream::F_Binary);
- if (!ErrMsg.empty()) {
- (*message)(LDPL_ERROR, "%s", ErrMsg.c_str());
- return LDPS_ERR;
- }
-
- objFile.os().write(buffer, bufsize);
- objFile.os().close();
- if (objFile.os().has_error()) {
- (*message)(LDPL_ERROR, "Error writing output file '%s'",
- objPath);
- objFile.os().clear_error();
- return LDPS_ERR;
+ if (lto_codegen_compile_to_file(code_gen, &objPath)) {
+ (*message)(LDPL_ERROR, "Could not produce a combined object file\n");
}
- objFile.keep();
lto_codegen_dispose(code_gen);
for (std::list<claimed_file>::iterator I = Modules.begin(),
diff --git a/tools/lto/LTOCodeGenerator.cpp b/tools/lto/LTOCodeGenerator.cpp
index 372cb31a4c..d95f35405b 100644
--- a/tools/lto/LTOCodeGenerator.cpp
+++ b/tools/lto/LTOCodeGenerator.cpp
@@ -176,54 +176,63 @@ bool LTOCodeGenerator::writeMergedModules(const char *path,
}
-const void* LTOCodeGenerator::compile(size_t* length, std::string& errMsg)
+bool LTOCodeGenerator::compile_to_file(const char** name, std::string& errMsg)
{
- // make unique temp .o file to put generated object file
- sys::PathWithStatus uniqueObjPath("lto-llvm.o");
- if ( uniqueObjPath.createTemporaryFileOnDisk(false, &errMsg) ) {
- uniqueObjPath.eraseFromDisk();
- return NULL;
- }
- sys::RemoveFileOnSignal(uniqueObjPath);
-
- // generate object file
- bool genResult = false;
- tool_output_file objFile(uniqueObjPath.c_str(), errMsg);
- if (!errMsg.empty())
- return NULL;
- genResult = this->generateObjectFile(objFile.os(), errMsg);
- objFile.os().close();
- if (objFile.os().has_error()) {
- objFile.os().clear_error();
- return NULL;
- }
- objFile.keep();
- if ( genResult ) {
- uniqueObjPath.eraseFromDisk();
- return NULL;
- }
+ // make unique temp .o file to put generated object file
+ sys::PathWithStatus uniqueObjPath("lto-llvm.o");
+ if ( uniqueObjPath.createTemporaryFileOnDisk(false, &errMsg) ) {
+ uniqueObjPath.eraseFromDisk();
+ return true;
+ }
+ sys::RemoveFileOnSignal(uniqueObjPath);
+
+ // generate object file
+ bool genResult = false;
+ tool_output_file objFile(uniqueObjPath.c_str(), errMsg);
+ if (!errMsg.empty())
+ return NULL;
+ genResult = this->generateObjectFile(objFile.os(), errMsg);
+ objFile.os().close();
+ if (objFile.os().has_error()) {
+ objFile.os().clear_error();
+ return true;
+ }
+ objFile.keep();
+ if ( genResult ) {
+ uniqueObjPath.eraseFromDisk();
+ return true;
+ }
- const std::string& uniqueObjStr = uniqueObjPath.str();
- // remove old buffer if compile() called twice
- delete _nativeObjectFile;
+ _nativeObjectPath = uniqueObjPath.str();
+ *name = _nativeObjectPath.c_str();
+ return false;
+}
- // read .o file into memory buffer
- OwningPtr<MemoryBuffer> BuffPtr;
- if (error_code ec = MemoryBuffer::getFile(uniqueObjStr.c_str(), BuffPtr,
- -1, false)) {
- errMsg = ec.message();
- return NULL;
- }
- _nativeObjectFile = BuffPtr.take();
+const void* LTOCodeGenerator::compile(size_t* length, std::string& errMsg)
+{
+ const char *name;
+ if (compile_to_file(&name, errMsg))
+ return NULL;
+
+ // remove old buffer if compile() called twice
+ delete _nativeObjectFile;
+
+ // read .o file into memory buffer
+ OwningPtr<MemoryBuffer> BuffPtr;
+ if (error_code ec = MemoryBuffer::getFile(name, BuffPtr, -1, false)) {
+ errMsg = ec.message();
+ return NULL;
+ }
+ _nativeObjectFile = BuffPtr.take();
- // remove temp files
- uniqueObjPath.eraseFromDisk();
+ // remove temp files
+ sys::Path(_nativeObjectPath).eraseFromDisk();
- // return buffer, unless error
- if ( _nativeObjectFile == NULL )
- return NULL;
- *length = _nativeObjectFile->getBufferSize();
- return _nativeObjectFile->getBufferStart();
+ // return buffer, unless error
+ if ( _nativeObjectFile == NULL )
+ return NULL;
+ *length = _nativeObjectFile->getBufferSize();
+ return _nativeObjectFile->getBufferStart();
}
bool LTOCodeGenerator::determineTarget(std::string& errMsg)
diff --git a/tools/lto/LTOCodeGenerator.h b/tools/lto/LTOCodeGenerator.h
index 7798db974c..f8fd357df4 100644
--- a/tools/lto/LTOCodeGenerator.h
+++ b/tools/lto/LTOCodeGenerator.h
@@ -41,6 +41,7 @@ struct LTOCodeGenerator {
void addMustPreserveSymbol(const char* sym);
bool writeMergedModules(const char* path,
std::string& errMsg);
+ bool compile_to_file(const char** name, std::string& errMsg);
const void* compile(size_t* length, std::string& errMsg);
void setCodeGenDebugOptions(const char *opts);
private:
@@ -66,6 +67,7 @@ private:
llvm::MemoryBuffer* _nativeObjectFile;
std::vector<const char*> _codegenOptions;
std::string _mCpu;
+ std::string _nativeObjectPath;
};
#endif // LTO_CODE_GENERATOR_H
diff --git a/tools/lto/lto.cpp b/tools/lto/lto.cpp
index cbac047c75..fe19921400 100644
--- a/tools/lto/lto.cpp
+++ b/tools/lto/lto.cpp
@@ -293,6 +293,12 @@ lto_codegen_compile(lto_code_gen_t cg, size_t* length)
return cg->compile(length, sLastErrorString);
}
+extern bool
+lto_codegen_compile_to_file(lto_code_gen_t cg, const char **name)
+{
+ return cg->compile_to_file(name, sLastErrorString);
+}
+
//
// Used to pass extra options to the code generator
diff --git a/tools/lto/lto.exports b/tools/lto/lto.exports
index 04b37e1f45..0fcfee59d3 100644
--- a/tools/lto/lto.exports
+++ b/tools/lto/lto.exports
@@ -26,3 +26,4 @@ lto_codegen_debug_options
lto_codegen_set_assembler_args
lto_codegen_set_assembler_path
lto_codegen_set_cpu
+lto_codegen_compile_to_file