authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-02-18 21:59:43-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-02-18 21:59:43-05:00
logd7968c6d33b054a8293edd89ce248f385e108469
tree6f8120d2bb3187a90ba5e855c87332386141bf63
parentdba12cd693495009ae624393337a04e80b0ea565
signature Commit is signed but in an unrecognized format.

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

8 files changed, 173 insertions(+), 170 deletions(-)

lib/std/build.zig+6-9
...@@ -1155,9 +1155,9 @@ pub const LibExeObjStep = struct {...@@ -1155,9 +1155,9 @@ pub const LibExeObjStep = struct {
1155 frameworks: BufSet,1155 frameworks: BufSet,
1156 verbose_link: bool,1156 verbose_link: bool,
1157 verbose_cc: bool,1157 verbose_cc: bool,
1158 emit_ir: bool,1158 emit_llvm_ir: bool = false,
1159 emit_asm: bool,1159 emit_asm: bool = false,
1160 emit_bin: bool,1160 emit_bin: bool = true,
1161 disable_gen_h: bool,1161 disable_gen_h: bool,
1162 bundle_compiler_rt: bool,1162 bundle_compiler_rt: bool,
1163 disable_stack_probing: bool,1163 disable_stack_probing: bool,
...@@ -1288,9 +1288,6 @@ pub const LibExeObjStep = struct {...@@ -1288,9 +1288,6 @@ pub const LibExeObjStep = struct {
1288 .builder = builder,1288 .builder = builder,
1289 .verbose_link = false,1289 .verbose_link = false,
1290 .verbose_cc = false,1290 .verbose_cc = false,
1291 .emit_ir = false,
1292 .emit_asm = false,
1293 .emit_bin = true,
1294 .build_mode = builtin.Mode.Debug,1291 .build_mode = builtin.Mode.Debug,
1295 .is_dynamic = is_dynamic,1292 .is_dynamic = is_dynamic,
1296 .kind = kind,1293 .kind = kind,
...@@ -1947,9 +1944,9 @@ pub const LibExeObjStep = struct {...@@ -1947,9 +1944,9 @@ pub const LibExeObjStep = struct {
1947 if (builder.verbose_link or self.verbose_link) zig_args.append("--verbose-link") catch unreachable;1944 if (builder.verbose_link or self.verbose_link) zig_args.append("--verbose-link") catch unreachable;
1948 if (builder.verbose_cc or self.verbose_cc) zig_args.append("--verbose-cc") catch unreachable;1945 if (builder.verbose_cc or self.verbose_cc) zig_args.append("--verbose-cc") catch unreachable;
19491946
1950 try zig_args.append(if (self.emit_ir) "-femit-llvm-ir" else "-fno-emit-llvm-ir");1947 if (self.emit_llvm_ir) try zig_args.append("-femit-llvm-ir");
1951 try zig_args.append(if (self.emit_asm) "-femit-asm" else "-fno-emit-asm");1948 if (self.emit_asm) try zig_args.append("-femit-asm");
1952 try zig_args.append(if (self.emit_bin) "-femit-bin" else "-fno-emit-bin");1949 if (!self.emit_bin) try zig_args.append("-fno-emit-bin");
19531950
1954 if (self.strip) {1951 if (self.strip) {
1955 try zig_args.append("--strip");1952 try zig_args.append("--strip");
src/all_types.hpp+6-4
...@@ -2136,8 +2136,10 @@ struct CodeGen {...@@ -2136,8 +2136,10 @@ struct CodeGen {
21362136
2137 Buf llvm_triple_str;2137 Buf llvm_triple_str;
2138 Buf global_asm;2138 Buf global_asm;
2139 Buf output_file_path;
2140 Buf o_file_output_path;2139 Buf o_file_output_path;
2140 Buf bin_file_output_path;
2141 Buf asm_file_output_path;
2142 Buf llvm_ir_file_output_path;
2141 Buf *cache_dir;2143 Buf *cache_dir;
2142 // As an input parameter, mutually exclusive with enable_cache. But it gets2144 // As an input parameter, mutually exclusive with enable_cache. But it gets
2143 // populated in codegen_build_and_link.2145 // populated in codegen_build_and_link.
...@@ -2198,8 +2200,6 @@ struct CodeGen {...@@ -2198,8 +2200,6 @@ struct CodeGen {
2198 bool verbose_cimport;2200 bool verbose_cimport;
2199 bool verbose_cc;2201 bool verbose_cc;
2200 bool verbose_llvm_cpu_features;2202 bool verbose_llvm_cpu_features;
2201 bool emit_asm;
2202 bool emit_llvm_ir;
2203 bool error_during_imports;2203 bool error_during_imports;
2204 bool generate_error_name_table;2204 bool generate_error_name_table;
2205 bool enable_cache; // mutually exclusive with output_dir2205 bool enable_cache; // mutually exclusive with output_dir
...@@ -2253,7 +2253,9 @@ struct CodeGen {...@@ -2253,7 +2253,9 @@ struct CodeGen {
2253 bool function_sections;2253 bool function_sections;
2254 bool enable_dump_analysis;2254 bool enable_dump_analysis;
2255 bool enable_doc_generation;2255 bool enable_doc_generation;
2256 bool disable_bin_generation;2256 bool emit_bin;
2257 bool emit_asm;
2258 bool emit_llvm_ir;
2257 bool test_is_evented;2259 bool test_is_evented;
2258 CodeModel code_model;2260 CodeModel code_model;
22592261
src/codegen.cpp+49-51
...@@ -7915,54 +7915,48 @@ static void do_code_gen(CodeGen *g) {...@@ -7915,54 +7915,48 @@ static void do_code_gen(CodeGen *g) {
7915 }7915 }
7916}7916}
79177917
7918void codegen_set_emit_asm(CodeGen *g, bool emit) {
7919 g->emit_asm = emit;
7920}
7921
7922void codegen_set_emit_llvm_ir(CodeGen *g, bool emit) {
7923 g->emit_llvm_ir = emit;
7924}
7925
7926static void zig_llvm_emit_output(CodeGen *g) {7918static void zig_llvm_emit_output(CodeGen *g) {
7927 g->pass1_arena->destruct(&heap::c_allocator);7919 g->pass1_arena->destruct(&heap::c_allocator);
7928 g->pass1_arena = nullptr;7920 g->pass1_arena = nullptr;
79297921
7930 bool is_small = g->build_mode == BuildModeSmallRelease;7922 bool is_small = g->build_mode == BuildModeSmallRelease;
79317923
7932 Buf *output_path = &g->o_file_output_path;
7933 char *err_msg = nullptr;7924 char *err_msg = nullptr;
7934 if (!g->disable_bin_generation) {7925 const char *asm_filename = nullptr;
7935 if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, buf_ptr(output_path),7926 const char *bin_filename = nullptr;
7936 ZigLLVM_EmitBinary, &err_msg, g->build_mode == BuildModeDebug, is_small,7927 const char *llvm_ir_filename = nullptr;
7937 g->enable_time_report))7928
7938 {7929 if (g->emit_bin) bin_filename = buf_ptr(&g->o_file_output_path);
7939 zig_panic("unable to write object file %s: %s", buf_ptr(output_path), err_msg);7930 if (g->emit_asm) asm_filename = buf_ptr(&g->asm_file_output_path);
7940 }7931 if (g->emit_llvm_ir) llvm_ir_filename = buf_ptr(&g->llvm_ir_file_output_path);
7941 validate_inline_fns(g);7932
7942 g->link_objects.append(output_path);7933 // Unfortunately, LLVM shits the bed when we ask for both binary and assembly. So we call the entire
7943 if (g->bundle_compiler_rt && (g->out_type == OutTypeObj ||7934 // pipeline multiple times if this is requested.
7944 (g->out_type == OutTypeLib && !g->is_dynamic)))7935 if (asm_filename != nullptr && bin_filename != nullptr) {
7936 if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, &err_msg, g->build_mode == BuildModeDebug,
7937 is_small, g->enable_time_report, nullptr, bin_filename, llvm_ir_filename))
7945 {7938 {
7946 zig_link_add_compiler_rt(g, g->sub_progress_node);7939 fprintf(stderr, "LLVM failed to emit file: %s\n", err_msg);
7940 exit(1);
7947 }7941 }
7942 bin_filename = nullptr;
7943 llvm_ir_filename = nullptr;
7948 }7944 }
7949 if (g->emit_asm) {7945
7950 if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, buf_ptr(output_path),7946 if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, &err_msg, g->build_mode == BuildModeDebug,
7951 ZigLLVM_EmitAssembly, &err_msg, g->build_mode == BuildModeDebug, is_small,7947 is_small, g->enable_time_report, asm_filename, bin_filename, llvm_ir_filename))
7952 g->enable_time_report))7948 {
7953 {7949 fprintf(stderr, "LLVM failed to emit file: %s\n", err_msg);
7954 zig_panic("unable to write assembly file %s: %s", buf_ptr(output_path), err_msg);7950 exit(1);
7955 }
7956 validate_inline_fns(g);
7957 }7951 }
7958 if (g->emit_llvm_ir) {7952
7959 if (ZigLLVMTargetMachineEmitToFile(g->target_machine, g->module, buf_ptr(output_path),7953 validate_inline_fns(g);
7960 ZigLLVM_EmitLLVMIr, &err_msg, g->build_mode == BuildModeDebug, is_small,7954
7961 g->enable_time_report))7955 if (g->emit_bin) {
7962 {7956 g->link_objects.append(&g->o_file_output_path);
7963 zig_panic("unable to write llvm-ir file %s: %s", buf_ptr(output_path), err_msg);7957 if (g->bundle_compiler_rt && (g->out_type == OutTypeObj || (g->out_type == OutTypeLib && !g->is_dynamic))) {
7958 zig_link_add_compiler_rt(g, g->sub_progress_node);
7964 }7959 }
7965 validate_inline_fns(g);
7966 }7960 }
79677961
7968 LLVMDisposeModule(g->module);7962 LLVMDisposeModule(g->module);
...@@ -10446,7 +10440,9 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {...@@ -10446,7 +10440,9 @@ static Error check_cache(CodeGen *g, Buf *manifest_dir, Buf *digest) {
10446 cache_bool(ch, g->function_sections);10440 cache_bool(ch, g->function_sections);
10447 cache_bool(ch, g->enable_dump_analysis);10441 cache_bool(ch, g->enable_dump_analysis);
10448 cache_bool(ch, g->enable_doc_generation);10442 cache_bool(ch, g->enable_doc_generation);
10449 cache_bool(ch, g->disable_bin_generation);10443 cache_bool(ch, g->emit_bin);
10444 cache_bool(ch, g->emit_llvm_ir);
10445 cache_bool(ch, g->emit_asm);
10450 cache_buf_opt(ch, g->mmacosx_version_min);10446 cache_buf_opt(ch, g->mmacosx_version_min);
10451 cache_buf_opt(ch, g->mios_version_min);10447 cache_buf_opt(ch, g->mios_version_min);
10452 cache_usize(ch, g->version_major);10448 cache_usize(ch, g->version_major);
...@@ -10491,15 +10487,15 @@ static void resolve_out_paths(CodeGen *g) {...@@ -10491,15 +10487,15 @@ static void resolve_out_paths(CodeGen *g) {
10491 assert(g->output_dir != nullptr);10487 assert(g->output_dir != nullptr);
10492 assert(g->root_out_name != nullptr);10488 assert(g->root_out_name != nullptr);
1049310489
10494 Buf *out_basename = buf_create_from_buf(g->root_out_name);10490 if (g->emit_bin) {
10495 Buf *o_basename = buf_create_from_buf(g->root_out_name);10491 Buf *out_basename = buf_create_from_buf(g->root_out_name);
10496 if (!g->disable_bin_generation) {10492 Buf *o_basename = buf_create_from_buf(g->root_out_name);
10497 switch (g->out_type) {10493 switch (g->out_type) {
10498 case OutTypeUnknown:10494 case OutTypeUnknown:
10499 zig_unreachable();10495 zig_unreachable();
10500 case OutTypeObj:10496 case OutTypeObj:
10501 if (g->enable_cache && g->link_objects.length == 1 && !need_llvm_module(g)) {10497 if (g->enable_cache && g->link_objects.length == 1 && !need_llvm_module(g)) {
10502 buf_init_from_buf(&g->output_file_path, g->link_objects.at(0));10498 buf_init_from_buf(&g->bin_file_output_path, g->link_objects.at(0));
10503 return;10499 return;
10504 }10500 }
10505 if (need_llvm_module(g) && g->link_objects.length != 0 && !g->enable_cache &&10501 if (need_llvm_module(g) && g->link_objects.length != 0 && !g->enable_cache &&
...@@ -10524,20 +10520,21 @@ static void resolve_out_paths(CodeGen *g) {...@@ -10524,20 +10520,21 @@ static void resolve_out_paths(CodeGen *g) {
10524 g->version_major, g->version_minor, g->version_patch));10520 g->version_major, g->version_minor, g->version_patch));
10525 break;10521 break;
10526 }10522 }
10523 os_path_join(g->output_dir, o_basename, &g->o_file_output_path);
10524 os_path_join(g->output_dir, out_basename, &g->bin_file_output_path);
10527 }10525 }
10528 else if (g->emit_asm) {10526 if (g->emit_asm) {
10527 Buf *asm_basename = buf_create_from_buf(g->root_out_name);
10529 const char *asm_ext = target_asm_file_ext(g->zig_target);10528 const char *asm_ext = target_asm_file_ext(g->zig_target);
10530 buf_append_str(o_basename, asm_ext);10529 buf_append_str(asm_basename, asm_ext);
10531 buf_append_str(out_basename, asm_ext);10530 os_path_join(g->output_dir, asm_basename, &g->asm_file_output_path);
10532 }10531 }
10533 else if (g->emit_llvm_ir) {10532 if (g->emit_llvm_ir) {
10533 Buf *llvm_ir_basename = buf_create_from_buf(g->root_out_name);
10534 const char *llvm_ir_ext = target_llvm_ir_file_ext(g->zig_target);10534 const char *llvm_ir_ext = target_llvm_ir_file_ext(g->zig_target);
10535 buf_append_str(o_basename, llvm_ir_ext);10535 buf_append_str(llvm_ir_basename, llvm_ir_ext);
10536 buf_append_str(out_basename, llvm_ir_ext);10536 os_path_join(g->output_dir, llvm_ir_basename, &g->llvm_ir_file_output_path);
10537 }10537 }
10538
10539 os_path_join(g->output_dir, o_basename, &g->o_file_output_path);
10540 os_path_join(g->output_dir, out_basename, &g->output_file_path);
10541}10538}
1054210539
10543void codegen_build_and_link(CodeGen *g) {10540void codegen_build_and_link(CodeGen *g) {
...@@ -10699,7 +10696,7 @@ void codegen_build_and_link(CodeGen *g) {...@@ -10699,7 +10696,7 @@ void codegen_build_and_link(CodeGen *g) {
10699 // If there is more than one object, we have to link them (with -r).10696 // If there is more than one object, we have to link them (with -r).
10700 // Finally, if we didn't make an object from zig source, and we don't have caching enabled,10697 // Finally, if we didn't make an object from zig source, and we don't have caching enabled,
10701 // then we have an object from C source that we must copy to the output dir which we do with a -r link.10698 // then we have an object from C source that we must copy to the output dir which we do with a -r link.
10702 if (!g->disable_bin_generation &&10699 if (g->emit_bin &&
10703 (g->out_type != OutTypeObj || g->link_objects.length > 1 ||10700 (g->out_type != OutTypeObj || g->link_objects.length > 1 ||
10704 (!need_llvm_module(g) && !g->enable_cache)))10701 (!need_llvm_module(g) && !g->enable_cache)))
10705 {10702 {
...@@ -10777,6 +10774,7 @@ CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget...@@ -10777,6 +10774,7 @@ CodeGen *codegen_create(Buf *main_pkg_path, Buf *root_src_path, const ZigTarget
10777 Stage2LibCInstallation *libc, Buf *cache_dir, bool is_test_build, Stage2ProgressNode *progress_node)10774 Stage2LibCInstallation *libc, Buf *cache_dir, bool is_test_build, Stage2ProgressNode *progress_node)
10778{10775{
10779 CodeGen *g = heap::c_allocator.create<CodeGen>();10776 CodeGen *g = heap::c_allocator.create<CodeGen>();
10777 g->emit_bin = true;
10780 g->pass1_arena = heap::ArenaAllocator::construct(&heap::c_allocator, &heap::c_allocator, "pass1");10778 g->pass1_arena = heap::ArenaAllocator::construct(&heap::c_allocator, &heap::c_allocator, "pass1");
10781 g->main_progress_node = progress_node;10779 g->main_progress_node = progress_node;
1078210780
src/codegen.hpp-3
...@@ -26,9 +26,6 @@ void codegen_set_clang_argv(CodeGen *codegen, const char **args, size_t len);...@@ -26,9 +26,6 @@ void codegen_set_clang_argv(CodeGen *codegen, const char **args, size_t len);
26void codegen_set_llvm_argv(CodeGen *codegen, const char **args, size_t len);26void codegen_set_llvm_argv(CodeGen *codegen, const char **args, size_t len);
27void codegen_set_each_lib_rpath(CodeGen *codegen, bool each_lib_rpath);27void codegen_set_each_lib_rpath(CodeGen *codegen, bool each_lib_rpath);
2828
29void codegen_set_emit_asm(CodeGen *codegen, bool emit);
30void codegen_set_emit_llvm_ir(CodeGen *codegen, bool emit);
31
32void codegen_set_strip(CodeGen *codegen, bool strip);29void codegen_set_strip(CodeGen *codegen, bool strip);
33void codegen_set_errmsg_color(CodeGen *codegen, ErrColor err_color);30void codegen_set_errmsg_color(CodeGen *codegen, ErrColor err_color);
34void codegen_set_out_name(CodeGen *codegen, Buf *out_name);31void codegen_set_out_name(CodeGen *codegen, Buf *out_name);
src/link.cpp+19-19
...@@ -605,7 +605,7 @@ static const char *build_libc_object(CodeGen *parent_gen, const char *name, CFil...@@ -605,7 +605,7 @@ static const char *build_libc_object(CodeGen *parent_gen, const char *name, CFil
605 c_source_files.append(c_file);605 c_source_files.append(c_file);
606 child_gen->c_source_files = c_source_files;606 child_gen->c_source_files = c_source_files;
607 codegen_build_and_link(child_gen);607 codegen_build_and_link(child_gen);
608 return buf_ptr(&child_gen->output_file_path);608 return buf_ptr(&child_gen->bin_file_output_path);
609}609}
610610
611static const char *path_from_zig_lib(CodeGen *g, const char *dir, const char *subpath) {611static const char *path_from_zig_lib(CodeGen *g, const char *dir, const char *subpath) {
...@@ -682,7 +682,7 @@ static const char *build_libunwind(CodeGen *parent, Stage2ProgressNode *progress...@@ -682,7 +682,7 @@ static const char *build_libunwind(CodeGen *parent, Stage2ProgressNode *progress
682 }682 }
683 child_gen->c_source_files = c_source_files;683 child_gen->c_source_files = c_source_files;
684 codegen_build_and_link(child_gen);684 codegen_build_and_link(child_gen);
685 return buf_ptr(&child_gen->output_file_path);685 return buf_ptr(&child_gen->bin_file_output_path);
686}686}
687687
688static void mingw_add_cc_args(CodeGen *parent, CFile *c_file) {688static void mingw_add_cc_args(CodeGen *parent, CFile *c_file) {
...@@ -1123,7 +1123,7 @@ static const char *build_musl(CodeGen *parent, Stage2ProgressNode *progress_node...@@ -1123,7 +1123,7 @@ static const char *build_musl(CodeGen *parent, Stage2ProgressNode *progress_node
11231123
1124 child_gen->c_source_files = c_source_files;1124 child_gen->c_source_files = c_source_files;
1125 codegen_build_and_link(child_gen);1125 codegen_build_and_link(child_gen);
1126 return buf_ptr(&child_gen->output_file_path);1126 return buf_ptr(&child_gen->bin_file_output_path);
1127}1127}
11281128
1129static void add_msvcrt_os_dep(CodeGen *parent, CodeGen *child_gen, const char *src_path) {1129static void add_msvcrt_os_dep(CodeGen *parent, CodeGen *child_gen, const char *src_path) {
...@@ -1253,7 +1253,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr...@@ -1253,7 +1253,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr
1253 child_gen->c_source_files.append(c_file);1253 child_gen->c_source_files.append(c_file);
1254 }1254 }
1255 codegen_build_and_link(child_gen);1255 codegen_build_and_link(child_gen);
1256 return buf_ptr(&child_gen->output_file_path);1256 return buf_ptr(&child_gen->bin_file_output_path);
1257 } else if (strcmp(file, "msvcrt-os.lib") == 0) {1257 } else if (strcmp(file, "msvcrt-os.lib") == 0) {
1258 CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr, "msvcrt-os", progress_node);1258 CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr, "msvcrt-os", progress_node);
12591259
...@@ -1270,7 +1270,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr...@@ -1270,7 +1270,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr
1270 }1270 }
1271 }1271 }
1272 codegen_build_and_link(child_gen);1272 codegen_build_and_link(child_gen);
1273 return buf_ptr(&child_gen->output_file_path);1273 return buf_ptr(&child_gen->bin_file_output_path);
1274 } else if (strcmp(file, "mingwex.lib") == 0) {1274 } else if (strcmp(file, "mingwex.lib") == 0) {
1275 CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr, "mingwex", progress_node);1275 CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr, "mingwex", progress_node);
12761276
...@@ -1295,7 +1295,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr...@@ -1295,7 +1295,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr
1295 zig_unreachable();1295 zig_unreachable();
1296 }1296 }
1297 codegen_build_and_link(child_gen);1297 codegen_build_and_link(child_gen);
1298 return buf_ptr(&child_gen->output_file_path);1298 return buf_ptr(&child_gen->bin_file_output_path);
1299 } else {1299 } else {
1300 zig_unreachable();1300 zig_unreachable();
1301 }1301 }
...@@ -1365,7 +1365,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr...@@ -1365,7 +1365,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr
1365 codegen_add_object(child_gen, buf_create_from_str(start_os));1365 codegen_add_object(child_gen, buf_create_from_str(start_os));
1366 codegen_add_object(child_gen, buf_create_from_str(abi_note_o));1366 codegen_add_object(child_gen, buf_create_from_str(abi_note_o));
1367 codegen_build_and_link(child_gen);1367 codegen_build_and_link(child_gen);
1368 return buf_ptr(&child_gen->output_file_path);1368 return buf_ptr(&child_gen->bin_file_output_path);
1369 } else if (strcmp(file, "libc_nonshared.a") == 0) {1369 } else if (strcmp(file, "libc_nonshared.a") == 0) {
1370 CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr, "c_nonshared", progress_node);1370 CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr, "c_nonshared", progress_node);
1371 {1371 {
...@@ -1445,7 +1445,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr...@@ -1445,7 +1445,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file, Stage2Pr
1445 build_libc_object(parent, deps[i].name, c_file, progress_node)));1445 build_libc_object(parent, deps[i].name, c_file, progress_node)));
1446 }1446 }
1447 codegen_build_and_link(child_gen);1447 codegen_build_and_link(child_gen);
1448 return buf_ptr(&child_gen->output_file_path);1448 return buf_ptr(&child_gen->bin_file_output_path);
1449 } else {1449 } else {
1450 zig_unreachable();1450 zig_unreachable();
1451 }1451 }
...@@ -1519,7 +1519,7 @@ static Buf *build_a_raw(CodeGen *parent_gen, const char *aname, Buf *full_path,...@@ -1519,7 +1519,7 @@ static Buf *build_a_raw(CodeGen *parent_gen, const char *aname, Buf *full_path,
1519 child_gen->want_stack_check = WantStackCheckDisabled;1519 child_gen->want_stack_check = WantStackCheckDisabled;
15201520
1521 codegen_build_and_link(child_gen);1521 codegen_build_and_link(child_gen);
1522 return &child_gen->output_file_path;1522 return &child_gen->bin_file_output_path;
1523}1523}
15241524
1525static Buf *build_compiler_rt(CodeGen *parent_gen, OutType child_out_type, Stage2ProgressNode *progress_node) {1525static Buf *build_compiler_rt(CodeGen *parent_gen, OutType child_out_type, Stage2ProgressNode *progress_node) {
...@@ -1681,7 +1681,7 @@ static void construct_linker_job_elf(LinkJob *lj) {...@@ -1681,7 +1681,7 @@ static void construct_linker_job_elf(LinkJob *lj) {
1681 } else if (is_dyn_lib) {1681 } else if (is_dyn_lib) {
1682 lj->args.append("-shared");1682 lj->args.append("-shared");
16831683
1684 assert(buf_len(&g->output_file_path) != 0);1684 assert(buf_len(&g->bin_file_output_path) != 0);
1685 soname = buf_sprintf("lib%s.so.%" ZIG_PRI_usize, buf_ptr(g->root_out_name), g->version_major);1685 soname = buf_sprintf("lib%s.so.%" ZIG_PRI_usize, buf_ptr(g->root_out_name), g->version_major);
1686 }1686 }
16871687
...@@ -1690,7 +1690,7 @@ static void construct_linker_job_elf(LinkJob *lj) {...@@ -1690,7 +1690,7 @@ static void construct_linker_job_elf(LinkJob *lj) {
1690 }1690 }
16911691
1692 lj->args.append("-o");1692 lj->args.append("-o");
1693 lj->args.append(buf_ptr(&g->output_file_path));1693 lj->args.append(buf_ptr(&g->bin_file_output_path));
16941694
1695 if (lj->link_in_crt) {1695 if (lj->link_in_crt) {
1696 const char *crt1o;1696 const char *crt1o;
...@@ -1872,7 +1872,7 @@ static void construct_linker_job_wasm(LinkJob *lj) {...@@ -1872,7 +1872,7 @@ static void construct_linker_job_wasm(LinkJob *lj) {
1872 }1872 }
1873 lj->args.append("--allow-undefined");1873 lj->args.append("--allow-undefined");
1874 lj->args.append("-o");1874 lj->args.append("-o");
1875 lj->args.append(buf_ptr(&g->output_file_path));1875 lj->args.append(buf_ptr(&g->bin_file_output_path));
18761876
1877 // .o files1877 // .o files
1878 for (size_t i = 0; i < g->link_objects.length; i += 1) {1878 for (size_t i = 0; i < g->link_objects.length; i += 1) {
...@@ -2248,7 +2248,7 @@ static void construct_linker_job_coff(LinkJob *lj) {...@@ -2248,7 +2248,7 @@ static void construct_linker_job_coff(LinkJob *lj) {
2248 lj->args.append("-DLL");2248 lj->args.append("-DLL");
2249 }2249 }
22502250
2251 lj->args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(&g->output_file_path))));2251 lj->args.append(buf_ptr(buf_sprintf("-OUT:%s", buf_ptr(&g->bin_file_output_path))));
22522252
2253 if (g->libc_link_lib != nullptr && g->libc != nullptr) {2253 if (g->libc_link_lib != nullptr && g->libc != nullptr) {
2254 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", g->libc->crt_dir)));2254 lj->args.append(buf_ptr(buf_sprintf("-LIBPATH:%s", g->libc->crt_dir)));
...@@ -2501,7 +2501,7 @@ static void construct_linker_job_macho(LinkJob *lj) {...@@ -2501,7 +2501,7 @@ static void construct_linker_job_macho(LinkJob *lj) {
2501 //lj->args.append("-install_name");2501 //lj->args.append("-install_name");
2502 //lj->args.append(buf_ptr(dylib_install_name));2502 //lj->args.append(buf_ptr(dylib_install_name));
25032503
2504 assert(buf_len(&g->output_file_path) != 0);2504 assert(buf_len(&g->bin_file_output_path) != 0);
2505 }2505 }
25062506
2507 lj->args.append("-arch");2507 lj->args.append("-arch");
...@@ -2532,14 +2532,14 @@ static void construct_linker_job_macho(LinkJob *lj) {...@@ -2532,14 +2532,14 @@ static void construct_linker_job_macho(LinkJob *lj) {
2532 }2532 }
25332533
2534 lj->args.append("-o");2534 lj->args.append("-o");
2535 lj->args.append(buf_ptr(&g->output_file_path));2535 lj->args.append(buf_ptr(&g->bin_file_output_path));
25362536
2537 for (size_t i = 0; i < g->rpath_list.length; i += 1) {2537 for (size_t i = 0; i < g->rpath_list.length; i += 1) {
2538 Buf *rpath = g->rpath_list.at(i);2538 Buf *rpath = g->rpath_list.at(i);
2539 add_rpath(lj, rpath);2539 add_rpath(lj, rpath);
2540 }2540 }
2541 if (is_dyn_lib) {2541 if (is_dyn_lib) {
2542 add_rpath(lj, &g->output_file_path);2542 add_rpath(lj, &g->bin_file_output_path);
2543 }2543 }
25442544
2545 if (is_dyn_lib) {2545 if (is_dyn_lib) {
...@@ -2659,14 +2659,14 @@ void codegen_link(CodeGen *g) {...@@ -2659,14 +2659,14 @@ void codegen_link(CodeGen *g) {
2659 progress_name, strlen(progress_name), 0));2659 progress_name, strlen(progress_name), 0));
2660 }2660 }
2661 if (g->verbose_link) {2661 if (g->verbose_link) {
2662 fprintf(stderr, "ar rcs %s", buf_ptr(&g->output_file_path));2662 fprintf(stderr, "ar rcs %s", buf_ptr(&g->bin_file_output_path));
2663 for (size_t i = 0; i < file_names.length; i += 1) {2663 for (size_t i = 0; i < file_names.length; i += 1) {
2664 fprintf(stderr, " %s", file_names.at(i));2664 fprintf(stderr, " %s", file_names.at(i));
2665 }2665 }
2666 fprintf(stderr, "\n");2666 fprintf(stderr, "\n");
2667 }2667 }
2668 if (ZigLLVMWriteArchive(buf_ptr(&g->output_file_path), file_names.items, file_names.length, os_type)) {2668 if (ZigLLVMWriteArchive(buf_ptr(&g->bin_file_output_path), file_names.items, file_names.length, os_type)) {
2669 fprintf(stderr, "Unable to write archive '%s'\n", buf_ptr(&g->output_file_path));2669 fprintf(stderr, "Unable to write archive '%s'\n", buf_ptr(&g->bin_file_output_path));
2670 exit(1);2670 exit(1);
2671 }2671 }
2672 return;2672 return;
src/main.cpp+31-32
...@@ -62,17 +62,21 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {...@@ -62,17 +62,21 @@ static int print_full_usage(const char *arg0, FILE *file, int return_code) {
62 " -fno-stack-check disable stack probing in safe builds\n"62 " -fno-stack-check disable stack probing in safe builds\n"
63 " -fsanitize-c enable C undefined behavior detection in unsafe builds\n"63 " -fsanitize-c enable C undefined behavior detection in unsafe builds\n"
64 " -fno-sanitize-c disable C undefined behavior detection in safe builds\n"64 " -fno-sanitize-c disable C undefined behavior detection in safe builds\n"
65 " --emit [asm|bin|llvm-ir] emit a specific file format as compilation output\n"65 " --emit [asm|bin|llvm-ir] (deprecated) emit a specific file format as compilation output\n"
66 " -fPIC enable Position Independent Code\n"66 " -fPIC enable Position Independent Code\n"
67 " -fno-PIC disable Position Independent Code\n"67 " -fno-PIC disable Position Independent Code\n"
68 " -ftime-report print timing diagnostics\n"68 " -ftime-report print timing diagnostics\n"
69 " -fstack-report print stack size diagnostics\n"69 " -fstack-report print stack size diagnostics\n"
70#ifdef ZIG_ENABLE_MEM_PROFILE
71 " -fmem-report print memory usage diagnostics\n"70 " -fmem-report print memory usage diagnostics\n"
72#endif
73 " -fdump-analysis write analysis.json file with type information\n"71 " -fdump-analysis write analysis.json file with type information\n"
74 " -femit-docs create a docs/ dir with html documentation\n"72 " -femit-docs create a docs/ dir with html documentation\n"
75 " -fno-emit-bin skip emitting machine code\n"73 " -fno-emit-docs do not produce docs/ dir with html documentation\n"
74 " -femit-bin (default) output machine code\n"
75 " -fno-emit-bin do not output machine code\n"
76 " -femit-asm output .s (assembly code)\n"
77 " -fno-emit-asm (default) do not output .s (assembly code)\n"
78 " -femit-llvm-ir produce a .ll file with LLVM IR\n"
79 " -fno-emit-llvm-ir (default) do not produce a .ll file with LLVM IR\n"
76 " --libc [file] Provide a file which specifies libc paths\n"80 " --libc [file] Provide a file which specifies libc paths\n"
77 " --name [name] override output name\n"81 " --name [name] override output name\n"
78 " --output-dir [dir] override output directory (defaults to cwd)\n"82 " --output-dir [dir] override output directory (defaults to cwd)\n"
...@@ -423,7 +427,7 @@ static int main0(int argc, char **argv) {...@@ -423,7 +427,7 @@ static int main0(int argc, char **argv) {
423 bool stack_report = false;427 bool stack_report = false;
424 bool enable_dump_analysis = false;428 bool enable_dump_analysis = false;
425 bool enable_doc_generation = false;429 bool enable_doc_generation = false;
426 bool disable_bin_generation = false;430 bool emit_bin = true;
427 bool emit_asm = false;431 bool emit_asm = false;
428 bool emit_llvm_ir = false;432 bool emit_llvm_ir = false;
429 const char *cache_dir = nullptr;433 const char *cache_dir = nullptr;
...@@ -553,7 +557,7 @@ static int main0(int argc, char **argv) {...@@ -553,7 +557,7 @@ static int main0(int argc, char **argv) {
553 }557 }
554558
555 Termination term;559 Termination term;
556 args.items[0] = buf_ptr(&g->output_file_path);560 args.items[0] = buf_ptr(&g->bin_file_output_path);
557 os_spawn_process(args, &term);561 os_spawn_process(args, &term);
558 if (term.how != TerminationIdClean || term.code != 0) {562 if (term.how != TerminationIdClean || term.code != 0) {
559 fprintf(stderr, "\nBuild failed. The following command failed:\n");563 fprintf(stderr, "\nBuild failed. The following command failed:\n");
...@@ -632,8 +636,6 @@ static int main0(int argc, char **argv) {...@@ -632,8 +636,6 @@ static int main0(int argc, char **argv) {
632 enable_dump_analysis = true;636 enable_dump_analysis = true;
633 } else if (strcmp(arg, "-femit-docs") == 0) {637 } else if (strcmp(arg, "-femit-docs") == 0) {
634 enable_doc_generation = true;638 enable_doc_generation = true;
635 } else if (strcmp(arg, "-fno-emit-bin") == 0) {
636 disable_bin_generation = true;
637 } else if (strcmp(arg, "--enable-valgrind") == 0) {639 } else if (strcmp(arg, "--enable-valgrind") == 0) {
638 valgrind_support = ValgrindSupportEnabled;640 valgrind_support = ValgrindSupportEnabled;
639 } else if (strcmp(arg, "--disable-valgrind") == 0) {641 } else if (strcmp(arg, "--disable-valgrind") == 0) {
...@@ -703,9 +705,9 @@ static int main0(int argc, char **argv) {...@@ -703,9 +705,9 @@ static int main0(int argc, char **argv) {
703 } else if (strcmp(arg, "--test-evented-io") == 0) {705 } else if (strcmp(arg, "--test-evented-io") == 0) {
704 test_evented_io = true;706 test_evented_io = true;
705 } else if (strcmp(arg, "-femit-bin") == 0) {707 } else if (strcmp(arg, "-femit-bin") == 0) {
706 disable_bin_generation = false;708 emit_bin = true;
707 } else if (strcmp(arg, "-fno-emit-bin") == 0) {709 } else if (strcmp(arg, "-fno-emit-bin") == 0) {
708 disable_bin_generation = true;710 emit_bin = false;
709 } else if (strcmp(arg, "-femit-asm") == 0) {711 } else if (strcmp(arg, "-femit-asm") == 0) {
710 emit_asm = true;712 emit_asm = true;
711 } else if (strcmp(arg, "-fno-emit-asm") == 0) {713 } else if (strcmp(arg, "-fno-emit-asm") == 0) {
...@@ -746,12 +748,12 @@ static int main0(int argc, char **argv) {...@@ -746,12 +748,12 @@ static int main0(int argc, char **argv) {
746 } else if (strcmp(arg, "--emit") == 0) {748 } else if (strcmp(arg, "--emit") == 0) {
747 if (strcmp(argv[i], "asm") == 0) {749 if (strcmp(argv[i], "asm") == 0) {
748 emit_asm = true;750 emit_asm = true;
749 disable_bin_generation = true;751 emit_bin = false;
750 } else if (strcmp(argv[i], "bin") == 0) {752 } else if (strcmp(argv[i], "bin") == 0) {
751 disable_bin_generation = false;753 emit_bin = true;
752 } else if (strcmp(argv[i], "llvm-ir") == 0) {754 } else if (strcmp(argv[i], "llvm-ir") == 0) {
753 emit_llvm_ir = true;755 emit_llvm_ir = true;
754 disable_bin_generation = true;756 emit_bin = false;
755 } else {757 } else {
756 fprintf(stderr, "--emit options are 'asm', 'bin', or 'llvm-ir'\n");758 fprintf(stderr, "--emit options are 'asm', 'bin', or 'llvm-ir'\n");
757 return print_error_usage(arg0);759 return print_error_usage(arg0);
...@@ -1113,8 +1115,8 @@ static int main0(int argc, char **argv) {...@@ -1113,8 +1115,8 @@ static int main0(int argc, char **argv) {
1113 {1115 {
1114 fprintf(stderr, "Expected source file argument.\n");1116 fprintf(stderr, "Expected source file argument.\n");
1115 return print_error_usage(arg0);1117 return print_error_usage(arg0);
1116 } else if (cmd == CmdRun && disable_bin_generation) {1118 } else if (cmd == CmdRun && !emit_bin) {
1117 fprintf(stderr, "Cannot run non-executable file.\n");1119 fprintf(stderr, "Cannot run without emitting a binary file.\n");
1118 return print_error_usage(arg0);1120 return print_error_usage(arg0);
1119 }1121 }
11201122
...@@ -1191,7 +1193,10 @@ static int main0(int argc, char **argv) {...@@ -1191,7 +1193,10 @@ static int main0(int argc, char **argv) {
1191 g->enable_stack_report = stack_report;1193 g->enable_stack_report = stack_report;
1192 g->enable_dump_analysis = enable_dump_analysis;1194 g->enable_dump_analysis = enable_dump_analysis;
1193 g->enable_doc_generation = enable_doc_generation;1195 g->enable_doc_generation = enable_doc_generation;
1194 g->disable_bin_generation = disable_bin_generation;1196 g->emit_bin = emit_bin;
1197 g->emit_asm = emit_asm;
1198 g->emit_llvm_ir = emit_llvm_ir;
1199
1195 codegen_set_out_name(g, buf_out_name);1200 codegen_set_out_name(g, buf_out_name);
1196 codegen_set_lib_version(g, ver_major, ver_minor, ver_patch);1201 codegen_set_lib_version(g, ver_major, ver_minor, ver_patch);
1197 g->want_single_threaded = want_single_threaded;1202 g->want_single_threaded = want_single_threaded;
...@@ -1277,9 +1282,6 @@ static int main0(int argc, char **argv) {...@@ -1277,9 +1282,6 @@ static int main0(int argc, char **argv) {
12771282
12781283
1279 if (cmd == CmdBuild || cmd == CmdRun) {1284 if (cmd == CmdBuild || cmd == CmdRun) {
1280 codegen_set_emit_asm(g, emit_asm);
1281 codegen_set_emit_llvm_ir(g, emit_llvm_ir);
1282
1283 g->enable_cache = get_cache_opt(enable_cache, cmd == CmdRun);1285 g->enable_cache = get_cache_opt(enable_cache, cmd == CmdRun);
1284 codegen_build_and_link(g);1286 codegen_build_and_link(g);
1285 if (root_progress_node != nullptr) {1287 if (root_progress_node != nullptr) {
...@@ -1297,7 +1299,7 @@ static int main0(int argc, char **argv) {...@@ -1297,7 +1299,7 @@ static int main0(int argc, char **argv) {
1297 mem::print_report();1299 mem::print_report();
1298#endif1300#endif
12991301
1300 const char *exec_path = buf_ptr(&g->output_file_path);1302 const char *exec_path = buf_ptr(&g->bin_file_output_path);
1301 ZigList<const char*> args = {0};1303 ZigList<const char*> args = {0};
13021304
1303 args.append(exec_path);1305 args.append(exec_path);
...@@ -1317,21 +1319,21 @@ static int main0(int argc, char **argv) {...@@ -1317,21 +1319,21 @@ static int main0(int argc, char **argv) {
1317 } else if (cmd == CmdBuild) {1319 } else if (cmd == CmdBuild) {
1318 if (g->enable_cache) {1320 if (g->enable_cache) {
1319#if defined(ZIG_OS_WINDOWS)1321#if defined(ZIG_OS_WINDOWS)
1320 buf_replace(&g->output_file_path, '/', '\\');1322 buf_replace(&g->bin_file_output_path, '/', '\\');
1321#endif1323#endif
1322 if (final_output_dir_step != nullptr) {1324 if (final_output_dir_step != nullptr) {
1323 Buf *dest_basename = buf_alloc();1325 Buf *dest_basename = buf_alloc();
1324 os_path_split(&g->output_file_path, nullptr, dest_basename);1326 os_path_split(&g->bin_file_output_path, nullptr, dest_basename);
1325 Buf *dest_path = buf_alloc();1327 Buf *dest_path = buf_alloc();
1326 os_path_join(final_output_dir_step, dest_basename, dest_path);1328 os_path_join(final_output_dir_step, dest_basename, dest_path);
13271329
1328 if ((err = os_update_file(&g->output_file_path, dest_path))) {1330 if ((err = os_update_file(&g->bin_file_output_path, dest_path))) {
1329 fprintf(stderr, "unable to copy %s to %s: %s\n", buf_ptr(&g->output_file_path),1331 fprintf(stderr, "unable to copy %s to %s: %s\n", buf_ptr(&g->bin_file_output_path),
1330 buf_ptr(dest_path), err_str(err));1332 buf_ptr(dest_path), err_str(err));
1331 return main_exit(root_progress_node, EXIT_FAILURE);1333 return main_exit(root_progress_node, EXIT_FAILURE);
1332 }1334 }
1333 } else {1335 } else {
1334 if (printf("%s\n", buf_ptr(&g->output_file_path)) < 0)1336 if (printf("%s\n", buf_ptr(&g->bin_file_output_path)) < 0)
1335 return main_exit(root_progress_node, EXIT_FAILURE);1337 return main_exit(root_progress_node, EXIT_FAILURE);
1336 }1338 }
1337 }1339 }
...@@ -1346,9 +1348,6 @@ static int main0(int argc, char **argv) {...@@ -1346,9 +1348,6 @@ static int main0(int argc, char **argv) {
1346 codegen_print_timing_report(g, stderr);1348 codegen_print_timing_report(g, stderr);
1347 return main_exit(root_progress_node, EXIT_SUCCESS);1349 return main_exit(root_progress_node, EXIT_SUCCESS);
1348 } else if (cmd == CmdTest) {1350 } else if (cmd == CmdTest) {
1349 codegen_set_emit_asm(g, emit_asm);
1350 codegen_set_emit_llvm_ir(g, emit_llvm_ir);
1351
1352 ZigTarget native;1351 ZigTarget native;
1353 get_native_target(&native);1352 get_native_target(&native);
13541353
...@@ -1367,17 +1366,17 @@ static int main0(int argc, char **argv) {...@@ -1367,17 +1366,17 @@ static int main0(int argc, char **argv) {
1367 zig_print_stack_report(g, stdout);1366 zig_print_stack_report(g, stdout);
1368 }1367 }
13691368
1370 if (g->disable_bin_generation) {1369 if (!g->emit_bin) {
1371 fprintf(stderr, "Semantic analysis complete. No binary produced due to -fno-emit-bin.\n");1370 fprintf(stderr, "Semantic analysis complete. No binary produced due to -fno-emit-bin.\n");
1372 return main_exit(root_progress_node, EXIT_SUCCESS);1371 return main_exit(root_progress_node, EXIT_SUCCESS);
1373 }1372 }
13741373
1375 Buf *test_exe_path_unresolved = &g->output_file_path;1374 Buf *test_exe_path_unresolved = &g->bin_file_output_path;
1376 Buf *test_exe_path = buf_alloc();1375 Buf *test_exe_path = buf_alloc();
1377 *test_exe_path = os_path_resolve(&test_exe_path_unresolved, 1);1376 *test_exe_path = os_path_resolve(&test_exe_path_unresolved, 1);
13781377
1379 if (disable_bin_generation) {1378 if (!g->emit_bin) {
1380 fprintf(stderr, "Created %s but skipping execution because it is non executable.\n",1379 fprintf(stderr, "Created %s but skipping execution because no binary generated.\n",
1381 buf_ptr(test_exe_path));1380 buf_ptr(test_exe_path));
1382 return main_exit(root_progress_node, EXIT_SUCCESS);1381 return main_exit(root_progress_node, EXIT_SUCCESS);
1383 }1382 }
src/zig_llvm.cpp+59-42
...@@ -161,17 +161,32 @@ unsigned ZigLLVMDataLayoutGetProgramAddressSpace(LLVMTargetDataRef TD) {...@@ -161,17 +161,32 @@ unsigned ZigLLVMDataLayoutGetProgramAddressSpace(LLVMTargetDataRef TD) {
161}161}
162162
163bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref,163bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref,
164 const char *filename, ZigLLVM_EmitOutputType output_type, char **error_message, bool is_debug,164 char **error_message, bool is_debug,
165 bool is_small, bool time_report)165 bool is_small, bool time_report,
166 const char *asm_filename, const char *bin_filename, const char *llvm_ir_filename)
166{167{
167 TimePassesIsEnabled = time_report;168 TimePassesIsEnabled = time_report;
168169
169 std::error_code EC;170 raw_fd_ostream *dest_asm = nullptr;
170 raw_fd_ostream dest(filename, EC, sys::fs::F_None);171 raw_fd_ostream *dest_bin = nullptr;
171 if (EC) {172
172 *error_message = strdup((const char *)StringRef(EC.message()).bytes_begin());173 if (asm_filename) {
173 return true;174 std::error_code EC;
175 dest_asm = new(std::nothrow) raw_fd_ostream(asm_filename, EC, sys::fs::F_None);
176 if (EC) {
177 *error_message = strdup((const char *)StringRef(EC.message()).bytes_begin());
178 return true;
179 }
174 }180 }
181 if (bin_filename) {
182 std::error_code EC;
183 dest_bin = new(std::nothrow) raw_fd_ostream(bin_filename, EC, sys::fs::F_None);
184 if (EC) {
185 *error_message = strdup((const char *)StringRef(EC.message()).bytes_begin());
186 return true;
187 }
188 }
189
175 TargetMachine* target_machine = reinterpret_cast<TargetMachine*>(targ_machine_ref);190 TargetMachine* target_machine = reinterpret_cast<TargetMachine*>(targ_machine_ref);
176 target_machine->setO0WantsFastISel(true);191 target_machine->setO0WantsFastISel(true);
177192
...@@ -222,49 +237,51 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM...@@ -222,49 +237,51 @@ bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMM
222 }237 }
223 PMBuilder->populateFunctionPassManager(FPM);238 PMBuilder->populateFunctionPassManager(FPM);
224239
225 // Set up the per-module pass manager.240 {
226 legacy::PassManager MPM;241 // Set up the per-module pass manager.
227 MPM.add(createTargetTransformInfoWrapperPass(target_machine->getTargetIRAnalysis()));242 legacy::PassManager MPM;
228 PMBuilder->populateModulePassManager(MPM);243 MPM.add(createTargetTransformInfoWrapperPass(target_machine->getTargetIRAnalysis()));
229244 PMBuilder->populateModulePassManager(MPM);
230 // Set output pass.245
231 TargetMachine::CodeGenFileType ft;246 // Set output passes.
232 if (output_type != ZigLLVM_EmitLLVMIr) {247 if (dest_bin) {
233 switch (output_type) {248 if (target_machine->addPassesToEmitFile(MPM, *dest_bin, nullptr, TargetMachine::CGFT_ObjectFile)) {
234 case ZigLLVM_EmitAssembly:249 *error_message = strdup("TargetMachine can't emit an object file");
235 ft = TargetMachine::CGFT_AssemblyFile;250 return true;
236 break;251 }
237 case ZigLLVM_EmitBinary:
238 ft = TargetMachine::CGFT_ObjectFile;
239 break;
240 default:
241 abort();
242 }252 }
243253 if (dest_asm) {
244 if (target_machine->addPassesToEmitFile(MPM, dest, nullptr, ft)) {254 if (target_machine->addPassesToEmitFile(MPM, *dest_asm, nullptr, TargetMachine::CGFT_AssemblyFile)) {
245 *error_message = strdup("TargetMachine can't emit a file of this type");255 *error_message = strdup("TargetMachine can't emit an assembly file");
246 return true;256 return true;
257 }
247 }258 }
248 }
249259
250 // run per function optimization passes260 // run per function optimization passes
251 FPM.doInitialization();261 FPM.doInitialization();
252 for (Function &F : *module)262 for (Function &F : *module)
253 if (!F.isDeclaration())263 if (!F.isDeclaration())
254 FPM.run(F);264 FPM.run(F);
255 FPM.doFinalization();265 FPM.doFinalization();
256266
257 MPM.run(*module);267 MPM.run(*module);
258268
259 if (output_type == ZigLLVM_EmitLLVMIr) {269 if (llvm_ir_filename) {
260 if (LLVMPrintModuleToFile(module_ref, filename, error_message)) {270 if (LLVMPrintModuleToFile(module_ref, llvm_ir_filename, error_message)) {
261 return true;271 return true;
272 }
262 }273 }
263 }
264274
265 if (time_report) {275 if (time_report) {
266 TimerGroup::printAll(errs());276 TimerGroup::printAll(errs());
277 }
278
279 // MPM goes out of scope and writes to the out streams
267 }280 }
281
282 delete dest_asm;
283 delete dest_bin;
284
268 return false;285 return false;
269}286}
270287
src/zig_llvm.h+3-10
...@@ -46,17 +46,10 @@ ZIG_EXTERN_C void ZigLLVMInitializeLowerIntrinsicsPass(LLVMPassRegistryRef R);...@@ -46,17 +46,10 @@ ZIG_EXTERN_C void ZigLLVMInitializeLowerIntrinsicsPass(LLVMPassRegistryRef R);
46ZIG_EXTERN_C char *ZigLLVMGetHostCPUName(void);46ZIG_EXTERN_C char *ZigLLVMGetHostCPUName(void);
47ZIG_EXTERN_C char *ZigLLVMGetNativeFeatures(void);47ZIG_EXTERN_C char *ZigLLVMGetNativeFeatures(void);
4848
49// We use a custom enum here since LLVM does not expose LLVMIr as an emit
50// output through the same mechanism as assembly/binary.
51enum ZigLLVM_EmitOutputType {
52 ZigLLVM_EmitAssembly,
53 ZigLLVM_EmitBinary,
54 ZigLLVM_EmitLLVMIr,
55};
56
57ZIG_EXTERN_C bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref,49ZIG_EXTERN_C bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machine_ref, LLVMModuleRef module_ref,
58 const char *filename, enum ZigLLVM_EmitOutputType output_type, char **error_message, bool is_debug,50 char **error_message, bool is_debug,
59 bool is_small, bool time_report);51 bool is_small, bool time_report,
52 const char *asm_filename, const char *bin_filename, const char *llvm_ir_filename);
6053
61ZIG_EXTERN_C LLVMTargetMachineRef ZigLLVMCreateTargetMachine(LLVMTargetRef T, const char *Triple,54ZIG_EXTERN_C LLVMTargetMachineRef ZigLLVMCreateTargetMachine(LLVMTargetRef T, const char *Triple,
62 const char *CPU, const char *Features, LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc,55 const char *CPU, const char *Features, LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc,