Skip to content

Commit

Permalink
make undefined as a constant value lazy
Browse files Browse the repository at this point in the history
closes #268
  • Loading branch information
andrewrk committed Apr 23, 2017
1 parent 2ed4707 commit 6de33de
Show file tree
Hide file tree
Showing 11 changed files with 139 additions and 93 deletions.
12 changes: 10 additions & 2 deletions src/all_types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,17 @@ struct ConstStructValue {
ConstParent parent;
};

enum ConstArraySpecial {
ConstArraySpecialNone,
ConstArraySpecialUndef,
};

struct ConstArrayValue {
ConstExprValue *elements;
ConstParent parent;
ConstArraySpecial special;
struct {
ConstExprValue *elements;
ConstParent parent;
} s_none;
};

enum ConstPtrSpecial {
Expand Down
76 changes: 45 additions & 31 deletions src/analyze.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2727,7 +2727,7 @@ void analyze_fn_ir(CodeGen *g, FnTableEntry *fn_table_entry, AstNode *return_typ

if (g->verbose) {
fprintf(stderr, "{ // (analyzed)\n");
ir_print(stderr, &fn_table_entry->analyzed_executable, 4);
ir_print(g, stderr, &fn_table_entry->analyzed_executable, 4);
fprintf(stderr, "}\n");
}

Expand Down Expand Up @@ -2766,9 +2766,9 @@ static void analyze_fn_body(CodeGen *g, FnTableEntry *fn_table_entry) {
}
if (g->verbose) {
fprintf(stderr, "\n");
ast_render(stderr, fn_table_entry->body_node, 4);
ast_render(g, stderr, fn_table_entry->body_node, 4);
fprintf(stderr, "\n{ // (IR)\n");
ir_print(stderr, &fn_table_entry->ir_executable, 4);
ir_print(g, stderr, &fn_table_entry->ir_executable, 4);
fprintf(stderr, "}\n");
}

Expand Down Expand Up @@ -3355,10 +3355,10 @@ bool type_requires_comptime(TypeTableEntry *type_entry) {
void init_const_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) {
const_val->special = ConstValSpecialStatic;
const_val->type = get_array_type(g, g->builtin_types.entry_u8, buf_len(str));
const_val->data.x_array.elements = allocate<ConstExprValue>(buf_len(str));
const_val->data.x_array.s_none.elements = allocate<ConstExprValue>(buf_len(str));

for (size_t i = 0; i < buf_len(str); i += 1) {
ConstExprValue *this_char = &const_val->data.x_array.elements[i];
ConstExprValue *this_char = &const_val->data.x_array.s_none.elements[i];
this_char->special = ConstValSpecialStatic;
this_char->type = g->builtin_types.entry_u8;
bignum_init_unsigned(&this_char->data.x_bignum, (uint8_t)buf_ptr(str)[i]);
Expand All @@ -3377,14 +3377,14 @@ void init_const_c_str_lit(CodeGen *g, ConstExprValue *const_val, Buf *str) {
ConstExprValue *array_val = allocate<ConstExprValue>(1);
array_val->special = ConstValSpecialStatic;
array_val->type = get_array_type(g, g->builtin_types.entry_u8, len_with_null);
array_val->data.x_array.elements = allocate<ConstExprValue>(len_with_null);
array_val->data.x_array.s_none.elements = allocate<ConstExprValue>(len_with_null);
for (size_t i = 0; i < buf_len(str); i += 1) {
ConstExprValue *this_char = &array_val->data.x_array.elements[i];
ConstExprValue *this_char = &array_val->data.x_array.s_none.elements[i];
this_char->special = ConstValSpecialStatic;
this_char->type = g->builtin_types.entry_u8;
bignum_init_unsigned(&this_char->data.x_bignum, (uint8_t)buf_ptr(str)[i]);
}
ConstExprValue *null_char = &array_val->data.x_array.elements[len_with_null - 1];
ConstExprValue *null_char = &array_val->data.x_array.s_none.elements[len_with_null - 1];
null_char->special = ConstValSpecialStatic;
null_char->type = g->builtin_types.entry_u8;
bignum_init_unsigned(&null_char->data.x_bignum, 0);
Expand Down Expand Up @@ -3564,19 +3564,7 @@ void init_const_undefined(CodeGen *g, ConstExprValue *const_val) {
TypeTableEntry *wanted_type = const_val->type;
if (wanted_type->id == TypeTableEntryIdArray) {
const_val->special = ConstValSpecialStatic;
size_t elem_count = wanted_type->data.array.len;
const_val->data.x_array.elements = allocate<ConstExprValue>(elem_count);
for (size_t i = 0; i < elem_count; i += 1) {
ConstExprValue *element_val = &const_val->data.x_array.elements[i];
element_val->type = wanted_type->data.array.child_type;
init_const_undefined(g, element_val);
ConstParent *parent = get_const_val_parent(element_val);
if (parent != nullptr) {
parent->id = ConstParentIdArray;
parent->data.p_array.array_val = const_val;
parent->data.p_array.elem_index = i;
}
}
const_val->data.x_array.special = ConstArraySpecialUndef;
} else if (wanted_type->id == TypeTableEntryIdStruct) {
ensure_complete_type(g, wanted_type);

Expand All @@ -3588,7 +3576,7 @@ void init_const_undefined(CodeGen *g, ConstExprValue *const_val) {
field_val->type = wanted_type->data.structure.fields[i].type_entry;
assert(field_val->type);
init_const_undefined(g, field_val);
ConstParent *parent = get_const_val_parent(field_val);
ConstParent *parent = get_const_val_parent(g, field_val);
if (parent != nullptr) {
parent->id = ConstParentIdStruct;
parent->data.p_struct.struct_val = const_val;
Expand Down Expand Up @@ -3802,7 +3790,7 @@ void eval_min_max_value(CodeGen *g, TypeTableEntry *type_entry, ConstExprValue *
}
}

void render_const_value(Buf *buf, ConstExprValue *const_val) {
void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) {
switch (const_val->special) {
case ConstValSpecialRuntime:
buf_appendf(buf, "(runtime value)");
Expand Down Expand Up @@ -3872,15 +3860,15 @@ void render_const_value(Buf *buf, ConstExprValue *const_val) {
case ConstPtrSpecialRef:
case ConstPtrSpecialBaseStruct:
buf_appendf(buf, "&");
render_const_value(buf, const_ptr_pointee(const_val));
render_const_value(g, buf, const_ptr_pointee(g, const_val));
return;
case ConstPtrSpecialBaseArray:
if (const_val->data.x_ptr.data.base_array.is_cstr) {
buf_appendf(buf, "&(c str lit)");
return;
} else {
buf_appendf(buf, "&");
render_const_value(buf, const_ptr_pointee(const_val));
render_const_value(g, buf, const_ptr_pointee(g, const_val));
return;
}
case ConstPtrSpecialHardCodedAddr:
Expand Down Expand Up @@ -3910,14 +3898,19 @@ void render_const_value(Buf *buf, ConstExprValue *const_val) {
TypeTableEntry *child_type = type_entry->data.array.child_type;
uint64_t len = type_entry->data.array.len;

if (const_val->data.x_array.special == ConstArraySpecialUndef) {
buf_append_str(buf, "undefined");
return;
}

// if it's []u8, assume UTF-8 and output a string
if (child_type->id == TypeTableEntryIdInt &&
child_type->data.integral.bit_count == 8 &&
!child_type->data.integral.is_signed)
{
buf_append_char(buf, '"');
for (uint64_t i = 0; i < len; i += 1) {
ConstExprValue *child_value = &const_val->data.x_array.elements[i];
ConstExprValue *child_value = &const_val->data.x_array.s_none.elements[i];
uint64_t big_c = child_value->data.x_bignum.data.x_uint;
assert(big_c <= UINT8_MAX);
uint8_t c = (uint8_t)big_c;
Expand All @@ -3935,8 +3928,8 @@ void render_const_value(Buf *buf, ConstExprValue *const_val) {
for (uint64_t i = 0; i < len; i += 1) {
if (i != 0)
buf_appendf(buf, ",");
ConstExprValue *child_value = &const_val->data.x_array.elements[i];
render_const_value(buf, child_value);
ConstExprValue *child_value = &const_val->data.x_array.s_none.elements[i];
render_const_value(g, buf, child_value);
}
buf_appendf(buf, "}");
return;
Expand All @@ -3954,7 +3947,7 @@ void render_const_value(Buf *buf, ConstExprValue *const_val) {
case TypeTableEntryIdMaybe:
{
if (const_val->data.x_maybe) {
render_const_value(buf, const_val->data.x_maybe);
render_const_value(g, buf, const_val->data.x_maybe);
} else {
buf_appendf(buf, "null");
}
Expand Down Expand Up @@ -4167,11 +4160,32 @@ bool zig_llvm_fn_key_eql(ZigLLVMFnKey a, ZigLLVMFnKey b) {
zig_unreachable();
}

ConstParent *get_const_val_parent(ConstExprValue *value) {
void expand_undef_array(CodeGen *g, ConstExprValue *const_val) {
assert(const_val->type->id == TypeTableEntryIdArray);
if (const_val->data.x_array.special == ConstArraySpecialUndef) {
const_val->data.x_array.special = ConstArraySpecialNone;
size_t elem_count = const_val->type->data.array.len;
const_val->data.x_array.s_none.elements = allocate<ConstExprValue>(elem_count);
for (size_t i = 0; i < elem_count; i += 1) {
ConstExprValue *element_val = &const_val->data.x_array.s_none.elements[i];
element_val->type = const_val->type->data.array.child_type;
init_const_undefined(g, element_val);
ConstParent *parent = get_const_val_parent(g, element_val);
if (parent != nullptr) {
parent->id = ConstParentIdArray;
parent->data.p_array.array_val = const_val;
parent->data.p_array.elem_index = i;
}
}
}
}

ConstParent *get_const_val_parent(CodeGen *g, ConstExprValue *value) {
assert(value->type);
TypeTableEntry *type_entry = value->type;
if (type_entry->id == TypeTableEntryIdArray) {
return &value->data.x_array.parent;
expand_undef_array(g, value);
return &value->data.x_array.s_none.parent;
} else if (type_entry->id == TypeTableEntryIdStruct) {
return &value->data.x_struct.parent;
}
Expand Down
5 changes: 3 additions & 2 deletions src/analyze.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ void eval_min_max_value(CodeGen *g, TypeTableEntry *type_entry, ConstExprValue *
int64_t min_signed_val(TypeTableEntry *type_entry);
uint64_t max_unsigned_val(TypeTableEntry *type_entry);

void render_const_value(Buf *buf, ConstExprValue *const_val);
void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val);
void define_local_param_variables(CodeGen *g, FnTableEntry *fn_table_entry, VariableTableEntry **arg_vars);
void analyze_fn_ir(CodeGen *g, FnTableEntry *fn_table_entry, AstNode *return_type_node);

Expand Down Expand Up @@ -145,8 +145,9 @@ ConstExprValue *create_const_arg_tuple(CodeGen *g, size_t arg_index_start, size_
void init_const_undefined(CodeGen *g, ConstExprValue *const_val);

TypeTableEntry *make_int_type(CodeGen *g, bool is_signed, uint32_t size_in_bits);
ConstParent *get_const_val_parent(ConstExprValue *value);
ConstParent *get_const_val_parent(CodeGen *g, ConstExprValue *value);
FnTableEntry *get_extern_panic_fn(CodeGen *g);
TypeTableEntry *create_enum_tag_type(CodeGen *g, TypeTableEntry *enum_type, TypeTableEntry *int_type);
void expand_undef_array(CodeGen *g, ConstExprValue *const_val);

#endif
9 changes: 6 additions & 3 deletions src/ast_render.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ void ast_print(FILE *f, AstNode *node, int indent) {


struct AstRender {
CodeGen *codegen;
int indent;
int indent_size;
FILE *f;
Expand Down Expand Up @@ -924,8 +925,9 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) {
}


void ast_render(FILE *f, AstNode *node, int indent_size) {
void ast_render(CodeGen *codegen, FILE *f, AstNode *node, int indent_size) {
AstRender ar = {0};
ar.codegen = codegen;
ar.f = f;
ar.indent_size = indent_size;
ar.indent = 0;
Expand Down Expand Up @@ -1030,15 +1032,16 @@ static void ast_render_tld_var(AstRender *ar, Buf *name, TldVar *tld_var) {
} else {
Buf buf = BUF_INIT;
buf_resize(&buf, 0);
render_const_value(&buf, var->value);
render_const_value(ar->codegen, &buf, var->value);
fprintf(ar->f, "%s", buf_ptr(&buf));
}

fprintf(ar->f, ";\n");
}

void ast_render_decls(FILE *f, int indent_size, ImportTableEntry *import) {
void ast_render_decls(CodeGen *codegen, FILE *f, int indent_size, ImportTableEntry *import) {
AstRender ar = {0};
ar.codegen = codegen;
ar.f = f;
ar.indent_size = indent_size;
ar.indent = 0;
Expand Down
4 changes: 2 additions & 2 deletions src/ast_render.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@

void ast_print(FILE *f, AstNode *node, int indent);

void ast_render(FILE *f, AstNode *node, int indent_size);
void ast_render(CodeGen *codegen, FILE *f, AstNode *node, int indent_size);

const char *container_string(ContainerKind kind);

void ast_render_decls(FILE *f, int indent_size, ImportTableEntry *import);
void ast_render_decls(CodeGen *codegen, FILE *f, int indent_size, ImportTableEntry *import);

#endif

13 changes: 9 additions & 4 deletions src/codegen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3051,7 +3051,8 @@ static LLVMValueRef gen_parent_ptr(CodeGen *g, ConstExprValue *val, ConstParent
}

static LLVMValueRef gen_const_ptr_array_recursive(CodeGen *g, ConstExprValue *array_const_val, size_t index) {
ConstParent *parent = &array_const_val->data.x_array.parent;
expand_undef_array(g, array_const_val);
ConstParent *parent = &array_const_val->data.x_array.s_none.parent;
LLVMValueRef base_ptr = gen_parent_ptr(g, array_const_val, parent);

TypeTableEntry *usize = g->builtin_types.entry_usize;
Expand Down Expand Up @@ -3283,9 +3284,13 @@ static LLVMValueRef gen_const_val(CodeGen *g, ConstExprValue *const_val) {
case TypeTableEntryIdArray:
{
uint64_t len = type_entry->data.array.len;
if (const_val->data.x_array.special == ConstArraySpecialUndef) {
return LLVMGetUndef(type_entry->type_ref);
}

LLVMValueRef *values = allocate<LLVMValueRef>(len);
for (uint64_t i = 0; i < len; i += 1) {
ConstExprValue *elem_value = &const_val->data.x_array.elements[i];
ConstExprValue *elem_value = &const_val->data.x_array.s_none.elements[i];
values[i] = gen_const_val(g, elem_value);
}
return LLVMConstArray(LLVMTypeOf(values[0]), values, (unsigned)len);
Expand Down Expand Up @@ -4577,11 +4582,11 @@ static void define_builtin_compile_vars(CodeGen *g) {
ConstExprValue *const_val = allocate<ConstExprValue>(1);
const_val->special = ConstValSpecialStatic;
const_val->type = get_array_type(g, str_type, g->link_libs.length);
const_val->data.x_array.elements = allocate<ConstExprValue>(g->link_libs.length);
const_val->data.x_array.s_none.elements = allocate<ConstExprValue>(g->link_libs.length);
for (size_t i = 0; i < g->link_libs.length; i += 1) {
Buf *link_lib_buf = g->link_libs.at(i);
ConstExprValue *array_val = create_const_str_lit(g, link_lib_buf);
init_const_slice(g, &const_val->data.x_array.elements[i], array_val, 0, buf_len(link_lib_buf), true);
init_const_slice(g, &const_val->data.x_array.s_none.elements[i], array_val, 0, buf_len(link_lib_buf), true);
}

add_compile_var(g, "link_libs", const_val);
Expand Down
Loading

0 comments on commit 6de33de

Please sign in to comment.