| ... | @@ -316,7 +316,7 @@ pub fn supportsTailCall(target: std.Target) bool { | ... | @@ -316,7 +316,7 @@ pub fn supportsTailCall(target: std.Target) bool { |
| 316 | } | 316 | } |
| 317 | | 317 | |
| 318 | /// TODO can this be done with simpler logic / different API binding? | 318 | /// TODO can this be done with simpler logic / different API binding? |
| 319 | fn deleteLlvmGlobal(llvm_global: *const llvm.Value) void { | 319 | fn deleteLlvmGlobal(llvm_global: *llvm.Value) void { |
| 320 | if (llvm_global.globalGetValueType().getTypeKind() == .Function) { | 320 | if (llvm_global.globalGetValueType().getTypeKind() == .Function) { |
| 321 | llvm_global.deleteFunction(); | 321 | llvm_global.deleteFunction(); |
| 322 | return; | 322 | return; |
| ... | @@ -327,7 +327,7 @@ fn deleteLlvmGlobal(llvm_global: *const llvm.Value) void { | ... | @@ -327,7 +327,7 @@ fn deleteLlvmGlobal(llvm_global: *const llvm.Value) void { |
| 327 | pub const Object = struct { | 327 | pub const Object = struct { |
| 328 | gpa: Allocator, | 328 | gpa: Allocator, |
| 329 | module: *Module, | 329 | module: *Module, |
| 330 | llvm_module: *const llvm.Module, | 330 | llvm_module: *llvm.Module, |
| 331 | di_builder: ?*llvm.DIBuilder, | 331 | di_builder: ?*llvm.DIBuilder, |
| 332 | /// One of these mappings: | 332 | /// One of these mappings: |
| 333 | /// - *Module.File => *DIFile | 333 | /// - *Module.File => *DIFile |
| ... | @@ -335,9 +335,9 @@ pub const Object = struct { | ... | @@ -335,9 +335,9 @@ pub const Object = struct { |
| 335 | /// - *Module.Decl (Non-Fn) => *DIGlobalVariable | 335 | /// - *Module.Decl (Non-Fn) => *DIGlobalVariable |
| 336 | di_map: std.AutoHashMapUnmanaged(*const anyopaque, *llvm.DINode), | 336 | di_map: std.AutoHashMapUnmanaged(*const anyopaque, *llvm.DINode), |
| 337 | di_compile_unit: ?*llvm.DICompileUnit, | 337 | di_compile_unit: ?*llvm.DICompileUnit, |
| 338 | context: *const llvm.Context, | 338 | context: *llvm.Context, |
| 339 | target_machine: *const llvm.TargetMachine, | 339 | target_machine: *llvm.TargetMachine, |
| 340 | target_data: *const llvm.TargetData, | 340 | target_data: *llvm.TargetData, |
| 341 | target: std.Target, | 341 | target: std.Target, |
| 342 | /// Ideally we would use `llvm_module.getNamedFunction` to go from *Decl to LLVM function, | 342 | /// Ideally we would use `llvm_module.getNamedFunction` to go from *Decl to LLVM function, |
| 343 | /// but that has some downsides: | 343 | /// but that has some downsides: |
| ... | @@ -347,9 +347,9 @@ pub const Object = struct { | ... | @@ -347,9 +347,9 @@ pub const Object = struct { |
| 347 | /// version of the name and incorrectly get function not found in the llvm module. | 347 | /// version of the name and incorrectly get function not found in the llvm module. |
| 348 | /// * it works for functions not all globals. | 348 | /// * it works for functions not all globals. |
| 349 | /// Therefore, this table keeps track of the mapping. | 349 | /// Therefore, this table keeps track of the mapping. |
| 350 | decl_map: std.AutoHashMapUnmanaged(Module.Decl.Index, *const llvm.Value), | 350 | decl_map: std.AutoHashMapUnmanaged(Module.Decl.Index, *llvm.Value), |
| 351 | /// Serves the same purpose as `decl_map` but only used for the `is_named_enum_value` instruction. | 351 | /// Serves the same purpose as `decl_map` but only used for the `is_named_enum_value` instruction. |
| 352 | named_enum_map: std.AutoHashMapUnmanaged(Module.Decl.Index, *const llvm.Value), | 352 | named_enum_map: std.AutoHashMapUnmanaged(Module.Decl.Index, *llvm.Value), |
| 353 | /// Maps Zig types to LLVM types. The table memory itself is backed by the GPA of | 353 | /// Maps Zig types to LLVM types. The table memory itself is backed by the GPA of |
| 354 | /// the compiler, but the Type/Value memory here is backed by `type_map_arena`. | 354 | /// the compiler, but the Type/Value memory here is backed by `type_map_arena`. |
| 355 | /// TODO we need to remove entries from this map in response to incremental compilation | 355 | /// TODO we need to remove entries from this map in response to incremental compilation |
| ... | @@ -363,7 +363,7 @@ pub const Object = struct { | ... | @@ -363,7 +363,7 @@ pub const Object = struct { |
| 363 | /// The LLVM global table which holds the names corresponding to Zig errors. | 363 | /// The LLVM global table which holds the names corresponding to Zig errors. |
| 364 | /// Note that the values are not added until flushModule, when all errors in | 364 | /// Note that the values are not added until flushModule, when all errors in |
| 365 | /// the compilation are known. | 365 | /// the compilation are known. |
| 366 | error_name_table: ?*const llvm.Value, | 366 | error_name_table: ?*llvm.Value, |
| 367 | /// This map is usually very close to empty. It tracks only the cases when a | 367 | /// This map is usually very close to empty. It tracks only the cases when a |
| 368 | /// second extern Decl could not be emitted with the correct name due to a | 368 | /// second extern Decl could not be emitted with the correct name due to a |
| 369 | /// name collision. | 369 | /// name collision. |
| ... | @@ -371,7 +371,7 @@ pub const Object = struct { | ... | @@ -371,7 +371,7 @@ pub const Object = struct { |
| 371 | | 371 | |
| 372 | pub const TypeMap = std.HashMapUnmanaged( | 372 | pub const TypeMap = std.HashMapUnmanaged( |
| 373 | Type, | 373 | Type, |
| 374 | *const llvm.Type, | 374 | *llvm.Type, |
| 375 | Type.HashContext64, | 375 | Type.HashContext64, |
| 376 | std.hash_map.default_max_load_percentage, | 376 | std.hash_map.default_max_load_percentage, |
| 377 | ); | 377 | ); |
| ... | @@ -405,7 +405,7 @@ pub const Object = struct { | ... | @@ -405,7 +405,7 @@ pub const Object = struct { |
| 405 | defer gpa.free(llvm_target_triple); | 405 | defer gpa.free(llvm_target_triple); |
| 406 | | 406 | |
| 407 | var error_message: [*:0]const u8 = undefined; | 407 | var error_message: [*:0]const u8 = undefined; |
| 408 | var target: *const llvm.Target = undefined; | 408 | var target: *llvm.Target = undefined; |
| 409 | if (llvm.Target.getFromTriple(llvm_target_triple.ptr, &target, &error_message).toBool()) { | 409 | if (llvm.Target.getFromTriple(llvm_target_triple.ptr, &target, &error_message).toBool()) { |
| 410 | defer llvm.disposeMessage(error_message); | 410 | defer llvm.disposeMessage(error_message); |
| 411 | | 411 | |
| ... | @@ -578,7 +578,7 @@ pub const Object = struct { | ... | @@ -578,7 +578,7 @@ pub const Object = struct { |
| 578 | | 578 | |
| 579 | const llvm_ptr_ty = self.context.intType(8).pointerType(0); // TODO: Address space | 579 | const llvm_ptr_ty = self.context.intType(8).pointerType(0); // TODO: Address space |
| 580 | const llvm_usize_ty = self.context.intType(target.cpu.arch.ptrBitWidth()); | 580 | const llvm_usize_ty = self.context.intType(target.cpu.arch.ptrBitWidth()); |
| 581 | const type_fields = [_]*const llvm.Type{ | 581 | const type_fields = [_]*llvm.Type{ |
| 582 | llvm_ptr_ty, | 582 | llvm_ptr_ty, |
| 583 | llvm_usize_ty, | 583 | llvm_usize_ty, |
| 584 | }; | 584 | }; |
| ... | @@ -587,7 +587,7 @@ pub const Object = struct { | ... | @@ -587,7 +587,7 @@ pub const Object = struct { |
| 587 | const slice_alignment = slice_ty.abiAlignment(target); | 587 | const slice_alignment = slice_ty.abiAlignment(target); |
| 588 | | 588 | |
| 589 | const error_name_list = mod.error_name_list.items; | 589 | const error_name_list = mod.error_name_list.items; |
| 590 | const llvm_errors = try mod.gpa.alloc(*const llvm.Value, error_name_list.len); | 590 | const llvm_errors = try mod.gpa.alloc(*llvm.Value, error_name_list.len); |
| 591 | defer mod.gpa.free(llvm_errors); | 591 | defer mod.gpa.free(llvm_errors); |
| 592 | | 592 | |
| 593 | llvm_errors[0] = llvm_slice_ty.getUndef(); | 593 | llvm_errors[0] = llvm_slice_ty.getUndef(); |
| ... | @@ -601,7 +601,7 @@ pub const Object = struct { | ... | @@ -601,7 +601,7 @@ pub const Object = struct { |
| 601 | str_global.setUnnamedAddr(.True); | 601 | str_global.setUnnamedAddr(.True); |
| 602 | str_global.setAlignment(1); | 602 | str_global.setAlignment(1); |
| 603 | | 603 | |
| 604 | const slice_fields = [_]*const llvm.Value{ | 604 | const slice_fields = [_]*llvm.Value{ |
| 605 | str_global.constBitCast(llvm_ptr_ty), | 605 | str_global.constBitCast(llvm_ptr_ty), |
| 606 | llvm_usize_ty.constInt(name.len, .False), | 606 | llvm_usize_ty.constInt(name.len, .False), |
| 607 | }; | 607 | }; |
| ... | @@ -911,7 +911,7 @@ pub const Object = struct { | ... | @@ -911,7 +911,7 @@ pub const Object = struct { |
| 911 | // This is the list of args we will use that correspond directly to the AIR arg | 911 | // This is the list of args we will use that correspond directly to the AIR arg |
| 912 | // instructions. Depending on the calling convention, this list is not necessarily | 912 | // instructions. Depending on the calling convention, this list is not necessarily |
| 913 | // a bijection with the actual LLVM parameters of the function. | 913 | // a bijection with the actual LLVM parameters of the function. |
| 914 | var args = std.ArrayList(*const llvm.Value).init(gpa); | 914 | var args = std.ArrayList(*llvm.Value).init(gpa); |
| 915 | defer args.deinit(); | 915 | defer args.deinit(); |
| 916 | | 916 | |
| 917 | { | 917 | { |
| ... | @@ -1028,7 +1028,7 @@ pub const Object = struct { | ... | @@ -1028,7 +1028,7 @@ pub const Object = struct { |
| 1028 | const param_alignment = param_ty.abiAlignment(target); | 1028 | const param_alignment = param_ty.abiAlignment(target); |
| 1029 | const arg_ptr = buildAllocaInner(builder, llvm_func, false, param_llvm_ty); | 1029 | const arg_ptr = buildAllocaInner(builder, llvm_func, false, param_llvm_ty); |
| 1030 | arg_ptr.setAlignment(param_alignment); | 1030 | arg_ptr.setAlignment(param_alignment); |
| 1031 | var field_types_buf: [8]*const llvm.Type = undefined; | 1031 | var field_types_buf: [8]*llvm.Type = undefined; |
| 1032 | const field_types = field_types_buf[0..llvm_ints.len]; | 1032 | const field_types = field_types_buf[0..llvm_ints.len]; |
| 1033 | for (llvm_ints) |int_bits, i| { | 1033 | for (llvm_ints) |int_bits, i| { |
| 1034 | field_types[i] = dg.context.intType(int_bits); | 1034 | field_types[i] = dg.context.intType(int_bits); |
| ... | @@ -1059,7 +1059,7 @@ pub const Object = struct { | ... | @@ -1059,7 +1059,7 @@ pub const Object = struct { |
| 1059 | const param_alignment = param_ty.abiAlignment(target); | 1059 | const param_alignment = param_ty.abiAlignment(target); |
| 1060 | const arg_ptr = buildAllocaInner(builder, llvm_func, false, param_llvm_ty); | 1060 | const arg_ptr = buildAllocaInner(builder, llvm_func, false, param_llvm_ty); |
| 1061 | arg_ptr.setAlignment(param_alignment); | 1061 | arg_ptr.setAlignment(param_alignment); |
| 1062 | var field_types_buf: [8]*const llvm.Type = undefined; | 1062 | var field_types_buf: [8]*llvm.Type = undefined; |
| 1063 | const field_types = field_types_buf[0..llvm_floats.len]; | 1063 | const field_types = field_types_buf[0..llvm_floats.len]; |
| 1064 | for (llvm_floats) |float_bits, i| { | 1064 | for (llvm_floats) |float_bits, i| { |
| 1065 | switch (float_bits) { | 1065 | switch (float_bits) { |
| ... | @@ -1215,7 +1215,7 @@ pub const Object = struct { | ... | @@ -1215,7 +1215,7 @@ pub const Object = struct { |
| 1215 | | 1215 | |
| 1216 | /// TODO replace this with a call to `Module::getNamedValue`. This will require adding | 1216 | /// TODO replace this with a call to `Module::getNamedValue`. This will require adding |
| 1217 | /// a new wrapper in zig_llvm.h/zig_llvm.cpp. | 1217 | /// a new wrapper in zig_llvm.h/zig_llvm.cpp. |
| 1218 | fn getLlvmGlobal(o: Object, name: [*:0]const u8) ?*const llvm.Value { | 1218 | fn getLlvmGlobal(o: Object, name: [*:0]const u8) ?*llvm.Value { |
| 1219 | if (o.llvm_module.getNamedFunction(name)) |x| return x; | 1219 | if (o.llvm_module.getNamedFunction(name)) |x| return x; |
| 1220 | if (o.llvm_module.getNamedGlobal(name)) |x| return x; | 1220 | if (o.llvm_module.getNamedGlobal(name)) |x| return x; |
| 1221 | return null; | 1221 | return null; |
| ... | @@ -2338,7 +2338,7 @@ pub const Object = struct { | ... | @@ -2338,7 +2338,7 @@ pub const Object = struct { |
| 2338 | }; | 2338 | }; |
| 2339 | | 2339 | |
| 2340 | pub const DeclGen = struct { | 2340 | pub const DeclGen = struct { |
| 2341 | context: *const llvm.Context, | 2341 | context: *llvm.Context, |
| 2342 | object: *Object, | 2342 | object: *Object, |
| 2343 | module: *Module, | 2343 | module: *Module, |
| 2344 | decl: *Module.Decl, | 2344 | decl: *Module.Decl, |
| ... | @@ -2354,7 +2354,7 @@ pub const DeclGen = struct { | ... | @@ -2354,7 +2354,7 @@ pub const DeclGen = struct { |
| 2354 | return error.CodegenFail; | 2354 | return error.CodegenFail; |
| 2355 | } | 2355 | } |
| 2356 | | 2356 | |
| 2357 | fn llvmModule(self: *DeclGen) *const llvm.Module { | 2357 | fn llvmModule(self: *DeclGen) *llvm.Module { |
| 2358 | return self.object.llvm_module; | 2358 | return self.object.llvm_module; |
| 2359 | } | 2359 | } |
| 2360 | | 2360 | |
| ... | @@ -2444,7 +2444,7 @@ pub const DeclGen = struct { | ... | @@ -2444,7 +2444,7 @@ pub const DeclGen = struct { |
| 2444 | /// If the llvm function does not exist, create it. | 2444 | /// If the llvm function does not exist, create it. |
| 2445 | /// Note that this can be called before the function's semantic analysis has | 2445 | /// Note that this can be called before the function's semantic analysis has |
| 2446 | /// completed, so if any attributes rely on that, they must be done in updateFunc, not here. | 2446 | /// completed, so if any attributes rely on that, they must be done in updateFunc, not here. |
| 2447 | fn resolveLlvmFunction(dg: *DeclGen, decl_index: Module.Decl.Index) !*const llvm.Value { | 2447 | fn resolveLlvmFunction(dg: *DeclGen, decl_index: Module.Decl.Index) !*llvm.Value { |
| 2448 | const decl = dg.module.declPtr(decl_index); | 2448 | const decl = dg.module.declPtr(decl_index); |
| 2449 | const zig_fn_type = decl.ty; | 2449 | const zig_fn_type = decl.ty; |
| 2450 | const gop = try dg.object.decl_map.getOrPut(dg.gpa, decl_index); | 2450 | const gop = try dg.object.decl_map.getOrPut(dg.gpa, decl_index); |
| ... | @@ -2559,7 +2559,7 @@ pub const DeclGen = struct { | ... | @@ -2559,7 +2559,7 @@ pub const DeclGen = struct { |
| 2559 | return llvm_fn; | 2559 | return llvm_fn; |
| 2560 | } | 2560 | } |
| 2561 | | 2561 | |
| 2562 | fn addCommonFnAttributes(dg: *DeclGen, llvm_fn: *const llvm.Value) void { | 2562 | fn addCommonFnAttributes(dg: *DeclGen, llvm_fn: *llvm.Value) void { |
| 2563 | const comp = dg.module.comp; | 2563 | const comp = dg.module.comp; |
| 2564 | | 2564 | |
| 2565 | if (!comp.bin_file.options.red_zone) { | 2565 | if (!comp.bin_file.options.red_zone) { |
| ... | @@ -2599,7 +2599,7 @@ pub const DeclGen = struct { | ... | @@ -2599,7 +2599,7 @@ pub const DeclGen = struct { |
| 2599 | } | 2599 | } |
| 2600 | } | 2600 | } |
| 2601 | | 2601 | |
| 2602 | fn resolveGlobalDecl(dg: *DeclGen, decl_index: Module.Decl.Index) Error!*const llvm.Value { | 2602 | fn resolveGlobalDecl(dg: *DeclGen, decl_index: Module.Decl.Index) Error!*llvm.Value { |
| 2603 | const gop = try dg.object.decl_map.getOrPut(dg.gpa, decl_index); | 2603 | const gop = try dg.object.decl_map.getOrPut(dg.gpa, decl_index); |
| 2604 | if (gop.found_existing) return gop.value_ptr.*; | 2604 | if (gop.found_existing) return gop.value_ptr.*; |
| 2605 | errdefer assert(dg.object.decl_map.remove(decl_index)); | 2605 | errdefer assert(dg.object.decl_map.remove(decl_index)); |
| ... | @@ -2661,7 +2661,7 @@ pub const DeclGen = struct { | ... | @@ -2661,7 +2661,7 @@ pub const DeclGen = struct { |
| 2661 | }; | 2661 | }; |
| 2662 | } | 2662 | } |
| 2663 | | 2663 | |
| 2664 | fn isUnnamedType(dg: *DeclGen, ty: Type, val: *const llvm.Value) bool { | 2664 | fn isUnnamedType(dg: *DeclGen, ty: Type, val: *llvm.Value) bool { |
| 2665 | // Once `lowerType` succeeds, successive calls to it with the same Zig type | 2665 | // Once `lowerType` succeeds, successive calls to it with the same Zig type |
| 2666 | // are guaranteed to succeed. So if a call to `lowerType` fails here it means | 2666 | // are guaranteed to succeed. So if a call to `lowerType` fails here it means |
| 2667 | // it is the first time lowering the type, which means the value can't possible | 2667 | // it is the first time lowering the type, which means the value can't possible |
| ... | @@ -2670,7 +2670,7 @@ pub const DeclGen = struct { | ... | @@ -2670,7 +2670,7 @@ pub const DeclGen = struct { |
| 2670 | return val.typeOf() != llvm_ty; | 2670 | return val.typeOf() != llvm_ty; |
| 2671 | } | 2671 | } |
| 2672 | | 2672 | |
| 2673 | fn lowerType(dg: *DeclGen, t: Type) Allocator.Error!*const llvm.Type { | 2673 | fn lowerType(dg: *DeclGen, t: Type) Allocator.Error!*llvm.Type { |
| 2674 | const llvm_ty = try lowerTypeInner(dg, t); | 2674 | const llvm_ty = try lowerTypeInner(dg, t); |
| 2675 | if (std.debug.runtime_safety and false) check: { | 2675 | if (std.debug.runtime_safety and false) check: { |
| 2676 | if (t.zigTypeTag() == .Opaque) break :check; | 2676 | if (t.zigTypeTag() == .Opaque) break :check; |
| ... | @@ -2688,7 +2688,7 @@ pub const DeclGen = struct { | ... | @@ -2688,7 +2688,7 @@ pub const DeclGen = struct { |
| 2688 | return llvm_ty; | 2688 | return llvm_ty; |
| 2689 | } | 2689 | } |
| 2690 | | 2690 | |
| 2691 | fn lowerTypeInner(dg: *DeclGen, t: Type) Allocator.Error!*const llvm.Type { | 2691 | fn lowerTypeInner(dg: *DeclGen, t: Type) Allocator.Error!*llvm.Type { |
| 2692 | const gpa = dg.gpa; | 2692 | const gpa = dg.gpa; |
| 2693 | const target = dg.module.getTarget(); | 2693 | const target = dg.module.getTarget(); |
| 2694 | switch (t.zigTypeTag()) { | 2694 | switch (t.zigTypeTag()) { |
| ... | @@ -2719,7 +2719,7 @@ pub const DeclGen = struct { | ... | @@ -2719,7 +2719,7 @@ pub const DeclGen = struct { |
| 2719 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | 2719 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; |
| 2720 | const ptr_type = t.slicePtrFieldType(&buf); | 2720 | const ptr_type = t.slicePtrFieldType(&buf); |
| 2721 | | 2721 | |
| 2722 | const fields: [2]*const llvm.Type = .{ | 2722 | const fields: [2]*llvm.Type = .{ |
| 2723 | try dg.lowerType(ptr_type), | 2723 | try dg.lowerType(ptr_type), |
| 2724 | try dg.lowerType(Type.usize), | 2724 | try dg.lowerType(Type.usize), |
| 2725 | }; | 2725 | }; |
| ... | @@ -2776,7 +2776,7 @@ pub const DeclGen = struct { | ... | @@ -2776,7 +2776,7 @@ pub const DeclGen = struct { |
| 2776 | } | 2776 | } |
| 2777 | | 2777 | |
| 2778 | comptime assert(optional_layout_version == 3); | 2778 | comptime assert(optional_layout_version == 3); |
| 2779 | var fields_buf: [3]*const llvm.Type = .{ | 2779 | var fields_buf: [3]*llvm.Type = .{ |
| 2780 | payload_llvm_ty, dg.context.intType(8), undefined, | 2780 | payload_llvm_ty, dg.context.intType(8), undefined, |
| 2781 | }; | 2781 | }; |
| 2782 | const offset = child_ty.abiSize(target) + 1; | 2782 | const offset = child_ty.abiSize(target) + 1; |
| ... | @@ -2802,7 +2802,7 @@ pub const DeclGen = struct { | ... | @@ -2802,7 +2802,7 @@ pub const DeclGen = struct { |
| 2802 | const payload_size = payload_ty.abiSize(target); | 2802 | const payload_size = payload_ty.abiSize(target); |
| 2803 | const error_size = Type.anyerror.abiSize(target); | 2803 | const error_size = Type.anyerror.abiSize(target); |
| 2804 | | 2804 | |
| 2805 | var fields_buf: [3]*const llvm.Type = undefined; | 2805 | var fields_buf: [3]*llvm.Type = undefined; |
| 2806 | if (error_align > payload_align) { | 2806 | if (error_align > payload_align) { |
| 2807 | fields_buf[0] = llvm_error_type; | 2807 | fields_buf[0] = llvm_error_type; |
| 2808 | fields_buf[1] = llvm_payload_type; | 2808 | fields_buf[1] = llvm_payload_type; |
| ... | @@ -2845,7 +2845,7 @@ pub const DeclGen = struct { | ... | @@ -2845,7 +2845,7 @@ pub const DeclGen = struct { |
| 2845 | const llvm_struct_ty = dg.context.structCreateNamed(""); | 2845 | const llvm_struct_ty = dg.context.structCreateNamed(""); |
| 2846 | gop.value_ptr.* = llvm_struct_ty; // must be done before any recursive calls | 2846 | gop.value_ptr.* = llvm_struct_ty; // must be done before any recursive calls |
| 2847 | | 2847 | |
| 2848 | var llvm_field_types: std.ArrayListUnmanaged(*const llvm.Type) = .{}; | 2848 | var llvm_field_types: std.ArrayListUnmanaged(*llvm.Type) = .{}; |
| 2849 | defer llvm_field_types.deinit(gpa); | 2849 | defer llvm_field_types.deinit(gpa); |
| 2850 | | 2850 | |
| 2851 | try llvm_field_types.ensureUnusedCapacity(gpa, tuple.types.len); | 2851 | try llvm_field_types.ensureUnusedCapacity(gpa, tuple.types.len); |
| ... | @@ -2908,7 +2908,7 @@ pub const DeclGen = struct { | ... | @@ -2908,7 +2908,7 @@ pub const DeclGen = struct { |
| 2908 | | 2908 | |
| 2909 | assert(struct_obj.haveFieldTypes()); | 2909 | assert(struct_obj.haveFieldTypes()); |
| 2910 | | 2910 | |
| 2911 | var llvm_field_types: std.ArrayListUnmanaged(*const llvm.Type) = .{}; | 2911 | var llvm_field_types: std.ArrayListUnmanaged(*llvm.Type) = .{}; |
| 2912 | defer llvm_field_types.deinit(gpa); | 2912 | defer llvm_field_types.deinit(gpa); |
| 2913 | | 2913 | |
| 2914 | try llvm_field_types.ensureUnusedCapacity(gpa, struct_obj.fields.count()); | 2914 | try llvm_field_types.ensureUnusedCapacity(gpa, struct_obj.fields.count()); |
| ... | @@ -2991,7 +2991,7 @@ pub const DeclGen = struct { | ... | @@ -2991,7 +2991,7 @@ pub const DeclGen = struct { |
| 2991 | @intCast(c_uint, layout.abi_size - layout.most_aligned_field_size) | 2991 | @intCast(c_uint, layout.abi_size - layout.most_aligned_field_size) |
| 2992 | else | 2992 | else |
| 2993 | @intCast(c_uint, layout.payload_size - layout.most_aligned_field_size); | 2993 | @intCast(c_uint, layout.payload_size - layout.most_aligned_field_size); |
| 2994 | const fields: [2]*const llvm.Type = .{ | 2994 | const fields: [2]*llvm.Type = .{ |
| 2995 | llvm_aligned_field_ty, | 2995 | llvm_aligned_field_ty, |
| 2996 | dg.context.intType(8).arrayType(padding_len), | 2996 | dg.context.intType(8).arrayType(padding_len), |
| 2997 | }; | 2997 | }; |
| ... | @@ -2999,7 +2999,7 @@ pub const DeclGen = struct { | ... | @@ -2999,7 +2999,7 @@ pub const DeclGen = struct { |
| 2999 | }; | 2999 | }; |
| 3000 | | 3000 | |
| 3001 | if (layout.tag_size == 0) { | 3001 | if (layout.tag_size == 0) { |
| 3002 | var llvm_fields: [1]*const llvm.Type = .{llvm_payload_ty}; | 3002 | var llvm_fields: [1]*llvm.Type = .{llvm_payload_ty}; |
| 3003 | llvm_union_ty.structSetBody(&llvm_fields, llvm_fields.len, .False); | 3003 | llvm_union_ty.structSetBody(&llvm_fields, llvm_fields.len, .False); |
| 3004 | return llvm_union_ty; | 3004 | return llvm_union_ty; |
| 3005 | } | 3005 | } |
| ... | @@ -3007,7 +3007,7 @@ pub const DeclGen = struct { | ... | @@ -3007,7 +3007,7 @@ pub const DeclGen = struct { |
| 3007 | | 3007 | |
| 3008 | // Put the tag before or after the payload depending on which one's | 3008 | // Put the tag before or after the payload depending on which one's |
| 3009 | // alignment is greater. | 3009 | // alignment is greater. |
| 3010 | var llvm_fields: [3]*const llvm.Type = undefined; | 3010 | var llvm_fields: [3]*llvm.Type = undefined; |
| 3011 | var llvm_fields_len: c_uint = 2; | 3011 | var llvm_fields_len: c_uint = 2; |
| 3012 | | 3012 | |
| 3013 | if (layout.tag_align >= layout.payload_align) { | 3013 | if (layout.tag_align >= layout.payload_align) { |
| ... | @@ -3040,12 +3040,12 @@ pub const DeclGen = struct { | ... | @@ -3040,12 +3040,12 @@ pub const DeclGen = struct { |
| 3040 | } | 3040 | } |
| 3041 | } | 3041 | } |
| 3042 | | 3042 | |
| 3043 | fn lowerTypeFn(dg: *DeclGen, fn_ty: Type) Allocator.Error!*const llvm.Type { | 3043 | fn lowerTypeFn(dg: *DeclGen, fn_ty: Type) Allocator.Error!*llvm.Type { |
| 3044 | const target = dg.module.getTarget(); | 3044 | const target = dg.module.getTarget(); |
| 3045 | const fn_info = fn_ty.fnInfo(); | 3045 | const fn_info = fn_ty.fnInfo(); |
| 3046 | const llvm_ret_ty = try lowerFnRetTy(dg, fn_info); | 3046 | const llvm_ret_ty = try lowerFnRetTy(dg, fn_info); |
| 3047 | | 3047 | |
| 3048 | var llvm_params = std.ArrayList(*const llvm.Type).init(dg.gpa); | 3048 | var llvm_params = std.ArrayList(*llvm.Type).init(dg.gpa); |
| 3049 | defer llvm_params.deinit(); | 3049 | defer llvm_params.deinit(); |
| 3050 | | 3050 | |
| 3051 | if (firstParamSRet(fn_info, target)) { | 3051 | if (firstParamSRet(fn_info, target)) { |
| ... | @@ -3135,7 +3135,7 @@ pub const DeclGen = struct { | ... | @@ -3135,7 +3135,7 @@ pub const DeclGen = struct { |
| 3135 | /// Use this instead of lowerType when you want to handle correctly the case of elem_ty | 3135 | /// Use this instead of lowerType when you want to handle correctly the case of elem_ty |
| 3136 | /// being a zero bit type, but it should still be lowered as an i8 in such case. | 3136 | /// being a zero bit type, but it should still be lowered as an i8 in such case. |
| 3137 | /// There are other similar cases handled here as well. | 3137 | /// There are other similar cases handled here as well. |
| 3138 | fn lowerPtrElemTy(dg: *DeclGen, elem_ty: Type) Allocator.Error!*const llvm.Type { | 3138 | fn lowerPtrElemTy(dg: *DeclGen, elem_ty: Type) Allocator.Error!*llvm.Type { |
| 3139 | const lower_elem_ty = switch (elem_ty.zigTypeTag()) { | 3139 | const lower_elem_ty = switch (elem_ty.zigTypeTag()) { |
| 3140 | .Opaque, .Fn => true, | 3140 | .Opaque, .Fn => true, |
| 3141 | .Array => elem_ty.childType().hasRuntimeBitsIgnoreComptime(), | 3141 | .Array => elem_ty.childType().hasRuntimeBitsIgnoreComptime(), |
| ... | @@ -3149,7 +3149,7 @@ pub const DeclGen = struct { | ... | @@ -3149,7 +3149,7 @@ pub const DeclGen = struct { |
| 3149 | return llvm_elem_ty; | 3149 | return llvm_elem_ty; |
| 3150 | } | 3150 | } |
| 3151 | | 3151 | |
| 3152 | fn lowerValue(dg: *DeclGen, tv: TypedValue) Error!*const llvm.Value { | 3152 | fn lowerValue(dg: *DeclGen, tv: TypedValue) Error!*llvm.Value { |
| 3153 | if (tv.val.isUndef()) { | 3153 | if (tv.val.isUndef()) { |
| 3154 | const llvm_type = try dg.lowerType(tv.ty); | 3154 | const llvm_type = try dg.lowerType(tv.ty); |
| 3155 | return llvm_type.getUndef(); | 3155 | return llvm_type.getUndef(); |
| ... | @@ -3264,7 +3264,7 @@ pub const DeclGen = struct { | ... | @@ -3264,7 +3264,7 @@ pub const DeclGen = struct { |
| 3264 | .slice => { | 3264 | .slice => { |
| 3265 | const slice = tv.val.castTag(.slice).?.data; | 3265 | const slice = tv.val.castTag(.slice).?.data; |
| 3266 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | 3266 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; |
| 3267 | const fields: [2]*const llvm.Value = .{ | 3267 | const fields: [2]*llvm.Value = .{ |
| 3268 | try dg.lowerValue(.{ | 3268 | try dg.lowerValue(.{ |
| 3269 | .ty = tv.ty.slicePtrFieldType(&buf), | 3269 | .ty = tv.ty.slicePtrFieldType(&buf), |
| 3270 | .val = slice.ptr, | 3270 | .val = slice.ptr, |
| ... | @@ -3336,7 +3336,7 @@ pub const DeclGen = struct { | ... | @@ -3336,7 +3336,7 @@ pub const DeclGen = struct { |
| 3336 | const elem_ty = tv.ty.elemType(); | 3336 | const elem_ty = tv.ty.elemType(); |
| 3337 | const gpa = dg.gpa; | 3337 | const gpa = dg.gpa; |
| 3338 | const len = @intCast(usize, tv.ty.arrayLenIncludingSentinel()); | 3338 | const len = @intCast(usize, tv.ty.arrayLenIncludingSentinel()); |
| 3339 | const llvm_elems = try gpa.alloc(*const llvm.Value, len); | 3339 | const llvm_elems = try gpa.alloc(*llvm.Value, len); |
| 3340 | defer gpa.free(llvm_elems); | 3340 | defer gpa.free(llvm_elems); |
| 3341 | var need_unnamed = false; | 3341 | var need_unnamed = false; |
| 3342 | for (elem_vals[0..len]) |elem_val, i| { | 3342 | for (elem_vals[0..len]) |elem_val, i| { |
| ... | @@ -3364,7 +3364,7 @@ pub const DeclGen = struct { | ... | @@ -3364,7 +3364,7 @@ pub const DeclGen = struct { |
| 3364 | const len = @intCast(usize, tv.ty.arrayLen()); | 3364 | const len = @intCast(usize, tv.ty.arrayLen()); |
| 3365 | const len_including_sent = len + @boolToInt(sentinel != null); | 3365 | const len_including_sent = len + @boolToInt(sentinel != null); |
| 3366 | const gpa = dg.gpa; | 3366 | const gpa = dg.gpa; |
| 3367 | const llvm_elems = try gpa.alloc(*const llvm.Value, len_including_sent); | 3367 | const llvm_elems = try gpa.alloc(*llvm.Value, len_including_sent); |
| 3368 | defer gpa.free(llvm_elems); | 3368 | defer gpa.free(llvm_elems); |
| 3369 | | 3369 | |
| 3370 | var need_unnamed = false; | 3370 | var need_unnamed = false; |
| ... | @@ -3398,7 +3398,7 @@ pub const DeclGen = struct { | ... | @@ -3398,7 +3398,7 @@ pub const DeclGen = struct { |
| 3398 | const elem_ty = tv.ty.elemType(); | 3398 | const elem_ty = tv.ty.elemType(); |
| 3399 | const sent_val = tv.ty.sentinel().?; | 3399 | const sent_val = tv.ty.sentinel().?; |
| 3400 | const sentinel = try dg.lowerValue(.{ .ty = elem_ty, .val = sent_val }); | 3400 | const sentinel = try dg.lowerValue(.{ .ty = elem_ty, .val = sent_val }); |
| 3401 | const llvm_elems: [1]*const llvm.Value = .{sentinel}; | 3401 | const llvm_elems: [1]*llvm.Value = .{sentinel}; |
| 3402 | const need_unnamed = dg.isUnnamedType(elem_ty, llvm_elems[0]); | 3402 | const need_unnamed = dg.isUnnamedType(elem_ty, llvm_elems[0]); |
| 3403 | if (need_unnamed) { | 3403 | if (need_unnamed) { |
| 3404 | return dg.context.constStruct(&llvm_elems, llvm_elems.len, .True); | 3404 | return dg.context.constStruct(&llvm_elems, llvm_elems.len, .True); |
| ... | @@ -3433,7 +3433,7 @@ pub const DeclGen = struct { | ... | @@ -3433,7 +3433,7 @@ pub const DeclGen = struct { |
| 3433 | assert(payload_ty.zigTypeTag() != .Fn); | 3433 | assert(payload_ty.zigTypeTag() != .Fn); |
| 3434 | | 3434 | |
| 3435 | const llvm_field_count = llvm_ty.countStructElementTypes(); | 3435 | const llvm_field_count = llvm_ty.countStructElementTypes(); |
| 3436 | var fields_buf: [3]*const llvm.Value = undefined; | 3436 | var fields_buf: [3]*llvm.Value = undefined; |
| 3437 | fields_buf[0] = try dg.lowerValue(.{ | 3437 | fields_buf[0] = try dg.lowerValue(.{ |
| 3438 | .ty = payload_ty, | 3438 | .ty = payload_ty, |
| 3439 | .val = if (tv.val.castTag(.opt_payload)) |pl| pl.data else Value.initTag(.undef), | 3439 | .val = if (tv.val.castTag(.opt_payload)) |pl| pl.data else Value.initTag(.undef), |
| ... | @@ -3489,7 +3489,7 @@ pub const DeclGen = struct { | ... | @@ -3489,7 +3489,7 @@ pub const DeclGen = struct { |
| 3489 | .ty = payload_type, | 3489 | .ty = payload_type, |
| 3490 | .val = if (tv.val.castTag(.eu_payload)) |pl| pl.data else Value.initTag(.undef), | 3490 | .val = if (tv.val.castTag(.eu_payload)) |pl| pl.data else Value.initTag(.undef), |
| 3491 | }); | 3491 | }); |
| 3492 | var fields_buf: [3]*const llvm.Value = undefined; | 3492 | var fields_buf: [3]*llvm.Value = undefined; |
| 3493 | | 3493 | |
| 3494 | const llvm_ty = try dg.lowerType(tv.ty); | 3494 | const llvm_ty = try dg.lowerType(tv.ty); |
| 3495 | const llvm_field_count = llvm_ty.countStructElementTypes(); | 3495 | const llvm_field_count = llvm_ty.countStructElementTypes(); |
| ... | @@ -3515,7 +3515,7 @@ pub const DeclGen = struct { | ... | @@ -3515,7 +3515,7 @@ pub const DeclGen = struct { |
| 3515 | | 3515 | |
| 3516 | if (tv.ty.isTupleOrAnonStruct()) { | 3516 | if (tv.ty.isTupleOrAnonStruct()) { |
| 3517 | const tuple = tv.ty.tupleFields(); | 3517 | const tuple = tv.ty.tupleFields(); |
| 3518 | var llvm_fields: std.ArrayListUnmanaged(*const llvm.Value) = .{}; | 3518 | var llvm_fields: std.ArrayListUnmanaged(*llvm.Value) = .{}; |
| 3519 | defer llvm_fields.deinit(gpa); | 3519 | defer llvm_fields.deinit(gpa); |
| 3520 | | 3520 | |
| 3521 | try llvm_fields.ensureUnusedCapacity(gpa, tuple.types.len); | 3521 | try llvm_fields.ensureUnusedCapacity(gpa, tuple.types.len); |
| ... | @@ -3584,7 +3584,7 @@ pub const DeclGen = struct { | ... | @@ -3584,7 +3584,7 @@ pub const DeclGen = struct { |
| 3584 | const int_llvm_ty = dg.context.intType(@intCast(c_uint, big_bits)); | 3584 | const int_llvm_ty = dg.context.intType(@intCast(c_uint, big_bits)); |
| 3585 | const fields = struct_obj.fields.values(); | 3585 | const fields = struct_obj.fields.values(); |
| 3586 | comptime assert(Type.packed_struct_layout_version == 2); | 3586 | comptime assert(Type.packed_struct_layout_version == 2); |
| 3587 | var running_int: *const llvm.Value = int_llvm_ty.constNull(); | 3587 | var running_int: *llvm.Value = int_llvm_ty.constNull(); |
| 3588 | var running_bits: u16 = 0; | 3588 | var running_bits: u16 = 0; |
| 3589 | for (field_vals) |field_val, i| { | 3589 | for (field_vals) |field_val, i| { |
| 3590 | const field = fields[i]; | 3590 | const field = fields[i]; |
| ... | @@ -3613,7 +3613,7 @@ pub const DeclGen = struct { | ... | @@ -3613,7 +3613,7 @@ pub const DeclGen = struct { |
| 3613 | } | 3613 | } |
| 3614 | | 3614 | |
| 3615 | const llvm_field_count = llvm_struct_ty.countStructElementTypes(); | 3615 | const llvm_field_count = llvm_struct_ty.countStructElementTypes(); |
| 3616 | var llvm_fields = try std.ArrayListUnmanaged(*const llvm.Value).initCapacity(gpa, llvm_field_count); | 3616 | var llvm_fields = try std.ArrayListUnmanaged(*llvm.Value).initCapacity(gpa, llvm_field_count); |
| 3617 | defer llvm_fields.deinit(gpa); | 3617 | defer llvm_fields.deinit(gpa); |
| 3618 | | 3618 | |
| 3619 | comptime assert(struct_layout_version == 2); | 3619 | comptime assert(struct_layout_version == 2); |
| ... | @@ -3706,14 +3706,14 @@ pub const DeclGen = struct { | ... | @@ -3706,14 +3706,14 @@ pub const DeclGen = struct { |
| 3706 | break :p field; | 3706 | break :p field; |
| 3707 | } | 3707 | } |
| 3708 | const padding_len = @intCast(c_uint, layout.payload_size - field_size); | 3708 | const padding_len = @intCast(c_uint, layout.payload_size - field_size); |
| 3709 | const fields: [2]*const llvm.Value = .{ | 3709 | const fields: [2]*llvm.Value = .{ |
| 3710 | field, dg.context.intType(8).arrayType(padding_len).getUndef(), | 3710 | field, dg.context.intType(8).arrayType(padding_len).getUndef(), |
| 3711 | }; | 3711 | }; |
| 3712 | break :p dg.context.constStruct(&fields, fields.len, .True); | 3712 | break :p dg.context.constStruct(&fields, fields.len, .True); |
| 3713 | }; | 3713 | }; |
| 3714 | | 3714 | |
| 3715 | if (layout.tag_size == 0) { | 3715 | if (layout.tag_size == 0) { |
| 3716 | const fields: [1]*const llvm.Value = .{payload}; | 3716 | const fields: [1]*llvm.Value = .{payload}; |
| 3717 | if (need_unnamed) { | 3717 | if (need_unnamed) { |
| 3718 | return dg.context.constStruct(&fields, fields.len, .False); | 3718 | return dg.context.constStruct(&fields, fields.len, .False); |
| 3719 | } else { | 3719 | } else { |
| ... | @@ -3724,7 +3724,7 @@ pub const DeclGen = struct { | ... | @@ -3724,7 +3724,7 @@ pub const DeclGen = struct { |
| 3724 | .ty = tv.ty.unionTagTypeSafety().?, | 3724 | .ty = tv.ty.unionTagTypeSafety().?, |
| 3725 | .val = tag_and_val.tag, | 3725 | .val = tag_and_val.tag, |
| 3726 | }); | 3726 | }); |
| 3727 | var fields: [3]*const llvm.Value = undefined; | 3727 | var fields: [3]*llvm.Value = undefined; |
| 3728 | var fields_len: c_uint = 2; | 3728 | var fields_len: c_uint = 2; |
| 3729 | if (layout.tag_align >= layout.payload_align) { | 3729 | if (layout.tag_align >= layout.payload_align) { |
| 3730 | fields = .{ llvm_tag_value, payload, undefined }; | 3730 | fields = .{ llvm_tag_value, payload, undefined }; |
| ... | @@ -3749,7 +3749,7 @@ pub const DeclGen = struct { | ... | @@ -3749,7 +3749,7 @@ pub const DeclGen = struct { |
| 3749 | assert(vector_len == bytes.len or vector_len + 1 == bytes.len); | 3749 | assert(vector_len == bytes.len or vector_len + 1 == bytes.len); |
| 3750 | | 3750 | |
| 3751 | const elem_ty = tv.ty.elemType(); | 3751 | const elem_ty = tv.ty.elemType(); |
| 3752 | const llvm_elems = try dg.gpa.alloc(*const llvm.Value, vector_len); | 3752 | const llvm_elems = try dg.gpa.alloc(*llvm.Value, vector_len); |
| 3753 | defer dg.gpa.free(llvm_elems); | 3753 | defer dg.gpa.free(llvm_elems); |
| 3754 | for (llvm_elems) |*elem, i| { | 3754 | for (llvm_elems) |*elem, i| { |
| 3755 | var byte_payload: Value.Payload.U64 = .{ | 3755 | var byte_payload: Value.Payload.U64 = .{ |
| ... | @@ -3774,7 +3774,7 @@ pub const DeclGen = struct { | ... | @@ -3774,7 +3774,7 @@ pub const DeclGen = struct { |
| 3774 | const vector_len = @intCast(usize, tv.ty.arrayLen()); | 3774 | const vector_len = @intCast(usize, tv.ty.arrayLen()); |
| 3775 | assert(vector_len == elem_vals.len or vector_len + 1 == elem_vals.len); | 3775 | assert(vector_len == elem_vals.len or vector_len + 1 == elem_vals.len); |
| 3776 | const elem_ty = tv.ty.elemType(); | 3776 | const elem_ty = tv.ty.elemType(); |
| 3777 | const llvm_elems = try dg.gpa.alloc(*const llvm.Value, vector_len); | 3777 | const llvm_elems = try dg.gpa.alloc(*llvm.Value, vector_len); |
| 3778 | defer dg.gpa.free(llvm_elems); | 3778 | defer dg.gpa.free(llvm_elems); |
| 3779 | for (llvm_elems) |*elem, i| { | 3779 | for (llvm_elems) |*elem, i| { |
| 3780 | elem.* = try dg.lowerValue(.{ .ty = elem_ty, .val = elem_vals[i] }); | 3780 | elem.* = try dg.lowerValue(.{ .ty = elem_ty, .val = elem_vals[i] }); |
| ... | @@ -3789,7 +3789,7 @@ pub const DeclGen = struct { | ... | @@ -3789,7 +3789,7 @@ pub const DeclGen = struct { |
| 3789 | const val = tv.val.castTag(.repeated).?.data; | 3789 | const val = tv.val.castTag(.repeated).?.data; |
| 3790 | const elem_ty = tv.ty.elemType(); | 3790 | const elem_ty = tv.ty.elemType(); |
| 3791 | const len = @intCast(usize, tv.ty.arrayLen()); | 3791 | const len = @intCast(usize, tv.ty.arrayLen()); |
| 3792 | const llvm_elems = try dg.gpa.alloc(*const llvm.Value, len); | 3792 | const llvm_elems = try dg.gpa.alloc(*llvm.Value, len); |
| 3793 | defer dg.gpa.free(llvm_elems); | 3793 | defer dg.gpa.free(llvm_elems); |
| 3794 | for (llvm_elems) |*elem| { | 3794 | for (llvm_elems) |*elem| { |
| 3795 | elem.* = try dg.lowerValue(.{ .ty = elem_ty, .val = val }); | 3795 | elem.* = try dg.lowerValue(.{ .ty = elem_ty, .val = val }); |
| ... | @@ -3821,7 +3821,7 @@ pub const DeclGen = struct { | ... | @@ -3821,7 +3821,7 @@ pub const DeclGen = struct { |
| 3821 | | 3821 | |
| 3822 | const ParentPtr = struct { | 3822 | const ParentPtr = struct { |
| 3823 | ty: Type, | 3823 | ty: Type, |
| 3824 | llvm_ptr: *const llvm.Value, | 3824 | llvm_ptr: *llvm.Value, |
| 3825 | }; | 3825 | }; |
| 3826 | | 3826 | |
| 3827 | fn lowerParentPtrDecl( | 3827 | fn lowerParentPtrDecl( |
| ... | @@ -3829,7 +3829,7 @@ pub const DeclGen = struct { | ... | @@ -3829,7 +3829,7 @@ pub const DeclGen = struct { |
| 3829 | ptr_val: Value, | 3829 | ptr_val: Value, |
| 3830 | decl_index: Module.Decl.Index, | 3830 | decl_index: Module.Decl.Index, |
| 3831 | ptr_child_ty: Type, | 3831 | ptr_child_ty: Type, |
| 3832 | ) Error!*const llvm.Value { | 3832 | ) Error!*llvm.Value { |
| 3833 | const decl = dg.module.declPtr(decl_index); | 3833 | const decl = dg.module.declPtr(decl_index); |
| 3834 | dg.module.markDeclAlive(decl); | 3834 | dg.module.markDeclAlive(decl); |
| 3835 | var ptr_ty_payload: Type.Payload.ElemType = .{ | 3835 | var ptr_ty_payload: Type.Payload.ElemType = .{ |
| ... | @@ -3846,7 +3846,7 @@ pub const DeclGen = struct { | ... | @@ -3846,7 +3846,7 @@ pub const DeclGen = struct { |
| 3846 | } | 3846 | } |
| 3847 | } | 3847 | } |
| 3848 | | 3848 | |
| 3849 | fn lowerParentPtr(dg: *DeclGen, ptr_val: Value, ptr_child_ty: Type) Error!*const llvm.Value { | 3849 | fn lowerParentPtr(dg: *DeclGen, ptr_val: Value, ptr_child_ty: Type) Error!*llvm.Value { |
| 3850 | const target = dg.module.getTarget(); | 3850 | const target = dg.module.getTarget(); |
| 3851 | var bitcast_needed: bool = undefined; | 3851 | var bitcast_needed: bool = undefined; |
| 3852 | const llvm_ptr = switch (ptr_val.tag()) { | 3852 | const llvm_ptr = switch (ptr_val.tag()) { |
| ... | @@ -3895,7 +3895,7 @@ pub const DeclGen = struct { | ... | @@ -3895,7 +3895,7 @@ pub const DeclGen = struct { |
| 3895 | 0 | 3895 | 0 |
| 3896 | else | 3896 | else |
| 3897 | @boolToInt(layout.tag_align >= layout.payload_align); | 3897 | @boolToInt(layout.tag_align >= layout.payload_align); |
| 3898 | const indices: [2]*const llvm.Value = .{ | 3898 | const indices: [2]*llvm.Value = .{ |
| 3899 | llvm_u32.constInt(0, .False), | 3899 | llvm_u32.constInt(0, .False), |
| 3900 | llvm_u32.constInt(llvm_pl_index, .False), | 3900 | llvm_u32.constInt(llvm_pl_index, .False), |
| 3901 | }; | 3901 | }; |
| ... | @@ -3926,7 +3926,7 @@ pub const DeclGen = struct { | ... | @@ -3926,7 +3926,7 @@ pub const DeclGen = struct { |
| 3926 | | 3926 | |
| 3927 | var ty_buf: Type.Payload.Pointer = undefined; | 3927 | var ty_buf: Type.Payload.Pointer = undefined; |
| 3928 | const llvm_field_index = llvmFieldIndex(parent_ty, field_index, target, &ty_buf).?; | 3928 | const llvm_field_index = llvmFieldIndex(parent_ty, field_index, target, &ty_buf).?; |
| 3929 | const indices: [2]*const llvm.Value = .{ | 3929 | const indices: [2]*llvm.Value = .{ |
| 3930 | llvm_u32.constInt(0, .False), | 3930 | llvm_u32.constInt(0, .False), |
| 3931 | llvm_u32.constInt(llvm_field_index, .False), | 3931 | llvm_u32.constInt(llvm_field_index, .False), |
| 3932 | }; | 3932 | }; |
| ... | @@ -3942,7 +3942,7 @@ pub const DeclGen = struct { | ... | @@ -3942,7 +3942,7 @@ pub const DeclGen = struct { |
| 3942 | bitcast_needed = !elem_ptr.elem_ty.eql(ptr_child_ty, dg.module); | 3942 | bitcast_needed = !elem_ptr.elem_ty.eql(ptr_child_ty, dg.module); |
| 3943 | | 3943 | |
| 3944 | const llvm_usize = try dg.lowerType(Type.usize); | 3944 | const llvm_usize = try dg.lowerType(Type.usize); |
| 3945 | const indices: [1]*const llvm.Value = .{ | 3945 | const indices: [1]*llvm.Value = .{ |
| 3946 | llvm_usize.constInt(elem_ptr.index, .False), | 3946 | llvm_usize.constInt(elem_ptr.index, .False), |
| 3947 | }; | 3947 | }; |
| 3948 | const elem_llvm_ty = try dg.lowerType(elem_ptr.elem_ty); | 3948 | const elem_llvm_ty = try dg.lowerType(elem_ptr.elem_ty); |
| ... | @@ -3965,7 +3965,7 @@ pub const DeclGen = struct { | ... | @@ -3965,7 +3965,7 @@ pub const DeclGen = struct { |
| 3965 | } | 3965 | } |
| 3966 | | 3966 | |
| 3967 | const llvm_u32 = dg.context.intType(32); | 3967 | const llvm_u32 = dg.context.intType(32); |
| 3968 | const indices: [2]*const llvm.Value = .{ | 3968 | const indices: [2]*llvm.Value = .{ |
| 3969 | llvm_u32.constInt(0, .False), | 3969 | llvm_u32.constInt(0, .False), |
| 3970 | llvm_u32.constInt(0, .False), | 3970 | llvm_u32.constInt(0, .False), |
| 3971 | }; | 3971 | }; |
| ... | @@ -3987,7 +3987,7 @@ pub const DeclGen = struct { | ... | @@ -3987,7 +3987,7 @@ pub const DeclGen = struct { |
| 3987 | | 3987 | |
| 3988 | const payload_offset: u8 = if (payload_ty.abiAlignment(target) > Type.anyerror.abiSize(target)) 2 else 1; | 3988 | const payload_offset: u8 = if (payload_ty.abiAlignment(target) > Type.anyerror.abiSize(target)) 2 else 1; |
| 3989 | const llvm_u32 = dg.context.intType(32); | 3989 | const llvm_u32 = dg.context.intType(32); |
| 3990 | const indices: [2]*const llvm.Value = .{ | 3990 | const indices: [2]*llvm.Value = .{ |
| 3991 | llvm_u32.constInt(0, .False), | 3991 | llvm_u32.constInt(0, .False), |
| 3992 | llvm_u32.constInt(payload_offset, .False), | 3992 | llvm_u32.constInt(payload_offset, .False), |
| 3993 | }; | 3993 | }; |
| ... | @@ -4007,7 +4007,7 @@ pub const DeclGen = struct { | ... | @@ -4007,7 +4007,7 @@ pub const DeclGen = struct { |
| 4007 | self: *DeclGen, | 4007 | self: *DeclGen, |
| 4008 | tv: TypedValue, | 4008 | tv: TypedValue, |
| 4009 | decl_index: Module.Decl.Index, | 4009 | decl_index: Module.Decl.Index, |
| 4010 | ) Error!*const llvm.Value { | 4010 | ) Error!*llvm.Value { |
| 4011 | if (tv.ty.isSlice()) { | 4011 | if (tv.ty.isSlice()) { |
| 4012 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | 4012 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; |
| 4013 | const ptr_ty = tv.ty.slicePtrFieldType(&buf); | 4013 | const ptr_ty = tv.ty.slicePtrFieldType(&buf); |
| ... | @@ -4015,7 +4015,7 @@ pub const DeclGen = struct { | ... | @@ -4015,7 +4015,7 @@ pub const DeclGen = struct { |
| 4015 | .base = .{ .tag = .int_u64 }, | 4015 | .base = .{ .tag = .int_u64 }, |
| 4016 | .data = tv.val.sliceLen(self.module), | 4016 | .data = tv.val.sliceLen(self.module), |
| 4017 | }; | 4017 | }; |
| 4018 | const fields: [2]*const llvm.Value = .{ | 4018 | const fields: [2]*llvm.Value = .{ |
| 4019 | try self.lowerValue(.{ | 4019 | try self.lowerValue(.{ |
| 4020 | .ty = ptr_ty, | 4020 | .ty = ptr_ty, |
| 4021 | .val = tv.val, | 4021 | .val = tv.val, |
| ... | @@ -4060,7 +4060,7 @@ pub const DeclGen = struct { | ... | @@ -4060,7 +4060,7 @@ pub const DeclGen = struct { |
| 4060 | } | 4060 | } |
| 4061 | } | 4061 | } |
| 4062 | | 4062 | |
| 4063 | fn lowerPtrToVoid(dg: *DeclGen, ptr_ty: Type) !*const llvm.Value { | 4063 | fn lowerPtrToVoid(dg: *DeclGen, ptr_ty: Type) !*llvm.Value { |
| 4064 | const alignment = ptr_ty.ptrInfo().data.@"align"; | 4064 | const alignment = ptr_ty.ptrInfo().data.@"align"; |
| 4065 | // Even though we are pointing at something which has zero bits (e.g. `void`), | 4065 | // Even though we are pointing at something which has zero bits (e.g. `void`), |
| 4066 | // Pointers are defined to have bits. So we must return something here. | 4066 | // Pointers are defined to have bits. So we must return something here. |
| ... | @@ -4086,19 +4086,19 @@ pub const DeclGen = struct { | ... | @@ -4086,19 +4086,19 @@ pub const DeclGen = struct { |
| 4086 | return int.constIntToPtr(llvm_ptr_ty); | 4086 | return int.constIntToPtr(llvm_ptr_ty); |
| 4087 | } | 4087 | } |
| 4088 | | 4088 | |
| 4089 | fn addAttr(dg: DeclGen, val: *const llvm.Value, index: llvm.AttributeIndex, name: []const u8) void { | 4089 | fn addAttr(dg: DeclGen, val: *llvm.Value, index: llvm.AttributeIndex, name: []const u8) void { |
| 4090 | return dg.addAttrInt(val, index, name, 0); | 4090 | return dg.addAttrInt(val, index, name, 0); |
| 4091 | } | 4091 | } |
| 4092 | | 4092 | |
| 4093 | fn addArgAttr(dg: DeclGen, fn_val: *const llvm.Value, param_index: u32, attr_name: []const u8) void { | 4093 | fn addArgAttr(dg: DeclGen, fn_val: *llvm.Value, param_index: u32, attr_name: []const u8) void { |
| 4094 | return dg.addAttr(fn_val, param_index + 1, attr_name); | 4094 | return dg.addAttr(fn_val, param_index + 1, attr_name); |
| 4095 | } | 4095 | } |
| 4096 | | 4096 | |
| 4097 | fn addArgAttrInt(dg: DeclGen, fn_val: *const llvm.Value, param_index: u32, attr_name: []const u8, int: u64) void { | 4097 | fn addArgAttrInt(dg: DeclGen, fn_val: *llvm.Value, param_index: u32, attr_name: []const u8, int: u64) void { |
| 4098 | return dg.addAttrInt(fn_val, param_index + 1, attr_name, int); | 4098 | return dg.addAttrInt(fn_val, param_index + 1, attr_name, int); |
| 4099 | } | 4099 | } |
| 4100 | | 4100 | |
| 4101 | fn removeAttr(val: *const llvm.Value, index: llvm.AttributeIndex, name: []const u8) void { | 4101 | fn removeAttr(val: *llvm.Value, index: llvm.AttributeIndex, name: []const u8) void { |
| 4102 | const kind_id = llvm.getEnumAttributeKindForName(name.ptr, name.len); | 4102 | const kind_id = llvm.getEnumAttributeKindForName(name.ptr, name.len); |
| 4103 | assert(kind_id != 0); | 4103 | assert(kind_id != 0); |
| 4104 | val.removeEnumAttributeAtIndex(index, kind_id); | 4104 | val.removeEnumAttributeAtIndex(index, kind_id); |
| ... | @@ -4106,7 +4106,7 @@ pub const DeclGen = struct { | ... | @@ -4106,7 +4106,7 @@ pub const DeclGen = struct { |
| 4106 | | 4106 | |
| 4107 | fn addAttrInt( | 4107 | fn addAttrInt( |
| 4108 | dg: DeclGen, | 4108 | dg: DeclGen, |
| 4109 | val: *const llvm.Value, | 4109 | val: *llvm.Value, |
| 4110 | index: llvm.AttributeIndex, | 4110 | index: llvm.AttributeIndex, |
| 4111 | name: []const u8, | 4111 | name: []const u8, |
| 4112 | int: u64, | 4112 | int: u64, |
| ... | @@ -4119,7 +4119,7 @@ pub const DeclGen = struct { | ... | @@ -4119,7 +4119,7 @@ pub const DeclGen = struct { |
| 4119 | | 4119 | |
| 4120 | fn addAttrString( | 4120 | fn addAttrString( |
| 4121 | dg: *DeclGen, | 4121 | dg: *DeclGen, |
| 4122 | val: *const llvm.Value, | 4122 | val: *llvm.Value, |
| 4123 | index: llvm.AttributeIndex, | 4123 | index: llvm.AttributeIndex, |
| 4124 | name: []const u8, | 4124 | name: []const u8, |
| 4125 | value: []const u8, | 4125 | value: []const u8, |
| ... | @@ -4133,19 +4133,19 @@ pub const DeclGen = struct { | ... | @@ -4133,19 +4133,19 @@ pub const DeclGen = struct { |
| 4133 | val.addAttributeAtIndex(index, llvm_attr); | 4133 | val.addAttributeAtIndex(index, llvm_attr); |
| 4134 | } | 4134 | } |
| 4135 | | 4135 | |
| 4136 | fn addFnAttr(dg: DeclGen, val: *const llvm.Value, name: []const u8) void { | 4136 | fn addFnAttr(dg: DeclGen, val: *llvm.Value, name: []const u8) void { |
| 4137 | dg.addAttr(val, std.math.maxInt(llvm.AttributeIndex), name); | 4137 | dg.addAttr(val, std.math.maxInt(llvm.AttributeIndex), name); |
| 4138 | } | 4138 | } |
| 4139 | | 4139 | |
| 4140 | fn addFnAttrString(dg: *DeclGen, val: *const llvm.Value, name: []const u8, value: []const u8) void { | 4140 | fn addFnAttrString(dg: *DeclGen, val: *llvm.Value, name: []const u8, value: []const u8) void { |
| 4141 | dg.addAttrString(val, std.math.maxInt(llvm.AttributeIndex), name, value); | 4141 | dg.addAttrString(val, std.math.maxInt(llvm.AttributeIndex), name, value); |
| 4142 | } | 4142 | } |
| 4143 | | 4143 | |
| 4144 | fn removeFnAttr(fn_val: *const llvm.Value, name: []const u8) void { | 4144 | fn removeFnAttr(fn_val: *llvm.Value, name: []const u8) void { |
| 4145 | removeAttr(fn_val, std.math.maxInt(llvm.AttributeIndex), name); | 4145 | removeAttr(fn_val, std.math.maxInt(llvm.AttributeIndex), name); |
| 4146 | } | 4146 | } |
| 4147 | | 4147 | |
| 4148 | fn addFnAttrInt(dg: DeclGen, fn_val: *const llvm.Value, name: []const u8, int: u64) void { | 4148 | fn addFnAttrInt(dg: DeclGen, fn_val: *llvm.Value, name: []const u8, int: u64) void { |
| 4149 | return dg.addAttrInt(fn_val, std.math.maxInt(llvm.AttributeIndex), name, int); | 4149 | return dg.addAttrInt(fn_val, std.math.maxInt(llvm.AttributeIndex), name, int); |
| 4150 | } | 4150 | } |
| 4151 | | 4151 | |
| ... | @@ -4153,7 +4153,7 @@ pub const DeclGen = struct { | ... | @@ -4153,7 +4153,7 @@ pub const DeclGen = struct { |
| 4153 | /// widen it before using it and then truncate the result. | 4153 | /// widen it before using it and then truncate the result. |
| 4154 | /// RMW exchange of floating-point values is bitcasted to same-sized integer | 4154 | /// RMW exchange of floating-point values is bitcasted to same-sized integer |
| 4155 | /// types to work around a LLVM deficiency when targeting ARM/AArch64. | 4155 | /// types to work around a LLVM deficiency when targeting ARM/AArch64. |
| 4156 | fn getAtomicAbiType(dg: *DeclGen, ty: Type, is_rmw_xchg: bool) ?*const llvm.Type { | 4156 | fn getAtomicAbiType(dg: *DeclGen, ty: Type, is_rmw_xchg: bool) ?*llvm.Type { |
| 4157 | const target = dg.module.getTarget(); | 4157 | const target = dg.module.getTarget(); |
| 4158 | var buffer: Type.Payload.Bits = undefined; | 4158 | var buffer: Type.Payload.Bits = undefined; |
| 4159 | const int_ty = switch (ty.zigTypeTag()) { | 4159 | const int_ty = switch (ty.zigTypeTag()) { |
| ... | @@ -4176,7 +4176,7 @@ pub const DeclGen = struct { | ... | @@ -4176,7 +4176,7 @@ pub const DeclGen = struct { |
| 4176 | | 4176 | |
| 4177 | fn addByValParamAttrs( | 4177 | fn addByValParamAttrs( |
| 4178 | dg: DeclGen, | 4178 | dg: DeclGen, |
| 4179 | llvm_fn: *const llvm.Value, | 4179 | llvm_fn: *llvm.Value, |
| 4180 | param_ty: Type, | 4180 | param_ty: Type, |
| 4181 | param_index: u32, | 4181 | param_index: u32, |
| 4182 | fn_info: Type.Payload.Function.Data, | 4182 | fn_info: Type.Payload.Function.Data, |
| ... | @@ -4213,11 +4213,11 @@ pub const DeclGen = struct { | ... | @@ -4213,11 +4213,11 @@ pub const DeclGen = struct { |
| 4213 | | 4213 | |
| 4214 | fn addByRefParamAttrs( | 4214 | fn addByRefParamAttrs( |
| 4215 | dg: DeclGen, | 4215 | dg: DeclGen, |
| 4216 | llvm_fn: *const llvm.Value, | 4216 | llvm_fn: *llvm.Value, |
| 4217 | llvm_arg_i: u32, | 4217 | llvm_arg_i: u32, |
| 4218 | alignment: u32, | 4218 | alignment: u32, |
| 4219 | byval_attr: bool, | 4219 | byval_attr: bool, |
| 4220 | param_llvm_ty: *const llvm.Type, | 4220 | param_llvm_ty: *llvm.Type, |
| 4221 | ) void { | 4221 | ) void { |
| 4222 | dg.addArgAttr(llvm_fn, llvm_arg_i, "nonnull"); | 4222 | dg.addArgAttr(llvm_fn, llvm_arg_i, "nonnull"); |
| 4223 | dg.addArgAttr(llvm_fn, llvm_arg_i, "readonly"); | 4223 | dg.addArgAttr(llvm_fn, llvm_arg_i, "readonly"); |
| ... | @@ -4233,8 +4233,8 @@ pub const FuncGen = struct { | ... | @@ -4233,8 +4233,8 @@ pub const FuncGen = struct { |
| 4233 | dg: *DeclGen, | 4233 | dg: *DeclGen, |
| 4234 | air: Air, | 4234 | air: Air, |
| 4235 | liveness: Liveness, | 4235 | liveness: Liveness, |
| 4236 | context: *const llvm.Context, | 4236 | context: *llvm.Context, |
| 4237 | builder: *const llvm.Builder, | 4237 | builder: *llvm.Builder, |
| 4238 | di_scope: ?*llvm.DIScope, | 4238 | di_scope: ?*llvm.DIScope, |
| 4239 | di_file: ?*llvm.DIFile, | 4239 | di_file: ?*llvm.DIFile, |
| 4240 | base_line: u32, | 4240 | base_line: u32, |
| ... | @@ -4250,30 +4250,30 @@ pub const FuncGen = struct { | ... | @@ -4250,30 +4250,30 @@ pub const FuncGen = struct { |
| 4250 | | 4250 | |
| 4251 | /// This stores the LLVM values used in a function, such that they can be referred to | 4251 | /// This stores the LLVM values used in a function, such that they can be referred to |
| 4252 | /// in other instructions. This table is cleared before every function is generated. | 4252 | /// in other instructions. This table is cleared before every function is generated. |
| 4253 | func_inst_table: std.AutoHashMapUnmanaged(Air.Inst.Ref, *const llvm.Value), | 4253 | func_inst_table: std.AutoHashMapUnmanaged(Air.Inst.Ref, *llvm.Value), |
| 4254 | | 4254 | |
| 4255 | /// If the return type is sret, this is the result pointer. Otherwise null. | 4255 | /// If the return type is sret, this is the result pointer. Otherwise null. |
| 4256 | /// Note that this can disagree with isByRef for the return type in the case | 4256 | /// Note that this can disagree with isByRef for the return type in the case |
| 4257 | /// of C ABI functions. | 4257 | /// of C ABI functions. |
| 4258 | ret_ptr: ?*const llvm.Value, | 4258 | ret_ptr: ?*llvm.Value, |
| 4259 | /// Any function that needs to perform Valgrind client requests needs an array alloca | 4259 | /// Any function that needs to perform Valgrind client requests needs an array alloca |
| 4260 | /// instruction, however a maximum of one per function is needed. | 4260 | /// instruction, however a maximum of one per function is needed. |
| 4261 | valgrind_client_request_array: ?*const llvm.Value = null, | 4261 | valgrind_client_request_array: ?*llvm.Value = null, |
| 4262 | /// These fields are used to refer to the LLVM value of the function parameters | 4262 | /// These fields are used to refer to the LLVM value of the function parameters |
| 4263 | /// in an Arg instruction. | 4263 | /// in an Arg instruction. |
| 4264 | /// This list may be shorter than the list according to the zig type system; | 4264 | /// This list may be shorter than the list according to the zig type system; |
| 4265 | /// it omits 0-bit types. If the function uses sret as the first parameter, | 4265 | /// it omits 0-bit types. If the function uses sret as the first parameter, |
| 4266 | /// this slice does not include it. | 4266 | /// this slice does not include it. |
| 4267 | args: []const *const llvm.Value, | 4267 | args: []const *llvm.Value, |
| 4268 | arg_index: c_uint, | 4268 | arg_index: c_uint, |
| 4269 | | 4269 | |
| 4270 | llvm_func: *const llvm.Value, | 4270 | llvm_func: *llvm.Value, |
| 4271 | | 4271 | |
| 4272 | err_ret_trace: ?*const llvm.Value = null, | 4272 | err_ret_trace: ?*llvm.Value = null, |
| 4273 | | 4273 | |
| 4274 | /// This data structure is used to implement breaking to blocks. | 4274 | /// This data structure is used to implement breaking to blocks. |
| 4275 | blocks: std.AutoHashMapUnmanaged(Air.Inst.Index, struct { | 4275 | blocks: std.AutoHashMapUnmanaged(Air.Inst.Index, struct { |
| 4276 | parent_bb: *const llvm.BasicBlock, | 4276 | parent_bb: *llvm.BasicBlock, |
| 4277 | breaks: *BreakList, | 4277 | breaks: *BreakList, |
| 4278 | }), | 4278 | }), |
| 4279 | | 4279 | |
| ... | @@ -4281,8 +4281,8 @@ pub const FuncGen = struct { | ... | @@ -4281,8 +4281,8 @@ pub const FuncGen = struct { |
| 4281 | | 4281 | |
| 4282 | const DbgState = struct { loc: *llvm.DILocation, scope: *llvm.DIScope, base_line: u32 }; | 4282 | const DbgState = struct { loc: *llvm.DILocation, scope: *llvm.DIScope, base_line: u32 }; |
| 4283 | const BreakList = std.MultiArrayList(struct { | 4283 | const BreakList = std.MultiArrayList(struct { |
| 4284 | bb: *const llvm.BasicBlock, | 4284 | bb: *llvm.BasicBlock, |
| 4285 | val: *const llvm.Value, | 4285 | val: *llvm.Value, |
| 4286 | }); | 4286 | }); |
| 4287 | | 4287 | |
| 4288 | fn deinit(self: *FuncGen) void { | 4288 | fn deinit(self: *FuncGen) void { |
| ... | @@ -4298,11 +4298,11 @@ pub const FuncGen = struct { | ... | @@ -4298,11 +4298,11 @@ pub const FuncGen = struct { |
| 4298 | return self.dg.todo(format, args); | 4298 | return self.dg.todo(format, args); |
| 4299 | } | 4299 | } |
| 4300 | | 4300 | |
| 4301 | fn llvmModule(self: *FuncGen) *const llvm.Module { | 4301 | fn llvmModule(self: *FuncGen) *llvm.Module { |
| 4302 | return self.dg.object.llvm_module; | 4302 | return self.dg.object.llvm_module; |
| 4303 | } | 4303 | } |
| 4304 | | 4304 | |
| 4305 | fn resolveInst(self: *FuncGen, inst: Air.Inst.Ref) !*const llvm.Value { | 4305 | fn resolveInst(self: *FuncGen, inst: Air.Inst.Ref) !*llvm.Value { |
| 4306 | const gop = try self.func_inst_table.getOrPut(self.dg.gpa, inst); | 4306 | const gop = try self.func_inst_table.getOrPut(self.dg.gpa, inst); |
| 4307 | if (gop.found_existing) return gop.value_ptr.*; | 4307 | if (gop.found_existing) return gop.value_ptr.*; |
| 4308 | | 4308 | |
| ... | @@ -4336,7 +4336,7 @@ pub const FuncGen = struct { | ... | @@ -4336,7 +4336,7 @@ pub const FuncGen = struct { |
| 4336 | fn genBody(self: *FuncGen, body: []const Air.Inst.Index) Error!void { | 4336 | fn genBody(self: *FuncGen, body: []const Air.Inst.Index) Error!void { |
| 4337 | const air_tags = self.air.instructions.items(.tag); | 4337 | const air_tags = self.air.instructions.items(.tag); |
| 4338 | for (body) |inst, i| { | 4338 | for (body) |inst, i| { |
| 4339 | const opt_value: ?*const llvm.Value = switch (air_tags[inst]) { | 4339 | const opt_value: ?*llvm.Value = switch (air_tags[inst]) { |
| 4340 | // zig fmt: off | 4340 | // zig fmt: off |
| 4341 | .add => try self.airAdd(inst, false), | 4341 | .add => try self.airAdd(inst, false), |
| 4342 | .addwrap => try self.airAddWrap(inst, false), | 4342 | .addwrap => try self.airAddWrap(inst, false), |
| ... | @@ -4563,7 +4563,7 @@ pub const FuncGen = struct { | ... | @@ -4563,7 +4563,7 @@ pub const FuncGen = struct { |
| 4563 | } | 4563 | } |
| 4564 | } | 4564 | } |
| 4565 | | 4565 | |
| 4566 | fn airCall(self: *FuncGen, inst: Air.Inst.Index, attr: llvm.CallAttr) !?*const llvm.Value { | 4566 | fn airCall(self: *FuncGen, inst: Air.Inst.Index, attr: llvm.CallAttr) !?*llvm.Value { |
| 4567 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; | 4567 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; |
| 4568 | const extra = self.air.extraData(Air.Call, pl_op.payload); | 4568 | const extra = self.air.extraData(Air.Call, pl_op.payload); |
| 4569 | const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]); | 4569 | const args = @ptrCast([]const Air.Inst.Ref, self.air.extra[extra.end..][0..extra.data.args_len]); |
| ... | @@ -4579,7 +4579,7 @@ pub const FuncGen = struct { | ... | @@ -4579,7 +4579,7 @@ pub const FuncGen = struct { |
| 4579 | const target = self.dg.module.getTarget(); | 4579 | const target = self.dg.module.getTarget(); |
| 4580 | const sret = firstParamSRet(fn_info, target); | 4580 | const sret = firstParamSRet(fn_info, target); |
| 4581 | | 4581 | |
| 4582 | var llvm_args = std.ArrayList(*const llvm.Value).init(self.gpa); | 4582 | var llvm_args = std.ArrayList(*llvm.Value).init(self.gpa); |
| 4583 | defer llvm_args.deinit(); | 4583 | defer llvm_args.deinit(); |
| 4584 | | 4584 | |
| 4585 | const ret_ptr = if (!sret) null else blk: { | 4585 | const ret_ptr = if (!sret) null else blk: { |
| ... | @@ -4693,7 +4693,7 @@ pub const FuncGen = struct { | ... | @@ -4693,7 +4693,7 @@ pub const FuncGen = struct { |
| 4693 | break :p p; | 4693 | break :p p; |
| 4694 | }; | 4694 | }; |
| 4695 | | 4695 | |
| 4696 | var field_types_buf: [8]*const llvm.Type = undefined; | 4696 | var field_types_buf: [8]*llvm.Type = undefined; |
| 4697 | const field_types = field_types_buf[0..llvm_ints.len]; | 4697 | const field_types = field_types_buf[0..llvm_ints.len]; |
| 4698 | for (llvm_ints) |int_bits, i| { | 4698 | for (llvm_ints) |int_bits, i| { |
| 4699 | field_types[i] = self.dg.context.intType(int_bits); | 4699 | field_types[i] = self.dg.context.intType(int_bits); |
| ... | @@ -4722,7 +4722,7 @@ pub const FuncGen = struct { | ... | @@ -4722,7 +4722,7 @@ pub const FuncGen = struct { |
| 4722 | break :p p; | 4722 | break :p p; |
| 4723 | }; | 4723 | }; |
| 4724 | | 4724 | |
| 4725 | var field_types_buf: [8]*const llvm.Type = undefined; | 4725 | var field_types_buf: [8]*llvm.Type = undefined; |
| 4726 | const field_types = field_types_buf[0..llvm_floats.len]; | 4726 | const field_types = field_types_buf[0..llvm_floats.len]; |
| 4727 | for (llvm_floats) |float_bits, i| { | 4727 | for (llvm_floats) |float_bits, i| { |
| 4728 | switch (float_bits) { | 4728 | switch (float_bits) { |
| ... | @@ -4840,7 +4840,7 @@ pub const FuncGen = struct { | ... | @@ -4840,7 +4840,7 @@ pub const FuncGen = struct { |
| 4840 | } | 4840 | } |
| 4841 | } | 4841 | } |
| 4842 | | 4842 | |
| 4843 | fn airRet(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 4843 | fn airRet(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 4844 | const un_op = self.air.instructions.items(.data)[inst].un_op; | 4844 | const un_op = self.air.instructions.items(.data)[inst].un_op; |
| 4845 | const ret_ty = self.air.typeOf(un_op); | 4845 | const ret_ty = self.air.typeOf(un_op); |
| 4846 | if (self.ret_ptr) |ret_ptr| { | 4846 | if (self.ret_ptr) |ret_ptr| { |
| ... | @@ -4901,7 +4901,7 @@ pub const FuncGen = struct { | ... | @@ -4901,7 +4901,7 @@ pub const FuncGen = struct { |
| 4901 | return null; | 4901 | return null; |
| 4902 | } | 4902 | } |
| 4903 | | 4903 | |
| 4904 | fn airRetLoad(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 4904 | fn airRetLoad(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 4905 | const un_op = self.air.instructions.items(.data)[inst].un_op; | 4905 | const un_op = self.air.instructions.items(.data)[inst].un_op; |
| 4906 | const ptr_ty = self.air.typeOf(un_op); | 4906 | const ptr_ty = self.air.typeOf(un_op); |
| 4907 | const ret_ty = ptr_ty.childType(); | 4907 | const ret_ty = ptr_ty.childType(); |
| ... | @@ -4936,7 +4936,7 @@ pub const FuncGen = struct { | ... | @@ -4936,7 +4936,7 @@ pub const FuncGen = struct { |
| 4936 | return null; | 4936 | return null; |
| 4937 | } | 4937 | } |
| 4938 | | 4938 | |
| 4939 | fn airCmp(self: *FuncGen, inst: Air.Inst.Index, op: math.CompareOperator, want_fast_math: bool) !?*const llvm.Value { | 4939 | fn airCmp(self: *FuncGen, inst: Air.Inst.Index, op: math.CompareOperator, want_fast_math: bool) !?*llvm.Value { |
| 4940 | if (self.liveness.isUnused(inst)) return null; | 4940 | if (self.liveness.isUnused(inst)) return null; |
| 4941 | self.builder.setFastMath(want_fast_math); | 4941 | self.builder.setFastMath(want_fast_math); |
| 4942 | | 4942 | |
| ... | @@ -4948,7 +4948,7 @@ pub const FuncGen = struct { | ... | @@ -4948,7 +4948,7 @@ pub const FuncGen = struct { |
| 4948 | return self.cmp(lhs, rhs, operand_ty, op); | 4948 | return self.cmp(lhs, rhs, operand_ty, op); |
| 4949 | } | 4949 | } |
| 4950 | | 4950 | |
| 4951 | fn airCmpVector(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value { | 4951 | fn airCmpVector(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value { |
| 4952 | if (self.liveness.isUnused(inst)) return null; | 4952 | if (self.liveness.isUnused(inst)) return null; |
| 4953 | self.builder.setFastMath(want_fast_math); | 4953 | self.builder.setFastMath(want_fast_math); |
| 4954 | | 4954 | |
| ... | @@ -4963,23 +4963,23 @@ pub const FuncGen = struct { | ... | @@ -4963,23 +4963,23 @@ pub const FuncGen = struct { |
| 4963 | return self.cmp(lhs, rhs, vec_ty, cmp_op); | 4963 | return self.cmp(lhs, rhs, vec_ty, cmp_op); |
| 4964 | } | 4964 | } |
| 4965 | | 4965 | |
| 4966 | fn airCmpLtErrorsLen(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 4966 | fn airCmpLtErrorsLen(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 4967 | if (self.liveness.isUnused(inst)) return null; | 4967 | if (self.liveness.isUnused(inst)) return null; |
| 4968 | | 4968 | |
| 4969 | const un_op = self.air.instructions.items(.data)[inst].un_op; | 4969 | const un_op = self.air.instructions.items(.data)[inst].un_op; |
| 4970 | const operand = try self.resolveInst(un_op); | 4970 | const operand = try self.resolveInst(un_op); |
| 4971 | const llvm_fn = try self.getCmpLtErrorsLenFunction(); | 4971 | const llvm_fn = try self.getCmpLtErrorsLenFunction(); |
| 4972 | const args: [1]*const llvm.Value = .{operand}; | 4972 | const args: [1]*llvm.Value = .{operand}; |
| 4973 | return self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &args, args.len, .Fast, .Auto, ""); | 4973 | return self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &args, args.len, .Fast, .Auto, ""); |
| 4974 | } | 4974 | } |
| 4975 | | 4975 | |
| 4976 | fn cmp( | 4976 | fn cmp( |
| 4977 | self: *FuncGen, | 4977 | self: *FuncGen, |
| 4978 | lhs: *const llvm.Value, | 4978 | lhs: *llvm.Value, |
| 4979 | rhs: *const llvm.Value, | 4979 | rhs: *llvm.Value, |
| 4980 | operand_ty: Type, | 4980 | operand_ty: Type, |
| 4981 | op: math.CompareOperator, | 4981 | op: math.CompareOperator, |
| 4982 | ) Allocator.Error!*const llvm.Value { | 4982 | ) Allocator.Error!*llvm.Value { |
| 4983 | var int_buffer: Type.Payload.Bits = undefined; | 4983 | var int_buffer: Type.Payload.Bits = undefined; |
| 4984 | var opt_buffer: Type.Payload.ElemType = undefined; | 4984 | var opt_buffer: Type.Payload.ElemType = undefined; |
| 4985 | | 4985 | |
| ... | @@ -5029,7 +5029,7 @@ pub const FuncGen = struct { | ... | @@ -5029,7 +5029,7 @@ pub const FuncGen = struct { |
| 5029 | const both_pl_block_end = self.builder.getInsertBlock(); | 5029 | const both_pl_block_end = self.builder.getInsertBlock(); |
| 5030 | | 5030 | |
| 5031 | self.builder.positionBuilderAtEnd(end_block); | 5031 | self.builder.positionBuilderAtEnd(end_block); |
| 5032 | const incoming_blocks: [3]*const llvm.BasicBlock = .{ | 5032 | const incoming_blocks: [3]*llvm.BasicBlock = .{ |
| 5033 | both_null_block, | 5033 | both_null_block, |
| 5034 | mixed_block, | 5034 | mixed_block, |
| 5035 | both_pl_block_end, | 5035 | both_pl_block_end, |
| ... | @@ -5037,7 +5037,7 @@ pub const FuncGen = struct { | ... | @@ -5037,7 +5037,7 @@ pub const FuncGen = struct { |
| 5037 | const llvm_i1 = self.context.intType(1); | 5037 | const llvm_i1 = self.context.intType(1); |
| 5038 | const llvm_i1_0 = llvm_i1.constInt(0, .False); | 5038 | const llvm_i1_0 = llvm_i1.constInt(0, .False); |
| 5039 | const llvm_i1_1 = llvm_i1.constInt(1, .False); | 5039 | const llvm_i1_1 = llvm_i1.constInt(1, .False); |
| 5040 | const incoming_values: [3]*const llvm.Value = .{ | 5040 | const incoming_values: [3]*llvm.Value = .{ |
| 5041 | switch (op) { | 5041 | switch (op) { |
| 5042 | .eq => llvm_i1_1, | 5042 | .eq => llvm_i1_1, |
| 5043 | .neq => llvm_i1_0, | 5043 | .neq => llvm_i1_0, |
| ... | @@ -5075,7 +5075,7 @@ pub const FuncGen = struct { | ... | @@ -5075,7 +5075,7 @@ pub const FuncGen = struct { |
| 5075 | return self.builder.buildICmp(operation, lhs, rhs, ""); | 5075 | return self.builder.buildICmp(operation, lhs, rhs, ""); |
| 5076 | } | 5076 | } |
| 5077 | | 5077 | |
| 5078 | fn airBlock(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 5078 | fn airBlock(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 5079 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; | 5079 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| 5080 | const extra = self.air.extraData(Air.Block, ty_pl.payload); | 5080 | const extra = self.air.extraData(Air.Block, ty_pl.payload); |
| 5081 | const body = self.air.extra[extra.end..][0..extra.data.body_len]; | 5081 | const body = self.air.extra[extra.end..][0..extra.data.body_len]; |
| ... | @@ -5127,7 +5127,7 @@ pub const FuncGen = struct { | ... | @@ -5127,7 +5127,7 @@ pub const FuncGen = struct { |
| 5127 | return phi_node; | 5127 | return phi_node; |
| 5128 | } | 5128 | } |
| 5129 | | 5129 | |
| 5130 | fn airBr(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 5130 | fn airBr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 5131 | const branch = self.air.instructions.items(.data)[inst].br; | 5131 | const branch = self.air.instructions.items(.data)[inst].br; |
| 5132 | const block = self.blocks.get(branch.block_inst).?; | 5132 | const block = self.blocks.get(branch.block_inst).?; |
| 5133 | | 5133 | |
| ... | @@ -5147,7 +5147,7 @@ pub const FuncGen = struct { | ... | @@ -5147,7 +5147,7 @@ pub const FuncGen = struct { |
| 5147 | return null; | 5147 | return null; |
| 5148 | } | 5148 | } |
| 5149 | | 5149 | |
| 5150 | fn airCondBr(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 5150 | fn airCondBr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 5151 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; | 5151 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; |
| 5152 | const cond = try self.resolveInst(pl_op.operand); | 5152 | const cond = try self.resolveInst(pl_op.operand); |
| 5153 | const extra = self.air.extraData(Air.CondBr, pl_op.payload); | 5153 | const extra = self.air.extraData(Air.CondBr, pl_op.payload); |
| ... | @@ -5168,7 +5168,7 @@ pub const FuncGen = struct { | ... | @@ -5168,7 +5168,7 @@ pub const FuncGen = struct { |
| 5168 | return null; | 5168 | return null; |
| 5169 | } | 5169 | } |
| 5170 | | 5170 | |
| 5171 | fn airTry(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 5171 | fn airTry(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 5172 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; | 5172 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; |
| 5173 | const err_union = try self.resolveInst(pl_op.operand); | 5173 | const err_union = try self.resolveInst(pl_op.operand); |
| 5174 | const extra = self.air.extraData(Air.Try, pl_op.payload); | 5174 | const extra = self.air.extraData(Air.Try, pl_op.payload); |
| ... | @@ -5178,7 +5178,7 @@ pub const FuncGen = struct { | ... | @@ -5178,7 +5178,7 @@ pub const FuncGen = struct { |
| 5178 | return lowerTry(self, err_union, body, err_union_ty, false, result_ty); | 5178 | return lowerTry(self, err_union, body, err_union_ty, false, result_ty); |
| 5179 | } | 5179 | } |
| 5180 | | 5180 | |
| 5181 | fn airTryPtr(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 5181 | fn airTryPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 5182 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; | 5182 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| 5183 | const extra = self.air.extraData(Air.TryPtr, ty_pl.payload); | 5183 | const extra = self.air.extraData(Air.TryPtr, ty_pl.payload); |
| 5184 | const err_union_ptr = try self.resolveInst(extra.data.ptr); | 5184 | const err_union_ptr = try self.resolveInst(extra.data.ptr); |
| ... | @@ -5190,12 +5190,12 @@ pub const FuncGen = struct { | ... | @@ -5190,12 +5190,12 @@ pub const FuncGen = struct { |
| 5190 | | 5190 | |
| 5191 | fn lowerTry( | 5191 | fn lowerTry( |
| 5192 | fg: *FuncGen, | 5192 | fg: *FuncGen, |
| 5193 | err_union: *const llvm.Value, | 5193 | err_union: *llvm.Value, |
| 5194 | body: []const Air.Inst.Index, | 5194 | body: []const Air.Inst.Index, |
| 5195 | err_union_ty: Type, | 5195 | err_union_ty: Type, |
| 5196 | operand_is_ptr: bool, | 5196 | operand_is_ptr: bool, |
| 5197 | result_ty: Type, | 5197 | result_ty: Type, |
| 5198 | ) !?*const llvm.Value { | 5198 | ) !?*llvm.Value { |
| 5199 | const payload_ty = err_union_ty.errorUnionPayload(); | 5199 | const payload_ty = err_union_ty.errorUnionPayload(); |
| 5200 | const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(); | 5200 | const payload_has_bits = payload_ty.hasRuntimeBitsIgnoreComptime(); |
| 5201 | const target = fg.dg.module.getTarget(); | 5201 | const target = fg.dg.module.getTarget(); |
| ... | @@ -5256,7 +5256,7 @@ pub const FuncGen = struct { | ... | @@ -5256,7 +5256,7 @@ pub const FuncGen = struct { |
| 5256 | return fg.builder.buildExtractValue(err_union, offset, ""); | 5256 | return fg.builder.buildExtractValue(err_union, offset, ""); |
| 5257 | } | 5257 | } |
| 5258 | | 5258 | |
| 5259 | fn airSwitchBr(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 5259 | fn airSwitchBr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 5260 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; | 5260 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; |
| 5261 | const cond = try self.resolveInst(pl_op.operand); | 5261 | const cond = try self.resolveInst(pl_op.operand); |
| 5262 | const switch_br = self.air.extraData(Air.SwitchBr, pl_op.payload); | 5262 | const switch_br = self.air.extraData(Air.SwitchBr, pl_op.payload); |
| ... | @@ -5305,7 +5305,7 @@ pub const FuncGen = struct { | ... | @@ -5305,7 +5305,7 @@ pub const FuncGen = struct { |
| 5305 | return null; | 5305 | return null; |
| 5306 | } | 5306 | } |
| 5307 | | 5307 | |
| 5308 | fn airLoop(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 5308 | fn airLoop(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 5309 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; | 5309 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| 5310 | const loop = self.air.extraData(Air.Block, ty_pl.payload); | 5310 | const loop = self.air.extraData(Air.Block, ty_pl.payload); |
| 5311 | const body = self.air.extra[loop.end..][0..loop.data.body_len]; | 5311 | const body = self.air.extra[loop.end..][0..loop.data.body_len]; |
| ... | @@ -5327,7 +5327,7 @@ pub const FuncGen = struct { | ... | @@ -5327,7 +5327,7 @@ pub const FuncGen = struct { |
| 5327 | return null; | 5327 | return null; |
| 5328 | } | 5328 | } |
| 5329 | | 5329 | |
| 5330 | fn airArrayToSlice(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 5330 | fn airArrayToSlice(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 5331 | if (self.liveness.isUnused(inst)) | 5331 | if (self.liveness.isUnused(inst)) |
| 5332 | return null; | 5332 | return null; |
| 5333 | | 5333 | |
| ... | @@ -5341,7 +5341,7 @@ pub const FuncGen = struct { | ... | @@ -5341,7 +5341,7 @@ pub const FuncGen = struct { |
| 5341 | return self.builder.buildInsertValue(slice_llvm_ty.getUndef(), len, 1, ""); | 5341 | return self.builder.buildInsertValue(slice_llvm_ty.getUndef(), len, 1, ""); |
| 5342 | } | 5342 | } |
| 5343 | const operand = try self.resolveInst(ty_op.operand); | 5343 | const operand = try self.resolveInst(ty_op.operand); |
| 5344 | const indices: [2]*const llvm.Value = .{ | 5344 | const indices: [2]*llvm.Value = .{ |
| 5345 | llvm_usize.constNull(), llvm_usize.constNull(), | 5345 | llvm_usize.constNull(), llvm_usize.constNull(), |
| 5346 | }; | 5346 | }; |
| 5347 | const array_llvm_ty = try self.dg.lowerType(array_ty); | 5347 | const array_llvm_ty = try self.dg.lowerType(array_ty); |
| ... | @@ -5350,7 +5350,7 @@ pub const FuncGen = struct { | ... | @@ -5350,7 +5350,7 @@ pub const FuncGen = struct { |
| 5350 | return self.builder.buildInsertValue(partial, len, 1, ""); | 5350 | return self.builder.buildInsertValue(partial, len, 1, ""); |
| 5351 | } | 5351 | } |
| 5352 | | 5352 | |
| 5353 | fn airIntToFloat(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 5353 | fn airIntToFloat(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 5354 | if (self.liveness.isUnused(inst)) | 5354 | if (self.liveness.isUnused(inst)) |
| 5355 | return null; | 5355 | return null; |
| 5356 | | 5356 | |
| ... | @@ -5394,22 +5394,22 @@ pub const FuncGen = struct { | ... | @@ -5394,22 +5394,22 @@ pub const FuncGen = struct { |
| 5394 | compiler_rt_dest_abbrev, | 5394 | compiler_rt_dest_abbrev, |
| 5395 | }) catch unreachable; | 5395 | }) catch unreachable; |
| 5396 | | 5396 | |
| 5397 | var param_types = [1]*const llvm.Type{rt_int_ty}; | 5397 | var param_types = [1]*llvm.Type{rt_int_ty}; |
| 5398 | if (rt_int_bits == 128 and (target.os.tag == .windows and target.cpu.arch == .x86_64)) { | 5398 | if (rt_int_bits == 128 and (target.os.tag == .windows and target.cpu.arch == .x86_64)) { |
| 5399 | // On Windows x86-64, "ti" functions must use Vector(2, u64) instead of the standard | 5399 | // On Windows x86-64, "ti" functions must use Vector(2, u64) instead of the standard |
| 5400 | // i128 calling convention to adhere to the ABI that LLVM expects compiler-rt to have. | 5400 | // i128 calling convention to adhere to the ABI that LLVM expects compiler-rt to have. |
| 5401 | const v2i64 = self.context.intType(64).vectorType(2); | 5401 | const v2i64 = self.context.intType(64).vectorType(2); |
| 5402 | extended = self.builder.buildBitCast(extended, v2i64, ""); | 5402 | extended = self.builder.buildBitCast(extended, v2i64, ""); |
| 5403 | param_types = [1]*const llvm.Type{v2i64}; | 5403 | param_types = [1]*llvm.Type{v2i64}; |
| 5404 | } | 5404 | } |
| 5405 | | 5405 | |
| 5406 | const libc_fn = self.getLibcFunction(fn_name, &param_types, dest_llvm_ty); | 5406 | const libc_fn = self.getLibcFunction(fn_name, &param_types, dest_llvm_ty); |
| 5407 | const params = [1]*const llvm.Value{extended}; | 5407 | const params = [1]*llvm.Value{extended}; |
| 5408 | | 5408 | |
| 5409 | return self.builder.buildCall(libc_fn.globalGetValueType(), libc_fn, &params, params.len, .C, .Auto, ""); | 5409 | return self.builder.buildCall(libc_fn.globalGetValueType(), libc_fn, &params, params.len, .C, .Auto, ""); |
| 5410 | } | 5410 | } |
| 5411 | | 5411 | |
| 5412 | fn airFloatToInt(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value { | 5412 | fn airFloatToInt(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value { |
| 5413 | if (self.liveness.isUnused(inst)) | 5413 | if (self.liveness.isUnused(inst)) |
| 5414 | return null; | 5414 | return null; |
| 5415 | | 5415 | |
| ... | @@ -5457,9 +5457,9 @@ pub const FuncGen = struct { | ... | @@ -5457,9 +5457,9 @@ pub const FuncGen = struct { |
| 5457 | }) catch unreachable; | 5457 | }) catch unreachable; |
| 5458 | | 5458 | |
| 5459 | const operand_llvm_ty = try self.dg.lowerType(operand_ty); | 5459 | const operand_llvm_ty = try self.dg.lowerType(operand_ty); |
| 5460 | const param_types = [1]*const llvm.Type{operand_llvm_ty}; | 5460 | const param_types = [1]*llvm.Type{operand_llvm_ty}; |
| 5461 | const libc_fn = self.getLibcFunction(fn_name, &param_types, libc_ret_ty); | 5461 | const libc_fn = self.getLibcFunction(fn_name, &param_types, libc_ret_ty); |
| 5462 | const params = [1]*const llvm.Value{operand}; | 5462 | const params = [1]*llvm.Value{operand}; |
| 5463 | | 5463 | |
| 5464 | var result = self.builder.buildCall(libc_fn.globalGetValueType(), libc_fn, &params, params.len, .C, .Auto, ""); | 5464 | var result = self.builder.buildCall(libc_fn.globalGetValueType(), libc_fn, &params, params.len, .C, .Auto, ""); |
| 5465 | | 5465 | |
| ... | @@ -5468,7 +5468,7 @@ pub const FuncGen = struct { | ... | @@ -5468,7 +5468,7 @@ pub const FuncGen = struct { |
| 5468 | return result; | 5468 | return result; |
| 5469 | } | 5469 | } |
| 5470 | | 5470 | |
| 5471 | fn airSliceField(self: *FuncGen, inst: Air.Inst.Index, index: c_uint) !?*const llvm.Value { | 5471 | fn airSliceField(self: *FuncGen, inst: Air.Inst.Index, index: c_uint) !?*llvm.Value { |
| 5472 | if (self.liveness.isUnused(inst)) return null; | 5472 | if (self.liveness.isUnused(inst)) return null; |
| 5473 | | 5473 | |
| 5474 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 5474 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| ... | @@ -5476,7 +5476,7 @@ pub const FuncGen = struct { | ... | @@ -5476,7 +5476,7 @@ pub const FuncGen = struct { |
| 5476 | return self.builder.buildExtractValue(operand, index, ""); | 5476 | return self.builder.buildExtractValue(operand, index, ""); |
| 5477 | } | 5477 | } |
| 5478 | | 5478 | |
| 5479 | fn airPtrSliceFieldPtr(self: *FuncGen, inst: Air.Inst.Index, index: c_uint) !?*const llvm.Value { | 5479 | fn airPtrSliceFieldPtr(self: *FuncGen, inst: Air.Inst.Index, index: c_uint) !?*llvm.Value { |
| 5480 | if (self.liveness.isUnused(inst)) return null; | 5480 | if (self.liveness.isUnused(inst)) return null; |
| 5481 | | 5481 | |
| 5482 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 5482 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| ... | @@ -5487,7 +5487,7 @@ pub const FuncGen = struct { | ... | @@ -5487,7 +5487,7 @@ pub const FuncGen = struct { |
| 5487 | return self.builder.buildStructGEP(slice_llvm_ty, slice_ptr, index, ""); | 5487 | return self.builder.buildStructGEP(slice_llvm_ty, slice_ptr, index, ""); |
| 5488 | } | 5488 | } |
| 5489 | | 5489 | |
| 5490 | fn airSliceElemVal(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 5490 | fn airSliceElemVal(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 5491 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; | 5491 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 5492 | const slice_ty = self.air.typeOf(bin_op.lhs); | 5492 | const slice_ty = self.air.typeOf(bin_op.lhs); |
| 5493 | if (!slice_ty.isVolatilePtr() and self.liveness.isUnused(inst)) return null; | 5493 | if (!slice_ty.isVolatilePtr() and self.liveness.isUnused(inst)) return null; |
| ... | @@ -5496,12 +5496,12 @@ pub const FuncGen = struct { | ... | @@ -5496,12 +5496,12 @@ pub const FuncGen = struct { |
| 5496 | const index = try self.resolveInst(bin_op.rhs); | 5496 | const index = try self.resolveInst(bin_op.rhs); |
| 5497 | const llvm_elem_ty = try self.dg.lowerPtrElemTy(slice_ty.childType()); | 5497 | const llvm_elem_ty = try self.dg.lowerPtrElemTy(slice_ty.childType()); |
| 5498 | const base_ptr = self.builder.buildExtractValue(slice, 0, ""); | 5498 | const base_ptr = self.builder.buildExtractValue(slice, 0, ""); |
| 5499 | const indices: [1]*const llvm.Value = .{index}; | 5499 | const indices: [1]*llvm.Value = .{index}; |
| 5500 | const ptr = self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, ""); | 5500 | const ptr = self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, ""); |
| 5501 | return self.load(ptr, slice_ty); | 5501 | return self.load(ptr, slice_ty); |
| 5502 | } | 5502 | } |
| 5503 | | 5503 | |
| 5504 | fn airSliceElemPtr(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 5504 | fn airSliceElemPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 5505 | if (self.liveness.isUnused(inst)) return null; | 5505 | if (self.liveness.isUnused(inst)) return null; |
| 5506 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; | 5506 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| 5507 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; | 5507 | const bin_op = self.air.extraData(Air.Bin, ty_pl.payload).data; |
| ... | @@ -5511,11 +5511,11 @@ pub const FuncGen = struct { | ... | @@ -5511,11 +5511,11 @@ pub const FuncGen = struct { |
| 5511 | const index = try self.resolveInst(bin_op.rhs); | 5511 | const index = try self.resolveInst(bin_op.rhs); |
| 5512 | const llvm_elem_ty = try self.dg.lowerPtrElemTy(slice_ty.childType()); | 5512 | const llvm_elem_ty = try self.dg.lowerPtrElemTy(slice_ty.childType()); |
| 5513 | const base_ptr = self.builder.buildExtractValue(slice, 0, ""); | 5513 | const base_ptr = self.builder.buildExtractValue(slice, 0, ""); |
| 5514 | const indices: [1]*const llvm.Value = .{index}; | 5514 | const indices: [1]*llvm.Value = .{index}; |
| 5515 | return self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, ""); | 5515 | return self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, ""); |
| 5516 | } | 5516 | } |
| 5517 | | 5517 | |
| 5518 | fn airArrayElemVal(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 5518 | fn airArrayElemVal(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 5519 | if (self.liveness.isUnused(inst)) return null; | 5519 | if (self.liveness.isUnused(inst)) return null; |
| 5520 | | 5520 | |
| 5521 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; | 5521 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| ... | @@ -5524,7 +5524,7 @@ pub const FuncGen = struct { | ... | @@ -5524,7 +5524,7 @@ pub const FuncGen = struct { |
| 5524 | const rhs = try self.resolveInst(bin_op.rhs); | 5524 | const rhs = try self.resolveInst(bin_op.rhs); |
| 5525 | if (isByRef(array_ty)) { | 5525 | if (isByRef(array_ty)) { |
| 5526 | const array_llvm_ty = try self.dg.lowerType(array_ty); | 5526 | const array_llvm_ty = try self.dg.lowerType(array_ty); |
| 5527 | const indices: [2]*const llvm.Value = .{ self.context.intType(32).constNull(), rhs }; | 5527 | const indices: [2]*llvm.Value = .{ self.context.intType(32).constNull(), rhs }; |
| 5528 | const elem_ptr = self.builder.buildInBoundsGEP(array_llvm_ty, array_llvm_val, &indices, indices.len, ""); | 5528 | const elem_ptr = self.builder.buildInBoundsGEP(array_llvm_ty, array_llvm_val, &indices, indices.len, ""); |
| 5529 | const elem_ty = array_ty.childType(); | 5529 | const elem_ty = array_ty.childType(); |
| 5530 | if (isByRef(elem_ty)) { | 5530 | if (isByRef(elem_ty)) { |
| ... | @@ -5539,7 +5539,7 @@ pub const FuncGen = struct { | ... | @@ -5539,7 +5539,7 @@ pub const FuncGen = struct { |
| 5539 | return self.builder.buildExtractElement(array_llvm_val, rhs, ""); | 5539 | return self.builder.buildExtractElement(array_llvm_val, rhs, ""); |
| 5540 | } | 5540 | } |
| 5541 | | 5541 | |
| 5542 | fn airPtrElemVal(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 5542 | fn airPtrElemVal(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 5543 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; | 5543 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 5544 | const ptr_ty = self.air.typeOf(bin_op.lhs); | 5544 | const ptr_ty = self.air.typeOf(bin_op.lhs); |
| 5545 | if (!ptr_ty.isVolatilePtr() and self.liveness.isUnused(inst)) return null; | 5545 | if (!ptr_ty.isVolatilePtr() and self.liveness.isUnused(inst)) return null; |
| ... | @@ -5550,16 +5550,16 @@ pub const FuncGen = struct { | ... | @@ -5550,16 +5550,16 @@ pub const FuncGen = struct { |
| 5550 | // TODO: when we go fully opaque pointers in LLVM 16 we can remove this branch | 5550 | // TODO: when we go fully opaque pointers in LLVM 16 we can remove this branch |
| 5551 | const ptr = if (ptr_ty.isSinglePointer()) ptr: { | 5551 | const ptr = if (ptr_ty.isSinglePointer()) ptr: { |
| 5552 | // If this is a single-item pointer to an array, we need another index in the GEP. | 5552 | // If this is a single-item pointer to an array, we need another index in the GEP. |
| 5553 | const indices: [2]*const llvm.Value = .{ self.context.intType(32).constNull(), rhs }; | 5553 | const indices: [2]*llvm.Value = .{ self.context.intType(32).constNull(), rhs }; |
| 5554 | break :ptr self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, ""); | 5554 | break :ptr self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, ""); |
| 5555 | } else ptr: { | 5555 | } else ptr: { |
| 5556 | const indices: [1]*const llvm.Value = .{rhs}; | 5556 | const indices: [1]*llvm.Value = .{rhs}; |
| 5557 | break :ptr self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, ""); | 5557 | break :ptr self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, ""); |
| 5558 | }; | 5558 | }; |
| 5559 | return self.load(ptr, ptr_ty); | 5559 | return self.load(ptr, ptr_ty); |
| 5560 | } | 5560 | } |
| 5561 | | 5561 | |
| 5562 | fn airPtrElemPtr(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 5562 | fn airPtrElemPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 5563 | if (self.liveness.isUnused(inst)) return null; | 5563 | if (self.liveness.isUnused(inst)) return null; |
| 5564 | | 5564 | |
| 5565 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; | 5565 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| ... | @@ -5573,15 +5573,15 @@ pub const FuncGen = struct { | ... | @@ -5573,15 +5573,15 @@ pub const FuncGen = struct { |
| 5573 | const llvm_elem_ty = try self.dg.lowerPtrElemTy(elem_ty); | 5573 | const llvm_elem_ty = try self.dg.lowerPtrElemTy(elem_ty); |
| 5574 | if (ptr_ty.isSinglePointer()) { | 5574 | if (ptr_ty.isSinglePointer()) { |
| 5575 | // If this is a single-item pointer to an array, we need another index in the GEP. | 5575 | // If this is a single-item pointer to an array, we need another index in the GEP. |
| 5576 | const indices: [2]*const llvm.Value = .{ self.context.intType(32).constNull(), rhs }; | 5576 | const indices: [2]*llvm.Value = .{ self.context.intType(32).constNull(), rhs }; |
| 5577 | return self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, ""); | 5577 | return self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, ""); |
| 5578 | } else { | 5578 | } else { |
| 5579 | const indices: [1]*const llvm.Value = .{rhs}; | 5579 | const indices: [1]*llvm.Value = .{rhs}; |
| 5580 | return self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, ""); | 5580 | return self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, ""); |
| 5581 | } | 5581 | } |
| 5582 | } | 5582 | } |
| 5583 | | 5583 | |
| 5584 | fn airStructFieldPtr(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 5584 | fn airStructFieldPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 5585 | if (self.liveness.isUnused(inst)) | 5585 | if (self.liveness.isUnused(inst)) |
| 5586 | return null; | 5586 | return null; |
| 5587 | | 5587 | |
| ... | @@ -5596,7 +5596,7 @@ pub const FuncGen = struct { | ... | @@ -5596,7 +5596,7 @@ pub const FuncGen = struct { |
| 5596 | self: *FuncGen, | 5596 | self: *FuncGen, |
| 5597 | inst: Air.Inst.Index, | 5597 | inst: Air.Inst.Index, |
| 5598 | field_index: u32, | 5598 | field_index: u32, |
| 5599 | ) !?*const llvm.Value { | 5599 | ) !?*llvm.Value { |
| 5600 | if (self.liveness.isUnused(inst)) return null; | 5600 | if (self.liveness.isUnused(inst)) return null; |
| 5601 | | 5601 | |
| 5602 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 5602 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| ... | @@ -5605,7 +5605,7 @@ pub const FuncGen = struct { | ... | @@ -5605,7 +5605,7 @@ pub const FuncGen = struct { |
| 5605 | return self.fieldPtr(inst, struct_ptr, struct_ptr_ty, field_index); | 5605 | return self.fieldPtr(inst, struct_ptr, struct_ptr_ty, field_index); |
| 5606 | } | 5606 | } |
| 5607 | | 5607 | |
| 5608 | fn airStructFieldVal(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 5608 | fn airStructFieldVal(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 5609 | if (self.liveness.isUnused(inst)) return null; | 5609 | if (self.liveness.isUnused(inst)) return null; |
| 5610 | | 5610 | |
| 5611 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; | 5611 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| ... | @@ -5683,7 +5683,7 @@ pub const FuncGen = struct { | ... | @@ -5683,7 +5683,7 @@ pub const FuncGen = struct { |
| 5683 | } | 5683 | } |
| 5684 | } | 5684 | } |
| 5685 | | 5685 | |
| 5686 | fn airFieldParentPtr(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 5686 | fn airFieldParentPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 5687 | if (self.liveness.isUnused(inst)) return null; | 5687 | if (self.liveness.isUnused(inst)) return null; |
| 5688 | | 5688 | |
| 5689 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; | 5689 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| ... | @@ -5706,7 +5706,7 @@ pub const FuncGen = struct { | ... | @@ -5706,7 +5706,7 @@ pub const FuncGen = struct { |
| 5706 | return self.builder.buildIntToPtr(base_ptr_int, res_ty, ""); | 5706 | return self.builder.buildIntToPtr(base_ptr_int, res_ty, ""); |
| 5707 | } | 5707 | } |
| 5708 | | 5708 | |
| 5709 | fn airNot(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 5709 | fn airNot(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 5710 | if (self.liveness.isUnused(inst)) | 5710 | if (self.liveness.isUnused(inst)) |
| 5711 | return null; | 5711 | return null; |
| 5712 | | 5712 | |
| ... | @@ -5716,13 +5716,13 @@ pub const FuncGen = struct { | ... | @@ -5716,13 +5716,13 @@ pub const FuncGen = struct { |
| 5716 | return self.builder.buildNot(operand, ""); | 5716 | return self.builder.buildNot(operand, ""); |
| 5717 | } | 5717 | } |
| 5718 | | 5718 | |
| 5719 | fn airUnreach(self: *FuncGen, inst: Air.Inst.Index) ?*const llvm.Value { | 5719 | fn airUnreach(self: *FuncGen, inst: Air.Inst.Index) ?*llvm.Value { |
| 5720 | _ = inst; | 5720 | _ = inst; |
| 5721 | _ = self.builder.buildUnreachable(); | 5721 | _ = self.builder.buildUnreachable(); |
| 5722 | return null; | 5722 | return null; |
| 5723 | } | 5723 | } |
| 5724 | | 5724 | |
| 5725 | fn airDbgStmt(self: *FuncGen, inst: Air.Inst.Index) ?*const llvm.Value { | 5725 | fn airDbgStmt(self: *FuncGen, inst: Air.Inst.Index) ?*llvm.Value { |
| 5726 | const di_scope = self.di_scope orelse return null; | 5726 | const di_scope = self.di_scope orelse return null; |
| 5727 | const dbg_stmt = self.air.instructions.items(.data)[inst].dbg_stmt; | 5727 | const dbg_stmt = self.air.instructions.items(.data)[inst].dbg_stmt; |
| 5728 | self.prev_dbg_line = @intCast(c_uint, self.base_line + dbg_stmt.line + 1); | 5728 | self.prev_dbg_line = @intCast(c_uint, self.base_line + dbg_stmt.line + 1); |
| ... | @@ -5735,7 +5735,7 @@ pub const FuncGen = struct { | ... | @@ -5735,7 +5735,7 @@ pub const FuncGen = struct { |
| 5735 | return null; | 5735 | return null; |
| 5736 | } | 5736 | } |
| 5737 | | 5737 | |
| 5738 | fn airDbgInlineBegin(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 5738 | fn airDbgInlineBegin(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 5739 | const dib = self.dg.object.di_builder orelse return null; | 5739 | const dib = self.dg.object.di_builder orelse return null; |
| 5740 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; | 5740 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| 5741 | | 5741 | |
| ... | @@ -5778,7 +5778,7 @@ pub const FuncGen = struct { | ... | @@ -5778,7 +5778,7 @@ pub const FuncGen = struct { |
| 5778 | return null; | 5778 | return null; |
| 5779 | } | 5779 | } |
| 5780 | | 5780 | |
| 5781 | fn airDbgInlineEnd(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 5781 | fn airDbgInlineEnd(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 5782 | if (self.dg.object.di_builder == null) return null; | 5782 | if (self.dg.object.di_builder == null) return null; |
| 5783 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; | 5783 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| 5784 | | 5784 | |
| ... | @@ -5793,7 +5793,7 @@ pub const FuncGen = struct { | ... | @@ -5793,7 +5793,7 @@ pub const FuncGen = struct { |
| 5793 | return null; | 5793 | return null; |
| 5794 | } | 5794 | } |
| 5795 | | 5795 | |
| 5796 | fn airDbgBlockBegin(self: *FuncGen) !?*const llvm.Value { | 5796 | fn airDbgBlockBegin(self: *FuncGen) !?*llvm.Value { |
| 5797 | const dib = self.dg.object.di_builder orelse return null; | 5797 | const dib = self.dg.object.di_builder orelse return null; |
| 5798 | const old_scope = self.di_scope.?; | 5798 | const old_scope = self.di_scope.?; |
| 5799 | try self.dbg_block_stack.append(self.gpa, old_scope); | 5799 | try self.dbg_block_stack.append(self.gpa, old_scope); |
| ... | @@ -5802,13 +5802,13 @@ pub const FuncGen = struct { | ... | @@ -5802,13 +5802,13 @@ pub const FuncGen = struct { |
| 5802 | return null; | 5802 | return null; |
| 5803 | } | 5803 | } |
| 5804 | | 5804 | |
| 5805 | fn airDbgBlockEnd(self: *FuncGen) !?*const llvm.Value { | 5805 | fn airDbgBlockEnd(self: *FuncGen) !?*llvm.Value { |
| 5806 | if (self.dg.object.di_builder == null) return null; | 5806 | if (self.dg.object.di_builder == null) return null; |
| 5807 | self.di_scope = self.dbg_block_stack.pop(); | 5807 | self.di_scope = self.dbg_block_stack.pop(); |
| 5808 | return null; | 5808 | return null; |
| 5809 | } | 5809 | } |
| 5810 | | 5810 | |
| 5811 | fn airDbgVarPtr(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 5811 | fn airDbgVarPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 5812 | const dib = self.dg.object.di_builder orelse return null; | 5812 | const dib = self.dg.object.di_builder orelse return null; |
| 5813 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; | 5813 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; |
| 5814 | const operand = try self.resolveInst(pl_op.operand); | 5814 | const operand = try self.resolveInst(pl_op.operand); |
| ... | @@ -5834,7 +5834,7 @@ pub const FuncGen = struct { | ... | @@ -5834,7 +5834,7 @@ pub const FuncGen = struct { |
| 5834 | return null; | 5834 | return null; |
| 5835 | } | 5835 | } |
| 5836 | | 5836 | |
| 5837 | fn airDbgVarVal(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 5837 | fn airDbgVarVal(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 5838 | const dib = self.dg.object.di_builder orelse return null; | 5838 | const dib = self.dg.object.di_builder orelse return null; |
| 5839 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; | 5839 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; |
| 5840 | const operand = try self.resolveInst(pl_op.operand); | 5840 | const operand = try self.resolveInst(pl_op.operand); |
| ... | @@ -5868,7 +5868,7 @@ pub const FuncGen = struct { | ... | @@ -5868,7 +5868,7 @@ pub const FuncGen = struct { |
| 5868 | return null; | 5868 | return null; |
| 5869 | } | 5869 | } |
| 5870 | | 5870 | |
| 5871 | fn airAssembly(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 5871 | fn airAssembly(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 5872 | // Eventually, the Zig compiler needs to be reworked to have inline assembly go | 5872 | // Eventually, the Zig compiler needs to be reworked to have inline assembly go |
| 5873 | // through the same parsing code regardless of backend, and have LLVM-flavored | 5873 | // through the same parsing code regardless of backend, and have LLVM-flavored |
| 5874 | // inline assembly be *output* from that assembler. | 5874 | // inline assembly be *output* from that assembler. |
| ... | @@ -5899,15 +5899,15 @@ pub const FuncGen = struct { | ... | @@ -5899,15 +5899,15 @@ pub const FuncGen = struct { |
| 5899 | // The exact number of return / parameter values depends on which output values | 5899 | // The exact number of return / parameter values depends on which output values |
| 5900 | // are passed by reference as indirect outputs (determined below). | 5900 | // are passed by reference as indirect outputs (determined below). |
| 5901 | const max_return_count = outputs.len; | 5901 | const max_return_count = outputs.len; |
| 5902 | const llvm_ret_types = try arena.alloc(*const llvm.Type, max_return_count); | 5902 | const llvm_ret_types = try arena.alloc(*llvm.Type, max_return_count); |
| 5903 | const llvm_ret_indirect = try arena.alloc(bool, max_return_count); | 5903 | const llvm_ret_indirect = try arena.alloc(bool, max_return_count); |
| 5904 | | 5904 | |
| 5905 | const max_param_count = inputs.len + outputs.len; | 5905 | const max_param_count = inputs.len + outputs.len; |
| 5906 | const llvm_param_types = try arena.alloc(*const llvm.Type, max_param_count); | 5906 | const llvm_param_types = try arena.alloc(*llvm.Type, max_param_count); |
| 5907 | const llvm_param_values = try arena.alloc(*const llvm.Value, max_param_count); | 5907 | const llvm_param_values = try arena.alloc(*llvm.Value, max_param_count); |
| 5908 | // This stores whether we need to add an elementtype attribute and | 5908 | // This stores whether we need to add an elementtype attribute and |
| 5909 | // if so, the element type itself. | 5909 | // if so, the element type itself. |
| 5910 | const llvm_param_attrs = try arena.alloc(?*const llvm.Type, max_param_count); | 5910 | const llvm_param_attrs = try arena.alloc(?*llvm.Type, max_param_count); |
| 5911 | const target = self.dg.module.getTarget(); | 5911 | const target = self.dg.module.getTarget(); |
| 5912 | | 5912 | |
| 5913 | var llvm_ret_i: usize = 0; | 5913 | var llvm_ret_i: usize = 0; |
| ... | @@ -5987,7 +5987,7 @@ pub const FuncGen = struct { | ... | @@ -5987,7 +5987,7 @@ pub const FuncGen = struct { |
| 5987 | | 5987 | |
| 5988 | const arg_llvm_value = try self.resolveInst(input); | 5988 | const arg_llvm_value = try self.resolveInst(input); |
| 5989 | const arg_ty = self.air.typeOf(input); | 5989 | const arg_ty = self.air.typeOf(input); |
| 5990 | var llvm_elem_ty: ?*const llvm.Type = null; | 5990 | var llvm_elem_ty: ?*llvm.Type = null; |
| 5991 | if (isByRef(arg_ty)) { | 5991 | if (isByRef(arg_ty)) { |
| 5992 | llvm_elem_ty = try self.dg.lowerPtrElemTy(arg_ty); | 5992 | llvm_elem_ty = try self.dg.lowerPtrElemTy(arg_ty); |
| 5993 | if (constraintAllowsMemory(constraint)) { | 5993 | if (constraintAllowsMemory(constraint)) { |
| ... | @@ -6208,7 +6208,7 @@ pub const FuncGen = struct { | ... | @@ -6208,7 +6208,7 @@ pub const FuncGen = struct { |
| 6208 | inst: Air.Inst.Index, | 6208 | inst: Air.Inst.Index, |
| 6209 | operand_is_ptr: bool, | 6209 | operand_is_ptr: bool, |
| 6210 | pred: llvm.IntPredicate, | 6210 | pred: llvm.IntPredicate, |
| 6211 | ) !?*const llvm.Value { | 6211 | ) !?*llvm.Value { |
| 6212 | if (self.liveness.isUnused(inst)) return null; | 6212 | if (self.liveness.isUnused(inst)) return null; |
| 6213 | | 6213 | |
| 6214 | const un_op = self.air.instructions.items(.data)[inst].un_op; | 6214 | const un_op = self.air.instructions.items(.data)[inst].un_op; |
| ... | @@ -6251,7 +6251,7 @@ pub const FuncGen = struct { | ... | @@ -6251,7 +6251,7 @@ pub const FuncGen = struct { |
| 6251 | inst: Air.Inst.Index, | 6251 | inst: Air.Inst.Index, |
| 6252 | op: llvm.IntPredicate, | 6252 | op: llvm.IntPredicate, |
| 6253 | operand_is_ptr: bool, | 6253 | operand_is_ptr: bool, |
| 6254 | ) !?*const llvm.Value { | 6254 | ) !?*llvm.Value { |
| 6255 | if (self.liveness.isUnused(inst)) return null; | 6255 | if (self.liveness.isUnused(inst)) return null; |
| 6256 | | 6256 | |
| 6257 | const un_op = self.air.instructions.items(.data)[inst].un_op; | 6257 | const un_op = self.air.instructions.items(.data)[inst].un_op; |
| ... | @@ -6293,7 +6293,7 @@ pub const FuncGen = struct { | ... | @@ -6293,7 +6293,7 @@ pub const FuncGen = struct { |
| 6293 | return self.builder.buildICmp(op, loaded, zero, ""); | 6293 | return self.builder.buildICmp(op, loaded, zero, ""); |
| 6294 | } | 6294 | } |
| 6295 | | 6295 | |
| 6296 | fn airOptionalPayloadPtr(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 6296 | fn airOptionalPayloadPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 6297 | if (self.liveness.isUnused(inst)) return null; | 6297 | if (self.liveness.isUnused(inst)) return null; |
| 6298 | | 6298 | |
| 6299 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 6299 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| ... | @@ -6318,7 +6318,7 @@ pub const FuncGen = struct { | ... | @@ -6318,7 +6318,7 @@ pub const FuncGen = struct { |
| 6318 | return self.builder.buildStructGEP(optional_llvm_ty, operand, 0, ""); | 6318 | return self.builder.buildStructGEP(optional_llvm_ty, operand, 0, ""); |
| 6319 | } | 6319 | } |
| 6320 | | 6320 | |
| 6321 | fn airOptionalPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 6321 | fn airOptionalPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 6322 | comptime assert(optional_layout_version == 3); | 6322 | comptime assert(optional_layout_version == 3); |
| 6323 | | 6323 | |
| 6324 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 6324 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| ... | @@ -6355,7 +6355,7 @@ pub const FuncGen = struct { | ... | @@ -6355,7 +6355,7 @@ pub const FuncGen = struct { |
| 6355 | return self.builder.buildStructGEP(optional_llvm_ty, operand, 0, ""); | 6355 | return self.builder.buildStructGEP(optional_llvm_ty, operand, 0, ""); |
| 6356 | } | 6356 | } |
| 6357 | | 6357 | |
| 6358 | fn airOptionalPayload(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 6358 | fn airOptionalPayload(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 6359 | if (self.liveness.isUnused(inst)) return null; | 6359 | if (self.liveness.isUnused(inst)) return null; |
| 6360 | | 6360 | |
| 6361 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 6361 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| ... | @@ -6377,7 +6377,7 @@ pub const FuncGen = struct { | ... | @@ -6377,7 +6377,7 @@ pub const FuncGen = struct { |
| 6377 | self: *FuncGen, | 6377 | self: *FuncGen, |
| 6378 | inst: Air.Inst.Index, | 6378 | inst: Air.Inst.Index, |
| 6379 | operand_is_ptr: bool, | 6379 | operand_is_ptr: bool, |
| 6380 | ) !?*const llvm.Value { | 6380 | ) !?*llvm.Value { |
| 6381 | if (self.liveness.isUnused(inst)) return null; | 6381 | if (self.liveness.isUnused(inst)) return null; |
| 6382 | | 6382 | |
| 6383 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 6383 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| ... | @@ -6415,7 +6415,7 @@ pub const FuncGen = struct { | ... | @@ -6415,7 +6415,7 @@ pub const FuncGen = struct { |
| 6415 | self: *FuncGen, | 6415 | self: *FuncGen, |
| 6416 | inst: Air.Inst.Index, | 6416 | inst: Air.Inst.Index, |
| 6417 | operand_is_ptr: bool, | 6417 | operand_is_ptr: bool, |
| 6418 | ) !?*const llvm.Value { | 6418 | ) !?*llvm.Value { |
| 6419 | if (self.liveness.isUnused(inst)) | 6419 | if (self.liveness.isUnused(inst)) |
| 6420 | return null; | 6420 | return null; |
| 6421 | | 6421 | |
| ... | @@ -6452,7 +6452,7 @@ pub const FuncGen = struct { | ... | @@ -6452,7 +6452,7 @@ pub const FuncGen = struct { |
| 6452 | return self.builder.buildExtractValue(operand, offset, ""); | 6452 | return self.builder.buildExtractValue(operand, offset, ""); |
| 6453 | } | 6453 | } |
| 6454 | | 6454 | |
| 6455 | fn airErrUnionPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 6455 | fn airErrUnionPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 6456 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 6456 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 6457 | const operand = try self.resolveInst(ty_op.operand); | 6457 | const operand = try self.resolveInst(ty_op.operand); |
| 6458 | const err_union_ty = self.air.typeOf(ty_op.operand).childType(); | 6458 | const err_union_ty = self.air.typeOf(ty_op.operand).childType(); |
| ... | @@ -6480,18 +6480,18 @@ pub const FuncGen = struct { | ... | @@ -6480,18 +6480,18 @@ pub const FuncGen = struct { |
| 6480 | return self.builder.buildStructGEP(err_union_llvm_ty, operand, payload_offset, ""); | 6480 | return self.builder.buildStructGEP(err_union_llvm_ty, operand, payload_offset, ""); |
| 6481 | } | 6481 | } |
| 6482 | | 6482 | |
| 6483 | fn airErrReturnTrace(self: *FuncGen, _: Air.Inst.Index) !?*const llvm.Value { | 6483 | fn airErrReturnTrace(self: *FuncGen, _: Air.Inst.Index) !?*llvm.Value { |
| 6484 | return self.err_ret_trace.?; | 6484 | return self.err_ret_trace.?; |
| 6485 | } | 6485 | } |
| 6486 | | 6486 | |
| 6487 | fn airSetErrReturnTrace(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 6487 | fn airSetErrReturnTrace(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 6488 | const un_op = self.air.instructions.items(.data)[inst].un_op; | 6488 | const un_op = self.air.instructions.items(.data)[inst].un_op; |
| 6489 | const operand = try self.resolveInst(un_op); | 6489 | const operand = try self.resolveInst(un_op); |
| 6490 | self.err_ret_trace = operand; | 6490 | self.err_ret_trace = operand; |
| 6491 | return null; | 6491 | return null; |
| 6492 | } | 6492 | } |
| 6493 | | 6493 | |
| 6494 | fn airWrapOptional(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 6494 | fn airWrapOptional(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 6495 | if (self.liveness.isUnused(inst)) return null; | 6495 | if (self.liveness.isUnused(inst)) return null; |
| 6496 | | 6496 | |
| 6497 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 6497 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| ... | @@ -6524,7 +6524,7 @@ pub const FuncGen = struct { | ... | @@ -6524,7 +6524,7 @@ pub const FuncGen = struct { |
| 6524 | return self.builder.buildInsertValue(partial, non_null_bit, 1, ""); | 6524 | return self.builder.buildInsertValue(partial, non_null_bit, 1, ""); |
| 6525 | } | 6525 | } |
| 6526 | | 6526 | |
| 6527 | fn airWrapErrUnionPayload(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 6527 | fn airWrapErrUnionPayload(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 6528 | if (self.liveness.isUnused(inst)) return null; | 6528 | if (self.liveness.isUnused(inst)) return null; |
| 6529 | | 6529 | |
| 6530 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 6530 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| ... | @@ -6560,7 +6560,7 @@ pub const FuncGen = struct { | ... | @@ -6560,7 +6560,7 @@ pub const FuncGen = struct { |
| 6560 | return self.builder.buildInsertValue(partial, operand, payload_offset, ""); | 6560 | return self.builder.buildInsertValue(partial, operand, payload_offset, ""); |
| 6561 | } | 6561 | } |
| 6562 | | 6562 | |
| 6563 | fn airWrapErrUnionErr(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 6563 | fn airWrapErrUnionErr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 6564 | if (self.liveness.isUnused(inst)) return null; | 6564 | if (self.liveness.isUnused(inst)) return null; |
| 6565 | | 6565 | |
| 6566 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 6566 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| ... | @@ -6598,31 +6598,31 @@ pub const FuncGen = struct { | ... | @@ -6598,31 +6598,31 @@ pub const FuncGen = struct { |
| 6598 | return partial; | 6598 | return partial; |
| 6599 | } | 6599 | } |
| 6600 | | 6600 | |
| 6601 | fn airWasmMemorySize(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 6601 | fn airWasmMemorySize(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 6602 | if (self.liveness.isUnused(inst)) return null; | 6602 | if (self.liveness.isUnused(inst)) return null; |
| 6603 | | 6603 | |
| 6604 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; | 6604 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; |
| 6605 | const index = pl_op.payload; | 6605 | const index = pl_op.payload; |
| 6606 | const llvm_u32 = self.context.intType(32); | 6606 | const llvm_u32 = self.context.intType(32); |
| 6607 | const llvm_fn = self.getIntrinsic("llvm.wasm.memory.size", &.{llvm_u32}); | 6607 | const llvm_fn = self.getIntrinsic("llvm.wasm.memory.size", &.{llvm_u32}); |
| 6608 | const args: [1]*const llvm.Value = .{llvm_u32.constInt(index, .False)}; | 6608 | const args: [1]*llvm.Value = .{llvm_u32.constInt(index, .False)}; |
| 6609 | return self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &args, args.len, .Fast, .Auto, ""); | 6609 | return self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &args, args.len, .Fast, .Auto, ""); |
| 6610 | } | 6610 | } |
| 6611 | | 6611 | |
| 6612 | fn airWasmMemoryGrow(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 6612 | fn airWasmMemoryGrow(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 6613 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; | 6613 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; |
| 6614 | const index = pl_op.payload; | 6614 | const index = pl_op.payload; |
| 6615 | const operand = try self.resolveInst(pl_op.operand); | 6615 | const operand = try self.resolveInst(pl_op.operand); |
| 6616 | const llvm_u32 = self.context.intType(32); | 6616 | const llvm_u32 = self.context.intType(32); |
| 6617 | const llvm_fn = self.getIntrinsic("llvm.wasm.memory.grow", &.{llvm_u32}); | 6617 | const llvm_fn = self.getIntrinsic("llvm.wasm.memory.grow", &.{llvm_u32}); |
| 6618 | const args: [2]*const llvm.Value = .{ | 6618 | const args: [2]*llvm.Value = .{ |
| 6619 | llvm_u32.constInt(index, .False), | 6619 | llvm_u32.constInt(index, .False), |
| 6620 | operand, | 6620 | operand, |
| 6621 | }; | 6621 | }; |
| 6622 | return self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &args, args.len, .Fast, .Auto, ""); | 6622 | return self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &args, args.len, .Fast, .Auto, ""); |
| 6623 | } | 6623 | } |
| 6624 | | 6624 | |
| 6625 | fn airMin(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 6625 | fn airMin(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 6626 | if (self.liveness.isUnused(inst)) return null; | 6626 | if (self.liveness.isUnused(inst)) return null; |
| 6627 | | 6627 | |
| 6628 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; | 6628 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| ... | @@ -6635,7 +6635,7 @@ pub const FuncGen = struct { | ... | @@ -6635,7 +6635,7 @@ pub const FuncGen = struct { |
| 6635 | return self.builder.buildUMin(lhs, rhs, ""); | 6635 | return self.builder.buildUMin(lhs, rhs, ""); |
| 6636 | } | 6636 | } |
| 6637 | | 6637 | |
| 6638 | fn airMax(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 6638 | fn airMax(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 6639 | if (self.liveness.isUnused(inst)) return null; | 6639 | if (self.liveness.isUnused(inst)) return null; |
| 6640 | | 6640 | |
| 6641 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; | 6641 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| ... | @@ -6648,7 +6648,7 @@ pub const FuncGen = struct { | ... | @@ -6648,7 +6648,7 @@ pub const FuncGen = struct { |
| 6648 | return self.builder.buildUMax(lhs, rhs, ""); | 6648 | return self.builder.buildUMax(lhs, rhs, ""); |
| 6649 | } | 6649 | } |
| 6650 | | 6650 | |
| 6651 | fn airSlice(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 6651 | fn airSlice(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 6652 | if (self.liveness.isUnused(inst)) return null; | 6652 | if (self.liveness.isUnused(inst)) return null; |
| 6653 | | 6653 | |
| 6654 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; | 6654 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| ... | @@ -6670,7 +6670,7 @@ pub const FuncGen = struct { | ... | @@ -6670,7 +6670,7 @@ pub const FuncGen = struct { |
| 6670 | return self.builder.buildInsertValue(partial, len, 1, ""); | 6670 | return self.builder.buildInsertValue(partial, len, 1, ""); |
| 6671 | } | 6671 | } |
| 6672 | | 6672 | |
| 6673 | fn airAdd(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value { | 6673 | fn airAdd(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value { |
| 6674 | if (self.liveness.isUnused(inst)) return null; | 6674 | if (self.liveness.isUnused(inst)) return null; |
| 6675 | self.builder.setFastMath(want_fast_math); | 6675 | self.builder.setFastMath(want_fast_math); |
| 6676 | | 6676 | |
| ... | @@ -6685,7 +6685,7 @@ pub const FuncGen = struct { | ... | @@ -6685,7 +6685,7 @@ pub const FuncGen = struct { |
| 6685 | return self.builder.buildNUWAdd(lhs, rhs, ""); | 6685 | return self.builder.buildNUWAdd(lhs, rhs, ""); |
| 6686 | } | 6686 | } |
| 6687 | | 6687 | |
| 6688 | fn airAddWrap(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value { | 6688 | fn airAddWrap(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value { |
| 6689 | if (self.liveness.isUnused(inst)) return null; | 6689 | if (self.liveness.isUnused(inst)) return null; |
| 6690 | self.builder.setFastMath(want_fast_math); | 6690 | self.builder.setFastMath(want_fast_math); |
| 6691 | | 6691 | |
| ... | @@ -6696,7 +6696,7 @@ pub const FuncGen = struct { | ... | @@ -6696,7 +6696,7 @@ pub const FuncGen = struct { |
| 6696 | return self.builder.buildAdd(lhs, rhs, ""); | 6696 | return self.builder.buildAdd(lhs, rhs, ""); |
| 6697 | } | 6697 | } |
| 6698 | | 6698 | |
| 6699 | fn airAddSat(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 6699 | fn airAddSat(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 6700 | if (self.liveness.isUnused(inst)) return null; | 6700 | if (self.liveness.isUnused(inst)) return null; |
| 6701 | | 6701 | |
| 6702 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; | 6702 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| ... | @@ -6711,7 +6711,7 @@ pub const FuncGen = struct { | ... | @@ -6711,7 +6711,7 @@ pub const FuncGen = struct { |
| 6711 | return self.builder.buildUAddSat(lhs, rhs, ""); | 6711 | return self.builder.buildUAddSat(lhs, rhs, ""); |
| 6712 | } | 6712 | } |
| 6713 | | 6713 | |
| 6714 | fn airSub(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value { | 6714 | fn airSub(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value { |
| 6715 | if (self.liveness.isUnused(inst)) return null; | 6715 | if (self.liveness.isUnused(inst)) return null; |
| 6716 | self.builder.setFastMath(want_fast_math); | 6716 | self.builder.setFastMath(want_fast_math); |
| 6717 | | 6717 | |
| ... | @@ -6726,7 +6726,7 @@ pub const FuncGen = struct { | ... | @@ -6726,7 +6726,7 @@ pub const FuncGen = struct { |
| 6726 | return self.builder.buildNUWSub(lhs, rhs, ""); | 6726 | return self.builder.buildNUWSub(lhs, rhs, ""); |
| 6727 | } | 6727 | } |
| 6728 | | 6728 | |
| 6729 | fn airSubWrap(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value { | 6729 | fn airSubWrap(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value { |
| 6730 | if (self.liveness.isUnused(inst)) return null; | 6730 | if (self.liveness.isUnused(inst)) return null; |
| 6731 | self.builder.setFastMath(want_fast_math); | 6731 | self.builder.setFastMath(want_fast_math); |
| 6732 | | 6732 | |
| ... | @@ -6737,7 +6737,7 @@ pub const FuncGen = struct { | ... | @@ -6737,7 +6737,7 @@ pub const FuncGen = struct { |
| 6737 | return self.builder.buildSub(lhs, rhs, ""); | 6737 | return self.builder.buildSub(lhs, rhs, ""); |
| 6738 | } | 6738 | } |
| 6739 | | 6739 | |
| 6740 | fn airSubSat(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 6740 | fn airSubSat(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 6741 | if (self.liveness.isUnused(inst)) return null; | 6741 | if (self.liveness.isUnused(inst)) return null; |
| 6742 | | 6742 | |
| 6743 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; | 6743 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| ... | @@ -6751,7 +6751,7 @@ pub const FuncGen = struct { | ... | @@ -6751,7 +6751,7 @@ pub const FuncGen = struct { |
| 6751 | return self.builder.buildUSubSat(lhs, rhs, ""); | 6751 | return self.builder.buildUSubSat(lhs, rhs, ""); |
| 6752 | } | 6752 | } |
| 6753 | | 6753 | |
| 6754 | fn airMul(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value { | 6754 | fn airMul(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value { |
| 6755 | if (self.liveness.isUnused(inst)) return null; | 6755 | if (self.liveness.isUnused(inst)) return null; |
| 6756 | self.builder.setFastMath(want_fast_math); | 6756 | self.builder.setFastMath(want_fast_math); |
| 6757 | | 6757 | |
| ... | @@ -6766,7 +6766,7 @@ pub const FuncGen = struct { | ... | @@ -6766,7 +6766,7 @@ pub const FuncGen = struct { |
| 6766 | return self.builder.buildNUWMul(lhs, rhs, ""); | 6766 | return self.builder.buildNUWMul(lhs, rhs, ""); |
| 6767 | } | 6767 | } |
| 6768 | | 6768 | |
| 6769 | fn airMulWrap(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value { | 6769 | fn airMulWrap(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value { |
| 6770 | if (self.liveness.isUnused(inst)) return null; | 6770 | if (self.liveness.isUnused(inst)) return null; |
| 6771 | self.builder.setFastMath(want_fast_math); | 6771 | self.builder.setFastMath(want_fast_math); |
| 6772 | | 6772 | |
| ... | @@ -6777,7 +6777,7 @@ pub const FuncGen = struct { | ... | @@ -6777,7 +6777,7 @@ pub const FuncGen = struct { |
| 6777 | return self.builder.buildMul(lhs, rhs, ""); | 6777 | return self.builder.buildMul(lhs, rhs, ""); |
| 6778 | } | 6778 | } |
| 6779 | | 6779 | |
| 6780 | fn airMulSat(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 6780 | fn airMulSat(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 6781 | if (self.liveness.isUnused(inst)) return null; | 6781 | if (self.liveness.isUnused(inst)) return null; |
| 6782 | | 6782 | |
| 6783 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; | 6783 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| ... | @@ -6791,7 +6791,7 @@ pub const FuncGen = struct { | ... | @@ -6791,7 +6791,7 @@ pub const FuncGen = struct { |
| 6791 | return self.builder.buildUMulFixSat(lhs, rhs, ""); | 6791 | return self.builder.buildUMulFixSat(lhs, rhs, ""); |
| 6792 | } | 6792 | } |
| 6793 | | 6793 | |
| 6794 | fn airDivFloat(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value { | 6794 | fn airDivFloat(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value { |
| 6795 | if (self.liveness.isUnused(inst)) return null; | 6795 | if (self.liveness.isUnused(inst)) return null; |
| 6796 | self.builder.setFastMath(want_fast_math); | 6796 | self.builder.setFastMath(want_fast_math); |
| 6797 | | 6797 | |
| ... | @@ -6803,7 +6803,7 @@ pub const FuncGen = struct { | ... | @@ -6803,7 +6803,7 @@ pub const FuncGen = struct { |
| 6803 | return self.buildFloatOp(.div, inst_ty, 2, .{ lhs, rhs }); | 6803 | return self.buildFloatOp(.div, inst_ty, 2, .{ lhs, rhs }); |
| 6804 | } | 6804 | } |
| 6805 | | 6805 | |
| 6806 | fn airDivTrunc(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value { | 6806 | fn airDivTrunc(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value { |
| 6807 | if (self.liveness.isUnused(inst)) return null; | 6807 | if (self.liveness.isUnused(inst)) return null; |
| 6808 | self.builder.setFastMath(want_fast_math); | 6808 | self.builder.setFastMath(want_fast_math); |
| 6809 | | 6809 | |
| ... | @@ -6821,7 +6821,7 @@ pub const FuncGen = struct { | ... | @@ -6821,7 +6821,7 @@ pub const FuncGen = struct { |
| 6821 | return self.builder.buildUDiv(lhs, rhs, ""); | 6821 | return self.builder.buildUDiv(lhs, rhs, ""); |
| 6822 | } | 6822 | } |
| 6823 | | 6823 | |
| 6824 | fn airDivFloor(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value { | 6824 | fn airDivFloor(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value { |
| 6825 | if (self.liveness.isUnused(inst)) return null; | 6825 | if (self.liveness.isUnused(inst)) return null; |
| 6826 | self.builder.setFastMath(want_fast_math); | 6826 | self.builder.setFastMath(want_fast_math); |
| 6827 | | 6827 | |
| ... | @@ -6854,7 +6854,7 @@ pub const FuncGen = struct { | ... | @@ -6854,7 +6854,7 @@ pub const FuncGen = struct { |
| 6854 | return self.builder.buildUDiv(lhs, rhs, ""); | 6854 | return self.builder.buildUDiv(lhs, rhs, ""); |
| 6855 | } | 6855 | } |
| 6856 | | 6856 | |
| 6857 | fn airDivExact(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value { | 6857 | fn airDivExact(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value { |
| 6858 | if (self.liveness.isUnused(inst)) return null; | 6858 | if (self.liveness.isUnused(inst)) return null; |
| 6859 | self.builder.setFastMath(want_fast_math); | 6859 | self.builder.setFastMath(want_fast_math); |
| 6860 | | 6860 | |
| ... | @@ -6869,7 +6869,7 @@ pub const FuncGen = struct { | ... | @@ -6869,7 +6869,7 @@ pub const FuncGen = struct { |
| 6869 | return self.builder.buildExactUDiv(lhs, rhs, ""); | 6869 | return self.builder.buildExactUDiv(lhs, rhs, ""); |
| 6870 | } | 6870 | } |
| 6871 | | 6871 | |
| 6872 | fn airRem(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value { | 6872 | fn airRem(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value { |
| 6873 | if (self.liveness.isUnused(inst)) return null; | 6873 | if (self.liveness.isUnused(inst)) return null; |
| 6874 | self.builder.setFastMath(want_fast_math); | 6874 | self.builder.setFastMath(want_fast_math); |
| 6875 | | 6875 | |
| ... | @@ -6884,7 +6884,7 @@ pub const FuncGen = struct { | ... | @@ -6884,7 +6884,7 @@ pub const FuncGen = struct { |
| 6884 | return self.builder.buildURem(lhs, rhs, ""); | 6884 | return self.builder.buildURem(lhs, rhs, ""); |
| 6885 | } | 6885 | } |
| 6886 | | 6886 | |
| 6887 | fn airMod(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value { | 6887 | fn airMod(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value { |
| 6888 | if (self.liveness.isUnused(inst)) return null; | 6888 | if (self.liveness.isUnused(inst)) return null; |
| 6889 | self.builder.setFastMath(want_fast_math); | 6889 | self.builder.setFastMath(want_fast_math); |
| 6890 | | 6890 | |
| ... | @@ -6914,7 +6914,7 @@ pub const FuncGen = struct { | ... | @@ -6914,7 +6914,7 @@ pub const FuncGen = struct { |
| 6914 | return self.builder.buildURem(lhs, rhs, ""); | 6914 | return self.builder.buildURem(lhs, rhs, ""); |
| 6915 | } | 6915 | } |
| 6916 | | 6916 | |
| 6917 | fn airPtrAdd(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 6917 | fn airPtrAdd(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 6918 | if (self.liveness.isUnused(inst)) return null; | 6918 | if (self.liveness.isUnused(inst)) return null; |
| 6919 | | 6919 | |
| 6920 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; | 6920 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| ... | @@ -6925,17 +6925,17 @@ pub const FuncGen = struct { | ... | @@ -6925,17 +6925,17 @@ pub const FuncGen = struct { |
| 6925 | const llvm_elem_ty = try self.dg.lowerPtrElemTy(ptr_ty.childType()); | 6925 | const llvm_elem_ty = try self.dg.lowerPtrElemTy(ptr_ty.childType()); |
| 6926 | if (ptr_ty.ptrSize() == .One) { | 6926 | if (ptr_ty.ptrSize() == .One) { |
| 6927 | // It's a pointer to an array, so according to LLVM we need an extra GEP index. | 6927 | // It's a pointer to an array, so according to LLVM we need an extra GEP index. |
| 6928 | const indices: [2]*const llvm.Value = .{ | 6928 | const indices: [2]*llvm.Value = .{ |
| 6929 | self.context.intType(32).constNull(), offset, | 6929 | self.context.intType(32).constNull(), offset, |
| 6930 | }; | 6930 | }; |
| 6931 | return self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, ""); | 6931 | return self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, ""); |
| 6932 | } else { | 6932 | } else { |
| 6933 | const indices: [1]*const llvm.Value = .{offset}; | 6933 | const indices: [1]*llvm.Value = .{offset}; |
| 6934 | return self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, ""); | 6934 | return self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, ""); |
| 6935 | } | 6935 | } |
| 6936 | } | 6936 | } |
| 6937 | | 6937 | |
| 6938 | fn airPtrSub(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 6938 | fn airPtrSub(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 6939 | if (self.liveness.isUnused(inst)) return null; | 6939 | if (self.liveness.isUnused(inst)) return null; |
| 6940 | | 6940 | |
| 6941 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; | 6941 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| ... | @@ -6947,12 +6947,12 @@ pub const FuncGen = struct { | ... | @@ -6947,12 +6947,12 @@ pub const FuncGen = struct { |
| 6947 | const llvm_elem_ty = try self.dg.lowerPtrElemTy(ptr_ty.childType()); | 6947 | const llvm_elem_ty = try self.dg.lowerPtrElemTy(ptr_ty.childType()); |
| 6948 | if (ptr_ty.ptrSize() == .One) { | 6948 | if (ptr_ty.ptrSize() == .One) { |
| 6949 | // It's a pointer to an array, so according to LLVM we need an extra GEP index. | 6949 | // It's a pointer to an array, so according to LLVM we need an extra GEP index. |
| 6950 | const indices: [2]*const llvm.Value = .{ | 6950 | const indices: [2]*llvm.Value = .{ |
| 6951 | self.context.intType(32).constNull(), negative_offset, | 6951 | self.context.intType(32).constNull(), negative_offset, |
| 6952 | }; | 6952 | }; |
| 6953 | return self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, ""); | 6953 | return self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, ""); |
| 6954 | } else { | 6954 | } else { |
| 6955 | const indices: [1]*const llvm.Value = .{negative_offset}; | 6955 | const indices: [1]*llvm.Value = .{negative_offset}; |
| 6956 | return self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, ""); | 6956 | return self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, ""); |
| 6957 | } | 6957 | } |
| 6958 | } | 6958 | } |
| ... | @@ -6962,7 +6962,7 @@ pub const FuncGen = struct { | ... | @@ -6962,7 +6962,7 @@ pub const FuncGen = struct { |
| 6962 | inst: Air.Inst.Index, | 6962 | inst: Air.Inst.Index, |
| 6963 | signed_intrinsic: []const u8, | 6963 | signed_intrinsic: []const u8, |
| 6964 | unsigned_intrinsic: []const u8, | 6964 | unsigned_intrinsic: []const u8, |
| 6965 | ) !?*const llvm.Value { | 6965 | ) !?*llvm.Value { |
| 6966 | if (self.liveness.isUnused(inst)) | 6966 | if (self.liveness.isUnused(inst)) |
| 6967 | return null; | 6967 | return null; |
| 6968 | | 6968 | |
| ... | @@ -6984,7 +6984,7 @@ pub const FuncGen = struct { | ... | @@ -6984,7 +6984,7 @@ pub const FuncGen = struct { |
| 6984 | const tg = self.dg.module.getTarget(); | 6984 | const tg = self.dg.module.getTarget(); |
| 6985 | | 6985 | |
| 6986 | const llvm_fn = self.getIntrinsic(intrinsic_name, &.{llvm_lhs_ty}); | 6986 | const llvm_fn = self.getIntrinsic(intrinsic_name, &.{llvm_lhs_ty}); |
| 6987 | const result_struct = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &[_]*const llvm.Value{ lhs, rhs }, 2, .Fast, .Auto, ""); | 6987 | const result_struct = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &[_]*llvm.Value{ lhs, rhs }, 2, .Fast, .Auto, ""); |
| 6988 | | 6988 | |
| 6989 | const result = self.builder.buildExtractValue(result_struct, 0, ""); | 6989 | const result = self.builder.buildExtractValue(result_struct, 0, ""); |
| 6990 | const overflow_bit = self.builder.buildExtractValue(result_struct, 1, ""); | 6990 | const overflow_bit = self.builder.buildExtractValue(result_struct, 1, ""); |
| ... | @@ -7018,11 +7018,11 @@ pub const FuncGen = struct { | ... | @@ -7018,11 +7018,11 @@ pub const FuncGen = struct { |
| 7018 | | 7018 | |
| 7019 | fn buildElementwiseCall( | 7019 | fn buildElementwiseCall( |
| 7020 | self: *FuncGen, | 7020 | self: *FuncGen, |
| 7021 | llvm_fn: *const llvm.Value, | 7021 | llvm_fn: *llvm.Value, |
| 7022 | args_vectors: []const *const llvm.Value, | 7022 | args_vectors: []const *llvm.Value, |
| 7023 | result_vector: *const llvm.Value, | 7023 | result_vector: *llvm.Value, |
| 7024 | vector_len: usize, | 7024 | vector_len: usize, |
| 7025 | ) !*const llvm.Value { | 7025 | ) !*llvm.Value { |
| 7026 | const args_len = @intCast(c_uint, args_vectors.len); | 7026 | const args_len = @intCast(c_uint, args_vectors.len); |
| 7027 | const llvm_i32 = self.context.intType(32); | 7027 | const llvm_i32 = self.context.intType(32); |
| 7028 | assert(args_len <= 3); | 7028 | assert(args_len <= 3); |
| ... | @@ -7032,7 +7032,7 @@ pub const FuncGen = struct { | ... | @@ -7032,7 +7032,7 @@ pub const FuncGen = struct { |
| 7032 | while (i < vector_len) : (i += 1) { | 7032 | while (i < vector_len) : (i += 1) { |
| 7033 | const index_i32 = llvm_i32.constInt(i, .False); | 7033 | const index_i32 = llvm_i32.constInt(i, .False); |
| 7034 | | 7034 | |
| 7035 | var args: [3]*const llvm.Value = undefined; | 7035 | var args: [3]*llvm.Value = undefined; |
| 7036 | for (args_vectors) |arg_vector, k| { | 7036 | for (args_vectors) |arg_vector, k| { |
| 7037 | args[k] = self.builder.buildExtractElement(arg_vector, index_i32, ""); | 7037 | args[k] = self.builder.buildExtractElement(arg_vector, index_i32, ""); |
| 7038 | } | 7038 | } |
| ... | @@ -7045,9 +7045,9 @@ pub const FuncGen = struct { | ... | @@ -7045,9 +7045,9 @@ pub const FuncGen = struct { |
| 7045 | fn getLibcFunction( | 7045 | fn getLibcFunction( |
| 7046 | self: *FuncGen, | 7046 | self: *FuncGen, |
| 7047 | fn_name: [:0]const u8, | 7047 | fn_name: [:0]const u8, |
| 7048 | param_types: []const *const llvm.Type, | 7048 | param_types: []const *llvm.Type, |
| 7049 | return_type: *const llvm.Type, | 7049 | return_type: *llvm.Type, |
| 7050 | ) *const llvm.Value { | 7050 | ) *llvm.Value { |
| 7051 | return self.dg.object.llvm_module.getNamedFunction(fn_name.ptr) orelse b: { | 7051 | return self.dg.object.llvm_module.getNamedFunction(fn_name.ptr) orelse b: { |
| 7052 | const alias = self.dg.object.llvm_module.getNamedGlobalAlias(fn_name.ptr, fn_name.len); | 7052 | const alias = self.dg.object.llvm_module.getNamedGlobalAlias(fn_name.ptr, fn_name.len); |
| 7053 | break :b if (alias) |a| a.getAliasee() else null; | 7053 | break :b if (alias) |a| a.getAliasee() else null; |
| ... | @@ -7105,8 +7105,8 @@ pub const FuncGen = struct { | ... | @@ -7105,8 +7105,8 @@ pub const FuncGen = struct { |
| 7105 | self: *FuncGen, | 7105 | self: *FuncGen, |
| 7106 | pred: math.CompareOperator, | 7106 | pred: math.CompareOperator, |
| 7107 | ty: Type, | 7107 | ty: Type, |
| 7108 | params: [2]*const llvm.Value, | 7108 | params: [2]*llvm.Value, |
| 7109 | ) !*const llvm.Value { | 7109 | ) !*llvm.Value { |
| 7110 | const target = self.dg.module.getTarget(); | 7110 | const target = self.dg.module.getTarget(); |
| 7111 | const scalar_ty = ty.scalarType(); | 7111 | const scalar_ty = ty.scalarType(); |
| 7112 | const scalar_llvm_ty = try self.dg.lowerType(scalar_ty); | 7112 | const scalar_llvm_ty = try self.dg.lowerType(scalar_ty); |
| ... | @@ -7138,7 +7138,7 @@ pub const FuncGen = struct { | ... | @@ -7138,7 +7138,7 @@ pub const FuncGen = struct { |
| 7138 | fn_base_name, compiler_rt_float_abbrev, | 7138 | fn_base_name, compiler_rt_float_abbrev, |
| 7139 | }) catch unreachable; | 7139 | }) catch unreachable; |
| 7140 | | 7140 | |
| 7141 | const param_types = [2]*const llvm.Type{ scalar_llvm_ty, scalar_llvm_ty }; | 7141 | const param_types = [2]*llvm.Type{ scalar_llvm_ty, scalar_llvm_ty }; |
| 7142 | const llvm_i32 = self.context.intType(32); | 7142 | const llvm_i32 = self.context.intType(32); |
| 7143 | const libc_fn = self.getLibcFunction(fn_name, param_types[0..], llvm_i32); | 7143 | const libc_fn = self.getLibcFunction(fn_name, param_types[0..], llvm_i32); |
| 7144 | | 7144 | |
| ... | @@ -7206,8 +7206,8 @@ pub const FuncGen = struct { | ... | @@ -7206,8 +7206,8 @@ pub const FuncGen = struct { |
| 7206 | comptime op: FloatOp, | 7206 | comptime op: FloatOp, |
| 7207 | ty: Type, | 7207 | ty: Type, |
| 7208 | comptime params_len: usize, | 7208 | comptime params_len: usize, |
| 7209 | params: [params_len]*const llvm.Value, | 7209 | params: [params_len]*llvm.Value, |
| 7210 | ) !*const llvm.Value { | 7210 | ) !*llvm.Value { |
| 7211 | const target = self.dg.module.getTarget(); | 7211 | const target = self.dg.module.getTarget(); |
| 7212 | const scalar_ty = ty.scalarType(); | 7212 | const scalar_ty = ty.scalarType(); |
| 7213 | const llvm_ty = try self.dg.lowerType(ty); | 7213 | const llvm_ty = try self.dg.lowerType(ty); |
| ... | @@ -7278,10 +7278,10 @@ pub const FuncGen = struct { | ... | @@ -7278,10 +7278,10 @@ pub const FuncGen = struct { |
| 7278 | }; | 7278 | }; |
| 7279 | }; | 7279 | }; |
| 7280 | | 7280 | |
| 7281 | const llvm_fn: *const llvm.Value = switch (strat) { | 7281 | const llvm_fn: *llvm.Value = switch (strat) { |
| 7282 | .intrinsic => |fn_name| self.getIntrinsic(fn_name, &.{llvm_ty}), | 7282 | .intrinsic => |fn_name| self.getIntrinsic(fn_name, &.{llvm_ty}), |
| 7283 | .libc => |fn_name| b: { | 7283 | .libc => |fn_name| b: { |
| 7284 | const param_types = [3]*const llvm.Type{ scalar_llvm_ty, scalar_llvm_ty, scalar_llvm_ty }; | 7284 | const param_types = [3]*llvm.Type{ scalar_llvm_ty, scalar_llvm_ty, scalar_llvm_ty }; |
| 7285 | const libc_fn = self.getLibcFunction(fn_name, param_types[0..params.len], scalar_llvm_ty); | 7285 | const libc_fn = self.getLibcFunction(fn_name, param_types[0..params.len], scalar_llvm_ty); |
| 7286 | if (ty.zigTypeTag() == .Vector) { | 7286 | if (ty.zigTypeTag() == .Vector) { |
| 7287 | const result = llvm_ty.getUndef(); | 7287 | const result = llvm_ty.getUndef(); |
| ... | @@ -7294,7 +7294,7 @@ pub const FuncGen = struct { | ... | @@ -7294,7 +7294,7 @@ pub const FuncGen = struct { |
| 7294 | return self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &params, params_len, .C, .Auto, ""); | 7294 | return self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &params, params_len, .C, .Auto, ""); |
| 7295 | } | 7295 | } |
| 7296 | | 7296 | |
| 7297 | fn airMulAdd(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 7297 | fn airMulAdd(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 7298 | if (self.liveness.isUnused(inst)) return null; | 7298 | if (self.liveness.isUnused(inst)) return null; |
| 7299 | | 7299 | |
| 7300 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; | 7300 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; |
| ... | @@ -7308,7 +7308,7 @@ pub const FuncGen = struct { | ... | @@ -7308,7 +7308,7 @@ pub const FuncGen = struct { |
| 7308 | return self.buildFloatOp(.fma, ty, 3, .{ mulend1, mulend2, addend }); | 7308 | return self.buildFloatOp(.fma, ty, 3, .{ mulend1, mulend2, addend }); |
| 7309 | } | 7309 | } |
| 7310 | | 7310 | |
| 7311 | fn airShlWithOverflow(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 7311 | fn airShlWithOverflow(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 7312 | if (self.liveness.isUnused(inst)) | 7312 | if (self.liveness.isUnused(inst)) |
| 7313 | return null; | 7313 | return null; |
| 7314 | | 7314 | |
| ... | @@ -7368,7 +7368,7 @@ pub const FuncGen = struct { | ... | @@ -7368,7 +7368,7 @@ pub const FuncGen = struct { |
| 7368 | return self.builder.buildInsertValue(partial, overflow_bit, overflow_index, ""); | 7368 | return self.builder.buildInsertValue(partial, overflow_bit, overflow_index, ""); |
| 7369 | } | 7369 | } |
| 7370 | | 7370 | |
| 7371 | fn airAnd(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 7371 | fn airAnd(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 7372 | if (self.liveness.isUnused(inst)) | 7372 | if (self.liveness.isUnused(inst)) |
| 7373 | return null; | 7373 | return null; |
| 7374 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; | 7374 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| ... | @@ -7377,7 +7377,7 @@ pub const FuncGen = struct { | ... | @@ -7377,7 +7377,7 @@ pub const FuncGen = struct { |
| 7377 | return self.builder.buildAnd(lhs, rhs, ""); | 7377 | return self.builder.buildAnd(lhs, rhs, ""); |
| 7378 | } | 7378 | } |
| 7379 | | 7379 | |
| 7380 | fn airOr(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 7380 | fn airOr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 7381 | if (self.liveness.isUnused(inst)) | 7381 | if (self.liveness.isUnused(inst)) |
| 7382 | return null; | 7382 | return null; |
| 7383 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; | 7383 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| ... | @@ -7386,7 +7386,7 @@ pub const FuncGen = struct { | ... | @@ -7386,7 +7386,7 @@ pub const FuncGen = struct { |
| 7386 | return self.builder.buildOr(lhs, rhs, ""); | 7386 | return self.builder.buildOr(lhs, rhs, ""); |
| 7387 | } | 7387 | } |
| 7388 | | 7388 | |
| 7389 | fn airXor(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 7389 | fn airXor(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 7390 | if (self.liveness.isUnused(inst)) | 7390 | if (self.liveness.isUnused(inst)) |
| 7391 | return null; | 7391 | return null; |
| 7392 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; | 7392 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| ... | @@ -7395,7 +7395,7 @@ pub const FuncGen = struct { | ... | @@ -7395,7 +7395,7 @@ pub const FuncGen = struct { |
| 7395 | return self.builder.buildXor(lhs, rhs, ""); | 7395 | return self.builder.buildXor(lhs, rhs, ""); |
| 7396 | } | 7396 | } |
| 7397 | | 7397 | |
| 7398 | fn airShlExact(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 7398 | fn airShlExact(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 7399 | if (self.liveness.isUnused(inst)) return null; | 7399 | if (self.liveness.isUnused(inst)) return null; |
| 7400 | | 7400 | |
| 7401 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; | 7401 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| ... | @@ -7418,7 +7418,7 @@ pub const FuncGen = struct { | ... | @@ -7418,7 +7418,7 @@ pub const FuncGen = struct { |
| 7418 | return self.builder.buildNUWShl(lhs, casted_rhs, ""); | 7418 | return self.builder.buildNUWShl(lhs, casted_rhs, ""); |
| 7419 | } | 7419 | } |
| 7420 | | 7420 | |
| 7421 | fn airShl(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 7421 | fn airShl(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 7422 | if (self.liveness.isUnused(inst)) return null; | 7422 | if (self.liveness.isUnused(inst)) return null; |
| 7423 | | 7423 | |
| 7424 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; | 7424 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| ... | @@ -7440,7 +7440,7 @@ pub const FuncGen = struct { | ... | @@ -7440,7 +7440,7 @@ pub const FuncGen = struct { |
| 7440 | return self.builder.buildShl(lhs, casted_rhs, ""); | 7440 | return self.builder.buildShl(lhs, casted_rhs, ""); |
| 7441 | } | 7441 | } |
| 7442 | | 7442 | |
| 7443 | fn airShlSat(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 7443 | fn airShlSat(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 7444 | if (self.liveness.isUnused(inst)) return null; | 7444 | if (self.liveness.isUnused(inst)) return null; |
| 7445 | | 7445 | |
| 7446 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; | 7446 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| ... | @@ -7485,7 +7485,7 @@ pub const FuncGen = struct { | ... | @@ -7485,7 +7485,7 @@ pub const FuncGen = struct { |
| 7485 | } | 7485 | } |
| 7486 | } | 7486 | } |
| 7487 | | 7487 | |
| 7488 | fn airShr(self: *FuncGen, inst: Air.Inst.Index, is_exact: bool) !?*const llvm.Value { | 7488 | fn airShr(self: *FuncGen, inst: Air.Inst.Index, is_exact: bool) !?*llvm.Value { |
| 7489 | if (self.liveness.isUnused(inst)) return null; | 7489 | if (self.liveness.isUnused(inst)) return null; |
| 7490 | | 7490 | |
| 7491 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; | 7491 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| ... | @@ -7521,7 +7521,7 @@ pub const FuncGen = struct { | ... | @@ -7521,7 +7521,7 @@ pub const FuncGen = struct { |
| 7521 | } | 7521 | } |
| 7522 | } | 7522 | } |
| 7523 | | 7523 | |
| 7524 | fn airIntCast(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 7524 | fn airIntCast(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 7525 | if (self.liveness.isUnused(inst)) | 7525 | if (self.liveness.isUnused(inst)) |
| 7526 | return null; | 7526 | return null; |
| 7527 | | 7527 | |
| ... | @@ -7546,7 +7546,7 @@ pub const FuncGen = struct { | ... | @@ -7546,7 +7546,7 @@ pub const FuncGen = struct { |
| 7546 | } | 7546 | } |
| 7547 | } | 7547 | } |
| 7548 | | 7548 | |
| 7549 | fn airTrunc(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 7549 | fn airTrunc(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 7550 | if (self.liveness.isUnused(inst)) return null; | 7550 | if (self.liveness.isUnused(inst)) return null; |
| 7551 | | 7551 | |
| 7552 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 7552 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| ... | @@ -7555,7 +7555,7 @@ pub const FuncGen = struct { | ... | @@ -7555,7 +7555,7 @@ pub const FuncGen = struct { |
| 7555 | return self.builder.buildTrunc(operand, dest_llvm_ty, ""); | 7555 | return self.builder.buildTrunc(operand, dest_llvm_ty, ""); |
| 7556 | } | 7556 | } |
| 7557 | | 7557 | |
| 7558 | fn airFptrunc(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 7558 | fn airFptrunc(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 7559 | if (self.liveness.isUnused(inst)) | 7559 | if (self.liveness.isUnused(inst)) |
| 7560 | return null; | 7560 | return null; |
| 7561 | | 7561 | |
| ... | @@ -7573,7 +7573,7 @@ pub const FuncGen = struct { | ... | @@ -7573,7 +7573,7 @@ pub const FuncGen = struct { |
| 7573 | return self.builder.buildFPTrunc(operand, dest_llvm_ty, ""); | 7573 | return self.builder.buildFPTrunc(operand, dest_llvm_ty, ""); |
| 7574 | } | 7574 | } |
| 7575 | | 7575 | |
| 7576 | fn airFpext(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 7576 | fn airFpext(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 7577 | if (self.liveness.isUnused(inst)) | 7577 | if (self.liveness.isUnused(inst)) |
| 7578 | return null; | 7578 | return null; |
| 7579 | | 7579 | |
| ... | @@ -7591,7 +7591,7 @@ pub const FuncGen = struct { | ... | @@ -7591,7 +7591,7 @@ pub const FuncGen = struct { |
| 7591 | return self.builder.buildFPExt(operand, dest_llvm_ty, ""); | 7591 | return self.builder.buildFPExt(operand, dest_llvm_ty, ""); |
| 7592 | } | 7592 | } |
| 7593 | | 7593 | |
| 7594 | fn airPtrToInt(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 7594 | fn airPtrToInt(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 7595 | if (self.liveness.isUnused(inst)) | 7595 | if (self.liveness.isUnused(inst)) |
| 7596 | return null; | 7596 | return null; |
| 7597 | | 7597 | |
| ... | @@ -7601,7 +7601,7 @@ pub const FuncGen = struct { | ... | @@ -7601,7 +7601,7 @@ pub const FuncGen = struct { |
| 7601 | return self.builder.buildPtrToInt(operand, dest_llvm_ty, ""); | 7601 | return self.builder.buildPtrToInt(operand, dest_llvm_ty, ""); |
| 7602 | } | 7602 | } |
| 7603 | | 7603 | |
| 7604 | fn airBitCast(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 7604 | fn airBitCast(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 7605 | if (self.liveness.isUnused(inst)) return null; | 7605 | if (self.liveness.isUnused(inst)) return null; |
| 7606 | | 7606 | |
| 7607 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 7607 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| ... | @@ -7645,7 +7645,7 @@ pub const FuncGen = struct { | ... | @@ -7645,7 +7645,7 @@ pub const FuncGen = struct { |
| 7645 | while (i < vector_len) : (i += 1) { | 7645 | while (i < vector_len) : (i += 1) { |
| 7646 | const index_usize = llvm_usize.constInt(i, .False); | 7646 | const index_usize = llvm_usize.constInt(i, .False); |
| 7647 | const index_u32 = llvm_u32.constInt(i, .False); | 7647 | const index_u32 = llvm_u32.constInt(i, .False); |
| 7648 | const indexes: [2]*const llvm.Value = .{ zero, index_usize }; | 7648 | const indexes: [2]*llvm.Value = .{ zero, index_usize }; |
| 7649 | const elem_ptr = self.builder.buildInBoundsGEP(llvm_dest_ty, array_ptr, &indexes, indexes.len, ""); | 7649 | const elem_ptr = self.builder.buildInBoundsGEP(llvm_dest_ty, array_ptr, &indexes, indexes.len, ""); |
| 7650 | const elem = self.builder.buildExtractElement(operand, index_u32, ""); | 7650 | const elem = self.builder.buildExtractElement(operand, index_u32, ""); |
| 7651 | _ = self.builder.buildStore(elem, elem_ptr); | 7651 | _ = self.builder.buildStore(elem, elem_ptr); |
| ... | @@ -7682,7 +7682,7 @@ pub const FuncGen = struct { | ... | @@ -7682,7 +7682,7 @@ pub const FuncGen = struct { |
| 7682 | while (i < vector_len) : (i += 1) { | 7682 | while (i < vector_len) : (i += 1) { |
| 7683 | const index_usize = llvm_usize.constInt(i, .False); | 7683 | const index_usize = llvm_usize.constInt(i, .False); |
| 7684 | const index_u32 = llvm_u32.constInt(i, .False); | 7684 | const index_u32 = llvm_u32.constInt(i, .False); |
| 7685 | const indexes: [2]*const llvm.Value = .{ zero, index_usize }; | 7685 | const indexes: [2]*llvm.Value = .{ zero, index_usize }; |
| 7686 | const elem_ptr = self.builder.buildInBoundsGEP(array_llvm_ty, operand, &indexes, indexes.len, ""); | 7686 | const elem_ptr = self.builder.buildInBoundsGEP(array_llvm_ty, operand, &indexes, indexes.len, ""); |
| 7687 | const elem = self.builder.buildLoad(elem_llvm_ty, elem_ptr, ""); | 7687 | const elem = self.builder.buildLoad(elem_llvm_ty, elem_ptr, ""); |
| 7688 | vector = self.builder.buildInsertElement(vector, elem, index_u32, ""); | 7688 | vector = self.builder.buildInsertElement(vector, elem, index_u32, ""); |
| ... | @@ -7731,7 +7731,7 @@ pub const FuncGen = struct { | ... | @@ -7731,7 +7731,7 @@ pub const FuncGen = struct { |
| 7731 | return self.builder.buildBitCast(operand, llvm_dest_ty, ""); | 7731 | return self.builder.buildBitCast(operand, llvm_dest_ty, ""); |
| 7732 | } | 7732 | } |
| 7733 | | 7733 | |
| 7734 | fn airBoolToInt(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 7734 | fn airBoolToInt(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 7735 | if (self.liveness.isUnused(inst)) | 7735 | if (self.liveness.isUnused(inst)) |
| 7736 | return null; | 7736 | return null; |
| 7737 | | 7737 | |
| ... | @@ -7740,7 +7740,7 @@ pub const FuncGen = struct { | ... | @@ -7740,7 +7740,7 @@ pub const FuncGen = struct { |
| 7740 | return operand; | 7740 | return operand; |
| 7741 | } | 7741 | } |
| 7742 | | 7742 | |
| 7743 | fn airArg(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 7743 | fn airArg(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 7744 | const arg_val = self.args[self.arg_index]; | 7744 | const arg_val = self.args[self.arg_index]; |
| 7745 | self.arg_index += 1; | 7745 | self.arg_index += 1; |
| 7746 | | 7746 | |
| ... | @@ -7787,7 +7787,7 @@ pub const FuncGen = struct { | ... | @@ -7787,7 +7787,7 @@ pub const FuncGen = struct { |
| 7787 | } else unreachable; | 7787 | } else unreachable; |
| 7788 | } | 7788 | } |
| 7789 | | 7789 | |
| 7790 | fn airAlloc(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 7790 | fn airAlloc(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 7791 | if (self.liveness.isUnused(inst)) return null; | 7791 | if (self.liveness.isUnused(inst)) return null; |
| 7792 | const ptr_ty = self.air.typeOfIndex(inst); | 7792 | const ptr_ty = self.air.typeOfIndex(inst); |
| 7793 | const pointee_type = ptr_ty.childType(); | 7793 | const pointee_type = ptr_ty.childType(); |
| ... | @@ -7801,7 +7801,7 @@ pub const FuncGen = struct { | ... | @@ -7801,7 +7801,7 @@ pub const FuncGen = struct { |
| 7801 | return alloca_inst; | 7801 | return alloca_inst; |
| 7802 | } | 7802 | } |
| 7803 | | 7803 | |
| 7804 | fn airRetPtr(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 7804 | fn airRetPtr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 7805 | if (self.liveness.isUnused(inst)) return null; | 7805 | if (self.liveness.isUnused(inst)) return null; |
| 7806 | const ptr_ty = self.air.typeOfIndex(inst); | 7806 | const ptr_ty = self.air.typeOfIndex(inst); |
| 7807 | const ret_ty = ptr_ty.childType(); | 7807 | const ret_ty = ptr_ty.childType(); |
| ... | @@ -7816,11 +7816,11 @@ pub const FuncGen = struct { | ... | @@ -7816,11 +7816,11 @@ pub const FuncGen = struct { |
| 7816 | | 7816 | |
| 7817 | /// Use this instead of builder.buildAlloca, because this function makes sure to | 7817 | /// Use this instead of builder.buildAlloca, because this function makes sure to |
| 7818 | /// put the alloca instruction at the top of the function! | 7818 | /// put the alloca instruction at the top of the function! |
| 7819 | fn buildAlloca(self: *FuncGen, llvm_ty: *const llvm.Type) *const llvm.Value { | 7819 | fn buildAlloca(self: *FuncGen, llvm_ty: *llvm.Type) *llvm.Value { |
| 7820 | return buildAllocaInner(self.builder, self.llvm_func, self.di_scope != null, llvm_ty); | 7820 | return buildAllocaInner(self.builder, self.llvm_func, self.di_scope != null, llvm_ty); |
| 7821 | } | 7821 | } |
| 7822 | | 7822 | |
| 7823 | fn airStore(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 7823 | fn airStore(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 7824 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; | 7824 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 7825 | const dest_ptr = try self.resolveInst(bin_op.lhs); | 7825 | const dest_ptr = try self.resolveInst(bin_op.lhs); |
| 7826 | const ptr_ty = self.air.typeOf(bin_op.lhs); | 7826 | const ptr_ty = self.air.typeOf(bin_op.lhs); |
| ... | @@ -7873,7 +7873,7 @@ pub const FuncGen = struct { | ... | @@ -7873,7 +7873,7 @@ pub const FuncGen = struct { |
| 7873 | inst: Air.Inst.Index, | 7873 | inst: Air.Inst.Index, |
| 7874 | body: []const Air.Inst.Index, | 7874 | body: []const Air.Inst.Index, |
| 7875 | body_i: usize, | 7875 | body_i: usize, |
| 7876 | ) !?*const llvm.Value { | 7876 | ) !?*llvm.Value { |
| 7877 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 7877 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 7878 | const ptr_ty = self.air.typeOf(ty_op.operand); | 7878 | const ptr_ty = self.air.typeOf(ty_op.operand); |
| 7879 | elide: { | 7879 | elide: { |
| ... | @@ -7899,14 +7899,14 @@ pub const FuncGen = struct { | ... | @@ -7899,14 +7899,14 @@ pub const FuncGen = struct { |
| 7899 | return self.load(ptr, ptr_ty); | 7899 | return self.load(ptr, ptr_ty); |
| 7900 | } | 7900 | } |
| 7901 | | 7901 | |
| 7902 | fn airBreakpoint(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 7902 | fn airBreakpoint(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 7903 | _ = inst; | 7903 | _ = inst; |
| 7904 | const llvm_fn = self.getIntrinsic("llvm.debugtrap", &.{}); | 7904 | const llvm_fn = self.getIntrinsic("llvm.debugtrap", &.{}); |
| 7905 | _ = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, undefined, 0, .C, .Auto, ""); | 7905 | _ = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, undefined, 0, .C, .Auto, ""); |
| 7906 | return null; | 7906 | return null; |
| 7907 | } | 7907 | } |
| 7908 | | 7908 | |
| 7909 | fn airRetAddr(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 7909 | fn airRetAddr(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 7910 | if (self.liveness.isUnused(inst)) return null; | 7910 | if (self.liveness.isUnused(inst)) return null; |
| 7911 | | 7911 | |
| 7912 | const llvm_usize = try self.dg.lowerType(Type.usize); | 7912 | const llvm_usize = try self.dg.lowerType(Type.usize); |
| ... | @@ -7918,30 +7918,30 @@ pub const FuncGen = struct { | ... | @@ -7918,30 +7918,30 @@ pub const FuncGen = struct { |
| 7918 | | 7918 | |
| 7919 | const llvm_i32 = self.context.intType(32); | 7919 | const llvm_i32 = self.context.intType(32); |
| 7920 | const llvm_fn = self.getIntrinsic("llvm.returnaddress", &.{}); | 7920 | const llvm_fn = self.getIntrinsic("llvm.returnaddress", &.{}); |
| 7921 | const params = [_]*const llvm.Value{llvm_i32.constNull()}; | 7921 | const params = [_]*llvm.Value{llvm_i32.constNull()}; |
| 7922 | const ptr_val = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &params, params.len, .Fast, .Auto, ""); | 7922 | const ptr_val = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &params, params.len, .Fast, .Auto, ""); |
| 7923 | return self.builder.buildPtrToInt(ptr_val, llvm_usize, ""); | 7923 | return self.builder.buildPtrToInt(ptr_val, llvm_usize, ""); |
| 7924 | } | 7924 | } |
| 7925 | | 7925 | |
| 7926 | fn airFrameAddress(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 7926 | fn airFrameAddress(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 7927 | if (self.liveness.isUnused(inst)) return null; | 7927 | if (self.liveness.isUnused(inst)) return null; |
| 7928 | | 7928 | |
| 7929 | const llvm_i32 = self.context.intType(32); | 7929 | const llvm_i32 = self.context.intType(32); |
| 7930 | const llvm_fn_name = "llvm.frameaddress.p0"; | 7930 | const llvm_fn_name = "llvm.frameaddress.p0"; |
| 7931 | const llvm_fn = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: { | 7931 | const llvm_fn = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: { |
| 7932 | const llvm_p0i8 = self.context.intType(8).pointerType(0); | 7932 | const llvm_p0i8 = self.context.intType(8).pointerType(0); |
| 7933 | const param_types = [_]*const llvm.Type{llvm_i32}; | 7933 | const param_types = [_]*llvm.Type{llvm_i32}; |
| 7934 | const fn_type = llvm.functionType(llvm_p0i8, &param_types, param_types.len, .False); | 7934 | const fn_type = llvm.functionType(llvm_p0i8, &param_types, param_types.len, .False); |
| 7935 | break :blk self.dg.object.llvm_module.addFunction(llvm_fn_name, fn_type); | 7935 | break :blk self.dg.object.llvm_module.addFunction(llvm_fn_name, fn_type); |
| 7936 | }; | 7936 | }; |
| 7937 | | 7937 | |
| 7938 | const params = [_]*const llvm.Value{llvm_i32.constNull()}; | 7938 | const params = [_]*llvm.Value{llvm_i32.constNull()}; |
| 7939 | const ptr_val = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &params, params.len, .Fast, .Auto, ""); | 7939 | const ptr_val = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &params, params.len, .Fast, .Auto, ""); |
| 7940 | const llvm_usize = try self.dg.lowerType(Type.usize); | 7940 | const llvm_usize = try self.dg.lowerType(Type.usize); |
| 7941 | return self.builder.buildPtrToInt(ptr_val, llvm_usize, ""); | 7941 | return self.builder.buildPtrToInt(ptr_val, llvm_usize, ""); |
| 7942 | } | 7942 | } |
| 7943 | | 7943 | |
| 7944 | fn airFence(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 7944 | fn airFence(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 7945 | const atomic_order = self.air.instructions.items(.data)[inst].fence; | 7945 | const atomic_order = self.air.instructions.items(.data)[inst].fence; |
| 7946 | const llvm_memory_order = toLlvmAtomicOrdering(atomic_order); | 7946 | const llvm_memory_order = toLlvmAtomicOrdering(atomic_order); |
| 7947 | const single_threaded = llvm.Bool.fromBool(self.single_threaded); | 7947 | const single_threaded = llvm.Bool.fromBool(self.single_threaded); |
| ... | @@ -7949,7 +7949,7 @@ pub const FuncGen = struct { | ... | @@ -7949,7 +7949,7 @@ pub const FuncGen = struct { |
| 7949 | return null; | 7949 | return null; |
| 7950 | } | 7950 | } |
| 7951 | | 7951 | |
| 7952 | fn airCmpxchg(self: *FuncGen, inst: Air.Inst.Index, is_weak: bool) !?*const llvm.Value { | 7952 | fn airCmpxchg(self: *FuncGen, inst: Air.Inst.Index, is_weak: bool) !?*llvm.Value { |
| 7953 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; | 7953 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| 7954 | const extra = self.air.extraData(Air.Cmpxchg, ty_pl.payload).data; | 7954 | const extra = self.air.extraData(Air.Cmpxchg, ty_pl.payload).data; |
| 7955 | var ptr = try self.resolveInst(extra.ptr); | 7955 | var ptr = try self.resolveInst(extra.ptr); |
| ... | @@ -7996,7 +7996,7 @@ pub const FuncGen = struct { | ... | @@ -7996,7 +7996,7 @@ pub const FuncGen = struct { |
| 7996 | return buildOptional(self, optional_ty, payload, non_null_bit); | 7996 | return buildOptional(self, optional_ty, payload, non_null_bit); |
| 7997 | } | 7997 | } |
| 7998 | | 7998 | |
| 7999 | fn airAtomicRmw(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 7999 | fn airAtomicRmw(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 8000 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; | 8000 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; |
| 8001 | const extra = self.air.extraData(Air.AtomicRmw, pl_op.payload).data; | 8001 | const extra = self.air.extraData(Air.AtomicRmw, pl_op.payload).data; |
| 8002 | const ptr = try self.resolveInst(pl_op.operand); | 8002 | const ptr = try self.resolveInst(pl_op.operand); |
| ... | @@ -8053,7 +8053,7 @@ pub const FuncGen = struct { | ... | @@ -8053,7 +8053,7 @@ pub const FuncGen = struct { |
| 8053 | return self.builder.buildIntToPtr(uncasted_result, operand_llvm_ty, ""); | 8053 | return self.builder.buildIntToPtr(uncasted_result, operand_llvm_ty, ""); |
| 8054 | } | 8054 | } |
| 8055 | | 8055 | |
| 8056 | fn airAtomicLoad(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 8056 | fn airAtomicLoad(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 8057 | const atomic_load = self.air.instructions.items(.data)[inst].atomic_load; | 8057 | const atomic_load = self.air.instructions.items(.data)[inst].atomic_load; |
| 8058 | const ptr = try self.resolveInst(atomic_load.ptr); | 8058 | const ptr = try self.resolveInst(atomic_load.ptr); |
| 8059 | const ptr_ty = self.air.typeOf(atomic_load.ptr); | 8059 | const ptr_ty = self.air.typeOf(atomic_load.ptr); |
| ... | @@ -8090,7 +8090,7 @@ pub const FuncGen = struct { | ... | @@ -8090,7 +8090,7 @@ pub const FuncGen = struct { |
| 8090 | self: *FuncGen, | 8090 | self: *FuncGen, |
| 8091 | inst: Air.Inst.Index, | 8091 | inst: Air.Inst.Index, |
| 8092 | ordering: llvm.AtomicOrdering, | 8092 | ordering: llvm.AtomicOrdering, |
| 8093 | ) !?*const llvm.Value { | 8093 | ) !?*llvm.Value { |
| 8094 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; | 8094 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 8095 | const ptr_ty = self.air.typeOf(bin_op.lhs); | 8095 | const ptr_ty = self.air.typeOf(bin_op.lhs); |
| 8096 | const operand_ty = ptr_ty.childType(); | 8096 | const operand_ty = ptr_ty.childType(); |
| ... | @@ -8112,7 +8112,7 @@ pub const FuncGen = struct { | ... | @@ -8112,7 +8112,7 @@ pub const FuncGen = struct { |
| 8112 | return null; | 8112 | return null; |
| 8113 | } | 8113 | } |
| 8114 | | 8114 | |
| 8115 | fn airMemset(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 8115 | fn airMemset(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 8116 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; | 8116 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; |
| 8117 | const extra = self.air.extraData(Air.Bin, pl_op.payload).data; | 8117 | const extra = self.air.extraData(Air.Bin, pl_op.payload).data; |
| 8118 | const dest_ptr = try self.resolveInst(pl_op.operand); | 8118 | const dest_ptr = try self.resolveInst(pl_op.operand); |
| ... | @@ -8134,7 +8134,7 @@ pub const FuncGen = struct { | ... | @@ -8134,7 +8134,7 @@ pub const FuncGen = struct { |
| 8134 | return null; | 8134 | return null; |
| 8135 | } | 8135 | } |
| 8136 | | 8136 | |
| 8137 | fn airMemcpy(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 8137 | fn airMemcpy(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 8138 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; | 8138 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; |
| 8139 | const extra = self.air.extraData(Air.Bin, pl_op.payload).data; | 8139 | const extra = self.air.extraData(Air.Bin, pl_op.payload).data; |
| 8140 | const dest_ptr = try self.resolveInst(pl_op.operand); | 8140 | const dest_ptr = try self.resolveInst(pl_op.operand); |
| ... | @@ -8158,7 +8158,7 @@ pub const FuncGen = struct { | ... | @@ -8158,7 +8158,7 @@ pub const FuncGen = struct { |
| 8158 | return null; | 8158 | return null; |
| 8159 | } | 8159 | } |
| 8160 | | 8160 | |
| 8161 | fn airSetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 8161 | fn airSetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 8162 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; | 8162 | const bin_op = self.air.instructions.items(.data)[inst].bin_op; |
| 8163 | const un_ty = self.air.typeOf(bin_op.lhs).childType(); | 8163 | const un_ty = self.air.typeOf(bin_op.lhs).childType(); |
| 8164 | const target = self.dg.module.getTarget(); | 8164 | const target = self.dg.module.getTarget(); |
| ... | @@ -8179,7 +8179,7 @@ pub const FuncGen = struct { | ... | @@ -8179,7 +8179,7 @@ pub const FuncGen = struct { |
| 8179 | return null; | 8179 | return null; |
| 8180 | } | 8180 | } |
| 8181 | | 8181 | |
| 8182 | fn airGetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 8182 | fn airGetUnionTag(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 8183 | if (self.liveness.isUnused(inst)) return null; | 8183 | if (self.liveness.isUnused(inst)) return null; |
| 8184 | | 8184 | |
| 8185 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 8185 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| ... | @@ -8205,7 +8205,7 @@ pub const FuncGen = struct { | ... | @@ -8205,7 +8205,7 @@ pub const FuncGen = struct { |
| 8205 | } | 8205 | } |
| 8206 | } | 8206 | } |
| 8207 | | 8207 | |
| 8208 | fn airUnaryOp(self: *FuncGen, inst: Air.Inst.Index, comptime op: FloatOp) !?*const llvm.Value { | 8208 | fn airUnaryOp(self: *FuncGen, inst: Air.Inst.Index, comptime op: FloatOp) !?*llvm.Value { |
| 8209 | if (self.liveness.isUnused(inst)) return null; | 8209 | if (self.liveness.isUnused(inst)) return null; |
| 8210 | | 8210 | |
| 8211 | const un_op = self.air.instructions.items(.data)[inst].un_op; | 8211 | const un_op = self.air.instructions.items(.data)[inst].un_op; |
| ... | @@ -8215,7 +8215,7 @@ pub const FuncGen = struct { | ... | @@ -8215,7 +8215,7 @@ pub const FuncGen = struct { |
| 8215 | return self.buildFloatOp(op, operand_ty, 1, .{operand}); | 8215 | return self.buildFloatOp(op, operand_ty, 1, .{operand}); |
| 8216 | } | 8216 | } |
| 8217 | | 8217 | |
| 8218 | fn airNeg(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value { | 8218 | fn airNeg(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value { |
| 8219 | if (self.liveness.isUnused(inst)) return null; | 8219 | if (self.liveness.isUnused(inst)) return null; |
| 8220 | self.builder.setFastMath(want_fast_math); | 8220 | self.builder.setFastMath(want_fast_math); |
| 8221 | | 8221 | |
| ... | @@ -8226,7 +8226,7 @@ pub const FuncGen = struct { | ... | @@ -8226,7 +8226,7 @@ pub const FuncGen = struct { |
| 8226 | return self.buildFloatOp(.neg, operand_ty, 1, .{operand}); | 8226 | return self.buildFloatOp(.neg, operand_ty, 1, .{operand}); |
| 8227 | } | 8227 | } |
| 8228 | | 8228 | |
| 8229 | fn airClzCtz(self: *FuncGen, inst: Air.Inst.Index, llvm_fn_name: []const u8) !?*const llvm.Value { | 8229 | fn airClzCtz(self: *FuncGen, inst: Air.Inst.Index, llvm_fn_name: []const u8) !?*llvm.Value { |
| 8230 | if (self.liveness.isUnused(inst)) return null; | 8230 | if (self.liveness.isUnused(inst)) return null; |
| 8231 | | 8231 | |
| 8232 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 8232 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| ... | @@ -8237,7 +8237,7 @@ pub const FuncGen = struct { | ... | @@ -8237,7 +8237,7 @@ pub const FuncGen = struct { |
| 8237 | const operand_llvm_ty = try self.dg.lowerType(operand_ty); | 8237 | const operand_llvm_ty = try self.dg.lowerType(operand_ty); |
| 8238 | const fn_val = self.getIntrinsic(llvm_fn_name, &.{operand_llvm_ty}); | 8238 | const fn_val = self.getIntrinsic(llvm_fn_name, &.{operand_llvm_ty}); |
| 8239 | | 8239 | |
| 8240 | const params = [_]*const llvm.Value{ operand, llvm_i1.constNull() }; | 8240 | const params = [_]*llvm.Value{ operand, llvm_i1.constNull() }; |
| 8241 | const wrong_size_result = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, &params, params.len, .C, .Auto, ""); | 8241 | const wrong_size_result = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, &params, params.len, .C, .Auto, ""); |
| 8242 | const result_ty = self.air.typeOfIndex(inst); | 8242 | const result_ty = self.air.typeOfIndex(inst); |
| 8243 | const result_llvm_ty = try self.dg.lowerType(result_ty); | 8243 | const result_llvm_ty = try self.dg.lowerType(result_ty); |
| ... | @@ -8254,14 +8254,14 @@ pub const FuncGen = struct { | ... | @@ -8254,14 +8254,14 @@ pub const FuncGen = struct { |
| 8254 | } | 8254 | } |
| 8255 | } | 8255 | } |
| 8256 | | 8256 | |
| 8257 | fn airBitOp(self: *FuncGen, inst: Air.Inst.Index, llvm_fn_name: []const u8) !?*const llvm.Value { | 8257 | fn airBitOp(self: *FuncGen, inst: Air.Inst.Index, llvm_fn_name: []const u8) !?*llvm.Value { |
| 8258 | if (self.liveness.isUnused(inst)) return null; | 8258 | if (self.liveness.isUnused(inst)) return null; |
| 8259 | | 8259 | |
| 8260 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 8260 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| 8261 | const operand_ty = self.air.typeOf(ty_op.operand); | 8261 | const operand_ty = self.air.typeOf(ty_op.operand); |
| 8262 | const operand = try self.resolveInst(ty_op.operand); | 8262 | const operand = try self.resolveInst(ty_op.operand); |
| 8263 | | 8263 | |
| 8264 | const params = [_]*const llvm.Value{operand}; | 8264 | const params = [_]*llvm.Value{operand}; |
| 8265 | const operand_llvm_ty = try self.dg.lowerType(operand_ty); | 8265 | const operand_llvm_ty = try self.dg.lowerType(operand_ty); |
| 8266 | const fn_val = self.getIntrinsic(llvm_fn_name, &.{operand_llvm_ty}); | 8266 | const fn_val = self.getIntrinsic(llvm_fn_name, &.{operand_llvm_ty}); |
| 8267 | | 8267 | |
| ... | @@ -8281,7 +8281,7 @@ pub const FuncGen = struct { | ... | @@ -8281,7 +8281,7 @@ pub const FuncGen = struct { |
| 8281 | } | 8281 | } |
| 8282 | } | 8282 | } |
| 8283 | | 8283 | |
| 8284 | fn airByteSwap(self: *FuncGen, inst: Air.Inst.Index, llvm_fn_name: []const u8) !?*const llvm.Value { | 8284 | fn airByteSwap(self: *FuncGen, inst: Air.Inst.Index, llvm_fn_name: []const u8) !?*llvm.Value { |
| 8285 | if (self.liveness.isUnused(inst)) return null; | 8285 | if (self.liveness.isUnused(inst)) return null; |
| 8286 | | 8286 | |
| 8287 | const target = self.dg.module.getTarget(); | 8287 | const target = self.dg.module.getTarget(); |
| ... | @@ -8301,7 +8301,7 @@ pub const FuncGen = struct { | ... | @@ -8301,7 +8301,7 @@ pub const FuncGen = struct { |
| 8301 | const vec_len = operand_ty.vectorLen(); | 8301 | const vec_len = operand_ty.vectorLen(); |
| 8302 | operand_llvm_ty = scalar_llvm_ty.vectorType(vec_len); | 8302 | operand_llvm_ty = scalar_llvm_ty.vectorType(vec_len); |
| 8303 | | 8303 | |
| 8304 | const shifts = try self.gpa.alloc(*const llvm.Value, vec_len); | 8304 | const shifts = try self.gpa.alloc(*llvm.Value, vec_len); |
| 8305 | defer self.gpa.free(shifts); | 8305 | defer self.gpa.free(shifts); |
| 8306 | | 8306 | |
| 8307 | for (shifts) |*elem| { | 8307 | for (shifts) |*elem| { |
| ... | @@ -8319,7 +8319,7 @@ pub const FuncGen = struct { | ... | @@ -8319,7 +8319,7 @@ pub const FuncGen = struct { |
| 8319 | bits = bits + 8; | 8319 | bits = bits + 8; |
| 8320 | } | 8320 | } |
| 8321 | | 8321 | |
| 8322 | const params = [_]*const llvm.Value{operand}; | 8322 | const params = [_]*llvm.Value{operand}; |
| 8323 | const fn_val = self.getIntrinsic(llvm_fn_name, &.{operand_llvm_ty}); | 8323 | const fn_val = self.getIntrinsic(llvm_fn_name, &.{operand_llvm_ty}); |
| 8324 | | 8324 | |
| 8325 | const wrong_size_result = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, &params, params.len, .C, .Auto, ""); | 8325 | const wrong_size_result = self.builder.buildCall(fn_val.globalGetValueType(), fn_val, &params, params.len, .C, .Auto, ""); |
| ... | @@ -8336,7 +8336,7 @@ pub const FuncGen = struct { | ... | @@ -8336,7 +8336,7 @@ pub const FuncGen = struct { |
| 8336 | } | 8336 | } |
| 8337 | } | 8337 | } |
| 8338 | | 8338 | |
| 8339 | fn airErrorSetHasValue(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 8339 | fn airErrorSetHasValue(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 8340 | if (self.liveness.isUnused(inst)) return null; | 8340 | if (self.liveness.isUnused(inst)) return null; |
| 8341 | | 8341 | |
| 8342 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 8342 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| ... | @@ -8372,10 +8372,10 @@ pub const FuncGen = struct { | ... | @@ -8372,10 +8372,10 @@ pub const FuncGen = struct { |
| 8372 | self.builder.positionBuilderAtEnd(end_block); | 8372 | self.builder.positionBuilderAtEnd(end_block); |
| 8373 | | 8373 | |
| 8374 | const llvm_type = self.dg.context.intType(1); | 8374 | const llvm_type = self.dg.context.intType(1); |
| 8375 | const incoming_values: [2]*const llvm.Value = .{ | 8375 | const incoming_values: [2]*llvm.Value = .{ |
| 8376 | llvm_type.constInt(1, .False), llvm_type.constInt(0, .False), | 8376 | llvm_type.constInt(1, .False), llvm_type.constInt(0, .False), |
| 8377 | }; | 8377 | }; |
| 8378 | const incoming_blocks: [2]*const llvm.BasicBlock = .{ | 8378 | const incoming_blocks: [2]*llvm.BasicBlock = .{ |
| 8379 | valid_block, invalid_block, | 8379 | valid_block, invalid_block, |
| 8380 | }; | 8380 | }; |
| 8381 | const phi_node = self.builder.buildPhi(llvm_type, ""); | 8381 | const phi_node = self.builder.buildPhi(llvm_type, ""); |
| ... | @@ -8383,7 +8383,7 @@ pub const FuncGen = struct { | ... | @@ -8383,7 +8383,7 @@ pub const FuncGen = struct { |
| 8383 | return phi_node; | 8383 | return phi_node; |
| 8384 | } | 8384 | } |
| 8385 | | 8385 | |
| 8386 | fn airIsNamedEnumValue(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 8386 | fn airIsNamedEnumValue(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 8387 | if (self.liveness.isUnused(inst)) return null; | 8387 | if (self.liveness.isUnused(inst)) return null; |
| 8388 | | 8388 | |
| 8389 | const un_op = self.air.instructions.items(.data)[inst].un_op; | 8389 | const un_op = self.air.instructions.items(.data)[inst].un_op; |
| ... | @@ -8391,11 +8391,11 @@ pub const FuncGen = struct { | ... | @@ -8391,11 +8391,11 @@ pub const FuncGen = struct { |
| 8391 | const enum_ty = self.air.typeOf(un_op); | 8391 | const enum_ty = self.air.typeOf(un_op); |
| 8392 | | 8392 | |
| 8393 | const llvm_fn = try self.getIsNamedEnumValueFunction(enum_ty); | 8393 | const llvm_fn = try self.getIsNamedEnumValueFunction(enum_ty); |
| 8394 | const params = [_]*const llvm.Value{operand}; | 8394 | const params = [_]*llvm.Value{operand}; |
| 8395 | return self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &params, params.len, .Fast, .Auto, ""); | 8395 | return self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &params, params.len, .Fast, .Auto, ""); |
| 8396 | } | 8396 | } |
| 8397 | | 8397 | |
| 8398 | fn getIsNamedEnumValueFunction(self: *FuncGen, enum_ty: Type) !*const llvm.Value { | 8398 | fn getIsNamedEnumValueFunction(self: *FuncGen, enum_ty: Type) !*llvm.Value { |
| 8399 | const enum_decl = enum_ty.getOwnerDecl(); | 8399 | const enum_decl = enum_ty.getOwnerDecl(); |
| 8400 | | 8400 | |
| 8401 | // TODO: detect when the type changes and re-emit this function. | 8401 | // TODO: detect when the type changes and re-emit this function. |
| ... | @@ -8414,7 +8414,7 @@ pub const FuncGen = struct { | ... | @@ -8414,7 +8414,7 @@ pub const FuncGen = struct { |
| 8414 | | 8414 | |
| 8415 | var int_tag_type_buffer: Type.Payload.Bits = undefined; | 8415 | var int_tag_type_buffer: Type.Payload.Bits = undefined; |
| 8416 | const int_tag_ty = enum_ty.intTagType(&int_tag_type_buffer); | 8416 | const int_tag_ty = enum_ty.intTagType(&int_tag_type_buffer); |
| 8417 | const param_types = [_]*const llvm.Type{try self.dg.lowerType(int_tag_ty)}; | 8417 | const param_types = [_]*llvm.Type{try self.dg.lowerType(int_tag_ty)}; |
| 8418 | | 8418 | |
| 8419 | const llvm_ret_ty = try self.dg.lowerType(Type.bool); | 8419 | const llvm_ret_ty = try self.dg.lowerType(Type.bool); |
| 8420 | const fn_type = llvm.functionType(llvm_ret_ty, &param_types, param_types.len, .False); | 8420 | const fn_type = llvm.functionType(llvm_ret_ty, &param_types, param_types.len, .False); |
| ... | @@ -8464,7 +8464,7 @@ pub const FuncGen = struct { | ... | @@ -8464,7 +8464,7 @@ pub const FuncGen = struct { |
| 8464 | return fn_val; | 8464 | return fn_val; |
| 8465 | } | 8465 | } |
| 8466 | | 8466 | |
| 8467 | fn airTagName(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 8467 | fn airTagName(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 8468 | if (self.liveness.isUnused(inst)) return null; | 8468 | if (self.liveness.isUnused(inst)) return null; |
| 8469 | | 8469 | |
| 8470 | const un_op = self.air.instructions.items(.data)[inst].un_op; | 8470 | const un_op = self.air.instructions.items(.data)[inst].un_op; |
| ... | @@ -8472,11 +8472,11 @@ pub const FuncGen = struct { | ... | @@ -8472,11 +8472,11 @@ pub const FuncGen = struct { |
| 8472 | const enum_ty = self.air.typeOf(un_op); | 8472 | const enum_ty = self.air.typeOf(un_op); |
| 8473 | | 8473 | |
| 8474 | const llvm_fn = try self.getEnumTagNameFunction(enum_ty); | 8474 | const llvm_fn = try self.getEnumTagNameFunction(enum_ty); |
| 8475 | const params = [_]*const llvm.Value{operand}; | 8475 | const params = [_]*llvm.Value{operand}; |
| 8476 | return self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &params, params.len, .Fast, .Auto, ""); | 8476 | return self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &params, params.len, .Fast, .Auto, ""); |
| 8477 | } | 8477 | } |
| 8478 | | 8478 | |
| 8479 | fn getEnumTagNameFunction(self: *FuncGen, enum_ty: Type) !*const llvm.Value { | 8479 | fn getEnumTagNameFunction(self: *FuncGen, enum_ty: Type) !*llvm.Value { |
| 8480 | const enum_decl = enum_ty.getOwnerDecl(); | 8480 | const enum_decl = enum_ty.getOwnerDecl(); |
| 8481 | | 8481 | |
| 8482 | // TODO: detect when the type changes and re-emit this function. | 8482 | // TODO: detect when the type changes and re-emit this function. |
| ... | @@ -8501,7 +8501,7 @@ pub const FuncGen = struct { | ... | @@ -8501,7 +8501,7 @@ pub const FuncGen = struct { |
| 8501 | | 8501 | |
| 8502 | var int_tag_type_buffer: Type.Payload.Bits = undefined; | 8502 | var int_tag_type_buffer: Type.Payload.Bits = undefined; |
| 8503 | const int_tag_ty = enum_ty.intTagType(&int_tag_type_buffer); | 8503 | const int_tag_ty = enum_ty.intTagType(&int_tag_type_buffer); |
| 8504 | const param_types = [_]*const llvm.Type{try self.dg.lowerType(int_tag_ty)}; | 8504 | const param_types = [_]*llvm.Type{try self.dg.lowerType(int_tag_ty)}; |
| 8505 | | 8505 | |
| 8506 | const fn_type = llvm.functionType(llvm_ret_ty, &param_types, param_types.len, .False); | 8506 | const fn_type = llvm.functionType(llvm_ret_ty, &param_types, param_types.len, .False); |
| 8507 | const fn_val = self.dg.object.llvm_module.addFunction(llvm_fn_name, fn_type); | 8507 | const fn_val = self.dg.object.llvm_module.addFunction(llvm_fn_name, fn_type); |
| ... | @@ -8528,7 +8528,7 @@ pub const FuncGen = struct { | ... | @@ -8528,7 +8528,7 @@ pub const FuncGen = struct { |
| 8528 | const tag_int_value = fn_val.getParam(0); | 8528 | const tag_int_value = fn_val.getParam(0); |
| 8529 | const switch_instr = self.builder.buildSwitch(tag_int_value, bad_value_block, @intCast(c_uint, fields.count())); | 8529 | const switch_instr = self.builder.buildSwitch(tag_int_value, bad_value_block, @intCast(c_uint, fields.count())); |
| 8530 | | 8530 | |
| 8531 | const array_ptr_indices = [_]*const llvm.Value{ | 8531 | const array_ptr_indices = [_]*llvm.Value{ |
| 8532 | usize_llvm_ty.constNull(), usize_llvm_ty.constNull(), | 8532 | usize_llvm_ty.constNull(), usize_llvm_ty.constNull(), |
| 8533 | }; | 8533 | }; |
| 8534 | | 8534 | |
| ... | @@ -8542,7 +8542,7 @@ pub const FuncGen = struct { | ... | @@ -8542,7 +8542,7 @@ pub const FuncGen = struct { |
| 8542 | str_global.setUnnamedAddr(.True); | 8542 | str_global.setUnnamedAddr(.True); |
| 8543 | str_global.setAlignment(1); | 8543 | str_global.setAlignment(1); |
| 8544 | | 8544 | |
| 8545 | const slice_fields = [_]*const llvm.Value{ | 8545 | const slice_fields = [_]*llvm.Value{ |
| 8546 | str_init_llvm_ty.constInBoundsGEP(str_global, &array_ptr_indices, array_ptr_indices.len), | 8546 | str_init_llvm_ty.constInBoundsGEP(str_global, &array_ptr_indices, array_ptr_indices.len), |
| 8547 | usize_llvm_ty.constInt(name.len, .False), | 8547 | usize_llvm_ty.constInt(name.len, .False), |
| 8548 | }; | 8548 | }; |
| ... | @@ -8578,7 +8578,7 @@ pub const FuncGen = struct { | ... | @@ -8578,7 +8578,7 @@ pub const FuncGen = struct { |
| 8578 | return fn_val; | 8578 | return fn_val; |
| 8579 | } | 8579 | } |
| 8580 | | 8580 | |
| 8581 | fn getCmpLtErrorsLenFunction(self: *FuncGen) !*const llvm.Value { | 8581 | fn getCmpLtErrorsLenFunction(self: *FuncGen) !*llvm.Value { |
| 8582 | if (self.dg.object.llvm_module.getNamedFunction(lt_errors_fn_name)) |llvm_fn| { | 8582 | if (self.dg.object.llvm_module.getNamedFunction(lt_errors_fn_name)) |llvm_fn| { |
| 8583 | return llvm_fn; | 8583 | return llvm_fn; |
| 8584 | } | 8584 | } |
| ... | @@ -8587,7 +8587,7 @@ pub const FuncGen = struct { | ... | @@ -8587,7 +8587,7 @@ pub const FuncGen = struct { |
| 8587 | | 8587 | |
| 8588 | const ret_llvm_ty = try self.dg.lowerType(Type.bool); | 8588 | const ret_llvm_ty = try self.dg.lowerType(Type.bool); |
| 8589 | const anyerror_llvm_ty = try self.dg.lowerType(Type.anyerror); | 8589 | const anyerror_llvm_ty = try self.dg.lowerType(Type.anyerror); |
| 8590 | const param_types = [_]*const llvm.Type{anyerror_llvm_ty}; | 8590 | const param_types = [_]*llvm.Type{anyerror_llvm_ty}; |
| 8591 | | 8591 | |
| 8592 | const fn_type = llvm.functionType(ret_llvm_ty, &param_types, param_types.len, .False); | 8592 | const fn_type = llvm.functionType(ret_llvm_ty, &param_types, param_types.len, .False); |
| 8593 | const llvm_fn = self.dg.object.llvm_module.addFunction(lt_errors_fn_name, fn_type); | 8593 | const llvm_fn = self.dg.object.llvm_module.addFunction(lt_errors_fn_name, fn_type); |
| ... | @@ -8597,7 +8597,7 @@ pub const FuncGen = struct { | ... | @@ -8597,7 +8597,7 @@ pub const FuncGen = struct { |
| 8597 | return llvm_fn; | 8597 | return llvm_fn; |
| 8598 | } | 8598 | } |
| 8599 | | 8599 | |
| 8600 | fn airErrorName(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 8600 | fn airErrorName(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 8601 | if (self.liveness.isUnused(inst)) return null; | 8601 | if (self.liveness.isUnused(inst)) return null; |
| 8602 | | 8602 | |
| 8603 | const un_op = self.air.instructions.items(.data)[inst].un_op; | 8603 | const un_op = self.air.instructions.items(.data)[inst].un_op; |
| ... | @@ -8608,12 +8608,12 @@ pub const FuncGen = struct { | ... | @@ -8608,12 +8608,12 @@ pub const FuncGen = struct { |
| 8608 | const error_name_table_ptr = try self.getErrorNameTable(); | 8608 | const error_name_table_ptr = try self.getErrorNameTable(); |
| 8609 | const ptr_slice_llvm_ty = slice_llvm_ty.pointerType(0); | 8609 | const ptr_slice_llvm_ty = slice_llvm_ty.pointerType(0); |
| 8610 | const error_name_table = self.builder.buildLoad(ptr_slice_llvm_ty, error_name_table_ptr, ""); | 8610 | const error_name_table = self.builder.buildLoad(ptr_slice_llvm_ty, error_name_table_ptr, ""); |
| 8611 | const indices = [_]*const llvm.Value{operand}; | 8611 | const indices = [_]*llvm.Value{operand}; |
| 8612 | const error_name_ptr = self.builder.buildInBoundsGEP(slice_llvm_ty, error_name_table, &indices, indices.len, ""); | 8612 | const error_name_ptr = self.builder.buildInBoundsGEP(slice_llvm_ty, error_name_table, &indices, indices.len, ""); |
| 8613 | return self.builder.buildLoad(slice_llvm_ty, error_name_ptr, ""); | 8613 | return self.builder.buildLoad(slice_llvm_ty, error_name_ptr, ""); |
| 8614 | } | 8614 | } |
| 8615 | | 8615 | |
| 8616 | fn airSplat(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 8616 | fn airSplat(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 8617 | if (self.liveness.isUnused(inst)) return null; | 8617 | if (self.liveness.isUnused(inst)) return null; |
| 8618 | | 8618 | |
| 8619 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; | 8619 | const ty_op = self.air.instructions.items(.data)[inst].ty_op; |
| ... | @@ -8623,7 +8623,7 @@ pub const FuncGen = struct { | ... | @@ -8623,7 +8623,7 @@ pub const FuncGen = struct { |
| 8623 | return self.builder.buildVectorSplat(len, scalar, ""); | 8623 | return self.builder.buildVectorSplat(len, scalar, ""); |
| 8624 | } | 8624 | } |
| 8625 | | 8625 | |
| 8626 | fn airSelect(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 8626 | fn airSelect(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 8627 | if (self.liveness.isUnused(inst)) return null; | 8627 | if (self.liveness.isUnused(inst)) return null; |
| 8628 | | 8628 | |
| 8629 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; | 8629 | const pl_op = self.air.instructions.items(.data)[inst].pl_op; |
| ... | @@ -8635,7 +8635,7 @@ pub const FuncGen = struct { | ... | @@ -8635,7 +8635,7 @@ pub const FuncGen = struct { |
| 8635 | return self.builder.buildSelect(pred, a, b, ""); | 8635 | return self.builder.buildSelect(pred, a, b, ""); |
| 8636 | } | 8636 | } |
| 8637 | | 8637 | |
| 8638 | fn airShuffle(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 8638 | fn airShuffle(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 8639 | if (self.liveness.isUnused(inst)) return null; | 8639 | if (self.liveness.isUnused(inst)) return null; |
| 8640 | | 8640 | |
| 8641 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; | 8641 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| ... | @@ -8651,7 +8651,7 @@ pub const FuncGen = struct { | ... | @@ -8651,7 +8651,7 @@ pub const FuncGen = struct { |
| 8651 | // when changing code, so Zig uses negative numbers to index the | 8651 | // when changing code, so Zig uses negative numbers to index the |
| 8652 | // second vector. These start at -1 and go down, and are easiest to use | 8652 | // second vector. These start at -1 and go down, and are easiest to use |
| 8653 | // with the ~ operator. Here we convert between the two formats. | 8653 | // with the ~ operator. Here we convert between the two formats. |
| 8654 | const values = try self.gpa.alloc(*const llvm.Value, mask_len); | 8654 | const values = try self.gpa.alloc(*llvm.Value, mask_len); |
| 8655 | defer self.gpa.free(values); | 8655 | defer self.gpa.free(values); |
| 8656 | | 8656 | |
| 8657 | const llvm_i32 = self.context.intType(32); | 8657 | const llvm_i32 = self.context.intType(32); |
| ... | @@ -8672,7 +8672,7 @@ pub const FuncGen = struct { | ... | @@ -8672,7 +8672,7 @@ pub const FuncGen = struct { |
| 8672 | return self.builder.buildShuffleVector(a, b, llvm_mask_value, ""); | 8672 | return self.builder.buildShuffleVector(a, b, llvm_mask_value, ""); |
| 8673 | } | 8673 | } |
| 8674 | | 8674 | |
| 8675 | fn airReduce(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*const llvm.Value { | 8675 | fn airReduce(self: *FuncGen, inst: Air.Inst.Index, want_fast_math: bool) !?*llvm.Value { |
| 8676 | if (self.liveness.isUnused(inst)) return null; | 8676 | if (self.liveness.isUnused(inst)) return null; |
| 8677 | self.builder.setFastMath(want_fast_math); | 8677 | self.builder.setFastMath(want_fast_math); |
| 8678 | | 8678 | |
| ... | @@ -8717,7 +8717,7 @@ pub const FuncGen = struct { | ... | @@ -8717,7 +8717,7 @@ pub const FuncGen = struct { |
| 8717 | } | 8717 | } |
| 8718 | } | 8718 | } |
| 8719 | | 8719 | |
| 8720 | fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 8720 | fn airAggregateInit(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 8721 | if (self.liveness.isUnused(inst)) return null; | 8721 | if (self.liveness.isUnused(inst)) return null; |
| 8722 | | 8722 | |
| 8723 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; | 8723 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| ... | @@ -8746,7 +8746,7 @@ pub const FuncGen = struct { | ... | @@ -8746,7 +8746,7 @@ pub const FuncGen = struct { |
| 8746 | const int_llvm_ty = self.dg.context.intType(@intCast(c_uint, big_bits)); | 8746 | const int_llvm_ty = self.dg.context.intType(@intCast(c_uint, big_bits)); |
| 8747 | const fields = struct_obj.fields.values(); | 8747 | const fields = struct_obj.fields.values(); |
| 8748 | comptime assert(Type.packed_struct_layout_version == 2); | 8748 | comptime assert(Type.packed_struct_layout_version == 2); |
| 8749 | var running_int: *const llvm.Value = int_llvm_ty.constNull(); | 8749 | var running_int: *llvm.Value = int_llvm_ty.constNull(); |
| 8750 | var running_bits: u16 = 0; | 8750 | var running_bits: u16 = 0; |
| 8751 | for (elements) |elem, i| { | 8751 | for (elements) |elem, i| { |
| 8752 | const field = fields[i]; | 8752 | const field = fields[i]; |
| ... | @@ -8780,7 +8780,7 @@ pub const FuncGen = struct { | ... | @@ -8780,7 +8780,7 @@ pub const FuncGen = struct { |
| 8780 | // even if we fully populate the fields. | 8780 | // even if we fully populate the fields. |
| 8781 | alloca_inst.setAlignment(result_ty.abiAlignment(target)); | 8781 | alloca_inst.setAlignment(result_ty.abiAlignment(target)); |
| 8782 | | 8782 | |
| 8783 | var indices: [2]*const llvm.Value = .{ llvm_u32.constNull(), undefined }; | 8783 | var indices: [2]*llvm.Value = .{ llvm_u32.constNull(), undefined }; |
| 8784 | for (elements) |elem, i| { | 8784 | for (elements) |elem, i| { |
| 8785 | if (result_ty.structFieldValueComptime(i) != null) continue; | 8785 | if (result_ty.structFieldValueComptime(i) != null) continue; |
| 8786 | | 8786 | |
| ... | @@ -8829,7 +8829,7 @@ pub const FuncGen = struct { | ... | @@ -8829,7 +8829,7 @@ pub const FuncGen = struct { |
| 8829 | const elem_ptr_ty = Type.initPayload(&elem_ptr_payload.base); | 8829 | const elem_ptr_ty = Type.initPayload(&elem_ptr_payload.base); |
| 8830 | | 8830 | |
| 8831 | for (elements) |elem, i| { | 8831 | for (elements) |elem, i| { |
| 8832 | const indices: [2]*const llvm.Value = .{ | 8832 | const indices: [2]*llvm.Value = .{ |
| 8833 | llvm_usize.constNull(), | 8833 | llvm_usize.constNull(), |
| 8834 | llvm_usize.constInt(@intCast(c_uint, i), .False), | 8834 | llvm_usize.constInt(@intCast(c_uint, i), .False), |
| 8835 | }; | 8835 | }; |
| ... | @@ -8838,7 +8838,7 @@ pub const FuncGen = struct { | ... | @@ -8838,7 +8838,7 @@ pub const FuncGen = struct { |
| 8838 | self.store(elem_ptr, elem_ptr_ty, llvm_elem, .NotAtomic); | 8838 | self.store(elem_ptr, elem_ptr_ty, llvm_elem, .NotAtomic); |
| 8839 | } | 8839 | } |
| 8840 | if (array_info.sentinel) |sent_val| { | 8840 | if (array_info.sentinel) |sent_val| { |
| 8841 | const indices: [2]*const llvm.Value = .{ | 8841 | const indices: [2]*llvm.Value = .{ |
| 8842 | llvm_usize.constNull(), | 8842 | llvm_usize.constNull(), |
| 8843 | llvm_usize.constInt(@intCast(c_uint, array_info.len), .False), | 8843 | llvm_usize.constInt(@intCast(c_uint, array_info.len), .False), |
| 8844 | }; | 8844 | }; |
| ... | @@ -8857,7 +8857,7 @@ pub const FuncGen = struct { | ... | @@ -8857,7 +8857,7 @@ pub const FuncGen = struct { |
| 8857 | } | 8857 | } |
| 8858 | } | 8858 | } |
| 8859 | | 8859 | |
| 8860 | fn airUnionInit(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 8860 | fn airUnionInit(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 8861 | if (self.liveness.isUnused(inst)) return null; | 8861 | if (self.liveness.isUnused(inst)) return null; |
| 8862 | | 8862 | |
| 8863 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; | 8863 | const ty_pl = self.air.instructions.items(.data)[inst].ty_pl; |
| ... | @@ -8910,17 +8910,17 @@ pub const FuncGen = struct { | ... | @@ -8910,17 +8910,17 @@ pub const FuncGen = struct { |
| 8910 | break :p field_llvm_ty; | 8910 | break :p field_llvm_ty; |
| 8911 | } | 8911 | } |
| 8912 | const padding_len = @intCast(c_uint, layout.payload_size - field_size); | 8912 | const padding_len = @intCast(c_uint, layout.payload_size - field_size); |
| 8913 | const fields: [2]*const llvm.Type = .{ | 8913 | const fields: [2]*llvm.Type = .{ |
| 8914 | field_llvm_ty, self.context.intType(8).arrayType(padding_len), | 8914 | field_llvm_ty, self.context.intType(8).arrayType(padding_len), |
| 8915 | }; | 8915 | }; |
| 8916 | break :p self.context.structType(&fields, fields.len, .False); | 8916 | break :p self.context.structType(&fields, fields.len, .False); |
| 8917 | }; | 8917 | }; |
| 8918 | if (layout.tag_size == 0) { | 8918 | if (layout.tag_size == 0) { |
| 8919 | const fields: [1]*const llvm.Type = .{payload}; | 8919 | const fields: [1]*llvm.Type = .{payload}; |
| 8920 | break :t self.context.structType(&fields, fields.len, .False); | 8920 | break :t self.context.structType(&fields, fields.len, .False); |
| 8921 | } | 8921 | } |
| 8922 | const tag_llvm_ty = try self.dg.lowerType(union_obj.tag_ty); | 8922 | const tag_llvm_ty = try self.dg.lowerType(union_obj.tag_ty); |
| 8923 | var fields: [3]*const llvm.Type = undefined; | 8923 | var fields: [3]*llvm.Type = undefined; |
| 8924 | var fields_len: c_uint = 2; | 8924 | var fields_len: c_uint = 2; |
| 8925 | if (layout.tag_align >= layout.payload_align) { | 8925 | if (layout.tag_align >= layout.payload_align) { |
| 8926 | fields = .{ tag_llvm_ty, payload, undefined }; | 8926 | fields = .{ tag_llvm_ty, payload, undefined }; |
| ... | @@ -8949,7 +8949,7 @@ pub const FuncGen = struct { | ... | @@ -8949,7 +8949,7 @@ pub const FuncGen = struct { |
| 8949 | }; | 8949 | }; |
| 8950 | const field_ptr_ty = Type.initPayload(&field_ptr_payload.base); | 8950 | const field_ptr_ty = Type.initPayload(&field_ptr_payload.base); |
| 8951 | if (layout.tag_size == 0) { | 8951 | if (layout.tag_size == 0) { |
| 8952 | const indices: [3]*const llvm.Value = .{ | 8952 | const indices: [3]*llvm.Value = .{ |
| 8953 | index_type.constNull(), | 8953 | index_type.constNull(), |
| 8954 | index_type.constNull(), | 8954 | index_type.constNull(), |
| 8955 | index_type.constNull(), | 8955 | index_type.constNull(), |
| ... | @@ -8961,7 +8961,7 @@ pub const FuncGen = struct { | ... | @@ -8961,7 +8961,7 @@ pub const FuncGen = struct { |
| 8961 | } | 8961 | } |
| 8962 | | 8962 | |
| 8963 | { | 8963 | { |
| 8964 | const indices: [3]*const llvm.Value = .{ | 8964 | const indices: [3]*llvm.Value = .{ |
| 8965 | index_type.constNull(), | 8965 | index_type.constNull(), |
| 8966 | index_type.constInt(@boolToInt(layout.tag_align >= layout.payload_align), .False), | 8966 | index_type.constInt(@boolToInt(layout.tag_align >= layout.payload_align), .False), |
| 8967 | index_type.constNull(), | 8967 | index_type.constNull(), |
| ... | @@ -8971,7 +8971,7 @@ pub const FuncGen = struct { | ... | @@ -8971,7 +8971,7 @@ pub const FuncGen = struct { |
| 8971 | self.store(field_ptr, field_ptr_ty, llvm_payload, .NotAtomic); | 8971 | self.store(field_ptr, field_ptr_ty, llvm_payload, .NotAtomic); |
| 8972 | } | 8972 | } |
| 8973 | { | 8973 | { |
| 8974 | const indices: [2]*const llvm.Value = .{ | 8974 | const indices: [2]*llvm.Value = .{ |
| 8975 | index_type.constNull(), | 8975 | index_type.constNull(), |
| 8976 | index_type.constInt(@boolToInt(layout.tag_align < layout.payload_align), .False), | 8976 | index_type.constInt(@boolToInt(layout.tag_align < layout.payload_align), .False), |
| 8977 | }; | 8977 | }; |
| ... | @@ -8985,7 +8985,7 @@ pub const FuncGen = struct { | ... | @@ -8985,7 +8985,7 @@ pub const FuncGen = struct { |
| 8985 | return result_ptr; | 8985 | return result_ptr; |
| 8986 | } | 8986 | } |
| 8987 | | 8987 | |
| 8988 | fn airPrefetch(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value { | 8988 | fn airPrefetch(self: *FuncGen, inst: Air.Inst.Index) !?*llvm.Value { |
| 8989 | const prefetch = self.air.instructions.items(.data)[inst].prefetch; | 8989 | const prefetch = self.air.instructions.items(.data)[inst].prefetch; |
| 8990 | | 8990 | |
| 8991 | comptime assert(@enumToInt(std.builtin.PrefetchOptions.Rw.read) == 0); | 8991 | comptime assert(@enumToInt(std.builtin.PrefetchOptions.Rw.read) == 0); |
| ... | @@ -9026,7 +9026,7 @@ pub const FuncGen = struct { | ... | @@ -9026,7 +9026,7 @@ pub const FuncGen = struct { |
| 9026 | const fn_val = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: { | 9026 | const fn_val = self.dg.object.llvm_module.getNamedFunction(llvm_fn_name) orelse blk: { |
| 9027 | // declare void @llvm.prefetch(i8*, i32, i32, i32) | 9027 | // declare void @llvm.prefetch(i8*, i32, i32, i32) |
| 9028 | const llvm_void = self.context.voidType(); | 9028 | const llvm_void = self.context.voidType(); |
| 9029 | const param_types = [_]*const llvm.Type{ | 9029 | const param_types = [_]*llvm.Type{ |
| 9030 | llvm_ptr_u8, llvm_u32, llvm_u32, llvm_u32, | 9030 | llvm_ptr_u8, llvm_u32, llvm_u32, llvm_u32, |
| 9031 | }; | 9031 | }; |
| 9032 | const fn_type = llvm.functionType(llvm_void, &param_types, param_types.len, .False); | 9032 | const fn_type = llvm.functionType(llvm_void, &param_types, param_types.len, .False); |
| ... | @@ -9036,7 +9036,7 @@ pub const FuncGen = struct { | ... | @@ -9036,7 +9036,7 @@ pub const FuncGen = struct { |
| 9036 | const ptr = try self.resolveInst(prefetch.ptr); | 9036 | const ptr = try self.resolveInst(prefetch.ptr); |
| 9037 | const ptr_u8 = self.builder.buildBitCast(ptr, llvm_ptr_u8, ""); | 9037 | const ptr_u8 = self.builder.buildBitCast(ptr, llvm_ptr_u8, ""); |
| 9038 | | 9038 | |
| 9039 | const params = [_]*const llvm.Value{ | 9039 | const params = [_]*llvm.Value{ |
| 9040 | ptr_u8, | 9040 | ptr_u8, |
| 9041 | llvm_u32.constInt(@enumToInt(prefetch.rw), .False), | 9041 | llvm_u32.constInt(@enumToInt(prefetch.rw), .False), |
| 9042 | llvm_u32.constInt(prefetch.locality, .False), | 9042 | llvm_u32.constInt(prefetch.locality, .False), |
| ... | @@ -9048,17 +9048,17 @@ pub const FuncGen = struct { | ... | @@ -9048,17 +9048,17 @@ pub const FuncGen = struct { |
| 9048 | | 9048 | |
| 9049 | fn softF80TruncOrExt( | 9049 | fn softF80TruncOrExt( |
| 9050 | self: *FuncGen, | 9050 | self: *FuncGen, |
| 9051 | operand: *const llvm.Value, | 9051 | operand: *llvm.Value, |
| 9052 | src_bits: u16, | 9052 | src_bits: u16, |
| 9053 | dest_bits: u16, | 9053 | dest_bits: u16, |
| 9054 | ) !?*const llvm.Value { | 9054 | ) !?*llvm.Value { |
| 9055 | const target = self.dg.module.getTarget(); | 9055 | const target = self.dg.module.getTarget(); |
| 9056 | | 9056 | |
| 9057 | var param_llvm_ty: *const llvm.Type = self.context.intType(80); | 9057 | var param_llvm_ty: *llvm.Type = self.context.intType(80); |
| 9058 | var ret_llvm_ty: *const llvm.Type = param_llvm_ty; | 9058 | var ret_llvm_ty: *llvm.Type = param_llvm_ty; |
| 9059 | var fn_name: [*:0]const u8 = undefined; | 9059 | var fn_name: [*:0]const u8 = undefined; |
| 9060 | var arg = operand; | 9060 | var arg = operand; |
| 9061 | var final_cast: ?*const llvm.Type = null; | 9061 | var final_cast: ?*llvm.Type = null; |
| 9062 | | 9062 | |
| 9063 | assert(src_bits == 80 or dest_bits == 80); | 9063 | assert(src_bits == 80 or dest_bits == 80); |
| 9064 | | 9064 | |
| ... | @@ -9116,18 +9116,18 @@ pub const FuncGen = struct { | ... | @@ -9116,18 +9116,18 @@ pub const FuncGen = struct { |
| 9116 | } | 9116 | } |
| 9117 | | 9117 | |
| 9118 | const llvm_fn = self.dg.object.llvm_module.getNamedFunction(fn_name) orelse f: { | 9118 | const llvm_fn = self.dg.object.llvm_module.getNamedFunction(fn_name) orelse f: { |
| 9119 | const param_types = [_]*const llvm.Type{param_llvm_ty}; | 9119 | const param_types = [_]*llvm.Type{param_llvm_ty}; |
| 9120 | const fn_type = llvm.functionType(ret_llvm_ty, &param_types, param_types.len, .False); | 9120 | const fn_type = llvm.functionType(ret_llvm_ty, &param_types, param_types.len, .False); |
| 9121 | break :f self.dg.object.llvm_module.addFunction(fn_name, fn_type); | 9121 | break :f self.dg.object.llvm_module.addFunction(fn_name, fn_type); |
| 9122 | }; | 9122 | }; |
| 9123 | | 9123 | |
| 9124 | var args: [1]*const llvm.Value = .{arg}; | 9124 | var args: [1]*llvm.Value = .{arg}; |
| 9125 | const result = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &args, args.len, .C, .Auto, ""); | 9125 | const result = self.builder.buildCall(llvm_fn.globalGetValueType(), llvm_fn, &args, args.len, .C, .Auto, ""); |
| 9126 | const final_cast_llvm_ty = final_cast orelse return result; | 9126 | const final_cast_llvm_ty = final_cast orelse return result; |
| 9127 | return self.builder.buildBitCast(result, final_cast_llvm_ty, ""); | 9127 | return self.builder.buildBitCast(result, final_cast_llvm_ty, ""); |
| 9128 | } | 9128 | } |
| 9129 | | 9129 | |
| 9130 | fn getErrorNameTable(self: *FuncGen) !*const llvm.Value { | 9130 | fn getErrorNameTable(self: *FuncGen) !*llvm.Value { |
| 9131 | if (self.dg.object.error_name_table) |table| { | 9131 | if (self.dg.object.error_name_table) |table| { |
| 9132 | return table; | 9132 | return table; |
| 9133 | } | 9133 | } |
| ... | @@ -9151,10 +9151,10 @@ pub const FuncGen = struct { | ... | @@ -9151,10 +9151,10 @@ pub const FuncGen = struct { |
| 9151 | /// Assumes the optional is not pointer-like and payload has bits. | 9151 | /// Assumes the optional is not pointer-like and payload has bits. |
| 9152 | fn optIsNonNull( | 9152 | fn optIsNonNull( |
| 9153 | self: *FuncGen, | 9153 | self: *FuncGen, |
| 9154 | opt_llvm_ty: *const llvm.Type, | 9154 | opt_llvm_ty: *llvm.Type, |
| 9155 | opt_handle: *const llvm.Value, | 9155 | opt_handle: *llvm.Value, |
| 9156 | is_by_ref: bool, | 9156 | is_by_ref: bool, |
| 9157 | ) *const llvm.Value { | 9157 | ) *llvm.Value { |
| 9158 | const non_null_llvm_ty = self.context.intType(8); | 9158 | const non_null_llvm_ty = self.context.intType(8); |
| 9159 | const field = b: { | 9159 | const field = b: { |
| 9160 | if (is_by_ref) { | 9160 | if (is_by_ref) { |
| ... | @@ -9171,10 +9171,10 @@ pub const FuncGen = struct { | ... | @@ -9171,10 +9171,10 @@ pub const FuncGen = struct { |
| 9171 | /// Assumes the optional is not pointer-like and payload has bits. | 9171 | /// Assumes the optional is not pointer-like and payload has bits. |
| 9172 | fn optPayloadHandle( | 9172 | fn optPayloadHandle( |
| 9173 | fg: *FuncGen, | 9173 | fg: *FuncGen, |
| 9174 | opt_llvm_ty: *const llvm.Type, | 9174 | opt_llvm_ty: *llvm.Type, |
| 9175 | opt_handle: *const llvm.Value, | 9175 | opt_handle: *llvm.Value, |
| 9176 | opt_ty: Type, | 9176 | opt_ty: Type, |
| 9177 | ) !*const llvm.Value { | 9177 | ) !*llvm.Value { |
| 9178 | var buf: Type.Payload.ElemType = undefined; | 9178 | var buf: Type.Payload.ElemType = undefined; |
| 9179 | const payload_ty = opt_ty.optionalChild(&buf); | 9179 | const payload_ty = opt_ty.optionalChild(&buf); |
| 9180 | | 9180 | |
| ... | @@ -9200,9 +9200,9 @@ pub const FuncGen = struct { | ... | @@ -9200,9 +9200,9 @@ pub const FuncGen = struct { |
| 9200 | fn buildOptional( | 9200 | fn buildOptional( |
| 9201 | self: *FuncGen, | 9201 | self: *FuncGen, |
| 9202 | optional_ty: Type, | 9202 | optional_ty: Type, |
| 9203 | payload: *const llvm.Value, | 9203 | payload: *llvm.Value, |
| 9204 | non_null_bit: *const llvm.Value, | 9204 | non_null_bit: *llvm.Value, |
| 9205 | ) !?*const llvm.Value { | 9205 | ) !?*llvm.Value { |
| 9206 | const optional_llvm_ty = try self.dg.lowerType(optional_ty); | 9206 | const optional_llvm_ty = try self.dg.lowerType(optional_ty); |
| 9207 | const non_null_field = self.builder.buildZExt(non_null_bit, self.dg.context.intType(8), ""); | 9207 | const non_null_field = self.builder.buildZExt(non_null_bit, self.dg.context.intType(8), ""); |
| 9208 | | 9208 | |
| ... | @@ -9233,10 +9233,10 @@ pub const FuncGen = struct { | ... | @@ -9233,10 +9233,10 @@ pub const FuncGen = struct { |
| 9233 | fn fieldPtr( | 9233 | fn fieldPtr( |
| 9234 | self: *FuncGen, | 9234 | self: *FuncGen, |
| 9235 | inst: Air.Inst.Index, | 9235 | inst: Air.Inst.Index, |
| 9236 | struct_ptr: *const llvm.Value, | 9236 | struct_ptr: *llvm.Value, |
| 9237 | struct_ptr_ty: Type, | 9237 | struct_ptr_ty: Type, |
| 9238 | field_index: u32, | 9238 | field_index: u32, |
| 9239 | ) !?*const llvm.Value { | 9239 | ) !?*llvm.Value { |
| 9240 | if (self.liveness.isUnused(inst)) return null; | 9240 | if (self.liveness.isUnused(inst)) return null; |
| 9241 | | 9241 | |
| 9242 | const target = self.dg.object.target; | 9242 | const target = self.dg.object.target; |
| ... | @@ -9268,7 +9268,7 @@ pub const FuncGen = struct { | ... | @@ -9268,7 +9268,7 @@ pub const FuncGen = struct { |
| 9268 | const ptr_as_bytes = self.builder.buildBitCast(struct_ptr, byte_llvm_ty.pointerType(0), ""); | 9268 | const ptr_as_bytes = self.builder.buildBitCast(struct_ptr, byte_llvm_ty.pointerType(0), ""); |
| 9269 | const llvm_usize = try self.dg.lowerType(Type.usize); | 9269 | const llvm_usize = try self.dg.lowerType(Type.usize); |
| 9270 | const llvm_index = llvm_usize.constInt(byte_offset, .False); | 9270 | const llvm_index = llvm_usize.constInt(byte_offset, .False); |
| 9271 | const indices: [1]*const llvm.Value = .{llvm_index}; | 9271 | const indices: [1]*llvm.Value = .{llvm_index}; |
| 9272 | const new_ptr = self.builder.buildInBoundsGEP(byte_llvm_ty, ptr_as_bytes, &indices, indices.len, ""); | 9272 | const new_ptr = self.builder.buildInBoundsGEP(byte_llvm_ty, ptr_as_bytes, &indices, indices.len, ""); |
| 9273 | return self.builder.buildBitCast(new_ptr, result_llvm_ty, ""); | 9273 | return self.builder.buildBitCast(new_ptr, result_llvm_ty, ""); |
| 9274 | }, | 9274 | }, |
| ... | @@ -9285,7 +9285,7 @@ pub const FuncGen = struct { | ... | @@ -9285,7 +9285,7 @@ pub const FuncGen = struct { |
| 9285 | // the struct. | 9285 | // the struct. |
| 9286 | const llvm_usize = try self.dg.lowerType(Type.usize); | 9286 | const llvm_usize = try self.dg.lowerType(Type.usize); |
| 9287 | const llvm_index = llvm_usize.constInt(1, .False); | 9287 | const llvm_index = llvm_usize.constInt(1, .False); |
| 9288 | const indices: [1]*const llvm.Value = .{llvm_index}; | 9288 | const indices: [1]*llvm.Value = .{llvm_index}; |
| 9289 | return self.builder.buildInBoundsGEP(struct_llvm_ty, struct_ptr, &indices, indices.len, ""); | 9289 | return self.builder.buildInBoundsGEP(struct_llvm_ty, struct_ptr, &indices, indices.len, ""); |
| 9290 | } | 9290 | } |
| 9291 | }, | 9291 | }, |
| ... | @@ -9298,9 +9298,9 @@ pub const FuncGen = struct { | ... | @@ -9298,9 +9298,9 @@ pub const FuncGen = struct { |
| 9298 | fn unionFieldPtr( | 9298 | fn unionFieldPtr( |
| 9299 | self: *FuncGen, | 9299 | self: *FuncGen, |
| 9300 | inst: Air.Inst.Index, | 9300 | inst: Air.Inst.Index, |
| 9301 | union_ptr: *const llvm.Value, | 9301 | union_ptr: *llvm.Value, |
| 9302 | union_ty: Type, | 9302 | union_ty: Type, |
| 9303 | ) !?*const llvm.Value { | 9303 | ) !?*llvm.Value { |
| 9304 | const target = self.dg.module.getTarget(); | 9304 | const target = self.dg.module.getTarget(); |
| 9305 | const layout = union_ty.unionGetLayout(target); | 9305 | const layout = union_ty.unionGetLayout(target); |
| 9306 | const result_llvm_ty = try self.dg.lowerType(self.air.typeOfIndex(inst)); | 9306 | const result_llvm_ty = try self.dg.lowerType(self.air.typeOfIndex(inst)); |
| ... | @@ -9313,7 +9313,7 @@ pub const FuncGen = struct { | ... | @@ -9313,7 +9313,7 @@ pub const FuncGen = struct { |
| 9313 | return self.builder.buildBitCast(union_field_ptr, result_llvm_ty, ""); | 9313 | return self.builder.buildBitCast(union_field_ptr, result_llvm_ty, ""); |
| 9314 | } | 9314 | } |
| 9315 | | 9315 | |
| 9316 | fn getIntrinsic(self: *FuncGen, name: []const u8, types: []const *const llvm.Type) *const llvm.Value { | 9316 | fn getIntrinsic(self: *FuncGen, name: []const u8, types: []const *llvm.Type) *llvm.Value { |
| 9317 | const id = llvm.lookupIntrinsicID(name.ptr, name.len); | 9317 | const id = llvm.lookupIntrinsicID(name.ptr, name.len); |
| 9318 | assert(id != 0); | 9318 | assert(id != 0); |
| 9319 | return self.llvmModule().getIntrinsicDeclaration(id, types.ptr, types.len); | 9319 | return self.llvmModule().getIntrinsicDeclaration(id, types.ptr, types.len); |
| ... | @@ -9322,7 +9322,7 @@ pub const FuncGen = struct { | ... | @@ -9322,7 +9322,7 @@ pub const FuncGen = struct { |
| 9322 | /// This function always performs a copy. For isByRef=true types, it creates a new | 9322 | /// This function always performs a copy. For isByRef=true types, it creates a new |
| 9323 | /// alloca and copies the value into it, then returns the alloca instruction. | 9323 | /// alloca and copies the value into it, then returns the alloca instruction. |
| 9324 | /// For isByRef=false types, it creates a load instruction and returns it. | 9324 | /// For isByRef=false types, it creates a load instruction and returns it. |
| 9325 | fn load(self: *FuncGen, ptr: *const llvm.Value, ptr_ty: Type) !?*const llvm.Value { | 9325 | fn load(self: *FuncGen, ptr: *llvm.Value, ptr_ty: Type) !?*llvm.Value { |
| 9326 | const info = ptr_ty.ptrInfo().data; | 9326 | const info = ptr_ty.ptrInfo().data; |
| 9327 | if (!info.pointee_type.hasRuntimeBitsIgnoreComptime()) return null; | 9327 | if (!info.pointee_type.hasRuntimeBitsIgnoreComptime()) return null; |
| 9328 | | 9328 | |
| ... | @@ -9396,9 +9396,9 @@ pub const FuncGen = struct { | ... | @@ -9396,9 +9396,9 @@ pub const FuncGen = struct { |
| 9396 | | 9396 | |
| 9397 | fn store( | 9397 | fn store( |
| 9398 | self: *FuncGen, | 9398 | self: *FuncGen, |
| 9399 | ptr: *const llvm.Value, | 9399 | ptr: *llvm.Value, |
| 9400 | ptr_ty: Type, | 9400 | ptr_ty: Type, |
| 9401 | elem: *const llvm.Value, | 9401 | elem: *llvm.Value, |
| 9402 | ordering: llvm.AtomicOrdering, | 9402 | ordering: llvm.AtomicOrdering, |
| 9403 | ) void { | 9403 | ) void { |
| 9404 | const info = ptr_ty.ptrInfo().data; | 9404 | const info = ptr_ty.ptrInfo().data; |
| ... | @@ -9463,7 +9463,7 @@ pub const FuncGen = struct { | ... | @@ -9463,7 +9463,7 @@ pub const FuncGen = struct { |
| 9463 | ); | 9463 | ); |
| 9464 | } | 9464 | } |
| 9465 | | 9465 | |
| 9466 | fn valgrindMarkUndef(fg: *FuncGen, ptr: *const llvm.Value, len: *const llvm.Value) void { | 9466 | fn valgrindMarkUndef(fg: *FuncGen, ptr: *llvm.Value, len: *llvm.Value) void { |
| 9467 | const VG_USERREQ__MAKE_MEM_UNDEFINED = 1296236545; | 9467 | const VG_USERREQ__MAKE_MEM_UNDEFINED = 1296236545; |
| 9468 | const target = fg.dg.module.getTarget(); | 9468 | const target = fg.dg.module.getTarget(); |
| 9469 | const usize_llvm_ty = fg.context.intType(target.cpu.arch.ptrBitWidth()); | 9469 | const usize_llvm_ty = fg.context.intType(target.cpu.arch.ptrBitWidth()); |
| ... | @@ -9475,14 +9475,14 @@ pub const FuncGen = struct { | ... | @@ -9475,14 +9475,14 @@ pub const FuncGen = struct { |
| 9475 | | 9475 | |
| 9476 | fn valgrindClientRequest( | 9476 | fn valgrindClientRequest( |
| 9477 | fg: *FuncGen, | 9477 | fg: *FuncGen, |
| 9478 | default_value: *const llvm.Value, | 9478 | default_value: *llvm.Value, |
| 9479 | request: *const llvm.Value, | 9479 | request: *llvm.Value, |
| 9480 | a1: *const llvm.Value, | 9480 | a1: *llvm.Value, |
| 9481 | a2: *const llvm.Value, | 9481 | a2: *llvm.Value, |
| 9482 | a3: *const llvm.Value, | 9482 | a3: *llvm.Value, |
| 9483 | a4: *const llvm.Value, | 9483 | a4: *llvm.Value, |
| 9484 | a5: *const llvm.Value, | 9484 | a5: *llvm.Value, |
| 9485 | ) *const llvm.Value { | 9485 | ) *llvm.Value { |
| 9486 | const target = fg.dg.module.getTarget(); | 9486 | const target = fg.dg.module.getTarget(); |
| 9487 | if (!target_util.hasValgrindSupport(target)) return default_value; | 9487 | if (!target_util.hasValgrindSupport(target)) return default_value; |
| 9488 | | 9488 | |
| ... | @@ -9498,10 +9498,10 @@ pub const FuncGen = struct { | ... | @@ -9498,10 +9498,10 @@ pub const FuncGen = struct { |
| 9498 | fg.valgrind_client_request_array = array_ptr; | 9498 | fg.valgrind_client_request_array = array_ptr; |
| 9499 | break :a array_ptr; | 9499 | break :a array_ptr; |
| 9500 | }; | 9500 | }; |
| 9501 | const array_elements = [_]*const llvm.Value{ request, a1, a2, a3, a4, a5 }; | 9501 | const array_elements = [_]*llvm.Value{ request, a1, a2, a3, a4, a5 }; |
| 9502 | const zero = usize_llvm_ty.constInt(0, .False); | 9502 | const zero = usize_llvm_ty.constInt(0, .False); |
| 9503 | for (array_elements) |elem, i| { | 9503 | for (array_elements) |elem, i| { |
| 9504 | const indexes = [_]*const llvm.Value{ | 9504 | const indexes = [_]*llvm.Value{ |
| 9505 | zero, usize_llvm_ty.constInt(@intCast(c_uint, i), .False), | 9505 | zero, usize_llvm_ty.constInt(@intCast(c_uint, i), .False), |
| 9506 | }; | 9506 | }; |
| 9507 | const elem_ptr = fg.builder.buildInBoundsGEP(array_llvm_ty, array_ptr, &indexes, indexes.len, ""); | 9507 | const elem_ptr = fg.builder.buildInBoundsGEP(array_llvm_ty, array_ptr, &indexes, indexes.len, ""); |
| ... | @@ -9518,8 +9518,8 @@ pub const FuncGen = struct { | ... | @@ -9518,8 +9518,8 @@ pub const FuncGen = struct { |
| 9518 | const asm_constraints = "={rdx},{rax},0,~{cc},~{memory}"; | 9518 | const asm_constraints = "={rdx},{rax},0,~{cc},~{memory}"; |
| 9519 | | 9519 | |
| 9520 | const array_ptr_as_usize = fg.builder.buildPtrToInt(array_ptr, usize_llvm_ty, ""); | 9520 | const array_ptr_as_usize = fg.builder.buildPtrToInt(array_ptr, usize_llvm_ty, ""); |
| 9521 | const args = [_]*const llvm.Value{ array_ptr_as_usize, default_value }; | 9521 | const args = [_]*llvm.Value{ array_ptr_as_usize, default_value }; |
| 9522 | const param_types = [_]*const llvm.Type{ usize_llvm_ty, usize_llvm_ty }; | 9522 | const param_types = [_]*llvm.Type{ usize_llvm_ty, usize_llvm_ty }; |
| 9523 | const fn_llvm_ty = llvm.functionType(usize_llvm_ty, &param_types, args.len, .False); | 9523 | const fn_llvm_ty = llvm.functionType(usize_llvm_ty, &param_types, args.len, .False); |
| 9524 | const asm_fn = llvm.getInlineAsm( | 9524 | const asm_fn = llvm.getInlineAsm( |
| 9525 | fn_llvm_ty, | 9525 | fn_llvm_ty, |
| ... | @@ -9898,7 +9898,7 @@ fn firstParamSRet(fn_info: Type.Payload.Function.Data, target: std.Target) bool | ... | @@ -9898,7 +9898,7 @@ fn firstParamSRet(fn_info: Type.Payload.Function.Data, target: std.Target) bool |
| 9898 | /// In order to support the C calling convention, some return types need to be lowered | 9898 | /// In order to support the C calling convention, some return types need to be lowered |
| 9899 | /// completely differently in the function prototype to honor the C ABI, and then | 9899 | /// completely differently in the function prototype to honor the C ABI, and then |
| 9900 | /// be effectively bitcasted to the actual return type. | 9900 | /// be effectively bitcasted to the actual return type. |
| 9901 | fn lowerFnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*const llvm.Type { | 9901 | fn lowerFnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*llvm.Type { |
| 9902 | if (!fn_info.return_type.hasRuntimeBitsIgnoreComptime()) { | 9902 | if (!fn_info.return_type.hasRuntimeBitsIgnoreComptime()) { |
| 9903 | // If the return type is an error set or an error union, then we make this | 9903 | // If the return type is an error set or an error union, then we make this |
| 9904 | // anyerror return type instead, so that it can be coerced into a function | 9904 | // anyerror return type instead, so that it can be coerced into a function |
| ... | @@ -9945,7 +9945,7 @@ fn lowerFnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*const llvm. | ... | @@ -9945,7 +9945,7 @@ fn lowerFnRetTy(dg: *DeclGen, fn_info: Type.Payload.Function.Data) !*const llvm. |
| 9945 | if (classes[0] == .memory) { | 9945 | if (classes[0] == .memory) { |
| 9946 | return dg.context.voidType(); | 9946 | return dg.context.voidType(); |
| 9947 | } | 9947 | } |
| 9948 | var llvm_types_buffer: [8]*const llvm.Type = undefined; | 9948 | var llvm_types_buffer: [8]*llvm.Type = undefined; |
| 9949 | var llvm_types_index: u32 = 0; | 9949 | var llvm_types_index: u32 = 0; |
| 9950 | for (classes) |class| { | 9950 | for (classes) |class| { |
| 9951 | switch (class) { | 9951 | switch (class) { |
| ... | @@ -10488,11 +10488,11 @@ fn compilerRtIntBits(bits: u16) u16 { | ... | @@ -10488,11 +10488,11 @@ fn compilerRtIntBits(bits: u16) u16 { |
| 10488 | } | 10488 | } |
| 10489 | | 10489 | |
| 10490 | fn buildAllocaInner( | 10490 | fn buildAllocaInner( |
| 10491 | builder: *const llvm.Builder, | 10491 | builder: *llvm.Builder, |
| 10492 | llvm_func: *const llvm.Value, | 10492 | llvm_func: *llvm.Value, |
| 10493 | di_scope_non_null: bool, | 10493 | di_scope_non_null: bool, |
| 10494 | llvm_ty: *const llvm.Type, | 10494 | llvm_ty: *llvm.Type, |
| 10495 | ) *const llvm.Value { | 10495 | ) *llvm.Value { |
| 10496 | const prev_block = builder.getInsertBlock(); | 10496 | const prev_block = builder.getInsertBlock(); |
| 10497 | const prev_debug_location = builder.getCurrentDebugLocation2(); | 10497 | const prev_debug_location = builder.getCurrentDebugLocation2(); |
| 10498 | defer { | 10498 | defer { |