| ... | @@ -238,9 +238,7 @@ pub const DeclGen = struct { | ... | @@ -238,9 +238,7 @@ pub const DeclGen = struct { |
| 238 | return try self.resolveDecl(fn_decl_index); | 238 | return try self.resolveDecl(fn_decl_index); |
| 239 | } | 239 | } |
| 240 | | 240 | |
| 241 | const result_id = self.spv.allocId(); | 241 | return try self.genConstant(ty, val, .direct); |
| 242 | try self.genConstant(result_id, ty, val, .direct); | | |
| 243 | return result_id; | | |
| 244 | } | 242 | } |
| 245 | const index = Air.refToIndex(inst).?; | 243 | const index = Air.refToIndex(inst).?; |
| 246 | return self.inst_results.get(index).?; // Assertion means instruction does not dominate usage. | 244 | return self.inst_results.get(index).?; // Assertion means instruction does not dominate usage. |
| ... | @@ -396,9 +394,15 @@ pub const DeclGen = struct { | ... | @@ -396,9 +394,15 @@ pub const DeclGen = struct { |
| 396 | return result_id; | 394 | return result_id; |
| 397 | } | 395 | } |
| 398 | | 396 | |
| | 397 | fn genConstant(self: *DeclGen, ty: Type, val: Value, repr: Repr) Error!IdRef { |
| | 398 | const result_id = self.spv.allocId(); |
| | 399 | try self.genConstantForId(result_id, ty, val, repr); |
| | 400 | return result_id; |
| | 401 | } |
| | 402 | |
| 399 | /// Generate a constant representing `val`. | 403 | /// Generate a constant representing `val`. |
| 400 | /// TODO: Deduplication? | 404 | /// TODO: Deduplication? |
| 401 | fn genConstant(self: *DeclGen, result_id: IdRef, ty: Type, val: Value, repr: Repr) Error!void { | 405 | fn genConstantForId(self: *DeclGen, result_id: IdRef, ty: Type, val: Value, repr: Repr) Error!void { |
| 402 | const target = self.getTarget(); | 406 | const target = self.getTarget(); |
| 403 | const section = &self.spv.sections.types_globals_constants; | 407 | const section = &self.spv.sections.types_globals_constants; |
| 404 | const result_ty_ref = try self.resolveType(ty, repr); | 408 | const result_ty_ref = try self.resolveType(ty, repr); |
| ... | @@ -449,8 +453,7 @@ pub const DeclGen = struct { | ... | @@ -449,8 +453,7 @@ pub const DeclGen = struct { |
| 449 | const constituents = try self.spv.gpa.alloc(IdRef, len); | 453 | const constituents = try self.spv.gpa.alloc(IdRef, len); |
| 450 | defer self.spv.gpa.free(constituents); | 454 | defer self.spv.gpa.free(constituents); |
| 451 | for (elem_vals[0..len], 0..) |elem_val, i| { | 455 | for (elem_vals[0..len], 0..) |elem_val, i| { |
| 452 | constituents[i] = self.spv.allocId(); | 456 | constituents[i] = try self.genConstant(elem_ty, elem_val, repr); |
| 453 | try self.genConstant(constituents[i], elem_ty, elem_val, repr); | | |
| 454 | } | 457 | } |
| 455 | try section.emit(self.spv.gpa, .OpSpecConstantComposite, .{ | 458 | try section.emit(self.spv.gpa, .OpSpecConstantComposite, .{ |
| 456 | .id_result_type = result_ty_id, | 459 | .id_result_type = result_ty_id, |
| ... | @@ -466,14 +469,12 @@ pub const DeclGen = struct { | ... | @@ -466,14 +469,12 @@ pub const DeclGen = struct { |
| 466 | const constituents = try self.spv.gpa.alloc(IdRef, total_len); | 469 | const constituents = try self.spv.gpa.alloc(IdRef, total_len); |
| 467 | defer self.spv.gpa.free(constituents); | 470 | defer self.spv.gpa.free(constituents); |
| 468 | | 471 | |
| 469 | const elem_val_id = self.spv.allocId(); | 472 | const elem_val_id = try self.genConstant(elem_ty, elem_val, repr); |
| 470 | try self.genConstant(elem_val_id, elem_ty, elem_val, repr); | | |
| 471 | for (constituents[0..len]) |*elem| { | 473 | for (constituents[0..len]) |*elem| { |
| 472 | elem.* = elem_val_id; | 474 | elem.* = elem_val_id; |
| 473 | } | 475 | } |
| 474 | if (ty.sentinel()) |sentinel| { | 476 | if (ty.sentinel()) |sentinel| { |
| 475 | constituents[len] = self.spv.allocId(); | 477 | constituents[len] = try self.genConstant(elem_ty, sentinel, repr); |
| 476 | try self.genConstant(constituents[len], elem_ty, sentinel, repr); | | |
| 477 | } | 478 | } |
| 478 | try section.emit(self.spv.gpa, .OpSpecConstantComposite, .{ | 479 | try section.emit(self.spv.gpa, .OpSpecConstantComposite, .{ |
| 479 | .id_result_type = result_ty_id, | 480 | .id_result_type = result_ty_id, |
| ... | @@ -517,8 +518,7 @@ pub const DeclGen = struct { | ... | @@ -517,8 +518,7 @@ pub const DeclGen = struct { |
| 517 | const elem_refs = try self.gpa.alloc(IdRef, vector_len); | 518 | const elem_refs = try self.gpa.alloc(IdRef, vector_len); |
| 518 | defer self.gpa.free(elem_refs); | 519 | defer self.gpa.free(elem_refs); |
| 519 | for (elem_refs, 0..) |*elem, i| { | 520 | for (elem_refs, 0..) |*elem, i| { |
| 520 | elem.* = self.spv.allocId(); | 521 | elem.* = try self.genConstant(elem_ty, elem_vals[i], repr); |
| 521 | try self.genConstant(elem.*, elem_ty, elem_vals[i], repr); | | |
| 522 | } | 522 | } |
| 523 | try section.emit(self.spv.gpa, .OpSpecConstantComposite, .{ | 523 | try section.emit(self.spv.gpa, .OpSpecConstantComposite, .{ |
| 524 | .id_result_type = result_ty_id, | 524 | .id_result_type = result_ty_id, |
| ... | @@ -539,17 +539,15 @@ pub const DeclGen = struct { | ... | @@ -539,17 +539,15 @@ pub const DeclGen = struct { |
| 539 | const constituents = try self.spv.gpa.alloc(IdRef, tuple.types.len); | 539 | const constituents = try self.spv.gpa.alloc(IdRef, tuple.types.len); |
| 540 | errdefer self.spv.gpa.free(constituents); | 540 | errdefer self.spv.gpa.free(constituents); |
| 541 | | 541 | |
| 542 | var member_index: usize = 0; | 542 | var member_i: usize = 0; |
| 543 | for (tuple.types, 0..) |field_ty, i| { | 543 | for (tuple.types, 0..) |field_ty, i| { |
| 544 | const field_val = tuple.values[i]; | 544 | const field_val = tuple.values[i]; |
| 545 | if (field_val.tag() != .unreachable_value or !field_ty.hasRuntimeBits()) continue; | 545 | if (field_val.tag() != .unreachable_value or !field_ty.hasRuntimeBits()) continue; |
| 546 | const member_id = self.spv.allocId(); | 546 | constituents[member_i] = try self.genConstant(field_ty, field_val, repr); |
| 547 | try self.genConstant(member_id, field_ty, field_val, repr); | 547 | member_i += 1; |
| 548 | constituents[member_index] = member_id; | | |
| 549 | member_index += 1; | | |
| 550 | } | 548 | } |
| 551 | | 549 | |
| 552 | break :blk constituents[0..member_index]; | 550 | break :blk constituents[0..member_i]; |
| 553 | } else blk: { | 551 | } else blk: { |
| 554 | const struct_ty = ty.castTag(.@"struct").?.data; | 552 | const struct_ty = ty.castTag(.@"struct").?.data; |
| 555 | | 553 | |
| ... | @@ -560,16 +558,14 @@ pub const DeclGen = struct { | ... | @@ -560,16 +558,14 @@ pub const DeclGen = struct { |
| 560 | const field_vals = val.castTag(.aggregate).?.data; | 558 | const field_vals = val.castTag(.aggregate).?.data; |
| 561 | const constituents = try self.spv.gpa.alloc(IdRef, struct_ty.fields.count()); | 559 | const constituents = try self.spv.gpa.alloc(IdRef, struct_ty.fields.count()); |
| 562 | errdefer self.spv.gpa.free(constituents); | 560 | errdefer self.spv.gpa.free(constituents); |
| 563 | var member_index: usize = 0; | 561 | var member_i: usize = 0; |
| 564 | for (struct_ty.fields.values(), 0..) |field, i| { | 562 | for (struct_ty.fields.values(), 0..) |field, i| { |
| 565 | if (field.is_comptime or !field.ty.hasRuntimeBits()) continue; | 563 | if (field.is_comptime or !field.ty.hasRuntimeBits()) continue; |
| 566 | const member_id = self.spv.allocId(); | 564 | constituents[member_i] = try self.genConstant(field.ty, field_vals[i], repr); |
| 567 | try self.genConstant(member_id, field.ty, field_vals[i], repr); | 565 | member_i += 1; |
| 568 | constituents[member_index] = member_id; | | |
| 569 | member_index += 1; | | |
| 570 | } | 566 | } |
| 571 | | 567 | |
| 572 | break :blk constituents[0..member_index]; | 568 | break :blk constituents[0..member_i]; |
| 573 | }; | 569 | }; |
| 574 | defer self.spv.gpa.free(constituents); | 570 | defer self.spv.gpa.free(constituents); |
| 575 | | 571 | |
| ... | @@ -580,20 +576,14 @@ pub const DeclGen = struct { | ... | @@ -580,20 +576,14 @@ pub const DeclGen = struct { |
| 580 | }); | 576 | }); |
| 581 | }, | 577 | }, |
| 582 | .Pointer => switch (val.tag()) { | 578 | .Pointer => switch (val.tag()) { |
| 583 | .decl_ref => { | 579 | .decl_ref_mut => try self.genDeclRef(result_ty_ref, result_id, val.castTag(.decl_ref_mut).?.data.decl_index), |
| 584 | const decl_index = val.castTag(.decl_ref).?.data; | 580 | .decl_ref => try self.genDeclRef(result_ty_ref, result_id, val.castTag(.decl_ref).?.data), |
| 585 | const decl_result_id = self.spv.allocId(); | | |
| 586 | try self.genDeclRef(decl_result_id, decl_index); | | |
| 587 | try self.variable(.global, result_id, result_ty_ref, decl_result_id); | | |
| 588 | }, | | |
| 589 | .slice => { | 581 | .slice => { |
| 590 | const slice = val.castTag(.slice).?.data; | 582 | const slice = val.castTag(.slice).?.data; |
| 591 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; | 583 | var buf: Type.SlicePtrFieldTypeBuffer = undefined; |
| 592 | | 584 | |
| 593 | const ptr_id = self.spv.allocId(); | 585 | const ptr_id = try self.genConstant(ty.slicePtrFieldType(&buf), slice.ptr, .indirect); |
| 594 | try self.genConstant(ptr_id, ty.slicePtrFieldType(&buf), slice.ptr, .indirect); | 586 | const len_id = try self.genConstant(Type.usize, slice.len, .indirect); |
| 595 | const len_id = self.spv.allocId(); | | |
| 596 | try self.genConstant(len_id, Type.usize, slice.len, .indirect); | | |
| 597 | | 587 | |
| 598 | const constituents = [_]IdRef{ ptr_id, len_id }; | 588 | const constituents = [_]IdRef{ ptr_id, len_id }; |
| 599 | try section.emit(self.spv.gpa, .OpSpecConstantComposite, .{ | 589 | try section.emit(self.spv.gpa, .OpSpecConstantComposite, .{ |
| ... | @@ -613,10 +603,11 @@ pub const DeclGen = struct { | ... | @@ -613,10 +603,11 @@ pub const DeclGen = struct { |
| 613 | } | 603 | } |
| 614 | } | 604 | } |
| 615 | | 605 | |
| 616 | fn genDeclRef(self: *DeclGen, result_id: IdRef, decl_index: Decl.Index) Error!void { | 606 | fn genDeclRef(self: *DeclGen, result_ty_ref: SpvType.Ref, result_id: IdRef, decl_index: Decl.Index) Error!void { |
| 617 | const decl = self.module.declPtr(decl_index); | 607 | const decl = self.module.declPtr(decl_index); |
| 618 | self.module.markDeclAlive(decl); | 608 | self.module.markDeclAlive(decl); |
| 619 | try self.genConstant(result_id, decl.ty, decl.val, .indirect); | 609 | const decl_id = try self.genConstant(decl.ty, decl.val, .indirect); |
| | 610 | try self.variable(.global, result_id, result_ty_ref, decl_id); |
| 620 | } | 611 | } |
| 621 | | 612 | |
| 622 | /// Turn a Zig type into a SPIR-V Type, and return its type result-id. | 613 | /// Turn a Zig type into a SPIR-V Type, and return its type result-id. |
| ... | @@ -915,7 +906,7 @@ pub const DeclGen = struct { | ... | @@ -915,7 +906,7 @@ pub const DeclGen = struct { |
| 915 | .name = fqn, | 906 | .name = fqn, |
| 916 | }); | 907 | }); |
| 917 | } else { | 908 | } else { |
| 918 | try self.genConstant(result_id, decl.ty, decl.val, .direct); | 909 | try self.genConstantForId(result_id, decl.ty, decl.val, .direct); |
| 919 | } | 910 | } |
| 920 | } | 911 | } |
| 921 | | 912 | |