authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-07-11 02:14:17-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-07-19 23:38:40-04:00
log1f8407c356b5cdc9eca0f2403a85d863744cf279
treef6d9574718afe541e038a073b35d62c78eb56792
parent7ec7fe53597a70a3f2c9f040d7da978ae3a52a6b

llvm: cleanup management and implement more const functions


3 files changed, 629 insertions(+), 140 deletions(-)

src/codegen/llvm.zig+25-39
......@@ -533,15 +533,6 @@ const DataLayoutBuilder = struct {
533533 }
534534};
535535
536/// TODO can this be done with simpler logic / different API binding?
537fn deleteLlvmGlobal(llvm_global: *llvm.Value) void {
538 if (llvm_global.globalGetValueType().getTypeKind() == .Function) {
539 llvm_global.deleteFunction();
540 return;
541 }
542 return llvm_global.deleteGlobal();
543}
544
545536pub const Object = struct {
546537 gpa: Allocator,
547538 builder: Builder,
......@@ -818,7 +809,7 @@ pub const Object = struct {
818809 .init = str_init,
819810 };
820811 try o.builder.llvm.globals.append(o.gpa, str_global);
821 const str_global_index = try o.builder.addGlobal(.none, global);
812 const str_global_index = try o.builder.addGlobal(.empty, global);
822813 try o.builder.variables.append(o.gpa, variable);
823814
824815 llvm_error.* = try o.builder.structConst(llvm_slice_ty, &.{
......@@ -848,7 +839,7 @@ pub const Object = struct {
848839 .init = error_name_table_init,
849840 };
850841 try o.builder.llvm.globals.append(o.gpa, error_name_table_global);
851 _ = try o.builder.addGlobal(.none, global);
842 _ = try o.builder.addGlobal(.empty, global);
852843 try o.builder.variables.append(o.gpa, variable);
853844
854845 const error_name_table_ptr = error_name_table_global;
......@@ -904,35 +895,27 @@ pub const Object = struct {
904895 // This map has externs with incorrect symbol names.
905896 for (object.extern_collisions.keys()) |decl_index| {
906897 const global = object.decl_map.get(decl_index) orelse continue;
907 const llvm_global = global.toLlvm(&object.builder);
908898 // Same logic as below but for externs instead of exports.
909899 const decl_name = object.builder.stringIfExists(mod.intern_pool.stringToSlice(mod.declPtr(decl_index).name)) orelse continue;
910900 const other_global = object.builder.getGlobal(decl_name) orelse continue;
911 const other_llvm_global = other_global.toLlvm(&object.builder);
912 if (other_llvm_global == llvm_global) continue;
901 if (other_global.eql(global, &object.builder)) continue;
913902
914 llvm_global.replaceAllUsesWith(other_llvm_global);
915 deleteLlvmGlobal(llvm_global);
916 object.builder.llvm.globals.items[@intFromEnum(global)] = other_llvm_global;
903 try global.replace(other_global, &object.builder);
917904 }
918905 object.extern_collisions.clearRetainingCapacity();
919906
920907 for (mod.decl_exports.keys(), mod.decl_exports.values()) |decl_index, export_list| {
921908 const global = object.decl_map.get(decl_index) orelse continue;
922 const llvm_global = global.toLlvm(&object.builder);
923909 for (export_list.items) |exp| {
924910 // Detect if the LLVM global has already been created as an extern. In such
925911 // case, we need to replace all uses of it with this exported global.
926912 const exp_name = object.builder.stringIfExists(mod.intern_pool.stringToSlice(exp.opts.name)) orelse continue;
927913
928914 const other_global = object.builder.getGlobal(exp_name) orelse continue;
929 const other_llvm_global = other_global.toLlvm(&object.builder);
930 if (other_llvm_global == llvm_global) continue;
915 if (other_global.eql(global, &object.builder)) continue;
931916
932 other_llvm_global.replaceAllUsesWith(llvm_global);
933 try global.takeName(&object.builder, other_global);
934 deleteLlvmGlobal(other_llvm_global);
935 object.builder.llvm.globals.items[@intFromEnum(other_global)] = llvm_global;
917 try global.takeName(other_global, &object.builder);
918 try other_global.replace(global, &object.builder);
936919 // Problem: now we need to replace in the decl_map that
937920 // the extern decl index points to this new global. However we don't
938921 // know the decl index.
......@@ -1519,7 +1502,7 @@ pub const Object = struct {
15191502 }
15201503 }
15211504
1522 try global.rename(&self.builder, decl_name);
1505 try global.rename(decl_name, &self.builder);
15231506 global.ptr(&self.builder).unnamed_addr = .default;
15241507 llvm_global.setUnnamedAddr(.False);
15251508 global.ptr(&self.builder).linkage = .external;
......@@ -1558,7 +1541,7 @@ pub const Object = struct {
15581541 global.ptr(&self.builder).updateAttributes();
15591542 } else if (exports.len != 0) {
15601543 const exp_name = try self.builder.string(mod.intern_pool.stringToSlice(exports[0].opts.name));
1561 try global.rename(&self.builder, exp_name);
1544 try global.rename(exp_name, &self.builder);
15621545 global.ptr(&self.builder).unnamed_addr = .default;
15631546 llvm_global.setUnnamedAddr(.False);
15641547 if (mod.wantDllExports()) {
......@@ -1641,7 +1624,7 @@ pub const Object = struct {
16411624 }
16421625 } else {
16431626 const fqn = try self.builder.string(mod.intern_pool.stringToSlice(try decl.getFullyQualifiedName(mod)));
1644 try global.rename(&self.builder, fqn);
1627 try global.rename(fqn, &self.builder);
16451628 global.ptr(&self.builder).linkage = .internal;
16461629 llvm_global.setLinkage(.Internal);
16471630 if (mod.wantDllExports()) {
......@@ -2738,7 +2721,7 @@ pub const Object = struct {
27382721 .init = llvm_init,
27392722 };
27402723 try o.builder.llvm.globals.append(o.gpa, llvm_global);
2741 _ = try o.builder.addGlobal(.none, global);
2724 _ = try o.builder.addGlobal(.empty, global);
27422725 try o.builder.variables.append(o.gpa, variable);
27432726
27442727 const addrspace_casted_global = if (llvm_wanted_addrspace != llvm_actual_addrspace)
......@@ -4473,8 +4456,8 @@ pub const DeclGen = struct {
44734456 _ = try o.resolveLlvmFunction(extern_func.decl);
44744457 } else {
44754458 const target = mod.getTarget();
4476 const object = try o.resolveGlobalDecl(decl_index);
4477 const global = object.ptrConst(&o.builder).global;
4459 const variable = try o.resolveGlobalDecl(decl_index);
4460 const global = variable.ptrConst(&o.builder).global;
44784461 var llvm_global = global.toLlvm(&o.builder);
44794462 global.ptr(&o.builder).alignment = Builder.Alignment.fromByteUnits(decl.getAlignment(mod));
44804463 llvm_global.setAlignment(decl.getAlignment(mod));
......@@ -4483,18 +4466,18 @@ pub const DeclGen = struct {
44834466 llvm_global.setSection(section);
44844467 }
44854468 assert(decl.has_tv);
4486 const init_val = if (decl.val.getVariable(mod)) |decl_var| init_val: {
4487 object.ptr(&o.builder).mutability = .global;
4488 break :init_val decl_var.init;
4489 } else init_val: {
4490 object.ptr(&o.builder).mutability = .constant;
4469 const init_val = if (decl.val.getVariable(mod)) |decl_var| decl_var.init else init_val: {
4470 variable.ptr(&o.builder).mutability = .constant;
44914471 llvm_global.setGlobalConstant(.True);
44924472 break :init_val decl.val.toIntern();
44934473 };
44944474 if (init_val != .none) {
44954475 const llvm_init = try o.lowerValue(init_val);
4476 const llvm_init_ty = llvm_init.typeOf(&o.builder);
4477 global.ptr(&o.builder).type = llvm_init_ty;
4478 variable.ptr(&o.builder).mutability = .global;
4479 variable.ptr(&o.builder).init = llvm_init;
44964480 if (llvm_global.globalGetValueType() == llvm_init.typeOf(&o.builder).toLlvm(&o.builder)) {
4497 object.ptr(&o.builder).init = llvm_init;
44984481 llvm_global.setInitializer(llvm_init.toLlvm(&o.builder));
44994482 } else {
45004483 // LLVM does not allow us to change the type of globals. So we must
......@@ -4512,7 +4495,7 @@ pub const DeclGen = struct {
45124495 // Related: https://github.com/ziglang/zig/issues/13265
45134496 const llvm_global_addrspace = toLlvmGlobalAddressSpace(decl.@"addrspace", target);
45144497 const new_global = o.llvm_module.addGlobalInAddressSpace(
4515 llvm_init.typeOf(&o.builder).toLlvm(&o.builder),
4498 llvm_init_ty.toLlvm(&o.builder),
45164499 "",
45174500 @intFromEnum(llvm_global_addrspace),
45184501 );
......@@ -4525,7 +4508,7 @@ pub const DeclGen = struct {
45254508 // TODO: How should this work then the address space of a global changed?
45264509 llvm_global.replaceAllUsesWith(new_global);
45274510 new_global.takeName(llvm_global);
4528 o.builder.llvm.globals.items[@intFromEnum(object.ptrConst(&o.builder).global)] =
4511 o.builder.llvm.globals.items[@intFromEnum(variable.ptrConst(&o.builder).global)] =
45294512 new_global;
45304513 llvm_global.deleteGlobal();
45314514 llvm_global = new_global;
......@@ -4672,7 +4655,7 @@ pub const FuncGen = struct {
46724655 .init = llvm_val,
46734656 };
46744657 try o.builder.llvm.globals.append(o.gpa, llvm_global);
4675 _ = try o.builder.addGlobal(.none, global);
4658 _ = try o.builder.addGlobal(.empty, global);
46764659 try o.builder.variables.append(o.gpa, variable);
46774660
46784661 const addrspace_casted_ptr = if (llvm_actual_addrspace != llvm_wanted_addrspace)
......@@ -9312,6 +9295,7 @@ pub const FuncGen = struct {
93129295 };
93139296 var function = Builder.Function{
93149297 .global = @enumFromInt(o.builder.globals.count()),
9298 .body = {},
93159299 };
93169300
93179301 const prev_block = self.builder.getInsertBlock();
......@@ -9395,6 +9379,7 @@ pub const FuncGen = struct {
93959379 };
93969380 var function = Builder.Function{
93979381 .global = @enumFromInt(o.builder.globals.count()),
9382 .body = {},
93989383 };
93999384
94009385 const prev_block = self.builder.getInsertBlock();
......@@ -9485,6 +9470,7 @@ pub const FuncGen = struct {
94859470 };
94869471 var function = Builder.Function{
94879472 .global = @enumFromInt(o.builder.globals.count()),
9473 .body = {},
94889474 };
94899475
94909476 try o.builder.llvm.globals.append(self.gpa, llvm_fn);
src/codegen/llvm/Builder.zig+514-65
......@@ -29,6 +29,7 @@ type_extra: std.ArrayListUnmanaged(u32) = .{},
2929
3030globals: std.AutoArrayHashMapUnmanaged(String, Global) = .{},
3131next_unnamed_global: String = @enumFromInt(0),
32next_replaced_global: String = .none,
3233next_unique_global_id: std.AutoHashMapUnmanaged(String, u32) = .{},
3334aliases: std.ArrayListUnmanaged(Alias) = .{},
3435variables: std.ArrayListUnmanaged(Variable) = .{},
......@@ -55,6 +56,11 @@ pub const String = enum(u32) {
5556 empty,
5657 _,
5758
59 pub fn isAnon(self: String) bool {
60 assert(self != .none);
61 return self.toIndex() == null;
62 }
63
5864 pub fn toSlice(self: String, b: *const Builder) ?[:0]const u8 {
5965 const index = self.toIndex() orelse return null;
6066 const start = b.string_indices.items[index];
......@@ -743,18 +749,36 @@ pub const Global = struct {
743749 alias: Alias.Index,
744750 variable: Variable.Index,
745751 function: Function.Index,
752 replaced: Global.Index,
746753 },
747754
748755 pub const Index = enum(u32) {
749756 none = std.math.maxInt(u32),
750757 _,
751758
759 pub fn unwrap(self: Index, builder: *const Builder) Index {
760 var cur = self;
761 while (true) {
762 const replacement = cur.getReplacement(builder);
763 if (replacement == .none) return cur;
764 cur = replacement;
765 }
766 }
767
768 pub fn eql(self: Index, other: Index, builder: *const Builder) bool {
769 return self.unwrap(builder) == other.unwrap(builder);
770 }
771
772 pub fn name(self: Index, builder: *const Builder) String {
773 return builder.globals.keys()[@intFromEnum(self.unwrap(builder))];
774 }
775
752776 pub fn ptr(self: Index, builder: *Builder) *Global {
753 return &builder.globals.values()[@intFromEnum(self)];
777 return &builder.globals.values()[@intFromEnum(self.unwrap(builder))];
754778 }
755779
756780 pub fn ptrConst(self: Index, builder: *const Builder) *const Global {
757 return &builder.globals.values()[@intFromEnum(self)];
781 return &builder.globals.values()[@intFromEnum(self.unwrap(builder))];
758782 }
759783
760784 pub fn toConst(self: Index) Constant {
......@@ -763,7 +787,7 @@ pub const Global = struct {
763787
764788 pub fn toLlvm(self: Index, builder: *const Builder) *llvm.Value {
765789 assert(builder.useLibLlvm());
766 return builder.llvm.globals.items[@intFromEnum(self)];
790 return builder.llvm.globals.items[@intFromEnum(self.unwrap(builder))];
767791 }
768792
769793 const FormatData = struct {
......@@ -777,44 +801,80 @@ pub const Global = struct {
777801 writer: anytype,
778802 ) @TypeOf(writer).Error!void {
779803 try writer.print("@{}", .{
780 data.builder.globals.keys()[@intFromEnum(data.global)].fmt(data.builder),
804 data.global.unwrap(data.builder).name(data.builder).fmt(data.builder),
781805 });
782806 }
783807 pub fn fmt(self: Index, builder: *const Builder) std.fmt.Formatter(format) {
784808 return .{ .data = .{ .global = self, .builder = builder } };
785809 }
786810
787 pub fn rename(self: Index, builder: *Builder, name: String) Allocator.Error!void {
788 try builder.ensureUnusedCapacityGlobal(name);
789 self.renameAssumeCapacity(builder, name);
811 pub fn rename(self: Index, new_name: String, builder: *Builder) Allocator.Error!void {
812 try builder.ensureUnusedCapacityGlobal(new_name);
813 self.renameAssumeCapacity(new_name, builder);
790814 }
791815
792 pub fn renameAssumeCapacity(self: Index, builder: *Builder, name: String) void {
793 const index = @intFromEnum(self);
794 if (builder.globals.keys()[index] == name) return;
795 if (builder.useLibLlvm()) builder.llvm.globals.appendAssumeCapacity(builder.llvm.globals.items[index]);
796 _ = builder.addGlobalAssumeCapacity(name, builder.globals.values()[index]);
797 if (builder.useLibLlvm()) _ = builder.llvm.globals.pop();
798 builder.globals.swapRemoveAt(index);
799 self.updateName(builder);
816 pub fn takeName(self: Index, other: Index, builder: *Builder) Allocator.Error!void {
817 try builder.ensureUnusedCapacityGlobal(.empty);
818 self.takeNameAssumeCapacity(other, builder);
800819 }
801820
802 pub fn takeName(self: Index, builder: *Builder, other: Index) Allocator.Error!void {
821 pub fn replace(self: Index, other: Index, builder: *Builder) Allocator.Error!void {
803822 try builder.ensureUnusedCapacityGlobal(.empty);
804 self.takeNameAssumeCapacity(builder, other);
823 self.replaceAssumeCapacity(other, builder);
824 }
825
826 fn renameAssumeCapacity(self: Index, new_name: String, builder: *Builder) void {
827 const old_name = self.name(builder);
828 if (new_name == old_name) return;
829 const index = @intFromEnum(self.unwrap(builder));
830 if (builder.useLibLlvm())
831 builder.llvm.globals.appendAssumeCapacity(builder.llvm.globals.items[index]);
832 _ = builder.addGlobalAssumeCapacity(new_name, builder.globals.values()[index]);
833 if (builder.useLibLlvm()) _ = builder.llvm.globals.pop();
834 builder.globals.swapRemoveAt(index);
835 self.updateName(builder);
836 if (!old_name.isAnon()) return;
837 builder.next_unnamed_global = @enumFromInt(@intFromEnum(builder.next_unnamed_global) - 1);
838 if (builder.next_unnamed_global == old_name) return;
839 builder.getGlobal(builder.next_unnamed_global).?.renameAssumeCapacity(old_name, builder);
805840 }
806841
807 pub fn takeNameAssumeCapacity(self: Index, builder: *Builder, other: Index) void {
808 const other_name = builder.globals.keys()[@intFromEnum(other)];
809 other.renameAssumeCapacity(builder, .none);
810 self.renameAssumeCapacity(builder, other_name);
842 fn takeNameAssumeCapacity(self: Index, other: Index, builder: *Builder) void {
843 const other_name = other.name(builder);
844 other.renameAssumeCapacity(.empty, builder);
845 self.renameAssumeCapacity(other_name, builder);
811846 }
812847
813848 fn updateName(self: Index, builder: *const Builder) void {
814849 if (!builder.useLibLlvm()) return;
815 const index = @intFromEnum(self);
816 const slice = builder.globals.keys()[index].toSlice(builder) orelse "";
817 builder.llvm.globals.items[index].setValueName2(slice.ptr, slice.len);
850 const index = @intFromEnum(self.unwrap(builder));
851 const name_slice = self.name(builder).toSlice(builder) orelse "";
852 builder.llvm.globals.items[index].setValueName2(name_slice.ptr, name_slice.len);
853 }
854
855 fn replaceAssumeCapacity(self: Index, other: Index, builder: *Builder) void {
856 if (self.eql(other, builder)) return;
857 builder.next_replaced_global = @enumFromInt(@intFromEnum(builder.next_replaced_global) - 1);
858 self.renameAssumeCapacity(builder.next_replaced_global, builder);
859 if (builder.useLibLlvm()) {
860 const self_llvm = self.toLlvm(builder);
861 self_llvm.replaceAllUsesWith(other.toLlvm(builder));
862 switch (self.ptr(builder).kind) {
863 .alias,
864 .variable,
865 => self_llvm.deleteGlobal(),
866 .function => self_llvm.deleteFunction(),
867 .replaced => unreachable,
868 }
869 }
870 self.ptr(builder).kind = .{ .replaced = other.unwrap(builder) };
871 }
872
873 fn getReplacement(self: Index, builder: *const Builder) Index {
874 return switch (builder.globals.values()[@intFromEnum(self)].kind) {
875 .replaced => |replacement| replacement,
876 else => .none,
877 };
818878 }
819879 };
820880
......@@ -1014,8 +1074,14 @@ pub const Constant = enum(u32) {
10141074 insertelement,
10151075 shufflevector,
10161076 add,
1077 @"add nsw",
1078 @"add nuw",
10171079 sub,
1080 @"sub nsw",
1081 @"sub nuw",
10181082 mul,
1083 @"mul nsw",
1084 @"mul nuw",
10191085 shl,
10201086 lshr,
10211087 ashr,
......@@ -1084,24 +1150,24 @@ pub const Constant = enum(u32) {
10841150 pub const Kind = enum { normal, inbounds };
10851151 };
10861152
1087 pub const Compare = struct {
1153 pub const Compare = extern struct {
10881154 cond: u32,
10891155 lhs: Constant,
10901156 rhs: Constant,
10911157 };
10921158
1093 pub const ExtractElement = struct {
1159 pub const ExtractElement = extern struct {
10941160 arg: Constant,
10951161 index: Constant,
10961162 };
10971163
1098 pub const InsertElement = struct {
1164 pub const InsertElement = extern struct {
10991165 arg: Constant,
11001166 elem: Constant,
11011167 index: Constant,
11021168 };
11031169
1104 pub const ShuffleVector = struct {
1170 pub const ShuffleVector = extern struct {
11051171 lhs: Constant,
11061172 rhs: Constant,
11071173 mask: Constant,
......@@ -1243,8 +1309,14 @@ pub const Constant = enum(u32) {
12431309 };
12441310 },
12451311 .add,
1312 .@"add nsw",
1313 .@"add nuw",
12461314 .sub,
1315 .@"sub nsw",
1316 .@"sub nuw",
12471317 .mul,
1318 .@"mul nsw",
1319 .@"mul nuw",
12481320 .shl,
12491321 .lshr,
12501322 .ashr,
......@@ -1326,14 +1398,14 @@ pub const Constant = enum(u32) {
13261398 switch (item.tag) {
13271399 .positive_integer,
13281400 .negative_integer,
1329 => {
1401 => |tag| {
13301402 const extra: *align(@alignOf(std.math.big.Limb)) Integer =
13311403 @ptrCast(data.builder.constant_limbs.items[item.data..][0..Integer.limbs]);
13321404 const limbs = data.builder.constant_limbs
13331405 .items[item.data + Integer.limbs ..][0..extra.limbs_len];
13341406 const bigint = std.math.big.int.Const{
13351407 .limbs = limbs,
1336 .positive = item.tag == .positive_integer,
1408 .positive = tag == .positive_integer,
13371409 };
13381410 const ExpectedContents = extern struct {
13391411 string: [(64 * 8 / std.math.log2(10)) + 2]u8,
......@@ -1352,23 +1424,63 @@ pub const Constant = enum(u32) {
13521424 defer allocator.free(str);
13531425 try writer.writeAll(str);
13541426 },
1427 .half,
1428 .bfloat,
1429 => |tag| try writer.print("0x{c}{X:0>4}", .{ @as(u8, switch (tag) {
1430 .half => 'H',
1431 .bfloat => 'R',
1432 else => unreachable,
1433 }), item.data >> switch (tag) {
1434 .half => 0,
1435 .bfloat => 16,
1436 else => unreachable,
1437 } }),
1438 .float => try writer.print("0x{X:0>16}", .{
1439 @as(u64, @bitCast(@as(f64, @as(f32, @bitCast(item.data))))),
1440 }),
1441 .double => {
1442 const extra = data.builder.constantExtraData(Double, item.data);
1443 try writer.print("0x{X:0>8}{X:0>8}", .{ extra.hi, extra.lo });
1444 },
1445 .fp128,
1446 .ppc_fp128,
1447 => |tag| {
1448 const extra = data.builder.constantExtraData(Fp128, item.data);
1449 try writer.print("0x{c}{X:0>8}{X:0>8}{X:0>8}{X:0>8}", .{
1450 @as(u8, switch (tag) {
1451 .fp128 => 'L',
1452 .ppc_fp128 => 'M',
1453 else => unreachable,
1454 }),
1455 extra.lo_hi,
1456 extra.lo_lo,
1457 extra.hi_hi,
1458 extra.hi_lo,
1459 });
1460 },
1461 .x86_fp80 => {
1462 const extra = data.builder.constantExtraData(Fp80, item.data);
1463 try writer.print("0xK{X:0>4}{X:0>8}{X:0>8}", .{
1464 extra.hi, extra.lo_hi, extra.lo_lo,
1465 });
1466 },
13551467 .null,
13561468 .none,
13571469 .zeroinitializer,
13581470 .undef,
13591471 .poison,
1360 => try writer.writeAll(@tagName(item.tag)),
1472 => |tag| try writer.writeAll(@tagName(tag)),
13611473 .structure,
13621474 .packed_structure,
13631475 .array,
13641476 .vector,
1365 => {
1477 => |tag| {
13661478 const extra = data.builder.constantExtraDataTrail(Aggregate, item.data);
13671479 const len = extra.data.type.aggregateLen(data.builder);
13681480 const vals: []const Constant =
13691481 @ptrCast(data.builder.constant_extra.items[extra.end..][0..len]);
13701482
1371 try writer.writeAll(switch (item.tag) {
1483 try writer.writeAll(switch (tag) {
13721484 .structure => "{ ",
13731485 .packed_structure => "<{ ",
13741486 .array => "[",
......@@ -1379,7 +1491,7 @@ pub const Constant = enum(u32) {
13791491 if (index > 0) try writer.writeAll(", ");
13801492 try writer.print("{%}", .{val.fmt(data.builder)});
13811493 }
1382 try writer.writeAll(switch (item.tag) {
1494 try writer.writeAll(switch (tag) {
13831495 .structure => " }",
13841496 .packed_structure => " }>",
13851497 .array => "]",
......@@ -1387,33 +1499,130 @@ pub const Constant = enum(u32) {
13871499 else => unreachable,
13881500 });
13891501 },
1390 .string => try writer.print(
1391 \\c{"}
1392 , .{@as(String, @enumFromInt(item.data)).fmt(data.builder)}),
1393 .string_null => try writer.print(
1394 \\c{"@}
1395 , .{@as(String, @enumFromInt(item.data)).fmt(data.builder)}),
1396 .blockaddress => {
1502 inline .string,
1503 .string_null,
1504 => |tag| try writer.print("c{\"" ++ switch (tag) {
1505 .string => "",
1506 .string_null => "@",
1507 else => unreachable,
1508 } ++ "}", .{@as(String, @enumFromInt(item.data)).fmt(data.builder)}),
1509 .blockaddress => |tag| {
13971510 const extra = data.builder.constantExtraData(BlockAddress, item.data);
13981511 const function = extra.function.ptrConst(data.builder);
13991512 try writer.print("{s}({}, %{d})", .{
1400 @tagName(item.tag),
1513 @tagName(tag),
14011514 function.global.fmt(data.builder),
14021515 @intFromEnum(extra.block), // TODO
14031516 });
14041517 },
14051518 .dso_local_equivalent,
14061519 .no_cfi,
1407 => {
1520 => |tag| {
14081521 const extra = data.builder.constantExtraData(FunctionReference, item.data);
14091522 try writer.print("{s} {}", .{
1410 @tagName(item.tag),
1523 @tagName(tag),
14111524 extra.function.ptrConst(data.builder).global.fmt(data.builder),
14121525 });
14131526 },
1414 else => try writer.print("<{s}:0x{X}>", .{
1415 @tagName(item.tag), @intFromEnum(data.constant),
1416 }),
1527 .trunc,
1528 .zext,
1529 .sext,
1530 .fptrunc,
1531 .fpext,
1532 .fptoui,
1533 .fptosi,
1534 .uitofp,
1535 .sitofp,
1536 .ptrtoint,
1537 .inttoptr,
1538 .bitcast,
1539 .addrspacecast,
1540 => |tag| {
1541 const extra = data.builder.constantExtraData(Cast, item.data);
1542 try writer.print("{s} ({%} to {%})", .{
1543 @tagName(tag),
1544 extra.arg.fmt(data.builder),
1545 extra.type.fmt(data.builder),
1546 });
1547 },
1548 .getelementptr,
1549 .@"getelementptr inbounds",
1550 => |tag| {
1551 const extra = data.builder.constantExtraDataTrail(GetElementPtr, item.data);
1552 const indices: []const Constant = @ptrCast(data.builder.constant_extra
1553 .items[extra.end..][0..extra.data.indices_len]);
1554 try writer.print("{s} ({%}, {%}", .{
1555 @tagName(tag),
1556 extra.data.type.fmt(data.builder),
1557 extra.data.base.fmt(data.builder),
1558 });
1559 for (indices) |index| try writer.print(", {%}", .{index.fmt(data.builder)});
1560 try writer.writeByte(')');
1561 },
1562 inline .icmp,
1563 .fcmp,
1564 => |tag| {
1565 const extra = data.builder.constantExtraData(Compare, item.data);
1566 try writer.print("{s} {s} ({%}, {%})", .{
1567 @tagName(tag),
1568 @tagName(@as(switch (tag) {
1569 .icmp => IntegerCondition,
1570 .fcmp => FloatCondition,
1571 else => unreachable,
1572 }, @enumFromInt(extra.cond))),
1573 extra.lhs.fmt(data.builder),
1574 extra.rhs.fmt(data.builder),
1575 });
1576 },
1577 .extractelement => |tag| {
1578 const extra = data.builder.constantExtraData(ExtractElement, item.data);
1579 try writer.print("{s} ({%}, {%})", .{
1580 @tagName(tag),
1581 extra.arg.fmt(data.builder),
1582 extra.index.fmt(data.builder),
1583 });
1584 },
1585 .insertelement => |tag| {
1586 const extra = data.builder.constantExtraData(InsertElement, item.data);
1587 try writer.print("{s} ({%}, {%}, {%})", .{
1588 @tagName(tag),
1589 extra.arg.fmt(data.builder),
1590 extra.elem.fmt(data.builder),
1591 extra.index.fmt(data.builder),
1592 });
1593 },
1594 .shufflevector => |tag| {
1595 const extra = data.builder.constantExtraData(ShuffleVector, item.data);
1596 try writer.print("{s} ({%}, {%}, {%})", .{
1597 @tagName(tag),
1598 extra.lhs.fmt(data.builder),
1599 extra.rhs.fmt(data.builder),
1600 extra.mask.fmt(data.builder),
1601 });
1602 },
1603 .add,
1604 .@"add nsw",
1605 .@"add nuw",
1606 .sub,
1607 .@"sub nsw",
1608 .@"sub nuw",
1609 .mul,
1610 .@"mul nsw",
1611 .@"mul nuw",
1612 .shl,
1613 .lshr,
1614 .ashr,
1615 .@"and",
1616 .@"or",
1617 .xor,
1618 => |tag| {
1619 const extra = data.builder.constantExtraData(Binary, item.data);
1620 try writer.print("{s} ({%}, {%})", .{
1621 @tagName(tag),
1622 extra.lhs.fmt(data.builder),
1623 extra.rhs.fmt(data.builder),
1624 });
1625 },
14171626 }
14181627 },
14191628 .global => |global| try writer.print("{}", .{global.fmt(data.builder)}),
......@@ -1882,6 +2091,7 @@ pub fn namedTypeSetBody(
18822091}
18832092
18842093pub fn addGlobal(self: *Builder, name: String, global: Global) Allocator.Error!Global.Index {
2094 assert(!name.isAnon());
18852095 try self.ensureUnusedTypeCapacity(1, null, 0);
18862096 try self.ensureUnusedCapacityGlobal(name);
18872097 return self.addGlobalAssumeCapacity(name, global);
......@@ -1890,9 +2100,10 @@ pub fn addGlobal(self: *Builder, name: String, global: Global) Allocator.Error!G
18902100pub fn addGlobalAssumeCapacity(self: *Builder, name: String, global: Global) Global.Index {
18912101 _ = self.ptrTypeAssumeCapacity(global.addr_space);
18922102 var id = name;
1893 if (id == .none) {
2103 if (name == .empty) {
18942104 id = self.next_unnamed_global;
1895 self.next_unnamed_global = @enumFromInt(@intFromEnum(self.next_unnamed_global) + 1);
2105 assert(id != self.next_replaced_global);
2106 self.next_unnamed_global = @enumFromInt(@intFromEnum(id) + 1);
18962107 }
18972108 while (true) {
18982109 const global_gop = self.globals.getOrPutAssumeCapacity(id);
......@@ -2136,7 +2347,7 @@ pub fn binConst(
21362347 return self.binConstAssumeCapacity(tag, lhs, rhs);
21372348}
21382349
2139pub fn dump(self: *Builder, writer: anytype) @TypeOf(writer).Error!void {
2350pub fn dump(self: *Builder, writer: anytype) (@TypeOf(writer).Error || Allocator.Error)!void {
21402351 if (self.source_filename != .none) try writer.print(
21412352 \\; ModuleID = '{s}'
21422353 \\source_filename = {"}
......@@ -2157,7 +2368,8 @@ pub fn dump(self: *Builder, writer: anytype) @TypeOf(writer).Error!void {
21572368 , .{ id.fmt(self), ty.fmt(self) });
21582369 try writer.writeByte('\n');
21592370 for (self.variables.items) |variable| {
2160 const global = self.globals.values()[@intFromEnum(variable.global)];
2371 if (variable.global.getReplacement(self) != .none) continue;
2372 const global = variable.global.ptrConst(self);
21612373 try writer.print(
21622374 \\{} ={}{}{}{}{}{}{}{} {s} {%}{ }{,}
21632375 \\
......@@ -2179,7 +2391,8 @@ pub fn dump(self: *Builder, writer: anytype) @TypeOf(writer).Error!void {
21792391 }
21802392 try writer.writeByte('\n');
21812393 for (self.functions.items) |function| {
2182 const global = self.globals.values()[@intFromEnum(function.global)];
2394 if (function.global.getReplacement(self) != .none) continue;
2395 const global = function.global.ptrConst(self);
21832396 const item = self.type_items.items[@intFromEnum(global.type)];
21842397 const extra = self.typeExtraDataTrail(Type.Function, item.data);
21852398 const params: []const Type =
......@@ -2207,14 +2420,51 @@ pub fn dump(self: *Builder, writer: anytype) @TypeOf(writer).Error!void {
22072420 },
22082421 else => unreachable,
22092422 }
2210 try writer.print(") {}{}", .{ global.unnamed_addr, global.alignment });
2211 if (function.body) |_| try writer.print(
2212 \\{{
2213 \\ ret {%}
2214 \\}}
2215 \\
2216 , .{extra.data.ret.fmt(self)});
2217 try writer.writeByte('\n');
2423 try writer.print("){}{}", .{ global.unnamed_addr, global.alignment });
2424 if (function.body) |_| {
2425 try writer.writeAll(" {\n ret ");
2426 void: {
2427 try writer.print("{%}", .{switch (extra.data.ret) {
2428 .void => |tag| {
2429 try writer.writeAll(@tagName(tag));
2430 break :void;
2431 },
2432 inline .half,
2433 .bfloat,
2434 .float,
2435 .double,
2436 .fp128,
2437 .x86_fp80,
2438 => |tag| try @field(Builder, @tagName(tag) ++ "Const")(self, 0.0),
2439 .ppc_fp128 => try self.ppc_fp128Const(.{ 0.0, 0.0 }),
2440 .x86_amx,
2441 .x86_mmx,
2442 .label,
2443 .metadata,
2444 => unreachable,
2445 .token => Constant.none,
2446 else => switch (extra.data.ret.tag(self)) {
2447 .simple,
2448 .function,
2449 .vararg_function,
2450 => unreachable,
2451 .integer => try self.intConst(extra.data.ret, 0),
2452 .pointer => try self.nullConst(extra.data.ret),
2453 .target,
2454 .vector,
2455 .scalable_vector,
2456 .small_array,
2457 .array,
2458 .structure,
2459 .packed_structure,
2460 .named_structure,
2461 => try self.zeroInitConst(extra.data.ret),
2462 },
2463 }.fmt(self)});
2464 }
2465 try writer.writeAll("\n}");
2466 }
2467 try writer.writeAll("\n\n");
22182468 }
22192469}
22202470
......@@ -2497,11 +2747,11 @@ fn opaqueTypeAssumeCapacity(self: *Builder, name: String) Type {
24972747 }
24982748 };
24992749 var id = name;
2500 if (name == .none) {
2750 if (name == .empty) {
25012751 id = self.next_unnamed_type;
25022752 assert(id != .none);
25032753 self.next_unnamed_type = @enumFromInt(@intFromEnum(id) + 1);
2504 } else assert(name.toIndex() != null);
2754 } else assert(!name.isAnon());
25052755 while (true) {
25062756 const type_gop = self.types.getOrPutAssumeCapacity(id);
25072757 if (!type_gop.found_existing) {
......@@ -2783,8 +3033,8 @@ fn doubleConstAssumeCapacity(self: *Builder, val: f64) Constant {
27833033 self.constant_items.appendAssumeCapacity(.{
27843034 .tag = .double,
27853035 .data = self.addConstantExtraAssumeCapacity(Constant.Double{
2786 .lo = @intCast(@as(u64, @bitCast(val)) >> 32),
2787 .hi = @truncate(@as(u64, @bitCast(val))),
3036 .lo = @truncate(@as(u64, @bitCast(val))),
3037 .hi = @intCast(@as(u64, @bitCast(val)) >> 32),
27883038 }),
27893039 });
27903040 if (self.useLibLlvm()) self.llvm.constants.appendAssumeCapacity(
......@@ -3401,6 +3651,190 @@ fn gepConstAssumeCapacity(
34013651 return @enumFromInt(gop.index);
34023652}
34033653
3654fn icmpConstAssumeCapacity(
3655 self: *Builder,
3656 cond: IntegerCondition,
3657 lhs: Constant,
3658 rhs: Constant,
3659) Constant {
3660 const Adapter = struct {
3661 builder: *const Builder,
3662 pub fn hash(_: @This(), key: Constant.Compare) u32 {
3663 return @truncate(std.hash.Wyhash.hash(
3664 std.hash.uint32(@intFromEnum(Constant.tag.icmp)),
3665 std.mem.asBytes(&key),
3666 ));
3667 }
3668 pub fn eql(ctx: @This(), lhs_key: Constant.Compare, _: void, rhs_index: usize) bool {
3669 if (ctx.builder.constant_items.items(.tag)[rhs_index] != .icmp) return false;
3670 const rhs_data = ctx.builder.constant_items.items(.data)[rhs_index];
3671 const rhs_extra = ctx.builder.constantExtraData(Constant.Compare, rhs_data);
3672 return std.meta.eql(lhs_key, rhs_extra);
3673 }
3674 };
3675 const data = Constant.Compare{ .cond = @intFromEnum(cond), .lhs = lhs, .rhs = rhs };
3676 const gop = self.constant_map.getOrPutAssumeCapacityAdapted(data, Adapter{ .builder = self });
3677 if (!gop.found_existing) {
3678 gop.key_ptr.* = {};
3679 gop.value_ptr.* = {};
3680 self.constant_items.appendAssumeCapacity(.{
3681 .tag = .icmp,
3682 .data = self.addConstantExtraAssumeCapacity(data),
3683 });
3684 if (self.useLibLlvm()) self.llvm.constants.appendAssumeCapacity(
3685 llvm.constICmp(@enumFromInt(@intFromEnum(cond)), lhs.toLlvm(self), rhs.toLlvm(self)),
3686 );
3687 }
3688 return @enumFromInt(gop.index);
3689}
3690
3691fn fcmpConstAssumeCapacity(
3692 self: *Builder,
3693 cond: FloatCondition,
3694 lhs: Constant,
3695 rhs: Constant,
3696) Constant {
3697 const Adapter = struct {
3698 builder: *const Builder,
3699 pub fn hash(_: @This(), key: Constant.Compare) u32 {
3700 return @truncate(std.hash.Wyhash.hash(
3701 std.hash.uint32(@intFromEnum(Constant.tag.fcmp)),
3702 std.mem.asBytes(&key),
3703 ));
3704 }
3705 pub fn eql(ctx: @This(), lhs_key: Constant.Compare, _: void, rhs_index: usize) bool {
3706 if (ctx.builder.constant_items.items(.tag)[rhs_index] != .fcmp) return false;
3707 const rhs_data = ctx.builder.constant_items.items(.data)[rhs_index];
3708 const rhs_extra = ctx.builder.constantExtraData(Constant.Compare, rhs_data);
3709 return std.meta.eql(lhs_key, rhs_extra);
3710 }
3711 };
3712 const data = Constant.Compare{ .cond = @intFromEnum(cond), .lhs = lhs, .rhs = rhs };
3713 const gop = self.constant_map.getOrPutAssumeCapacityAdapted(data, Adapter{ .builder = self });
3714 if (!gop.found_existing) {
3715 gop.key_ptr.* = {};
3716 gop.value_ptr.* = {};
3717 self.constant_items.appendAssumeCapacity(.{
3718 .tag = .fcmp,
3719 .data = self.addConstantExtraAssumeCapacity(data),
3720 });
3721 if (self.useLibLlvm()) self.llvm.constants.appendAssumeCapacity(
3722 llvm.constFCmp(@enumFromInt(@intFromEnum(cond)), lhs.toLlvm(self), rhs.toLlvm(self)),
3723 );
3724 }
3725 return @enumFromInt(gop.index);
3726}
3727
3728fn extractElementConstAssumeCapacity(
3729 self: *Builder,
3730 arg: Constant,
3731 index: Constant,
3732) Constant {
3733 const Adapter = struct {
3734 builder: *const Builder,
3735 pub fn hash(_: @This(), key: Constant.ExtractElement) u32 {
3736 return @truncate(std.hash.Wyhash.hash(
3737 comptime std.hash.uint32(@intFromEnum(Constant.Tag.extractelement)),
3738 std.mem.asBytes(&key),
3739 ));
3740 }
3741 pub fn eql(ctx: @This(), lhs_key: Constant.ExtractElement, _: void, rhs_index: usize) bool {
3742 if (ctx.builder.constant_items.items(.tag)[rhs_index] != .extractelement) return false;
3743 const rhs_data = ctx.builder.constant_items.items(.data)[rhs_index];
3744 const rhs_extra = ctx.builder.constantExtraData(Constant.ExtractElement, rhs_data);
3745 return std.meta.eql(lhs_key, rhs_extra);
3746 }
3747 };
3748 const data = Constant.ExtractElement{ .arg = arg, .index = index };
3749 const gop = self.constant_map.getOrPutAssumeCapacityAdapted(data, Adapter{ .builder = self });
3750 if (!gop.found_existing) {
3751 gop.key_ptr.* = {};
3752 gop.value_ptr.* = {};
3753 self.constant_items.appendAssumeCapacity(.{
3754 .tag = .extractelement,
3755 .data = self.addConstantExtraAssumeCapacity(data),
3756 });
3757 if (self.useLibLlvm()) self.llvm.constants.appendAssumeCapacity(
3758 arg.toLlvm(self).constExtractElement(index.toLlvm(self)),
3759 );
3760 }
3761 return @enumFromInt(gop.index);
3762}
3763
3764fn insertElementConstAssumeCapacity(
3765 self: *Builder,
3766 arg: Constant,
3767 elem: Constant,
3768 index: Constant,
3769) Constant {
3770 const Adapter = struct {
3771 builder: *const Builder,
3772 pub fn hash(_: @This(), key: Constant.InsertElement) u32 {
3773 return @truncate(std.hash.Wyhash.hash(
3774 comptime std.hash.uint32(@intFromEnum(Constant.Tag.insertelement)),
3775 std.mem.asBytes(&key),
3776 ));
3777 }
3778 pub fn eql(ctx: @This(), lhs_key: Constant.InsertElement, _: void, rhs_index: usize) bool {
3779 if (ctx.builder.constant_items.items(.tag)[rhs_index] != .insertelement) return false;
3780 const rhs_data = ctx.builder.constant_items.items(.data)[rhs_index];
3781 const rhs_extra = ctx.builder.constantExtraData(Constant.InsertElement, rhs_data);
3782 return std.meta.eql(lhs_key, rhs_extra);
3783 }
3784 };
3785 const data = Constant.InsertElement{ .arg = arg, .elem = elem, .index = index };
3786 const gop = self.constant_map.getOrPutAssumeCapacityAdapted(data, Adapter{ .builder = self });
3787 if (!gop.found_existing) {
3788 gop.key_ptr.* = {};
3789 gop.value_ptr.* = {};
3790 self.constant_items.appendAssumeCapacity(.{
3791 .tag = .insertelement,
3792 .data = self.addConstantExtraAssumeCapacity(data),
3793 });
3794 if (self.useLibLlvm()) self.llvm.constants.appendAssumeCapacity(
3795 arg.toLlvm(self).constInsertElement(elem.toLlvm(self), index.toLlvm(self)),
3796 );
3797 }
3798 return @enumFromInt(gop.index);
3799}
3800
3801fn shuffleVectorConstAssumeCapacity(
3802 self: *Builder,
3803 lhs: Constant,
3804 rhs: Constant,
3805 mask: Constant,
3806) Constant {
3807 const Adapter = struct {
3808 builder: *const Builder,
3809 pub fn hash(_: @This(), key: Constant.ShuffleVector) u32 {
3810 return @truncate(std.hash.Wyhash.hash(
3811 comptime std.hash.uint32(@intFromEnum(Constant.Tag.shufflevector)),
3812 std.mem.asBytes(&key),
3813 ));
3814 }
3815 pub fn eql(ctx: @This(), lhs_key: Constant.ShuffleVector, _: void, rhs_index: usize) bool {
3816 if (ctx.builder.constant_items.items(.tag)[rhs_index] != .shufflevector) return false;
3817 const rhs_data = ctx.builder.constant_items.items(.data)[rhs_index];
3818 const rhs_extra = ctx.builder.constantExtraData(Constant.ShuffleVector, rhs_data);
3819 return std.meta.eql(lhs_key, rhs_extra);
3820 }
3821 };
3822 const data = Constant.ShuffleVector{ .lhs = lhs, .rhs = rhs, .mask = mask };
3823 const gop = self.constant_map.getOrPutAssumeCapacityAdapted(data, Adapter{ .builder = self });
3824 if (!gop.found_existing) {
3825 gop.key_ptr.* = {};
3826 gop.value_ptr.* = {};
3827 self.constant_items.appendAssumeCapacity(.{
3828 .tag = .shufflevector,
3829 .data = self.addConstantExtraAssumeCapacity(data),
3830 });
3831 if (self.useLibLlvm()) self.llvm.constants.appendAssumeCapacity(
3832 lhs.toLlvm(self).constShuffleVector(rhs.toLlvm(self), mask.toLlvm(self)),
3833 );
3834 }
3835 return @enumFromInt(gop.index);
3836}
3837
34043838fn binConstAssumeCapacity(
34053839 self: *Builder,
34063840 tag: Constant.Tag,
......@@ -3408,7 +3842,22 @@ fn binConstAssumeCapacity(
34083842 rhs: Constant,
34093843) Constant {
34103844 switch (tag) {
3411 .add, .sub, .mul, .shl, .lshr, .ashr, .@"and", .@"or", .xor => {},
3845 .add,
3846 .@"add nsw",
3847 .@"add nuw",
3848 .sub,
3849 .@"sub nsw",
3850 .@"sub nuw",
3851 .mul,
3852 .@"mul nsw",
3853 .@"mul nuw",
3854 .shl,
3855 .lshr,
3856 .ashr,
3857 .@"and",
3858 .@"or",
3859 .xor,
3860 => {},
34123861 else => unreachable,
34133862 }
34143863 const Key = struct { tag: Constant.Tag, bin: Constant.Binary };
src/codegen/llvm/bindings.zig+90-36
......@@ -168,6 +168,66 @@ pub const Value = opaque {
168168 pub const setAliasee = LLVMAliasSetAliasee;
169169 extern fn LLVMAliasSetAliasee(Alias: *Value, Aliasee: *Value) void;
170170
171 pub const constZExtOrBitCast = LLVMConstZExtOrBitCast;
172 extern fn LLVMConstZExtOrBitCast(ConstantVal: *Value, ToType: *Type) *Value;
173
174 pub const constNeg = LLVMConstNeg;
175 extern fn LLVMConstNeg(ConstantVal: *Value) *Value;
176
177 pub const constNSWNeg = LLVMConstNSWNeg;
178 extern fn LLVMConstNSWNeg(ConstantVal: *Value) *Value;
179
180 pub const constNUWNeg = LLVMConstNUWNeg;
181 extern fn LLVMConstNUWNeg(ConstantVal: *Value) *Value;
182
183 pub const constNot = LLVMConstNot;
184 extern fn LLVMConstNot(ConstantVal: *Value) *Value;
185
186 pub const constAdd = LLVMConstAdd;
187 extern fn LLVMConstAdd(LHSConstant: *Value, RHSConstant: *Value) *Value;
188
189 pub const constNSWAdd = LLVMConstNSWAdd;
190 extern fn LLVMConstNSWAdd(LHSConstant: *Value, RHSConstant: *Value) *Value;
191
192 pub const constNUWAdd = LLVMConstNUWAdd;
193 extern fn LLVMConstNUWAdd(LHSConstant: *Value, RHSConstant: *Value) *Value;
194
195 pub const constSub = LLVMConstSub;
196 extern fn LLVMConstSub(LHSConstant: *Value, RHSConstant: *Value) *Value;
197
198 pub const constNSWSub = LLVMConstNSWSub;
199 extern fn LLVMConstNSWSub(LHSConstant: *Value, RHSConstant: *Value) *Value;
200
201 pub const constNUWSub = LLVMConstNUWSub;
202 extern fn LLVMConstNUWSub(LHSConstant: *Value, RHSConstant: *Value) *Value;
203
204 pub const constMul = LLVMConstMul;
205 extern fn LLVMConstMul(LHSConstant: *Value, RHSConstant: *Value) *Value;
206
207 pub const constNSWMul = LLVMConstNSWMul;
208 extern fn LLVMConstNSWMul(LHSConstant: *Value, RHSConstant: *Value) *Value;
209
210 pub const constNUWMul = LLVMConstNUWMul;
211 extern fn LLVMConstNUWMul(LHSConstant: *Value, RHSConstant: *Value) *Value;
212
213 pub const constAnd = LLVMConstAnd;
214 extern fn LLVMConstAnd(LHSConstant: *Value, RHSConstant: *Value) *Value;
215
216 pub const constOr = LLVMConstOr;
217 extern fn LLVMConstOr(LHSConstant: *Value, RHSConstant: *Value) *Value;
218
219 pub const constXor = LLVMConstXor;
220 extern fn LLVMConstXor(LHSConstant: *Value, RHSConstant: *Value) *Value;
221
222 pub const constShl = LLVMConstShl;
223 extern fn LLVMConstShl(LHSConstant: *Value, RHSConstant: *Value) *Value;
224
225 pub const constLShr = LLVMConstLShr;
226 extern fn LLVMConstLShr(LHSConstant: *Value, RHSConstant: *Value) *Value;
227
228 pub const constAShr = LLVMConstAShr;
229 extern fn LLVMConstAShr(LHSConstant: *Value, RHSConstant: *Value) *Value;
230
171231 pub const constTrunc = LLVMConstTrunc;
172232 extern fn LLVMConstTrunc(ConstantVal: *Value, ToType: *Type) *Value;
173233
......@@ -204,41 +264,35 @@ pub const Value = opaque {
204264 pub const constBitCast = LLVMConstBitCast;
205265 extern fn LLVMConstBitCast(ConstantVal: *Value, ToType: *Type) *Value;
206266
207 pub const constZExtOrBitCast = LLVMConstZExtOrBitCast;
208 extern fn LLVMConstZExtOrBitCast(ConstantVal: *Value, ToType: *Type) *Value;
209
210 pub const constNot = LLVMConstNot;
211 extern fn LLVMConstNot(ConstantVal: *Value) *Value;
212
213 pub const constAdd = LLVMConstAdd;
214 extern fn LLVMConstAdd(LHSConstant: *Value, RHSConstant: *Value) *Value;
215
216 pub const constSub = LLVMConstSub;
217 extern fn LLVMConstSub(LHSConstant: *Value, RHSConstant: *Value) *Value;
218
219 pub const constMul = LLVMConstMul;
220 extern fn LLVMConstMul(LHSConstant: *Value, RHSConstant: *Value) *Value;
221
222 pub const constAnd = LLVMConstAnd;
223 extern fn LLVMConstAnd(LHSConstant: *Value, RHSConstant: *Value) *Value;
224
225 pub const constOr = LLVMConstOr;
226 extern fn LLVMConstOr(LHSConstant: *Value, RHSConstant: *Value) *Value;
267 pub const constAddrSpaceCast = LLVMConstAddrSpaceCast;
268 extern fn LLVMConstAddrSpaceCast(ConstantVal: *Value, ToType: *Type) *Value;
227269
228 pub const constXor = LLVMConstXor;
229 extern fn LLVMConstXor(LHSConstant: *Value, RHSConstant: *Value) *Value;
270 pub const constSelect = LLVMConstSelect;
271 extern fn LLVMConstSelect(
272 ConstantCondition: *Value,
273 ConstantIfTrue: *Value,
274 ConstantIfFalse: *Value,
275 ) *Value;
230276
231 pub const constShl = LLVMConstShl;
232 extern fn LLVMConstShl(LHSConstant: *Value, RHSConstant: *Value) *Value;
277 pub const constExtractElement = LLVMConstExtractElement;
278 extern fn LLVMConstExtractElement(VectorConstant: *Value, IndexConstant: *Value) *Value;
233279
234 pub const constLShr = LLVMConstLShr;
235 extern fn LLVMConstLShr(LHSConstant: *Value, RHSConstant: *Value) *Value;
280 pub const constInsertElement = LLVMConstInsertElement;
281 extern fn LLVMConstInsertElement(
282 VectorConstant: *Value,
283 ElementValueConstant: *Value,
284 IndexConstant: *Value,
285 ) *Value;
236286
237 pub const constAShr = LLVMConstAShr;
238 extern fn LLVMConstAShr(LHSConstant: *Value, RHSConstant: *Value) *Value;
287 pub const constShuffleVector = LLVMConstShuffleVector;
288 extern fn LLVMConstShuffleVector(
289 VectorAConstant: *Value,
290 VectorBConstant: *Value,
291 MaskConstant: *Value,
292 ) *Value;
239293
240 pub const constAddrSpaceCast = LLVMConstAddrSpaceCast;
241 extern fn LLVMConstAddrSpaceCast(ConstantVal: *Value, ToType: *Type) *Value;
294 pub const blockAddress = LLVMBlockAddress;
295 extern fn LLVMBlockAddress(F: *Value, BB: *BasicBlock) *Value;
242296
243297 pub const setWeak = LLVMSetWeak;
244298 extern fn LLVMSetWeak(CmpXchgInst: *Value, IsWeak: Bool) void;
......@@ -323,9 +377,6 @@ pub const Value = opaque {
323377 pub const attachMetaData = ZigLLVMAttachMetaData;
324378 extern fn ZigLLVMAttachMetaData(GlobalVar: *Value, DIG: *DIGlobalVariableExpression) void;
325379
326 pub const blockAddress = LLVMBlockAddress;
327 extern fn LLVMBlockAddress(F: *Value, BB: *BasicBlock) *Value;
328
329380 pub const dump = LLVMDumpValue;
330381 extern fn LLVMDumpValue(Val: *Value) void;
331382};
......@@ -522,15 +573,18 @@ pub const VerifierFailureAction = enum(c_int) {
522573 ReturnStatus,
523574};
524575
525pub const constNeg = LLVMConstNeg;
526extern fn LLVMConstNeg(ConstantVal: *Value) *Value;
527
528576pub const constVector = LLVMConstVector;
529577extern fn LLVMConstVector(
530578 ScalarConstantVals: [*]*Value,
531579 Size: c_uint,
532580) *Value;
533581
582pub const constICmp = LLVMConstICmp;
583extern fn LLVMConstICmp(Predicate: IntPredicate, LHSConstant: *Value, RHSConstant: *Value) *Value;
584
585pub const constFCmp = LLVMConstFCmp;
586extern fn LLVMConstFCmp(Predicate: RealPredicate, LHSConstant: *Value, RHSConstant: *Value) *Value;
587
534588pub const getEnumAttributeKindForName = LLVMGetEnumAttributeKindForName;
535589extern fn LLVMGetEnumAttributeKindForName(Name: [*]const u8, SLen: usize) c_uint;
536590