authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-01-03 22:11:19-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-01-03 22:11:19-05:00
log14fcfe29817c03c3cac023b045433ea7abe4bd47
tree9c209c80ec8d0382921934b7ef7baec8a78b7f31
parent695c8f756b7ef12c4e8993720503b9c6d2242689
signaturelock-open Commit is signed but in an unrecognized format.

translate-c supports --cache on

this will be used to provide a zig build step

4 files changed, 103 insertions(+), 6 deletions(-)

src/codegen.cpp+96-2
...@@ -194,6 +194,7 @@ static LLVMValueRef build_alloca(CodeGen *g, ZigType *type_entry, const char *na...@@ -194,6 +194,7 @@ static LLVMValueRef build_alloca(CodeGen *g, ZigType *type_entry, const char *na
194static LLVMValueRef gen_await_early_return(CodeGen *g, IrInstruction *source_instr,194static LLVMValueRef gen_await_early_return(CodeGen *g, IrInstruction *source_instr,
195 LLVMValueRef target_frame_ptr, ZigType *result_type, ZigType *ptr_result_type,195 LLVMValueRef target_frame_ptr, ZigType *result_type, ZigType *ptr_result_type,
196 LLVMValueRef result_loc, bool non_async);196 LLVMValueRef result_loc, bool non_async);
197static Error get_tmp_filename(CodeGen *g, Buf *out, Buf *suffix);
197198
198static void addLLVMAttr(LLVMValueRef val, LLVMAttributeIndex attr_index, const char *attr_name) {199static void addLLVMAttr(LLVMValueRef val, LLVMAttributeIndex attr_index, const char *attr_name) {
199 unsigned kind_id = LLVMGetEnumAttributeKindForName(attr_name, strlen(attr_name));200 unsigned kind_id = LLVMGetEnumAttributeKindForName(attr_name, strlen(attr_name));
...@@ -9102,8 +9103,9 @@ void add_cc_args(CodeGen *g, ZigList<const char *> &args, const char *out_dep_pa...@@ -9102,8 +9103,9 @@ void add_cc_args(CodeGen *g, ZigList<const char *> &args, const char *out_dep_pa
91029103
9103}9104}
91049105
9105void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file) {9106void codegen_translate_c(CodeGen *g, Buf *full_path) {
9106 Error err;9107 Error err;
9108
9107 Buf *src_basename = buf_alloc();9109 Buf *src_basename = buf_alloc();
9108 Buf *src_dirname = buf_alloc();9110 Buf *src_dirname = buf_alloc();
9109 os_path_split(full_path, src_dirname, src_basename);9111 os_path_split(full_path, src_dirname, src_basename);
...@@ -9111,12 +9113,61 @@ void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file) {...@@ -9111,12 +9113,61 @@ void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file) {
9111 Buf noextname = BUF_INIT;9113 Buf noextname = BUF_INIT;
9112 os_path_extname(src_basename, &noextname, nullptr);9114 os_path_extname(src_basename, &noextname, nullptr);
91139115
9116 Buf *zig_basename = buf_sprintf("%s.zig", buf_ptr(&noextname));
9117
9114 detect_libc(g);9118 detect_libc(g);
91159119
9120 Buf cache_digest = BUF_INIT;
9121 buf_resize(&cache_digest, 0);
9122
9123 CacheHash *cache_hash = nullptr;
9124 if (g->enable_cache) {
9125 if ((err = create_c_object_cache(g, &cache_hash, true))) {
9126 // Already printed error; verbose = true
9127 exit(1);
9128 }
9129 cache_file(cache_hash, full_path);
9130 // to distinguish from generating a C object
9131 cache_buf(cache_hash, buf_create_from_str("translate-c"));
9132
9133 if ((err = cache_hit(cache_hash, &cache_digest))) {
9134 if (err != ErrorInvalidFormat) {
9135 fprintf(stderr, "unable to check cache: %s\n", err_str(err));
9136 exit(1);
9137 }
9138 }
9139 if (cache_hash->manifest_file_path != nullptr) {
9140 g->caches_to_release.append(cache_hash);
9141 }
9142 }
9143
9144 if (g->enable_cache && buf_len(&cache_digest) != 0) {
9145 // cache hit
9146 Buf *cached_path = buf_sprintf("%s" OS_SEP CACHE_OUT_SUBDIR OS_SEP "%s" OS_SEP "%s",
9147 buf_ptr(g->cache_dir), buf_ptr(&cache_digest), buf_ptr(zig_basename));
9148 fprintf(stdout, "%s\n", buf_ptr(cached_path));
9149 return;
9150 }
9151
9152 // cache miss or cache disabled
9116 init(g);9153 init(g);
91179154
9155 Buf *out_dep_path = nullptr;
9156 const char *out_dep_path_cstr = nullptr;
9157
9158 if (g->enable_cache) {
9159 buf_alloc();// we can't know the digest until we do the C compiler invocation, so we
9160 // need a tmp filename.
9161 out_dep_path = buf_alloc();
9162 if ((err = get_tmp_filename(g, out_dep_path, buf_sprintf("%s.d", buf_ptr(zig_basename))))) {
9163 fprintf(stderr, "unable to create tmp dir: %s\n", err_str(err));
9164 exit(1);
9165 }
9166 out_dep_path_cstr = buf_ptr(out_dep_path);
9167 }
9168
9118 ZigList<const char *> clang_argv = {0};9169 ZigList<const char *> clang_argv = {0};
9119 add_cc_args(g, clang_argv, nullptr, true);9170 add_cc_args(g, clang_argv, out_dep_path_cstr, true);
91209171
9121 clang_argv.append(buf_ptr(full_path));9172 clang_argv.append(buf_ptr(full_path));
91229173
...@@ -9160,7 +9211,50 @@ void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file) {...@@ -9160,7 +9211,50 @@ void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file) {
9160 exit(1);9211 exit(1);
9161 }9212 }
91629213
9214 if (!g->enable_cache) {
9215 stage2_render_ast(ast, stdout);
9216 return;
9217 }
9218
9219 // add the files depended on to the cache system
9220 if ((err = cache_add_dep_file(cache_hash, out_dep_path, true))) {
9221 // Don't treat the absence of the .d file as a fatal error, the
9222 // compiler may not produce one eg. when compiling .s files
9223 if (err != ErrorFileNotFound) {
9224 fprintf(stderr, "Failed to add C source dependencies to cache: %s\n", err_str(err));
9225 exit(1);
9226 }
9227 }
9228 if (err != ErrorFileNotFound) {
9229 os_delete_file(out_dep_path);
9230 }
9231
9232 if ((err = cache_final(cache_hash, &cache_digest))) {
9233 fprintf(stderr, "Unable to finalize cache hash: %s\n", err_str(err));
9234 exit(1);
9235 }
9236
9237 Buf *artifact_dir = buf_sprintf("%s" OS_SEP CACHE_OUT_SUBDIR OS_SEP "%s",
9238 buf_ptr(g->cache_dir), buf_ptr(&cache_digest));
9239
9240 if ((err = os_make_path(artifact_dir))) {
9241 fprintf(stderr, "Unable to make dir: %s\n", err_str(err));
9242 exit(1);
9243 }
9244
9245 Buf *cached_path = buf_sprintf("%s" OS_SEP "%s", buf_ptr(artifact_dir), buf_ptr(zig_basename));
9246
9247 FILE *out_file = fopen(buf_ptr(cached_path), "wb");
9248 if (out_file == nullptr) {
9249 fprintf(stderr, "Unable to open output file: %s\n", strerror(errno));
9250 exit(1);
9251 }
9163 stage2_render_ast(ast, out_file);9252 stage2_render_ast(ast, out_file);
9253 if (fclose(out_file) != 0) {
9254 fprintf(stderr, "Unable to write to output file: %s\n", strerror(errno));
9255 exit(1);
9256 }
9257 fprintf(stdout, "%s\n", buf_ptr(cached_path));
9164}9258}
91659259
9166static void update_test_functions_builtin_decl(CodeGen *g) {9260static void update_test_functions_builtin_decl(CodeGen *g) {
src/codegen.hpp+1-1
...@@ -54,7 +54,7 @@ ZigPackage *codegen_create_package(CodeGen *g, const char *root_src_dir, const c...@@ -54,7 +54,7 @@ ZigPackage *codegen_create_package(CodeGen *g, const char *root_src_dir, const c
54void codegen_add_assembly(CodeGen *g, Buf *path);54void codegen_add_assembly(CodeGen *g, Buf *path);
55void codegen_add_object(CodeGen *g, Buf *object_path);55void codegen_add_object(CodeGen *g, Buf *object_path);
5656
57void codegen_translate_c(CodeGen *g, Buf *full_path, FILE *out_file);57void codegen_translate_c(CodeGen *g, Buf *full_path);
5858
59Buf *codegen_generate_builtin_source(CodeGen *g);59Buf *codegen_generate_builtin_source(CodeGen *g);
6060
src/main.cpp+3-2
...@@ -1164,7 +1164,7 @@ int main(int argc, char **argv) {...@@ -1164,7 +1164,7 @@ int main(int argc, char **argv) {
1164 return print_error_usage(arg0);1164 return print_error_usage(arg0);
1165 }1165 }
11661166
1167 Buf *zig_root_source_file = cmd == CmdTranslateC ? nullptr : in_file_buf;1167 Buf *zig_root_source_file = (cmd == CmdTranslateC) ? nullptr : in_file_buf;
11681168
1169 if (cmd == CmdRun && buf_out_name == nullptr) {1169 if (cmd == CmdRun && buf_out_name == nullptr) {
1170 buf_out_name = buf_create_from_str("run");1170 buf_out_name = buf_create_from_str("run");
...@@ -1330,7 +1330,8 @@ int main(int argc, char **argv) {...@@ -1330,7 +1330,8 @@ int main(int argc, char **argv) {
1330 zig_unreachable();1330 zig_unreachable();
1331 }1331 }
1332 } else if (cmd == CmdTranslateC) {1332 } else if (cmd == CmdTranslateC) {
1333 codegen_translate_c(g, in_file_buf, stdout);1333 g->enable_cache = get_cache_opt(enable_cache, false);
1334 codegen_translate_c(g, in_file_buf);
1334 if (timing_info)1335 if (timing_info)
1335 codegen_print_timing_report(g, stderr);1336 codegen_print_timing_report(g, stderr);
1336 return main_exit(root_progress_node, EXIT_SUCCESS);1337 return main_exit(root_progress_node, EXIT_SUCCESS);
test/run_translated_c.zig+3-1
...@@ -1,4 +1,6 @@...@@ -1,4 +1,6 @@
1const std = @import("std");
1const tests = @import("tests.zig");2const tests = @import("tests.zig");
3const nl = std.cstr.line_sep;
24
3pub fn addCases(cases: *tests.RunTranslatedCContext) void {5pub fn addCases(cases: *tests.RunTranslatedCContext) void {
4 cases.add("hello world",6 cases.add("hello world",
...@@ -8,7 +10,7 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void {...@@ -8,7 +10,7 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void {
8 \\ printf("hello, world!\n");10 \\ printf("hello, world!\n");
9 \\ return 0;11 \\ return 0;
10 \\}12 \\}
11 , "hello, world!\n");13 , "hello, world!" ++ nl);
1214
13 cases.add("anon struct init",15 cases.add("anon struct init",
14 \\#include <stdlib.h>16 \\#include <stdlib.h>