stage2: register allocator processes operand deaths

also rework the IR data structures
This commit is contained in:
Andrew Kelley
2020-07-20 13:11:07 -07:00
parent a8065a05a5
commit ef91b11295
8 changed files with 708 additions and 527 deletions

View File

@@ -92,9 +92,9 @@ fn genFn(file: *C, decl: *Decl) !void {
for (instructions) |inst| {
try writer.writeAll("\n\t");
switch (inst.tag) {
.assembly => try genAsm(file, inst.cast(Inst.Assembly).?, decl),
.call => try genCall(file, inst.cast(Inst.Call).?, decl),
.ret => try genRet(file, inst.cast(Inst.Ret).?, decl, tv.ty.fnReturnType()),
.assembly => try genAsm(file, inst.castTag(.assembly).?, decl),
.call => try genCall(file, inst.castTag(.call).?, decl),
.ret => try genRet(file, inst.castTag(.ret).?, decl, tv.ty.fnReturnType()),
.retvoid => try file.main.writer().print("return;", .{}),
else => |e| return file.fail(decl.src(), "TODO implement C codegen for {}", .{e}),
}
@@ -105,9 +105,9 @@ fn genFn(file: *C, decl: *Decl) !void {
try writer.writeAll("}\n\n");
}
fn genRet(file: *C, inst: *Inst.Ret, decl: *Decl, expected_return_type: Type) !void {
fn genRet(file: *C, inst: *Inst.UnOp, decl: *Decl, expected_return_type: Type) !void {
const writer = file.main.writer();
const ret_value = inst.args.operand;
const ret_value = inst.operand;
const value = ret_value.value().?;
if (expected_return_type.eql(ret_value.ty))
return file.fail(decl.src(), "TODO return {}", .{expected_return_type})
@@ -126,7 +126,7 @@ fn genRet(file: *C, inst: *Inst.Ret, decl: *Decl, expected_return_type: Type) !v
fn genCall(file: *C, inst: *Inst.Call, decl: *Decl) !void {
const writer = file.main.writer();
const header = file.header.writer();
if (inst.args.func.cast(Inst.Constant)) |func_inst| {
if (inst.func.castTag(.constant)) |func_inst| {
if (func_inst.val.cast(Value.Payload.Function)) |func_val| {
const target = func_val.func.owner_decl;
const target_ty = target.typed_value.most_recent.typed_value.ty;
@@ -144,7 +144,7 @@ fn genCall(file: *C, inst: *Inst.Call, decl: *Decl) !void {
} else {
return file.fail(decl.src(), "TODO non-function call target?", .{});
}
if (inst.args.args.len != 0) {
if (inst.args.len != 0) {
return file.fail(decl.src(), "TODO function arguments", .{});
}
} else {
@@ -152,14 +152,13 @@ fn genCall(file: *C, inst: *Inst.Call, decl: *Decl) !void {
}
}
fn genAsm(file: *C, inst: *Inst.Assembly, decl: *Decl) !void {
const as = inst.args;
fn genAsm(file: *C, as: *Inst.Assembly, decl: *Decl) !void {
const writer = file.main.writer();
for (as.inputs) |i, index| {
if (i[0] == '{' and i[i.len - 1] == '}') {
const reg = i[1 .. i.len - 1];
const arg = as.args[index];
if (arg.cast(Inst.Constant)) |c| {
if (arg.castTag(.constant)) |c| {
if (c.val.tag() == .int_u64) {
try writer.writeAll("register ");
try renderType(file, writer, arg.ty, decl.src());
@@ -190,7 +189,7 @@ fn genAsm(file: *C, inst: *Inst.Assembly, decl: *Decl) !void {
if (index > 0) {
try writer.writeAll(", ");
}
if (arg.cast(Inst.Constant)) |c| {
if (arg.castTag(.constant)) |c| {
try writer.print("\"\"({}_constant)", .{reg});
} else {
// This is blocked by the earlier test