#include #include #include #include #include #include #include #include #include Target create_native_target() { DEBUG("creating native target..."); Target target; target.name.str = "tmp"; target.name.allocation = NONE; target.triple.str = LLVMGetDefaultTargetTriple(); target.triple.allocation = LLVM; assert(target.triple.str != NULL); target.cpu.str = LLVMGetHostCPUName(); target.cpu.allocation = LLVM; assert(target.cpu.str != NULL); target.features.str = LLVMGetHostCPUFeatures(); target.features.allocation = LLVM; assert(target.features.str != NULL); target.opt = LLVMCodeGenLevelNone; target.reloc = LLVMRelocDefault; target.model = LLVMCodeModelDefault; return target; } LLVMCodeGenOptLevel llvm_opt_from_int(int level) { switch (level) { case 1: return LLVMCodeGenLevelLess; case 2: return LLVMCodeGenLevelDefault; case 3: return LLVMCodeGenLevelAggressive; default: break; } PANIC("invalid code generation optimization level: %d", level); } static char* create_target_output_name(const TargetConfig* config) { char* prefix = ""; if (config->mode == Library) { prefix = "lib"; } char* name = g_strjoin("", prefix, config->name, NULL); char* cached_name = mem_strdup(MemoryNamespaceLlvm, name); g_free(name); return cached_name; } Target create_target_from_config(const TargetConfig* config) { DEBUG("Building target from configuration"); Target target = create_native_target(); target.name.str = create_target_output_name(config); target.name.allocation = NONE; // freed later by compiler target.opt = llvm_opt_from_int(config->optimization_level); INFO("Configured target: %s/%d: (%s) on %s { %s }", target.name.str, target.opt, target.triple.str, target.cpu.str, target.features.str); return target; } static void delete_string(String string) { DEBUG("deleting string..."); switch (string.allocation) { case LLVM: LLVMDisposeMessage(string.str); break; case LIBC: free(string.str); break; case NONE: break; } } void delete_target(Target target) { delete_string(target.name); delete_string(target.cpu); delete_string(target.features); delete_string(target.triple); } typedef enum LLVMBackendError_t { UnresolvedImport } LLVMBackendError; static BackendError llvm_backend_codegen(const Module* unit, const TargetConfig* target) { return parse_module(unit, target); } static BackendError llvm_backend_codegen_init(void) { return new_backend_error(Success); } static BackendError llvm_backend_codegen_deinit(void) { return new_backend_error(Success); } void llvm_backend_init() { BackendError err = set_backend(&llvm_backend_codegen_init, &llvm_backend_codegen_deinit, &llvm_backend_codegen, "LLVM"); if (err.kind != Success) { PANIC("unable to init llvm backend: %ld", err); } }