Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dialects: Add print_int, print_char ops. #1311

Merged
merged 28 commits into from
Aug 14, 2023
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
19170eb
dialects: Add print_char operation
JosseVanDelm Jul 17, 2023
19d8ad3
dialects: Add printchar to putchar lowering
JosseVanDelm Jul 18, 2023
79eacec
dialects: Add print_int op
JosseVanDelm Jul 18, 2023
1f2b0d4
dialects: Add initial version of itoa func
JosseVanDelm Jul 20, 2023
1f4e5b7
dialects: Fix algorithm
JosseVanDelm Jul 21, 2023
95eb1d5
Restructure format of itoa
JosseVanDelm Jul 21, 2023
2f1ef88
Extend test for print_char and print_int
JosseVanDelm Jul 21, 2023
8606a35
Working while loop
JosseVanDelm Jul 21, 2023
0048909
dialects: Favor remainder integer division instead of floating point …
JosseVanDelm Jul 24, 2023
52b0fed
printchar: Add from_constant_char constructor
JosseVanDelm Jul 25, 2023
34716ab
Factor out print_minus_if_negative
JosseVanDelm Jul 30, 2023
e901295
printchar: Factor out print_digits
JosseVanDelm Jul 30, 2023
1249a10
Refactor test to use mlir-cpu-runner
JosseVanDelm Jul 30, 2023
5e8086d
arith: Add extuiop
JosseVanDelm Jul 30, 2023
4ca8b69
arith: add TrunciOpw
JosseVanDelm Jul 30, 2023
7e37621
Refactor printchar to use signless bytes
JosseVanDelm Jul 30, 2023
50dc2d4
Address Alban's comments
JosseVanDelm Aug 3, 2023
38877a9
Move printchar test to mlir-interop test folder
JosseVanDelm Aug 3, 2023
efcb6ce
Add mlir-cpu-runner to targets to build
JosseVanDelm Aug 3, 2023
2668ecc
Hack the github actions cache away
JosseVanDelm Aug 3, 2023
ed2adb8
Revert "Hack the github actions cache away"
JosseVanDelm Aug 7, 2023
1f5db45
Revert "Add mlir-cpu-runner to targets to build"
JosseVanDelm Aug 7, 2023
6facd94
dialects: Add constructors and valueerrors
JosseVanDelm Aug 9, 2023
baeb22a
dialects: Add extra checks to and rename to printf_to_putchar
JosseVanDelm Aug 9, 2023
029bf08
dialects: refactor inline_itoa to mlir_itoa
JosseVanDelm Aug 9, 2023
d3ce4d6
dialects: fix lit test and change test name
JosseVanDelm Aug 9, 2023
f8dc0c3
Address Sasha's comments
JosseVanDelm Aug 11, 2023
0ec51de
Address comments
JosseVanDelm Aug 14, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 14 additions & 1 deletion tests/dialects/test_arith.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,6 @@ def test_cmpi_incorrect_comparison():
def test_cmpi_index_type():
a = Constant.from_int_and_width(1, IndexType())
b = Constant.from_int_and_width(2, IndexType())

Cmpi(a, b, "eq").verify()


Expand All @@ -280,3 +279,17 @@ def test_extend_truncate_iops():
assert extu_op.result.type == i64
assert trunc_op.input == b.result
assert trunc_op.result.type == i32


def test_trunci_incorrect_bitwidth():
a = Constant.from_int_and_width(1, 16)
# bitwidth of b has to be smaller than the one of a
with pytest.raises(VerifyException):
_trunci_op = TruncIOp(a, i32).verify()


def test_extui_incorrect_bitwidth():
a = Constant.from_int_and_width(1, 64)
# bitwidth of b has to be larger than the one of a
with pytest.raises(VerifyException):
_extui_op = ExtUIOp(a, i32).verify()
10 changes: 10 additions & 0 deletions tests/dialects/test_printf.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,13 @@ def test_global_symbol_name_generation():
s3 = printf_to_llvm._key_from_str(")") # pyright: ignore[reportPrivateUsage]

assert s2 == s3


def test_printchar_non_ascii():
with pytest.raises(ValueError):
JosseVanDelm marked this conversation as resolved.
Show resolved Hide resolved
print_dialect.PrintCharOp.from_constant_char("🔥")
JosseVanDelm marked this conversation as resolved.
Show resolved Hide resolved


def test_printchar_no_char():
with pytest.raises(ValueError):
print_dialect.PrintCharOp.from_constant_char("This should not work")
9 changes: 9 additions & 0 deletions tests/filecheck/dialects/arith/arith_ops.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"builtin.module"() ({
%lhsi1, %rhsi1 = "test.op"() : () -> (i1, i1)
%lhsi32, %rhsi32 = "test.op"() : () -> (i32, i32)
%lhsi64, %rhsi64 = "test.op"() : () -> (i64, i64)
%lhsindex, %rhsindex = "test.op"() : () -> (index, index)
%lhsf32, %rhsf32 = "test.op"() : () -> (f32, f32)
%lhsf64, %rhsf64 = "test.op"() : () -> (f64, f64)
Expand Down Expand Up @@ -136,10 +137,18 @@

// CHECK-NEXT: %extf = "arith.extf"(%lhsf32) : (f32) -> f64

%extui = "arith.extui"(%lhsi32) : (i32) -> i64

// CHECK-NEXT: %extui = "arith.extui"(%lhsi32) : (i32) -> i64

%truncf = "arith.truncf"(%lhsf64) : (f64) -> f32

// CHECK-NEXT: %truncf = "arith.truncf"(%lhsf64) : (f64) -> f32

%trunci = "arith.trunci"(%lhsi64) : (i64) -> i32

// CHECK-NEXT: %trunci = "arith.trunci"(%lhsi64) : (i64) -> i32

%cmpf = "arith.cmpf"(%lhsf32, %rhsf32) {"predicate" = 2 : i64} : (f32, f32) -> i1

// CHECK-NEXT: %cmpf = "arith.cmpf"(%lhsf32, %rhsf32) {"predicate" = 2 : i64} : (f32, f32) -> i1
Expand Down
7 changes: 6 additions & 1 deletion tests/filecheck/dialects/print/print_basics.mlir
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,21 @@ builtin.module {

%144 = "test.op"() : () -> i32
%12 = "test.op"() : () -> i32
%byte = "test.op"() : () -> i8

printf.print_format "Uses vals twice {} {} {} {}", %12 : i32, %144 : i32, %12 : i32, %144 : i32

printf.print_format "{}", %144 : i32
printf.print_format "{}", %144 : i32 {unit}
"printf.print_char"(%byte) : (i8) -> ()
"printf.print_int"(%12) : (i32) -> ()
}

// CHECK: printf.print_format "Hello world!"
// CHECK-NEXT: %0 = "test.op"() : () -> i32
// CHECK-NEXT: %1 = "test.op"() : () -> i32
// CHECK-NEXT: %byte = "test.op"() : () -> i8
// CHECK-NEXT: printf.print_format "Uses vals twice {} {} {} {}", %1 : i32, %0 : i32, %1 : i32, %0 : i32
// CHECK-NEXT: printf.print_format "{}", %0 : i32
// CHECK-NEXT: printf.print_format "{}", %0 : i32 {"unit"}
// CHECK-NEXT: "printf.print_char"(%{{.*}}) : (i8) -> ()
// CHECK-NEXT: "printf.print_int"(%{{.*}}) : (i32) -> ()
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// RUN: xdsl-opt -p printf-to-putchar %s | mlir-opt --convert-math-to-funcs --test-lower-to-llvm | mlir-cpu-runner --entry-point-result=void | filecheck %s

builtin.module{
"func.func"() ({
%n = arith.constant 110 : i8
%i = arith.constant 105 : i8
%c = arith.constant 99 : i8
%e = arith.constant 101 : i8
%exclamation = arith.constant 33 : i8
%newline = arith.constant 10 : i8
%integer = arith.constant -2147483648: i32

"printf.print_char"(%n) : (i8) -> ()
"printf.print_char"(%i) : (i8) -> ()
"printf.print_char"(%c) : (i8) -> ()
"printf.print_char"(%e) : (i8) -> ()
"printf.print_char"(%exclamation) : (i8) -> ()
"printf.print_char"(%newline) : (i8) -> ()
"printf.print_int"(%integer) : (i32) -> ()
"printf.print_char"(%newline) : (i8) -> ()
"func.return"() : () -> ()
}) {"sym_name" = "main", "function_type" = () -> (), "sym_visibility" = "private"} : () -> ()
}

// CHECK: nice!
// CHECK-NEXT: -2147483648
16 changes: 16 additions & 0 deletions xdsl/dialects/arith.py
Original file line number Diff line number Diff line change
Expand Up @@ -744,6 +744,14 @@ class TruncIOp(IRDLOperation):
def __init__(self, op: SSAValue | Operation, target_type: IntegerType):
return super().__init__(operands=[op], result_types=[target_type])

def verify_(self) -> None:
assert isinstance(self.input.type, IntegerType)
assert isinstance(self.result.type, IntegerType)
if not self.result.type.width.data < self.input.type.width.data:
raise VerifyException(
"Destination bit-width must be smaller than the input bit-width"
)


@irdl_op_definition
class ExtSIOp(IRDLOperation):
Expand All @@ -766,6 +774,14 @@ class ExtUIOp(IRDLOperation):
def __init__(self, op: SSAValue | Operation, target_type: IntegerType):
return super().__init__(operands=[op], result_types=[target_type])

def verify_(self) -> None:
assert isinstance(self.input.type, IntegerType)
assert isinstance(self.result.type, IntegerType)
if not self.result.type.width.data > self.input.type.width.data:
raise VerifyException(
"Destination bit-width must be larger than the input bit-width"
)


Arith = Dialect(
[
Expand Down
57 changes: 53 additions & 4 deletions xdsl/dialects/printf.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
from __future__ import annotations

from xdsl.dialects import builtin
from xdsl.dialects import arith, builtin
from xdsl.ir import Dialect, Operation, SSAValue, VerifyException
from xdsl.irdl import (
IRDLOperation,
Operand,
VarOperand,
attr_def,
irdl_op_definition,
operand_def,
var_operand_def,
)
from xdsl.parser import Parser
from xdsl.printer import Printer

i8 = builtin.IntegerType(8)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure but i8 seems useful to be put in xdsl/dialect/builtin.py?

Copy link
Collaborator Author

@JosseVanDelm JosseVanDelm Aug 11, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also not sure, I don't think it matters that much though, it would save about one line in code



@irdl_op_definition
class PrintFormatOp(IRDLOperation):
Expand Down Expand Up @@ -85,9 +89,54 @@ def parse(cls: type[PrintFormatOp], parser: Parser) -> PrintFormatOp:
return op


@irdl_op_definition
class PrintCharOp(IRDLOperation):
"""
Print a single character

Equivalent to putchar in C, but uses signless bytes as input (instead of ui32).
Unlike the C implementation, this op does not return anything.
"""

name = "printf.print_char"
char: Operand = operand_def(i8)
JosseVanDelm marked this conversation as resolved.
Show resolved Hide resolved

def __init__(self, char: SSAValue | Operation):
super().__init__(
operands=[char],
)

@staticmethod
def from_constant_char(char: str) -> PrintCharOp:
"""
This constructor returns a PrintCharOp that prints the value supplied
in "char" as a python char.
"""
if len(char) != 1:
raise ValueError("Only single characters are supported")
JosseVanDelm marked this conversation as resolved.
Show resolved Hide resolved
ascii_value = ord(char)
if ascii_value > 128:
raise ValueError("Only ascii characters are supported")
char_constant = arith.Constant.from_int_and_width(ascii_value, i8)
return PrintCharOp(char_constant)


@irdl_op_definition
class PrintIntOp(IRDLOperation):
"""
Print a single Integer
"""

name = "printf.print_int"
int: Operand = operand_def(builtin.IntegerType)
JosseVanDelm marked this conversation as resolved.
Show resolved Hide resolved

def __init__(self, integer: SSAValue | Operation):
super().__init__(
operands=[integer],
)


Printf = Dialect(
[
PrintFormatOp,
],
[PrintFormatOp, PrintCharOp, PrintIntOp],
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
[PrintFormatOp, PrintCharOp, PrintIntOp],
[PrintFormatOp, PrintCharOp, PrintIntOp,],

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This would be a useful change to minimise spurious git diffs in the future

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

plz

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, but what do you mean with

to minimise spurious git diffs in the future

?

[],
)
2 changes: 2 additions & 0 deletions xdsl/tools/command_line_tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
lower_snitch_runtime,
mlir_opt,
printf_to_llvm,
printf_to_putchar,
reconcile_unrealized_casts,
riscv_register_allocation,
)
Expand Down Expand Up @@ -105,6 +106,7 @@ def get_all_passes() -> list[type[ModulePass]]:
lower_snitch_runtime.LowerSnitchRuntimePass,
mlir_opt.MLIROptPass,
printf_to_llvm.PrintfToLLVM,
printf_to_putchar.PrintfToPutcharPass,
riscv_register_allocation.RISCVRegisterAllocation,
RISCVLowerArith,
LowerFuncToRiscvFunc,
Expand Down
Loading