aboutsummaryrefslogtreecommitdiff
path: root/src/codegen.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/codegen.cpp')
-rw-r--r--src/codegen.cpp100
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;