| ... | ... | @@ -88,8 +88,8 @@ static bool value_is_all_undef(CodeGen *g, ZigValue *const_val); |
| 88 | 88 | static void gen_undef_init(CodeGen *g, ZigType *ptr_type, ZigType *value_type, LLVMValueRef ptr); |
| 89 | 89 | static LLVMValueRef build_alloca(CodeGen *g, ZigType *type_entry, const char *name, uint32_t alignment); |
| 90 | 90 | static LLVMValueRef gen_await_early_return(CodeGen *g, Stage1AirInst *source_instr, |
| 91 | | LLVMValueRef target_frame_ptr, ZigType *result_type, ZigType *ptr_result_type, |
| 92 | | LLVMValueRef result_loc, bool non_async); |
| 91 | LLVMTypeRef target_frame_struct_llvm_ty, LLVMValueRef target_frame_ptr, |
| 92 | ZigType *result_type, ZigType *ptr_result_type, LLVMValueRef result_loc, bool non_async); |
| 93 | 93 | |
| 94 | 94 | static void addLLVMAttr(LLVMValueRef val, LLVMAttributeIndex attr_index, const char *attr_name) { |
| 95 | 95 | unsigned kind_id = LLVMGetEnumAttributeKindForName(attr_name, strlen(attr_name)); |
| ... | ... | @@ -911,10 +911,10 @@ static LLVMValueRef gen_store(CodeGen *g, LLVMValueRef value, LLVMValueRef ptr, |
| 911 | 911 | return gen_store_untyped(g, value, ptr, alignment, ptr_type->data.pointer.is_volatile); |
| 912 | 912 | } |
| 913 | 913 | |
| 914 | | static LLVMValueRef gen_load_untyped(CodeGen *g, LLVMValueRef ptr, uint32_t alignment, bool is_volatile, |
| 915 | | const char *name) |
| 914 | static LLVMValueRef gen_load_untyped(CodeGen *g, LLVMTypeRef elem_llvm_ty, LLVMValueRef ptr, |
| 915 | uint32_t alignment, bool is_volatile, const char *name) |
| 916 | 916 | { |
| 917 | | LLVMValueRef result = LLVMBuildLoad(g->builder, ptr, name); |
| 917 | LLVMValueRef result = LLVMBuildLoad2(g->builder, elem_llvm_ty, ptr, name); |
| 918 | 918 | if (is_volatile) LLVMSetVolatile(result, true); |
| 919 | 919 | if (alignment == 0) { |
| 920 | 920 | LLVMSetAlignment(result, LLVMABIAlignmentOfType(g->target_data_ref, LLVMGetElementType(LLVMTypeOf(ptr)))); |
| ... | ... | @@ -927,7 +927,9 @@ static LLVMValueRef gen_load_untyped(CodeGen *g, LLVMValueRef ptr, uint32_t alig |
| 927 | 927 | static LLVMValueRef gen_load(CodeGen *g, LLVMValueRef ptr, ZigType *ptr_type, const char *name) { |
| 928 | 928 | assert(ptr_type->id == ZigTypeIdPointer); |
| 929 | 929 | uint32_t alignment = get_ptr_align(g, ptr_type); |
| 930 | | return gen_load_untyped(g, ptr, alignment, ptr_type->data.pointer.is_volatile, name); |
| 930 | LLVMTypeRef elem_llvm_ty = get_llvm_type(g, ptr_type->data.pointer.child_type); |
| 931 | bool is_volatile = ptr_type->data.pointer.is_volatile; |
| 932 | return gen_load_untyped(g, elem_llvm_ty, ptr, alignment, is_volatile, name); |
| 931 | 933 | } |
| 932 | 934 | |
| 933 | 935 | static LLVMValueRef get_handle_value(CodeGen *g, LLVMValueRef ptr, ZigType *type, ZigType *ptr_type) { |
| ... | ... | @@ -1090,7 +1092,7 @@ static void gen_panic(CodeGen *g, LLVMValueRef msg_arg, LLVMValueRef stack_trace |
| 1090 | 1092 | msg_arg, |
| 1091 | 1093 | stack_trace_arg, |
| 1092 | 1094 | }; |
| 1093 | | ZigLLVMBuildCall(g->builder, fn_val, args, 2, llvm_cc, ZigLLVM_CallAttrAuto, ""); |
| 1095 | ZigLLVMBuildCall(g->builder, LLVMTypeOf(fn_val), fn_val, args, 2, llvm_cc, ZigLLVM_CallAttrAuto, ""); |
| 1094 | 1096 | if (!stack_trace_is_llvm_alloca) { |
| 1095 | 1097 | // The stack trace argument is not in the stack of the caller, so |
| 1096 | 1098 | // we'd like to set tail call here, but because slices (the type of msg_arg) are |
| ... | ... | @@ -1265,26 +1267,37 @@ static LLVMValueRef get_add_error_return_trace_addr_fn(CodeGen *g) { |
| 1265 | 1267 | LLVMValueRef address_value = LLVMGetParam(fn_val, 1); |
| 1266 | 1268 | |
| 1267 | 1269 | size_t index_field_index = g->stack_trace_type->data.structure.fields[0]->gen_index; |
| 1268 | | LLVMValueRef index_field_ptr = LLVMBuildStructGEP(g->builder, err_ret_trace_ptr, (unsigned)index_field_index, ""); |
| 1270 | LLVMValueRef index_field_ptr = LLVMBuildStructGEP2(g->builder, |
| 1271 | get_llvm_type(g, g->stack_trace_type), |
| 1272 | err_ret_trace_ptr, (unsigned)index_field_index, ""); |
| 1269 | 1273 | size_t addresses_field_index = g->stack_trace_type->data.structure.fields[1]->gen_index; |
| 1270 | | LLVMValueRef addresses_field_ptr = LLVMBuildStructGEP(g->builder, err_ret_trace_ptr, (unsigned)addresses_field_index, ""); |
| 1274 | LLVMValueRef addresses_field_ptr = LLVMBuildStructGEP2(g->builder, |
| 1275 | get_llvm_type(g, g->stack_trace_type), |
| 1276 | err_ret_trace_ptr, (unsigned)addresses_field_index, ""); |
| 1271 | 1277 | |
| 1272 | 1278 | ZigType *slice_type = g->stack_trace_type->data.structure.fields[1]->type_entry; |
| 1273 | 1279 | size_t ptr_field_index = slice_type->data.structure.fields[slice_ptr_index]->gen_index; |
| 1274 | | LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, addresses_field_ptr, (unsigned)ptr_field_index, ""); |
| 1280 | LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP2(g->builder, |
| 1281 | LLVMGetGEPSourceElementType(addresses_field_ptr), |
| 1282 | addresses_field_ptr, (unsigned)ptr_field_index, ""); |
| 1275 | 1283 | size_t len_field_index = slice_type->data.structure.fields[slice_len_index]->gen_index; |
| 1276 | | LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, addresses_field_ptr, (unsigned)len_field_index, ""); |
| 1277 | | |
| 1278 | | LLVMValueRef len_value = gen_load_untyped(g, len_field_ptr, 0, false, ""); |
| 1279 | | LLVMValueRef index_val = gen_load_untyped(g, index_field_ptr, 0, false, ""); |
| 1284 | LLVMValueRef len_field_ptr = LLVMBuildStructGEP2(g->builder, |
| 1285 | LLVMGetGEPSourceElementType(addresses_field_ptr), |
| 1286 | addresses_field_ptr, (unsigned)len_field_index, ""); |
| 1287 | |
| 1288 | LLVMValueRef len_value = gen_load_untyped(g, LLVMGetGEPSourceElementType(len_field_ptr), |
| 1289 | len_field_ptr, 0, false, ""); |
| 1290 | LLVMValueRef index_val = gen_load_untyped(g, LLVMGetGEPSourceElementType(index_field_ptr), |
| 1291 | index_field_ptr, 0, false, ""); |
| 1280 | 1292 | LLVMValueRef len_val_minus_one = LLVMBuildSub(g->builder, len_value, LLVMConstInt(usize_type_ref, 1, false), ""); |
| 1281 | 1293 | LLVMValueRef masked_val = LLVMBuildAnd(g->builder, index_val, len_val_minus_one, ""); |
| 1282 | 1294 | LLVMValueRef address_indices[] = { |
| 1283 | 1295 | masked_val, |
| 1284 | 1296 | }; |
| 1285 | 1297 | |
| 1286 | | LLVMValueRef ptr_value = gen_load_untyped(g, ptr_field_ptr, 0, false, ""); |
| 1287 | | LLVMValueRef address_slot = LLVMBuildInBoundsGEP(g->builder, ptr_value, address_indices, 1, ""); |
| 1298 | LLVMValueRef ptr_value = gen_load_untyped(g, LLVMGetGEPSourceElementType(ptr_field_ptr), |
| 1299 | ptr_field_ptr, 0, false, ""); |
| 1300 | LLVMValueRef address_slot = LLVMBuildInBoundsGEP2(g->builder, usize_type_ref, ptr_value, address_indices, 1, ""); |
| 1288 | 1301 | |
| 1289 | 1302 | gen_store_untyped(g, address_value, address_slot, 0, false); |
| 1290 | 1303 | |
| ... | ... | @@ -1340,7 +1353,8 @@ static LLVMValueRef get_return_err_fn(CodeGen *g) { |
| 1340 | 1353 | |
| 1341 | 1354 | LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type; |
| 1342 | 1355 | LLVMValueRef zero = LLVMConstNull(get_llvm_type(g, g->builtin_types.entry_i32)); |
| 1343 | | LLVMValueRef return_address_ptr = LLVMBuildCall(g->builder, get_return_address_fn_val(g), &zero, 1, ""); |
| 1356 | LLVMValueRef return_address_ptr = LLVMBuildCall2(g->builder, |
| 1357 | LLVMTypeOf(get_return_address_fn_val(g)), get_return_address_fn_val(g), &zero, 1, ""); |
| 1344 | 1358 | LLVMValueRef return_address = LLVMBuildPtrToInt(g->builder, return_address_ptr, usize_type_ref, ""); |
| 1345 | 1359 | |
| 1346 | 1360 | LLVMBasicBlockRef return_block = LLVMAppendBasicBlock(fn_val, "Return"); |
| ... | ... | @@ -1355,7 +1369,8 @@ static LLVMValueRef get_return_err_fn(CodeGen *g) { |
| 1355 | 1369 | |
| 1356 | 1370 | LLVMPositionBuilderAtEnd(g->builder, dest_non_null_block); |
| 1357 | 1371 | LLVMValueRef args[] = { err_ret_trace_ptr, return_address }; |
| 1358 | | ZigLLVMBuildCall(g->builder, add_error_return_trace_addr_fn_val, args, 2, |
| 1372 | ZigLLVMBuildCall(g->builder, LLVMTypeOf(add_error_return_trace_addr_fn_val), |
| 1373 | add_error_return_trace_addr_fn_val, args, 2, |
| 1359 | 1374 | get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_CallAttrAlwaysInline, ""); |
| 1360 | 1375 | LLVMBuildRetVoid(g->builder); |
| 1361 | 1376 | |
| ... | ... | @@ -1446,25 +1461,32 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) { |
| 1446 | 1461 | LLVMConstNull(usize_ty->llvm_type), |
| 1447 | 1462 | err_val, |
| 1448 | 1463 | }; |
| 1449 | | LLVMValueRef err_name_val = LLVMBuildInBoundsGEP(g->builder, g->err_name_table, err_table_indices, 2, ""); |
| 1464 | LLVMValueRef err_name_val = LLVMBuildInBoundsGEP2(g->builder, |
| 1465 | get_llvm_type(g, str_type), |
| 1466 | g->err_name_table, err_table_indices, 2, ""); |
| 1450 | 1467 | |
| 1451 | | LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, err_name_val, slice_ptr_index, ""); |
| 1452 | | LLVMValueRef err_name_ptr = gen_load_untyped(g, ptr_field_ptr, 0, false, ""); |
| 1468 | LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP2(g->builder, |
| 1469 | LLVMGetGEPSourceElementType(err_name_val), err_name_val, slice_ptr_index, ""); |
| 1470 | LLVMValueRef err_name_ptr = gen_load_untyped(g, LLVMGetGEPSourceElementType(ptr_field_ptr), |
| 1471 | ptr_field_ptr, 0, false, ""); |
| 1453 | 1472 | |
| 1454 | | LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, err_name_val, slice_len_index, ""); |
| 1455 | | LLVMValueRef err_name_len = gen_load_untyped(g, len_field_ptr, 0, false, ""); |
| 1473 | LLVMValueRef len_field_ptr = LLVMBuildStructGEP2(g->builder, |
| 1474 | LLVMGetGEPSourceElementType(err_name_val), err_name_val, slice_len_index, ""); |
| 1475 | LLVMValueRef err_name_len = gen_load_untyped(g, LLVMGetGEPSourceElementType(len_field_ptr), |
| 1476 | len_field_ptr, 0, false, ""); |
| 1456 | 1477 | |
| 1457 | 1478 | LLVMValueRef msg_prefix_len = LLVMConstInt(usize_ty->llvm_type, strlen(unwrap_err_msg_text), false); |
| 1458 | 1479 | // Points to the beginning of msg_buffer |
| 1459 | 1480 | LLVMValueRef msg_buffer_ptr_indices[] = { |
| 1460 | 1481 | LLVMConstNull(usize_ty->llvm_type), |
| 1461 | 1482 | }; |
| 1462 | | LLVMValueRef msg_buffer_ptr = LLVMBuildInBoundsGEP(g->builder, msg_buffer, msg_buffer_ptr_indices, 1, ""); |
| 1483 | LLVMValueRef msg_buffer_ptr = LLVMBuildInBoundsGEP2(g->builder, LLVMInt8Type(), msg_buffer, |
| 1484 | msg_buffer_ptr_indices, 1, ""); |
| 1463 | 1485 | // Points to the beginning of the constant prefix message |
| 1464 | 1486 | LLVMValueRef msg_prefix_ptr_indices[] = { |
| 1465 | 1487 | LLVMConstNull(usize_ty->llvm_type), |
| 1466 | 1488 | }; |
| 1467 | | LLVMValueRef msg_prefix_ptr = LLVMConstInBoundsGEP(msg_prefix, msg_prefix_ptr_indices, 1); |
| 1489 | LLVMValueRef msg_prefix_ptr = LLVMConstInBoundsGEP2(LLVMInt8Type(), msg_prefix, msg_prefix_ptr_indices, 1); |
| 1468 | 1490 | |
| 1469 | 1491 | // Build the message using the prefix... |
| 1470 | 1492 | ZigLLVMBuildMemCpy(g->builder, msg_buffer_ptr, 1, msg_prefix_ptr, 1, msg_prefix_len, false); |
| ... | ... | @@ -1472,16 +1494,18 @@ static LLVMValueRef get_safety_crash_err_fn(CodeGen *g) { |
| 1472 | 1494 | LLVMValueRef msg_buffer_ptr_after_indices[] = { |
| 1473 | 1495 | msg_prefix_len, |
| 1474 | 1496 | }; |
| 1475 | | LLVMValueRef msg_buffer_ptr_after = LLVMBuildInBoundsGEP(g->builder, msg_buffer, msg_buffer_ptr_after_indices, 1, ""); |
| 1497 | LLVMValueRef msg_buffer_ptr_after = LLVMBuildInBoundsGEP2(g->builder, LLVMInt8Type(), msg_buffer, msg_buffer_ptr_after_indices, 1, ""); |
| 1476 | 1498 | ZigLLVMBuildMemCpy(g->builder, msg_buffer_ptr_after, 1, err_name_ptr, 1, err_name_len, false); |
| 1477 | 1499 | |
| 1478 | 1500 | // Set the slice pointer |
| 1479 | | LLVMValueRef msg_slice_ptr_field_ptr = LLVMBuildStructGEP(g->builder, msg_slice, slice_ptr_index, ""); |
| 1501 | LLVMValueRef msg_slice_ptr_field_ptr = LLVMBuildStructGEP2(g->builder, |
| 1502 | get_llvm_type(g, str_type), msg_slice, slice_ptr_index, ""); |
| 1480 | 1503 | gen_store_untyped(g, msg_buffer_ptr, msg_slice_ptr_field_ptr, 0, false); |
| 1481 | 1504 | |
| 1482 | 1505 | // Set the slice length |
| 1483 | 1506 | LLVMValueRef slice_len = LLVMBuildNUWAdd(g->builder, msg_prefix_len, err_name_len, ""); |
| 1484 | | LLVMValueRef msg_slice_len_field_ptr = LLVMBuildStructGEP(g->builder, msg_slice, slice_len_index, ""); |
| 1507 | LLVMValueRef msg_slice_len_field_ptr = LLVMBuildStructGEP2(g->builder, |
| 1508 | get_llvm_type(g, str_type), msg_slice, slice_len_index, ""); |
| 1485 | 1509 | gen_store_untyped(g, slice_len, msg_slice_len_field_ptr, 0, false); |
| 1486 | 1510 | |
| 1487 | 1511 | // Call panic() |
| ... | ... | @@ -1522,13 +1546,15 @@ static void gen_safety_crash_for_err(CodeGen *g, LLVMValueRef err_val, Scope *sc |
| 1522 | 1546 | err_ret_trace_val, |
| 1523 | 1547 | err_val, |
| 1524 | 1548 | }; |
| 1525 | | call_instruction = ZigLLVMBuildCall(g->builder, safety_crash_err_fn, args, 2, |
| 1549 | call_instruction = ZigLLVMBuildCall(g->builder, LLVMTypeOf(safety_crash_err_fn), |
| 1550 | safety_crash_err_fn, args, 2, |
| 1526 | 1551 | get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_CallAttrAuto, ""); |
| 1527 | 1552 | } else { |
| 1528 | 1553 | LLVMValueRef args[] = { |
| 1529 | 1554 | err_val, |
| 1530 | 1555 | }; |
| 1531 | | call_instruction = ZigLLVMBuildCall(g->builder, safety_crash_err_fn, args, 1, |
| 1556 | call_instruction = ZigLLVMBuildCall(g->builder, LLVMTypeOf(safety_crash_err_fn), |
| 1557 | safety_crash_err_fn, args, 1, |
| 1532 | 1558 | get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_CallAttrAuto, ""); |
| 1533 | 1559 | } |
| 1534 | 1560 | if (!is_llvm_alloca) { |
| ... | ... | @@ -1573,7 +1599,7 @@ static void add_bounds_check(CodeGen *g, LLVMValueRef target_val, |
| 1573 | 1599 | static void add_sentinel_check(CodeGen *g, LLVMValueRef sentinel_elem_ptr, ZigValue *sentinel) { |
| 1574 | 1600 | LLVMValueRef expected_sentinel = gen_const_val(g, sentinel, ""); |
| 1575 | 1601 | |
| 1576 | | LLVMValueRef actual_sentinel = gen_load_untyped(g, sentinel_elem_ptr, 0, false, ""); |
| 1602 | LLVMValueRef actual_sentinel = gen_load_untyped(g, LLVMTypeOf(expected_sentinel), sentinel_elem_ptr, 0, false, ""); |
| 1577 | 1603 | LLVMValueRef ok_bit; |
| 1578 | 1604 | if (sentinel->type->id == ZigTypeIdFloat) { |
| 1579 | 1605 | ok_bit = LLVMBuildFCmp(g->builder, LLVMRealOEQ, actual_sentinel, expected_sentinel, ""); |
| ... | ... | @@ -1706,7 +1732,7 @@ static LLVMValueRef gen_soft_float_widen_or_shorten(CodeGen *g, ZigType *actual_ |
| 1706 | 1732 | func_ref = LLVMAddFunction(g->module, fn_name, fn_type); |
| 1707 | 1733 | } |
| 1708 | 1734 | |
| 1709 | | result = LLVMBuildCall(g->builder, func_ref, &expr_val, 1, ""); |
| 1735 | result = LLVMBuildCall2(g->builder, LLVMTypeOf(func_ref), func_ref, &expr_val, 1, ""); |
| 1710 | 1736 | |
| 1711 | 1737 | // On non-Arm platforms we need to bitcast __trunc<>fhf2 result back to f16 |
| 1712 | 1738 | if (castTruncatedToF16) { |
| ... | ... | @@ -1852,7 +1878,7 @@ static LLVMValueRef gen_overflow_op(CodeGen *g, ZigType *operand_type, AddSubMul |
| 1852 | 1878 | val1, |
| 1853 | 1879 | val2, |
| 1854 | 1880 | }; |
| 1855 | | LLVMValueRef result_struct = LLVMBuildCall(g->builder, fn_val, params, 2, ""); |
| 1881 | LLVMValueRef result_struct = LLVMBuildCall2(g->builder, LLVMTypeOf(fn_val), fn_val, params, 2, ""); |
| 1856 | 1882 | LLVMValueRef result = LLVMBuildExtractValue(g->builder, result_struct, 0, ""); |
| 1857 | 1883 | LLVMValueRef overflow_bit = LLVMBuildExtractValue(g->builder, result_struct, 1, ""); |
| 1858 | 1884 | if (operand_type->id == ZigTypeIdVector) { |
| ... | ... | @@ -2272,9 +2298,8 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_ |
| 2272 | 2298 | fn_walk->data.attrs.gen_i += 1; |
| 2273 | 2299 | break; |
| 2274 | 2300 | case FnWalkIdCall: { |
| 2275 | | LLVMTypeRef ptr_to_int_type_ref = LLVMPointerType(LLVMIntType((unsigned)ty_size * 8), 0); |
| 2276 | | LLVMValueRef bitcasted = LLVMBuildBitCast(g->builder, val, ptr_to_int_type_ref, ""); |
| 2277 | | LLVMValueRef loaded = LLVMBuildLoad(g->builder, bitcasted, ""); |
| 2301 | LLVMTypeRef ptr_elem_llvm_ty = LLVMIntType((unsigned)ty_size * 8); |
| 2302 | LLVMValueRef loaded = LLVMBuildLoad2(g->builder, ptr_elem_llvm_ty, val, ""); |
| 2278 | 2303 | fn_walk->data.call.gen_param_values->append(loaded); |
| 2279 | 2304 | break; |
| 2280 | 2305 | } |
| ... | ... | @@ -2342,18 +2367,17 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_ |
| 2342 | 2367 | break; |
| 2343 | 2368 | } |
| 2344 | 2369 | case FnWalkIdCall: { |
| 2345 | | LLVMValueRef abi_ptr_to_struct = LLVMBuildBitCast(g->builder, val, LLVMPointerType(abi_type, 0), ""); |
| 2346 | 2370 | if (number_of_regs == 1) { |
| 2347 | | LLVMValueRef loaded = LLVMBuildLoad(g->builder, abi_ptr_to_struct, ""); |
| 2371 | LLVMValueRef loaded = LLVMBuildLoad2(g->builder, abi_type, val, ""); |
| 2348 | 2372 | fn_walk->data.call.gen_param_values->append(loaded); |
| 2349 | 2373 | break; |
| 2350 | 2374 | } |
| 2351 | 2375 | for (uint32_t i = 0; i < number_of_regs; i += 1) { |
| 2352 | | LLVMValueRef zero = LLVMConstInt(LLVMInt32Type(), 0, false); |
| 2353 | | LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, false); |
| 2354 | | LLVMValueRef indices[] = { zero, index }; |
| 2355 | | LLVMValueRef adjusted_ptr_to_struct = LLVMBuildInBoundsGEP(g->builder, abi_ptr_to_struct, indices, 2, ""); |
| 2356 | | LLVMValueRef loaded = LLVMBuildLoad(g->builder, adjusted_ptr_to_struct, ""); |
| 2376 | LLVMValueRef adjusted_ptr_to_struct = LLVMBuildStructGEP2(g->builder, |
| 2377 | abi_type, val, i, ""); |
| 2378 | LLVMValueRef loaded = LLVMBuildLoad2(g->builder, |
| 2379 | LLVMGetGEPSourceElementType(adjusted_ptr_to_struct), |
| 2380 | adjusted_ptr_to_struct, ""); |
| 2357 | 2381 | fn_walk->data.call.gen_param_values->append(loaded); |
| 2358 | 2382 | } |
| 2359 | 2383 | break; |
| ... | ... | @@ -2388,13 +2412,13 @@ static bool iter_function_params_c_abi(CodeGen *g, ZigType *fn_type, FnWalk *fn_ |
| 2388 | 2412 | LLVMValueRef bitcasted = LLVMBuildBitCast(g->builder, var->value_ref, ptr_to_int_type_ref, ""); |
| 2389 | 2413 | gen_store_untyped(g, arg, bitcasted, var->align_bytes, false); |
| 2390 | 2414 | } else { |
| 2391 | | LLVMValueRef abi_ptr_to_struct = LLVMBuildBitCast(g->builder, var->value_ref, LLVMPointerType(abi_type, 0), ""); |
| 2392 | 2415 | for (uint32_t i = 0; i < number_of_regs; i += 1) { |
| 2393 | 2416 | LLVMValueRef arg = LLVMGetParam(llvm_fn, fn_walk->data.inits.gen_i + i); |
| 2394 | 2417 | LLVMValueRef zero = LLVMConstInt(LLVMInt32Type(), 0, false); |
| 2395 | 2418 | LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), i, false); |
| 2396 | 2419 | LLVMValueRef indices[] = { zero, index }; |
| 2397 | | LLVMValueRef adjusted_ptr_to_struct = LLVMBuildInBoundsGEP(g->builder, abi_ptr_to_struct, indices, 2, ""); |
| 2420 | LLVMValueRef adjusted_ptr_to_struct = LLVMBuildInBoundsGEP2(g->builder, |
| 2421 | abi_type, var->value_ref, indices, 2, ""); |
| 2398 | 2422 | LLVMBuildStore(g->builder, arg, adjusted_ptr_to_struct); |
| 2399 | 2423 | } |
| 2400 | 2424 | fn_walk->data.inits.gen_i += 1; |
| ... | ... | @@ -2573,8 +2597,9 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) { |
| 2573 | 2597 | LLVMBasicBlockRef return_block = LLVMAppendBasicBlock(fn_val, "Return"); |
| 2574 | 2598 | LLVMBasicBlockRef non_null_block = LLVMAppendBasicBlock(fn_val, "NonNull"); |
| 2575 | 2599 | |
| 2576 | | LLVMValueRef frame_index_ptr = LLVMBuildAlloca(g->builder, g->builtin_types.entry_usize->llvm_type, "frame_index"); |
| 2577 | | LLVMValueRef frames_left_ptr = LLVMBuildAlloca(g->builder, g->builtin_types.entry_usize->llvm_type, "frames_left"); |
| 2600 | LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type; |
| 2601 | LLVMValueRef frame_index_ptr = LLVMBuildAlloca(g->builder, usize_type_ref, "frame_index"); |
| 2602 | LLVMValueRef frames_left_ptr = LLVMBuildAlloca(g->builder, usize_type_ref, "frames_left"); |
| 2578 | 2603 | |
| 2579 | 2604 | LLVMValueRef dest_stack_trace_ptr = LLVMGetParam(fn_val, 0); |
| 2580 | 2605 | LLVMValueRef src_stack_trace_ptr = LLVMGetParam(fn_val, 1); |
| ... | ... | @@ -2589,18 +2614,27 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) { |
| 2589 | 2614 | LLVMPositionBuilderAtEnd(g->builder, non_null_block); |
| 2590 | 2615 | size_t src_index_field_index = g->stack_trace_type->data.structure.fields[0]->gen_index; |
| 2591 | 2616 | size_t src_addresses_field_index = g->stack_trace_type->data.structure.fields[1]->gen_index; |
| 2592 | | LLVMValueRef src_index_field_ptr = LLVMBuildStructGEP(g->builder, src_stack_trace_ptr, |
| 2617 | LLVMValueRef src_index_field_ptr = LLVMBuildStructGEP2(g->builder, |
| 2618 | get_llvm_type(g, g->stack_trace_type), src_stack_trace_ptr, |
| 2593 | 2619 | (unsigned)src_index_field_index, ""); |
| 2594 | | LLVMValueRef src_addresses_field_ptr = LLVMBuildStructGEP(g->builder, src_stack_trace_ptr, |
| 2620 | LLVMValueRef src_addresses_field_ptr = LLVMBuildStructGEP2(g->builder, |
| 2621 | get_llvm_type(g, g->stack_trace_type), src_stack_trace_ptr, |
| 2595 | 2622 | (unsigned)src_addresses_field_index, ""); |
| 2596 | 2623 | ZigType *slice_type = g->stack_trace_type->data.structure.fields[1]->type_entry; |
| 2597 | 2624 | size_t ptr_field_index = slice_type->data.structure.fields[slice_ptr_index]->gen_index; |
| 2598 | | LLVMValueRef src_ptr_field_ptr = LLVMBuildStructGEP(g->builder, src_addresses_field_ptr, (unsigned)ptr_field_index, ""); |
| 2625 | LLVMValueRef src_ptr_field_ptr = LLVMBuildStructGEP2(g->builder, |
| 2626 | LLVMGetGEPSourceElementType(src_addresses_field_ptr), |
| 2627 | src_addresses_field_ptr, (unsigned)ptr_field_index, ""); |
| 2599 | 2628 | size_t len_field_index = slice_type->data.structure.fields[slice_len_index]->gen_index; |
| 2600 | | LLVMValueRef src_len_field_ptr = LLVMBuildStructGEP(g->builder, src_addresses_field_ptr, (unsigned)len_field_index, ""); |
| 2601 | | LLVMValueRef src_index_val = LLVMBuildLoad(g->builder, src_index_field_ptr, ""); |
| 2602 | | LLVMValueRef src_ptr_val = LLVMBuildLoad(g->builder, src_ptr_field_ptr, ""); |
| 2603 | | LLVMValueRef src_len_val = LLVMBuildLoad(g->builder, src_len_field_ptr, ""); |
| 2629 | LLVMValueRef src_len_field_ptr = LLVMBuildStructGEP2(g->builder, |
| 2630 | LLVMGetGEPSourceElementType(src_addresses_field_ptr), |
| 2631 | src_addresses_field_ptr, (unsigned)len_field_index, ""); |
| 2632 | LLVMValueRef src_index_val = LLVMBuildLoad2(g->builder, |
| 2633 | LLVMGetGEPSourceElementType(src_index_field_ptr), src_index_field_ptr, ""); |
| 2634 | LLVMValueRef src_ptr_val = LLVMBuildLoad2(g->builder, |
| 2635 | LLVMGetGEPSourceElementType(src_ptr_field_ptr), src_ptr_field_ptr, ""); |
| 2636 | LLVMValueRef src_len_val = LLVMBuildLoad2(g->builder, |
| 2637 | LLVMGetGEPSourceElementType(src_len_field_ptr), src_len_field_ptr, ""); |
| 2604 | 2638 | LLVMValueRef no_wrap_bit = LLVMBuildICmp(g->builder, LLVMIntULT, src_index_val, src_len_val, ""); |
| 2605 | 2639 | LLVMBasicBlockRef no_wrap_block = LLVMAppendBasicBlock(fn_val, "NoWrap"); |
| 2606 | 2640 | LLVMBasicBlockRef yes_wrap_block = LLVMAppendBasicBlock(fn_val, "YesWrap"); |
| ... | ... | @@ -2608,14 +2642,14 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) { |
| 2608 | 2642 | LLVMBuildCondBr(g->builder, no_wrap_bit, no_wrap_block, yes_wrap_block); |
| 2609 | 2643 | |
| 2610 | 2644 | LLVMPositionBuilderAtEnd(g->builder, no_wrap_block); |
| 2611 | | LLVMValueRef usize_zero = LLVMConstNull(g->builtin_types.entry_usize->llvm_type); |
| 2645 | LLVMValueRef usize_zero = LLVMConstNull(usize_type_ref); |
| 2612 | 2646 | LLVMBuildStore(g->builder, usize_zero, frame_index_ptr); |
| 2613 | 2647 | LLVMBuildStore(g->builder, src_index_val, frames_left_ptr); |
| 2614 | 2648 | LLVMValueRef frames_left_eq_zero_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, src_index_val, usize_zero, ""); |
| 2615 | 2649 | LLVMBuildCondBr(g->builder, frames_left_eq_zero_bit, return_block, loop_block); |
| 2616 | 2650 | |
| 2617 | 2651 | LLVMPositionBuilderAtEnd(g->builder, yes_wrap_block); |
| 2618 | | LLVMValueRef usize_one = LLVMConstInt(g->builtin_types.entry_usize->llvm_type, 1, false); |
| 2652 | LLVMValueRef usize_one = LLVMConstInt(usize_type_ref, 1, false); |
| 2619 | 2653 | LLVMValueRef plus_one = LLVMBuildNUWAdd(g->builder, src_index_val, usize_one, ""); |
| 2620 | 2654 | LLVMValueRef mod_len = LLVMBuildURem(g->builder, plus_one, src_len_val, ""); |
| 2621 | 2655 | LLVMBuildStore(g->builder, mod_len, frame_index_ptr); |
| ... | ... | @@ -2623,12 +2657,15 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) { |
| 2623 | 2657 | LLVMBuildBr(g->builder, loop_block); |
| 2624 | 2658 | |
| 2625 | 2659 | LLVMPositionBuilderAtEnd(g->builder, loop_block); |
| 2626 | | LLVMValueRef ptr_index = LLVMBuildLoad(g->builder, frame_index_ptr, ""); |
| 2627 | | LLVMValueRef addr_ptr = LLVMBuildInBoundsGEP(g->builder, src_ptr_val, &ptr_index, 1, ""); |
| 2628 | | LLVMValueRef this_addr_val = LLVMBuildLoad(g->builder, addr_ptr, ""); |
| 2660 | LLVMValueRef ptr_index = LLVMBuildLoad2(g->builder, usize_type_ref, frame_index_ptr, ""); |
| 2661 | LLVMValueRef addr_ptr = LLVMBuildInBoundsGEP2(g->builder, |
| 2662 | usize_type_ref, src_ptr_val, &ptr_index, 1, ""); |
| 2663 | LLVMValueRef this_addr_val = LLVMBuildLoad2(g->builder, LLVMGetGEPSourceElementType(addr_ptr), |
| 2664 | addr_ptr, ""); |
| 2629 | 2665 | LLVMValueRef args[] = {dest_stack_trace_ptr, this_addr_val}; |
| 2630 | | ZigLLVMBuildCall(g->builder, add_error_return_trace_addr_fn_val, args, 2, get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_CallAttrAlwaysInline, ""); |
| 2631 | | LLVMValueRef prev_frames_left = LLVMBuildLoad(g->builder, frames_left_ptr, ""); |
| 2666 | ZigLLVMBuildCall(g->builder, LLVMTypeOf(add_error_return_trace_addr_fn_val), |
| 2667 | add_error_return_trace_addr_fn_val, args, 2, get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_CallAttrAlwaysInline, ""); |
| 2668 | LLVMValueRef prev_frames_left = LLVMBuildLoad2(g->builder, usize_type_ref, frames_left_ptr, ""); |
| 2632 | 2669 | LLVMValueRef new_frames_left = LLVMBuildNUWSub(g->builder, prev_frames_left, usize_one, ""); |
| 2633 | 2670 | LLVMValueRef done_bit = LLVMBuildICmp(g->builder, LLVMIntEQ, new_frames_left, usize_zero, ""); |
| 2634 | 2671 | LLVMBasicBlockRef continue_block = LLVMAppendBasicBlock(fn_val, "Continue"); |
| ... | ... | @@ -2639,7 +2676,7 @@ static LLVMValueRef get_merge_err_ret_traces_fn_val(CodeGen *g) { |
| 2639 | 2676 | |
| 2640 | 2677 | LLVMPositionBuilderAtEnd(g->builder, continue_block); |
| 2641 | 2678 | LLVMBuildStore(g->builder, new_frames_left, frames_left_ptr); |
| 2642 | | LLVMValueRef prev_index = LLVMBuildLoad(g->builder, frame_index_ptr, ""); |
| 2679 | LLVMValueRef prev_index = LLVMBuildLoad2(g->builder, usize_type_ref, frame_index_ptr, ""); |
| 2643 | 2680 | LLVMValueRef index_plus_one = LLVMBuildNUWAdd(g->builder, prev_index, usize_one, ""); |
| 2644 | 2681 | LLVMValueRef index_mod_len = LLVMBuildURem(g->builder, index_plus_one, src_len_val, ""); |
| 2645 | 2682 | LLVMBuildStore(g->builder, index_mod_len, frame_index_ptr); |
| ... | ... | @@ -2666,13 +2703,14 @@ static LLVMValueRef ir_render_save_err_ret_addr(CodeGen *g, Stage1Air *executabl |
| 2666 | 2703 | bool is_llvm_alloca; |
| 2667 | 2704 | LLVMValueRef my_err_trace_val = get_cur_err_ret_trace_val(g, save_err_ret_addr_instruction->base.scope, |
| 2668 | 2705 | &is_llvm_alloca); |
| 2669 | | ZigLLVMBuildCall(g->builder, return_err_fn, &my_err_trace_val, 1, |
| 2706 | ZigLLVMBuildCall(g->builder, LLVMTypeOf(return_err_fn), return_err_fn, &my_err_trace_val, 1, |
| 2670 | 2707 | get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_CallAttrAuto, ""); |
| 2671 | 2708 | |
| 2672 | 2709 | ZigType *ret_type = g->cur_fn->type_entry->data.fn.fn_type_id.return_type; |
| 2673 | 2710 | if (fn_is_async(g->cur_fn) && codegen_fn_has_err_ret_tracing_arg(g, ret_type)) { |
| 2674 | | LLVMValueRef trace_ptr_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, |
| 2675 | | frame_index_trace_arg(g, ret_type), ""); |
| 2711 | ZigType *frame_type = get_fn_frame_type(g, g->cur_fn); |
| 2712 | LLVMValueRef trace_ptr_ptr = LLVMBuildStructGEP2(g->builder, get_llvm_type(g, frame_type), |
| 2713 | g->cur_frame_ptr, frame_index_trace_arg(g, ret_type), ""); |
| 2676 | 2714 | LLVMBuildStore(g->builder, my_err_trace_val, trace_ptr_ptr); |
| 2677 | 2715 | } |
| 2678 | 2716 | |
| ... | ... | @@ -2702,16 +2740,20 @@ static void gen_assert_resume_id(CodeGen *g, Stage1AirInst *source_instr, Resume |
| 2702 | 2740 | LLVMPositionBuilderAtEnd(g->builder, end_bb); |
| 2703 | 2741 | } |
| 2704 | 2742 | |
| 2705 | | static LLVMValueRef gen_resume(CodeGen *g, LLVMValueRef fn_val, LLVMValueRef target_frame_ptr, ResumeId resume_id) { |
| 2743 | static LLVMValueRef gen_resume(CodeGen *g, LLVMValueRef fn_val, LLVMValueRef target_frame_ptr, |
| 2744 | ResumeId resume_id) |
| 2745 | { |
| 2706 | 2746 | LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type; |
| 2707 | 2747 | if (fn_val == nullptr) { |
| 2708 | | LLVMValueRef fn_ptr_ptr = LLVMBuildStructGEP(g->builder, target_frame_ptr, frame_fn_ptr_index, ""); |
| 2709 | | fn_val = LLVMBuildLoad(g->builder, fn_ptr_ptr, ""); |
| 2748 | LLVMValueRef fn_ptr_ptr = LLVMBuildStructGEP2(g->builder, g->any_frame_header_llvm_ty, |
| 2749 | target_frame_ptr, frame_fn_ptr_index, ""); |
| 2750 | fn_val = LLVMBuildLoad2(g->builder, LLVMPointerTypeInContext(LLVMGetGlobalContext(), 0), |
| 2751 | fn_ptr_ptr, ""); |
| 2710 | 2752 | } |
| 2711 | 2753 | LLVMValueRef arg_val = LLVMConstSub(LLVMConstAllOnes(usize_type_ref), |
| 2712 | 2754 | LLVMConstInt(usize_type_ref, resume_id, false)); |
| 2713 | 2755 | LLVMValueRef args[] = {target_frame_ptr, arg_val}; |
| 2714 | | return ZigLLVMBuildCall(g->builder, fn_val, args, 2, ZigLLVM_Fast, ZigLLVM_CallAttrAuto, ""); |
| 2756 | return ZigLLVMBuildCall(g->builder, LLVMTypeOf(fn_val), fn_val, args, 2, ZigLLVM_Fast, ZigLLVM_CallAttrAuto, ""); |
| 2715 | 2757 | } |
| 2716 | 2758 | |
| 2717 | 2759 | static LLVMBasicBlockRef gen_suspend_begin(CodeGen *g, const char *name_hint) { |
| ... | ... | @@ -2733,11 +2775,11 @@ static void set_tail_call_if_appropriate(CodeGen *g, LLVMValueRef call_inst) { |
| 2733 | 2775 | LLVMSetTailCall(call_inst, true); |
| 2734 | 2776 | } |
| 2735 | 2777 | |
| 2736 | | static LLVMValueRef gen_maybe_atomic_op(CodeGen *g, LLVMAtomicRMWBinOp op, LLVMValueRef ptr, LLVMValueRef val, |
| 2737 | | LLVMAtomicOrdering order) |
| 2778 | static LLVMValueRef gen_maybe_atomic_op(CodeGen *g, LLVMAtomicRMWBinOp op, LLVMValueRef ptr, |
| 2779 | LLVMValueRef val, LLVMAtomicOrdering order) |
| 2738 | 2780 | { |
| 2739 | 2781 | if (g->is_single_threaded) { |
| 2740 | | LLVMValueRef loaded = LLVMBuildLoad(g->builder, ptr, ""); |
| 2782 | LLVMValueRef loaded = LLVMBuildLoad2(g->builder, LLVMTypeOf(val), ptr, ""); |
| 2741 | 2783 | LLVMValueRef modified; |
| 2742 | 2784 | switch (op) { |
| 2743 | 2785 | case LLVMAtomicRMWBinOpXchg: |
| ... | ... | @@ -2811,8 +2853,11 @@ static void gen_async_return(CodeGen *g, Stage1AirInstReturn *instruction) { |
| 2811 | 2853 | // If the awaiter result pointer is non-null, we need to copy the result to there. |
| 2812 | 2854 | LLVMBasicBlockRef copy_block = LLVMAppendBasicBlock(g->cur_fn_val, "CopyResult"); |
| 2813 | 2855 | LLVMBasicBlockRef copy_end_block = LLVMAppendBasicBlock(g->cur_fn_val, "CopyResultEnd"); |
| 2814 | | LLVMValueRef awaiter_ret_ptr_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, frame_ret_start + 1, ""); |
| 2815 | | LLVMValueRef awaiter_ret_ptr = LLVMBuildLoad(g->builder, awaiter_ret_ptr_ptr, ""); |
| 2856 | LLVMValueRef awaiter_ret_ptr_ptr = LLVMBuildStructGEP2(g->builder, |
| 2857 | get_llvm_type(g, get_fn_frame_type(g, g->cur_fn)), |
| 2858 | g->cur_frame_ptr, frame_ret_start + 1, ""); |
| 2859 | LLVMValueRef awaiter_ret_ptr = LLVMBuildLoad2(g->builder, |
| 2860 | LLVMPointerTypeInContext(LLVMGetGlobalContext(), 0), awaiter_ret_ptr_ptr, ""); |
| 2816 | 2861 | LLVMValueRef zero_ptr = LLVMConstNull(LLVMTypeOf(awaiter_ret_ptr)); |
| 2817 | 2862 | LLVMValueRef need_copy_bit = LLVMBuildICmp(g->builder, LLVMIntNE, awaiter_ret_ptr, zero_ptr, ""); |
| 2818 | 2863 | LLVMBuildCondBr(g->builder, need_copy_bit, copy_block, copy_end_block); |
| ... | ... | @@ -2831,20 +2876,25 @@ static void gen_async_return(CodeGen *g, Stage1AirInstReturn *instruction) { |
| 2831 | 2876 | |
| 2832 | 2877 | LLVMPositionBuilderAtEnd(g->builder, copy_end_block); |
| 2833 | 2878 | if (codegen_fn_has_err_ret_tracing_arg(g, ret_type)) { |
| 2834 | | LLVMValueRef awaiter_trace_ptr_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, |
| 2835 | | frame_index_trace_arg(g, ret_type) + 1, ""); |
| 2836 | | LLVMValueRef dest_trace_ptr = LLVMBuildLoad(g->builder, awaiter_trace_ptr_ptr, ""); |
| 2879 | LLVMValueRef awaiter_trace_ptr_ptr = LLVMBuildStructGEP2(g->builder, |
| 2880 | get_llvm_type(g, get_fn_frame_type(g, g->cur_fn)), |
| 2881 | g->cur_frame_ptr, frame_index_trace_arg(g, ret_type) + 1, ""); |
| 2882 | LLVMValueRef dest_trace_ptr = LLVMBuildLoad2(g->builder, |
| 2883 | LLVMPointerTypeInContext(LLVMGetGlobalContext(), 0), |
| 2884 | awaiter_trace_ptr_ptr, ""); |
| 2837 | 2885 | bool is_llvm_alloca; |
| 2838 | 2886 | LLVMValueRef my_err_trace_val = get_cur_err_ret_trace_val(g, instruction->base.scope, &is_llvm_alloca); |
| 2839 | 2887 | LLVMValueRef args[] = { dest_trace_ptr, my_err_trace_val }; |
| 2840 | | ZigLLVMBuildCall(g->builder, get_merge_err_ret_traces_fn_val(g), args, 2, |
| 2888 | ZigLLVMBuildCall(g->builder, LLVMTypeOf(get_merge_err_ret_traces_fn_val(g)), |
| 2889 | get_merge_err_ret_traces_fn_val(g), args, 2, |
| 2841 | 2890 | get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_CallAttrAuto, ""); |
| 2842 | 2891 | } |
| 2843 | 2892 | } |
| 2844 | 2893 | |
| 2845 | 2894 | // Resume the caller by tail calling them. |
| 2846 | 2895 | ZigType *any_frame_type = get_any_frame_type(g, ret_type); |
| 2847 | | LLVMValueRef their_frame_ptr = LLVMBuildIntToPtr(g->builder, prev_val, get_llvm_type(g, any_frame_type), ""); |
| 2896 | LLVMValueRef their_frame_ptr = LLVMBuildIntToPtr(g->builder, prev_val, |
| 2897 | get_llvm_type(g, any_frame_type), ""); |
| 2848 | 2898 | LLVMValueRef call_inst = gen_resume(g, nullptr, their_frame_ptr, ResumeIdReturn); |
| 2849 | 2899 | set_tail_call_if_appropriate(g, call_inst); |
| 2850 | 2900 | LLVMBuildRetVoid(g->builder); |
| ... | ... | @@ -2853,21 +2903,14 @@ static void gen_async_return(CodeGen *g, Stage1AirInstReturn *instruction) { |
| 2853 | 2903 | static LLVMValueRef gen_convert_to_c_abi(CodeGen *g, LLVMValueRef location, LLVMValueRef value) { |
| 2854 | 2904 | ZigType *return_type = g->cur_fn->type_entry->data.fn.gen_return_type; |
| 2855 | 2905 | size_t size = type_size(g, return_type); |
| 2856 | | |
| 2857 | 2906 | LLVMTypeRef abi_return_type = get_llvm_c_abi_type(g, return_type); |
| 2858 | | LLVMTypeRef abi_return_type_pointer = LLVMPointerType(abi_return_type, 0); |
| 2859 | 2907 | |
| 2860 | 2908 | if (size < 8) { |
| 2861 | | LLVMValueRef bitcast = LLVMBuildBitCast(g->builder, value, abi_return_type_pointer, ""); |
| 2862 | | return LLVMBuildLoad(g->builder, bitcast, ""); |
| 2909 | return LLVMBuildLoad2(g->builder, abi_return_type, value, ""); |
| 2863 | 2910 | } else { |
| 2864 | | LLVMTypeRef i8ptr = LLVMPointerType(LLVMInt8Type(), 0); |
| 2865 | | LLVMValueRef bc_location = LLVMBuildBitCast(g->builder, location, i8ptr, ""); |
| 2866 | | LLVMValueRef bc_value = LLVMBuildBitCast(g->builder, value, i8ptr, ""); |
| 2867 | | |
| 2868 | 2911 | LLVMValueRef len = LLVMConstInt(LLVMInt64Type(), size, false); |
| 2869 | | ZigLLVMBuildMemCpy(g->builder, bc_location, 8, bc_value, return_type->abi_align, len, false); |
| 2870 | | return LLVMBuildLoad(g->builder, location, ""); |
| 2912 | ZigLLVMBuildMemCpy(g->builder, location, 8, value, return_type->abi_align, len, false); |
| 2913 | return LLVMBuildLoad2(g->builder, abi_return_type, location, ""); |
| 2871 | 2914 | } |
| 2872 | 2915 | } |
| 2873 | 2916 | |
| ... | ... | @@ -2903,19 +2946,21 @@ static LLVMValueRef ir_render_return(CodeGen *g, Stage1Air *executable, Stage1Ai |
| 2903 | 2946 | } else if (g->cur_fn->type_entry->data.fn.fn_type_id.cc != CallingConventionAsync && |
| 2904 | 2947 | handle_is_ptr(g, g->cur_fn->type_entry->data.fn.fn_type_id.return_type)) |
| 2905 | 2948 | { |
| 2949 | LLVMTypeRef ret_llvm_ty = get_llvm_type(g, g->cur_fn->type_entry->data.fn.fn_type_id.return_type); |
| 2906 | 2950 | if (instruction->operand == nullptr) { |
| 2907 | | LLVMValueRef by_val_value = gen_load_untyped(g, g->cur_ret_ptr, 0, false, ""); |
| 2951 | LLVMValueRef by_val_value = gen_load_untyped(g, ret_llvm_ty, g->cur_ret_ptr, 0, false, ""); |
| 2908 | 2952 | LLVMBuildRet(g->builder, by_val_value); |
| 2909 | 2953 | } else { |
| 2910 | 2954 | LLVMValueRef value = ir_llvm_value(g, instruction->operand); |
| 2911 | | LLVMValueRef by_val_value = gen_load_untyped(g, value, 0, false, ""); |
| 2955 | LLVMValueRef by_val_value = gen_load_untyped(g, ret_llvm_ty, value, 0, false, ""); |
| 2912 | 2956 | LLVMBuildRet(g->builder, by_val_value); |
| 2913 | 2957 | } |
| 2914 | 2958 | } else if (instruction->operand == nullptr) { |
| 2915 | 2959 | if (g->cur_ret_ptr == nullptr) { |
| 2916 | 2960 | LLVMBuildRetVoid(g->builder); |
| 2917 | 2961 | } else { |
| 2918 | | LLVMValueRef by_val_value = gen_load_untyped(g, g->cur_ret_ptr, 0, false, ""); |
| 2962 | LLVMTypeRef ret_llvm_ty = get_llvm_type(g, g->cur_fn->type_entry->data.fn.fn_type_id.return_type); |
| 2963 | LLVMValueRef by_val_value = gen_load_untyped(g, ret_llvm_ty, g->cur_ret_ptr, 0, false, ""); |
| 2919 | 2964 | LLVMBuildRet(g->builder, by_val_value); |
| 2920 | 2965 | } |
| 2921 | 2966 | } else { |
| ... | ... | @@ -3011,20 +3056,18 @@ static LLVMValueRef gen_soft_float_un_op(CodeGen *g, LLVMValueRef op, ZigType *o |
| 3011 | 3056 | float_un_op_to_name(op_id), libc_float_suffix(g, scalar_type)); |
| 3012 | 3057 | LLVMValueRef func_ref = get_soft_float_fn(g, fn_name, 1, scalar_type->llvm_type, scalar_type->llvm_type); |
| 3013 | 3058 | |
| 3014 | | LLVMValueRef result; |
| 3015 | 3059 | if (vector_len == 0) { |
| 3016 | | return LLVMBuildCall(g->builder, func_ref, &op, 1, ""); |
| 3060 | return LLVMBuildCall2(g->builder, LLVMTypeOf(func_ref), func_ref, &op, 1, ""); |
| 3017 | 3061 | } else { |
| 3018 | | result = build_alloca(g, operand_type, "", 0); |
| 3062 | LLVMValueRef result = LLVMGetUndef(operand_type->llvm_type); |
| 3019 | 3063 | LLVMTypeRef usize_ref = g->builtin_types.entry_usize->llvm_type; |
| 3020 | 3064 | for (uint32_t i = 0; i < vector_len; i++) { |
| 3021 | 3065 | LLVMValueRef index_value = LLVMConstInt(usize_ref, i, false); |
| 3022 | 3066 | LLVMValueRef param = LLVMBuildExtractElement(g->builder, op, index_value, ""); |
| 3023 | | LLVMValueRef call_result = LLVMBuildCall(g->builder, func_ref, &param, 1, ""); |
| 3024 | | LLVMBuildInsertElement(g->builder, LLVMBuildLoad(g->builder, result, ""), |
| 3025 | | call_result, index_value, ""); |
| 3067 | LLVMValueRef call_result = LLVMBuildCall2(g->builder, LLVMTypeOf(func_ref), func_ref, &param, 1, ""); |
| 3068 | result = LLVMBuildInsertElement(g->builder, result, call_result, index_value, ""); |
| 3026 | 3069 | } |
| 3027 | | return LLVMBuildLoad(g->builder, result, ""); |
| 3070 | return result; |
| 3028 | 3071 | } |
| 3029 | 3072 | } |
| 3030 | 3073 | |
| ... | ... | @@ -3038,7 +3081,7 @@ static LLVMValueRef gen_float_un_op(CodeGen *g, LLVMValueRef operand, ZigType *o |
| 3038 | 3081 | return gen_soft_float_un_op(g, operand, operand_type, op); |
| 3039 | 3082 | } |
| 3040 | 3083 | LLVMValueRef float_op_fn = get_float_fn(g, operand_type, ZigLLVMFnIdFloatOp, op); |
| 3041 | | return LLVMBuildCall(g->builder, float_op_fn, &operand, 1, ""); |
| 3084 | return LLVMBuildCall2(g->builder, LLVMTypeOf(float_op_fn), float_op_fn, &operand, 1, ""); |
| 3042 | 3085 | } |
| 3043 | 3086 | |
| 3044 | 3087 | enum DivKind { |
| ... | ... | @@ -3404,7 +3447,7 @@ static LLVMValueRef gen_soft_int_to_float_op(CodeGen *g, LLVMValueRef value_ref, |
| 3404 | 3447 | } |
| 3405 | 3448 | |
| 3406 | 3449 | LLVMValueRef params[1] = {value_ref}; |
| 3407 | | return LLVMBuildCall(g->builder, func_ref, params, param_count, ""); |
| 3450 | return LLVMBuildCall2(g->builder, LLVMTypeOf(func_ref), func_ref, params, param_count, ""); |
| 3408 | 3451 | } |
| 3409 | 3452 | |
| 3410 | 3453 | static LLVMValueRef gen_soft_float_to_int_op(CodeGen *g, LLVMValueRef value_ref, ZigType *operand_type, ZigType *result_type) { |
| ... | ... | @@ -3440,7 +3483,7 @@ static LLVMValueRef gen_soft_float_to_int_op(CodeGen *g, LLVMValueRef value_ref, |
| 3440 | 3483 | } |
| 3441 | 3484 | |
| 3442 | 3485 | LLVMValueRef params[1] = {value_ref}; |
| 3443 | | LLVMValueRef result = LLVMBuildCall(g->builder, func_ref, params, param_count, ""); |
| 3486 | LLVMValueRef result = LLVMBuildCall2(g->builder, LLVMTypeOf(func_ref), func_ref, params, param_count, ""); |
| 3444 | 3487 | |
| 3445 | 3488 | if ((wider_type->data.integral.bit_count == 128) && (g->zig_target->os == OsWindows) && (g->zig_target->arch == ZigLLVM_x86_64)) { |
| 3446 | 3489 | result = LLVMBuildBitCast(g->builder, result, wider_type->llvm_type, ""); |
| ... | ... | @@ -3553,12 +3596,12 @@ static LLVMValueRef gen_soft_float_bin_op(CodeGen *g, LLVMValueRef op1_value, LL |
| 3553 | 3596 | LLVMValueRef result; |
| 3554 | 3597 | if (vector_len == 0) { |
| 3555 | 3598 | LLVMValueRef params[2] = {op1_value, op2_value}; |
| 3556 | | result = LLVMBuildCall(g->builder, func_ref, params, param_count, ""); |
| 3599 | result = LLVMBuildCall2(g->builder, LLVMTypeOf(func_ref), func_ref, params, param_count, ""); |
| 3557 | 3600 | result = add_icmp(g, result, res_icmp); |
| 3558 | 3601 | } else { |
| 3559 | 3602 | ZigType *alloca_ty = operand_type; |
| 3560 | 3603 | if (res_icmp != NONE) alloca_ty = get_vector_type(g, vector_len, g->builtin_types.entry_bool); |
| 3561 | | result = build_alloca(g, alloca_ty, "", 0); |
| 3604 | result = LLVMGetUndef(alloca_ty->llvm_type); |
| 3562 | 3605 | |
| 3563 | 3606 | LLVMTypeRef usize_ref = g->builtin_types.entry_usize->llvm_type; |
| 3564 | 3607 | for (uint32_t i = 0; i < vector_len; i++) { |
| ... | ... | @@ -3567,13 +3610,10 @@ static LLVMValueRef gen_soft_float_bin_op(CodeGen *g, LLVMValueRef op1_value, LL |
| 3567 | 3610 | LLVMBuildExtractElement(g->builder, op1_value, index_value, ""), |
| 3568 | 3611 | LLVMBuildExtractElement(g->builder, op2_value, index_value, ""), |
| 3569 | 3612 | }; |
| 3570 | | LLVMValueRef call_result = LLVMBuildCall(g->builder, func_ref, params, param_count, ""); |
| 3613 | LLVMValueRef call_result = LLVMBuildCall2(g->builder, LLVMTypeOf(func_ref), func_ref, params, param_count, ""); |
| 3571 | 3614 | call_result = add_icmp(g, call_result, res_icmp); |
| 3572 | | LLVMBuildInsertElement(g->builder, LLVMBuildLoad(g->builder, result, ""), |
| 3573 | | call_result, index_value, ""); |
| 3615 | result = LLVMBuildInsertElement(g->builder, result, call_result, index_value, ""); |
| 3574 | 3616 | } |
| 3575 | | |
| 3576 | | result = LLVMBuildLoad(g->builder, result, ""); |
| 3577 | 3617 | } |
| 3578 | 3618 | |
| 3579 | 3619 | // Some operations are implemented as compound ops and require us to perform some |
| ... | ... | @@ -3703,7 +3743,9 @@ static LLVMValueRef ir_render_bin_op(CodeGen *g, Stage1Air *executable, |
| 3703 | 3743 | } |
| 3704 | 3744 | |
| 3705 | 3745 | // TODO runtime safety |
| 3706 | | return LLVMBuildInBoundsGEP(g->builder, op1_value, &subscript_value, 1, ""); |
| 3746 | LLVMTypeRef elem_llvm_ty = get_llvm_type(g, scalar_type->data.pointer.child_type); |
| 3747 | return LLVMBuildInBoundsGEP2(g->builder, elem_llvm_ty, op1_value, |
| 3748 | &subscript_value, 1, ""); |
| 3707 | 3749 | } else if (scalar_type->id == ZigTypeIdFloat) { |
| 3708 | 3750 | ZigLLVMSetFastMath(g->builder, ir_want_fast_math(g, &bin_op_instruction->base)); |
| 3709 | 3751 | return float_op[add_sub_mul](g->builder, op1_value, op2_value, ""); |
| ... | ... | @@ -4044,20 +4086,23 @@ static LLVMValueRef ir_render_ptr_of_array_to_slice(CodeGen *g, Stage1Air *execu |
| 4044 | 4086 | assert(array_type->id == ZigTypeIdArray); |
| 4045 | 4087 | |
| 4046 | 4088 | if (type_has_bits(g, actual_type)) { |
| 4047 | | LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, result_loc, ptr_index, ""); |
| 4089 | LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP2(g->builder, get_llvm_type(g, slice_type), |
| 4090 | result_loc, ptr_index, ""); |
| 4048 | 4091 | LLVMValueRef indices[] = { |
| 4049 | 4092 | LLVMConstNull(g->builtin_types.entry_usize->llvm_type), |
| 4050 | 4093 | LLVMConstInt(g->builtin_types.entry_usize->llvm_type, 0, false), |
| 4051 | 4094 | }; |
| 4052 | 4095 | LLVMValueRef expr_val = ir_llvm_value(g, instruction->operand); |
| 4053 | | LLVMValueRef slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, expr_val, indices, 2, ""); |
| 4096 | LLVMTypeRef elem_llvm_ty = get_llvm_type(g, array_type->data.array.child_type); |
| 4097 | LLVMValueRef slice_start_ptr = LLVMBuildInBoundsGEP2(g->builder, elem_llvm_ty, expr_val, |
| 4098 | indices, 2, ""); |
| 4054 | 4099 | gen_store_untyped(g, slice_start_ptr, ptr_field_ptr, 0, false); |
| 4055 | 4100 | } else if (ir_want_runtime_safety(g, &instruction->base) && ptr_index != SIZE_MAX) { |
| 4056 | | LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, result_loc, ptr_index, ""); |
| 4101 | LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP2(g->builder, get_llvm_type(g, slice_type), result_loc, ptr_index, ""); |
| 4057 | 4102 | gen_undef_init(g, slice_ptr_type, slice_ptr_type, ptr_field_ptr); |
| 4058 | 4103 | } |
| 4059 | 4104 | |
| 4060 | | LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, result_loc, len_index, ""); |
| 4105 | LLVMValueRef len_field_ptr = LLVMBuildStructGEP2(g->builder, get_llvm_type(g, slice_type), result_loc, len_index, ""); |
| 4061 | 4106 | LLVMValueRef len_value = LLVMConstInt(g->builtin_types.entry_usize->llvm_type, |
| 4062 | 4107 | array_type->data.array.len, false); |
| 4063 | 4108 | gen_store_untyped(g, len_value, len_field_ptr, 0, false); |
| ... | ... | @@ -4102,20 +4147,20 @@ static LLVMValueRef ir_render_bit_cast(CodeGen *g, Stage1Air *executable, |
| 4102 | 4147 | bool actual_is_ptr = handle_is_ptr(g, actual_type); |
| 4103 | 4148 | if (wanted_is_ptr == actual_is_ptr) { |
| 4104 | 4149 | // We either bitcast the value directly or bitcast the pointer which does a pointer cast |
| 4105 | | LLVMTypeRef wanted_type_ref = wanted_is_ptr ? |
| 4106 | | LLVMPointerType(get_llvm_type(g, wanted_type), 0) : get_llvm_type(g, wanted_type); |
| 4107 | | return LLVMBuildBitCast(g->builder, value, wanted_type_ref, ""); |
| 4150 | if (wanted_is_ptr) { |
| 4151 | return value; |
| 4152 | } else { |
| 4153 | LLVMTypeRef wanted_type_ref = get_llvm_type(g, wanted_type); |
| 4154 | return LLVMBuildBitCast(g->builder, value, wanted_type_ref, ""); |
| 4155 | } |
| 4108 | 4156 | } else if (actual_is_ptr) { |
| 4109 | 4157 | // A scalar is wanted but we got a pointer |
| 4110 | | LLVMTypeRef wanted_ptr_type_ref = LLVMPointerType(get_llvm_type(g, wanted_type), 0); |
| 4111 | | LLVMValueRef bitcasted_ptr = LLVMBuildBitCast(g->builder, value, wanted_ptr_type_ref, ""); |
| 4112 | 4158 | uint32_t alignment = get_abi_alignment(g, actual_type); |
| 4113 | | return gen_load_untyped(g, bitcasted_ptr, alignment, false, ""); |
| 4159 | return gen_load_untyped(g, get_llvm_type(g, wanted_type), value, alignment, false, ""); |
| 4114 | 4160 | } else { |
| 4115 | 4161 | // A pointer is wanted but we got a scalar |
| 4116 | 4162 | assert(actual_type->id == ZigTypeIdPointer); |
| 4117 | | LLVMTypeRef wanted_ptr_type_ref = LLVMPointerType(get_llvm_type(g, wanted_type), 0); |
| 4118 | | return LLVMBuildBitCast(g->builder, value, wanted_ptr_type_ref, ""); |
| 4163 | return value; |
| 4119 | 4164 | } |
| 4120 | 4165 | } |
| 4121 | 4166 | |
| ... | ... | @@ -4298,32 +4343,26 @@ static LLVMValueRef ir_render_binary_not(CodeGen *g, Stage1Air *executable, |
| 4298 | 4343 | |
| 4299 | 4344 | static LLVMValueRef gen_soft_float_neg(CodeGen *g, ZigType *operand_type, LLVMValueRef operand) { |
| 4300 | 4345 | uint32_t vector_len = operand_type->id == ZigTypeIdVector ? operand_type->data.vector.len : 0; |
| 4301 | | uint16_t num_bits = operand_type->data.floating.bit_count; |
| 4346 | uint16_t num_bits = operand_type->id == ZigTypeIdVector ? |
| 4347 | operand_type->data.vector.elem_type->data.floating.bit_count : |
| 4348 | operand_type->data.floating.bit_count; |
| 4302 | 4349 | |
| 4303 | 4350 | ZigType *iX_type = get_int_type(g, true, num_bits); |
| 4304 | | LLVMValueRef sign_mask = LLVMConstInt(iX_type->llvm_type, 1, false); |
| 4305 | | sign_mask = LLVMConstShl(sign_mask, LLVMConstInt(iX_type->llvm_type, num_bits - 1, false)); |
| 4351 | LLVMValueRef sign_mask = LLVMConstShl( |
| 4352 | LLVMConstInt(iX_type->llvm_type, 1, false), |
| 4353 | LLVMConstInt(iX_type->llvm_type, num_bits - 1, false)); |
| 4306 | 4354 | |
| 4307 | | if (vector_len == 0) { |
| 4308 | | LLVMValueRef bitcasted_operand = LLVMBuildBitCast(g->builder, operand, iX_type->llvm_type, ""); |
| 4309 | | LLVMValueRef result = LLVMBuildXor(g->builder, bitcasted_operand, sign_mask, ""); |
| 4355 | LLVMValueRef sign_mask_splat = (vector_len == 0) ? sign_mask : |
| 4356 | LLVMBuildVectorSplat(g->builder, vector_len, sign_mask, ""); |
| 4310 | 4357 | |
| 4311 | | return LLVMBuildBitCast(g->builder, result, operand_type->llvm_type, ""); |
| 4312 | | } else { |
| 4313 | | LLVMTypeRef usize_ref = g->builtin_types.entry_usize->llvm_type; |
| 4314 | | ZigType *iX_vector_type = get_vector_type(g, vector_len, iX_type); |
| 4358 | LLVMValueRef bitcasted_operand = LLVMBuildBitCast(g->builder, operand, |
| 4359 | (vector_len == 0) ? |
| 4360 | iX_type->llvm_type : |
| 4361 | get_vector_type(g, vector_len, iX_type)->llvm_type, |
| 4362 | ""); |
| 4315 | 4363 | |
| 4316 | | LLVMValueRef result = build_alloca(g, iX_vector_type, "", 0); |
| 4317 | | LLVMValueRef bitcasted_operand = LLVMBuildBitCast(g->builder, operand, iX_vector_type->llvm_type, ""); |
| 4318 | | for (uint32_t i = 0; i < vector_len; i++) { |
| 4319 | | LLVMValueRef index_value = LLVMConstInt(usize_ref, i, false); |
| 4320 | | LLVMValueRef elem = LLVMBuildExtractElement(g->builder, bitcasted_operand, index_value, ""); |
| 4321 | | LLVMValueRef result_elem = LLVMBuildXor(g->builder, elem, sign_mask, ""); |
| 4322 | | LLVMBuildInsertElement(g->builder, LLVMBuildLoad(g->builder, result, ""), |
| 4323 | | result_elem, index_value, ""); |
| 4324 | | } |
| 4325 | | return LLVMBuildBitCast(g->builder, LLVMBuildLoad(g->builder, result, ""), operand_type->llvm_type, ""); |
| 4326 | | } |
| 4364 | LLVMValueRef result = LLVMBuildXor(g->builder, bitcasted_operand, sign_mask_splat, ""); |
| 4365 | return LLVMBuildBitCast(g->builder, result, operand_type->llvm_type, ""); |
| 4327 | 4366 | } |
| 4328 | 4367 | |
| 4329 | 4368 | static LLVMValueRef gen_negation(CodeGen *g, Stage1AirInst *inst, Stage1AirInst *operand, bool wrapping) { |
| ... | ... | @@ -4398,7 +4437,7 @@ static LLVMValueRef ir_render_load_ptr(CodeGen *g, Stage1Air *executable, |
| 4398 | 4437 | if (ptr_type->data.pointer.vector_index != VECTOR_INDEX_NONE) { |
| 4399 | 4438 | LLVMValueRef index_val = LLVMConstInt(LLVMInt32Type(), |
| 4400 | 4439 | ptr_type->data.pointer.vector_index, false); |
| 4401 | | LLVMValueRef loaded_vector = LLVMBuildLoad(g->builder, ptr, ""); |
| 4440 | LLVMValueRef loaded_vector = LLVMBuildLoad2(g->builder, get_llvm_type(g, child_type), ptr, ""); |
| 4402 | 4441 | return LLVMBuildExtractElement(g->builder, loaded_vector, index_val, ""); |
| 4403 | 4442 | } |
| 4404 | 4443 | |
| ... | ... | @@ -4524,7 +4563,8 @@ static LLVMValueRef gen_valgrind_client_request(CodeGen *g, LLVMValueRef default |
| 4524 | 4563 | zero, |
| 4525 | 4564 | LLVMConstInt(usize_type_ref, i, false), |
| 4526 | 4565 | }; |
| 4527 | | LLVMValueRef elem_ptr = LLVMBuildInBoundsGEP(g->builder, array_ptr, indexes, 2, ""); |
| 4566 | LLVMValueRef elem_ptr = LLVMBuildInBoundsGEP2(g->builder, usize_type_ref, |
| 4567 | array_ptr, indexes, 2, ""); |
| 4528 | 4568 | LLVMBuildStore(g->builder, array_elements[i], elem_ptr); |
| 4529 | 4569 | } |
| 4530 | 4570 | |
| ... | ... | @@ -4545,7 +4585,7 @@ static LLVMValueRef gen_valgrind_client_request(CodeGen *g, LLVMValueRef default |
| 4545 | 4585 | LLVMValueRef asm_fn = LLVMGetInlineAsm(function_type, buf_ptr(asm_template), buf_len(asm_template), |
| 4546 | 4586 | buf_ptr(asm_constraints), buf_len(asm_constraints), asm_has_side_effects, asm_is_alignstack, |
| 4547 | 4587 | LLVMInlineAsmDialectATT, false); |
| 4548 | | return LLVMBuildCall(g->builder, asm_fn, param_values, input_and_output_count, ""); |
| 4588 | return LLVMBuildCall2(g->builder, LLVMTypeOf(asm_fn), asm_fn, param_values, input_and_output_count, ""); |
| 4549 | 4589 | } |
| 4550 | 4590 | } |
| 4551 | 4591 | zig_unreachable(); |
| ... | ... | @@ -4713,16 +4753,13 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, Stage1Air *executable, Stage1 |
| 4713 | 4753 | size_t host_int_bytes = ptr_type->data.pointer.host_int_bytes; |
| 4714 | 4754 | if (host_int_bytes != 0) { |
| 4715 | 4755 | uint32_t size_in_bits = type_size_bits(g, ptr_type->data.pointer.child_type); |
| 4716 | | LLVMTypeRef ptr_u8_type_ref = LLVMPointerType(LLVMInt8Type(), 0); |
| 4717 | | LLVMValueRef u8_array_ptr = LLVMBuildBitCast(g->builder, array_ptr, ptr_u8_type_ref, ""); |
| 4718 | 4756 | assert(size_in_bits % 8 == 0); |
| 4719 | 4757 | LLVMValueRef elem_size_bytes = LLVMConstInt(g->builtin_types.entry_usize->llvm_type, |
| 4720 | 4758 | size_in_bits / 8, false); |
| 4721 | 4759 | LLVMValueRef byte_offset = LLVMBuildNUWMul(g->builder, subscript_value, elem_size_bytes, ""); |
| 4722 | | LLVMValueRef indices[] = { |
| 4723 | | byte_offset |
| 4724 | | }; |
| 4725 | | LLVMValueRef elem_byte_ptr = LLVMBuildInBoundsGEP(g->builder, u8_array_ptr, indices, 1, ""); |
| 4760 | LLVMValueRef indices[] = { byte_offset }; |
| 4761 | LLVMValueRef elem_byte_ptr = LLVMBuildInBoundsGEP2(g->builder, LLVMInt8Type(), |
| 4762 | array_ptr, indices, 1, ""); |
| 4726 | 4763 | return LLVMBuildBitCast(g->builder, elem_byte_ptr, LLVMPointerType(get_llvm_type(g, child_type), 0), ""); |
| 4727 | 4764 | } |
| 4728 | 4765 | } |
| ... | ... | @@ -4730,14 +4767,14 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, Stage1Air *executable, Stage1 |
| 4730 | 4767 | LLVMConstNull(g->builtin_types.entry_usize->llvm_type), |
| 4731 | 4768 | subscript_value |
| 4732 | 4769 | }; |
| 4733 | | return LLVMBuildInBoundsGEP(g->builder, array_ptr, indices, 2, ""); |
| 4770 | return LLVMBuildInBoundsGEP2(g->builder, get_llvm_type(g, child_type), array_ptr, |
| 4771 | indices, 2, ""); |
| 4734 | 4772 | } else if (array_type->id == ZigTypeIdPointer) { |
| 4735 | 4773 | LLVMValueRef array_ptr = get_handle_value(g, array_ptr_ptr, array_type, array_ptr_type); |
| 4736 | 4774 | assert(LLVMGetTypeKind(LLVMTypeOf(array_ptr)) == LLVMPointerTypeKind); |
| 4737 | | LLVMValueRef indices[] = { |
| 4738 | | subscript_value |
| 4739 | | }; |
| 4740 | | return LLVMBuildInBoundsGEP(g->builder, array_ptr, indices, 1, ""); |
| 4775 | LLVMValueRef indices[] = { subscript_value }; |
| 4776 | LLVMTypeRef elem_llvm_ty = get_llvm_type(g, array_type->data.pointer.child_type); |
| 4777 | return LLVMBuildInBoundsGEP2(g->builder, elem_llvm_ty, array_ptr, indices, 1, ""); |
| 4741 | 4778 | } else if (array_type->id == ZigTypeIdStruct) { |
| 4742 | 4779 | LLVMValueRef array_ptr = get_handle_value(g, array_ptr_ptr, array_type, array_ptr_type); |
| 4743 | 4780 | assert(array_type->data.structure.special == StructSpecialSlice); |
| ... | ... | @@ -4752,22 +4789,26 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, Stage1Air *executable, Stage1 |
| 4752 | 4789 | } |
| 4753 | 4790 | |
| 4754 | 4791 | assert(LLVMGetTypeKind(LLVMTypeOf(array_ptr)) == LLVMPointerTypeKind); |
| 4755 | | assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(array_ptr))) == LLVMStructTypeKind); |
| 4756 | 4792 | |
| 4757 | 4793 | if (safety_check_on) { |
| 4758 | 4794 | size_t len_index = array_type->data.structure.fields[slice_len_index]->gen_index; |
| 4759 | 4795 | assert(len_index != SIZE_MAX); |
| 4760 | | LLVMValueRef len_ptr = LLVMBuildStructGEP(g->builder, array_ptr, (unsigned)len_index, ""); |
| 4761 | | LLVMValueRef len = gen_load_untyped(g, len_ptr, 0, false, ""); |
| 4796 | LLVMValueRef len_ptr = LLVMBuildStructGEP2(g->builder, get_llvm_type(g, array_type), |
| 4797 | array_ptr, (unsigned)len_index, ""); |
| 4798 | LLVMValueRef len = gen_load_untyped(g, LLVMGetGEPSourceElementType(len_ptr), len_ptr, |
| 4799 | 0, false, ""); |
| 4762 | 4800 | LLVMIntPredicate upper_op = (ptr_type->data.pointer.sentinel != nullptr) ? LLVMIntULE : LLVMIntULT; |
| 4763 | 4801 | add_bounds_check(g, subscript_value, LLVMIntEQ, nullptr, upper_op, len); |
| 4764 | 4802 | } |
| 4765 | 4803 | |
| 4766 | 4804 | size_t ptr_index = array_type->data.structure.fields[slice_ptr_index]->gen_index; |
| 4767 | 4805 | assert(ptr_index != SIZE_MAX); |
| 4768 | | LLVMValueRef ptr_ptr = LLVMBuildStructGEP(g->builder, array_ptr, (unsigned)ptr_index, ""); |
| 4769 | | LLVMValueRef ptr = gen_load_untyped(g, ptr_ptr, 0, false, ""); |
| 4770 | | return LLVMBuildInBoundsGEP(g->builder, ptr, &subscript_value, 1, ""); |
| 4806 | LLVMValueRef ptr_ptr = LLVMBuildStructGEP2(g->builder, get_llvm_type(g, array_type), |
| 4807 | array_ptr, (unsigned)ptr_index, ""); |
| 4808 | LLVMValueRef ptr = gen_load_untyped(g, LLVMGetGEPSourceElementType(ptr_ptr), ptr_ptr, 0, |
| 4809 | false, ""); |
| 4810 | LLVMTypeRef elem_llvm_ty = get_llvm_type(g, ptr_type->data.pointer.child_type); |
| 4811 | return LLVMBuildInBoundsGEP2(g->builder, elem_llvm_ty, ptr, &subscript_value, 1, ""); |
| 4771 | 4812 | } else if (array_type->id == ZigTypeIdVector) { |
| 4772 | 4813 | return array_ptr_ptr; |
| 4773 | 4814 | } else { |
| ... | ... | @@ -4775,12 +4816,16 @@ static LLVMValueRef ir_render_elem_ptr(CodeGen *g, Stage1Air *executable, Stage1 |
| 4775 | 4816 | } |
| 4776 | 4817 | } |
| 4777 | 4818 | |
| 4778 | | static LLVMValueRef get_new_stack_addr(CodeGen *g, LLVMValueRef new_stack) { |
| 4779 | | LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, new_stack, (unsigned)slice_ptr_index, ""); |
| 4780 | | LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, new_stack, (unsigned)slice_len_index, ""); |
| 4819 | static LLVMValueRef get_new_stack_addr(CodeGen *g, LLVMTypeRef new_stack_llvm_ty, |
| 4820 | LLVMValueRef new_stack) |
| 4821 | { |
| 4822 | LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP2(g->builder, new_stack_llvm_ty, new_stack, (unsigned)slice_ptr_index, ""); |
| 4823 | LLVMValueRef len_field_ptr = LLVMBuildStructGEP2(g->builder, new_stack_llvm_ty, new_stack, (unsigned)slice_len_index, ""); |
| 4781 | 4824 | |
| 4782 | | LLVMValueRef ptr_value = gen_load_untyped(g, ptr_field_ptr, 0, false, ""); |
| 4783 | | LLVMValueRef len_value = gen_load_untyped(g, len_field_ptr, 0, false, ""); |
| 4825 | LLVMValueRef ptr_value = gen_load_untyped(g, LLVMGetGEPSourceElementType(ptr_field_ptr), |
| 4826 | ptr_field_ptr, 0, false, ""); |
| 4827 | LLVMValueRef len_value = gen_load_untyped(g, LLVMGetGEPSourceElementType(len_field_ptr), |
| 4828 | len_field_ptr, 0, false, ""); |
| 4784 | 4829 | |
| 4785 | 4830 | LLVMValueRef ptr_addr = LLVMBuildPtrToInt(g->builder, ptr_value, LLVMTypeOf(len_value), ""); |
| 4786 | 4831 | LLVMValueRef end_addr = LLVMBuildNUWAdd(g->builder, ptr_addr, len_value, ""); |
| ... | ... | @@ -4804,7 +4849,7 @@ static void gen_set_stack_pointer(CodeGen *g, LLVMValueRef aligned_end_addr) { |
| 4804 | 4849 | aligned_end_addr, |
| 4805 | 4850 | }; |
| 4806 | 4851 | |
| 4807 | | LLVMBuildCall(g->builder, write_register_fn_val, params, 2, ""); |
| 4852 | LLVMBuildCall2(g->builder, LLVMTypeOf(write_register_fn_val), write_register_fn_val, params, 2, ""); |
| 4808 | 4853 | } |
| 4809 | 4854 | |
| 4810 | 4855 | static void render_async_spills(CodeGen *g) { |
| ... | ... | @@ -4834,7 +4879,9 @@ static void render_async_spills(CodeGen *g) { |
| 4834 | 4879 | } |
| 4835 | 4880 | |
| 4836 | 4881 | calc_llvm_field_index_add(g, &arg_calc, var->var_type); |
| 4837 | | var->value_ref = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, arg_calc.field_index - 1, var->name); |
| 4882 | var->value_ref = LLVMBuildStructGEP2(g->builder, |
| 4883 | get_llvm_type(g, get_fn_frame_type(g, g->cur_fn)), |
| 4884 | g->cur_frame_ptr, arg_calc.field_index - 1, var->name); |
| 4838 | 4885 | if (var->decl_node) { |
| 4839 | 4886 | var->di_loc_var = ZigLLVMCreateAutoVariable(g->dbuilder, get_di_scope(g, var->parent_scope), |
| 4840 | 4887 | var->name, import->data.structure.root_struct->di_file, |
| ... | ... | @@ -4852,7 +4899,9 @@ static void render_async_spills(CodeGen *g) { |
| 4852 | 4899 | continue; |
| 4853 | 4900 | |
| 4854 | 4901 | size_t gen_index = frame_type->data.structure.fields[instruction->field_index]->gen_index; |
| 4855 | | instruction->base.llvm_value = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, gen_index, |
| 4902 | instruction->base.llvm_value = LLVMBuildStructGEP2(g->builder, |
| 4903 | get_llvm_type(g, get_fn_frame_type(g, g->cur_fn)), |
| 4904 | g->cur_frame_ptr, gen_index, |
| 4856 | 4905 | instruction->name_hint); |
| 4857 | 4906 | } |
| 4858 | 4907 | } |
| ... | ... | @@ -4892,11 +4941,9 @@ static void render_async_var_decls(CodeGen *g, Scope *scope) { |
| 4892 | 4941 | static LLVMValueRef gen_frame_size(CodeGen *g, LLVMValueRef fn_val) { |
| 4893 | 4942 | assert(g->need_frame_size_prefix_data); |
| 4894 | 4943 | LLVMTypeRef usize_llvm_type = g->builtin_types.entry_usize->llvm_type; |
| 4895 | | LLVMTypeRef ptr_usize_llvm_type = LLVMPointerType(usize_llvm_type, 0); |
| 4896 | | LLVMValueRef casted_fn_val = LLVMBuildBitCast(g->builder, fn_val, ptr_usize_llvm_type, ""); |
| 4897 | 4944 | LLVMValueRef negative_one = LLVMConstInt(LLVMInt32Type(), -1, true); |
| 4898 | | LLVMValueRef prefix_ptr = LLVMBuildInBoundsGEP(g->builder, casted_fn_val, &negative_one, 1, ""); |
| 4899 | | LLVMValueRef load_inst = LLVMBuildLoad(g->builder, prefix_ptr, ""); |
| 4945 | LLVMValueRef prefix_ptr = LLVMBuildInBoundsGEP2(g->builder, usize_llvm_type, fn_val, &negative_one, 1, ""); |
| 4946 | LLVMValueRef load_inst = LLVMBuildLoad2(g->builder, usize_llvm_type, prefix_ptr, ""); |
| 4900 | 4947 | |
| 4901 | 4948 | // Some architectures (e.g SPARCv9) has different alignment requirements between a |
| 4902 | 4949 | // function/usize pointer and also require all loads to be aligned. |
| ... | ... | @@ -4910,17 +4957,23 @@ static LLVMValueRef gen_frame_size(CodeGen *g, LLVMValueRef fn_val) { |
| 4910 | 4957 | static void gen_init_stack_trace(CodeGen *g, LLVMValueRef trace_field_ptr, LLVMValueRef addrs_field_ptr) { |
| 4911 | 4958 | LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type; |
| 4912 | 4959 | LLVMValueRef zero = LLVMConstNull(usize_type_ref); |
| 4960 | LLVMTypeRef stack_trace_llvm_ty = get_llvm_type(g, get_stack_trace_type(g)); |
| 4913 | 4961 | |
| 4914 | | LLVMValueRef index_ptr = LLVMBuildStructGEP(g->builder, trace_field_ptr, 0, ""); |
| 4962 | LLVMValueRef index_ptr = LLVMBuildStructGEP2(g->builder, stack_trace_llvm_ty, trace_field_ptr, 0, ""); |
| 4915 | 4963 | LLVMBuildStore(g->builder, zero, index_ptr); |
| 4916 | 4964 | |
| 4917 | | LLVMValueRef addrs_slice_ptr = LLVMBuildStructGEP(g->builder, trace_field_ptr, 1, ""); |
| 4918 | | LLVMValueRef addrs_ptr_ptr = LLVMBuildStructGEP(g->builder, addrs_slice_ptr, slice_ptr_index, ""); |
| 4965 | LLVMValueRef addrs_slice_ptr = LLVMBuildStructGEP2(g->builder, stack_trace_llvm_ty, trace_field_ptr, 1, ""); |
| 4966 | LLVMValueRef addrs_ptr_ptr = LLVMBuildStructGEP2(g->builder, |
| 4967 | LLVMGetGEPSourceElementType(addrs_slice_ptr), |
| 4968 | addrs_slice_ptr, slice_ptr_index, ""); |
| 4919 | 4969 | LLVMValueRef indices[] = { LLVMConstNull(usize_type_ref), LLVMConstNull(usize_type_ref) }; |
| 4920 | | LLVMValueRef trace_field_addrs_as_ptr = LLVMBuildInBoundsGEP(g->builder, addrs_field_ptr, indices, 2, ""); |
| 4970 | LLVMValueRef trace_field_addrs_as_ptr = LLVMBuildInBoundsGEP2(g->builder, |
| 4971 | usize_type_ref, addrs_field_ptr, indices, 2, ""); |
| 4921 | 4972 | LLVMBuildStore(g->builder, trace_field_addrs_as_ptr, addrs_ptr_ptr); |
| 4922 | 4973 | |
| 4923 | | LLVMValueRef addrs_len_ptr = LLVMBuildStructGEP(g->builder, addrs_slice_ptr, slice_len_index, ""); |
| 4974 | LLVMValueRef addrs_len_ptr = LLVMBuildStructGEP2(g->builder, |
| 4975 | LLVMGetGEPSourceElementType(addrs_slice_ptr), |
| 4976 | addrs_slice_ptr, slice_len_index, ""); |
| 4924 | 4977 | LLVMBuildStore(g->builder, LLVMConstInt(usize_type_ref, stack_trace_ptr_count, false), addrs_len_ptr); |
| 4925 | 4978 | } |
| 4926 | 4979 | |
| ... | ... | @@ -4943,6 +4996,10 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI |
| 4943 | 4996 | callee_is_async = fn_type->data.fn.fn_type_id.cc == CallingConventionAsync; |
| 4944 | 4997 | } |
| 4945 | 4998 | |
| 4999 | LLVMTypeRef frame_struct_llvm_ty = (instruction->fn_entry != nullptr) ? |
| 5000 | get_llvm_type(g, get_fn_frame_type(g, instruction->fn_entry)) : |
| 5001 | g->any_frame_header_llvm_ty; |
| 5002 | |
| 4946 | 5003 | FnTypeId *fn_type_id = &fn_type->data.fn.fn_type_id; |
| 4947 | 5004 | |
| 4948 | 5005 | ZigType *src_return_type = fn_type_id->return_type; |
| ... | ... | @@ -4971,8 +5028,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI |
| 4971 | 5028 | ir_assert(instruction->frame_result_loc != nullptr, &instruction->base); |
| 4972 | 5029 | frame_result_loc_uncasted = ir_llvm_value(g, instruction->frame_result_loc); |
| 4973 | 5030 | ir_assert(instruction->fn_entry != nullptr, &instruction->base); |
| 4974 | | frame_result_loc = LLVMBuildBitCast(g->builder, frame_result_loc_uncasted, |
| 4975 | | LLVMPointerType(get_llvm_type(g, instruction->fn_entry->frame_type), 0), ""); |
| 5031 | frame_result_loc = frame_result_loc_uncasted; |
| 4976 | 5032 | } |
| 4977 | 5033 | } else { |
| 4978 | 5034 | if (instruction->new_stack->value->type->id == ZigTypeIdPointer && |
| ... | ... | @@ -4981,9 +5037,12 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI |
| 4981 | 5037 | frame_result_loc = ir_llvm_value(g, instruction->new_stack); |
| 4982 | 5038 | } else { |
| 4983 | 5039 | LLVMValueRef frame_slice_ptr = ir_llvm_value(g, instruction->new_stack); |
| 5040 | LLVMTypeRef frame_slice_llvm_ty = |
| 5041 | get_llvm_type(g, instruction->new_stack->value->type->data.pointer.child_type); |
| 4984 | 5042 | if (ir_want_runtime_safety(g, &instruction->base)) { |
| 4985 | | LLVMValueRef given_len_ptr = LLVMBuildStructGEP(g->builder, frame_slice_ptr, slice_len_index, ""); |
| 4986 | | LLVMValueRef given_frame_len = LLVMBuildLoad(g->builder, given_len_ptr, ""); |
| 5043 | LLVMValueRef given_len_ptr = LLVMBuildStructGEP2(g->builder, |
| 5044 | frame_slice_llvm_ty, frame_slice_ptr, slice_len_index, ""); |
| 5045 | LLVMValueRef given_frame_len = LLVMBuildLoad2(g->builder, usize_type_ref, given_len_ptr, ""); |
| 4987 | 5046 | LLVMValueRef actual_frame_len = gen_frame_size(g, fn_val); |
| 4988 | 5047 | |
| 4989 | 5048 | LLVMBasicBlockRef fail_block = LLVMAppendBasicBlock(g->cur_fn_val, "FrameSizeCheckFail"); |
| ... | ... | @@ -4998,18 +5057,18 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI |
| 4998 | 5057 | LLVMPositionBuilderAtEnd(g->builder, ok_block); |
| 4999 | 5058 | } |
| 5000 | 5059 | need_frame_ptr_ptr_spill = true; |
| 5001 | | LLVMValueRef frame_ptr_ptr = LLVMBuildStructGEP(g->builder, frame_slice_ptr, slice_ptr_index, ""); |
| 5002 | | LLVMValueRef frame_ptr = LLVMBuildLoad(g->builder, frame_ptr_ptr, ""); |
| 5060 | LLVMValueRef frame_ptr_ptr = LLVMBuildStructGEP2(g->builder, frame_slice_llvm_ty, |
| 5061 | frame_slice_ptr, slice_ptr_index, ""); |
| 5062 | LLVMValueRef frame_ptr = LLVMBuildLoad2(g->builder, |
| 5063 | LLVMGetGEPSourceElementType(frame_ptr_ptr), frame_ptr_ptr, ""); |
| 5003 | 5064 | if (instruction->fn_entry == nullptr) { |
| 5004 | 5065 | anyframe_type = get_any_frame_type(g, src_return_type); |
| 5005 | | frame_result_loc = LLVMBuildBitCast(g->builder, frame_ptr, get_llvm_type(g, anyframe_type), ""); |
| 5066 | frame_result_loc = frame_ptr; |
| 5006 | 5067 | } else { |
| 5007 | 5068 | ZigType *frame_type = get_fn_frame_type(g, instruction->fn_entry); |
| 5008 | 5069 | if ((err = type_resolve(g, frame_type, ResolveStatusLLVMFull))) |
| 5009 | 5070 | codegen_report_errors_and_exit(g); |
| 5010 | | ZigType *ptr_frame_type = get_pointer_to_type(g, frame_type, false); |
| 5011 | | frame_result_loc = LLVMBuildBitCast(g->builder, frame_ptr, |
| 5012 | | get_llvm_type(g, ptr_frame_type), ""); |
| 5071 | frame_result_loc = frame_ptr; |
| 5013 | 5072 | } |
| 5014 | 5073 | } |
| 5015 | 5074 | } |
| ... | ... | @@ -5019,7 +5078,8 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI |
| 5019 | 5078 | |
| 5020 | 5079 | if (ret_has_bits) { |
| 5021 | 5080 | // Use the result location which is inside the frame if this is an async call. |
| 5022 | | ret_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_ret_start + 2, ""); |
| 5081 | ret_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty, |
| 5082 | frame_result_loc, frame_ret_start + 2, ""); |
| 5023 | 5083 | } |
| 5024 | 5084 | } else { |
| 5025 | 5085 | awaiter_init_val = zero; |
| ... | ... | @@ -5030,7 +5090,8 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI |
| 5030 | 5090 | ret_ptr = result_loc; |
| 5031 | 5091 | } else { |
| 5032 | 5092 | // no result location provided to @asyncCall - use the one inside the frame. |
| 5033 | | ret_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_ret_start + 2, ""); |
| 5093 | ret_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty, |
| 5094 | frame_result_loc, frame_ret_start + 2, ""); |
| 5034 | 5095 | } |
| 5035 | 5096 | } |
| 5036 | 5097 | } |
| ... | ... | @@ -5050,20 +5111,20 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI |
| 5050 | 5111 | if (ret_has_bits) { |
| 5051 | 5112 | if (result_loc == nullptr) { |
| 5052 | 5113 | // return type is a scalar, but we still need a pointer to it. Use the async fn frame. |
| 5053 | | ret_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_ret_start + 2, ""); |
| 5114 | ret_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty, frame_result_loc, frame_ret_start + 2, ""); |
| 5054 | 5115 | } else { |
| 5055 | 5116 | // Use the call instruction's result location. |
| 5056 | 5117 | ret_ptr = result_loc; |
| 5057 | 5118 | } |
| 5058 | 5119 | |
| 5059 | 5120 | // Store a zero in the awaiter's result ptr to indicate we do not need a copy made. |
| 5060 | | LLVMValueRef awaiter_ret_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_ret_start + 1, ""); |
| 5121 | LLVMValueRef awaiter_ret_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty, frame_result_loc, frame_ret_start + 1, ""); |
| 5061 | 5122 | LLVMValueRef zero_ptr = LLVMConstNull(LLVMGetElementType(LLVMTypeOf(awaiter_ret_ptr))); |
| 5062 | 5123 | LLVMBuildStore(g->builder, zero_ptr, awaiter_ret_ptr); |
| 5063 | 5124 | } |
| 5064 | 5125 | |
| 5065 | 5126 | if (prefix_arg_err_ret_stack) { |
| 5066 | | LLVMValueRef err_ret_trace_ptr_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, |
| 5127 | LLVMValueRef err_ret_trace_ptr_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty, frame_result_loc, |
| 5067 | 5128 | frame_index_trace_arg(g, src_return_type) + 1, ""); |
| 5068 | 5129 | bool is_llvm_alloca; |
| 5069 | 5130 | LLVMValueRef my_err_ret_trace_val = get_cur_err_ret_trace_val(g, instruction->base.scope, |
| ... | ... | @@ -5074,19 +5135,19 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI |
| 5074 | 5135 | |
| 5075 | 5136 | assert(frame_result_loc != nullptr); |
| 5076 | 5137 | |
| 5077 | | LLVMValueRef fn_ptr_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_fn_ptr_index, ""); |
| 5138 | LLVMValueRef fn_ptr_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty, frame_result_loc, frame_fn_ptr_index, ""); |
| 5078 | 5139 | LLVMValueRef bitcasted_fn_val = LLVMBuildBitCast(g->builder, fn_val, |
| 5079 | 5140 | LLVMGetElementType(LLVMTypeOf(fn_ptr_ptr)), ""); |
| 5080 | 5141 | LLVMBuildStore(g->builder, bitcasted_fn_val, fn_ptr_ptr); |
| 5081 | 5142 | |
| 5082 | | LLVMValueRef resume_index_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_resume_index, ""); |
| 5143 | LLVMValueRef resume_index_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty, frame_result_loc, frame_resume_index, ""); |
| 5083 | 5144 | LLVMBuildStore(g->builder, zero, resume_index_ptr); |
| 5084 | 5145 | |
| 5085 | | LLVMValueRef awaiter_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_awaiter_index, ""); |
| 5146 | LLVMValueRef awaiter_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty, frame_result_loc, frame_awaiter_index, ""); |
| 5086 | 5147 | LLVMBuildStore(g->builder, awaiter_init_val, awaiter_ptr); |
| 5087 | 5148 | |
| 5088 | 5149 | if (ret_has_bits) { |
| 5089 | | LLVMValueRef ret_ptr_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_ret_start, ""); |
| 5150 | LLVMValueRef ret_ptr_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty, frame_result_loc, frame_ret_start, ""); |
| 5090 | 5151 | LLVMBuildStore(g->builder, ret_ptr, ret_ptr_ptr); |
| 5091 | 5152 | } |
| 5092 | 5153 | } else if (instruction->modifier == CallModifierAsync) { |
| ... | ... | @@ -5097,12 +5158,12 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI |
| 5097 | 5158 | frame_result_loc = result_loc; |
| 5098 | 5159 | awaiter_init_val = LLVMConstAllOnes(usize_type_ref); |
| 5099 | 5160 | |
| 5100 | | LLVMValueRef awaiter_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_awaiter_index, ""); |
| 5161 | LLVMValueRef awaiter_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty, frame_result_loc, frame_awaiter_index, ""); |
| 5101 | 5162 | LLVMBuildStore(g->builder, awaiter_init_val, awaiter_ptr); |
| 5102 | 5163 | |
| 5103 | 5164 | if (ret_has_bits) { |
| 5104 | | ret_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_ret_start + 2, ""); |
| 5105 | | LLVMValueRef ret_ptr_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_ret_start, ""); |
| 5165 | ret_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty, frame_result_loc, frame_ret_start + 2, ""); |
| 5166 | LLVMValueRef ret_ptr_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty, frame_result_loc, frame_ret_start, ""); |
| 5106 | 5167 | LLVMBuildStore(g->builder, ret_ptr, ret_ptr_ptr); |
| 5107 | 5168 | |
| 5108 | 5169 | if (first_arg_ret) { |
| ... | ... | @@ -5113,11 +5174,11 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI |
| 5113 | 5174 | // Then we have to wire up the StackTrace pointers. |
| 5114 | 5175 | // Await is responsible for merging error return traces. |
| 5115 | 5176 | uint32_t trace_field_index_start = frame_index_trace_arg(g, src_return_type); |
| 5116 | | LLVMValueRef callee_trace_ptr_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, |
| 5177 | LLVMValueRef callee_trace_ptr_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty, frame_result_loc, |
| 5117 | 5178 | trace_field_index_start, ""); |
| 5118 | | LLVMValueRef trace_field_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, |
| 5179 | LLVMValueRef trace_field_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty, frame_result_loc, |
| 5119 | 5180 | trace_field_index_start + 2, ""); |
| 5120 | | LLVMValueRef addrs_field_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, |
| 5181 | LLVMValueRef addrs_field_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty, frame_result_loc, |
| 5121 | 5182 | trace_field_index_start + 3, ""); |
| 5122 | 5183 | |
| 5123 | 5184 | LLVMBuildStore(g->builder, trace_field_ptr, callee_trace_ptr_ptr); |
| ... | ... | @@ -5177,7 +5238,7 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI |
| 5177 | 5238 | CalcLLVMFieldIndex arg_calc_start = {0}; |
| 5178 | 5239 | frame_index_arg_calc(g, &arg_calc_start, fn_type->data.fn.fn_type_id.return_type); |
| 5179 | 5240 | |
| 5180 | | LLVMValueRef casted_frame; |
| 5241 | LLVMTypeRef casted_frame_llvm_ty; |
| 5181 | 5242 | if (instruction->new_stack != nullptr && instruction->fn_entry == nullptr) { |
| 5182 | 5243 | // We need the frame type to be a pointer to a struct that includes the args |
| 5183 | 5244 | |
| ... | ... | @@ -5208,17 +5269,15 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI |
| 5208 | 5269 | } |
| 5209 | 5270 | LLVMTypeRef frame_with_args_type = LLVMStructType(field_types, field_count, false); |
| 5210 | 5271 | heap::c_allocator.deallocate(field_types, field_count); |
| 5211 | | LLVMTypeRef ptr_frame_with_args_type = LLVMPointerType(frame_with_args_type, 0); |
| 5212 | | |
| 5213 | | casted_frame = LLVMBuildBitCast(g->builder, frame_result_loc, ptr_frame_with_args_type, ""); |
| 5272 | casted_frame_llvm_ty = frame_with_args_type; |
| 5214 | 5273 | } else { |
| 5215 | | casted_frame = frame_result_loc; |
| 5274 | casted_frame_llvm_ty = frame_struct_llvm_ty; |
| 5216 | 5275 | } |
| 5217 | 5276 | |
| 5218 | 5277 | CalcLLVMFieldIndex arg_calc = arg_calc_start; |
| 5219 | 5278 | for (size_t arg_i = 0; arg_i < gen_param_values.length; arg_i += 1) { |
| 5220 | 5279 | calc_llvm_field_index_add(g, &arg_calc, gen_param_types.at(arg_i)); |
| 5221 | | LLVMValueRef arg_ptr = LLVMBuildStructGEP(g->builder, casted_frame, arg_calc.field_index - 1, ""); |
| 5280 | LLVMValueRef arg_ptr = LLVMBuildStructGEP2(g->builder, casted_frame_llvm_ty, frame_result_loc, arg_calc.field_index - 1, ""); |
| 5222 | 5281 | gen_assign_raw(g, arg_ptr, get_pointer_to_type(g, gen_param_types.at(arg_i), true), |
| 5223 | 5282 | gen_param_values.at(arg_i)); |
| 5224 | 5283 | } |
| ... | ... | @@ -5235,8 +5294,8 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI |
| 5235 | 5294 | gen_resume(g, fn_val, frame_result_loc, ResumeIdCall); |
| 5236 | 5295 | |
| 5237 | 5296 | if (ir_want_runtime_safety(g, &instruction->base)) { |
| 5238 | | LLVMValueRef awaiter_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, |
| 5239 | | frame_awaiter_index, ""); |
| 5297 | LLVMValueRef awaiter_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty, |
| 5298 | frame_result_loc, frame_awaiter_index, ""); |
| 5240 | 5299 | LLVMValueRef all_ones = LLVMConstAllOnes(usize_type_ref); |
| 5241 | 5300 | LLVMValueRef prev_val = gen_maybe_atomic_op(g, LLVMAtomicRMWBinOpXchg, awaiter_ptr, |
| 5242 | 5301 | all_ones, LLVMAtomicOrderingRelease); |
| ... | ... | @@ -5255,7 +5314,8 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI |
| 5255 | 5314 | |
| 5256 | 5315 | ZigType *result_type = instruction->base.value->type; |
| 5257 | 5316 | ZigType *ptr_result_type = get_pointer_to_type(g, result_type, true); |
| 5258 | | return gen_await_early_return(g, &instruction->base, frame_result_loc, |
| 5317 | return gen_await_early_return(g, &instruction->base, |
| 5318 | frame_struct_llvm_ty, frame_result_loc, |
| 5259 | 5319 | result_type, ptr_result_type, result_loc, true); |
| 5260 | 5320 | } else { |
| 5261 | 5321 | ZigType *ptr_result_type = get_pointer_to_type(g, src_return_type, true); |
| ... | ... | @@ -5284,8 +5344,11 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI |
| 5284 | 5344 | |
| 5285 | 5345 | if (need_frame_ptr_ptr_spill) { |
| 5286 | 5346 | LLVMValueRef frame_slice_ptr = ir_llvm_value(g, instruction->new_stack); |
| 5287 | | LLVMValueRef frame_ptr_ptr = LLVMBuildStructGEP(g->builder, frame_slice_ptr, slice_ptr_index, ""); |
| 5288 | | frame_result_loc_uncasted = LLVMBuildLoad(g->builder, frame_ptr_ptr, ""); |
| 5347 | LLVMValueRef frame_ptr_ptr = LLVMBuildStructGEP2(g->builder, |
| 5348 | get_llvm_type(g, instruction->new_stack->value->type->data.pointer.child_type), |
| 5349 | frame_slice_ptr, slice_ptr_index, ""); |
| 5350 | frame_result_loc_uncasted = LLVMBuildLoad2(g->builder, |
| 5351 | LLVMGetGEPSourceElementType(frame_ptr_ptr), frame_ptr_ptr, ""); |
| 5289 | 5352 | } |
| 5290 | 5353 | if (frame_result_loc_uncasted != nullptr) { |
| 5291 | 5354 | if (instruction->fn_entry != nullptr) { |
| ... | ... | @@ -5297,31 +5360,34 @@ static LLVMValueRef ir_render_call(CodeGen *g, Stage1Air *executable, Stage1AirI |
| 5297 | 5360 | } |
| 5298 | 5361 | } |
| 5299 | 5362 | |
| 5300 | | LLVMValueRef result_ptr = LLVMBuildStructGEP(g->builder, frame_result_loc, frame_ret_start + 2, ""); |
| 5301 | | return LLVMBuildLoad(g->builder, result_ptr, ""); |
| 5363 | LLVMValueRef result_ptr = LLVMBuildStructGEP2(g->builder, frame_struct_llvm_ty, |
| 5364 | frame_result_loc, frame_ret_start + 2, ""); |
| 5365 | return LLVMBuildLoad2(g->builder, get_llvm_type(g, src_return_type), result_ptr, ""); |
| 5302 | 5366 | } |
| 5303 | 5367 | } else { |
| 5304 | 5368 | gen_param_types.deinit(); |
| 5305 | 5369 | } |
| 5306 | 5370 | |
| 5307 | 5371 | if (instruction->new_stack == nullptr || instruction->is_async_call_builtin) { |
| 5308 | | result = ZigLLVMBuildCall(g->builder, fn_val, |
| 5372 | result = ZigLLVMBuildCall(g->builder, LLVMTypeOf(fn_val), fn_val, |
| 5309 | 5373 | gen_param_values.items, (unsigned)gen_param_values.length, llvm_cc, call_attr, ""); |
| 5310 | 5374 | } else if (instruction->modifier == CallModifierAsync) { |
| 5311 | 5375 | zig_panic("TODO @asyncCall of non-async function"); |
| 5312 | 5376 | } else { |
| 5313 | | LLVMValueRef new_stack_addr = get_new_stack_addr(g, ir_llvm_value(g, instruction->new_stack)); |
| 5377 | LLVMValueRef new_stack_addr = get_new_stack_addr(g, |
| 5378 | get_llvm_type(g, instruction->new_stack->value->type), |
| 5379 | ir_llvm_value(g, instruction->new_stack)); |
| 5314 | 5380 | LLVMValueRef old_stack_ref; |
| 5315 | 5381 | if (src_return_type->id != ZigTypeIdUnreachable) { |
| 5316 | 5382 | LLVMValueRef stacksave_fn_val = get_stacksave_fn_val(g); |
| 5317 | | old_stack_ref = LLVMBuildCall(g->builder, stacksave_fn_val, nullptr, 0, ""); |
| 5383 | old_stack_ref = LLVMBuildCall2(g->builder, LLVMTypeOf(stacksave_fn_val), stacksave_fn_val, nullptr, 0, ""); |
| 5318 | 5384 | } |
| 5319 | 5385 | gen_set_stack_pointer(g, new_stack_addr); |
| 5320 | | result = ZigLLVMBuildCall(g->builder, fn_val, |
| 5386 | result = ZigLLVMBuildCall(g->builder, LLVMTypeOf(fn_val), fn_val, |
| 5321 | 5387 | gen_param_values.items, (unsigned)gen_param_values.length, llvm_cc, call_attr, ""); |
| 5322 | 5388 | if (src_return_type->id != ZigTypeIdUnreachable) { |
| 5323 | 5389 | LLVMValueRef stackrestore_fn_val = get_stackrestore_fn_val(g); |
| 5324 | | LLVMBuildCall(g->builder, stackrestore_fn_val, &old_stack_ref, 1, ""); |
| 5390 | LLVMBuildCall2(g->builder, LLVMTypeOf(stackrestore_fn_val), stackrestore_fn_val, &old_stack_ref, 1, ""); |
| 5325 | 5391 | } |
| 5326 | 5392 | } |
| 5327 | 5393 | |
| ... | ... | @@ -5361,6 +5427,8 @@ static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, Stage1Air *executable |
| 5361 | 5427 | LLVMValueRef struct_ptr = ir_llvm_value(g, instruction->struct_ptr); |
| 5362 | 5428 | // not necessarily a pointer. could be ZigTypeIdStruct |
| 5363 | 5429 | ZigType *struct_ptr_type = instruction->struct_ptr->value->type; |
| 5430 | ZigType *struct_ty = (struct_ptr_type->id == ZigTypeIdPointer) ? |
| 5431 | struct_ptr_type->data.pointer.child_type : struct_ptr_type; |
| 5364 | 5432 | TypeStructField *field = instruction->field; |
| 5365 | 5433 | |
| 5366 | 5434 | if (!type_has_bits(g, field->type_entry)) |
| ... | ... | @@ -5387,7 +5455,8 @@ static LLVMValueRef ir_render_struct_field_ptr(CodeGen *g, Stage1Air *executable |
| 5387 | 5455 | codegen_report_errors_and_exit(g); |
| 5388 | 5456 | |
| 5389 | 5457 | ir_assert(field->gen_index != SIZE_MAX, &instruction->base); |
| 5390 | | LLVMValueRef field_ptr_val = LLVMBuildStructGEP(g->builder, struct_ptr, (unsigned)field->gen_index, ""); |
| 5458 | LLVMValueRef field_ptr_val = LLVMBuildStructGEP2(g->builder, |
| 5459 | get_llvm_type(g, struct_ty), struct_ptr, (unsigned)field->gen_index, ""); |
| 5391 | 5460 | ZigType *res_type = instruction->base.value->type; |
| 5392 | 5461 | ir_assert(res_type->id == ZigTypeIdPointer, &instruction->base); |
| 5393 | 5462 | if (res_type->data.pointer.host_int_bytes != 0) { |
| ... | ... | @@ -5432,8 +5501,9 @@ static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, Stage1Air *executable, |
| 5432 | 5501 | LLVMPointerType(tag_type_ref, 0), ""); |
| 5433 | 5502 | } else { |
| 5434 | 5503 | assert(union_type->data.unionation.gen_tag_index != SIZE_MAX); |
| 5435 | | tag_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr, |
| 5436 | | union_type->data.unionation.gen_tag_index, ""); |
| 5504 | tag_field_ptr = LLVMBuildStructGEP2(g->builder, |
| 5505 | get_llvm_type(g, union_type), |
| 5506 | union_ptr, union_type->data.unionation.gen_tag_index, ""); |
| 5437 | 5507 | } |
| 5438 | 5508 | |
| 5439 | 5509 | LLVMValueRef tag_value = bigint_to_llvm_const(tag_type_ref, |
| ... | ... | @@ -5448,19 +5518,25 @@ static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, Stage1Air *executable, |
| 5448 | 5518 | LLVMTypeRef field_type_ref = LLVMPointerType(get_llvm_type(g, field->type_entry), 0); |
| 5449 | 5519 | |
| 5450 | 5520 | if (union_type->data.unionation.gen_tag_index == SIZE_MAX) { |
| 5451 | | LLVMValueRef union_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr, 0, ""); |
| 5521 | LLVMValueRef union_field_ptr = LLVMBuildStructGEP2(g->builder, |
| 5522 | get_llvm_type(g, union_type), union_ptr, 0, ""); |
| 5452 | 5523 | LLVMValueRef bitcasted_union_field_ptr = LLVMBuildBitCast(g->builder, union_field_ptr, field_type_ref, ""); |
| 5453 | 5524 | return bitcasted_union_field_ptr; |
| 5454 | 5525 | } |
| 5455 | 5526 | |
| 5456 | 5527 | if (instruction->initializing) { |
| 5457 | | LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr, union_type->data.unionation.gen_tag_index, ""); |
| 5528 | LLVMValueRef tag_field_ptr = LLVMBuildStructGEP2(g->builder, |
| 5529 | get_llvm_type(g, union_type), |
| 5530 | union_ptr, union_type->data.unionation.gen_tag_index, ""); |
| 5458 | 5531 | LLVMValueRef tag_value = bigint_to_llvm_const(get_llvm_type(g, union_type->data.unionation.tag_type), |
| 5459 | 5532 | &field->enum_field->value); |
| 5460 | 5533 | gen_store_untyped(g, tag_value, tag_field_ptr, 0, false); |
| 5461 | 5534 | } else if (instruction->safety_check_on && ir_want_runtime_safety(g, &instruction->base)) { |
| 5462 | | LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr, union_type->data.unionation.gen_tag_index, ""); |
| 5463 | | LLVMValueRef tag_value = gen_load_untyped(g, tag_field_ptr, 0, false, ""); |
| 5535 | LLVMValueRef tag_field_ptr = LLVMBuildStructGEP2(g->builder, |
| 5536 | get_llvm_type(g, union_type), |
| 5537 | union_ptr, union_type->data.unionation.gen_tag_index, ""); |
| 5538 | LLVMValueRef tag_value = gen_load_untyped(g, LLVMGetGEPSourceElementType(tag_field_ptr), |
| 5539 | tag_field_ptr, 0, false, ""); |
| 5464 | 5540 | |
| 5465 | 5541 | |
| 5466 | 5542 | LLVMValueRef expected_tag_value = bigint_to_llvm_const(get_llvm_type(g, union_type->data.unionation.tag_type), |
| ... | ... | @@ -5476,10 +5552,9 @@ static LLVMValueRef ir_render_union_field_ptr(CodeGen *g, Stage1Air *executable, |
| 5476 | 5552 | LLVMPositionBuilderAtEnd(g->builder, ok_block); |
| 5477 | 5553 | } |
| 5478 | 5554 | |
| 5479 | | LLVMValueRef union_field_ptr = LLVMBuildStructGEP(g->builder, union_ptr, |
| 5480 | | union_type->data.unionation.gen_union_index, ""); |
| 5481 | | LLVMValueRef bitcasted_union_field_ptr = LLVMBuildBitCast(g->builder, union_field_ptr, field_type_ref, ""); |
| 5482 | | return bitcasted_union_field_ptr; |
| 5555 | LLVMValueRef union_field_ptr = LLVMBuildStructGEP2(g->builder, get_llvm_type(g, union_type), |
| 5556 | union_ptr, union_type->data.unionation.gen_union_index, ""); |
| 5557 | return union_field_ptr; |
| 5483 | 5558 | } |
| 5484 | 5559 | |
| 5485 | 5560 | static size_t find_asm_index(CodeGen *g, AstNode *node, AsmToken *tok, Buf *src_template) { |
| ... | ... | @@ -5660,7 +5735,7 @@ static LLVMValueRef ir_render_asm_gen(CodeGen *g, Stage1Air *executable, Stage1A |
| 5660 | 5735 | LLVMValueRef asm_fn = LLVMGetInlineAsm(function_type, buf_ptr(&llvm_template), buf_len(&llvm_template), |
| 5661 | 5736 | buf_ptr(&constraint_buf), buf_len(&constraint_buf), is_volatile, false, LLVMInlineAsmDialectATT, false); |
| 5662 | 5737 | |
| 5663 | | LLVMValueRef built_call = LLVMBuildCall(g->builder, asm_fn, param_values, (unsigned)input_and_output_count, ""); |
| 5738 | LLVMValueRef built_call = LLVMBuildCall2(g->builder, LLVMTypeOf(asm_fn), asm_fn, param_values, (unsigned)input_and_output_count, ""); |
| 5664 | 5739 | |
| 5665 | 5740 | for (size_t i = 0; i < input_and_output_count; i += 1) { |
| 5666 | 5741 | if (param_needs_attr[i]) { |
| ... | ... | @@ -5689,8 +5764,9 @@ static LLVMValueRef gen_non_null_bit(CodeGen *g, ZigType *maybe_type, LLVMValueR |
| 5689 | 5764 | if (is_scalar) |
| 5690 | 5765 | return LLVMBuildICmp(g->builder, LLVMIntNE, maybe_handle, LLVMConstNull(get_llvm_type(g, maybe_type)), ""); |
| 5691 | 5766 | |
| 5692 | | LLVMValueRef maybe_field_ptr = LLVMBuildStructGEP(g->builder, maybe_handle, maybe_null_index, ""); |
| 5693 | | return gen_load_untyped(g, maybe_field_ptr, 0, false, ""); |
| 5767 | LLVMValueRef maybe_field_ptr = LLVMBuildStructGEP2(g->builder, |
| 5768 | get_llvm_type(g, maybe_type), maybe_handle, maybe_null_index, ""); |
| 5769 | return gen_load_untyped(g, LLVMGetGEPSourceElementType(maybe_field_ptr), maybe_field_ptr, 0, false, ""); |
| 5694 | 5770 | } |
| 5695 | 5771 | |
| 5696 | 5772 | static LLVMValueRef ir_render_test_non_null(CodeGen *g, Stage1Air *executable, |
| ... | ... | @@ -5736,12 +5812,13 @@ static LLVMValueRef ir_render_optional_unwrap_ptr(CodeGen *g, Stage1Air *executa |
| 5736 | 5812 | } else { |
| 5737 | 5813 | LLVMValueRef optional_struct_ref = get_handle_value(g, base_ptr, maybe_type, ptr_type); |
| 5738 | 5814 | if (instruction->initializing) { |
| 5739 | | LLVMValueRef non_null_bit_ptr = LLVMBuildStructGEP(g->builder, optional_struct_ref, |
| 5740 | | maybe_null_index, ""); |
| 5815 | LLVMValueRef non_null_bit_ptr = LLVMBuildStructGEP2(g->builder, |
| 5816 | get_llvm_type(g, maybe_type), optional_struct_ref, maybe_null_index, ""); |
| 5741 | 5817 | LLVMValueRef non_null_bit = LLVMConstInt(LLVMInt1Type(), 1, false); |
| 5742 | 5818 | gen_store_untyped(g, non_null_bit, non_null_bit_ptr, 0, false); |
| 5743 | 5819 | } |
| 5744 | | return LLVMBuildStructGEP(g->builder, optional_struct_ref, maybe_child_index, ""); |
| 5820 | return LLVMBuildStructGEP2(g->builder, |
| 5821 | get_llvm_type(g, maybe_type), optional_struct_ref, maybe_child_index, ""); |
| 5745 | 5822 | } |
| 5746 | 5823 | } |
| 5747 | 5824 | } |
| ... | ... | @@ -5818,7 +5895,7 @@ static LLVMValueRef ir_render_clz(CodeGen *g, Stage1Air *executable, Stage1AirIn |
| 5818 | 5895 | operand, |
| 5819 | 5896 | LLVMConstNull(LLVMInt1Type()), |
| 5820 | 5897 | }; |
| 5821 | | LLVMValueRef wrong_size_int = LLVMBuildCall(g->builder, fn_val, params, 2, ""); |
| 5898 | LLVMValueRef wrong_size_int = LLVMBuildCall2(g->builder, LLVMTypeOf(fn_val), fn_val, params, 2, ""); |
| 5822 | 5899 | return gen_widen_or_shorten(g, false, int_type, instruction->base.value->type, wrong_size_int); |
| 5823 | 5900 | } |
| 5824 | 5901 | |
| ... | ... | @@ -5830,7 +5907,7 @@ static LLVMValueRef ir_render_ctz(CodeGen *g, Stage1Air *executable, Stage1AirIn |
| 5830 | 5907 | operand, |
| 5831 | 5908 | LLVMConstNull(LLVMInt1Type()), |
| 5832 | 5909 | }; |
| 5833 | | LLVMValueRef wrong_size_int = LLVMBuildCall(g->builder, fn_val, params, 2, ""); |
| 5910 | LLVMValueRef wrong_size_int = LLVMBuildCall2(g->builder, LLVMTypeOf(fn_val), fn_val, params, 2, ""); |
| 5834 | 5911 | return gen_widen_or_shorten(g, false, int_type, instruction->base.value->type, wrong_size_int); |
| 5835 | 5912 | } |
| 5836 | 5913 | |
| ... | ... | @@ -5887,7 +5964,7 @@ static LLVMValueRef ir_render_pop_count(CodeGen *g, Stage1Air *executable, Stage |
| 5887 | 5964 | ZigType *int_type = instruction->op->value->type; |
| 5888 | 5965 | LLVMValueRef fn_val = get_int_builtin_fn(g, int_type, BuiltinFnIdPopCount); |
| 5889 | 5966 | LLVMValueRef operand = ir_llvm_value(g, instruction->op); |
| 5890 | | LLVMValueRef wrong_size_int = LLVMBuildCall(g->builder, fn_val, &operand, 1, ""); |
| 5967 | LLVMValueRef wrong_size_int = LLVMBuildCall2(g->builder, LLVMTypeOf(fn_val), fn_val, &operand, 1, ""); |
| 5891 | 5968 | return gen_widen_or_shorten(g, false, int_type, instruction->base.value->type, wrong_size_int); |
| 5892 | 5969 | } |
| 5893 | 5970 | |
| ... | ... | @@ -5978,7 +6055,11 @@ static LLVMValueRef ir_render_err_name(CodeGen *g, Stage1Air *executable, Stage1 |
| 5978 | 6055 | LLVMConstNull(g->builtin_types.entry_usize->llvm_type), |
| 5979 | 6056 | err_val, |
| 5980 | 6057 | }; |
| 5981 | | return LLVMBuildInBoundsGEP(g->builder, g->err_name_table, indices, 2, ""); |
| 6058 | ZigType *u8_ptr_type = get_pointer_to_type_extra(g, g->builtin_types.entry_u8, true, false, |
| 6059 | PtrLenUnknown, get_abi_alignment(g, g->builtin_types.entry_u8), 0, 0, false); |
| 6060 | ZigType *str_type = get_slice_type(g, u8_ptr_type); |
| 6061 | LLVMTypeRef elem_llvm_ty = get_llvm_type(g, str_type); |
| 6062 | return LLVMBuildInBoundsGEP2(g->builder, elem_llvm_ty, g->err_name_table, indices, 2, ""); |
| 5982 | 6063 | } |
| 5983 | 6064 | |
| 5984 | 6065 | static LLVMValueRef get_enum_tag_name_function(CodeGen *g, ZigType *enum_type) { |
| ... | ... | @@ -6050,7 +6131,7 @@ static LLVMValueRef get_enum_tag_name_function(CodeGen *g, ZigType *enum_type) { |
| 6050 | 6131 | LLVMSetAlignment(str_global, LLVMABIAlignmentOfType(g->target_data_ref, LLVMTypeOf(str_init))); |
| 6051 | 6132 | |
| 6052 | 6133 | LLVMValueRef fields[] = { |
| 6053 | | LLVMConstGEP(str_global, array_ptr_indices, 2), |
| 6134 | LLVMConstInBoundsGEP2(LLVMInt8Type(), str_global, array_ptr_indices, 2), |
| 6054 | 6135 | LLVMConstInt(g->builtin_types.entry_usize->llvm_type, buf_len(name), false), |
| 6055 | 6136 | }; |
| 6056 | 6137 | LLVMValueRef slice_init_value = LLVMConstNamedStruct(get_llvm_type(g, u8_slice_type), fields, 2); |
| ... | ... | @@ -6099,7 +6180,8 @@ static LLVMValueRef ir_render_enum_tag_name(CodeGen *g, Stage1Air *executable, |
| 6099 | 6180 | LLVMValueRef enum_name_function = get_enum_tag_name_function(g, enum_type); |
| 6100 | 6181 | |
| 6101 | 6182 | LLVMValueRef enum_tag_value = ir_llvm_value(g, instruction->target); |
| 6102 | | return ZigLLVMBuildCall(g->builder, enum_name_function, &enum_tag_value, 1, |
| 6183 | return ZigLLVMBuildCall(g->builder, LLVMTypeOf(enum_name_function), enum_name_function, |
| 6184 | &enum_tag_value, 1, |
| 6103 | 6185 | get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_CallAttrAuto, ""); |
| 6104 | 6186 | } |
| 6105 | 6187 | |
| ... | ... | @@ -6166,8 +6248,10 @@ static LLVMValueRef ir_render_align_cast(CodeGen *g, Stage1Air *executable, Stag |
| 6166 | 6248 | align_bytes = get_ptr_align(g, slice_ptr_type); |
| 6167 | 6249 | |
| 6168 | 6250 | size_t ptr_index = target_type->data.structure.fields[slice_ptr_index]->gen_index; |
| 6169 | | LLVMValueRef ptr_val_ptr = LLVMBuildStructGEP(g->builder, target_val, (unsigned)ptr_index, ""); |
| 6170 | | ptr_val = gen_load_untyped(g, ptr_val_ptr, 0, false, ""); |
| 6251 | LLVMValueRef ptr_val_ptr = LLVMBuildStructGEP2(g->builder, |
| 6252 | get_llvm_type(g, instruction->target->value->type->data.pointer.child_type), |
| 6253 | target_val, (unsigned)ptr_index, ""); |
| 6254 | ptr_val = gen_load_untyped(g, LLVMGetGEPSourceElementType(ptr_val_ptr), ptr_val_ptr, 0, false, ""); |
| 6171 | 6255 | } else { |
| 6172 | 6256 | zig_unreachable(); |
| 6173 | 6257 | } |
| ... | ... | @@ -6319,12 +6403,16 @@ static LLVMValueRef ir_render_cmpxchg(CodeGen *g, Stage1Air *executable, Stage1A |
| 6319 | 6403 | if (actual_abi_type != nullptr) { |
| 6320 | 6404 | payload_val = LLVMBuildTrunc(g->builder, payload_val, get_llvm_type(g, operand_type), ""); |
| 6321 | 6405 | } |
| 6322 | | LLVMValueRef val_ptr = LLVMBuildStructGEP(g->builder, result_loc, maybe_child_index, ""); |
| 6406 | LLVMTypeRef result_loc_struct_llvm_ty = get_llvm_type(g, |
| 6407 | instruction->result_loc->value->type->data.pointer.child_type); |
| 6408 | LLVMValueRef val_ptr = LLVMBuildStructGEP2(g->builder, |
| 6409 | result_loc_struct_llvm_ty, result_loc, maybe_child_index, ""); |
| 6323 | 6410 | gen_assign_raw(g, val_ptr, get_pointer_to_type(g, child_type, false), payload_val); |
| 6324 | 6411 | |
| 6325 | 6412 | LLVMValueRef success_bit = LLVMBuildExtractValue(g->builder, result_val, 1, ""); |
| 6326 | 6413 | LLVMValueRef nonnull_bit = LLVMBuildNot(g->builder, success_bit, ""); |
| 6327 | | LLVMValueRef maybe_ptr = LLVMBuildStructGEP(g->builder, result_loc, maybe_null_index, ""); |
| 6414 | LLVMValueRef maybe_ptr = LLVMBuildStructGEP2(g->builder, result_loc_struct_llvm_ty, result_loc, |
| 6415 | maybe_null_index, ""); |
| 6328 | 6416 | gen_store_untyped(g, nonnull_bit, maybe_ptr, 0, false); |
| 6329 | 6417 | return result_loc; |
| 6330 | 6418 | } |
| ... | ... | @@ -6469,7 +6557,7 @@ static LLVMValueRef ir_render_memcpy(CodeGen *g, Stage1Air *executable, Stage1Ai |
| 6469 | 6557 | static LLVMValueRef ir_render_wasm_memory_size(CodeGen *g, Stage1Air *executable, Stage1AirInstWasmMemorySize *instruction) { |
| 6470 | 6558 | // TODO adjust for wasm64 |
| 6471 | 6559 | LLVMValueRef param = ir_llvm_value(g, instruction->index); |
| 6472 | | LLVMValueRef val = LLVMBuildCall(g->builder, gen_wasm_memory_size(g), &param, 1, ""); |
| 6560 | LLVMValueRef val = LLVMBuildCall2(g->builder, LLVMTypeOf(gen_wasm_memory_size(g)), gen_wasm_memory_size(g), &param, 1, ""); |
| 6473 | 6561 | return val; |
| 6474 | 6562 | } |
| 6475 | 6563 | |
| ... | ... | @@ -6479,7 +6567,7 @@ static LLVMValueRef ir_render_wasm_memory_grow(CodeGen *g, Stage1Air *executable |
| 6479 | 6567 | ir_llvm_value(g, instruction->index), |
| 6480 | 6568 | ir_llvm_value(g, instruction->delta), |
| 6481 | 6569 | }; |
| 6482 | | LLVMValueRef val = LLVMBuildCall(g->builder, gen_wasm_memory_grow(g), params, 2, ""); |
| 6570 | LLVMValueRef val = LLVMBuildCall2(g->builder, LLVMTypeOf(gen_wasm_memory_grow(g)), gen_wasm_memory_grow(g), params, 2, ""); |
| 6483 | 6571 | return val; |
| 6484 | 6572 | } |
| 6485 | 6573 | |
| ... | ... | @@ -6525,7 +6613,7 @@ static LLVMValueRef ir_render_prefetch(CodeGen *g, Stage1Air *executable, Stage1 |
| 6525 | 6613 | LLVMConstInt(LLVMInt32Type(), instruction->locality, false), |
| 6526 | 6614 | LLVMConstInt(LLVMInt32Type(), instruction->cache, false), |
| 6527 | 6615 | }; |
| 6528 | | LLVMValueRef val = LLVMBuildCall(g->builder, gen_prefetch(g), params, 4, ""); |
| 6616 | LLVMValueRef val = LLVMBuildCall2(g->builder, LLVMTypeOf(gen_prefetch(g)), gen_prefetch(g), params, 4, ""); |
| 6529 | 6617 | return val; |
| 6530 | 6618 | } |
| 6531 | 6619 | |
| ... | ... | @@ -6591,12 +6679,15 @@ static LLVMValueRef ir_render_slice(CodeGen *g, Stage1Air *executable, Stage1Air |
| 6591 | 6679 | codegen_report_errors_and_exit(g); |
| 6592 | 6680 | |
| 6593 | 6681 | if (value_has_bits) { |
| 6682 | LLVMTypeRef elem_llvm_ty = get_llvm_type(g, array_type->data.array.child_type); |
| 6683 | |
| 6594 | 6684 | if (want_runtime_safety && sentinel != nullptr) { |
| 6595 | 6685 | LLVMValueRef indices[] = { |
| 6596 | 6686 | LLVMConstNull(g->builtin_types.entry_usize->llvm_type), |
| 6597 | 6687 | end_val, |
| 6598 | 6688 | }; |
| 6599 | | LLVMValueRef sentinel_elem_ptr = LLVMBuildInBoundsGEP(g->builder, array_ptr, indices, 2, ""); |
| 6689 | LLVMValueRef sentinel_elem_ptr = LLVMBuildInBoundsGEP2(g->builder, |
| 6690 | elem_llvm_ty, array_ptr, indices, 2, ""); |
| 6600 | 6691 | add_sentinel_check(g, sentinel_elem_ptr, sentinel); |
| 6601 | 6692 | } |
| 6602 | 6693 | |
| ... | ... | @@ -6604,7 +6695,7 @@ static LLVMValueRef ir_render_slice(CodeGen *g, Stage1Air *executable, Stage1Air |
| 6604 | 6695 | LLVMConstNull(g->builtin_types.entry_usize->llvm_type), |
| 6605 | 6696 | start_val, |
| 6606 | 6697 | }; |
| 6607 | | slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, array_ptr, indices, 2, ""); |
| 6698 | slice_start_ptr = LLVMBuildInBoundsGEP2(g->builder, elem_llvm_ty, array_ptr, indices, 2, ""); |
| 6608 | 6699 | } |
| 6609 | 6700 | |
| 6610 | 6701 | len_value = LLVMBuildNUWSub(g->builder, end_val, start_val, ""); |
| ... | ... | @@ -6623,27 +6714,31 @@ static LLVMValueRef ir_render_slice(CodeGen *g, Stage1Air *executable, Stage1Air |
| 6623 | 6714 | codegen_report_errors_and_exit(g); |
| 6624 | 6715 | |
| 6625 | 6716 | if (value_has_bits) { |
| 6717 | LLVMTypeRef elem_llvm_ty = get_llvm_type(g, array_type->data.pointer.child_type); |
| 6718 | |
| 6626 | 6719 | if (want_runtime_safety && sentinel != nullptr) { |
| 6627 | | LLVMValueRef sentinel_elem_ptr = LLVMBuildInBoundsGEP(g->builder, array_ptr, &end_val, 1, ""); |
| 6720 | LLVMValueRef sentinel_elem_ptr = LLVMBuildInBoundsGEP2(g->builder, elem_llvm_ty, |
| 6721 | array_ptr, &end_val, 1, ""); |
| 6628 | 6722 | add_sentinel_check(g, sentinel_elem_ptr, sentinel); |
| 6629 | 6723 | } |
| 6630 | 6724 | |
| 6631 | | slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, array_ptr, &start_val, 1, ""); |
| 6725 | slice_start_ptr = LLVMBuildInBoundsGEP2(g->builder, elem_llvm_ty, array_ptr, |
| 6726 | &start_val, 1, ""); |
| 6632 | 6727 | } |
| 6633 | 6728 | |
| 6634 | 6729 | len_value = LLVMBuildNUWSub(g->builder, end_val, start_val, ""); |
| 6635 | 6730 | } else if (array_type->id == ZigTypeIdStruct) { |
| 6636 | 6731 | assert(array_type->data.structure.special == StructSpecialSlice); |
| 6637 | 6732 | assert(LLVMGetTypeKind(LLVMTypeOf(array_ptr)) == LLVMPointerTypeKind); |
| 6638 | | assert(LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(array_ptr))) == LLVMStructTypeKind); |
| 6639 | 6733 | |
| 6640 | 6734 | const size_t gen_len_index = array_type->data.structure.fields[slice_len_index]->gen_index; |
| 6641 | 6735 | assert(gen_len_index != SIZE_MAX); |
| 6642 | 6736 | |
| 6643 | 6737 | LLVMValueRef prev_end = nullptr; |
| 6644 | 6738 | if (!instruction->end || want_runtime_safety) { |
| 6645 | | LLVMValueRef src_len_ptr = LLVMBuildStructGEP(g->builder, array_ptr, gen_len_index, ""); |
| 6646 | | prev_end = gen_load_untyped(g, src_len_ptr, 0, false, ""); |
| 6739 | LLVMValueRef src_len_ptr = LLVMBuildStructGEP2(g->builder, |
| 6740 | get_llvm_type(g, array_type), array_ptr, gen_len_index, ""); |
| 6741 | prev_end = gen_load_untyped(g, LLVMGetGEPSourceElementType(src_len_ptr), src_len_ptr, 0, false, ""); |
| 6647 | 6742 | } |
| 6648 | 6743 | |
| 6649 | 6744 | LLVMValueRef start_val = ir_llvm_value(g, instruction->start); |
| ... | ... | @@ -6682,18 +6777,22 @@ static LLVMValueRef ir_render_slice(CodeGen *g, Stage1Air *executable, Stage1Air |
| 6682 | 6777 | codegen_report_errors_and_exit(g); |
| 6683 | 6778 | |
| 6684 | 6779 | if (ptr_has_bits) { |
| 6780 | LLVMTypeRef elem_llvm_ty = get_llvm_type(g, ptr_field_type->data.pointer.child_type); |
| 6685 | 6781 | const size_t gen_ptr_index = array_type->data.structure.fields[slice_ptr_index]->gen_index; |
| 6686 | 6782 | assert(gen_ptr_index != SIZE_MAX); |
| 6687 | 6783 | |
| 6688 | | LLVMValueRef src_ptr_ptr = LLVMBuildStructGEP(g->builder, array_ptr, gen_ptr_index, ""); |
| 6689 | | LLVMValueRef src_ptr = gen_load_untyped(g, src_ptr_ptr, 0, false, ""); |
| 6784 | LLVMValueRef src_ptr_ptr = LLVMBuildStructGEP2(g->builder, |
| 6785 | get_llvm_type(g, array_type), array_ptr, gen_ptr_index, ""); |
| 6786 | LLVMValueRef src_ptr = gen_load_untyped(g, LLVMGetGEPSourceElementType(src_ptr_ptr), |
| 6787 | src_ptr_ptr, 0, false, ""); |
| 6690 | 6788 | |
| 6691 | 6789 | if (sentinel != nullptr) { |
| 6692 | | LLVMValueRef sentinel_elem_ptr = LLVMBuildInBoundsGEP(g->builder, src_ptr, &end_val, 1, ""); |
| 6790 | LLVMValueRef sentinel_elem_ptr = LLVMBuildInBoundsGEP2(g->builder, elem_llvm_ty, |
| 6791 | src_ptr, &end_val, 1, ""); |
| 6693 | 6792 | add_sentinel_check(g, sentinel_elem_ptr, sentinel); |
| 6694 | 6793 | } |
| 6695 | 6794 | |
| 6696 | | slice_start_ptr = LLVMBuildInBoundsGEP(g->builder, src_ptr, &start_val, 1, ""); |
| 6795 | slice_start_ptr = LLVMBuildInBoundsGEP2(g->builder, elem_llvm_ty, src_ptr, &start_val, 1, ""); |
| 6697 | 6796 | } |
| 6698 | 6797 | |
| 6699 | 6798 | len_value = LLVMBuildNUWSub(g->builder, end_val, start_val, ""); |
| ... | ... | @@ -6735,7 +6834,8 @@ static LLVMValueRef ir_render_slice(CodeGen *g, Stage1Air *executable, Stage1Air |
| 6735 | 6834 | // The slice may not have a pointer at all if it points to a zero-sized type |
| 6736 | 6835 | const size_t gen_ptr_index = result_type->data.structure.fields[slice_ptr_index]->gen_index; |
| 6737 | 6836 | if (gen_ptr_index != SIZE_MAX) { |
| 6738 | | LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, gen_ptr_index, ""); |
| 6837 | LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP2(g->builder, |
| 6838 | get_llvm_type(g, result_type), tmp_struct_ptr, gen_ptr_index, ""); |
| 6739 | 6839 | if (slice_start_ptr != nullptr) { |
| 6740 | 6840 | gen_store_untyped(g, slice_start_ptr, ptr_field_ptr, 0, false); |
| 6741 | 6841 | } else if (want_runtime_safety) { |
| ... | ... | @@ -6748,7 +6848,8 @@ static LLVMValueRef ir_render_slice(CodeGen *g, Stage1Air *executable, Stage1Air |
| 6748 | 6848 | const size_t gen_len_index = result_type->data.structure.fields[slice_len_index]->gen_index; |
| 6749 | 6849 | assert(gen_len_index != SIZE_MAX); |
| 6750 | 6850 | |
| 6751 | | LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, tmp_struct_ptr, gen_len_index, ""); |
| 6851 | LLVMValueRef len_field_ptr = LLVMBuildStructGEP2(g->builder, |
| 6852 | get_llvm_type(g, result_type), tmp_struct_ptr, gen_len_index, ""); |
| 6752 | 6853 | gen_store_untyped(g, len_value, len_field_ptr, 0, false); |
| 6753 | 6854 | |
| 6754 | 6855 | return tmp_struct_ptr; |
| ... | ... | @@ -6767,7 +6868,7 @@ static LLVMValueRef get_trap_fn_val(CodeGen *g) { |
| 6767 | 6868 | |
| 6768 | 6869 | |
| 6769 | 6870 | static LLVMValueRef ir_render_breakpoint(CodeGen *g, Stage1Air *executable, Stage1AirInstBreakpoint *instruction) { |
| 6770 | | LLVMBuildCall(g->builder, get_trap_fn_val(g), nullptr, 0, ""); |
| 6871 | LLVMBuildCall2(g->builder, LLVMTypeOf(get_trap_fn_val(g)), get_trap_fn_val(g), nullptr, 0, ""); |
| 6771 | 6872 | return nullptr; |
| 6772 | 6873 | } |
| 6773 | 6874 | |
| ... | ... | @@ -6781,7 +6882,7 @@ static LLVMValueRef ir_render_return_address(CodeGen *g, Stage1Air *executable, |
| 6781 | 6882 | } |
| 6782 | 6883 | |
| 6783 | 6884 | LLVMValueRef zero = LLVMConstNull(g->builtin_types.entry_i32->llvm_type); |
| 6784 | | LLVMValueRef ptr_val = LLVMBuildCall(g->builder, get_return_address_fn_val(g), &zero, 1, ""); |
| 6885 | LLVMValueRef ptr_val = LLVMBuildCall2(g->builder, LLVMTypeOf(get_return_address_fn_val(g)), get_return_address_fn_val(g), &zero, 1, ""); |
| 6785 | 6886 | return LLVMBuildPtrToInt(g->builder, ptr_val, g->builtin_types.entry_usize->llvm_type, ""); |
| 6786 | 6887 | } |
| 6787 | 6888 | |
| ... | ... | @@ -6803,7 +6904,7 @@ static LLVMValueRef ir_render_frame_address(CodeGen *g, Stage1Air *executable, |
| 6803 | 6904 | Stage1AirInstFrameAddress *instruction) |
| 6804 | 6905 | { |
| 6805 | 6906 | LLVMValueRef zero = LLVMConstNull(g->builtin_types.entry_i32->llvm_type); |
| 6806 | | LLVMValueRef ptr_val = LLVMBuildCall(g->builder, get_frame_address_fn_val(g), &zero, 1, ""); |
| 6907 | LLVMValueRef ptr_val = LLVMBuildCall2(g->builder, LLVMTypeOf(get_frame_address_fn_val(g)), get_frame_address_fn_val(g), &zero, 1, ""); |
| 6807 | 6908 | return LLVMBuildPtrToInt(g->builder, ptr_val, g->builtin_types.entry_usize->llvm_type, ""); |
| 6808 | 6909 | } |
| 6809 | 6910 | |
| ... | ... | @@ -6866,7 +6967,7 @@ static LLVMValueRef ir_render_overflow_op(CodeGen *g, Stage1Air *executable, Sta |
| 6866 | 6967 | op2, |
| 6867 | 6968 | }; |
| 6868 | 6969 | |
| 6869 | | LLVMValueRef result_struct = LLVMBuildCall(g->builder, fn_val, params, 2, ""); |
| 6970 | LLVMValueRef result_struct = LLVMBuildCall2(g->builder, LLVMTypeOf(fn_val), fn_val, params, 2, ""); |
| 6870 | 6971 | LLVMValueRef result = LLVMBuildExtractValue(g->builder, result_struct, 0, ""); |
| 6871 | 6972 | LLVMValueRef overflow_bit = LLVMBuildExtractValue(g->builder, result_struct, 1, ""); |
| 6872 | 6973 | gen_store(g, result, ptr_result, instruction->result_ptr->value->type); |
| ... | ... | @@ -6881,8 +6982,9 @@ static LLVMValueRef ir_render_test_err(CodeGen *g, Stage1Air *executable, Stage1 |
| 6881 | 6982 | |
| 6882 | 6983 | LLVMValueRef err_val; |
| 6883 | 6984 | if (type_has_bits(g, payload_type)) { |
| 6884 | | LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, err_union_handle, err_union_err_index, ""); |
| 6885 | | err_val = gen_load_untyped(g, err_val_ptr, 0, false, ""); |
| 6985 | LLVMValueRef err_val_ptr = LLVMBuildStructGEP2(g->builder, |
| 6986 | get_llvm_type(g, err_union_type), err_union_handle, err_union_err_index, ""); |
| 6987 | err_val = gen_load_untyped(g, LLVMGetGEPSourceElementType(err_val_ptr), err_val_ptr, 0, false, ""); |
| 6886 | 6988 | } else { |
| 6887 | 6989 | err_val = err_union_handle; |
| 6888 | 6990 | } |
| ... | ... | @@ -6907,7 +7009,8 @@ static LLVMValueRef ir_render_unwrap_err_code(CodeGen *g, Stage1Air *executable, |
| 6907 | 7009 | } else { |
| 6908 | 7010 | // TODO assign undef to the payload |
| 6909 | 7011 | LLVMValueRef err_union_handle = get_handle_value(g, err_union_ptr, err_union_type, ptr_type); |
| 6910 | | return LLVMBuildStructGEP(g->builder, err_union_handle, err_union_err_index, ""); |
| 7012 | return LLVMBuildStructGEP2(g->builder, get_llvm_type(g, err_union_type), err_union_handle, |
| 7013 | err_union_err_index, ""); |
| 6911 | 7014 | } |
| 6912 | 7015 | } |
| 6913 | 7016 | |
| ... | ... | @@ -6946,11 +7049,14 @@ static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, Stage1Air *executab |
| 6946 | 7049 | return err_union_handle; |
| 6947 | 7050 | } |
| 6948 | 7051 | |
| 7052 | LLVMTypeRef err_union_llvm_ty = get_llvm_type(g, err_union_type); |
| 7053 | |
| 6949 | 7054 | if (want_safety) { |
| 6950 | 7055 | LLVMValueRef err_val; |
| 6951 | 7056 | if (type_has_bits(g, payload_type)) { |
| 6952 | | LLVMValueRef err_val_ptr = LLVMBuildStructGEP(g->builder, err_union_handle, err_union_err_index, ""); |
| 6953 | | err_val = gen_load_untyped(g, err_val_ptr, 0, false, ""); |
| 7057 | LLVMValueRef err_val_ptr = LLVMBuildStructGEP2(g->builder, err_union_llvm_ty, |
| 7058 | err_union_handle, err_union_err_index, ""); |
| 7059 | err_val = gen_load_untyped(g, LLVMGetGEPSourceElementType(err_val_ptr), err_val_ptr, 0, false, ""); |
| 6954 | 7060 | } else { |
| 6955 | 7061 | err_val = err_union_handle; |
| 6956 | 7062 | } |
| ... | ... | @@ -6967,11 +7073,13 @@ static LLVMValueRef ir_render_unwrap_err_payload(CodeGen *g, Stage1Air *executab |
| 6967 | 7073 | |
| 6968 | 7074 | if (type_has_bits(g, payload_type)) { |
| 6969 | 7075 | if (instruction->initializing) { |
| 6970 | | LLVMValueRef err_tag_ptr = LLVMBuildStructGEP(g->builder, err_union_handle, err_union_err_index, ""); |
| 7076 | LLVMValueRef err_tag_ptr = LLVMBuildStructGEP2(g->builder, err_union_llvm_ty, |
| 7077 | err_union_handle, err_union_err_index, ""); |
| 6971 | 7078 | LLVMValueRef ok_err_val = LLVMConstNull(get_llvm_type(g, g->err_tag_type)); |
| 6972 | 7079 | gen_store_untyped(g, ok_err_val, err_tag_ptr, 0, false); |
| 6973 | 7080 | } |
| 6974 | | return LLVMBuildStructGEP(g->builder, err_union_handle, err_union_payload_index, ""); |
| 7081 | return LLVMBuildStructGEP2(g->builder, err_union_llvm_ty, err_union_handle, |
| 7082 | err_union_payload_index, ""); |
| 6975 | 7083 | } else { |
| 6976 | 7084 | if (instruction->initializing) { |
| 6977 | 7085 | gen_store_untyped(g, zero, err_union_ptr, 0, false); |
| ... | ... | @@ -7006,11 +7114,14 @@ static LLVMValueRef ir_render_optional_wrap(CodeGen *g, Stage1Air *executable, S |
| 7006 | 7114 | } |
| 7007 | 7115 | |
| 7008 | 7116 | LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc); |
| 7117 | LLVMTypeRef result_llvm_struct_ty = get_llvm_type(g, wanted_type); |
| 7009 | 7118 | |
| 7010 | | LLVMValueRef val_ptr = LLVMBuildStructGEP(g->builder, result_loc, maybe_child_index, ""); |
| 7119 | LLVMValueRef val_ptr = LLVMBuildStructGEP2(g->builder, result_llvm_struct_ty, result_loc, |
| 7120 | maybe_child_index, ""); |
| 7011 | 7121 | // child_type and instruction->value->value->type may differ by constness |
| 7012 | 7122 | gen_assign_raw(g, val_ptr, get_pointer_to_type(g, child_type, false), payload_val); |
| 7013 | | LLVMValueRef maybe_ptr = LLVMBuildStructGEP(g->builder, result_loc, maybe_null_index, ""); |
| 7123 | LLVMValueRef maybe_ptr = LLVMBuildStructGEP2(g->builder, result_llvm_struct_ty, result_loc, |
| 7124 | maybe_null_index, ""); |
| 7014 | 7125 | gen_store_untyped(g, LLVMConstAllOnes(LLVMInt1Type()), maybe_ptr, 0, false); |
| 7015 | 7126 | |
| 7016 | 7127 | return result_loc; |
| ... | ... | @@ -7028,7 +7139,8 @@ static LLVMValueRef ir_render_err_wrap_code(CodeGen *g, Stage1Air *executable, S |
| 7028 | 7139 | |
| 7029 | 7140 | LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc); |
| 7030 | 7141 | |
| 7031 | | LLVMValueRef err_tag_ptr = LLVMBuildStructGEP(g->builder, result_loc, err_union_err_index, ""); |
| 7142 | LLVMValueRef err_tag_ptr = LLVMBuildStructGEP2(g->builder, get_llvm_type(g, wanted_type), |
| 7143 | result_loc, err_union_err_index, ""); |
| 7032 | 7144 | gen_store_untyped(g, err_val, err_tag_ptr, 0, false); |
| 7033 | 7145 | |
| 7034 | 7146 | // TODO store undef to the payload |
| ... | ... | @@ -7057,11 +7169,14 @@ static LLVMValueRef ir_render_err_wrap_payload(CodeGen *g, Stage1Air *executable |
| 7057 | 7169 | LLVMValueRef result_loc = ir_llvm_value(g, instruction->result_loc); |
| 7058 | 7170 | |
| 7059 | 7171 | LLVMValueRef payload_val = ir_llvm_value(g, instruction->operand); |
| 7172 | LLVMTypeRef result_struct_llvm_ty = get_llvm_type(g, wanted_type); |
| 7060 | 7173 | |
| 7061 | | LLVMValueRef err_tag_ptr = LLVMBuildStructGEP(g->builder, result_loc, err_union_err_index, ""); |
| 7174 | LLVMValueRef err_tag_ptr = LLVMBuildStructGEP2(g->builder, result_struct_llvm_ty, result_loc, |
| 7175 | err_union_err_index, ""); |
| 7062 | 7176 | gen_store_untyped(g, ok_err_val, err_tag_ptr, 0, false); |
| 7063 | 7177 | |
| 7064 | | LLVMValueRef payload_ptr = LLVMBuildStructGEP(g->builder, result_loc, err_union_payload_index, ""); |
| 7178 | LLVMValueRef payload_ptr = LLVMBuildStructGEP2(g->builder, result_struct_llvm_ty, result_loc, |
| 7179 | err_union_payload_index, ""); |
| 7065 | 7180 | gen_assign_raw(g, payload_ptr, get_pointer_to_type(g, payload_type, false), payload_val); |
| 7066 | 7181 | |
| 7067 | 7182 | return result_loc; |
| ... | ... | @@ -7079,7 +7194,8 @@ static LLVMValueRef ir_render_union_tag(CodeGen *g, Stage1Air *executable, Stage |
| 7079 | 7194 | return union_val; |
| 7080 | 7195 | |
| 7081 | 7196 | assert(union_type->data.unionation.gen_tag_index != SIZE_MAX); |
| 7082 | | LLVMValueRef tag_field_ptr = LLVMBuildStructGEP(g->builder, union_val, |
| 7197 | LLVMValueRef tag_field_ptr = LLVMBuildStructGEP2(g->builder, |
| 7198 | get_llvm_type(g, union_type), union_val, |
| 7083 | 7199 | union_type->data.unionation.gen_tag_index, ""); |
| 7084 | 7200 | ZigType *ptr_type = get_pointer_to_type(g, tag_type, false); |
| 7085 | 7201 | return get_handle_value(g, tag_field_ptr, tag_type, ptr_type); |
| ... | ... | @@ -7221,14 +7337,12 @@ static LLVMValueRef ir_render_soft_mul_add(CodeGen *g, Stage1Air *executable, St |
| 7221 | 7337 | LLVMValueRef op1 = ir_llvm_value(g, instruction->op1); |
| 7222 | 7338 | LLVMValueRef op2 = ir_llvm_value(g, instruction->op2); |
| 7223 | 7339 | LLVMValueRef op3 = ir_llvm_value(g, instruction->op3); |
| 7224 | | LLVMValueRef result; |
| 7225 | 7340 | if (vector_len == 0) { |
| 7226 | 7341 | LLVMValueRef params[3] = { op1, op2, op3 }; |
| 7227 | | result = LLVMBuildCall(g->builder, func_ref, params, 3, ""); |
| 7228 | | } else { |
| 7229 | | result = build_alloca(g, instruction->op1->value->type, "", 0); |
| 7342 | return LLVMBuildCall2(g->builder, LLVMTypeOf(func_ref), func_ref, params, 3, ""); |
| 7230 | 7343 | } |
| 7231 | 7344 | |
| 7345 | LLVMValueRef result = LLVMGetUndef(get_llvm_type(g, instruction->op1->value->type)); |
| 7232 | 7346 | LLVMTypeRef usize_ref = g->builtin_types.entry_usize->llvm_type; |
| 7233 | 7347 | for (uint32_t i = 0; i < vector_len; i++) { |
| 7234 | 7348 | LLVMValueRef index_value = LLVMConstInt(usize_ref, i, false); |
| ... | ... | @@ -7238,12 +7352,8 @@ static LLVMValueRef ir_render_soft_mul_add(CodeGen *g, Stage1Air *executable, St |
| 7238 | 7352 | LLVMBuildExtractElement(g->builder, op2, index_value, ""), |
| 7239 | 7353 | LLVMBuildExtractElement(g->builder, op3, index_value, ""), |
| 7240 | 7354 | }; |
| 7241 | | LLVMValueRef call_result = LLVMBuildCall(g->builder, func_ref, params, 3, ""); |
| 7242 | | LLVMBuildInsertElement(g->builder, LLVMBuildLoad(g->builder, result, ""), |
| 7243 | | call_result, index_value, ""); |
| 7244 | | } |
| 7245 | | if (vector_len != 0) { |
| 7246 | | result = LLVMBuildLoad(g->builder, result, ""); |
| 7355 | LLVMValueRef call_result = LLVMBuildCall2(g->builder, LLVMTypeOf(func_ref), func_ref, params, 3, ""); |
| 7356 | result = LLVMBuildInsertElement(g->builder, result, call_result, index_value, ""); |
| 7247 | 7357 | } |
| 7248 | 7358 | return result; |
| 7249 | 7359 | } |
| ... | ... | @@ -7262,7 +7372,7 @@ static LLVMValueRef ir_render_mul_add(CodeGen *g, Stage1Air *executable, Stage1A |
| 7262 | 7372 | instruction->base.value->type->id == ZigTypeIdVector); |
| 7263 | 7373 | LLVMValueRef fn_val = get_float_fn(g, instruction->base.value->type, ZigLLVMFnIdFMA, BuiltinFnIdMulAdd); |
| 7264 | 7374 | LLVMValueRef args[3] = { op1, op2, op3 }; |
| 7265 | | return LLVMBuildCall(g->builder, fn_val, args, 3, ""); |
| 7375 | return LLVMBuildCall2(g->builder, LLVMTypeOf(fn_val), fn_val, args, 3, ""); |
| 7266 | 7376 | } |
| 7267 | 7377 | |
| 7268 | 7378 | static LLVMValueRef ir_render_bswap(CodeGen *g, Stage1Air *executable, Stage1AirInstBswap *instruction) { |
| ... | ... | @@ -7273,7 +7383,7 @@ static LLVMValueRef ir_render_bswap(CodeGen *g, Stage1Air *executable, Stage1Air |
| 7273 | 7383 | assert(int_type->id == ZigTypeIdInt); |
| 7274 | 7384 | if (int_type->data.integral.bit_count % 16 == 0) { |
| 7275 | 7385 | LLVMValueRef fn_val = get_int_builtin_fn(g, expr_type, BuiltinFnIdBswap); |
| 7276 | | return LLVMBuildCall(g->builder, fn_val, &op, 1, ""); |
| 7386 | return LLVMBuildCall2(g->builder, LLVMTypeOf(fn_val), fn_val, &op, 1, ""); |
| 7277 | 7387 | } |
| 7278 | 7388 | // Not an even number of bytes, so we zext 1 byte, then bswap, shift right 1 byte, truncate |
| 7279 | 7389 | ZigType *extended_type = get_int_type(g, int_type->data.integral.is_signed, |
| ... | ... | @@ -7292,7 +7402,7 @@ static LLVMValueRef ir_render_bswap(CodeGen *g, Stage1Air *executable, Stage1Air |
| 7292 | 7402 | LLVMValueRef extended = LLVMBuildZExt(g->builder, op, get_llvm_type(g, extended_type), ""); |
| 7293 | 7403 | // 00aabbcc |
| 7294 | 7404 | LLVMValueRef fn_val = get_int_builtin_fn(g, extended_type, BuiltinFnIdBswap); |
| 7295 | | LLVMValueRef swapped = LLVMBuildCall(g->builder, fn_val, &extended, 1, ""); |
| 7405 | LLVMValueRef swapped = LLVMBuildCall2(g->builder, LLVMTypeOf(fn_val), fn_val, &extended, 1, ""); |
| 7296 | 7406 | // ccbbaa00 |
| 7297 | 7407 | LLVMValueRef shifted = ZigLLVMBuildLShrExact(g->builder, swapped, shift_amt, ""); |
| 7298 | 7408 | // 00ccbbaa |
| ... | ... | @@ -7328,7 +7438,7 @@ static LLVMValueRef ir_render_bit_reverse(CodeGen *g, Stage1Air *executable, Sta |
| 7328 | 7438 | ZigType *int_type = instruction->base.value->type; |
| 7329 | 7439 | assert(int_type->id == ZigTypeIdInt); |
| 7330 | 7440 | LLVMValueRef fn_val = get_int_builtin_fn(g, instruction->base.value->type, BuiltinFnIdBitReverse); |
| 7331 | | return LLVMBuildCall(g->builder, fn_val, &op, 1, ""); |
| 7441 | return LLVMBuildCall2(g->builder, LLVMTypeOf(fn_val), fn_val, &op, 1, ""); |
| 7332 | 7442 | } |
| 7333 | 7443 | |
| 7334 | 7444 | static LLVMValueRef ir_render_vector_to_array(CodeGen *g, Stage1Air *executable, |
| ... | ... | @@ -7341,6 +7451,7 @@ static LLVMValueRef ir_render_vector_to_array(CodeGen *g, Stage1Air *executable, |
| 7341 | 7451 | LLVMValueRef vector = ir_llvm_value(g, instruction->vector); |
| 7342 | 7452 | |
| 7343 | 7453 | ZigType *elem_type = array_type->data.array.child_type; |
| 7454 | LLVMTypeRef elem_llvm_ty = get_llvm_type(g, elem_type); |
| 7344 | 7455 | bool bitcast_ok = elem_type->size_in_bits == elem_type->abi_size * 8; |
| 7345 | 7456 | if (bitcast_ok) { |
| 7346 | 7457 | LLVMValueRef casted_ptr = LLVMBuildBitCast(g->builder, result_loc, |
| ... | ... | @@ -7357,7 +7468,7 @@ static LLVMValueRef ir_render_vector_to_array(CodeGen *g, Stage1Air *executable, |
| 7357 | 7468 | LLVMValueRef index_usize = LLVMConstInt(usize_type_ref, i, false); |
| 7358 | 7469 | LLVMValueRef index_u32 = LLVMConstInt(u32_type_ref, i, false); |
| 7359 | 7470 | LLVMValueRef indexes[] = { zero, index_usize }; |
| 7360 | | LLVMValueRef elem_ptr = LLVMBuildInBoundsGEP(g->builder, result_loc, indexes, 2, ""); |
| 7471 | LLVMValueRef elem_ptr = LLVMBuildInBoundsGEP2(g->builder, elem_llvm_ty, result_loc, indexes, 2, ""); |
| 7361 | 7472 | LLVMValueRef elem = LLVMBuildExtractElement(g->builder, vector, index_u32, ""); |
| 7362 | 7473 | LLVMBuildStore(g->builder, elem, elem_ptr); |
| 7363 | 7474 | } |
| ... | ... | @@ -7377,12 +7488,10 @@ static LLVMValueRef ir_render_array_to_vector(CodeGen *g, Stage1Air *executable, |
| 7377 | 7488 | ZigType *elem_type = vector_type->data.vector.elem_type; |
| 7378 | 7489 | bool bitcast_ok = elem_type->size_in_bits == elem_type->abi_size * 8; |
| 7379 | 7490 | if (bitcast_ok) { |
| 7380 | | LLVMValueRef casted_ptr = LLVMBuildBitCast(g->builder, array_ptr, |
| 7381 | | LLVMPointerType(vector_type_ref, 0), ""); |
| 7382 | 7491 | ZigType *array_type = instruction->array->value->type; |
| 7383 | 7492 | assert(array_type->id == ZigTypeIdArray); |
| 7384 | 7493 | uint32_t alignment = get_abi_alignment(g, array_type->data.array.child_type); |
| 7385 | | return gen_load_untyped(g, casted_ptr, alignment, false, ""); |
| 7494 | return gen_load_untyped(g, vector_type_ref, array_ptr, alignment, false, ""); |
| 7386 | 7495 | } else { |
| 7387 | 7496 | // If the ABI size of the element type is not evenly divisible by size_in_bits, a simple bitcast |
| 7388 | 7497 | // will not work, and we fall back to insertelement. |
| ... | ... | @@ -7390,12 +7499,14 @@ static LLVMValueRef ir_render_array_to_vector(CodeGen *g, Stage1Air *executable, |
| 7390 | 7499 | LLVMTypeRef u32_type_ref = LLVMInt32Type(); |
| 7391 | 7500 | LLVMValueRef zero = LLVMConstInt(usize_type_ref, 0, false); |
| 7392 | 7501 | LLVMValueRef vector = LLVMGetUndef(vector_type_ref); |
| 7502 | LLVMTypeRef elem_llvm_ty = get_llvm_type(g, elem_type); |
| 7393 | 7503 | for (uintptr_t i = 0; i < instruction->base.value->type->data.vector.len; i++) { |
| 7394 | 7504 | LLVMValueRef index_usize = LLVMConstInt(usize_type_ref, i, false); |
| 7395 | 7505 | LLVMValueRef index_u32 = LLVMConstInt(u32_type_ref, i, false); |
| 7396 | 7506 | LLVMValueRef indexes[] = { zero, index_usize }; |
| 7397 | | LLVMValueRef elem_ptr = LLVMBuildInBoundsGEP(g->builder, array_ptr, indexes, 2, ""); |
| 7398 | | LLVMValueRef elem = LLVMBuildLoad(g->builder, elem_ptr, ""); |
| 7507 | LLVMValueRef elem_ptr = LLVMBuildInBoundsGEP2(g->builder, elem_llvm_ty, array_ptr, |
| 7508 | indexes, 2, ""); |
| 7509 | LLVMValueRef elem = LLVMBuildLoad2(g->builder, elem_llvm_ty, elem_ptr, ""); |
| 7399 | 7510 | vector = LLVMBuildInsertElement(g->builder, vector, elem, index_u32, ""); |
| 7400 | 7511 | } |
| 7401 | 7512 | return vector; |
| ... | ... | @@ -7461,14 +7572,16 @@ static LLVMValueRef ir_render_suspend_finish(CodeGen *g, Stage1Air *executable, |
| 7461 | 7572 | } |
| 7462 | 7573 | |
| 7463 | 7574 | static LLVMValueRef gen_await_early_return(CodeGen *g, Stage1AirInst *source_instr, |
| 7464 | | LLVMValueRef target_frame_ptr, ZigType *result_type, ZigType *ptr_result_type, |
| 7465 | | LLVMValueRef result_loc, bool non_async) |
| 7575 | LLVMTypeRef target_frame_struct_llvm_ty, LLVMValueRef target_frame_ptr, |
| 7576 | ZigType *result_type, ZigType *ptr_result_type, LLVMValueRef result_loc, bool non_async) |
| 7466 | 7577 | { |
| 7467 | 7578 | LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type; |
| 7468 | 7579 | LLVMValueRef their_result_ptr = nullptr; |
| 7469 | 7580 | if (type_has_bits(g, result_type) && (non_async || result_loc != nullptr)) { |
| 7470 | | LLVMValueRef their_result_ptr_ptr = LLVMBuildStructGEP(g->builder, target_frame_ptr, frame_ret_start, ""); |
| 7471 | | their_result_ptr = LLVMBuildLoad(g->builder, their_result_ptr_ptr, ""); |
| 7581 | LLVMValueRef their_result_ptr_ptr = LLVMBuildStructGEP2(g->builder, |
| 7582 | target_frame_struct_llvm_ty, target_frame_ptr, frame_ret_start, ""); |
| 7583 | their_result_ptr = LLVMBuildLoad2(g->builder, |
| 7584 | LLVMGetGEPSourceElementType(their_result_ptr_ptr), their_result_ptr_ptr, ""); |
| 7472 | 7585 | if (result_loc != nullptr) { |
| 7473 | 7586 | LLVMTypeRef ptr_u8 = LLVMPointerType(LLVMInt8Type(), 0); |
| 7474 | 7587 | LLVMValueRef dest_ptr_casted = LLVMBuildBitCast(g->builder, result_loc, ptr_u8, ""); |
| ... | ... | @@ -7482,13 +7595,16 @@ static LLVMValueRef gen_await_early_return(CodeGen *g, Stage1AirInst *source_ins |
| 7482 | 7595 | } |
| 7483 | 7596 | } |
| 7484 | 7597 | if (codegen_fn_has_err_ret_tracing_arg(g, result_type)) { |
| 7485 | | LLVMValueRef their_trace_ptr_ptr = LLVMBuildStructGEP(g->builder, target_frame_ptr, |
| 7598 | LLVMValueRef their_trace_ptr_ptr = LLVMBuildStructGEP2(g->builder, |
| 7599 | target_frame_struct_llvm_ty, target_frame_ptr, |
| 7486 | 7600 | frame_index_trace_arg(g, result_type), ""); |
| 7487 | | LLVMValueRef src_trace_ptr = LLVMBuildLoad(g->builder, their_trace_ptr_ptr, ""); |
| 7601 | LLVMValueRef src_trace_ptr = LLVMBuildLoad2(g->builder, |
| 7602 | LLVMGetGEPSourceElementType(their_trace_ptr_ptr), their_trace_ptr_ptr, ""); |
| 7488 | 7603 | bool is_llvm_alloca; |
| 7489 | 7604 | LLVMValueRef dest_trace_ptr = get_cur_err_ret_trace_val(g, source_instr->scope, &is_llvm_alloca); |
| 7490 | 7605 | LLVMValueRef args[] = { dest_trace_ptr, src_trace_ptr }; |
| 7491 | | ZigLLVMBuildCall(g->builder, get_merge_err_ret_traces_fn_val(g), args, 2, |
| 7606 | ZigLLVMBuildCall(g->builder, LLVMTypeOf(get_merge_err_ret_traces_fn_val(g)), |
| 7607 | get_merge_err_ret_traces_fn_val(g), args, 2, |
| 7492 | 7608 | get_llvm_cc(g, CallingConventionUnspecified), ZigLLVM_CallAttrAuto, ""); |
| 7493 | 7609 | } |
| 7494 | 7610 | if (non_async && type_has_bits(g, result_type)) { |
| ... | ... | @@ -7503,6 +7619,8 @@ static LLVMValueRef ir_render_await(CodeGen *g, Stage1Air *executable, Stage1Air |
| 7503 | 7619 | LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type; |
| 7504 | 7620 | LLVMValueRef zero = LLVMConstNull(usize_type_ref); |
| 7505 | 7621 | LLVMValueRef target_frame_ptr = ir_llvm_value(g, instruction->frame); |
| 7622 | LLVMTypeRef target_frame_llvm_ty = get_llvm_type(g, |
| 7623 | instruction->frame->value->type->data.pointer.child_type); |
| 7506 | 7624 | ZigType *result_type = instruction->base.value->type; |
| 7507 | 7625 | ZigType *ptr_result_type = get_pointer_to_type(g, result_type, true); |
| 7508 | 7626 | |
| ... | ... | @@ -7512,8 +7630,8 @@ static LLVMValueRef ir_render_await(CodeGen *g, Stage1Air *executable, Stage1Air |
| 7512 | 7630 | if (instruction->is_nosuspend || |
| 7513 | 7631 | (instruction->target_fn != nullptr && !fn_is_async(instruction->target_fn))) |
| 7514 | 7632 | { |
| 7515 | | return gen_await_early_return(g, &instruction->base, target_frame_ptr, result_type, |
| 7516 | | ptr_result_type, result_loc, true); |
| 7633 | return gen_await_early_return(g, &instruction->base, target_frame_llvm_ty, |
| 7634 | target_frame_ptr, result_type, ptr_result_type, result_loc, true); |
| 7517 | 7635 | } |
| 7518 | 7636 | |
| 7519 | 7637 | // Prepare to be suspended |
| ... | ... | @@ -7525,7 +7643,8 @@ static LLVMValueRef ir_render_await(CodeGen *g, Stage1Air *executable, Stage1Air |
| 7525 | 7643 | |
| 7526 | 7644 | // supply the awaiter return pointer |
| 7527 | 7645 | if (type_has_bits(g, result_type)) { |
| 7528 | | LLVMValueRef awaiter_ret_ptr_ptr = LLVMBuildStructGEP(g->builder, target_frame_ptr, frame_ret_start + 1, ""); |
| 7646 | LLVMValueRef awaiter_ret_ptr_ptr = LLVMBuildStructGEP2(g->builder, target_frame_llvm_ty, |
| 7647 | target_frame_ptr, frame_ret_start + 1, ""); |
| 7529 | 7648 | if (result_loc == nullptr) { |
| 7530 | 7649 | // no copy needed |
| 7531 | 7650 | LLVMBuildStore(g->builder, LLVMConstNull(LLVMGetElementType(LLVMTypeOf(awaiter_ret_ptr_ptr))), |
| ... | ... | @@ -7540,14 +7659,15 @@ static LLVMValueRef ir_render_await(CodeGen *g, Stage1Air *executable, Stage1Air |
| 7540 | 7659 | bool is_llvm_alloca; |
| 7541 | 7660 | LLVMValueRef my_err_ret_trace_val = get_cur_err_ret_trace_val(g, instruction->base.scope, &is_llvm_alloca); |
| 7542 | 7661 | assert(my_err_ret_trace_val != nullptr); |
| 7543 | | LLVMValueRef err_ret_trace_ptr_ptr = LLVMBuildStructGEP(g->builder, target_frame_ptr, |
| 7544 | | frame_index_trace_arg(g, result_type) + 1, ""); |
| 7662 | LLVMValueRef err_ret_trace_ptr_ptr = LLVMBuildStructGEP2(g->builder, target_frame_llvm_ty, |
| 7663 | target_frame_ptr, frame_index_trace_arg(g, result_type) + 1, ""); |
| 7545 | 7664 | LLVMBuildStore(g->builder, my_err_ret_trace_val, err_ret_trace_ptr_ptr); |
| 7546 | 7665 | } |
| 7547 | 7666 | |
| 7548 | 7667 | // caller's own frame pointer |
| 7549 | 7668 | LLVMValueRef awaiter_init_val = LLVMBuildPtrToInt(g->builder, g->cur_frame_ptr, usize_type_ref, ""); |
| 7550 | | LLVMValueRef awaiter_ptr = LLVMBuildStructGEP(g->builder, target_frame_ptr, frame_awaiter_index, ""); |
| 7669 | LLVMValueRef awaiter_ptr = LLVMBuildStructGEP2(g->builder, target_frame_llvm_ty, |
| 7670 | target_frame_ptr, frame_awaiter_index, ""); |
| 7551 | 7671 | LLVMValueRef prev_val = gen_maybe_atomic_op(g, LLVMAtomicRMWBinOpXchg, awaiter_ptr, awaiter_init_val, |
| 7552 | 7672 | LLVMAtomicOrderingRelease); |
| 7553 | 7673 | |
| ... | ... | @@ -7572,8 +7692,8 @@ static LLVMValueRef ir_render_await(CodeGen *g, Stage1Air *executable, Stage1Air |
| 7572 | 7692 | // Early return: The async function has already completed. We must copy the result and |
| 7573 | 7693 | // the error return trace if applicable. |
| 7574 | 7694 | LLVMPositionBuilderAtEnd(g->builder, early_return_block); |
| 7575 | | gen_await_early_return(g, &instruction->base, target_frame_ptr, result_type, ptr_result_type, |
| 7576 | | result_loc, false); |
| 7695 | gen_await_early_return(g, &instruction->base, target_frame_llvm_ty, target_frame_ptr, |
| 7696 | result_type, ptr_result_type, result_loc, false); |
| 7577 | 7697 | LLVMBuildBr(g->builder, end_bb); |
| 7578 | 7698 | |
| 7579 | 7699 | LLVMPositionBuilderAtEnd(g->builder, resume_bb); |
| ... | ... | @@ -7631,7 +7751,8 @@ static LLVMValueRef ir_render_spill_end(CodeGen *g, Stage1Air *executable, Stage |
| 7631 | 7751 | zig_unreachable(); |
| 7632 | 7752 | case SpillIdRetErrCode: { |
| 7633 | 7753 | LLVMValueRef ptr = ir_llvm_value(g, g->cur_fn->err_code_spill); |
| 7634 | | return LLVMBuildLoad(g->builder, ptr, ""); |
| 7754 | LLVMTypeRef llvm_ty = g->builtin_types.entry_global_error_set->llvm_type; |
| 7755 | return LLVMBuildLoad2(g->builder, llvm_ty, ptr, ""); |
| 7635 | 7756 | } |
| 7636 | 7757 | |
| 7637 | 7758 | } |
| ... | ... | @@ -7923,24 +8044,12 @@ static LLVMValueRef gen_const_ptr_array_recursive(CodeGen *g, ZigValue *array_co |
| 7923 | 8044 | ConstParent *parent = &array_const_val->parent; |
| 7924 | 8045 | LLVMValueRef base_ptr = gen_parent_ptr(g, array_const_val, parent); |
| 7925 | 8046 | |
| 7926 | | LLVMTypeKind el_type = LLVMGetTypeKind(LLVMGetElementType(LLVMTypeOf(base_ptr))); |
| 7927 | | if (el_type == LLVMArrayTypeKind) { |
| 7928 | | ZigType *usize = g->builtin_types.entry_usize; |
| 7929 | | LLVMValueRef indices[] = { |
| 7930 | | LLVMConstNull(usize->llvm_type), |
| 7931 | | LLVMConstInt(usize->llvm_type, index, false), |
| 7932 | | }; |
| 7933 | | return LLVMConstInBoundsGEP(base_ptr, indices, 2); |
| 7934 | | } else if (el_type == LLVMStructTypeKind) { |
| 7935 | | ZigType *u32 = g->builtin_types.entry_u32; |
| 7936 | | LLVMValueRef indices[] = { |
| 7937 | | LLVMConstNull(get_llvm_type(g, u32)), |
| 7938 | | LLVMConstInt(get_llvm_type(g, u32), index, false), |
| 7939 | | }; |
| 7940 | | return LLVMConstInBoundsGEP(base_ptr, indices, 2); |
| 7941 | | } else { |
| 7942 | | return base_ptr; |
| 7943 | | } |
| 8047 | ZigType *usize = g->builtin_types.entry_usize; |
| 8048 | LLVMValueRef indices[] = { |
| 8049 | LLVMConstNull(usize->llvm_type), |
| 8050 | LLVMConstInt(usize->llvm_type, index, false), |
| 8051 | }; |
| 8052 | return LLVMConstInBoundsGEP2(get_llvm_type(g, array_const_val->type), base_ptr, indices, 2); |
| 7944 | 8053 | } |
| 7945 | 8054 | |
| 7946 | 8055 | static LLVMValueRef gen_const_ptr_struct_recursive(CodeGen *g, ZigValue *struct_const_val, size_t field_index) { |
| ... | ... | @@ -7957,9 +8066,7 @@ static LLVMValueRef gen_const_ptr_struct_recursive(CodeGen *g, ZigValue *struct_ |
| 7957 | 8066 | // alignment purposes and have the following LLVM type: <{ %T, [N x i8] }>. |
| 7958 | 8067 | // Add an extra bitcast as we're only interested in the %T part. |
| 7959 | 8068 | assert(handle_is_ptr(g, struct_const_val->type)); |
| 7960 | | LLVMValueRef casted_base_ptr = LLVMConstBitCast(base_ptr, |
| 7961 | | LLVMPointerType(get_llvm_type(g, struct_const_val->type), 0)); |
| 7962 | | return LLVMConstInBoundsGEP(casted_base_ptr, indices, 2); |
| 8069 | return LLVMConstInBoundsGEP2(get_llvm_type(g, struct_const_val->type), base_ptr, indices, 2); |
| 7963 | 8070 | } |
| 7964 | 8071 | |
| 7965 | 8072 | static LLVMValueRef gen_const_ptr_err_union_code_recursive(CodeGen *g, ZigValue *err_union_const_val) { |
| ... | ... | @@ -7971,7 +8078,7 @@ static LLVMValueRef gen_const_ptr_err_union_code_recursive(CodeGen *g, ZigValue |
| 7971 | 8078 | LLVMConstNull(get_llvm_type(g, u32)), |
| 7972 | 8079 | LLVMConstInt(get_llvm_type(g, u32), err_union_err_index, false), |
| 7973 | 8080 | }; |
| 7974 | | return LLVMConstInBoundsGEP(base_ptr, indices, 2); |
| 8081 | return LLVMConstInBoundsGEP2(get_llvm_type(g, err_union_const_val->type), base_ptr, indices, 2); |
| 7975 | 8082 | } |
| 7976 | 8083 | |
| 7977 | 8084 | static LLVMValueRef gen_const_ptr_err_union_payload_recursive(CodeGen *g, ZigValue *err_union_const_val) { |
| ... | ... | @@ -7983,7 +8090,7 @@ static LLVMValueRef gen_const_ptr_err_union_payload_recursive(CodeGen *g, ZigVal |
| 7983 | 8090 | LLVMConstNull(get_llvm_type(g, u32)), |
| 7984 | 8091 | LLVMConstInt(get_llvm_type(g, u32), err_union_payload_index, false), |
| 7985 | 8092 | }; |
| 7986 | | return LLVMConstInBoundsGEP(base_ptr, indices, 2); |
| 8093 | return LLVMConstInBoundsGEP2(get_llvm_type(g, err_union_const_val->type), base_ptr, indices, 2); |
| 7987 | 8094 | } |
| 7988 | 8095 | |
| 7989 | 8096 | static LLVMValueRef gen_const_ptr_optional_payload_recursive(CodeGen *g, ZigValue *optional_const_val) { |
| ... | ... | @@ -7995,7 +8102,7 @@ static LLVMValueRef gen_const_ptr_optional_payload_recursive(CodeGen *g, ZigValu |
| 7995 | 8102 | LLVMConstNull(get_llvm_type(g, u32)), |
| 7996 | 8103 | LLVMConstInt(get_llvm_type(g, u32), maybe_child_index, false), |
| 7997 | 8104 | }; |
| 7998 | | return LLVMConstInBoundsGEP(base_ptr, indices, 2); |
| 8105 | return LLVMConstInBoundsGEP2(get_llvm_type(g, optional_const_val->type), base_ptr, indices, 2); |
| 7999 | 8106 | } |
| 8000 | 8107 | |
| 8001 | 8108 | static LLVMValueRef gen_const_ptr_union_recursive(CodeGen *g, ZigValue *union_const_val) { |
| ... | ... | @@ -8012,7 +8119,7 @@ static LLVMValueRef gen_const_ptr_union_recursive(CodeGen *g, ZigValue *union_co |
| 8012 | 8119 | LLVMConstNull(get_llvm_type(g, u32)), |
| 8013 | 8120 | LLVMConstInt(get_llvm_type(g, u32), union_payload_index, false), |
| 8014 | 8121 | }; |
| 8015 | | return LLVMConstInBoundsGEP(base_ptr, indices, (union_payload_index != SIZE_MAX) ? 2 : 1); |
| 8122 | return LLVMConstInBoundsGEP2(get_llvm_type(g, union_const_val->type), base_ptr, indices, (union_payload_index != SIZE_MAX) ? 2 : 1); |
| 8016 | 8123 | } |
| 8017 | 8124 | |
| 8018 | 8125 | static LLVMValueRef pack_const_int(CodeGen *g, LLVMTypeRef big_int_type_ref, ZigValue *const_val) { |
| ... | ... | @@ -9206,28 +9313,38 @@ static void do_code_gen(CodeGen *g) { |
| 9206 | 9313 | } |
| 9207 | 9314 | } |
| 9208 | 9315 | |
| 9316 | LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type; |
| 9317 | |
| 9209 | 9318 | // finishing error return trace setup. we have to do this after all the allocas. |
| 9210 | 9319 | if (have_err_ret_trace_stack) { |
| 9211 | 9320 | ZigType *usize = g->builtin_types.entry_usize; |
| 9212 | 9321 | size_t index_field_index = g->stack_trace_type->data.structure.fields[0]->gen_index; |
| 9213 | | LLVMValueRef index_field_ptr = LLVMBuildStructGEP(g->builder, g->cur_err_ret_trace_val_stack, (unsigned)index_field_index, ""); |
| 9322 | LLVMValueRef index_field_ptr = LLVMBuildStructGEP2(g->builder, |
| 9323 | get_llvm_type(g, g->stack_trace_type), |
| 9324 | g->cur_err_ret_trace_val_stack, (unsigned)index_field_index, ""); |
| 9214 | 9325 | gen_store_untyped(g, LLVMConstNull(usize->llvm_type), index_field_ptr, 0, false); |
| 9215 | 9326 | |
| 9216 | 9327 | size_t addresses_field_index = g->stack_trace_type->data.structure.fields[1]->gen_index; |
| 9217 | | LLVMValueRef addresses_field_ptr = LLVMBuildStructGEP(g->builder, g->cur_err_ret_trace_val_stack, (unsigned)addresses_field_index, ""); |
| 9328 | LLVMValueRef addresses_field_ptr = LLVMBuildStructGEP2(g->builder, |
| 9329 | get_llvm_type(g, g->stack_trace_type), |
| 9330 | g->cur_err_ret_trace_val_stack, (unsigned)addresses_field_index, ""); |
| 9218 | 9331 | |
| 9219 | 9332 | ZigType *slice_type = g->stack_trace_type->data.structure.fields[1]->type_entry; |
| 9220 | 9333 | size_t ptr_field_index = slice_type->data.structure.fields[slice_ptr_index]->gen_index; |
| 9221 | | LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP(g->builder, addresses_field_ptr, (unsigned)ptr_field_index, ""); |
| 9334 | LLVMValueRef ptr_field_ptr = LLVMBuildStructGEP2(g->builder, |
| 9335 | LLVMGetGEPSourceElementType(addresses_field_ptr), |
| 9336 | addresses_field_ptr, (unsigned)ptr_field_index, ""); |
| 9222 | 9337 | LLVMValueRef zero = LLVMConstNull(usize->llvm_type); |
| 9223 | 9338 | LLVMValueRef indices[] = {zero, zero}; |
| 9224 | | LLVMValueRef err_ret_array_val_elem0_ptr = LLVMBuildInBoundsGEP(g->builder, err_ret_array_val, |
| 9225 | | indices, 2, ""); |
| 9339 | LLVMValueRef err_ret_array_val_elem0_ptr = LLVMBuildInBoundsGEP2(g->builder, |
| 9340 | usize_type_ref, err_ret_array_val, indices, 2, ""); |
| 9226 | 9341 | ZigType *ptr_ptr_usize_type = get_pointer_to_type(g, get_pointer_to_type(g, usize, false), false); |
| 9227 | 9342 | gen_store(g, err_ret_array_val_elem0_ptr, ptr_field_ptr, ptr_ptr_usize_type); |
| 9228 | 9343 | |
| 9229 | 9344 | size_t len_field_index = slice_type->data.structure.fields[slice_len_index]->gen_index; |
| 9230 | | LLVMValueRef len_field_ptr = LLVMBuildStructGEP(g->builder, addresses_field_ptr, (unsigned)len_field_index, ""); |
| 9345 | LLVMValueRef len_field_ptr = LLVMBuildStructGEP2(g->builder, |
| 9346 | LLVMGetGEPSourceElementType(addresses_field_ptr), |
| 9347 | addresses_field_ptr, (unsigned)len_field_index, ""); |
| 9231 | 9348 | gen_store(g, LLVMConstInt(usize->llvm_type, stack_trace_ptr_count, false), len_field_ptr, get_pointer_to_type(g, usize, false)); |
| 9232 | 9349 | } |
| 9233 | 9350 | |
| ... | ... | @@ -9235,7 +9352,6 @@ static void do_code_gen(CodeGen *g) { |
| 9235 | 9352 | (void)get_llvm_type(g, fn_table_entry->frame_type); |
| 9236 | 9353 | g->cur_resume_block_count = 0; |
| 9237 | 9354 | |
| 9238 | | LLVMTypeRef usize_type_ref = g->builtin_types.entry_usize->llvm_type; |
| 9239 | 9355 | LLVMValueRef size_val = LLVMConstInt(usize_type_ref, fn_table_entry->frame_type->abi_size, false); |
| 9240 | 9356 | if (g->need_frame_size_prefix_data) { |
| 9241 | 9357 | ZigLLVMFunctionSetPrefixData(fn_table_entry->llvm_value, size_val); |
| ... | ... | @@ -9254,22 +9370,31 @@ static void do_code_gen(CodeGen *g) { |
| 9254 | 9370 | |
| 9255 | 9371 | LLVMPositionBuilderAtEnd(g->builder, g->cur_preamble_llvm_block); |
| 9256 | 9372 | render_async_spills(g); |
| 9257 | | g->cur_async_awaiter_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, frame_awaiter_index, ""); |
| 9258 | | LLVMValueRef resume_index_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, frame_resume_index, ""); |
| 9373 | g->cur_async_awaiter_ptr = LLVMBuildStructGEP2(g->builder, |
| 9374 | get_llvm_type(g, get_fn_frame_type(g, g->cur_fn)), |
| 9375 | g->cur_frame_ptr, frame_awaiter_index, ""); |
| 9376 | LLVMValueRef resume_index_ptr = LLVMBuildStructGEP2(g->builder, |
| 9377 | get_llvm_type(g, get_fn_frame_type(g, g->cur_fn)), |
| 9378 | g->cur_frame_ptr, frame_resume_index, ""); |
| 9259 | 9379 | g->cur_async_resume_index_ptr = resume_index_ptr; |
| 9260 | 9380 | |
| 9261 | 9381 | if (type_has_bits(g, fn_type_id->return_type)) { |
| 9262 | | LLVMValueRef cur_ret_ptr_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, frame_ret_start, ""); |
| 9263 | | g->cur_ret_ptr = LLVMBuildLoad(g->builder, cur_ret_ptr_ptr, ""); |
| 9382 | LLVMValueRef cur_ret_ptr_ptr = LLVMBuildStructGEP2(g->builder, |
| 9383 | get_llvm_type(g, get_fn_frame_type(g, g->cur_fn)), |
| 9384 | g->cur_frame_ptr, frame_ret_start, ""); |
| 9385 | g->cur_ret_ptr = LLVMBuildLoad2(g->builder, |
| 9386 | LLVMPointerTypeInContext(LLVMGetGlobalContext(), 0), cur_ret_ptr_ptr, ""); |
| 9264 | 9387 | } |
| 9265 | 9388 | uint32_t trace_field_index_stack = UINT32_MAX; |
| 9266 | 9389 | if (codegen_fn_has_err_ret_tracing_stack(g, fn_table_entry, true)) { |
| 9267 | 9390 | trace_field_index_stack = frame_index_trace_stack(g, fn_table_entry); |
| 9268 | | g->cur_err_ret_trace_val_stack = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, |
| 9391 | g->cur_err_ret_trace_val_stack = LLVMBuildStructGEP2(g->builder, |
| 9392 | get_llvm_type(g, get_fn_frame_type(g, g->cur_fn)), |
| 9393 | g->cur_frame_ptr, |
| 9269 | 9394 | trace_field_index_stack, ""); |
| 9270 | 9395 | } |
| 9271 | 9396 | |
| 9272 | | LLVMValueRef resume_index = LLVMBuildLoad(g->builder, resume_index_ptr, ""); |
| 9397 | LLVMValueRef resume_index = LLVMBuildLoad2(g->builder, usize_type_ref, resume_index_ptr, ""); |
| 9273 | 9398 | LLVMValueRef switch_instr = LLVMBuildSwitch(g->builder, resume_index, bad_resume_block, 4); |
| 9274 | 9399 | g->cur_async_switch_instr = switch_instr; |
| 9275 | 9400 | |
| ... | ... | @@ -9293,15 +9418,21 @@ static void do_code_gen(CodeGen *g) { |
| 9293 | 9418 | LLVMBuildStore(g->builder, g->cur_bad_not_suspended_index, g->cur_async_resume_index_ptr); |
| 9294 | 9419 | if (trace_field_index_stack != UINT32_MAX) { |
| 9295 | 9420 | if (codegen_fn_has_err_ret_tracing_arg(g, fn_type_id->return_type)) { |
| 9296 | | LLVMValueRef trace_ptr_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, |
| 9421 | LLVMValueRef trace_ptr_ptr = LLVMBuildStructGEP2(g->builder, |
| 9422 | get_llvm_type(g, get_fn_frame_type(g, g->cur_fn)), |
| 9423 | g->cur_frame_ptr, |
| 9297 | 9424 | frame_index_trace_arg(g, fn_type_id->return_type), ""); |
| 9298 | 9425 | LLVMValueRef zero_ptr = LLVMConstNull(LLVMGetElementType(LLVMTypeOf(trace_ptr_ptr))); |
| 9299 | 9426 | LLVMBuildStore(g->builder, zero_ptr, trace_ptr_ptr); |
| 9300 | 9427 | } |
| 9301 | 9428 | |
| 9302 | | LLVMValueRef trace_field_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, |
| 9429 | LLVMValueRef trace_field_ptr = LLVMBuildStructGEP2(g->builder, |
| 9430 | get_llvm_type(g, get_fn_frame_type(g, g->cur_fn)), |
| 9431 | g->cur_frame_ptr, |
| 9303 | 9432 | trace_field_index_stack, ""); |
| 9304 | | LLVMValueRef addrs_field_ptr = LLVMBuildStructGEP(g->builder, g->cur_frame_ptr, |
| 9433 | LLVMValueRef addrs_field_ptr = LLVMBuildStructGEP2(g->builder, |
| 9434 | get_llvm_type(g, get_fn_frame_type(g, g->cur_fn)), |
| 9435 | g->cur_frame_ptr, |
| 9305 | 9436 | trace_field_index_stack + 1, ""); |
| 9306 | 9437 | |
| 9307 | 9438 | gen_init_stack_trace(g, trace_field_ptr, addrs_field_ptr); |