diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2020-02-18 21:59:43 -0500 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2020-02-18 21:59:43 -0500 |
| commit | d7968c6d33b054a8293edd89ce248f385e108469 (patch) | |
| tree | 6f8120d2bb3187a90ba5e855c87332386141bf63 /src/codegen.cpp | |
| parent | dba12cd693495009ae624393337a04e80b0ea565 (diff) | |
| download | zig-d7968c6d33b054a8293edd89ce248f385e108469.tar.gz zig-d7968c6d33b054a8293edd89ce248f385e108469.zip | |
improvements which allow zig to emit multiple things at once
example: zig build-obj test.zig -femit-llvm-ir -femit-asm
this will generate all three: test.o test.s test.ll
Diffstat (limited to 'src/codegen.cpp')
| -rw-r--r-- | src/codegen.cpp | 100 |
1 files changed, 49 insertions, 51 deletions
diff --git a/src/codegen.cpp b/src/codegen.cpp index 84753e1053..a28d2d469d 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -7915,54 +7915,48 @@ static void do_code_gen(CodeGen *g) { } } -void codegen_set_emit_asm(CodeGen *g, bool emit) { - g->emit_asm = emit; -} - -void codegen_set_emit_llvm_ir(CodeGen *g, bool emit) { - g->emit_llvm_ir = emit; -} - static void zig_llvm_emit_output(CodeGen *g) { g->pass1_arena->destruct(&heap::c_allocator); g->pass1_arena = nullptr; bool is_small = g->build_mode == BuildModeSmallRelease; - Buf *output_path = &g->o_file_output_path; char *err_msg = nullptr; - if (!g->disable_bin_generation) { - if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, buf_ptr(output_path), - ZigLLVM_EmitBinary, &err_msg, g->build_mode == BuildModeDebug, is_small, - g->enable_time_report)) - { - zig_panic("unable to write object file %s: %s", buf_ptr(output_path), err_msg); - } - validate_inline_fns(g); - g->link_objects.append(output_path); - if (g->bundle_compiler_rt && (g->out_type == OutTypeObj || - (g->out_type == OutTypeLib && !g->is_dynamic))) + const char *asm_filename = nullptr; + const char *bin_filename = nullptr; + const char *llvm_ir_filename = nullptr; + + if (g->emit_bin) bin_filename = buf_ptr(&g->o_file_output_path); + if (g->emit_asm) asm_filename = buf_ptr(&g->asm_file_output_path); + if (g->emit_llvm_ir) llvm_ir_filename = buf_ptr(&g->llvm_ir_file_output_path); + + // Unfortunately, LLVM shits the bed when we ask for both binary and assembly. So we call the entire + // pipeline multiple times if this is requested. + if (asm_filename != nullptr && bin_filename != nullptr) { + if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, &err_msg, g->build_mode == BuildModeDebug, + is_small, g->enable_time_report, nullptr, bin_filename, llvm_ir_filename)) { - zig_link_add_compiler_rt(g, g->sub_progress_node); + fprintf(stderr, "LLVM failed to emit file: %s\n", err_msg); + exit(1); } + bin_filename = nullptr; + llvm_ir_filename = nullptr; } - if (g->emit_asm) { - if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, buf_ptr(output_path), - ZigLLVM_EmitAssembly, &err_msg, g->build_mode == BuildModeDebug, is_small, - g->enable_time_report)) - { - zig_panic("unable to write assembly file %s: %s", buf_ptr(output_path), err_msg); - } - validate_inline_fns(g); + + if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, &err_msg, g->build_mode == BuildModeDebug, + is_small, g->enable_time_report, asm_filename, bin_filename, llvm_ir_filename)) + { + fprintf(stderr, "LLVM failed to emit file: %s\n", err_msg); + exit(1); } - if (g->emit_llvm_ir) { - if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, buf_ptr(output_path), - ZigLLVM_EmitLLVMIr, &err_msg, g->build_mode == BuildModeDebug, is_small, - g->enable_time_report)) - { - zig_panic("unable to write llvm-ir file %s: %s", buf_ptr(output_path), err_msg); + + validate_inline_fns(g); + + if (g->emit_bin) { + g->link_objects.append(&g->o_file_output_path); + if (g->bundle_compiler_rt && (g->out_type == OutTypeObj || (g->out_type == OutTypeLib && !g->is_dynamic))) { + zig_link_add_compiler_rt(g, g->sub_progress_node); } - validate_inline_fns(g); } LLVMDisposeModule(g->module); @@ -10446,7 +10440,9 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) { cache_bool(ch, g->function_sections); cache_bool(ch, g->enable_dump_analysis); cache_bool(ch, g->enable_doc_generation); - cache_bool(ch, g->disable_bin_generation); + cache_bool(ch, g->emit_bin); + cache_bool(ch, g->emit_llvm_ir); + cache_bool(ch, g->emit_asm); cache_buf_opt(ch, g->mmacosx_version_min); cache_buf_opt(ch, g->mios_version_min); cache_usize(ch, g->version_major); @@ -10491,15 +10487,15 @@ static void resolve_out_paths(CodeGen *g) { assert(g->output_dir != nullptr); assert(g->root_out_name != nullptr); - Buf *out_basename = buf_create_from_buf(g->root_out_name); - Buf *o_basename = buf_create_from_buf(g->root_out_name); - if (!g->disable_bin_generation) { + if (g->emit_bin) { + Buf *out_basename = buf_create_from_buf(g->root_out_name); + Buf *o_basename = buf_create_from_buf(g->root_out_name); switch (g->out_type) { case OutTypeUnknown: zig_unreachable(); case OutTypeObj: if (g->enable_cache && g->link_objects.length == 1 && !need_llvm_module(g)) { - buf_init_from_buf(&g->output_file_path, g->link_objects.at(0)); + buf_init_from_buf(&g->bin_file_output_path, g->link_objects.at(0)); return; } if (need_llvm_module(g) && g->link_objects.length != 0 && !g->enable_cache && @@ -10524,20 +10520,21 @@ static void resolve_out_paths(CodeGen *g) { g->version_major, g->version_minor, g->version_patch)); break; } + os_path_join(g->output_dir, o_basename, &g->o_file_output_path); + os_path_join(g->output_dir, out_basename, &g->bin_file_output_path); } - else if (g->emit_asm) { + if (g->emit_asm) { + Buf *asm_basename = buf_create_from_buf(g->root_out_name); const char *asm_ext = target_asm_file_ext(g->zig_target); - buf_append_str(o_basename, asm_ext); - buf_append_str(out_basename, asm_ext); + buf_append_str(asm_basename, asm_ext); + os_path_join(g->output_dir, asm_basename, &g->asm_file_output_path); } - else if (g->emit_llvm_ir) { + if (g->emit_llvm_ir) { + Buf *llvm_ir_basename = buf_create_from_buf(g->root_out_name); const char *llvm_ir_ext = target_llvm_ir_file_ext(g->zig_target); - buf_append_str(o_basename, llvm_ir_ext); - buf_append_str(out_basename, llvm_ir_ext); + buf_append_str(llvm_ir_basename, llvm_ir_ext); + os_path_join(g->output_dir, llvm_ir_basename, &g->llvm_ir_file_output_path); } - - os_path_join(g->output_dir, o_basename, &g->o_file_output_path); - os_path_join(g->output_dir, out_basename, &g->output_file_path); } void codegen_build_and_link(CodeGen *g) { @@ -10699,7 +10696,7 @@ void codegen_build_and_link(CodeGen *g) { // If there is more than one object, we have to link them (with -r). // Finally, if we didn't make an object from zig source, and we don't have caching enabled, // then we have an object from C source that we must copy to the output dir which we do with a -r link. - if (!g->disable_bin_generation && + if (g->emit_bin && (g->out_type != OutTypeObj || g->link_objects.length > 1 || (!need_llvm_module(g) && !g->enable_cache))) { @@ -10777,6 +10774,7 @@ CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget Stage2LibCInstallation *libc, Buf *cache_dir, bool is_test_build, Stage2ProgressNode *progress_node) { CodeGen *g = heap::c_allocator.create<CodeGen>(); + g->emit_bin = true; g->pass1_arena = heap::ArenaAllocator::construct(&heap::c_allocator, &heap::c_allocator, "pass1"); g->main_progress_node = progress_node; |
