From 93955a0fd8b8387b08a314649b8b705bdfc8c9d2 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 19 Mar 2020 15:03:02 +0000 Subject: [PATCH] Remove `context.std*` parameters; Fix unary boolean not --- core/fmt/fmt.odin | 12 +-- core/os/os_windows.odin | 2 +- core/runtime/core.odin | 14 +-- examples/demo/demo.odin | 97 ++++++++++++++------- src/llvm_backend.cpp | 188 +++++++++++++++------------------------- 5 files changed, 153 insertions(+), 160 deletions(-) diff --git a/core/fmt/fmt.odin b/core/fmt/fmt.odin index b9bb1ee2c..372002e8f 100644 --- a/core/fmt/fmt.odin +++ b/core/fmt/fmt.odin @@ -59,13 +59,13 @@ fprintf :: proc(fd: os.Handle, fmt: string, args: ..any) -> int { // print* procedures return the number of bytes written -print :: proc(args: ..any) -> int { return fprint(context.stdout, ..args); } -println :: proc(args: ..any) -> int { return fprintln(context.stdout, ..args); } -printf :: proc(fmt: string, args: ..any) -> int { return fprintf(context.stdout, fmt, ..args); } +print :: proc(args: ..any) -> int { return fprint(os.stdout, ..args); } +println :: proc(args: ..any) -> int { return fprintln(os.stdout, ..args); } +printf :: proc(fmt: string, args: ..any) -> int { return fprintf(os.stdout, fmt, ..args); } -eprint :: proc(args: ..any) -> int { return fprint(context.stderr, ..args); } -eprintln :: proc(args: ..any) -> int { return fprintln(context.stderr, ..args); } -eprintf :: proc(fmt: string, args: ..any) -> int { return fprintf(context.stderr, fmt, ..args); } +eprint :: proc(args: ..any) -> int { return fprint(os.stderr, ..args); } +eprintln :: proc(args: ..any) -> int { return fprintln(os.stderr, ..args); } +eprintf :: proc(fmt: string, args: ..any) -> int { return fprintf(os.stderr, fmt, ..args); } @(deprecated="prefer eprint") print_err :: proc(args: ..any) -> int { return eprint(..args); } diff --git a/core/os/os_windows.odin b/core/os/os_windows.odin index 0b1a53955..4eb9a3ec8 100644 --- a/core/os/os_windows.odin +++ b/core/os/os_windows.odin @@ -201,7 +201,7 @@ stdout := get_std_handle(win32.STD_OUTPUT_HANDLE); stderr := get_std_handle(win32.STD_ERROR_HANDLE); -get_std_handle :: proc(h: int) -> Handle { +get_std_handle :: proc "contextless" (h: int) -> Handle { fd := win32.get_std_handle(i32(h)); win32.set_handle_information(fd, win32.HANDLE_FLAG_INHERIT, 0); return Handle(fd); diff --git a/core/runtime/core.odin b/core/runtime/core.odin index 87af6b7bb..13b3ef008 100644 --- a/core/runtime/core.odin +++ b/core/runtime/core.odin @@ -288,9 +288,9 @@ Context :: struct { assertion_failure_proc: Assertion_Failure_Proc, logger: Logger, - stdin: os.Handle, - stdout: os.Handle, - stderr: os.Handle, + // stdin: os.Handle, + // stdout: os.Handle, + // stderr: os.Handle, thread_id: int, @@ -463,9 +463,9 @@ __init_context :: proc "contextless" (c: ^Context) { c.logger.procedure = default_logger_proc; c.logger.data = nil; - c.stdin = os.stdin; - c.stdout = os.stdout; - c.stderr = os.stderr; + // c.stdin = os.stdin; + // c.stdout = os.stdout; + // c.stderr = os.stderr; } @builtin @@ -474,7 +474,7 @@ init_global_temporary_allocator :: proc(data: []byte, backup_allocator := contex } default_assertion_failure_proc :: proc(prefix, message: string, loc: Source_Code_Location) { - fd := context.stderr; + fd := os.stderr; print_caller_location(fd, loc); os.write_string(fd, " "); os.write_string(fd, prefix); diff --git a/examples/demo/demo.odin b/examples/demo/demo.odin index 4ef9b2a8c..4438229bf 100644 --- a/examples/demo/demo.odin +++ b/examples/demo/demo.odin @@ -1931,35 +1931,74 @@ union_maybe :: proc() { fmt.println(z, z_ok); } +icons_texture_data_size := [2]int{0 = 512, 1 = 256}; + + main :: proc() { - when true { - the_basics(); - control_flow(); - named_proc_return_parameters(); - explicit_procedure_overloading(); - struct_type(); - union_type(); - using_statement(); - implicit_context_system(); - parametric_polymorphism(); - array_programming(); - map_type(); - implicit_selector_expression(); - partial_switch(); - cstring_example(); - bit_set_type(); - deferred_procedure_associations(); - reflection(); - quaternions(); - inline_for_statement(); - where_clauses(); - foreign_system(); - ranged_fields_for_array_compound_literals(); - deprecated_attribute(); - range_statements_with_multiple_return_values(); - threading_example(); - soa_struct_layout(); - constant_literal_expressions(); - union_maybe(); + // cache size + Nx := 512; + Ny := 128; + Nz := 0; + is_array := false; + + // detect target based on input size + switch { + case Nz > 0 && !is_array: fmt.println("1"); + case Nz > 0 && is_array: fmt.println("2"); + case Ny > 0 && !is_array: fmt.println("3"); + case Ny > 0 && is_array: fmt.println("4"); + case: fmt.println("5"); + } + + // fmt.println("(Nz > 0 && !is_array) ==", Nz > 0 && !is_array); + // fmt.println("(Nz > 0 && is_array) ==", Nz > 0 && is_array); + // fmt.println("(Ny > 0 && !is_array) ==", Ny > 0 && !is_array); + // fmt.println("(Ny > 0 && is_array) ==", Ny > 0 && is_array); + + c0 := (Nz > 0) && !is_array; + c1 := (Nz > 0) && is_array; + c2 := (Ny > 0) && !is_array; + c3 := (Ny > 0) && is_array; + assert(c0 == false); + assert(c1 == false); + assert(c2 == true); + assert(c3 == false); + // switch { + // case c0: fmt.println("1"); + // case c1: fmt.println("2"); + // case c2: fmt.println("3"); + // case c3: fmt.println("4"); + // case: fmt.println("5"); + // } + + when false { + // the_basics(); + // control_flow(); + // named_proc_return_parameters(); + // explicit_procedure_overloading(); + // struct_type(); + // union_type(); + // using_statement(); + // implicit_context_system(); + // parametric_polymorphism(); + // array_programming(); + // map_type(); + // implicit_selector_expression(); + // partial_switch(); + // cstring_example(); + // bit_set_type(); + // deferred_procedure_associations(); + // reflection(); + // quaternions(); + // inline_for_statement(); + // where_clauses(); + // foreign_system(); + // ranged_fields_for_array_compound_literals(); + // deprecated_attribute(); + // range_statements_with_multiple_return_values(); + // threading_example(); + // soa_struct_layout(); + // constant_literal_expressions(); + // union_maybe(); } } diff --git a/src/llvm_backend.cpp b/src/llvm_backend.cpp index 1720b97bb..a5c148bfd 100644 --- a/src/llvm_backend.cpp +++ b/src/llvm_backend.cpp @@ -2735,29 +2735,20 @@ void lb_build_switch_stmt(lbProcedure *p, AstSwitchStmt *ss) { lbBlock *default_block = nullptr; lbBlock *fall = nullptr; - bool append_fall = false; isize case_count = body->stmts.count; for_array(i, body->stmts) { Ast *clause = body->stmts[i]; - lbBlock *body = fall; - ast_node(cc, CaseClause, clause); + lbBlock *body = fall; + if (body == nullptr) { - if (cc->list.count == 0) { - body = lb_create_block(p, "switch.dflt.body"); - } else { - body = lb_create_block(p, "switch.case.body"); - } - } - if (append_fall && body == fall) { - append_fall = false; + body = lb_create_block(p, "switch.case.body"); } fall = done; if (i+1 < case_count) { - append_fall = true; fall = lb_create_block(p, "switch.fall.body"); } @@ -2773,6 +2764,7 @@ void lb_build_switch_stmt(lbProcedure *p, AstSwitchStmt *ss) { for_array(j, cc->list) { Ast *expr = unparen_expr(cc->list[j]); next_cond = lb_create_block(p, "switch.case.next"); + lbValue cond = lb_const_bool(p->module, t_llvm_bool, false); if (is_ast_range(expr)) { ast_node(ie, BinaryExpr, expr); @@ -3583,19 +3575,11 @@ lbValue lb_emit_clamp(lbProcedure *p, Type *t, lbValue x, lbValue min, lbValue m - -lbValue lb_find_or_add_entity_string(lbModule *m, String const &str) { +LLVMValueRef lb_find_or_add_entity_string_ptr(lbModule *m, String const &str) { HashKey key = hash_string(str); LLVMValueRef *found = map_get(&m->const_strings, key); if (found != nullptr) { - LLVMValueRef ptr = *found; - LLVMValueRef str_len = LLVMConstInt(lb_type(m, t_int), str.len, true); - LLVMValueRef values[2] = {ptr, str_len}; - - lbValue res = {}; - res.value = LLVMConstNamedStruct(lb_type(m, t_string), values, 2); - res.type = t_string; - return res; + return *found; } else { LLVMValueRef indices[2] = {llvm_zero32(m), llvm_zero32(m)}; LLVMValueRef data = LLVMConstStringInContext(m->ctx, @@ -3614,62 +3598,49 @@ lbValue lb_find_or_add_entity_string(lbModule *m, String const &str) { LLVMSetInitializer(global_data, data); LLVMValueRef ptr = LLVMConstInBoundsGEP(global_data, indices, 2); - - LLVMValueRef str_len = LLVMConstInt(lb_type(m, t_int), str.len, true); - LLVMValueRef values[2] = {ptr, str_len}; - - lbValue res = {}; - res.value = LLVMConstNamedStruct(lb_type(m, t_string), values, 2); - res.type = t_string; - map_set(&m->const_strings, key, ptr); - - return res; + return ptr; } } +lbValue lb_find_or_add_entity_string(lbModule *m, String const &str) { + LLVMValueRef ptr = lb_find_or_add_entity_string_ptr(m, str); + LLVMValueRef str_len = LLVMConstInt(lb_type(m, t_int), str.len, true); + LLVMValueRef values[2] = {ptr, str_len}; + + lbValue res = {}; + res.value = LLVMConstNamedStruct(lb_type(m, t_string), values, 2); + res.type = t_string; + return res; +} + lbValue lb_find_or_add_entity_string_byte_slice(lbModule *m, String const &str) { - HashKey key = hash_string(str); - LLVMValueRef *found = map_get(&m->const_strings, key); - if (found != nullptr) { - LLVMValueRef ptr = *found; - LLVMValueRef len = LLVMConstInt(lb_type(m, t_int), str.len, true); - LLVMValueRef values[2] = {ptr, len}; - - lbValue res = {}; - res.value = LLVMConstNamedStruct(lb_type(m, t_u8_slice), values, 2); - res.type = t_u8_slice; - return res; - } else { - LLVMValueRef indices[2] = {llvm_zero32(m), llvm_zero32(m)}; - LLVMValueRef data = LLVMConstStringInContext(m->ctx, - cast(char const *)str.text, - cast(unsigned)str.len, - false); + LLVMValueRef indices[2] = {llvm_zero32(m), llvm_zero32(m)}; + LLVMValueRef data = LLVMConstStringInContext(m->ctx, + cast(char const *)str.text, + cast(unsigned)str.len, + false); + char *name = nullptr; + { isize max_len = 7+8+1; - char *name = gb_alloc_array(heap_allocator(), char, max_len); + name = gb_alloc_array(heap_allocator(), char, max_len); isize len = gb_snprintf(name, max_len, "csbs$%x", m->global_array_index); len -= 1; m->global_array_index++; - - LLVMValueRef global_data = LLVMAddGlobal(m->mod, LLVMTypeOf(data), name); - LLVMSetInitializer(global_data, data); - - LLVMValueRef ptr = LLVMConstInBoundsGEP(global_data, indices, 2); - - LLVMValueRef str_len = LLVMConstInt(lb_type(m, t_int), str.len, true); - LLVMValueRef values[2] = {ptr, str_len}; - - lbValue res = {}; - res.value = LLVMConstNamedStruct(lb_type(m, t_u8_slice), values, 2); - res.type = t_u8_slice; - - map_set(&m->const_strings, key, ptr); - - return res; } + LLVMValueRef global_data = LLVMAddGlobal(m->mod, LLVMTypeOf(data), name); + LLVMSetInitializer(global_data, data); + + LLVMValueRef ptr = LLVMConstInBoundsGEP(global_data, indices, 2); + LLVMValueRef len = LLVMConstInt(lb_type(m, t_int), str.len, true); + LLVMValueRef values[2] = {ptr, len}; + + lbValue res = {}; + res.value = LLVMConstNamedStruct(lb_type(m, t_u8_slice), values, 2); + res.type = t_u8_slice; + return res; } isize lb_type_info_index(CheckerInfo *info, Type *type, bool err_on_not_found=true) { @@ -3880,54 +3851,17 @@ lbValue lb_const_value(lbModule *m, Type *type, ExactValue value) { return res; case ExactValue_String: { - HashKey key = hash_string(value.value_string); - LLVMValueRef *found = map_get(&m->const_strings, key); - if (found != nullptr && false) { - LLVMValueRef ptr = *found; - lbValue res = {}; - res.type = default_type(original_type); - if (is_type_cstring(res.type)) { - res.value = ptr; - } else { - LLVMValueRef str_len = LLVMConstInt(lb_type(m, t_int), value.value_string.len, true); - LLVMValueRef values[2] = {ptr, str_len}; - - res.value = LLVMConstNamedStruct(lb_type(m, original_type), values, 2); - } - - return res; - } - - LLVMValueRef indices[2] = {llvm_zero32(m), llvm_zero32(m)}; - LLVMValueRef data = LLVMConstStringInContext(ctx, - cast(char const *)value.value_string.text, - cast(unsigned)value.value_string.len, - false); - - - isize max_len = 7+8+1; - char *str = gb_alloc_array(heap_allocator(), char, max_len); - isize len = gb_snprintf(str, max_len, "csbs$%x", m->global_array_index); - len -= 1; - m->global_array_index++; - - LLVMValueRef global_data = LLVMAddGlobal(m->mod, LLVMTypeOf(data), str); - LLVMSetInitializer(global_data, data); - - LLVMValueRef ptr = LLVMConstInBoundsGEP(global_data, indices, 2); - - if (is_type_cstring(type)) { - res.value = ptr; - return res; - } - - LLVMValueRef str_len = LLVMConstInt(lb_type(m, t_int), value.value_string.len, true); - LLVMValueRef values[2] = {ptr, str_len}; - - res.value = LLVMConstNamedStruct(lb_type(m, original_type), values, 2); + LLVMValueRef ptr = lb_find_or_add_entity_string_ptr(m, value.value_string); + lbValue res = {}; res.type = default_type(original_type); + if (is_type_cstring(res.type)) { + res.value = ptr; + } else { + LLVMValueRef str_len = LLVMConstInt(lb_type(m, t_int), value.value_string.len, true); + LLVMValueRef values[2] = {ptr, str_len}; - map_set(&m->const_strings, key, ptr); + res.value = LLVMConstNamedStruct(lb_type(m, original_type), values, 2); + } return res; } @@ -4413,13 +4347,21 @@ lbValue lb_emit_unary_arith(lbProcedure *p, TokenKind op, lbValue x, Type *type) } - if (op == Token_Not) { + if (op == Token_Xor) { lbValue cmp = {}; cmp.value = LLVMBuildNot(p->builder, x.value, ""); cmp.type = x.type; return lb_emit_conv(p, cmp, type); } + if (op == Token_Not) { + lbValue cmp = {}; + LLVMValueRef zero = LLVMConstInt(lb_type(p->module, x.type), 0, false); + cmp.value = LLVMBuildICmp(p->builder, LLVMIntEQ, x.value, zero, ""); + cmp.type = t_llvm_bool; + return lb_emit_conv(p, cmp, type); + } + if (op == Token_Sub && is_type_integer(type) && is_type_different_to_arch_endianness(type)) { Type *platform_type = integer_endian_type_to_platform_type(type); lbValue v = lb_emit_byte_swap(p, x, platform_type); @@ -5433,7 +5375,9 @@ lbAddr lb_find_or_generate_context_ptr(lbProcedure *p) { return p->context_stack[p->context_stack.count-1].ctx; } - if (p->name == LB_STARTUP_RUNTIME_PROC_NAME) { + Type *pt = base_type(p->type); + GB_ASSERT(pt->kind == Type_Proc); + if (pt->Proc.calling_convention != ProcCC_Odin) { return p->module->global_default_context; } else { lbAddr c = lb_add_local_generated(p, t_context, false); @@ -6041,10 +5985,11 @@ lbValue lb_emit_array_ep(lbProcedure *p, lbValue s, lbValue index) { GB_ASSERT(is_type_pointer(t)); Type *st = base_type(type_deref(t)); GB_ASSERT_MSG(is_type_array(st) || is_type_enumerated_array(st), "%s", type_to_string(st)); + GB_ASSERT_MSG(is_type_integer(index.type), "%s", type_to_string(index.type)); LLVMValueRef indices[2] = {}; indices[0] = llvm_zero32(p->module); - indices[1] = lb_emit_conv(p, index, t_i32).value; + indices[1] = lb_emit_conv(p, index, t_int).value; Type *ptr = base_array_type(st); lbValue res = {}; @@ -7218,13 +7163,21 @@ String lb_get_const_string(lbModule *m, lbValue value) { Type *t = base_type(value.type); GB_ASSERT(are_types_identical(t, t_string)); + + unsigned ptr_indices[1] = {0}; unsigned len_indices[1] = {1}; LLVMValueRef underlying_ptr = LLVMConstExtractValue(value.value, ptr_indices, gb_count_of(ptr_indices)); LLVMValueRef underlying_len = LLVMConstExtractValue(value.value, len_indices, gb_count_of(len_indices)); + GB_ASSERT(LLVMGetConstOpcode(underlying_ptr) == LLVMGetElementPtr); + underlying_ptr = LLVMGetOperand(underlying_ptr, 0); + GB_ASSERT(LLVMIsAGlobalVariable(underlying_ptr)); + underlying_ptr = LLVMGetInitializer(underlying_ptr); + size_t length = 0; char const *text = LLVMGetAsString(underlying_ptr, &length); + isize real_length = cast(isize)LLVMConstIntGetSExtValue(underlying_len); return make_string(cast(u8 const *)text, real_length); @@ -11000,6 +10953,7 @@ void lb_generate_code(lbGenerator *gen) { if (build_context.keep_temp_files) { TIME_SECTION("LLVM Print Module to File"); LLVMPrintModuleToFile(mod, cast(char const *)filepath_ll.text, &llvm_error); + // exit(1); } LLVMDIBuilderFinalize(m->debug_builder); LLVMVerifyModule(mod, LLVMAbortProcessAction, &llvm_error); @@ -11007,8 +10961,8 @@ void lb_generate_code(lbGenerator *gen) { TIME_SECTION("LLVM Object Generation"); - LLVMBool ok = LLVMTargetMachineEmitToFile(target_machine, mod, cast(char *)filepath_obj.text, LLVMObjectFile, &llvm_error); - if (ok) { + LLVMBool was_an_error = LLVMTargetMachineEmitToFile(target_machine, mod, cast(char *)filepath_obj.text, LLVMObjectFile, &llvm_error); + if (was_an_error) { gb_printf_err("LLVM Error: %s\n", llvm_error); gb_exit(1); return;