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 {...@@ -3289,6 +3289,7 @@ enum FnWalkId {
3289 FnWalkIdCall,3289 FnWalkIdCall,
3290 FnWalkIdTypes,3290 FnWalkIdTypes,
3291 FnWalkIdVars,3291 FnWalkIdVars,
3292 FnWalkIdInits,
3292};3293};
32933294
3294struct FnWalkAttrs {3295struct FnWalkAttrs {
...@@ -3315,6 +3316,12 @@ struct FnWalkVars {...@@ -3315,6 +3316,12 @@ struct FnWalkVars {
3315 unsigned gen_i;3316 unsigned gen_i;
3316};3317};
33173318
3319struct FnWalkInits {
3320 LLVMValueRef llvm_fn;
3321 ZigFn *fn;
3322 unsigned gen_i;
3323};
3324
3318struct FnWalk {3325struct FnWalk {
3319 FnWalkId id;3326 FnWalkId id;
3320 union {3327 union {
...@@ -3322,6 +3329,7 @@ struct FnWalk {...@@ -3322,6 +3329,7 @@ struct FnWalk {
3322 FnWalkCall call;3329 FnWalkCall call;
3323 FnWalkTypes types;3330 FnWalkTypes types;
3324 FnWalkVars vars;3331 FnWalkVars vars;
3332 FnWalkInits inits;
3325 } data;3333 } data;
3326};3334};
33273335
src/codegen.cpp+76-114
...@@ -1954,6 +1954,15 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_...@@ -1954,6 +1954,15 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
1954 source_node = var->decl_node;1954 source_node = var->decl_node;
1955 llvm_fn = fn_walk->data.vars.llvm_fn;1955 llvm_fn = fn_walk->data.vars.llvm_fn;
1956 break;1956 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;
1957 }1966 }
19581967
1959 if (type_is_c_abi_int(g, ty) || ty->id == ZigTypeIdFloat ||1968 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_...@@ -1990,6 +1999,14 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
1990 dest_ty = ty;1999 dest_ty = ty;
1991 goto var_ok;2000 goto var_ok;
1992 }2001 }
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;
1993 }2010 }
1994 return true;2011 return true;
1995 }2012 }
...@@ -2018,6 +2035,12 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_...@@ -2018,6 +2035,12 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
2018 fn_walk->data.vars.gen_i += 1;2035 fn_walk->data.vars.gen_i += 1;
2019 goto var_ok;2036 goto var_ok;
2020 }2037 }
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;
2021 }2044 }
2022 return true;2045 return true;
2023 }2046 }
...@@ -2052,6 +2075,12 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_...@@ -2052,6 +2075,12 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
2052 fn_walk->data.vars.gen_i += 1;2075 fn_walk->data.vars.gen_i += 1;
2053 goto var_ok;2076 goto var_ok;
2054 }2077 }
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;
2055 }2084 }
2056 return true;2085 return true;
2057 }2086 }
...@@ -2092,6 +2121,18 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_...@@ -2092,6 +2121,18 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
2092 fn_walk->data.vars.gen_i += 1;2121 fn_walk->data.vars.gen_i += 1;
2093 goto var_ok;2122 goto var_ok;
2094 }2123 }
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 }
2095 }2136 }
2096 return true;2137 return true;
2097 }2138 }
...@@ -2140,6 +2181,7 @@ void walk_function_params(CodeGen *g, ZigType *fn_type, FnWalk *fn_walk) {...@@ -2140,6 +2181,7 @@ void walk_function_params(CodeGen *g, ZigType *fn_type, FnWalk *fn_walk) {
2140 }2181 }
2141 return;2182 return;
2142 }2183 }
2184 size_t next_var_i = 0;
2143 for (size_t param_i = 0; param_i < fn_type->data.fn.fn_type_id.param_count; param_i += 1) {2185 for (size_t param_i = 0; param_i < fn_type->data.fn.fn_type_id.param_count; param_i += 1) {
2144 FnGenParamInfo *gen_info = &fn_type->data.fn.gen_param_info[param_i];2186 FnGenParamInfo *gen_info = &fn_type->data.fn.gen_param_info[param_i];
2145 size_t gen_index = gen_info->gen_index;2187 size_t gen_index = gen_info->gen_index;
...@@ -2166,6 +2208,27 @@ void walk_function_params(CodeGen *g, ZigType *fn_type, FnWalk *fn_walk) {...@@ -2166,6 +2208,27 @@ void walk_function_params(CodeGen *g, ZigType *fn_type, FnWalk *fn_walk) {
2166 }2208 }
2167 break;2209 break;
2168 }2210 }
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 }
2169 case FnWalkIdCall:2232 case FnWalkIdCall:
2170 // handled before for loop2233 // handled before for loop
2171 zig_unreachable();2234 zig_unreachable();
...@@ -3402,80 +3465,6 @@ static void set_call_instr_sret(CodeGen *g, LLVMValueRef call_instr) {...@@ -3402,80 +3465,6 @@ static void set_call_instr_sret(CodeGen *g, LLVMValueRef call_instr) {
3402 LLVMAddCallSiteAttribute(call_instr, 1, sret_attr);3465 LLVMAddCallSiteAttribute(call_instr, 1, sret_attr);
3403}3466}
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
3479static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstructionCall *instruction) {3468static LLVMValueRef ir_render_call(CodeGen *g, IrExecutable *executable, IrInstructionCall *instruction) {
3480 LLVMValueRef fn_val;3469 LLVMValueRef fn_val;
3481 ZigType *fn_type;3470 ZigType *fn_type;
...@@ -6289,12 +6278,12 @@ static void do_code_gen(CodeGen *g) {...@@ -6289,12 +6278,12 @@ static void do_code_gen(CodeGen *g) {
6289 ImportTableEntry *import = get_scope_import(&fn_table_entry->fndef_scope->base);6278 ImportTableEntry *import = get_scope_import(&fn_table_entry->fndef_scope->base);
62906279
6291 // create debug variable declarations for variables and allocate all local variables6280 // create debug variable declarations for variables and allocate all local variables
6292 FnWalk fn_walk = {};6281 FnWalk fn_walk_var = {};
6293 fn_walk.id = FnWalkIdVars;6282 fn_walk_var.id = FnWalkIdVars;
6294 fn_walk.data.vars.import = import;6283 fn_walk_var.data.vars.import = import;
6295 fn_walk.data.vars.fn = fn_table_entry;6284 fn_walk_var.data.vars.fn = fn_table_entry;
6296 fn_walk.data.vars.llvm_fn = fn;6285 fn_walk_var.data.vars.llvm_fn = fn;
6297 fn_walk.data.vars.gen_i = 0;6286 fn_walk_var.data.vars.gen_i = 0;
6298 for (size_t var_i = 0; var_i < fn_table_entry->variable_list.length; var_i += 1) {6287 for (size_t var_i = 0; var_i < fn_table_entry->variable_list.length; var_i += 1) {
6299 ZigVar *var = fn_table_entry->variable_list.at(var_i);6288 ZigVar *var = fn_table_entry->variable_list.at(var_i);
63006289
...@@ -6314,8 +6303,8 @@ static void do_code_gen(CodeGen *g) {...@@ -6314,8 +6303,8 @@ static void do_code_gen(CodeGen *g) {
6314 var->value->type->di_type, !g->strip_debug_symbols, 0);6303 var->value->type->di_type, !g->strip_debug_symbols, 0);
63156304
6316 } else if (is_c_abi) {6305 } else if (is_c_abi) {
6317 fn_walk.data.vars.var = var;6306 fn_walk_var.data.vars.var = var;
6318 iter_function_params_c_abi(g, fn_table_entry->type_entry, &fn_walk, var->src_arg_index);6307 iter_function_params_c_abi(g, fn_table_entry->type_entry, &fn_walk_var, var->src_arg_index);
6319 } else {6308 } else {
6320 assert(var->gen_arg_index != SIZE_MAX);6309 assert(var->gen_arg_index != SIZE_MAX);
6321 ZigType *gen_type;6310 ZigType *gen_type;
...@@ -6367,40 +6356,13 @@ static void do_code_gen(CodeGen *g) {...@@ -6367,40 +6356,13 @@ static void do_code_gen(CodeGen *g) {
6367 gen_store(g, LLVMConstInt(usize->type_ref, stack_trace_ptr_count, false), len_field_ptr, get_pointer_to_type(g, usize, false));6356 gen_store(g, LLVMConstInt(usize->type_ref, stack_trace_ptr_count, false), len_field_ptr, get_pointer_to_type(g, usize, false));
6368 }6357 }
63696358
6370 FnTypeId *fn_type_id = &fn_table_entry->type_entry->data.fn.fn_type_id;
6371
6372 // create debug variable declarations for parameters6359 // create debug variable declarations for parameters
6373 // rely on the first variables in the variable_list being parameters.6360 // rely on the first variables in the variable_list being parameters.
6374 size_t next_var_i = 0;6361 FnWalk fn_walk_init = {};
6375 unsigned c_abi_arg_init_index = 0;6362 fn_walk_init.id = FnWalkIdInits;
6376 for (size_t param_i = 0; param_i < fn_type_id->param_count; param_i += 1) {6363 fn_walk_init.data.inits.fn = fn_table_entry;
6377 if (is_c_abi) {6364 fn_walk_init.data.inits.llvm_fn = fn;
6378 ZigVar *var = fn_table_entry->variable_list.at(param_i);6365 walk_function_params(g, fn_table_entry->type_entry, &fn_walk_init);
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 }
64046366
6405 ir_render(g, fn_table_entry);6367 ir_render(g, fn_table_entry);
64066368