| ... | ... | @@ -5694,7 +5694,7 @@ pub const WipFunction = struct { |
| 5694 | 5694 | ) Allocator.Error!Value { |
| 5695 | 5695 | const val_ty = val.typeOfWip(self); |
| 5696 | 5696 | if (val_ty == ty) return val; |
| 5697 | | return self.cast(self.builder.convTag(Instruction.Tag, signedness, val_ty, ty), val, ty, name); |
| 5697 | return self.cast(self.builder.convTag(signedness, val_ty, ty), val, ty, name); |
| 5698 | 5698 | } |
| 5699 | 5699 | |
| 5700 | 5700 | pub fn cast( |
| ... | ... | @@ -6891,39 +6891,19 @@ pub const Constant = enum(u32) { |
| 6891 | 6891 | dso_local_equivalent, |
| 6892 | 6892 | no_cfi, |
| 6893 | 6893 | trunc, |
| 6894 | | zext, |
| 6895 | | sext, |
| 6896 | | fptrunc, |
| 6897 | | fpext, |
| 6898 | | fptoui, |
| 6899 | | fptosi, |
| 6900 | | uitofp, |
| 6901 | | sitofp, |
| 6902 | 6894 | ptrtoint, |
| 6903 | 6895 | inttoptr, |
| 6904 | 6896 | bitcast, |
| 6905 | 6897 | addrspacecast, |
| 6906 | 6898 | getelementptr, |
| 6907 | 6899 | @"getelementptr inbounds", |
| 6908 | | icmp, |
| 6909 | | fcmp, |
| 6910 | | extractelement, |
| 6911 | | insertelement, |
| 6912 | | shufflevector, |
| 6913 | 6900 | add, |
| 6914 | 6901 | @"add nsw", |
| 6915 | 6902 | @"add nuw", |
| 6916 | 6903 | sub, |
| 6917 | 6904 | @"sub nsw", |
| 6918 | 6905 | @"sub nuw", |
| 6919 | | mul, |
| 6920 | | @"mul nsw", |
| 6921 | | @"mul nuw", |
| 6922 | 6906 | shl, |
| 6923 | | lshr, |
| 6924 | | ashr, |
| 6925 | | @"and", |
| 6926 | | @"or", |
| 6927 | 6907 | xor, |
| 6928 | 6908 | @"asm", |
| 6929 | 6909 | @"asm sideeffect", |
| ... | ... | @@ -6952,15 +6932,7 @@ pub const Constant = enum(u32) { |
| 6952 | 6932 | .@"sub nsw", |
| 6953 | 6933 | .@"sub nuw", |
| 6954 | 6934 | => .sub, |
| 6955 | | .mul, |
| 6956 | | .@"mul nsw", |
| 6957 | | .@"mul nuw", |
| 6958 | | => .mul, |
| 6959 | 6935 | .shl => .shl, |
| 6960 | | .lshr => .lshr, |
| 6961 | | .ashr => .ashr, |
| 6962 | | .@"and" => .@"and", |
| 6963 | | .@"or" => .@"or", |
| 6964 | 6936 | .xor => .xor, |
| 6965 | 6937 | else => unreachable, |
| 6966 | 6938 | }; |
| ... | ... | @@ -6969,14 +6941,6 @@ pub const Constant = enum(u32) { |
| 6969 | 6941 | pub fn toCastOpcode(self: Tag) CastOpcode { |
| 6970 | 6942 | return switch (self) { |
| 6971 | 6943 | .trunc => .trunc, |
| 6972 | | .zext => .zext, |
| 6973 | | .sext => .sext, |
| 6974 | | .fptoui => .fptoui, |
| 6975 | | .fptosi => .fptosi, |
| 6976 | | .uitofp => .uitofp, |
| 6977 | | .sitofp => .sitofp, |
| 6978 | | .fptrunc => .fptrunc, |
| 6979 | | .fpext => .fpext, |
| 6980 | 6944 | .ptrtoint => .ptrtoint, |
| 6981 | 6945 | .inttoptr => .inttoptr, |
| 6982 | 6946 | .bitcast => .bitcast, |
| ... | ... | @@ -7051,29 +7015,6 @@ pub const Constant = enum(u32) { |
| 7051 | 7015 | pub const Info = packed struct(u32) { indices_len: u16, inrange: InRangeIndex }; |
| 7052 | 7016 | }; |
| 7053 | 7017 | |
| 7054 | | pub const Compare = extern struct { |
| 7055 | | cond: u32, |
| 7056 | | lhs: Constant, |
| 7057 | | rhs: Constant, |
| 7058 | | }; |
| 7059 | | |
| 7060 | | pub const ExtractElement = extern struct { |
| 7061 | | val: Constant, |
| 7062 | | index: Constant, |
| 7063 | | }; |
| 7064 | | |
| 7065 | | pub const InsertElement = extern struct { |
| 7066 | | val: Constant, |
| 7067 | | elem: Constant, |
| 7068 | | index: Constant, |
| 7069 | | }; |
| 7070 | | |
| 7071 | | pub const ShuffleVector = extern struct { |
| 7072 | | lhs: Constant, |
| 7073 | | rhs: Constant, |
| 7074 | | mask: Constant, |
| 7075 | | }; |
| 7076 | | |
| 7077 | 7018 | pub const Binary = extern struct { |
| 7078 | 7019 | lhs: Constant, |
| 7079 | 7020 | rhs: Constant, |
| ... | ... | @@ -7149,14 +7090,6 @@ pub const Constant = enum(u32) { |
| 7149 | 7090 | => builder.ptrTypeAssumeCapacity(@as(Function.Index, @enumFromInt(item.data)) |
| 7150 | 7091 | .ptrConst(builder).global.ptrConst(builder).addr_space), |
| 7151 | 7092 | .trunc, |
| 7152 | | .zext, |
| 7153 | | .sext, |
| 7154 | | .fptrunc, |
| 7155 | | .fpext, |
| 7156 | | .fptoui, |
| 7157 | | .fptosi, |
| 7158 | | .uitofp, |
| 7159 | | .sitofp, |
| 7160 | 7093 | .ptrtoint, |
| 7161 | 7094 | .inttoptr, |
| 7162 | 7095 | .bitcast, |
| ... | ... | @@ -7176,35 +7109,13 @@ pub const Constant = enum(u32) { |
| 7176 | 7109 | }; |
| 7177 | 7110 | return base_ty; |
| 7178 | 7111 | }, |
| 7179 | | .icmp, |
| 7180 | | .fcmp, |
| 7181 | | => builder.constantExtraData(Compare, item.data).lhs.typeOf(builder) |
| 7182 | | .changeScalarAssumeCapacity(.i1, builder), |
| 7183 | | .extractelement => builder.constantExtraData(ExtractElement, item.data) |
| 7184 | | .val.typeOf(builder).childType(builder), |
| 7185 | | .insertelement => builder.constantExtraData(InsertElement, item.data) |
| 7186 | | .val.typeOf(builder), |
| 7187 | | .shufflevector => { |
| 7188 | | const extra = builder.constantExtraData(ShuffleVector, item.data); |
| 7189 | | return extra.lhs.typeOf(builder).changeLengthAssumeCapacity( |
| 7190 | | extra.mask.typeOf(builder).vectorLen(builder), |
| 7191 | | builder, |
| 7192 | | ); |
| 7193 | | }, |
| 7194 | 7112 | .add, |
| 7195 | 7113 | .@"add nsw", |
| 7196 | 7114 | .@"add nuw", |
| 7197 | 7115 | .sub, |
| 7198 | 7116 | .@"sub nsw", |
| 7199 | 7117 | .@"sub nuw", |
| 7200 | | .mul, |
| 7201 | | .@"mul nsw", |
| 7202 | | .@"mul nuw", |
| 7203 | 7118 | .shl, |
| 7204 | | .lshr, |
| 7205 | | .ashr, |
| 7206 | | .@"and", |
| 7207 | | .@"or", |
| 7208 | 7119 | .xor, |
| 7209 | 7120 | => builder.constantExtraData(Binary, item.data).lhs.typeOf(builder), |
| 7210 | 7121 | .@"asm", |
| ... | ... | @@ -7516,14 +7427,6 @@ pub const Constant = enum(u32) { |
| 7516 | 7427 | }); |
| 7517 | 7428 | }, |
| 7518 | 7429 | .trunc, |
| 7519 | | .zext, |
| 7520 | | .sext, |
| 7521 | | .fptrunc, |
| 7522 | | .fpext, |
| 7523 | | .fptoui, |
| 7524 | | .fptosi, |
| 7525 | | .uitofp, |
| 7526 | | .sitofp, |
| 7527 | 7430 | .ptrtoint, |
| 7528 | 7431 | .inttoptr, |
| 7529 | 7432 | .bitcast, |
| ... | ... | @@ -7550,61 +7453,13 @@ pub const Constant = enum(u32) { |
| 7550 | 7453 | for (indices) |index| try writer.print(", {%}", .{index.fmt(data.builder)}); |
| 7551 | 7454 | try writer.writeByte(')'); |
| 7552 | 7455 | }, |
| 7553 | | inline .icmp, |
| 7554 | | .fcmp, |
| 7555 | | => |tag| { |
| 7556 | | const extra = data.builder.constantExtraData(Compare, item.data); |
| 7557 | | try writer.print("{s} {s} ({%}, {%})", .{ |
| 7558 | | @tagName(tag), |
| 7559 | | @tagName(@as(switch (tag) { |
| 7560 | | .icmp => IntegerCondition, |
| 7561 | | .fcmp => FloatCondition, |
| 7562 | | else => unreachable, |
| 7563 | | }, @enumFromInt(extra.cond))), |
| 7564 | | extra.lhs.fmt(data.builder), |
| 7565 | | extra.rhs.fmt(data.builder), |
| 7566 | | }); |
| 7567 | | }, |
| 7568 | | .extractelement => |tag| { |
| 7569 | | const extra = data.builder.constantExtraData(ExtractElement, item.data); |
| 7570 | | try writer.print("{s} ({%}, {%})", .{ |
| 7571 | | @tagName(tag), |
| 7572 | | extra.val.fmt(data.builder), |
| 7573 | | extra.index.fmt(data.builder), |
| 7574 | | }); |
| 7575 | | }, |
| 7576 | | .insertelement => |tag| { |
| 7577 | | const extra = data.builder.constantExtraData(InsertElement, item.data); |
| 7578 | | try writer.print("{s} ({%}, {%}, {%})", .{ |
| 7579 | | @tagName(tag), |
| 7580 | | extra.val.fmt(data.builder), |
| 7581 | | extra.elem.fmt(data.builder), |
| 7582 | | extra.index.fmt(data.builder), |
| 7583 | | }); |
| 7584 | | }, |
| 7585 | | .shufflevector => |tag| { |
| 7586 | | const extra = data.builder.constantExtraData(ShuffleVector, item.data); |
| 7587 | | try writer.print("{s} ({%}, {%}, {%})", .{ |
| 7588 | | @tagName(tag), |
| 7589 | | extra.lhs.fmt(data.builder), |
| 7590 | | extra.rhs.fmt(data.builder), |
| 7591 | | extra.mask.fmt(data.builder), |
| 7592 | | }); |
| 7593 | | }, |
| 7594 | 7456 | .add, |
| 7595 | 7457 | .@"add nsw", |
| 7596 | 7458 | .@"add nuw", |
| 7597 | 7459 | .sub, |
| 7598 | 7460 | .@"sub nsw", |
| 7599 | 7461 | .@"sub nuw", |
| 7600 | | .mul, |
| 7601 | | .@"mul nsw", |
| 7602 | | .@"mul nuw", |
| 7603 | 7462 | .shl, |
| 7604 | | .lshr, |
| 7605 | | .ashr, |
| 7606 | | .@"and", |
| 7607 | | .@"or", |
| 7608 | 7463 | .xor, |
| 7609 | 7464 | => |tag| { |
| 7610 | 7465 | const extra = data.builder.constantExtraData(Binary, item.data); |
| ... | ... | @@ -9278,21 +9133,19 @@ pub fn noCfiValue(self: *Builder, function: Function.Index) Allocator.Error!Valu |
| 9278 | 9133 | |
| 9279 | 9134 | pub fn convConst( |
| 9280 | 9135 | self: *Builder, |
| 9281 | | signedness: Constant.Cast.Signedness, |
| 9282 | 9136 | val: Constant, |
| 9283 | 9137 | ty: Type, |
| 9284 | 9138 | ) Allocator.Error!Constant { |
| 9285 | 9139 | try self.ensureUnusedConstantCapacity(1, Constant.Cast, 0); |
| 9286 | | return self.convConstAssumeCapacity(signedness, val, ty); |
| 9140 | return self.convConstAssumeCapacity(val, ty); |
| 9287 | 9141 | } |
| 9288 | 9142 | |
| 9289 | 9143 | pub fn convValue( |
| 9290 | 9144 | self: *Builder, |
| 9291 | | signedness: Constant.Cast.Signedness, |
| 9292 | 9145 | val: Constant, |
| 9293 | 9146 | ty: Type, |
| 9294 | 9147 | ) Allocator.Error!Value { |
| 9295 | | return (try self.convConst(signedness, val, ty)).toValue(); |
| 9148 | return (try self.convConst(val, ty)).toValue(); |
| 9296 | 9149 | } |
| 9297 | 9150 | |
| 9298 | 9151 | pub fn castConst(self: *Builder, tag: Constant.Tag, val: Constant, ty: Type) Allocator.Error!Constant { |
| ... | ... | @@ -9328,92 +9181,6 @@ pub fn gepValue( |
| 9328 | 9181 | return (try self.gepConst(kind, ty, base, inrange, indices)).toValue(); |
| 9329 | 9182 | } |
| 9330 | 9183 | |
| 9331 | | pub fn icmpConst( |
| 9332 | | self: *Builder, |
| 9333 | | cond: IntegerCondition, |
| 9334 | | lhs: Constant, |
| 9335 | | rhs: Constant, |
| 9336 | | ) Allocator.Error!Constant { |
| 9337 | | try self.ensureUnusedConstantCapacity(1, Constant.Compare, 0); |
| 9338 | | return self.icmpConstAssumeCapacity(cond, lhs, rhs); |
| 9339 | | } |
| 9340 | | |
| 9341 | | pub fn icmpValue( |
| 9342 | | self: *Builder, |
| 9343 | | cond: IntegerCondition, |
| 9344 | | lhs: Constant, |
| 9345 | | rhs: Constant, |
| 9346 | | ) Allocator.Error!Value { |
| 9347 | | return (try self.icmpConst(cond, lhs, rhs)).toValue(); |
| 9348 | | } |
| 9349 | | |
| 9350 | | pub fn fcmpConst( |
| 9351 | | self: *Builder, |
| 9352 | | cond: FloatCondition, |
| 9353 | | lhs: Constant, |
| 9354 | | rhs: Constant, |
| 9355 | | ) Allocator.Error!Constant { |
| 9356 | | try self.ensureUnusedConstantCapacity(1, Constant.Compare, 0); |
| 9357 | | return self.icmpConstAssumeCapacity(cond, lhs, rhs); |
| 9358 | | } |
| 9359 | | |
| 9360 | | pub fn fcmpValue( |
| 9361 | | self: *Builder, |
| 9362 | | cond: FloatCondition, |
| 9363 | | lhs: Constant, |
| 9364 | | rhs: Constant, |
| 9365 | | ) Allocator.Error!Value { |
| 9366 | | return (try self.fcmpConst(cond, lhs, rhs)).toValue(); |
| 9367 | | } |
| 9368 | | |
| 9369 | | pub fn extractElementConst(self: *Builder, val: Constant, index: Constant) Allocator.Error!Constant { |
| 9370 | | try self.ensureUnusedConstantCapacity(1, Constant.ExtractElement, 0); |
| 9371 | | return self.extractElementConstAssumeCapacity(val, index); |
| 9372 | | } |
| 9373 | | |
| 9374 | | pub fn extractElementValue(self: *Builder, val: Constant, index: Constant) Allocator.Error!Value { |
| 9375 | | return (try self.extractElementConst(val, index)).toValue(); |
| 9376 | | } |
| 9377 | | |
| 9378 | | pub fn insertElementConst( |
| 9379 | | self: *Builder, |
| 9380 | | val: Constant, |
| 9381 | | elem: Constant, |
| 9382 | | index: Constant, |
| 9383 | | ) Allocator.Error!Constant { |
| 9384 | | try self.ensureUnusedConstantCapacity(1, Constant.InsertElement, 0); |
| 9385 | | return self.insertElementConstAssumeCapacity(val, elem, index); |
| 9386 | | } |
| 9387 | | |
| 9388 | | pub fn insertElementValue( |
| 9389 | | self: *Builder, |
| 9390 | | val: Constant, |
| 9391 | | elem: Constant, |
| 9392 | | index: Constant, |
| 9393 | | ) Allocator.Error!Value { |
| 9394 | | return (try self.insertElementConst(val, elem, index)).toValue(); |
| 9395 | | } |
| 9396 | | |
| 9397 | | pub fn shuffleVectorConst( |
| 9398 | | self: *Builder, |
| 9399 | | lhs: Constant, |
| 9400 | | rhs: Constant, |
| 9401 | | mask: Constant, |
| 9402 | | ) Allocator.Error!Constant { |
| 9403 | | try self.ensureUnusedTypeCapacity(1, Type.Array, 0); |
| 9404 | | try self.ensureUnusedConstantCapacity(1, Constant.ShuffleVector, 0); |
| 9405 | | return self.shuffleVectorConstAssumeCapacity(lhs, rhs, mask); |
| 9406 | | } |
| 9407 | | |
| 9408 | | pub fn shuffleVectorValue( |
| 9409 | | self: *Builder, |
| 9410 | | lhs: Constant, |
| 9411 | | rhs: Constant, |
| 9412 | | mask: Constant, |
| 9413 | | ) Allocator.Error!Value { |
| 9414 | | return (try self.shuffleVectorConst(lhs, rhs, mask)).toValue(); |
| 9415 | | } |
| 9416 | | |
| 9417 | 9184 | pub fn binConst( |
| 9418 | 9185 | self: *Builder, |
| 9419 | 9186 | tag: Constant.Tag, |
| ... | ... | @@ -11390,11 +11157,10 @@ fn noCfiConstAssumeCapacity(self: *Builder, function: Function.Index) Constant { |
| 11390 | 11157 | |
| 11391 | 11158 | fn convTag( |
| 11392 | 11159 | self: *Builder, |
| 11393 | | comptime Tag: type, |
| 11394 | 11160 | signedness: Constant.Cast.Signedness, |
| 11395 | 11161 | val_ty: Type, |
| 11396 | 11162 | ty: Type, |
| 11397 | | ) Tag { |
| 11163 | ) Function.Instruction.Tag { |
| 11398 | 11164 | assert(val_ty != ty); |
| 11399 | 11165 | return switch (val_ty.scalarTag(self)) { |
| 11400 | 11166 | .simple => switch (ty.scalarTag(self)) { |
| ... | ... | @@ -11437,15 +11203,38 @@ fn convTag( |
| 11437 | 11203 | }; |
| 11438 | 11204 | } |
| 11439 | 11205 | |
| 11206 | fn convConstTag( |
| 11207 | self: *Builder, |
| 11208 | val_ty: Type, |
| 11209 | ty: Type, |
| 11210 | ) Constant.Tag { |
| 11211 | assert(val_ty != ty); |
| 11212 | return switch (val_ty.scalarTag(self)) { |
| 11213 | .integer => switch (ty.scalarTag(self)) { |
| 11214 | .integer => switch (std.math.order(val_ty.scalarBits(self), ty.scalarBits(self))) { |
| 11215 | .gt => .trunc, |
| 11216 | else => unreachable, |
| 11217 | }, |
| 11218 | .pointer => .inttoptr, |
| 11219 | else => unreachable, |
| 11220 | }, |
| 11221 | .pointer => switch (ty.scalarTag(self)) { |
| 11222 | .integer => .ptrtoint, |
| 11223 | .pointer => .addrspacecast, |
| 11224 | else => unreachable, |
| 11225 | }, |
| 11226 | else => unreachable, |
| 11227 | }; |
| 11228 | } |
| 11229 | |
| 11440 | 11230 | fn convConstAssumeCapacity( |
| 11441 | 11231 | self: *Builder, |
| 11442 | | signedness: Constant.Cast.Signedness, |
| 11443 | 11232 | val: Constant, |
| 11444 | 11233 | ty: Type, |
| 11445 | 11234 | ) Constant { |
| 11446 | 11235 | const val_ty = val.typeOf(self); |
| 11447 | 11236 | if (val_ty == ty) return val; |
| 11448 | | return self.castConstAssumeCapacity(self.convTag(Constant.Tag, signedness, val_ty, ty), val, ty); |
| 11237 | return self.castConstAssumeCapacity(self.convConstTag(val_ty, ty), val, ty); |
| 11449 | 11238 | } |
| 11450 | 11239 | |
| 11451 | 11240 | fn castConstAssumeCapacity(self: *Builder, tag: Constant.Tag, val: Constant, ty: Type) Constant { |
| ... | ... | @@ -11570,179 +11359,6 @@ fn gepConstAssumeCapacity( |
| 11570 | 11359 | return @enumFromInt(gop.index); |
| 11571 | 11360 | } |
| 11572 | 11361 | |
| 11573 | | fn icmpConstAssumeCapacity( |
| 11574 | | self: *Builder, |
| 11575 | | cond: IntegerCondition, |
| 11576 | | lhs: Constant, |
| 11577 | | rhs: Constant, |
| 11578 | | ) Constant { |
| 11579 | | const Adapter = struct { |
| 11580 | | builder: *const Builder, |
| 11581 | | pub fn hash(_: @This(), key: Constant.Compare) u32 { |
| 11582 | | return @truncate(std.hash.Wyhash.hash( |
| 11583 | | std.hash.uint32(@intFromEnum(Constant.tag.icmp)), |
| 11584 | | std.mem.asBytes(&key), |
| 11585 | | )); |
| 11586 | | } |
| 11587 | | pub fn eql(ctx: @This(), lhs_key: Constant.Compare, _: void, rhs_index: usize) bool { |
| 11588 | | if (ctx.builder.constant_items.items(.tag)[rhs_index] != .icmp) return false; |
| 11589 | | const rhs_data = ctx.builder.constant_items.items(.data)[rhs_index]; |
| 11590 | | const rhs_extra = ctx.builder.constantExtraData(Constant.Compare, rhs_data); |
| 11591 | | return std.meta.eql(lhs_key, rhs_extra); |
| 11592 | | } |
| 11593 | | }; |
| 11594 | | const data = Constant.Compare{ .cond = @intFromEnum(cond), .lhs = lhs, .rhs = rhs }; |
| 11595 | | const gop = self.constant_map.getOrPutAssumeCapacityAdapted(data, Adapter{ .builder = self }); |
| 11596 | | if (!gop.found_existing) { |
| 11597 | | gop.key_ptr.* = {}; |
| 11598 | | gop.value_ptr.* = {}; |
| 11599 | | self.constant_items.appendAssumeCapacity(.{ |
| 11600 | | .tag = .icmp, |
| 11601 | | .data = self.addConstantExtraAssumeCapacity(data), |
| 11602 | | }); |
| 11603 | | } |
| 11604 | | return @enumFromInt(gop.index); |
| 11605 | | } |
| 11606 | | |
| 11607 | | fn fcmpConstAssumeCapacity( |
| 11608 | | self: *Builder, |
| 11609 | | cond: FloatCondition, |
| 11610 | | lhs: Constant, |
| 11611 | | rhs: Constant, |
| 11612 | | ) Constant { |
| 11613 | | const Adapter = struct { |
| 11614 | | builder: *const Builder, |
| 11615 | | pub fn hash(_: @This(), key: Constant.Compare) u32 { |
| 11616 | | return @truncate(std.hash.Wyhash.hash( |
| 11617 | | std.hash.uint32(@intFromEnum(Constant.tag.fcmp)), |
| 11618 | | std.mem.asBytes(&key), |
| 11619 | | )); |
| 11620 | | } |
| 11621 | | pub fn eql(ctx: @This(), lhs_key: Constant.Compare, _: void, rhs_index: usize) bool { |
| 11622 | | if (ctx.builder.constant_items.items(.tag)[rhs_index] != .fcmp) return false; |
| 11623 | | const rhs_data = ctx.builder.constant_items.items(.data)[rhs_index]; |
| 11624 | | const rhs_extra = ctx.builder.constantExtraData(Constant.Compare, rhs_data); |
| 11625 | | return std.meta.eql(lhs_key, rhs_extra); |
| 11626 | | } |
| 11627 | | }; |
| 11628 | | const data = Constant.Compare{ .cond = @intFromEnum(cond), .lhs = lhs, .rhs = rhs }; |
| 11629 | | const gop = self.constant_map.getOrPutAssumeCapacityAdapted(data, Adapter{ .builder = self }); |
| 11630 | | if (!gop.found_existing) { |
| 11631 | | gop.key_ptr.* = {}; |
| 11632 | | gop.value_ptr.* = {}; |
| 11633 | | self.constant_items.appendAssumeCapacity(.{ |
| 11634 | | .tag = .fcmp, |
| 11635 | | .data = self.addConstantExtraAssumeCapacity(data), |
| 11636 | | }); |
| 11637 | | } |
| 11638 | | return @enumFromInt(gop.index); |
| 11639 | | } |
| 11640 | | |
| 11641 | | fn extractElementConstAssumeCapacity( |
| 11642 | | self: *Builder, |
| 11643 | | val: Constant, |
| 11644 | | index: Constant, |
| 11645 | | ) Constant { |
| 11646 | | const Adapter = struct { |
| 11647 | | builder: *const Builder, |
| 11648 | | pub fn hash(_: @This(), key: Constant.ExtractElement) u32 { |
| 11649 | | return @truncate(std.hash.Wyhash.hash( |
| 11650 | | comptime std.hash.uint32(@intFromEnum(Constant.Tag.extractelement)), |
| 11651 | | std.mem.asBytes(&key), |
| 11652 | | )); |
| 11653 | | } |
| 11654 | | pub fn eql(ctx: @This(), lhs_key: Constant.ExtractElement, _: void, rhs_index: usize) bool { |
| 11655 | | if (ctx.builder.constant_items.items(.tag)[rhs_index] != .extractelement) return false; |
| 11656 | | const rhs_data = ctx.builder.constant_items.items(.data)[rhs_index]; |
| 11657 | | const rhs_extra = ctx.builder.constantExtraData(Constant.ExtractElement, rhs_data); |
| 11658 | | return std.meta.eql(lhs_key, rhs_extra); |
| 11659 | | } |
| 11660 | | }; |
| 11661 | | const data = Constant.ExtractElement{ .val = val, .index = index }; |
| 11662 | | const gop = self.constant_map.getOrPutAssumeCapacityAdapted(data, Adapter{ .builder = self }); |
| 11663 | | if (!gop.found_existing) { |
| 11664 | | gop.key_ptr.* = {}; |
| 11665 | | gop.value_ptr.* = {}; |
| 11666 | | self.constant_items.appendAssumeCapacity(.{ |
| 11667 | | .tag = .extractelement, |
| 11668 | | .data = self.addConstantExtraAssumeCapacity(data), |
| 11669 | | }); |
| 11670 | | } |
| 11671 | | return @enumFromInt(gop.index); |
| 11672 | | } |
| 11673 | | |
| 11674 | | fn insertElementConstAssumeCapacity( |
| 11675 | | self: *Builder, |
| 11676 | | val: Constant, |
| 11677 | | elem: Constant, |
| 11678 | | index: Constant, |
| 11679 | | ) Constant { |
| 11680 | | const Adapter = struct { |
| 11681 | | builder: *const Builder, |
| 11682 | | pub fn hash(_: @This(), key: Constant.InsertElement) u32 { |
| 11683 | | return @truncate(std.hash.Wyhash.hash( |
| 11684 | | comptime std.hash.uint32(@intFromEnum(Constant.Tag.insertelement)), |
| 11685 | | std.mem.asBytes(&key), |
| 11686 | | )); |
| 11687 | | } |
| 11688 | | pub fn eql(ctx: @This(), lhs_key: Constant.InsertElement, _: void, rhs_index: usize) bool { |
| 11689 | | if (ctx.builder.constant_items.items(.tag)[rhs_index] != .insertelement) return false; |
| 11690 | | const rhs_data = ctx.builder.constant_items.items(.data)[rhs_index]; |
| 11691 | | const rhs_extra = ctx.builder.constantExtraData(Constant.InsertElement, rhs_data); |
| 11692 | | return std.meta.eql(lhs_key, rhs_extra); |
| 11693 | | } |
| 11694 | | }; |
| 11695 | | const data = Constant.InsertElement{ .val = val, .elem = elem, .index = index }; |
| 11696 | | const gop = self.constant_map.getOrPutAssumeCapacityAdapted(data, Adapter{ .builder = self }); |
| 11697 | | if (!gop.found_existing) { |
| 11698 | | gop.key_ptr.* = {}; |
| 11699 | | gop.value_ptr.* = {}; |
| 11700 | | self.constant_items.appendAssumeCapacity(.{ |
| 11701 | | .tag = .insertelement, |
| 11702 | | .data = self.addConstantExtraAssumeCapacity(data), |
| 11703 | | }); |
| 11704 | | } |
| 11705 | | return @enumFromInt(gop.index); |
| 11706 | | } |
| 11707 | | |
| 11708 | | fn shuffleVectorConstAssumeCapacity( |
| 11709 | | self: *Builder, |
| 11710 | | lhs: Constant, |
| 11711 | | rhs: Constant, |
| 11712 | | mask: Constant, |
| 11713 | | ) Constant { |
| 11714 | | assert(lhs.typeOf(self).isVector(self.builder)); |
| 11715 | | assert(lhs.typeOf(self) == rhs.typeOf(self)); |
| 11716 | | assert(mask.typeOf(self).scalarType(self).isInteger(self)); |
| 11717 | | _ = lhs.typeOf(self).changeLengthAssumeCapacity(mask.typeOf(self).vectorLen(self), self); |
| 11718 | | const Adapter = struct { |
| 11719 | | builder: *const Builder, |
| 11720 | | pub fn hash(_: @This(), key: Constant.ShuffleVector) u32 { |
| 11721 | | return @truncate(std.hash.Wyhash.hash( |
| 11722 | | comptime std.hash.uint32(@intFromEnum(Constant.Tag.shufflevector)), |
| 11723 | | std.mem.asBytes(&key), |
| 11724 | | )); |
| 11725 | | } |
| 11726 | | pub fn eql(ctx: @This(), lhs_key: Constant.ShuffleVector, _: void, rhs_index: usize) bool { |
| 11727 | | if (ctx.builder.constant_items.items(.tag)[rhs_index] != .shufflevector) return false; |
| 11728 | | const rhs_data = ctx.builder.constant_items.items(.data)[rhs_index]; |
| 11729 | | const rhs_extra = ctx.builder.constantExtraData(Constant.ShuffleVector, rhs_data); |
| 11730 | | return std.meta.eql(lhs_key, rhs_extra); |
| 11731 | | } |
| 11732 | | }; |
| 11733 | | const data = Constant.ShuffleVector{ .lhs = lhs, .rhs = rhs, .mask = mask }; |
| 11734 | | const gop = self.constant_map.getOrPutAssumeCapacityAdapted(data, Adapter{ .builder = self }); |
| 11735 | | if (!gop.found_existing) { |
| 11736 | | gop.key_ptr.* = {}; |
| 11737 | | gop.value_ptr.* = {}; |
| 11738 | | self.constant_items.appendAssumeCapacity(.{ |
| 11739 | | .tag = .shufflevector, |
| 11740 | | .data = self.addConstantExtraAssumeCapacity(data), |
| 11741 | | }); |
| 11742 | | } |
| 11743 | | return @enumFromInt(gop.index); |
| 11744 | | } |
| 11745 | | |
| 11746 | 11362 | fn binConstAssumeCapacity( |
| 11747 | 11363 | self: *Builder, |
| 11748 | 11364 | tag: Constant.Tag, |
| ... | ... | @@ -11756,14 +11372,7 @@ fn binConstAssumeCapacity( |
| 11756 | 11372 | .sub, |
| 11757 | 11373 | .@"sub nsw", |
| 11758 | 11374 | .@"sub nuw", |
| 11759 | | .mul, |
| 11760 | | .@"mul nsw", |
| 11761 | | .@"mul nuw", |
| 11762 | 11375 | .shl, |
| 11763 | | .lshr, |
| 11764 | | .ashr, |
| 11765 | | .@"and", |
| 11766 | | .@"or", |
| 11767 | 11376 | .xor, |
| 11768 | 11377 | => {}, |
| 11769 | 11378 | else => unreachable, |
| ... | ... | @@ -13938,16 +13547,8 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co |
| 13938 | 13547 | .bitcast, |
| 13939 | 13548 | .inttoptr, |
| 13940 | 13549 | .ptrtoint, |
| 13941 | | .fptosi, |
| 13942 | | .fptoui, |
| 13943 | | .sitofp, |
| 13944 | | .uitofp, |
| 13945 | 13550 | .addrspacecast, |
| 13946 | | .fptrunc, |
| 13947 | 13551 | .trunc, |
| 13948 | | .fpext, |
| 13949 | | .sext, |
| 13950 | | .zext, |
| 13951 | 13552 | => |tag| { |
| 13952 | 13553 | const extra = self.constantExtraData(Constant.Cast, data); |
| 13953 | 13554 | try constants_block.writeAbbrevAdapted(Constants.Cast{ |
| ... | ... | @@ -13962,14 +13563,7 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co |
| 13962 | 13563 | .sub, |
| 13963 | 13564 | .@"sub nsw", |
| 13964 | 13565 | .@"sub nuw", |
| 13965 | | .mul, |
| 13966 | | .@"mul nsw", |
| 13967 | | .@"mul nuw", |
| 13968 | 13566 | .shl, |
| 13969 | | .lshr, |
| 13970 | | .ashr, |
| 13971 | | .@"and", |
| 13972 | | .@"or", |
| 13973 | 13567 | .xor, |
| 13974 | 13568 | => |tag| { |
| 13975 | 13569 | const extra = self.constantExtraData(Constant.Binary, data); |
| ... | ... | @@ -13979,55 +13573,6 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co |
| 13979 | 13573 | .rhs = extra.rhs, |
| 13980 | 13574 | }, constant_adapter); |
| 13981 | 13575 | }, |
| 13982 | | .icmp, |
| 13983 | | .fcmp, |
| 13984 | | => { |
| 13985 | | const extra = self.constantExtraData(Constant.Compare, data); |
| 13986 | | try constants_block.writeAbbrevAdapted(Constants.Cmp{ |
| 13987 | | .ty = extra.lhs.typeOf(self), |
| 13988 | | .lhs = extra.lhs, |
| 13989 | | .rhs = extra.rhs, |
| 13990 | | .pred = extra.cond, |
| 13991 | | }, constant_adapter); |
| 13992 | | }, |
| 13993 | | .extractelement => { |
| 13994 | | const extra = self.constantExtraData(Constant.ExtractElement, data); |
| 13995 | | try constants_block.writeAbbrevAdapted(Constants.ExtractElement{ |
| 13996 | | .val_type = extra.val.typeOf(self), |
| 13997 | | .val = extra.val, |
| 13998 | | .index_type = extra.index.typeOf(self), |
| 13999 | | .index = extra.index, |
| 14000 | | }, constant_adapter); |
| 14001 | | }, |
| 14002 | | .insertelement => { |
| 14003 | | const extra = self.constantExtraData(Constant.InsertElement, data); |
| 14004 | | try constants_block.writeAbbrevAdapted(Constants.InsertElement{ |
| 14005 | | .val = extra.val, |
| 14006 | | .elem = extra.elem, |
| 14007 | | .index_type = extra.index.typeOf(self), |
| 14008 | | .index = extra.index, |
| 14009 | | }, constant_adapter); |
| 14010 | | }, |
| 14011 | | .shufflevector => { |
| 14012 | | const extra = self.constantExtraData(Constant.ShuffleVector, data); |
| 14013 | | const ty = constant.typeOf(self); |
| 14014 | | const lhs_type = extra.lhs.typeOf(self); |
| 14015 | | // Check if instruction is widening, truncating or not |
| 14016 | | if (ty == lhs_type) { |
| 14017 | | try constants_block.writeAbbrevAdapted(Constants.ShuffleVector{ |
| 14018 | | .lhs = extra.lhs, |
| 14019 | | .rhs = extra.rhs, |
| 14020 | | .mask = extra.mask, |
| 14021 | | }, constant_adapter); |
| 14022 | | } else { |
| 14023 | | try constants_block.writeAbbrevAdapted(Constants.ShuffleVectorEx{ |
| 14024 | | .ty = ty, |
| 14025 | | .lhs = extra.lhs, |
| 14026 | | .rhs = extra.rhs, |
| 14027 | | .mask = extra.mask, |
| 14028 | | }, constant_adapter); |
| 14029 | | } |
| 14030 | | }, |
| 14031 | 13576 | .getelementptr, |
| 14032 | 13577 | .@"getelementptr inbounds", |
| 14033 | 13578 | => |tag| { |