瀏覽代碼

Merge branch 'master' into llvm-integration

gingerBill 5 年之前
父節點
當前提交
18fb6a4be4
共有 12 個文件被更改,包括 119 次插入32 次删除
  1. 7 7
      core/os/os.odin
  2. 1 1
      core/runtime/default_allocators.odin
  3. 5 5
      core/sys/win32/kernel32.odin
  4. 4 2
      src/build_settings.cpp
  5. 5 0
      src/check_decl.cpp
  6. 2 2
      src/check_stmt.cpp
  7. 7 0
      src/check_type.cpp
  8. 18 4
      src/checker.cpp
  9. 2 1
      src/checker.hpp
  10. 7 6
      src/entity.cpp
  11. 31 4
      src/ir.cpp
  12. 30 0
      src/ir_print.cpp

+ 7 - 7
core/os/os.odin

@@ -87,11 +87,11 @@ read_entire_file :: proc(name: string) -> (data: []byte, success: bool) {
 	}
 
 	bytes_read, read_err := read(fd, data);
-	if read_err != 0 {
+	if read_err != ERROR_NONE {
 		delete(data);
 		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 {

+ 1 - 1
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;

+ 5 - 5
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 ---;

+ 4 - 2
src/build_settings.cpp

@@ -656,7 +656,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);
 
@@ -669,9 +668,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.

+ 5 - 0
src/check_decl.cpp

@@ -844,6 +844,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) {

+ 2 - 2
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:

+ 7 - 0
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;
+				}
+			}
 		}
 	}
 

+ 18 - 4
src/checker.cpp

@@ -806,6 +806,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) {
@@ -827,6 +828,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);
 
 }
 
@@ -1748,6 +1750,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);
 }
 
@@ -2334,7 +2342,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;
@@ -3297,11 +3311,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;
@@ -3354,7 +3368,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);
 	}

+ 2 - 1
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;
@@ -260,6 +260,7 @@ struct CheckerInfo {
 	PtrSet<isize>         minimum_dependency_type_info_set;
 
 	Array<Entity *>       required_foreign_imports_through_force;
+	Array<Entity *>       required_global_variables;
 
 
 	bool allow_identifier_uses;

+ 7 - 6
src/entity.cpp

@@ -45,14 +45,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
 

+ 31 - 4
src/ir.cpp

@@ -10096,6 +10096,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)) {
@@ -10114,8 +10116,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);
@@ -10141,8 +10141,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);
 				}
@@ -10152,14 +10156,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);
@@ -10171,6 +10178,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));
@@ -10199,6 +10210,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)));
@@ -10214,6 +10229,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);
@@ -10232,6 +10251,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);
@@ -10253,6 +10276,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;
@@ -11815,6 +11840,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;

+ 30 - 0
src/ir_print.cpp

@@ -341,6 +341,10 @@ void ir_print_proc_type_without_pointer(irFileBuffer *f, irModule *m, Type *t) {
 		// 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");
+		}
 		if (param_count > 0 || t->Proc.calling_convention == ProcCC_Odin)  {
 			ir_write_string(f, str_lit(", "));
 		}
@@ -363,6 +367,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++;
 				}
@@ -2183,6 +2190,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++;
@@ -2195,6 +2205,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);
@@ -2235,6 +2248,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++;
@@ -2245,6 +2261,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++;
@@ -2363,6 +2382,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;
 	}
@@ -2389,6 +2412,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);
@@ -2401,6 +2428,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);
 					}