mirror of
https://github.com/ziglang/zig.git
synced 2026-02-21 16:54:52 +00:00
const interning for 1-possible-value types
This commit is contained in:
parent
8f3e972da6
commit
a647a88dfc
@ -2021,6 +2021,13 @@ struct CodeGen {
|
||||
ZigType *entry_any_frame;
|
||||
} builtin_types;
|
||||
|
||||
struct {
|
||||
ZigValue x_undefined;
|
||||
ZigValue x_void;
|
||||
ZigValue x_null;
|
||||
ZigValue x_unreachable;
|
||||
} intern_values;
|
||||
|
||||
ZigType *align_amt_type;
|
||||
ZigType *stack_trace_type;
|
||||
ZigType *err_tag_type;
|
||||
|
||||
@ -195,6 +195,11 @@ void bigint_init_bigint(BigInt *dest, const BigInt *src) {
|
||||
memcpy(dest->data.digits, src->data.digits, sizeof(uint64_t) * dest->digit_count);
|
||||
}
|
||||
|
||||
void bigint_deinit(BigInt *bi) {
|
||||
if (bi->digit_count > 1)
|
||||
deallocate<uint64_t>(bi->data.digits, bi->digit_count);
|
||||
}
|
||||
|
||||
void bigint_init_bigfloat(BigInt *dest, const BigFloat *op) {
|
||||
float128_t zero;
|
||||
ui32_to_f128M(0, &zero);
|
||||
|
||||
@ -34,6 +34,7 @@ void bigint_init_signed(BigInt *dest, int64_t x);
|
||||
void bigint_init_bigint(BigInt *dest, const BigInt *src);
|
||||
void bigint_init_bigfloat(BigInt *dest, const BigFloat *op);
|
||||
void bigint_init_data(BigInt *dest, const uint64_t *digits, size_t digit_count, bool is_negative);
|
||||
void bigint_deinit(BigInt *bi);
|
||||
|
||||
// panics if number won't fit
|
||||
uint64_t bigint_as_u64(const BigInt *bigint);
|
||||
|
||||
@ -8008,6 +8008,33 @@ static void define_builtin_types(CodeGen *g) {
|
||||
}
|
||||
}
|
||||
|
||||
static void define_intern_values(CodeGen *g) {
|
||||
{
|
||||
auto& value = g->intern_values.x_undefined;
|
||||
value.type = g->builtin_types.entry_undef;
|
||||
value.global_refs = allocate<ConstGlobalRefs>(1, "ConstGlobalRefs.undefined");
|
||||
value.special = ConstValSpecialStatic;
|
||||
}
|
||||
{
|
||||
auto& value = g->intern_values.x_void;
|
||||
value.type = g->builtin_types.entry_void;
|
||||
value.global_refs = allocate<ConstGlobalRefs>(1, "ConstGlobalRefs.void");
|
||||
value.special = ConstValSpecialStatic;
|
||||
}
|
||||
{
|
||||
auto& value = g->intern_values.x_null;
|
||||
value.type = g->builtin_types.entry_null;
|
||||
value.global_refs = allocate<ConstGlobalRefs>(1, "ConstGlobalRefs.null");
|
||||
value.special = ConstValSpecialStatic;
|
||||
}
|
||||
{
|
||||
auto& value = g->intern_values.x_unreachable;
|
||||
value.type = g->builtin_types.entry_unreachable;
|
||||
value.global_refs = allocate<ConstGlobalRefs>(1, "ConstGlobalRefs.unreachable");
|
||||
value.special = ConstValSpecialStatic;
|
||||
}
|
||||
}
|
||||
|
||||
static BuiltinFnEntry *create_builtin_fn(CodeGen *g, BuiltinFnId id, const char *name, size_t count) {
|
||||
BuiltinFnEntry *builtin_fn = allocate<BuiltinFnEntry>(1);
|
||||
buf_init_from_str(&builtin_fn->name, name);
|
||||
@ -8629,6 +8656,7 @@ static void init(CodeGen *g) {
|
||||
g->dummy_di_file = nullptr;
|
||||
|
||||
define_builtin_types(g);
|
||||
define_intern_values(g);
|
||||
|
||||
IrInstruction *sentinel_instructions = allocate<IrInstruction>(2);
|
||||
g->invalid_instruction = &sentinel_instructions[0];
|
||||
|
||||
@ -23,10 +23,10 @@ public:
|
||||
}
|
||||
|
||||
struct Entry {
|
||||
bool used;
|
||||
int distance_from_start_index;
|
||||
K key;
|
||||
V value;
|
||||
bool used;
|
||||
int distance_from_start_index;
|
||||
};
|
||||
|
||||
void clear() {
|
||||
@ -187,10 +187,10 @@ private:
|
||||
if (distance_from_start_index > _max_distance_from_start_index)
|
||||
_max_distance_from_start_index = distance_from_start_index;
|
||||
*entry = {
|
||||
true,
|
||||
distance_from_start_index,
|
||||
key,
|
||||
value,
|
||||
true,
|
||||
distance_from_start_index,
|
||||
};
|
||||
key = tmp.key;
|
||||
value = tmp.value;
|
||||
@ -208,10 +208,10 @@ private:
|
||||
if (distance_from_start_index > _max_distance_from_start_index)
|
||||
_max_distance_from_start_index = distance_from_start_index;
|
||||
*entry = {
|
||||
true,
|
||||
distance_from_start_index,
|
||||
key,
|
||||
value,
|
||||
true,
|
||||
distance_from_start_index,
|
||||
};
|
||||
return;
|
||||
}
|
||||
|
||||
63
src/ir.cpp
63
src/ir.cpp
@ -1161,6 +1161,22 @@ static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_no
|
||||
return special_instruction;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static T *ir_create_instruction_noval(IrBuilder *irb, Scope *scope, AstNode *source_node) {
|
||||
const char *name = nullptr;
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
T *dummy = nullptr;
|
||||
name = ir_instruction_type_str(ir_instruction_id(dummy));
|
||||
#endif
|
||||
T *special_instruction = allocate<T>(1, name);
|
||||
special_instruction->base.id = ir_instruction_id(special_instruction);
|
||||
special_instruction->base.scope = scope;
|
||||
special_instruction->base.source_node = source_node;
|
||||
special_instruction->base.debug_id = exec_next_debug_id(irb->exec);
|
||||
special_instruction->base.owner_bb = irb->current_basic_block;
|
||||
return special_instruction;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
static T *ir_build_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) {
|
||||
T *special_instruction = ir_create_instruction<T>(irb, scope, source_node);
|
||||
@ -1214,16 +1230,22 @@ static IrInstruction *ir_build_return(IrBuilder *irb, Scope *scope, AstNode *sou
|
||||
}
|
||||
|
||||
static IrInstruction *ir_build_const_void(IrBuilder *irb, Scope *scope, AstNode *source_node) {
|
||||
IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node);
|
||||
const_instruction->base.value->type = irb->codegen->builtin_types.entry_void;
|
||||
const_instruction->base.value->special = ConstValSpecialStatic;
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
memprof_intern_count.x_void += 1;
|
||||
#endif
|
||||
IrInstructionConst *const_instruction = ir_create_instruction_noval<IrInstructionConst>(irb, scope, source_node);
|
||||
ir_instruction_append(irb->current_basic_block, &const_instruction->base);
|
||||
const_instruction->base.value = &irb->codegen->intern_values.x_void;
|
||||
return &const_instruction->base;
|
||||
}
|
||||
|
||||
static IrInstruction *ir_build_const_undefined(IrBuilder *irb, Scope *scope, AstNode *source_node) {
|
||||
IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node);
|
||||
const_instruction->base.value->special = ConstValSpecialUndef;
|
||||
const_instruction->base.value->type = irb->codegen->builtin_types.entry_undef;
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
memprof_intern_count.x_undefined += 1;
|
||||
#endif
|
||||
IrInstructionConst *const_instruction = ir_create_instruction_noval<IrInstructionConst>(irb, scope, source_node);
|
||||
ir_instruction_append(irb->current_basic_block, &const_instruction->base);
|
||||
const_instruction->base.value = &irb->codegen->intern_values.x_undefined;
|
||||
return &const_instruction->base;
|
||||
}
|
||||
|
||||
@ -1252,9 +1274,12 @@ static IrInstruction *ir_build_const_bigfloat(IrBuilder *irb, Scope *scope, AstN
|
||||
}
|
||||
|
||||
static IrInstruction *ir_build_const_null(IrBuilder *irb, Scope *scope, AstNode *source_node) {
|
||||
IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node);
|
||||
const_instruction->base.value->type = irb->codegen->builtin_types.entry_null;
|
||||
const_instruction->base.value->special = ConstValSpecialStatic;
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
memprof_intern_count.x_null += 1;
|
||||
#endif
|
||||
IrInstructionConst *const_instruction = ir_create_instruction_noval<IrInstructionConst>(irb, scope, source_node);
|
||||
ir_instruction_append(irb->current_basic_block, &const_instruction->base);
|
||||
const_instruction->base.value = &irb->codegen->intern_values.x_null;
|
||||
return &const_instruction->base;
|
||||
}
|
||||
|
||||
@ -11113,6 +11138,12 @@ static IrInstruction *ir_const(IrAnalyze *ira, IrInstruction *old_instruction, Z
|
||||
return new_instruction;
|
||||
}
|
||||
|
||||
static IrInstruction *ir_const_noval(IrAnalyze *ira, IrInstruction *old_instruction) {
|
||||
IrInstructionConst *const_instruction = ir_create_instruction_noval<IrInstructionConst>(&ira->new_irb,
|
||||
old_instruction->scope, old_instruction->source_node);
|
||||
return &const_instruction->base;
|
||||
}
|
||||
|
||||
static IrInstruction *ir_resolve_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value,
|
||||
ZigType *wanted_type, CastOp cast_op)
|
||||
{
|
||||
@ -11429,13 +11460,21 @@ static IrInstruction *ir_const_undef(IrAnalyze *ira, IrInstruction *source_instr
|
||||
}
|
||||
|
||||
static IrInstruction *ir_const_unreachable(IrAnalyze *ira, IrInstruction *source_instruction) {
|
||||
IrInstruction *result = ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_unreachable);
|
||||
result->value->special = ConstValSpecialStatic;
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
memprof_intern_count.x_unreachable += 1;
|
||||
#endif
|
||||
IrInstruction *result = ir_const_noval(ira, source_instruction);
|
||||
result->value = &ira->codegen->intern_values.x_unreachable;
|
||||
return result;
|
||||
}
|
||||
|
||||
static IrInstruction *ir_const_void(IrAnalyze *ira, IrInstruction *source_instruction) {
|
||||
return ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_void);
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
memprof_intern_count.x_void += 1;
|
||||
#endif
|
||||
IrInstruction *result = ir_const_noval(ira, source_instruction);
|
||||
result->value = &ira->codegen->intern_values.x_void;
|
||||
return result;
|
||||
}
|
||||
|
||||
static IrInstruction *ir_const_unsigned(IrAnalyze *ira, IrInstruction *source_instruction, uint64_t value) {
|
||||
|
||||
@ -6,6 +6,8 @@
|
||||
|
||||
#ifdef ZIG_ENABLE_MEM_PROFILE
|
||||
|
||||
MemprofInternCount memprof_intern_count;
|
||||
|
||||
static bool str_eql_str(const char *a, const char *b) {
|
||||
return strcmp(a, b) == 0;
|
||||
}
|
||||
@ -29,7 +31,6 @@ ZigList<const char *> unknown_names = {};
|
||||
HashMap<const char *, CountAndSize, str_hash, str_eql_str> usage_table = {};
|
||||
bool table_active = false;
|
||||
|
||||
|
||||
static const char *get_default_name(const char *name_or_null, size_t type_size) {
|
||||
if (name_or_null != nullptr) return name_or_null;
|
||||
if (type_size >= unknown_names.length) {
|
||||
@ -134,6 +135,12 @@ void memprof_dump_stats(FILE *file) {
|
||||
|
||||
list.deinit();
|
||||
table_active = true;
|
||||
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "undefined: interned %zu times\n", memprof_intern_count.x_undefined);
|
||||
fprintf(stderr, "void: interned %zu times\n", memprof_intern_count.x_void);
|
||||
fprintf(stderr, "null: interned %zu times\n", memprof_intern_count.x_null);
|
||||
fprintf(stderr, "unreachable: interned %zu times\n", memprof_intern_count.x_unreachable);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -13,6 +13,14 @@
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
|
||||
struct MemprofInternCount {
|
||||
size_t x_undefined;
|
||||
size_t x_void;
|
||||
size_t x_null;
|
||||
size_t x_unreachable;
|
||||
};
|
||||
extern MemprofInternCount memprof_intern_count;
|
||||
|
||||
void memprof_init(void);
|
||||
|
||||
void memprof_alloc(const char *name, size_t item_count, size_t type_size);
|
||||
|
||||
@ -121,18 +121,18 @@ SplitIterator memSplit(Slice<uint8_t> buffer, Slice<uint8_t> split_bytes) {
|
||||
|
||||
void zig_pretty_print_bytes(FILE *f, double n) {
|
||||
if (n > 1024.0 * 1024.0 * 1024.0) {
|
||||
fprintf(f, "%.02f GiB", n / 1024.0 / 1024.0 / 1024.0);
|
||||
fprintf(f, "%.03f GiB", n / 1024.0 / 1024.0 / 1024.0);
|
||||
return;
|
||||
}
|
||||
if (n > 1024.0 * 1024.0) {
|
||||
fprintf(f, "%.02f MiB", n / 1024.0 / 1024.0);
|
||||
fprintf(f, "%.03f MiB", n / 1024.0 / 1024.0);
|
||||
return;
|
||||
}
|
||||
if (n > 1024.0) {
|
||||
fprintf(f, "%.02f KiB", n / 1024.0);
|
||||
fprintf(f, "%.03f KiB", n / 1024.0);
|
||||
return;
|
||||
}
|
||||
fprintf(f, "%.02f bytes", n );
|
||||
fprintf(f, "%.03f bytes", n );
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user