mirror of
https://github.com/RPCS3/llvm.git
synced 2025-01-18 07:52:35 +00:00
Make the C++ LTO API easier to use from C++ clients.
Start using C++ types such as StringRef and MemoryBuffer in the C++ LTO API. In doing so, clarify the ownership of the native object file: the caller now owns it, not the LTOCodeGenerator. The C libLTO library has been modified to use a derived class of LTOCodeGenerator that owns the object file. Differential Revision: http://reviews.llvm.org/D10114 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@238776 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
9be6a55ba0
commit
3fcf5a99cb
@ -82,7 +82,7 @@ struct LTOCodeGenerator {
|
||||
void setShouldInternalize(bool Value) { ShouldInternalize = Value; }
|
||||
void setShouldEmbedUselists(bool Value) { ShouldEmbedUselists = Value; }
|
||||
|
||||
void addMustPreserveSymbol(const char *sym) { MustPreserveSymbols[sym] = 1; }
|
||||
void addMustPreserveSymbol(StringRef sym) { MustPreserveSymbols[sym] = 1; }
|
||||
|
||||
// To pass options to the driver and optimization passes. These options are
|
||||
// not necessarily for debugging purpose (The function name is misleading).
|
||||
@ -117,11 +117,10 @@ struct LTOCodeGenerator {
|
||||
// (linker), it brings the object to a buffer, and return the buffer to the
|
||||
// caller. This function should delete intermediate object file once its content
|
||||
// is brought to memory. Return NULL if the compilation was not successful.
|
||||
const void *compile(size_t *length,
|
||||
bool disableInline,
|
||||
bool disableGVNLoadPRE,
|
||||
bool disableVectorization,
|
||||
std::string &errMsg);
|
||||
std::unique_ptr<MemoryBuffer> compile(bool disableInline,
|
||||
bool disableGVNLoadPRE,
|
||||
bool disableVectorization,
|
||||
std::string &errMsg);
|
||||
|
||||
// Optimizes the merged module. Returns true on success.
|
||||
bool optimize(bool disableInline,
|
||||
@ -132,7 +131,7 @@ struct LTOCodeGenerator {
|
||||
// Compiles the merged optimized module into a single object file. It brings
|
||||
// the object to a buffer, and returns the buffer to the caller. Return NULL
|
||||
// if the compilation was not successful.
|
||||
const void *compileOptimized(size_t *length, std::string &errMsg);
|
||||
std::unique_ptr<MemoryBuffer> compileOptimized(std::string &errMsg);
|
||||
|
||||
void setDiagnosticHandler(lto_diagnostic_handler_t, void *);
|
||||
|
||||
@ -166,7 +165,6 @@ private:
|
||||
lto_codegen_model CodeModel = LTO_CODEGEN_PIC_MODEL_DEFAULT;
|
||||
StringSet MustPreserveSymbols;
|
||||
StringSet AsmUndefinedRefs;
|
||||
std::unique_ptr<MemoryBuffer> NativeObjectFile;
|
||||
std::vector<char *> CodegenOptions;
|
||||
std::string MCpu;
|
||||
std::string MAttr;
|
||||
|
@ -250,8 +250,8 @@ bool LTOCodeGenerator::compileOptimizedToFile(const char **name,
|
||||
return true;
|
||||
}
|
||||
|
||||
const void *LTOCodeGenerator::compileOptimized(size_t *length,
|
||||
std::string &errMsg) {
|
||||
std::unique_ptr<MemoryBuffer>
|
||||
LTOCodeGenerator::compileOptimized(std::string &errMsg) {
|
||||
const char *name;
|
||||
if (!compileOptimizedToFile(&name, errMsg))
|
||||
return nullptr;
|
||||
@ -264,16 +264,11 @@ const void *LTOCodeGenerator::compileOptimized(size_t *length,
|
||||
sys::fs::remove(NativeObjectPath);
|
||||
return nullptr;
|
||||
}
|
||||
NativeObjectFile = std::move(*BufferOrErr);
|
||||
|
||||
// remove temp files
|
||||
sys::fs::remove(NativeObjectPath);
|
||||
|
||||
// return buffer, unless error
|
||||
if (!NativeObjectFile)
|
||||
return nullptr;
|
||||
*length = NativeObjectFile->getBufferSize();
|
||||
return NativeObjectFile->getBufferStart();
|
||||
return std::move(*BufferOrErr);
|
||||
}
|
||||
|
||||
|
||||
@ -289,16 +284,14 @@ bool LTOCodeGenerator::compile_to_file(const char **name,
|
||||
return compileOptimizedToFile(name, errMsg);
|
||||
}
|
||||
|
||||
const void* LTOCodeGenerator::compile(size_t *length,
|
||||
bool disableInline,
|
||||
bool disableGVNLoadPRE,
|
||||
bool disableVectorization,
|
||||
std::string &errMsg) {
|
||||
std::unique_ptr<MemoryBuffer>
|
||||
LTOCodeGenerator::compile(bool disableInline, bool disableGVNLoadPRE,
|
||||
bool disableVectorization, std::string &errMsg) {
|
||||
if (!optimize(disableInline, disableGVNLoadPRE,
|
||||
disableVectorization, errMsg))
|
||||
return nullptr;
|
||||
|
||||
return compileOptimized(length, errMsg);
|
||||
return compileOptimized(errMsg);
|
||||
}
|
||||
|
||||
bool LTOCodeGenerator::determineTarget(std::string &errMsg) {
|
||||
|
@ -253,11 +253,9 @@ int main(int argc, char **argv) {
|
||||
CodeGen.setAttr(attrs.c_str());
|
||||
|
||||
if (!OutputFilename.empty()) {
|
||||
size_t len = 0;
|
||||
std::string ErrorInfo;
|
||||
const void *Code =
|
||||
CodeGen.compile(&len, DisableInline, DisableGVNLoadPRE,
|
||||
DisableLTOVectorization, ErrorInfo);
|
||||
std::unique_ptr<MemoryBuffer> Code = CodeGen.compile(
|
||||
DisableInline, DisableGVNLoadPRE, DisableLTOVectorization, ErrorInfo);
|
||||
if (!Code) {
|
||||
errs() << argv[0]
|
||||
<< ": error compiling the code: " << ErrorInfo << "\n";
|
||||
@ -272,7 +270,7 @@ int main(int argc, char **argv) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
FileStream.write(reinterpret_cast<const char *>(Code), len);
|
||||
FileStream.write(Code->getBufferStart(), Code->getBufferSize());
|
||||
} else {
|
||||
std::string ErrorInfo;
|
||||
const char *OutputName = nullptr;
|
||||
|
@ -73,7 +73,22 @@ static void lto_initialize() {
|
||||
}
|
||||
}
|
||||
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LTOCodeGenerator, lto_code_gen_t)
|
||||
namespace {
|
||||
|
||||
// This derived class owns the native object file. This helps implement the
|
||||
// libLTO API semantics, which require that the code generator owns the object
|
||||
// file.
|
||||
struct LibLTOCodeGenerator : LTOCodeGenerator {
|
||||
LibLTOCodeGenerator() {}
|
||||
LibLTOCodeGenerator(std::unique_ptr<LLVMContext> Context)
|
||||
: LTOCodeGenerator(std::move(Context)) {}
|
||||
|
||||
std::unique_ptr<MemoryBuffer> NativeObjectFile;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LibLTOCodeGenerator, lto_code_gen_t)
|
||||
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LTOModule, lto_module_t)
|
||||
|
||||
// Convert the subtarget features into a string to pass to LTOCodeGenerator.
|
||||
@ -235,11 +250,10 @@ static lto_code_gen_t createCodeGen(bool InLocalContext) {
|
||||
|
||||
TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
|
||||
|
||||
LTOCodeGenerator *CodeGen =
|
||||
InLocalContext ? new LTOCodeGenerator(make_unique<LLVMContext>())
|
||||
: new LTOCodeGenerator();
|
||||
if (CodeGen)
|
||||
CodeGen->setTargetOptions(Options);
|
||||
LibLTOCodeGenerator *CodeGen =
|
||||
InLocalContext ? new LibLTOCodeGenerator(make_unique<LLVMContext>())
|
||||
: new LibLTOCodeGenerator();
|
||||
CodeGen->setTargetOptions(Options);
|
||||
return wrap(CodeGen);
|
||||
}
|
||||
|
||||
@ -304,9 +318,13 @@ bool lto_codegen_write_merged_modules(lto_code_gen_t cg, const char *path) {
|
||||
|
||||
const void *lto_codegen_compile(lto_code_gen_t cg, size_t *length) {
|
||||
maybeParseOptions(cg);
|
||||
return unwrap(cg)->compile(length, DisableInline,
|
||||
DisableGVNLoadPRE, DisableLTOVectorization,
|
||||
sLastErrorString);
|
||||
LibLTOCodeGenerator *CG = unwrap(cg);
|
||||
CG->NativeObjectFile = CG->compile(DisableInline, DisableGVNLoadPRE,
|
||||
DisableLTOVectorization, sLastErrorString);
|
||||
if (!CG->NativeObjectFile)
|
||||
return nullptr;
|
||||
*length = CG->NativeObjectFile->getBufferSize();
|
||||
return CG->NativeObjectFile->getBufferStart();
|
||||
}
|
||||
|
||||
bool lto_codegen_optimize(lto_code_gen_t cg) {
|
||||
@ -318,7 +336,12 @@ bool lto_codegen_optimize(lto_code_gen_t cg) {
|
||||
|
||||
const void *lto_codegen_compile_optimized(lto_code_gen_t cg, size_t *length) {
|
||||
maybeParseOptions(cg);
|
||||
return unwrap(cg)->compileOptimized(length, sLastErrorString);
|
||||
LibLTOCodeGenerator *CG = unwrap(cg);
|
||||
CG->NativeObjectFile = CG->compileOptimized(sLastErrorString);
|
||||
if (!CG->NativeObjectFile)
|
||||
return nullptr;
|
||||
*length = CG->NativeObjectFile->getBufferSize();
|
||||
return CG->NativeObjectFile->getBufferStart();
|
||||
}
|
||||
|
||||
bool lto_codegen_compile_to_file(lto_code_gen_t cg, const char **name) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user