diff --git a/include/llvm-c/lto.h b/include/llvm-c/lto.h index 40110fddfc1..907007c6525 100644 --- a/include/llvm-c/lto.h +++ b/include/llvm-c/lto.h @@ -27,7 +27,7 @@ * @{ */ -#define LTO_API_VERSION 4 +#define LTO_API_VERSION 5 typedef enum { LTO_SYMBOL_ALIGNMENT_MASK = 0x0000001F, /* log2 of alignment */ @@ -284,6 +284,22 @@ lto_codegen_compile(lto_code_gen_t cg, size_t* length); extern bool lto_codegen_compile_to_file(lto_code_gen_t cg, const char** name); +struct NativeObjectFile { + const void *content; + size_t length; +}; + +/** + * Generates code for merged module into an array of native object files. + * On success returns a pointer to an array of NativeObjectFile. The + * count parameter returns the number of elements in the array. Each + * element is a pointer/length for a generated mach-o/ELF buffer. The + * buffer is owned by the lto_code_gen_t and will be freed when + * lto_codegen_dispose() is called, or lto_codegen_compile() is called again. + * On failure, returns NULL (check lto_get_error_message() for details). + */ +extern const struct NativeObjectFile* +lto_codegen_compile_parallel(lto_code_gen_t cg, size_t *count); /** * Sets options to help debug codegen bugs. diff --git a/tools/lto/LTOCodeGenerator.cpp b/tools/lto/LTOCodeGenerator.cpp index 3fe7af25afd..daeb9648e30 100644 --- a/tools/lto/LTOCodeGenerator.cpp +++ b/tools/lto/LTOCodeGenerator.cpp @@ -74,7 +74,7 @@ LTOCodeGenerator::LTOCodeGenerator() _linker(new Module("ld-temp.o", _context)), _target(NULL), _emitDwarfDebugInfo(false), _scopeRestrictionsDone(false), _codeModel(LTO_CODEGEN_PIC_MODEL_DYNAMIC), - _nativeObjectFile(NULL) { + _nativeObjectFile(NULL), ObjBufVect(0) { InitializeAllTargets(); InitializeAllTargetMCs(); InitializeAllAsmPrinters(); @@ -85,6 +85,7 @@ LTOCodeGenerator::~LTOCodeGenerator() { delete _target; delete _nativeObjectFile; delete _linker.getModule(); + delete[] ObjBufVect; for (std::vector::iterator I = _codegenOptions.begin(), E = _codegenOptions.end(); I != E; ++I) @@ -246,6 +247,23 @@ const void* LTOCodeGenerator::compile(size_t* length, std::string& errMsg) { return _nativeObjectFile->getBufferStart(); } +// Currently compile() and compile_parallel() have no difference. +NativeObjectFile *LTOCodeGenerator::compile_parallel(size_t *count, + std::string &ErrMsg) { + assert(ObjBufVect == 0 && "Should be NULL"); + + size_t Len; + const void *Buf = compile(&Len, ErrMsg); + if (!Buf) + return 0; + + *count = 1; + ObjBufVect = new NativeObjectFile[1]; + ObjBufVect[0].content = Buf; + ObjBufVect[0].length = Len; + return ObjBufVect; +} + bool LTOCodeGenerator::determineTarget(std::string &errMsg) { if (_target != NULL) return true; diff --git a/tools/lto/LTOCodeGenerator.h b/tools/lto/LTOCodeGenerator.h index 8f37cf0e1d5..21c6b212925 100644 --- a/tools/lto/LTOCodeGenerator.h +++ b/tools/lto/LTOCodeGenerator.h @@ -102,6 +102,17 @@ struct LTOCodeGenerator { // const void *compile(size_t *length, std::string &errMsg); + // Corresponding to lto_codegen_compile_parallel() API. + // Generates code for merged module into an array of native object files. + // On success returns a pointer to an array of NativeObjectFile. The count + // parameter returns the number of elements in the array. Each element is + // a pointer/length for a generated mach-o/ELF buffer. The buffer is owned + // by the lto_code_gen_t and will be freed when lto_codegen_dispose() is + // called, or lto_codegen_compile() is called again. On failure, returns + // NULL (check lto_get_error_message() for details). + // + NativeObjectFile *compile_parallel(size_t *count, std::string &ErrMsg); + private: void initializeLTOPasses(); @@ -127,6 +138,7 @@ private: std::vector _codegenOptions; std::string _mCpu; std::string _nativeObjectPath; + NativeObjectFile *ObjBufVect; }; #endif // LTO_CODE_GENERATOR_H diff --git a/tools/lto/lto.cpp b/tools/lto/lto.cpp index db7147c2bc7..bbb6071ce8a 100644 --- a/tools/lto/lto.cpp +++ b/tools/lto/lto.cpp @@ -207,6 +207,11 @@ bool lto_codegen_compile_to_file(lto_code_gen_t cg, const char **name) { return !cg->compile_to_file(name, sLastErrorString); } +extern const struct NativeObjectFile * +lto_codegen_compile_parallel(lto_code_gen_t cg, size_t *count) { + return cg->compile_parallel(count, sLastErrorString); +} + /// lto_codegen_debug_options - Used to pass extra options to the code /// generator. void lto_codegen_debug_options(lto_code_gen_t cg, const char *opt) { diff --git a/tools/lto/lto.exports b/tools/lto/lto.exports index 46d0d74c82a..61f0817f335 100644 --- a/tools/lto/lto.exports +++ b/tools/lto/lto.exports @@ -28,6 +28,7 @@ lto_codegen_set_assembler_args lto_codegen_set_assembler_path lto_codegen_set_cpu lto_codegen_compile_to_file +lto_codegen_compile_parallel LLVMCreateDisasm LLVMCreateDisasmCPU LLVMDisasmDispose