Builder: add indirectbr llvm instruction
This commit is contained in:
@@ -4157,6 +4157,7 @@ pub const Function = struct {
|
||||
@"icmp ugt",
|
||||
@"icmp ule",
|
||||
@"icmp ult",
|
||||
indirectbr,
|
||||
insertelement,
|
||||
insertvalue,
|
||||
inttoptr,
|
||||
@@ -4367,6 +4368,7 @@ pub const Function = struct {
|
||||
return switch (wip.instructions.items(.tag)[@intFromEnum(self)]) {
|
||||
.br,
|
||||
.br_cond,
|
||||
.indirectbr,
|
||||
.ret,
|
||||
.@"ret void",
|
||||
.@"switch",
|
||||
@@ -4381,6 +4383,7 @@ pub const Function = struct {
|
||||
.br,
|
||||
.br_cond,
|
||||
.fence,
|
||||
.indirectbr,
|
||||
.ret,
|
||||
.@"ret void",
|
||||
.store,
|
||||
@@ -4471,6 +4474,7 @@ pub const Function = struct {
|
||||
.br,
|
||||
.br_cond,
|
||||
.fence,
|
||||
.indirectbr,
|
||||
.ret,
|
||||
.@"ret void",
|
||||
.store,
|
||||
@@ -4657,6 +4661,7 @@ pub const Function = struct {
|
||||
.br,
|
||||
.br_cond,
|
||||
.fence,
|
||||
.indirectbr,
|
||||
.ret,
|
||||
.@"ret void",
|
||||
.store,
|
||||
@@ -4837,6 +4842,12 @@ pub const Function = struct {
|
||||
//case_blocks: [cases_len]Block.Index,
|
||||
};
|
||||
|
||||
pub const IndirectBr = struct {
|
||||
addr: Value,
|
||||
targets_len: u32,
|
||||
//targets: [targets_len]Block.Index,
|
||||
};
|
||||
|
||||
pub const Binary = struct {
|
||||
lhs: Value,
|
||||
rhs: Value,
|
||||
@@ -5294,10 +5305,27 @@ pub const WipFunction = struct {
|
||||
return .{ .index = 0, .instruction = instruction };
|
||||
}
|
||||
|
||||
pub fn indirectbr(
|
||||
self: *WipFunction,
|
||||
addr: Value,
|
||||
targets: []const Block.Index,
|
||||
) Allocator.Error!Instruction.Index {
|
||||
try self.ensureUnusedExtraCapacity(1, Instruction.IndirectBr, targets.len);
|
||||
const instruction = try self.addInst(null, .{
|
||||
.tag = .indirectbr,
|
||||
.data = self.addExtraAssumeCapacity(Instruction.IndirectBr{
|
||||
.addr = addr,
|
||||
.targets_len = @intCast(targets.len),
|
||||
}),
|
||||
});
|
||||
_ = self.extra.appendSliceAssumeCapacity(@ptrCast(targets));
|
||||
for (targets) |target| target.ptr(self).branches += 1;
|
||||
return instruction;
|
||||
}
|
||||
|
||||
pub fn @"unreachable"(self: *WipFunction) Allocator.Error!Instruction.Index {
|
||||
try self.ensureUnusedExtraCapacity(1, NoExtra, 0);
|
||||
const instruction = try self.addInst(null, .{ .tag = .@"unreachable", .data = undefined });
|
||||
return instruction;
|
||||
return try self.addInst(null, .{ .tag = .@"unreachable", .data = undefined });
|
||||
}
|
||||
|
||||
pub fn un(
|
||||
@@ -6299,8 +6327,7 @@ pub const WipFunction = struct {
|
||||
});
|
||||
names[@intFromEnum(new_block_index)] = try wip_name.map(current_block.name, "");
|
||||
for (current_block.instructions.items) |old_instruction_index| {
|
||||
const new_instruction_index: Instruction.Index =
|
||||
@enumFromInt(function.instructions.len);
|
||||
const new_instruction_index: Instruction.Index = @enumFromInt(function.instructions.len);
|
||||
var instruction = self.instructions.get(@intFromEnum(old_instruction_index));
|
||||
switch (instruction.tag) {
|
||||
.add,
|
||||
@@ -6509,6 +6536,15 @@ pub const WipFunction = struct {
|
||||
});
|
||||
wip_extra.appendMappedValues(indices, instructions);
|
||||
},
|
||||
.indirectbr => {
|
||||
var extra = self.extraDataTrail(Instruction.IndirectBr, instruction.data);
|
||||
const targets = extra.trail.next(extra.data.targets_len, Block.Index, self);
|
||||
instruction.data = wip_extra.addExtra(Instruction.IndirectBr{
|
||||
.addr = instructions.map(extra.data.addr),
|
||||
.targets_len = extra.data.targets_len,
|
||||
});
|
||||
wip_extra.appendSlice(targets);
|
||||
},
|
||||
.insertelement => {
|
||||
const extra = self.extraData(Instruction.InsertElement, instruction.data);
|
||||
instruction.data = wip_extra.addExtra(Instruction.InsertElement{
|
||||
@@ -7555,10 +7591,10 @@ pub const Constant = enum(u32) {
|
||||
.blockaddress => |tag| {
|
||||
const extra = data.builder.constantExtraData(BlockAddress, item.data);
|
||||
const function = extra.function.ptrConst(data.builder);
|
||||
try writer.print("{s}({}, %{d})", .{
|
||||
try writer.print("{s}({}, {})", .{
|
||||
@tagName(tag),
|
||||
function.global.fmt(data.builder),
|
||||
@intFromEnum(extra.block), // TODO
|
||||
extra.block.toInst(function).fmt(extra.function, data.builder),
|
||||
});
|
||||
},
|
||||
.dso_local_equivalent,
|
||||
@@ -9902,6 +9938,23 @@ pub fn printUnbuffered(
|
||||
index.fmt(function_index, self),
|
||||
});
|
||||
},
|
||||
.indirectbr => |tag| {
|
||||
var extra =
|
||||
function.extraDataTrail(Function.Instruction.IndirectBr, instruction.data);
|
||||
const targets =
|
||||
extra.trail.next(extra.data.targets_len, Function.Block.Index, &function);
|
||||
try writer.print(" {s} {%}, [", .{
|
||||
@tagName(tag),
|
||||
extra.data.addr.fmt(function_index, self),
|
||||
});
|
||||
for (0.., targets) |target_index, target| {
|
||||
if (target_index > 0) try writer.writeAll(", ");
|
||||
try writer.print("{%}", .{
|
||||
target.toInst(&function).fmt(function_index, self),
|
||||
});
|
||||
}
|
||||
try writer.writeByte(']');
|
||||
},
|
||||
.insertelement => |tag| {
|
||||
const extra =
|
||||
function.extraData(Function.Instruction.InsertElement, instruction.data);
|
||||
@@ -14777,15 +14830,6 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co
|
||||
.indices = indices,
|
||||
});
|
||||
},
|
||||
.insertvalue => {
|
||||
var extra = func.extraDataTrail(Function.Instruction.InsertValue, data);
|
||||
const indices = extra.trail.next(extra.data.indices_len, u32, &func);
|
||||
try function_block.writeAbbrev(FunctionBlock.InsertValue{
|
||||
.val = adapter.getOffsetValueIndex(extra.data.val),
|
||||
.elem = adapter.getOffsetValueIndex(extra.data.elem),
|
||||
.indices = indices,
|
||||
});
|
||||
},
|
||||
.extractelement => {
|
||||
const extra = func.extraData(Function.Instruction.ExtractElement, data);
|
||||
try function_block.writeAbbrev(FunctionBlock.ExtractElement{
|
||||
@@ -14793,6 +14837,20 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co
|
||||
.index = adapter.getOffsetValueIndex(extra.index),
|
||||
});
|
||||
},
|
||||
.indirectbr => {
|
||||
var extra =
|
||||
func.extraDataTrail(Function.Instruction.IndirectBr, datas[instr_index]);
|
||||
const targets =
|
||||
extra.trail.next(extra.data.targets_len, Function.Block.Index, &func);
|
||||
try function_block.writeAbbrevAdapted(
|
||||
FunctionBlock.IndirectBr{
|
||||
.ty = extra.data.addr.typeOf(@enumFromInt(func_index), self),
|
||||
.addr = extra.data.addr,
|
||||
.targets = targets,
|
||||
},
|
||||
adapter,
|
||||
);
|
||||
},
|
||||
.insertelement => {
|
||||
const extra = func.extraData(Function.Instruction.InsertElement, data);
|
||||
try function_block.writeAbbrev(FunctionBlock.InsertElement{
|
||||
@@ -14801,6 +14859,15 @@ pub fn toBitcode(self: *Builder, allocator: Allocator) bitcode_writer.Error![]co
|
||||
.index = adapter.getOffsetValueIndex(extra.index),
|
||||
});
|
||||
},
|
||||
.insertvalue => {
|
||||
var extra = func.extraDataTrail(Function.Instruction.InsertValue, datas[instr_index]);
|
||||
const indices = extra.trail.next(extra.data.indices_len, u32, &func);
|
||||
try function_block.writeAbbrev(FunctionBlock.InsertValue{
|
||||
.val = adapter.getOffsetValueIndex(extra.data.val),
|
||||
.elem = adapter.getOffsetValueIndex(extra.data.elem),
|
||||
.indices = indices,
|
||||
});
|
||||
},
|
||||
.select => {
|
||||
const extra = func.extraData(Function.Instruction.Select, data);
|
||||
try function_block.writeAbbrev(FunctionBlock.Select{
|
||||
|
||||
@@ -19,6 +19,7 @@ const LineAbbrev = AbbrevOp{ .vbr = 8 };
|
||||
const ColumnAbbrev = AbbrevOp{ .vbr = 8 };
|
||||
|
||||
const BlockAbbrev = AbbrevOp{ .vbr = 6 };
|
||||
const BlockArrayAbbrev = AbbrevOp{ .array_vbr = 6 };
|
||||
|
||||
/// Unused tags are commented out so that they are omitted in the generated
|
||||
/// bitcode, which scans over this enum using reflection.
|
||||
@@ -1294,6 +1295,7 @@ pub const FunctionBlock = struct {
|
||||
DebugLoc,
|
||||
DebugLocAgain,
|
||||
ColdOperandBundle,
|
||||
IndirectBr,
|
||||
};
|
||||
|
||||
pub const DeclareBlocks = struct {
|
||||
@@ -1813,6 +1815,18 @@ pub const FunctionBlock = struct {
|
||||
.{ .literal = 0 },
|
||||
};
|
||||
};
|
||||
|
||||
pub const IndirectBr = struct {
|
||||
pub const ops = [_]AbbrevOp{
|
||||
.{ .literal = 31 },
|
||||
.{ .fixed_runtime = Builder.Type },
|
||||
ValueAbbrev,
|
||||
BlockArrayAbbrev,
|
||||
};
|
||||
ty: Builder.Type,
|
||||
addr: Builder.Value,
|
||||
targets: []const Builder.Function.Block.Index,
|
||||
};
|
||||
};
|
||||
|
||||
pub const FunctionValueSymbolTable = struct {
|
||||
|
||||
Reference in New Issue
Block a user