aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2020-03-15 14:31:26 +0000
committergingerBill <bill@gingerbill.org>2020-03-15 14:31:26 +0000
commit18fb6a4be41f30de75b445266b958e153ecc16d9 (patch)
tree6770795d754effc1751d8c7beb13652db39f3770 /src
parentbf0c6f5a30e406a0e0f73014c024ba63dcb47b43 (diff)
parent8dba0e332c73a08301c5ac6c0d310c483c66cb11 (diff)
Merge branch 'master' into llvm-integration
Diffstat (limited to 'src')
-rw-r--r--src/build_settings.cpp6
-rw-r--r--src/check_decl.cpp5
-rw-r--r--src/check_stmt.cpp4
-rw-r--r--src/check_type.cpp7
-rw-r--r--src/checker.cpp22
-rw-r--r--src/checker.hpp3
-rw-r--r--src/entity.cpp13
-rw-r--r--src/ir.cpp35
-rw-r--r--src/ir_print.cpp30
9 files changed, 106 insertions, 19 deletions
diff --git a/src/build_settings.cpp b/src/build_settings.cpp
index 9d2453929..8cb40cadc 100644
--- a/src/build_settings.cpp
+++ b/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.
diff --git a/src/check_decl.cpp b/src/check_decl.cpp
index 8a231fe36..13f05c5b5 100644
--- a/src/check_decl.cpp
+++ b/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) {
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/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/checker.cpp b/src/checker.cpp
index 0494bde4b..c8b737df8 100644
--- a/src/checker.cpp
+++ b/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);
}
diff --git a/src/checker.hpp b/src/checker.hpp
index e1330478e..39ab94c70 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;
@@ -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;
diff --git a/src/entity.cpp b/src/entity.cpp
index 49bce00df..dbe4f926c 100644
--- a/src/entity.cpp
+++ b/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
diff --git a/src/ir.cpp b/src/ir.cpp
index 16999a209..ab6cbb151 100644
--- a/src/ir.cpp
+++ b/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;
diff --git a/src/ir_print.cpp b/src/ir_print.cpp
index 4e5838785..32cc3809d 100644
--- a/src/ir_print.cpp
+++ b/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);
}