authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-01-11 20:58:28-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-01-11 21:02:30-05:00
log3268276b58d8b65cb295b738d7c14174005bd84e
treec52b5524962c7ab37129318b5aba31b9d83820f6
parent465e75bc5a41aa899b673c0a3ff59d6da871fbe6

the same string literal codegens to the same constant

this makes it so that you can send the same string literal as a comptime slice and get the same type

6 files changed, 31 insertions(+), 5 deletions(-)

src/all_types.hpp+1
...@@ -1421,6 +1421,7 @@ struct CodeGen {...@@ -1421,6 +1421,7 @@ struct CodeGen {
1421 HashMap<ZigLLVMFnKey, LLVMValueRef, zig_llvm_fn_key_hash, zig_llvm_fn_key_eql> llvm_fn_table;1421 HashMap<ZigLLVMFnKey, LLVMValueRef, zig_llvm_fn_key_hash, zig_llvm_fn_key_eql> llvm_fn_table;
1422 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> exported_symbol_names;1422 HashMap<Buf *, AstNode *, buf_hash, buf_eql_buf> exported_symbol_names;
1423 HashMap<Buf *, Tld *, buf_hash, buf_eql_buf> external_prototypes;1423 HashMap<Buf *, Tld *, buf_hash, buf_eql_buf> external_prototypes;
1424 HashMap<Buf *, ConstExprValue *, buf_hash, buf_eql_buf> string_literals_table;
14241425
14251426
1426 ZigList<ImportTableEntry *> import_queue;1427 ZigList<ImportTableEntry *> import_queue;
src/analyze.cpp+8
...@@ -4370,6 +4370,12 @@ bool type_requires_comptime(TypeTableEntry *type_entry) {...@@ -4370,6 +4370,12 @@ bool type_requires_comptime(TypeTableEntry *type_entry) {
4370}4370}
43714371
4372void init_const_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) {4372void init_const_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) {
4373 auto entry = g->string_literals_table.maybe_get(str);
4374 if (entry != nullptr) {
4375 *const_val = *entry->value;
4376 return;
4377 }
4378
4373 const_val->special = ConstValSpecialStatic;4379 const_val->special = ConstValSpecialStatic;
4374 const_val->type = get_array_type(g, g->builtin_types.entry_u8, buf_len(str));4380 const_val->type = get_array_type(g, g->builtin_types.entry_u8, buf_len(str));
4375 const_val->data.x_array.s_none.elements = create_const_vals(buf_len(str));4381 const_val->data.x_array.s_none.elements = create_const_vals(buf_len(str));
...@@ -4380,6 +4386,8 @@ void init_const_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) {...@@ -4380,6 +4386,8 @@ void init_const_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) {
4380 this_char->type = g->builtin_types.entry_u8;4386 this_char->type = g->builtin_types.entry_u8;
4381 bigint_init_unsigned(&this_char->data.x_bigint, (uint8_t)buf_ptr(str)[i]);4387 bigint_init_unsigned(&this_char->data.x_bigint, (uint8_t)buf_ptr(str)[i]);
4382 }4388 }
4389
4390 g->string_literals_table.put(str, const_val);
4383}4391}
43844392
4385ConstExprValue *create_const_str_lit(CodeGen *g, Buf *str) {4393ConstExprValue *create_const_str_lit(CodeGen *g, Buf *str) {
src/buffer.cpp+4-1
...@@ -67,9 +67,12 @@ bool buf_eql_buf(Buf *buf, Buf *other) {...@@ -67,9 +67,12 @@ bool buf_eql_buf(Buf *buf, Buf *other) {
6767
68uint32_t buf_hash(Buf *buf) {68uint32_t buf_hash(Buf *buf) {
69 assert(buf->list.length);69 assert(buf->list.length);
70 size_t interval = buf->list.length / 256;
71 if (interval == 0)
72 interval = 1;
70 // FNV 32-bit hash73 // FNV 32-bit hash
71 uint32_t h = 2166136261;74 uint32_t h = 2166136261;
72 for (size_t i = 0; i < buf_len(buf); i += 1) {75 for (size_t i = 0; i < buf_len(buf); i += interval) {
73 h = h ^ ((uint8_t)buf->list.at(i));76 h = h ^ ((uint8_t)buf->list.at(i));
74 h = h * 16777619;77 h = h * 16777619;
75 }78 }
src/codegen.cpp+1
...@@ -87,6 +87,7 @@ CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out...@@ -87,6 +87,7 @@ CodeGen *codegen_create(Buf *root_src_path, const ZigTarget *target, OutType out
87 g->memoized_fn_eval_table.init(16);87 g->memoized_fn_eval_table.init(16);
88 g->exported_symbol_names.init(8);88 g->exported_symbol_names.init(8);
89 g->external_prototypes.init(8);89 g->external_prototypes.init(8);
90 g->string_literals_table.init(16);
90 g->is_test_build = false;91 g->is_test_build = false;
91 g->want_h_file = (out_type == OutTypeObj || out_type == OutTypeLib);92 g->want_h_file = (out_type == OutTypeObj || out_type == OutTypeLib);
92 buf_resize(&g->global_asm, 0);93 buf_resize(&g->global_asm, 0);
src/ir.cpp+4-4
...@@ -13224,9 +13224,9 @@ static TypeTableEntry *ir_analyze_instruction_embed_file(IrAnalyze *ira, IrInstr...@@ -13224,9 +13224,9 @@ static TypeTableEntry *ir_analyze_instruction_embed_file(IrAnalyze *ira, IrInstr
13224 os_path_resolve(&source_dir_path, rel_file_path, &file_path);13224 os_path_resolve(&source_dir_path, rel_file_path, &file_path);
1322513225
13226 // load from file system into const expr13226 // load from file system into const expr
13227 Buf file_contents = BUF_INIT;13227 Buf *file_contents = buf_alloc();
13228 int err;13228 int err;
13229 if ((err = os_fetch_file_path(&file_path, &file_contents))) {13229 if ((err = os_fetch_file_path(&file_path, file_contents))) {
13230 if (err == ErrorFileNotFound) {13230 if (err == ErrorFileNotFound) {
13231 ir_add_error(ira, instruction->name, buf_sprintf("unable to find '%s'", buf_ptr(&file_path)));13231 ir_add_error(ira, instruction->name, buf_sprintf("unable to find '%s'", buf_ptr(&file_path)));
13232 return ira->codegen->builtin_types.entry_invalid;13232 return ira->codegen->builtin_types.entry_invalid;
...@@ -13240,9 +13240,9 @@ static TypeTableEntry *ir_analyze_instruction_embed_file(IrAnalyze *ira, IrInstr...@@ -13240,9 +13240,9 @@ static TypeTableEntry *ir_analyze_instruction_embed_file(IrAnalyze *ira, IrInstr
13240 // we'll have to invalidate the cache13240 // we'll have to invalidate the cache
1324113241
13242 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);13242 ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base);
13243 init_const_str_lit(ira->codegen, out_val, &file_contents);13243 init_const_str_lit(ira->codegen, out_val, file_contents);
1324413244
13245 return get_array_type(ira->codegen, ira->codegen->builtin_types.entry_u8, buf_len(&file_contents));13245 return get_array_type(ira->codegen, ira->codegen->builtin_types.entry_u8, buf_len(file_contents));
13246}13246}
1324713247
13248static TypeTableEntry *ir_analyze_instruction_cmpxchg(IrAnalyze *ira, IrInstructionCmpxchg *instruction) {13248static TypeTableEntry *ir_analyze_instruction_cmpxchg(IrAnalyze *ira, IrInstructionCmpxchg *instruction) {
test/cases/eval.zig+13
...@@ -375,3 +375,16 @@ test "f128 at compile time is lossy" {...@@ -375,3 +375,16 @@ test "f128 at compile time is lossy" {
375375
376// TODO need a better implementation of bigfloat_init_bigint376// TODO need a better implementation of bigfloat_init_bigint
377// assert(f128(1 << 113) == 10384593717069655257060992658440192);377// assert(f128(1 << 113) == 10384593717069655257060992658440192);
378
379pub fn TypeWithCompTimeSlice(comptime field_name: []const u8) -> type {
380 return struct {
381 pub const Node = struct { };
382 };
383}
384
385test "string literal used as comptime slice is memoized" {
386 const a = "link";
387 const b = "link";
388 comptime assert(TypeWithCompTimeSlice(a).Node == TypeWithCompTimeSlice(b).Node);
389 comptime assert(TypeWithCompTimeSlice("link").Node == TypeWithCompTimeSlice("link").Node);
390}