llvm.org GIT mirror llvm / 3fcf5a9
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 Peter Collingbourne 4 years ago
4 changed file(s) with 49 addition(s) and 37 deletion(s). Raw diff Collapse all Expand all
8181 void setShouldInternalize(bool Value) { ShouldInternalize = Value; }
8282 void setShouldEmbedUselists(bool Value) { ShouldEmbedUselists = Value; }
8383
84 void addMustPreserveSymbol(const char *sym) { MustPreserveSymbols[sym] = 1; }
84 void addMustPreserveSymbol(StringRef sym) { MustPreserveSymbols[sym] = 1; }
8585
8686 // To pass options to the driver and optimization passes. These options are
8787 // not necessarily for debugging purpose (The function name is misleading).
116116 // (linker), it brings the object to a buffer, and return the buffer to the
117117 // caller. This function should delete intermediate object file once its content
118118 // is brought to memory. Return NULL if the compilation was not successful.
119 const void *compile(size_t *length,
120 bool disableInline,
121 bool disableGVNLoadPRE,
122 bool disableVectorization,
123 std::string &errMsg);
119 std::unique_ptr compile(bool disableInline,
120 bool disableGVNLoadPRE,
121 bool disableVectorization,
122 std::string &errMsg);
124123
125124 // Optimizes the merged module. Returns true on success.
126125 bool optimize(bool disableInline,
131130 // Compiles the merged optimized module into a single object file. It brings
132131 // the object to a buffer, and returns the buffer to the caller. Return NULL
133132 // if the compilation was not successful.
134 const void *compileOptimized(size_t *length, std::string &errMsg);
133 std::unique_ptr compileOptimized(std::string &errMsg);
135134
136135 void setDiagnosticHandler(lto_diagnostic_handler_t, void *);
137136
165164 lto_codegen_model CodeModel = LTO_CODEGEN_PIC_MODEL_DEFAULT;
166165 StringSet MustPreserveSymbols;
167166 StringSet AsmUndefinedRefs;
168 std::unique_ptr NativeObjectFile;
169167 std::vector CodegenOptions;
170168 std::string MCpu;
171169 std::string MAttr;
249249 return true;
250250 }
251251
252 const void *LTOCodeGenerator::compileOptimized(size_t *length,
253 std::string &errMsg) {
252 std::unique_ptr
253 LTOCodeGenerator::compileOptimized(std::string &errMsg) {
254254 const char *name;
255255 if (!compileOptimizedToFile(&name, errMsg))
256256 return nullptr;
263263 sys::fs::remove(NativeObjectPath);
264264 return nullptr;
265265 }
266 NativeObjectFile = std::move(*BufferOrErr);
267266
268267 // remove temp files
269268 sys::fs::remove(NativeObjectPath);
270269
271 // return buffer, unless error
272 if (!NativeObjectFile)
273 return nullptr;
274 *length = NativeObjectFile->getBufferSize();
275 return NativeObjectFile->getBufferStart();
270 return std::move(*BufferOrErr);
276271 }
277272
278273
288283 return compileOptimizedToFile(name, errMsg);
289284 }
290285
291 const void* LTOCodeGenerator::compile(size_t *length,
292 bool disableInline,
293 bool disableGVNLoadPRE,
294 bool disableVectorization,
295 std::string &errMsg) {
286 std::unique_ptr
287 LTOCodeGenerator::compile(bool disableInline, bool disableGVNLoadPRE,
288 bool disableVectorization, std::string &errMsg) {
296289 if (!optimize(disableInline, disableGVNLoadPRE,
297290 disableVectorization, errMsg))
298291 return nullptr;
299292
300 return compileOptimized(length, errMsg);
293 return compileOptimized(errMsg);
301294 }
302295
303296 bool LTOCodeGenerator::determineTarget(std::string &errMsg) {
252252 CodeGen.setAttr(attrs.c_str());
253253
254254 if (!OutputFilename.empty()) {
255 size_t len = 0;
256255 std::string ErrorInfo;
257 const void *Code =
258 CodeGen.compile(&len, DisableInline, DisableGVNLoadPRE,
259 DisableLTOVectorization, ErrorInfo);
256 std::unique_ptr Code = CodeGen.compile(
257 DisableInline, DisableGVNLoadPRE, DisableLTOVectorization, ErrorInfo);
260258 if (!Code) {
261259 errs() << argv[0]
262260 << ": error compiling the code: " << ErrorInfo << "\n";
271269 return 1;
272270 }
273271
274 FileStream.write(reinterpret_cast(Code), len);
272 FileStream.write(Code->getBufferStart(), Code->getBufferSize());
275273 } else {
276274 std::string ErrorInfo;
277275 const char *OutputName = nullptr;
7272 }
7373 }
7474
75 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LTOCodeGenerator, lto_code_gen_t)
75 namespace {
76
77 // This derived class owns the native object file. This helps implement the
78 // libLTO API semantics, which require that the code generator owns the object
79 // file.
80 struct LibLTOCodeGenerator : LTOCodeGenerator {
81 LibLTOCodeGenerator() {}
82 LibLTOCodeGenerator(std::unique_ptr Context)
83 : LTOCodeGenerator(std::move(Context)) {}
84
85 std::unique_ptr NativeObjectFile;
86 };
87
88 }
89
90 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LibLTOCodeGenerator, lto_code_gen_t)
7691 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LTOModule, lto_module_t)
7792
7893 // Convert the subtarget features into a string to pass to LTOCodeGenerator.
234249
235250 TargetOptions Options = InitTargetOptionsFromCodeGenFlags();
236251
237 LTOCodeGenerator *CodeGen =
238 InLocalContext ? new LTOCodeGenerator(make_unique())
239 : new LTOCodeGenerator();
240 if (CodeGen)
241 CodeGen->setTargetOptions(Options);
252 LibLTOCodeGenerator *CodeGen =
253 InLocalContext ? new LibLTOCodeGenerator(make_unique())
254 : new LibLTOCodeGenerator();
255 CodeGen->setTargetOptions(Options);
242256 return wrap(CodeGen);
243257 }
244258
303317
304318 const void *lto_codegen_compile(lto_code_gen_t cg, size_t *length) {
305319 maybeParseOptions(cg);
306 return unwrap(cg)->compile(length, DisableInline,
307 DisableGVNLoadPRE, DisableLTOVectorization,
308 sLastErrorString);
320 LibLTOCodeGenerator *CG = unwrap(cg);
321 CG->NativeObjectFile = CG->compile(DisableInline, DisableGVNLoadPRE,
322 DisableLTOVectorization, sLastErrorString);
323 if (!CG->NativeObjectFile)
324 return nullptr;
325 *length = CG->NativeObjectFile->getBufferSize();
326 return CG->NativeObjectFile->getBufferStart();
309327 }
310328
311329 bool lto_codegen_optimize(lto_code_gen_t cg) {
317335
318336 const void *lto_codegen_compile_optimized(lto_code_gen_t cg, size_t *length) {
319337 maybeParseOptions(cg);
320 return unwrap(cg)->compileOptimized(length, sLastErrorString);
338 LibLTOCodeGenerator *CG = unwrap(cg);
339 CG->NativeObjectFile = CG->compileOptimized(sLastErrorString);
340 if (!CG->NativeObjectFile)
341 return nullptr;
342 *length = CG->NativeObjectFile->getBufferSize();
343 return CG->NativeObjectFile->getBufferStart();
321344 }
322345
323346 bool lto_codegen_compile_to_file(lto_code_gen_t cg, const char **name) {