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).
// (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,
// 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 *);
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;
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;
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);
}
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) {
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";
return 1;
}
- FileStream.write(reinterpret_cast<const char *>(Code), len);
+ FileStream.write(Code->getBufferStart(), Code->getBufferSize());
} else {
std::string ErrorInfo;
const char *OutputName = nullptr;
}
}
-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.
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);
}
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) {
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) {