| author | |
| committer | |
| log | 221fb30b3c961f81e99bfe9b25db8460e6231824 |
| tree | 5ac2c73284624453368d4e537b770b930b792b79 |
| parent | 53373c4c719ff6244d7099ad1ceeda18d40e09e3 |
12 files changed, 561 insertions(+), 222 deletions(-)
lib/std/zig/llvm/Builder.zig+300-136| ... | ... | @@ -1284,7 +1284,7 @@ pub const Attribute = union(Kind) { |
| 1284 | 1284 | try w.print(" {t}(\"", .{attribute}); |
| 1285 | 1285 | var any = false; |
| 1286 | 1286 | inline for (@typeInfo(AllocKind).@"struct".fields) |field| { |
| 1287 | if (comptime std.mem.eql(u8, field.name, "_")) continue; | |
| 1287 | if (comptime std.mem.eql(u8, field.name, "unused")) continue; | |
| 1288 | 1288 | if (@field(allockind, field.name)) { |
| 1289 | 1289 | if (!any) { |
| 1290 | 1290 | try w.writeByte(','); |
| ... | ... | @@ -1469,7 +1469,7 @@ pub const Attribute = union(Kind) { |
| 1469 | 1469 | positive_subnormal: bool = false, |
| 1470 | 1470 | positive_normal: bool = false, |
| 1471 | 1471 | positive_infinity: bool = false, |
| 1472 | _: u22 = 0, | |
| 1472 | unused: enum(u22) { unused = 0 } = .unused, | |
| 1473 | 1473 | |
| 1474 | 1474 | pub const all = FpClass{ |
| 1475 | 1475 | .signaling_nan = true, |
| ... | ... | @@ -1512,7 +1512,7 @@ pub const Attribute = union(Kind) { |
| 1512 | 1512 | uninitialized: bool, |
| 1513 | 1513 | zeroed: bool, |
| 1514 | 1514 | aligned: bool, |
| 1515 | _: u26 = 0, | |
| 1515 | unused: enum(u26) { unused = 0 } = .unused, | |
| 1516 | 1516 | }; |
| 1517 | 1517 | |
| 1518 | 1518 | pub const AllocSize = packed struct(u32) { |
| ... | ... | @@ -1533,7 +1533,7 @@ pub const Attribute = union(Kind) { |
| 1533 | 1533 | argmem: Effect = .none, |
| 1534 | 1534 | inaccessiblemem: Effect = .none, |
| 1535 | 1535 | other: Effect = .none, |
| 1536 | _: u26 = 0, | |
| 1536 | unused: enum(u26) { unused = 0 } = .unused, | |
| 1537 | 1537 | |
| 1538 | 1538 | pub const Effect = enum(u2) { none, read, write, readwrite }; |
| 1539 | 1539 | |
| ... | ... | @@ -1553,7 +1553,7 @@ pub const Attribute = union(Kind) { |
| 1553 | 1553 | pub const VScaleRange = packed struct(u32) { |
| 1554 | 1554 | min: Alignment, |
| 1555 | 1555 | max: Alignment, |
| 1556 | _: u20 = 0, | |
| 1556 | unused: enum(u20) { unused = 0 } = .unused, | |
| 1557 | 1557 | |
| 1558 | 1558 | fn toLlvm(self: VScaleRange) packed struct(u64) { max: u32, min: u32 } { |
| 1559 | 1559 | return .{ |
| ... | ... | @@ -1870,7 +1870,7 @@ pub const ThreadLocal = enum(u3) { |
| 1870 | 1870 | |
| 1871 | 1871 | pub fn format(p: Prefixed, w: *Writer) Writer.Error!void { |
| 1872 | 1872 | switch (p.thread_local) { |
| 1873 | .default => return, | |
| 1873 | .default => {}, | |
| 1874 | 1874 | .generaldynamic => { |
| 1875 | 1875 | var vecs: [2][]const u8 = .{ p.prefix, "thread_local" }; |
| 1876 | 1876 | return w.writeVecAll(&vecs); |
| ... | ... | @@ -4221,7 +4221,6 @@ pub const Function = struct { |
| 4221 | 4221 | call, |
| 4222 | 4222 | @"call fast", |
| 4223 | 4223 | cmpxchg, |
| 4224 | @"cmpxchg weak", | |
| 4225 | 4224 | extractelement, |
| 4226 | 4225 | extractvalue, |
| 4227 | 4226 | fadd, |
| ... | ... | @@ -4619,9 +4618,7 @@ pub const Function = struct { |
| 4619 | 4618 | .@"tail call", |
| 4620 | 4619 | .@"tail call fast", |
| 4621 | 4620 | => wip.extraData(Call, instruction.data).ty.functionReturn(wip.builder), |
| 4622 | .cmpxchg, | |
| 4623 | .@"cmpxchg weak", | |
| 4624 | => wip.builder.structTypeAssumeCapacity(.normal, &.{ | |
| 4621 | .cmpxchg => wip.builder.structTypeAssumeCapacity(.normal, &.{ | |
| 4625 | 4622 | wip.extraData(CmpXchg, instruction.data).cmp.typeOfWip(wip), |
| 4626 | 4623 | .i1, |
| 4627 | 4624 | }), |
| ... | ... | @@ -4806,9 +4803,7 @@ pub const Function = struct { |
| 4806 | 4803 | .@"tail call", |
| 4807 | 4804 | .@"tail call fast", |
| 4808 | 4805 | => function.extraData(Call, instruction.data).ty.functionReturn(builder), |
| 4809 | .cmpxchg, | |
| 4810 | .@"cmpxchg weak", | |
| 4811 | => builder.structTypeAssumeCapacity(.normal, &.{ | |
| 4806 | .cmpxchg => builder.structTypeAssumeCapacity(.normal, &.{ | |
| 4812 | 4807 | function.extraData(CmpXchg, instruction.data) |
| 4813 | 4808 | .cmp.typeOf(function_index, builder), |
| 4814 | 4809 | .i1, |
| ... | ... | @@ -5027,33 +5022,86 @@ pub const Function = struct { |
| 5027 | 5022 | pub const Info = packed struct(u32) { |
| 5028 | 5023 | alignment: Alignment, |
| 5029 | 5024 | addr_space: AddrSpace, |
| 5030 | _: u2 = undefined, | |
| 5025 | unused: enum(u2) { unused = 0 } = .unused, | |
| 5031 | 5026 | }; |
| 5032 | 5027 | }; |
| 5033 | 5028 | |
| 5034 | 5029 | pub const Load = struct { |
| 5035 | info: MemoryAccessInfo, | |
| 5030 | info: Info, | |
| 5036 | 5031 | type: Type, |
| 5037 | 5032 | ptr: Value, |
| 5033 | //range: if (info.has_range) Metadata else void, | |
| 5034 | ||
| 5035 | pub const Info = packed struct(u32) { | |
| 5036 | access_kind: MemoryAccessKind, | |
| 5037 | sync_scope: SyncScope, | |
| 5038 | ordering: AtomicOrdering, | |
| 5039 | alignment: Alignment, | |
| 5040 | has_range: bool, | |
| 5041 | unused: enum(u20) { unused = 0 } = .unused, | |
| 5042 | }; | |
| 5038 | 5043 | }; |
| 5039 | 5044 | |
| 5040 | 5045 | pub const Store = struct { |
| 5041 | info: MemoryAccessInfo, | |
| 5046 | info: Info, | |
| 5042 | 5047 | val: Value, |
| 5043 | 5048 | ptr: Value, |
| 5049 | ||
| 5050 | pub const Info = packed struct(u32) { | |
| 5051 | access_kind: MemoryAccessKind, | |
| 5052 | sync_scope: SyncScope, | |
| 5053 | ordering: AtomicOrdering, | |
| 5054 | alignment: Alignment, | |
| 5055 | unused: enum(u21) { unused = 0 } = .unused, | |
| 5056 | }; | |
| 5044 | 5057 | }; |
| 5045 | 5058 | |
| 5046 | 5059 | pub const CmpXchg = struct { |
| 5047 | info: MemoryAccessInfo, | |
| 5060 | info: Info, | |
| 5048 | 5061 | ptr: Value, |
| 5049 | 5062 | cmp: Value, |
| 5050 | 5063 | new: Value, |
| 5051 | 5064 | |
| 5052 | pub const Kind = enum { strong, weak }; | |
| 5065 | pub const Kind = enum(u1) { | |
| 5066 | strong, | |
| 5067 | weak, | |
| 5068 | ||
| 5069 | pub fn format(kind: Kind, w: *Writer) Writer.Error!void { | |
| 5070 | return Prefixed.format(.{ .kind = kind, .prefix = "" }, w); | |
| 5071 | } | |
| 5072 | ||
| 5073 | pub const Prefixed = struct { | |
| 5074 | kind: Kind, | |
| 5075 | prefix: []const u8, | |
| 5076 | ||
| 5077 | pub fn format(p: Prefixed, w: *Writer) Writer.Error!void { | |
| 5078 | switch (p.kind) { | |
| 5079 | .strong => {}, | |
| 5080 | .weak => { | |
| 5081 | var vecs: [2][]const u8 = .{ p.prefix, "weak" }; | |
| 5082 | try w.writeVecAll(&vecs); | |
| 5083 | }, | |
| 5084 | } | |
| 5085 | } | |
| 5086 | }; | |
| 5087 | ||
| 5088 | pub fn fmt(kind: Kind, prefix: []const u8) Prefixed { | |
| 5089 | return .{ .kind = kind, .prefix = prefix }; | |
| 5090 | } | |
| 5091 | }; | |
| 5092 | pub const Info = packed struct(u32) { | |
| 5093 | kind: Kind, | |
| 5094 | access_kind: MemoryAccessKind, | |
| 5095 | sync_scope: SyncScope, | |
| 5096 | success_ordering: AtomicOrdering, | |
| 5097 | failure_ordering: AtomicOrdering, | |
| 5098 | alignment: Alignment, | |
| 5099 | unused: enum(u17) { unused = 0 } = .unused, | |
| 5100 | }; | |
| 5053 | 5101 | }; |
| 5054 | 5102 | |
| 5055 | 5103 | pub const AtomicRmw = struct { |
| 5056 | info: MemoryAccessInfo, | |
| 5104 | info: Info, | |
| 5057 | 5105 | ptr: Value, |
| 5058 | 5106 | val: Value, |
| 5059 | 5107 | |
| ... | ... | @@ -5073,8 +5121,21 @@ pub const Function = struct { |
| 5073 | 5121 | fsub = 12, |
| 5074 | 5122 | fmax = 13, |
| 5075 | 5123 | fmin = 14, |
| 5076 | none = maxInt(u5), | |
| 5077 | 5124 | }; |
| 5125 | pub const Info = packed struct(u32) { | |
| 5126 | access_kind: MemoryAccessKind, | |
| 5127 | operation: Operation, | |
| 5128 | sync_scope: SyncScope, | |
| 5129 | ordering: AtomicOrdering, | |
| 5130 | alignment: Alignment, | |
| 5131 | unused: enum(u16) { unused = 0 } = .unused, | |
| 5132 | }; | |
| 5133 | }; | |
| 5134 | ||
| 5135 | pub const Fence = packed struct(u32) { | |
| 5136 | sync_scope: SyncScope, | |
| 5137 | success_ordering: AtomicOrdering, | |
| 5138 | unused: enum(u28) { unused = 0 } = .unused, | |
| 5078 | 5139 | }; |
| 5079 | 5140 | |
| 5080 | 5141 | pub const GetElementPtr = struct { |
| ... | ... | @@ -5112,6 +5173,7 @@ pub const Function = struct { |
| 5112 | 5173 | callee: Value, |
| 5113 | 5174 | args_len: u32, |
| 5114 | 5175 | //args: [args_len]Value, |
| 5176 | //callees: if (info.has_callees) Metadata else void, | |
| 5115 | 5177 | |
| 5116 | 5178 | pub const Kind = enum { |
| 5117 | 5179 | normal, |
| ... | ... | @@ -5125,8 +5187,9 @@ pub const Function = struct { |
| 5125 | 5187 | }; |
| 5126 | 5188 | pub const Info = packed struct(u32) { |
| 5127 | 5189 | call_conv: CallConv, |
| 5190 | has_callees: bool, | |
| 5128 | 5191 | has_op_bundle_cold: bool, |
| 5129 | _: u21 = undefined, | |
| 5192 | unused: enum(u20) { unused = 0 } = .unused, | |
| 5130 | 5193 | }; |
| 5131 | 5194 | }; |
| 5132 | 5195 | |
| ... | ... | @@ -5195,8 +5258,11 @@ pub const Function = struct { |
| 5195 | 5258 | Value, |
| 5196 | 5259 | Instruction.BrCond.Weights, |
| 5197 | 5260 | => @enumFromInt(value), |
| 5198 | MemoryAccessInfo, | |
| 5199 | 5261 | Instruction.Alloca.Info, |
| 5262 | Instruction.Load.Info, | |
| 5263 | Instruction.Store.Info, | |
| 5264 | Instruction.CmpXchg.Info, | |
| 5265 | Instruction.AtomicRmw.Info, | |
| 5200 | 5266 | Instruction.Call.Info, |
| 5201 | 5267 | => @bitCast(value), |
| 5202 | 5268 | else => @compileError("bad field type: " ++ field.name ++ ": " ++ @typeName(field.type)), |
| ... | ... | @@ -5706,6 +5772,10 @@ pub const WipFunction = struct { |
| 5706 | 5772 | return instruction.toValue(); |
| 5707 | 5773 | } |
| 5708 | 5774 | |
| 5775 | pub const LoadMetadata = struct { | |
| 5776 | range: Metadata.Optional = .none, | |
| 5777 | }; | |
| 5778 | ||
| 5709 | 5779 | pub fn load( |
| 5710 | 5780 | self: *WipFunction, |
| 5711 | 5781 | access_kind: MemoryAccessKind, |
| ... | ... | @@ -5714,7 +5784,19 @@ pub const WipFunction = struct { |
| 5714 | 5784 | alignment: Alignment, |
| 5715 | 5785 | name: []const u8, |
| 5716 | 5786 | ) Allocator.Error!Value { |
| 5717 | return self.loadAtomic(access_kind, ty, ptr, .system, .none, alignment, name); | |
| 5787 | return self.loadMetadata(access_kind, ty, ptr, alignment, .{}, name); | |
| 5788 | } | |
| 5789 | ||
| 5790 | pub fn loadMetadata( | |
| 5791 | self: *WipFunction, | |
| 5792 | access_kind: MemoryAccessKind, | |
| 5793 | ty: Type, | |
| 5794 | ptr: Value, | |
| 5795 | alignment: Alignment, | |
| 5796 | metadata: LoadMetadata, | |
| 5797 | name: []const u8, | |
| 5798 | ) Allocator.Error!Value { | |
| 5799 | return self.loadAtomicMetadata(access_kind, ty, ptr, .system, .none, alignment, metadata, name); | |
| 5718 | 5800 | } |
| 5719 | 5801 | |
| 5720 | 5802 | pub fn loadAtomic( |
| ... | ... | @@ -5726,6 +5808,20 @@ pub const WipFunction = struct { |
| 5726 | 5808 | ordering: AtomicOrdering, |
| 5727 | 5809 | alignment: Alignment, |
| 5728 | 5810 | name: []const u8, |
| 5811 | ) Allocator.Error!Value { | |
| 5812 | return self.loadAtomicMetadata(access_kind, ty, ptr, sync_scope, ordering, alignment, .{}, name); | |
| 5813 | } | |
| 5814 | ||
| 5815 | pub fn loadAtomicMetadata( | |
| 5816 | self: *WipFunction, | |
| 5817 | access_kind: MemoryAccessKind, | |
| 5818 | ty: Type, | |
| 5819 | ptr: Value, | |
| 5820 | sync_scope: SyncScope, | |
| 5821 | ordering: AtomicOrdering, | |
| 5822 | alignment: Alignment, | |
| 5823 | metadata: LoadMetadata, | |
| 5824 | name: []const u8, | |
| 5729 | 5825 | ) Allocator.Error!Value { |
| 5730 | 5826 | assert(ptr.typeOfWip(self).isPointer(self.builder)); |
| 5731 | 5827 | try self.ensureUnusedExtraCapacity(1, Instruction.Load, 0); |
| ... | ... | @@ -5741,13 +5837,15 @@ pub const WipFunction = struct { |
| 5741 | 5837 | .none => .system, |
| 5742 | 5838 | else => sync_scope, |
| 5743 | 5839 | }, |
| 5744 | .success_ordering = ordering, | |
| 5840 | .ordering = ordering, | |
| 5745 | 5841 | .alignment = alignment, |
| 5842 | .has_range = !metadata.range.is_none, | |
| 5746 | 5843 | }, |
| 5747 | 5844 | .type = ty, |
| 5748 | 5845 | .ptr = ptr, |
| 5749 | 5846 | }), |
| 5750 | 5847 | }); |
| 5848 | if (metadata.range.unwrap()) |range| self.extra.appendAssumeCapacity(@bitCast(range)); | |
| 5751 | 5849 | return instruction.toValue(); |
| 5752 | 5850 | } |
| 5753 | 5851 | |
| ... | ... | @@ -5784,7 +5882,7 @@ pub const WipFunction = struct { |
| 5784 | 5882 | .none => .system, |
| 5785 | 5883 | else => sync_scope, |
| 5786 | 5884 | }, |
| 5787 | .success_ordering = ordering, | |
| 5885 | .ordering = ordering, | |
| 5788 | 5886 | .alignment = alignment, |
| 5789 | 5887 | }, |
| 5790 | 5888 | .val = val, |
| ... | ... | @@ -5803,7 +5901,7 @@ pub const WipFunction = struct { |
| 5803 | 5901 | try self.ensureUnusedExtraCapacity(1, NoExtra, 0); |
| 5804 | 5902 | const instruction = try self.addInst(null, .{ |
| 5805 | 5903 | .tag = .fence, |
| 5806 | .data = @bitCast(MemoryAccessInfo{ | |
| 5904 | .data = @bitCast(Instruction.Fence{ | |
| 5807 | 5905 | .sync_scope = sync_scope, |
| 5808 | 5906 | .success_ordering = ordering, |
| 5809 | 5907 | }), |
| ... | ... | @@ -5833,12 +5931,10 @@ pub const WipFunction = struct { |
| 5833 | 5931 | _ = try self.builder.structType(.normal, &.{ ty, .i1 }); |
| 5834 | 5932 | try self.ensureUnusedExtraCapacity(1, Instruction.CmpXchg, 0); |
| 5835 | 5933 | const instruction = try self.addInst(name, .{ |
| 5836 | .tag = switch (kind) { | |
| 5837 | .strong => .cmpxchg, | |
| 5838 | .weak => .@"cmpxchg weak", | |
| 5839 | }, | |
| 5934 | .tag = .cmpxchg, | |
| 5840 | 5935 | .data = self.addExtraAssumeCapacity(Instruction.CmpXchg{ |
| 5841 | 5936 | .info = .{ |
| 5937 | .kind = kind, | |
| 5842 | 5938 | .access_kind = access_kind, |
| 5843 | 5939 | .sync_scope = sync_scope, |
| 5844 | 5940 | .success_ordering = success_ordering, |
| ... | ... | @@ -5873,9 +5969,9 @@ pub const WipFunction = struct { |
| 5873 | 5969 | .data = self.addExtraAssumeCapacity(Instruction.AtomicRmw{ |
| 5874 | 5970 | .info = .{ |
| 5875 | 5971 | .access_kind = access_kind, |
| 5876 | .atomic_rmw_operation = operation, | |
| 5972 | .operation = operation, | |
| 5877 | 5973 | .sync_scope = sync_scope, |
| 5878 | .success_ordering = ordering, | |
| 5974 | .ordering = ordering, | |
| 5879 | 5975 | .alignment = alignment, |
| 5880 | 5976 | }, |
| 5881 | 5977 | .ptr = ptr, |
| ... | ... | @@ -6079,6 +6175,11 @@ pub const WipFunction = struct { |
| 6079 | 6175 | }, cond, lhs, rhs, name); |
| 6080 | 6176 | } |
| 6081 | 6177 | |
| 6178 | pub const CallMetadata = struct { | |
| 6179 | callees: Metadata.Optional = .none, | |
| 6180 | has_op_bundle_cold: bool = false, | |
| 6181 | }; | |
| 6182 | ||
| 6082 | 6183 | pub fn call( |
| 6083 | 6184 | self: *WipFunction, |
| 6084 | 6185 | kind: Instruction.Call.Kind, |
| ... | ... | @@ -6089,10 +6190,10 @@ pub const WipFunction = struct { |
| 6089 | 6190 | args: []const Value, |
| 6090 | 6191 | name: []const u8, |
| 6091 | 6192 | ) Allocator.Error!Value { |
| 6092 | return self.callInner(kind, call_conv, function_attributes, ty, callee, args, name, false); | |
| 6193 | return self.callMetadata(kind, call_conv, function_attributes, ty, callee, args, .{}, name); | |
| 6093 | 6194 | } |
| 6094 | 6195 | |
| 6095 | fn callInner( | |
| 6196 | pub fn callMetadata( | |
| 6096 | 6197 | self: *WipFunction, |
| 6097 | 6198 | kind: Instruction.Call.Kind, |
| 6098 | 6199 | call_conv: CallConv, |
| ... | ... | @@ -6100,8 +6201,8 @@ pub const WipFunction = struct { |
| 6100 | 6201 | ty: Type, |
| 6101 | 6202 | callee: Value, |
| 6102 | 6203 | args: []const Value, |
| 6204 | metadata: CallMetadata, | |
| 6103 | 6205 | name: []const u8, |
| 6104 | has_op_bundle_cold: bool, | |
| 6105 | 6206 | ) Allocator.Error!Value { |
| 6106 | 6207 | const ret_ty = ty.functionReturn(self.builder); |
| 6107 | 6208 | assert(ty.isFunction(self.builder)); |
| ... | ... | @@ -6109,7 +6210,8 @@ pub const WipFunction = struct { |
| 6109 | 6210 | const params = ty.functionParameters(self.builder); |
| 6110 | 6211 | for (params, args[0..params.len]) |param, arg_val| assert(param == arg_val.typeOfWip(self)); |
| 6111 | 6212 | |
| 6112 | try self.ensureUnusedExtraCapacity(1, Instruction.Call, args.len); | |
| 6213 | try self.ensureUnusedExtraCapacity(1, Instruction.Call, args.len + | |
| 6214 | @intFromBool(!metadata.callees.is_none)); | |
| 6113 | 6215 | const instruction = try self.addInst(switch (ret_ty) { |
| 6114 | 6216 | .void => null, |
| 6115 | 6217 | else => name, |
| ... | ... | @@ -6127,7 +6229,8 @@ pub const WipFunction = struct { |
| 6127 | 6229 | .data = self.addExtraAssumeCapacity(Instruction.Call{ |
| 6128 | 6230 | .info = .{ |
| 6129 | 6231 | .call_conv = call_conv, |
| 6130 | .has_op_bundle_cold = has_op_bundle_cold, | |
| 6232 | .has_callees = !metadata.callees.is_none, | |
| 6233 | .has_op_bundle_cold = metadata.has_op_bundle_cold, | |
| 6131 | 6234 | }, |
| 6132 | 6235 | .attributes = function_attributes, |
| 6133 | 6236 | .ty = ty, |
| ... | ... | @@ -6136,6 +6239,7 @@ pub const WipFunction = struct { |
| 6136 | 6239 | }), |
| 6137 | 6240 | }); |
| 6138 | 6241 | self.extra.appendSliceAssumeCapacity(@ptrCast(args)); |
| 6242 | if (metadata.callees.unwrap()) |callees| self.extra.appendAssumeCapacity(@bitCast(callees)); | |
| 6139 | 6243 | return instruction.toValue(); |
| 6140 | 6244 | } |
| 6141 | 6245 | |
| ... | ... | @@ -6176,15 +6280,15 @@ pub const WipFunction = struct { |
| 6176 | 6280 | |
| 6177 | 6281 | pub fn callIntrinsicAssumeCold(self: *WipFunction) Allocator.Error!Value { |
| 6178 | 6282 | const intrinsic = try self.builder.getIntrinsic(.assume, &.{}); |
| 6179 | return self.callInner( | |
| 6283 | return self.callMetadata( | |
| 6180 | 6284 | .normal, |
| 6181 | 6285 | CallConv.default, |
| 6182 | 6286 | .none, |
| 6183 | 6287 | intrinsic.typeOf(self.builder), |
| 6184 | 6288 | intrinsic.toValue(self.builder), |
| 6185 | 6289 | &.{try self.builder.intValue(.i1, 1)}, |
| 6186 | "", | |
| 6187 | true, | |
| 6290 | .{ .has_op_bundle_cold = true }, | |
| 6291 | undefined, | |
| 6188 | 6292 | ); |
| 6189 | 6293 | } |
| 6190 | 6294 | |
| ... | ... | @@ -6355,8 +6459,11 @@ pub const WipFunction = struct { |
| 6355 | 6459 | Value, |
| 6356 | 6460 | Instruction.BrCond.Weights, |
| 6357 | 6461 | => @intFromEnum(value), |
| 6358 | MemoryAccessInfo, | |
| 6359 | 6462 | Instruction.Alloca.Info, |
| 6463 | Instruction.Load.Info, | |
| 6464 | Instruction.Store.Info, | |
| 6465 | Instruction.CmpXchg.Info, | |
| 6466 | Instruction.AtomicRmw.Info, | |
| 6360 | 6467 | Instruction.Call.Info, |
| 6361 | 6468 | => @bitCast(value), |
| 6362 | 6469 | else => @compileError("bad field type: " ++ field.name ++ ": " ++ @typeName(field.type)), |
| ... | ... | @@ -6648,6 +6755,7 @@ pub const WipFunction = struct { |
| 6648 | 6755 | => { |
| 6649 | 6756 | var extra = self.extraDataTrail(Instruction.Call, instruction.data); |
| 6650 | 6757 | const args = extra.trail.next(extra.data.args_len, Value, self); |
| 6758 | const callees = extra.trail.next(@intFromBool(extra.data.info.has_callees), Metadata, self); | |
| 6651 | 6759 | instruction.data = wip_extra.addExtra(Instruction.Call{ |
| 6652 | 6760 | .info = extra.data.info, |
| 6653 | 6761 | .attributes = extra.data.attributes, |
| ... | ... | @@ -6656,10 +6764,9 @@ pub const WipFunction = struct { |
| 6656 | 6764 | .args_len = extra.data.args_len, |
| 6657 | 6765 | }); |
| 6658 | 6766 | wip_extra.appendMappedValues(args, instructions); |
| 6767 | wip_extra.appendSlice(callees); | |
| 6659 | 6768 | }, |
| 6660 | .cmpxchg, | |
| 6661 | .@"cmpxchg weak", | |
| 6662 | => { | |
| 6769 | .cmpxchg => { | |
| 6663 | 6770 | const extra = self.extraData(Instruction.CmpXchg, instruction.data); |
| 6664 | 6771 | instruction.data = wip_extra.addExtra(Instruction.CmpXchg{ |
| 6665 | 6772 | .info = extra.info, |
| ... | ... | @@ -6730,12 +6837,14 @@ pub const WipFunction = struct { |
| 6730 | 6837 | .load, |
| 6731 | 6838 | .@"load atomic", |
| 6732 | 6839 | => { |
| 6733 | const extra = self.extraData(Instruction.Load, instruction.data); | |
| 6840 | var extra = self.extraDataTrail(Instruction.Load, instruction.data); | |
| 6841 | const range = extra.trail.next(@intFromBool(extra.data.info.has_range), Metadata, self); | |
| 6734 | 6842 | instruction.data = wip_extra.addExtra(Instruction.Load{ |
| 6735 | .type = extra.type, | |
| 6736 | .ptr = instructions.map(extra.ptr), | |
| 6737 | .info = extra.info, | |
| 6843 | .type = extra.data.type, | |
| 6844 | .ptr = instructions.map(extra.data.ptr), | |
| 6845 | .info = extra.data.info, | |
| 6738 | 6846 | }); |
| 6847 | wip_extra.appendSlice(range); | |
| 6739 | 6848 | }, |
| 6740 | 6849 | .phi, |
| 6741 | 6850 | .@"phi fast", |
| ... | ... | @@ -7011,8 +7120,11 @@ pub const WipFunction = struct { |
| 7011 | 7120 | Value, |
| 7012 | 7121 | Instruction.BrCond.Weights, |
| 7013 | 7122 | => @intFromEnum(value), |
| 7014 | MemoryAccessInfo, | |
| 7015 | 7123 | Instruction.Alloca.Info, |
| 7124 | Instruction.Load.Info, | |
| 7125 | Instruction.Store.Info, | |
| 7126 | Instruction.CmpXchg.Info, | |
| 7127 | Instruction.AtomicRmw.Info, | |
| 7016 | 7128 | Instruction.Call.Info, |
| 7017 | 7129 | => @bitCast(value), |
| 7018 | 7130 | else => @compileError("bad field type: " ++ field.name ++ ": " ++ @typeName(field.type)), |
| ... | ... | @@ -7060,8 +7172,11 @@ pub const WipFunction = struct { |
| 7060 | 7172 | Value, |
| 7061 | 7173 | Instruction.BrCond.Weights, |
| 7062 | 7174 | => @enumFromInt(value), |
| 7063 | MemoryAccessInfo, | |
| 7064 | 7175 | Instruction.Alloca.Info, |
| 7176 | Instruction.Load.Info, | |
| 7177 | Instruction.Store.Info, | |
| 7178 | Instruction.CmpXchg.Info, | |
| 7179 | Instruction.AtomicRmw.Info, | |
| 7065 | 7180 | Instruction.Call.Info, |
| 7066 | 7181 | => @bitCast(value), |
| 7067 | 7182 | else => @compileError("bad field type: " ++ field.name ++ ": " ++ @typeName(field.type)), |
| ... | ... | @@ -7121,10 +7236,10 @@ pub const MemoryAccessKind = enum(u1) { |
| 7121 | 7236 | |
| 7122 | 7237 | pub fn format(p: Prefixed, w: *Writer) Writer.Error!void { |
| 7123 | 7238 | switch (p.memory_access_kind) { |
| 7124 | .normal => return, | |
| 7239 | .normal => {}, | |
| 7125 | 7240 | .@"volatile" => { |
| 7126 | 7241 | var vecs: [2][]const u8 = .{ p.prefix, "volatile" }; |
| 7127 | return w.writeVecAll(&vecs); | |
| 7242 | try w.writeVecAll(&vecs); | |
| 7128 | 7243 | }, |
| 7129 | 7244 | } |
| 7130 | 7245 | } |
| ... | ... | @@ -7149,10 +7264,10 @@ pub const SyncScope = enum(u1) { |
| 7149 | 7264 | |
| 7150 | 7265 | pub fn format(p: Prefixed, w: *Writer) Writer.Error!void { |
| 7151 | 7266 | switch (p.sync_scope) { |
| 7152 | .system => return, | |
| 7267 | .system => {}, | |
| 7153 | 7268 | .singlethread => { |
| 7154 | 7269 | var vecs: [2][]const u8 = .{ p.prefix, "syncscope(\"singlethread\")" }; |
| 7155 | return w.writeVecAll(&vecs); | |
| 7270 | try w.writeVecAll(&vecs); | |
| 7156 | 7271 | }, |
| 7157 | 7272 | } |
| 7158 | 7273 | } |
| ... | ... | @@ -7182,10 +7297,10 @@ pub const AtomicOrdering = enum(u3) { |
| 7182 | 7297 | |
| 7183 | 7298 | pub fn format(p: Prefixed, w: *Writer) Writer.Error!void { |
| 7184 | 7299 | switch (p.atomic_ordering) { |
| 7185 | .none => return, | |
| 7300 | .none => {}, | |
| 7186 | 7301 | else => { |
| 7187 | 7302 | var vecs: [2][]const u8 = .{ p.prefix, @tagName(p.atomic_ordering) }; |
| 7188 | return w.writeVecAll(&vecs); | |
| 7303 | try w.writeVecAll(&vecs); | |
| 7189 | 7304 | }, |
| 7190 | 7305 | } |
| 7191 | 7306 | } |
| ... | ... | @@ -7196,16 +7311,6 @@ pub const AtomicOrdering = enum(u3) { |
| 7196 | 7311 | } |
| 7197 | 7312 | }; |
| 7198 | 7313 | |
| 7199 | const MemoryAccessInfo = packed struct(u32) { | |
| 7200 | access_kind: MemoryAccessKind = .normal, | |
| 7201 | atomic_rmw_operation: Function.Instruction.AtomicRmw.Operation = .none, | |
| 7202 | sync_scope: SyncScope, | |
| 7203 | success_ordering: AtomicOrdering, | |
| 7204 | failure_ordering: AtomicOrdering = .none, | |
| 7205 | alignment: Alignment = .default, | |
| 7206 | _: u13 = undefined, | |
| 7207 | }; | |
| 7208 | ||
| 7209 | 7314 | pub const FastMath = packed struct(u8) { |
| 7210 | 7315 | unsafe_algebra: bool = false, // Legacy |
| 7211 | 7316 | nnan: bool = false, |
| ... | ... | @@ -7533,7 +7638,7 @@ pub const Constant = enum(u32) { |
| 7533 | 7638 | const item = builder.constant_items.get(constant); |
| 7534 | 7639 | return switch (item.tag) { |
| 7535 | 7640 | .positive_integer => { |
| 7536 | const extra: *align(@alignOf(std.math.big.Limb)) Integer = | |
| 7641 | const extra: *align(@alignOf(std.math.big.Limb)) const Integer = | |
| 7537 | 7642 | @ptrCast(builder.constant_limbs.items[item.data..][0..Integer.limbs]); |
| 7538 | 7643 | const limbs = builder.constant_limbs |
| 7539 | 7644 | .items[item.data + Integer.limbs ..][0..extra.limbs_len]; |
| ... | ... | @@ -7568,6 +7673,21 @@ pub const Constant = enum(u32) { |
| 7568 | 7673 | } |
| 7569 | 7674 | } |
| 7570 | 7675 | |
| 7676 | pub fn toInt(self: Constant, builder: *const Builder) ?std.math.big.int.Const { | |
| 7677 | const item = builder.constant_items.get(self.unwrap().constant); | |
| 7678 | switch (item.tag) { | |
| 7679 | .positive_integer, .negative_integer => { | |
| 7680 | const extra: *align(@alignOf(std.math.big.Limb)) const Integer = | |
| 7681 | @ptrCast(builder.constant_limbs.items[item.data..][0..Integer.limbs]); | |
| 7682 | return .{ | |
| 7683 | .positive = item.tag == .positive_integer, | |
| 7684 | .limbs = builder.constant_limbs.items[item.data + Integer.limbs ..][0..extra.limbs_len], | |
| 7685 | }; | |
| 7686 | }, | |
| 7687 | else => return null, | |
| 7688 | } | |
| 7689 | } | |
| 7690 | ||
| 7571 | 7691 | pub fn getBase(self: Constant, builder: *const Builder) Global.Index { |
| 7572 | 7692 | var cur = self; |
| 7573 | 7693 | while (true) switch (cur.unwrap()) { |
| ... | ... | @@ -8183,7 +8303,7 @@ pub const Metadata = packed struct(u32) { |
| 8183 | 8303 | }; |
| 8184 | 8304 | |
| 8185 | 8305 | pub const DIFlags = packed struct(u32) { |
| 8186 | Visibility: enum(u2) { Zero, Private, Protected, Public } = .Zero, | |
| 8306 | Visibility: enum(u2) { None, Private, Protected, Public } = .None, | |
| 8187 | 8307 | FwdDecl: bool = false, |
| 8188 | 8308 | AppleBlock: bool = false, |
| 8189 | 8309 | ReservedBit4: u1 = 0, |
| ... | ... | @@ -8199,11 +8319,11 @@ pub const Metadata = packed struct(u32) { |
| 8199 | 8319 | RValueReference: bool = false, |
| 8200 | 8320 | ExportSymbols: bool = false, |
| 8201 | 8321 | Inheritance: enum(u2) { |
| 8202 | Zero, | |
| 8322 | None, | |
| 8203 | 8323 | SingleInheritance, |
| 8204 | 8324 | MultipleInheritance, |
| 8205 | 8325 | VirtualInheritance, |
| 8206 | } = .Zero, | |
| 8326 | } = .None, | |
| 8207 | 8327 | IntroducedVirtual: bool = false, |
| 8208 | 8328 | BitField: bool = false, |
| 8209 | 8329 | NoReturn: bool = false, |
| ... | ... | @@ -8226,7 +8346,7 @@ pub const Metadata = packed struct(u32) { |
| 8226 | 8346 | if (need_pipe) try w.writeAll(" | ") else need_pipe = true; |
| 8227 | 8347 | try w.print("DIFlag{s}", .{field.name}); |
| 8228 | 8348 | }, |
| 8229 | .@"enum" => if (@field(self, field.name) != .Zero) { | |
| 8349 | .@"enum" => if (@field(self, field.name) != .None) { | |
| 8230 | 8350 | if (need_pipe) try w.writeAll(" | ") else need_pipe = true; |
| 8231 | 8351 | try w.print("DIFlag{s}", .{@tagName(@field(self, field.name))}); |
| 8232 | 8352 | }, |
| ... | ... | @@ -8262,7 +8382,7 @@ pub const Metadata = packed struct(u32) { |
| 8262 | 8382 | }; |
| 8263 | 8383 | |
| 8264 | 8384 | pub const DISPFlags = packed struct(u32) { |
| 8265 | Virtuality: enum(u2) { Zero, Virtual, PureVirtual } = .Zero, | |
| 8385 | Virtuality: enum(u2) { None, Virtual, PureVirtual } = .None, | |
| 8266 | 8386 | LocalToUnit: bool = false, |
| 8267 | 8387 | Definition: bool = false, |
| 8268 | 8388 | Optimized: bool = false, |
| ... | ... | @@ -8283,7 +8403,7 @@ pub const Metadata = packed struct(u32) { |
| 8283 | 8403 | if (need_pipe) try w.writeAll(" | ") else need_pipe = true; |
| 8284 | 8404 | try w.print("DISPFlag{s}", .{field.name}); |
| 8285 | 8405 | }, |
| 8286 | .@"enum" => if (@field(self, field.name) != .Zero) { | |
| 8406 | .@"enum" => if (@field(self, field.name) != .None) { | |
| 8287 | 8407 | if (need_pipe) try w.writeAll(" | ") else need_pipe = true; |
| 8288 | 8408 | try w.print("DISPFlag{s}", .{@tagName(@field(self, field.name))}); |
| 8289 | 8409 | }, |
| ... | ... | @@ -10007,11 +10127,11 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void |
| 10007 | 10127 | instruction_index.name(&function).fmt(self), |
| 10008 | 10128 | tag, |
| 10009 | 10129 | extra.info.access_kind.fmt(" "), |
| 10010 | extra.info.atomic_rmw_operation, | |
| 10130 | extra.info.operation, | |
| 10011 | 10131 | extra.ptr.fmt(function_index, self, .{ .percent = true }), |
| 10012 | 10132 | extra.val.fmt(function_index, self, .{ .percent = true }), |
| 10013 | 10133 | extra.info.sync_scope.fmt(" "), |
| 10014 | extra.info.success_ordering.fmt(" "), | |
| 10134 | extra.info.ordering.fmt(" "), | |
| 10015 | 10135 | extra.info.alignment.fmt(", "), |
| 10016 | 10136 | }); |
| 10017 | 10137 | }, |
| ... | ... | @@ -10055,9 +10175,10 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void |
| 10055 | 10175 | .@"tail call", |
| 10056 | 10176 | .@"tail call fast", |
| 10057 | 10177 | => |tag| { |
| 10058 | var extra = | |
| 10059 | function.extraDataTrail(Function.Instruction.Call, instruction.data); | |
| 10178 | var extra = function.extraDataTrail(Function.Instruction.Call, instruction.data); | |
| 10060 | 10179 | const args = extra.trail.next(extra.data.args_len, Value, &function); |
| 10180 | const callees = | |
| 10181 | extra.trail.next(@intFromBool(extra.data.info.has_callees), Metadata, &function); | |
| 10061 | 10182 | try w.writeAll(" "); |
| 10062 | 10183 | const ret_ty = extra.data.ty.functionReturn(self); |
| 10063 | 10184 | switch (ret_ty) { |
| ... | ... | @@ -10089,9 +10210,6 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void |
| 10089 | 10210 | }); |
| 10090 | 10211 | } |
| 10091 | 10212 | try w.writeByte(')'); |
| 10092 | if (extra.data.info.has_op_bundle_cold) { | |
| 10093 | try w.writeAll(" [ \"cold\"() ]"); | |
| 10094 | } | |
| 10095 | 10213 | const call_function_attributes = extra.data.attributes.func(self); |
| 10096 | 10214 | if (call_function_attributes != .none) try w.print(" #{d}", .{ |
| 10097 | 10215 | (try attribute_groups.getOrPutValue( |
| ... | ... | @@ -10100,15 +10218,19 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void |
| 10100 | 10218 | {}, |
| 10101 | 10219 | )).index, |
| 10102 | 10220 | }); |
| 10221 | if (extra.data.info.has_op_bundle_cold) try w.writeAll(" [ \"cold\"() ]"); | |
| 10222 | metadata_formatter.need_comma = true; | |
| 10223 | defer metadata_formatter.need_comma = undefined; | |
| 10224 | for (callees) |metadata| try w.print("{f}", .{ | |
| 10225 | try metadata_formatter.fmt("!callees ", metadata, null), | |
| 10226 | }); | |
| 10103 | 10227 | }, |
| 10104 | .cmpxchg, | |
| 10105 | .@"cmpxchg weak", | |
| 10106 | => |tag| { | |
| 10107 | const extra = | |
| 10108 | function.extraData(Function.Instruction.CmpXchg, instruction.data); | |
| 10109 | try w.print(" %{f} = {t}{f} {f}, {f}, {f}{f}{f}{f}{f}", .{ | |
| 10228 | .cmpxchg => |tag| { | |
| 10229 | const extra = function.extraData(Function.Instruction.CmpXchg, instruction.data); | |
| 10230 | try w.print(" %{f} = {t}{f}{f} {f}, {f}, {f}{f}{f}{f}{f}", .{ | |
| 10110 | 10231 | instruction_index.name(&function).fmt(self), |
| 10111 | 10232 | tag, |
| 10233 | extra.info.kind.fmt(" "), | |
| 10112 | 10234 | extra.info.access_kind.fmt(" "), |
| 10113 | 10235 | extra.ptr.fmt(function_index, self, .{ .percent = true }), |
| 10114 | 10236 | extra.cmp.fmt(function_index, self, .{ .percent = true }), |
| ... | ... | @@ -10143,11 +10265,11 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void |
| 10143 | 10265 | for (indices) |index| try w.print(", {d}", .{index}); |
| 10144 | 10266 | }, |
| 10145 | 10267 | .fence => |tag| { |
| 10146 | const info: MemoryAccessInfo = @bitCast(instruction.data); | |
| 10268 | const fence: Function.Instruction.Fence = @bitCast(instruction.data); | |
| 10147 | 10269 | try w.print(" {t}{f}{f}", .{ |
| 10148 | 10270 | tag, |
| 10149 | info.sync_scope.fmt(" "), | |
| 10150 | info.success_ordering.fmt(" "), | |
| 10271 | fence.sync_scope.fmt(" "), | |
| 10272 | fence.success_ordering.fmt(" "), | |
| 10151 | 10273 | }); |
| 10152 | 10274 | }, |
| 10153 | 10275 | .fneg, |
| ... | ... | @@ -10221,16 +10343,22 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void |
| 10221 | 10343 | .load, |
| 10222 | 10344 | .@"load atomic", |
| 10223 | 10345 | => |tag| { |
| 10224 | const extra = function.extraData(Function.Instruction.Load, instruction.data); | |
| 10346 | var extra = function.extraDataTrail(Function.Instruction.Load, instruction.data); | |
| 10347 | const range = extra.trail.next(@intFromBool(extra.data.info.has_range), Metadata, &function); | |
| 10225 | 10348 | try w.print(" %{f} = {t}{f} {f}, {f}{f}{f}{f}", .{ |
| 10226 | 10349 | instruction_index.name(&function).fmt(self), |
| 10227 | 10350 | tag, |
| 10228 | extra.info.access_kind.fmt(" "), | |
| 10229 | extra.type.fmt(self, .percent), | |
| 10230 | extra.ptr.fmt(function_index, self, .{ .percent = true }), | |
| 10231 | extra.info.sync_scope.fmt(" "), | |
| 10232 | extra.info.success_ordering.fmt(" "), | |
| 10233 | extra.info.alignment.fmt(", "), | |
| 10351 | extra.data.info.access_kind.fmt(" "), | |
| 10352 | extra.data.type.fmt(self, .percent), | |
| 10353 | extra.data.ptr.fmt(function_index, self, .{ .percent = true }), | |
| 10354 | extra.data.info.sync_scope.fmt(" "), | |
| 10355 | extra.data.info.ordering.fmt(" "), | |
| 10356 | extra.data.info.alignment.fmt(", "), | |
| 10357 | }); | |
| 10358 | metadata_formatter.need_comma = true; | |
| 10359 | defer metadata_formatter.need_comma = undefined; | |
| 10360 | for (range) |metadata| if (metadata.unwrap(self) != Metadata.empty_tuple) try w.print("{f}", .{ | |
| 10361 | try metadata_formatter.fmt("!range ", metadata, null), | |
| 10234 | 10362 | }); |
| 10235 | 10363 | }, |
| 10236 | 10364 | .phi, |
| ... | ... | @@ -10296,7 +10424,7 @@ pub fn print(self: *Builder, w: *Writer) (Writer.Error || Allocator.Error)!void |
| 10296 | 10424 | extra.val.fmt(function_index, self, .{ .percent = true }), |
| 10297 | 10425 | extra.ptr.fmt(function_index, self, .{ .percent = true }), |
| 10298 | 10426 | extra.info.sync_scope.fmt(" "), |
| 10299 | extra.info.success_ordering.fmt(" "), | |
| 10427 | extra.info.ordering.fmt(" "), | |
| 10300 | 10428 | extra.info.alignment.fmt(", "), |
| 10301 | 10429 | }); |
| 10302 | 10430 | }, |
| ... | ... | @@ -12291,9 +12419,12 @@ pub fn debugFloatType( |
| 12291 | 12419 | return self.debugFloatTypeAssumeCapacity(name, size_in_bits); |
| 12292 | 12420 | } |
| 12293 | 12421 | |
| 12294 | pub fn debugForwardReference(self: *Builder) Allocator.Error!Metadata { | |
| 12422 | /// Deprecated, use `metadataForwardReference`. | |
| 12423 | pub const debugForwardReference = metadataForwardReference; | |
| 12424 | ||
| 12425 | pub fn metadataForwardReference(self: *Builder) Allocator.Error!Metadata { | |
| 12295 | 12426 | try self.metadata_forward_references.ensureUnusedCapacity(self.gpa, 1); |
| 12296 | return self.debugForwardReferenceAssumeCapacity(); | |
| 12427 | return self.metadataForwardReferenceAssumeCapacity(); | |
| 12297 | 12428 | } |
| 12298 | 12429 | |
| 12299 | 12430 | pub fn debugStructType( |
| ... | ... | @@ -12521,15 +12652,8 @@ pub fn debugExpression(self: *Builder, elements: []const u32) Allocator.Error!Me |
| 12521 | 12652 | } |
| 12522 | 12653 | |
| 12523 | 12654 | pub fn metadataTuple(self: *Builder, elements: []const Metadata) Allocator.Error!Metadata { |
| 12524 | return self.metadataTupleOptionals(@ptrCast(elements)); | |
| 12525 | } | |
| 12526 | ||
| 12527 | pub fn metadataTupleOptionals( | |
| 12528 | self: *Builder, | |
| 12529 | elements: []const Metadata.Optional, | |
| 12530 | ) Allocator.Error!Metadata { | |
| 12531 | 12655 | try self.ensureUnusedMetadataCapacity(1, Metadata.Tuple, elements.len); |
| 12532 | return self.metadataTupleOptionalsAssumeCapacity(elements); | |
| 12656 | return self.metadataTupleAssumeCapacity(elements); | |
| 12533 | 12657 | } |
| 12534 | 12658 | |
| 12535 | 12659 | pub fn debugLocalVar( |
| ... | ... | @@ -12595,9 +12719,12 @@ pub fn metadataConstant(self: *Builder, value: Constant) Allocator.Error!Metadat |
| 12595 | 12719 | return self.metadataConstantAssumeCapacity(value); |
| 12596 | 12720 | } |
| 12597 | 12721 | |
| 12722 | /// Deprecated, use `resolveMetadataForwardReference`. | |
| 12723 | pub const resolveDebugForwardReference = resolveMetadataForwardReference; | |
| 12724 | ||
| 12598 | 12725 | /// Resolves the given forward reference to the given value (which is not itself a forward |
| 12599 | 12726 | /// reference). If the forward reference is already resolved, its target is replaced. |
| 12600 | pub fn resolveDebugForwardReference(self: *Builder, fwd_ref: Metadata, value: Metadata) void { | |
| 12727 | pub fn resolveMetadataForwardReference(self: *Builder, fwd_ref: Metadata, value: Metadata) void { | |
| 12601 | 12728 | assert(fwd_ref.kind == .forward); |
| 12602 | 12729 | assert(value.kind != .forward); |
| 12603 | 12730 | self.metadata_forward_references.items[fwd_ref.index] = value.toOptional(); |
| ... | ... | @@ -12790,8 +12917,7 @@ fn debugFloatTypeAssumeCapacity(self: *Builder, name: ?Metadata.String, size_in_ |
| 12790 | 12917 | }); |
| 12791 | 12918 | } |
| 12792 | 12919 | |
| 12793 | fn debugForwardReferenceAssumeCapacity(self: *Builder) Metadata { | |
| 12794 | assert(!self.strip); | |
| 12920 | fn metadataForwardReferenceAssumeCapacity(self: *Builder) Metadata { | |
| 12795 | 12921 | const index = self.metadata_forward_references.items.len; |
| 12796 | 12922 | self.metadata_forward_references.appendAssumeCapacity(.none); |
| 12797 | 12923 | return .{ .index = @intCast(index), .kind = .forward }; |
| ... | ... | @@ -13164,9 +13290,9 @@ fn debugExpressionAssumeCapacity(self: *Builder, elements: []const u32) Metadata |
| 13164 | 13290 | return .{ .index = @intCast(gop.index), .kind = .node }; |
| 13165 | 13291 | } |
| 13166 | 13292 | |
| 13167 | fn metadataTupleOptionalsAssumeCapacity(self: *Builder, elements: []const Metadata.Optional) Metadata { | |
| 13293 | fn metadataTupleAssumeCapacity(self: *Builder, elements: []const Metadata) Metadata { | |
| 13168 | 13294 | const Key = struct { |
| 13169 | elements: []const Metadata.Optional, | |
| 13295 | elements: []const Metadata, | |
| 13170 | 13296 | }; |
| 13171 | 13297 | const Adapter = struct { |
| 13172 | 13298 | builder: *const Builder, |
| ... | ... | @@ -13181,9 +13307,9 @@ fn metadataTupleOptionalsAssumeCapacity(self: *Builder, elements: []const Metada |
| 13181 | 13307 | const rhs_data = ctx.builder.metadata_items.items(.data)[rhs_index]; |
| 13182 | 13308 | var rhs_extra = ctx.builder.metadataExtraDataTrail(Metadata.Tuple, rhs_data); |
| 13183 | 13309 | return std.mem.eql( |
| 13184 | Metadata.Optional, | |
| 13310 | Metadata, | |
| 13185 | 13311 | lhs_key.elements, |
| 13186 | rhs_extra.trail.next(rhs_extra.data.elements_len, Metadata.Optional, ctx.builder), | |
| 13312 | rhs_extra.trail.next(rhs_extra.data.elements_len, Metadata, ctx.builder), | |
| 13187 | 13313 | ); |
| 13188 | 13314 | } |
| 13189 | 13315 | }; |
| ... | ... | @@ -13949,7 +14075,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco |
| 13949 | 14075 | .positive_integer, |
| 13950 | 14076 | .negative_integer, |
| 13951 | 14077 | => |tag| { |
| 13952 | const extra: *align(@alignOf(std.math.big.Limb)) Constant.Integer = | |
| 14078 | const extra: *align(@alignOf(std.math.big.Limb)) const Constant.Integer = | |
| 13953 | 14079 | @ptrCast(self.constant_limbs.items[data..][0..Constant.Integer.limbs]); |
| 13954 | 14080 | const bigint: std.math.big.int.Const = .{ |
| 13955 | 14081 | .limbs = self.constant_limbs |
| ... | ... | @@ -15109,7 +15235,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco |
| 15109 | 15235 | .ty = extra.type, |
| 15110 | 15236 | .alignment = extra.info.alignment.toLlvm(), |
| 15111 | 15237 | .is_volatile = extra.info.access_kind == .@"volatile", |
| 15112 | .success_ordering = extra.info.success_ordering, | |
| 15238 | .ordering = extra.info.ordering, | |
| 15113 | 15239 | .sync_scope = extra.info.sync_scope, |
| 15114 | 15240 | }); |
| 15115 | 15241 | }, |
| ... | ... | @@ -15129,7 +15255,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco |
| 15129 | 15255 | .val = adapter.getOffsetValueIndex(extra.val), |
| 15130 | 15256 | .alignment = extra.info.alignment.toLlvm(), |
| 15131 | 15257 | .is_volatile = extra.info.access_kind == .@"volatile", |
| 15132 | .success_ordering = extra.info.success_ordering, | |
| 15258 | .ordering = extra.info.ordering, | |
| 15133 | 15259 | .sync_scope = extra.info.sync_scope, |
| 15134 | 15260 | }); |
| 15135 | 15261 | }, |
| ... | ... | @@ -15212,18 +15338,15 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco |
| 15212 | 15338 | try function_block.writeAbbrev(FunctionBlock.AtomicRmw{ |
| 15213 | 15339 | .ptr = adapter.getOffsetValueIndex(extra.ptr), |
| 15214 | 15340 | .val = adapter.getOffsetValueIndex(extra.val), |
| 15215 | .operation = extra.info.atomic_rmw_operation, | |
| 15341 | .operation = extra.info.operation, | |
| 15216 | 15342 | .is_volatile = extra.info.access_kind == .@"volatile", |
| 15217 | .success_ordering = extra.info.success_ordering, | |
| 15343 | .ordering = extra.info.ordering, | |
| 15218 | 15344 | .sync_scope = extra.info.sync_scope, |
| 15219 | 15345 | .alignment = extra.info.alignment.toLlvm(), |
| 15220 | 15346 | }); |
| 15221 | 15347 | }, |
| 15222 | .cmpxchg, | |
| 15223 | .@"cmpxchg weak", | |
| 15224 | => |kind| { | |
| 15348 | .cmpxchg => { | |
| 15225 | 15349 | const extra = func.extraData(Function.Instruction.CmpXchg, data); |
| 15226 | ||
| 15227 | 15350 | try function_block.writeAbbrev(FunctionBlock.CmpXchg{ |
| 15228 | 15351 | .ptr = adapter.getOffsetValueIndex(extra.ptr), |
| 15229 | 15352 | .cmp = adapter.getOffsetValueIndex(extra.cmp), |
| ... | ... | @@ -15232,15 +15355,15 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco |
| 15232 | 15355 | .success_ordering = extra.info.success_ordering, |
| 15233 | 15356 | .sync_scope = extra.info.sync_scope, |
| 15234 | 15357 | .failure_ordering = extra.info.failure_ordering, |
| 15235 | .is_weak = kind == .@"cmpxchg weak", | |
| 15358 | .is_weak = extra.info.kind == .weak, | |
| 15236 | 15359 | .alignment = extra.info.alignment.toLlvm(), |
| 15237 | 15360 | }); |
| 15238 | 15361 | }, |
| 15239 | 15362 | .fence => { |
| 15240 | const info: MemoryAccessInfo = @bitCast(data); | |
| 15363 | const fence: Function.Instruction.Fence = @bitCast(data); | |
| 15241 | 15364 | try function_block.writeAbbrev(FunctionBlock.Fence{ |
| 15242 | .ordering = info.success_ordering, | |
| 15243 | .sync_scope = info.sync_scope, | |
| 15365 | .ordering = fence.success_ordering, | |
| 15366 | .sync_scope = fence.sync_scope, | |
| 15244 | 15367 | }); |
| 15245 | 15368 | }, |
| 15246 | 15369 | } |
| ... | ... | @@ -15313,17 +15436,58 @@ pub fn toBitcode(self: *Builder, allocator: Allocator, producer: Producer) bitco |
| 15313 | 15436 | }; |
| 15314 | 15437 | switch (weights) { |
| 15315 | 15438 | .none => {}, |
| 15316 | .unpredictable => try metadata_attach_block.writeAbbrevAdapted(MetadataAttachmentBlock.AttachmentInstructionSingle{ | |
| 15439 | .unpredictable => try metadata_attach_block.writeAbbrevAdapted( | |
| 15440 | MetadataAttachmentBlock.AttachmentInstructionSingle{ | |
| 15441 | .inst = instr_index, | |
| 15442 | .kind = .unpredictable, | |
| 15443 | .metadata = .empty_tuple, | |
| 15444 | }, | |
| 15445 | metadata_adapter, | |
| 15446 | ), | |
| 15447 | _ => try metadata_attach_block.writeAbbrevAdapted( | |
| 15448 | MetadataAttachmentBlock.AttachmentInstructionSingle{ | |
| 15449 | .inst = instr_index, | |
| 15450 | .kind = .prof, | |
| 15451 | .metadata = weights.toMetadata(), | |
| 15452 | }, | |
| 15453 | metadata_adapter, | |
| 15454 | ), | |
| 15455 | } | |
| 15456 | instr_index += 1; | |
| 15457 | }, | |
| 15458 | .call, | |
| 15459 | .@"call fast", | |
| 15460 | .@"musttail call", | |
| 15461 | .@"musttail call fast", | |
| 15462 | .@"notail call", | |
| 15463 | .@"notail call fast", | |
| 15464 | .@"tail call", | |
| 15465 | .@"tail call fast", | |
| 15466 | => { | |
| 15467 | var extra = func.extraDataTrail(Function.Instruction.Call, data); | |
| 15468 | _ = extra.trail.next(extra.data.args_len, Value, &func); | |
| 15469 | const callees = extra.trail.next(@intFromBool(extra.data.info.has_callees), Metadata, &func); | |
| 15470 | for (callees) |metadata| try metadata_attach_block.writeAbbrevAdapted( | |
| 15471 | MetadataAttachmentBlock.AttachmentInstructionSingle{ | |
| 15317 | 15472 | .inst = instr_index, |
| 15318 | .kind = .unpredictable, | |
| 15319 | .metadata = .empty_tuple, | |
| 15320 | }, metadata_adapter), | |
| 15321 | _ => try metadata_attach_block.writeAbbrevAdapted(MetadataAttachmentBlock.AttachmentInstructionSingle{ | |
| 15473 | .kind = .callees, | |
| 15474 | .metadata = metadata, | |
| 15475 | }, | |
| 15476 | metadata_adapter, | |
| 15477 | ); | |
| 15478 | instr_index += 1; | |
| 15479 | }, | |
| 15480 | .load, .@"load atomic" => { | |
| 15481 | var extra = func.extraDataTrail(Function.Instruction.Load, data); | |
| 15482 | const range = extra.trail.next(@intFromBool(extra.data.info.has_range), Metadata, &func); | |
| 15483 | for (range) |metadata| if (metadata.unwrap(self) != Metadata.empty_tuple) try metadata_attach_block.writeAbbrevAdapted( | |
| 15484 | MetadataAttachmentBlock.AttachmentInstructionSingle{ | |
| 15322 | 15485 | .inst = instr_index, |
| 15323 | .kind = .prof, | |
| 15324 | .metadata = weights.toMetadata(), | |
| 15325 | }, metadata_adapter), | |
| 15326 | } | |
| 15486 | .kind = .range, | |
| 15487 | .metadata = metadata, | |
| 15488 | }, | |
| 15489 | metadata_adapter, | |
| 15490 | ); | |
| 15327 | 15491 | instr_index += 1; |
| 15328 | 15492 | }, |
| 15329 | 15493 | }; |
lib/std/zig/llvm/ir.zig+5-5| ... | ... | @@ -79,7 +79,7 @@ pub const FixedMetadataKind = enum(u6) { |
| 79 | 79 | //tbaa = 1, |
| 80 | 80 | prof = 2, |
| 81 | 81 | //fpmath = 3, |
| 82 | //range = 4, | |
| 82 | range = 4, | |
| 83 | 83 | //@"tbaa.struct" = 5, |
| 84 | 84 | //@"invariant.load" = 6, |
| 85 | 85 | //@"alias.scope" = 7, |
| ... | ... | @@ -98,7 +98,7 @@ pub const FixedMetadataKind = enum(u6) { |
| 98 | 98 | //section_prefix = 20, |
| 99 | 99 | //absolute_symbol = 21, |
| 100 | 100 | //associated = 22, |
| 101 | //callees = 23, | |
| 101 | callees = 23, | |
| 102 | 102 | //irr_loop = 24, |
| 103 | 103 | //@"llvm.access.group" = 25, |
| 104 | 104 | //callback = 26, |
| ... | ... | @@ -1232,7 +1232,7 @@ pub const ModuleBlock = struct { |
| 1232 | 1232 | ty: Builder.Type, |
| 1233 | 1233 | alignment: std.meta.Int(.unsigned, @bitSizeOf(Builder.Alignment)), |
| 1234 | 1234 | is_volatile: bool, |
| 1235 | success_ordering: Builder.AtomicOrdering, | |
| 1235 | ordering: Builder.AtomicOrdering, | |
| 1236 | 1236 | sync_scope: Builder.SyncScope, |
| 1237 | 1237 | }; |
| 1238 | 1238 | |
| ... | ... | @@ -1264,7 +1264,7 @@ pub const ModuleBlock = struct { |
| 1264 | 1264 | val: u32, |
| 1265 | 1265 | alignment: std.meta.Int(.unsigned, @bitSizeOf(Builder.Alignment)), |
| 1266 | 1266 | is_volatile: bool, |
| 1267 | success_ordering: Builder.AtomicOrdering, | |
| 1267 | ordering: Builder.AtomicOrdering, | |
| 1268 | 1268 | sync_scope: Builder.SyncScope, |
| 1269 | 1269 | }; |
| 1270 | 1270 | |
| ... | ... | @@ -1315,7 +1315,7 @@ pub const ModuleBlock = struct { |
| 1315 | 1315 | val: u32, |
| 1316 | 1316 | operation: Builder.Function.Instruction.AtomicRmw.Operation, |
| 1317 | 1317 | is_volatile: bool, |
| 1318 | success_ordering: Builder.AtomicOrdering, | |
| 1318 | ordering: Builder.AtomicOrdering, | |
| 1319 | 1319 | sync_scope: Builder.SyncScope, |
| 1320 | 1320 | alignment: std.meta.Int(.unsigned, @bitSizeOf(Builder.Alignment)), |
| 1321 | 1321 | }; |
src/InternPool.zig+5-2| ... | ... | @@ -7998,7 +7998,7 @@ pub fn get(ip: *InternPool, gpa: Allocator, io: Io, tid: Zcu.PerThread.Id, key: |
| 7998 | 7998 | }); |
| 7999 | 7999 | }, |
| 8000 | 8000 | .restricted_value => |restricted_value| { |
| 8001 | assert(restricted_value.ty.unwrap(ip).getTag(ip) == .type_restricted); | |
| 8001 | assert(ip.isRestrictedType(restricted_value.ty)); | |
| 8002 | 8002 | assert(!ip.isUndef(restricted_value.unrestricted_value)); |
| 8003 | 8003 | items.appendAssumeCapacity(.{ |
| 8004 | 8004 | .tag = .restricted_value, |
| ... | ... | @@ -9019,7 +9019,10 @@ pub fn getUnion( |
| 9019 | 9019 | ) Allocator.Error!Index { |
| 9020 | 9020 | assert(un.ty != .none); |
| 9021 | 9021 | assert(un.val != .none); |
| 9022 | assert(ip.loadUnionType(un.ty).layout != .@"packed"); | |
| 9022 | ||
| 9023 | const loaded_union = ip.loadUnionType(un.ty); | |
| 9024 | assert(loaded_union.layout != .@"packed"); | |
| 9025 | assert(loaded_union.enum_tag_type == ip.typeOf(un.tag)); | |
| 9023 | 9026 | |
| 9024 | 9027 | var gop = try ip.getOrPutKey(gpa, io, tid, .{ .un = un }); |
| 9025 | 9028 | defer gop.deinit(); |
src/Sema.zig+41-18| ... | ... | @@ -10053,6 +10053,7 @@ fn analyzeSwitchBlock( |
| 10053 | 10053 | ) CompileError!?Air.Inst.Ref { |
| 10054 | 10054 | const pt = sema.pt; |
| 10055 | 10055 | const zcu = pt.zcu; |
| 10056 | const ip = &zcu.intern_pool; | |
| 10056 | 10057 | const gpa = sema.gpa; |
| 10057 | 10058 | |
| 10058 | 10059 | const src_node_offset = zir_switch.switch_src_node_offset; |
| ... | ... | @@ -10076,7 +10077,13 @@ fn analyzeSwitchBlock( |
| 10076 | 10077 | operand_ty.containerLayout(zcu) != .@"packed") |
| 10077 | 10078 | { |
| 10078 | 10079 | const tag_val = try sema.unionToTag(block, val); |
| 10079 | break :init .{ tag_val, sema.typeOf(tag_val) }; | |
| 10080 | const tag_ty = sema.typeOf(tag_val); | |
| 10081 | const unrestricted_tag_ty = tag_ty.unrestrictedType(zcu) orelse tag_ty; | |
| 10082 | const unrestricted_tag_val = if (unrestricted_tag_ty.toIntern() != tag_ty.toIntern()) | |
| 10083 | try sema.unwrapRestricted(block, unrestricted_tag_ty, tag_val, src) | |
| 10084 | else | |
| 10085 | tag_val; | |
| 10086 | break :init .{ unrestricted_tag_val, unrestricted_tag_ty }; | |
| 10080 | 10087 | } |
| 10081 | 10088 | break :init .{ |
| 10082 | 10089 | if (maybe_operand_opv) |operand_opv| .fromValue(operand_opv) else val, |
| ... | ... | @@ -10269,7 +10276,7 @@ fn analyzeSwitchBlock( |
| 10269 | 10276 | break :item_val item_opv; |
| 10270 | 10277 | } |
| 10271 | 10278 | if (maybe_operand_opv) |operand_opv| { |
| 10272 | break :item_val .fromInterned(zcu.intern_pool.indexToKey(operand_opv.toIntern()).un.val); | |
| 10279 | break :item_val .fromInterned(ip.indexToKey(operand_opv.toIntern()).un.val); | |
| 10273 | 10280 | } |
| 10274 | 10281 | assert(zir_switch.any_maybe_runtime_capture); // there's a payload capture |
| 10275 | 10282 | const operand_val, const operand_ref = switch (operand) { |
| ... | ... | @@ -11211,7 +11218,8 @@ fn validateSwitchBlock( |
| 11211 | 11218 | const union_obj = ip.loadUnionType(operand_ty.toIntern()); |
| 11212 | 11219 | switch (union_obj.tag_usage) { |
| 11213 | 11220 | .tagged => { |
| 11214 | break :item_ty .fromInterned(union_obj.enum_tag_type); | |
| 11221 | const enum_tag_ty: Type = .fromInterned(union_obj.enum_tag_type); | |
| 11222 | break :item_ty enum_tag_ty.unrestrictedType(zcu) orelse enum_tag_ty; | |
| 11215 | 11223 | }, |
| 11216 | 11224 | .none => { |
| 11217 | 11225 | if (union_obj.layout == .@"packed") { |
| ... | ... | @@ -16636,7 +16644,8 @@ fn zirTypeInfo(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Ai |
| 16636 | 16644 | const union_field_ty = try sema.getBuiltinType(src, .@"Type.UnionField"); |
| 16637 | 16645 | |
| 16638 | 16646 | const union_obj = ip.loadUnionType(unrestricted_ty.toIntern()); |
| 16639 | const enum_obj = ip.loadEnumType(union_obj.enum_tag_type); | |
| 16647 | const enum_tag_ty: Type = .fromInterned(union_obj.enum_tag_type); | |
| 16648 | const enum_obj = ip.loadEnumType((enum_tag_ty.unrestrictedType(zcu) orelse enum_tag_ty).toIntern()); | |
| 16640 | 16649 | const layout = union_obj.layout; |
| 16641 | 16650 | |
| 16642 | 16651 | const union_field_vals = try gpa.alloc(InternPool.Index, enum_obj.field_names.len); |
| ... | ... | @@ -18220,7 +18229,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 18220 | 18229 | break :blk ty; |
| 18221 | 18230 | }; |
| 18222 | 18231 | |
| 18223 | if (elem_ty.zigTypeTag(zcu) == .noreturn) | |
| 18232 | if (elem_ty.toIntern() == .noreturn_type) | |
| 18224 | 18233 | return sema.fail(block, elem_ty_src, "pointer to noreturn not allowed", .{}); |
| 18225 | 18234 | |
| 18226 | 18235 | const target = zcu.getTarget(); |
| ... | ... | @@ -18253,7 +18262,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 18253 | 18262 | const ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_i]); |
| 18254 | 18263 | extra_i += 1; |
| 18255 | 18264 | break :blk try sema.resolveAddressSpace(block, addrspace_src, ref, .pointer); |
| 18256 | } else if (elem_ty.zigTypeTag(zcu) == .@"fn" and target.cpu.arch == .avr) .flash else .generic; | |
| 18265 | } else if (target.cpu.arch == .avr and ip.isFunctionType(elem_ty.toIntern())) .flash else .generic; | |
| 18257 | 18266 | |
| 18258 | 18267 | const bit_offset: u16 = if (inst_data.flags.has_bit_range) blk: { |
| 18259 | 18268 | const ref: Zir.Inst.Ref = @enumFromInt(sema.code.extra[extra_i]); |
| ... | ... | @@ -18284,7 +18293,7 @@ fn zirPtrType(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air |
| 18284 | 18293 | } |
| 18285 | 18294 | } |
| 18286 | 18295 | |
| 18287 | if (elem_ty.zigTypeTag(zcu) == .@"fn") { | |
| 18296 | if (ip.isFunctionType(elem_ty.toIntern())) { | |
| 18288 | 18297 | if (inst_data.size != .one) { |
| 18289 | 18298 | return sema.fail(block, elem_ty_src, "function pointers must be single pointers", .{}); |
| 18290 | 18299 | } |
| ... | ... | @@ -18594,7 +18603,8 @@ fn zirStructInit( |
| 18594 | 18603 | ); |
| 18595 | 18604 | const field_index = try sema.unionFieldIndex(block, resolved_ty, field_name, field_src); |
| 18596 | 18605 | const tag_ty = resolved_ty.unionTagTypeHypothetical(zcu); |
| 18597 | const tag_val = try pt.enumValueFieldIndex(tag_ty, field_index); | |
| 18606 | const unrestricted_tag_ty = tag_ty.unrestrictedType(zcu) orelse tag_ty; | |
| 18607 | const tag_val = try pt.enumValueFieldIndex(unrestricted_tag_ty, field_index); | |
| 18598 | 18608 | const field_ty: Type = .fromInterned(zcu.typeToUnion(resolved_ty).?.field_types.get(ip)[field_index]); |
| 18599 | 18609 | |
| 18600 | 18610 | if (field_ty.classify(zcu) == .no_possible_value) { |
| ... | ... | @@ -18626,7 +18636,10 @@ fn zirStructInit( |
| 18626 | 18636 | if (sema.resolveValue(init_inst)) |val| { |
| 18627 | 18637 | const struct_val = Value.fromInterned(try pt.internUnion(.{ |
| 18628 | 18638 | .ty = resolved_ty.toIntern(), |
| 18629 | .tag = tag_val.toIntern(), | |
| 18639 | .tag = if (unrestricted_tag_ty.toIntern() != tag_ty.toIntern()) | |
| 18640 | try pt.intern(.{ .restricted_value = .{ .ty = tag_ty.toIntern(), .unrestricted_value = tag_val.toIntern() } }) | |
| 18641 | else | |
| 18642 | tag_val.toIntern(), | |
| 18630 | 18643 | .val = val.toIntern(), |
| 18631 | 18644 | })); |
| 18632 | 18645 | const final_val_inst = try sema.coerce(block, result_ty, Air.internedToRef(struct_val.toIntern()), src); |
| ... | ... | @@ -19358,7 +19371,8 @@ fn fieldType( |
| 19358 | 19371 | }, |
| 19359 | 19372 | .@"union" => { |
| 19360 | 19373 | const union_obj = zcu.typeToUnion(cur_ty).?; |
| 19361 | const enum_obj = ip.loadEnumType(union_obj.enum_tag_type); | |
| 19374 | const enum_tag_ty: Type = .fromInterned(union_obj.enum_tag_type); | |
| 19375 | const enum_obj = ip.loadEnumType((enum_tag_ty.unrestrictedType(zcu) orelse enum_tag_ty).toIntern()); | |
| 19362 | 19376 | const field_index = enum_obj.nameIndex(ip, field_name) orelse |
| 19363 | 19377 | return sema.failWithBadUnionFieldAccess(block, cur_ty, union_obj, field_src, field_name); |
| 19364 | 19378 | const field_ty = union_obj.field_types.get(ip)[field_index]; |
| ... | ... | @@ -26604,6 +26618,7 @@ fn unionFieldPtr( |
| 26604 | 26618 | |
| 26605 | 26619 | const union_obj = zcu.typeToUnion(union_ty).?; |
| 26606 | 26620 | const tag_ty: Type = .fromInterned(union_obj.enum_tag_type); |
| 26621 | const unrestricted_tag_ty = tag_ty.unrestrictedType(zcu) orelse tag_ty; | |
| 26607 | 26622 | |
| 26608 | 26623 | const field_index = try sema.unionFieldIndex(block, union_ty, field_name, field_name_src); |
| 26609 | 26624 | const field_ty: Type = .fromInterned(union_obj.field_types.get(ip)[field_index]); |
| ... | ... | @@ -26630,17 +26645,17 @@ fn unionFieldPtr( |
| 26630 | 26645 | break :ct; |
| 26631 | 26646 | } |
| 26632 | 26647 | // Store to the union to initialize the tag. |
| 26633 | const field_tag = try pt.enumValueFieldIndex(tag_ty, field_index); | |
| 26648 | const field_tag = try pt.enumValueFieldIndex(unrestricted_tag_ty, field_index); | |
| 26634 | 26649 | const payload_val = try field_ty.onePossibleValue(pt) orelse try pt.undefValue(field_ty); |
| 26635 | 26650 | const new_union_val = try pt.unionValue(union_ty, field_tag, payload_val); |
| 26636 | 26651 | try sema.storePtrVal(block, src, union_ptr_val, new_union_val, union_ty); |
| 26637 | 26652 | } else { |
| 26638 | 26653 | const union_val = try sema.pointerDeref(block, src, union_ptr_val, union_ptr_val.typeOf(zcu)) orelse break :ct; |
| 26639 | 26654 | if (union_val.isUndef(zcu)) return sema.failWithUseOfUndef(block, src, null); |
| 26640 | const active_index = tag_ty.enumTagFieldIndex(union_val.unionTag(zcu).?, zcu).?; | |
| 26655 | const active_index = unrestricted_tag_ty.enumTagFieldIndex(union_val.unionTag(zcu).?, zcu).?; | |
| 26641 | 26656 | if (active_index != field_index) { |
| 26642 | 26657 | const msg = msg: { |
| 26643 | const active_field_name = tag_ty.enumFieldName(active_index, zcu); | |
| 26658 | const active_field_name = unrestricted_tag_ty.enumFieldName(active_index, zcu); | |
| 26644 | 26659 | const msg = try sema.errMsg(src, "access of union field '{f}' while field '{f}' is active", .{ |
| 26645 | 26660 | field_name.fmt(ip), |
| 26646 | 26661 | active_field_name.fmt(ip), |
| ... | ... | @@ -26660,19 +26675,26 @@ fn unionFieldPtr( |
| 26660 | 26675 | // If the union has a tag, we must either set or or safety check it depending on `initializing`. |
| 26661 | 26676 | tag: { |
| 26662 | 26677 | if (union_ty.containerLayout(zcu) != .auto) break :tag; |
| 26663 | if (tag_ty.classify(zcu) == .one_possible_value) break :tag; | |
| 26678 | if (unrestricted_tag_ty.classify(zcu) == .one_possible_value) break :tag; | |
| 26664 | 26679 | // There is a hypothetical non-trivial tag. We must set it even if not there at runtime, but |
| 26665 | 26680 | // only emit a safety check if it's available at runtime (i.e. it's safety-tagged). |
| 26666 | const want_tag = try pt.enumValueFieldIndex(tag_ty, field_index); | |
| 26681 | const want_tag = try pt.enumValueFieldIndex(unrestricted_tag_ty, field_index); | |
| 26667 | 26682 | if (initializing) { |
| 26668 | const set_tag_inst = try block.addBinOp(.set_union_tag, union_ptr, .fromValue(want_tag)); | |
| 26683 | const set_tag_inst = try block.addBinOp(.set_union_tag, union_ptr, if (unrestricted_tag_ty.toIntern() != tag_ty.toIntern()) | |
| 26684 | .fromIntern(try pt.intern(.{ .restricted_value = .{ .ty = tag_ty.toIntern(), .unrestricted_value = want_tag.toIntern() } })) | |
| 26685 | else | |
| 26686 | .fromValue(want_tag)); | |
| 26669 | 26687 | try sema.checkComptimeKnownStore(block, set_tag_inst, .unneeded); // `unneeded` since this isn't a "proper" store |
| 26670 | 26688 | } else if (block.wantSafety() and union_obj.has_runtime_tag) { |
| 26671 | 26689 | // The tag exists at runtime (actual or safety tag), so emit a safety check. |
| 26672 | 26690 | // TODO would it be better if get_union_tag supported pointers to unions? |
| 26673 | 26691 | const union_val = try block.addTyOp(.load, union_ty, union_ptr); |
| 26674 | 26692 | const active_tag = try block.addTyOp(.get_union_tag, tag_ty, union_val); |
| 26675 | try sema.addSafetyCheckInactiveUnionField(block, src, active_tag, .fromValue(want_tag)); | |
| 26693 | const unrestricted_active_tag = if (unrestricted_tag_ty.toIntern() != tag_ty.toIntern()) | |
| 26694 | try sema.unwrapRestricted(block, unrestricted_tag_ty, active_tag, src) | |
| 26695 | else | |
| 26696 | active_tag; | |
| 26697 | try sema.addSafetyCheckInactiveUnionField(block, src, unrestricted_active_tag, .fromValue(want_tag)); | |
| 26676 | 26698 | } |
| 26677 | 26699 | } |
| 26678 | 26700 | if (field_ty.classify(zcu) == .no_possible_value) { |
| ... | ... | @@ -33539,7 +33561,8 @@ fn unionFieldIndex( |
| 33539 | 33561 | const zcu = pt.zcu; |
| 33540 | 33562 | const ip = &zcu.intern_pool; |
| 33541 | 33563 | const union_obj = zcu.typeToUnion(union_ty).?; |
| 33542 | const enum_obj = ip.loadEnumType(union_obj.enum_tag_type); | |
| 33564 | const enum_tag_ty: Type = .fromInterned(union_obj.enum_tag_type); | |
| 33565 | const enum_obj = ip.loadEnumType((enum_tag_ty.unrestrictedType(zcu) orelse enum_tag_ty).toIntern()); | |
| 33543 | 33566 | const field_index = enum_obj.nameIndex(ip, field_name) orelse |
| 33544 | 33567 | return sema.failWithBadUnionFieldAccess(block, union_ty, union_obj, field_src, field_name); |
| 33545 | 33568 | return @intCast(field_index); |
src/Sema/type_resolution.zig+5-3| ... | ... | @@ -694,8 +694,9 @@ pub fn resolveUnionLayout(sema: *Sema, union_ty: Type) CompileError!void { |
| 694 | 694 | break :tag_ty try sema.analyzeAsType(&block, tag_type_src, .union_enum_tag_type, type_ref); |
| 695 | 695 | }, |
| 696 | 696 | }; |
| 697 | const unrestricted_tag_ty = tag_ty.unrestrictedType(zcu) orelse tag_ty; | |
| 697 | 698 | // Because the type is explicitly specified, we need to validate it. |
| 698 | if (tag_ty.zigTypeTag(zcu) != .@"enum") return sema.fail( | |
| 699 | if (unrestricted_tag_ty.zigTypeTag(zcu) != .@"enum") return sema.fail( | |
| 699 | 700 | &block, |
| 700 | 701 | block.src(.container_arg), |
| 701 | 702 | "expected enum tag type, found '{f}'", |
| ... | ... | @@ -738,9 +739,10 @@ pub fn resolveUnionLayout(sema: *Sema, union_ty: Type) CompileError!void { |
| 738 | 739 | }, |
| 739 | 740 | }, |
| 740 | 741 | }; |
| 742 | const unrestricted_enum_tag_ty = enum_tag_ty.unrestrictedType(zcu) orelse enum_tag_ty; | |
| 741 | 743 | |
| 742 | try sema.ensureLayoutResolved(enum_tag_ty, block.src(.container_arg), .backing_enum); | |
| 743 | const enum_obj = ip.loadEnumType(enum_tag_ty.toIntern()); | |
| 744 | try sema.ensureLayoutResolved(unrestricted_enum_tag_ty, block.src(.container_arg), .backing_enum); | |
| 745 | const enum_obj = ip.loadEnumType(unrestricted_enum_tag_ty.toIntern()); | |
| 744 | 746 | |
| 745 | 747 | if (union_obj.is_reified) { |
| 746 | 748 | // We have field names in `union_obj.reified_field_names`, but we haven't |
src/Type.zig+1-1| ... | ... | @@ -3241,7 +3241,7 @@ pub fn validateExtern(ty: Type, position: ExternPosition, zcu: *const Zcu) bool |
| 3241 | 3241 | .pointer => { |
| 3242 | 3242 | if (ty.isSlice(zcu)) return false; |
| 3243 | 3243 | const child_ty = ty.childType(zcu); |
| 3244 | if (child_ty.zigTypeTag(zcu) == .@"fn") { | |
| 3244 | if (zcu.intern_pool.isFunctionType(child_ty.toIntern())) { | |
| 3245 | 3245 | return ty.isConstPtr(zcu) and validateExternCallconv(child_ty.fnCallingConvention(zcu)); |
| 3246 | 3246 | } |
| 3247 | 3247 | return true; |
src/Zcu.zig+8-3| ... | ... | @@ -4165,9 +4165,14 @@ pub const UnionLayout = struct { |
| 4165 | 4165 | pub fn unionTagFieldIndex(zcu: *const Zcu, loaded_union: InternPool.LoadedUnionType, enum_tag: Value) ?u32 { |
| 4166 | 4166 | const ip = &zcu.intern_pool; |
| 4167 | 4167 | if (enum_tag.toIntern() == .none) return null; |
| 4168 | const enum_tag_key = ip.indexToKey(enum_tag.toIntern()).enum_tag; | |
| 4169 | assert(enum_tag_key.ty == loaded_union.enum_tag_type); | |
| 4170 | const loaded_enum = ip.loadEnumType(loaded_union.enum_tag_type); | |
| 4168 | const enum_tag_key = switch (ip.indexToKey(enum_tag.toIntern())) { | |
| 4169 | else => unreachable, | |
| 4170 | .enum_tag => |enum_tag_key| enum_tag_key, | |
| 4171 | .restricted_value => |restricted_value| ip.indexToKey(restricted_value.unrestricted_value).enum_tag, | |
| 4172 | }; | |
| 4173 | const enum_tag_ty: Type = .fromInterned(loaded_union.enum_tag_type); | |
| 4174 | assert(enum_tag_key.ty == (enum_tag_ty.unrestrictedType(zcu) orelse enum_tag_ty).toIntern()); | |
| 4175 | const loaded_enum = ip.loadEnumType(enum_tag_key.ty); | |
| 4171 | 4176 | return loaded_enum.tagValueIndex(ip, enum_tag_key.int); |
| 4172 | 4177 | } |
| 4173 | 4178 |
src/codegen/llvm.zig+114-31| ... | ... | @@ -626,8 +626,8 @@ pub const Object = struct { |
| 626 | 626 | try builder.metadataString(compile_unit_dir), |
| 627 | 627 | ); |
| 628 | 628 | |
| 629 | const debug_enums_fwd_ref = try builder.debugForwardReference(); | |
| 630 | const debug_globals_fwd_ref = try builder.debugForwardReference(); | |
| 629 | const debug_enums_fwd_ref = try builder.metadataForwardReference(); | |
| 630 | const debug_globals_fwd_ref = try builder.metadataForwardReference(); | |
| 631 | 631 | |
| 632 | 632 | const debug_compile_unit = try builder.debugCompileUnit( |
| 633 | 633 | debug_file, |
| ... | ... | @@ -701,9 +701,12 @@ pub const Object = struct { |
| 701 | 701 | const RestrictedDecls = struct { |
| 702 | 702 | len: Builder.Variable.Index, |
| 703 | 703 | array: Builder.Variable.Index, |
| 704 | enum_seen: []const Builder.Variable.Index, | |
| 704 | 705 | values: std.array_hash_map.Auto(InternPool.Index, Builder.Constant), |
| 706 | metadata: Builder.Metadata.Optional, | |
| 705 | 707 | |
| 706 | 708 | fn deinit(rd: *RestrictedDecls, gpa: Allocator) void { |
| 709 | gpa.free(rd.enum_seen); | |
| 707 | 710 | rd.values.deinit(gpa); |
| 708 | 711 | rd.* = undefined; |
| 709 | 712 | } |
| ... | ... | @@ -716,7 +719,8 @@ pub const Object = struct { |
| 716 | 719 | const zcu = o.zcu; |
| 717 | 720 | const target = zcu.getTarget(); |
| 718 | 721 | const ip = &zcu.intern_pool; |
| 719 | const unrestricted_ty = restricted_ty.unrestrictedType(zcu).?; | |
| 722 | const restricted_type_key = ip.indexToKey(restricted_ty.toIntern()).restricted_type; | |
| 723 | const unrestricted_type = restricted_type_key.unrestricted_type; | |
| 720 | 724 | |
| 721 | 725 | const ty_name = ip.loadRestrictedType(restricted_ty.toIntern()).name.toSlice(ip); |
| 722 | 726 | gop.value_ptr.* = .{ |
| ... | ... | @@ -730,7 +734,28 @@ pub const Object = struct { |
| 730 | 734 | .void, |
| 731 | 735 | .default, |
| 732 | 736 | ), |
| 737 | .enum_seen = if (ip.isEnumType(unrestricted_type)) enum_seen: { | |
| 738 | const owner_mod = zcu.fileByIndex(restricted_type_key.zir_index.resolveFile(ip)).mod.?; | |
| 739 | if (owner_mod.optimize_mode != .ReleaseSmall) break :enum_seen &.{}; | |
| 740 | const field_names = ip.loadEnumType(unrestricted_type).field_names; | |
| 741 | const enum_seen = try o.gpa.alloc(Builder.Variable.Index, field_names.len); | |
| 742 | errdefer o.gpa.free(enum_seen); | |
| 743 | for (enum_seen, field_names.get(ip)) |*global, field_name| { | |
| 744 | global.* = try o.builder.addVariable( | |
| 745 | try o.builder.strtabStringFmt("{s}.{f}", .{ ty_name, field_name.fmt(ip) }), | |
| 746 | .i1, | |
| 747 | .default, | |
| 748 | ); | |
| 749 | global.setLinkage(.private, &o.builder); | |
| 750 | global.setMutability(.global, &o.builder); | |
| 751 | global.setAlignment(InternPool.Alignment.@"1".toLlvm(), &o.builder); | |
| 752 | global.setUnnamedAddr(.unnamed_addr, &o.builder); | |
| 753 | try global.setInitializer(.false, &o.builder); | |
| 754 | } | |
| 755 | break :enum_seen enum_seen; | |
| 756 | } else &.{}, | |
| 733 | 757 | .values = .empty, |
| 758 | .metadata = .none, | |
| 734 | 759 | }; |
| 735 | 760 | gop.value_ptr.len.setLinkage(.private, &o.builder); |
| 736 | 761 | gop.value_ptr.len.setMutability(.constant, &o.builder); |
| ... | ... | @@ -738,23 +763,80 @@ pub const Object = struct { |
| 738 | 763 | gop.value_ptr.len.setUnnamedAddr(.unnamed_addr, &o.builder); |
| 739 | 764 | gop.value_ptr.array.setLinkage(.private, &o.builder); |
| 740 | 765 | gop.value_ptr.array.setMutability(.constant, &o.builder); |
| 741 | gop.value_ptr.array.setAlignment(unrestricted_ty.abiAlignment(zcu).toLlvm(), &o.builder); | |
| 742 | // Setting unnamed_addr here would reduce safety, and the module emitting the safety checks may not be the same module | |
| 743 | // that defined the restricted type. In any case, llvm will add unnamed_addr itself if no safety checks end up being emitted. | |
| 744 | gop.value_ptr.array.setUnnamedAddr(.default, &o.builder); | |
| 766 | gop.value_ptr.array.setAlignment(Type.fromInterned(unrestricted_type).abiAlignment(zcu).toLlvm(), &o.builder); | |
| 767 | gop.value_ptr.array.setUnnamedAddr(.unnamed_addr, &o.builder); | |
| 745 | 768 | return gop.value_ptr; |
| 746 | 769 | } |
| 747 | 770 | fn genRestrictedDecls(o: *Object) Allocator.Error!void { |
| 748 | for (o.restricted_map.values()) |restricted_decls| { | |
| 771 | const zcu = o.zcu; | |
| 772 | const ip = &zcu.intern_pool; | |
| 773 | for (o.restricted_map.keys(), o.restricted_map.values()) |restricted_ty, restricted_decls| { | |
| 749 | 774 | const len = restricted_decls.values.count(); |
| 750 | 775 | try restricted_decls.len.setInitializer(try o.builder.intConst(.i32, len), &o.builder); |
| 751 | 776 | try restricted_decls.array.setInitializer(switch (len) { |
| 752 | 0 => try o.builder.zeroInitConst(.i8), // ensure unique address | |
| 777 | 0 => try o.builder.structConst(try o.builder.structType(.normal, &.{}), &.{}), | |
| 753 | 778 | else => try o.builder.arrayConst( |
| 754 | 779 | try o.builder.arrayType(len, restricted_decls.values.values()[0].typeOf(&o.builder)), |
| 755 | 780 | restricted_decls.values.values(), |
| 756 | 781 | ), |
| 757 | 782 | }, &o.builder); |
| 783 | if (restricted_decls.metadata.unwrap()) |metadata| { | |
| 784 | const gpa = zcu.gpa; | |
| 785 | const unrestricted_ty = ip.indexToKey(restricted_ty).restricted_type.unrestricted_type; | |
| 786 | if (ip.isPointerType(unrestricted_ty)) { | |
| 787 | assert(ip.isFunctionType(ip.indexToKey(unrestricted_ty).ptr_type.child)); | |
| 788 | const callees = try gpa.alloc(Builder.Metadata, len); | |
| 789 | defer gpa.free(callees); | |
| 790 | for (callees, restricted_decls.values.values()) |*callee, value| | |
| 791 | callee.* = try o.builder.metadataConstant(value); | |
| 792 | o.builder.resolveMetadataForwardReference(metadata, try o.builder.metadataTuple(callees)); | |
| 793 | } else { | |
| 794 | assert(Type.fromInterned(unrestricted_ty).isAbiInt(zcu)); | |
| 795 | const ints = try gpa.alloc(std.math.big.int.Const, len); | |
| 796 | defer gpa.free(ints); | |
| 797 | var range: std.ArrayList(Builder.Metadata) = .empty; | |
| 798 | defer range.deinit(gpa); | |
| 799 | o.builder.resolveMetadataForwardReference(metadata, range: { | |
| 800 | if (len == 0) break :range .empty_tuple; | |
| 801 | const values = restricted_decls.values.values(); | |
| 802 | for (ints, values) |*int, value| int.* = value.toInt(&o.builder) orelse | |
| 803 | break :range .empty_tuple; | |
| 804 | std.mem.sortUnstable(std.math.big.int.Const, ints, {}, struct { | |
| 805 | fn lessThan(_: void, lhs: std.math.big.int.Const, rhs: std.math.big.int.Const) bool { | |
| 806 | return lhs.order(rhs).compare(.lt); | |
| 807 | } | |
| 808 | }.lessThan); | |
| 809 | var int_ty = values[0].typeOf(&o.builder); | |
| 810 | var start = ints[0]; | |
| 811 | var end: std.math.big.int.Mutable = .{ | |
| 812 | .limbs = try gpa.alloc( | |
| 813 | std.math.big.Limb, | |
| 814 | std.math.big.int.calcNonZeroTwosCompLimbCount(int_ty.scalarBits(&o.builder)), | |
| 815 | ), | |
| 816 | .len = undefined, | |
| 817 | .positive = undefined, | |
| 818 | }; | |
| 819 | defer gpa.free(end.limbs); | |
| 820 | end.copy(start); | |
| 821 | for (ints[1..]) |int| { | |
| 822 | end.addScalar(end.toConst(), 1); | |
| 823 | if (end.toConst().eql(int)) continue; | |
| 824 | try range.appendSlice(gpa, &.{ | |
| 825 | try o.builder.metadataConstant(try o.builder.bigIntConst(int_ty, start)), | |
| 826 | try o.builder.metadataConstant(try o.builder.bigIntConst(int_ty, end.toConst())), | |
| 827 | }); | |
| 828 | start = int; | |
| 829 | end.copy(int); | |
| 830 | } | |
| 831 | end.addScalar(end.toConst(), 1); | |
| 832 | try range.appendSlice(gpa, &.{ | |
| 833 | try o.builder.metadataConstant(try o.builder.bigIntConst(int_ty, start)), | |
| 834 | try o.builder.metadataConstant(try o.builder.bigIntConst(int_ty, end.toConst())), | |
| 835 | }); | |
| 836 | break :range try o.builder.metadataTuple(range.items); | |
| 837 | }); | |
| 838 | } | |
| 839 | } | |
| 758 | 840 | } |
| 759 | 841 | } |
| 760 | 842 | |
| ... | ... | @@ -861,17 +943,17 @@ pub const Object = struct { |
| 861 | 943 | if (!o.builder.strip) { |
| 862 | 944 | if (o.debug_anyerror_fwd_ref.unwrap()) |fwd_ref| { |
| 863 | 945 | const debug_anyerror_type = try o.lowerDebugAnyerrorType(); |
| 864 | o.builder.resolveDebugForwardReference(fwd_ref, debug_anyerror_type); | |
| 946 | o.builder.resolveMetadataForwardReference(fwd_ref, debug_anyerror_type); | |
| 865 | 947 | } |
| 866 | 948 | |
| 867 | 949 | try o.flushTypePool(pt); |
| 868 | 950 | |
| 869 | o.builder.resolveDebugForwardReference( | |
| 951 | o.builder.resolveMetadataForwardReference( | |
| 870 | 952 | o.debug_enums_fwd_ref.unwrap().?, |
| 871 | 953 | try o.builder.metadataTuple(o.debug_enums.items), |
| 872 | 954 | ); |
| 873 | 955 | |
| 874 | o.builder.resolveDebugForwardReference( | |
| 956 | o.builder.resolveMetadataForwardReference( | |
| 875 | 957 | o.debug_globals_fwd_ref.unwrap().?, |
| 876 | 958 | try o.builder.metadataTuple(o.debug_globals.items), |
| 877 | 959 | ); |
| ... | ... | @@ -1936,7 +2018,7 @@ pub const Object = struct { |
| 1936 | 2018 | if (!o.builder.strip) { |
| 1937 | 2019 | assert(@intFromEnum(index) == o.debug_types.items.len); |
| 1938 | 2020 | try o.debug_types.ensureUnusedCapacity(gpa, 1); |
| 1939 | const fwd_ref = try o.builder.debugForwardReference(); | |
| 2021 | const fwd_ref = try o.builder.metadataForwardReference(); | |
| 1940 | 2022 | o.debug_types.appendAssumeCapacity(fwd_ref); |
| 1941 | 2023 | if (val == .anyerror_type) { |
| 1942 | 2024 | assert(o.debug_anyerror_fwd_ref.is_none); |
| ... | ... | @@ -1968,7 +2050,7 @@ pub const Object = struct { |
| 1968 | 2050 | .@"fn" => try o.builder.debugSubroutineType(null), |
| 1969 | 2051 | else => try o.builder.debugSignedType(name_str, 0), |
| 1970 | 2052 | }; |
| 1971 | o.builder.resolveDebugForwardReference(fwd_ref, debug_incomplete_type); | |
| 2053 | o.builder.resolveMetadataForwardReference(fwd_ref, debug_incomplete_type); | |
| 1972 | 2054 | } |
| 1973 | 2055 | } |
| 1974 | 2056 | /// Should only be called by the `link.ConstPool` implementation. |
| ... | ... | @@ -1992,7 +2074,7 @@ pub const Object = struct { |
| 1992 | 2074 | assert(o.debug_anyerror_fwd_ref == fwd_ref.toOptional()); |
| 1993 | 2075 | } else { |
| 1994 | 2076 | const debug_type = try o.lowerDebugType(pt, ty, fwd_ref); |
| 1995 | o.builder.resolveDebugForwardReference(fwd_ref, debug_type); | |
| 2077 | o.builder.resolveMetadataForwardReference(fwd_ref, debug_type); | |
| 1996 | 2078 | } |
| 1997 | 2079 | } |
| 1998 | 2080 | } |
| ... | ... | @@ -2527,7 +2609,7 @@ pub const Object = struct { |
| 2527 | 2609 | const payload_fwd_ref = if (layout.tag_size == 0) |
| 2528 | 2610 | ty_fwd_ref |
| 2529 | 2611 | else |
| 2530 | try o.builder.debugForwardReference(); | |
| 2612 | try o.builder.metadataForwardReference(); | |
| 2531 | 2613 | |
| 2532 | 2614 | for (0..union_type.field_types.len) |field_index| { |
| 2533 | 2615 | const field_ty = union_type.field_types.get(ip)[field_index]; |
| ... | ... | @@ -2566,7 +2648,7 @@ pub const Object = struct { |
| 2566 | 2648 | return debug_payload_type; |
| 2567 | 2649 | } |
| 2568 | 2650 | |
| 2569 | o.builder.resolveDebugForwardReference(payload_fwd_ref, debug_payload_type); | |
| 2651 | o.builder.resolveMetadataForwardReference(payload_fwd_ref, debug_payload_type); | |
| 2570 | 2652 | |
| 2571 | 2653 | const tag_offset: u64, const payload_offset: u64 = offsets: { |
| 2572 | 2654 | if (layout.tag_align.compare(.gte, layout.payload_align)) { |
| ... | ... | @@ -3988,6 +4070,11 @@ pub const Object = struct { |
| 3988 | 4070 | const restricted_decls = try o.getRestrictedDecls(ty); |
| 3989 | 4071 | const gop = try restricted_decls.values.getOrPut(o.gpa, arg_val); |
| 3990 | 4072 | if (!gop.found_existing) gop.value_ptr.* = try o.lowerValue(restricted_value.unrestricted_value); |
| 4073 | if (restricted_decls.enum_seen.len > 0) enum_seen: { | |
| 4074 | const unrestricted_val: Value = .fromInterned(restricted_value.unrestricted_value); | |
| 4075 | const tag_index = unrestricted_val.typeOf(zcu).enumTagFieldIndex(unrestricted_val, zcu) orelse break :enum_seen; | |
| 4076 | try restricted_decls.enum_seen[tag_index].setInitializer(.true, &o.builder); | |
| 4077 | } | |
| 3991 | 4078 | return o.builder.intConst(.i32, gop.index); |
| 3992 | 4079 | }, |
| 3993 | 4080 | .memoized_call => unreachable, |
| ... | ... | @@ -4002,37 +4089,29 @@ pub const Object = struct { |
| 4002 | 4089 | const zcu = o.zcu; |
| 4003 | 4090 | const ptr = zcu.intern_pool.indexToKey(ptr_val).ptr; |
| 4004 | 4091 | const offset: u64 = prev_offset + ptr.byte_offset; |
| 4005 | return switch (ptr.base_addr) { | |
| 4006 | .nav => |nav| { | |
| 4007 | const base_ptr = try o.lowerNavRef(nav); | |
| 4008 | return o.builder.gepConst(.inbounds, .i8, base_ptr, null, &.{ | |
| 4009 | try o.builder.intConst(.i64, offset), | |
| 4010 | }); | |
| 4011 | }, | |
| 4092 | const base_ptr = base_ptr: switch (ptr.base_addr) { | |
| 4093 | .nav => |nav| try o.lowerNavRef(nav), | |
| 4012 | 4094 | .uav => |uav| { |
| 4013 | 4095 | const orig_ptr_ty: Type = .fromInterned(uav.orig_ty); |
| 4014 | const base_ptr = try o.lowerUavRef( | |
| 4096 | break :base_ptr try o.lowerUavRef( | |
| 4015 | 4097 | uav.val, |
| 4016 | 4098 | orig_ptr_ty.ptrAlignment(zcu), |
| 4017 | 4099 | orig_ptr_ty.ptrAddressSpace(zcu), |
| 4018 | 4100 | ); |
| 4019 | return o.builder.gepConst(.inbounds, .i8, base_ptr, null, &.{ | |
| 4020 | try o.builder.intConst(.i64, offset), | |
| 4021 | }); | |
| 4022 | 4101 | }, |
| 4023 | .int => try o.builder.castConst( | |
| 4102 | .int => return o.builder.castConst( | |
| 4024 | 4103 | .inttoptr, |
| 4025 | 4104 | try o.builder.intConst(try o.lowerType(.usize), offset), |
| 4026 | 4105 | try o.lowerType(.fromInterned(ptr.ty)), |
| 4027 | 4106 | ), |
| 4028 | .eu_payload => |eu_ptr| try o.lowerPtr( | |
| 4107 | .eu_payload => |eu_ptr| return o.lowerPtr( | |
| 4029 | 4108 | eu_ptr, |
| 4030 | 4109 | offset + codegen.errUnionPayloadOffset( |
| 4031 | 4110 | Value.fromInterned(eu_ptr).typeOf(zcu).childType(zcu), |
| 4032 | 4111 | zcu, |
| 4033 | 4112 | ), |
| 4034 | 4113 | ), |
| 4035 | .opt_payload => |opt_ptr| try o.lowerPtr(opt_ptr, offset), | |
| 4114 | .opt_payload => |opt_ptr| return o.lowerPtr(opt_ptr, offset), | |
| 4036 | 4115 | .field => |field| { |
| 4037 | 4116 | const agg_ty = Value.fromInterned(field.base).typeOf(zcu).childType(zcu); |
| 4038 | 4117 | const field_off: u64 = switch (agg_ty.zigTypeTag(zcu)) { |
| ... | ... | @@ -4061,6 +4140,10 @@ pub const Object = struct { |
| 4061 | 4140 | .comptime_field => unreachable, |
| 4062 | 4141 | .comptime_alloc => unreachable, |
| 4063 | 4142 | }; |
| 4143 | if (offset == 0) return base_ptr; | |
| 4144 | return o.builder.gepConst(.inbounds, .i8, base_ptr, null, &.{ | |
| 4145 | try o.builder.intConst(.i64, offset), | |
| 4146 | }); | |
| 4064 | 4147 | } |
| 4065 | 4148 | |
| 4066 | 4149 | pub fn lowerPtrToVoid( |
src/codegen/llvm/FuncGen.zig+68-21| ... | ... | @@ -826,7 +826,7 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif |
| 826 | 826 | }; |
| 827 | 827 | } |
| 828 | 828 | |
| 829 | const call = try self.wip.call( | |
| 829 | const call = try self.wip.callMetadata( | |
| 830 | 830 | switch (modifier) { |
| 831 | 831 | .auto, .never_inline => .normal, |
| 832 | 832 | .never_tail => .notail, |
| ... | ... | @@ -838,6 +838,17 @@ fn airCall(self: *FuncGen, inst: Air.Inst.Index, modifier: std.builtin.CallModif |
| 838 | 838 | try o.lowerType(zig_fn_ty), |
| 839 | 839 | llvm_fn, |
| 840 | 840 | llvm_args.items, |
| 841 | .{ | |
| 842 | .callees = if (air_call.callee.toIndex()) |callee_inst| switch (self.air.instructions.items(.tag)[@intFromEnum(callee_inst)]) { | |
| 843 | else => .none, | |
| 844 | .unwrap_restricted, .unwrap_restricted_safe => callees: { | |
| 845 | const restricted_ty = self.typeOf(self.air.instructions.items(.data)[@intFromEnum(callee_inst)].ty_op.operand); | |
| 846 | const restricted_decls = try o.getRestrictedDecls(restricted_ty); | |
| 847 | if (restricted_decls.metadata.is_none) restricted_decls.metadata = .wrap(try o.builder.metadataForwardReference()); | |
| 848 | break :callees restricted_decls.metadata; | |
| 849 | }, | |
| 850 | } else .none, | |
| 851 | }, | |
| 841 | 852 | "", |
| 842 | 853 | ); |
| 843 | 854 | |
| ... | ... | @@ -1667,6 +1678,7 @@ fn lowerTry( |
| 1667 | 1678 | fn airSwitchBr(self: *FuncGen, inst: Air.Inst.Index, is_dispatch_loop: bool) TodoError!void { |
| 1668 | 1679 | const o = self.object; |
| 1669 | 1680 | const zcu = o.zcu; |
| 1681 | const ip = &zcu.intern_pool; | |
| 1670 | 1682 | |
| 1671 | 1683 | const switch_br = self.air.unwrapSwitch(inst); |
| 1672 | 1684 | |
| ... | ... | @@ -1694,6 +1706,7 @@ fn airSwitchBr(self: *FuncGen, inst: Air.Inst.Index, is_dispatch_loop: bool) Tod |
| 1694 | 1706 | // This asm is really, really, not what we want. As such, we will construct the jump table manually where |
| 1695 | 1707 | // appropriate (the values are dense and relatively few), and use it when lowering dispatches. |
| 1696 | 1708 | |
| 1709 | const cond_ty = self.typeOf(switch_br.operand); | |
| 1697 | 1710 | const jmp_table: ?SwitchDispatchInfo.JmpTable = jmp_table: { |
| 1698 | 1711 | if (!is_dispatch_loop) break :jmp_table null; |
| 1699 | 1712 | |
| ... | ... | @@ -1706,7 +1719,6 @@ fn airSwitchBr(self: *FuncGen, inst: Air.Inst.Index, is_dispatch_loop: bool) Tod |
| 1706 | 1719 | // about acceptable - it won't fill L1d cache on most CPUs. |
| 1707 | 1720 | const max_table_len = 1024; |
| 1708 | 1721 | |
| 1709 | const cond_ty = self.typeOf(switch_br.operand); | |
| 1710 | 1722 | switch (cond_ty.zigTypeTag(zcu)) { |
| 1711 | 1723 | .bool, .pointer => break :jmp_table null, |
| 1712 | 1724 | .@"enum", .int, .error_set, .@"struct", .@"union" => {}, |
| ... | ... | @@ -1859,6 +1871,18 @@ fn airSwitchBr(self: *FuncGen, inst: Air.Inst.Index, is_dispatch_loop: bool) Tod |
| 1859 | 1871 | assert(self.switch_dispatch_info.remove(inst)); |
| 1860 | 1872 | }; |
| 1861 | 1873 | |
| 1874 | const restricted_enum_seen = if (ip.isEnumType(cond_ty.toIntern())) restricted_enum_seen: { | |
| 1875 | const operand_inst = switch_br.operand.toIndex() orelse break :restricted_enum_seen &.{}; | |
| 1876 | switch (self.air.instructions.items(.tag)[@intFromEnum(operand_inst)]) { | |
| 1877 | else => break :restricted_enum_seen &.{}, | |
| 1878 | .unwrap_restricted, .unwrap_restricted_safe => { | |
| 1879 | const restricted_ty = self.typeOf(self.air.instructions.items(.data)[@intFromEnum(operand_inst)].ty_op.operand); | |
| 1880 | const restricted_decls = try o.getRestrictedDecls(restricted_ty); | |
| 1881 | break :restricted_enum_seen restricted_decls.enum_seen; | |
| 1882 | }, | |
| 1883 | } | |
| 1884 | } else &.{}; | |
| 1885 | ||
| 1862 | 1886 | // Generate the initial dispatch. |
| 1863 | 1887 | // If this is a simple `switch_br`, this is the only dispatch. |
| 1864 | 1888 | try self.lowerSwitchDispatch(inst, switch_br.operand, dispatch_info); |
| ... | ... | @@ -1869,6 +1893,16 @@ fn airSwitchBr(self: *FuncGen, inst: Air.Inst.Index, is_dispatch_loop: bool) Tod |
| 1869 | 1893 | const case_block = case_blocks[case.idx]; |
| 1870 | 1894 | self.wip.cursor = .{ .block = case_block }; |
| 1871 | 1895 | if (switch_br.getHint(case.idx) == .cold) _ = try self.wip.callIntrinsicAssumeCold(); |
| 1896 | if (restricted_enum_seen.len > 0) restricted_enum_seen: { | |
| 1897 | var maybe_any_seen: ?Builder.Value = null; | |
| 1898 | for (case.items) |item| { | |
| 1899 | const tag_index = cond_ty.enumTagFieldIndex(.fromInterned(item.toInterned().?), zcu) orelse break :restricted_enum_seen; | |
| 1900 | const tag_seen = try self.wip.load(.normal, .i1, restricted_enum_seen[tag_index].toValue(&o.builder), InternPool.Alignment.@"1".toLlvm(), ""); | |
| 1901 | maybe_any_seen = if (maybe_any_seen) |any_seen| try self.wip.bin(.@"or", any_seen, tag_seen, "") else tag_seen; | |
| 1902 | } | |
| 1903 | assert(case.ranges.len == 0); // not supported by Sema yet | |
| 1904 | _ = try self.wip.callIntrinsic(.normal, .none, .assume, &.{}, &.{maybe_any_seen.?}, ""); | |
| 1905 | } | |
| 1872 | 1906 | try self.genBodyDebugScope(null, case.body, .none); |
| 1873 | 1907 | } |
| 1874 | 1908 | self.wip.cursor = .{ .block = case_blocks[case_blocks.len - 1] }; |
| ... | ... | @@ -2124,11 +2158,7 @@ fn airSliceElemVal(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder |
| 2124 | 2158 | const elem_align = slice_ty.ptrAlignment(zcu).min(elem_ty.abiAlignment(zcu)); |
| 2125 | 2159 | const access_kind: Builder.MemoryAccessKind = if (slice_info.flags.is_volatile) .@"volatile" else .normal; |
| 2126 | 2160 | self.maybeMarkAllowZeroAccess(slice_info); |
| 2127 | if (isByRef(elem_ty, zcu)) { | |
| 2128 | return self.loadByRef(ptr, elem_ty, elem_align.toLlvm(), access_kind); | |
| 2129 | } else { | |
| 2130 | return self.loadTruncate(access_kind, elem_ty, ptr, elem_align.toLlvm()); | |
| 2131 | } | |
| 2161 | return self.load(ptr, elem_ty, elem_align.toLlvm(), access_kind); | |
| 2132 | 2162 | } |
| 2133 | 2163 | |
| 2134 | 2164 | fn airSliceElemPtr(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| ... | ... | @@ -2153,12 +2183,7 @@ fn airArrayElemVal(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder |
| 2153 | 2183 | const elem_ty = array_ty.childType(zcu); |
| 2154 | 2184 | if (isByRef(array_ty, zcu)) { |
| 2155 | 2185 | const elem_ptr = try self.ptraddScaled(array_llvm_val, rhs, elem_ty.abiSize(zcu)); |
| 2156 | if (isByRef(elem_ty, zcu)) { | |
| 2157 | const elem_align = elem_ty.abiAlignment(zcu).toLlvm(); | |
| 2158 | return self.loadByRef(elem_ptr, elem_ty, elem_align, .normal); | |
| 2159 | } else { | |
| 2160 | return self.loadTruncate(.normal, elem_ty, elem_ptr, .default); | |
| 2161 | } | |
| 2186 | return self.load(elem_ptr, elem_ty, elem_ty.abiAlignment(zcu).toLlvm(), .normal); | |
| 2162 | 2187 | } |
| 2163 | 2188 | |
| 2164 | 2189 | // This branch can be reached for vectors, which are always by-value. |
| ... | ... | @@ -2277,11 +2302,7 @@ fn airStructFieldVal(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Build |
| 2277 | 2302 | else => struct_ptr_align.minStrict(.fromLog2Units(@ctz(offset))), |
| 2278 | 2303 | }; |
| 2279 | 2304 | |
| 2280 | if (isByRef(field_ty, zcu)) { | |
| 2281 | return self.loadByRef(field_ptr, field_ty, field_ptr_align.toLlvm(), .normal); | |
| 2282 | } else { | |
| 2283 | return self.loadTruncate(.normal, field_ty, field_ptr, field_ptr_align.toLlvm()); | |
| 2284 | } | |
| 2305 | return self.load(field_ptr, field_ty, field_ptr_align.toLlvm(), .normal); | |
| 2285 | 2306 | } |
| 2286 | 2307 | |
| 2287 | 2308 | fn airFieldParentPtr(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| ... | ... | @@ -3259,6 +3280,7 @@ fn airUnwrapRestricted(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocat |
| 3259 | 3280 | const target = zcu.getTarget(); |
| 3260 | 3281 | const ty_op = fg.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 3261 | 3282 | const unrestricted_ty = ty_op.ty.toType(); |
| 3283 | const unrestricted_align = unrestricted_ty.abiAlignment(zcu); | |
| 3262 | 3284 | const restricted_ty = fg.typeOf(ty_op.operand); |
| 3263 | 3285 | const operand = try fg.resolveInst(ty_op.operand); |
| 3264 | 3286 | const restricted_decls = try o.getRestrictedDecls(restricted_ty); |
| ... | ... | @@ -3281,7 +3303,13 @@ fn airUnwrapRestricted(fg: *FuncGen, inst: Air.Inst.Index, safety: bool) Allocat |
| 3281 | 3303 | fg.wip.cursor = .{ .block = valid_block }; |
| 3282 | 3304 | } |
| 3283 | 3305 | const ptr = try fg.ptraddScaled(restricted_decls.array.toValue(&o.builder), operand, unrestricted_ty.abiSize(zcu)); |
| 3284 | return fg.load(ptr, unrestricted_ty, unrestricted_ty.abiAlignment(zcu).toLlvm(), .normal); | |
| 3306 | if (isByRef(unrestricted_ty, zcu)) return fg.loadByRef(ptr, unrestricted_ty, unrestricted_align.toLlvm(), .normal); | |
| 3307 | return fg.wip.loadMetadata(.normal, try o.lowerType(unrestricted_ty), ptr, unrestricted_align.toLlvm(), .{ | |
| 3308 | .range = if (unrestricted_ty.isAbiInt(zcu)) range: { | |
| 3309 | if (restricted_decls.metadata.is_none) restricted_decls.metadata = .wrap(try o.builder.metadataForwardReference()); | |
| 3310 | break :range restricted_decls.metadata; | |
| 3311 | } else .none, | |
| 3312 | }, ""); | |
| 3285 | 3313 | } |
| 3286 | 3314 | |
| 3287 | 3315 | fn airWasmMemorySize(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Value { |
| ... | ... | @@ -6042,8 +6070,27 @@ fn airUnionInit(self: *FuncGen, inst: Air.Inst.Index) Allocator.Error!Builder.Va |
| 6042 | 6070 | } |
| 6043 | 6071 | |
| 6044 | 6072 | if (layout.tag_size != 0) { |
| 6045 | const loaded_enum = ip.loadEnumType(union_obj.enum_tag_type); | |
| 6046 | const llvm_tag_val = switch (loaded_enum.field_values.getOrNone(ip, extra.field_index)) { | |
| 6073 | const tag_ty: Type = .fromInterned(union_obj.enum_tag_type); | |
| 6074 | const llvm_tag_val = if (tag_ty.unrestrictedType(zcu)) |unrestricted_tag_ty| llvm_tag_val: { | |
| 6075 | const restricted_decls = try o.getRestrictedDecls(tag_ty); | |
| 6076 | const unrestricted_tag_val = try self.pt.enumValueFieldIndex(unrestricted_tag_ty, extra.field_index); | |
| 6077 | const tag_val = try self.pt.intern(.{ .restricted_value = .{ | |
| 6078 | .ty = union_obj.enum_tag_type, | |
| 6079 | .unrestricted_value = unrestricted_tag_val.toIntern(), | |
| 6080 | } }); | |
| 6081 | const gop = try restricted_decls.values.getOrPut(o.gpa, tag_val); | |
| 6082 | if (!gop.found_existing) gop.value_ptr.* = try o.lowerValue(unrestricted_tag_val.toIntern()); | |
| 6083 | if (restricted_decls.enum_seen.len > 0) enum_seen: { | |
| 6084 | const tag_index = unrestricted_tag_ty.enumTagFieldIndex(unrestricted_tag_val, zcu) orelse break :enum_seen; | |
| 6085 | _ = try self.wip.store( | |
| 6086 | .normal, | |
| 6087 | .true, | |
| 6088 | restricted_decls.enum_seen[tag_index].toValue(&o.builder), | |
| 6089 | InternPool.Alignment.@"1".toLlvm(), | |
| 6090 | ); | |
| 6091 | } | |
| 6092 | break :llvm_tag_val try o.builder.intConst(.i32, gop.index); | |
| 6093 | } else switch (ip.loadEnumType(union_obj.enum_tag_type).field_values.getOrNone(ip, extra.field_index)) { | |
| 6047 | 6094 | .none => try o.builder.intConst( |
| 6048 | 6095 | try o.lowerType(.fromInterned(union_obj.enum_tag_type)), |
| 6049 | 6096 | extra.field_index, // auto-numbered |
src/codegen/x86_64/CodeGen.zig+2-1| ... | ... | @@ -172764,8 +172764,9 @@ fn genBody(cg: *CodeGen, body: []const Air.Inst.Index) InnerError!void { |
| 172764 | 172764 | var res = try cg.tempAllocMem(union_ty); |
| 172765 | 172765 | const union_layout = union_ty.unionGetLayout(zcu); |
| 172766 | 172766 | if (union_layout.tag_size > 0) { |
| 172767 | const tag_ty = union_ty.unionTagTypeRuntime(zcu).?; | |
| 172767 | 172768 | var tag_temp = try cg.tempFromValue(try pt.enumValueFieldIndex( |
| 172768 | union_ty.unionTagTypeRuntime(zcu).?, | |
| 172769 | tag_ty.unrestrictedType(zcu) orelse tag_ty, | |
| 172769 | 172770 | union_init.field_index, |
| 172770 | 172771 | )); |
| 172771 | 172772 | try res.write(&tag_temp, .{ |
src/link/Dwarf.zig+2-1| ... | ... | @@ -4046,7 +4046,8 @@ fn updateConstInner(dwarf: *Dwarf, pt: Zcu.PerThread, debug_const_index: link.Co |
| 4046 | 4046 | const union_layout = Type.getUnionLayout(loaded_union, zcu); |
| 4047 | 4047 | try diw.writeUleb128(union_layout.abi_size); |
| 4048 | 4048 | try diw.writeUleb128(union_layout.abi_align.toByteUnits().?); |
| 4049 | const loaded_tag = ip.loadEnumType(loaded_union.enum_tag_type); | |
| 4049 | const enum_tag_ty: Type = .fromInterned(loaded_union.enum_tag_type); | |
| 4050 | const loaded_tag = ip.loadEnumType((enum_tag_ty.unrestrictedType(zcu) orelse enum_tag_ty).toIntern()); | |
| 4050 | 4051 | if (loaded_union.has_runtime_tag) { |
| 4051 | 4052 | try wip_nav.abbrevCode(.tagged_union); |
| 4052 | 4053 | try wip_nav.infoSectionOffset( |
src/zig_llvm.cpp+10| ... | ... | @@ -51,6 +51,7 @@ |
| 51 | 51 | #include <llvm/Target/CodeGenCWrappers.h> |
| 52 | 52 | #include <llvm/Transforms/IPO.h> |
| 53 | 53 | #include <llvm/Transforms/IPO/AlwaysInliner.h> |
| 54 | #include <llvm/Transforms/IPO/GlobalOpt.h> | |
| 54 | 55 | #include <llvm/Transforms/Instrumentation/ThreadSanitizer.h> |
| 55 | 56 | #include <llvm/Transforms/Instrumentation/SanitizerCoverage.h> |
| 56 | 57 | #include <llvm/Transforms/Scalar.h> |
| ... | ... | @@ -348,6 +349,10 @@ ZIG_EXTERN_C bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machi |
| 348 | 349 | }); |
| 349 | 350 | |
| 350 | 351 | pass_builder.registerOptimizerLastEPCallback([&](ModulePassManager &module_pm, OptimizationLevel level, ThinOrFullLTOPhase lto_phase) { |
| 352 | // Restricted enums require an extra global optimization pass sometime after | |
| 353 | // DropUnnecessaryAssumesPass to fully eliminate the helper global variables. | |
| 354 | if (level.isOptimizingForSize()) module_pm.addPass(GlobalOptPass()); | |
| 355 | ||
| 351 | 356 | if (!early_san) { |
| 352 | 357 | // Code coverage instrumentation. |
| 353 | 358 | if (options->sancov) { |
| ... | ... | @@ -404,6 +409,11 @@ ZIG_EXTERN_C bool ZigLLVMTargetMachineEmitToFile(LLVMTargetMachineRef targ_machi |
| 404 | 409 | } |
| 405 | 410 | } |
| 406 | 411 | |
| 412 | if (false) { | |
| 413 | module_pm.printPipeline(outs(), [](StringRef S) { return S; }); | |
| 414 | outs() << '\n'; | |
| 415 | } | |
| 416 | ||
| 407 | 417 | // Optimization phase |
| 408 | 418 | module_pm.run(llvm_module, module_am); |
| 409 | 419 |