| ... | ... | @@ -22,6 +22,8 @@ const Opcode = spec.Opcode; |
| 22 | 22 | const IdResult = spec.IdResult; |
| 23 | 23 | const StorageClass = spec.StorageClass; |
| 24 | 24 | |
| 25 | const InternPool = @import("../../InternPool.zig"); |
| 26 | |
| 25 | 27 | const Self = @This(); |
| 26 | 28 | |
| 27 | 29 | map: std.AutoArrayHashMapUnmanaged(void, void) = .{}, |
| ... | ... | @@ -31,6 +33,8 @@ extra: std.ArrayListUnmanaged(u32) = .{}, |
| 31 | 33 | string_bytes: std.ArrayListUnmanaged(u8) = .{}, |
| 32 | 34 | strings: std.AutoArrayHashMapUnmanaged(void, u32) = .{}, |
| 33 | 35 | |
| 36 | recursive_ptrs: std.AutoHashMapUnmanaged(Ref, void) = .{}, |
| 37 | |
| 34 | 38 | const Item = struct { |
| 35 | 39 | tag: Tag, |
| 36 | 40 | /// The result-id that this item uses. |
| ... | ... | @@ -62,18 +66,21 @@ const Tag = enum { |
| 62 | 66 | /// Function (proto)type |
| 63 | 67 | /// data is payload to FunctionType |
| 64 | 68 | type_function, |
| 65 | | /// Pointer type in the CrossWorkgroup storage class |
| 66 | | /// data is child type |
| 67 | | type_ptr_generic, |
| 68 | | /// Pointer type in the CrossWorkgroup storage class |
| 69 | | /// data is child type |
| 70 | | type_ptr_crosswgp, |
| 71 | | /// Pointer type in the Function storage class |
| 72 | | /// data is child type |
| 73 | | type_ptr_function, |
| 69 | // /// Pointer type in the CrossWorkgroup storage class |
| 70 | // /// data is child type |
| 71 | // type_ptr_generic, |
| 72 | // /// Pointer type in the CrossWorkgroup storage class |
| 73 | // /// data is child type |
| 74 | // type_ptr_crosswgp, |
| 75 | // /// Pointer type in the Function storage class |
| 76 | // /// data is child type |
| 77 | // type_ptr_function, |
| 74 | 78 | /// Simple pointer type that does not have any decorations. |
| 75 | 79 | /// data is payload to SimplePointerType |
| 76 | 80 | type_ptr_simple, |
| 81 | /// A forward declaration for a pointer. |
| 82 | /// data is ForwardPointerType |
| 83 | type_fwd_ptr, |
| 77 | 84 | /// Simple structure type that does not have any decorations. |
| 78 | 85 | /// data is payload to SimpleStructType |
| 79 | 86 | type_struct_simple, |
| ... | ... | @@ -142,6 +149,12 @@ const Tag = enum { |
| 142 | 149 | const SimplePointerType = struct { |
| 143 | 150 | storage_class: StorageClass, |
| 144 | 151 | child_type: Ref, |
| 152 | fwd: Ref, |
| 153 | }; |
| 154 | |
| 155 | const ForwardPointerType = struct { |
| 156 | storage_class: StorageClass, |
| 157 | zig_child_type: InternPool.Index, |
| 145 | 158 | }; |
| 146 | 159 | |
| 147 | 160 | /// Trailing: |
| ... | ... | @@ -163,14 +176,14 @@ const Tag = enum { |
| 163 | 176 | fn encode(value: f64) Float64 { |
| 164 | 177 | const bits = @as(u64, @bitCast(value)); |
| 165 | 178 | return .{ |
| 166 | | .low = @as(u32, @truncate(bits)), |
| 167 | | .high = @as(u32, @truncate(bits >> 32)), |
| 179 | .low = @truncate(bits), |
| 180 | .high = @truncate(bits >> 32), |
| 168 | 181 | }; |
| 169 | 182 | } |
| 170 | 183 | |
| 171 | 184 | fn decode(self: Float64) f64 { |
| 172 | 185 | const bits = @as(u64, self.low) | (@as(u64, self.high) << 32); |
| 173 | | return @as(f64, @bitCast(bits)); |
| 186 | return @bitCast(bits); |
| 174 | 187 | } |
| 175 | 188 | }; |
| 176 | 189 | |
| ... | ... | @@ -192,8 +205,8 @@ const Tag = enum { |
| 192 | 205 | fn encode(ty: Ref, value: u64) Int64 { |
| 193 | 206 | return .{ |
| 194 | 207 | .ty = ty, |
| 195 | | .low = @as(u32, @truncate(value)), |
| 196 | | .high = @as(u32, @truncate(value >> 32)), |
| 208 | .low = @truncate(value), |
| 209 | .high = @truncate(value >> 32), |
| 197 | 210 | }; |
| 198 | 211 | } |
| 199 | 212 | |
| ... | ... | @@ -210,8 +223,8 @@ const Tag = enum { |
| 210 | 223 | fn encode(ty: Ref, value: i64) Int64 { |
| 211 | 224 | return .{ |
| 212 | 225 | .ty = ty, |
| 213 | | .low = @as(u32, @truncate(@as(u64, @bitCast(value)))), |
| 214 | | .high = @as(u32, @truncate(@as(u64, @bitCast(value)) >> 32)), |
| 226 | .low = @truncate(@as(u64, @bitCast(value))), |
| 227 | .high = @truncate(@as(u64, @bitCast(value)) >> 32), |
| 215 | 228 | }; |
| 216 | 229 | } |
| 217 | 230 | |
| ... | ... | @@ -237,6 +250,7 @@ pub const Key = union(enum) { |
| 237 | 250 | array_type: ArrayType, |
| 238 | 251 | function_type: FunctionType, |
| 239 | 252 | ptr_type: PointerType, |
| 253 | fwd_ptr_type: ForwardPointerType, |
| 240 | 254 | struct_type: StructType, |
| 241 | 255 | opaque_type: OpaqueType, |
| 242 | 256 | |
| ... | ... | @@ -273,12 +287,18 @@ pub const Key = union(enum) { |
| 273 | 287 | pub const PointerType = struct { |
| 274 | 288 | storage_class: StorageClass, |
| 275 | 289 | child_type: Ref, |
| 290 | fwd: Ref, |
| 276 | 291 | // TODO: Decorations: |
| 277 | 292 | // - Alignment |
| 278 | 293 | // - ArrayStride, |
| 279 | 294 | // - MaxByteOffset, |
| 280 | 295 | }; |
| 281 | 296 | |
| 297 | pub const ForwardPointerType = struct { |
| 298 | zig_child_type: InternPool.Index, |
| 299 | storage_class: StorageClass, |
| 300 | }; |
| 301 | |
| 282 | 302 | pub const StructType = struct { |
| 283 | 303 | // TODO: Decorations. |
| 284 | 304 | /// The name of the structure. Can be `.none`. |
| ... | ... | @@ -313,21 +333,21 @@ pub const Key = union(enum) { |
| 313 | 333 | /// Turns this value into the corresponding 32-bit literal, 2s complement signed. |
| 314 | 334 | fn toBits32(self: Int) u32 { |
| 315 | 335 | return switch (self.value) { |
| 316 | | .uint64 => |val| @as(u32, @intCast(val)), |
| 317 | | .int64 => |val| if (val < 0) @as(u32, @bitCast(@as(i32, @intCast(val)))) else @as(u32, @intCast(val)), |
| 336 | .uint64 => |val| @intCast(val), |
| 337 | .int64 => |val| if (val < 0) @bitCast(@as(i32, @intCast(val))) else @intCast(val), |
| 318 | 338 | }; |
| 319 | 339 | } |
| 320 | 340 | |
| 321 | 341 | fn toBits64(self: Int) u64 { |
| 322 | 342 | return switch (self.value) { |
| 323 | 343 | .uint64 => |val| val, |
| 324 | | .int64 => |val| @as(u64, @bitCast(val)), |
| 344 | .int64 => |val| @bitCast(val), |
| 325 | 345 | }; |
| 326 | 346 | } |
| 327 | 347 | |
| 328 | 348 | fn to(self: Int, comptime T: type) T { |
| 329 | 349 | return switch (self.value) { |
| 330 | | inline else => |val| @as(T, @intCast(val)), |
| 350 | inline else => |val| @intCast(val), |
| 331 | 351 | }; |
| 332 | 352 | } |
| 333 | 353 | }; |
| ... | ... | @@ -387,7 +407,7 @@ pub const Key = union(enum) { |
| 387 | 407 | }, |
| 388 | 408 | inline else => |key| std.hash.autoHash(&hasher, key), |
| 389 | 409 | } |
| 390 | | return @as(u32, @truncate(hasher.final())); |
| 410 | return @truncate(hasher.final()); |
| 391 | 411 | } |
| 392 | 412 | |
| 393 | 413 | fn eql(a: Key, b: Key) bool { |
| ... | ... | @@ -419,7 +439,7 @@ pub const Key = union(enum) { |
| 419 | 439 | |
| 420 | 440 | pub fn eql(ctx: @This(), a: Key, b_void: void, b_index: usize) bool { |
| 421 | 441 | _ = b_void; |
| 422 | | return ctx.self.lookup(@as(Ref, @enumFromInt(b_index))).eql(a); |
| 442 | return ctx.self.lookup(@enumFromInt(b_index)).eql(a); |
| 423 | 443 | } |
| 424 | 444 | |
| 425 | 445 | pub fn hash(ctx: @This(), a: Key) u32 { |
| ... | ... | @@ -450,6 +470,7 @@ pub fn deinit(self: *Self, spv: *const Module) void { |
| 450 | 470 | self.extra.deinit(spv.gpa); |
| 451 | 471 | self.string_bytes.deinit(spv.gpa); |
| 452 | 472 | self.strings.deinit(spv.gpa); |
| 473 | self.recursive_ptrs.deinit(spv.gpa); |
| 453 | 474 | } |
| 454 | 475 | |
| 455 | 476 | /// Actually materialize the database into spir-v instructions. |
| ... | ... | @@ -460,7 +481,7 @@ pub fn materialize(self: *const Self, spv: *Module) !Section { |
| 460 | 481 | var section = Section{}; |
| 461 | 482 | errdefer section.deinit(spv.gpa); |
| 462 | 483 | for (self.items.items(.result_id), 0..) |result_id, index| { |
| 463 | | try self.emit(spv, result_id, @as(Ref, @enumFromInt(index)), &section); |
| 484 | try self.emit(spv, result_id, @enumFromInt(index), &section); |
| 464 | 485 | } |
| 465 | 486 | return section; |
| 466 | 487 | } |
| ... | ... | @@ -538,6 +559,15 @@ fn emit( |
| 538 | 559 | }); |
| 539 | 560 | // TODO: Decorations? |
| 540 | 561 | }, |
| 562 | .fwd_ptr_type => |fwd| { |
| 563 | // Only emit the OpTypeForwardPointer if its actually required. |
| 564 | if (self.recursive_ptrs.contains(ref)) { |
| 565 | try section.emit(spv.gpa, .OpTypeForwardPointer, .{ |
| 566 | .pointer_type = result_id, |
| 567 | .storage_class = fwd.storage_class, |
| 568 | }); |
| 569 | } |
| 570 | }, |
| 541 | 571 | .struct_type => |struct_type| { |
| 542 | 572 | try section.emitRaw(spv.gpa, .OpTypeStruct, 1 + struct_type.member_types.len); |
| 543 | 573 | section.writeOperand(IdResult, result_id); |
| ... | ... | @@ -549,7 +579,7 @@ fn emit( |
| 549 | 579 | } |
| 550 | 580 | for (struct_type.memberNames(), 0..) |member_name, i| { |
| 551 | 581 | if (self.getString(member_name)) |name| { |
| 552 | | try spv.memberDebugName(result_id, @as(u32, @intCast(i)), name); |
| 582 | try spv.memberDebugName(result_id, @intCast(i), name); |
| 553 | 583 | } |
| 554 | 584 | } |
| 555 | 585 | // TODO: Decorations? |
| ... | ... | @@ -625,13 +655,12 @@ pub fn resolve(self: *Self, spv: *Module, key: Key) !Ref { |
| 625 | 655 | const adapter: Key.Adapter = .{ .self = self }; |
| 626 | 656 | const entry = try self.map.getOrPutAdapted(spv.gpa, key, adapter); |
| 627 | 657 | if (entry.found_existing) { |
| 628 | | return @as(Ref, @enumFromInt(entry.index)); |
| 658 | return @enumFromInt(entry.index); |
| 629 | 659 | } |
| 630 | | const result_id = spv.allocId(); |
| 631 | 660 | const item: Item = switch (key) { |
| 632 | 661 | inline .void_type, .bool_type => .{ |
| 633 | 662 | .tag = .type_simple, |
| 634 | | .result_id = result_id, |
| 663 | .result_id = spv.allocId(), |
| 635 | 664 | .data = @intFromEnum(key.toSimpleType()), |
| 636 | 665 | }, |
| 637 | 666 | .int_type => |int| blk: { |
| ... | ... | @@ -641,87 +670,104 @@ pub fn resolve(self: *Self, spv: *Module, key: Key) !Ref { |
| 641 | 670 | }; |
| 642 | 671 | break :blk .{ |
| 643 | 672 | .tag = t, |
| 644 | | .result_id = result_id, |
| 673 | .result_id = spv.allocId(), |
| 645 | 674 | .data = int.bits, |
| 646 | 675 | }; |
| 647 | 676 | }, |
| 648 | 677 | .float_type => |float| .{ |
| 649 | 678 | .tag = .type_float, |
| 650 | | .result_id = result_id, |
| 679 | .result_id = spv.allocId(), |
| 651 | 680 | .data = float.bits, |
| 652 | 681 | }, |
| 653 | 682 | .vector_type => |vector| .{ |
| 654 | 683 | .tag = .type_vector, |
| 655 | | .result_id = result_id, |
| 684 | .result_id = spv.allocId(), |
| 656 | 685 | .data = try self.addExtra(spv, vector), |
| 657 | 686 | }, |
| 658 | 687 | .array_type => |array| .{ |
| 659 | 688 | .tag = .type_array, |
| 660 | | .result_id = result_id, |
| 689 | .result_id = spv.allocId(), |
| 661 | 690 | .data = try self.addExtra(spv, array), |
| 662 | 691 | }, |
| 663 | 692 | .function_type => |function| blk: { |
| 664 | 693 | const extra = try self.addExtra(spv, Tag.FunctionType{ |
| 665 | | .param_len = @as(u32, @intCast(function.parameters.len)), |
| 694 | .param_len = @intCast(function.parameters.len), |
| 666 | 695 | .return_type = function.return_type, |
| 667 | 696 | }); |
| 668 | | try self.extra.appendSlice(spv.gpa, @as([]const u32, @ptrCast(function.parameters))); |
| 697 | try self.extra.appendSlice(spv.gpa, @ptrCast(function.parameters)); |
| 669 | 698 | break :blk .{ |
| 670 | 699 | .tag = .type_function, |
| 671 | | .result_id = result_id, |
| 700 | .result_id = spv.allocId(), |
| 672 | 701 | .data = extra, |
| 673 | 702 | }; |
| 674 | 703 | }, |
| 675 | | .ptr_type => |ptr| switch (ptr.storage_class) { |
| 676 | | .Generic => Item{ |
| 677 | | .tag = .type_ptr_generic, |
| 678 | | .result_id = result_id, |
| 679 | | .data = @intFromEnum(ptr.child_type), |
| 680 | | }, |
| 681 | | .CrossWorkgroup => Item{ |
| 682 | | .tag = .type_ptr_crosswgp, |
| 683 | | .result_id = result_id, |
| 684 | | .data = @intFromEnum(ptr.child_type), |
| 685 | | }, |
| 686 | | .Function => Item{ |
| 687 | | .tag = .type_ptr_function, |
| 688 | | .result_id = result_id, |
| 689 | | .data = @intFromEnum(ptr.child_type), |
| 690 | | }, |
| 691 | | else => |storage_class| Item{ |
| 692 | | .tag = .type_ptr_simple, |
| 693 | | .result_id = result_id, |
| 694 | | .data = try self.addExtra(spv, Tag.SimplePointerType{ |
| 695 | | .storage_class = storage_class, |
| 696 | | .child_type = ptr.child_type, |
| 697 | | }), |
| 698 | | }, |
| 704 | // .ptr_type => |ptr| switch (ptr.storage_class) { |
| 705 | // .Generic => Item{ |
| 706 | // .tag = .type_ptr_generic, |
| 707 | // .result_id = spv.allocId(), |
| 708 | // .data = @intFromEnum(ptr.child_type), |
| 709 | // }, |
| 710 | // .CrossWorkgroup => Item{ |
| 711 | // .tag = .type_ptr_crosswgp, |
| 712 | // .result_id = spv.allocId(), |
| 713 | // .data = @intFromEnum(ptr.child_type), |
| 714 | // }, |
| 715 | // .Function => Item{ |
| 716 | // .tag = .type_ptr_function, |
| 717 | // .result_id = spv.allocId(), |
| 718 | // .data = @intFromEnum(ptr.child_type), |
| 719 | // }, |
| 720 | // else => |storage_class| Item{ |
| 721 | // .tag = .type_ptr_simple, |
| 722 | // .result_id = spv.allocId(), |
| 723 | // .data = try self.addExtra(spv, Tag.SimplePointerType{ |
| 724 | // .storage_class = storage_class, |
| 725 | // .child_type = ptr.child_type, |
| 726 | // }), |
| 727 | // }, |
| 728 | // }, |
| 729 | .ptr_type => |ptr| Item{ |
| 730 | .tag = .type_ptr_simple, |
| 731 | .result_id = self.resultId(ptr.fwd), |
| 732 | .data = try self.addExtra(spv, Tag.SimplePointerType{ |
| 733 | .storage_class = ptr.storage_class, |
| 734 | .child_type = ptr.child_type, |
| 735 | .fwd = ptr.fwd, |
| 736 | }), |
| 737 | }, |
| 738 | .fwd_ptr_type => |fwd| Item{ |
| 739 | .tag = .type_fwd_ptr, |
| 740 | .result_id = spv.allocId(), |
| 741 | .data = try self.addExtra(spv, Tag.ForwardPointerType{ |
| 742 | .zig_child_type = fwd.zig_child_type, |
| 743 | .storage_class = fwd.storage_class, |
| 744 | }), |
| 699 | 745 | }, |
| 700 | 746 | .struct_type => |struct_type| blk: { |
| 701 | 747 | const extra = try self.addExtra(spv, Tag.SimpleStructType{ |
| 702 | 748 | .name = struct_type.name, |
| 703 | | .members_len = @as(u32, @intCast(struct_type.member_types.len)), |
| 749 | .members_len = @intCast(struct_type.member_types.len), |
| 704 | 750 | }); |
| 705 | | try self.extra.appendSlice(spv.gpa, @as([]const u32, @ptrCast(struct_type.member_types))); |
| 751 | try self.extra.appendSlice(spv.gpa, @ptrCast(struct_type.member_types)); |
| 706 | 752 | |
| 707 | 753 | if (struct_type.member_names) |member_names| { |
| 708 | | try self.extra.appendSlice(spv.gpa, @as([]const u32, @ptrCast(member_names))); |
| 754 | try self.extra.appendSlice(spv.gpa, @ptrCast(member_names)); |
| 709 | 755 | break :blk Item{ |
| 710 | 756 | .tag = .type_struct_simple_with_member_names, |
| 711 | | .result_id = result_id, |
| 757 | .result_id = spv.allocId(), |
| 712 | 758 | .data = extra, |
| 713 | 759 | }; |
| 714 | 760 | } else { |
| 715 | 761 | break :blk Item{ |
| 716 | 762 | .tag = .type_struct_simple, |
| 717 | | .result_id = result_id, |
| 763 | .result_id = spv.allocId(), |
| 718 | 764 | .data = extra, |
| 719 | 765 | }; |
| 720 | 766 | } |
| 721 | 767 | }, |
| 722 | 768 | .opaque_type => |opaque_type| Item{ |
| 723 | 769 | .tag = .type_opaque, |
| 724 | | .result_id = result_id, |
| 770 | .result_id = spv.allocId(), |
| 725 | 771 | .data = @intFromEnum(opaque_type.name), |
| 726 | 772 | }, |
| 727 | 773 | .int => |int| blk: { |
| ... | ... | @@ -729,13 +775,13 @@ pub fn resolve(self: *Self, spv: *Module, key: Key) !Ref { |
| 729 | 775 | if (int_type.signedness == .unsigned and int_type.bits == 8) { |
| 730 | 776 | break :blk .{ |
| 731 | 777 | .tag = .uint8, |
| 732 | | .result_id = result_id, |
| 778 | .result_id = spv.allocId(), |
| 733 | 779 | .data = int.to(u8), |
| 734 | 780 | }; |
| 735 | 781 | } else if (int_type.signedness == .unsigned and int_type.bits == 32) { |
| 736 | 782 | break :blk .{ |
| 737 | 783 | .tag = .uint32, |
| 738 | | .result_id = result_id, |
| 784 | .result_id = spv.allocId(), |
| 739 | 785 | .data = int.to(u32), |
| 740 | 786 | }; |
| 741 | 787 | } |
| ... | ... | @@ -745,32 +791,32 @@ pub fn resolve(self: *Self, spv: *Module, key: Key) !Ref { |
| 745 | 791 | if (val >= 0 and val <= std.math.maxInt(u32)) { |
| 746 | 792 | break :blk .{ |
| 747 | 793 | .tag = .uint_small, |
| 748 | | .result_id = result_id, |
| 794 | .result_id = spv.allocId(), |
| 749 | 795 | .data = try self.addExtra(spv, Tag.UInt32{ |
| 750 | 796 | .ty = int.ty, |
| 751 | | .value = @as(u32, @intCast(val)), |
| 797 | .value = @intCast(val), |
| 752 | 798 | }), |
| 753 | 799 | }; |
| 754 | 800 | } else if (val >= std.math.minInt(i32) and val <= std.math.maxInt(i32)) { |
| 755 | 801 | break :blk .{ |
| 756 | 802 | .tag = .int_small, |
| 757 | | .result_id = result_id, |
| 803 | .result_id = spv.allocId(), |
| 758 | 804 | .data = try self.addExtra(spv, Tag.Int32{ |
| 759 | 805 | .ty = int.ty, |
| 760 | | .value = @as(i32, @intCast(val)), |
| 806 | .value = @intCast(val), |
| 761 | 807 | }), |
| 762 | 808 | }; |
| 763 | 809 | } else if (val < 0) { |
| 764 | 810 | break :blk .{ |
| 765 | 811 | .tag = .int_large, |
| 766 | | .result_id = result_id, |
| 767 | | .data = try self.addExtra(spv, Tag.Int64.encode(int.ty, @as(i64, @intCast(val)))), |
| 812 | .result_id = spv.allocId(), |
| 813 | .data = try self.addExtra(spv, Tag.Int64.encode(int.ty, @intCast(val))), |
| 768 | 814 | }; |
| 769 | 815 | } else { |
| 770 | 816 | break :blk .{ |
| 771 | 817 | .tag = .uint_large, |
| 772 | | .result_id = result_id, |
| 773 | | .data = try self.addExtra(spv, Tag.UInt64.encode(int.ty, @as(u64, @intCast(val)))), |
| 818 | .result_id = spv.allocId(), |
| 819 | .data = try self.addExtra(spv, Tag.UInt64.encode(int.ty, @intCast(val))), |
| 774 | 820 | }; |
| 775 | 821 | } |
| 776 | 822 | }, |
| ... | ... | @@ -779,29 +825,29 @@ pub fn resolve(self: *Self, spv: *Module, key: Key) !Ref { |
| 779 | 825 | .float => |float| switch (self.lookup(float.ty).float_type.bits) { |
| 780 | 826 | 16 => .{ |
| 781 | 827 | .tag = .float16, |
| 782 | | .result_id = result_id, |
| 828 | .result_id = spv.allocId(), |
| 783 | 829 | .data = @as(u16, @bitCast(float.value.float16)), |
| 784 | 830 | }, |
| 785 | 831 | 32 => .{ |
| 786 | 832 | .tag = .float32, |
| 787 | | .result_id = result_id, |
| 833 | .result_id = spv.allocId(), |
| 788 | 834 | .data = @as(u32, @bitCast(float.value.float32)), |
| 789 | 835 | }, |
| 790 | 836 | 64 => .{ |
| 791 | 837 | .tag = .float64, |
| 792 | | .result_id = result_id, |
| 838 | .result_id = spv.allocId(), |
| 793 | 839 | .data = try self.addExtra(spv, Tag.Float64.encode(float.value.float64)), |
| 794 | 840 | }, |
| 795 | 841 | else => unreachable, |
| 796 | 842 | }, |
| 797 | 843 | .undef => |undef| .{ |
| 798 | 844 | .tag = .undef, |
| 799 | | .result_id = result_id, |
| 845 | .result_id = spv.allocId(), |
| 800 | 846 | .data = @intFromEnum(undef.ty), |
| 801 | 847 | }, |
| 802 | 848 | .null => |null_info| .{ |
| 803 | 849 | .tag = .null, |
| 804 | | .result_id = result_id, |
| 850 | .result_id = spv.allocId(), |
| 805 | 851 | .data = @intFromEnum(null_info.ty), |
| 806 | 852 | }, |
| 807 | 853 | .bool => |bool_info| .{ |
| ... | ... | @@ -809,13 +855,13 @@ pub fn resolve(self: *Self, spv: *Module, key: Key) !Ref { |
| 809 | 855 | true => Tag.bool_true, |
| 810 | 856 | false => Tag.bool_false, |
| 811 | 857 | }, |
| 812 | | .result_id = result_id, |
| 858 | .result_id = spv.allocId(), |
| 813 | 859 | .data = @intFromEnum(bool_info.ty), |
| 814 | 860 | }, |
| 815 | 861 | }; |
| 816 | 862 | try self.items.append(spv.gpa, item); |
| 817 | 863 | |
| 818 | | return @as(Ref, @enumFromInt(entry.index)); |
| 864 | return @enumFromInt(entry.index); |
| 819 | 865 | } |
| 820 | 866 | |
| 821 | 867 | /// Turn a Ref back into a Key. |
| ... | ... | @@ -830,14 +876,14 @@ pub fn lookup(self: *const Self, ref: Ref) Key { |
| 830 | 876 | }, |
| 831 | 877 | .type_int_signed => .{ .int_type = .{ |
| 832 | 878 | .signedness = .signed, |
| 833 | | .bits = @as(u16, @intCast(data)), |
| 879 | .bits = @intCast(data), |
| 834 | 880 | } }, |
| 835 | 881 | .type_int_unsigned => .{ .int_type = .{ |
| 836 | 882 | .signedness = .unsigned, |
| 837 | | .bits = @as(u16, @intCast(data)), |
| 883 | .bits = @intCast(data), |
| 838 | 884 | } }, |
| 839 | 885 | .type_float => .{ .float_type = .{ |
| 840 | | .bits = @as(u16, @intCast(data)), |
| 886 | .bits = @intCast(data), |
| 841 | 887 | } }, |
| 842 | 888 | .type_vector => .{ .vector_type = self.extraData(Tag.VectorType, data) }, |
| 843 | 889 | .type_array => .{ .array_type = self.extraData(Tag.ArrayType, data) }, |
| ... | ... | @@ -846,40 +892,50 @@ pub fn lookup(self: *const Self, ref: Ref) Key { |
| 846 | 892 | return .{ |
| 847 | 893 | .function_type = .{ |
| 848 | 894 | .return_type = payload.data.return_type, |
| 849 | | .parameters = @as([]const Ref, @ptrCast(self.extra.items[payload.trail..][0..payload.data.param_len])), |
| 895 | .parameters = @ptrCast(self.extra.items[payload.trail..][0..payload.data.param_len]), |
| 850 | 896 | }, |
| 851 | 897 | }; |
| 852 | 898 | }, |
| 853 | | .type_ptr_generic => .{ |
| 854 | | .ptr_type = .{ |
| 855 | | .storage_class = .Generic, |
| 856 | | .child_type = @as(Ref, @enumFromInt(data)), |
| 857 | | }, |
| 858 | | }, |
| 859 | | .type_ptr_crosswgp => .{ |
| 860 | | .ptr_type = .{ |
| 861 | | .storage_class = .CrossWorkgroup, |
| 862 | | .child_type = @as(Ref, @enumFromInt(data)), |
| 863 | | }, |
| 864 | | }, |
| 865 | | .type_ptr_function => .{ |
| 866 | | .ptr_type = .{ |
| 867 | | .storage_class = .Function, |
| 868 | | .child_type = @as(Ref, @enumFromInt(data)), |
| 869 | | }, |
| 870 | | }, |
| 899 | // .type_ptr_generic => .{ |
| 900 | // .ptr_type = .{ |
| 901 | // .storage_class = .Generic, |
| 902 | // .child_type = @enumFromInt(data), |
| 903 | // }, |
| 904 | // }, |
| 905 | // .type_ptr_crosswgp => .{ |
| 906 | // .ptr_type = .{ |
| 907 | // .storage_class = .CrossWorkgroup, |
| 908 | // .child_type = @enumFromInt(data), |
| 909 | // }, |
| 910 | // }, |
| 911 | // .type_ptr_function => .{ |
| 912 | // .ptr_type = .{ |
| 913 | // .storage_class = .Function, |
| 914 | // .child_type = @enumFromInt(data), |
| 915 | // }, |
| 916 | // }, |
| 871 | 917 | .type_ptr_simple => { |
| 872 | 918 | const payload = self.extraData(Tag.SimplePointerType, data); |
| 873 | 919 | return .{ |
| 874 | 920 | .ptr_type = .{ |
| 875 | 921 | .storage_class = payload.storage_class, |
| 876 | 922 | .child_type = payload.child_type, |
| 923 | .fwd = payload.fwd, |
| 924 | }, |
| 925 | }; |
| 926 | }, |
| 927 | .type_fwd_ptr => { |
| 928 | const payload = self.extraData(Tag.ForwardPointerType, data); |
| 929 | return .{ |
| 930 | .fwd_ptr_type = .{ |
| 931 | .zig_child_type = payload.zig_child_type, |
| 932 | .storage_class = payload.storage_class, |
| 877 | 933 | }, |
| 878 | 934 | }; |
| 879 | 935 | }, |
| 880 | 936 | .type_struct_simple => { |
| 881 | 937 | const payload = self.extraDataTrail(Tag.SimpleStructType, data); |
| 882 | | const member_types = @as([]const Ref, @ptrCast(self.extra.items[payload.trail..][0..payload.data.members_len])); |
| 938 | const member_types: []const Ref = @ptrCast(self.extra.items[payload.trail..][0..payload.data.members_len]); |
| 883 | 939 | return .{ |
| 884 | 940 | .struct_type = .{ |
| 885 | 941 | .name = payload.data.name, |
| ... | ... | @@ -891,8 +947,8 @@ pub fn lookup(self: *const Self, ref: Ref) Key { |
| 891 | 947 | .type_struct_simple_with_member_names => { |
| 892 | 948 | const payload = self.extraDataTrail(Tag.SimpleStructType, data); |
| 893 | 949 | const trailing = self.extra.items[payload.trail..]; |
| 894 | | const member_types = @as([]const Ref, @ptrCast(trailing[0..payload.data.members_len])); |
| 895 | | const member_names = @as([]const String, @ptrCast(trailing[payload.data.members_len..][0..payload.data.members_len])); |
| 950 | const member_types: []const Ref = @ptrCast(trailing[0..payload.data.members_len]); |
| 951 | const member_names: []const String = @ptrCast(trailing[payload.data.members_len..][0..payload.data.members_len]); |
| 896 | 952 | return .{ |
| 897 | 953 | .struct_type = .{ |
| 898 | 954 | .name = payload.data.name, |
| ... | ... | @@ -903,16 +959,16 @@ pub fn lookup(self: *const Self, ref: Ref) Key { |
| 903 | 959 | }, |
| 904 | 960 | .type_opaque => .{ |
| 905 | 961 | .opaque_type = .{ |
| 906 | | .name = @as(String, @enumFromInt(data)), |
| 962 | .name = @enumFromInt(data), |
| 907 | 963 | }, |
| 908 | 964 | }, |
| 909 | 965 | .float16 => .{ .float = .{ |
| 910 | 966 | .ty = self.get(.{ .float_type = .{ .bits = 16 } }), |
| 911 | | .value = .{ .float16 = @as(f16, @bitCast(@as(u16, @intCast(data)))) }, |
| 967 | .value = .{ .float16 = @bitCast(@as(u16, @intCast(data))) }, |
| 912 | 968 | } }, |
| 913 | 969 | .float32 => .{ .float = .{ |
| 914 | 970 | .ty = self.get(.{ .float_type = .{ .bits = 32 } }), |
| 915 | | .value = .{ .float32 = @as(f32, @bitCast(data)) }, |
| 971 | .value = .{ .float32 = @bitCast(data) }, |
| 916 | 972 | } }, |
| 917 | 973 | .float64 => .{ .float = .{ |
| 918 | 974 | .ty = self.get(.{ .float_type = .{ .bits = 64 } }), |
| ... | ... | @@ -955,17 +1011,17 @@ pub fn lookup(self: *const Self, ref: Ref) Key { |
| 955 | 1011 | } }; |
| 956 | 1012 | }, |
| 957 | 1013 | .undef => .{ .undef = .{ |
| 958 | | .ty = @as(Ref, @enumFromInt(data)), |
| 1014 | .ty = @enumFromInt(data), |
| 959 | 1015 | } }, |
| 960 | 1016 | .null => .{ .null = .{ |
| 961 | | .ty = @as(Ref, @enumFromInt(data)), |
| 1017 | .ty = @enumFromInt(data), |
| 962 | 1018 | } }, |
| 963 | 1019 | .bool_true => .{ .bool = .{ |
| 964 | | .ty = @as(Ref, @enumFromInt(data)), |
| 1020 | .ty = @enumFromInt(data), |
| 965 | 1021 | .value = true, |
| 966 | 1022 | } }, |
| 967 | 1023 | .bool_false => .{ .bool = .{ |
| 968 | | .ty = @as(Ref, @enumFromInt(data)), |
| 1024 | .ty = @enumFromInt(data), |
| 969 | 1025 | .value = false, |
| 970 | 1026 | } }, |
| 971 | 1027 | }; |
| ... | ... | @@ -981,7 +1037,7 @@ pub fn resultId(self: Self, ref: Ref) IdResult { |
| 981 | 1037 | fn get(self: *const Self, key: Key) Ref { |
| 982 | 1038 | const adapter: Key.Adapter = .{ .self = self }; |
| 983 | 1039 | const index = self.map.getIndexAdapted(key, adapter).?; |
| 984 | | return @as(Ref, @enumFromInt(index)); |
| 1040 | return @enumFromInt(index); |
| 985 | 1041 | } |
| 986 | 1042 | |
| 987 | 1043 | fn addExtra(self: *Self, spv: *Module, extra: anytype) !u32 { |
| ... | ... | @@ -991,15 +1047,16 @@ fn addExtra(self: *Self, spv: *Module, extra: anytype) !u32 { |
| 991 | 1047 | } |
| 992 | 1048 | |
| 993 | 1049 | fn addExtraAssumeCapacity(self: *Self, extra: anytype) !u32 { |
| 994 | | const payload_offset = @as(u32, @intCast(self.extra.items.len)); |
| 1050 | const payload_offset: u32 = @intCast(self.extra.items.len); |
| 995 | 1051 | inline for (@typeInfo(@TypeOf(extra)).Struct.fields) |field| { |
| 996 | 1052 | const field_val = @field(extra, field.name); |
| 997 | | const word = switch (field.type) { |
| 1053 | const word: u32 = switch (field.type) { |
| 998 | 1054 | u32 => field_val, |
| 999 | | i32 => @as(u32, @bitCast(field_val)), |
| 1055 | i32 => @bitCast(field_val), |
| 1000 | 1056 | Ref => @intFromEnum(field_val), |
| 1001 | 1057 | StorageClass => @intFromEnum(field_val), |
| 1002 | 1058 | String => @intFromEnum(field_val), |
| 1059 | InternPool.Index => @intFromEnum(field_val), |
| 1003 | 1060 | else => @compileError("Invalid type: " ++ @typeName(field.type)), |
| 1004 | 1061 | }; |
| 1005 | 1062 | self.extra.appendAssumeCapacity(word); |
| ... | ... | @@ -1018,10 +1075,11 @@ fn extraDataTrail(self: Self, comptime T: type, offset: u32) struct { data: T, t |
| 1018 | 1075 | const word = self.extra.items[offset + i]; |
| 1019 | 1076 | @field(result, field.name) = switch (field.type) { |
| 1020 | 1077 | u32 => word, |
| 1021 | | i32 => @as(i32, @bitCast(word)), |
| 1022 | | Ref => @as(Ref, @enumFromInt(word)), |
| 1023 | | StorageClass => @as(StorageClass, @enumFromInt(word)), |
| 1024 | | String => @as(String, @enumFromInt(word)), |
| 1078 | i32 => @bitCast(word), |
| 1079 | Ref => @enumFromInt(word), |
| 1080 | StorageClass => @enumFromInt(word), |
| 1081 | String => @enumFromInt(word), |
| 1082 | InternPool.Index => @enumFromInt(word), |
| 1025 | 1083 | else => @compileError("Invalid type: " ++ @typeName(field.type)), |
| 1026 | 1084 | }; |
| 1027 | 1085 | } |
| ... | ... | @@ -1049,7 +1107,7 @@ pub const String = enum(u32) { |
| 1049 | 1107 | _ = ctx; |
| 1050 | 1108 | var hasher = std.hash.Wyhash.init(0); |
| 1051 | 1109 | hasher.update(a); |
| 1052 | | return @as(u32, @truncate(hasher.final())); |
| 1110 | return @truncate(hasher.final()); |
| 1053 | 1111 | } |
| 1054 | 1112 | }; |
| 1055 | 1113 | }; |
| ... | ... | @@ -1064,10 +1122,10 @@ pub fn addString(self: *Self, spv: *Module, str: []const u8) !String { |
| 1064 | 1122 | try self.string_bytes.ensureUnusedCapacity(spv.gpa, 1 + str.len); |
| 1065 | 1123 | self.string_bytes.appendSliceAssumeCapacity(str); |
| 1066 | 1124 | self.string_bytes.appendAssumeCapacity(0); |
| 1067 | | entry.value_ptr.* = @as(u32, @intCast(offset)); |
| 1125 | entry.value_ptr.* = @intCast(offset); |
| 1068 | 1126 | } |
| 1069 | 1127 | |
| 1070 | | return @as(String, @enumFromInt(entry.index)); |
| 1128 | return @enumFromInt(entry.index); |
| 1071 | 1129 | } |
| 1072 | 1130 | |
| 1073 | 1131 | pub fn getString(self: *const Self, ref: String) ?[]const u8 { |