authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-09-07 12:23:50-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-09-07 12:23:50-04:00
log04d7b565f78895d96e5a43e8b1f4873ea5f529cf
tree95ae4c50915c84dfb059784f27d84658def0c1db
parentbe6cccb3a51512dea011326d9ad30ad495e7c716
signaturelock-open Commit is signed but in an unrecognized format.

stage1: refactor fn type analysis to use C ABI walk fn


5 files changed, 64 insertions(+), 76 deletions(-)

src/all_types.hpp+7
......@@ -3287,6 +3287,7 @@ enum FloatMode {
32873287enum FnWalkId {
32883288 FnWalkIdAttrs,
32893289 FnWalkIdCall,
3290 FnWalkIdTypes,
32903291};
32913292
32923293struct FnWalkAttrs {
......@@ -3300,11 +3301,17 @@ struct FnWalkCall {
33003301 bool is_var_args;
33013302};
33023303
3304struct FnWalkTypes {
3305 ZigList<ZigLLVMDIType *> *param_di_types;
3306 ZigList<LLVMTypeRef> *gen_param_types;
3307};
3308
33033309struct FnWalk {
33043310 FnWalkId id;
33053311 union {
33063312 FnWalkAttrs attrs;
33073313 FnWalkCall call;
3314 FnWalkTypes types;
33083315 } data;
33093316};
33103317
src/analyze.cpp+12-73
......@@ -1061,76 +1061,6 @@ ZigType *get_ptr_to_stack_trace_type(CodeGen *g) {
10611061 return g->ptr_to_stack_trace_type;
10621062}
10631063
1064bool type_is_c_abi_int(CodeGen *g, ZigType *ty) {
1065 size_t ty_size = type_size(g, ty);
1066 if (ty_size > g->pointer_size_bytes)
1067 return false;
1068 return (ty->id == ZigTypeIdInt ||
1069 ty->id == ZigTypeIdFloat ||
1070 ty->id == ZigTypeIdBool ||
1071 ty->id == ZigTypeIdEnum ||
1072 get_codegen_ptr_type(ty) != nullptr);
1073}
1074
1075// If you edit this function you have to edit the corresponding code:
1076// analyze.cpp:gen_c_abi_param_type
1077// codegen.cpp:gen_c_abi_param_var
1078// codegen.cpp:gen_c_abi_param_var_init
1079static void gen_c_abi_param_type(CodeGen *g, ZigList<LLVMTypeRef> *gen_param_types,
1080 ZigList<ZigLLVMDIType *> *param_di_types, ZigType *ty)
1081{
1082 if (type_is_c_abi_int(g, ty) || ty->id == ZigTypeIdFloat ||
1083 ty->id == ZigTypeIdInt // TODO investigate if we need to change this
1084 ) {
1085 gen_param_types->append(ty->type_ref);
1086 param_di_types->append(ty->di_type);
1087 return;
1088 }
1089
1090 // Arrays are just pointers
1091 if (ty->id == ZigTypeIdArray) {
1092 ZigType *gen_type = get_pointer_to_type(g, ty, true);
1093 gen_param_types->append(gen_type->type_ref);
1094 param_di_types->append(gen_type->di_type);
1095 return;
1096 }
1097
1098 if (g->zig_target.arch.arch == ZigLLVM_x86_64) {
1099 size_t ty_size = type_size(g, ty);
1100 if (ty->id == ZigTypeIdStruct || ty->id == ZigTypeIdUnion) {
1101 // "If the size of an object is larger than four eightbytes, or it contains unaligned
1102 // fields, it has class MEMORY"
1103 if (ty_size > 32) {
1104 ZigType *gen_type = get_pointer_to_type(g, ty, true);
1105 gen_param_types->append(gen_type->type_ref);
1106 param_di_types->append(gen_type->di_type);
1107 return;
1108 }
1109 }
1110 if (ty->id == ZigTypeIdStruct) {
1111 // "If the size of the aggregate exceeds a single eightbyte, each is classified
1112 // separately. Each eightbyte gets initialized to class NO_CLASS."
1113 if (ty_size <= 8) {
1114 bool contains_int = false;
1115 for (size_t i = 0; i < ty->data.structure.src_field_count; i += 1) {
1116 if (type_is_c_abi_int(g, ty->data.structure.fields[i].type_entry)) {
1117 contains_int = true;
1118 break;
1119 }
1120 }
1121 if (contains_int) {
1122 ZigType *gen_type = get_int_type(g, false, ty_size * 8);
1123 gen_param_types->append(gen_type->type_ref);
1124 param_di_types->append(gen_type->di_type);
1125 return;
1126 }
1127 }
1128 }
1129 }
1130
1131 // allow codegen code to report a compile error
1132}
1133
11341064ZigType *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
11351065 Error err;
11361066 auto table_entry = g->fn_type_table.maybe_get(fn_type_id);
......@@ -1249,9 +1179,10 @@ ZigType *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
12491179 if ((err = ensure_complete_type(g, type_entry)))
12501180 return g->builtin_types.entry_invalid;
12511181
1252 if (is_c_abi) {
1253 gen_c_abi_param_type(g, &gen_param_types, &param_di_types, type_entry);
1254 } else if (type_has_bits(type_entry)) {
1182 if (is_c_abi)
1183 continue;
1184
1185 if (type_has_bits(type_entry)) {
12551186 ZigType *gen_type;
12561187 if (handle_is_ptr(type_entry)) {
12571188 gen_type = get_pointer_to_type(g, type_entry, true);
......@@ -1267,6 +1198,14 @@ ZigType *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
12671198 }
12681199 }
12691200
1201 if (is_c_abi) {
1202 FnWalk fn_walk = {};
1203 fn_walk.id = FnWalkIdTypes;
1204 fn_walk.data.types.param_di_types = &param_di_types;
1205 fn_walk.data.types.gen_param_types = &gen_param_types;
1206 walk_function_params(g, fn_type, &fn_walk);
1207 }
1208
12701209 fn_type->data.fn.gen_param_count = gen_param_types.length;
12711210
12721211 fn_type->data.fn.raw_type_ref = LLVMFunctionType(gen_return_type->type_ref,
src/analyze.hpp+2-1
......@@ -210,6 +210,7 @@ ZigType *get_primitive_type(CodeGen *g, Buf *name);
210210bool calling_convention_allows_zig_types(CallingConvention cc);
211211const char *calling_convention_name(CallingConvention cc);
212212
213bool type_is_c_abi_int(CodeGen *g, ZigType *ty);
213void walk_function_params(CodeGen *g, ZigType *fn_type, FnWalk *fn_walk);
214
214215
215216#endif
src/codegen.cpp+43
......@@ -1893,6 +1893,17 @@ static void give_up_with_c_abi_error(CodeGen *g, AstNode *source_node) {
18931893 report_errors_and_exit(g);
18941894}
18951895
1896static bool type_is_c_abi_int(CodeGen *g, ZigType *ty) {
1897 size_t ty_size = type_size(g, ty);
1898 if (ty_size > g->pointer_size_bytes)
1899 return false;
1900 return (ty->id == ZigTypeIdInt ||
1901 ty->id == ZigTypeIdFloat ||
1902 ty->id == ZigTypeIdBool ||
1903 ty->id == ZigTypeIdEnum ||
1904 get_codegen_ptr_type(ty) != nullptr);
1905}
1906
18961907static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_walk, size_t src_i) {
18971908 // Initialized from the type for some walks, but because of C var args,
18981909 // initialized based on callsite instructions for that one.
......@@ -1919,7 +1930,14 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
19191930 val = ir_llvm_value(g, arg);
19201931 break;
19211932 }
1933 case FnWalkIdTypes:
1934 if (src_i >= fn_type->data.fn.fn_type_id.param_count)
1935 return false;
1936 param_info = &fn_type->data.fn.fn_type_id.param_info[src_i];
1937 ty = param_info->type;
1938 break;
19221939 }
1940
19231941 if (type_is_c_abi_int(g, ty) || ty->id == ZigTypeIdFloat ||
19241942 ty->id == ZigTypeIdInt // TODO investigate if we need to change this
19251943 ) {
......@@ -1943,6 +1961,10 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
19431961 case FnWalkIdCall:
19441962 fn_walk->data.call.gen_param_values->append(val);
19451963 break;
1964 case FnWalkIdTypes:
1965 fn_walk->data.types.gen_param_types->append(ty->type_ref);
1966 fn_walk->data.types.param_di_types->append(ty->di_type);
1967 break;
19461968 }
19471969 return true;
19481970 }
......@@ -1958,6 +1980,12 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
19581980 case FnWalkIdCall:
19591981 fn_walk->data.call.gen_param_values->append(val);
19601982 break;
1983 case FnWalkIdTypes: {
1984 ZigType *gen_type = get_pointer_to_type(g, ty, true);
1985 fn_walk->data.types.gen_param_types->append(gen_type->type_ref);
1986 fn_walk->data.types.param_di_types->append(gen_type->di_type);
1987 break;
1988 }
19611989 }
19621990 return true;
19631991 }
......@@ -1979,6 +2007,12 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
19792007 case FnWalkIdCall:
19802008 fn_walk->data.call.gen_param_values->append(val);
19812009 break;
2010 case FnWalkIdTypes: {
2011 ZigType *gen_type = get_pointer_to_type(g, ty, true);
2012 fn_walk->data.types.gen_param_types->append(gen_type->type_ref);
2013 fn_walk->data.types.param_di_types->append(gen_type->di_type);
2014 break;
2015 }
19822016 }
19832017 return true;
19842018 }
......@@ -2007,6 +2041,12 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
20072041 fn_walk->data.call.gen_param_values->append(loaded);
20082042 break;
20092043 }
2044 case FnWalkIdTypes: {
2045 ZigType *gen_type = get_int_type(g, false, ty_size * 8);
2046 fn_walk->data.types.gen_param_types->append(gen_type->type_ref);
2047 fn_walk->data.types.param_di_types->append(gen_type->di_type);
2048 break;
2049 }
20102050 }
20112051 return true;
20122052 }
......@@ -2074,6 +2114,9 @@ void walk_function_params(CodeGen *g, ZigType *fn_type, FnWalk *fn_walk) {
20742114 case FnWalkIdCall:
20752115 // handled before for loop
20762116 zig_unreachable();
2117 case FnWalkIdTypes:
2118 // Not called for non-c-abi
2119 zig_unreachable();
20772120 }
20782121 }
20792122}
src/codegen.hpp-2
......@@ -61,6 +61,4 @@ void codegen_translate_c(CodeGen *g, Buf *path);
6161
6262Buf *codegen_generate_builtin_source(CodeGen *g);
6363
64void walk_function_params(CodeGen *g, ZigType *fn_type, FnWalk *fn_walk);
65
6664#endif