aboutsummaryrefslogtreecommitdiff
path: root/src/codegen
diff options
context:
space:
mode:
Diffstat (limited to 'src/codegen')
-rw-r--r--src/codegen/codegen.cpp1
-rw-r--r--src/codegen/print_llvm.cpp156
-rw-r--r--src/codegen/ssa.cpp218
3 files changed, 264 insertions, 111 deletions
diff --git a/src/codegen/codegen.cpp b/src/codegen/codegen.cpp
index 87aaab101..9999c7cdb 100644
--- a/src/codegen/codegen.cpp
+++ b/src/codegen/codegen.cpp
@@ -278,6 +278,7 @@ void ssa_gen_tree(ssaGen *s) {
}
{ // NOTE(bill): Setup type_info data
+ // TODO(bill): Try and make a lot of this constant aggregate literals in LLVM IR
ssaValue *type_info_data = NULL;
ssaValue *type_info_member_data = NULL;
diff --git a/src/codegen/print_llvm.cpp b/src/codegen/print_llvm.cpp
index 3957b0e36..3ae53e596 100644
--- a/src/codegen/print_llvm.cpp
+++ b/src/codegen/print_llvm.cpp
@@ -263,7 +263,32 @@ void ssa_print_type(ssaFileBuffer *f, ssaModule *m, Type *t) {
}
}
-void ssa_print_value(ssaFileBuffer *f, ssaModule *m, ssaValue *value, Type *type_hint);
+void ssa_print_exact_value(ssaFileBuffer *f, ssaModule *m, ExactValue value, Type *type);
+
+void ssa_print_compound_element(ssaFileBuffer *f, ssaModule *m, ExactValue v, Type *elem_type) {
+ if (v.kind == ExactValue_Invalid) {
+ ssa_fprintf(f, "zeroinitializer");
+ } else if (v.kind == ExactValue_String) {
+ // HACK NOTE(bill): This is a hack but it works because strings are created at the very end
+ // of the .ll file
+ ssaValue *str_array = ssa_add_global_string_array(m, v.value_string);
+
+ ssa_fprintf(f, "{i8* getelementptr inbounds (");
+ ssa_print_type(f, m, str_array->Global.entity->type);
+ ssa_fprintf(f, ", ");
+ ssa_print_type(f, m, str_array->Global.entity->type);
+ ssa_fprintf(f, "* ");
+ ssa_print_encoded_global(f, str_array->Global.entity->token.string, false);
+ ssa_fprintf(f, ", ");
+ ssa_print_type(f, m, t_int);
+ ssa_fprintf(f, " 0, i32 0), ");
+ ssa_print_type(f, m, t_int);
+ ssa_fprintf(f, " %lld}", cast(i64)v.value_string.len);
+
+ } else {
+ ssa_print_exact_value(f, m, v, elem_type);
+ }
+}
void ssa_print_exact_value(ssaFileBuffer *f, ssaModule *m, ExactValue value, Type *type) {
type = base_type(type);
@@ -324,14 +349,19 @@ void ssa_print_exact_value(ssaFileBuffer *f, ssaModule *m, ExactValue value, Typ
break;
case ExactValue_Compound: {
- // ssa_fprintf(f, "%s", (value.value_bool ? "true" : "false"));
type = base_type(type);
if (is_type_array(type)) {
+ ast_node(cl, CompoundLit, value.value_compound);
+ isize elem_count = cl->elems != NULL ? gb_array_count(cl->elems) : 0;
+ if (elem_count == 0) {
+ ssa_fprintf(f, "zeroinitializer");
+ break;
+ }
+
ssa_fprintf(f, "[");
Type *elem_type = type->Array.elem;
- ast_node(cl, CompoundLit, value.value_compound);
- for (isize i = 0; i < type->Array.count; i++) {
+ for (isize i = 0; i < elem_count; i++) {
if (i > 0) {
ssa_fprintf(f, ", ");
}
@@ -340,10 +370,55 @@ void ssa_print_exact_value(ssaFileBuffer *f, ssaModule *m, ExactValue value, Typ
TypeAndValue *tav = type_and_value_of_expression(m->info, cl->elems[i]);
GB_ASSERT(tav != NULL);
- ssa_print_exact_value(f, m, tav->value, elem_type);
+ ssa_print_compound_element(f, m, tav->value, elem_type);
+ }
+ for (isize i = elem_count; i < type->Array.count; i++) {
+ if (i >= elem_count) {
+ ssa_fprintf(f, ", ");
+ }
+ ssa_print_type(f, m, elem_type);
+ ssa_fprintf(f, " zeroinitializer");
}
ssa_fprintf(f, "]");
+ } else if (is_type_vector(type)) {
+ ast_node(cl, CompoundLit, value.value_compound);
+ isize elem_count = cl->elems != NULL ? gb_array_count(cl->elems) : 0;
+ if (elem_count == 0) {
+ ssa_fprintf(f, "zeroinitializer");
+ break;
+ }
+
+ ssa_fprintf(f, "<");
+ Type *elem_type = type->Vector.elem;
+
+ if (elem_count == 1 && type->Vector.count > 1) {
+ TypeAndValue *tav = type_and_value_of_expression(m->info, cl->elems[0]);
+ GB_ASSERT(tav != NULL);
+
+ for (isize i = 0; i < type->Vector.count; i++) {
+ if (i > 0) {
+ ssa_fprintf(f, ", ");
+ }
+ ssa_print_type(f, m, elem_type);
+ ssa_fprintf(f, " ");
+ ssa_print_compound_element(f, m, tav->value, elem_type);
+ }
+ } else {
+ for (isize i = 0; i < elem_count; i++) {
+ if (i > 0) {
+ ssa_fprintf(f, ", ");
+ }
+ ssa_print_type(f, m, elem_type);
+ ssa_fprintf(f, " ");
+
+ TypeAndValue *tav = type_and_value_of_expression(m->info, cl->elems[i]);
+ GB_ASSERT(tav != NULL);
+ ssa_print_compound_element(f, m, tav->value, elem_type);
+ }
+ }
+
+ ssa_fprintf(f, ">");
} else if (is_type_struct(type)) {
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&m->tmp_arena);
defer (gb_temp_arena_memory_end(tmp));
@@ -361,7 +436,7 @@ void ssa_print_exact_value(ssaFileBuffer *f, ssaModule *m, ExactValue value, Typ
if (cl->elems[0]->kind == AstNode_FieldValue) {
- isize elem_count = gb_array_count(cl->elems);
+ isize elem_count = cl->elems != NULL ? gb_array_count(cl->elems) : 0;
for (isize i = 0; i < elem_count; i++) {
ast_node(fv, FieldValue, cl->elems[i]);
String name = fv->field->Ident.string;
@@ -401,30 +476,7 @@ void ssa_print_exact_value(ssaFileBuffer *f, ssaModule *m, ExactValue value, Typ
ssa_print_type(f, m, elem_type);
ssa_fprintf(f, " ");
-
- ExactValue v = values[i];
- if (v.kind == ExactValue_Invalid) {
- ssa_fprintf(f, "zeroinitializer");
- } else if (v.kind == ExactValue_String) {
- // HACK NOTE(bill): This is a hack but it works because strings are created at the very end
- // of the .ll file
- ssaValue *str_array = ssa_add_global_string_array(m, v.value_string);
-
- ssa_fprintf(f, "{i8* getelementptr inbounds (");
- ssa_print_type(f, m, str_array->Global.entity->type);
- ssa_fprintf(f, ", ");
- ssa_print_type(f, m, str_array->Global.entity->type);
- ssa_fprintf(f, "* ");
- ssa_print_encoded_global(f, str_array->Global.entity->token.string, false);
- ssa_fprintf(f, ", ");
- ssa_print_type(f, m, t_int);
- ssa_fprintf(f, " 0, i32 0), ");
- ssa_print_type(f, m, t_int);
- ssa_fprintf(f, " %lld}", cast(i64)v.value_string.len);
-
- } else {
- ssa_print_exact_value(f, m, v, elem_type);
- }
+ ssa_print_compound_element(f, m, values[i], elem_type);
}
@@ -455,9 +507,37 @@ void ssa_print_value(ssaFileBuffer *f, ssaModule *m, ssaValue *value, Type *type
return;
}
switch (value->kind) {
+ default: GB_PANIC("Unknown ssaValue kind"); break;
+
case ssaValue_Constant:
ssa_print_exact_value(f, m, value->Constant.value, type_hint);
break;
+
+ case ssaValue_ConstantSlice: {
+ auto *cs = &value->ConstantSlice;
+ if (cs->backing_array == NULL || cs->count == 0) {
+ ssa_fprintf(f, "zeroinitializer");
+ } else {
+ Type *at = base_type(type_deref(ssa_type(cs->backing_array)));
+ Type *et = at->Array.elem;
+ ssa_fprintf(f, "{");
+ ssa_print_type(f, m, et);
+ ssa_fprintf(f, "* getelementptr inbounds (");
+ ssa_print_type(f, m, at);
+ ssa_fprintf(f, ", ");
+ ssa_print_type(f, m, at);
+ ssa_fprintf(f, "* ");
+ ssa_print_value(f, m, cs->backing_array, at);
+ ssa_fprintf(f, ", ");
+ ssa_print_type(f, m, t_int);
+ ssa_fprintf(f, " 0, i32 0), ");
+ ssa_print_type(f, m, t_int);
+ ssa_fprintf(f, " %lld, ", cs->count);
+ ssa_print_type(f, m, t_int);
+ ssa_fprintf(f, " %lld}", cs->count);
+ }
+ } break;
+
case ssaValue_TypeName:
ssa_print_encoded_local(f, value->TypeName.name);
break;
@@ -467,21 +547,7 @@ void ssa_print_value(ssaFileBuffer *f, ssaModule *m, ssaValue *value, Type *type
if (scope != NULL) {
in_global_scope = scope->is_global || scope->is_init;
}
- // if (type_hint != NULL && is_type_string(type_hint)) {
- // ssa_fprintf(f, "{i8* getelementptr inbounds (");
- // ssa_print_type(f, m, value->Global.entity->type);
- // ssa_fprintf(f, ", ");
- // ssa_print_type(f, m, value->Global.entity->type);
- // ssa_fprintf(f, "* ");
- // ssa_print_encoded_global(f, value->Global.entity->token.string, in_global_scope);
- // ssa_fprintf(f, ", ");
- // ssa_print_type(f, m, t_int);
- // ssa_fprintf(f, " 0, i32 0), ");
- // ssa_print_type(f, m, t_int);
- // ssa_fprintf(f, " %lld}", 0);
- // } else {
- ssa_print_encoded_global(f, value->Global.entity->token.string, in_global_scope);
- // }
+ ssa_print_encoded_global(f, value->Global.entity->token.string, in_global_scope);
} break;
case ssaValue_Param:
ssa_print_encoded_local(f, value->Param.entity->token.string);
diff --git a/src/codegen/ssa.cpp b/src/codegen/ssa.cpp
index 7cc23e2ce..e8aa3bebf 100644
--- a/src/codegen/ssa.cpp
+++ b/src/codegen/ssa.cpp
@@ -62,9 +62,9 @@ struct ssaModule {
Map<String> type_names; // Key: Type *
Map<ssaDebugInfo *> debug_info; // Key: Unique pointer
i32 global_string_index;
+ i32 global_array_index; // For ConstantSlice
gbArray(ssaValue *) procs; // NOTE(bill): Procedures to generate
- gbArray(ssaValue *) const_compound_lits;
};
@@ -144,6 +144,7 @@ struct ssaProcedure {
SSA_INSTR_KIND(Load), \
SSA_INSTR_KIND(GetElementPtr), \
SSA_INSTR_KIND(ExtractValue), \
+ SSA_INSTR_KIND(InsertValue), \
SSA_INSTR_KIND(Conv), \
SSA_INSTR_KIND(Br), \
SSA_INSTR_KIND(Ret), \
@@ -239,6 +240,11 @@ struct ssaInstr {
i32 index;
} ExtractValue;
struct {
+ ssaValue *value;
+ ssaValue *elem;
+ ssaValue *index;
+ } InsertValue;
+ struct {
ssaConvKind kind;
ssaValue *value;
Type *from, *to;
@@ -291,7 +297,7 @@ enum ssaValueKind {
ssaValue_Invalid,
ssaValue_Constant,
- ssaValue_ConstantArray,
+ ssaValue_ConstantSlice,
ssaValue_TypeName,
ssaValue_Global,
ssaValue_Param,
@@ -314,8 +320,9 @@ struct ssaValue {
} Constant;
struct {
Type *type;
- gbArray(ssaValue *) values;
- } ConstantArray;
+ ssaValue *backing_array;
+ i64 count;
+ } ConstantSlice;
struct {
String name;
Type * type;
@@ -415,7 +422,6 @@ void ssa_init_module(ssaModule *m, Checker *c) {
map_init(&m->debug_info, gb_heap_allocator());
map_init(&m->type_names, gb_heap_allocator());
gb_array_init(m->procs, gb_heap_allocator());
- gb_array_init(m->const_compound_lits, gb_heap_allocator());
// Default states
m->stmt_state_flags = 0;
@@ -480,7 +486,6 @@ void ssa_destroy_module(ssaModule *m) {
map_destroy(&m->type_names);
map_destroy(&m->debug_info);
gb_array_free(m->procs);
- gb_array_free(m->const_compound_lits);
gb_arena_free(&m->arena);
}
@@ -498,6 +503,8 @@ Type *ssa_type(ssaInstr *instr) {
return instr->GetElementPtr.result_type;
case ssaInstr_ExtractValue:
return instr->ExtractValue.result_type;
+ case ssaInstr_InsertValue:
+ return ssa_type(instr->InsertValue.value);
case ssaInstr_BinaryOp:
return instr->BinaryOp.type;
case ssaInstr_Conv:
@@ -531,6 +538,8 @@ Type *ssa_type(ssaValue *value) {
switch (value->kind) {
case ssaValue_Constant:
return value->Constant.type;
+ case ssaValue_ConstantSlice:
+ return value->ConstantSlice.type;
case ssaValue_TypeName:
return value->TypeName.type;
case ssaValue_Global:
@@ -697,6 +706,15 @@ ssaValue *ssa_make_instr_extract_value(ssaProcedure *p, ssaValue *address, i32 i
// GB_ASSERT(et->kind == Type_Struct || et->kind == Type_Array || et->kind == Type_Tuple);
return v;
}
+ssaValue *ssa_make_instr_insert_value(ssaProcedure *p, ssaValue *value, ssaValue *elem, ssaValue *index) {
+ Type *t = ssa_type(value);
+ GB_ASSERT(is_type_array(t) || is_type_struct(t));
+ ssaValue *v = ssa_alloc_instr(p, ssaInstr_InsertValue);
+ v->Instr.InsertValue.value = value;
+ v->Instr.InsertValue.elem = elem;
+ v->Instr.InsertValue.index = index;
+ return v;
+}
ssaValue *ssa_make_instr_binary_op(ssaProcedure *p, Token op, ssaValue *left, ssaValue *right, Type *type) {
@@ -803,6 +821,15 @@ ssaValue *ssa_make_value_constant(gbAllocator a, Type *type, ExactValue value) {
return v;
}
+
+ssaValue *ssa_make_value_constant_slice(gbAllocator a, Type *type, ssaValue *backing_array, i64 count) {
+ ssaValue *v = ssa_alloc_value(a, ssaValue_ConstantSlice);
+ v->ConstantSlice.type = type;
+ v->ConstantSlice.backing_array = backing_array;
+ v->ConstantSlice.count = count;
+ return v;
+}
+
ssaValue *ssa_make_const_int(gbAllocator a, i64 i) {
return ssa_make_value_constant(a, t_int, make_exact_value_integer(i));
}
@@ -817,13 +844,39 @@ ssaValue *ssa_make_const_bool(gbAllocator a, b32 b) {
}
ssaValue *ssa_add_module_constant(ssaModule *m, Type *type, ExactValue value) {
- ssaValue *v = ssa_make_value_constant(m->allocator, type, value);
+ if (is_type_slice(type)) {
+ ast_node(cl, CompoundLit, value.value_compound);
+ gbAllocator a = m->allocator;
+
+ isize count = 0;
+ if (cl->elems) {
+ count = gb_array_count(cl->elems);
+ }
+ if (count > 0) {
+ Type *elem = base_type(type)->Slice.elem;
+ Type *t = make_type_array(a, elem, count);
+ ssaValue *backing_array = ssa_add_module_constant(m, t, value);
- if (!is_type_constant_type(type)) {
- gb_array_append(m->const_compound_lits, v);
+
+ isize max_len = 7+8+1;
+ u8 *str = cast(u8 *)gb_alloc_array(a, u8, max_len);
+ isize len = gb_snprintf(cast(char *)str, max_len, "__csba$%x", m->global_array_index);
+ m->global_array_index++;
+
+ String name = make_string(str, len-1);
+
+ Entity *e = make_entity_constant(a, NULL, make_token_ident(name), t, value);
+ ssaValue *g = ssa_make_value_global(a, e, backing_array);
+ ssa_module_add_value(m, e, g);
+ map_set(&m->members, hash_string(name), g);
+
+ return ssa_make_value_constant_slice(a, type, g, count);
+ } else {
+ return ssa_make_value_constant_slice(a, type, NULL, 0);
+ }
}
- return v;
+ return ssa_make_value_constant(m->allocator, type, value);
}
@@ -1547,7 +1600,7 @@ ssaValue *ssa_add_local_slice(ssaProcedure *proc, Type *slice_type, ssaValue *ba
ssaValue *ssa_add_global_string_array(ssaModule *m, String string) {
gbAllocator a = m->allocator;
- isize max_len = 4+8+1;
+ isize max_len = 6+8+1;
u8 *str = cast(u8 *)gb_alloc_array(a, u8, max_len);
isize len = gb_snprintf(cast(char *)str, max_len, "__str$%x", m->global_string_index);
m->global_string_index++;
@@ -2119,33 +2172,45 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
case Type_Slice: et = bt->Slice.elem; break;
}
+ auto is_elem_const = [](ssaModule *m, AstNode *elem) -> b32 {
+ if (elem->kind == AstNode_FieldValue) {
+ elem = elem->FieldValue.value;
+ }
+ TypeAndValue *tav = type_and_value_of_expression(m->info, elem);
+ GB_ASSERT(tav != NULL);
+ return tav->value.kind != ExactValue_Invalid;
+ };
+
switch (bt->kind) {
default: GB_PANIC("Unknown CompoundLit type: %s", type_to_string(type)); break;
case Type_Vector: {
+ ssaValue *result = ssa_add_module_constant(proc->module, type, make_exact_value_compound(expr));
+ if (cl->elems != NULL) {
+ for (isize index = 0; index < gb_array_count(cl->elems); index++) {
+ AstNode *elem = cl->elems[index];
+ if (is_elem_const(proc->module, elem)) {
+ continue;
+ }
+ ssaValue *field_elem = ssa_build_expr(proc, elem);
+ Type *t = ssa_type(field_elem);
+ GB_ASSERT(t->kind != Type_Tuple);
+ ssaValue *ev = ssa_emit_conv(proc, field_elem, et);
+ ssaValue *i = ssa_make_const_int(proc->module->allocator, index);
+ result = ssa_emit(proc, ssa_make_instr_insert_element(proc, result, ev, i));
+ }
- ssaValue *result = ssa_emit_load(proc, v);
- for (isize index = 0; index < gb_array_count(cl->elems); index++) {
- AstNode *elem = cl->elems[index];
- ssaValue *field_elem = ssa_build_expr(proc, elem);
- Type *t = ssa_type(field_elem);
- GB_ASSERT(t->kind != Type_Tuple);
- ssaValue *ev = ssa_emit_conv(proc, field_elem, et);
- ssaValue *i = ssa_make_const_int(proc->module->allocator, index);
- result = ssa_emit(proc, ssa_make_instr_insert_element(proc, result, ev, i));
- }
-
- if (gb_array_count(cl->elems) == 1 && bt->Vector.count > 1) {
- isize index_count = bt->Vector.count;
- i32 *indices = gb_alloc_array(proc->module->allocator, i32, index_count);
- for (isize i = 0; i < index_count; i++) {
- indices[i] = 0;
+ if (gb_array_count(cl->elems) == 1 && bt->Vector.count > 1) {
+ isize index_count = bt->Vector.count;
+ i32 *indices = gb_alloc_array(proc->module->allocator, i32, index_count);
+ for (isize i = 0; i < index_count; i++) {
+ indices[i] = 0;
+ }
+ ssaValue *sv = ssa_emit(proc, ssa_make_instr_shuffle_vector(proc, result, indices, index_count));
+ ssa_emit_store(proc, v, sv);
+ return ssa_emit_load(proc, v);
}
- ssaValue *sv = ssa_emit(proc, ssa_make_instr_shuffle_vector(proc, result, indices, index_count));
- ssa_emit_store(proc, v, sv);
- return ssa_emit_load(proc, v);
}
-
return result;
} break;
@@ -2153,18 +2218,24 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
GB_ASSERT(is_type_struct(bt));
auto *st = &bt->Record;
if (cl->elems != NULL && gb_array_count(cl->elems) > 0) {
+ ssa_emit_store(proc, v, ssa_add_module_constant(proc->module, type, make_exact_value_compound(expr)));
gb_for_array(field_index, cl->elems) {
- isize index = field_index;
- AstNode *elem = cl->elems[index];
+ AstNode *elem = cl->elems[field_index];
+ if (is_elem_const(proc->module, elem)) {
+ continue;
+ }
+
ssaValue *field_expr = NULL;
Entity *field = NULL;
+ isize index = field_index;
if (elem->kind == AstNode_FieldValue) {
- ast_node(kv, FieldValue, elem);
- Selection sel = lookup_field(proc->module->allocator, bt, kv->field->Ident.string, false);
+ ast_node(fv, FieldValue, elem);
+ Selection sel = lookup_field(proc->module->allocator, bt, fv->field->Ident.string, false);
index = sel.index[0];
- field_expr = ssa_build_expr(proc, kv->value);
+ field_expr = ssa_build_expr(proc, fv->value);
} else {
+ TypeAndValue *tav = type_and_value_of_expression(proc->module->info, elem);
Selection sel = lookup_field(proc->module->allocator, bt, st->fields_in_src_order[field_index]->token.string, false);
index = sel.index[0];
field_expr = ssa_build_expr(proc, elem);
@@ -2182,47 +2253,62 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
}
} break;
case Type_Array: {
- gb_for_array(i, cl->elems) {
- AstNode *elem = cl->elems[i];
- ssaValue *field_expr = ssa_build_expr(proc, elem);
- Type *t = ssa_type(field_expr);
- GB_ASSERT(t->kind != Type_Tuple);
- ssaValue *ev = ssa_emit_conv(proc, field_expr, et);
- ssaValue *gep = ssa_emit_struct_gep(proc, v, i, et);
- ssa_emit_store(proc, gep, ev);
+ if (cl->elems != NULL && gb_array_count(cl->elems) > 0) {
+ ssa_emit_store(proc, v, ssa_add_module_constant(proc->module, type, make_exact_value_compound(expr)));
+ gb_for_array(i, cl->elems) {
+ AstNode *elem = cl->elems[i];
+ if (is_elem_const(proc->module, elem)) {
+ continue;
+ }
+ ssaValue *field_expr = ssa_build_expr(proc, elem);
+ Type *t = ssa_type(field_expr);
+ GB_ASSERT(t->kind != Type_Tuple);
+ ssaValue *ev = ssa_emit_conv(proc, field_expr, et);
+ ssaValue *gep = ssa_emit_struct_gep(proc, v, i, et);
+ ssa_emit_store(proc, gep, ev);
+ }
}
} break;
case Type_Slice: {
- i64 count = gb_array_count(cl->elems);
- Type *elem_type = bt->Slice.elem;
- Type *elem_ptr_type = make_type_pointer(proc->module->allocator, elem_type);
- ssaValue *array = ssa_add_local_generated(proc, make_type_array(proc->module->allocator, elem_type, count));
-
- gb_for_array(i, cl->elems) {
- AstNode *elem = cl->elems[i];
- ssaValue *field_expr = ssa_build_expr(proc, elem);
- Type *t = ssa_type(field_expr);
- GB_ASSERT(t->kind != Type_Tuple);
- ssaValue *ev = ssa_emit_conv(proc, field_expr, elem_type);
- ssaValue *gep = ssa_emit_struct_gep(proc, array, i, elem_ptr_type);
- ssa_emit_store(proc, gep, ev);
- }
+ if (cl->elems != NULL && gb_array_count(cl->elems) > 0) {
+ Type *elem_type = bt->Slice.elem;
+ Type *elem_ptr_type = make_type_pointer(proc->module->allocator, elem_type);
+ Type *elem_ptr_ptr_type = make_type_pointer(proc->module->allocator, elem_ptr_type);
+ Type *t_int_ptr = make_type_pointer(proc->module->allocator, t_int);
+ ssaValue *slice = ssa_add_module_constant(proc->module, type, make_exact_value_compound(expr));
+ GB_ASSERT(slice->kind == ssaValue_ConstantSlice);
+
+ ssaValue *data = ssa_emit_struct_gep(proc, slice->ConstantSlice.backing_array, v_zero32, elem_ptr_type);
+
+ gb_for_array(i, cl->elems) {
+ AstNode *elem = cl->elems[i];
+ if (is_elem_const(proc->module,elem)) {
+ continue;
+ }
- ssaValue *elem = ssa_array_elem(proc, array);
- ssaValue *len = ssa_array_len(proc, ssa_emit_load(proc, array));
- ssaValue *gep0 = ssa_emit_struct_gep(proc, v, v_zero32, ssa_type(elem));
- ssaValue *gep1 = ssa_emit_struct_gep(proc, v, v_one32, t_int);
- ssaValue *gep2 = ssa_emit_struct_gep(proc, v, v_two32, t_int);
+ ssaValue *field_expr = ssa_build_expr(proc, elem);
+ Type *t = ssa_type(field_expr);
+ GB_ASSERT(t->kind != Type_Tuple);
+ ssaValue *ev = ssa_emit_conv(proc, field_expr, elem_type);
+ ssaValue *offset = ssa_emit_ptr_offset(proc, data, ssa_make_const_int(proc->module->allocator, i));
+ ssa_emit_store(proc, offset, ev);
+ }
- ssa_emit_store(proc, gep0, elem);
- ssa_emit_store(proc, gep1, len);
- ssa_emit_store(proc, gep2, len);
+ ssaValue *gep0 = ssa_emit_struct_gep(proc, v, v_zero32, elem_ptr_ptr_type);
+ ssaValue *gep1 = ssa_emit_struct_gep(proc, v, v_one32, t_int_ptr);
+ ssaValue *gep2 = ssa_emit_struct_gep(proc, v, v_two32, t_int_ptr);
+
+ ssa_emit_store(proc, gep0, data);
+ ssa_emit_store(proc, gep1, ssa_make_const_int(proc->module->allocator, slice->ConstantSlice.count));
+ ssa_emit_store(proc, gep2, ssa_make_const_int(proc->module->allocator, slice->ConstantSlice.count));
+ }
} break;
}
return ssa_emit_load(proc, v);
case_end;
+
case_ast_node(ce, CallExpr, expr);
AstNode *p = unparen_expr(ce->proc);
if (p->kind == AstNode_Ident) {