diff --git a/src/llvm_backend.hpp b/src/llvm_backend.hpp index 4a056e915..79f0f37e7 100644 --- a/src/llvm_backend.hpp +++ b/src/llvm_backend.hpp @@ -357,8 +357,9 @@ lbValue lb_build_expr(lbProcedure *p, Ast *expr); lbAddr lb_build_addr(lbProcedure *p, Ast *expr); void lb_build_stmt_list(lbProcedure *p, Array const &stmts); -lbValue lb_build_gep(lbProcedure *p, lbValue const &value, i32 index) ; - +lbValue lb_emit_epi(lbProcedure *p, lbValue const &value, isize index); +lbValue lb_emit_epi(lbModule *m, lbValue const &value, isize index); +lbValue lb_emit_array_epi(lbModule *m, lbValue s, isize index); lbValue lb_emit_struct_ep(lbProcedure *p, lbValue s, i32 index); lbValue lb_emit_struct_ev(lbProcedure *p, lbValue s, i32 index); lbValue lb_emit_array_epi(lbProcedure *p, lbValue value, isize index); diff --git a/src/llvm_backend_general.cpp b/src/llvm_backend_general.cpp index 7138ac191..082163b2f 100644 --- a/src/llvm_backend_general.cpp +++ b/src/llvm_backend_general.cpp @@ -212,6 +212,45 @@ void lb_loop_end(lbProcedure *p, lbLoopData const &data) { } +// This emits a GEP at 0, index +lbValue lb_emit_epi(lbProcedure *p, lbValue const &value, isize index) { + GB_ASSERT(is_type_pointer(value.type)); + Type *type = type_deref(value.type); + + LLVMValueRef indices[2] = { + LLVMConstInt(lb_type(p->module, t_int), 0, false), + LLVMConstInt(lb_type(p->module, t_int), cast(unsigned long long)index, false), + }; + LLVMTypeRef llvm_type = lb_type(p->module, type); + lbValue res = {}; + Type *ptr = base_array_type(type); + res.type = alloc_type_pointer(ptr); + if (LLVMIsConstant(value.value)) { + res.value = LLVMConstGEP2(llvm_type, value.value, indices, gb_count_of(indices)); + } else { + res.value = LLVMBuildGEP2(p->builder, llvm_type, value.value, indices, gb_count_of(indices), ""); + } + return res; +} +// This emits a GEP at 0, index +lbValue lb_emit_epi(lbModule *m, lbValue const &value, isize index) { + GB_ASSERT(is_type_pointer(value.type)); + GB_ASSERT(LLVMIsConstant(value.value)); + Type *type = type_deref(value.type); + + LLVMValueRef indices[2] = { + LLVMConstInt(lb_type(m, t_int), 0, false), + LLVMConstInt(lb_type(m, t_int), cast(unsigned long long)index, false), + }; + lbValue res = {}; + Type *ptr = base_array_type(type); + res.type = alloc_type_pointer(ptr); + res.value = LLVMConstGEP2(lb_type(m, type), value.value, indices, gb_count_of(indices)); + return res; +} + + + LLVMValueRef llvm_zero(lbModule *m) { return LLVMConstInt(lb_type(m, t_int), 0, false); } diff --git a/src/llvm_backend_type.cpp b/src/llvm_backend_type.cpp index 3d20b3d72..d424fa5b2 100644 --- a/src/llvm_backend_type.cpp +++ b/src/llvm_backend_type.cpp @@ -98,36 +98,8 @@ lbValue lb_type_info(lbModule *m, Type *type) { isize index = lb_type_info_index(m->info, type); GB_ASSERT(index >= 0); - LLVMTypeRef it = lb_type(m, t_int); - LLVMValueRef indices[2] = { - LLVMConstInt(it, 0, false), - LLVMConstInt(it, index, true), - }; - - lbValue value = {}; lbValue data = lb_global_type_info_data_ptr(m); - value.value = LLVMConstGEP2(lb_type(m, type_deref(data.type)), data.value, indices, gb_count_of(indices)); - value.type = t_type_info_ptr; - return value; -} - -lbValue lb_get_type_info_ptr(lbModule *m, Type *type) { - GB_ASSERT(!build_context.disallow_rtti); - - i32 index = cast(i32)lb_type_info_index(m->info, type); - GB_ASSERT(index >= 0); - // gb_printf_err("%d %s\n", index, type_to_string(type)); - - LLVMValueRef indices[2] = { - LLVMConstInt(lb_type(m, t_int), 0, false), - LLVMConstInt(lb_type(m, t_int), index, false), - }; - - lbValue res = {}; - res.type = t_type_info_ptr; - lbValue data = lb_global_type_info_data_ptr(m); - res.value = LLVMConstGEP2(lb_type(m, type_deref(data.type)), data.value, indices, cast(unsigned)gb_count_of(indices)); - return res; + return lb_emit_array_epi(m, data, index); } LLVMTypeRef lb_get_procedure_raw_type(lbModule *m, Type *type) { @@ -267,7 +239,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da LLVMValueRef vals[4] = { lb_const_string(p->module, t->Named.type_name->token.string).value, - lb_get_type_info_ptr(m, t->Named.base).value, + lb_type_info(m, t->Named.base).value, pkg_name, loc.value }; @@ -426,7 +398,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da case Type_Pointer: { tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_pointer_ptr); - lbValue gep = lb_get_type_info_ptr(m, t->Pointer.elem); + lbValue gep = lb_type_info(m, t->Pointer.elem); LLVMValueRef vals[1] = { gep.value, @@ -440,7 +412,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da } case Type_MultiPointer: { tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_multi_pointer_ptr); - lbValue gep = lb_get_type_info_ptr(m, t->MultiPointer.elem); + lbValue gep = lb_type_info(m, t->MultiPointer.elem); LLVMValueRef vals[1] = { gep.value, @@ -454,7 +426,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da } case Type_SoaPointer: { tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_soa_pointer_ptr); - lbValue gep = lb_get_type_info_ptr(m, t->SoaPointer.elem); + lbValue gep = lb_type_info(m, t->SoaPointer.elem); LLVMValueRef vals[1] = { gep.value, @@ -471,7 +443,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da i64 ez = type_size_of(t->Array.elem); LLVMValueRef vals[3] = { - lb_get_type_info_ptr(m, t->Array.elem).value, + lb_type_info(m, t->Array.elem).value, lb_const_int(m, t_int, ez).value, lb_const_int(m, t_int, t->Array.count).value, }; @@ -486,8 +458,8 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_enumerated_array_ptr); LLVMValueRef vals[7] = { - lb_get_type_info_ptr(m, t->EnumeratedArray.elem).value, - lb_get_type_info_ptr(m, t->EnumeratedArray.index).value, + lb_type_info(m, t->EnumeratedArray.elem).value, + lb_type_info(m, t->EnumeratedArray.index).value, lb_const_int(m, t_int, type_size_of(t->EnumeratedArray.elem)).value, lb_const_int(m, t_int, t->EnumeratedArray.count).value, @@ -518,7 +490,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_dynamic_array_ptr); LLVMValueRef vals[2] = { - lb_get_type_info_ptr(m, t->DynamicArray.elem).value, + lb_type_info(m, t->DynamicArray.elem).value, lb_const_int(m, t_int, type_size_of(t->DynamicArray.elem)).value, }; @@ -532,7 +504,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_slice_ptr); LLVMValueRef vals[2] = { - lb_get_type_info_ptr(m, t->Slice.elem).value, + lb_type_info(m, t->Slice.elem).value, lb_const_int(m, t_int, type_size_of(t->Slice.elem)).value, }; @@ -548,10 +520,10 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da LLVMValueRef params = LLVMConstNull(lb_type(m, t_type_info_ptr)); LLVMValueRef results = LLVMConstNull(lb_type(m, t_type_info_ptr)); if (t->Proc.params != nullptr) { - params = lb_get_type_info_ptr(m, t->Proc.params).value; + params = lb_type_info(m, t->Proc.params).value; } if (t->Proc.results != nullptr) { - results = lb_get_type_info_ptr(m, t->Proc.results).value; + results = lb_type_info(m, t->Proc.results).value; } LLVMValueRef vals[4] = { @@ -670,7 +642,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da // NOTE(bill): Zeroth is nil so ignore it for (isize variant_index = 0; variant_index < variant_count; variant_index++) { Type *vt = t->Union.variants[variant_index]; - lbValue tip = lb_get_type_info_ptr(m, vt); + lbValue tip = lb_type_info(m, vt); lbValue index = lb_const_int(m, t_int, variant_index); lbValue type_info = lb_emit_ptr_offset(p, memory_types, index); @@ -758,7 +730,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da for (isize source_index = 0; source_index < count; source_index++) { // TODO(bill): Order fields in source order not layout order Entity *f = t->Struct.fields[source_index]; - lbValue tip = lb_get_type_info_ptr(m, f->type); + lbValue tip = lb_type_info(m, f->type); i64 foffset = 0; if (!t->Struct.is_raw_union) { GB_ASSERT(t->Struct.offsets != nullptr); @@ -815,11 +787,11 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_map_ptr); init_map_internal_types(t); - lbValue gst = lb_get_type_info_ptr(m, t->Map.generated_struct_type); + lbValue gst = lb_type_info(m, t->Map.generated_struct_type); LLVMValueRef vals[5] = { - lb_get_type_info_ptr(m, t->Map.key).value, - lb_get_type_info_ptr(m, t->Map.value).value, + lb_type_info(m, t->Map.key).value, + lb_type_info(m, t->Map.value).value, gst.value, lb_get_equal_proc_for_type(m, t->Map.key).value, lb_get_hasher_proc_for_type(m, t->Map.key).value @@ -840,13 +812,13 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da LLVMValueRef vals[4] = { - lb_get_type_info_ptr(m, t->BitSet.elem).value, + lb_type_info(m, t->BitSet.elem).value, LLVMConstNull(lb_type(m, t_type_info_ptr)), lb_const_int(m, t_i64, t->BitSet.lower).value, lb_const_int(m, t_i64, t->BitSet.upper).value, }; if (t->BitSet.underlying != nullptr) { - vals[1] =lb_get_type_info_ptr(m, t->BitSet.underlying).value; + vals[1] =lb_type_info(m, t->BitSet.underlying).value; } lbValue res = {}; @@ -862,7 +834,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da LLVMValueRef vals[3] = {}; - vals[0] = lb_get_type_info_ptr(m, t->SimdVector.elem).value; + vals[0] = lb_type_info(m, t->SimdVector.elem).value; vals[1] = lb_const_int(m, t_int, type_size_of(t->SimdVector.elem)).value; vals[2] = lb_const_int(m, t_int, t->SimdVector.count).value; @@ -877,8 +849,8 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da { tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_relative_pointer_ptr); LLVMValueRef vals[2] = { - lb_get_type_info_ptr(m, t->RelativePointer.pointer_type).value, - lb_get_type_info_ptr(m, t->RelativePointer.base_integer).value, + lb_type_info(m, t->RelativePointer.pointer_type).value, + lb_type_info(m, t->RelativePointer.base_integer).value, }; lbValue res = {}; @@ -891,8 +863,8 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da { tag = lb_const_ptr_cast(m, variant_ptr, t_type_info_relative_slice_ptr); LLVMValueRef vals[2] = { - lb_get_type_info_ptr(m, t->RelativeSlice.slice_type).value, - lb_get_type_info_ptr(m, t->RelativeSlice.base_integer).value, + lb_type_info(m, t->RelativeSlice.slice_type).value, + lb_type_info(m, t->RelativeSlice.base_integer).value, }; lbValue res = {}; @@ -907,7 +879,7 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da i64 ez = type_size_of(t->Matrix.elem); LLVMValueRef vals[5] = { - lb_get_type_info_ptr(m, t->Matrix.elem).value, + lb_type_info(m, t->Matrix.elem).value, lb_const_int(m, t_int, ez).value, lb_const_int(m, t_int, matrix_type_stride_in_elems(t)).value, lb_const_int(m, t_int, t->Matrix.row_count).value, diff --git a/src/llvm_backend_utility.cpp b/src/llvm_backend_utility.cpp index 3485c8436..ce7b43321 100644 --- a/src/llvm_backend_utility.cpp +++ b/src/llvm_backend_utility.cpp @@ -1002,6 +1002,7 @@ lbValue lb_emit_struct_ep(lbProcedure *p, lbValue s, i32 index) { index = lb_convert_struct_index(p->module, t, index); if (lb_is_const(s)) { + // NOTE(bill): this cannot be replaced with lb_emit_epi lbModule *m = p->module; lbValue res = {}; LLVMValueRef indices[2] = {llvm_zero(m), LLVMConstInt(lb_type(m, t_i32), index, false)}; @@ -1252,27 +1253,13 @@ lbValue lb_emit_array_ep(lbProcedure *p, lbValue s, lbValue index) { Type *ptr = base_array_type(st); lbValue res = {}; - res.value = LLVMBuildGEP2(p->builder, lb_type(p->module, st), s.value, indices, 2, ""); - res.type = alloc_type_pointer(ptr); - return res; -} -// This emits a GEP at 0, index -static inline lbValue lb_emit_gep(lbProcedure *p, Type *type, LLVMValueRef value, isize index) -{ - LLVMValueRef indices[2] = { - LLVMConstInt(lb_type(p->module, t_int), 0, false), - LLVMConstInt(lb_type(p->module, t_int), cast(unsigned)index, false), - }; - LLVMTypeRef llvm_type = lb_type(p->module, type); - lbValue res = {}; - Type *ptr = base_array_type(type); - res.type = alloc_type_pointer(ptr); - if (LLVMIsConstant(value)) { - res.value = LLVMConstGEP2(llvm_type, value, indices, gb_count_of(indices)); + if (LLVMIsConstant(s.value) && LLVMIsConstant(index.value)) { + res.value = LLVMConstGEP2(lb_type(p->module, st), s.value, indices, gb_count_of(indices)); } else { - res.value = LLVMBuildGEP2(p->builder, llvm_type, value, indices, gb_count_of(indices), ""); + res.value = LLVMBuildGEP2(p->builder, lb_type(p->module, st), s.value, indices, gb_count_of(indices), ""); } + res.type = alloc_type_pointer(ptr); return res; } @@ -1282,7 +1269,15 @@ lbValue lb_emit_array_epi(lbProcedure *p, lbValue s, isize index) { Type *st = base_type(type_deref(t)); GB_ASSERT_MSG(is_type_array(st) || is_type_enumerated_array(st) || is_type_matrix(st), "%s", type_to_string(st)); GB_ASSERT(0 <= index); - return lb_emit_gep(p, st, s.value, index); + return lb_emit_epi(p, s, index); +} +lbValue lb_emit_array_epi(lbModule *m, lbValue s, isize index) { + Type *t = s.type; + GB_ASSERT(is_type_pointer(t)); + Type *st = base_type(type_deref(t)); + GB_ASSERT_MSG(is_type_array(st) || is_type_enumerated_array(st) || is_type_matrix(st), "%s", type_to_string(st)); + GB_ASSERT(0 <= index); + return lb_emit_epi(m, s, index); } lbValue lb_emit_ptr_offset(lbProcedure *p, lbValue ptr, lbValue index) { @@ -1306,16 +1301,16 @@ lbValue lb_emit_matrix_epi(lbProcedure *p, lbValue s, isize row, isize column) { Type *mt = base_type(type_deref(t)); if (column == 0) { GB_ASSERT_MSG(is_type_matrix(mt) || is_type_array_like(mt), "%s", type_to_string(mt)); - return lb_emit_gep(p, mt, s.value, row); + return lb_emit_epi(p, s, row); } else if (row == 0 && is_type_array_like(mt)) { - return lb_emit_gep(p, mt, s.value, column); + return lb_emit_epi(p, s, column); } GB_ASSERT_MSG(is_type_matrix(mt), "%s", type_to_string(mt)); isize offset = matrix_indices_to_offset(mt, row, column); - return lb_emit_gep(p, mt, s.value, offset); + return lb_emit_epi(p, s, offset); } lbValue lb_emit_matrix_ep(lbProcedure *p, lbValue s, lbValue row, lbValue column) {