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 {...@@ -3287,6 +3287,7 @@ enum FloatMode {
3287enum FnWalkId {3287enum FnWalkId {
3288 FnWalkIdAttrs,3288 FnWalkIdAttrs,
3289 FnWalkIdCall,3289 FnWalkIdCall,
3290 FnWalkIdTypes,
3290};3291};
32913292
3292struct FnWalkAttrs {3293struct FnWalkAttrs {
...@@ -3300,11 +3301,17 @@ struct FnWalkCall {...@@ -3300,11 +3301,17 @@ struct FnWalkCall {
3300 bool is_var_args;3301 bool is_var_args;
3301};3302};
33023303
3304struct FnWalkTypes {
3305 ZigList<ZigLLVMDIType *> *param_di_types;
3306 ZigList<LLVMTypeRef> *gen_param_types;
3307};
3308
3303struct FnWalk {3309struct FnWalk {
3304 FnWalkId id;3310 FnWalkId id;
3305 union {3311 union {
3306 FnWalkAttrs attrs;3312 FnWalkAttrs attrs;
3307 FnWalkCall call;3313 FnWalkCall call;
3314 FnWalkTypes types;
3308 } data;3315 } data;
3309};3316};
33103317
src/analyze.cpp+12-73
...@@ -1061,76 +1061,6 @@ ZigType *get_ptr_to_stack_trace_type(CodeGen *g) {...@@ -1061,76 +1061,6 @@ ZigType *get_ptr_to_stack_trace_type(CodeGen *g) {
1061 return g->ptr_to_stack_trace_type;1061 return g->ptr_to_stack_trace_type;
1062}1062}
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
1134ZigType *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {1064ZigType *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
1135 Error err;1065 Error err;
1136 auto table_entry = g->fn_type_table.maybe_get(fn_type_id);1066 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) {...@@ -1249,9 +1179,10 @@ ZigType *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
1249 if ((err = ensure_complete_type(g, type_entry)))1179 if ((err = ensure_complete_type(g, type_entry)))
1250 return g->builtin_types.entry_invalid;1180 return g->builtin_types.entry_invalid;
12511181
1252 if (is_c_abi) {1182 if (is_c_abi)
1253 gen_c_abi_param_type(g, &gen_param_types, &param_di_types, type_entry);1183 continue;
1254 } else if (type_has_bits(type_entry)) {1184
1185 if (type_has_bits(type_entry)) {
1255 ZigType *gen_type;1186 ZigType *gen_type;
1256 if (handle_is_ptr(type_entry)) {1187 if (handle_is_ptr(type_entry)) {
1257 gen_type = get_pointer_to_type(g, type_entry, true);1188 gen_type = get_pointer_to_type(g, type_entry, true);
...@@ -1267,6 +1198,14 @@ ZigType *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {...@@ -1267,6 +1198,14 @@ ZigType *get_fn_type(CodeGen *g, FnTypeId *fn_type_id) {
1267 }1198 }
1268 }1199 }
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
1270 fn_type->data.fn.gen_param_count = gen_param_types.length;1209 fn_type->data.fn.gen_param_count = gen_param_types.length;
12711210
1272 fn_type->data.fn.raw_type_ref = LLVMFunctionType(gen_return_type->type_ref,1211 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);...@@ -210,6 +210,7 @@ ZigType *get_primitive_type(CodeGen *g, Buf *name);
210bool calling_convention_allows_zig_types(CallingConvention cc);210bool calling_convention_allows_zig_types(CallingConvention cc);
211const char *calling_convention_name(CallingConvention cc);211const 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
215#endif216#endif
src/codegen.cpp+43
...@@ -1893,6 +1893,17 @@ static void give_up_with_c_abi_error(CodeGen *g, AstNode *source_node) {...@@ -1893,6 +1893,17 @@ static void give_up_with_c_abi_error(CodeGen *g, AstNode *source_node) {
1893 report_errors_and_exit(g);1893 report_errors_and_exit(g);
1894}1894}
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
1896static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_walk, size_t src_i) {1907static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_walk, size_t src_i) {
1897 // Initialized from the type for some walks, but because of C var args,1908 // Initialized from the type for some walks, but because of C var args,
1898 // initialized based on callsite instructions for that one.1909 // 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_...@@ -1919,7 +1930,14 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
1919 val = ir_llvm_value(g, arg);1930 val = ir_llvm_value(g, arg);
1920 break;1931 break;
1921 }1932 }
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;
1922 }1939 }
1940
1923 if (type_is_c_abi_int(g, ty) || ty->id == ZigTypeIdFloat ||1941 if (type_is_c_abi_int(g, ty) || ty->id == ZigTypeIdFloat ||
1924 ty->id == ZigTypeIdInt // TODO investigate if we need to change this1942 ty->id == ZigTypeIdInt // TODO investigate if we need to change this
1925 ) {1943 ) {
...@@ -1943,6 +1961,10 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_...@@ -1943,6 +1961,10 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
1943 case FnWalkIdCall:1961 case FnWalkIdCall:
1944 fn_walk->data.call.gen_param_values->append(val);1962 fn_walk->data.call.gen_param_values->append(val);
1945 break;1963 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;
1946 }1968 }
1947 return true;1969 return true;
1948 }1970 }
...@@ -1958,6 +1980,12 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_...@@ -1958,6 +1980,12 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
1958 case FnWalkIdCall:1980 case FnWalkIdCall:
1959 fn_walk->data.call.gen_param_values->append(val);1981 fn_walk->data.call.gen_param_values->append(val);
1960 break;1982 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 }
1961 }1989 }
1962 return true;1990 return true;
1963 }1991 }
...@@ -1979,6 +2007,12 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_...@@ -1979,6 +2007,12 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
1979 case FnWalkIdCall:2007 case FnWalkIdCall:
1980 fn_walk->data.call.gen_param_values->append(val);2008 fn_walk->data.call.gen_param_values->append(val);
1981 break;2009 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 }
1982 }2016 }
1983 return true;2017 return true;
1984 }2018 }
...@@ -2007,6 +2041,12 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_...@@ -2007,6 +2041,12 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_
2007 fn_walk->data.call.gen_param_values->append(loaded);2041 fn_walk->data.call.gen_param_values->append(loaded);
2008 break;2042 break;
2009 }2043 }
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 }
2010 }2050 }
2011 return true;2051 return true;
2012 }2052 }
...@@ -2074,6 +2114,9 @@ void walk_function_params(CodeGen *g, ZigType *fn_type, FnWalk *fn_walk) {...@@ -2074,6 +2114,9 @@ void walk_function_params(CodeGen *g, ZigType *fn_type, FnWalk *fn_walk) {
2074 case FnWalkIdCall:2114 case FnWalkIdCall:
2075 // handled before for loop2115 // handled before for loop
2076 zig_unreachable();2116 zig_unreachable();
2117 case FnWalkIdTypes:
2118 // Not called for non-c-abi
2119 zig_unreachable();
2077 }2120 }
2078 }2121 }
2079}2122}
src/codegen.hpp-2
...@@ -61,6 +61,4 @@ void codegen_translate_c(CodeGen *g, Buf *path);...@@ -61,6 +61,4 @@ void codegen_translate_c(CodeGen *g, Buf *path);
6161
62Buf *codegen_generate_builtin_source(CodeGen *g);62Buf *codegen_generate_builtin_source(CodeGen *g);
6363
64void walk_function_params(CodeGen *g, ZigType *fn_type, FnWalk *fn_walk);
65
66#endif64#endif