The git repo for the project now has a way to encode predicates, which I figured was a good first step towards adding some useful control flow (IF+LOOPS). Specifically, the toy language/compiler now supports the following operators:
- <
- <=
- >
- >=
- EQ
- NE
This list works for any floating point or integer type (including BOOL, which is like “INT1”). I also added AND,OR,XOR (for integer types, including BOOL.) The grammar has a NOT operator, but it’s not implemented in the parser yet.
Here’s a sample program:
My MLIR is:
module {
toy.program {
toy.declare "b" : i1
toy.declare "i1" : i1
toy.declare "l16" : i16
%true = arith.constant true
toy.assign "i1", %true : i1
%c-100_i64 = arith.constant -100 : i64
toy.assign "l16", %c-100_i64 : i64
%0 = toy.load "i1" : i1
%1 = toy.load "l16" : i16
%2 = "toy.less"(%0, %1) : (i1, i16) -> i1
toy.assign "b", %2 : i1
%3 = toy.load "b" : i1
toy.print %3 : i1
%4 = toy.load "i1" : i1
%5 = toy.load "l16" : i16
%6 = "toy.less"(%5, %4) : (i16, i1) -> i1
toy.assign "b", %6 : i1
%7 = toy.load "b" : i1
toy.print %7 : i1
toy.exit
}
}
Here’s the LLVM-IR after lowering:
declare void @__toy_print_f64(double)
declare void @__toy_print_i64(i64)
define i32 @main() !dbg !4 {
%1 = alloca i1, i64 1, align 1, !dbg !8
#dbg_declare(ptr %1, !9, !DIExpression(), !8)
%2 = alloca i1, i64 1, align 1, !dbg !11
#dbg_declare(ptr %2, !12, !DIExpression(), !11)
%3 = alloca i16, i64 1, align 2, !dbg !13
#dbg_declare(ptr %3, !14, !DIExpression(), !13)
store i1 true, ptr %2, align 1, !dbg !16
store i16 -100, ptr %3, align 2, !dbg !17
%4 = load i1, ptr %2, align 1, !dbg !18
%5 = load i16, ptr %3, align 2, !dbg !18
%6 = zext i1 %4 to i16, !dbg !18
%7 = icmp slt i16 %6, %5, !dbg !18
store i1 %7, ptr %1, align 1, !dbg !18
%8 = load i1, ptr %1, align 1, !dbg !19
%9 = zext i1 %8 to i64, !dbg !19
call void @__toy_print_i64(i64 %9), !dbg !19
%10 = load i1, ptr %2, align 1, !dbg !20
%11 = load i16, ptr %3, align 2, !dbg !20
%12 = zext i1 %10 to i16, !dbg !20
%13 = icmp slt i16 %11, %12, !dbg !20
store i1 %13, ptr %1, align 1, !dbg !20
%14 = load i1, ptr %1, align 1, !dbg !21
%15 = zext i1 %14 to i64, !dbg !21
call void @__toy_print_i64(i64 %15), !dbg !21
ret i32 0, !dbg !8
}
I’m going to want to try to refactor the type conversion logic, as what I have now in lowering is pretty clunky.
