From 2a2d3273eae791c5c21eb77374f4818c2a76ae1b Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 12 Mar 2020 14:40:13 +0000 Subject: [PATCH 01/12] Add `@require` for global variables --- src/check_decl.cpp | 5 +++++ src/checker.cpp | 22 ++++++++++++++++++---- src/checker.hpp | 3 ++- src/ir.cpp | 2 ++ 4 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/check_decl.cpp b/src/check_decl.cpp index ece38e84f..0e12a2822 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -843,6 +843,11 @@ void check_global_variable_decl(CheckerContext *ctx, Entity *e, Ast *type_expr, check_decl_attributes(ctx, decl->attributes, var_decl_attribute, &ac); } + if (ac.require_declaration) { + array_add(&ctx->info->required_global_variables, e); + } + + e->Variable.thread_local_model = ac.thread_local_model; e->Variable.is_export = ac.is_export; if (ac.is_static) { diff --git a/src/checker.cpp b/src/checker.cpp index 3f9d3ba71..c840faa45 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -805,6 +805,7 @@ void init_checker_info(CheckerInfo *i) { map_init(&i->packages, a); array_init(&i->variable_init_order, a); array_init(&i->required_foreign_imports_through_force, a); + array_init(&i->required_global_variables, a); i->allow_identifier_uses = build_context.query_data_set_settings.kind == QueryDataSet_GoToDefinitions; if (i->allow_identifier_uses) { @@ -826,6 +827,7 @@ void destroy_checker_info(CheckerInfo *i) { array_free(&i->variable_init_order); array_free(&i->identifier_uses); array_free(&i->required_foreign_imports_through_force); + array_free(&i->required_global_variables); } @@ -1744,6 +1746,12 @@ void generate_minimum_dependency_set(Checker *c, Entity *start) { add_dependency_to_set(c, e); } + for_array(i, c->info.required_global_variables) { + Entity *e = c->info.required_global_variables[i]; + e->flags |= EntityFlag_Used; + add_dependency_to_set(c, e); + } + add_dependency_to_set(c, start); } @@ -2330,7 +2338,13 @@ DECL_ATTRIBUTE_PROC(var_decl_attribute) { return true; } - if (name == "export") { + if (name == "require") { + if (value != nullptr) { + error(elem, "'static' does not have any parameters"); + } + ac->require_declaration = true; + return true; + } else if (name == "export") { ExactValue ev = check_decl_attribute_value(c, value); if (ev.kind == ExactValue_Invalid) { ac->is_export = true; @@ -3293,11 +3307,11 @@ void check_add_import_decl(CheckerContext *ctx, Ast *decl) { } DECL_ATTRIBUTE_PROC(foreign_import_decl_attribute) { - if (name == "force") { + if (name == "force" || name == "require") { if (value != nullptr) { error(elem, "Expected no parameter for '%.*s'", LIT(name)); } - ac->force_foreign_import = true; + ac->require_declaration = true; return true; } return false; @@ -3350,7 +3364,7 @@ void check_add_foreign_import_decl(CheckerContext *ctx, Ast *decl) { AttributeContext ac = {}; check_decl_attributes(ctx, fl->attributes, foreign_import_decl_attribute, &ac); - if (ac.force_foreign_import) { + if (ac.require_declaration) { array_add(&ctx->info->required_foreign_imports_through_force, e); add_entity_use(ctx, nullptr, e); } diff --git a/src/checker.hpp b/src/checker.hpp index 8ad0c0481..afa16e261 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -98,7 +98,7 @@ struct AttributeContext { bool is_export; bool is_static; bool require_results; - bool force_foreign_import; + bool require_declaration; bool has_disabled_proc; bool disabled_proc; String link_name; @@ -259,6 +259,7 @@ struct CheckerInfo { PtrSet minimum_dependency_type_info_set; Array required_foreign_imports_through_force; + Array required_global_variables; bool allow_identifier_uses; diff --git a/src/ir.cpp b/src/ir.cpp index da0075ec8..867a28259 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -11844,6 +11844,8 @@ void ir_gen_tree(irGen *s) { if (!ir_min_dep_entity(m, e)) { continue; } + + DeclInfo *decl = decl_info_of_entity(e); if (decl == nullptr) { continue; From 1181d7cf90a47fb1ca2353a76333e0b6307908d5 Mon Sep 17 00:00:00 2001 From: Tetralux Date: Thu, 12 Mar 2020 16:32:10 +0000 Subject: [PATCH 02/12] Fix os.read / os.read_entire_file - DWORDs are NOT i32 - os.read didn't correctly read as much as it could --- core/os/os.odin | 16 ++++++++-------- core/os/os_windows.odin | 30 ++++++++++++++---------------- core/sys/win32/kernel32.odin | 4 ++-- 3 files changed, 24 insertions(+), 26 deletions(-) diff --git a/core/os/os.odin b/core/os/os.odin index 2c7205a54..52efa7924 100644 --- a/core/os/os.odin +++ b/core/os/os.odin @@ -85,13 +85,13 @@ read_entire_file :: proc(name: string) -> (data: []byte, success: bool) { if data == nil { return nil, false; } + defer if !success do delete(data); bytes_read, read_err := read(fd, data); - if read_err != 0 { - delete(data); + if read_err != ERROR_NONE { return nil, false; } - return data[0:bytes_read], true; + return data[:bytes_read], true; } write_entire_file :: proc(name: string, data: []byte, truncate := true) -> (success: bool) { @@ -100,11 +100,11 @@ write_entire_file :: proc(name: string, data: []byte, truncate := true) -> (succ flags |= O_TRUNC; } - mode: int = 0; - when OS == "linux" { - // NOTE(justasd): 644 (owner read, write; group read; others read) - mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; - } + mode: int = 0; + when OS == "linux" { + // NOTE(justasd): 644 (owner read, write; group read; others read) + mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; + } fd, err := open(name, flags, mode); if err != 0 { diff --git a/core/os/os_windows.odin b/core/os/os_windows.odin index 0b1a53955..d445a2e0c 100644 --- a/core/os/os_windows.odin +++ b/core/os/os_windows.odin @@ -123,14 +123,14 @@ close :: proc(fd: Handle) -> Errno { write :: proc(fd: Handle, data: []byte) -> (int, Errno) { if len(data) == 0 do return 0, ERROR_NONE; - single_write_length: i32; + single_write_length: u32; total_write: i64; length := i64(len(data)); for total_write < length { remaining := length - total_write; MAX :: 1<<31-1; - to_write: i32 = min(i32(remaining), MAX); + to_write: u32 = min(u32(remaining), MAX); e := win32.write_file(win32.Handle(fd), &data[total_write], to_write, &single_write_length, nil); if single_write_length <= 0 || !e { @@ -145,23 +145,21 @@ write :: proc(fd: Handle, data: []byte) -> (int, Errno) { read :: proc(fd: Handle, data: []byte) -> (int, Errno) { if len(data) == 0 do return 0, ERROR_NONE; - single_read_length: i32; - total_read: i64; - length := i64(len(data)); + read := 0; + for { + to_read := u32(min(1<<29-1, len(data)-read)); + if to_read <= 0 do break; - for total_read < length { - remaining := length - total_read; - MAX :: 1<<32-1; - to_read: u32 = min(u32(remaining), MAX); - - e := win32.read_file(win32.Handle(fd), &data[total_read], to_read, &single_read_length, nil); - if single_read_length <= 0 || !e { - err := Errno(win32.get_last_error()); - return int(total_read), err; + n: u32; + ok := win32.read_file(win32.Handle(fd), &data[to_read], to_read, &n, nil); + if !ok { + return int(read), Errno(win32.get_last_error()); } - total_read += i64(single_read_length); + + read += int(n); } - return int(total_read), ERROR_NONE; + + return int(read), ERROR_NONE; } seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Errno) { diff --git a/core/sys/win32/kernel32.odin b/core/sys/win32/kernel32.odin index ff2400556..03d9ca40b 100644 --- a/core/sys/win32/kernel32.odin +++ b/core/sys/win32/kernel32.odin @@ -58,8 +58,8 @@ foreign kernel32 { creation, flags_and_attribs: u32, template_file: Handle) -> Handle ---; - @(link_name="ReadFile") read_file :: proc(h: Handle, buf: rawptr, to_read: u32, bytes_read: ^i32, overlapped: rawptr) -> Bool ---; - @(link_name="WriteFile") write_file :: proc(h: Handle, buf: rawptr, len: i32, written_result: ^i32, overlapped: rawptr) -> Bool ---; + @(link_name="ReadFile") read_file :: proc(h: Handle, buf: rawptr, to_read: u32, bytes_read: ^u32, overlapped: rawptr) -> Bool ---; + @(link_name="WriteFile") write_file :: proc(h: Handle, buf: rawptr, len: u32, written_result: ^u32, overlapped: rawptr) -> Bool ---; @(link_name="GetFileSizeEx") get_file_size_ex :: proc(file_handle: Handle, file_size: ^i64) -> Bool ---; @(link_name="GetFileInformationByHandle") get_file_information_by_handle :: proc(file_handle: Handle, file_info: ^By_Handle_File_Information) -> Bool ---; From da283d5a7fb531427e74cb6003f451cb9b15f0ca Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 12 Mar 2020 22:33:49 +0000 Subject: [PATCH 03/12] Add `byval` --- src/check_type.cpp | 7 +++++++ src/entity.cpp | 13 +++++++------ src/ir_print.cpp | 22 ++++++++++++++++++++++ 3 files changed, 36 insertions(+), 6 deletions(-) diff --git a/src/check_type.cpp b/src/check_type.cpp index 010b31f03..089e66c4d 100644 --- a/src/check_type.cpp +++ b/src/check_type.cpp @@ -2434,6 +2434,13 @@ void set_procedure_abi_types(gbAllocator allocator, Type *type) { } break; } + + if (build_context.ODIN_OS == "linux" || + build_context.ODIN_OS == "darwin") { + if (is_type_pointer(new_type) & !is_type_pointer(e->type)) { + e->flags |= EntityFlag_ByVal; + } + } } } diff --git a/src/entity.cpp b/src/entity.cpp index b89522b07..9cc77360e 100644 --- a/src/entity.cpp +++ b/src/entity.cpp @@ -43,14 +43,15 @@ enum EntityFlag { EntityFlag_TypeField = 1<<9, EntityFlag_Value = 1<<10, EntityFlag_Sret = 1<<11, - EntityFlag_BitFieldValue = 1<<12, - EntityFlag_PolyConst = 1<<13, - EntityFlag_NotExported = 1<<14, - EntityFlag_ConstInput = 1<<15, + EntityFlag_ByVal = 1<<12, + EntityFlag_BitFieldValue = 1<<13, + EntityFlag_PolyConst = 1<<14, + EntityFlag_NotExported = 1<<15, + EntityFlag_ConstInput = 1<<16, - EntityFlag_Static = 1<<16, + EntityFlag_Static = 1<<17, - EntityFlag_ImplicitReference = 1<<17, // NOTE(bill): equivalent to `const &` in C++ + EntityFlag_ImplicitReference = 1<<18, // NOTE(bill): equivalent to `const &` in C++ EntityFlag_SoaPtrField = 1<<19, // to allow s.x[0] where `s.x` is a pointer rather than a slice diff --git a/src/ir_print.cpp b/src/ir_print.cpp index bcbdca615..d5271444d 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -363,6 +363,9 @@ void ir_print_proc_type_without_pointer(irFileBuffer *f, irModule *m, Type *t) { if (e->flags&EntityFlag_NoAlias) { ir_write_str_lit(f, " noalias"); } + if (e->flags&EntityFlag_ByVal) { + ir_write_str_lit(f, " byval"); + } ir_write_byte(f, ' '); param_index++; } @@ -2184,6 +2187,9 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) { if (e->flags&EntityFlag_NoAlias) { ir_write_str_lit(f, " noalias"); } + if (e->flags&EntityFlag_ByVal) { + ir_write_str_lit(f, " byval"); + } ir_write_byte(f, ' '); ir_print_value(f, m, arg, t); param_index++; @@ -2196,6 +2202,9 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) { if (e->flags&EntityFlag_ImplicitReference) { ir_write_str_lit(f, " nonnull dereferenceable"); } + if (e->flags&EntityFlag_ByVal) { + ir_write_str_lit(f, " byval"); + } ir_write_byte(f, ' '); irValue *arg = call->args[arg_index++]; ir_print_value(f, m, arg, t); @@ -2236,6 +2245,9 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) { if (e->flags&EntityFlag_NoAlias) { ir_write_str_lit(f, " noalias"); } + if (e->flags&EntityFlag_ByVal) { + ir_write_str_lit(f, " byval"); + } ir_write_byte(f, ' '); ir_print_value(f, m, arg, t); param_index++; @@ -2246,6 +2258,9 @@ void ir_print_instr(irFileBuffer *f, irModule *m, irValue *value) { if (e->flags&EntityFlag_NoAlias) { ir_write_str_lit(f, " noalias"); } + if (e->flags&EntityFlag_ByVal) { + ir_write_str_lit(f, " byval"); + } ir_write_byte(f, ' '); ir_print_value(f, m, arg, t); param_index++; @@ -2390,6 +2405,10 @@ void ir_print_proc(irFileBuffer *f, irModule *m, irProcedure *proc) { if (e->flags&EntityFlag_NoAlias) { ir_write_str_lit(f, " noalias"); } + if (e->flags&EntityFlag_ByVal) { + ir_write_str_lit(f, " byval"); + } + if (proc->body != nullptr) { ir_fprintf(f, " %%_.%td", parameter_index+j); @@ -2402,6 +2421,9 @@ void ir_print_proc(irFileBuffer *f, irModule *m, irProcedure *proc) { if (e->flags&EntityFlag_NoAlias) { ir_write_str_lit(f, " noalias"); } + if (e->flags&EntityFlag_ByVal) { + ir_write_str_lit(f, " byval"); + } if (proc->body != nullptr) { ir_fprintf(f, " %%_.%td", parameter_index); } From 6abc93ad8488cd2b584667075798a1795151733f Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 12 Mar 2020 23:22:01 +0000 Subject: [PATCH 04/12] Fix os.read for windows --- core/os/os_windows.odin | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/core/os/os_windows.odin b/core/os/os_windows.odin index d445a2e0c..217de4561 100644 --- a/core/os/os_windows.odin +++ b/core/os/os_windows.odin @@ -145,21 +145,23 @@ write :: proc(fd: Handle, data: []byte) -> (int, Errno) { read :: proc(fd: Handle, data: []byte) -> (int, Errno) { if len(data) == 0 do return 0, ERROR_NONE; - read := 0; - for { - to_read := u32(min(1<<29-1, len(data)-read)); - if to_read <= 0 do break; + single_read_length: u32; + total_read: i64; + length := i64(len(data)); - n: u32; - ok := win32.read_file(win32.Handle(fd), &data[to_read], to_read, &n, nil); - if !ok { - return int(read), Errno(win32.get_last_error()); + for total_read < length { + remaining := length - total_read; + MAX :: 1<<31-1; + to_read: u32 = min(u32(remaining), MAX); + + e := win32.read_file(win32.Handle(fd), &data[total_read], to_read, &single_read_length, nil); + if !e { + err := Errno(win32.get_last_error()); + return int(total_read), err; } - - read += int(n); + total_read += i64(single_read_length); } - - return int(read), ERROR_NONE; + return int(total_read), ERROR_NONE; } seek :: proc(fd: Handle, offset: i64, whence: int) -> (i64, Errno) { From a985449c31aa88d5586723e517ac192c60fed469 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 12 Mar 2020 23:24:30 +0000 Subject: [PATCH 05/12] Fix os_windows.h --- core/os/os_windows.odin | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/os/os_windows.odin b/core/os/os_windows.odin index 217de4561..4c3c7e824 100644 --- a/core/os/os_windows.odin +++ b/core/os/os_windows.odin @@ -133,7 +133,7 @@ write :: proc(fd: Handle, data: []byte) -> (int, Errno) { to_write: u32 = min(u32(remaining), MAX); e := win32.write_file(win32.Handle(fd), &data[total_write], to_write, &single_write_length, nil); - if single_write_length <= 0 || !e { + if single_write_length == 0 || !e { err := Errno(win32.get_last_error()); return int(total_write), err; } @@ -151,11 +151,11 @@ read :: proc(fd: Handle, data: []byte) -> (int, Errno) { for total_read < length { remaining := length - total_read; - MAX :: 1<<31-1; + MAX :: 1<<32-1; to_read: u32 = min(u32(remaining), MAX); e := win32.read_file(win32.Handle(fd), &data[total_read], to_read, &single_read_length, nil); - if !e { + if single_read_length == 0 || !e { err := Errno(win32.get_last_error()); return int(total_read), err; } From 2ce1f4ba9f5680e12299cf51f31d37992e4eb11e Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 12 Mar 2020 23:37:24 +0000 Subject: [PATCH 06/12] Revert os_windows.odin behaviour --- core/os/os_windows.odin | 10 +++++----- core/sys/win32/kernel32.odin | 14 +++++++------- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/core/os/os_windows.odin b/core/os/os_windows.odin index 4c3c7e824..0b1a53955 100644 --- a/core/os/os_windows.odin +++ b/core/os/os_windows.odin @@ -123,17 +123,17 @@ close :: proc(fd: Handle) -> Errno { write :: proc(fd: Handle, data: []byte) -> (int, Errno) { if len(data) == 0 do return 0, ERROR_NONE; - single_write_length: u32; + single_write_length: i32; total_write: i64; length := i64(len(data)); for total_write < length { remaining := length - total_write; MAX :: 1<<31-1; - to_write: u32 = min(u32(remaining), MAX); + to_write: i32 = min(i32(remaining), MAX); e := win32.write_file(win32.Handle(fd), &data[total_write], to_write, &single_write_length, nil); - if single_write_length == 0 || !e { + if single_write_length <= 0 || !e { err := Errno(win32.get_last_error()); return int(total_write), err; } @@ -145,7 +145,7 @@ write :: proc(fd: Handle, data: []byte) -> (int, Errno) { read :: proc(fd: Handle, data: []byte) -> (int, Errno) { if len(data) == 0 do return 0, ERROR_NONE; - single_read_length: u32; + single_read_length: i32; total_read: i64; length := i64(len(data)); @@ -155,7 +155,7 @@ read :: proc(fd: Handle, data: []byte) -> (int, Errno) { to_read: u32 = min(u32(remaining), MAX); e := win32.read_file(win32.Handle(fd), &data[total_read], to_read, &single_read_length, nil); - if single_read_length == 0 || !e { + if single_read_length <= 0 || !e { err := Errno(win32.get_last_error()); return int(total_read), err; } diff --git a/core/sys/win32/kernel32.odin b/core/sys/win32/kernel32.odin index 03d9ca40b..fe3a906fe 100644 --- a/core/sys/win32/kernel32.odin +++ b/core/sys/win32/kernel32.odin @@ -10,11 +10,11 @@ foreign kernel32 { inherit_handle: Bool, creation_flags: u32, environment: rawptr, current_direcotry: cstring, startup_info: ^Startup_Info, process_information: ^Process_Information) -> Bool ---; - @(link_name="CreateProcessW") create_process_w :: proc(application_name, command_line: Wstring, - process_attributes, thread_attributes: ^Security_Attributes, - inherit_handle: Bool, creation_flags: u32, environment: rawptr, - current_direcotry: cstring, startup_info: ^Startup_Info, - process_information: ^Process_Information) -> Bool ---; + @(link_name="CreateProcessW") create_process_w :: proc(application_name, command_line: Wstring, + process_attributes, thread_attributes: ^Security_Attributes, + inherit_handle: Bool, creation_flags: u32, environment: rawptr, + current_direcotry: cstring, startup_info: ^Startup_Info, + process_information: ^Process_Information) -> Bool ---; @(link_name="GetExitCodeProcess") get_exit_code_process :: proc(process: Handle, exit: ^u32) -> Bool ---; @(link_name="ExitProcess") exit_process :: proc(exit_code: u32) ---; @(link_name="GetModuleHandleA") get_module_handle_a :: proc(module_name: cstring) -> Hmodule ---; @@ -58,8 +58,8 @@ foreign kernel32 { creation, flags_and_attribs: u32, template_file: Handle) -> Handle ---; - @(link_name="ReadFile") read_file :: proc(h: Handle, buf: rawptr, to_read: u32, bytes_read: ^u32, overlapped: rawptr) -> Bool ---; - @(link_name="WriteFile") write_file :: proc(h: Handle, buf: rawptr, len: u32, written_result: ^u32, overlapped: rawptr) -> Bool ---; + @(link_name="ReadFile") read_file :: proc(h: Handle, buf: rawptr, to_read: u32, bytes_read: ^i32, overlapped: rawptr) -> Bool ---; + @(link_name="WriteFile") write_file :: proc(h: Handle, buf: rawptr, len: i32, written_result: ^i32, overlapped: rawptr) -> Bool ---; @(link_name="GetFileSizeEx") get_file_size_ex :: proc(file_handle: Handle, file_size: ^i64) -> Bool ---; @(link_name="GetFileInformationByHandle") get_file_information_by_handle :: proc(file_handle: Handle, file_info: ^By_Handle_File_Information) -> Bool ---; From a0d0e93475458a5a9018ecd76e02fd6096d7f94e Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 12 Mar 2020 23:45:46 +0000 Subject: [PATCH 07/12] Fix os.read_entire_file --- core/os/os.odin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/os/os.odin b/core/os/os.odin index 52efa7924..a5926834f 100644 --- a/core/os/os.odin +++ b/core/os/os.odin @@ -85,10 +85,10 @@ read_entire_file :: proc(name: string) -> (data: []byte, success: bool) { if data == nil { return nil, false; } - defer if !success do delete(data); bytes_read, read_err := read(fd, data); if read_err != ERROR_NONE { + delete(data); return nil, false; } return data[:bytes_read], true; From ce90509a072939c7cebde40523d66f92e5354327 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 13 Mar 2020 00:04:03 +0000 Subject: [PATCH 08/12] Add initial `-mem2reg` pass to `opt` --- src/build_settings.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/build_settings.cpp b/src/build_settings.cpp index c264fbaaa..e5f3bf5a2 100644 --- a/src/build_settings.cpp +++ b/src/build_settings.cpp @@ -654,7 +654,6 @@ void init_build_context(TargetMetrics *cross_target) { gb_exit(1); } - bc->llc_flags = make_string_c(llc_flags); bc->optimization_level = gb_clamp(bc->optimization_level, 0, 3); @@ -667,9 +666,12 @@ void init_build_context(TargetMetrics *cross_target) { // -memcpyopt: MemCpy optimization } if (bc->ODIN_DEBUG == false) { - opt_flags = gb_string_appendc(opt_flags, "-memcpyopt -die "); + opt_flags = gb_string_appendc(opt_flags, "-mem2reg -memcpyopt -die "); } + bc->llc_flags = make_string_c(llc_flags); + + // NOTE(lachsinc): This optimization option was previously required to get // around an issue in fmt.odin. Thank bp for tracking it down! Leaving for now until the issue // is resolved and confirmed by Bill. Maybe it should be readded in non-debug builds. From 06e364b9bd0761aa6445d8c630ee283694925b05 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 13 Mar 2020 08:52:23 +0000 Subject: [PATCH 09/12] Apply byval to sret for System V ABI --- src/ir_print.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/ir_print.cpp b/src/ir_print.cpp index d5271444d..fb224648d 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -338,9 +338,13 @@ void ir_print_proc_type_without_pointer(irFileBuffer *f, irModule *m, Type *t) { ir_write_string(f, str_lit(" (")); if (t->Proc.return_by_pointer) { ir_print_type(f, m, reduce_tuple_to_single_type(t->Proc.results)); - // ir_fprintf(f, "* sret noalias "); + ir_fprintf(f, "* sret noalias "); + if (build_context.ODIN_OS == "darwin" || + build_context.ODIN_OS == "linux") { + ir_fprintf(f, "byval "); + } // ir_write_string(f, str_lit("* noalias ")); - ir_write_string(f, str_lit("*")); + // ir_write_string(f, str_lit("*")); if (param_count > 0 || t->Proc.calling_convention == ProcCC_Odin) { ir_write_string(f, str_lit(", ")); } @@ -2379,6 +2383,10 @@ void ir_print_proc(irFileBuffer *f, irModule *m, irProcedure *proc) { if (proc_type->return_by_pointer) { ir_print_type(f, m, reduce_tuple_to_single_type(proc_type->results)); ir_write_str_lit(f, "* sret noalias "); + if (build_context.ODIN_OS == "darwin" || + build_context.ODIN_OS == "linux") { + ir_fprintf(f, "byval "); + } ir_write_str_lit(f, "%agg.result"); param_index += 1; } From 10bac2445bb4e0e2b8e3b229f79a4bae9dedfdf7 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Fri, 13 Mar 2020 16:48:10 +0000 Subject: [PATCH 10/12] Fix ir_print for byval types --- src/ir_print.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ir_print.cpp b/src/ir_print.cpp index fb224648d..6c1b5a792 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -338,13 +338,13 @@ void ir_print_proc_type_without_pointer(irFileBuffer *f, irModule *m, Type *t) { ir_write_string(f, str_lit(" (")); if (t->Proc.return_by_pointer) { ir_print_type(f, m, reduce_tuple_to_single_type(t->Proc.results)); - ir_fprintf(f, "* sret noalias "); + // ir_fprintf(f, "* sret noalias "); + // ir_write_string(f, str_lit("* noalias ")); + ir_write_string(f, str_lit("*")); if (build_context.ODIN_OS == "darwin" || build_context.ODIN_OS == "linux") { - ir_fprintf(f, "byval "); + ir_fprintf(f, " byval"); } - // ir_write_string(f, str_lit("* noalias ")); - // ir_write_string(f, str_lit("*")); if (param_count > 0 || t->Proc.calling_convention == ProcCC_Odin) { ir_write_string(f, str_lit(", ")); } From 3951b93d0a1f68b0c7ed1a32324f72e5cdc253fb Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 15 Mar 2020 14:27:54 +0000 Subject: [PATCH 11/12] Fix branch statements within inline for blocks (partial hack) --- src/check_stmt.cpp | 4 ++-- src/ir.cpp | 33 +++++++++++++++++++++++++++++---- 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index 4b250c6a6..67172d951 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -1692,12 +1692,12 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) { switch (token.kind) { case Token_break: if ((flags & Stmt_BreakAllowed) == 0 && bs->label == nullptr) { - error(token, "'break' only allowed in loops or 'switch' statements"); + error(token, "'break' only allowed in non-inline loops or 'switch' statements"); } break; case Token_continue: if ((flags & Stmt_ContinueAllowed) == 0 && bs->label == nullptr) { - error(token, "'continue' only allowed in loops"); + error(token, "'continue' only allowed in non-inline loops"); } break; case Token_fallthrough: diff --git a/src/ir.cpp b/src/ir.cpp index 867a28259..7779b02b3 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -10125,6 +10125,8 @@ void ir_build_stmt_internal(irProcedure *proc, Ast *node) { ir_emit_comment(proc, str_lit("InlineRangeStmt")); ir_open_scope(proc); // Open scope here + irBlock *done = ir_new_block(proc, node, "inline.for.done"); + Type *val0_type = nullptr; Type *val1_type = nullptr; if (rs->val0 != nullptr && !is_blank_ident(rs->val0)) { @@ -10143,8 +10145,6 @@ void ir_build_stmt_internal(irProcedure *proc, Ast *node) { irValue *val = nullptr; irValue *key = nullptr; - irBlock *loop = nullptr; - irBlock *done = nullptr; Ast *expr = unparen_expr(rs->expr); TypeAndValue tav = type_and_value_of_expr(expr); @@ -10170,8 +10170,12 @@ void ir_build_stmt_internal(irProcedure *proc, Ast *node) { compare_exact_values(Token_LtEq, val, end); val = exact_value_increment_one(val), index = exact_value_increment_one(index)) { + irBlock *body = ir_new_block(proc, node, "inline.for.body"); + ir_emit_jump(proc, body); + if (val0_type) ir_addr_store(proc, val0_addr, ir_value_constant(val0_type, val)); if (val1_type) ir_addr_store(proc, val1_addr, ir_value_constant(val1_type, index)); + ir_start_block(proc, body); ir_build_stmt(proc, rs->body); } @@ -10181,14 +10185,17 @@ void ir_build_stmt_internal(irProcedure *proc, Ast *node) { compare_exact_values(Token_Lt, val, end); val = exact_value_increment_one(val), index = exact_value_increment_one(index)) { + irBlock *body = ir_new_block(proc, node, "inline.for.body"); + ir_emit_jump(proc, body); + ir_start_block(proc, body); + if (val0_type) ir_addr_store(proc, val0_addr, ir_value_constant(val0_type, val)); if (val1_type) ir_addr_store(proc, val1_addr, ir_value_constant(val1_type, index)); + ir_build_stmt(proc, rs->body); } } - - } else if (tav.mode == Addressing_Type) { GB_ASSERT(is_type_enum(type_deref(tav.type))); Type *et = type_deref(tav.type); @@ -10200,6 +10207,10 @@ void ir_build_stmt_internal(irProcedure *proc, Ast *node) { if (val1_type) val1_addr = ir_build_addr(proc, rs->val1); for_array(i, bet->Enum.fields) { + irBlock *body = ir_new_block(proc, node, "inline.for.body"); + ir_emit_jump(proc, body); + ir_start_block(proc, body); + Entity *field = bet->Enum.fields[i]; GB_ASSERT(field->kind == Entity_Constant); if (val0_type) ir_addr_store(proc, val0_addr, ir_value_constant(val0_type, field->Constant.value)); @@ -10228,6 +10239,10 @@ void ir_build_stmt_internal(irProcedure *proc, Ast *node) { Rune codepoint = 0; isize offset = 0; do { + irBlock *body = ir_new_block(proc, node, "inline.for.body"); + ir_emit_jump(proc, body); + ir_start_block(proc, body); + isize width = gb_utf8_decode(str.text+offset, str.len-offset, &codepoint); if (val0_type) ir_addr_store(proc, val0_addr, ir_value_constant(val0_type, exact_value_i64(codepoint))); if (val1_type) ir_addr_store(proc, val1_addr, ir_value_constant(val1_type, exact_value_i64(offset))); @@ -10243,6 +10258,10 @@ void ir_build_stmt_internal(irProcedure *proc, Ast *node) { irValue *val_addr = ir_address_from_load_or_generate_local(proc, val); for (i64 i = 0; i < t->Array.count; i++) { + irBlock *body = ir_new_block(proc, node, "inline.for.body"); + ir_emit_jump(proc, body); + ir_start_block(proc, body); + if (val0_type) { // NOTE(bill): Due to weird legacy issues in LLVM, this needs to be an i32 irValue *elem = ir_emit_array_epi(proc, val_addr, cast(i32)i); @@ -10261,6 +10280,10 @@ void ir_build_stmt_internal(irProcedure *proc, Ast *node) { irValue *val_addr = ir_address_from_load_or_generate_local(proc, val); for (i64 i = 0; i < t->EnumeratedArray.count; i++) { + irBlock *body = ir_new_block(proc, node, "inline.for.body"); + ir_emit_jump(proc, body); + ir_start_block(proc, body); + if (val0_type) { // NOTE(bill): Due to weird legacy issues in LLVM, this needs to be an i32 irValue *elem = ir_emit_array_epi(proc, val_addr, cast(i32)i); @@ -10282,6 +10305,8 @@ void ir_build_stmt_internal(irProcedure *proc, Ast *node) { } } + ir_emit_jump(proc, done); + ir_start_block(proc, done); ir_close_scope(proc, irDeferExit_Default, nullptr); case_end; From 8dba0e332c73a08301c5ac6c0d310c483c66cb11 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 15 Mar 2020 14:29:45 +0000 Subject: [PATCH 12/12] Fix #590 --- core/runtime/default_allocators.odin | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/runtime/default_allocators.odin b/core/runtime/default_allocators.odin index a4ba9f33b..a20283b5a 100644 --- a/core/runtime/default_allocators.odin +++ b/core/runtime/default_allocators.odin @@ -124,7 +124,7 @@ default_temp_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode clear(&allocator.leaked_allocations); case .Resize: - last_ptr := rawptr(&allocator.data[allocator.prev_offset]); + last_ptr := #no_bounds_check rawptr(&allocator.data[allocator.prev_offset]); if old_memory == last_ptr && len(allocator.data)-allocator.prev_offset >= size { allocator.curr_offset = allocator.prev_offset+size; return old_memory;