1 //===-lto.cpp - LLVM Link Time Optimizer ----------------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file implements the Link Time Optimization library. This library is 11 // intended to be used by linker to optimize code at link time. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "llvm-c/lto.h" 16 #include "llvm/ADT/STLExtras.h" 17 #include "llvm/CodeGen/CommandFlags.h" 18 #include "llvm/IR/DiagnosticInfo.h" 19 #include "llvm/IR/DiagnosticPrinter.h" 20 #include "llvm/IR/LLVMContext.h" 21 #include "llvm/LTO/LTOCodeGenerator.h" 22 #include "llvm/LTO/LTOModule.h" 23 #include "llvm/Support/MemoryBuffer.h" 24 #include "llvm/Support/Signals.h" 25 #include "llvm/Support/TargetSelect.h" 26 #include "llvm/Support/raw_ostream.h" 27 28 // extra command-line flags needed for LTOCodeGenerator 29 static cl::opt<char> 30 OptLevel("O", 31 cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] " 32 "(default = '-O2')"), 33 cl::Prefix, 34 cl::ZeroOrMore, 35 cl::init('2')); 36 37 static cl::opt<bool> 38 DisableInline("disable-inlining", cl::init(false), 39 cl::desc("Do not run the inliner pass")); 40 41 static cl::opt<bool> 42 DisableGVNLoadPRE("disable-gvn-loadpre", cl::init(false), 43 cl::desc("Do not run the GVN load PRE pass")); 44 45 static cl::opt<bool> 46 DisableLTOVectorization("disable-lto-vectorization", cl::init(false), 47 cl::desc("Do not run loop or slp vectorization during LTO")); 48 49 #ifdef NDEBUG 50 static bool VerifyByDefault = false; 51 #else 52 static bool VerifyByDefault = true; 53 #endif 54 55 static cl::opt<bool> DisableVerify( 56 "disable-llvm-verifier", cl::init(!VerifyByDefault), 57 cl::desc("Don't run the LLVM verifier during the optimization pipeline")); 58 59 // Holds most recent error string. 60 // *** Not thread safe *** 61 static std::string sLastErrorString; 62 63 // Holds the initialization state of the LTO module. 64 // *** Not thread safe *** 65 static bool initialized = false; 66 67 // Holds the command-line option parsing state of the LTO module. 68 static bool parsedOptions = false; 69 70 static LLVMContext *LTOContext = nullptr; 71 72 static void diagnosticHandler(const DiagnosticInfo &DI, void *Context) { 73 if (DI.getSeverity() != DS_Error) { 74 DiagnosticPrinterRawOStream DP(errs()); 75 DI.print(DP); 76 errs() << '\n'; 77 return; 78 } 79 sLastErrorString = ""; 80 { 81 raw_string_ostream Stream(sLastErrorString); 82 DiagnosticPrinterRawOStream DP(Stream); 83 DI.print(DP); 84 } 85 } 86 87 // Initialize the configured targets if they have not been initialized. 88 static void lto_initialize() { 89 if (!initialized) { 90 #ifdef LLVM_ON_WIN32 91 // Dialog box on crash disabling doesn't work across DLL boundaries, so do 92 // it here. 93 llvm::sys::DisableSystemDialogsOnCrash(); 94 #endif 95 96 InitializeAllTargetInfos(); 97 InitializeAllTargets(); 98 InitializeAllTargetMCs(); 99 InitializeAllAsmParsers(); 100 InitializeAllAsmPrinters(); 101 InitializeAllDisassemblers(); 102 103 LTOContext = &getGlobalContext(); 104 LTOContext->setDiagnosticHandler(diagnosticHandler, nullptr, true); 105 initialized = true; 106 } 107 } 108 109 namespace { 110 111 static void handleLibLTODiagnostic(lto_codegen_diagnostic_severity_t Severity, 112 const char *Msg, void *) { 113 sLastErrorString = Msg; 114 } 115 116 // This derived class owns the native object file. This helps implement the 117 // libLTO API semantics, which require that the code generator owns the object 118 // file. 119 struct LibLTOCodeGenerator : LTOCodeGenerator { 120 LibLTOCodeGenerator() : LTOCodeGenerator(*LTOContext) { 121 setDiagnosticHandler(handleLibLTODiagnostic, nullptr); } 122 LibLTOCodeGenerator(std::unique_ptr<LLVMContext> Context) 123 : LTOCodeGenerator(*Context), OwnedContext(std::move(Context)) { 124 setDiagnosticHandler(handleLibLTODiagnostic, nullptr); } 125 126 // Reset the module first in case MergedModule is created in OwnedContext. 127 // Module must be destructed before its context gets destructed. 128 ~LibLTOCodeGenerator() { resetMergedModule(); } 129 130 std::unique_ptr<MemoryBuffer> NativeObjectFile; 131 std::unique_ptr<LLVMContext> OwnedContext; 132 }; 133 134 } 135 136 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LibLTOCodeGenerator, lto_code_gen_t) 137 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LTOModule, lto_module_t) 138 139 // Convert the subtarget features into a string to pass to LTOCodeGenerator. 140 static void lto_add_attrs(lto_code_gen_t cg) { 141 LTOCodeGenerator *CG = unwrap(cg); 142 if (MAttrs.size()) { 143 std::string attrs; 144 for (unsigned i = 0; i < MAttrs.size(); ++i) { 145 if (i > 0) 146 attrs.append(","); 147 attrs.append(MAttrs[i]); 148 } 149 150 CG->setAttr(attrs.c_str()); 151 } 152 153 if (OptLevel < '0' || OptLevel > '3') 154 report_fatal_error("Optimization level must be between 0 and 3"); 155 CG->setOptLevel(OptLevel - '0'); 156 } 157 158 extern const char* lto_get_version() { 159 return LTOCodeGenerator::getVersionString(); 160 } 161 162 const char* lto_get_error_message() { 163 return sLastErrorString.c_str(); 164 } 165 166 bool lto_module_is_object_file(const char* path) { 167 return LTOModule::isBitcodeFile(path); 168 } 169 170 bool lto_module_is_object_file_for_target(const char* path, 171 const char* target_triplet_prefix) { 172 ErrorOr<std::unique_ptr<MemoryBuffer>> Buffer = MemoryBuffer::getFile(path); 173 if (!Buffer) 174 return false; 175 return LTOModule::isBitcodeForTarget(Buffer->get(), target_triplet_prefix); 176 } 177 178 bool lto_module_is_object_file_in_memory(const void* mem, size_t length) { 179 return LTOModule::isBitcodeFile(mem, length); 180 } 181 182 bool 183 lto_module_is_object_file_in_memory_for_target(const void* mem, 184 size_t length, 185 const char* target_triplet_prefix) { 186 std::unique_ptr<MemoryBuffer> buffer(LTOModule::makeBuffer(mem, length)); 187 if (!buffer) 188 return false; 189 return LTOModule::isBitcodeForTarget(buffer.get(), target_triplet_prefix); 190 } 191 192 lto_module_t lto_module_create(const char* path) { 193 lto_initialize(); 194 llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags(); 195 ErrorOr<std::unique_ptr<LTOModule>> M = 196 LTOModule::createFromFile(*LTOContext, path, Options); 197 if (!M) 198 return nullptr; 199 return wrap(M->release()); 200 } 201 202 lto_module_t lto_module_create_from_fd(int fd, const char *path, size_t size) { 203 lto_initialize(); 204 llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags(); 205 ErrorOr<std::unique_ptr<LTOModule>> M = 206 LTOModule::createFromOpenFile(*LTOContext, fd, path, size, Options); 207 if (!M) 208 return nullptr; 209 return wrap(M->release()); 210 } 211 212 lto_module_t lto_module_create_from_fd_at_offset(int fd, const char *path, 213 size_t file_size, 214 size_t map_size, 215 off_t offset) { 216 lto_initialize(); 217 llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags(); 218 ErrorOr<std::unique_ptr<LTOModule>> M = LTOModule::createFromOpenFileSlice( 219 *LTOContext, fd, path, map_size, offset, Options); 220 if (!M) 221 return nullptr; 222 return wrap(M->release()); 223 } 224 225 lto_module_t lto_module_create_from_memory(const void* mem, size_t length) { 226 lto_initialize(); 227 llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags(); 228 ErrorOr<std::unique_ptr<LTOModule>> M = 229 LTOModule::createFromBuffer(*LTOContext, mem, length, Options); 230 if (!M) 231 return nullptr; 232 return wrap(M->release()); 233 } 234 235 lto_module_t lto_module_create_from_memory_with_path(const void* mem, 236 size_t length, 237 const char *path) { 238 lto_initialize(); 239 llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags(); 240 ErrorOr<std::unique_ptr<LTOModule>> M = 241 LTOModule::createFromBuffer(*LTOContext, mem, length, Options, path); 242 if (!M) 243 return nullptr; 244 return wrap(M->release()); 245 } 246 247 lto_module_t lto_module_create_in_local_context(const void *mem, size_t length, 248 const char *path) { 249 lto_initialize(); 250 llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags(); 251 ErrorOr<std::unique_ptr<LTOModule>> M = 252 LTOModule::createInLocalContext(mem, length, Options, path); 253 if (!M) 254 return nullptr; 255 return wrap(M->release()); 256 } 257 258 lto_module_t lto_module_create_in_codegen_context(const void *mem, 259 size_t length, 260 const char *path, 261 lto_code_gen_t cg) { 262 lto_initialize(); 263 llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags(); 264 ErrorOr<std::unique_ptr<LTOModule>> M = LTOModule::createInContext( 265 mem, length, Options, path, &unwrap(cg)->getContext()); 266 return wrap(M->release()); 267 } 268 269 void lto_module_dispose(lto_module_t mod) { delete unwrap(mod); } 270 271 const char* lto_module_get_target_triple(lto_module_t mod) { 272 return unwrap(mod)->getTargetTriple().c_str(); 273 } 274 275 void lto_module_set_target_triple(lto_module_t mod, const char *triple) { 276 return unwrap(mod)->setTargetTriple(triple); 277 } 278 279 unsigned int lto_module_get_num_symbols(lto_module_t mod) { 280 return unwrap(mod)->getSymbolCount(); 281 } 282 283 const char* lto_module_get_symbol_name(lto_module_t mod, unsigned int index) { 284 return unwrap(mod)->getSymbolName(index); 285 } 286 287 lto_symbol_attributes lto_module_get_symbol_attribute(lto_module_t mod, 288 unsigned int index) { 289 return unwrap(mod)->getSymbolAttributes(index); 290 } 291 292 const char* lto_module_get_linkeropts(lto_module_t mod) { 293 return unwrap(mod)->getLinkerOpts(); 294 } 295 296 void lto_codegen_set_diagnostic_handler(lto_code_gen_t cg, 297 lto_diagnostic_handler_t diag_handler, 298 void *ctxt) { 299 unwrap(cg)->setDiagnosticHandler(diag_handler, ctxt); 300 } 301 302 static lto_code_gen_t createCodeGen(bool InLocalContext) { 303 lto_initialize(); 304 305 TargetOptions Options = InitTargetOptionsFromCodeGenFlags(); 306 307 LibLTOCodeGenerator *CodeGen = 308 InLocalContext ? new LibLTOCodeGenerator(make_unique<LLVMContext>()) 309 : new LibLTOCodeGenerator(); 310 CodeGen->setTargetOptions(Options); 311 return wrap(CodeGen); 312 } 313 314 lto_code_gen_t lto_codegen_create(void) { 315 return createCodeGen(/* InLocalContext */ false); 316 } 317 318 lto_code_gen_t lto_codegen_create_in_local_context(void) { 319 return createCodeGen(/* InLocalContext */ true); 320 } 321 322 void lto_codegen_dispose(lto_code_gen_t cg) { delete unwrap(cg); } 323 324 bool lto_codegen_add_module(lto_code_gen_t cg, lto_module_t mod) { 325 return !unwrap(cg)->addModule(unwrap(mod)); 326 } 327 328 void lto_codegen_set_module(lto_code_gen_t cg, lto_module_t mod) { 329 unwrap(cg)->setModule(std::unique_ptr<LTOModule>(unwrap(mod))); 330 } 331 332 bool lto_codegen_set_debug_model(lto_code_gen_t cg, lto_debug_model debug) { 333 unwrap(cg)->setDebugInfo(debug); 334 return false; 335 } 336 337 bool lto_codegen_set_pic_model(lto_code_gen_t cg, lto_codegen_model model) { 338 switch (model) { 339 case LTO_CODEGEN_PIC_MODEL_STATIC: 340 unwrap(cg)->setCodePICModel(Reloc::Static); 341 return false; 342 case LTO_CODEGEN_PIC_MODEL_DYNAMIC: 343 unwrap(cg)->setCodePICModel(Reloc::PIC_); 344 return false; 345 case LTO_CODEGEN_PIC_MODEL_DYNAMIC_NO_PIC: 346 unwrap(cg)->setCodePICModel(Reloc::DynamicNoPIC); 347 return false; 348 case LTO_CODEGEN_PIC_MODEL_DEFAULT: 349 unwrap(cg)->setCodePICModel(Reloc::Default); 350 return false; 351 } 352 sLastErrorString = "Unknown PIC model"; 353 return true; 354 } 355 356 void lto_codegen_set_cpu(lto_code_gen_t cg, const char *cpu) { 357 return unwrap(cg)->setCpu(cpu); 358 } 359 360 void lto_codegen_set_assembler_path(lto_code_gen_t cg, const char *path) { 361 // In here only for backwards compatibility. We use MC now. 362 } 363 364 void lto_codegen_set_assembler_args(lto_code_gen_t cg, const char **args, 365 int nargs) { 366 // In here only for backwards compatibility. We use MC now. 367 } 368 369 void lto_codegen_add_must_preserve_symbol(lto_code_gen_t cg, 370 const char *symbol) { 371 unwrap(cg)->addMustPreserveSymbol(symbol); 372 } 373 374 static void maybeParseOptions(lto_code_gen_t cg) { 375 if (!parsedOptions) { 376 unwrap(cg)->parseCodeGenDebugOptions(); 377 lto_add_attrs(cg); 378 parsedOptions = true; 379 } 380 } 381 382 bool lto_codegen_write_merged_modules(lto_code_gen_t cg, const char *path) { 383 maybeParseOptions(cg); 384 return !unwrap(cg)->writeMergedModules(path); 385 } 386 387 const void *lto_codegen_compile(lto_code_gen_t cg, size_t *length) { 388 maybeParseOptions(cg); 389 LibLTOCodeGenerator *CG = unwrap(cg); 390 CG->NativeObjectFile = 391 CG->compile(DisableVerify, DisableInline, DisableGVNLoadPRE, 392 DisableLTOVectorization); 393 if (!CG->NativeObjectFile) 394 return nullptr; 395 *length = CG->NativeObjectFile->getBufferSize(); 396 return CG->NativeObjectFile->getBufferStart(); 397 } 398 399 bool lto_codegen_optimize(lto_code_gen_t cg) { 400 maybeParseOptions(cg); 401 return !unwrap(cg)->optimize(DisableVerify, DisableInline, DisableGVNLoadPRE, 402 DisableLTOVectorization); 403 } 404 405 const void *lto_codegen_compile_optimized(lto_code_gen_t cg, size_t *length) { 406 maybeParseOptions(cg); 407 LibLTOCodeGenerator *CG = unwrap(cg); 408 CG->NativeObjectFile = CG->compileOptimized(); 409 if (!CG->NativeObjectFile) 410 return nullptr; 411 *length = CG->NativeObjectFile->getBufferSize(); 412 return CG->NativeObjectFile->getBufferStart(); 413 } 414 415 bool lto_codegen_compile_to_file(lto_code_gen_t cg, const char **name) { 416 maybeParseOptions(cg); 417 return !unwrap(cg)->compile_to_file( 418 name, DisableVerify, DisableInline, DisableGVNLoadPRE, 419 DisableLTOVectorization); 420 } 421 422 void lto_codegen_debug_options(lto_code_gen_t cg, const char *opt) { 423 unwrap(cg)->setCodeGenDebugOptions(opt); 424 } 425 426 unsigned int lto_api_version() { return LTO_API_VERSION; } 427 428 void lto_codegen_set_should_internalize(lto_code_gen_t cg, 429 bool ShouldInternalize) { 430 unwrap(cg)->setShouldInternalize(ShouldInternalize); 431 } 432 433 void lto_codegen_set_should_embed_uselists(lto_code_gen_t cg, 434 lto_bool_t ShouldEmbedUselists) { 435 unwrap(cg)->setShouldEmbedUselists(ShouldEmbedUselists); 436 } 437