enum Index [src]

Fields

none = std.math.maxInt(u31)
_

Members

Source

pub const Index = enum(u32) { none = std.math.maxInt(u31), _, pub fn name(self: Instruction.Index, function: *const Function) String { return function.names[@intFromEnum(self)]; } pub fn valueIndex(self: Instruction.Index, function: *const Function) u32 { return function.value_indices[@intFromEnum(self)]; } pub fn toValue(self: Instruction.Index) Value { return @enumFromInt(@intFromEnum(self)); } pub fn isTerminatorWip(self: Instruction.Index, wip: *const WipFunction) bool { return switch (wip.instructions.items(.tag)[@intFromEnum(self)]) { .br, .br_cond, .indirectbr, .ret, .@"ret void", .@"switch", .@"unreachable", => true, else => false, }; } pub fn hasResultWip(self: Instruction.Index, wip: *const WipFunction) bool { return switch (wip.instructions.items(.tag)[@intFromEnum(self)]) { .br, .br_cond, .fence, .indirectbr, .ret, .@"ret void", .store, .@"store atomic", .@"switch", .@"unreachable", .block, => false, .call, .@"call fast", .@"musttail call", .@"musttail call fast", .@"notail call", .@"notail call fast", .@"tail call", .@"tail call fast", => self.typeOfWip(wip) != .void, else => true, }; } pub fn typeOfWip(self: Instruction.Index, wip: *const WipFunction) Type { const instruction = wip.instructions.get(@intFromEnum(self)); return switch (instruction.tag) { .add, .@"add nsw", .@"add nuw", .@"add nuw nsw", .@"and", .ashr, .@"ashr exact", .fadd, .@"fadd fast", .fdiv, .@"fdiv fast", .fmul, .@"fmul fast", .frem, .@"frem fast", .fsub, .@"fsub fast", .lshr, .@"lshr exact", .mul, .@"mul nsw", .@"mul nuw", .@"mul nuw nsw", .@"or", .sdiv, .@"sdiv exact", .shl, .@"shl nsw", .@"shl nuw", .@"shl nuw nsw", .srem, .sub, .@"sub nsw", .@"sub nuw", .@"sub nuw nsw", .udiv, .@"udiv exact", .urem, .xor, => wip.extraData(Binary, instruction.data).lhs.typeOfWip(wip), .addrspacecast, .bitcast, .fpext, .fptosi, .fptoui, .fptrunc, .inttoptr, .ptrtoint, .sext, .sitofp, .trunc, .uitofp, .zext, => wip.extraData(Cast, instruction.data).type, .alloca, .@"alloca inalloca", => wip.builder.ptrTypeAssumeCapacity( wip.extraData(Alloca, instruction.data).info.addr_space, ), .arg => wip.function.typeOf(wip.builder) .functionParameters(wip.builder)[instruction.data], .atomicrmw => wip.extraData(AtomicRmw, instruction.data).val.typeOfWip(wip), .block => .label, .br, .br_cond, .fence, .indirectbr, .ret, .@"ret void", .store, .@"store atomic", .@"switch", .@"unreachable", => .none, .call, .@"call fast", .@"musttail call", .@"musttail call fast", .@"notail call", .@"notail call fast", .@"tail call", .@"tail call fast", => wip.extraData(Call, instruction.data).ty.functionReturn(wip.builder), .cmpxchg, .@"cmpxchg weak", => wip.builder.structTypeAssumeCapacity(.normal, &.{ wip.extraData(CmpXchg, instruction.data).cmp.typeOfWip(wip), .i1, }), .extractelement => wip.extraData(ExtractElement, instruction.data) .val.typeOfWip(wip).childType(wip.builder), .extractvalue => { var extra = wip.extraDataTrail(ExtractValue, instruction.data); const indices = extra.trail.next(extra.data.indices_len, u32, wip); return extra.data.val.typeOfWip(wip).childTypeAt(indices, wip.builder); }, .@"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", .@"icmp eq", .@"icmp ne", .@"icmp sge", .@"icmp sgt", .@"icmp sle", .@"icmp slt", .@"icmp uge", .@"icmp ugt", .@"icmp ule", .@"icmp ult", => wip.extraData(Binary, instruction.data).lhs.typeOfWip(wip) .changeScalarAssumeCapacity(.i1, wip.builder), .fneg, .@"fneg fast", => @as(Value, @enumFromInt(instruction.data)).typeOfWip(wip), .getelementptr, .@"getelementptr inbounds", => { var extra = wip.extraDataTrail(GetElementPtr, instruction.data); const indices = extra.trail.next(extra.data.indices_len, Value, wip); const base_ty = extra.data.base.typeOfWip(wip); if (!base_ty.isVector(wip.builder)) for (indices) |index| { const index_ty = index.typeOfWip(wip); if (!index_ty.isVector(wip.builder)) continue; return index_ty.changeScalarAssumeCapacity(base_ty, wip.builder); }; return base_ty; }, .insertelement => wip.extraData(InsertElement, instruction.data).val.typeOfWip(wip), .insertvalue => wip.extraData(InsertValue, instruction.data).val.typeOfWip(wip), .load, .@"load atomic", => wip.extraData(Load, instruction.data).type, .phi, .@"phi fast", => wip.extraData(Phi, instruction.data).type, .select, .@"select fast", => wip.extraData(Select, instruction.data).lhs.typeOfWip(wip), .shufflevector => { const extra = wip.extraData(ShuffleVector, instruction.data); return extra.lhs.typeOfWip(wip).changeLengthAssumeCapacity( extra.mask.typeOfWip(wip).vectorLen(wip.builder), wip.builder, ); }, .va_arg => wip.extraData(VaArg, instruction.data).type, }; } pub fn typeOf( self: Instruction.Index, function_index: Function.Index, builder: *Builder, ) Type { const function = function_index.ptrConst(builder); const instruction = function.instructions.get(@intFromEnum(self)); return switch (instruction.tag) { .add, .@"add nsw", .@"add nuw", .@"add nuw nsw", .@"and", .ashr, .@"ashr exact", .fadd, .@"fadd fast", .fdiv, .@"fdiv fast", .fmul, .@"fmul fast", .frem, .@"frem fast", .fsub, .@"fsub fast", .lshr, .@"lshr exact", .mul, .@"mul nsw", .@"mul nuw", .@"mul nuw nsw", .@"or", .sdiv, .@"sdiv exact", .shl, .@"shl nsw", .@"shl nuw", .@"shl nuw nsw", .srem, .sub, .@"sub nsw", .@"sub nuw", .@"sub nuw nsw", .udiv, .@"udiv exact", .urem, .xor, => function.extraData(Binary, instruction.data).lhs.typeOf(function_index, builder), .addrspacecast, .bitcast, .fpext, .fptosi, .fptoui, .fptrunc, .inttoptr, .ptrtoint, .sext, .sitofp, .trunc, .uitofp, .zext, => function.extraData(Cast, instruction.data).type, .alloca, .@"alloca inalloca", => builder.ptrTypeAssumeCapacity( function.extraData(Alloca, instruction.data).info.addr_space, ), .arg => function.global.typeOf(builder) .functionParameters(builder)[instruction.data], .atomicrmw => function.extraData(AtomicRmw, instruction.data) .val.typeOf(function_index, builder), .block => .label, .br, .br_cond, .fence, .indirectbr, .ret, .@"ret void", .store, .@"store atomic", .@"switch", .@"unreachable", => .none, .call, .@"call fast", .@"musttail call", .@"musttail call fast", .@"notail call", .@"notail call fast", .@"tail call", .@"tail call fast", => function.extraData(Call, instruction.data).ty.functionReturn(builder), .cmpxchg, .@"cmpxchg weak", => builder.structTypeAssumeCapacity(.normal, &.{ function.extraData(CmpXchg, instruction.data) .cmp.typeOf(function_index, builder), .i1, }), .extractelement => function.extraData(ExtractElement, instruction.data) .val.typeOf(function_index, builder).childType(builder), .extractvalue => { var extra = function.extraDataTrail(ExtractValue, instruction.data); const indices = extra.trail.next(extra.data.indices_len, u32, function); return extra.data.val.typeOf(function_index, builder) .childTypeAt(indices, builder); }, .@"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", .@"icmp eq", .@"icmp ne", .@"icmp sge", .@"icmp sgt", .@"icmp sle", .@"icmp slt", .@"icmp uge", .@"icmp ugt", .@"icmp ule", .@"icmp ult", => function.extraData(Binary, instruction.data).lhs.typeOf(function_index, builder) .changeScalarAssumeCapacity(.i1, builder), .fneg, .@"fneg fast", => @as(Value, @enumFromInt(instruction.data)).typeOf(function_index, builder), .getelementptr, .@"getelementptr inbounds", => { var extra = function.extraDataTrail(GetElementPtr, instruction.data); const indices = extra.trail.next(extra.data.indices_len, Value, function); const base_ty = extra.data.base.typeOf(function_index, builder); if (!base_ty.isVector(builder)) for (indices) |index| { const index_ty = index.typeOf(function_index, builder); if (!index_ty.isVector(builder)) continue; return index_ty.changeScalarAssumeCapacity(base_ty, builder); }; return base_ty; }, .insertelement => function.extraData(InsertElement, instruction.data) .val.typeOf(function_index, builder), .insertvalue => function.extraData(InsertValue, instruction.data) .val.typeOf(function_index, builder), .load, .@"load atomic", => function.extraData(Load, instruction.data).type, .phi, .@"phi fast", => function.extraData(Phi, instruction.data).type, .select, .@"select fast", => function.extraData(Select, instruction.data).lhs.typeOf(function_index, builder), .shufflevector => { const extra = function.extraData(ShuffleVector, instruction.data); return extra.lhs.typeOf(function_index, builder).changeLengthAssumeCapacity( extra.mask.typeOf(function_index, builder).vectorLen(builder), builder, ); }, .va_arg => function.extraData(VaArg, instruction.data).type, }; } const FormatData = struct { instruction: Instruction.Index, function: Function.Index, builder: *Builder, }; fn format( data: FormatData, comptime fmt_str: []const u8, _: std.fmt.FormatOptions, writer: anytype, ) @TypeOf(writer).Error!void { if (comptime std.mem.indexOfNone(u8, fmt_str, ", %")) |_| @compileError("invalid format string: '" ++ fmt_str ++ "'"); if (comptime std.mem.indexOfScalar(u8, fmt_str, ',') != null) { if (data.instruction == .none) return; try writer.writeByte(','); } if (comptime std.mem.indexOfScalar(u8, fmt_str, ' ') != null) { if (data.instruction == .none) return; try writer.writeByte(' '); } if (comptime std.mem.indexOfScalar(u8, fmt_str, '%') != null) try writer.print( "{%} ", .{data.instruction.typeOf(data.function, data.builder).fmt(data.builder)}, ); assert(data.instruction != .none); try writer.print("%{}", .{ data.instruction.name(data.function.ptrConst(data.builder)).fmt(data.builder), }); } pub fn fmt( self: Instruction.Index, function: Function.Index, builder: *Builder, ) std.fmt.Formatter(format) { return .{ .data = .{ .instruction = self, .function = function, .builder = builder } }; } }