Sema: more AIR memory layout reworking progress

Additionally: ZIR encoding for floats now supports float literals up to
f64, not only f32. This is because we no longer need a source location
for this instruction.
This commit is contained in:
Andrew Kelley 2021-07-14 19:04:02 -07:00
parent 7bb2d13a09
commit 27be4f3140
5 changed files with 486 additions and 517 deletions

View File

@ -94,6 +94,11 @@ pub const Inst = struct {
bitcast,
/// Uses the `ty_pl` field with payload `Block`.
block,
/// A labeled block of code that loops forever. At the end of the body it is implied
/// to repeat; no explicit "repeat" instruction terminates loop bodies.
/// Result type is always noreturn; no instructions in a block follow this one.
/// Uses the `ty_pl` field. Payload is `Block`.
loop,
/// Return from a block with a result.
/// Result type is always noreturn; no instructions in a block follow this one.
/// Uses the `br` field.
@ -181,11 +186,6 @@ pub const Inst = struct {
/// Read a value from a pointer.
/// Uses the `ty_op` field.
load,
/// A labeled block of code that loops forever. At the end of the body it is implied
/// to repeat; no explicit "repeat" instruction terminates loop bodies.
/// Result type is always noreturn; no instructions in a block follow this one.
/// Uses the `ty_pl` field. Payload is `Block`.
loop,
/// Converts a pointer to its address. Result type is always `usize`.
/// Uses the `un_op` field.
ptrtoint,
@ -279,6 +279,7 @@ pub const Inst = struct {
/// this union. `Tag` determines which union field is active, as well as
/// how to interpret the data within.
pub const Data = union {
no_op: void,
un_op: Ref,
bin_op: struct {
lhs: Ref,

View File

@ -6589,12 +6589,12 @@ fn floatLiteral(gz: *GenZir, rl: ResultLoc, node: ast.Node.Index) InnerError!Zir
} else std.fmt.parseFloat(f128, bytes) catch |err| switch (err) {
error.InvalidCharacter => unreachable, // validated by tokenizer
};
// If the value fits into a f32 without losing any precision, store it that way.
// If the value fits into a f64 without losing any precision, store it that way.
@setFloatMode(.Strict);
const smaller_float = @floatCast(f32, float_number);
const smaller_float = @floatCast(f64, float_number);
const bigger_again: f128 = smaller_float;
if (bigger_again == float_number) {
const result = try gz.addFloat(smaller_float, node);
const result = try gz.addFloat(smaller_float);
return rvalue(gz, rl, result, node);
}
// We need to use 128 bits. Break the float into 4 u32 values so we can
@ -9145,13 +9145,10 @@ const GenZir = struct {
return indexToRef(new_index);
}
fn addFloat(gz: *GenZir, number: f32, src_node: ast.Node.Index) !Zir.Inst.Ref {
fn addFloat(gz: *GenZir, number: f64) !Zir.Inst.Ref {
return gz.add(.{
.tag = .float,
.data = .{ .float = .{
.src_node = gz.nodeIndexToRelative(src_node),
.number = number,
} },
.data = .{ .float = number },
});
}

View File

@ -1226,6 +1226,17 @@ pub const Scope = struct {
return block.src_decl.namespace.file_scope;
}
pub fn addTy(
block: *Block,
tag: Air.Inst.Tag,
ty: Type,
) error{OutOfMemory}!Air.Inst.Ref {
return block.addInst(.{
.tag = tag,
.data = .{ .ty = ty },
});
}
pub fn addTyOp(
block: *Block,
tag: Air.Inst.Tag,
@ -1241,6 +1252,13 @@ pub const Scope = struct {
});
}
pub fn addNoOp(block: *Block, tag: Air.Inst.Tag) error{OutOfMemory}!Air.Inst.Ref {
return block.addInst(.{
.tag = tag,
.data = .no_op,
});
}
pub fn addUnOp(
block: *Block,
tag: Air.Inst.Tag,
@ -1252,6 +1270,20 @@ pub const Scope = struct {
});
}
pub fn addBr(
block: *Block,
target_block: Air.Inst.Index,
operand: Air.Inst.Ref,
) error{OutOfMemory}!Air.Inst.Ref {
return block.addInst(.{
.tag = .br,
.data = .{ .br = .{
.block_inst = target_block,
.operand = operand,
} },
});
}
pub fn addBinOp(
block: *Block,
tag: Air.Inst.Tag,

File diff suppressed because it is too large Load Diff

View File

@ -386,7 +386,7 @@ pub const Inst = struct {
int,
/// Arbitrary sized integer literal. Uses the `str` union field.
int_big,
/// A float literal that fits in a f32. Uses the float union value.
/// A float literal that fits in a f64. Uses the float union value.
float,
/// A float literal that fits in a f128. Uses the `pl_node` union value.
/// Payload is `Float128`.
@ -2058,16 +2058,7 @@ pub const Inst = struct {
/// Offset from Decl AST node index.
node: i32,
int: u64,
float: struct {
/// Offset from Decl AST node index.
/// `Tag` determines which kind of AST node this points to.
src_node: i32,
number: f32,
pub fn src(self: @This()) LazySrcLoc {
return .{ .node_offset = self.src_node };
}
},
float: f64,
array_type_sentinel: struct {
len: Ref,
/// index into extra, points to an `ArrayTypeSentinel`
@ -3256,10 +3247,8 @@ const Writer = struct {
}
fn writeFloat(self: *Writer, stream: anytype, inst: Inst.Index) !void {
const inst_data = self.code.instructions.items(.data)[inst].float;
const src = inst_data.src();
try stream.print("{d}) ", .{inst_data.number});
try self.writeSrc(stream, src);
const number = self.code.instructions.items(.data)[inst].float;
try stream.print("{d})", .{number});
}
fn writeFloat128(self: *Writer, stream: anytype, inst: Inst.Index) !void {