Merge branch 'master' into new-matrix-type

This commit is contained in:
gingerBill
2021-10-23 19:24:47 +01:00
18 changed files with 270 additions and 123 deletions
+4
View File
@@ -2749,6 +2749,8 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
case BuiltinProc_volatile_store:
/*fallthrough*/
case BuiltinProc_unaligned_store:
/*fallthrough*/
case BuiltinProc_atomic_store:
case BuiltinProc_atomic_store_rel:
case BuiltinProc_atomic_store_relaxed:
@@ -2770,6 +2772,8 @@ bool check_builtin_procedure(CheckerContext *c, Operand *operand, Ast *call, i32
case BuiltinProc_volatile_load:
/*fallthrough*/
case BuiltinProc_unaligned_load:
/*fallthrough*/
case BuiltinProc_atomic_load:
case BuiltinProc_atomic_load_acq:
case BuiltinProc_atomic_load_relaxed:
+21 -9
View File
@@ -837,7 +837,7 @@ void check_assignment(CheckerContext *c, Operand *operand, Type *type, String co
operand->mode = Addressing_Invalid;
}
convert_to_typed(c, operand, type);
return;
}
@@ -3208,6 +3208,10 @@ void update_untyped_expr_type(CheckerContext *c, Ast *e, Type *type, bool final)
if (type != nullptr && type != t_invalid) {
if (e->tav.type == nullptr || e->tav.type == t_invalid) {
add_type_and_value(c->info, e, e->tav.mode, type ? type : e->tav.type, e->tav.value);
if (e->kind == Ast_TernaryIfExpr) {
update_untyped_expr_type(c, e->TernaryIfExpr.x, type, final);
update_untyped_expr_type(c, e->TernaryIfExpr.y, type, final);
}
}
}
return;
@@ -3414,9 +3418,9 @@ void convert_to_typed(CheckerContext *c, Operand *operand, Type *target_type) {
case Basic_UntypedNil:
if (is_type_any(target_type)) {
target_type = t_untyped_nil;
// target_type = t_untyped_nil;
} else if (is_type_cstring(target_type)) {
target_type = t_untyped_nil;
// target_type = t_untyped_nil;
} else if (!type_has_nil(target_type)) {
operand->mode = Addressing_Invalid;
convert_untyped_error(c, operand, target_type);
@@ -3587,6 +3591,14 @@ void convert_to_typed(CheckerContext *c, Operand *operand, Type *target_type) {
}
break;
}
if (is_type_any(target_type) && is_type_untyped(operand->type)) {
if (is_type_untyped_nil(operand->type) && is_type_untyped_undef(operand->type)) {
} else {
target_type = default_type(operand->type);
}
}
update_untyped_expr_type(c, operand->expr, target_type, true);
operand->type = target_type;
@@ -7030,18 +7042,18 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type
return kind;
}
Type *type = x.type;
if (is_type_untyped_nil(type) || is_type_untyped_undef(type)) {
type = y.type;
o->type = x.type;
if (is_type_untyped_nil(o->type) || is_type_untyped_undef(o->type)) {
o->type = y.type;
}
o->type = type;
o->mode = Addressing_Value;
if (type_hint != nullptr && is_type_untyped(type)) {
o->expr = node;
if (type_hint != nullptr && is_type_untyped(o->type)) {
if (check_cast_internal(c, &x, type_hint) &&
check_cast_internal(c, &y, type_hint)) {
convert_to_typed(c, o, type_hint);
update_untyped_expr_type(c, node, type_hint, !is_type_untyped(type_hint));
o->type = type_hint;
}
}
case_end;
+11 -2
View File
@@ -1111,9 +1111,12 @@ void check_set_expr_info(CheckerContext *c, Ast *expr, AddressingMode mode, Type
void check_remove_expr_info(CheckerContext *c, Ast *e) {
if (c->untyped != nullptr) {
map_remove(c->untyped, hash_pointer(e));
GB_ASSERT(map_get(c->untyped, hash_pointer(e)) == nullptr);
} else {
auto *untyped = &c->info->global_untyped;
mutex_lock(&c->info->global_untyped_mutex);
map_remove(&c->info->global_untyped, hash_pointer(e));
map_remove(untyped, hash_pointer(e));
GB_ASSERT(map_get(untyped, hash_pointer(e)) == nullptr);
mutex_unlock(&c->info->global_untyped_mutex);
}
}
@@ -1190,7 +1193,13 @@ void add_type_and_value(CheckerInfo *i, Ast *expr, AddressingMode mode, Type *ty
while (prev_expr != expr) {
prev_expr = expr;
expr->tav.mode = mode;
expr->tav.type = type;
if (type != nullptr && expr->tav.type != nullptr &&
is_type_any(type) && is_type_untyped(expr->tav.type)) {
// ignore
} else {
expr->tav.type = type;
}
if (mode == Addressing_Constant || mode == Addressing_Invalid) {
expr->tav.value = value;
} else if (mode == Addressing_Value && is_type_typeid(type)) {
+6
View File
@@ -77,6 +77,9 @@ enum BuiltinProcId {
BuiltinProc_volatile_store,
BuiltinProc_volatile_load,
BuiltinProc_unaligned_store,
BuiltinProc_unaligned_load,
BuiltinProc_prefetch_read_instruction,
BuiltinProc_prefetch_read_data,
BuiltinProc_prefetch_write_instruction,
@@ -326,6 +329,9 @@ gb_global BuiltinProc builtin_procs[BuiltinProc_COUNT] = {
{STR_LIT("volatile_store"), 2, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
{STR_LIT("volatile_load"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("unaligned_store"), 2, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
{STR_LIT("unaligned_load"), 1, false, Expr_Expr, BuiltinProcPkg_intrinsics},
{STR_LIT("prefetch_read_instruction"), 2, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
{STR_LIT("prefetch_read_data"), 2, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
{STR_LIT("prefetch_write_instruction"), 2, false, Expr_Stmt, BuiltinProcPkg_intrinsics},
+1 -1
View File
@@ -329,7 +329,7 @@ LLVMValueRef lb_big_int_to_llvm(lbModule *m, Type *original_type, BigInt const *
debug_print_big_int(a);
gb_printf_err("%s -> %tu\n", type_to_string(original_type), sz);;
}
GB_ASSERT_MSG(sz >= max_count, "max_count: %tu, sz: %tu, written: %tu", max_count, sz, written);
GB_ASSERT_MSG(sz >= max_count, "max_count: %tu, sz: %tu, written: %tu, type %s", max_count, sz, written, type_to_string(original_type));
GB_ASSERT(gb_size_of(rop64) >= sz);
mp_err err = mp_pack(rop, sz, &written,
+13 -13
View File
@@ -2806,17 +2806,18 @@ lbValue lb_build_expr(lbProcedure *p, Ast *expr) {
TokenPos expr_pos = ast_token(expr).pos;
TypeAndValue tv = type_and_value_of_expr(expr);
Type *type = type_of_expr(expr);
GB_ASSERT_MSG(tv.mode != Addressing_Invalid, "invalid expression '%s' (tv.mode = %d, tv.type = %s) @ %s\n Current Proc: %.*s : %s", expr_to_string(expr), tv.mode, type_to_string(tv.type), token_pos_to_string(expr_pos), LIT(p->name), type_to_string(p->type));
if (tv.value.kind != ExactValue_Invalid) {
// NOTE(bill): The commented out code below is just for debug purposes only
// GB_ASSERT_MSG(!is_type_untyped(tv.type), "%s @ %s\n%s", type_to_string(tv.type), token_pos_to_string(expr_pos), expr_to_string(expr));
// if (is_type_untyped(tv.type)) {
// gb_printf_err("%s %s\n", token_pos_to_string(expr_pos), expr_to_string(expr));
// if (is_type_untyped(type)) {
// gb_printf_err("%s %s : %s @ %p\n", token_pos_to_string(expr_pos), expr_to_string(expr), type_to_string(expr->tav.type), expr);
// GB_PANIC("%s\n", type_to_string(tv.type));
// }
// NOTE(bill): Short on constant values
return lb_const_value(p->module, tv.type, tv.value);
return lb_const_value(p->module, type, tv.value);
}
#if 0
@@ -2847,12 +2848,12 @@ lbValue lb_build_expr(lbProcedure *p, Ast *expr) {
case_ast_node(u, Undef, expr)
lbValue res = {};
if (is_type_untyped(tv.type)) {
if (is_type_untyped(type)) {
res.value = nullptr;
res.type = t_untyped_undef;
} else {
res.value = LLVMGetUndef(lb_type(m, tv.type));
res.type = tv.type;
res.value = LLVMGetUndef(lb_type(m, type));
res.type = type;
}
return res;
case_end;
@@ -2893,7 +2894,7 @@ lbValue lb_build_expr(lbProcedure *p, Ast *expr) {
TypeAndValue tav = type_and_value_of_expr(expr);
GB_ASSERT(tav.mode == Addressing_Constant);
return lb_const_value(p->module, tv.type, tv.value);
return lb_const_value(p->module, type, tv.value);
case_end;
case_ast_node(se, SelectorCallExpr, expr);
@@ -2966,7 +2967,6 @@ lbValue lb_build_expr(lbProcedure *p, Ast *expr) {
case_ast_node(ta, TypeAssertion, expr);
TokenPos pos = ast_token(expr).pos;
Type *type = tv.type;
lbValue e = lb_build_expr(p, ta->expr);
Type *t = type_deref(e.type);
if (is_type_union(t)) {
@@ -2986,16 +2986,16 @@ lbValue lb_build_expr(lbProcedure *p, Ast *expr) {
lbValue e = lb_build_expr(p, tc->expr);
switch (tc->token.kind) {
case Token_cast:
return lb_emit_conv(p, e, tv.type);
return lb_emit_conv(p, e, type);
case Token_transmute:
return lb_emit_transmute(p, e, tv.type);
return lb_emit_transmute(p, e, type);
}
GB_PANIC("Invalid AST TypeCast");
case_end;
case_ast_node(ac, AutoCast, expr);
lbValue value = lb_build_expr(p, ac->expr);
return lb_emit_conv(p, value, tv.type);
return lb_emit_conv(p, value, type);
case_end;
case_ast_node(ue, UnaryExpr, expr);
@@ -3005,7 +3005,7 @@ lbValue lb_build_expr(lbProcedure *p, Ast *expr) {
default:
{
lbValue v = lb_build_expr(p, ue->expr);
return lb_emit_unary_arith(p, ue->op.kind, v, tv.type);
return lb_emit_unary_arith(p, ue->op.kind, v, type);
}
}
case_end;
+88 -50
View File
@@ -1,3 +1,62 @@
void lb_mem_copy_overlapping(lbProcedure *p, lbValue dst, lbValue src, lbValue len, bool is_volatile=false) {
dst = lb_emit_conv(p, dst, t_rawptr);
src = lb_emit_conv(p, src, t_rawptr);
len = lb_emit_conv(p, len, t_int);
char const *name = "llvm.memmove";
if (LLVMIsConstant(len.value)) {
i64 const_len = cast(i64)LLVMConstIntGetSExtValue(len.value);
if (const_len <= 4*build_context.word_size) {
name = "llvm.memmove.inline";
}
}
LLVMTypeRef types[3] = {
lb_type(p->module, t_rawptr),
lb_type(p->module, t_rawptr),
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] = {};
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=false) {
dst = lb_emit_conv(p, dst, t_rawptr);
src = lb_emit_conv(p, src, t_rawptr);
len = lb_emit_conv(p, len, t_int);
char const *name = "llvm.memcpy";
if (LLVMIsConstant(len.value)) {
i64 const_len = cast(i64)LLVMConstIntGetSExtValue(len.value);
if (const_len <= 4*build_context.word_size) {
name = "llvm.memcpy.inline";
}
}
LLVMTypeRef types[3] = {
lb_type(p->module, t_rawptr),
lb_type(p->module, t_rawptr),
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] = {};
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), "");
}
lbProcedure *lb_create_procedure(lbModule *m, Entity *entity, bool ignore_body) {
GB_ASSERT(entity != nullptr);
@@ -1487,61 +1546,21 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
}
case BuiltinProc_mem_copy:
{
lbValue dst = lb_build_expr(p, ce->args[0]);
lbValue src = lb_build_expr(p, ce->args[1]);
lbValue len = lb_build_expr(p, ce->args[2]);
lb_mem_copy_overlapping(p, dst, src, len, false);
return {};
}
case BuiltinProc_mem_copy_non_overlapping:
{
lbValue dst = lb_build_expr(p, ce->args[0]);
lbValue src = lb_build_expr(p, ce->args[1]);
lbValue len = lb_build_expr(p, ce->args[2]);
dst = lb_emit_conv(p, dst, t_rawptr);
src = lb_emit_conv(p, src, t_rawptr);
len = lb_emit_conv(p, len, t_int);
bool is_inlinable = false;
if (ce->args[2]->tav.mode == Addressing_Constant) {
ExactValue ev = exact_value_to_integer(ce->args[2]->tav.value);
i64 const_len = exact_value_to_i64(ev);
// TODO(bill): Determine when it is better to do the `*.inline` versions
if (const_len <= 4*build_context.word_size) {
is_inlinable = true;
}
}
char const *name = nullptr;
switch (id) {
case BuiltinProc_mem_copy:
if (is_inlinable) {
name = "llvm.memmove.inline";
} else {
name = "llvm.memmove";
}
break;
case BuiltinProc_mem_copy_non_overlapping:
if (is_inlinable) {
name = "llvm.memcpy.line";
} else {
name = "llvm.memcpy";
}
break;
}
LLVMTypeRef types[3] = {
lb_type(p->module, t_rawptr),
lb_type(p->module, t_rawptr),
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] = {};
args[0] = dst.value;
args[1] = src.value;
args[2] = len.value;
args[3] = LLVMConstInt(LLVMInt1TypeInContext(p->module->ctx), 0, false); // is_volatile parameter
LLVMBuildCall(p->builder, ip, args, gb_count_of(args), "");
lb_mem_copy_non_overlapping(p, dst, src, len, false);
return {};
}
@@ -1647,6 +1666,25 @@ lbValue lb_build_builtin_proc(lbProcedure *p, Ast *expr, TypeAndValue const &tv,
res.type = type_deref(dst.type);
return res;
}
case BuiltinProc_unaligned_store:
{
lbValue dst = lb_build_expr(p, ce->args[0]);
lbValue src = lb_build_expr(p, ce->args[1]);
src = lb_address_from_load_or_generate_local(p, src);
Type *t = type_deref(dst.type);
lb_mem_copy_non_overlapping(p, dst, src, lb_const_int(p->module, t_int, type_size_of(t)), false);
return {};
}
case BuiltinProc_unaligned_load:
{
lbValue src = lb_build_expr(p, ce->args[0]);
Type *t = type_deref(src.type);
lbAddr dst = lb_add_local_generated(p, t, false);
lb_mem_copy_non_overlapping(p, dst.addr, src, lb_const_int(p->module, t_int, type_size_of(t)), false);
return lb_addr_load(p, dst);
}
case BuiltinProc_atomic_add:
case BuiltinProc_atomic_add_acq:
+6 -3
View File
@@ -632,7 +632,9 @@ enum BuildFlagKind {
BuildFlag_IgnoreWarnings,
BuildFlag_WarningsAsErrors,
BuildFlag_VerboseErrors,
BuildFlag_IgnoreLazy, // internal use only
// internal use only
BuildFlag_InternalIgnoreLazy,
#if defined(GB_SYSTEM_WINDOWS)
BuildFlag_IgnoreVsSearch,
@@ -779,7 +781,8 @@ bool parse_build_flags(Array<String> args) {
add_flag(&build_flags, BuildFlag_IgnoreWarnings, str_lit("ignore-warnings"), BuildFlagParam_None, Command_all);
add_flag(&build_flags, BuildFlag_WarningsAsErrors, str_lit("warnings-as-errors"), BuildFlagParam_None, Command_all);
add_flag(&build_flags, BuildFlag_VerboseErrors, str_lit("verbose-errors"), BuildFlagParam_None, Command_all);
add_flag(&build_flags, BuildFlag_IgnoreLazy, str_lit("ignore-lazy"), BuildFlagParam_None, Command_all);
add_flag(&build_flags, BuildFlag_InternalIgnoreLazy, str_lit("internal-ignore-lazy"), BuildFlagParam_None, Command_all);
#if defined(GB_SYSTEM_WINDOWS)
add_flag(&build_flags, BuildFlag_IgnoreVsSearch, str_lit("ignore-vs-search"), BuildFlagParam_None, Command__does_build);
@@ -1393,7 +1396,7 @@ bool parse_build_flags(Array<String> args) {
build_context.show_error_line = true;
break;
case BuildFlag_IgnoreLazy:
case BuildFlag_InternalIgnoreLazy:
build_context.ignore_lazy = true;
break;
+22 -18
View File
@@ -114,16 +114,17 @@ gb_internal isize map__add_entry(Map<T> *h, HashKey const &key) {
template <typename T>
gb_internal MapFindResult map__find(Map<T> *h, HashKey const &key) {
MapFindResult fr = {-1, -1, -1};
if (h->hashes.count > 0) {
fr.hash_index = key.key & (h->hashes.count-1);
fr.entry_index = h->hashes.data[fr.hash_index];
while (fr.entry_index >= 0) {
if (hash_key_equal(h->entries.data[fr.entry_index].key, key)) {
return fr;
}
fr.entry_prev = fr.entry_index;
fr.entry_index = h->entries.data[fr.entry_index].next;
if (h->hashes.count == 0) {
return fr;
}
fr.hash_index = key.key & (h->hashes.count-1);
fr.entry_index = h->hashes.data[fr.hash_index];
while (fr.entry_index >= 0) {
if (hash_key_equal(h->entries.data[fr.entry_index].key, key)) {
return fr;
}
fr.entry_prev = fr.entry_index;
fr.entry_index = h->entries.data[fr.entry_index].next;
}
return fr;
}
@@ -131,16 +132,17 @@ gb_internal MapFindResult map__find(Map<T> *h, HashKey const &key) {
template <typename T>
gb_internal MapFindResult map__find_from_entry(Map<T> *h, MapEntry<T> *e) {
MapFindResult fr = {-1, -1, -1};
if (h->hashes.count > 0) {
fr.hash_index = e->key.key & (h->hashes.count-1);
fr.entry_index = h->hashes.data[fr.hash_index];
while (fr.entry_index >= 0) {
if (&h->entries.data[fr.entry_index] == e) {
return fr;
}
fr.entry_prev = fr.entry_index;
fr.entry_index = h->entries.data[fr.entry_index].next;
if (h->hashes.count == 0) {
return fr;
}
fr.hash_index = e->key.key & (h->hashes.count-1);
fr.entry_index = h->hashes.data[fr.hash_index];
while (fr.entry_index >= 0) {
if (&h->entries.data[fr.entry_index] == e) {
return fr;
}
fr.entry_prev = fr.entry_index;
fr.entry_index = h->entries.data[fr.entry_index].next;
}
return fr;
}
@@ -246,6 +248,8 @@ void map__erase(Map<T> *h, MapFindResult const &fr) {
return;
}
h->entries.data[fr.entry_index] = h->entries.data[h->entries.count-1];
array_pop(&h->entries);
last = map__find(h, h->entries.data[fr.entry_index].key);
if (last.entry_prev >= 0) {
h->entries.data[last.entry_prev].next = fr.entry_index;
+4 -2
View File
@@ -2572,6 +2572,9 @@ bool is_literal_type(Ast *node) {
case Ast_MatrixType:
case Ast_CallExpr:
return true;
case Ast_MultiPointerType:
// For better error messages
return true;
}
return false;
}
@@ -5426,8 +5429,7 @@ bool parse_file(Parser *p, AstFile *f) {
// Ignore
} else if (f->flags & AstFile_IsTest) {
// Ignore
} else if (build_context.command_kind == Command_doc &&
f->pkg->kind == Package_Init) {
} else if (f->pkg->kind == Package_Init && build_context.command_kind == Command_doc) {
// Ignore
} else {
f->flags |= AstFile_IsLazy;
+1 -1
View File
@@ -28,9 +28,9 @@ enum AddressingMode : u8 {
};
struct TypeAndValue {
Type * type;
AddressingMode mode;
bool is_lhs; // Debug info
Type * type;
ExactValue value;
};