From e1d8073d2fc0df6fbc5ce983312e3da374a9889b Mon Sep 17 00:00:00 2001 From: Timon Kruiper Date: Sun, 10 Jan 2021 17:36:01 +0100 Subject: stage2: add support for loops in LLVM backend A simple `while(true) {}` loop generates the following LLVMIR: ``` define i32 @main() { Entry: br label %Loop Loop: ; preds = %Loop, %Entry br label %Loop } ``` Also implement TZIR printing for loops and add a corresponding test. --- src/codegen/llvm.zig | 12 ++++++++++++ src/zir.zig | 21 +++++++++++++++++++-- 2 files changed, 31 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/codegen/llvm.zig b/src/codegen/llvm.zig index d6515f9ec6..5d753c41cb 100644 --- a/src/codegen/llvm.zig +++ b/src/codegen/llvm.zig @@ -396,6 +396,7 @@ pub const LLVMIRModule = struct { .condbr => try self.genCondBr(inst.castTag(.condbr).?), .intcast => try self.genIntCast(inst.castTag(.intcast).?), .load => try self.genLoad(inst.castTag(.load).?), + .loop => try self.genLoop(inst.castTag(.loop).?), .not => try self.genNot(inst.castTag(.not).?), .ret => try self.genRet(inst.castTag(.ret).?), .retvoid => self.genRetVoid(inst.castTag(.retvoid).?), @@ -559,6 +560,17 @@ pub const LLVMIRModule = struct { return null; } + fn genLoop(self: *LLVMIRModule, inst: *Inst.Loop) !?*const llvm.Value { + const loop_block = self.context.appendBasicBlock(self.llvm_func, "Loop"); + _ = self.builder.buildBr(loop_block); + + self.builder.positionBuilderAtEnd(loop_block); + try self.genBody(inst.body); + + _ = self.builder.buildBr(loop_block); + return null; + } + fn genNot(self: *LLVMIRModule, inst: *Inst.UnOp) !?*const llvm.Value { return self.builder.buildNot(try self.resolveInst(inst.operand), ""); } diff --git a/src/zir.zig b/src/zir.zig index 4aee20991c..8d99218b3d 100644 --- a/src/zir.zig +++ b/src/zir.zig @@ -2011,11 +2011,15 @@ const DumpTzir = struct { try dtz.fetchInstsAndResolveConsts(condbr.else_body); }, + .loop => { + const loop = inst.castTag(.loop).?; + try dtz.fetchInstsAndResolveConsts(loop.body); + }, + // TODO fill out this debug printing .assembly, .call, .constant, - .loop, .varptr, .switchbr, => {}, @@ -2229,11 +2233,24 @@ const DumpTzir = struct { try writer.writeAll(")\n"); }, + .loop => { + const loop = inst.castTag(.loop).?; + + try writer.writeAll("\n"); + + const old_indent = dtz.indent; + dtz.indent += 2; + try dtz.dumpBody(loop.body, writer); + dtz.indent = old_indent; + + try writer.writeByteNTimes(' ', dtz.indent); + try writer.writeAll(")\n"); + }, + // TODO fill out this debug printing .assembly, .call, .constant, - .loop, .varptr, .switchbr, => { -- cgit v1.2.3