mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 15:48:51 +00:00
Merge pull request #1933 from lerno/reduce_reliance_on_ptr_type
Removed use of deprecated functions. Cleaned up most deprecated use o…
This commit is contained in:
@@ -739,11 +739,11 @@ lbProcedure *lb_create_startup_runtime(lbModule *main_module, lbProcedure *start
|
|||||||
lb_begin_procedure_body(p);
|
lb_begin_procedure_body(p);
|
||||||
|
|
||||||
if (startup_type_info) {
|
if (startup_type_info) {
|
||||||
LLVMBuildCall2(p->builder, LLVMGetElementType(lb_type(main_module, startup_type_info->type)), startup_type_info->value, nullptr, 0, "");
|
LLVMBuildCall2(p->builder, lb_llvm_get_pointer_type(lb_type(main_module, startup_type_info->type)), startup_type_info->value, nullptr, 0, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (objc_names) {
|
if (objc_names) {
|
||||||
LLVMBuildCall2(p->builder, LLVMGetElementType(lb_type(main_module, objc_names->type)), objc_names->value, nullptr, 0, "");
|
LLVMBuildCall2(p->builder, lb_llvm_get_pointer_type(lb_type(main_module, objc_names->type)), objc_names->value, nullptr, 0, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
for_array(i, global_variables) {
|
for_array(i, global_variables) {
|
||||||
@@ -762,7 +762,7 @@ lbProcedure *lb_create_startup_runtime(lbModule *main_module, lbProcedure *start
|
|||||||
if (init_expr != nullptr) {
|
if (init_expr != nullptr) {
|
||||||
lbValue init = lb_build_expr(p, init_expr);
|
lbValue init = lb_build_expr(p, init_expr);
|
||||||
if (init.value == nullptr) {
|
if (init.value == nullptr) {
|
||||||
LLVMTypeRef global_type = LLVMGetElementType(LLVMTypeOf(var->var.value));
|
LLVMTypeRef global_type = llvm_addr_type(p->module, var->var);
|
||||||
if (is_type_untyped_undef(init.type)) {
|
if (is_type_untyped_undef(init.type)) {
|
||||||
// LLVMSetInitializer(var->var.value, LLVMGetUndef(global_type));
|
// LLVMSetInitializer(var->var.value, LLVMGetUndef(global_type));
|
||||||
LLVMSetInitializer(var->var.value, LLVMConstNull(global_type));
|
LLVMSetInitializer(var->var.value, LLVMConstNull(global_type));
|
||||||
@@ -805,8 +805,7 @@ lbProcedure *lb_create_startup_runtime(lbModule *main_module, lbProcedure *start
|
|||||||
lb_emit_store(p, data, lb_emit_conv(p, gp, t_rawptr));
|
lb_emit_store(p, data, lb_emit_conv(p, gp, t_rawptr));
|
||||||
lb_emit_store(p, ti, lb_type_info(main_module, var_type));
|
lb_emit_store(p, ti, lb_type_info(main_module, var_type));
|
||||||
} else {
|
} else {
|
||||||
LLVMTypeRef pvt = LLVMTypeOf(var->var.value);
|
LLVMTypeRef vt = llvm_addr_type(p->module, var->var);
|
||||||
LLVMTypeRef vt = LLVMGetElementType(pvt);
|
|
||||||
lbValue src0 = lb_emit_conv(p, var->init, t);
|
lbValue src0 = lb_emit_conv(p, var->init, t);
|
||||||
LLVMValueRef src = OdinLLVMBuildTransmute(p, src0.value, vt);
|
LLVMValueRef src = OdinLLVMBuildTransmute(p, src0.value, vt);
|
||||||
LLVMValueRef dst = var->var.value;
|
LLVMValueRef dst = var->var.value;
|
||||||
@@ -933,7 +932,7 @@ lbProcedure *lb_create_main_procedure(lbModule *m, lbProcedure *startup_runtime)
|
|||||||
GB_ASSERT(LLVMIsConstant(vals[1]));
|
GB_ASSERT(LLVMIsConstant(vals[1]));
|
||||||
GB_ASSERT(LLVMIsConstant(vals[2]));
|
GB_ASSERT(LLVMIsConstant(vals[2]));
|
||||||
|
|
||||||
LLVMValueRef dst = LLVMConstInBoundsGEP(all_tests_array.value, indices, gb_count_of(indices));
|
LLVMValueRef dst = LLVMConstInBoundsGEP2(llvm_addr_type(m, all_tests_array), all_tests_array.value, indices, gb_count_of(indices));
|
||||||
LLVMValueRef src = llvm_const_named_struct(m, t_Internal_Test, vals, gb_count_of(vals));
|
LLVMValueRef src = llvm_const_named_struct(m, t_Internal_Test, vals, gb_count_of(vals));
|
||||||
|
|
||||||
LLVMBuildStore(p->builder, src, dst);
|
LLVMBuildStore(p->builder, src, dst);
|
||||||
|
|||||||
+20
-2
@@ -42,6 +42,18 @@
|
|||||||
#define ODIN_LLVM_MINIMUM_VERSION_12 0
|
#define ODIN_LLVM_MINIMUM_VERSION_12 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if LLVM_VERSION_MAJOR > 13 || (LLVM_VERSION_MAJOR == 13 && LLVM_VERSION_MINOR >= 0 && LLVM_VERSION_PATCH > 0)
|
||||||
|
#define ODIN_LLVM_MINIMUM_VERSION_13 1
|
||||||
|
#else
|
||||||
|
#define ODIN_LLVM_MINIMUM_VERSION_13 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if LLVM_VERSION_MAJOR > 14 || (LLVM_VERSION_MAJOR == 14 && LLVM_VERSION_MINOR >= 0 && LLVM_VERSION_PATCH > 0)
|
||||||
|
#define ODIN_LLVM_MINIMUM_VERSION_14 1
|
||||||
|
#else
|
||||||
|
#define ODIN_LLVM_MINIMUM_VERSION_14 0
|
||||||
|
#endif
|
||||||
|
|
||||||
struct lbProcedure;
|
struct lbProcedure;
|
||||||
|
|
||||||
struct lbValue {
|
struct lbValue {
|
||||||
@@ -299,7 +311,11 @@ struct lbProcedure {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if !ODIN_LLVM_MINIMUM_VERSION_14
|
||||||
|
#define LLVMConstGEP2(Ty__, ConstantVal__, ConstantIndices__, NumIndices__) LLVMConstGEP(ConstantVal__, ConstantIndices__, NumIndices__)
|
||||||
|
#define LLVMConstInBoundsGEP2(Ty__, ConstantVal__, ConstantIndices__, NumIndices__) LLVMConstInBoundsGEP(ConstantVal__, ConstantIndices__, NumIndices__)
|
||||||
|
#define LLVMBuildPtrDiff2(Builder__, Ty__, LHS__, RHS__, Name__) LLVMBuildPtrDiff(Builder__, LHS__, RHS__, Name__)
|
||||||
|
#endif
|
||||||
|
|
||||||
bool lb_init_generator(lbGenerator *gen, Checker *c);
|
bool lb_init_generator(lbGenerator *gen, Checker *c);
|
||||||
|
|
||||||
@@ -327,7 +343,8 @@ lbValue lb_const_int(lbModule *m, Type *type, u64 value);
|
|||||||
|
|
||||||
lbAddr lb_addr(lbValue addr);
|
lbAddr lb_addr(lbValue addr);
|
||||||
Type *lb_addr_type(lbAddr const &addr);
|
Type *lb_addr_type(lbAddr const &addr);
|
||||||
LLVMTypeRef lb_addr_lb_type(lbAddr const &addr);
|
LLVMTypeRef lb_llvm_get_pointer_type(LLVMTypeRef type);
|
||||||
|
LLVMTypeRef llvm_addr_type(lbModule *module, lbValue addr_val);
|
||||||
void lb_addr_store(lbProcedure *p, lbAddr addr, lbValue value);
|
void lb_addr_store(lbProcedure *p, lbAddr addr, lbValue value);
|
||||||
lbValue lb_addr_load(lbProcedure *p, lbAddr const &addr);
|
lbValue lb_addr_load(lbProcedure *p, lbAddr const &addr);
|
||||||
lbValue lb_emit_load(lbProcedure *p, lbValue v);
|
lbValue lb_emit_load(lbProcedure *p, lbValue v);
|
||||||
@@ -480,6 +497,7 @@ LLVMTypeRef lb_type_padding_filler(lbModule *m, i64 padding, i64 padding_align);
|
|||||||
|
|
||||||
LLVMValueRef llvm_basic_shuffle(lbProcedure *p, LLVMValueRef vector, LLVMValueRef mask);
|
LLVMValueRef llvm_basic_shuffle(lbProcedure *p, LLVMValueRef vector, LLVMValueRef mask);
|
||||||
|
|
||||||
|
LLVMValueRef lb_call_intrinsic(lbProcedure *p, const char *name, LLVMValueRef* args, unsigned arg_count, LLVMTypeRef* types, unsigned type_count);
|
||||||
void lb_mem_copy_overlapping(lbProcedure *p, lbValue dst, lbValue src, lbValue len, bool is_volatile=false);
|
void lb_mem_copy_overlapping(lbProcedure *p, lbValue dst, lbValue src, lbValue len, bool is_volatile=false);
|
||||||
void lb_mem_copy_non_overlapping(lbProcedure *p, lbValue dst, lbValue src, lbValue len, bool is_volatile=false);
|
void lb_mem_copy_non_overlapping(lbProcedure *p, lbValue dst, lbValue src, lbValue len, bool is_volatile=false);
|
||||||
LLVMValueRef lb_mem_zero_ptr_internal(lbProcedure *p, LLVMValueRef ptr, LLVMValueRef len, unsigned alignment, bool is_volatile);
|
LLVMValueRef lb_mem_zero_ptr_internal(lbProcedure *p, LLVMValueRef ptr, LLVMValueRef len, unsigned alignment, bool is_volatile);
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ bool lb_is_const(lbValue value) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO remove use of LLVMGetElementType
|
||||||
bool lb_is_const_or_global(lbValue value) {
|
bool lb_is_const_or_global(lbValue value) {
|
||||||
if (lb_is_const(value)) {
|
if (lb_is_const(value)) {
|
||||||
return true;
|
return true;
|
||||||
@@ -418,7 +418,7 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc
|
|||||||
|
|
||||||
{
|
{
|
||||||
LLVMValueRef indices[2] = {llvm_zero(m), llvm_zero(m)};
|
LLVMValueRef indices[2] = {llvm_zero(m), llvm_zero(m)};
|
||||||
LLVMValueRef ptr = LLVMBuildInBoundsGEP(p->builder, array_data, indices, 2, "");
|
LLVMValueRef ptr = LLVMBuildInBoundsGEP2(p->builder, llvm_type, array_data, indices, 2, "");
|
||||||
LLVMValueRef len = LLVMConstInt(lb_type(m, t_int), count, true);
|
LLVMValueRef len = LLVMConstInt(lb_type(m, t_int), count, true);
|
||||||
lbAddr slice = lb_add_local_generated(p, type, false);
|
lbAddr slice = lb_add_local_generated(p, type, false);
|
||||||
lb_fill_slice(p, slice, {ptr, alloc_type_pointer(elem)}, {len, t_int});
|
lb_fill_slice(p, slice, {ptr, alloc_type_pointer(elem)}, {len, t_int});
|
||||||
@@ -445,7 +445,7 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc
|
|||||||
|
|
||||||
{
|
{
|
||||||
LLVMValueRef indices[2] = {llvm_zero(m), llvm_zero(m)};
|
LLVMValueRef indices[2] = {llvm_zero(m), llvm_zero(m)};
|
||||||
LLVMValueRef ptr = LLVMConstInBoundsGEP(array_data, indices, 2);
|
LLVMValueRef ptr = LLVMConstInBoundsGEP2(lb_type(m, t), array_data, indices, 2);
|
||||||
LLVMValueRef len = LLVMConstInt(lb_type(m, t_int), count, true);
|
LLVMValueRef len = LLVMConstInt(lb_type(m, t_int), count, true);
|
||||||
LLVMValueRef values[2] = {ptr, len};
|
LLVMValueRef values[2] = {ptr, len};
|
||||||
|
|
||||||
@@ -1007,7 +1007,7 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bool allow_loc
|
|||||||
for (isize i = 0; i < value_count; i++) {
|
for (isize i = 0; i < value_count; i++) {
|
||||||
LLVMValueRef val = old_values[i];
|
LLVMValueRef val = old_values[i];
|
||||||
if (!LLVMIsConstant(val)) {
|
if (!LLVMIsConstant(val)) {
|
||||||
LLVMValueRef dst = LLVMBuildStructGEP(p->builder, v.addr.value, cast(unsigned)i, "");
|
LLVMValueRef dst = LLVMBuildStructGEP2(p->builder, llvm_addr_type(p->module, v.addr), v.addr.value, cast(unsigned)i, "");
|
||||||
LLVMBuildStore(p->builder, val, dst);
|
LLVMBuildStore(p->builder, val, dst);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-12
@@ -243,8 +243,9 @@ lbValue lb_emit_unary_arith(lbProcedure *p, TokenKind op, lbValue x, Type *type)
|
|||||||
LLVMValueRef v1 = LLVMBuildFNeg(p->builder, LLVMBuildExtractValue(p->builder, x.value, 1, ""), "");
|
LLVMValueRef v1 = LLVMBuildFNeg(p->builder, LLVMBuildExtractValue(p->builder, x.value, 1, ""), "");
|
||||||
|
|
||||||
lbAddr addr = lb_add_local_generated(p, x.type, false);
|
lbAddr addr = lb_add_local_generated(p, x.type, false);
|
||||||
LLVMBuildStore(p->builder, v0, LLVMBuildStructGEP(p->builder, addr.addr.value, 0, ""));
|
LLVMTypeRef type = llvm_addr_type(p->module, addr.addr);
|
||||||
LLVMBuildStore(p->builder, v1, LLVMBuildStructGEP(p->builder, addr.addr.value, 1, ""));
|
LLVMBuildStore(p->builder, v0, LLVMBuildStructGEP2(p->builder, type, addr.addr.value, 0, ""));
|
||||||
|
LLVMBuildStore(p->builder, v1, LLVMBuildStructGEP2(p->builder, type, addr.addr.value, 1, ""));
|
||||||
return lb_addr_load(p, addr);
|
return lb_addr_load(p, addr);
|
||||||
|
|
||||||
} else if (is_type_quaternion(x.type)) {
|
} else if (is_type_quaternion(x.type)) {
|
||||||
@@ -254,10 +255,11 @@ lbValue lb_emit_unary_arith(lbProcedure *p, TokenKind op, lbValue x, Type *type)
|
|||||||
LLVMValueRef v3 = LLVMBuildFNeg(p->builder, LLVMBuildExtractValue(p->builder, x.value, 3, ""), "");
|
LLVMValueRef v3 = LLVMBuildFNeg(p->builder, LLVMBuildExtractValue(p->builder, x.value, 3, ""), "");
|
||||||
|
|
||||||
lbAddr addr = lb_add_local_generated(p, x.type, false);
|
lbAddr addr = lb_add_local_generated(p, x.type, false);
|
||||||
LLVMBuildStore(p->builder, v0, LLVMBuildStructGEP(p->builder, addr.addr.value, 0, ""));
|
LLVMTypeRef type = llvm_addr_type(p->module, addr.addr);
|
||||||
LLVMBuildStore(p->builder, v1, LLVMBuildStructGEP(p->builder, addr.addr.value, 1, ""));
|
LLVMBuildStore(p->builder, v0, LLVMBuildStructGEP2(p->builder, type, addr.addr.value, 0, ""));
|
||||||
LLVMBuildStore(p->builder, v2, LLVMBuildStructGEP(p->builder, addr.addr.value, 2, ""));
|
LLVMBuildStore(p->builder, v1, LLVMBuildStructGEP2(p->builder, type, addr.addr.value, 1, ""));
|
||||||
LLVMBuildStore(p->builder, v3, LLVMBuildStructGEP(p->builder, addr.addr.value, 3, ""));
|
LLVMBuildStore(p->builder, v2, LLVMBuildStructGEP2(p->builder, type, addr.addr.value, 2, ""));
|
||||||
|
LLVMBuildStore(p->builder, v3, LLVMBuildStructGEP2(p->builder, type, addr.addr.value, 3, ""));
|
||||||
return lb_addr_load(p, addr);
|
return lb_addr_load(p, addr);
|
||||||
} else if (is_type_simd_vector(x.type)) {
|
} else if (is_type_simd_vector(x.type)) {
|
||||||
Type *elem = base_array_type(x.type);
|
Type *elem = base_array_type(x.type);
|
||||||
@@ -543,7 +545,7 @@ LLVMValueRef lb_matrix_to_vector(lbProcedure *p, lbValue matrix) {
|
|||||||
#if 1
|
#if 1
|
||||||
LLVMValueRef ptr = lb_address_from_load_or_generate_local(p, matrix).value;
|
LLVMValueRef ptr = lb_address_from_load_or_generate_local(p, matrix).value;
|
||||||
LLVMValueRef matrix_vector_ptr = LLVMBuildPointerCast(p->builder, ptr, LLVMPointerType(total_matrix_type, 0), "");
|
LLVMValueRef matrix_vector_ptr = LLVMBuildPointerCast(p->builder, ptr, LLVMPointerType(total_matrix_type, 0), "");
|
||||||
LLVMValueRef matrix_vector = LLVMBuildLoad(p->builder, matrix_vector_ptr, "");
|
LLVMValueRef matrix_vector = LLVMBuildLoad2(p->builder, total_matrix_type, matrix_vector_ptr, "");
|
||||||
LLVMSetAlignment(matrix_vector, cast(unsigned)type_align_of(mt));
|
LLVMSetAlignment(matrix_vector, cast(unsigned)type_align_of(mt));
|
||||||
return matrix_vector;
|
return matrix_vector;
|
||||||
#else
|
#else
|
||||||
@@ -2724,7 +2726,7 @@ lbValue lb_emit_comp_against_nil(lbProcedure *p, TokenKind op_kind, lbValue x) {
|
|||||||
unsigned indices[2] = {0, 0};
|
unsigned indices[2] = {0, 0};
|
||||||
lbValue hashes_data = lb_emit_struct_ep(p, map_ptr, 0);
|
lbValue hashes_data = lb_emit_struct_ep(p, map_ptr, 0);
|
||||||
lbValue hashes_data_ptr_ptr = lb_emit_struct_ep(p, hashes_data, 0);
|
lbValue hashes_data_ptr_ptr = lb_emit_struct_ep(p, hashes_data, 0);
|
||||||
LLVMValueRef hashes_data_ptr = LLVMBuildLoad(p->builder, hashes_data_ptr_ptr.value, "");
|
LLVMValueRef hashes_data_ptr = LLVMBuildLoad2(p->builder, llvm_addr_type(p->module, hashes_data_ptr_ptr), hashes_data_ptr_ptr.value, "");
|
||||||
|
|
||||||
if (op_kind == Token_CmpEq) {
|
if (op_kind == Token_CmpEq) {
|
||||||
res.value = LLVMBuildIsNull(p->builder, hashes_data_ptr, "");
|
res.value = LLVMBuildIsNull(p->builder, hashes_data_ptr, "");
|
||||||
@@ -3343,7 +3345,7 @@ lbValue lb_build_expr_internal(lbProcedure *p, Ast *expr) {
|
|||||||
default: GB_PANIC("Unhandled inline asm dialect"); break;
|
default: GB_PANIC("Unhandled inline asm dialect"); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
LLVMTypeRef func_type = LLVMGetElementType(lb_type(p->module, t));
|
LLVMTypeRef func_type = lb_llvm_get_pointer_type(lb_type(p->module, t));
|
||||||
LLVMValueRef the_asm = llvm_get_inline_asm(func_type, asm_string, constraints_string, ia->has_side_effects, ia->has_side_effects, dialect);
|
LLVMValueRef the_asm = llvm_get_inline_asm(func_type, asm_string, constraints_string, ia->has_side_effects, ia->has_side_effects, dialect);
|
||||||
GB_ASSERT(the_asm != nullptr);
|
GB_ASSERT(the_asm != nullptr);
|
||||||
return {the_asm, t};
|
return {the_asm, t};
|
||||||
@@ -3810,7 +3812,7 @@ lbAddr lb_build_addr_internal(lbProcedure *p, Ast *expr) {
|
|||||||
lbValue v = {};
|
lbValue v = {};
|
||||||
|
|
||||||
LLVMValueRef indices[1] = {index.value};
|
LLVMValueRef indices[1] = {index.value};
|
||||||
v.value = LLVMBuildGEP(p->builder, multi_ptr.value, indices, 1, "");
|
v.value = LLVMBuildGEP2(p->builder, lb_type(p->module, t->MultiPointer.elem), multi_ptr.value, indices, 1, "foo");
|
||||||
v.type = alloc_type_pointer(t->MultiPointer.elem);
|
v.type = alloc_type_pointer(t->MultiPointer.elem);
|
||||||
return lb_addr(v);
|
return lb_addr(v);
|
||||||
}
|
}
|
||||||
@@ -3986,7 +3988,7 @@ lbAddr lb_build_addr_internal(lbProcedure *p, Ast *expr) {
|
|||||||
if (se->high == nullptr) {
|
if (se->high == nullptr) {
|
||||||
lbValue offset = base;
|
lbValue offset = base;
|
||||||
LLVMValueRef indices[1] = {low.value};
|
LLVMValueRef indices[1] = {low.value};
|
||||||
offset.value = LLVMBuildGEP(p->builder, offset.value, indices, 1, "");
|
offset.value = LLVMBuildGEP2(p->builder, lb_type(p->module, offset.type->MultiPointer.elem), offset.value, indices, 1, "");
|
||||||
lb_addr_store(p, res, offset);
|
lb_addr_store(p, res, offset);
|
||||||
} else {
|
} else {
|
||||||
low = lb_emit_conv(p, low, t_int);
|
low = lb_emit_conv(p, low, t_int);
|
||||||
@@ -3995,7 +3997,7 @@ lbAddr lb_build_addr_internal(lbProcedure *p, Ast *expr) {
|
|||||||
lb_emit_multi_pointer_slice_bounds_check(p, se->open, low, high);
|
lb_emit_multi_pointer_slice_bounds_check(p, se->open, low, high);
|
||||||
|
|
||||||
LLVMValueRef indices[1] = {low.value};
|
LLVMValueRef indices[1] = {low.value};
|
||||||
LLVMValueRef ptr = LLVMBuildGEP(p->builder, base.value, indices, 1, "");
|
LLVMValueRef ptr = LLVMBuildGEP2(p->builder, lb_type(p->module, base.type->MultiPointer.elem), base.value, indices, 1, "");
|
||||||
LLVMValueRef len = LLVMBuildSub(p->builder, high.value, low.value, "");
|
LLVMValueRef len = LLVMBuildSub(p->builder, high.value, low.value, "");
|
||||||
|
|
||||||
LLVMValueRef gep0 = lb_emit_struct_ep(p, res.addr, 0).value;
|
LLVMValueRef gep0 = lb_emit_struct_ep(p, res.addr, 0).value;
|
||||||
|
|||||||
@@ -341,9 +341,6 @@ Type *lb_addr_type(lbAddr const &addr) {
|
|||||||
}
|
}
|
||||||
return type_deref(addr.addr.type);
|
return type_deref(addr.addr.type);
|
||||||
}
|
}
|
||||||
LLVMTypeRef lb_addr_lb_type(lbAddr const &addr) {
|
|
||||||
return LLVMGetElementType(LLVMTypeOf(addr.addr.value));
|
|
||||||
}
|
|
||||||
|
|
||||||
lbValue lb_addr_get_ptr(lbProcedure *p, lbAddr const &addr) {
|
lbValue lb_addr_get_ptr(lbProcedure *p, lbAddr const &addr) {
|
||||||
if (addr.addr.value == nullptr) {
|
if (addr.addr.value == nullptr) {
|
||||||
@@ -854,7 +851,7 @@ void lb_emit_store(lbProcedure *p, lbValue ptr, lbValue value) {
|
|||||||
Type *a = type_deref(ptr.type);
|
Type *a = type_deref(ptr.type);
|
||||||
|
|
||||||
if (LLVMIsNull(value.value)) {
|
if (LLVMIsNull(value.value)) {
|
||||||
LLVMTypeRef src_t = LLVMGetElementType(LLVMTypeOf(ptr.value));
|
LLVMTypeRef src_t = llvm_addr_type(p->module, ptr);
|
||||||
if (lb_sizeof(src_t) <= lb_max_zero_init_size()) {
|
if (lb_sizeof(src_t) <= lb_max_zero_init_size()) {
|
||||||
LLVMBuildStore(p->builder, LLVMConstNull(src_t), ptr.value);
|
LLVMBuildStore(p->builder, LLVMConstNull(src_t), ptr.value);
|
||||||
} else {
|
} else {
|
||||||
@@ -904,8 +901,8 @@ void lb_emit_store(lbProcedure *p, lbValue ptr, lbValue value) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LLVMTypeRef llvm_addr_type(lbValue addr_val) {
|
LLVMTypeRef llvm_addr_type(lbModule *module, lbValue addr_val) {
|
||||||
return LLVMGetElementType(LLVMTypeOf(addr_val.value));
|
return lb_type(module, type_deref(addr_val.type));
|
||||||
}
|
}
|
||||||
|
|
||||||
lbValue lb_emit_load(lbProcedure *p, lbValue value) {
|
lbValue lb_emit_load(lbProcedure *p, lbValue value) {
|
||||||
@@ -914,7 +911,7 @@ lbValue lb_emit_load(lbProcedure *p, lbValue value) {
|
|||||||
Type *vt = base_type(value.type);
|
Type *vt = base_type(value.type);
|
||||||
GB_ASSERT(vt->kind == Type_MultiPointer);
|
GB_ASSERT(vt->kind == Type_MultiPointer);
|
||||||
Type *t = vt->MultiPointer.elem;
|
Type *t = vt->MultiPointer.elem;
|
||||||
LLVMValueRef v = LLVMBuildLoad2(p->builder, llvm_addr_type(value), value.value, "");
|
LLVMValueRef v = LLVMBuildLoad2(p->builder, lb_type(p->module, t), value.value, "");
|
||||||
return lbValue{v, t};
|
return lbValue{v, t};
|
||||||
} else if (is_type_soa_pointer(value.type)) {
|
} else if (is_type_soa_pointer(value.type)) {
|
||||||
lbValue ptr = lb_emit_struct_ev(p, value, 0);
|
lbValue ptr = lb_emit_struct_ev(p, value, 0);
|
||||||
@@ -925,7 +922,7 @@ lbValue lb_emit_load(lbProcedure *p, lbValue value) {
|
|||||||
|
|
||||||
GB_ASSERT(is_type_pointer(value.type));
|
GB_ASSERT(is_type_pointer(value.type));
|
||||||
Type *t = type_deref(value.type);
|
Type *t = type_deref(value.type);
|
||||||
LLVMValueRef v = LLVMBuildLoad2(p->builder, llvm_addr_type(value), value.value, "");
|
LLVMValueRef v = LLVMBuildLoad2(p->builder, lb_type(p->module, t), value.value, "");
|
||||||
return lbValue{v, t};
|
return lbValue{v, t};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1190,12 +1187,12 @@ lbValue lb_emit_union_tag_ptr(lbProcedure *p, lbValue u) {
|
|||||||
|
|
||||||
Type *tag_type = union_tag_type(ut);
|
Type *tag_type = union_tag_type(ut);
|
||||||
|
|
||||||
LLVMTypeRef uvt = LLVMGetElementType(LLVMTypeOf(u.value));
|
LLVMTypeRef uvt = llvm_addr_type(p->module, u);
|
||||||
unsigned element_count = LLVMCountStructElementTypes(uvt);
|
unsigned element_count = LLVMCountStructElementTypes(uvt);
|
||||||
GB_ASSERT_MSG(element_count >= 2, "element_count=%u (%s) != (%s)", element_count, type_to_string(ut), LLVMPrintTypeToString(uvt));
|
GB_ASSERT_MSG(element_count >= 2, "element_count=%u (%s) != (%s)", element_count, type_to_string(ut), LLVMPrintTypeToString(uvt));
|
||||||
|
|
||||||
lbValue tag_ptr = {};
|
lbValue tag_ptr = {};
|
||||||
tag_ptr.value = LLVMBuildStructGEP(p->builder, u.value, 1, "");
|
tag_ptr.value = LLVMBuildStructGEP2(p->builder, uvt, u.value, 1, "");
|
||||||
tag_ptr.type = alloc_type_pointer(tag_type);
|
tag_ptr.type = alloc_type_pointer(tag_type);
|
||||||
return tag_ptr;
|
return tag_ptr;
|
||||||
}
|
}
|
||||||
@@ -2012,7 +2009,7 @@ LLVMTypeRef lb_type_internal(lbModule *m, Type *type) {
|
|||||||
|
|
||||||
map_set(&m->function_type_map, type, ft);
|
map_set(&m->function_type_map, type, ft);
|
||||||
LLVMTypeRef new_abi_fn_ptr_type = lb_function_type_to_llvm_ptr(ft, type->Proc.c_vararg);
|
LLVMTypeRef new_abi_fn_ptr_type = lb_function_type_to_llvm_ptr(ft, type->Proc.c_vararg);
|
||||||
LLVMTypeRef new_abi_fn_type = LLVMGetElementType(new_abi_fn_ptr_type);
|
LLVMTypeRef new_abi_fn_type = lb_llvm_get_pointer_type(new_abi_fn_ptr_type);
|
||||||
|
|
||||||
GB_ASSERT_MSG(LLVMGetTypeContext(new_abi_fn_type) == m->ctx,
|
GB_ASSERT_MSG(LLVMGetTypeContext(new_abi_fn_type) == m->ctx,
|
||||||
"\n\tFuncTypeCtx: %p\n\tCurrentCtx: %p\n\tGlobalCtx: %p",
|
"\n\tFuncTypeCtx: %p\n\tCurrentCtx: %p\n\tGlobalCtx: %p",
|
||||||
@@ -2344,7 +2341,7 @@ general_end:;
|
|||||||
if (LLVMIsALoadInst(val) && (src_size >= dst_size && src_align >= dst_align)) {
|
if (LLVMIsALoadInst(val) && (src_size >= dst_size && src_align >= dst_align)) {
|
||||||
LLVMValueRef val_ptr = LLVMGetOperand(val, 0);
|
LLVMValueRef val_ptr = LLVMGetOperand(val, 0);
|
||||||
val_ptr = LLVMBuildPointerCast(p->builder, val_ptr, LLVMPointerType(dst_type, 0), "");
|
val_ptr = LLVMBuildPointerCast(p->builder, val_ptr, LLVMPointerType(dst_type, 0), "");
|
||||||
LLVMValueRef loaded_val = LLVMBuildLoad(p->builder, val_ptr, "");
|
LLVMValueRef loaded_val = LLVMBuildLoad2(p->builder, dst_type, val_ptr, "");
|
||||||
|
|
||||||
// LLVMSetAlignment(loaded_val, gb_min(src_align, dst_align));
|
// LLVMSetAlignment(loaded_val, gb_min(src_align, dst_align));
|
||||||
|
|
||||||
@@ -2360,7 +2357,7 @@ general_end:;
|
|||||||
LLVMValueRef nptr = LLVMBuildPointerCast(p->builder, ptr, LLVMPointerType(src_type, 0), "");
|
LLVMValueRef nptr = LLVMBuildPointerCast(p->builder, ptr, LLVMPointerType(src_type, 0), "");
|
||||||
LLVMBuildStore(p->builder, val, nptr);
|
LLVMBuildStore(p->builder, val, nptr);
|
||||||
|
|
||||||
return LLVMBuildLoad(p->builder, ptr, "");
|
return LLVMBuildLoad2(p->builder, dst_type, ptr, "");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2386,14 +2383,15 @@ LLVMValueRef lb_find_or_add_entity_string_ptr(lbModule *m, String const &str) {
|
|||||||
isize len = gb_snprintf(name, max_len, "csbs$%x", id);
|
isize len = gb_snprintf(name, max_len, "csbs$%x", id);
|
||||||
len -= 1;
|
len -= 1;
|
||||||
|
|
||||||
LLVMValueRef global_data = LLVMAddGlobal(m->mod, LLVMTypeOf(data), name);
|
LLVMTypeRef type = LLVMTypeOf(data);
|
||||||
|
LLVMValueRef global_data = LLVMAddGlobal(m->mod, type, name);
|
||||||
LLVMSetInitializer(global_data, data);
|
LLVMSetInitializer(global_data, data);
|
||||||
LLVMSetLinkage(global_data, LLVMPrivateLinkage);
|
LLVMSetLinkage(global_data, LLVMPrivateLinkage);
|
||||||
LLVMSetUnnamedAddress(global_data, LLVMGlobalUnnamedAddr);
|
LLVMSetUnnamedAddress(global_data, LLVMGlobalUnnamedAddr);
|
||||||
LLVMSetAlignment(global_data, 1);
|
LLVMSetAlignment(global_data, 1);
|
||||||
LLVMSetGlobalConstant(global_data, true);
|
LLVMSetGlobalConstant(global_data, true);
|
||||||
|
|
||||||
LLVMValueRef ptr = LLVMConstInBoundsGEP(global_data, indices, 2);
|
LLVMValueRef ptr = LLVMConstInBoundsGEP2(type, global_data, indices, 2);
|
||||||
string_map_set(&m->const_strings, key, ptr);
|
string_map_set(&m->const_strings, key, ptr);
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
@@ -2431,7 +2429,8 @@ lbValue lb_find_or_add_entity_string_byte_slice(lbModule *m, String const &str)
|
|||||||
isize len = gb_snprintf(name, max_len, "csbs$%x", id);
|
isize len = gb_snprintf(name, max_len, "csbs$%x", id);
|
||||||
len -= 1;
|
len -= 1;
|
||||||
}
|
}
|
||||||
LLVMValueRef global_data = LLVMAddGlobal(m->mod, LLVMTypeOf(data), name);
|
LLVMTypeRef type = LLVMTypeOf(data);
|
||||||
|
LLVMValueRef global_data = LLVMAddGlobal(m->mod, type, name);
|
||||||
LLVMSetInitializer(global_data, data);
|
LLVMSetInitializer(global_data, data);
|
||||||
LLVMSetLinkage(global_data, LLVMPrivateLinkage);
|
LLVMSetLinkage(global_data, LLVMPrivateLinkage);
|
||||||
LLVMSetUnnamedAddress(global_data, LLVMGlobalUnnamedAddr);
|
LLVMSetUnnamedAddress(global_data, LLVMGlobalUnnamedAddr);
|
||||||
@@ -2440,7 +2439,7 @@ lbValue lb_find_or_add_entity_string_byte_slice(lbModule *m, String const &str)
|
|||||||
|
|
||||||
LLVMValueRef ptr = nullptr;
|
LLVMValueRef ptr = nullptr;
|
||||||
if (str.len != 0) {
|
if (str.len != 0) {
|
||||||
ptr = LLVMConstInBoundsGEP(global_data, indices, 2);
|
ptr = LLVMConstInBoundsGEP2(type, global_data, indices, 2);
|
||||||
} else {
|
} else {
|
||||||
ptr = LLVMConstNull(lb_type(m, t_u8_ptr));
|
ptr = LLVMConstNull(lb_type(m, t_u8_ptr));
|
||||||
}
|
}
|
||||||
|
|||||||
+70
-129
@@ -1,3 +1,13 @@
|
|||||||
|
|
||||||
|
LLVMValueRef lb_call_intrinsic(lbProcedure *p, const char *name, LLVMValueRef* args, unsigned arg_count, LLVMTypeRef* types, unsigned type_count)
|
||||||
|
{
|
||||||
|
unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
|
||||||
|
GB_ASSERT_MSG(id != 0, "Unable to find %s", name);
|
||||||
|
LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, type_count);
|
||||||
|
LLVMTypeRef call_type = LLVMIntrinsicGetType(p->module->ctx, id, types, type_count);
|
||||||
|
return LLVMBuildCall2(p->builder, call_type, ip, args, arg_count, "");
|
||||||
|
}
|
||||||
|
|
||||||
void lb_mem_copy_overlapping(lbProcedure *p, lbValue dst, lbValue src, lbValue len, bool is_volatile) {
|
void lb_mem_copy_overlapping(lbProcedure *p, lbValue dst, lbValue src, lbValue len, bool is_volatile) {
|
||||||
dst = lb_emit_conv(p, dst, t_rawptr);
|
dst = lb_emit_conv(p, dst, t_rawptr);
|
||||||
src = lb_emit_conv(p, src, t_rawptr);
|
src = lb_emit_conv(p, src, t_rawptr);
|
||||||
@@ -10,23 +20,23 @@ void lb_mem_copy_overlapping(lbProcedure *p, lbValue dst, lbValue src, lbValue l
|
|||||||
name = "llvm.memmove.inline";
|
name = "llvm.memmove.inline";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LLVMTypeRef types[3] = {
|
LLVMTypeRef types[3] = {
|
||||||
lb_type(p->module, t_rawptr),
|
lb_type(p->module, t_rawptr),
|
||||||
lb_type(p->module, t_rawptr),
|
lb_type(p->module, t_rawptr),
|
||||||
lb_type(p->module, t_int)
|
lb_type(p->module, t_int)
|
||||||
};
|
};
|
||||||
unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
|
LLVMValueRef args[4] = {
|
||||||
GB_ASSERT_MSG(id != 0, "Unable to find %s.%s.%s.%s", name, LLVMPrintTypeToString(types[0]), LLVMPrintTypeToString(types[1]), LLVMPrintTypeToString(types[2]));
|
dst.value,
|
||||||
LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
|
src.value,
|
||||||
|
len.value,
|
||||||
|
LLVMConstInt(LLVMInt1TypeInContext(p->module->ctx), 0, is_volatile)
|
||||||
|
};
|
||||||
|
|
||||||
LLVMValueRef args[4] = {};
|
lb_call_intrinsic(p, name, args, gb_count_of(args), types, gb_count_of(types));
|
||||||
args[0] = dst.value;
|
|
||||||
args[1] = src.value;
|
|
||||||
args[2] = len.value;
|
|
||||||
args[3] = LLVMConstInt(LLVMInt1TypeInContext(p->module->ctx), 0, is_volatile);
|
|
||||||
LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void lb_mem_copy_non_overlapping(lbProcedure *p, lbValue dst, lbValue src, lbValue len, bool is_volatile) {
|
void lb_mem_copy_non_overlapping(lbProcedure *p, lbValue dst, lbValue src, lbValue len, bool is_volatile) {
|
||||||
dst = lb_emit_conv(p, dst, t_rawptr);
|
dst = lb_emit_conv(p, dst, t_rawptr);
|
||||||
src = lb_emit_conv(p, src, t_rawptr);
|
src = lb_emit_conv(p, src, t_rawptr);
|
||||||
@@ -45,16 +55,14 @@ void lb_mem_copy_non_overlapping(lbProcedure *p, lbValue dst, lbValue src, lbVal
|
|||||||
lb_type(p->module, t_rawptr),
|
lb_type(p->module, t_rawptr),
|
||||||
lb_type(p->module, t_int)
|
lb_type(p->module, t_int)
|
||||||
};
|
};
|
||||||
unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
|
|
||||||
GB_ASSERT_MSG(id != 0, "Unable to find %s.%s.%s.%s", name, LLVMPrintTypeToString(types[0]), LLVMPrintTypeToString(types[1]), LLVMPrintTypeToString(types[2]));
|
|
||||||
LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
|
|
||||||
|
|
||||||
LLVMValueRef args[4] = {};
|
LLVMValueRef args[4] = {
|
||||||
args[0] = dst.value;
|
dst.value,
|
||||||
args[1] = src.value;
|
src.value,
|
||||||
args[2] = len.value;
|
len.value,
|
||||||
args[3] = LLVMConstInt(LLVMInt1TypeInContext(p->module->ctx), 0, is_volatile);
|
LLVMConstInt(LLVMInt1TypeInContext(p->module->ctx), 0, is_volatile) };
|
||||||
LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
|
|
||||||
|
lb_call_intrinsic(p, name, args, gb_count_of(args), types, gb_count_of(types));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -122,7 +130,7 @@ lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool ignore_body)
|
|||||||
|
|
||||||
char *c_link_name = alloc_cstring(permanent_allocator(), p->name);
|
char *c_link_name = alloc_cstring(permanent_allocator(), p->name);
|
||||||
LLVMTypeRef func_ptr_type = lb_type(m, p->type);
|
LLVMTypeRef func_ptr_type = lb_type(m, p->type);
|
||||||
LLVMTypeRef func_type = LLVMGetElementType(func_ptr_type);
|
LLVMTypeRef func_type = lb_llvm_get_pointer_type(func_ptr_type);
|
||||||
|
|
||||||
p->value = LLVMAddFunction(m->mod, c_link_name, func_type);
|
p->value = LLVMAddFunction(m->mod, c_link_name, func_type);
|
||||||
|
|
||||||
@@ -347,7 +355,7 @@ lbProcedure *lb_create_dummy_procedure(lbModule *m, String link_name, Type *type
|
|||||||
|
|
||||||
char *c_link_name = alloc_cstring(permanent_allocator(), p->name);
|
char *c_link_name = alloc_cstring(permanent_allocator(), p->name);
|
||||||
LLVMTypeRef func_ptr_type = lb_type(m, p->type);
|
LLVMTypeRef func_ptr_type = lb_type(m, p->type);
|
||||||
LLVMTypeRef func_type = LLVMGetElementType(func_ptr_type);
|
LLVMTypeRef func_type = lb_llvm_get_pointer_type(func_ptr_type);
|
||||||
|
|
||||||
p->value = LLVMAddFunction(m->mod, c_link_name, func_type);
|
p->value = LLVMAddFunction(m->mod, c_link_name, func_type);
|
||||||
|
|
||||||
@@ -750,7 +758,7 @@ lbValue lb_emit_call_internal(lbProcedure *p, lbValue value, lbValue return_ptr,
|
|||||||
if (!lb_is_type_kind(LLVMTypeOf(value.value), LLVMFunctionTypeKind)) {
|
if (!lb_is_type_kind(LLVMTypeOf(value.value), LLVMFunctionTypeKind)) {
|
||||||
fn = LLVMBuildPointerCast(p->builder, fn, ftp, "");
|
fn = LLVMBuildPointerCast(p->builder, fn, ftp, "");
|
||||||
}
|
}
|
||||||
LLVMTypeRef fnp = LLVMGetElementType(LLVMTypeOf(fn));
|
LLVMTypeRef fnp = lb_llvm_get_pointer_type(LLVMTypeOf(fn));
|
||||||
GB_ASSERT_MSG(lb_is_type_kind(fnp, LLVMFunctionTypeKind), "%s", LLVMPrintTypeToString(fnp));
|
GB_ASSERT_MSG(lb_is_type_kind(fnp, LLVMFunctionTypeKind), "%s", LLVMPrintTypeToString(fnp));
|
||||||
|
|
||||||
{
|
{
|
||||||
@@ -1264,13 +1272,8 @@ lbValue lb_build_builtin_simd_proc(lbProcedure *p, Ast *expr, TypeAndValue const
|
|||||||
}
|
}
|
||||||
args[args_count++] = arg0.value;
|
args[args_count++] = arg0.value;
|
||||||
|
|
||||||
|
|
||||||
LLVMTypeRef types[1] = {lb_type(p->module, arg0.type)};
|
LLVMTypeRef types[1] = {lb_type(p->module, arg0.type)};
|
||||||
unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
|
res.value = lb_call_intrinsic(p, name, args, cast(unsigned)args_count, types, gb_count_of(types));
|
||||||
GB_ASSERT_MSG(id != 0, "Unable to find %s.%s", name, LLVMPrintTypeToString(types[0]));
|
|
||||||
LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
|
|
||||||
|
|
||||||
res.value = LLVMBuildCall(p->builder, ip, args, cast(unsigned)args_count, "");
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
case BuiltinProc_simd_reduce_min:
|
case BuiltinProc_simd_reduce_min:
|
||||||
@@ -1303,15 +1306,11 @@ lbValue lb_build_builtin_simd_proc(lbProcedure *p, Ast *expr, TypeAndValue const
|
|||||||
case BuiltinProc_simd_reduce_or: name = "llvm.vector.reduce.or"; break;
|
case BuiltinProc_simd_reduce_or: name = "llvm.vector.reduce.or"; break;
|
||||||
case BuiltinProc_simd_reduce_xor: name = "llvm.vector.reduce.xor"; break;
|
case BuiltinProc_simd_reduce_xor: name = "llvm.vector.reduce.xor"; break;
|
||||||
}
|
}
|
||||||
LLVMTypeRef types[1] = {lb_type(p->module, arg0.type)};
|
|
||||||
unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
|
|
||||||
GB_ASSERT_MSG(id != 0, "Unable to find %s.%s", name, LLVMPrintTypeToString(types[0]));
|
|
||||||
LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
|
|
||||||
|
|
||||||
LLVMValueRef args[1] = {};
|
LLVMTypeRef types[1] = { lb_type(p->module, arg0.type) };
|
||||||
args[0] = arg0.value;
|
LLVMValueRef args[1] = { arg0.value };
|
||||||
|
|
||||||
res.value = LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
|
res.value = lb_call_intrinsic(p, name, args, gb_count_of(args), types, gb_count_of(types));
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1360,15 +1359,10 @@ lbValue lb_build_builtin_simd_proc(lbProcedure *p, Ast *expr, TypeAndValue const
|
|||||||
case BuiltinProc_simd_nearest: name = "llvm.nearbyint"; break;
|
case BuiltinProc_simd_nearest: name = "llvm.nearbyint"; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
LLVMTypeRef types[1] = {lb_type(p->module, arg0.type)};
|
LLVMTypeRef types[1] = { lb_type(p->module, arg0.type) };
|
||||||
unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
|
LLVMValueRef args[1] = { arg0.value };
|
||||||
GB_ASSERT_MSG(id != 0, "Unable to find %s.%s", name, LLVMPrintTypeToString(types[0]));
|
|
||||||
LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
|
|
||||||
|
|
||||||
LLVMValueRef args[1] = {};
|
res.value = lb_call_intrinsic(p, name, args, gb_count_of(args), types, gb_count_of(types));
|
||||||
args[0] = arg0.value;
|
|
||||||
|
|
||||||
res.value = LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1432,15 +1426,10 @@ lbValue lb_build_builtin_simd_proc(lbProcedure *p, Ast *expr, TypeAndValue const
|
|||||||
}
|
}
|
||||||
|
|
||||||
LLVMTypeRef types[1] = {lb_type(p->module, arg0.type)};
|
LLVMTypeRef types[1] = {lb_type(p->module, arg0.type)};
|
||||||
unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
|
|
||||||
GB_ASSERT_MSG(id != 0, "Unable to find %s.%s", name, LLVMPrintTypeToString(types[0]));
|
|
||||||
LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
|
|
||||||
|
|
||||||
LLVMValueRef args[2] = {};
|
LLVMValueRef args[2] = { arg0.value, arg1.value };
|
||||||
args[0] = arg0.value;
|
|
||||||
args[1] = arg1.value;
|
|
||||||
|
|
||||||
res.value = LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
|
res.value = lb_call_intrinsic(p, name, args, gb_count_of(args), types, gb_count_of(types));
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1903,11 +1892,7 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
|
|||||||
case BuiltinProc_trap: name = "llvm.trap"; break;
|
case BuiltinProc_trap: name = "llvm.trap"; break;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
|
lb_call_intrinsic(p, name, nullptr, 0, nullptr, 0);
|
||||||
GB_ASSERT_MSG(id != 0, "Unable to find %s", name);
|
|
||||||
LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, nullptr, 0);
|
|
||||||
|
|
||||||
LLVMBuildCall(p->builder, ip, nullptr, 0, "");
|
|
||||||
if (id == BuiltinProc_trap) {
|
if (id == BuiltinProc_trap) {
|
||||||
LLVMBuildUnreachable(p->builder);
|
LLVMBuildUnreachable(p->builder);
|
||||||
}
|
}
|
||||||
@@ -1927,11 +1912,7 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
|
|||||||
res.value = LLVMBuildCall2(p->builder, func_type, the_asm, nullptr, 0, "");
|
res.value = LLVMBuildCall2(p->builder, func_type, the_asm, nullptr, 0, "");
|
||||||
} else {
|
} else {
|
||||||
char const *name = "llvm.readcyclecounter";
|
char const *name = "llvm.readcyclecounter";
|
||||||
unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
|
res.value = lb_call_intrinsic(p, name, nullptr, 0, nullptr, 0);
|
||||||
GB_ASSERT_MSG(id != 0, "Unable to find %s", name);
|
|
||||||
LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, nullptr, 0);
|
|
||||||
|
|
||||||
res.value = LLVMBuildCall(p->builder, ip, nullptr, 0, "");
|
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -1986,16 +1967,11 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
LLVMTypeRef types[1] = {lb_type(p->module, type)};
|
LLVMTypeRef types[1] = {lb_type(p->module, type)};
|
||||||
unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
|
|
||||||
GB_ASSERT_MSG(id != 0, "Unable to find %s.%s", name, LLVMPrintTypeToString(types[0]));
|
|
||||||
LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
|
|
||||||
|
|
||||||
LLVMValueRef args[2] = {};
|
LLVMValueRef args[2] = { x.value, y.value };
|
||||||
args[0] = x.value;
|
|
||||||
args[1] = y.value;
|
|
||||||
|
|
||||||
lbValue res = {};
|
lbValue res = {};
|
||||||
res.value = LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
|
res.value = lb_call_intrinsic(p, name, args, gb_count_of(args), types, gb_count_of(types));
|
||||||
|
|
||||||
if (is_type_tuple(main_type)) {
|
if (is_type_tuple(main_type)) {
|
||||||
Type *res_type = nullptr;
|
Type *res_type = nullptr;
|
||||||
@@ -2022,15 +1998,11 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
|
|||||||
|
|
||||||
char const *name = "llvm.sqrt";
|
char const *name = "llvm.sqrt";
|
||||||
LLVMTypeRef types[1] = {lb_type(p->module, type)};
|
LLVMTypeRef types[1] = {lb_type(p->module, type)};
|
||||||
unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
|
|
||||||
GB_ASSERT_MSG(id != 0, "Unable to find %s.%s", name, LLVMPrintTypeToString(types[0]));
|
|
||||||
LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
|
|
||||||
|
|
||||||
LLVMValueRef args[1] = {};
|
LLVMValueRef args[1] = { x.value };
|
||||||
args[0] = x.value;
|
|
||||||
|
|
||||||
lbValue res = {};
|
lbValue res = {};
|
||||||
res.value = LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
|
res.value = lb_call_intrinsic(p, name, args, gb_count_of(args), types, gb_count_of(types));
|
||||||
res.type = type;
|
res.type = type;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -2045,17 +2017,11 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
|
|||||||
|
|
||||||
char const *name = "llvm.fma";
|
char const *name = "llvm.fma";
|
||||||
LLVMTypeRef types[1] = {lb_type(p->module, type)};
|
LLVMTypeRef types[1] = {lb_type(p->module, type)};
|
||||||
unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
|
|
||||||
GB_ASSERT_MSG(id != 0, "Unable to find %s.%s", name, LLVMPrintTypeToString(types[0]));
|
|
||||||
LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
|
|
||||||
|
|
||||||
LLVMValueRef args[3] = {};
|
LLVMValueRef args[3] = { x.value, y.value, z.value };
|
||||||
args[0] = x.value;
|
|
||||||
args[1] = y.value;
|
|
||||||
args[2] = z.value;
|
|
||||||
|
|
||||||
lbValue res = {};
|
lbValue res = {};
|
||||||
res.value = LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
|
res.value = lb_call_intrinsic(p, name, args, gb_count_of(args), types, gb_count_of(types));
|
||||||
res.type = type;
|
res.type = type;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -2114,7 +2080,7 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
|
|||||||
|
|
||||||
lbValue res = {};
|
lbValue res = {};
|
||||||
res.type = tv.type;
|
res.type = tv.type;
|
||||||
res.value = LLVMBuildGEP(p->builder, ptr.value, indices, gb_count_of(indices), "");
|
res.value = LLVMBuildGEP2(p->builder, lb_type(p->module, type_deref(tv.type)), ptr.value, indices, gb_count_of(indices), "");
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
case BuiltinProc_ptr_sub:
|
case BuiltinProc_ptr_sub:
|
||||||
@@ -2123,7 +2089,7 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
|
|||||||
lbValue ptr1 = lb_build_expr(p, ce->args[1]);
|
lbValue ptr1 = lb_build_expr(p, ce->args[1]);
|
||||||
|
|
||||||
LLVMTypeRef type_int = lb_type(p->module, t_int);
|
LLVMTypeRef type_int = lb_type(p->module, t_int);
|
||||||
LLVMValueRef diff = LLVMBuildPtrDiff(p->builder, ptr0.value, ptr1.value, "");
|
LLVMValueRef diff = LLVMBuildPtrDiff2(p->builder, lb_type(p->module, ptr0.type), ptr0.value, ptr1.value, "");
|
||||||
diff = LLVMBuildIntCast2(p->builder, diff, type_int, /*signed*/true, "");
|
diff = LLVMBuildIntCast2(p->builder, diff, type_int, /*signed*/true, "");
|
||||||
|
|
||||||
lbValue res = {};
|
lbValue res = {};
|
||||||
@@ -2174,7 +2140,7 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
|
|||||||
case BuiltinProc_atomic_load_explicit: {
|
case BuiltinProc_atomic_load_explicit: {
|
||||||
lbValue dst = lb_build_expr(p, ce->args[0]);
|
lbValue dst = lb_build_expr(p, ce->args[0]);
|
||||||
|
|
||||||
LLVMValueRef instr = LLVMBuildLoad(p->builder, dst.value, "");
|
LLVMValueRef instr = LLVMBuildLoad2(p->builder, lb_type(p->module, type_deref(dst.type)), dst.value, "");
|
||||||
switch (id) {
|
switch (id) {
|
||||||
case BuiltinProc_non_temporal_load:
|
case BuiltinProc_non_temporal_load:
|
||||||
{
|
{
|
||||||
@@ -2348,18 +2314,14 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
|
|||||||
GB_ASSERT(name != nullptr);
|
GB_ASSERT(name != nullptr);
|
||||||
|
|
||||||
LLVMTypeRef types[1] = {lb_type(p->module, platform_type)};
|
LLVMTypeRef types[1] = {lb_type(p->module, platform_type)};
|
||||||
unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
|
|
||||||
GB_ASSERT_MSG(id != 0, "Unable to find %s.%s", name, LLVMPrintTypeToString(types[0]));
|
|
||||||
LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
|
|
||||||
|
|
||||||
lbValue res = {};
|
lbValue res = {};
|
||||||
|
|
||||||
LLVMValueRef args[3] = {};
|
LLVMValueRef args[3] = {
|
||||||
args[0] = x.value;
|
x.value,
|
||||||
args[1] = y.value;
|
y.value,
|
||||||
args[2] = scale.value;
|
scale.value };
|
||||||
|
|
||||||
res.value = LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
|
res.value = lb_call_intrinsic(p, name, args, gb_count_of(args), types, gb_count_of(types));
|
||||||
res.type = platform_type;
|
res.type = platform_type;
|
||||||
return lb_emit_conv(p, res, tv.type);
|
return lb_emit_conv(p, res, tv.type);
|
||||||
}
|
}
|
||||||
@@ -2373,17 +2335,10 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
|
|||||||
char const *name = "llvm.expect";
|
char const *name = "llvm.expect";
|
||||||
|
|
||||||
LLVMTypeRef types[1] = {lb_type(p->module, t)};
|
LLVMTypeRef types[1] = {lb_type(p->module, t)};
|
||||||
unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
|
|
||||||
GB_ASSERT_MSG(id != 0, "Unable to find %s.%s", name, LLVMPrintTypeToString(types[0]));
|
|
||||||
LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
|
|
||||||
|
|
||||||
lbValue res = {};
|
lbValue res = {};
|
||||||
|
LLVMValueRef args[2] = { x.value, y.value };
|
||||||
|
|
||||||
LLVMValueRef args[2] = {};
|
res.value = lb_call_intrinsic(p, name, args, gb_count_of(args), types, gb_count_of(types));
|
||||||
args[0] = x.value;
|
|
||||||
args[1] = y.value;
|
|
||||||
|
|
||||||
res.value = LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
|
|
||||||
res.type = t;
|
res.type = t;
|
||||||
return lb_emit_conv(p, res, t);
|
return lb_emit_conv(p, res, t);
|
||||||
}
|
}
|
||||||
@@ -2419,9 +2374,6 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
|
|||||||
char const *name = "llvm.prefetch";
|
char const *name = "llvm.prefetch";
|
||||||
|
|
||||||
LLVMTypeRef types[1] = {lb_type(p->module, t_rawptr)};
|
LLVMTypeRef types[1] = {lb_type(p->module, t_rawptr)};
|
||||||
unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
|
|
||||||
GB_ASSERT_MSG(id != 0, "Unable to find %s.%s", name, LLVMPrintTypeToString(types[0]));
|
|
||||||
LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
|
|
||||||
|
|
||||||
LLVMTypeRef llvm_i32 = lb_type(p->module, t_i32);
|
LLVMTypeRef llvm_i32 = lb_type(p->module, t_i32);
|
||||||
LLVMValueRef args[4] = {};
|
LLVMValueRef args[4] = {};
|
||||||
@@ -2431,7 +2383,7 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
|
|||||||
args[3] = LLVMConstInt(llvm_i32, cache, false);
|
args[3] = LLVMConstInt(llvm_i32, cache, false);
|
||||||
|
|
||||||
lbValue res = {};
|
lbValue res = {};
|
||||||
res.value = LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
|
res.value = lb_call_intrinsic(p, name, args, gb_count_of(args), types, gb_count_of(types));
|
||||||
res.type = nullptr;
|
res.type = nullptr;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -2677,7 +2629,8 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
|
|||||||
isize len = gb_snprintf(name, max_len, "csbs$%x", id);
|
isize len = gb_snprintf(name, max_len, "csbs$%x", id);
|
||||||
len -= 1;
|
len -= 1;
|
||||||
}
|
}
|
||||||
LLVMValueRef global_data = LLVMAddGlobal(m->mod, LLVMTypeOf(array), name);
|
LLVMTypeRef type = LLVMTypeOf(array);
|
||||||
|
LLVMValueRef global_data = LLVMAddGlobal(m->mod, type, name);
|
||||||
LLVMSetInitializer(global_data, array);
|
LLVMSetInitializer(global_data, array);
|
||||||
LLVMSetLinkage(global_data, LLVMInternalLinkage);
|
LLVMSetLinkage(global_data, LLVMInternalLinkage);
|
||||||
|
|
||||||
@@ -2689,7 +2642,7 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
|
|||||||
};
|
};
|
||||||
lbValue res = {};
|
lbValue res = {};
|
||||||
res.type = tv.type;
|
res.type = tv.type;
|
||||||
res.value = LLVMBuildInBoundsGEP(p->builder, global_data, indices, gb_count_of(indices), "");
|
res.value = LLVMBuildInBoundsGEP2(p->builder, type, global_data, indices, gb_count_of(indices), "");
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -2700,9 +2653,6 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
|
|||||||
LLVMTypeRef types[1] = {
|
LLVMTypeRef types[1] = {
|
||||||
lb_type(p->module, t_uintptr),
|
lb_type(p->module, t_uintptr),
|
||||||
};
|
};
|
||||||
unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
|
|
||||||
GB_ASSERT_MSG(id != 0, "Unable to find %s", name, LLVMPrintTypeToString(types[0]));
|
|
||||||
LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
|
|
||||||
|
|
||||||
LLVMValueRef args[2] = {};
|
LLVMValueRef args[2] = {};
|
||||||
args[0] = lb_emit_conv(p, lb_build_expr(p, ce->args[0]), t_uintptr).value;
|
args[0] = lb_emit_conv(p, lb_build_expr(p, ce->args[0]), t_uintptr).value;
|
||||||
@@ -2710,7 +2660,7 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
|
|||||||
|
|
||||||
lbValue res = {};
|
lbValue res = {};
|
||||||
res.type = tv.type;
|
res.type = tv.type;
|
||||||
res.value = LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
|
res.value = lb_call_intrinsic(p, name, args, gb_count_of(args), types, gb_count_of(types));
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
case BuiltinProc_wasm_memory_size:
|
case BuiltinProc_wasm_memory_size:
|
||||||
@@ -2719,16 +2669,13 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
|
|||||||
LLVMTypeRef types[1] = {
|
LLVMTypeRef types[1] = {
|
||||||
lb_type(p->module, t_uintptr),
|
lb_type(p->module, t_uintptr),
|
||||||
};
|
};
|
||||||
unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
|
|
||||||
GB_ASSERT_MSG(id != 0, "Unable to find %s", name, LLVMPrintTypeToString(types[0]));
|
|
||||||
LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
|
|
||||||
|
|
||||||
LLVMValueRef args[1] = {};
|
LLVMValueRef args[1] = {};
|
||||||
args[0] = lb_emit_conv(p, lb_build_expr(p, ce->args[0]), t_uintptr).value;
|
args[0] = lb_emit_conv(p, lb_build_expr(p, ce->args[0]), t_uintptr).value;
|
||||||
|
|
||||||
lbValue res = {};
|
lbValue res = {};
|
||||||
res.type = tv.type;
|
res.type = tv.type;
|
||||||
res.value = LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
|
res.value = lb_call_intrinsic(p, name, args, gb_count_of(args), types, gb_count_of(types));
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2738,9 +2685,6 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
|
|||||||
LLVMTypeRef types[1] = {
|
LLVMTypeRef types[1] = {
|
||||||
lb_type(p->module, t_u32),
|
lb_type(p->module, t_u32),
|
||||||
};
|
};
|
||||||
unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
|
|
||||||
GB_ASSERT_MSG(id != 0, "Unable to find %s", name, LLVMPrintTypeToString(types[0]));
|
|
||||||
LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, nullptr, 0); // types, gb_count_of(types));
|
|
||||||
|
|
||||||
Type *t_u32_ptr = alloc_type_pointer(t_u32);
|
Type *t_u32_ptr = alloc_type_pointer(t_u32);
|
||||||
|
|
||||||
@@ -2751,7 +2695,7 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
|
|||||||
|
|
||||||
lbValue res = {};
|
lbValue res = {};
|
||||||
res.type = tv.type;
|
res.type = tv.type;
|
||||||
res.value = LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
|
res.value = lb_call_intrinsic(p, name, args, gb_count_of(args), types, gb_count_of(types));
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2761,19 +2705,16 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
|
|||||||
LLVMTypeRef types[1] = {
|
LLVMTypeRef types[1] = {
|
||||||
lb_type(p->module, t_u32),
|
lb_type(p->module, t_u32),
|
||||||
};
|
};
|
||||||
unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
|
|
||||||
GB_ASSERT_MSG(id != 0, "Unable to find %s", name, LLVMPrintTypeToString(types[0]));
|
|
||||||
LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, nullptr, 0); // types, gb_count_of(types));
|
|
||||||
|
|
||||||
Type *t_u32_ptr = alloc_type_pointer(t_u32);
|
Type *t_u32_ptr = alloc_type_pointer(t_u32);
|
||||||
|
|
||||||
LLVMValueRef args[2] = {};
|
LLVMValueRef args[2] = {
|
||||||
args[0] = lb_emit_conv(p, lb_build_expr(p, ce->args[0]), t_u32_ptr).value;
|
lb_emit_conv(p, lb_build_expr(p, ce->args[0]), t_u32_ptr).value,
|
||||||
args[1] = lb_emit_conv(p, lb_build_expr(p, ce->args[1]), t_u32).value;
|
lb_emit_conv(p, lb_build_expr(p, ce->args[1]), t_u32).value };
|
||||||
|
|
||||||
lbValue res = {};
|
lbValue res = {};
|
||||||
res.type = tv.type;
|
res.type = tv.type;
|
||||||
res.value = LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
|
res.value = lb_call_intrinsic(p, name, args, gb_count_of(args), types, gb_count_of(types));
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2782,7 +2723,7 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
|
|||||||
{
|
{
|
||||||
Type *param_types[2] = {t_u32, t_u32};
|
Type *param_types[2] = {t_u32, t_u32};
|
||||||
Type *type = alloc_type_proc_from_types(param_types, gb_count_of(param_types), tv.type, false, ProcCC_None);
|
Type *type = alloc_type_proc_from_types(param_types, gb_count_of(param_types), tv.type, false, ProcCC_None);
|
||||||
LLVMTypeRef func_type = LLVMGetElementType(lb_type(p->module, type));
|
LLVMTypeRef func_type = lb_llvm_get_pointer_type(lb_type(p->module, type));
|
||||||
LLVMValueRef the_asm = llvm_get_inline_asm(
|
LLVMValueRef the_asm = llvm_get_inline_asm(
|
||||||
func_type,
|
func_type,
|
||||||
str_lit("cpuid"),
|
str_lit("cpuid"),
|
||||||
@@ -2802,7 +2743,7 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
|
|||||||
case BuiltinProc_x86_xgetbv:
|
case BuiltinProc_x86_xgetbv:
|
||||||
{
|
{
|
||||||
Type *type = alloc_type_proc_from_types(&t_u32, 1, tv.type, false, ProcCC_None);
|
Type *type = alloc_type_proc_from_types(&t_u32, 1, tv.type, false, ProcCC_None);
|
||||||
LLVMTypeRef func_type = LLVMGetElementType(lb_type(p->module, type));
|
LLVMTypeRef func_type = lb_llvm_get_pointer_type(lb_type(p->module, type));
|
||||||
LLVMValueRef the_asm = llvm_get_inline_asm(
|
LLVMValueRef the_asm = llvm_get_inline_asm(
|
||||||
func_type,
|
func_type,
|
||||||
str_lit("xgetbv"),
|
str_lit("xgetbv"),
|
||||||
|
|||||||
@@ -105,7 +105,8 @@ lbValue lb_type_info(lbModule *m, Type *type) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
lbValue value = {};
|
lbValue value = {};
|
||||||
value.value = LLVMConstGEP(lb_global_type_info_data_ptr(m).value, indices, gb_count_of(indices));
|
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;
|
value.type = t_type_info_ptr;
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
@@ -124,10 +125,16 @@ lbValue lb_get_type_info_ptr(lbModule *m, Type *type) {
|
|||||||
|
|
||||||
lbValue res = {};
|
lbValue res = {};
|
||||||
res.type = t_type_info_ptr;
|
res.type = t_type_info_ptr;
|
||||||
res.value = LLVMConstGEP(lb_global_type_info_data_ptr(m).value, indices, cast(unsigned)gb_count_of(indices));
|
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 res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The use of this method needs to be eliminated.
|
||||||
|
LLVMTypeRef lb_llvm_get_pointer_type(LLVMTypeRef type)
|
||||||
|
{
|
||||||
|
return LLVMGetElementType(type);
|
||||||
|
}
|
||||||
|
|
||||||
lbValue lb_type_info_member_types_offset(lbProcedure *p, isize count) {
|
lbValue lb_type_info_member_types_offset(lbProcedure *p, isize count) {
|
||||||
GB_ASSERT(p->module == &p->module->gen->default_module);
|
GB_ASSERT(p->module == &p->module->gen->default_module);
|
||||||
@@ -179,10 +186,10 @@ void lb_setup_type_info_data(lbProcedure *p) { // NOTE(bill): Setup type_info da
|
|||||||
|
|
||||||
LLVMValueRef indices[2] = {llvm_zero(m), llvm_zero(m)};
|
LLVMValueRef indices[2] = {llvm_zero(m), llvm_zero(m)};
|
||||||
LLVMValueRef values[2] = {
|
LLVMValueRef values[2] = {
|
||||||
LLVMConstInBoundsGEP(lb_global_type_info_data_ptr(m).value, indices, gb_count_of(indices)),
|
LLVMConstInBoundsGEP2(lb_type(m, lb_global_type_info_data_entity->type), lb_global_type_info_data_ptr(m).value, indices, gb_count_of(indices)),
|
||||||
LLVMConstInt(lb_type(m, t_int), type->Array.count, true),
|
LLVMConstInt(lb_type(m, t_int), type->Array.count, true),
|
||||||
};
|
};
|
||||||
LLVMValueRef slice = llvm_const_named_struct_internal(llvm_addr_type(global_type_table), values, gb_count_of(values));
|
LLVMValueRef slice = llvm_const_named_struct_internal(lb_type(m, type_deref(global_type_table.type)), values, gb_count_of(values));
|
||||||
|
|
||||||
LLVMSetInitializer(global_type_table.value, slice);
|
LLVMSetInitializer(global_type_table.value, slice);
|
||||||
}
|
}
|
||||||
|
|||||||
+66
-146
@@ -79,9 +79,6 @@ LLVMValueRef lb_mem_zero_ptr_internal(lbProcedure *p, LLVMValueRef ptr, LLVMValu
|
|||||||
lb_type(p->module, t_int)
|
lb_type(p->module, t_int)
|
||||||
};
|
};
|
||||||
if (true || is_inlinable) {
|
if (true || is_inlinable) {
|
||||||
unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
|
|
||||||
GB_ASSERT_MSG(id != 0, "Unable to find %s.%s.%s", name, LLVMPrintTypeToString(types[0]), LLVMPrintTypeToString(types[1]));
|
|
||||||
LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
|
|
||||||
|
|
||||||
LLVMValueRef args[4] = {};
|
LLVMValueRef args[4] = {};
|
||||||
args[0] = LLVMBuildPointerCast(p->builder, ptr, types[0], "");
|
args[0] = LLVMBuildPointerCast(p->builder, ptr, types[0], "");
|
||||||
@@ -89,16 +86,20 @@ LLVMValueRef lb_mem_zero_ptr_internal(lbProcedure *p, LLVMValueRef ptr, LLVMValu
|
|||||||
args[2] = LLVMBuildIntCast2(p->builder, len, types[1], /*signed*/false, "");
|
args[2] = LLVMBuildIntCast2(p->builder, len, types[1], /*signed*/false, "");
|
||||||
args[3] = LLVMConstInt(LLVMInt1TypeInContext(p->module->ctx), is_volatile, false);
|
args[3] = LLVMConstInt(LLVMInt1TypeInContext(p->module->ctx), is_volatile, false);
|
||||||
|
|
||||||
return LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
|
return lb_call_intrinsic(p, name, args, gb_count_of(args), types, gb_count_of(types));
|
||||||
} else {
|
} else {
|
||||||
LLVMValueRef ip = lb_lookup_runtime_procedure(p->module, str_lit("memset")).value;
|
lbValue pr = lb_lookup_runtime_procedure(p->module, str_lit("memset"));
|
||||||
|
|
||||||
LLVMValueRef args[3] = {};
|
LLVMValueRef args[3] = {};
|
||||||
args[0] = LLVMBuildPointerCast(p->builder, ptr, types[0], "");
|
args[0] = LLVMBuildPointerCast(p->builder, ptr, types[0], "");
|
||||||
args[1] = LLVMConstInt(LLVMInt32TypeInContext(p->module->ctx), 0, false);
|
args[1] = LLVMConstInt(LLVMInt32TypeInContext(p->module->ctx), 0, false);
|
||||||
args[2] = LLVMBuildIntCast2(p->builder, len, types[1], /*signed*/false, "");
|
args[2] = LLVMBuildIntCast2(p->builder, len, types[1], /*signed*/false, "");
|
||||||
|
|
||||||
return LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
|
// We always get the function pointer type rather than the function and there is apparently no way around that?
|
||||||
|
LLVMTypeRef type = lb_type(p->module, pr.type);
|
||||||
|
|
||||||
|
type = lb_llvm_get_pointer_type(type);
|
||||||
|
return LLVMBuildCall2(p->builder, type, pr.value, args, gb_count_of(args), "");
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -483,15 +484,11 @@ lbValue lb_emit_byte_swap(lbProcedure *p, lbValue value, Type *end_type) {
|
|||||||
|
|
||||||
char const *name = "llvm.bswap";
|
char const *name = "llvm.bswap";
|
||||||
LLVMTypeRef types[1] = {lb_type(p->module, value.type)};
|
LLVMTypeRef types[1] = {lb_type(p->module, value.type)};
|
||||||
unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
|
|
||||||
GB_ASSERT_MSG(id != 0, "Unable to find %s.%s", name, LLVMPrintTypeToString(types[0]));
|
|
||||||
LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
|
|
||||||
|
|
||||||
LLVMValueRef args[1] = {};
|
LLVMValueRef args[1] = { value.value };
|
||||||
args[0] = value.value;
|
|
||||||
|
|
||||||
lbValue res = {};
|
lbValue res = {};
|
||||||
res.value = LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
|
res.value = lb_call_intrinsic(p, name, args, gb_count_of(args), types, gb_count_of(types));
|
||||||
res.type = value.type;
|
res.type = value.type;
|
||||||
|
|
||||||
if (is_type_float(original_type)) {
|
if (is_type_float(original_type)) {
|
||||||
@@ -509,15 +506,10 @@ lbValue lb_emit_count_ones(lbProcedure *p, lbValue x, Type *type) {
|
|||||||
|
|
||||||
char const *name = "llvm.ctpop";
|
char const *name = "llvm.ctpop";
|
||||||
LLVMTypeRef types[1] = {lb_type(p->module, type)};
|
LLVMTypeRef types[1] = {lb_type(p->module, type)};
|
||||||
unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
|
LLVMValueRef args[1] = { x.value };
|
||||||
GB_ASSERT_MSG(id != 0, "Unable to find %s.%s", name, LLVMPrintTypeToString(types[0]));
|
|
||||||
LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
|
|
||||||
|
|
||||||
LLVMValueRef args[1] = {};
|
|
||||||
args[0] = x.value;
|
|
||||||
|
|
||||||
lbValue res = {};
|
lbValue res = {};
|
||||||
res.value = LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
|
res.value = lb_call_intrinsic(p, name, args, gb_count_of(args), types, gb_count_of(types));
|
||||||
res.type = type;
|
res.type = type;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -538,16 +530,13 @@ lbValue lb_emit_count_trailing_zeros(lbProcedure *p, lbValue x, Type *type) {
|
|||||||
|
|
||||||
char const *name = "llvm.cttz";
|
char const *name = "llvm.cttz";
|
||||||
LLVMTypeRef types[1] = {lb_type(p->module, type)};
|
LLVMTypeRef types[1] = {lb_type(p->module, type)};
|
||||||
unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
|
|
||||||
GB_ASSERT_MSG(id != 0, "Unable to find %s.%s", name, LLVMPrintTypeToString(types[0]));
|
|
||||||
LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
|
|
||||||
|
|
||||||
LLVMValueRef args[2] = {};
|
LLVMValueRef args[2] = {
|
||||||
args[0] = x.value;
|
x.value,
|
||||||
args[1] = LLVMConstNull(LLVMInt1TypeInContext(p->module->ctx));
|
LLVMConstNull(LLVMInt1TypeInContext(p->module->ctx)) };
|
||||||
|
|
||||||
lbValue res = {};
|
lbValue res = {};
|
||||||
res.value = LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
|
res.value = lb_call_intrinsic(p, name, args, gb_count_of(args), types, gb_count_of(types));
|
||||||
res.type = type;
|
res.type = type;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -557,16 +546,13 @@ lbValue lb_emit_count_leading_zeros(lbProcedure *p, lbValue x, Type *type) {
|
|||||||
|
|
||||||
char const *name = "llvm.ctlz";
|
char const *name = "llvm.ctlz";
|
||||||
LLVMTypeRef types[1] = {lb_type(p->module, type)};
|
LLVMTypeRef types[1] = {lb_type(p->module, type)};
|
||||||
unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
|
|
||||||
GB_ASSERT_MSG(id != 0, "Unable to find %s.%s", name, LLVMPrintTypeToString(types[0]));
|
|
||||||
LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
|
|
||||||
|
|
||||||
LLVMValueRef args[2] = {};
|
LLVMValueRef args[2] = {
|
||||||
args[0] = x.value;
|
x.value,
|
||||||
args[1] = LLVMConstNull(LLVMInt1TypeInContext(p->module->ctx));
|
LLVMConstNull(LLVMInt1TypeInContext(p->module->ctx)) };
|
||||||
|
|
||||||
lbValue res = {};
|
lbValue res = {};
|
||||||
res.value = LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
|
res.value = lb_call_intrinsic(p, name, args, gb_count_of(args), types, gb_count_of(types));
|
||||||
res.type = type;
|
res.type = type;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -578,15 +564,11 @@ lbValue lb_emit_reverse_bits(lbProcedure *p, lbValue x, Type *type) {
|
|||||||
|
|
||||||
char const *name = "llvm.bitreverse";
|
char const *name = "llvm.bitreverse";
|
||||||
LLVMTypeRef types[1] = {lb_type(p->module, type)};
|
LLVMTypeRef types[1] = {lb_type(p->module, type)};
|
||||||
unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
|
|
||||||
GB_ASSERT_MSG(id != 0, "Unable to find %s.%s", name, LLVMPrintTypeToString(types[0]));
|
|
||||||
LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
|
|
||||||
|
|
||||||
LLVMValueRef args[1] = {};
|
LLVMValueRef args[1] = { x.value };
|
||||||
args[0] = x.value;
|
|
||||||
|
|
||||||
lbValue res = {};
|
lbValue res = {};
|
||||||
res.value = LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
|
res.value = lb_call_intrinsic(p, name, args, gb_count_of(args), types, gb_count_of(types));
|
||||||
res.type = type;
|
res.type = type;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -1025,12 +1007,12 @@ lbValue lb_emit_struct_ep(lbProcedure *p, lbValue s, i32 index) {
|
|||||||
lbModule *m = p->module;
|
lbModule *m = p->module;
|
||||||
lbValue res = {};
|
lbValue res = {};
|
||||||
LLVMValueRef indices[2] = {llvm_zero(m), LLVMConstInt(lb_type(m, t_i32), index, false)};
|
LLVMValueRef indices[2] = {llvm_zero(m), LLVMConstInt(lb_type(m, t_i32), index, false)};
|
||||||
res.value = LLVMConstGEP(s.value, indices, gb_count_of(indices));
|
res.value = LLVMConstGEP2(lb_type(m, type_deref(s.type)), s.value, indices, gb_count_of(indices));
|
||||||
res.type = alloc_type_pointer(result_type);
|
res.type = alloc_type_pointer(result_type);
|
||||||
return res;
|
return res;
|
||||||
} else {
|
} else {
|
||||||
lbValue res = {};
|
lbValue res = {};
|
||||||
LLVMTypeRef st = LLVMGetElementType(LLVMTypeOf(s.value));
|
LLVMTypeRef st = lb_type(p->module, type_deref(s.type));
|
||||||
// gb_printf_err("%s\n", type_to_string(s.type));
|
// gb_printf_err("%s\n", type_to_string(s.type));
|
||||||
// gb_printf_err("%s\n", LLVMPrintTypeToString(LLVMTypeOf(s.value)));
|
// gb_printf_err("%s\n", LLVMPrintTypeToString(LLVMTypeOf(s.value)));
|
||||||
// gb_printf_err("%d\n", index);
|
// gb_printf_err("%d\n", index);
|
||||||
@@ -1038,7 +1020,7 @@ lbValue lb_emit_struct_ep(lbProcedure *p, lbValue s, i32 index) {
|
|||||||
unsigned count = LLVMCountStructElementTypes(st);
|
unsigned count = LLVMCountStructElementTypes(st);
|
||||||
GB_ASSERT_MSG(count >= cast(unsigned)index, "%u %d %d", count, index, original_index);
|
GB_ASSERT_MSG(count >= cast(unsigned)index, "%u %d %d", count, index, original_index);
|
||||||
|
|
||||||
res.value = LLVMBuildStructGEP(p->builder, s.value, cast(unsigned)index, "");
|
res.value = LLVMBuildStructGEP2(p->builder, st, s.value, cast(unsigned)index, "");
|
||||||
res.type = alloc_type_pointer(result_type);
|
res.type = alloc_type_pointer(result_type);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -1272,34 +1254,37 @@ lbValue lb_emit_array_ep(lbProcedure *p, lbValue s, lbValue index) {
|
|||||||
|
|
||||||
Type *ptr = base_array_type(st);
|
Type *ptr = base_array_type(st);
|
||||||
lbValue res = {};
|
lbValue res = {};
|
||||||
res.value = LLVMBuildGEP(p->builder, s.value, indices, 2, "");
|
res.value = LLVMBuildGEP2(p->builder, lb_type(p->module, st), s.value, indices, 2, "");
|
||||||
res.type = alloc_type_pointer(ptr);
|
res.type = alloc_type_pointer(ptr);
|
||||||
return res;
|
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));
|
||||||
|
} else {
|
||||||
|
res.value = LLVMBuildGEP2(p->builder, llvm_type, value, indices, gb_count_of(indices), "");
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
lbValue lb_emit_array_epi(lbProcedure *p, lbValue s, isize index) {
|
lbValue lb_emit_array_epi(lbProcedure *p, lbValue s, isize index) {
|
||||||
Type *t = s.type;
|
Type *t = s.type;
|
||||||
GB_ASSERT(is_type_pointer(t));
|
GB_ASSERT(is_type_pointer(t));
|
||||||
Type *st = base_type(type_deref(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_MSG(is_type_array(st) || is_type_enumerated_array(st) || is_type_matrix(st), "%s", type_to_string(st));
|
||||||
|
|
||||||
GB_ASSERT(0 <= index);
|
GB_ASSERT(0 <= index);
|
||||||
Type *ptr = base_array_type(st);
|
return lb_emit_gep(p, st, s.value, index);
|
||||||
|
|
||||||
|
|
||||||
LLVMValueRef indices[2] = {
|
|
||||||
LLVMConstInt(lb_type(p->module, t_int), 0, false),
|
|
||||||
LLVMConstInt(lb_type(p->module, t_int), cast(unsigned)index, false),
|
|
||||||
};
|
|
||||||
|
|
||||||
lbValue res = {};
|
|
||||||
if (lb_is_const(s)) {
|
|
||||||
res.value = LLVMConstGEP(s.value, indices, gb_count_of(indices));
|
|
||||||
} else {
|
|
||||||
res.value = LLVMBuildGEP(p->builder, s.value, indices, gb_count_of(indices), "");
|
|
||||||
}
|
|
||||||
res.type = alloc_type_pointer(ptr);
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lbValue lb_emit_ptr_offset(lbProcedure *p, lbValue ptr, lbValue index) {
|
lbValue lb_emit_ptr_offset(lbProcedure *p, lbValue ptr, lbValue index) {
|
||||||
@@ -1307,11 +1292,12 @@ lbValue lb_emit_ptr_offset(lbProcedure *p, lbValue ptr, lbValue index) {
|
|||||||
LLVMValueRef indices[1] = {index.value};
|
LLVMValueRef indices[1] = {index.value};
|
||||||
lbValue res = {};
|
lbValue res = {};
|
||||||
res.type = ptr.type;
|
res.type = ptr.type;
|
||||||
|
LLVMTypeRef type = lb_type(p->module, type_deref(ptr.type));
|
||||||
|
|
||||||
if (lb_is_const(ptr) && lb_is_const(index)) {
|
if (lb_is_const(ptr) && lb_is_const(index)) {
|
||||||
res.value = LLVMConstGEP(ptr.value, indices, 1);
|
res.value = LLVMConstGEP2(type, ptr.value, indices, 1);
|
||||||
} else {
|
} else {
|
||||||
res.value = LLVMBuildGEP(p->builder, ptr.value, indices, 1, "");
|
res.value = LLVMBuildGEP2(p->builder, type, ptr.value, indices, 1, "");
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@@ -1320,63 +1306,18 @@ lbValue lb_emit_matrix_epi(lbProcedure *p, lbValue s, isize row, isize column) {
|
|||||||
Type *t = s.type;
|
Type *t = s.type;
|
||||||
GB_ASSERT(is_type_pointer(t));
|
GB_ASSERT(is_type_pointer(t));
|
||||||
Type *mt = base_type(type_deref(t));
|
Type *mt = base_type(type_deref(t));
|
||||||
|
|
||||||
Type *ptr = base_array_type(mt);
|
|
||||||
|
|
||||||
if (column == 0) {
|
if (column == 0) {
|
||||||
GB_ASSERT_MSG(is_type_matrix(mt) || is_type_array_like(mt), "%s", type_to_string(mt));
|
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);
|
||||||
LLVMValueRef indices[2] = {
|
|
||||||
LLVMConstInt(lb_type(p->module, t_int), 0, false),
|
|
||||||
LLVMConstInt(lb_type(p->module, t_int), cast(unsigned)row, false),
|
|
||||||
};
|
|
||||||
|
|
||||||
lbValue res = {};
|
|
||||||
if (lb_is_const(s)) {
|
|
||||||
res.value = LLVMConstGEP(s.value, indices, gb_count_of(indices));
|
|
||||||
} else {
|
|
||||||
res.value = LLVMBuildGEP(p->builder, s.value, indices, gb_count_of(indices), "");
|
|
||||||
}
|
|
||||||
|
|
||||||
Type *ptr = base_array_type(mt);
|
|
||||||
res.type = alloc_type_pointer(ptr);
|
|
||||||
return res;
|
|
||||||
} else if (row == 0 && is_type_array_like(mt)) {
|
} else if (row == 0 && is_type_array_like(mt)) {
|
||||||
LLVMValueRef indices[2] = {
|
return lb_emit_gep(p, mt, s.value, column);
|
||||||
LLVMConstInt(lb_type(p->module, t_int), 0, false),
|
|
||||||
LLVMConstInt(lb_type(p->module, t_int), cast(unsigned)column, false),
|
|
||||||
};
|
|
||||||
|
|
||||||
lbValue res = {};
|
|
||||||
if (lb_is_const(s)) {
|
|
||||||
res.value = LLVMConstGEP(s.value, indices, gb_count_of(indices));
|
|
||||||
} else {
|
|
||||||
res.value = LLVMBuildGEP(p->builder, s.value, indices, gb_count_of(indices), "");
|
|
||||||
}
|
|
||||||
|
|
||||||
Type *ptr = base_array_type(mt);
|
|
||||||
res.type = alloc_type_pointer(ptr);
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
GB_ASSERT_MSG(is_type_matrix(mt), "%s", type_to_string(mt));
|
GB_ASSERT_MSG(is_type_matrix(mt), "%s", type_to_string(mt));
|
||||||
|
|
||||||
isize offset = matrix_indices_to_offset(mt, row, column);
|
isize offset = matrix_indices_to_offset(mt, row, column);
|
||||||
|
return lb_emit_gep(p, mt, s.value, offset);
|
||||||
LLVMValueRef indices[2] = {
|
|
||||||
LLVMConstInt(lb_type(p->module, t_int), 0, false),
|
|
||||||
LLVMConstInt(lb_type(p->module, t_int), cast(unsigned)offset, false),
|
|
||||||
};
|
|
||||||
|
|
||||||
lbValue res = {};
|
|
||||||
if (lb_is_const(s)) {
|
|
||||||
res.value = LLVMConstGEP(s.value, indices, gb_count_of(indices));
|
|
||||||
} else {
|
|
||||||
res.value = LLVMBuildGEP(p->builder, s.value, indices, gb_count_of(indices), "");
|
|
||||||
}
|
|
||||||
res.type = alloc_type_pointer(ptr);
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lbValue lb_emit_matrix_ep(lbProcedure *p, lbValue s, lbValue row, lbValue column) {
|
lbValue lb_emit_matrix_ep(lbProcedure *p, lbValue s, lbValue row, lbValue column) {
|
||||||
@@ -1399,11 +1340,12 @@ lbValue lb_emit_matrix_ep(lbProcedure *p, lbValue s, lbValue row, lbValue column
|
|||||||
index,
|
index,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
LLVMTypeRef type = lb_type(p->module, mt);
|
||||||
lbValue res = {};
|
lbValue res = {};
|
||||||
if (lb_is_const(s)) {
|
if (lb_is_const(s)) {
|
||||||
res.value = LLVMConstGEP(s.value, indices, gb_count_of(indices));
|
res.value = LLVMConstGEP2(type, s.value, indices, gb_count_of(indices));
|
||||||
} else {
|
} else {
|
||||||
res.value = LLVMBuildGEP(p->builder, s.value, indices, gb_count_of(indices), "");
|
res.value = LLVMBuildGEP2(p->builder, type, s.value, indices, gb_count_of(indices), "");
|
||||||
}
|
}
|
||||||
res.type = alloc_type_pointer(ptr);
|
res.type = alloc_type_pointer(ptr);
|
||||||
return res;
|
return res;
|
||||||
@@ -1607,18 +1549,12 @@ lbValue lb_emit_mul_add(lbProcedure *p, lbValue a, lbValue b, lbValue c, Type *t
|
|||||||
|
|
||||||
if (is_possible) {
|
if (is_possible) {
|
||||||
char const *name = "llvm.fma";
|
char const *name = "llvm.fma";
|
||||||
unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
|
LLVMTypeRef types[1] = { lb_type(m, t) };
|
||||||
GB_ASSERT_MSG(id != 0, "Unable to find %s", name);
|
LLVMValueRef values[3] = {
|
||||||
|
a.value,
|
||||||
LLVMTypeRef types[1] = {};
|
b.value,
|
||||||
types[0] = lb_type(m, t);
|
c.value };
|
||||||
|
LLVMValueRef call = lb_call_intrinsic(p, name, values, gb_count_of(values), types, gb_count_of(types));
|
||||||
LLVMValueRef ip = LLVMGetIntrinsicDeclaration(m->mod, id, types, gb_count_of(types));
|
|
||||||
LLVMValueRef values[3] = {};
|
|
||||||
values[0] = a.value;
|
|
||||||
values[1] = b.value;
|
|
||||||
values[2] = c.value;
|
|
||||||
LLVMValueRef call = LLVMBuildCall(p->builder, ip, values, gb_count_of(values), "");
|
|
||||||
return {call, t};
|
return {call, t};
|
||||||
} else {
|
} else {
|
||||||
lbValue x = lb_emit_arith(p, Token_Mul, a, b, t);
|
lbValue x = lb_emit_arith(p, Token_Mul, a, b, t);
|
||||||
@@ -1747,15 +1683,9 @@ LLVMValueRef llvm_vector_reduce_add(lbProcedure *p, LLVMValueRef value) {
|
|||||||
|
|
||||||
unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
|
unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
|
||||||
if (id != 0 && false) {
|
if (id != 0 && false) {
|
||||||
LLVMTypeRef types[1] = {};
|
LLVMTypeRef types[1] = { type };
|
||||||
types[0] = type;
|
LLVMValueRef values[2] = { LLVMConstNull(elem), value };
|
||||||
|
return lb_call_intrinsic(p, name, values + value_offset, value_count, types, gb_count_of(types));
|
||||||
LLVMValueRef ip = LLVMGetIntrinsicDeclaration(p->module->mod, id, types, gb_count_of(types));
|
|
||||||
LLVMValueRef values[2] = {};
|
|
||||||
values[0] = LLVMConstNull(elem);
|
|
||||||
values[1] = value;
|
|
||||||
LLVMValueRef call = LLVMBuildCall(p->builder, ip, values+value_offset, value_count, "");
|
|
||||||
return call;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Manual reduce
|
// Manual reduce
|
||||||
@@ -1824,7 +1754,6 @@ LLVMValueRef llvm_vector_dot(lbProcedure *p, LLVMValueRef a, LLVMValueRef b) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
LLVMValueRef llvm_vector_mul_add(lbProcedure *p, LLVMValueRef a, LLVMValueRef b, LLVMValueRef c) {
|
LLVMValueRef llvm_vector_mul_add(lbProcedure *p, LLVMValueRef a, LLVMValueRef b, LLVMValueRef c) {
|
||||||
lbModule *m = p->module;
|
|
||||||
|
|
||||||
LLVMTypeRef t = LLVMTypeOf(a);
|
LLVMTypeRef t = LLVMTypeOf(a);
|
||||||
GB_ASSERT(t == LLVMTypeOf(b));
|
GB_ASSERT(t == LLVMTypeOf(b));
|
||||||
@@ -1847,18 +1776,9 @@ LLVMValueRef llvm_vector_mul_add(lbProcedure *p, LLVMValueRef a, LLVMValueRef b,
|
|||||||
|
|
||||||
if (is_possible) {
|
if (is_possible) {
|
||||||
char const *name = "llvm.fmuladd";
|
char const *name = "llvm.fmuladd";
|
||||||
unsigned id = LLVMLookupIntrinsicID(name, gb_strlen(name));
|
LLVMTypeRef types[1] = { t };
|
||||||
GB_ASSERT_MSG(id != 0, "Unable to find %s", name);
|
LLVMValueRef values[3] = { a, b, c};
|
||||||
|
LLVMValueRef call = lb_call_intrinsic(p, name, values, gb_count_of(values), types, gb_count_of(types));
|
||||||
LLVMTypeRef types[1] = {};
|
|
||||||
types[0] = t;
|
|
||||||
|
|
||||||
LLVMValueRef ip = LLVMGetIntrinsicDeclaration(m->mod, id, types, gb_count_of(types));
|
|
||||||
LLVMValueRef values[3] = {};
|
|
||||||
values[0] = a;
|
|
||||||
values[1] = b;
|
|
||||||
values[2] = c;
|
|
||||||
LLVMValueRef call = LLVMBuildCall(p->builder, ip, values, gb_count_of(values), "");
|
|
||||||
return call;
|
return call;
|
||||||
} else {
|
} else {
|
||||||
LLVMValueRef x = llvm_vector_mul(p, a, b);
|
LLVMValueRef x = llvm_vector_mul(p, a, b);
|
||||||
|
|||||||
Reference in New Issue
Block a user