authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-09-07 13:24:41-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-09-07 13:24:41-04:00
log421ca1523feec17db75e7c53b05e5abe4c88d58f
tree4204e2eaa8243f05a5d3ab2cc67e8e7c1df3a6ab
parentc528c0090089041e63f9bdbb52f951e53ce94631
signaturelock-open Commit is signed but in an unrecognized format.

stage1: refactor variable inits to use c abi fn walk


2 files changed, 84 insertions(+), 114 deletions(-)

src/all_types.hpp+8
......@@ -3289,6 +3289,7 @@ enum FnWalkId {
32893289 FnWalkIdCall,
32903290 FnWalkIdTypes,
32913291 FnWalkIdVars,
3292 FnWalkIdInits,
32923293};
32933294
32943295struct FnWalkAttrs {
......@@ -3315,6 +3316,12 @@ struct FnWalkVars {
33153316 unsigned gen_i;
33163317};
33173318
3319struct FnWalkInits {
3320 LLVMValueRef llvm_fn;
3321 ZigFn *fn;
3322 unsigned gen_i;
3323};
3324
33183325struct FnWalk {
33193326 FnWalkId id;
33203327 union {
......@@ -3322,6 +3329,7 @@ struct FnWalk {
33223329 FnWalkCall call;
33233330 FnWalkTypes types;
33243331 FnWalkVars vars;
3332 FnWalkInits inits;
33253333 } data;
33263334};
33273335
src/codegen.cpp+76-114
......@@ -1954,6 +1954,15 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
19541954 source_node = var->decl_node;
19551955 llvm_fn = fn_walk->data.vars.llvm_fn;
19561956 break;
1957 case FnWalkIdInits:
1958 if (src_i >= fn_type->data.fn.fn_type_id.param_count)
1959 return false;
1960 param_info = &fn_type->data.fn.fn_type_id.param_info[src_i];
1961 ty = param_info->type;
1962 var = fn_walk->data.inits.fn->variable_list.at(src_i);
1963 source_node = fn_walk->data.inits.fn->proto_node;
1964 llvm_fn = fn_walk->data.inits.llvm_fn;
1965 break;
19571966 }
19581967
19591968 if (type_is_c_abi_int(g, ty) || ty->id == ZigTypeIdFloat ||
......@@ -1990,6 +1999,14 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
19901999 dest_ty = ty;
19912000 goto var_ok;
19922001 }
2002 case FnWalkIdInits:
2003 clear_debug_source_node(g);
2004 gen_store_untyped(g, LLVMGetParam(llvm_fn, fn_walk->data.inits.gen_i), var->value_ref, var->align_bytes, false);
2005 if (var->decl_node) {
2006 gen_var_debug_decl(g, var);
2007 }
2008 fn_walk->data.inits.gen_i += 1;
2009 break;
19932010 }
19942011 return true;
19952012 }
......@@ -2018,6 +2035,12 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
20182035 fn_walk->data.vars.gen_i += 1;
20192036 goto var_ok;
20202037 }
2038 case FnWalkIdInits:
2039 if (var->decl_node) {
2040 gen_var_debug_decl(g, var);
2041 }
2042 fn_walk->data.inits.gen_i += 1;
2043 break;
20212044 }
20222045 return true;
20232046 }
......@@ -2052,6 +2075,12 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
20522075 fn_walk->data.vars.gen_i += 1;
20532076 goto var_ok;
20542077 }
2078 case FnWalkIdInits:
2079 if (var->decl_node) {
2080 gen_var_debug_decl(g, var);
2081 }
2082 fn_walk->data.inits.gen_i += 1;
2083 break;
20552084 }
20562085 return true;
20572086 }
......@@ -2092,6 +2121,18 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
20922121 fn_walk->data.vars.gen_i += 1;
20932122 goto var_ok;
20942123 }
2124 case FnWalkIdInits: {
2125 clear_debug_source_node(g);
2126 LLVMValueRef arg = LLVMGetParam(llvm_fn, fn_walk->data.inits.gen_i += 1);
2127 LLVMTypeRef ptr_to_int_type_ref = LLVMPointerType(LLVMIntType((unsigned)ty_size * 8), 0);
2128 LLVMValueRef bitcasted = LLVMBuildBitCast(g->builder, var->value_ref, ptr_to_int_type_ref, "");
2129 gen_store_untyped(g, arg, bitcasted, var->align_bytes, false);
2130 if (var->decl_node) {
2131 gen_var_debug_decl(g, var);
2132 }
2133 fn_walk->data.inits.gen_i += 1;
2134 break;
2135 }
20952136 }
20962137 return true;
20972138 }
......@@ -2140,6 +2181,7 @@ void walk_function_params(CodeGen *g, ZigType *fn_type, FnWalk *fn_walk) {
21402181 }
21412182 return;
21422183 }
2184 size_t next_var_i = 0;
21432185 for (size_t param_i = 0; param_i < fn_type->data.fn.fn_type_id.param_count; param_i += 1) {
21442186 FnGenParamInfo *gen_info = &fn_type->data.fn.gen_param_info[param_i];
21452187 size_t gen_index = gen_info->gen_index;
......@@ -2166,6 +2208,27 @@ void walk_function_params(CodeGen *g, ZigType *fn_type, FnWalk *fn_walk) {
21662208 }
21672209 break;
21682210 }
2211 case FnWalkIdInits: {
2212 ZigFn *fn_table_entry = fn_walk->data.inits.fn;
2213 LLVMValueRef llvm_fn = fn_table_entry->llvm_value;
2214 ZigVar *variable = fn_table_entry->variable_list.at(next_var_i);
2215 assert(variable->src_arg_index != SIZE_MAX);
2216 next_var_i += 1;
2217
2218 assert(variable);
2219 assert(variable->value_ref);
2220
2221 if (!handle_is_ptr(variable->value->type)) {
2222 clear_debug_source_node(g);
2223 gen_store_untyped(g, LLVMGetParam(llvm_fn, (unsigned)variable->gen_arg_index), variable->value_ref,
2224 variable->align_bytes, false);
2225 }
2226
2227 if (variable->decl_node) {
2228 gen_var_debug_decl(g, variable);
2229 }
2230 break;
2231 }
21692232 case FnWalkIdCall:
21702233 // handled before for loop
21712234 zig_unreachable();
......@@ -3402,80 +3465,6 @@ static void set_call_instr_sret(CodeGen *g, LLVMValueRef call_instr) {
34023465 LLVMAddCallSiteAttribute(call_instr, 1, sret_attr);
34033466}
34043467
3405// If you edit this function you have to edit the corresponding code:
3406// codegen.cpp:gen_c_abi_param_var
3407// codegen.cpp:gen_c_abi_param_var_init
3408static void gen_c_abi_param_var_init(CodeGen *g, ImportTableEntry *import, LLVMValueRef llvm_fn, ZigFn *fn,
3409 ZigVar *var, unsigned *arg_index)
3410{
3411 ZigType *ty = var->value->type;
3412
3413 if (type_is_c_abi_int(g, ty) || ty->id == ZigTypeIdFloat ||
3414 ty->id == ZigTypeIdInt // TODO investigate if we need to change this
3415 ) {
3416 clear_debug_source_node(g);
3417 gen_store_untyped(g, LLVMGetParam(llvm_fn, *arg_index), var->value_ref, var->align_bytes, false);
3418 if (var->decl_node) {
3419 gen_var_debug_decl(g, var);
3420 }
3421 *arg_index += 1;
3422 return;
3423 }
3424
3425 // Arrays are just pointers
3426 if (ty->id == ZigTypeIdArray) {
3427 if (var->decl_node) {
3428 gen_var_debug_decl(g, var);
3429 }
3430 *arg_index += 1;
3431 return;
3432 }
3433
3434 if (g->zig_target.arch.arch == ZigLLVM_x86_64) {
3435 assert(handle_is_ptr(ty));
3436 size_t ty_size = type_size(g, ty);
3437
3438 if (ty->id == ZigTypeIdStruct || ty->id == ZigTypeIdUnion) {
3439 // "If the size of an object is larger than four eightbytes, or it contains unaligned
3440 // fields, it has class MEMORY"
3441 if (ty_size > 32) {
3442 if (var->decl_node) {
3443 gen_var_debug_decl(g, var);
3444 }
3445 *arg_index += 1;
3446 return;
3447 }
3448 }
3449 if (ty->id == ZigTypeIdStruct) {
3450 // "If the size of the aggregate exceeds a single eightbyte, each is classified
3451 // separately. Each eightbyte gets initialized to class NO_CLASS."
3452 if (ty_size <= 8) {
3453 bool contains_int = false;
3454 for (size_t i = 0; i < ty->data.structure.src_field_count; i += 1) {
3455 if (type_is_c_abi_int(g, ty->data.structure.fields[i].type_entry)) {
3456 contains_int = true;
3457 break;
3458 }
3459 }
3460 if (contains_int) {
3461 clear_debug_source_node(g);
3462 LLVMValueRef arg = LLVMGetParam(llvm_fn, *arg_index);
3463 LLVMTypeRef ptr_to_int_type_ref = LLVMPointerType(LLVMIntType((unsigned)ty_size * 8), 0);
3464 LLVMValueRef bitcasted = LLVMBuildBitCast(g->builder, var->value_ref, ptr_to_int_type_ref, "");
3465 gen_store_untyped(g, arg, bitcasted, var->align_bytes, false);
3466 if (var->decl_node) {
3467 gen_var_debug_decl(g, var);
3468 }
3469 *arg_index += 1;
3470 return;
3471 }
3472 }
3473 }
3474 }
3475
3476 give_up_with_c_abi_error(g, fn->proto_node);
3477}
3478
34793468static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstructionCall *instruction) {
34803469 LLVMValueRef fn_val;
34813470 ZigType *fn_type;
......@@ -6289,12 +6278,12 @@ static void do_code_gen(CodeGen *g) {
62896278 ImportTableEntry *import = get_scope_import(&fn_table_entry->fndef_scope->base);
62906279
62916280 // create debug variable declarations for variables and allocate all local variables
6292 FnWalk fn_walk = {};
6293 fn_walk.id = FnWalkIdVars;
6294 fn_walk.data.vars.import = import;
6295 fn_walk.data.vars.fn = fn_table_entry;
6296 fn_walk.data.vars.llvm_fn = fn;
6297 fn_walk.data.vars.gen_i = 0;
6281 FnWalk fn_walk_var = {};
6282 fn_walk_var.id = FnWalkIdVars;
6283 fn_walk_var.data.vars.import = import;
6284 fn_walk_var.data.vars.fn = fn_table_entry;
6285 fn_walk_var.data.vars.llvm_fn = fn;
6286 fn_walk_var.data.vars.gen_i = 0;
62986287 for (size_t var_i = 0; var_i < fn_table_entry->variable_list.length; var_i += 1) {
62996288 ZigVar *var = fn_table_entry->variable_list.at(var_i);
63006289
......@@ -6314,8 +6303,8 @@ static void do_code_gen(CodeGen *g) {
63146303 var->value->type->di_type, !g->strip_debug_symbols, 0);
63156304
63166305 } else if (is_c_abi) {
6317 fn_walk.data.vars.var = var;
6318 iter_function_params_c_abi(g, fn_table_entry->type_entry, &fn_walk, var->src_arg_index);
6306 fn_walk_var.data.vars.var = var;
6307 iter_function_params_c_abi(g, fn_table_entry->type_entry, &fn_walk_var, var->src_arg_index);
63196308 } else {
63206309 assert(var->gen_arg_index != SIZE_MAX);
63216310 ZigType *gen_type;
......@@ -6367,40 +6356,13 @@ static void do_code_gen(CodeGen *g) {
63676356 gen_store(g, LLVMConstInt(usize->type_ref, stack_trace_ptr_count, false), len_field_ptr, get_pointer_to_type(g, usize, false));
63686357 }
63696358
6370 FnTypeId *fn_type_id = &fn_table_entry->type_entry->data.fn.fn_type_id;
6371
63726359 // create debug variable declarations for parameters
63736360 // rely on the first variables in the variable_list being parameters.
6374 size_t next_var_i = 0;
6375 unsigned c_abi_arg_init_index = 0;
6376 for (size_t param_i = 0; param_i < fn_type_id->param_count; param_i += 1) {
6377 if (is_c_abi) {
6378 ZigVar *var = fn_table_entry->variable_list.at(param_i);
6379 gen_c_abi_param_var_init(g, import, fn, fn_table_entry, var, &c_abi_arg_init_index);
6380 continue;
6381 }
6382
6383 FnGenParamInfo *info = &fn_table_entry->type_entry->data.fn.gen_param_info[param_i];
6384 if (info->gen_index == SIZE_MAX)
6385 continue;
6386
6387 ZigVar *variable = fn_table_entry->variable_list.at(next_var_i);
6388 assert(variable->src_arg_index != SIZE_MAX);
6389 next_var_i += 1;
6390
6391 assert(variable);
6392 assert(variable->value_ref);
6393
6394 if (!handle_is_ptr(variable->value->type)) {
6395 clear_debug_source_node(g);
6396 gen_store_untyped(g, LLVMGetParam(fn, (unsigned)variable->gen_arg_index), variable->value_ref,
6397 variable->align_bytes, false);
6398 }
6399
6400 if (variable->decl_node) {
6401 gen_var_debug_decl(g, variable);
6402 }
6403 }
6361 FnWalk fn_walk_init = {};
6362 fn_walk_init.id = FnWalkIdInits;
6363 fn_walk_init.data.inits.fn = fn_table_entry;
6364 fn_walk_init.data.inits.llvm_fn = fn;
6365 walk_function_params(g, fn_table_entry->type_entry, &fn_walk_init);
64046366
64056367 ir_render(g, fn_table_entry);
64066368