Commit 35cd56a369
Changed files (2)
src
codegen
src/codegen/llvm/Builder.zig
@@ -2320,6 +2320,10 @@ pub const Alias = struct {
return self.ptrConst(builder).global.name(builder);
}
+ pub fn rename(self: Index, new_name: String, builder: *Builder) Allocator.Error!void {
+ return self.ptrConst(builder).global.rename(new_name, builder);
+ }
+
pub fn typeOf(self: Index, builder: *const Builder) Type {
return self.ptrConst(builder).global.typeOf(builder);
}
@@ -2373,6 +2377,10 @@ pub const Variable = struct {
return self.ptrConst(builder).global.name(builder);
}
+ pub fn rename(self: Index, new_name: String, builder: *Builder) Allocator.Error!void {
+ return self.ptrConst(builder).global.rename(new_name, builder);
+ }
+
pub fn typeOf(self: Index, builder: *const Builder) Type {
return self.ptrConst(builder).global.typeOf(builder);
}
@@ -3812,6 +3820,10 @@ pub const Function = struct {
return self.ptrConst(builder).global.name(builder);
}
+ pub fn rename(self: Index, new_name: String, builder: *Builder) Allocator.Error!void {
+ return self.ptrConst(builder).global.rename(new_name, builder);
+ }
+
pub fn typeOf(self: Index, builder: *const Builder) Type {
return self.ptrConst(builder).global.typeOf(builder);
}
@@ -9393,518 +9405,521 @@ pub fn printUnbuffered(
need_newline = true;
}
- var attribute_groups: std.AutoArrayHashMapUnmanaged(Attributes, void) = .{};
- defer attribute_groups.deinit(self.gpa);
-
- if (self.functions.items.len > 0) {
+ if (self.aliases.items.len > 0) {
if (need_newline) try writer.writeByte('\n');
- for (0.., self.functions.items) |function_i, function| {
- if (function_i > 0) try writer.writeByte('\n');
- const function_index: Function.Index = @enumFromInt(function_i);
- if (function.global.getReplacement(self) != .none) continue;
- const global = function.global.ptrConst(self);
- const params_len = global.type.functionParameters(self).len;
- const function_attributes = function.attributes.func(self);
- if (function_attributes != .none) try writer.print(
- \\; Function Attrs:{}
- \\
- , .{function_attributes.fmt(self)});
+ for (self.aliases.items) |alias| {
+ if (alias.global.getReplacement(self) != .none) continue;
+ const global = alias.global.ptrConst(self);
try writer.print(
- \\{s}{}{}{}{}{}{"} {} {}(
+ \\{} ={}{}{}{}{ }{} alias {%}, {%}
+ \\
, .{
- if (function.instructions.len > 0) "define" else "declare",
+ alias.global.fmt(self),
global.linkage,
global.preemption,
global.visibility,
global.dll_storage_class,
- function.call_conv,
- function.attributes.ret(self).fmt(self),
- global.type.functionReturn(self).fmt(self),
- function.global.fmt(self),
+ alias.thread_local,
+ global.unnamed_addr,
+ global.type.fmt(self),
+ alias.aliasee.fmt(self),
});
- for (0..params_len) |arg| {
- if (arg > 0) try writer.writeAll(", ");
- try writer.print(
- \\{%}{"}
- , .{
- global.type.functionParameters(self)[arg].fmt(self),
- function.attributes.param(arg, self).fmt(self),
- });
- if (function.instructions.len > 0)
- try writer.print(" {}", .{function.arg(@intCast(arg)).fmt(function_index, self)})
- else
- try writer.print(" %{d}", .{arg});
- }
- switch (global.type.functionKind(self)) {
- .normal => {},
- .vararg => {
- if (params_len > 0) try writer.writeAll(", ");
- try writer.writeAll("...");
- },
- }
- try writer.print("){}{ }", .{ global.unnamed_addr, global.addr_space });
- if (function_attributes != .none) try writer.print(" #{d}", .{
- (try attribute_groups.getOrPutValue(self.gpa, function_attributes, {})).index,
+ }
+ need_newline = true;
+ }
+
+ var attribute_groups: std.AutoArrayHashMapUnmanaged(Attributes, void) = .{};
+ defer attribute_groups.deinit(self.gpa);
+
+ for (0.., self.functions.items) |function_i, function| {
+ if (function.global.getReplacement(self) != .none) continue;
+ if (need_newline) try writer.writeByte('\n');
+ const function_index: Function.Index = @enumFromInt(function_i);
+ const global = function.global.ptrConst(self);
+ const params_len = global.type.functionParameters(self).len;
+ const function_attributes = function.attributes.func(self);
+ if (function_attributes != .none) try writer.print(
+ \\; Function Attrs:{}
+ \\
+ , .{function_attributes.fmt(self)});
+ try writer.print(
+ \\{s}{}{}{}{}{}{"} {} {}(
+ , .{
+ if (function.instructions.len > 0) "define" else "declare",
+ global.linkage,
+ global.preemption,
+ global.visibility,
+ global.dll_storage_class,
+ function.call_conv,
+ function.attributes.ret(self).fmt(self),
+ global.type.functionReturn(self).fmt(self),
+ function.global.fmt(self),
+ });
+ for (0..params_len) |arg| {
+ if (arg > 0) try writer.writeAll(", ");
+ try writer.print(
+ \\{%}{"}
+ , .{
+ global.type.functionParameters(self)[arg].fmt(self),
+ function.attributes.param(arg, self).fmt(self),
});
- try writer.print("{ }", .{function.alignment});
- if (function.instructions.len > 0) {
- var block_incoming_len: u32 = undefined;
- try writer.writeAll(" {\n");
- for (params_len..function.instructions.len) |instruction_i| {
- const instruction_index: Function.Instruction.Index = @enumFromInt(instruction_i);
- const instruction = function.instructions.get(@intFromEnum(instruction_index));
- switch (instruction.tag) {
- .add,
- .@"add nsw",
- .@"add nuw",
- .@"add nuw nsw",
- .@"and",
- .ashr,
- .@"ashr exact",
- .fadd,
- .@"fadd fast",
- .@"fcmp false",
- .@"fcmp fast false",
- .@"fcmp fast oeq",
- .@"fcmp fast oge",
- .@"fcmp fast ogt",
- .@"fcmp fast ole",
- .@"fcmp fast olt",
- .@"fcmp fast one",
- .@"fcmp fast ord",
- .@"fcmp fast true",
- .@"fcmp fast ueq",
- .@"fcmp fast uge",
- .@"fcmp fast ugt",
- .@"fcmp fast ule",
- .@"fcmp fast ult",
- .@"fcmp fast une",
- .@"fcmp fast uno",
- .@"fcmp oeq",
- .@"fcmp oge",
- .@"fcmp ogt",
- .@"fcmp ole",
- .@"fcmp olt",
- .@"fcmp one",
- .@"fcmp ord",
- .@"fcmp true",
- .@"fcmp ueq",
- .@"fcmp uge",
- .@"fcmp ugt",
- .@"fcmp ule",
- .@"fcmp ult",
- .@"fcmp une",
- .@"fcmp uno",
- .fdiv,
- .@"fdiv fast",
- .fmul,
- .@"fmul fast",
- .frem,
- .@"frem fast",
- .fsub,
- .@"fsub fast",
- .@"icmp eq",
- .@"icmp ne",
- .@"icmp sge",
- .@"icmp sgt",
- .@"icmp sle",
- .@"icmp slt",
- .@"icmp uge",
- .@"icmp ugt",
- .@"icmp ule",
- .@"icmp ult",
- .lshr,
- .@"lshr exact",
- .mul,
- .@"mul nsw",
- .@"mul nuw",
- .@"mul nuw nsw",
- .@"or",
- .sdiv,
- .@"sdiv exact",
- .srem,
- .shl,
- .@"shl nsw",
- .@"shl nuw",
- .@"shl nuw nsw",
- .sub,
- .@"sub nsw",
- .@"sub nuw",
- .@"sub nuw nsw",
- .udiv,
- .@"udiv exact",
- .urem,
- .xor,
- => |tag| {
- const extra =
- function.extraData(Function.Instruction.Binary, instruction.data);
- try writer.print(" %{} = {s} {%}, {}\n", .{
- instruction_index.name(&function).fmt(self),
- @tagName(tag),
- extra.lhs.fmt(function_index, self),
- extra.rhs.fmt(function_index, self),
- });
- },
- .addrspacecast,
- .bitcast,
- .fpext,
- .fptosi,
- .fptoui,
- .fptrunc,
- .inttoptr,
- .ptrtoint,
- .sext,
- .sitofp,
- .trunc,
- .uitofp,
- .zext,
- => |tag| {
- const extra =
- function.extraData(Function.Instruction.Cast, instruction.data);
- try writer.print(" %{} = {s} {%} to {%}\n", .{
- instruction_index.name(&function).fmt(self),
- @tagName(tag),
- extra.val.fmt(function_index, self),
- extra.type.fmt(self),
- });
- },
- .alloca,
- .@"alloca inalloca",
- => |tag| {
- const extra =
- function.extraData(Function.Instruction.Alloca, instruction.data);
- try writer.print(" %{} = {s} {%}{,%}{, }{, }\n", .{
- instruction_index.name(&function).fmt(self),
- @tagName(tag),
- extra.type.fmt(self),
- extra.len.fmt(function_index, self),
- extra.info.alignment,
- extra.info.addr_space,
- });
- },
- .arg => unreachable,
- .atomicrmw => |tag| {
- const extra =
- function.extraData(Function.Instruction.AtomicRmw, instruction.data);
- try writer.print(" %{} = {s}{ } {s} {%}, {%}{ }{ }{, }\n", .{
- instruction_index.name(&function).fmt(self),
- @tagName(tag),
- extra.info.access_kind,
- @tagName(extra.info.atomic_rmw_operation),
- extra.ptr.fmt(function_index, self),
- extra.val.fmt(function_index, self),
- extra.info.sync_scope,
- extra.info.success_ordering,
- extra.info.alignment,
- });
- },
- .block => {
- block_incoming_len = instruction.data;
- const name = instruction_index.name(&function);
- if (@intFromEnum(instruction_index) > params_len)
- try writer.writeByte('\n');
- try writer.print("{}:\n", .{name.fmt(self)});
- },
- .br => |tag| {
- const target: Function.Block.Index = @enumFromInt(instruction.data);
- try writer.print(" {s} {%}\n", .{
- @tagName(tag), target.toInst(&function).fmt(function_index, self),
- });
- },
- .br_cond => {
- const extra =
- function.extraData(Function.Instruction.BrCond, instruction.data);
- try writer.print(" br {%}, {%}, {%}\n", .{
- extra.cond.fmt(function_index, self),
- extra.then.toInst(&function).fmt(function_index, self),
- extra.@"else".toInst(&function).fmt(function_index, self),
- });
- },
- .call,
- .@"call fast",
- .@"musttail call",
- .@"musttail call fast",
- .@"notail call",
- .@"notail call fast",
- .@"tail call",
- .@"tail call fast",
- => |tag| {
- var extra =
- function.extraDataTrail(Function.Instruction.Call, instruction.data);
- const args = extra.trail.next(extra.data.args_len, Value, &function);
- try writer.writeAll(" ");
- const ret_ty = extra.data.ty.functionReturn(self);
- switch (ret_ty) {
- .void => {},
- else => try writer.print("%{} = ", .{
- instruction_index.name(&function).fmt(self),
- }),
- .none => unreachable,
- }
- try writer.print("{s}{}{}{} {%} {}(", .{
- @tagName(tag),
- extra.data.info.call_conv,
- extra.data.attributes.ret(self).fmt(self),
- extra.data.callee.typeOf(function_index, self).pointerAddrSpace(self),
- switch (extra.data.ty.functionKind(self)) {
- .normal => ret_ty,
- .vararg => extra.data.ty,
- }.fmt(self),
- extra.data.callee.fmt(function_index, self),
- });
- for (0.., args) |arg_index, arg| {
- if (arg_index > 0) try writer.writeAll(", ");
- try writer.print("{%}{} {}", .{
- arg.typeOf(function_index, self).fmt(self),
- extra.data.attributes.param(arg_index, self).fmt(self),
- arg.fmt(function_index, self),
- });
- }
- try writer.writeByte(')');
- const call_function_attributes = extra.data.attributes.func(self);
- if (call_function_attributes != .none) try writer.print(" #{d}", .{
- (try attribute_groups.getOrPutValue(
- self.gpa,
- call_function_attributes,
- {},
- )).index,
- });
- try writer.writeByte('\n');
- },
- .cmpxchg,
- .@"cmpxchg weak",
- => |tag| {
- const extra =
- function.extraData(Function.Instruction.CmpXchg, instruction.data);
- try writer.print(" %{} = {s}{ } {%}, {%}, {%}{ }{ }{ }{, }\n", .{
- instruction_index.name(&function).fmt(self),
- @tagName(tag),
- extra.info.access_kind,
- extra.ptr.fmt(function_index, self),
- extra.cmp.fmt(function_index, self),
- extra.new.fmt(function_index, self),
- extra.info.sync_scope,
- extra.info.success_ordering,
- extra.info.failure_ordering,
- extra.info.alignment,
- });
- },
- .extractelement => |tag| {
- const extra = function.extraData(
- Function.Instruction.ExtractElement,
- instruction.data,
- );
- try writer.print(" %{} = {s} {%}, {%}\n", .{
- instruction_index.name(&function).fmt(self),
- @tagName(tag),
- extra.val.fmt(function_index, self),
- extra.index.fmt(function_index, self),
- });
- },
- .extractvalue => |tag| {
- var extra = function.extraDataTrail(
- Function.Instruction.ExtractValue,
- instruction.data,
- );
- const indices = extra.trail.next(extra.data.indices_len, u32, &function);
- try writer.print(" %{} = {s} {%}", .{
- instruction_index.name(&function).fmt(self),
- @tagName(tag),
- extra.data.val.fmt(function_index, self),
- });
- for (indices) |index| try writer.print(", {d}", .{index});
- try writer.writeByte('\n');
- },
- .fence => |tag| {
- const info: MemoryAccessInfo = @bitCast(instruction.data);
- try writer.print(" {s}{ }{ }", .{
- @tagName(tag),
- info.sync_scope,
- info.success_ordering,
- });
- },
- .fneg,
- .@"fneg fast",
- => |tag| {
- const val: Value = @enumFromInt(instruction.data);
- try writer.print(" %{} = {s} {%}\n", .{
- instruction_index.name(&function).fmt(self),
- @tagName(tag),
- val.fmt(function_index, self),
- });
- },
- .getelementptr,
- .@"getelementptr inbounds",
- => |tag| {
- var extra = function.extraDataTrail(
- Function.Instruction.GetElementPtr,
- instruction.data,
- );
- const indices = extra.trail.next(extra.data.indices_len, Value, &function);
- try writer.print(" %{} = {s} {%}, {%}", .{
- instruction_index.name(&function).fmt(self),
- @tagName(tag),
- extra.data.type.fmt(self),
- extra.data.base.fmt(function_index, self),
- });
- for (indices) |index| try writer.print(", {%}", .{
- index.fmt(function_index, self),
- });
- try writer.writeByte('\n');
- },
- .insertelement => |tag| {
- const extra = function.extraData(
- Function.Instruction.InsertElement,
- instruction.data,
- );
- try writer.print(" %{} = {s} {%}, {%}, {%}\n", .{
- instruction_index.name(&function).fmt(self),
- @tagName(tag),
- extra.val.fmt(function_index, self),
- extra.elem.fmt(function_index, self),
- extra.index.fmt(function_index, self),
- });
- },
- .insertvalue => |tag| {
- var extra = function.extraDataTrail(
- Function.Instruction.InsertValue,
- instruction.data,
- );
- const indices = extra.trail.next(extra.data.indices_len, u32, &function);
- try writer.print(" %{} = {s} {%}, {%}", .{
- instruction_index.name(&function).fmt(self),
- @tagName(tag),
- extra.data.val.fmt(function_index, self),
- extra.data.elem.fmt(function_index, self),
- });
- for (indices) |index| try writer.print(", {d}", .{index});
- try writer.writeByte('\n');
- },
- .load,
- .@"load atomic",
- => |tag| {
- const extra =
- function.extraData(Function.Instruction.Load, instruction.data);
- try writer.print(" %{} = {s}{ } {%}, {%}{ }{ }{, }\n", .{
- instruction_index.name(&function).fmt(self),
- @tagName(tag),
- extra.info.access_kind,
- extra.type.fmt(self),
- extra.ptr.fmt(function_index, self),
- extra.info.sync_scope,
- extra.info.success_ordering,
- extra.info.alignment,
- });
- },
- .phi,
- .@"phi fast",
- => |tag| {
- var extra =
- function.extraDataTrail(Function.Instruction.Phi, instruction.data);
- const vals = extra.trail.next(block_incoming_len, Value, &function);
- const blocks =
- extra.trail.next(block_incoming_len, Function.Block.Index, &function);
- try writer.print(" %{} = {s} {%} ", .{
- instruction_index.name(&function).fmt(self),
- @tagName(tag),
- vals[0].typeOf(function_index, self).fmt(self),
- });
- for (0.., vals, blocks) |incoming_index, incoming_val, incoming_block| {
- if (incoming_index > 0) try writer.writeAll(", ");
- try writer.print("[ {}, {} ]", .{
- incoming_val.fmt(function_index, self),
- incoming_block.toInst(&function).fmt(function_index, self),
- });
- }
+ if (function.instructions.len > 0)
+ try writer.print(" {}", .{function.arg(@intCast(arg)).fmt(function_index, self)})
+ else
+ try writer.print(" %{d}", .{arg});
+ }
+ switch (global.type.functionKind(self)) {
+ .normal => {},
+ .vararg => {
+ if (params_len > 0) try writer.writeAll(", ");
+ try writer.writeAll("...");
+ },
+ }
+ try writer.print("){}{ }", .{ global.unnamed_addr, global.addr_space });
+ if (function_attributes != .none) try writer.print(" #{d}", .{
+ (try attribute_groups.getOrPutValue(self.gpa, function_attributes, {})).index,
+ });
+ try writer.print("{ }", .{function.alignment});
+ if (function.instructions.len > 0) {
+ var block_incoming_len: u32 = undefined;
+ try writer.writeAll(" {\n");
+ for (params_len..function.instructions.len) |instruction_i| {
+ const instruction_index: Function.Instruction.Index = @enumFromInt(instruction_i);
+ const instruction = function.instructions.get(@intFromEnum(instruction_index));
+ switch (instruction.tag) {
+ .add,
+ .@"add nsw",
+ .@"add nuw",
+ .@"add nuw nsw",
+ .@"and",
+ .ashr,
+ .@"ashr exact",
+ .fadd,
+ .@"fadd fast",
+ .@"fcmp false",
+ .@"fcmp fast false",
+ .@"fcmp fast oeq",
+ .@"fcmp fast oge",
+ .@"fcmp fast ogt",
+ .@"fcmp fast ole",
+ .@"fcmp fast olt",
+ .@"fcmp fast one",
+ .@"fcmp fast ord",
+ .@"fcmp fast true",
+ .@"fcmp fast ueq",
+ .@"fcmp fast uge",
+ .@"fcmp fast ugt",
+ .@"fcmp fast ule",
+ .@"fcmp fast ult",
+ .@"fcmp fast une",
+ .@"fcmp fast uno",
+ .@"fcmp oeq",
+ .@"fcmp oge",
+ .@"fcmp ogt",
+ .@"fcmp ole",
+ .@"fcmp olt",
+ .@"fcmp one",
+ .@"fcmp ord",
+ .@"fcmp true",
+ .@"fcmp ueq",
+ .@"fcmp uge",
+ .@"fcmp ugt",
+ .@"fcmp ule",
+ .@"fcmp ult",
+ .@"fcmp une",
+ .@"fcmp uno",
+ .fdiv,
+ .@"fdiv fast",
+ .fmul,
+ .@"fmul fast",
+ .frem,
+ .@"frem fast",
+ .fsub,
+ .@"fsub fast",
+ .@"icmp eq",
+ .@"icmp ne",
+ .@"icmp sge",
+ .@"icmp sgt",
+ .@"icmp sle",
+ .@"icmp slt",
+ .@"icmp uge",
+ .@"icmp ugt",
+ .@"icmp ule",
+ .@"icmp ult",
+ .lshr,
+ .@"lshr exact",
+ .mul,
+ .@"mul nsw",
+ .@"mul nuw",
+ .@"mul nuw nsw",
+ .@"or",
+ .sdiv,
+ .@"sdiv exact",
+ .srem,
+ .shl,
+ .@"shl nsw",
+ .@"shl nuw",
+ .@"shl nuw nsw",
+ .sub,
+ .@"sub nsw",
+ .@"sub nuw",
+ .@"sub nuw nsw",
+ .udiv,
+ .@"udiv exact",
+ .urem,
+ .xor,
+ => |tag| {
+ const extra = function.extraData(Function.Instruction.Binary, instruction.data);
+ try writer.print(" %{} = {s} {%}, {}\n", .{
+ instruction_index.name(&function).fmt(self),
+ @tagName(tag),
+ extra.lhs.fmt(function_index, self),
+ extra.rhs.fmt(function_index, self),
+ });
+ },
+ .addrspacecast,
+ .bitcast,
+ .fpext,
+ .fptosi,
+ .fptoui,
+ .fptrunc,
+ .inttoptr,
+ .ptrtoint,
+ .sext,
+ .sitofp,
+ .trunc,
+ .uitofp,
+ .zext,
+ => |tag| {
+ const extra = function.extraData(Function.Instruction.Cast, instruction.data);
+ try writer.print(" %{} = {s} {%} to {%}\n", .{
+ instruction_index.name(&function).fmt(self),
+ @tagName(tag),
+ extra.val.fmt(function_index, self),
+ extra.type.fmt(self),
+ });
+ },
+ .alloca,
+ .@"alloca inalloca",
+ => |tag| {
+ const extra = function.extraData(Function.Instruction.Alloca, instruction.data);
+ try writer.print(" %{} = {s} {%}{,%}{, }{, }\n", .{
+ instruction_index.name(&function).fmt(self),
+ @tagName(tag),
+ extra.type.fmt(self),
+ extra.len.fmt(function_index, self),
+ extra.info.alignment,
+ extra.info.addr_space,
+ });
+ },
+ .arg => unreachable,
+ .atomicrmw => |tag| {
+ const extra =
+ function.extraData(Function.Instruction.AtomicRmw, instruction.data);
+ try writer.print(" %{} = {s}{ } {s} {%}, {%}{ }{ }{, }\n", .{
+ instruction_index.name(&function).fmt(self),
+ @tagName(tag),
+ extra.info.access_kind,
+ @tagName(extra.info.atomic_rmw_operation),
+ extra.ptr.fmt(function_index, self),
+ extra.val.fmt(function_index, self),
+ extra.info.sync_scope,
+ extra.info.success_ordering,
+ extra.info.alignment,
+ });
+ },
+ .block => {
+ block_incoming_len = instruction.data;
+ const name = instruction_index.name(&function);
+ if (@intFromEnum(instruction_index) > params_len)
try writer.writeByte('\n');
- },
- .ret => |tag| {
- const val: Value = @enumFromInt(instruction.data);
- try writer.print(" {s} {%}\n", .{
- @tagName(tag),
- val.fmt(function_index, self),
- });
- },
- .@"ret void",
- .@"unreachable",
- => |tag| try writer.print(" {s}\n", .{@tagName(tag)}),
- .select,
- .@"select fast",
- => |tag| {
- const extra =
- function.extraData(Function.Instruction.Select, instruction.data);
- try writer.print(" %{} = {s} {%}, {%}, {%}\n", .{
- instruction_index.name(&function).fmt(self),
- @tagName(tag),
- extra.cond.fmt(function_index, self),
- extra.lhs.fmt(function_index, self),
- extra.rhs.fmt(function_index, self),
- });
- },
- .shufflevector => |tag| {
- const extra = function.extraData(
- Function.Instruction.ShuffleVector,
- instruction.data,
- );
- try writer.print(" %{} = {s} {%}, {%}, {%}\n", .{
+ try writer.print("{}:\n", .{name.fmt(self)});
+ },
+ .br => |tag| {
+ const target: Function.Block.Index = @enumFromInt(instruction.data);
+ try writer.print(" {s} {%}\n", .{
+ @tagName(tag), target.toInst(&function).fmt(function_index, self),
+ });
+ },
+ .br_cond => {
+ const extra = function.extraData(Function.Instruction.BrCond, instruction.data);
+ try writer.print(" br {%}, {%}, {%}\n", .{
+ extra.cond.fmt(function_index, self),
+ extra.then.toInst(&function).fmt(function_index, self),
+ extra.@"else".toInst(&function).fmt(function_index, self),
+ });
+ },
+ .call,
+ .@"call fast",
+ .@"musttail call",
+ .@"musttail call fast",
+ .@"notail call",
+ .@"notail call fast",
+ .@"tail call",
+ .@"tail call fast",
+ => |tag| {
+ var extra =
+ function.extraDataTrail(Function.Instruction.Call, instruction.data);
+ const args = extra.trail.next(extra.data.args_len, Value, &function);
+ try writer.writeAll(" ");
+ const ret_ty = extra.data.ty.functionReturn(self);
+ switch (ret_ty) {
+ .void => {},
+ else => try writer.print("%{} = ", .{
instruction_index.name(&function).fmt(self),
- @tagName(tag),
- extra.lhs.fmt(function_index, self),
- extra.rhs.fmt(function_index, self),
- extra.mask.fmt(function_index, self),
- });
- },
- .store,
- .@"store atomic",
- => |tag| {
- const extra =
- function.extraData(Function.Instruction.Store, instruction.data);
- try writer.print(" {s}{ } {%}, {%}{ }{ }{, }\n", .{
- @tagName(tag),
- extra.info.access_kind,
- extra.val.fmt(function_index, self),
- extra.ptr.fmt(function_index, self),
- extra.info.sync_scope,
- extra.info.success_ordering,
- extra.info.alignment,
- });
- },
- .@"switch" => |tag| {
- var extra =
- function.extraDataTrail(Function.Instruction.Switch, instruction.data);
- const vals = extra.trail.next(extra.data.cases_len, Constant, &function);
- const blocks =
- extra.trail.next(extra.data.cases_len, Function.Block.Index, &function);
- try writer.print(" {s} {%}, {%} [\n", .{
- @tagName(tag),
- extra.data.val.fmt(function_index, self),
- extra.data.default.toInst(&function).fmt(function_index, self),
+ }),
+ .none => unreachable,
+ }
+ try writer.print("{s}{}{}{} {%} {}(", .{
+ @tagName(tag),
+ extra.data.info.call_conv,
+ extra.data.attributes.ret(self).fmt(self),
+ extra.data.callee.typeOf(function_index, self).pointerAddrSpace(self),
+ switch (extra.data.ty.functionKind(self)) {
+ .normal => ret_ty,
+ .vararg => extra.data.ty,
+ }.fmt(self),
+ extra.data.callee.fmt(function_index, self),
+ });
+ for (0.., args) |arg_index, arg| {
+ if (arg_index > 0) try writer.writeAll(", ");
+ try writer.print("{%}{} {}", .{
+ arg.typeOf(function_index, self).fmt(self),
+ extra.data.attributes.param(arg_index, self).fmt(self),
+ arg.fmt(function_index, self),
});
- for (vals, blocks) |case_val, case_block| try writer.print(
- " {%}, {%}\n",
- .{
- case_val.fmt(self),
- case_block.toInst(&function).fmt(function_index, self),
- },
- );
- try writer.writeAll(" ]\n");
- },
- .va_arg => |tag| {
- const extra =
- function.extraData(Function.Instruction.VaArg, instruction.data);
- try writer.print(" %{} = {s} {%}, {%}\n", .{
- instruction_index.name(&function).fmt(self),
- @tagName(tag),
- extra.list.fmt(function_index, self),
- extra.type.fmt(self),
+ }
+ try writer.writeByte(')');
+ const call_function_attributes = extra.data.attributes.func(self);
+ if (call_function_attributes != .none) try writer.print(" #{d}", .{
+ (try attribute_groups.getOrPutValue(
+ self.gpa,
+ call_function_attributes,
+ {},
+ )).index,
+ });
+ try writer.writeByte('\n');
+ },
+ .cmpxchg,
+ .@"cmpxchg weak",
+ => |tag| {
+ const extra =
+ function.extraData(Function.Instruction.CmpXchg, instruction.data);
+ try writer.print(" %{} = {s}{ } {%}, {%}, {%}{ }{ }{ }{, }\n", .{
+ instruction_index.name(&function).fmt(self),
+ @tagName(tag),
+ extra.info.access_kind,
+ extra.ptr.fmt(function_index, self),
+ extra.cmp.fmt(function_index, self),
+ extra.new.fmt(function_index, self),
+ extra.info.sync_scope,
+ extra.info.success_ordering,
+ extra.info.failure_ordering,
+ extra.info.alignment,
+ });
+ },
+ .extractelement => |tag| {
+ const extra =
+ function.extraData(Function.Instruction.ExtractElement, instruction.data);
+ try writer.print(" %{} = {s} {%}, {%}\n", .{
+ instruction_index.name(&function).fmt(self),
+ @tagName(tag),
+ extra.val.fmt(function_index, self),
+ extra.index.fmt(function_index, self),
+ });
+ },
+ .extractvalue => |tag| {
+ var extra = function.extraDataTrail(
+ Function.Instruction.ExtractValue,
+ instruction.data,
+ );
+ const indices = extra.trail.next(extra.data.indices_len, u32, &function);
+ try writer.print(" %{} = {s} {%}", .{
+ instruction_index.name(&function).fmt(self),
+ @tagName(tag),
+ extra.data.val.fmt(function_index, self),
+ });
+ for (indices) |index| try writer.print(", {d}", .{index});
+ try writer.writeByte('\n');
+ },
+ .fence => |tag| {
+ const info: MemoryAccessInfo = @bitCast(instruction.data);
+ try writer.print(" {s}{ }{ }", .{
+ @tagName(tag),
+ info.sync_scope,
+ info.success_ordering,
+ });
+ },
+ .fneg,
+ .@"fneg fast",
+ => |tag| {
+ const val: Value = @enumFromInt(instruction.data);
+ try writer.print(" %{} = {s} {%}\n", .{
+ instruction_index.name(&function).fmt(self),
+ @tagName(tag),
+ val.fmt(function_index, self),
+ });
+ },
+ .getelementptr,
+ .@"getelementptr inbounds",
+ => |tag| {
+ var extra = function.extraDataTrail(
+ Function.Instruction.GetElementPtr,
+ instruction.data,
+ );
+ const indices = extra.trail.next(extra.data.indices_len, Value, &function);
+ try writer.print(" %{} = {s} {%}, {%}", .{
+ instruction_index.name(&function).fmt(self),
+ @tagName(tag),
+ extra.data.type.fmt(self),
+ extra.data.base.fmt(function_index, self),
+ });
+ for (indices) |index| try writer.print(", {%}", .{
+ index.fmt(function_index, self),
+ });
+ try writer.writeByte('\n');
+ },
+ .insertelement => |tag| {
+ const extra =
+ function.extraData(Function.Instruction.InsertElement, instruction.data);
+ try writer.print(" %{} = {s} {%}, {%}, {%}\n", .{
+ instruction_index.name(&function).fmt(self),
+ @tagName(tag),
+ extra.val.fmt(function_index, self),
+ extra.elem.fmt(function_index, self),
+ extra.index.fmt(function_index, self),
+ });
+ },
+ .insertvalue => |tag| {
+ var extra =
+ function.extraDataTrail(Function.Instruction.InsertValue, instruction.data);
+ const indices = extra.trail.next(extra.data.indices_len, u32, &function);
+ try writer.print(" %{} = {s} {%}, {%}", .{
+ instruction_index.name(&function).fmt(self),
+ @tagName(tag),
+ extra.data.val.fmt(function_index, self),
+ extra.data.elem.fmt(function_index, self),
+ });
+ for (indices) |index| try writer.print(", {d}", .{index});
+ try writer.writeByte('\n');
+ },
+ .load,
+ .@"load atomic",
+ => |tag| {
+ const extra = function.extraData(Function.Instruction.Load, instruction.data);
+ try writer.print(" %{} = {s}{ } {%}, {%}{ }{ }{, }\n", .{
+ instruction_index.name(&function).fmt(self),
+ @tagName(tag),
+ extra.info.access_kind,
+ extra.type.fmt(self),
+ extra.ptr.fmt(function_index, self),
+ extra.info.sync_scope,
+ extra.info.success_ordering,
+ extra.info.alignment,
+ });
+ },
+ .phi,
+ .@"phi fast",
+ => |tag| {
+ var extra = function.extraDataTrail(Function.Instruction.Phi, instruction.data);
+ const vals = extra.trail.next(block_incoming_len, Value, &function);
+ const blocks =
+ extra.trail.next(block_incoming_len, Function.Block.Index, &function);
+ try writer.print(" %{} = {s} {%} ", .{
+ instruction_index.name(&function).fmt(self),
+ @tagName(tag),
+ vals[0].typeOf(function_index, self).fmt(self),
+ });
+ for (0.., vals, blocks) |incoming_index, incoming_val, incoming_block| {
+ if (incoming_index > 0) try writer.writeAll(", ");
+ try writer.print("[ {}, {} ]", .{
+ incoming_val.fmt(function_index, self),
+ incoming_block.toInst(&function).fmt(function_index, self),
});
- },
- }
+ }
+ try writer.writeByte('\n');
+ },
+ .ret => |tag| {
+ const val: Value = @enumFromInt(instruction.data);
+ try writer.print(" {s} {%}\n", .{
+ @tagName(tag),
+ val.fmt(function_index, self),
+ });
+ },
+ .@"ret void",
+ .@"unreachable",
+ => |tag| try writer.print(" {s}\n", .{@tagName(tag)}),
+ .select,
+ .@"select fast",
+ => |tag| {
+ const extra = function.extraData(Function.Instruction.Select, instruction.data);
+ try writer.print(" %{} = {s} {%}, {%}, {%}\n", .{
+ instruction_index.name(&function).fmt(self),
+ @tagName(tag),
+ extra.cond.fmt(function_index, self),
+ extra.lhs.fmt(function_index, self),
+ extra.rhs.fmt(function_index, self),
+ });
+ },
+ .shufflevector => |tag| {
+ const extra =
+ function.extraData(Function.Instruction.ShuffleVector, instruction.data);
+ try writer.print(" %{} = {s} {%}, {%}, {%}\n", .{
+ instruction_index.name(&function).fmt(self),
+ @tagName(tag),
+ extra.lhs.fmt(function_index, self),
+ extra.rhs.fmt(function_index, self),
+ extra.mask.fmt(function_index, self),
+ });
+ },
+ .store,
+ .@"store atomic",
+ => |tag| {
+ const extra = function.extraData(Function.Instruction.Store, instruction.data);
+ try writer.print(" {s}{ } {%}, {%}{ }{ }{, }\n", .{
+ @tagName(tag),
+ extra.info.access_kind,
+ extra.val.fmt(function_index, self),
+ extra.ptr.fmt(function_index, self),
+ extra.info.sync_scope,
+ extra.info.success_ordering,
+ extra.info.alignment,
+ });
+ },
+ .@"switch" => |tag| {
+ var extra =
+ function.extraDataTrail(Function.Instruction.Switch, instruction.data);
+ const vals = extra.trail.next(extra.data.cases_len, Constant, &function);
+ const blocks =
+ extra.trail.next(extra.data.cases_len, Function.Block.Index, &function);
+ try writer.print(" {s} {%}, {%} [\n", .{
+ @tagName(tag),
+ extra.data.val.fmt(function_index, self),
+ extra.data.default.toInst(&function).fmt(function_index, self),
+ });
+ for (vals, blocks) |case_val, case_block| try writer.print(
+ " {%}, {%}\n",
+ .{
+ case_val.fmt(self),
+ case_block.toInst(&function).fmt(function_index, self),
+ },
+ );
+ try writer.writeAll(" ]\n");
+ },
+ .va_arg => |tag| {
+ const extra = function.extraData(Function.Instruction.VaArg, instruction.data);
+ try writer.print(" %{} = {s} {%}, {%}\n", .{
+ instruction_index.name(&function).fmt(self),
+ @tagName(tag),
+ extra.list.fmt(function_index, self),
+ extra.type.fmt(self),
+ });
+ },
}
- try writer.writeByte('}');
}
- try writer.writeByte('\n');
+ try writer.writeByte('}');
}
+ try writer.writeByte('\n');
need_newline = true;
}
src/codegen/llvm.zig
@@ -1079,7 +1079,8 @@ pub const Object = struct {
// Same logic as below but for externs instead of exports.
const decl_name = object.builder.stringIfExists(mod.intern_pool.stringToSlice(mod.declPtr(decl_index).name)) orelse continue;
const other_global = object.builder.getGlobal(decl_name) orelse continue;
- if (other_global.eql(global, &object.builder)) continue;
+ if (other_global.toConst().getBase(&object.builder) ==
+ global.toConst().getBase(&object.builder)) continue;
try global.replace(other_global, &object.builder);
}
@@ -1087,13 +1088,14 @@ pub const Object = struct {
for (mod.decl_exports.keys(), mod.decl_exports.values()) |decl_index, export_list| {
const global = object.decl_map.get(decl_index) orelse continue;
+ const global_base = global.toConst().getBase(&object.builder);
for (export_list.items) |exp| {
// Detect if the LLVM global has already been created as an extern. In such
// case, we need to replace all uses of it with this exported global.
const exp_name = object.builder.stringIfExists(mod.intern_pool.stringToSlice(exp.opts.name)) orelse continue;
const other_global = object.builder.getGlobal(exp_name) orelse continue;
- if (other_global.eql(global, &object.builder)) continue;
+ if (other_global.toConst().getBase(&object.builder) == global_base) continue;
try global.takeName(other_global, &object.builder);
try other_global.replace(global, &object.builder);
@@ -1714,7 +1716,7 @@ pub const Object = struct {
try self.builder.string(section),
&self.builder,
),
- else => unreachable,
+ .alias, .replaced => unreachable,
};
if (decl.val.getVariable(mod)) |decl_var| if (decl_var.is_threadlocal)
global_index.ptrConst(&self.builder).kind
@@ -1735,15 +1737,16 @@ pub const Object = struct {
continue;
},
.variable, .function => {},
- else => unreachable,
+ .replaced => unreachable,
}
}
- _ = try self.builder.addAlias(
- exp_name,
+ const alias_index = try self.builder.addAlias(
+ .empty,
global_index.typeOf(&self.builder),
.default,
global_index.toConst(),
);
+ try alias_index.rename(exp_name, &self.builder);
}
} else {
const fqn = try self.builder.string(
@@ -7703,7 +7706,7 @@ pub const FuncGen = struct {
if (o.builder.getGlobal(fn_name)) |global| return switch (global.ptrConst(&o.builder).kind) {
.alias => |alias| alias.getAliasee(&o.builder).ptrConst(&o.builder).kind.function,
.function => |function| function,
- else => unreachable,
+ .variable, .replaced => unreachable,
};
return o.builder.addFunction(
try o.builder.fnType(return_type, param_types, .normal),
@@ -7751,11 +7754,7 @@ pub const FuncGen = struct {
};
const fn_name = try o.builder.fmt("__{s}{s}f2", .{ fn_base_name, compiler_rt_float_abbrev });
- const libc_fn = try self.getLibcFunction(
- fn_name,
- ([1]Builder.Type{scalar_llvm_ty} ** 2)[0..],
- .i32,
- );
+ const libc_fn = try self.getLibcFunction(fn_name, &.{ scalar_llvm_ty, scalar_llvm_ty }, .i32);
const zero = try o.builder.intConst(.i32, 0);
const int_cond: Builder.IntegerCondition = switch (pred) {