Skip to content

Commit

Permalink
move std to func
Browse files Browse the repository at this point in the history
  • Loading branch information
webmiche committed Mar 23, 2022
1 parent 3980220 commit bcd9595
Show file tree
Hide file tree
Showing 16 changed files with 169 additions and 151 deletions.
22 changes: 21 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,26 @@
# xDSL

TODO
## Testing

xDSL includes pytest unit test and llvm-style filecheck tests. They can be executed using to following commands from within the root directory of the project:

```
# Executes pytests which are located in tests/
pytest
# Executes filecheck tests
lit test/filecheck
```

## Generating executables through MLIR

xDSL can generate executables using MLIR as the backend. To use this functionality, make sure to install the [MLIR Python Bindings](https://mlir.llvm.org/docs/Bindings/Python/). Given an input file `input.xdsl`, that contains IR with only the mirrored dialects found in `src/xdsl/dialects` (arith, memref, func, cf, scf, and builtin), run:

```
mlir-opt --convert-scf-to-cf --convert-cf-to-llvm --convert-func-to-llvm --convert-arith-to-llvm --convert-memref-to-llvm --reconcile-unrealized-casts *input.xdsl* | mlir-translate --mlir-to-llvmir > tmp.ll
```

The generated `tmp.ll` file contains LLVMIR, so it can be directly passed to a compiler like clang.

## Prerequisits

Expand Down
40 changes: 0 additions & 40 deletions src/xdsl/dialects/builtin.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ def __post_init__(self):
self.ctx.register_attr(IndexType)

self.ctx.register_op(ModuleOp)
self.ctx.register_op(FuncOp)


@irdl_attr_definition
Expand Down Expand Up @@ -344,45 +343,6 @@ def from_attrs(inputs: ArrayAttr, outputs: ArrayAttr) -> Attribute:
return FunctionType([inputs, outputs])


@irdl_op_definition
class FuncOp(Operation):
name: str = "builtin.func"

body = RegionDef()
sym_name = AttributeDef(StringAttr)
type = AttributeDef(FunctionType)
sym_visibility = AttributeDef(StringAttr)

@staticmethod
def from_callable(
name: str, input_types: List[Attribute],
return_types: List[Attribute],
func: Callable[[BlockArgument, ...], List[Operation]]) -> FuncOp:
type_attr = FunctionType.from_lists(input_types, return_types)
op = FuncOp.build(attributes={
"sym_name": name,
"type": type_attr,
"sym_visibility": "private"
},
regions=[
Region.from_block_list(
[Block.from_callable(input_types, func)])
])
return op

@staticmethod
def from_region(name: str, input_types: List[Attribute],
return_types: List[Attribute], region: Region) -> FuncOp:
type_attr = FunctionType.from_lists(input_types, return_types)
op = FuncOp.build(attributes={
"sym_name": name,
"type": type_attr,
"sym_visibility": "private"
},
regions=[region])
return op


@irdl_op_definition
class ModuleOp(Operation):
name: str = "module"
Expand Down
84 changes: 84 additions & 0 deletions src/xdsl/dialects/func.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
from __future__ import annotations
from dataclasses import dataclass

from xdsl.irdl import *
from xdsl.ir import *
from xdsl.dialects.builtin import *


@dataclass
class Func:
ctx: MLContext

def __post_init__(self):
self.ctx.register_op(FuncOp)
self.ctx.register_op(Call)
self.ctx.register_op(Return)


@irdl_op_definition
class FuncOp(Operation):
name: str = "func.func"

body = RegionDef()
sym_name = AttributeDef(StringAttr)
function_type = AttributeDef(FunctionType)
sym_visibility = AttributeDef(StringAttr)

@staticmethod
def from_callable(
name: str, input_types: List[Attribute],
return_types: List[Attribute],
func: Callable[[BlockArgument, ...], List[Operation]]) -> FuncOp:
type_attr = FunctionType.from_lists(input_types, return_types)
op = FuncOp.build(attributes={
"sym_name": name,
"function_type": type_attr,
"sym_visibility": "private"
},
regions=[
Region.from_block_list(
[Block.from_callable(input_types, func)])
])
return op

@staticmethod
def from_region(name: str, input_types: List[Attribute],
return_types: List[Attribute], region: Region) -> FuncOp:
type_attr = FunctionType.from_lists(input_types, return_types)
op = FuncOp.build(attributes={
"sym_name": name,
"function_type": type_attr,
"sym_visibility": "private"
},
regions=[region])
return op


@irdl_op_definition
class Call(Operation):
name: str = "func.call"
arguments = VarOperandDef(AnyAttr())
callee = AttributeDef(FlatSymbolRefAttr)

# Note: naming this results triggers an ArgumentError
res = VarResultDef(AnyAttr())
# TODO how do we verify that the types are correct?

@staticmethod
def get(callee: Union[str, FlatSymbolRefAttr],
operands: List[Union[SSAValue, Operation]],
return_types: List[Attribute]) -> Call:
return Call.build(operands=operands,
result_types=return_types,
attributes={"callee": callee})


@irdl_op_definition
class Return(Operation):
name: str = "func.return"
arguments = VarOperandDef(AnyAttr())

@staticmethod
def get(*ops: Union[Operation, SSAValue]) -> Return:
return Return.build(operands=[[op for op in ops]])
43 changes: 0 additions & 43 deletions src/xdsl/dialects/std.py

This file was deleted.

4 changes: 2 additions & 2 deletions src/xdsl/xdsl_opt.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from xdsl.ir import *
from xdsl.parser import *
from xdsl.printer import *
from xdsl.dialects.std import *
from xdsl.dialects.func import *
from xdsl.dialects.scf import *
from xdsl.dialects.arith import *
from xdsl.dialects.affine import *
Expand All @@ -22,7 +22,7 @@
def __main__(input_str: str):
ctx = MLContext()
builtin = Builtin(ctx)
std = Std(ctx)
func = Func(ctx)
arith = Arith(ctx)
affine = Affine(ctx)
scf = Scf(ctx)
Expand Down
6 changes: 3 additions & 3 deletions tests/affine_test.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
from xdsl.dialects.builtin import *
from xdsl.dialects.std import *
from xdsl.dialects.func import *
from xdsl.dialects.arith import *
from xdsl.printer import Printer
from xdsl.dialects.affine import *


def get_example_affine_program(ctx: MLContext, builtin: Builtin, std: Std,
def get_example_affine_program(ctx: MLContext, builtin: Builtin, func: Func,
affine: Affine) -> Operation:

def affine_mm(arg0: BlockArgument, arg1: BlockArgument,
Expand Down Expand Up @@ -35,7 +35,7 @@ def affine_mm(arg0: BlockArgument, arg1: BlockArgument,
def test_affine():
ctx = MLContext()
builtin = Builtin(ctx)
std = Std(ctx)
std = Func(ctx)
arith = Arith(ctx)
affine = Affine(ctx)

Expand Down
30 changes: 15 additions & 15 deletions tests/cf_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
from xdsl.parser import Parser
from xdsl.printer import Printer
from xdsl.dialects.cf import *
from xdsl.dialects.std import *
from xdsl.dialects.func import *
from xdsl.dialects.arith import *


def get_example_cf_program_unconditional_noargs(ctx: MLContext, std: Std,
def get_example_cf_program_unconditional_noargs(ctx: MLContext, func: Func,
cf: Cf) -> (Operation, str):

a = Block()
Expand All @@ -20,7 +20,7 @@ def get_example_cf_program_unconditional_noargs(ctx: MLContext, std: Std,
f = FuncOp.from_region("test", [], [], [a, b])

prog = """
builtin.func() ["sym_name" = "test", "type" = !fun<[], []>, "sym_visibility" = "private"] {
func.func() ["sym_name" = "test", "function_type" = !fun<[], []>, "sym_visibility" = "private"] {
^0:
cf.br() (^1)
^1:
Expand All @@ -30,7 +30,7 @@ def get_example_cf_program_unconditional_noargs(ctx: MLContext, std: Std,
return f, prog


def get_example_cf_program_unconditional_args(ctx: MLContext, std: Std,
def get_example_cf_program_unconditional_args(ctx: MLContext, func: Func,
cf: Cf) -> (Operation, str):

a = Block.from_arg_types([IntegerType.from_width(32)])
Expand All @@ -42,7 +42,7 @@ def get_example_cf_program_unconditional_args(ctx: MLContext, std: Std,
f = FuncOp.from_region("test", [], [], [a, b])

prog = """
builtin.func() ["sym_name" = "test", "type" = !fun<[], []>, "sym_visibility" = "private"] {
func.func() ["sym_name" = "test", "function_type" = !fun<[], []>, "sym_visibility" = "private"] {
^0(%0 : !i32):
cf.br(%0 : !i32) (^1)
^1(%1 : !i32):
Expand All @@ -52,7 +52,7 @@ def get_example_cf_program_unconditional_args(ctx: MLContext, std: Std,
return f, prog


def get_example_cf_program_conditional_args(ctx: MLContext, std: Std,
def get_example_cf_program_conditional_args(ctx: MLContext, func: Func,
cf: Cf) -> (Operation, str):

a = Block.from_arg_types([IntegerType.from_width(32)])
Expand All @@ -67,7 +67,7 @@ def get_example_cf_program_conditional_args(ctx: MLContext, std: Std,
f = FuncOp.from_region("test", [], [], [a, b])

prog = """
builtin.func() ["sym_name" = "test", "type" = !fun<[], []>, "sym_visibility" = "private"] {
func.func() ["sym_name" = "test", "function_type" = !fun<[], []>, "sym_visibility" = "private"] {
^0(%0 : !i32):
cf.br(%0 : !i32) (^1)
^1(%1 : !i32):
Expand All @@ -80,10 +80,10 @@ def get_example_cf_program_conditional_args(ctx: MLContext, std: Std,

def test_get():
ctx = MLContext()
std = Std(ctx)
func = Func(ctx)
cf = Cf(ctx)

f, prog = get_example_cf_program_unconditional_noargs(ctx, std, cf)
f, prog = get_example_cf_program_unconditional_noargs(ctx, func, cf)

f.verify()

Expand All @@ -92,15 +92,15 @@ def test_get():
printer.print_op(f)
assert file.getvalue().strip() == prog.strip()

f, prog = get_example_cf_program_unconditional_args(ctx, std, cf)
f, prog = get_example_cf_program_unconditional_args(ctx, func, cf)

f.verify()
file = StringIO("")
printer = Printer(stream=file)
printer.print_op(f)
assert file.getvalue().strip() == prog.strip()

f, prog = get_example_cf_program_conditional_args(ctx, std, cf)
f, prog = get_example_cf_program_conditional_args(ctx, func, cf)

f.verify()
printer = Printer()
Expand All @@ -113,18 +113,18 @@ def test_get():

test_prog = """
module() {
builtin.func() ["sym_name" = "br", "type" = !fun<[!i32], [!i32]>, "sym_visibility" = "private"]
func.func() ["sym_name" = "br", "function_type" = !fun<[!i32], [!i32]>, "sym_visibility" = "private"]
{
^2(%22: !i32):
cf.br(%22: !i32)(^2)
}
builtin.func() ["sym_name" = "cond_br", "type" = !fun<[!i32], [!i32]>, "sym_visibility" = "private"]
func.func() ["sym_name" = "cond_br", "function_type" = !fun<[!i32], [!i32]>, "sym_visibility" = "private"]
{
^3(%cond : !i1, %arg: !i32):
cf.cond_br(%cond: !i1, %cond: !i1, %arg : !i32, %arg : !i32, %arg : !i32, %arg : !i32)(^3, ^4) ["operand_segment_sizes" = !dense<!vector<[2 : !i64], !i32>, [2 : !i32, 3 : !i32]>]
^4(%24 : !i32, %25 : !i32, %26 : !i32):
std.return(%24 : !i32)
func.return(%24 : !i32)
}
}
"""
Expand All @@ -134,7 +134,7 @@ def test_main():
ctx = MLContext()
builtin = Builtin(ctx)
cf = Cf(ctx)
std = Std(ctx)
func = Func(ctx)

parser = Parser(ctx, test_prog)
module = parser.parse_op()
Expand Down
4 changes: 2 additions & 2 deletions tests/filecheck/arith_ops.test
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// RUN: ../../src/xdsl/xdsl_opt.py -f %s | ../../src/xdsl/xdsl_opt.py | filecheck %s

module() {
builtin.func() ["sym_name" = "test", "type" = !fun<[], []>, "sym_visibility" = "private"]{
func.func() ["sym_name" = "test", "function_type" = !fun<[], []>, "sym_visibility" = "private"]{
%0 : !i32 = arith.constant() ["value" = 42 : !i32]
%1 : !i32 = arith.constant() ["value" = 42 : !i32]
%2 : !i32 = arith.addi(%0 : !i32, %1 : !i32)
Expand All @@ -12,7 +12,7 @@ module() {
}
}

// CHECK: builtin.func() ["sym_name" = "test"
// CHECK: func.func() ["sym_name" = "test"
// CHECK-NEXT: %{{.*}} : !i32 = arith.constant() ["value" = 42 : !i32]
// CHECK-NEXT: %{{.*}} : !i32 = arith.constant() ["value" = 42 : !i32]
// CHECK-NEXT: %{{.*}} : !i32 = arith.addi(%{{.*}} : !i32, %{{.*}} : !i32)
Expand Down
Loading

0 comments on commit bcd9595

Please sign in to comment.