lto.cpp revision dce4a407a24b04eebc6a376f8e62b41aaa7b071f
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-c/Core.h" 17#include "llvm-c/Target.h" 18#include "llvm/CodeGen/CommandFlags.h" 19#include "llvm/LTO/LTOCodeGenerator.h" 20#include "llvm/LTO/LTOModule.h" 21 22// extra command-line flags needed for LTOCodeGenerator 23static cl::opt<bool> 24DisableOpt("disable-opt", cl::init(false), 25 cl::desc("Do not run any optimization passes")); 26 27static cl::opt<bool> 28DisableInline("disable-inlining", cl::init(false), 29 cl::desc("Do not run the inliner pass")); 30 31static cl::opt<bool> 32DisableGVNLoadPRE("disable-gvn-loadpre", cl::init(false), 33 cl::desc("Do not run the GVN load PRE pass")); 34 35// Holds most recent error string. 36// *** Not thread safe *** 37static std::string sLastErrorString; 38 39// Holds the initialization state of the LTO module. 40// *** Not thread safe *** 41static bool initialized = false; 42 43// Holds the command-line option parsing state of the LTO module. 44static bool parsedOptions = false; 45 46// Initialize the configured targets if they have not been initialized. 47static void lto_initialize() { 48 if (!initialized) { 49 LLVMInitializeAllTargetInfos(); 50 LLVMInitializeAllTargets(); 51 LLVMInitializeAllTargetMCs(); 52 LLVMInitializeAllAsmParsers(); 53 LLVMInitializeAllAsmPrinters(); 54 LLVMInitializeAllDisassemblers(); 55 initialized = true; 56 } 57} 58 59DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LTOCodeGenerator, lto_code_gen_t) 60DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LTOModule, lto_module_t) 61 62// Convert the subtarget features into a string to pass to LTOCodeGenerator. 63static void lto_add_attrs(lto_code_gen_t cg) { 64 LTOCodeGenerator *CG = unwrap(cg); 65 if (MAttrs.size()) { 66 std::string attrs; 67 for (unsigned i = 0; i < MAttrs.size(); ++i) { 68 if (i > 0) 69 attrs.append(","); 70 attrs.append(MAttrs[i]); 71 } 72 73 CG->setAttr(attrs.c_str()); 74 } 75} 76 77extern const char* lto_get_version() { 78 return LTOCodeGenerator::getVersionString(); 79} 80 81const char* lto_get_error_message() { 82 return sLastErrorString.c_str(); 83} 84 85bool lto_module_is_object_file(const char* path) { 86 return LTOModule::isBitcodeFile(path); 87} 88 89bool lto_module_is_object_file_for_target(const char* path, 90 const char* target_triplet_prefix) { 91 return LTOModule::isBitcodeFileForTarget(path, target_triplet_prefix); 92} 93 94bool lto_module_is_object_file_in_memory(const void* mem, size_t length) { 95 return LTOModule::isBitcodeFile(mem, length); 96} 97 98bool 99lto_module_is_object_file_in_memory_for_target(const void* mem, 100 size_t length, 101 const char* target_triplet_prefix) { 102 return LTOModule::isBitcodeFileForTarget(mem, length, target_triplet_prefix); 103} 104 105lto_module_t lto_module_create(const char* path) { 106 lto_initialize(); 107 llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags(); 108 return wrap(LTOModule::makeLTOModule(path, Options, sLastErrorString)); 109} 110 111lto_module_t lto_module_create_from_fd(int fd, const char *path, size_t size) { 112 lto_initialize(); 113 llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags(); 114 return wrap( 115 LTOModule::makeLTOModule(fd, path, size, Options, sLastErrorString)); 116} 117 118lto_module_t lto_module_create_from_fd_at_offset(int fd, const char *path, 119 size_t file_size, 120 size_t map_size, 121 off_t offset) { 122 lto_initialize(); 123 llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags(); 124 return wrap(LTOModule::makeLTOModule(fd, path, map_size, offset, Options, 125 sLastErrorString)); 126} 127 128lto_module_t lto_module_create_from_memory(const void* mem, size_t length) { 129 lto_initialize(); 130 llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags(); 131 return wrap(LTOModule::makeLTOModule(mem, length, Options, sLastErrorString)); 132} 133 134lto_module_t lto_module_create_from_memory_with_path(const void* mem, 135 size_t length, 136 const char *path) { 137 lto_initialize(); 138 llvm::TargetOptions Options = InitTargetOptionsFromCodeGenFlags(); 139 return wrap( 140 LTOModule::makeLTOModule(mem, length, Options, sLastErrorString, path)); 141} 142 143void lto_module_dispose(lto_module_t mod) { delete unwrap(mod); } 144 145const char* lto_module_get_target_triple(lto_module_t mod) { 146 return unwrap(mod)->getTargetTriple(); 147} 148 149void lto_module_set_target_triple(lto_module_t mod, const char *triple) { 150 return unwrap(mod)->setTargetTriple(triple); 151} 152 153unsigned int lto_module_get_num_symbols(lto_module_t mod) { 154 return unwrap(mod)->getSymbolCount(); 155} 156 157const char* lto_module_get_symbol_name(lto_module_t mod, unsigned int index) { 158 return unwrap(mod)->getSymbolName(index); 159} 160 161lto_symbol_attributes lto_module_get_symbol_attribute(lto_module_t mod, 162 unsigned int index) { 163 return unwrap(mod)->getSymbolAttributes(index); 164} 165 166unsigned int lto_module_get_num_deplibs(lto_module_t mod) { 167 return unwrap(mod)->getDependentLibraryCount(); 168} 169 170const char* lto_module_get_deplib(lto_module_t mod, unsigned int index) { 171 return unwrap(mod)->getDependentLibrary(index); 172} 173 174unsigned int lto_module_get_num_linkeropts(lto_module_t mod) { 175 return unwrap(mod)->getLinkerOptCount(); 176} 177 178const char* lto_module_get_linkeropt(lto_module_t mod, unsigned int index) { 179 return unwrap(mod)->getLinkerOpt(index); 180} 181 182void lto_codegen_set_diagnostic_handler(lto_code_gen_t cg, 183 lto_diagnostic_handler_t diag_handler, 184 void *ctxt) { 185 unwrap(cg)->setDiagnosticHandler(diag_handler, ctxt); 186} 187 188lto_code_gen_t lto_codegen_create(void) { 189 lto_initialize(); 190 191 TargetOptions Options = InitTargetOptionsFromCodeGenFlags(); 192 193 LTOCodeGenerator *CodeGen = new LTOCodeGenerator(); 194 if (CodeGen) 195 CodeGen->setTargetOptions(Options); 196 return wrap(CodeGen); 197} 198 199void lto_codegen_dispose(lto_code_gen_t cg) { delete unwrap(cg); } 200 201bool lto_codegen_add_module(lto_code_gen_t cg, lto_module_t mod) { 202 return !unwrap(cg)->addModule(unwrap(mod), sLastErrorString); 203} 204 205bool lto_codegen_set_debug_model(lto_code_gen_t cg, lto_debug_model debug) { 206 unwrap(cg)->setDebugInfo(debug); 207 return false; 208} 209 210bool lto_codegen_set_pic_model(lto_code_gen_t cg, lto_codegen_model model) { 211 unwrap(cg)->setCodePICModel(model); 212 return false; 213} 214 215void lto_codegen_set_cpu(lto_code_gen_t cg, const char *cpu) { 216 return unwrap(cg)->setCpu(cpu); 217} 218 219void lto_codegen_set_attr(lto_code_gen_t cg, const char *attr) { 220 return unwrap(cg)->setAttr(attr); 221} 222 223void lto_codegen_set_assembler_path(lto_code_gen_t cg, const char *path) { 224 // In here only for backwards compatibility. We use MC now. 225} 226 227void lto_codegen_set_assembler_args(lto_code_gen_t cg, const char **args, 228 int nargs) { 229 // In here only for backwards compatibility. We use MC now. 230} 231 232void lto_codegen_add_must_preserve_symbol(lto_code_gen_t cg, 233 const char *symbol) { 234 unwrap(cg)->addMustPreserveSymbol(symbol); 235} 236 237bool lto_codegen_write_merged_modules(lto_code_gen_t cg, const char *path) { 238 if (!parsedOptions) { 239 unwrap(cg)->parseCodeGenDebugOptions(); 240 lto_add_attrs(cg); 241 parsedOptions = true; 242 } 243 return !unwrap(cg)->writeMergedModules(path, sLastErrorString); 244} 245 246const void *lto_codegen_compile(lto_code_gen_t cg, size_t *length) { 247 if (!parsedOptions) { 248 unwrap(cg)->parseCodeGenDebugOptions(); 249 lto_add_attrs(cg); 250 parsedOptions = true; 251 } 252 return unwrap(cg)->compile(length, DisableOpt, DisableInline, 253 DisableGVNLoadPRE, sLastErrorString); 254} 255 256bool lto_codegen_compile_to_file(lto_code_gen_t cg, const char **name) { 257 if (!parsedOptions) { 258 unwrap(cg)->parseCodeGenDebugOptions(); 259 lto_add_attrs(cg); 260 parsedOptions = true; 261 } 262 return !unwrap(cg)->compile_to_file(name, DisableOpt, DisableInline, 263 DisableGVNLoadPRE, sLastErrorString); 264} 265 266void lto_codegen_debug_options(lto_code_gen_t cg, const char *opt) { 267 unwrap(cg)->setCodeGenDebugOptions(opt); 268} 269