authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-08-08 11:40:51-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2023-08-08 21:32:50-04:00
log35cd56a3693d55eedb80e8bd1538420597b05ff5
tree3c82332603b02fc2c1dd4e4c26a54e5fdb5a842c
parent2bdd180c6f6c76940ccfe8c8532fefec208661ea

llvm: fix alias issues


2 files changed, 522 insertions(+), 508 deletions(-)

src/codegen/llvm.zig+11-12
...@@ -1079,7 +1079,8 @@ pub const Object = struct {...@@ -1079,7 +1079,8 @@ pub const Object = struct {
1079 // Same logic as below but for externs instead of exports.1079 // Same logic as below but for externs instead of exports.
1080 const decl_name = object.builder.stringIfExists(mod.intern_pool.stringToSlice(mod.declPtr(decl_index).name)) orelse continue;1080 const decl_name = object.builder.stringIfExists(mod.intern_pool.stringToSlice(mod.declPtr(decl_index).name)) orelse continue;
1081 const other_global = object.builder.getGlobal(decl_name) orelse continue;1081 const other_global = object.builder.getGlobal(decl_name) orelse continue;
1082 if (other_global.eql(global, &object.builder)) continue;1082 if (other_global.toConst().getBase(&object.builder) ==
1083 global.toConst().getBase(&object.builder)) continue;
10831084
1084 try global.replace(other_global, &object.builder);1085 try global.replace(other_global, &object.builder);
1085 }1086 }
...@@ -1087,13 +1088,14 @@ pub const Object = struct {...@@ -1087,13 +1088,14 @@ pub const Object = struct {
10871088
1088 for (mod.decl_exports.keys(), mod.decl_exports.values()) |decl_index, export_list| {1089 for (mod.decl_exports.keys(), mod.decl_exports.values()) |decl_index, export_list| {
1089 const global = object.decl_map.get(decl_index) orelse continue;1090 const global = object.decl_map.get(decl_index) orelse continue;
1091 const global_base = global.toConst().getBase(&object.builder);
1090 for (export_list.items) |exp| {1092 for (export_list.items) |exp| {
1091 // Detect if the LLVM global has already been created as an extern. In such1093 // Detect if the LLVM global has already been created as an extern. In such
1092 // case, we need to replace all uses of it with this exported global.1094 // case, we need to replace all uses of it with this exported global.
1093 const exp_name = object.builder.stringIfExists(mod.intern_pool.stringToSlice(exp.opts.name)) orelse continue;1095 const exp_name = object.builder.stringIfExists(mod.intern_pool.stringToSlice(exp.opts.name)) orelse continue;
10941096
1095 const other_global = object.builder.getGlobal(exp_name) orelse continue;1097 const other_global = object.builder.getGlobal(exp_name) orelse continue;
1096 if (other_global.eql(global, &object.builder)) continue;1098 if (other_global.toConst().getBase(&object.builder) == global_base) continue;
10971099
1098 try global.takeName(other_global, &object.builder);1100 try global.takeName(other_global, &object.builder);
1099 try other_global.replace(global, &object.builder);1101 try other_global.replace(global, &object.builder);
...@@ -1714,7 +1716,7 @@ pub const Object = struct {...@@ -1714,7 +1716,7 @@ pub const Object = struct {
1714 try self.builder.string(section),1716 try self.builder.string(section),
1715 &self.builder,1717 &self.builder,
1716 ),1718 ),
1717 else => unreachable,1719 .alias, .replaced => unreachable,
1718 };1720 };
1719 if (decl.val.getVariable(mod)) |decl_var| if (decl_var.is_threadlocal)1721 if (decl.val.getVariable(mod)) |decl_var| if (decl_var.is_threadlocal)
1720 global_index.ptrConst(&self.builder).kind1722 global_index.ptrConst(&self.builder).kind
...@@ -1735,15 +1737,16 @@ pub const Object = struct {...@@ -1735,15 +1737,16 @@ pub const Object = struct {
1735 continue;1737 continue;
1736 },1738 },
1737 .variable, .function => {},1739 .variable, .function => {},
1738 else => unreachable,1740 .replaced => unreachable,
1739 }1741 }
1740 }1742 }
1741 _ = try self.builder.addAlias(1743 const alias_index = try self.builder.addAlias(
1742 exp_name,1744 .empty,
1743 global_index.typeOf(&self.builder),1745 global_index.typeOf(&self.builder),
1744 .default,1746 .default,
1745 global_index.toConst(),1747 global_index.toConst(),
1746 );1748 );
1749 try alias_index.rename(exp_name, &self.builder);
1747 }1750 }
1748 } else {1751 } else {
1749 const fqn = try self.builder.string(1752 const fqn = try self.builder.string(
...@@ -7703,7 +7706,7 @@ pub const FuncGen = struct {...@@ -7703,7 +7706,7 @@ pub const FuncGen = struct {
7703 if (o.builder.getGlobal(fn_name)) |global| return switch (global.ptrConst(&o.builder).kind) {7706 if (o.builder.getGlobal(fn_name)) |global| return switch (global.ptrConst(&o.builder).kind) {
7704 .alias => |alias| alias.getAliasee(&o.builder).ptrConst(&o.builder).kind.function,7707 .alias => |alias| alias.getAliasee(&o.builder).ptrConst(&o.builder).kind.function,
7705 .function => |function| function,7708 .function => |function| function,
7706 else => unreachable,7709 .variable, .replaced => unreachable,
7707 };7710 };
7708 return o.builder.addFunction(7711 return o.builder.addFunction(
7709 try o.builder.fnType(return_type, param_types, .normal),7712 try o.builder.fnType(return_type, param_types, .normal),
...@@ -7751,11 +7754,7 @@ pub const FuncGen = struct {...@@ -7751,11 +7754,7 @@ pub const FuncGen = struct {
7751 };7754 };
7752 const fn_name = try o.builder.fmt("__{s}{s}f2", .{ fn_base_name, compiler_rt_float_abbrev });7755 const fn_name = try o.builder.fmt("__{s}{s}f2", .{ fn_base_name, compiler_rt_float_abbrev });
77537756
7754 const libc_fn = try self.getLibcFunction(7757 const libc_fn = try self.getLibcFunction(fn_name, &.{ scalar_llvm_ty, scalar_llvm_ty }, .i32);
7755 fn_name,
7756 ([1]Builder.Type{scalar_llvm_ty} ** 2)[0..],
7757 .i32,
7758 );
77597758
7760 const zero = try o.builder.intConst(.i32, 0);7759 const zero = try o.builder.intConst(.i32, 0);
7761 const int_cond: Builder.IntegerCondition = switch (pred) {7760 const int_cond: Builder.IntegerCondition = switch (pred) {
src/codegen/llvm/Builder.zig+511-496
...@@ -2320,6 +2320,10 @@ pub const Alias = struct {...@@ -2320,6 +2320,10 @@ pub const Alias = struct {
2320 return self.ptrConst(builder).global.name(builder);2320 return self.ptrConst(builder).global.name(builder);
2321 }2321 }
23222322
2323 pub fn rename(self: Index, new_name: String, builder: *Builder) Allocator.Error!void {
2324 return self.ptrConst(builder).global.rename(new_name, builder);
2325 }
2326
2323 pub fn typeOf(self: Index, builder: *const Builder) Type {2327 pub fn typeOf(self: Index, builder: *const Builder) Type {
2324 return self.ptrConst(builder).global.typeOf(builder);2328 return self.ptrConst(builder).global.typeOf(builder);
2325 }2329 }
...@@ -2373,6 +2377,10 @@ pub const Variable = struct {...@@ -2373,6 +2377,10 @@ pub const Variable = struct {
2373 return self.ptrConst(builder).global.name(builder);2377 return self.ptrConst(builder).global.name(builder);
2374 }2378 }
23752379
2380 pub fn rename(self: Index, new_name: String, builder: *Builder) Allocator.Error!void {
2381 return self.ptrConst(builder).global.rename(new_name, builder);
2382 }
2383
2376 pub fn typeOf(self: Index, builder: *const Builder) Type {2384 pub fn typeOf(self: Index, builder: *const Builder) Type {
2377 return self.ptrConst(builder).global.typeOf(builder);2385 return self.ptrConst(builder).global.typeOf(builder);
2378 }2386 }
...@@ -3812,6 +3820,10 @@ pub const Function = struct {...@@ -3812,6 +3820,10 @@ pub const Function = struct {
3812 return self.ptrConst(builder).global.name(builder);3820 return self.ptrConst(builder).global.name(builder);
3813 }3821 }
38143822
3823 pub fn rename(self: Index, new_name: String, builder: *Builder) Allocator.Error!void {
3824 return self.ptrConst(builder).global.rename(new_name, builder);
3825 }
3826
3815 pub fn typeOf(self: Index, builder: *const Builder) Type {3827 pub fn typeOf(self: Index, builder: *const Builder) Type {
3816 return self.ptrConst(builder).global.typeOf(builder);3828 return self.ptrConst(builder).global.typeOf(builder);
3817 }3829 }
...@@ -9393,518 +9405,521 @@ pub fn printUnbuffered(...@@ -9393,518 +9405,521 @@ pub fn printUnbuffered(
9393 need_newline = true;9405 need_newline = true;
9394 }9406 }
93959407
9396 var attribute_groups: std.AutoArrayHashMapUnmanaged(Attributes, void) = .{};9408 if (self.aliases.items.len > 0) {
9397 defer attribute_groups.deinit(self.gpa);
9398
9399 if (self.functions.items.len > 0) {
9400 if (need_newline) try writer.writeByte('\n');9409 if (need_newline) try writer.writeByte('\n');
9401 for (0.., self.functions.items) |function_i, function| {9410 for (self.aliases.items) |alias| {
9402 if (function_i > 0) try writer.writeByte('\n');9411 if (alias.global.getReplacement(self) != .none) continue;
9403 const function_index: Function.Index = @enumFromInt(function_i);9412 const global = alias.global.ptrConst(self);
9404 if (function.global.getReplacement(self) != .none) continue;
9405 const global = function.global.ptrConst(self);
9406 const params_len = global.type.functionParameters(self).len;
9407 const function_attributes = function.attributes.func(self);
9408 if (function_attributes != .none) try writer.print(
9409 \\; Function Attrs:{}
9410 \\
9411 , .{function_attributes.fmt(self)});
9412 try writer.print(9413 try writer.print(
9413 \\{s}{}{}{}{}{}{"} {} {}(9414 \\{} ={}{}{}{}{ }{} alias {%}, {%}
9415 \\
9414 , .{9416 , .{
9415 if (function.instructions.len > 0) "define" else "declare",9417 alias.global.fmt(self),
9416 global.linkage,9418 global.linkage,
9417 global.preemption,9419 global.preemption,
9418 global.visibility,9420 global.visibility,
9419 global.dll_storage_class,9421 global.dll_storage_class,
9420 function.call_conv,9422 alias.thread_local,
9421 function.attributes.ret(self).fmt(self),9423 global.unnamed_addr,
9422 global.type.functionReturn(self).fmt(self),9424 global.type.fmt(self),
9423 function.global.fmt(self),9425 alias.aliasee.fmt(self),
9424 });9426 });
9425 for (0..params_len) |arg| {9427 }
9426 if (arg > 0) try writer.writeAll(", ");9428 need_newline = true;
9427 try writer.print(9429 }
9428 \\{%}{"}9430
9429 , .{9431 var attribute_groups: std.AutoArrayHashMapUnmanaged(Attributes, void) = .{};
9430 global.type.functionParameters(self)[arg].fmt(self),9432 defer attribute_groups.deinit(self.gpa);
9431 function.attributes.param(arg, self).fmt(self),9433
9432 });9434 for (0.., self.functions.items) |function_i, function| {
9433 if (function.instructions.len > 0)9435 if (function.global.getReplacement(self) != .none) continue;
9434 try writer.print(" {}", .{function.arg(@intCast(arg)).fmt(function_index, self)})9436 if (need_newline) try writer.writeByte('\n');
9435 else9437 const function_index: Function.Index = @enumFromInt(function_i);
9436 try writer.print(" %{d}", .{arg});9438 const global = function.global.ptrConst(self);
9437 }9439 const params_len = global.type.functionParameters(self).len;
9438 switch (global.type.functionKind(self)) {9440 const function_attributes = function.attributes.func(self);
9439 .normal => {},9441 if (function_attributes != .none) try writer.print(
9440 .vararg => {9442 \\; Function Attrs:{}
9441 if (params_len > 0) try writer.writeAll(", ");9443 \\
9442 try writer.writeAll("...");9444 , .{function_attributes.fmt(self)});
9443 },9445 try writer.print(
9444 }9446 \\{s}{}{}{}{}{}{"} {} {}(
9445 try writer.print("){}{ }", .{ global.unnamed_addr, global.addr_space });9447 , .{
9446 if (function_attributes != .none) try writer.print(" #{d}", .{9448 if (function.instructions.len > 0) "define" else "declare",
9447 (try attribute_groups.getOrPutValue(self.gpa, function_attributes, {})).index,9449 global.linkage,
9450 global.preemption,
9451 global.visibility,
9452 global.dll_storage_class,
9453 function.call_conv,
9454 function.attributes.ret(self).fmt(self),
9455 global.type.functionReturn(self).fmt(self),
9456 function.global.fmt(self),
9457 });
9458 for (0..params_len) |arg| {
9459 if (arg > 0) try writer.writeAll(", ");
9460 try writer.print(
9461 \\{%}{"}
9462 , .{
9463 global.type.functionParameters(self)[arg].fmt(self),
9464 function.attributes.param(arg, self).fmt(self),
9448 });9465 });
9449 try writer.print("{ }", .{function.alignment});9466 if (function.instructions.len > 0)
9450 if (function.instructions.len > 0) {9467 try writer.print(" {}", .{function.arg(@intCast(arg)).fmt(function_index, self)})
9451 var block_incoming_len: u32 = undefined;9468 else
9452 try writer.writeAll(" {\n");9469 try writer.print(" %{d}", .{arg});
9453 for (params_len..function.instructions.len) |instruction_i| {9470 }
9454 const instruction_index: Function.Instruction.Index = @enumFromInt(instruction_i);9471 switch (global.type.functionKind(self)) {
9455 const instruction = function.instructions.get(@intFromEnum(instruction_index));9472 .normal => {},
9456 switch (instruction.tag) {9473 .vararg => {
9457 .add,9474 if (params_len > 0) try writer.writeAll(", ");
9458 .@"add nsw",9475 try writer.writeAll("...");
9459 .@"add nuw",9476 },
9460 .@"add nuw nsw",9477 }
9461 .@"and",9478 try writer.print("){}{ }", .{ global.unnamed_addr, global.addr_space });
9462 .ashr,9479 if (function_attributes != .none) try writer.print(" #{d}", .{
9463 .@"ashr exact",9480 (try attribute_groups.getOrPutValue(self.gpa, function_attributes, {})).index,
9464 .fadd,9481 });
9465 .@"fadd fast",9482 try writer.print("{ }", .{function.alignment});
9466 .@"fcmp false",9483 if (function.instructions.len > 0) {
9467 .@"fcmp fast false",9484 var block_incoming_len: u32 = undefined;
9468 .@"fcmp fast oeq",9485 try writer.writeAll(" {\n");
9469 .@"fcmp fast oge",9486 for (params_len..function.instructions.len) |instruction_i| {
9470 .@"fcmp fast ogt",9487 const instruction_index: Function.Instruction.Index = @enumFromInt(instruction_i);
9471 .@"fcmp fast ole",9488 const instruction = function.instructions.get(@intFromEnum(instruction_index));
9472 .@"fcmp fast olt",9489 switch (instruction.tag) {
9473 .@"fcmp fast one",9490 .add,
9474 .@"fcmp fast ord",9491 .@"add nsw",
9475 .@"fcmp fast true",9492 .@"add nuw",
9476 .@"fcmp fast ueq",9493 .@"add nuw nsw",
9477 .@"fcmp fast uge",9494 .@"and",
9478 .@"fcmp fast ugt",9495 .ashr,
9479 .@"fcmp fast ule",9496 .@"ashr exact",
9480 .@"fcmp fast ult",9497 .fadd,
9481 .@"fcmp fast une",9498 .@"fadd fast",
9482 .@"fcmp fast uno",9499 .@"fcmp false",
9483 .@"fcmp oeq",9500 .@"fcmp fast false",
9484 .@"fcmp oge",9501 .@"fcmp fast oeq",
9485 .@"fcmp ogt",9502 .@"fcmp fast oge",
9486 .@"fcmp ole",9503 .@"fcmp fast ogt",
9487 .@"fcmp olt",9504 .@"fcmp fast ole",
9488 .@"fcmp one",9505 .@"fcmp fast olt",
9489 .@"fcmp ord",9506 .@"fcmp fast one",
9490 .@"fcmp true",9507 .@"fcmp fast ord",
9491 .@"fcmp ueq",9508 .@"fcmp fast true",
9492 .@"fcmp uge",9509 .@"fcmp fast ueq",
9493 .@"fcmp ugt",9510 .@"fcmp fast uge",
9494 .@"fcmp ule",9511 .@"fcmp fast ugt",
9495 .@"fcmp ult",9512 .@"fcmp fast ule",
9496 .@"fcmp une",9513 .@"fcmp fast ult",
9497 .@"fcmp uno",9514 .@"fcmp fast une",
9498 .fdiv,9515 .@"fcmp fast uno",
9499 .@"fdiv fast",9516 .@"fcmp oeq",
9500 .fmul,9517 .@"fcmp oge",
9501 .@"fmul fast",9518 .@"fcmp ogt",
9502 .frem,9519 .@"fcmp ole",
9503 .@"frem fast",9520 .@"fcmp olt",
9504 .fsub,9521 .@"fcmp one",
9505 .@"fsub fast",9522 .@"fcmp ord",
9506 .@"icmp eq",9523 .@"fcmp true",
9507 .@"icmp ne",9524 .@"fcmp ueq",
9508 .@"icmp sge",9525 .@"fcmp uge",
9509 .@"icmp sgt",9526 .@"fcmp ugt",
9510 .@"icmp sle",9527 .@"fcmp ule",
9511 .@"icmp slt",9528 .@"fcmp ult",
9512 .@"icmp uge",9529 .@"fcmp une",
9513 .@"icmp ugt",9530 .@"fcmp uno",
9514 .@"icmp ule",9531 .fdiv,
9515 .@"icmp ult",9532 .@"fdiv fast",
9516 .lshr,9533 .fmul,
9517 .@"lshr exact",9534 .@"fmul fast",
9518 .mul,9535 .frem,
9519 .@"mul nsw",9536 .@"frem fast",
9520 .@"mul nuw",9537 .fsub,
9521 .@"mul nuw nsw",9538 .@"fsub fast",
9522 .@"or",9539 .@"icmp eq",
9523 .sdiv,9540 .@"icmp ne",
9524 .@"sdiv exact",9541 .@"icmp sge",
9525 .srem,9542 .@"icmp sgt",
9526 .shl,9543 .@"icmp sle",
9527 .@"shl nsw",9544 .@"icmp slt",
9528 .@"shl nuw",9545 .@"icmp uge",
9529 .@"shl nuw nsw",9546 .@"icmp ugt",
9530 .sub,9547 .@"icmp ule",
9531 .@"sub nsw",9548 .@"icmp ult",
9532 .@"sub nuw",9549 .lshr,
9533 .@"sub nuw nsw",9550 .@"lshr exact",
9534 .udiv,9551 .mul,
9535 .@"udiv exact",9552 .@"mul nsw",
9536 .urem,9553 .@"mul nuw",
9537 .xor,9554 .@"mul nuw nsw",
9538 => |tag| {9555 .@"or",
9539 const extra =9556 .sdiv,
9540 function.extraData(Function.Instruction.Binary, instruction.data);9557 .@"sdiv exact",
9541 try writer.print(" %{} = {s} {%}, {}\n", .{9558 .srem,
9542 instruction_index.name(&function).fmt(self),9559 .shl,
9543 @tagName(tag),9560 .@"shl nsw",
9544 extra.lhs.fmt(function_index, self),9561 .@"shl nuw",
9545 extra.rhs.fmt(function_index, self),9562 .@"shl nuw nsw",
9546 });9563 .sub,
9547 },9564 .@"sub nsw",
9548 .addrspacecast,9565 .@"sub nuw",
9549 .bitcast,9566 .@"sub nuw nsw",
9550 .fpext,9567 .udiv,
9551 .fptosi,9568 .@"udiv exact",
9552 .fptoui,9569 .urem,
9553 .fptrunc,9570 .xor,
9554 .inttoptr,9571 => |tag| {
9555 .ptrtoint,9572 const extra = function.extraData(Function.Instruction.Binary, instruction.data);
9556 .sext,9573 try writer.print(" %{} = {s} {%}, {}\n", .{
9557 .sitofp,9574 instruction_index.name(&function).fmt(self),
9558 .trunc,9575 @tagName(tag),
9559 .uitofp,9576 extra.lhs.fmt(function_index, self),
9560 .zext,9577 extra.rhs.fmt(function_index, self),
9561 => |tag| {9578 });
9562 const extra =9579 },
9563 function.extraData(Function.Instruction.Cast, instruction.data);9580 .addrspacecast,
9564 try writer.print(" %{} = {s} {%} to {%}\n", .{9581 .bitcast,
9565 instruction_index.name(&function).fmt(self),9582 .fpext,
9566 @tagName(tag),9583 .fptosi,
9567 extra.val.fmt(function_index, self),9584 .fptoui,
9568 extra.type.fmt(self),9585 .fptrunc,
9569 });9586 .inttoptr,
9570 },9587 .ptrtoint,
9571 .alloca,9588 .sext,
9572 .@"alloca inalloca",9589 .sitofp,
9573 => |tag| {9590 .trunc,
9574 const extra =9591 .uitofp,
9575 function.extraData(Function.Instruction.Alloca, instruction.data);9592 .zext,
9576 try writer.print(" %{} = {s} {%}{,%}{, }{, }\n", .{9593 => |tag| {
9577 instruction_index.name(&function).fmt(self),9594 const extra = function.extraData(Function.Instruction.Cast, instruction.data);
9578 @tagName(tag),9595 try writer.print(" %{} = {s} {%} to {%}\n", .{
9579 extra.type.fmt(self),9596 instruction_index.name(&function).fmt(self),
9580 extra.len.fmt(function_index, self),9597 @tagName(tag),
9581 extra.info.alignment,9598 extra.val.fmt(function_index, self),
9582 extra.info.addr_space,9599 extra.type.fmt(self),
9583 });9600 });
9584 },9601 },
9585 .arg => unreachable,9602 .alloca,
9586 .atomicrmw => |tag| {9603 .@"alloca inalloca",
9587 const extra =9604 => |tag| {
9588 function.extraData(Function.Instruction.AtomicRmw, instruction.data);9605 const extra = function.extraData(Function.Instruction.Alloca, instruction.data);
9589 try writer.print(" %{} = {s}{ } {s} {%}, {%}{ }{ }{, }\n", .{9606 try writer.print(" %{} = {s} {%}{,%}{, }{, }\n", .{
9590 instruction_index.name(&function).fmt(self),9607 instruction_index.name(&function).fmt(self),
9591 @tagName(tag),9608 @tagName(tag),
9592 extra.info.access_kind,9609 extra.type.fmt(self),
9593 @tagName(extra.info.atomic_rmw_operation),9610 extra.len.fmt(function_index, self),
9594 extra.ptr.fmt(function_index, self),9611 extra.info.alignment,
9595 extra.val.fmt(function_index, self),9612 extra.info.addr_space,
9596 extra.info.sync_scope,9613 });
9597 extra.info.success_ordering,9614 },
9598 extra.info.alignment,9615 .arg => unreachable,
9599 });9616 .atomicrmw => |tag| {
9600 },9617 const extra =
9601 .block => {9618 function.extraData(Function.Instruction.AtomicRmw, instruction.data);
9602 block_incoming_len = instruction.data;9619 try writer.print(" %{} = {s}{ } {s} {%}, {%}{ }{ }{, }\n", .{
9603 const name = instruction_index.name(&function);9620 instruction_index.name(&function).fmt(self),
9604 if (@intFromEnum(instruction_index) > params_len)9621 @tagName(tag),
9605 try writer.writeByte('\n');9622 extra.info.access_kind,
9606 try writer.print("{}:\n", .{name.fmt(self)});9623 @tagName(extra.info.atomic_rmw_operation),
9607 },9624 extra.ptr.fmt(function_index, self),
9608 .br => |tag| {9625 extra.val.fmt(function_index, self),
9609 const target: Function.Block.Index = @enumFromInt(instruction.data);9626 extra.info.sync_scope,
9610 try writer.print(" {s} {%}\n", .{9627 extra.info.success_ordering,
9611 @tagName(tag), target.toInst(&function).fmt(function_index, self),9628 extra.info.alignment,
9612 });9629 });
9613 },9630 },
9614 .br_cond => {9631 .block => {
9615 const extra =9632 block_incoming_len = instruction.data;
9616 function.extraData(Function.Instruction.BrCond, instruction.data);9633 const name = instruction_index.name(&function);
9617 try writer.print(" br {%}, {%}, {%}\n", .{9634 if (@intFromEnum(instruction_index) > params_len)
9618 extra.cond.fmt(function_index, self),
9619 extra.then.toInst(&function).fmt(function_index, self),
9620 extra.@"else".toInst(&function).fmt(function_index, self),
9621 });
9622 },
9623 .call,
9624 .@"call fast",
9625 .@"musttail call",
9626 .@"musttail call fast",
9627 .@"notail call",
9628 .@"notail call fast",
9629 .@"tail call",
9630 .@"tail call fast",
9631 => |tag| {
9632 var extra =
9633 function.extraDataTrail(Function.Instruction.Call, instruction.data);
9634 const args = extra.trail.next(extra.data.args_len, Value, &function);
9635 try writer.writeAll(" ");
9636 const ret_ty = extra.data.ty.functionReturn(self);
9637 switch (ret_ty) {
9638 .void => {},
9639 else => try writer.print("%{} = ", .{
9640 instruction_index.name(&function).fmt(self),
9641 }),
9642 .none => unreachable,
9643 }
9644 try writer.print("{s}{}{}{} {%} {}(", .{
9645 @tagName(tag),
9646 extra.data.info.call_conv,
9647 extra.data.attributes.ret(self).fmt(self),
9648 extra.data.callee.typeOf(function_index, self).pointerAddrSpace(self),
9649 switch (extra.data.ty.functionKind(self)) {
9650 .normal => ret_ty,
9651 .vararg => extra.data.ty,
9652 }.fmt(self),
9653 extra.data.callee.fmt(function_index, self),
9654 });
9655 for (0.., args) |arg_index, arg| {
9656 if (arg_index > 0) try writer.writeAll(", ");
9657 try writer.print("{%}{} {}", .{
9658 arg.typeOf(function_index, self).fmt(self),
9659 extra.data.attributes.param(arg_index, self).fmt(self),
9660 arg.fmt(function_index, self),
9661 });
9662 }
9663 try writer.writeByte(')');
9664 const call_function_attributes = extra.data.attributes.func(self);
9665 if (call_function_attributes != .none) try writer.print(" #{d}", .{
9666 (try attribute_groups.getOrPutValue(
9667 self.gpa,
9668 call_function_attributes,
9669 {},
9670 )).index,
9671 });
9672 try writer.writeByte('\n');
9673 },
9674 .cmpxchg,
9675 .@"cmpxchg weak",
9676 => |tag| {
9677 const extra =
9678 function.extraData(Function.Instruction.CmpXchg, instruction.data);
9679 try writer.print(" %{} = {s}{ } {%}, {%}, {%}{ }{ }{ }{, }\n", .{
9680 instruction_index.name(&function).fmt(self),
9681 @tagName(tag),
9682 extra.info.access_kind,
9683 extra.ptr.fmt(function_index, self),
9684 extra.cmp.fmt(function_index, self),
9685 extra.new.fmt(function_index, self),
9686 extra.info.sync_scope,
9687 extra.info.success_ordering,
9688 extra.info.failure_ordering,
9689 extra.info.alignment,
9690 });
9691 },
9692 .extractelement => |tag| {
9693 const extra = function.extraData(
9694 Function.Instruction.ExtractElement,
9695 instruction.data,
9696 );
9697 try writer.print(" %{} = {s} {%}, {%}\n", .{
9698 instruction_index.name(&function).fmt(self),
9699 @tagName(tag),
9700 extra.val.fmt(function_index, self),
9701 extra.index.fmt(function_index, self),
9702 });
9703 },
9704 .extractvalue => |tag| {
9705 var extra = function.extraDataTrail(
9706 Function.Instruction.ExtractValue,
9707 instruction.data,
9708 );
9709 const indices = extra.trail.next(extra.data.indices_len, u32, &function);
9710 try writer.print(" %{} = {s} {%}", .{
9711 instruction_index.name(&function).fmt(self),
9712 @tagName(tag),
9713 extra.data.val.fmt(function_index, self),
9714 });
9715 for (indices) |index| try writer.print(", {d}", .{index});
9716 try writer.writeByte('\n');
9717 },
9718 .fence => |tag| {
9719 const info: MemoryAccessInfo = @bitCast(instruction.data);
9720 try writer.print(" {s}{ }{ }", .{
9721 @tagName(tag),
9722 info.sync_scope,
9723 info.success_ordering,
9724 });
9725 },
9726 .fneg,
9727 .@"fneg fast",
9728 => |tag| {
9729 const val: Value = @enumFromInt(instruction.data);
9730 try writer.print(" %{} = {s} {%}\n", .{
9731 instruction_index.name(&function).fmt(self),
9732 @tagName(tag),
9733 val.fmt(function_index, self),
9734 });
9735 },
9736 .getelementptr,
9737 .@"getelementptr inbounds",
9738 => |tag| {
9739 var extra = function.extraDataTrail(
9740 Function.Instruction.GetElementPtr,
9741 instruction.data,
9742 );
9743 const indices = extra.trail.next(extra.data.indices_len, Value, &function);
9744 try writer.print(" %{} = {s} {%}, {%}", .{
9745 instruction_index.name(&function).fmt(self),
9746 @tagName(tag),
9747 extra.data.type.fmt(self),
9748 extra.data.base.fmt(function_index, self),
9749 });
9750 for (indices) |index| try writer.print(", {%}", .{
9751 index.fmt(function_index, self),
9752 });
9753 try writer.writeByte('\n');
9754 },
9755 .insertelement => |tag| {
9756 const extra = function.extraData(
9757 Function.Instruction.InsertElement,
9758 instruction.data,
9759 );
9760 try writer.print(" %{} = {s} {%}, {%}, {%}\n", .{
9761 instruction_index.name(&function).fmt(self),
9762 @tagName(tag),
9763 extra.val.fmt(function_index, self),
9764 extra.elem.fmt(function_index, self),
9765 extra.index.fmt(function_index, self),
9766 });
9767 },
9768 .insertvalue => |tag| {
9769 var extra = function.extraDataTrail(
9770 Function.Instruction.InsertValue,
9771 instruction.data,
9772 );
9773 const indices = extra.trail.next(extra.data.indices_len, u32, &function);
9774 try writer.print(" %{} = {s} {%}, {%}", .{
9775 instruction_index.name(&function).fmt(self),
9776 @tagName(tag),
9777 extra.data.val.fmt(function_index, self),
9778 extra.data.elem.fmt(function_index, self),
9779 });
9780 for (indices) |index| try writer.print(", {d}", .{index});
9781 try writer.writeByte('\n');
9782 },
9783 .load,
9784 .@"load atomic",
9785 => |tag| {
9786 const extra =
9787 function.extraData(Function.Instruction.Load, instruction.data);
9788 try writer.print(" %{} = {s}{ } {%}, {%}{ }{ }{, }\n", .{
9789 instruction_index.name(&function).fmt(self),
9790 @tagName(tag),
9791 extra.info.access_kind,
9792 extra.type.fmt(self),
9793 extra.ptr.fmt(function_index, self),
9794 extra.info.sync_scope,
9795 extra.info.success_ordering,
9796 extra.info.alignment,
9797 });
9798 },
9799 .phi,
9800 .@"phi fast",
9801 => |tag| {
9802 var extra =
9803 function.extraDataTrail(Function.Instruction.Phi, instruction.data);
9804 const vals = extra.trail.next(block_incoming_len, Value, &function);
9805 const blocks =
9806 extra.trail.next(block_incoming_len, Function.Block.Index, &function);
9807 try writer.print(" %{} = {s} {%} ", .{
9808 instruction_index.name(&function).fmt(self),
9809 @tagName(tag),
9810 vals[0].typeOf(function_index, self).fmt(self),
9811 });
9812 for (0.., vals, blocks) |incoming_index, incoming_val, incoming_block| {
9813 if (incoming_index > 0) try writer.writeAll(", ");
9814 try writer.print("[ {}, {} ]", .{
9815 incoming_val.fmt(function_index, self),
9816 incoming_block.toInst(&function).fmt(function_index, self),
9817 });
9818 }
9819 try writer.writeByte('\n');9635 try writer.writeByte('\n');
9820 },9636 try writer.print("{}:\n", .{name.fmt(self)});
9821 .ret => |tag| {9637 },
9822 const val: Value = @enumFromInt(instruction.data);9638 .br => |tag| {
9823 try writer.print(" {s} {%}\n", .{9639 const target: Function.Block.Index = @enumFromInt(instruction.data);
9824 @tagName(tag),9640 try writer.print(" {s} {%}\n", .{
9825 val.fmt(function_index, self),9641 @tagName(tag), target.toInst(&function).fmt(function_index, self),
9826 });9642 });
9827 },9643 },
9828 .@"ret void",9644 .br_cond => {
9829 .@"unreachable",9645 const extra = function.extraData(Function.Instruction.BrCond, instruction.data);
9830 => |tag| try writer.print(" {s}\n", .{@tagName(tag)}),9646 try writer.print(" br {%}, {%}, {%}\n", .{
9831 .select,9647 extra.cond.fmt(function_index, self),
9832 .@"select fast",9648 extra.then.toInst(&function).fmt(function_index, self),
9833 => |tag| {9649 extra.@"else".toInst(&function).fmt(function_index, self),
9834 const extra =9650 });
9835 function.extraData(Function.Instruction.Select, instruction.data);9651 },
9836 try writer.print(" %{} = {s} {%}, {%}, {%}\n", .{9652 .call,
9837 instruction_index.name(&function).fmt(self),9653 .@"call fast",
9838 @tagName(tag),9654 .@"musttail call",
9839 extra.cond.fmt(function_index, self),9655 .@"musttail call fast",
9840 extra.lhs.fmt(function_index, self),9656 .@"notail call",
9841 extra.rhs.fmt(function_index, self),9657 .@"notail call fast",
9842 });9658 .@"tail call",
9843 },9659 .@"tail call fast",
9844 .shufflevector => |tag| {9660 => |tag| {
9845 const extra = function.extraData(9661 var extra =
9846 Function.Instruction.ShuffleVector,9662 function.extraDataTrail(Function.Instruction.Call, instruction.data);
9847 instruction.data,9663 const args = extra.trail.next(extra.data.args_len, Value, &function);
9848 );9664 try writer.writeAll(" ");
9849 try writer.print(" %{} = {s} {%}, {%}, {%}\n", .{9665 const ret_ty = extra.data.ty.functionReturn(self);
9666 switch (ret_ty) {
9667 .void => {},
9668 else => try writer.print("%{} = ", .{
9850 instruction_index.name(&function).fmt(self),9669 instruction_index.name(&function).fmt(self),
9851 @tagName(tag),9670 }),
9852 extra.lhs.fmt(function_index, self),9671 .none => unreachable,
9853 extra.rhs.fmt(function_index, self),9672 }
9854 extra.mask.fmt(function_index, self),9673 try writer.print("{s}{}{}{} {%} {}(", .{
9855 });9674 @tagName(tag),
9856 },9675 extra.data.info.call_conv,
9857 .store,9676 extra.data.attributes.ret(self).fmt(self),
9858 .@"store atomic",9677 extra.data.callee.typeOf(function_index, self).pointerAddrSpace(self),
9859 => |tag| {9678 switch (extra.data.ty.functionKind(self)) {
9860 const extra =9679 .normal => ret_ty,
9861 function.extraData(Function.Instruction.Store, instruction.data);9680 .vararg => extra.data.ty,
9862 try writer.print(" {s}{ } {%}, {%}{ }{ }{, }\n", .{9681 }.fmt(self),
9863 @tagName(tag),9682 extra.data.callee.fmt(function_index, self),
9864 extra.info.access_kind,9683 });
9865 extra.val.fmt(function_index, self),9684 for (0.., args) |arg_index, arg| {
9866 extra.ptr.fmt(function_index, self),9685 if (arg_index > 0) try writer.writeAll(", ");
9867 extra.info.sync_scope,9686 try writer.print("{%}{} {}", .{
9868 extra.info.success_ordering,9687 arg.typeOf(function_index, self).fmt(self),
9869 extra.info.alignment,9688 extra.data.attributes.param(arg_index, self).fmt(self),
9870 });9689 arg.fmt(function_index, self),
9871 },
9872 .@"switch" => |tag| {
9873 var extra =
9874 function.extraDataTrail(Function.Instruction.Switch, instruction.data);
9875 const vals = extra.trail.next(extra.data.cases_len, Constant, &function);
9876 const blocks =
9877 extra.trail.next(extra.data.cases_len, Function.Block.Index, &function);
9878 try writer.print(" {s} {%}, {%} [\n", .{
9879 @tagName(tag),
9880 extra.data.val.fmt(function_index, self),
9881 extra.data.default.toInst(&function).fmt(function_index, self),
9882 });9690 });
9883 for (vals, blocks) |case_val, case_block| try writer.print(9691 }
9884 " {%}, {%}\n",9692 try writer.writeByte(')');
9885 .{9693 const call_function_attributes = extra.data.attributes.func(self);
9886 case_val.fmt(self),9694 if (call_function_attributes != .none) try writer.print(" #{d}", .{
9887 case_block.toInst(&function).fmt(function_index, self),9695 (try attribute_groups.getOrPutValue(
9888 },9696 self.gpa,
9889 );9697 call_function_attributes,
9890 try writer.writeAll(" ]\n");9698 {},
9891 },9699 )).index,
9892 .va_arg => |tag| {9700 });
9893 const extra =9701 try writer.writeByte('\n');
9894 function.extraData(Function.Instruction.VaArg, instruction.data);9702 },
9895 try writer.print(" %{} = {s} {%}, {%}\n", .{9703 .cmpxchg,
9896 instruction_index.name(&function).fmt(self),9704 .@"cmpxchg weak",
9897 @tagName(tag),9705 => |tag| {
9898 extra.list.fmt(function_index, self),9706 const extra =
9899 extra.type.fmt(self),9707 function.extraData(Function.Instruction.CmpXchg, instruction.data);
9708 try writer.print(" %{} = {s}{ } {%}, {%}, {%}{ }{ }{ }{, }\n", .{
9709 instruction_index.name(&function).fmt(self),
9710 @tagName(tag),
9711 extra.info.access_kind,
9712 extra.ptr.fmt(function_index, self),
9713 extra.cmp.fmt(function_index, self),
9714 extra.new.fmt(function_index, self),
9715 extra.info.sync_scope,
9716 extra.info.success_ordering,
9717 extra.info.failure_ordering,
9718 extra.info.alignment,
9719 });
9720 },
9721 .extractelement => |tag| {
9722 const extra =
9723 function.extraData(Function.Instruction.ExtractElement, instruction.data);
9724 try writer.print(" %{} = {s} {%}, {%}\n", .{
9725 instruction_index.name(&function).fmt(self),
9726 @tagName(tag),
9727 extra.val.fmt(function_index, self),
9728 extra.index.fmt(function_index, self),
9729 });
9730 },
9731 .extractvalue => |tag| {
9732 var extra = function.extraDataTrail(
9733 Function.Instruction.ExtractValue,
9734 instruction.data,
9735 );
9736 const indices = extra.trail.next(extra.data.indices_len, u32, &function);
9737 try writer.print(" %{} = {s} {%}", .{
9738 instruction_index.name(&function).fmt(self),
9739 @tagName(tag),
9740 extra.data.val.fmt(function_index, self),
9741 });
9742 for (indices) |index| try writer.print(", {d}", .{index});
9743 try writer.writeByte('\n');
9744 },
9745 .fence => |tag| {
9746 const info: MemoryAccessInfo = @bitCast(instruction.data);
9747 try writer.print(" {s}{ }{ }", .{
9748 @tagName(tag),
9749 info.sync_scope,
9750 info.success_ordering,
9751 });
9752 },
9753 .fneg,
9754 .@"fneg fast",
9755 => |tag| {
9756 const val: Value = @enumFromInt(instruction.data);
9757 try writer.print(" %{} = {s} {%}\n", .{
9758 instruction_index.name(&function).fmt(self),
9759 @tagName(tag),
9760 val.fmt(function_index, self),
9761 });
9762 },
9763 .getelementptr,
9764 .@"getelementptr inbounds",
9765 => |tag| {
9766 var extra = function.extraDataTrail(
9767 Function.Instruction.GetElementPtr,
9768 instruction.data,
9769 );
9770 const indices = extra.trail.next(extra.data.indices_len, Value, &function);
9771 try writer.print(" %{} = {s} {%}, {%}", .{
9772 instruction_index.name(&function).fmt(self),
9773 @tagName(tag),
9774 extra.data.type.fmt(self),
9775 extra.data.base.fmt(function_index, self),
9776 });
9777 for (indices) |index| try writer.print(", {%}", .{
9778 index.fmt(function_index, self),
9779 });
9780 try writer.writeByte('\n');
9781 },
9782 .insertelement => |tag| {
9783 const extra =
9784 function.extraData(Function.Instruction.InsertElement, instruction.data);
9785 try writer.print(" %{} = {s} {%}, {%}, {%}\n", .{
9786 instruction_index.name(&function).fmt(self),
9787 @tagName(tag),
9788 extra.val.fmt(function_index, self),
9789 extra.elem.fmt(function_index, self),
9790 extra.index.fmt(function_index, self),
9791 });
9792 },
9793 .insertvalue => |tag| {
9794 var extra =
9795 function.extraDataTrail(Function.Instruction.InsertValue, instruction.data);
9796 const indices = extra.trail.next(extra.data.indices_len, u32, &function);
9797 try writer.print(" %{} = {s} {%}, {%}", .{
9798 instruction_index.name(&function).fmt(self),
9799 @tagName(tag),
9800 extra.data.val.fmt(function_index, self),
9801 extra.data.elem.fmt(function_index, self),
9802 });
9803 for (indices) |index| try writer.print(", {d}", .{index});
9804 try writer.writeByte('\n');
9805 },
9806 .load,
9807 .@"load atomic",
9808 => |tag| {
9809 const extra = function.extraData(Function.Instruction.Load, instruction.data);
9810 try writer.print(" %{} = {s}{ } {%}, {%}{ }{ }{, }\n", .{
9811 instruction_index.name(&function).fmt(self),
9812 @tagName(tag),
9813 extra.info.access_kind,
9814 extra.type.fmt(self),
9815 extra.ptr.fmt(function_index, self),
9816 extra.info.sync_scope,
9817 extra.info.success_ordering,
9818 extra.info.alignment,
9819 });
9820 },
9821 .phi,
9822 .@"phi fast",
9823 => |tag| {
9824 var extra = function.extraDataTrail(Function.Instruction.Phi, instruction.data);
9825 const vals = extra.trail.next(block_incoming_len, Value, &function);
9826 const blocks =
9827 extra.trail.next(block_incoming_len, Function.Block.Index, &function);
9828 try writer.print(" %{} = {s} {%} ", .{
9829 instruction_index.name(&function).fmt(self),
9830 @tagName(tag),
9831 vals[0].typeOf(function_index, self).fmt(self),
9832 });
9833 for (0.., vals, blocks) |incoming_index, incoming_val, incoming_block| {
9834 if (incoming_index > 0) try writer.writeAll(", ");
9835 try writer.print("[ {}, {} ]", .{
9836 incoming_val.fmt(function_index, self),
9837 incoming_block.toInst(&function).fmt(function_index, self),
9900 });9838 });
9901 },9839 }
9902 }9840 try writer.writeByte('\n');
9841 },
9842 .ret => |tag| {
9843 const val: Value = @enumFromInt(instruction.data);
9844 try writer.print(" {s} {%}\n", .{
9845 @tagName(tag),
9846 val.fmt(function_index, self),
9847 });
9848 },
9849 .@"ret void",
9850 .@"unreachable",
9851 => |tag| try writer.print(" {s}\n", .{@tagName(tag)}),
9852 .select,
9853 .@"select fast",
9854 => |tag| {
9855 const extra = function.extraData(Function.Instruction.Select, instruction.data);
9856 try writer.print(" %{} = {s} {%}, {%}, {%}\n", .{
9857 instruction_index.name(&function).fmt(self),
9858 @tagName(tag),
9859 extra.cond.fmt(function_index, self),
9860 extra.lhs.fmt(function_index, self),
9861 extra.rhs.fmt(function_index, self),
9862 });
9863 },
9864 .shufflevector => |tag| {
9865 const extra =
9866 function.extraData(Function.Instruction.ShuffleVector, instruction.data);
9867 try writer.print(" %{} = {s} {%}, {%}, {%}\n", .{
9868 instruction_index.name(&function).fmt(self),
9869 @tagName(tag),
9870 extra.lhs.fmt(function_index, self),
9871 extra.rhs.fmt(function_index, self),
9872 extra.mask.fmt(function_index, self),
9873 });
9874 },
9875 .store,
9876 .@"store atomic",
9877 => |tag| {
9878 const extra = function.extraData(Function.Instruction.Store, instruction.data);
9879 try writer.print(" {s}{ } {%}, {%}{ }{ }{, }\n", .{
9880 @tagName(tag),
9881 extra.info.access_kind,
9882 extra.val.fmt(function_index, self),
9883 extra.ptr.fmt(function_index, self),
9884 extra.info.sync_scope,
9885 extra.info.success_ordering,
9886 extra.info.alignment,
9887 });
9888 },
9889 .@"switch" => |tag| {
9890 var extra =
9891 function.extraDataTrail(Function.Instruction.Switch, instruction.data);
9892 const vals = extra.trail.next(extra.data.cases_len, Constant, &function);
9893 const blocks =
9894 extra.trail.next(extra.data.cases_len, Function.Block.Index, &function);
9895 try writer.print(" {s} {%}, {%} [\n", .{
9896 @tagName(tag),
9897 extra.data.val.fmt(function_index, self),
9898 extra.data.default.toInst(&function).fmt(function_index, self),
9899 });
9900 for (vals, blocks) |case_val, case_block| try writer.print(
9901 " {%}, {%}\n",
9902 .{
9903 case_val.fmt(self),
9904 case_block.toInst(&function).fmt(function_index, self),
9905 },
9906 );
9907 try writer.writeAll(" ]\n");
9908 },
9909 .va_arg => |tag| {
9910 const extra = function.extraData(Function.Instruction.VaArg, instruction.data);
9911 try writer.print(" %{} = {s} {%}, {%}\n", .{
9912 instruction_index.name(&function).fmt(self),
9913 @tagName(tag),
9914 extra.list.fmt(function_index, self),
9915 extra.type.fmt(self),
9916 });
9917 },
9903 }9918 }
9904 try writer.writeByte('}');
9905 }9919 }
9906 try writer.writeByte('\n');9920 try writer.writeByte('}');
9907 }9921 }
9922 try writer.writeByte('\n');
9908 need_newline = true;9923 need_newline = true;
9909 }9924 }
99109925