Compare commits

...

30 Commits

Author SHA1 Message Date
937dc57c4e tool: validate: resolve op definitions; run test pass 2026-01-19 14:00:25 +00:00
b8c0d139a8 vim: update type and attribute prefixes 2026-01-19 14:00:04 +00:00
abf43a9022 doc: update ir sample files 2026-01-19 13:59:43 +00:00
4700ce7778 build: bump minimum CMake version 2026-01-19 13:59:14 +00:00
95c51045b6 meta: update clang-format config 2026-01-19 13:59:00 +00:00
e62c9c4775 mie: ir: add stub rewriter interface 2026-01-19 13:58:24 +00:00
a97678a1c2 mie: add stub memref dialect 2026-01-19 13:58:12 +00:00
5e13824706 mie: add parent pointers to region and block; two-way link between a register and its users 2026-01-19 13:57:25 +00:00
da140ed0d1 mie: parse: remove duplicate sub-parsers in parse_generic_op 2026-01-19 13:52:21 +00:00
cb3d37043c mie: update b_bstr usage 2026-01-19 13:51:27 +00:00
55161cd6c8 mie: re-implement vectors of blocks and registers using vector move callbacks
vector move callbacks allow mie_name instances to be stored in movable memory,
as the internal bst pointers can now be fixed during vector resize operations.
2026-01-18 22:58:17 +00:00
759aaf9fd8 mie: vector: add copy- and move-constructor support 2026-01-18 21:52:39 +00:00
04af390fe8 mie: pass: add a group of builtin passes
right now, the group only contains a single pass: prefix-func-with-underscore.
this is a test pass that visits instances of func.func and prepends
an underscore to the func's symbol name.
2026-01-18 21:19:15 +00:00
0add39f304 mie: implement a pass system
passes allow defined units of functionality to be applied
on an IR structure. the pass manager can be used to schedule
passes at certain depths of the IR structure and/or on or within
certain types of ops (or ops that have certain traits/interfaces).
2026-01-18 21:17:44 +00:00
429ec770b5 mie: attribute: map: implement REPLACE flag in put() 2026-01-18 21:16:28 +00:00
092c9969cf mie: add NAME_EXISTS status code 2026-01-18 21:16:10 +00:00
6fcc3c8edd mie: ir: op: add functions to query a certain trait or interface 2026-01-18 21:14:50 +00:00
d335cd9823 mie: ir: walk: walk is no longer recursive by default 2026-01-18 20:27:55 +00:00
c014895051 mie: func: add return op 2026-01-17 10:31:52 +00:00
76477be5bd mie: arith: add cmpi and constant ops 2026-01-17 10:31:39 +00:00
ee9e2d3050 mie: arith: implement op printer callbacks 2026-01-17 10:31:08 +00:00
e5ecdd40e8 mie: cf: implement op printer callbacks 2026-01-17 10:29:47 +00:00
c410e0a6e3 mie: builtin: implement op printer callbacks 2026-01-17 10:28:51 +00:00
3ba20e5ed4 mie: print: add more functions to printer interface 2026-01-17 10:27:23 +00:00
f19dfaa050 mie: ctx: fix mie_ctx_resolve_op not checking op-definition pointer properly 2026-01-17 10:26:37 +00:00
2869e98556 mie: builtin: add function to get int/float value from an attribute 2026-01-17 10:25:49 +00:00
b289c6e2de mie: ir: op: add function to get type from mie_op_arg 2026-01-17 10:22:38 +00:00
fd72d217f6 mie: ir: implement a walker interface for traversing ir structures 2026-01-17 10:21:58 +00:00
e1f7f46d3e mie: ir: replace mie_module ir object with a builtin generic "module" op
the builtin.module op behaves exactly like any other op, and is designed
to be a container for other ops of any type. it can be used as the
top-level container for other ops (other top-level containers can be used
instead).

this also changes the file format. now, an ir file can only contain a
single top-level op. any other ops in the ir must be contained
directly or indirectly by this top-level op.
2026-01-16 10:01:19 +00:00
65905bc55b mie: implement support for custom op print formats 2026-01-15 14:20:13 +00:00
86 changed files with 2793 additions and 708 deletions

View File

@@ -1,64 +1,6 @@
BasedOnStyle: WebKit
IndentWidth: 8
---
Language: C
DerivePointerAlignment: false
PointerAlignment: Right
ColumnLimit: 80
AlignAfterOpenBracket: AlwaysBreak
AlignConsecutiveAssignments: None
AlignConsecutiveBitFields: None
AlignConsecutiveDeclarations: None
AlignConsecutiveMacros: AcrossEmptyLinesAndComments
AlignEscapedNewlines: Right
AlignOperands: AlignAfterOperator
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: false
AllowAllConstructorInitializersOnNextLine: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: Empty
AllowShortCaseLabelsOnASingleLine: false
AllowShortEnumsOnASingleLine: false
AllowShortFunctionsOnASingleLine: false
AllowShortIfStatementsOnASingleLine: false
AllowShortLambdasOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: true
BinPackParameters: true
ExperimentalAutoDetectBinPacking: false
BitFieldColonSpacing: Both
BreakBeforeBraces: Linux
BreakBeforeBinaryOperators: All
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeComma
BreakInheritanceList: BeforeComma
BreakStringLiterals: true
ContinuationIndentWidth: 8
Cpp11BracedListStyle: true
IncludeBlocks: Regroup
SortIncludes: true
IndentRequires: true
NamespaceIndentation: Inner
ReflowComments: true
SpacesBeforeTrailingComments: 3
TabWidth: 8
UseTab: AlignWithSpaces
PenaltyReturnTypeOnItsOwnLine: 1000000
PenaltyExcessCharacter: 5
PenaltyBreakOpenParenthesis: 5
PenaltyBreakBeforeFirstCallParameter: 5
PenaltyIndentedWhitespace: 0
AttributeMacros:
- BLUELIB_API
ForEachMacros:
- b_btree_foreach
- b_queue_foreach
MacroBlockBegin: "MIE_.*_BEGIN"
MacroBlockEnd: "MIE_.*_END"
---
Language: Cpp
DerivePointerAlignment: false
PointerAlignment: Right
@@ -114,61 +56,5 @@ AttributeMacros:
ForEachMacros:
- b_btree_foreach
- b_queue_foreach
---
Language: ObjC
DerivePointerAlignment: false
PointerAlignment: Right
ColumnLimit: 80
AlignAfterOpenBracket: AlwaysBreak
AlignConsecutiveAssignments: None
AlignConsecutiveBitFields: None
AlignConsecutiveDeclarations: None
AlignConsecutiveMacros: AcrossEmptyLinesAndComments
AlignEscapedNewlines: Right
AlignOperands: AlignAfterOperator
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: false
AllowAllConstructorInitializersOnNextLine: false
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: Empty
AllowShortCaseLabelsOnASingleLine: false
AllowShortEnumsOnASingleLine: false
AllowShortFunctionsOnASingleLine: false
AllowShortIfStatementsOnASingleLine: false
AllowShortLambdasOnASingleLine: false
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: true
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: true
BinPackParameters: true
ExperimentalAutoDetectBinPacking: false
BitFieldColonSpacing: Both
BreakBeforeBraces: Linux
BreakBeforeBinaryOperators: All
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeComma
BreakInheritanceList: BeforeComma
BreakStringLiterals: true
ContinuationIndentWidth: 8
Cpp11BracedListStyle: true
IncludeBlocks: Regroup
SortIncludes: true
IndentRequires: true
NamespaceIndentation: Inner
ReflowComments: true
SpacesBeforeTrailingComments: 3
TabWidth: 8
UseTab: AlignWithSpaces
PenaltyReturnTypeOnItsOwnLine: 1000000
PenaltyExcessCharacter: 5
PenaltyBreakOpenParenthesis: 5
PenaltyBreakBeforeFirstCallParameter: 5
PenaltyIndentedWhitespace: 0
AttributeMacros:
- BLUELIB_API
ForEachMacros:
- b_btree_foreach
- b_queue_foreach
MacroBlockBegin: "B_TYPE_.*_BEGIN"
MacroBlockEnd: "B_TYPE_.*_END"
MacroBlockBegin: "MIE_.*_BEGIN"
MacroBlockEnd: "MIE_.*_END"

View File

@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.5)
cmake_minimum_required(VERSION 3.14)
project(mie C)
if (WIN32)

View File

@@ -8,15 +8,15 @@ ivy.module {
%cout = ivy.global-ref @cout -> ptr
ivy.class @Person {
%self.name = ivy.object-var @name : #ivy.id -> ptr
%self.age = ivy.object-var @age : #ivy.id -> ptr
%self.val = ivy.object-var @val : #ivy.id -> ptr
%self.__example-property-4 = ivy.object-var @val : #ivy.id -> ptr
%self.__example-property-5 = ivy.object-var @val : #ivy.id -> ptr
%self.name = ivy.object-var @name : !ivy.id -> ptr
%self.age = ivy.object-var @age : !ivy.id -> ptr
%self.val = ivy.object-var @val : !ivy.id -> ptr
%self.__example-property-4 = ivy.object-var @val : !ivy.id -> ptr
%self.__example-property-5 = ivy.object-var @val : !ivy.id -> ptr
ivy.msgh.object init(name:%name, age:%age) -> void {
ptr.store %name, %self.name : #ivy.id, ptr
ptr.store %age, %self.age : #ivy.id, ptr
ptr.store %name, %self.name : !ivy.id, ptr
ptr.store %age, %self.age : !ivy.id, ptr
func.return : ()
}
@@ -24,41 +24,41 @@ ivy.module {
%0 = ivy.string-builder.begin
ivy.string-builder.add %0 << "Received "
ivy.string-builder.add %0 << %data : #ivy.id
ivy.string-builder.add %0 << %data : !ivy.id
ivy.string-builder.add %0 << ", "
ivy.string-builder.add %0 << %extra : #ivy.id
ivy.string-builder.add %0 << %extra : !ivy.id
%1 = ivy.string-builder.end %0 -> #ivy.id
%1 = ivy.string-builder.end %0 -> !ivy.id
%2 = ptr.load %cout : ptr -> #ivy.id
%2 = ptr.load %cout : ptr -> !ivy.id
ivy.msg.send to %2, put:%1 -> void
func.return : ()
}
ivy.msgh.object name -> #ivy.id {
%0 = ptr.load %self.name : ptr -> #ivy.id
func.return %0 : #ivy.id
ivy.msgh.object name -> !ivy.id {
%0 = ptr.load %self.name : ptr -> !ivy.id
func.return %0 : !ivy.id
}
ivy.msgh.object age -> #ivy.id {
%0 = ptr.load %self.age : ptr -> #ivy.id
func.return %0 : #ivy.id
ivy.msgh.object age -> !ivy.id {
%0 = ptr.load %self.age : ptr -> !ivy.id
func.return %0 : !ivy.id
}
ivy.msgh.object age-in-months -> #ivy.id {
%0 = ptr.load %self.age : ptr -> #ivy.id
ivy.msgh.object age-in-months -> !ivy.id {
%0 = ptr.load %self.age : ptr -> !ivy.id
%1 = arith.constant 12 : i32
%multmp = ivy.mul %0, %1 : (#ivy.id, i32) -> #ivy.id
func.return %multmp : #ivy.id
%multmp = ivy.mul %0, %1 : (!ivy.id, i32) -> !ivy.id
func.return %multmp : !ivy.id
}
ivy.msgh.object set-name:%name -> void {
ptr.store %name, %self.name : #ivy.id, ptr
ptr.store %name, %self.name : !ivy.id, ptr
func.return : ()
}
ivy.msgh.object set-age:%age -> void {
ptr.store %age, %self.age : #ivy.id, ptr
ptr.store %age, %self.age : !ivy.id, ptr
func.return : ()
}
@@ -66,28 +66,28 @@ ivy.module {
scf.switch : () -> void
case {
%0 = ivy.atom "years"
%cmptmp.0 = ivy.cmp eq %age, %0 : (#ivy.id, #ivy.atom) -> i1
%cmptmp.0 = ivy.cmp eq %age, %0 : (!ivy.id, !ivy.atom) -> i1
scf.switch-condition %cmptmp.0
} then {
ptr.store %age, %self.age : #ivy.id, ptr
ptr.store %age, %self.age : !ivy.id, ptr
scf.switch-break : ()
} case {
%1 = ivy.atom "months"
%cmptmp.1 = ivy.cmp eq %age, %1 : (#ivy.id, #ivy.atom) -> i1
%cmptmp.1 = ivy.cmp eq %age, %1 : (!ivy.id, !ivy.atom) -> i1
scf.condition %cmptmp.1
} then {
%d0 = arith.constant 12 : i32
%divtmp.0 = ivy.div %age, %d0 : (#ivy.id, i32) -> #ivy.id
ptr.store %divtmp.0, %self.age : #ivy.id, ptr
%divtmp.0 = ivy.div %age, %d0 : (!ivy.id, i32) -> !ivy.id
ptr.store %divtmp.0, %self.age : !ivy.id, ptr
scf.switch-break : ()
} case {
%2 = ivy.atom "days"
%cmptmp.2 = ivy.cmp eq %age, %2 : (#ivy.id, #ivy.atom) -> i1
%cmptmp.2 = ivy.cmp eq %age, %2 : (!ivy.id, !ivy.atom) -> i1
scf.condition %cmptmp.2
} then {
%d1 = arith.constant 365 : i32
%divtmp.1 = ivy.div %age, %d1 : (#ivy.id, i32) -> #ivy.id
ptr.store %divtmp.1, %self.age : #ivy.id, ptr
%divtmp.1 = ivy.div %age, %d1 : (!ivy.id, i32) -> !ivy.id
ptr.store %divtmp.1, %self.age : !ivy.id, ptr
scf.switch-break : ()
} default {
%d2 = arith.constant 0 : i32
@@ -97,56 +97,56 @@ ivy.module {
func.return : ()
}
ivy.msgh.object get-age-in-units:%units -> #ivy.id {
%result = scf.switch : () -> #ivy.id
ivy.msgh.object get-age-in-units:%units -> !ivy.id {
%result = scf.switch : () -> !ivy.id
case {
%0 = ivy.atom "years"
%cmptmp.0 = ivy.cmp eq %age, %0 : (#ivy.id, #ivy.atom) -> i1
%cmptmp.0 = ivy.cmp eq %age, %0 : (!ivy.id, !ivy.atom) -> i1
scf.switch-condition %cmptmp.0
} then {
%v0 = ptr.load %self.age : ptr -> #ivy.id
scf.switch-break %v0 : #ivy.id
%v0 = ptr.load %self.age : ptr -> !ivy.id
scf.switch-break %v0 : !ivy.id
} case {
%1 = ivy.atom "months"
%cmptmp.1 = ivy.cmp eq %age, %1 : (#ivy.id, #ivy.atom) -> i1
%cmptmp.1 = ivy.cmp eq %age, %1 : (!ivy.id, !ivy.atom) -> i1
scf.condition %cmptmp.1
} then {
%v0 = ptr.load %self.age : ptr -> #ivy.id
%v0 = ptr.load %self.age : ptr -> !ivy.id
%d0 = arith.constant 12 : i32
%divtmp.0 = ivy.div %v0, %d0 : (#ivy.id, i32) -> #ivy.id
scf.switch-break %divtmp.0 : #ivy.id
%divtmp.0 = ivy.div %v0, %d0 : (!ivy.id, i32) -> !ivy.id
scf.switch-break %divtmp.0 : !ivy.id
} case {
%2 = ivy.atom "days"
%cmptmp.2 = ivy.cmp eq %age, %2 : (#ivy.id, #ivy.atom) -> i1
%cmptmp.2 = ivy.cmp eq %age, %2 : (!ivy.id, !ivy.atom) -> i1
scf.condition %cmptmp.2
} then {
%v1 = ptr.load %self.age : ptr -> #ivy.id
%v1 = ptr.load %self.age : ptr -> !ivy.id
%d1 = arith.constant 365 : i32
%divtmp.1 = ivy.div %v1, %d1 : (#ivy.id, i32) -> #ivy.id
scf.switch-break %divtmp.1 : #ivy.id
%divtmp.1 = ivy.div %v1, %d1 : (!ivy.id, i32) -> !ivy.id
scf.switch-break %divtmp.1 : !ivy.id
} default {
%d2 = arith.constant 0 : i32
scf.switch-break %d2 : #ivy.id
scf.switch-break %d2 : !ivy.id
}
func.return %result : #ivy.id
func.return %result : !ivy.id
}
ivy.object-prop example-property
get {
%0 = ptr.load %self.val : ptr -> #ivy.id
func.return %0 : #ivy.id
%0 = ptr.load %self.val : ptr -> !ivy.id
func.return %0 : !ivy.id
}
set (%value: #ivy.id) {
ptr.store %value, %self.val : #ivy.id, ptr
set (%value: !ivy.id) {
ptr.store %value, %self.val : !ivy.id, ptr
func.return : ()
}
ivy.object-prop example-property-2 get {
%0 = ptr.load %self.val : ptr -> #ivy.id
func.return %0 : #ivy.id
} set (%x: #ivy.id) {
ptr.store %x, %self.val : #ivy.id, ptr
%0 = ptr.load %self.val : ptr -> !ivy.id
func.return %0 : !ivy.id
} set (%x: !ivy.id) {
ptr.store %x, %self.val : !ivy.id, ptr
func.return : ()
}
@@ -156,16 +156,16 @@ ivy.module {
}
ivy.object-prop example-property-4 get {
%0 = ptr.load %self.__example-property-4 : ptr -> #ivy.id
func.return %0 : #ivy.id
} set (%0: #ivy.id) {
ptr.store %0, %self.__example-property-4 : #ivy.id, ptr
%0 = ptr.load %self.__example-property-4 : ptr -> !ivy.id
func.return %0 : !ivy.id
} set (%0: !ivy.id) {
ptr.store %0, %self.__example-property-4 : !ivy.id, ptr
func.return : ()
}
ivy.object-prop example-property-5 get {
%0 = ptr.load %self.__example-property-5 : ptr -> #ivy.id
func.return %0 : #ivy.id
%0 = ptr.load %self.__example-property-5 : ptr -> !ivy.id
func.return %0 : !ivy.id
}
}
@@ -175,19 +175,19 @@ ivy.module {
%0 = ivy.str.constant "John Doe"
%1 = arith.constant 34 : i32
%2 = ivy.msg.send to %Person, new(name:%0, age:%1) -> #ivy.id
%2 = ivy.msg.send to %Person, new(name:%0, age:%1) -> !ivy.id
%p1 = ptr.alloca #ivy.id -> ptr
ptr.store %2, %p1 : #ivy.id, ptr
%p1 = ptr.alloca !ivy.id -> ptr
ptr.store %2, %p1 : !ivy.id, ptr
; p1 set-age:100 in-unit:$months.
%3 = ptr.load %p1 : ptr -> #ivy.id
%3 = ptr.load %p1 : ptr -> !ivy.id
%4 = arith.constant 100 : i32
%5 = ivy.atom "months"
ivy.msg.send to %3, set-age:%4 in-units:%5 -> void
; p1 test(param:'Hello', 'World').
%6 = ptr.load %p1 : ptr -> #ivy.id
%6 = ptr.load %p1 : ptr -> !ivy.id
%7 = ivy.str.constant "Hello"
%8 = ivy.str.constant "World"
ivy.msg.send to %6, test(param:%7, _:%8) -> void
@@ -213,9 +213,9 @@ ivy.module {
%14 = ptr.load %i : ptr -> i32
ivy.string-builder.add %12 << %14 : i32
%15 = ivy.string-builder.end %12 -> #ivy.id
%15 = ivy.string-builder.end %12 -> !ivy.id
%16 = ptr.load %cout : ptr -> #ivy.id
%16 = ptr.load %cout : ptr -> !ivy.id
ivy.msg.send to %16, put:%15 -> void
; i += 2
@@ -229,7 +229,7 @@ ivy.module {
%19 = arith.constant 0 : i32
%20 = arith.constant 100 : i32
%21 = arith.constant 2 : i32
%22 = ivy.msg.send to %19, to:%20 step:%21 -> #ivy.id
%22 = ivy.msg.send to %19, to:%20 step:%21 -> !ivy.id
; for x in 0 to:100 step:2 do
ivy.for %x in %22 -> void {
@@ -237,12 +237,12 @@ ivy.module {
; 'Count is {x}'
ivy.string-builder.add %23 << "Count is "
ivy.string-builder.add %23 << %x : #ivy.id
ivy.string-builder.add %23 << %x : !ivy.id
%25 = ivy.string-builder.end %23 -> #ivy.id
%25 = ivy.string-builder.end %23 -> !ivy.id
; cout put:"Count is {x}"
%26 = ptr.load %cout : ptr -> #ivy.id
%26 = ptr.load %cout : ptr -> !ivy.id
ivy.msg.send to %26, put:%25 -> void
}
@@ -251,16 +251,16 @@ ivy.module {
%28 = arith.constant 100 : i32
%29 = arith.constant 2 : i32
; [ :i | cout put:'Count: {i}' ]
%30 = ivy.lambda %i : (#ivy.id) -> void {
%30 = ivy.lambda %i : (!ivy.id) -> void {
%0 = ivy.string-builder.begin
ivy.string-builder.add %0 << "Count is "
ivy.string-builder.add %0 << %i : #ivy.id
ivy.string-builder.add %0 << %i : !ivy.id
%2 = ivy.string-builder.end %0 -> #ivy.id
%2 = ivy.string-builder.end %0 -> !ivy.id
%cout = ivy.global-ref @cout -> ptr
%3 = ptr.load %cout : ptr -> #ivy.id
%3 = ptr.load %cout : ptr -> !ivy.id
ivy.msg.send to %3, put:%2 -> void
}
@@ -273,29 +273,29 @@ ivy.module {
ptr.store %31, %q : i32, ptr
; l = [ cout put:'Value of q is {q}' ].
%l = ptr.alloca #ivy.id
%l = ptr.alloca !ivy.id
%32 = ptr.load %q : ptr -> i32
%33 = ivy.lambda (%env.q = %32) : () -> void {
%0 = ivy.string-builder.begin
ivy.string-builder.add %0 << "Value of q is "
ivy.string-builder.add %0 << %env.q : #ivy.id
ivy.string-builder.add %0 << %env.q : !ivy.id
%2 = ivy.string-builder.end %0 -> #ivy.id
%2 = ivy.string-builder.end %0 -> !ivy.id
%cout = ivy.global-ref @cout -> ptr
%3 = ptr.load %cout : ptr -> #ivy.id
%3 = ptr.load %cout : ptr -> !ivy.id
ivy.msg.send to %3, put:%2 -> void
}
ptr.store %33, %l : #ivy.id, ptr
ptr.store %33, %l : !ivy.id, ptr
; q = 64.
%34 = arith.constant 64 : i32
ptr.store %34, %q : i32, ptr
; l call.
%35 = ptr.load %l : ptr -> #ivy.id
%35 = ptr.load %l : ptr -> !ivy.id
ivy.msg.send to %35, call -> void
%j = ptr.alloca i32 -> ptr
@@ -311,14 +311,14 @@ ivy.module {
%39 = ivy.lambda : () -> void {
%cout = ivy.global-ref @cout -> ptr
%0 = ivy.str.constant "True!"
%1 = ptr.load %cout : ptr -> #ivy.id
%1 = ptr.load %cout : ptr -> !ivy.id
ivy.msg.send to %1, put:%0 -> void
}
%40 = ivy.lambda : () -> void {
%cout = ivy.global-ref @cout -> ptr
%0 = ivy.str.constant "False!"
%1 = ptr.load %cout : ptr -> #ivy.id
%1 = ptr.load %cout : ptr -> !ivy.id
ivy.msg.send to %1, put:%0 -> void
}
@@ -331,53 +331,53 @@ ivy.module {
scf.if %cmptmp.0 -> void {
%43 = ivy.str.constant "True!"
%44 = ptr.load %cout : ptr -> #ivy.id
%44 = ptr.load %cout : ptr -> !ivy.id
ivy.msg.send to %44, put:%43 -> void
}
; pkg = {}.
%pkg = ptr.alloca #ivy.id -> ptr
%pkg = ptr.alloca !ivy.id -> ptr
%Package = ivy.global-ref @std.lang.Package -> ptr
%45 = ivy.msg.send to %Package, new -> #ivy.id
ptr.store %45, %pkg : #ivy.id, ptr
%45 = ivy.msg.send to %Package, new -> !ivy.id
ptr.store %45, %pkg : !ivy.id, ptr
; pkg[0] = 16.
%46 = ptr.load %pkg : ptr -> #ivy.id
%46 = ptr.load %pkg : ptr -> !ivy.id
%47 = arith.constant 0 : i32
%48 = arith.constant 16 : i32
ivy.msg.send to %46, at:%47 put:%48 -> void
; tuple = (32, 'a string')
%tuple = ptr.alloca #ivy.id -> ptr
%tuple = ptr.alloca !ivy.id -> ptr
%49 = arith.constant 32 : i32
%50 = ivy.str.constant "a string"
%51 = ivy.tuple.create %49, %50 : (i32, #ivy.id) -> #ivy.id
%51 = ivy.tuple.create %49, %50 : (i32, !ivy.id) -> !ivy.id
ptr.store %51, %tuple : #ivy.id, ptr
ptr.store %51, %tuple : !ivy.id, ptr
%52 = ptr.load %tuple : ptr -> #ivy.id
%53 = ivy.msg.send to %52, get-iterator -> #ivy.id
%52 = ptr.load %tuple : ptr -> !ivy.id
%53 = ivy.msg.send to %52, get-iterator -> !ivy.id
ivy.for %54 in %53 -> void {
%key = ivy.tuple.get-item %54[0] : (#ivy.id, i32) -> #ivy.id
%val = ivy.tuple.get-item %54[1] : (#ivy.id, i32) -> #ivy.id
%key = ivy.tuple.get-item %54[0] : (!ivy.id, i32) -> !ivy.id
%val = ivy.tuple.get-item %54[1] : (!ivy.id, i32) -> !ivy.id
; '{key} -> {val}'
%55 = ivy.string-builder.begin
ivy.string-builder.add %55 << %key : #ivy.id
ivy.string-builder.add %55 << %key : !ivy.id
ivy.string-builder.add %55 << " -> "
ivy.string-builder.add %55 << %val : #ivy.id
ivy.string-builder.add %55 << %val : !ivy.id
%57 = ivy.string-builder.end %55 -> #ivy.id
%57 = ivy.string-builder.end %55 -> !ivy.id
; cout put:'{key} -> {val}'
%58 = ptr.load %cout : ptr -> #ivy.id
%58 = ptr.load %cout : ptr -> !ivy.id
ivy.msg.send to %58, put:%57 -> void
}
@@ -387,20 +387,20 @@ ivy.module {
%multmp = arith.mul %59, %60 : (i32, i32) -> i32
; a = (32, 64).
%a = ptr.alloca #ivy.id -> ptr
%a = ptr.alloca !ivy.id -> ptr
%61 = arith.constant 32 : i32
%62 = arith.constant 64 : i32
%63 = ivy.tuple.create %61, %62 : (i32, i32) -> #ivy.id
%63 = ivy.tuple.create %61, %62 : (i32, i32) -> !ivy.id
ptr.store %63, %a : #ivy.id, ptr
ptr.store %63, %a : !ivy.id, ptr
%v = ptr.alloca #ivy.id -> ptr
%v = ptr.alloca !ivy.id -> ptr
%64 = ptr.load %a : ptr -> #ivy.id
%65 = ivy.tuple.get-item %64[1] : #ivy.id -> #ivy.id
%64 = ptr.load %a : ptr -> !ivy.id
%65 = ivy.tuple.get-item %64[1] : !ivy.id -> !ivy.id
ptr.store %65, %v : #ivy.id, ptr
ptr.store %65, %v : !ivy.id, ptr
%66 = ivy.atom "err:number-format"
@@ -413,47 +413,47 @@ ivy.module {
}
%67 = ivy.lambda : () -> void {
%v = ptr.alloca #ivy.id -> ptr
%v = ptr.alloca !ivy.id -> ptr
%Int = ivy.global-ref @Int -> ptr
%0 = ivy.str.constant "342"
%1 = ivy.msg.send to %Int, parse:%0
ptr.store %1, %v : #ivy.id, ptr
ptr.store %1, %v : !ivy.id, ptr
}
%68 = ivy.lambda %err, %data : (#ivy.id, #ivy.id) -> void {
%68 = ivy.lambda %err, %data : (!ivy.id, !ivy.id) -> void {
%0 = ivy.string-builder.begin
ivy.string-builder.add %0 << "Cannot parse integer string ("
ivy.string-builder.add %0 << %err : #ivy.id
ivy.string-builder.add %0 << %err : !ivy.id
ivy.string-builder.add %0 << ")"
%3 = ivy.string-builder.end %0 -> #ivy.id
%3 = ivy.string-builder.end %0 -> !ivy.id
; cout put:'{key} -> {val}'
%4 = ptr.load %cout : ptr -> #ivy.id
%4 = ptr.load %cout : ptr -> !ivy.id
ivy.msg.send to %4, put:%3 -> void
}
%69 = ivy.lambda %err, %data : (#ivy.id, #ivy.id) -> void {
%69 = ivy.lambda %err, %data : (!ivy.id, !ivy.id) -> void {
%0 = ivy.string-builder.create
ivy.string-builder.add %0 << "Error "
ivy.string-builder.add %0 << %err : #ivy.id
ivy.string-builder.add %0 << %err : !ivy.id
ivy.string-builder.add %0 << " occurred ("
ivy.string-builder.add %0 << %data : #ivy.id
ivy.string-builder.add %0 << %data : !ivy.id
ivy.string-builder.add %0 << ")"
%4 = ivy.string-builder.end %0 -> #ivy.id
%4 = ivy.string-builder.end %0 -> !ivy.id
; cout put:'{key} -> {val}'
%5 = ptr.load %cout : ptr -> #ivy.id
%5 = ptr.load %cout : ptr -> !ivy.id
ivy.msg.send to %5, put:%4 -> void
}
%70 = ivy.atom "err:number-format"
ivy.msg.send to %67, on:%70 do:%68 -> #ivy.id
ivy.msg.send to %67, on:%70 do:%68 -> !ivy.id
ivy.msg.send to %67, on-error:%69 -> void
ivy.msg.send to %67, call -> void
}

View File

@@ -1,6 +1,26 @@
%1, %reg.2, $X0 = ~scf.for(%a, %b) ({
^b0:
~arith.constant() : () -> ()
^b1:
~arith.constant() : () -> ()
}) {test_attrib = 2 : i32 } : (i8, i1) -> (i32, i32, i32)
~builtin.module() ({
~func.func() ({
^entry(%buffer: i32, %lb: index, %ub: index, %step: index):
; Initial sum set to 0.
%sum.0 = ~arith.constant() {value = 0.0 : f32} : () -> f32
; iter_args binds initial values to the loop's region arguments.
;%sum = "scf.for"(%lb, %ub, %step) -> (f32) {
~cf.br() [ ^for.entry:(%lb: index, %sum.0: f32) ] : () -> ()
^for.entry(%iv: index, %sum.iter: f32):
%t, %x, %z = ~memref.load(%buffer, %iv) : (i32, index) -> (f32, i1, i1)
%sum.next = ~arith.addf(%sum.iter, %t) : (f32, f32) -> f32
~cf.br() [ ^for.cond:(%iv: index, %sum.next: f32) ] : () -> ()
^for.cond(%iv2: index, %sum.next2: f32):
; Yield current iteration sum to next iteration %sum.iter or to %sum
; if final iteration.
%iv.next = ~arith.addi(%iv, %step) : (index, index) -> index
%stop = ~arith.cmpi(%iv.next, %ub) { predicate = 9 } : (index, index) -> i1
~cf.br-cond(%stop) [ ^for.end, ^for.entry:(%iv.next: index, %sum.next: f32) ] : (i1) -> ()
^for.end(%sum: f32):
~func.return(%sum) : (f32) -> ()
}) {sym_name = "reduce", function_type = (i32, index, index, index) -> f32 } : () -> ()
}) : () -> ()

View File

@@ -31,7 +31,8 @@ syn match mieBuiltinType /\<ptr\>/
syn match mieBuiltinType /\<index\>/
syn match mieBuiltinType "\<[if][0-9]\>"
syn match mieBuiltinType "\<[if][1-9][0-9]\+\>"
syn match mieDialectType /#[A-Za-z][A-Za-z0-9\-]*\(\.[A-Za-z][A-Za-z0-9\-]*\)\+/
syn match mieDialectType /![A-Za-z][A-Za-z0-9\-]*\(\.[A-Za-z][A-Za-z0-9\-]*\)\+/
syn match mieDialectAttribute /#[A-Za-z][A-Za-z0-9\-]*\(\.[A-Za-z][A-Za-z0-9\-]*\)\+/
syn match mieInstruction /\*[A-Za-z][A-Za-z0-9\-]*\(\.[A-Za-z][A-Za-z0-9\-]*\)\+\([>\*]\)\@!\>/
syn match mieGenericOperation /\~[A-Za-z][A-Za-z0-9\-]*\(\.[A-Za-z][A-Za-z0-9\-]*\)\+\([>\*]\)\@!\>/
@@ -77,6 +78,7 @@ hi def link mieBrackets Delimiter
hi def link mieAngleBrackets StorageClass
hi def link mieDialectType Type
hi def link mieDialectAttribute @attribute
hi def link mieGenericOperation @function.builtin
hi def link mieGraphOperation Statement

View File

@@ -25,3 +25,15 @@ struct mie_attribute_definition *mie_attribute_definition_create(
return out;
}
bool mie_attribute_definition_check_name(
const struct mie_attribute_definition *def, const char *dialect_name,
const char *attrib_name)
{
if (!def || !def->a_parent) {
return false;
}
return (!strcmp(def->a_name, attrib_name)
&& !strcmp(def->a_parent->d_name, dialect_name));
}

View File

@@ -149,6 +149,7 @@ enum mie_status mie_attribute_map_put(
struct attribute_map_entry *entry = get_entry(&map->m_entries, name_hash);
struct attribute_map_item *item = NULL;
struct attribute_map_bucket *bucket = NULL;
enum mie_status status = MIE_SUCCESS;
if (!entry) {
item = create_item(name, name_hash, value);
@@ -162,6 +163,17 @@ enum mie_status mie_attribute_map_put(
if (entry->e_type == ATTRMAP_ENTRY_ITEM) {
item = (struct attribute_map_item *)entry;
if (!strcmp(item->i_name, name)) {
status = MIE_ERR_NAME_EXISTS;
if (flags & MIE_ATTRMAP_F_REPLACE) {
item->i_value = value;
status = MIE_SUCCESS;
}
return status;
}
bucket = convert_item_to_bucket(map, item);
} else {
bucket = (struct attribute_map_bucket *)entry;

View File

@@ -0,0 +1,14 @@
#include <mie/attribute/attribute-definition.h>
#include <mie/attribute/attribute.h>
bool mie_attribute_check_name(
const struct mie_attribute *attrib, const char *dialect_name,
const char *attrib_name)
{
if (!attrib || !attrib->a_def) {
return false;
}
return mie_attribute_definition_check_name(
attrib->a_def, dialect_name, attrib_name);
}

119
mie/ctx.c
View File

@@ -9,7 +9,10 @@
#include <mie/dialect/dialect.h>
#include <mie/dialect/index.h>
#include <mie/interface/interface-definition.h>
#include <mie/ir/op-definition.h>
#include <mie/ir/op.h>
#include <mie/pass/pass-definition.h>
#include <mie/pass/pass.h>
#include <mie/trait/trait-definition.h>
#include <mie/trait/trait.h>
#include <mie/type/function.h>
@@ -35,6 +38,10 @@
MIE_ID(0xc6, 0x94, 0x38, 0x34, 0xdb, 0x08, 0x45, 0xc7, 0xb9, 0x89, \
0x69, 0x82, 0x7a, 0x9d, 0x42, 0xd8)
#define PASS_NS_ID \
MIE_ID(0x76, 0xfc, 0xdd, 0xb5, 0xc0, 0x20, 0x47, 0x13, 0x8d, 0xfa, \
0x3f, 0x28, 0x2f, 0x81, 0x6d, 0x7d)
struct mie_ctx *mie_ctx_create(void)
{
struct mie_ctx *out = malloc(sizeof *out);
@@ -57,15 +64,15 @@ struct mie_ctx *mie_ctx_create(void)
mie_id attributes_ns = ATTRIBUTE_NS_ID;
mie_id_map_init(&out->ctx_attributes, &attributes_ns);
mie_id pass_ns = PASS_NS_ID;
mie_id_map_init(&out->ctx_passes, &pass_ns);
return out;
}
bool mie_ctx_resolve_op(const struct mie_ctx *ctx, struct mie_op *op)
{
bool fully_resolved = MIE_TEST_FLAGS(
op->op_flags, MIE_OP_F_OP_RESOLVED | MIE_OP_F_ARG_RESOLVED);
if (fully_resolved) {
if (op->op_flags & MIE_OP_F_OP_RESOLVED) {
return true;
}
@@ -95,7 +102,7 @@ bool mie_ctx_resolve_op(const struct mie_ctx *ctx, struct mie_op *op)
const struct mie_op_definition *op_info
= mie_dialect_get_op(dialect, op_name);
if (!op) {
if (!op_info) {
return false;
}
@@ -120,6 +127,27 @@ struct mie_dialect *mie_ctx_get_dialect(const struct mie_ctx *ctx, const char *n
return b_unbox(struct mie_dialect, target, d_id);
}
const struct mie_op_definition *mie_ctx_get_op_definition(
const struct mie_ctx *ctx, const char *dialect_name, const char *op_name)
{
b_rope dialect_name_rope = B_ROPE_CSTR(dialect_name);
mie_id id;
mie_id_init_ns(
&id, mie_id_map_get_ns(&ctx->ctx_dialects), &dialect_name_rope);
mie_id *target = mie_id_map_get(&ctx->ctx_dialects, &id);
struct mie_dialect *dialect = b_unbox(struct mie_dialect, target, d_id);
if (!dialect) {
return NULL;
}
b_rope op_name_rope = B_ROPE_CSTR(op_name);
mie_id_init_ns(&id, mie_id_map_get_ns(&dialect->d_ops), &op_name_rope);
target = mie_id_map_get(&dialect->d_ops, &id);
return b_unbox(struct mie_op_definition, target, op_id);
}
struct mie_type_definition *mie_ctx_get_type_definition(
const struct mie_ctx *ctx, const char *dialect_name, const char *type_name)
{
@@ -246,7 +274,7 @@ struct mie_type *mie_ctx_get_type(
memset(type, 0x0, sizeof *type);
type->ty_def = type_info;
type->ty_name = b_bstr_fmt("%s.%s", dialect_name, type_name);
type->ty_name = b_bstr_fmt(NULL, "%s.%s", dialect_name, type_name);
if (type_info->ty_init) {
type_info->ty_init(type_info, type);
@@ -293,7 +321,7 @@ const struct mie_trait *mie_ctx_get_trait(
memset(trait, 0x0, sizeof trait_info->tr_data_size);
trait->tr_def = trait_info;
trait->tr_name = b_bstr_fmt("%s.%s", dialect_name, trait_name);
trait->tr_name = b_bstr_fmt(NULL, "%s.%s", dialect_name, trait_name);
if (trait_info->tr_init) {
trait_info->tr_init(trait_info, trait);
@@ -358,3 +386,80 @@ struct mie_type *mie_ctx_get_function_type(
mie_id_map_put_id(&ctx->ctx_types, &new_type->func_base.ty_id);
return (struct mie_type *)new_type;
}
enum mie_status mie_ctx_register_pass(
struct mie_ctx *ctx, struct mie_pass_definition *pass)
{
if (pass->p_data_size < sizeof(struct mie_pass)) {
return MIE_ERR_INVALID_ARGUMENT;
}
switch (pass->p_type) {
case MIE_PASS_ANALYSE:
case MIE_PASS_TRANSFORM:
break;
default:
return MIE_ERR_INVALID_ARGUMENT;
}
mie_id id;
struct mie_id_builder id_builder;
mie_id_builder_begin(&id_builder, mie_id_map_get_ns(&ctx->ctx_passes));
mie_id_builder_add_cstr(&id_builder, pass->p_name);
mie_id_builder_end(&id_builder, &id);
mie_id *target = mie_id_map_get(&ctx->ctx_passes, &id);
if (target) {
return MIE_ERR_NAME_EXISTS;
}
pass->p_id = id;
mie_id_map_put_id(&ctx->ctx_passes, &pass->p_id);
return MIE_SUCCESS;
}
enum mie_status mie_ctx_get_pass(
struct mie_ctx *ctx, const char *name,
const struct mie_attribute_map *args, struct mie_pass **out)
{
mie_id id;
struct mie_id_builder id_builder;
mie_id_builder_begin(&id_builder, mie_id_map_get_ns(&ctx->ctx_passes));
mie_id_builder_add_cstr(&id_builder, name);
mie_id_builder_end(&id_builder, &id);
mie_id *target = mie_id_map_get(&ctx->ctx_passes, &id);
if (!target) {
return MIE_ERR_NO_ENTRY;
}
struct mie_pass_definition *pass_def
= b_unbox(struct mie_pass_definition, target, p_id);
if (pass_def->p_data_size < sizeof(struct mie_pass)) {
return MIE_ERR_BAD_STATE;
}
struct mie_pass *pass = malloc(pass_def->p_data_size);
if (!pass) {
return MIE_ERR_NO_MEMORY;
}
memset(pass, 0x0, pass_def->p_data_size);
pass->p_def = pass_def;
enum mie_status status = MIE_SUCCESS;
if (pass_def->p_init) {
status = pass_def->p_init(pass, args);
}
if (status != MIE_SUCCESS) {
free(pass);
pass = NULL;
}
*out = pass;
return status;
}

View File

@@ -5,5 +5,7 @@
MIE_DIALECT_BEGIN(mie_arith, struct mie_dialect, "arith")
MIE_DIALECT_ADD_OP(mie_arith_addi);
MIE_DIALECT_ADD_OP(mie_arith_cmpi);
MIE_DIALECT_ADD_OP(mie_arith_addf);
MIE_DIALECT_ADD_OP(mie_arith_constant);
MIE_DIALECT_END()

View File

@@ -1,9 +1,25 @@
#include <mie/dialect/dialect.h>
#include <mie/ir/op-definition.h>
#include <mie/ir/op.h>
#include <mie/macros.h>
#include <mie/print/printer.h>
static enum mie_status print(const struct mie_op *op, b_stream *out)
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
{
if (MIE_VECTOR_COUNT(op->op_args) != 2) {
return MIE_SUCCESS;
}
const struct mie_op_arg *left = &op->op_args.items[0];
const struct mie_op_arg *right = &op->op_args.items[1];
b_stream_write_char(printer->p_stream, ' ');
mie_printer_print_op_arg(printer, left, false);
b_stream_write_string(printer->p_stream, ", ", NULL);
mie_printer_print_op_arg(printer, right, false);
b_stream_write_string(printer->p_stream, " : ", NULL);
mie_printer_print_type(printer, mie_op_arg_get_type(left));
return MIE_SUCCESS;
}

View File

@@ -1,9 +1,25 @@
#include <mie/dialect/dialect.h>
#include <mie/ir/op-definition.h>
#include <mie/ir/op.h>
#include <mie/macros.h>
#include <mie/print/printer.h>
static enum mie_status print(const struct mie_op *op, b_stream *out)
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
{
if (MIE_VECTOR_COUNT(op->op_args) != 2) {
return MIE_SUCCESS;
}
const struct mie_op_arg *left = &op->op_args.items[0];
const struct mie_op_arg *right = &op->op_args.items[1];
b_stream_write_char(printer->p_stream, ' ');
mie_printer_print_op_arg(printer, left, false);
b_stream_write_string(printer->p_stream, ", ", NULL);
mie_printer_print_op_arg(printer, right, false);
b_stream_write_string(printer->p_stream, " : ", NULL);
mie_printer_print_type(printer, mie_op_arg_get_type(left));
return MIE_SUCCESS;
}

View File

@@ -0,0 +1,80 @@
#include <mie/dialect/builtin.h>
#include <mie/dialect/dialect.h>
#include <mie/ir/op-definition.h>
#include <mie/ir/op.h>
#include <mie/macros.h>
#include <mie/print/printer.h>
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
{
if (MIE_VECTOR_COUNT(op->op_args) != 2
|| MIE_VECTOR_COUNT(op->op_result) != 1) {
return MIE_SUCCESS;
}
const struct mie_op_arg *left = &op->op_args.items[0];
const struct mie_op_arg *right = &op->op_args.items[1];
const struct mie_register *result = &op->op_result.items[0];
const struct mie_attribute *pred_attr
= mie_attribute_map_get(&op->op_attrib, "predicate");
long long pred;
if (!mie_int_get_value(pred_attr, &pred)) {
return MIE_SUCCESS;
}
b_stream_write_char(printer->p_stream, ' ');
switch (pred) {
case 0:
b_stream_write_string(printer->p_stream, "eq", NULL);
break;
case 1:
b_stream_write_string(printer->p_stream, "ne", NULL);
break;
case 2:
b_stream_write_string(printer->p_stream, "slt", NULL);
break;
case 3:
b_stream_write_string(printer->p_stream, "sle", NULL);
break;
case 4:
b_stream_write_string(printer->p_stream, "sgt", NULL);
break;
case 5:
b_stream_write_string(printer->p_stream, "sge", NULL);
break;
case 6:
b_stream_write_string(printer->p_stream, "ult", NULL);
break;
case 7:
b_stream_write_string(printer->p_stream, "ule", NULL);
break;
case 8:
b_stream_write_string(printer->p_stream, "ugt", NULL);
break;
case 9:
b_stream_write_string(printer->p_stream, "uge", NULL);
break;
default:
return MIE_SUCCESS;
}
b_stream_write_char(printer->p_stream, ' ');
mie_printer_print_op_arg(printer, left, false);
b_stream_write_string(printer->p_stream, ", ", NULL);
mie_printer_print_op_arg(printer, right, false);
b_stream_write_string(printer->p_stream, " : ", NULL);
mie_printer_print_type(printer, mie_op_arg_get_type(left));
return MIE_SUCCESS;
}
static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
{
return MIE_SUCCESS;
}
MIE_OP_DEFINITION_BEGIN(mie_arith_cmpi, "cmpi")
MIE_OP_DEFINITION_PRINT(print);
MIE_OP_DEFINITION_PARSE(parse);
MIE_OP_DEFINITION_END()

View File

@@ -0,0 +1,46 @@
#include <mie/attribute/attribute.h>
#include <mie/dialect/builtin.h>
#include <mie/dialect/dialect.h>
#include <mie/ir/op-definition.h>
#include <mie/ir/op.h>
#include <mie/macros.h>
#include <mie/print/printer.h>
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
{
const struct mie_attribute *value
= mie_attribute_map_get(&op->op_attrib, "value");
if (!value) {
return MIE_SUCCESS;
}
const struct mie_type *type = NULL;
if (mie_attribute_check_name(value, "builtin", "int")) {
const struct mie_int *i = (const struct mie_int *)value;
b_stream_write_fmt(
printer->p_stream, NULL, " %lld : ", i->i_val.v_small);
type = i->i_type;
} else if (mie_attribute_check_name(value, "builtin", "float")) {
const struct mie_float *f = (const struct mie_float *)value;
double d;
mie_float_get_value(value, &d);
b_stream_write_fmt(printer->p_stream, NULL, " %g : ", d);
type = f->f_type;
} else {
return MIE_SUCCESS;
}
mie_printer_print_type(printer, type);
return MIE_SUCCESS;
}
static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
{
return MIE_SUCCESS;
}
MIE_OP_DEFINITION_BEGIN(mie_arith_constant, "constant")
MIE_OP_DEFINITION_PRINT(print);
MIE_OP_DEFINITION_PARSE(parse);
MIE_OP_DEFINITION_END()

View File

@@ -0,0 +1,103 @@
#include <mie/attribute/attribute-definition.h>
#include <mie/attribute/attribute.h>
#include <mie/ctx.h>
#include <mie/dialect/builtin.h>
#include <mie/dialect/dialect.h>
#include <mie/macros.h>
#include <mie/parse/parser.h>
#include <mie/print/printer.h>
static enum mie_status print(
const struct mie_attribute *value, struct mie_printer *out)
{
const struct mie_array *array = (const struct mie_array *)value;
if (!(out->p_flags & MIE_PRINT_F_ABBREVIATED)) {
b_stream_write_string(out->p_stream, "#builtin.array<", NULL);
}
b_stream_write_char(out->p_stream, '[');
for (size_t i = 0; i < MIE_VECTOR_COUNT(array->a_items); i++) {
if (i > 0) {
b_stream_write_char(out->p_stream, ',');
}
b_stream_write_char(out->p_stream, ' ');
mie_printer_print_attribute(out, array->a_items.items[i]);
}
if (MIE_VECTOR_COUNT(array->a_items) != 0) {
b_stream_write_char(out->p_stream, ' ');
}
b_stream_write_char(out->p_stream, ']');
if (!(out->p_flags & MIE_PRINT_F_ABBREVIATED)) {
b_stream_write_char(out->p_stream, '>');
}
return MIE_SUCCESS;
}
static struct mie_array *array_create(struct mie_ctx *ctx)
{
struct mie_array *array = malloc(sizeof *array);
if (!array) {
return NULL;
}
memset(array, 0x0, sizeof *array);
array->a_base.a_def
= mie_ctx_get_attribute_definition(ctx, "builtin", "array");
return array;
}
static enum mie_status parse(
struct mie_parser *ctx, const struct mie_attribute **out)
{
if (!mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_BRACKET)) {
return MIE_ERR_BAD_SYNTAX;
}
struct mie_array *array = array_create(mie_parser_get_mie_ctx(ctx));
if (!array) {
return MIE_ERR_NO_MEMORY;
}
const struct mie_attribute *item = NULL;
if (!mie_parser_parse_attribute(ctx, &item)) {
free(array);
return MIE_ERR_BAD_FORMAT;
}
mie_vector_push_back(array->a_items, &item, NULL);
while (1) {
if (mie_parser_parse_symbol(ctx, MIE_SYM_RIGHT_BRACKET)) {
break;
}
if (!mie_parser_parse_symbol(ctx, MIE_SYM_COMMA)) {
return false;
}
if (!mie_parser_parse_attribute(ctx, &item)) {
free(array);
return MIE_ERR_BAD_FORMAT;
}
mie_vector_push_back(array->a_items, &item, NULL);
}
*out = (struct mie_attribute *)array;
return MIE_SUCCESS;
}
MIE_ATTRIBUTE_DEFINITION_BEGIN(mie_builtin_array, "array")
MIE_ATTRIBUTE_DEFINITION_STRUCT(struct mie_array);
MIE_ATTRIBUTE_DEFINITION_PRINT(print);
MIE_ATTRIBUTE_DEFINITION_PARSE(parse);
MIE_ATTRIBUTE_DEFINITION_END()

View File

@@ -51,30 +51,52 @@ static enum mie_status parse(
struct mie_file_span span;
if (!mie_parser_parse_float(ctx, &value, &span)) {
return false;
return MIE_ERR_BAD_SYNTAX;
}
if (!mie_parser_parse_symbol(ctx, MIE_SYM_COLON)) {
return false;
return MIE_ERR_BAD_SYNTAX;
}
const struct mie_type *type = NULL;
if (!mie_parser_parse_type(ctx, &type)) {
return false;
return MIE_ERR_BAD_SYNTAX;
}
size_t width = mie_float_type_get_width(type);
if (width == (size_t)-1) {
return false;
return MIE_ERR_BAD_SYNTAX;
}
struct mie_attribute *v
= mie_ctx_get_float(mie_parser_get_mie_ctx(ctx), value, width);
if (!v) {
return false;
return MIE_ERR_NO_MEMORY;
}
*out = v;
return MIE_SUCCESS;
}
bool mie_float_get_value(const struct mie_attribute *attrib, double *out)
{
if (!mie_attribute_check_name(attrib, "builtin", "float")) {
return false;
}
const struct mie_float *v = (const struct mie_float *)attrib;
switch (mie_float_type_get_width(v->f_type)) {
case MIE_FLOAT_32:
*out = v->f_val.v_32;
break;
case MIE_FLOAT_64:
*out = v->f_val.v_64;
break;
default:
return false;
}
return true;
}

View File

@@ -15,20 +15,25 @@ static enum mie_status print(
{
const struct mie_int *int_val = (const struct mie_int *)value;
const struct int_type *int_ty = (const struct int_type *)int_val->i_type;
if (!(out->p_flags & MIE_PRINT_F_ABBREVIATED)) {
bool abbrev = ((out->p_flags & MIE_PRINT_F_ABBREVIATED) != 0);
if (!abbrev) {
b_stream_write_string(out->p_stream, "#builtin.int<", NULL);
}
if (int_ty->i_width <= 64) {
if (int_ty->i_width < 64 || !abbrev) {
b_stream_write_fmt(
out->p_stream, NULL, "%zu : i%zu",
int_val->i_val.v_small, int_ty->i_width);
} else if (int_ty->i_width == 64 && abbrev) {
b_stream_write_fmt(
out->p_stream, NULL, "%zu", int_val->i_val.v_small);
} else {
b_stream_write_fmt(
out->p_stream, NULL, "INF : i%zu", int_ty->i_width);
}
if (!(out->p_flags & MIE_PRINT_F_ABBREVIATED)) {
if (!abbrev) {
b_stream_write_string(out->p_stream, ">", NULL);
}
@@ -42,30 +47,43 @@ static enum mie_status parse(
struct mie_file_span span;
if (!mie_parser_parse_int(ctx, &value, &span)) {
return false;
}
if (!mie_parser_parse_symbol(ctx, MIE_SYM_COLON)) {
return false;
return MIE_ERR_BAD_SYNTAX;
}
const struct mie_type *type = NULL;
if (!mie_parser_parse_type(ctx, &type)) {
size_t width = (size_t)-1;
if (!mie_parser_parse_symbol(ctx, MIE_SYM_COLON)) {
width = 64;
} else if (!mie_parser_parse_type(ctx, &type)) {
return false;
} else {
width = mie_int_type_get_width(type);
}
size_t width = mie_int_type_get_width(type);
if (width == (size_t)-1) {
return false;
return MIE_ERR_BAD_SYNTAX;
}
struct mie_attribute *v
= mie_ctx_get_int(mie_parser_get_mie_ctx(ctx), value, width);
if (!v) {
return false;
return MIE_ERR_NO_MEMORY;
}
*out = v;
return MIE_SUCCESS;
}
bool mie_int_get_value(const struct mie_attribute *attrib, long long *out)
{
if (!mie_attribute_check_name(attrib, "builtin", "int")) {
return false;
}
const struct mie_int *v = (const struct mie_int *)attrib;
*out = v->i_val.v_small;
return true;
}

View File

@@ -26,18 +26,28 @@ static enum mie_status parse(
b_string *str = mie_parser_get_tempstr(ctx);
struct mie_file_span span;
if (!mie_parser_parse_string(ctx, str, &span)) {
return false;
return MIE_ERR_BAD_SYNTAX;
}
struct mie_attribute *v = mie_ctx_get_string(
mie_parser_get_mie_ctx(ctx), b_string_ptr(str));
if (!v) {
return false;
return MIE_ERR_NO_MEMORY;
}
*out = v;
return true;
return MIE_SUCCESS;
}
const char *mie_string_get_cstr(const struct mie_attribute *attrib)
{
if (!mie_attribute_check_name(attrib, "builtin", "string")) {
return NULL;
}
const struct mie_string *str = (const struct mie_string *)attrib;
return str->str_val;
}
MIE_ATTRIBUTE_DEFINITION_BEGIN(mie_builtin_string, "string")

View File

@@ -0,0 +1,78 @@
#include <mie/attribute/attribute-definition.h>
#include <mie/attribute/attribute.h>
#include <mie/ctx.h>
#include <mie/dialect/builtin.h>
#include <mie/dialect/dialect.h>
#include <mie/macros.h>
#include <mie/parse/parser.h>
#include <mie/print/printer.h>
static enum mie_status print(
const struct mie_attribute *value, struct mie_printer *out)
{
const struct mie_type_attr *ty = (const struct mie_type_attr *)value;
if (!(out->p_flags & MIE_PRINT_F_ABBREVIATED)) {
b_stream_write_string(out->p_stream, "#builtin.type<", NULL);
}
mie_printer_print_type(out, ty->ty_value);
if (!(out->p_flags & MIE_PRINT_F_ABBREVIATED)) {
b_stream_write_char(out->p_stream, '>');
}
return MIE_SUCCESS;
}
static struct mie_type_attr *type_attr_create(struct mie_ctx *ctx)
{
struct mie_type_attr *ty = malloc(sizeof *ty);
if (!ty) {
return NULL;
}
memset(ty, 0x0, sizeof *ty);
ty->ty_base.a_def
= mie_ctx_get_attribute_definition(ctx, "builtin", "type");
return ty;
}
static enum mie_status parse(
struct mie_parser *ctx, const struct mie_attribute **out)
{
struct mie_type_attr *ty = type_attr_create(mie_parser_get_mie_ctx(ctx));
if (!ty) {
return MIE_ERR_NO_MEMORY;
}
const struct mie_type *type = NULL;
if (!mie_parser_parse_type(ctx, &type)) {
free(ty);
return MIE_ERR_BAD_FORMAT;
}
ty->ty_value = type;
*out = (struct mie_attribute *)ty;
return MIE_SUCCESS;
}
const struct mie_type *mie_type_attr_get_type(const struct mie_attribute *attrib)
{
if (!mie_attribute_check_name(attrib, "builtin", "type")) {
return NULL;
}
const struct mie_type_attr *ty = (const struct mie_type_attr *)attrib;
return ty->ty_value;
}
MIE_ATTRIBUTE_DEFINITION_BEGIN(mie_builtin_type, "type")
MIE_ATTRIBUTE_DEFINITION_STRUCT(struct mie_type_attr);
MIE_ATTRIBUTE_DEFINITION_PRINT(print);
MIE_ATTRIBUTE_DEFINITION_PARSE(parse);
MIE_ATTRIBUTE_DEFINITION_END()

View File

@@ -84,6 +84,7 @@ struct mie_attribute *mie_ctx_get_index(struct mie_ctx *ctx, size_t val)
MIE_DIALECT_BEGIN(mie_builtin, struct builtin_dialect, "builtin")
MIE_DIALECT_INIT(init);
MIE_DIALECT_CLEANUP(cleanup);
MIE_DIALECT_ADD_OP(mie_builtin_module);
MIE_DIALECT_ADD_TYPE(mie_builtin_string);
MIE_DIALECT_ADD_TYPE(mie_builtin_int);
MIE_DIALECT_ADD_TYPE(mie_builtin_float);
@@ -91,6 +92,8 @@ MIE_DIALECT_BEGIN(mie_builtin, struct builtin_dialect, "builtin")
MIE_DIALECT_ADD_ATTRIBUTE(mie_builtin_string);
MIE_DIALECT_ADD_ATTRIBUTE(mie_builtin_int);
MIE_DIALECT_ADD_ATTRIBUTE(mie_builtin_float);
MIE_DIALECT_ADD_ATTRIBUTE(mie_builtin_array);
MIE_DIALECT_ADD_ATTRIBUTE(mie_builtin_type);
MIE_DIALECT_ADD_TRAIT(mie_builtin_isolated_from_above);
MIE_DIALECT_ADD_TRAIT(mie_builtin_symbol_table);
MIE_DIALECT_ADD_INTERFACE(mie_builtin_symbol);

View File

@@ -0,0 +1,29 @@
#include <mie/dialect/dialect.h>
#include <mie/ir/op-definition.h>
#include <mie/ir/op.h>
#include <mie/ir/region.h>
#include <mie/macros.h>
#include <mie/print/printer.h>
static enum mie_status print(struct mie_printer *out, const struct mie_op *op)
{
b_stream_write_char(out->p_stream, ' ');
if (MIE_VECTOR_COUNT(op->op_regions) == 0) {
return MIE_SUCCESS;
}
struct mie_region *region = &op->op_regions.items[0];
mie_printer_print_region(out, region, 0);
return MIE_SUCCESS;
}
static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
{
return MIE_SUCCESS;
}
MIE_OP_DEFINITION_BEGIN(mie_builtin_module, "module")
MIE_OP_DEFINITION_PRINT(print);
MIE_OP_DEFINITION_PARSE(parse);
MIE_OP_DEFINITION_END()

View File

@@ -34,7 +34,7 @@ struct mie_type *mie_ctx_get_float_type(struct mie_ctx *ctx, size_t bit_width)
return NULL;
}
type->f_base.ty_name = b_bstr_fmt("builtin.float<%zu>", bit_width);
type->f_base.ty_name = b_bstr_fmt(NULL, "builtin.float<%zu>", bit_width);
type->f_base.ty_instance_size = sizeof(struct mie_float);
type->f_width = bit_width;

View File

@@ -15,17 +15,7 @@ static void type_init(
type->ty_instance_size = sizeof(struct mie_index);
}
static enum mie_status print(const struct mie_type *ty, struct mie_printer *out)
{
b_stream_write_string(
out->p_stream,
(out->p_flags & MIE_PRINT_F_ABBREVIATED) ? "index" : "!builtin.index",
NULL);
return MIE_SUCCESS;
}
MIE_TYPE_DEFINITION_BEGIN(mie_builtin_index, "index")
MIE_TYPE_DEFINITION_STRUCT(struct index_type);
MIE_TYPE_DEFINITION_INIT(type_init);
MIE_TYPE_DEFINITION_PRINT(print);
MIE_TYPE_DEFINITION_END()

View File

@@ -34,7 +34,7 @@ struct mie_type *mie_ctx_get_int_type(struct mie_ctx *ctx, size_t bit_width)
return NULL;
}
type->i_base.ty_name = b_bstr_fmt("builtin.int<%zu>", bit_width);
type->i_base.ty_name = b_bstr_fmt(NULL, "builtin.int<%zu>", bit_width);
type->i_base.ty_instance_size = sizeof(struct mie_int);
type->i_width = bit_width;

View File

@@ -15,6 +15,10 @@ static void type_init(
static enum mie_status print(const struct mie_type *ty, struct mie_printer *out)
{
b_stream_write_string(
out->p_stream,
(out->p_flags & MIE_PRINT_F_ABBREVIATED) ? "str" : "!builtin.string",
NULL);
return MIE_SUCCESS;
}

View File

@@ -1,9 +1,30 @@
#include <mie/dialect/dialect.h>
#include <mie/ir/op-definition.h>
#include <mie/ir/op.h>
#include <mie/macros.h>
#include <mie/print/printer.h>
static enum mie_status print(const struct mie_op *op, b_stream *out)
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
{
if (MIE_VECTOR_COUNT(op->op_args) != 1) {
return MIE_SUCCESS;
}
if (MIE_VECTOR_COUNT(op->op_successors) != 2) {
return MIE_SUCCESS;
}
const struct mie_op_arg *cond = &op->op_args.items[0];
const struct mie_op_successor *if_true = &op->op_successors.items[0];
const struct mie_op_successor *if_false = &op->op_successors.items[1];
b_stream_write_char(printer->p_stream, ' ');
mie_printer_print_op_arg(printer, cond, false);
b_stream_write_string(printer->p_stream, ", ", NULL);
mie_printer_print_op_successor(printer, if_true, true);
b_stream_write_string(printer->p_stream, ", ", NULL);
mie_printer_print_op_successor(printer, if_false, true);
return MIE_SUCCESS;
}

View File

@@ -1,9 +1,17 @@
#include <mie/dialect/dialect.h>
#include <mie/ir/block.h>
#include <mie/ir/op-definition.h>
#include <mie/ir/op.h>
#include <mie/macros.h>
#include <mie/print/printer.h>
static enum mie_status print(const struct mie_op *op, b_stream *out)
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
{
b_stream_write_char(printer->p_stream, ' ');
const struct mie_op_successor *successor = &op->op_successors.items[0];
mie_printer_print_op_successor(printer, successor, true);
return MIE_SUCCESS;
}

View File

@@ -4,4 +4,5 @@
MIE_DIALECT_BEGIN(mie_func, struct mie_dialect, "func")
MIE_DIALECT_ADD_OP(mie_func_func);
MIE_DIALECT_ADD_OP(mie_func_return);
MIE_DIALECT_END()

View File

@@ -1,13 +1,69 @@
#include <mie/attribute/attribute-map.h>
#include <mie/ctx.h>
#include <mie/dialect/builtin.h>
#include <mie/dialect/dialect.h>
#include <mie/interface/interface-definition.h>
#include <mie/interface/interface.h>
#include <mie/ir/block.h>
#include <mie/ir/op-definition.h>
#include <mie/ir/op.h>
#include <mie/ir/region.h>
#include <mie/macros.h>
#include <mie/print/printer.h>
#include <mie/type/function.h>
static enum mie_status print(const struct mie_op *op, b_stream *out)
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
{
const struct mie_attribute *sym_name
= mie_attribute_map_get(&op->op_attrib, "sym_name");
const struct mie_attribute *function_type_attr
= mie_attribute_map_get(&op->op_attrib, "function_type");
const char *sym_name_cstr = mie_string_get_cstr(sym_name);
const struct mie_type *function_type_g
= mie_type_attr_get_type(function_type_attr);
const struct mie_function_type *function_ty
= (const struct mie_function_type *)function_type_g;
b_stream_write_fmt(printer->p_stream, NULL, " @%s(", sym_name_cstr);
const struct mie_region *code = &op->op_regions.items[0];
const struct mie_block *entry = &code->r_blocks.items[0];
for (size_t i = 0; i < MIE_VECTOR_COUNT(entry->b_params); i++) {
if (i > 0) {
b_stream_write_string(printer->p_stream, ", ", NULL);
}
const struct mie_register *param = &entry->b_params.items[i];
mie_printer_print_register(printer, param, MIE_PRINT_F_INCLUDE_TYPE);
}
b_stream_write_string(printer->p_stream, ") -> ", NULL);
if (MIE_VECTOR_COUNT(function_ty->func_out) != 1) {
b_stream_write_char(printer->p_stream, '(');
}
for (size_t i = 0; i < MIE_VECTOR_COUNT(function_ty->func_out); i++) {
if (i > 0) {
b_stream_write_string(printer->p_stream, ", ", NULL);
}
const struct mie_type *ty = function_ty->func_out.items[i];
mie_printer_print_type(printer, ty);
}
if (MIE_VECTOR_COUNT(function_ty->func_out) != 1) {
b_stream_write_char(printer->p_stream, ')');
}
b_stream_write_char(printer->p_stream, ' ');
mie_printer_print_region(
printer, code, MIE_PRINT_F_EXCLUDE_FIRST_BLOCK_HEADER);
return MIE_SUCCESS;
}

View File

@@ -0,0 +1,49 @@
#include <mie/attribute/attribute-map.h>
#include <mie/ctx.h>
#include <mie/dialect/builtin.h>
#include <mie/dialect/dialect.h>
#include <mie/interface/interface-definition.h>
#include <mie/interface/interface.h>
#include <mie/ir/block.h>
#include <mie/ir/op-definition.h>
#include <mie/ir/op.h>
#include <mie/ir/region.h>
#include <mie/macros.h>
#include <mie/print/printer.h>
#include <mie/type/function.h>
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
{
b_stream_write_char(printer->p_stream, ' ');
for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_args); i++) {
if (i > 0) {
b_stream_write_string(printer->p_stream, ", ", NULL);
}
mie_printer_print_op_arg(printer, &op->op_args.items[i], false);
}
b_stream_write_string(printer->p_stream, " : ", NULL);
for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_args); i++) {
if (i > 0) {
b_stream_write_string(printer->p_stream, ", ", NULL);
}
mie_printer_print_type(
printer, mie_op_arg_get_type(&op->op_args.items[i]));
}
return MIE_SUCCESS;
}
static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
{
return MIE_SUCCESS;
}
MIE_OP_DEFINITION_BEGIN(mie_func_return, "return")
MIE_OP_DEFINITION_PRINT(print);
MIE_OP_DEFINITION_PARSE(parse);
MIE_OP_DEFINITION_END()

View File

@@ -0,0 +1,10 @@
#include <mie/dialect/dialect.h>
#include <mie/dialect/memref.h>
#include <mie/macros.h>
#include <mie/print/printer.h>
#include <mie/type/type-definition.h>
#include <mie/type/type.h>
MIE_DIALECT_BEGIN(mie_memref, struct mie_dialect, "memref")
MIE_DIALECT_ADD_TYPE(mie_memref_memref);
MIE_DIALECT_END()

View File

@@ -0,0 +1,52 @@
#include <mie/dialect/dialect.h>
#include <mie/dialect/memref.h>
#include <mie/macros.h>
#include <mie/print/printer.h>
#include <mie/type/type-definition.h>
#include <mie/type/type.h>
enum memref_rank_type {
MEMREF_RANK_UNKNOWN = 0,
MEMREF_RANK_STATIC,
MEMREF_RANK_TYPE,
};
struct memref_rank {
enum memref_rank_type r_ranktype;
union {
size_t r_static;
const struct mie_type *r_type;
};
};
struct memref_type {
struct mie_type m_base;
MIE_VECTOR_DECLARE(struct memref_rank, m_rank);
};
static void type_init(
const struct mie_type_definition *type_info, struct mie_type *type)
{
}
static enum mie_status print(const struct mie_type *ty, struct mie_printer *out)
{
b_stream_write_string(
out->p_stream,
(out->p_flags & MIE_PRINT_F_ABBREVIATED) ? "memref" : "memref.memref",
NULL);
return MIE_SUCCESS;
}
static enum mie_status parse(struct mie_parser *parser, const struct mie_type **out)
{
printf("Parse memref!\n");
return MIE_ERR_BAD_FORMAT;
}
MIE_TYPE_DEFINITION_BEGIN(mie_memref_memref, "memref")
MIE_TYPE_DEFINITION_INIT(type_init);
MIE_TYPE_DEFINITION_PRINT(print);
MIE_TYPE_DEFINITION_PARSE(parse);
MIE_TYPE_DEFINITION_END()

View File

@@ -2,7 +2,7 @@
#include <mie/ir/op-definition.h>
#include <mie/macros.h>
static enum mie_status print(const struct mie_op *op, b_stream *out)
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
{
return MIE_SUCCESS;
}

View File

@@ -2,7 +2,7 @@
#include <mie/ir/op-definition.h>
#include <mie/macros.h>
static enum mie_status print(const struct mie_op *op, b_stream *out)
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
{
return MIE_SUCCESS;
}

View File

@@ -2,7 +2,7 @@
#include <mie/ir/op-definition.h>
#include <mie/macros.h>
static enum mie_status print(const struct mie_op *op, b_stream *out)
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
{
return MIE_SUCCESS;
}

View File

@@ -2,7 +2,7 @@
#include <mie/ir/op-definition.h>
#include <mie/macros.h>
static enum mie_status print(const struct mie_op *op, b_stream *out)
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
{
return MIE_SUCCESS;
}

View File

@@ -2,7 +2,7 @@
#include <mie/ir/op-definition.h>
#include <mie/macros.h>
static enum mie_status print(const struct mie_op *op, b_stream *out)
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
{
return MIE_SUCCESS;
}

View File

@@ -2,7 +2,7 @@
#include <mie/ir/op-definition.h>
#include <mie/macros.h>
static enum mie_status print(const struct mie_op *op, b_stream *out)
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
{
return MIE_SUCCESS;
}

View File

@@ -4,7 +4,7 @@
#include <mie/macros.h>
#include <mie/trait/trait.h>
static enum mie_status print(const struct mie_op *op, b_stream *out)
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
{
return MIE_SUCCESS;
}

View File

@@ -114,7 +114,7 @@ void mie_id_to_string(const mie_id *id, char *out, size_t max)
b_bstr_write_char(&str, '-');
}
b_bstr_write_fmt(&str, "%02x", id->id_bytes[i]);
b_bstr_write_fmt(&str, NULL, "%02x", id->id_bytes[i]);
}
}

View File

@@ -26,4 +26,8 @@ struct mie_attribute_definition {
MIE_API struct mie_attribute_definition *mie_attribute_definition_create(
struct mie_dialect *parent, const char *name);
MIE_API bool mie_attribute_definition_check_name(
const struct mie_attribute_definition *def, const char *dialect_name,
const char *attrib_name);
#endif

View File

@@ -1,10 +1,17 @@
#ifndef MIE_ATTRIBUTE_ATTRIBUTE_H_
#define MIE_ATTRIBUTE_ATTRIBUTE_H_
#include <mie/misc.h>
#include <stdbool.h>
struct mie_attribute_definition;
struct mie_attribute {
const struct mie_attribute_definition *a_def;
};
MIE_API bool mie_attribute_check_name(
const struct mie_attribute *attrib, const char *dialect_name,
const char *attrib_name);
#endif

View File

@@ -6,10 +6,12 @@
#include <mie/id.h>
struct mie_op;
struct mie_pass;
struct mie_int_cache;
struct mie_index_cache;
struct mie_string_cache;
;
struct mie_attribute_map;
struct mie_pass_definition;
struct mie_ctx {
#if 0
@@ -27,6 +29,8 @@ struct mie_ctx {
struct mie_id_map ctx_traits;
/* map of struct mie_attribute */
struct mie_id_map ctx_attributes;
/* map of struct mie_pass_definition */
struct mie_id_map ctx_passes;
};
MIE_API struct mie_ctx *mie_ctx_create(void);
@@ -38,6 +42,8 @@ MIE_API struct mie_dialect *mie_ctx_get_dialect(
const struct mie_ctx *ctx, const char *name);
MIE_API struct mie_type_definition *mie_ctx_get_type_definition(
const struct mie_ctx *ctx, const char *dialect_name, const char *type_name);
MIE_API const struct mie_op_definition *mie_ctx_get_op_definition(
const struct mie_ctx *ctx, const char *dialect_name, const char *op_name);
MIE_API const struct mie_trait_definition *mie_ctx_get_trait_definition(
const struct mie_ctx *ctx, const char *dialect_name,
const char *trait_name);
@@ -59,4 +65,10 @@ MIE_API struct mie_type *mie_ctx_get_function_type(
MIE_API struct mie_value *mie_ctx_get_null(struct mie_ctx *ctx);
MIE_API enum mie_status mie_ctx_register_pass(
struct mie_ctx *ctx, struct mie_pass_definition *pass);
MIE_API enum mie_status mie_ctx_get_pass(
struct mie_ctx *ctx, const char *name,
const struct mie_attribute_map *args, struct mie_pass **out);
#endif

View File

@@ -6,6 +6,7 @@
#include <mie/interface/interface.h>
#include <mie/misc.h>
#include <mie/trait/trait.h>
#include <mie/vector.h>
struct mie_dialect;
@@ -54,6 +55,16 @@ struct mie_index {
size_t i_value;
};
struct mie_array {
struct mie_attribute a_base;
MIE_VECTOR_DECLARE(const struct mie_attribute *, a_items);
};
struct mie_type_attr {
struct mie_attribute ty_base;
const struct mie_type *ty_value;
};
struct mie_symbol {
struct mie_interface sym_base;
const char *(*sym_get_name)(const struct mie_op *);
@@ -100,6 +111,12 @@ MIE_API struct mie_attribute *mie_ctx_get_string(
struct mie_ctx *ctx, const char *s);
MIE_API struct mie_attribute *mie_ctx_get_index(struct mie_ctx *ctx, size_t val);
MIE_API const char *mie_string_get_cstr(const struct mie_attribute *attrib);
MIE_API const struct mie_type *mie_type_attr_get_type(
const struct mie_attribute *attrib);
MIE_API bool mie_int_get_value(const struct mie_attribute *attrib, long long *out);
MIE_API bool mie_float_get_value(const struct mie_attribute *attrib, double *out);
MIE_API struct mie_type *mie_ctx_get_int_type(struct mie_ctx *ctx, size_t bit_width);
MIE_API struct mie_type *mie_ctx_get_float_type(
struct mie_ctx *ctx, size_t bit_width);

View File

@@ -11,11 +11,14 @@ struct mie_register;
struct mie_block {
struct mie_name b_name;
struct mie_region *b_parent;
MIE_VECTOR_DECLARE(struct mie_register *, b_params);
MIE_VECTOR_DECLARE(struct mie_register, b_params);
MIE_VECTOR_DECLARE(struct mie_op, b_ops);
};
extern struct mie_vector_ops mie_block_vector_ops;
MIE_API struct mie_op *mie_block_add_op(struct mie_block *block);
#endif

View File

@@ -1,22 +0,0 @@
#ifndef MIE_IR_MODULE_H_
#define MIE_IR_MODULE_H_
#include <blue/core/stream.h>
#include <mie/misc.h>
#include <mie/name.h>
#include <mie/vector.h>
#include <stddef.h>
struct mie_op;
struct mie_module {
struct mie_name_map *m_names;
MIE_VECTOR_DECLARE(struct mie_op, m_ops);
};
MIE_API struct mie_module *mie_module_create(void);
MIE_API void mie_module_destroy(struct mie_module *mod);
MIE_API struct mie_op *mie_module_add_op(struct mie_module *mod);
#endif

View File

@@ -12,6 +12,7 @@
#define MIE_OP_MAX_RESULTS 8
struct mie_op;
struct mie_printer;
struct mie_parser;
struct mie_dialect;
@@ -101,7 +102,7 @@ struct mie_op_definition {
const struct mie_op_param op_params[MIE_OP_MAX_PARAMS];
const struct mie_op_result op_results[MIE_OP_MAX_RESULTS];
enum mie_status (*op_print)(const struct mie_op *, b_stream *);
enum mie_status (*op_print)(struct mie_printer *, const struct mie_op *);
enum mie_status (*op_parse)(struct mie_parser *, struct mie_op *);
};

View File

@@ -29,7 +29,7 @@ struct mie_op_arg {
struct mie_file_span arg_span;
union {
/* only valid if F_ARG_RESOLVED is set in arg_flags */
struct mie_register *arg_value;
struct mie_register_use arg_value;
/* only valid if F_ARG_RESOLVED is NOT set in arg_flags */
struct mie_register_ref arg_unresolved;
};
@@ -63,12 +63,20 @@ struct mie_op {
MIE_VECTOR_DECLARE(struct mie_op_successor, op_successors);
struct mie_attribute_map op_attrib;
MIE_VECTOR_DECLARE(struct mie_op_arg, op_args);
MIE_VECTOR_DECLARE(struct mie_register *, op_result);
MIE_VECTOR_DECLARE(struct mie_register, op_result);
};
MIE_API struct mie_op *mie_op_create(void);
MIE_API void mie_op_destroy(struct mie_op *op);
MIE_API struct mie_region *mie_op_add_region(struct mie_op *op);
MIE_API struct mie_op_successor *mie_op_add_successor(struct mie_op *op);
MIE_API void mie_op_init(struct mie_op *op);
MIE_API void mie_op_cleanup(struct mie_op *op);
MIE_API bool mie_op_has_trait(
const struct mie_op *op, const char *dialect_name, const char *trait_name);
MIE_API bool mie_op_has_interface(
const struct mie_op *op, const char *dialect_name, const char *iface_name);
MIE_API const struct mie_type *mie_op_arg_get_type(const struct mie_op_arg *arg);
#endif

View File

@@ -5,11 +5,13 @@
#include <mie/vector.h>
#include <stddef.h>
struct mie_op;
struct mie_block;
struct mie_region {
struct mie_name_map *r_names;
MIE_VECTOR_DECLARE(struct mie_block *, r_blocks);
struct mie_op *r_parent;
MIE_VECTOR_DECLARE(struct mie_block, r_blocks);
};
MIE_API struct mie_block *mie_region_add_block(struct mie_region *region);

View File

@@ -2,7 +2,10 @@
#define MIE_IR_REGISTER_H_
#include <mie/name.h>
#include <mie/vector.h>
struct mie_op;
struct mie_register;
struct mie_target_register;
enum mie_register_flags {
@@ -25,6 +28,13 @@ struct mie_register_ref {
const struct mie_type *reg_type;
};
/* represents a use of/resolved reference to a mie_register */
struct mie_register_use {
b_queue_entry u_entry;
struct mie_op *u_user;
struct mie_register *u_reg;
};
struct mie_register {
enum mie_register_flags reg_flags;
union {
@@ -46,6 +56,14 @@ struct mie_register {
* for which this register is a parameter
* if this is a BLOCK_PARAM register, this pointer is NULL */
struct mie_op *reg_op;
/* list of struct mie_register_use, representing all the places
* where this register is used. */
b_queue reg_use;
};
extern struct mie_vector_ops mie_register_vector_ops;
MIE_API void mie_register_move(struct mie_register *dest, struct mie_register *src);
MIE_API void mie_register_cleanup(struct mie_register *reg);
#endif

View File

@@ -0,0 +1,6 @@
#ifndef MIE_IR_REWRITE_H_
#define MIE_IR_REWRITE_H_
struct mie_rewriter;
#endif

44
mie/include/mie/ir/walk.h Normal file
View File

@@ -0,0 +1,44 @@
#ifndef MIE_IR_WALK_H_
#define MIE_IR_WALK_H_
#include <mie/misc.h>
#include <mie/status.h>
#include <stddef.h>
struct mie_op;
struct mie_walker;
enum mie_walker_flags {
MIE_WALKER_F_NONE = 0x00u,
/* 0: default behaviour */
MIE_WALKER_F_PREORDER = 0x00u,
MIE_WALKER_F_POSTORDER = 0x01u,
/* 0: default behaviour */
MIE_WALKER_F_FORWARD = 0x00u,
MIE_WALKER_F_BACKWARD = 0x02u,
MIE_WALKER_F_RECURSIVE = 0x04u,
MIE_WALKER_F_INCLUDE_OPS = 0x08u,
MIE_WALKER_F_INCLUDE_REGIONS = 0x10u,
MIE_WALKER_F_INCLUDE_BLOCKS = 0x20u,
};
struct mie_walker_item {
size_t i_depth;
struct mie_op *i_op;
struct mie_block *i_block;
struct mie_region *i_region;
};
MIE_API struct mie_walker *mie_walker_begin(
struct mie_op *op, enum mie_walker_flags flags);
MIE_API void mie_walker_end(struct mie_walker *walker);
MIE_API enum mie_status mie_walker_step(struct mie_walker *walker);
MIE_API struct mie_walker_item *mie_walker_get(struct mie_walker *walker);
#endif

View File

@@ -1,7 +1,11 @@
#ifndef MIE_MACROS_H_
#define MIE_MACROS_H_
#define __MIE_DIALECT_BEGIN(func_prefix, c_struct, dialect_name) \
/******************************************************************************/
/* DIALECT DEFINITION MACROS */
/******************************************************************************/
#define MIE_DIALECT_BEGIN(func_prefix, c_struct, dialect_name) \
struct mie_dialect *func_prefix##_dialect_create(struct mie_ctx *ctx) \
{ \
struct mie_dialect *self = mie_dialect_create( \
@@ -15,11 +19,38 @@
struct mie_attribute_definition *attribute = NULL; \
struct mie_interface_definition *interface = NULL;
#define __MIE_DIALECT_END() \
#define MIE_DIALECT_END() \
return self; \
}
#define __MIE_OP_DEFINITION_BEGIN(func_prefix, op_name) \
#define MIE_DIALECT_INIT(func) func(self)
#define MIE_DIALECT_CLEANUP(func) self->d_cleanup = (func)
#define MIE_DIALECT_ADD_OP(op_id) \
extern struct mie_op_definition *op_id##_op_create( \
struct mie_dialect *, struct mie_ctx *); \
op = op_id##_op_create(self, ctx)
#define MIE_DIALECT_ADD_TYPE(type_id) \
extern struct mie_type_definition *type_id##_type_create( \
struct mie_dialect *, struct mie_ctx *); \
type = type_id##_type_create(self, ctx)
#define MIE_DIALECT_ADD_TRAIT(trait_id) \
extern struct mie_trait_definition *trait_id##_trait_create( \
struct mie_dialect *, struct mie_ctx *); \
trait = trait_id##_trait_create(self, ctx)
#define MIE_DIALECT_ADD_ATTRIBUTE(attr_id) \
extern struct mie_attribute_definition *attr_id##_attribute_create( \
struct mie_dialect *, struct mie_ctx *); \
attribute = attr_id##_attribute_create(self, ctx)
#define MIE_DIALECT_ADD_INTERFACE(iface_id) \
extern struct mie_interface_definition *iface_id##_interface_create( \
struct mie_dialect *, struct mie_ctx *); \
interface = iface_id##_interface_create(self, ctx)
/******************************************************************************/
/* OP DEFINITION MACROS */
/******************************************************************************/
#define MIE_OP_DEFINITION_BEGIN(func_prefix, op_name) \
struct mie_op_definition *func_prefix##_op_create( \
struct mie_dialect *d, struct mie_ctx *ctx) \
{ \
@@ -32,11 +63,29 @@
struct mie_interface *i = NULL; \
const struct mie_interface_definition *id = NULL;
#define __MIE_OP_DEFINITION_END() \
#define MIE_OP_DEFINITION_END() \
return op; \
}
#define __MIE_TYPE_DEFINITION_BEGIN(func_prefix, type_name) \
#define MIE_OP_DEFINITION_PRINT(func) op->op_print = (func)
#define MIE_OP_DEFINITION_PARSE(func) op->op_parse = (func)
#define MIE_OP_DEFINITION_TRAIT(trait_dialect, trait_name) \
trait = mie_ctx_get_trait(ctx, trait_dialect, trait_name); \
mie_op_definition_add_trait(op, trait);
#define MIE_OP_INTERFACE_BEGIN(dialect_name, if_name, c_struct) \
id = mie_ctx_get_interface_definition(ctx, dialect_name, if_name); \
if (id) { \
c_struct *iface = (c_struct *)mie_interface_create(id);
#define MIE_OP_INTERFACE_FUNC(func_name) iface->func_name
#define MIE_OP_INTERFACE_END() \
mie_op_definition_add_interface(op, (struct mie_interface *)iface); \
}
/******************************************************************************/
/* TYPE DEFINITION MACROS */
/******************************************************************************/
#define MIE_TYPE_DEFINITION_BEGIN(func_prefix, type_name) \
struct mie_type_definition *func_prefix##_type_create( \
struct mie_dialect *d, struct mie_ctx *ctx) \
{ \
@@ -47,106 +96,10 @@
} \
const struct mie_trait *trait = NULL;
#define __MIE_TYPE_DEFINITION_END() \
#define MIE_TYPE_DEFINITION_END() \
return type; \
}
#define __MIE_TRAIT_DEFINITION_BEGIN(func_prefix, trait_name) \
struct mie_trait_definition *func_prefix##_trait_create( \
struct mie_dialect *d, struct mie_ctx *ctx) \
{ \
struct mie_trait_definition *trait \
= mie_trait_definition_create(d, trait_name); \
if (!trait) { \
return NULL; \
}
#define __MIE_TRAIT_DEFINITION_END() \
return trait; \
}
#define __MIE_ATTRIBUTE_DEFINITION_BEGIN(func_prefix, attribute_name) \
struct mie_attribute_definition *func_prefix##_attribute_create( \
struct mie_dialect *d, struct mie_ctx *ctx) \
{ \
struct mie_attribute_definition *attribute \
= mie_attribute_definition_create(d, attribute_name); \
if (!attribute) { \
return NULL; \
}
#define __MIE_ATTRIBUTE_DEFINITION_END() \
return attribute; \
}
#define __MIE_INTERFACE_DEFINITION_BEGIN(func_prefix, iface_name) \
struct mie_interface_definition *func_prefix##_interface_create( \
struct mie_dialect *d, struct mie_ctx *ctx) \
{ \
struct mie_interface_definition *i \
= mie_interface_definition_create(d, iface_name); \
if (!i) { \
return NULL; \
}
#define __MIE_INTERFACE_DEFINITION_END() \
return i; \
}
#define __MIE_DIALECT_INIT(func) func(self)
#define __MIE_DIALECT_CLEANUP(func) self->d_cleanup = (func)
#define __MIE_DIALECT_ADD_OP(op_id) \
extern struct mie_op_definition *op_id##_op_create( \
struct mie_dialect *, struct mie_ctx *); \
op = op_id##_op_create(self, ctx)
#define __MIE_DIALECT_ADD_TYPE(type_id) \
extern struct mie_type_definition *type_id##_type_create( \
struct mie_dialect *, struct mie_ctx *); \
type = type_id##_type_create(self, ctx)
#define __MIE_DIALECT_ADD_TRAIT(trait_id) \
extern struct mie_trait_definition *trait_id##_trait_create( \
struct mie_dialect *, struct mie_ctx *); \
trait = trait_id##_trait_create(self, ctx)
#define __MIE_DIALECT_ADD_ATTRIBUTE(attribute_id) \
extern struct mie_attribute_definition *attribute_id##_attribute_create( \
struct mie_dialect *, struct mie_ctx *); \
attribute = attribute_id##_attribute_create(self, ctx)
#define __MIE_DIALECT_ADD_INTERFACE(interface_id) \
extern struct mie_interface_definition *interface_id##_interface_create( \
struct mie_dialect *, struct mie_ctx *); \
interface = interface_id##_interface_create(self, ctx)
#define MIE_DIALECT_BEGIN(c_sym, c_struct, name) \
__MIE_DIALECT_BEGIN(c_sym, c_struct, name)
#define MIE_DIALECT_END() __MIE_DIALECT_END()
#define MIE_DIALECT_INIT(func) __MIE_DIALECT_INIT(func)
#define MIE_DIALECT_CLEANUP(func) __MIE_DIALECT_CLEANUP(func)
#define MIE_DIALECT_ADD_OP(c_sym) __MIE_DIALECT_ADD_OP(c_sym)
#define MIE_DIALECT_ADD_TYPE(c_sym) __MIE_DIALECT_ADD_TYPE(c_sym)
#define MIE_DIALECT_ADD_TRAIT(c_sym) __MIE_DIALECT_ADD_TRAIT(c_sym)
#define MIE_DIALECT_ADD_ATTRIBUTE(c_sym) __MIE_DIALECT_ADD_ATTRIBUTE(c_sym)
#define MIE_DIALECT_ADD_INTERFACE(c_sym) __MIE_DIALECT_ADD_INTERFACE(c_sym)
#define MIE_OP_DEFINITION_BEGIN(c_sym, op) __MIE_OP_DEFINITION_BEGIN(c_sym, op)
#define MIE_OP_DEFINITION_END() __MIE_OP_DEFINITION_END()
#define MIE_OP_DEFINITION_PRINT(func) op->op_print = (func)
#define MIE_OP_DEFINITION_PARSE(func) op->op_parse = (func)
#define MIE_OP_DEFINITION_TRAIT(trait_dialect, trait_name) \
trait = mie_ctx_get_trait(ctx, trait_dialect, trait_name); \
mie_op_definition_add_trait(op, trait);
#define MIE_OP_INTERFACE_BEGIN(dialect_name, if_name, c_struct) \
id = mie_ctx_get_interface_definition(ctx, dialect_name, if_name); \
if (id) { \
c_struct *iface = (c_struct *)mie_interface_create(id);
#define MIE_OP_INTERFACE_FUNC(func_name) iface->func_name
#define MIE_OP_INTERFACE_END() \
mie_op_definition_add_interface(op, (struct mie_interface *)iface); \
}
#define MIE_TYPE_DEFINITION_BEGIN(c_sym, type) \
__MIE_TYPE_DEFINITION_BEGIN(c_sym, type)
#define MIE_TYPE_DEFINITION_END() __MIE_TYPE_DEFINITION_END()
#define MIE_TYPE_DEFINITION_FLAGS(flags) type->ty_flags = flags
#define MIE_TYPE_DEFINITION_STRUCT(name) type->ty_data_size = sizeof(name)
#define MIE_TYPE_DEFINITION_INIT(func) type->ty_init = (func)
@@ -159,9 +112,24 @@
trait = mie_ctx_get_trait(ctx, trait_dialect, trait_name); \
mie_type_definition_add_trait(type, trait);
#define MIE_TRAIT_DEFINITION_BEGIN(c_sym, trait) \
__MIE_TRAIT_DEFINITION_BEGIN(c_sym, trait)
#define MIE_TRAIT_DEFINITION_END() __MIE_TRAIT_DEFINITION_END()
/******************************************************************************/
/* TRAIT DEFINITION MACROS */
/******************************************************************************/
#define MIE_TRAIT_DEFINITION_BEGIN(func_prefix, trait_name) \
struct mie_trait_definition *func_prefix##_trait_create( \
struct mie_dialect *d, struct mie_ctx *ctx) \
{ \
struct mie_trait_definition *trait \
= mie_trait_definition_create(d, trait_name); \
if (!trait) { \
return NULL; \
}
#define MIE_TRAIT_DEFINITION_END() \
return trait; \
}
#define MIE_TRAIT_DEFINITION_TARGETS(targets) trait->tr_target = (targets)
#define MIE_TRAIT_DEFINITION_STRUCT(name) trait->tr_data_size = sizeof(name)
#define MIE_TRAIT_DEFINITION_PRINT(func) trait->tr_print = (func)
@@ -169,9 +137,24 @@
#define MIE_TRAIT_DEFINITION_CLEANUP(func) trait->tr_cleanup = (func)
#define MIE_TRAIT_DEFINITION_VALIDATE(func) trait->tr_validate = (func)
#define MIE_ATTRIBUTE_DEFINITION_BEGIN(c_sym, attribute) \
__MIE_ATTRIBUTE_DEFINITION_BEGIN(c_sym, attribute)
#define MIE_ATTRIBUTE_DEFINITION_END() __MIE_ATTRIBUTE_DEFINITION_END()
/******************************************************************************/
/* ATTRIBUTE DEFINITION MACROS */
/******************************************************************************/
#define MIE_ATTRIBUTE_DEFINITION_BEGIN(func_prefix, attribute_name) \
struct mie_attribute_definition *func_prefix##_attribute_create( \
struct mie_dialect *d, struct mie_ctx *ctx) \
{ \
struct mie_attribute_definition *attribute \
= mie_attribute_definition_create(d, attribute_name); \
if (!attribute) { \
return NULL; \
}
#define MIE_ATTRIBUTE_DEFINITION_END() \
return attribute; \
}
#define MIE_ATTRIBUTE_DEFINITION_STRUCT(name) \
attribute->a_data_size = sizeof(name)
#define MIE_ATTRIBUTE_DEFINITION_INIT(func) attribute->a_init = (func)
@@ -179,9 +162,87 @@
#define MIE_ATTRIBUTE_DEFINITION_PRINT(func) attribute->a_print = (func)
#define MIE_ATTRIBUTE_DEFINITION_PARSE(func) attribute->a_parse = (func)
#define MIE_INTERFACE_DEFINITION_BEGIN(c_sym, iface) \
__MIE_INTERFACE_DEFINITION_BEGIN(c_sym, iface)
#define MIE_INTERFACE_DEFINITION_END() __MIE_INTERFACE_DEFINITION_END()
/******************************************************************************/
/* INTERFACE DEFINITION MACROS */
/******************************************************************************/
#define MIE_INTERFACE_DEFINITION_BEGIN(func_prefix, iface_name) \
struct mie_interface_definition *func_prefix##_interface_create( \
struct mie_dialect *d, struct mie_ctx *ctx) \
{ \
struct mie_interface_definition *i \
= mie_interface_definition_create(d, iface_name); \
if (!i) { \
return NULL; \
}
#define MIE_INTERFACE_DEFINITION_END() \
return i; \
}
#define MIE_INTERFACE_DEFINITION_STRUCT(name) i->if_size = sizeof(name)
/******************************************************************************/
/* PASS DEFINITION MACROS */
/******************************************************************************/
#define MIE_PASS_DEFINITION_BEGIN(prefix) \
struct mie_pass_definition *prefix##_pass_create(struct mie_ctx *ctx) \
{ \
struct mie_pass_definition *p = mie_pass_definition_create(); \
if (!p) { \
return NULL; \
}
#define MIE_PASS_DEFINITION_END() \
if (mie_ctx_register_pass(ctx, p) != MIE_SUCCESS) { \
return NULL; \
} \
return p; \
}
#define MIE_PASS_NAME(name) p->p_name = (name)
#define MIE_PASS_DESCRIPTION(desc) p->p_description = (desc)
#define MIE_PASS_STRUCT(c_struct) p->p_data_size = sizeof(c_struct)
#define MIE_PASS_TYPE(type) p->p_type = (type)
#define MIE_PASS_INIT(func) p->p_init = (func)
#define MIE_PASS_TRANSFORM(func) \
p->p_transform = (func); \
p->p_type = MIE_PASS_TRANSFORM
#define MIE_PASS_ANALYSE(func) \
p->p_analyse = (func); \
p->p_type = MIE_PASS_ANALYSE
#define MIE_PASS_FILTER_OP(dialect, op) \
p->p_filter.f_op = mie_ctx_get_op_definition(ctx, dialect, op)
#define MIE_PASS_FILTER_TRAIT(dialect, tr) \
p->p_filter.f_trait = mie_ctx_get_trait_definition(ctx, dialect, tr)
#define MIE_PASS_FILTER_INTERFACE(dialect, ifn) \
p->p_filter.f_iface = mie_ctx_get_iface_definition(ctx, dialect, ifn)
/******************************************************************************/
/* PASS GROUP MACROS */
/******************************************************************************/
#define MIE_PASS_GROUP_BEGIN(prefix) \
enum mie_status prefix##_passes_register(struct mie_ctx *ctx) \
{ \
struct mie_pass_definition *pass = NULL;
#define MIE_PASS_GROUP_END() \
return MIE_SUCCESS; \
}
#define MIE_PASS_GROUP_DECLARATION(prefix) \
enum mie_status prefix##_passes_register(struct mie_ctx *);
#define MIE_PASS_GROUP_ADD_PASS(id) \
do { \
extern struct mie_pass_definition *id##_pass_create( \
struct mie_ctx *); \
pass = id##_pass_create(ctx); \
if (!pass) { \
return MIE_ERR_INTERNAL_FAILURE; \
} \
} while (0)
#endif

View File

@@ -35,16 +35,26 @@ struct mie_name_map_entry {
};
};
struct mie_name_bucket {
struct mie_name_map_entry b_base;
b_queue b_names;
};
/* stores a unique name, and forms a binary tree of similar entries.
* this struct is designed to be embedded directly within a larger struct
* (rather than just as a pointer), allowing the larger struct to be part
* of a name map. Because of this, mie_name CANNOT be used in any memory that
* may be re-allocated. If a mie_name is moved after it is added to a
* mie_name_map, the internal bst pointers that make up the map will be
* invalidated, causing some very obscure memory-related errors. */
* invalidated, causing some very obscure memory-related errors.
*
* if mie_name IS stored in movable memory, care must be taken to use
* mie_name_move rather than memcpy/memmove to move the mie_name from
* one location to another. */
struct mie_name {
struct mie_name_map_entry n_base;
struct mie_name_map *n_parent;
struct mie_name_bucket *n_bucket;
char *n_str;
/* if this name was read from a file, these structs can be used to
@@ -52,11 +62,6 @@ struct mie_name {
struct mie_file_span n_start, n_end;
};
struct mie_name_bucket {
struct mie_name_map_entry b_base;
b_queue b_names;
};
struct mie_name_map {
const struct mie_name_map *m_parent;
b_btree m_entries;
@@ -73,6 +78,7 @@ extern struct mie_name *mie_name_map_put(
struct mie_name_map *map, struct mie_name *entry, const char *hint,
enum mie_name_map_flags flags);
extern void mie_name_move(struct mie_name *dst, struct mie_name *src);
extern void mie_name_destroy(struct mie_name *name);
#endif

View File

@@ -102,12 +102,13 @@ MIE_API bool mie_parser_parse_register(
struct mie_register *out);
MIE_API bool mie_parser_parse_register_list(
struct mie_parser *ctx, struct mie_name_map *names,
MIE_VECTOR_REF_PARAM(struct mie_register *, out));
MIE_VECTOR_REF_PARAM(struct mie_register, out));
MIE_API bool mie_parser_parse_region(
struct mie_parser *ctx, struct mie_region *region);
struct mie_parser *ctx, struct mie_op *parent, struct mie_region *region);
MIE_API bool mie_parser_parse_region_list(
struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_region, out));
struct mie_parser *ctx, struct mie_op *parent,
MIE_VECTOR_REF_PARAM(struct mie_region, out));
MIE_API bool mie_parser_parse_anonymous_block(
struct mie_parser *ctx, struct mie_name_map *names,
struct mie_block *block);

View File

@@ -0,0 +1,10 @@
#ifndef MIE_PASS_BUILTIN_H_
#define MIE_PASS_BUILTIN_H_
#include <mie/misc.h>
struct mie_ctx;
MIE_API enum mie_status mie_builtin_passes_register(struct mie_ctx *);
#endif

View File

@@ -0,0 +1,67 @@
#ifndef MIE_PASS_PASS_DEFINITION_H_
#define MIE_PASS_PASS_DEFINITION_H_
#include <mie/id.h>
#include <stddef.h>
#define MIE_PASS_CONTINUE \
((struct mie_pass_result) {.r_type = MIE_PASS_RESULT_CONTINUE, \
.r_status = MIE_SUCCESS})
#define MIE_PASS_INTERRUPT(status) \
((struct mie_pass_result) {.r_type = MIE_PASS_RESULT_INTERRUPT, \
.r_status = (status)})
struct mie_op;
struct mie_ctx;
struct mie_pass;
struct mie_op_definition;
struct mie_trait_definition;
struct mie_interface_definition;
struct mie_attribute_map;
enum mie_pass_type {
MIE_PASS_NONE = 0,
MIE_PASS_TRANSFORM,
MIE_PASS_ANALYSE,
};
enum mie_pass_result_type {
MIE_PASS_RESULT_CONTINUE = 0,
MIE_PASS_RESULT_INTERRUPT,
};
struct mie_pass_result {
enum mie_pass_result_type r_type;
enum mie_status r_status;
};
struct mie_pass_args {
struct mie_ctx *p_ctx;
};
struct mie_pass_filter {
const struct mie_op_definition *f_op;
const struct mie_trait_definition *f_trait;
const struct mie_interface_definition *f_iface;
};
struct mie_pass_definition {
mie_id p_id;
const char *p_name;
const char *p_description;
size_t p_data_size;
enum mie_pass_type p_type;
enum mie_status (*p_init)(
struct mie_pass *, const struct mie_attribute_map *);
struct mie_pass_result (*p_transform)(
struct mie_pass *, struct mie_op *, struct mie_pass_args *);
struct mie_pass_result (*p_analyse)(
struct mie_pass *, const struct mie_op *, struct mie_pass_args *);
struct mie_pass_filter p_filter;
};
MIE_API struct mie_pass_definition *mie_pass_definition_create(void);
#endif

View File

@@ -0,0 +1,46 @@
#ifndef MIE_PASS_PASS_MANAGER_H_
#define MIE_PASS_PASS_MANAGER_H_
#include <mie/pass/pass-definition.h>
#include <mie/status.h>
#include <mie/vector.h>
struct mie_pass;
struct mie_op;
struct mie_op_pass;
enum mie_pass_manager_flags {
MIE_PASSMGR_F_NONE = 0x00u,
};
struct mie_pass_manager {
enum mie_pass_manager_flags pm_flags;
struct mie_ctx *pm_ctx;
size_t pm_depth;
MIE_VECTOR_DECLARE(struct mie_pass *, pm_passes);
MIE_VECTOR_DECLARE(struct mie_pass_manager *, pm_nested);
struct mie_pass_filter pm_filter;
};
MIE_API struct mie_pass_manager *mie_pass_manager_create(struct mie_ctx *ctx);
MIE_API void mie_pass_manager_destroy(struct mie_pass_manager *pm);
MIE_API struct mie_pass_manager *mie_pass_manager_nest(struct mie_pass_manager *pm);
MIE_API enum mie_status mie_pass_manager_filter_op(
struct mie_pass_manager *pm, const char *dialect_name, const char *op_name);
MIE_API enum mie_status mie_pass_manager_filter_trait(
struct mie_pass_manager *pm, const char *dialect_name,
const char *trait_name);
MIE_API enum mie_status mie_pass_manager_filter_interface(
struct mie_pass_manager *pm, const char *dialect_name,
const char *iface_name);
MIE_API void mie_pass_manager_add_pass(
struct mie_pass_manager *pm, struct mie_pass *pass);
MIE_API struct mie_pass_result mie_pass_manager_run(
struct mie_pass_manager *pm, struct mie_op *target);
#endif

View File

@@ -0,0 +1,14 @@
#ifndef MIE_PASS_PASS_H_
#define MIE_PASS_PASS_H_
#include <mie/pass/pass-definition.h>
struct mie_pass {
const struct mie_pass_definition *p_def;
};
MIE_API const char *mie_pass_get_name(const struct mie_pass *pass);
MIE_API struct mie_pass_result mie_pass_execute(
struct mie_pass *pass, struct mie_op *op, struct mie_pass_args *args);
#endif

View File

@@ -8,6 +8,8 @@
struct mie_ctx;
struct mie_module;
struct mie_op;
struct mie_op_arg;
struct mie_op_successor;
struct mie_region;
struct mie_block;
struct mie_type;
@@ -17,6 +19,10 @@ struct mie_register;
enum mie_print_flags {
MIE_PRINT_F_GENERIC = 0x01u,
MIE_PRINT_F_ABBREVIATED = 0x02u,
MIE_PRINT_F_INCLUDE_TYPE = 0x04u,
MIE_PRINT_F_EXCLUDE_BLOCK_HEADER = 0x08u,
MIE_PRINT_F_EXCLUDE_FIRST_BLOCK_HEADER = 0x10u,
};
struct mie_printer {
@@ -34,14 +40,28 @@ MIE_API void mie_printer_print_module(
MIE_API void mie_printer_print_op(
struct mie_printer *printer, const struct mie_op *op);
MIE_API void mie_printer_print_region(
struct mie_printer *printer, const struct mie_region *region);
struct mie_printer *printer, const struct mie_region *region,
enum mie_print_flags flags);
MIE_API void mie_printer_print_block(
struct mie_printer *printer, const struct mie_block *block,
enum mie_print_flags flags);
MIE_API void mie_printer_print_block_ref(
struct mie_printer *printer, const struct mie_block *block);
MIE_API void mie_printer_print_type(
struct mie_printer *printer, const struct mie_type *type);
MIE_API void mie_printer_print_attribute(
struct mie_printer *printer, const struct mie_attribute *attrib);
MIE_API void mie_printer_print_register(
struct mie_printer *printer, const struct mie_register *reg);
struct mie_printer *printer, const struct mie_register *reg,
enum mie_print_flags flags);
MIE_API void mie_printer_print_op_name(
struct mie_printer *printer, const struct mie_op *op);
MIE_API void mie_printer_print_op_successor(
struct mie_printer *printer, const struct mie_op_successor *s,
bool compact);
MIE_API void mie_printer_print_op_arg(
struct mie_printer *printer, const struct mie_op_arg *arg,
bool include_type);
#endif

View File

@@ -13,13 +13,14 @@ enum mie_status {
MIE_ERR_BAD_SYNTAX,
MIE_ERR_BAD_FORMAT,
MIE_ERR_BAD_STATE,
MIE_ERR_NOT_SUPPORTED,
MIE_ERR_INVALID_VALUE,
MIE_ERR_INVALID_ARGUMENT,
MIE_ERR_INTERNAL_FAILURE,
MIE_ERR_NO_MEMORY,
MIE_ERR_NO_ENTRY,
MIE_ERR_NO_DATA,
MIE_ERR_NAME_EXISTS,
MIE_ERR_NOT_SUPPORTED,
MIE_ERR_INTERNAL_FAILURE,
};
MIE_API const struct b_error_vendor *mie_error_vendor(void);

View File

@@ -2,14 +2,14 @@
#define MIE_VECTOR_H_
#include <mie/misc.h>
#include <mie/status.h>
#include <stddef.h>
#if 0
#define MIE_VECTOR_DEFINE(type, name) \
size_t name##_count = 0; \
size_t name##_max = 0; \
type *name = NULL
#endif
struct mie_vector_ops {
enum mie_status (*v_copy)(void *, const void *, size_t);
enum mie_status (*v_move)(void *, void *, size_t);
enum mie_status (*v_destroy)(void *);
};
#define MIE_VECTOR_DEFINE(type, name) \
struct { \
@@ -43,52 +43,65 @@
#define MIE_VECTOR_REF2(name) &(name.items), &(name.count), &(name.max)
/* use these functions if you're accessing a vector directly. */
#define mie_vector_push_back(vector, ptr) \
#define mie_vector_push_back(vector, ptr, ops) \
__mie_vector_push_back( \
(void **)&(vector.items), ptr, sizeof *ptr, &(vector.count), \
&(vector.max))
#define mie_vector_pop_back(vector) \
&(vector.max), ops)
#define mie_vector_pop_back(vector, ops) \
__mie_vector_pop_back( \
(void **)&(vector), sizeof *vector, &(vector.count), \
&(vector.max))
#define mie_vector_emplace_back(vector) \
&(vector.max), ops)
#define mie_vector_emplace_back(vector, ops) \
__mie_vector_emplace_back( \
(void **)&(vector.items), sizeof *vector.items, \
&(vector.count), &(vector.max))
#define mie_vector_destroy(vector, dtor) \
&(vector.count), &(vector.max), ops)
#define mie_vector_trim(vector, ops) \
__mie_vector_trim( \
(void **)&(vector.items), sizeof *vector.items, \
&(vector.count), &(vector.max), ops)
#define mie_vector_destroy(vector, ops) \
__mie_vector_destroy( \
(void **)&(vector.items), sizeof *vector.items, \
&(vector.count), &(vector.max), dtor)
&(vector.count), &(vector.max), ops)
/* use these functions if you're accessing a vector as a reference
* via MIE_VECTOR_REF_PARAM. */
#define mie_vector_ref_push_back(vector, ptr) \
#define mie_vector_ref_push_back(vector, ptr, ops) \
__mie_vector_push_back( \
(void **)(vector), ptr, sizeof *ptr, (vector##_count), \
(vector##_max))
#define mie_vector_ref_pop_back(vector) \
(vector##_max), ops)
#define mie_vector_ref_pop_back(vector, ops) \
__mie_vector_pop_back( \
(void **)(vector), sizeof **vector, (vector##_count), \
(vector##_max))
#define mie_vector_ref_emplace_back(vector) \
(vector##_max), ops)
#define mie_vector_ref_emplace_back(vector, ops) \
__mie_vector_emplace_back( \
(void **)(vector), sizeof **vector, (vector##_count), \
(vector##_max))
#define mie_vector_ref_destroy(vector, dtor) \
(vector##_max), ops)
#define mie_vector_ref_trim(vector, ops) \
__mie_vector_trim( \
(void **)(vector), sizeof **vector, (vector##_count), \
(vector##_max), ops)
#define mie_vector_ref_destroy(vector, ops) \
__mie_vector_destroy( \
(void **)(vector), sizeof **vector, (vector##_count), \
(vector##_max), dtor)
(vector##_max), ops)
/* don't use these functions */
MIE_API int __mie_vector_push_back(
void **vector, const void *item, size_t item_size, size_t *count,
size_t *max);
size_t *max, const struct mie_vector_ops *ops);
MIE_API void __mie_vector_pop_back(
void **vector, size_t item_size, size_t *count, size_t *max);
void **vector, size_t item_size, size_t *count, size_t *max,
const struct mie_vector_ops *ops);
MIE_API void *__mie_vector_emplace_back(
void **vector, size_t item_size, size_t *count, size_t *max);
void **vector, size_t item_size, size_t *count, size_t *max,
const struct mie_vector_ops *ops);
MIE_API void __mie_vector_trim(
void **vector, size_t item_size, size_t *count, size_t *max,
const struct mie_vector_ops *ops);
MIE_API void __mie_vector_destroy(
void **vector, size_t item_size, size_t *count, size_t *max,
void (*dtor)(void *));
const struct mie_vector_ops *ops);
#endif

View File

@@ -1,28 +0,0 @@
#include <mie/ir/module.h>
#include <mie/ir/op.h>
#include <stdlib.h>
#include <string.h>
struct mie_module *mie_module_create(void)
{
struct mie_module *out = malloc(sizeof *out);
if (!out) {
return NULL;
}
memset(out, 0x0, sizeof *out);
out->m_names = mie_name_map_create(NULL);
return out;
}
void mie_module_destroy(struct mie_module *mod)
{
/* TODO */
}
struct mie_op *mie_module_add_op(struct mie_module *mod)
{
return mie_vector_emplace_back(mod->m_ops);
}

10
mie/ir/op-arg.c Normal file
View File

@@ -0,0 +1,10 @@
#include <mie/ir/op.h>
const struct mie_type *mie_op_arg_get_type(const struct mie_op_arg *arg)
{
if (arg->arg_flags & MIE_OP_F_ARG_RESOLVED) {
return arg->arg_value.u_reg->reg_type;
}
return arg->arg_unresolved.reg_type;
}

64
mie/ir/op.c Normal file
View File

@@ -0,0 +1,64 @@
#include <mie/ir/op-definition.h>
#include <mie/ir/op.h>
#include <stdlib.h>
struct mie_op *mie_op_create(void)
{
struct mie_op *out = malloc(sizeof *out);
if (!out) {
return NULL;
}
mie_op_init(out);
return out;
}
void mie_op_destroy(struct mie_op *op)
{
mie_op_cleanup(op);
free(op);
}
void mie_op_init(struct mie_op *op)
{
memset(op, 0x0, sizeof *op);
mie_attribute_map_init(&op->op_attrib);
}
void mie_op_cleanup(struct mie_op *op)
{
/* TODO */
}
bool mie_op_has_trait(
const struct mie_op *op, const char *dialect_name, const char *trait_name)
{
if (!op->op_info) {
return false;
}
if (mie_trait_table_get_unique(
&op->op_info->op_traits, dialect_name, trait_name)) {
return true;
}
struct mie_trait_table_iterator it;
enum mie_status status = mie_trait_table_get_generic(
&op->op_info->op_traits, dialect_name, trait_name, &it);
return (status == MIE_SUCCESS);
}
bool mie_op_has_interface(
const struct mie_op *op, const char *dialect_name, const char *iface_name)
{
if (!op->op_info) {
return false;
}
const struct mie_interface *p = mie_interface_map_get(
&op->op_info->op_iface, dialect_name, iface_name);
return p != NULL;
}

View File

@@ -5,14 +5,14 @@
struct mie_block *mie_region_add_block(struct mie_region *region)
{
struct mie_block *block = malloc(sizeof *block);
struct mie_block *block = mie_vector_emplace_back(
region->r_blocks, &mie_block_vector_ops);
if (!block) {
return NULL;
}
memset(block, 0x0, sizeof *block);
mie_vector_push_back(region->r_blocks, &block);
block->b_parent = region;
return block;
}

37
mie/ir/register.c Normal file
View File

@@ -0,0 +1,37 @@
#include <assert.h>
#include <mie/ir/register.h>
static enum mie_status cleanup(void *p)
{
mie_register_cleanup(p);
return MIE_SUCCESS;
}
static enum mie_status move(void *dst, void *src, size_t itemsz)
{
assert(itemsz == sizeof(struct mie_register));
struct mie_register *dest_reg = dst, *src_reg = src;
mie_register_move(dest_reg, src_reg);
return MIE_SUCCESS;
}
struct mie_vector_ops mie_register_vector_ops = {
.v_destroy = cleanup,
.v_move = move,
};
void mie_register_move(struct mie_register *dest, struct mie_register *src)
{
memmove(dest, src, sizeof *dest);
if (src->reg_flags & MIE_REGISTER_F_VIRTUAL) {
mie_name_move(&dest->reg_name, &src->reg_name);
}
}
void mie_register_cleanup(struct mie_register *reg)
{
if (reg->reg_flags & MIE_REGISTER_F_VIRTUAL) {
mie_name_destroy(&reg->reg_name);
}
}

0
mie/ir/rewrite.c Normal file
View File

347
mie/ir/walk.c Normal file
View File

@@ -0,0 +1,347 @@
#include <mie/ir/block.h>
#include <mie/ir/op.h>
#include <mie/ir/region.h>
#include <mie/ir/walk.h>
#define ITEM_TYPE(f) ((f) & 0x0Fu)
enum walk_schedule_item_flags {
SCHED_ITEM_F_NONE = 0,
SCHED_ITEM_F_OP = 0x01u,
SCHED_ITEM_F_BLOCK = 0x02u,
SCHED_ITEM_F_REGION = 0x04u,
SCHED_ITEM_F_VISITED = 0x10u,
SCHED_ITEM_F_CHILDREN_SCHEDULED = 0x20u,
};
struct walk_schedule_item {
enum walk_schedule_item_flags i_flags;
b_queue_entry i_entry;
size_t i_depth;
union {
struct mie_op *i_op;
struct mie_block *i_block;
struct mie_region *i_region;
};
};
struct mie_walker {
enum mie_walker_flags w_flags;
struct mie_op *w_root;
struct mie_walker_item w_cur;
b_queue w_sched;
};
static struct walk_schedule_item *op_schedule_item_create(struct mie_op *op)
{
struct walk_schedule_item *out = malloc(sizeof *out);
if (!out) {
return NULL;
}
memset(out, 0x0, sizeof *out);
out->i_flags = SCHED_ITEM_F_OP;
out->i_op = op;
return out;
}
static struct walk_schedule_item *block_schedule_item_create(struct mie_block *block)
{
struct walk_schedule_item *out = malloc(sizeof *out);
if (!out) {
return NULL;
}
memset(out, 0x0, sizeof *out);
out->i_flags = SCHED_ITEM_F_BLOCK;
out->i_block = block;
return out;
}
static struct walk_schedule_item *region_schedule_item_create(
struct mie_region *region)
{
struct walk_schedule_item *out = malloc(sizeof *out);
if (!out) {
return NULL;
}
memset(out, 0x0, sizeof *out);
out->i_flags = SCHED_ITEM_F_REGION;
out->i_region = region;
return out;
}
static bool should_ignore_item(
const struct mie_walker *walker, const struct walk_schedule_item *item)
{
switch (ITEM_TYPE(item->i_flags)) {
case SCHED_ITEM_F_OP:
return (walker->w_flags & MIE_WALKER_F_INCLUDE_OPS) == 0;
case SCHED_ITEM_F_BLOCK:
return (walker->w_flags & MIE_WALKER_F_INCLUDE_BLOCKS) == 0;
case SCHED_ITEM_F_REGION:
return (walker->w_flags & MIE_WALKER_F_INCLUDE_REGIONS) == 0;
default:
return true;
}
}
static void schedule_child(
struct mie_walker *walker, struct walk_schedule_item *parent,
struct walk_schedule_item *child, b_queue_entry **ep)
{
#define REVERSE 0x04u
enum {
PREORDER = 0x01u,
PREORDER_REVERSE = PREORDER | REVERSE,
POSTORDER = 0x02u,
POSTORDER_REVERSE = POSTORDER | REVERSE,
} mode;
if (walker->w_flags & MIE_WALKER_F_POSTORDER) {
mode = POSTORDER;
} else {
mode = PREORDER;
}
if (walker->w_flags & MIE_WALKER_F_BACKWARD) {
mode |= REVERSE;
}
child->i_depth = parent->i_depth;
if (!should_ignore_item(walker, child)) {
child->i_depth++;
}
switch (mode) {
case PREORDER:
b_queue_insert_after(&walker->w_sched, &child->i_entry, *ep);
*ep = &child->i_entry;
break;
case PREORDER_REVERSE:
b_queue_insert_after(
&walker->w_sched, &child->i_entry, &parent->i_entry);
*ep = &parent->i_entry;
break;
case POSTORDER:
if (*ep == &parent->i_entry) {
b_queue_insert_before(
&walker->w_sched, &child->i_entry, *ep);
} else {
b_queue_insert_after(
&walker->w_sched, &child->i_entry, *ep);
}
*ep = &child->i_entry;
break;
case POSTORDER_REVERSE:
b_queue_insert_before(&walker->w_sched, &child->i_entry, *ep);
*ep = &child->i_entry;
break;
default:
return;
}
#undef REVERSE
}
static enum mie_status schedule_children_of_region(
struct mie_walker *walker, struct walk_schedule_item *item)
{
struct mie_region *region = item->i_region;
b_queue_entry *tmp = &item->i_entry;
for (size_t i = 0; i < MIE_VECTOR_COUNT(region->r_blocks); i++) {
struct mie_block *block = &region->r_blocks.items[i];
struct walk_schedule_item *child
= block_schedule_item_create(block);
schedule_child(walker, item, child, &tmp);
}
return MIE_SUCCESS;
}
static enum mie_status schedule_children_of_block(
struct mie_walker *walker, struct walk_schedule_item *item)
{
struct mie_block *block = item->i_block;
b_queue_entry *tmp = &item->i_entry;
for (size_t i = 0; i < MIE_VECTOR_COUNT(block->b_ops); i++) {
struct mie_op *op = &block->b_ops.items[i];
struct walk_schedule_item *child = op_schedule_item_create(op);
schedule_child(walker, item, child, &tmp);
}
return MIE_SUCCESS;
}
static enum mie_status schedule_children_of_op(
struct mie_walker *walker, struct walk_schedule_item *item)
{
struct mie_op *op = item->i_op;
b_queue_entry *tmp = &item->i_entry;
for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_regions); i++) {
struct mie_region *region = &op->op_regions.items[i];
struct walk_schedule_item *child
= region_schedule_item_create(region);
schedule_child(walker, item, child, &tmp);
}
return MIE_SUCCESS;
}
static enum mie_status schedule_children(
struct mie_walker *walker, struct walk_schedule_item *item)
{
if (item->i_flags & SCHED_ITEM_F_CHILDREN_SCHEDULED) {
return MIE_SUCCESS;
}
enum mie_status status;
switch (ITEM_TYPE(item->i_flags)) {
case SCHED_ITEM_F_BLOCK:
status = schedule_children_of_block(walker, item);
break;
case SCHED_ITEM_F_REGION:
status = schedule_children_of_region(walker, item);
break;
case SCHED_ITEM_F_OP:
status = schedule_children_of_op(walker, item);
break;
default:
status = MIE_ERR_BAD_STATE;
break;
}
item->i_flags |= SCHED_ITEM_F_CHILDREN_SCHEDULED;
return MIE_SUCCESS;
}
static enum mie_status prepare_postorder_traversal(struct mie_walker *walker)
{
b_queue_entry *cur = b_queue_last(&walker->w_sched);
while (cur) {
struct walk_schedule_item *item
= b_unbox(struct walk_schedule_item, cur, i_entry);
schedule_children(walker, item);
cur = b_queue_prev(cur);
}
return MIE_SUCCESS;
}
struct mie_walker *mie_walker_begin(struct mie_op *op, enum mie_walker_flags flags)
{
struct mie_walker *out = malloc(sizeof *out);
if (!out) {
return NULL;
}
memset(out, 0x0, sizeof *out);
out->w_flags = flags;
out->w_root = op;
struct walk_schedule_item *item = op_schedule_item_create(op);
b_queue_push_back(&out->w_sched, &item->i_entry);
if (flags & MIE_WALKER_F_POSTORDER) {
prepare_postorder_traversal(out);
}
return out;
}
void mie_walker_end(struct mie_walker *walker)
{
}
static struct walk_schedule_item *current_item(struct mie_walker *walker)
{
b_queue_entry *top = b_queue_first(&walker->w_sched);
if (!top) {
return NULL;
}
return b_unbox(struct walk_schedule_item, top, i_entry);
}
static enum mie_status step(struct mie_walker *walker)
{
struct walk_schedule_item *cur = current_item(walker);
if (!cur) {
return MIE_ERR_NO_DATA;
}
if (walker->w_flags & MIE_WALKER_F_RECURSIVE || cur->i_depth == 0) {
schedule_children(walker, cur);
}
b_queue_delete(&walker->w_sched, &cur->i_entry);
free(cur);
if (!current_item(walker)) {
return MIE_ERR_NO_DATA;
}
return MIE_SUCCESS;
}
enum mie_status mie_walker_step(struct mie_walker *walker)
{
struct walk_schedule_item *cur = current_item(walker);
do {
step(walker);
cur = current_item(walker);
} while (cur && should_ignore_item(walker, cur));
return cur ? MIE_SUCCESS : MIE_ERR_NO_DATA;
}
struct mie_walker_item *mie_walker_get(struct mie_walker *walker)
{
struct walk_schedule_item *cur = current_item(walker);
if (!cur) {
return NULL;
}
memset(&walker->w_cur, 0x0, sizeof walker->w_cur);
walker->w_cur.i_depth = cur->i_depth;
switch (ITEM_TYPE(cur->i_flags)) {
case SCHED_ITEM_F_OP:
walker->w_cur.i_op = cur->i_op;
break;
case SCHED_ITEM_F_BLOCK:
walker->w_cur.i_block = cur->i_block;
break;
case SCHED_ITEM_F_REGION:
walker->w_cur.i_region = cur->i_region;
break;
default:
return NULL;
}
return &walker->w_cur;
}

View File

@@ -88,6 +88,7 @@ static b_status put_name_in_bucket(
}
b_queue_push_back(&bucket->b_names, &name->n_base.e_entry);
name->n_bucket = bucket;
return B_SUCCESS;
}
@@ -125,6 +126,8 @@ static b_status put_name(struct mie_name_map *map, struct mie_name *name)
b_queue_push_back(&bucket->b_names, &existing_name->n_base.e_entry);
b_queue_push_back(&bucket->b_names, &name->n_base.e_entry);
existing_name->n_bucket = name->n_bucket = bucket;
put_entry(&map->m_entries, &bucket->b_base);
return B_SUCCESS;
@@ -279,6 +282,26 @@ struct mie_name *mie_name_map_put(
return NULL;
}
void mie_name_move(struct mie_name *dst, struct mie_name *src)
{
if (!src->n_parent) {
memmove(dst, src, sizeof *src);
return;
}
memmove(dst, src, sizeof *src);
if (src->n_bucket) {
b_queue_move(
&src->n_bucket->b_names, &dst->n_base.e_entry,
&src->n_base.e_entry);
} else {
b_btree_move(
&src->n_parent->m_entries, &dst->n_base.e_node,
&src->n_base.e_node);
}
}
void mie_name_destroy(struct mie_name *name)
{
struct mie_name_map *parent = name->n_parent;

View File

@@ -5,7 +5,6 @@
#include <mie/dialect/dialect.h>
#include <mie/dialect/index.h>
#include <mie/ir/block.h>
#include <mie/ir/module.h>
#include <mie/ir/op.h>
#include <mie/ir/region.h>
#include <mie/ir/register.h>
@@ -355,8 +354,25 @@ static bool parse_type_name(struct mie_parser *ctx, const struct mie_type **out)
return false;
}
*out = NULL;
return false;
const struct mie_type_definition *ty_def
= get_type_by_full_name(ctx, name);
if (!ty_def) {
return false;
}
const struct mie_type *ty = NULL;
enum mie_status status = MIE_SUCCESS;
if (ty_def->ty_parse) {
status = ty_def->ty_parse(ctx, &ty);
} else {
ty = mie_ctx_get_type(
ctx->p_ctx, ty_def->ty_parent->d_name, ty_def->ty_name);
}
*out = ty;
return ty != NULL;
}
static bool parse_composite_type(struct mie_parser *ctx, const struct mie_type **out)
@@ -382,7 +398,7 @@ static bool parse_composite_type(struct mie_parser *ctx, const struct mie_type *
ok = mie_parser_parse_type(ctx, &temp);
if (temp) {
mie_vector_push_back(type_list_2, &temp);
mie_vector_push_back(type_list_2, &temp, NULL);
}
}
@@ -433,13 +449,13 @@ bool mie_parser_parse_type_list(
return true;
}
type_slot = mie_vector_ref_emplace_back(out);
type_slot = mie_vector_ref_emplace_back(out, NULL);
if (!type_slot) {
return false;
}
if (!mie_parser_parse_type(ctx, type_slot)) {
mie_vector_ref_pop_back(out);
mie_vector_ref_pop_back(out, NULL);
return false;
}
@@ -448,13 +464,13 @@ bool mie_parser_parse_type_list(
break;
}
type_slot = mie_vector_ref_emplace_back(out);
type_slot = mie_vector_ref_emplace_back(out, NULL);
if (!type_slot) {
return false;
}
if (!mie_parser_parse_type(ctx, type_slot)) {
mie_vector_ref_pop_back(out);
mie_vector_ref_pop_back(out, NULL);
return false;
}
}
@@ -490,7 +506,7 @@ MIE_API bool mie_parser_parse_function_type(
ok = mie_parser_parse_type(ctx, &type);
if (type) {
mie_vector_push_back(out_parts, &type);
mie_vector_push_back(out_parts, &type, NULL);
}
}
@@ -542,7 +558,7 @@ bool mie_parser_parse_operand_list(
return false;
}
operand = mie_vector_ref_emplace_back(out);
operand = mie_vector_ref_emplace_back(out, NULL);
if (!operand) {
return false;
}
@@ -566,7 +582,7 @@ bool mie_parser_parse_operand_list(
return false;
}
operand = mie_vector_ref_emplace_back(out);
operand = mie_vector_ref_emplace_back(out, NULL);
if (!operand) {
return false;
}
@@ -618,7 +634,7 @@ bool mie_parser_parse_parameter_list(
return false;
}
operand = mie_vector_ref_emplace_back(out);
operand = mie_vector_ref_emplace_back(out, NULL);
if (!operand) {
return false;
}
@@ -642,7 +658,7 @@ bool mie_parser_parse_parameter_list(
return false;
}
operand = mie_vector_ref_emplace_back(out);
operand = mie_vector_ref_emplace_back(out, NULL);
if (!operand) {
return false;
}
@@ -660,6 +676,10 @@ bool mie_parser_parse_register(
{
memset(out, 0x0, sizeof *out);
if (!names) {
return false;
}
struct mie_token *tok = mie_parser_peek(ctx);
enum mie_token_type type = MIE_TOKEN_TYPE(tok);
switch (type) {
@@ -697,7 +717,7 @@ bool mie_parser_parse_register(
bool mie_parser_parse_register_list(
struct mie_parser *ctx, struct mie_name_map *names,
MIE_VECTOR_REF_PARAM(struct mie_register *, out))
MIE_VECTOR_REF_PARAM(struct mie_register, out))
{
bool ok = false;
struct mie_register *reg = NULL;
@@ -708,12 +728,7 @@ bool mie_parser_parse_register_list(
return false;
}
reg = calloc(1, sizeof *reg);
if (!reg) {
return false;
}
mie_vector_ref_push_back(out, &reg);
reg = mie_vector_ref_emplace_back(out, &mie_register_vector_ops);
if (!mie_parser_parse_register(ctx, names, reg)) {
return false;
@@ -734,11 +749,7 @@ bool mie_parser_parse_register_list(
return false;
}
reg = calloc(1, sizeof *reg);
if (!reg) {
return false;
}
mie_vector_ref_push_back(out, &reg);
reg = mie_vector_ref_emplace_back(out, &mie_register_vector_ops);
if (!mie_parser_parse_register(ctx, names, reg)) {
return false;
@@ -748,44 +759,11 @@ bool mie_parser_parse_register_list(
return true;
}
bool mie_parser_parse_module(struct mie_parser *ctx, struct mie_module *mod)
{
#define OP_TOKEN_TYPES \
(MIE_TOK_NAME | MIE_TOK_OPNAME | MIE_TOK_VREGNAME | MIE_TOK_MREGNAME \
| MIE_TOK_GRAPHNAME | MIE_TOK_INSTNAME)
for (size_t i = 0;; i++) {
if (mie_parser_check_eof(ctx)) {
break;
}
if (i > 0 && !mie_parser_parse_linefeed(ctx)) {
return false;
}
enum mie_token_type type = mie_parser_peek_type(ctx);
bool is_op = (type & OP_TOKEN_TYPES);
if (!is_op) {
break;
}
struct mie_op *op = mie_module_add_op(mod);
if (!op) {
return false;
}
if (!mie_parser_parse_op(ctx, mod->m_names, op)) {
return false;
}
}
return true;
}
bool mie_parser_parse_region(struct mie_parser *ctx, struct mie_region *region)
bool mie_parser_parse_region(
struct mie_parser *ctx, struct mie_op *parent, struct mie_region *region)
{
region->r_names = mie_name_map_create(NULL);
region->r_parent = parent;
if (!mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_BRACE)) {
return false;
@@ -821,15 +799,16 @@ bool mie_parser_parse_region(struct mie_parser *ctx, struct mie_region *region)
}
bool mie_parser_parse_region_list(
struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_region, out))
struct mie_parser *ctx, struct mie_op *parent,
MIE_VECTOR_REF_PARAM(struct mie_region, out))
{
if (!mie_parser_check_symbol(ctx, MIE_SYM_LEFT_BRACE)) {
return false;
}
struct mie_region *region = mie_vector_ref_emplace_back(out);
struct mie_region *region = mie_vector_ref_emplace_back(out, NULL);
if (!mie_parser_parse_region(ctx, region)) {
if (!mie_parser_parse_region(ctx, parent, region)) {
return false;
}
@@ -842,9 +821,10 @@ bool mie_parser_parse_region_list(
break;
}
struct mie_region *region = mie_vector_ref_emplace_back(out);
struct mie_region *region = mie_vector_ref_emplace_back(out, NULL);
if (!mie_parser_parse_region(ctx, parent, region)) {
if (!mie_parser_parse_region(ctx, region)) {
return false;
}
}
@@ -857,7 +837,9 @@ bool mie_parser_parse_anonymous_block(
{
mie_parser_parse_linefeed(ctx);
struct mie_op *op = mie_vector_emplace_back(block->b_ops);
struct mie_op *op = mie_vector_emplace_back(block->b_ops, NULL);
mie_op_init(op);
if (!mie_parser_parse_op(ctx, names, op)) {
return false;
}
@@ -873,7 +855,9 @@ bool mie_parser_parse_anonymous_block(
break;
}
struct mie_op *op = mie_vector_emplace_back(block->b_ops);
struct mie_op *op = mie_vector_emplace_back(block->b_ops, NULL);
mie_op_init(op);
if (!mie_parser_parse_op(ctx, names, op)) {
return false;
}
@@ -889,6 +873,10 @@ bool mie_parser_parse_anonymous_block(
static bool parse_block_parameters(
struct mie_parser *ctx, struct mie_name_map *names, struct mie_block *block)
{
if (!names) {
return false;
}
if (!mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_PAREN)) {
return false;
}
@@ -905,8 +893,8 @@ static bool parse_block_parameters(
}
for (size_t i = 0; i < MIE_VECTOR_COUNT(block_params); i++) {
struct mie_register *param_reg = calloc(1, sizeof *param_reg);
mie_vector_push_back(block->b_params, &param_reg);
struct mie_register *param_reg = mie_vector_emplace_back(
block->b_params, &mie_register_vector_ops);
param_reg->reg_flags = block_params.items[i].arg_unresolved.reg_flags
| MIE_REGISTER_F_BLOCK_PARAM;
@@ -926,6 +914,10 @@ static bool parse_block_parameters(
bool mie_parser_parse_block(
struct mie_parser *ctx, struct mie_name_map *names, struct mie_block *block)
{
if (!names) {
return NULL;
}
b_string *str = get_temp_string(ctx);
struct mie_file_span span;
@@ -958,7 +950,8 @@ bool mie_parser_parse_block(
break;
}
struct mie_op *op = mie_vector_emplace_back(block->b_ops);
struct mie_op *op = mie_vector_emplace_back(block->b_ops, NULL);
mie_op_init(op);
if (!mie_parser_parse_op(ctx, names, op)) {
return false;
}
@@ -1021,7 +1014,7 @@ bool mie_parser_parse_successor_list(
bool ok = false;
struct mie_op_successor *successor = NULL;
successor = mie_vector_ref_emplace_back(out);
successor = mie_vector_ref_emplace_back(out, NULL);
if (!successor) {
return false;
}
@@ -1040,7 +1033,7 @@ bool mie_parser_parse_successor_list(
mie_parser_advance(ctx);
mie_parser_parse_linefeed(ctx);
successor = mie_vector_ref_emplace_back(out);
successor = mie_vector_ref_emplace_back(out, NULL);
if (!successor) {
return false;
}
@@ -1098,29 +1091,7 @@ static bool parse_generic_op(
if (mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_PAREN)) {
mie_parser_parse_linefeed(ctx);
if (!mie_parser_parse_region_list(
ctx, MIE_VECTOR_REF(dest->op_regions))) {
return false;
}
if (!mie_parser_parse_symbol(ctx, MIE_SYM_RIGHT_PAREN)) {
return false;
}
}
if (mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_BRACKET)) {
if (!mie_parser_parse_successor_list(
ctx, MIE_VECTOR_REF(dest->op_successors))) {
return false;
}
if (!mie_parser_parse_symbol(ctx, MIE_SYM_RIGHT_BRACKET)) {
return false;
}
}
if (mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_PAREN)) {
if (!mie_parser_parse_region_list(
ctx, MIE_VECTOR_REF(dest->op_regions))) {
ctx, dest, MIE_VECTOR_REF(dest->op_regions))) {
return false;
}
@@ -1164,7 +1135,7 @@ static bool parse_generic_op(
}
for (size_t i = 0; i < MIE_VECTOR_COUNT(func_type->func_out); i++) {
dest->op_result.items[i]->reg_type = func_type->func_out.items[i];
dest->op_result.items[i].reg_type = func_type->func_out.items[i];
}
return true;
@@ -1244,6 +1215,10 @@ bool mie_parser_parse_attribute(
attribute = mie_ctx_get_attribute_definition(
ctx->p_ctx, "builtin", "dict");
break;
case MIE_SYM_LEFT_PAREN:
attribute = mie_ctx_get_attribute_definition(
ctx->p_ctx, "builtin", "type");
break;
default:
break;
}
@@ -1273,7 +1248,7 @@ bool mie_parser_parse_attribute(
return false;
}
if (!attribute->a_parse(ctx, dest)) {
if (attribute->a_parse(ctx, dest) != MIE_SUCCESS) {
return false;
}

View File

@@ -0,0 +1,7 @@
#include <mie/ctx.h>
#include <mie/macros.h>
#include <mie/pass/pass-definition.h>
MIE_PASS_GROUP_BEGIN(mie_builtin)
MIE_PASS_GROUP_ADD_PASS(prefix_func_with_underscore);
MIE_PASS_GROUP_END()

View File

@@ -0,0 +1,35 @@
#include <mie/ctx.h>
#include <mie/dialect/builtin.h>
#include <mie/ir/op.h>
#include <mie/macros.h>
#include <mie/pass/pass-definition.h>
#include <mie/pass/pass.h>
static struct mie_pass_result transform(
struct mie_pass *pass, struct mie_op *op, struct mie_pass_args *args)
{
const struct mie_attribute *sym_name_attr
= mie_attribute_map_get(&op->op_attrib, "sym_name");
const char *sym_name = mie_string_get_cstr(sym_name_attr);
char tmp[256];
snprintf(tmp, sizeof tmp, "_%s", sym_name);
const struct mie_attribute *new_name
= mie_ctx_get_string(args->p_ctx, tmp);
mie_attribute_map_put(
&op->op_attrib, "sym_name", new_name, MIE_ATTRMAP_F_REPLACE);
printf("%s: taking a look at @%s\n", mie_pass_get_name(pass), sym_name);
return MIE_PASS_CONTINUE;
}
MIE_PASS_DEFINITION_BEGIN(prefix_func_with_underscore)
MIE_PASS_NAME("prefix-func-with-underscore");
MIE_PASS_DESCRIPTION(
"Test pass that prefixes the identifier of every function with "
"an underscore.");
MIE_PASS_TRANSFORM(transform);
MIE_PASS_FILTER_OP("func", "func");
MIE_PASS_DEFINITION_END()

View File

@@ -0,0 +1,16 @@
#include <mie/pass/pass-definition.h>
#include <mie/pass/pass.h>
struct mie_pass_definition *mie_pass_definition_create(void)
{
struct mie_pass_definition *out = malloc(sizeof *out);
if (!out) {
return NULL;
}
memset(out, 0x0, sizeof *out);
out->p_data_size = sizeof(struct mie_pass);
return out;
}

271
mie/pass/pass-manager.c Normal file
View File

@@ -0,0 +1,271 @@
#include <blue/core/queue.h>
#include <mie/ctx.h>
#include <mie/dialect/dialect.h>
#include <mie/interface/interface-definition.h>
#include <mie/ir/block.h>
#include <mie/ir/op.h>
#include <mie/ir/region.h>
#include <mie/ir/walk.h>
#include <mie/pass/pass-definition.h>
#include <mie/pass/pass-manager.h>
#include <mie/pass/pass.h>
#include <mie/trait/trait-definition.h>
#include <stdlib.h>
#include <string.h>
struct pass_sched {
struct mie_op *s_op;
b_queue_entry s_entry;
/* queue of struct pass_sched_item */
b_queue s_items;
};
struct pass_sched_item {
b_queue_entry i_entry;
struct mie_pass *i_pass;
};
static struct pass_sched *pass_sched_create(struct mie_op *op)
{
struct pass_sched *out = malloc(sizeof *out);
if (!out) {
return NULL;
}
memset(out, 0x0, sizeof *out);
out->s_op = op;
return out;
}
static struct pass_sched_item *pass_sched_item_create(struct mie_pass *pass)
{
struct pass_sched_item *out = malloc(sizeof *out);
if (!out) {
return NULL;
}
memset(out, 0x0, sizeof *out);
out->i_pass = pass;
return out;
}
struct mie_pass_manager *mie_pass_manager_create(struct mie_ctx *ctx)
{
struct mie_pass_manager *out = malloc(sizeof *out);
if (!out) {
return NULL;
}
memset(out, 0x0, sizeof *out);
out->pm_ctx = ctx;
return out;
}
void mie_pass_manager_destroy(struct mie_pass_manager *pm)
{
/* TODO */
}
struct mie_pass_manager *mie_pass_manager_nest(struct mie_pass_manager *pm)
{
struct mie_pass_manager *nest = mie_pass_manager_create(pm->pm_ctx);
nest->pm_depth = pm->pm_depth + 1;
mie_vector_push_back(pm->pm_nested, &nest, NULL);
return nest;
}
enum mie_status mie_pass_manager_filter_op(
struct mie_pass_manager *pm, const char *dialect_name, const char *op_name)
{
if (!dialect_name && !op_name) {
pm->pm_filter.f_op = NULL;
return MIE_SUCCESS;
}
if (!dialect_name || !op_name) {
return MIE_ERR_INVALID_ARGUMENT;
}
const struct mie_op_definition *op
= mie_ctx_get_op_definition(pm->pm_ctx, dialect_name, op_name);
if (!op) {
return MIE_ERR_NO_ENTRY;
}
pm->pm_filter.f_op = op;
return MIE_SUCCESS;
}
enum mie_status mie_pass_manager_filter_trait(
struct mie_pass_manager *pm, const char *dialect_name, const char *trait_name)
{
if (!dialect_name && !trait_name) {
pm->pm_filter.f_trait = NULL;
return MIE_SUCCESS;
}
if (!dialect_name || !trait_name) {
return MIE_ERR_INVALID_ARGUMENT;
}
const struct mie_trait_definition *trait = mie_ctx_get_trait_definition(
pm->pm_ctx, dialect_name, trait_name);
if (!trait) {
return MIE_ERR_NO_ENTRY;
}
pm->pm_filter.f_trait = trait;
return MIE_SUCCESS;
}
enum mie_status mie_pass_manager_filter_interface(
struct mie_pass_manager *pm, const char *dialect_name, const char *iface_name)
{
if (!dialect_name && !iface_name) {
pm->pm_filter.f_iface = NULL;
return MIE_SUCCESS;
}
if (!dialect_name || !iface_name) {
return MIE_ERR_INVALID_ARGUMENT;
}
const struct mie_interface_definition *interface = mie_ctx_get_interface_definition(
pm->pm_ctx, dialect_name, iface_name);
if (!interface) {
return MIE_ERR_NO_ENTRY;
}
pm->pm_filter.f_iface = interface;
return MIE_SUCCESS;
}
static bool filter_check_op(
const struct mie_pass_filter *filter, const struct mie_op *op)
{
if (filter->f_op && op->op_info != filter->f_op) {
return false;
}
if (filter->f_trait
&& !mie_op_has_trait(
op, filter->f_trait->tr_parent->d_name,
filter->f_trait->tr_name)) {
return false;
}
if (filter->f_iface
&& !mie_op_has_interface(
op, filter->f_iface->if_parent->d_name,
filter->f_iface->if_name)) {
return false;
}
return true;
}
void mie_pass_manager_add_pass(struct mie_pass_manager *pm, struct mie_pass *pass)
{
mie_vector_push_back(pm->pm_passes, &pass, NULL);
}
static void schedule_passes(
struct mie_pass_manager *pm, b_queue *schedule, struct mie_op *op,
size_t depth)
{
b_queue passes = B_QUEUE_INIT;
if (!filter_check_op(&pm->pm_filter, op) || depth > pm->pm_depth) {
return;
}
for (size_t i = 0; i < MIE_VECTOR_COUNT(pm->pm_passes); i++) {
struct mie_pass *pass = pm->pm_passes.items[i];
if (!filter_check_op(&pass->p_def->p_filter, op)) {
continue;
}
struct pass_sched_item *item = pass_sched_item_create(pass);
b_queue_push_back(&passes, &item->i_entry);
}
if (!b_queue_empty(&passes)) {
struct pass_sched *sched = pass_sched_create(op);
sched->s_items = passes;
b_queue_push_back(schedule, &sched->s_entry);
}
struct mie_walker *walker = mie_walker_begin(op, MIE_WALKER_F_INCLUDE_OPS);
while (mie_walker_step(walker) == MIE_SUCCESS) {
for (size_t i = 0; i < MIE_VECTOR_COUNT(pm->pm_nested); i++) {
struct mie_pass_manager *nested = pm->pm_nested.items[i];
struct mie_walker_item *item = mie_walker_get(walker);
schedule_passes(nested, schedule, item->i_op, depth + 1);
}
}
mie_walker_end(walker);
}
static void sched_item_execute(
struct pass_sched_item *sched_item, struct mie_op *op,
struct mie_pass_args *args, struct mie_pass_result *result)
{
if (result->r_type != MIE_PASS_RESULT_CONTINUE) {
return;
}
*result = mie_pass_execute(sched_item->i_pass, op, args);
}
static void sched_execute(
struct pass_sched *sched, struct mie_pass_args *args,
struct mie_pass_result *result)
{
b_queue_entry *cur_item = NULL, *next_item = NULL;
struct pass_sched_item *sched_item = NULL;
cur_item = b_queue_first(&sched->s_items);
while (cur_item) {
sched_item = b_unbox(struct pass_sched_item, cur_item, i_entry);
next_item = b_queue_next(cur_item);
b_queue_delete(&sched->s_items, cur_item);
sched_item_execute(sched_item, sched->s_op, args, result);
free(sched_item);
cur_item = next_item;
}
}
struct mie_pass_result mie_pass_manager_run(
struct mie_pass_manager *pm, struct mie_op *target)
{
b_queue schedule = B_QUEUE_INIT;
schedule_passes(pm, &schedule, target, 0);
b_queue_entry *cur_sched = b_queue_first(&schedule), *next_sched = NULL;
struct pass_sched *sched = NULL;
struct mie_pass_result result = MIE_PASS_CONTINUE;
struct mie_pass_args args = {
.p_ctx = pm->pm_ctx,
};
while (cur_sched) {
sched = b_unbox(struct pass_sched, cur_sched, s_entry);
next_sched = b_queue_next(cur_sched);
b_queue_delete(&schedule, cur_sched);
sched_execute(sched, &args, &result);
free(sched);
cur_sched = next_sched;
}
return result;
}

29
mie/pass/pass.c Normal file
View File

@@ -0,0 +1,29 @@
#include <mie/pass/pass.h>
const char *mie_pass_get_name(const struct mie_pass *pass)
{
return pass->p_def ? pass->p_def->p_name : NULL;
}
struct mie_pass_result mie_pass_execute(
struct mie_pass *pass, struct mie_op *op, struct mie_pass_args *args)
{
struct mie_pass_result result = MIE_PASS_INTERRUPT(MIE_ERR_BAD_STATE);
if (!pass->p_def) {
return result;
}
switch (pass->p_def->p_type) {
case MIE_PASS_TRANSFORM:
result = pass->p_def->p_transform(pass, op, args);
break;
case MIE_PASS_ANALYSE:
result = pass->p_def->p_analyse(pass, op, args);
break;
default:
break;
}
return result;
}

View File

@@ -1,8 +1,29 @@
#include <assert.h>
#include <mie/ir/block.h>
#include <mie/ir/op.h>
#include <mie/ir/register.h>
#include <mie/print/printer.h>
static enum mie_status cleanup(void *p)
{
return MIE_SUCCESS;
}
static enum mie_status move(void *dst, void *src, size_t itemsz)
{
assert(itemsz == sizeof(struct mie_block));
struct mie_block *dest_block = dst, *src_block = src;
memmove(dest_block, src_block, sizeof *src_block);
mie_name_move(&dest_block->b_name, &src_block->b_name);
return MIE_SUCCESS;
}
struct mie_vector_ops mie_block_vector_ops = {
.v_destroy = cleanup,
.v_move = move,
};
static void print_block_header_params(
struct mie_printer *printer, const struct mie_block *block)
{
@@ -17,11 +38,11 @@ static void print_block_header_params(
b_stream_write_string(printer->p_stream, ", ", NULL);
}
mie_printer_print_register(printer, block->b_params.items[i]);
mie_printer_print_register(printer, &block->b_params.items[i], 0);
b_stream_write_string(printer->p_stream, ": ", NULL);
mie_printer_print_type(printer, block->b_params.items[i]->reg_type);
mie_printer_print_type(printer, block->b_params.items[i].reg_type);
}
b_stream_write_char(printer->p_stream, ')');
@@ -46,9 +67,13 @@ static void print_block_header(
}
void mie_printer_print_block(
struct mie_printer *printer, const struct mie_block *block)
struct mie_printer *printer, const struct mie_block *block,
enum mie_print_flags flags)
{
print_block_header(printer, block);
if (!(flags & MIE_PRINT_F_EXCLUDE_BLOCK_HEADER)) {
print_block_header(printer, block);
}
b_stream_push_indent(printer->p_stream, 4);
for (size_t i = 0; i < MIE_VECTOR_COUNT(block->b_ops); i++) {
@@ -59,3 +84,9 @@ void mie_printer_print_block(
b_stream_pop_indent(printer->p_stream);
}
void mie_printer_print_block_ref(
struct mie_printer *printer, const struct mie_block *block)
{
print_block_header(printer, block);
}

View File

@@ -1,12 +0,0 @@
#include <mie/ir/module.h>
#include <mie/ir/op.h>
#include <mie/print/printer.h>
void mie_printer_print_module(
struct mie_printer *printer, const struct mie_module *mod)
{
for (size_t i = 0; i < MIE_VECTOR_COUNT(mod->m_ops); i++) {
mie_printer_print_op(printer, &mod->m_ops.items[i]);
b_stream_write_char(printer->p_stream, '\n');
}
}

View File

@@ -5,7 +5,7 @@
#include <mie/ir/region.h>
#include <mie/print/printer.h>
static void print_op_arg(
void mie_printer_print_op_arg(
struct mie_printer *printer, const struct mie_op_arg *arg, bool include_type)
{
enum mie_register_flags arg_flags = 0;
@@ -13,9 +13,9 @@ static void print_op_arg(
const struct mie_type *arg_type = NULL;
if (MIE_TEST_FLAGS(arg->arg_flags, MIE_OP_F_ARG_RESOLVED)) {
arg_flags = arg->arg_value->reg_flags;
arg_name = arg->arg_value->reg_name.n_str;
arg_type = arg->arg_value->reg_type;
arg_flags = arg->arg_value.u_reg->reg_flags;
arg_name = arg->arg_value.u_reg->reg_name.n_str;
arg_type = arg->arg_value.u_reg->reg_type;
} else {
arg_flags = arg->arg_unresolved.reg_flags;
arg_name = arg->arg_unresolved.reg_name;
@@ -39,8 +39,9 @@ static void print_op_arg(
mie_printer_print_type(printer, arg_type);
}
static void print_successor(
struct mie_printer *printer, const struct mie_op_successor *successor)
void mie_printer_print_op_successor(
struct mie_printer *printer, const struct mie_op_successor *successor,
bool compact)
{
b_stream_write_char(printer->p_stream, '^');
if (successor->s_flags & MIE_OP_F_SUCCESSOR_RESOLVED) {
@@ -55,14 +56,18 @@ static void print_successor(
return;
}
b_stream_write_string(printer->p_stream, ":(", NULL);
if (!compact) {
b_stream_write_char(printer->p_stream, ':');
}
b_stream_write_char(printer->p_stream, '(');
for (size_t i = 0; i < MIE_VECTOR_COUNT(successor->s_args); i++) {
if (i > 0) {
b_stream_write_string(printer->p_stream, ", ", NULL);
}
print_op_arg(printer, &successor->s_args.items[i], true);
mie_printer_print_op_arg(printer, &successor->s_args.items[i], true);
}
b_stream_write_char(printer->p_stream, ')');
@@ -82,7 +87,8 @@ static void print_successor_list(
b_stream_write_string(printer->p_stream, ", ", NULL);
}
print_successor(printer, &op->op_successors.items[i]);
mie_printer_print_op_successor(
printer, &op->op_successors.items[i], false);
}
b_stream_write_string(printer->p_stream, " ]", NULL);
@@ -101,7 +107,7 @@ static void print_region_list(struct mie_printer *printer, const struct mie_op *
b_stream_write_string(printer->p_stream, ", ", NULL);
}
mie_printer_print_region(printer, &op->op_regions.items[i]);
mie_printer_print_region(printer, &op->op_regions.items[i], 0);
}
b_stream_write_string(printer->p_stream, ")", NULL);
@@ -154,7 +160,7 @@ static void print_type_signature(
const struct mie_op_arg *arg = &op->op_args.items[i];
if (arg->arg_flags & MIE_OP_F_ARG_RESOLVED) {
type = arg->arg_value->reg_type;
type = arg->arg_value.u_reg->reg_type;
} else {
type = arg->arg_unresolved.reg_type;
}
@@ -173,7 +179,7 @@ static void print_type_signature(
b_stream_write_string(printer->p_stream, ", ", NULL);
}
type = op->op_result.items[i]->reg_type;
type = op->op_result.items[i].reg_type;
mie_printer_print_type(printer, type);
}
@@ -182,23 +188,9 @@ static void print_type_signature(
}
}
void mie_printer_print_op(struct mie_printer *printer, const struct mie_op *op)
static void print_generic_op(struct mie_printer *printer, const struct mie_op *op)
{
for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_result); i++) {
if (i > 0) {
b_stream_write_string(printer->p_stream, ", ", NULL);
}
mie_printer_print_register(printer, op->op_result.items[i]);
}
if (MIE_VECTOR_COUNT(op->op_result) > 0) {
b_stream_write_string(printer->p_stream, " = ", NULL);
}
if (printer->p_flags & MIE_PRINT_F_GENERIC) {
b_stream_write_char(printer->p_stream, '~');
}
b_stream_write_char(printer->p_stream, '~');
if (op->op_flags & MIE_OP_F_OP_RESOLVED) {
b_stream_write_fmt(
@@ -215,7 +207,7 @@ void mie_printer_print_op(struct mie_printer *printer, const struct mie_op *op)
b_stream_write_string(printer->p_stream, ", ", NULL);
}
print_op_arg(printer, &op->op_args.items[i], false);
mie_printer_print_op_arg(printer, &op->op_args.items[i], false);
}
b_stream_write_char(printer->p_stream, ')');
@@ -225,3 +217,67 @@ void mie_printer_print_op(struct mie_printer *printer, const struct mie_op *op)
print_attribute_list(printer, op);
print_type_signature(printer, op);
}
void mie_printer_print_op(struct mie_printer *printer, const struct mie_op *op)
{
for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_result); i++) {
if (i > 0) {
b_stream_write_string(printer->p_stream, ", ", NULL);
}
mie_printer_print_register(printer, &op->op_result.items[i], 0);
}
if (MIE_VECTOR_COUNT(op->op_result) > 0) {
b_stream_write_string(printer->p_stream, " = ", NULL);
}
bool use_generic = !op->op_info || !op->op_info->op_print
|| printer->p_flags & MIE_PRINT_F_GENERIC;
if (use_generic) {
print_generic_op(printer, op);
return;
}
mie_printer_print_op_name(printer, op);
op->op_info->op_print(printer, op);
}
void mie_printer_print_op_name(struct mie_printer *printer, const struct mie_op *op)
{
bool builtin = false;
bool resolved = false;
bool generic = false;
bool abbreviate = false;
if (op->op_flags & MIE_OP_F_OP_RESOLVED) {
resolved = true;
}
if (printer->p_flags & MIE_PRINT_F_ABBREVIATED) {
abbreviate = true;
}
if (printer->p_flags & MIE_PRINT_F_GENERIC) {
generic = true;
b_stream_write_char(printer->p_stream, '~');
} else if (!strcmp(op->op_dialect->d_name, "builtin")) {
builtin = true;
}
if (!resolved) {
b_stream_write_string(printer->p_stream, op->op_name, NULL);
return;
}
if (generic || !builtin || !abbreviate) {
b_stream_write_fmt(
printer->p_stream, NULL, "%s.", op->op_dialect->d_name);
}
b_stream_write_string(printer->p_stream, op->op_info->op_name, NULL);
return;
}

View File

@@ -3,13 +3,20 @@
#include <mie/print/printer.h>
void mie_printer_print_region(
struct mie_printer *printer, const struct mie_region *region)
struct mie_printer *printer, const struct mie_region *region,
enum mie_print_flags flags)
{
b_stream_write_string(printer->p_stream, "{\n", NULL);
for (size_t i = 0; i < MIE_VECTOR_COUNT(region->r_blocks); i++) {
const struct mie_block *block = region->r_blocks.items[i];
mie_printer_print_block(printer, block);
enum mie_print_flags block_flags = 0;
if ((flags & MIE_PRINT_F_EXCLUDE_FIRST_BLOCK_HEADER) && (i == 0)) {
block_flags = MIE_PRINT_F_EXCLUDE_BLOCK_HEADER;
}
const struct mie_block *block = &region->r_blocks.items[i];
mie_printer_print_block(printer, block, block_flags);
}
b_stream_write_string(printer->p_stream, "}", NULL);

View File

@@ -2,7 +2,8 @@
#include <mie/print/printer.h>
void mie_printer_print_register(
struct mie_printer *printer, const struct mie_register *reg)
struct mie_printer *printer, const struct mie_register *reg,
enum mie_print_flags flags)
{
if (reg->reg_flags & MIE_REGISTER_F_VIRTUAL) {
b_stream_write_fmt(
@@ -14,4 +15,9 @@ void mie_printer_print_register(
} else {
b_stream_write_string(printer->p_stream, "?REG", NULL);
}
if (flags & MIE_PRINT_F_INCLUDE_TYPE) {
b_stream_write_string(printer->p_stream, ": ", NULL);
mie_printer_print_type(printer, reg->reg_type);
}
}

View File

@@ -1,14 +1,27 @@
#include <mie/dialect/dialect.h>
#include <mie/print/printer.h>
#include <mie/type/type-definition.h>
#include <mie/type/type.h>
#define TYPE_HAS_PRINT_CALLBACK(p) (type->ty_def && type->ty_def->ty_print)
#define TYPE_IS_BUILTIN(p) \
(p->ty_def && p->ty_def->ty_parent \
&& !strcmp(p->ty_def->ty_parent->d_name, "builtin"))
#define TYPE_HAS_NAME(p) (type->ty_name)
#define TYPE_DEF_HAS_NAME(p) (type->ty_def && type->ty_def->ty_name)
void mie_printer_print_type(struct mie_printer *printer, const struct mie_type *type)
{
if (type->ty_def && type->ty_def->ty_print) {
if (TYPE_HAS_PRINT_CALLBACK(type)) {
type->ty_def->ty_print(type, printer);
} else if (type->ty_name) {
} else if (TYPE_IS_BUILTIN(type)) {
b_stream_write_string(
printer->p_stream, type->ty_def->ty_name, NULL);
} else if (TYPE_HAS_NAME(type)) {
b_stream_write_char(printer->p_stream, '!');
b_stream_write_string(printer->p_stream, type->ty_name, NULL);
} else if (type->ty_def && type->ty_def->ty_name) {
} else if (TYPE_DEF_HAS_NAME(type)) {
b_stream_write_char(printer->p_stream, '!');
b_stream_write_string(
printer->p_stream, type->ty_def->ty_name, NULL);
} else {

View File

@@ -74,13 +74,13 @@ struct mie_function_type *mie_function_type_create(void)
void mie_function_type_add_in_part(
struct mie_function_type *ty, const struct mie_type *part)
{
mie_vector_push_back(ty->func_in, &part);
mie_vector_push_back(ty->func_in, &part, NULL);
}
void mie_function_type_add_out_part(
struct mie_function_type *ty, const struct mie_type *part)
{
mie_vector_push_back(ty->func_out, &part);
mie_vector_push_back(ty->func_out, &part, NULL);
}
void mie_function_type_print(

View File

@@ -56,7 +56,7 @@ struct mie_storage_type *mie_storage_type_create(void)
void mie_storage_type_add_part(
struct mie_storage_type *ty, const struct mie_type *part)
{
mie_vector_push_back(ty->st_parts, &part);
mie_vector_push_back(ty->st_parts, &part, NULL);
}
void mie_storage_type_build_id(

View File

@@ -30,26 +30,84 @@ static void vector_unwrap(
*max = v->v_max;
}
static int vector_reserve(struct vector *v, size_t new_capacity)
static int move_vector_items(
struct vector *v, void *new_buf, size_t new_capacity,
const struct mie_vector_ops *ops)
{
size_t items_to_copy = MIN(v->v_count, new_capacity);
if (!ops || (!ops->v_copy && !ops->v_move)) {
memcpy(new_buf, v->v_buf, items_to_copy * v->v_itemsz);
return 0;
}
char *src = v->v_buf;
char *dst = new_buf;
for (size_t i = 0; i < items_to_copy; i++) {
if (ops->v_move) {
ops->v_move(dst, src, v->v_itemsz);
} else if (ops->v_copy) {
ops->v_copy(dst, src, v->v_itemsz);
} else {
memcpy(dst, src, v->v_itemsz);
}
src += v->v_itemsz;
dst += v->v_itemsz;
}
return 0;
}
static int trim_excess_items(
struct vector *v, size_t new_capacity, const struct mie_vector_ops *ops)
{
size_t to_trim = v->v_count - new_capacity;
size_t start = new_capacity;
char *item = &v->v_buf[start];
for (size_t i = start; i < v->v_count; i++) {
ops->v_destroy(item);
item += v->v_itemsz;
}
return 0;
}
static int vector_resize(
struct vector *v, size_t new_capacity, const struct mie_vector_ops *ops)
{
if (v->v_max >= new_capacity) {
return 0;
}
void *ptr = realloc(v->v_buf, new_capacity * v->v_itemsz);
if (!ptr) {
void *new_buf = malloc(new_capacity * v->v_itemsz);
if (!new_buf) {
return -1;
}
v->v_buf = ptr;
move_vector_items(v, new_buf, new_capacity, ops);
if (ops && ops->v_destroy && new_capacity < v->v_count) {
trim_excess_items(v, new_capacity, ops);
}
if (v->v_buf) {
free(v->v_buf);
}
v->v_buf = new_buf;
v->v_max = new_capacity;
if (new_capacity < v->v_count) {
v->v_count = new_capacity;
}
return 0;
}
static int vector_push_back(struct vector *v, const void *item)
static int vector_push_back(
struct vector *v, const void *item, const struct mie_vector_ops *ops)
{
int err = vector_reserve(v, v->v_count + DEFAULT_CAPACITY);
int err = vector_resize(v, v->v_count + DEFAULT_CAPACITY, ops);
if (err != 0) {
return err;
}
@@ -61,7 +119,7 @@ static int vector_push_back(struct vector *v, const void *item)
return 0;
}
static int vector_pop_back(struct vector *v)
static int vector_pop_back(struct vector *v, const struct mie_vector_ops *ops)
{
if (v->v_count > 0) {
v->v_count--;
@@ -70,9 +128,13 @@ static int vector_pop_back(struct vector *v)
return 0;
}
static void *vector_emplace_back(struct vector *v)
static void *vector_emplace_back(struct vector *v, const struct mie_vector_ops *ops)
{
int err = vector_reserve(v, v->v_count + 1);
int err = 0;
if (v->v_count >= v->v_max) {
err = vector_resize(v, v->v_count + DEFAULT_CAPACITY, ops);
}
if (err != 0) {
return NULL;
}
@@ -84,18 +146,25 @@ static void *vector_emplace_back(struct vector *v)
return dest;
}
static void vector_destroy_items(struct vector *v, void (*dtor)(void *))
static void vector_destroy_items(struct vector *v, const struct mie_vector_ops *ops)
{
for (size_t i = 0; i < v->v_count; i++) {
void *item = (char *)v->v_buf + (i * v->v_itemsz);
dtor(item);
ops->v_destroy(item);
}
}
static void vector_destroy(struct vector *v, void (*dtor)(void *))
static void vector_trim(struct vector *v, const struct mie_vector_ops *ops)
{
if (dtor) {
vector_destroy_items(v, dtor);
if (v->v_max > v->v_count) {
vector_resize(v, v->v_count, ops);
}
}
static void vector_destroy(struct vector *v, const struct mie_vector_ops *ops)
{
if (ops && ops->v_destroy) {
vector_destroy_items(v, ops);
}
if (v->v_buf) {
@@ -109,47 +178,59 @@ static void vector_destroy(struct vector *v, void (*dtor)(void *))
int __mie_vector_push_back(
void **vector, const void *item, size_t item_size, size_t *count,
size_t *max)
size_t *max, const struct mie_vector_ops *ops)
{
struct vector v = {};
int err = 0;
vector_wrap(&v, vector, item_size, count, max);
err = vector_push_back(&v, item);
err = vector_push_back(&v, item, ops);
vector_unwrap(&v, vector, item_size, count, max);
return err;
}
void __mie_vector_pop_back(
void **vector, size_t item_size, size_t *count, size_t *max)
void **vector, size_t item_size, size_t *count, size_t *max,
const struct mie_vector_ops *ops)
{
struct vector v = {};
vector_wrap(&v, vector, item_size, count, max);
vector_pop_back(&v);
vector_pop_back(&v, ops);
vector_unwrap(&v, vector, item_size, count, max);
}
void *__mie_vector_emplace_back(
void **vector, size_t item_size, size_t *count, size_t *max)
void **vector, size_t item_size, size_t *count, size_t *max,
const struct mie_vector_ops *ops)
{
struct vector v = {};
void *p = 0;
vector_wrap(&v, vector, item_size, count, max);
p = vector_emplace_back(&v);
p = vector_emplace_back(&v, ops);
vector_unwrap(&v, vector, item_size, count, max);
return p;
}
void __mie_vector_destroy(
void __mie_vector_trim(
void **vector, size_t item_size, size_t *count, size_t *max,
void (*dtor)(void *))
const struct mie_vector_ops *ops)
{
struct vector v = {};
vector_wrap(&v, vector, item_size, count, max);
vector_destroy(&v, dtor);
vector_trim(&v, ops);
vector_unwrap(&v, vector, item_size, count, max);
}
void __mie_vector_destroy(
void **vector, size_t item_size, size_t *count, size_t *max,
const struct mie_vector_ops *ops)
{
struct vector v = {};
vector_wrap(&v, vector, item_size, count, max);
vector_destroy(&v, ops);
vector_unwrap(&v, vector, item_size, count, max);
}

View File

@@ -5,6 +5,7 @@
#include <blue/io/file.h>
#include <blue/io/path.h>
#include <blue/term.h>
#include <mie/attribute/attribute-definition.h>
#include <mie/ctx.h>
#include <mie/dialect/arith.h>
#include <mie/dialect/builtin.h>
@@ -16,15 +17,20 @@
#include <mie/dialect/ptr.h>
#include <mie/dialect/scf.h>
#include <mie/dialect/select.h>
#include <mie/interface/interface-definition.h>
#include <mie/ir/block.h>
#include <mie/ir/op-definition.h>
#include <mie/ir/op.h>
#include <mie/ir/region.h>
#include <mie/ir/register.h>
#include <mie/ir/walk.h>
#include <mie/name.h>
#include <mie/parse/lex.h>
#include <mie/parse/parse.h>
#include <mie/parse/parser.h>
#include <mie/parse/token.h>
#include <mie/pass/builtin.h>
#include <mie/pass/pass-manager.h>
#include <mie/print/printer.h>
#include <mie/trait/trait-definition.h>
#include <mie/trait/trait.h>
#include <mie/type/type-definition.h>
@@ -45,16 +51,16 @@ static int trait_ref_print(const struct mie_trait *trait, void *arg)
return 0;
}
static void mie_op_arg_print(const struct mie_op_arg *arg)
static void op_arg_dump(struct mie_printer *printer, const struct mie_op_arg *arg)
{
enum mie_register_flags arg_flags = 0;
const char *arg_name = NULL;
const struct mie_type *arg_type = NULL;
if (MIE_TEST_FLAGS(arg->arg_flags, MIE_OP_F_ARG_RESOLVED)) {
arg_flags = arg->arg_value->reg_flags;
arg_name = arg->arg_value->reg_name.n_str;
arg_type = arg->arg_value->reg_type;
arg_flags = arg->arg_value.u_reg->reg_flags;
arg_name = arg->arg_value.u_reg->reg_name.n_str;
arg_type = arg->arg_value.u_reg->reg_type;
} else {
arg_flags = arg->arg_unresolved.reg_flags;
arg_name = arg->arg_unresolved.reg_name;
@@ -68,13 +74,15 @@ static void mie_op_arg_print(const struct mie_op_arg *arg)
}
printf(":(");
mie_type_print(arg_type, b_stdout);
mie_printer_print_type(printer, arg_type);
b_printf(")%s[reset]", arg_name);
}
static void mie_op_print(const struct mie_op *op)
static void op_dump(const struct mie_op *op)
{
b_stringstream *tmp = b_stringstream_create();
struct mie_printer printer;
mie_printer_init(&printer, NULL, b_stdout, MIE_PRINT_F_GENERIC);
printf("FLAGS:");
(op->op_flags & MIE_OP_F_OP_RESOLVED) && printf(" OP_RESOLVED");
@@ -88,11 +96,14 @@ static void mie_op_print(const struct mie_op *op)
mie_trait_table_iterate(&op->op_info->op_traits, trait_ref_print, NULL);
printf("\n");
printf("ATTRIBUTES:");
#if 0
for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_attrib); i++) {
printf(" (%s = ", op->op_attrib.items[i].attrib_name);
mie_value_print(op->op_attrib.items[i].attrib_value, b_stdout);
mie_printer_print_value(
&printer, op->op_attrib.items[i].attrib_value);
printf(")");
}
#endif
printf("\n");
printf("REGIONS: %zu\n", MIE_VECTOR_COUNT(op->op_regions));
@@ -109,7 +120,7 @@ static void mie_op_print(const struct mie_op *op)
for (size_t i = 0; i < MIE_VECTOR_COUNT(s->s_args); i++) {
const struct mie_op_arg *arg = &s->s_args.items[i];
mie_op_arg_print(arg);
op_arg_dump(&printer, arg);
}
printf(" )");
@@ -119,7 +130,7 @@ static void mie_op_print(const struct mie_op *op)
printf("ARGS:");
for (size_t i = 0; i < op->op_args.count; i++) {
const struct mie_op_arg *arg = &op->op_args.items[i];
mie_op_arg_print(arg);
op_arg_dump(&printer, arg);
}
printf("\n");
@@ -128,7 +139,7 @@ static void mie_op_print(const struct mie_op *op)
const struct mie_register *reg = &op->op_result.items[i];
printf(" %s:(",
(reg->reg_flags & MIE_REGISTER_F_MACHINE) ? "MR" : "VR");
mie_type_print(reg->reg_type, b_stdout);
mie_printer_print_type(&printer, reg->reg_type);
printf(")%s", reg->reg_name.n_str);
}
printf("\n");
@@ -161,6 +172,35 @@ static void mie_trait_definition_print(const struct mie_trait_definition *trait)
trait->tr_name, id_str);
}
static void mie_attribute_definition_print(
const struct mie_attribute_definition *attribute)
{
char id_str[MIE_ID_STRING_MAX];
mie_id_to_string(&attribute->a_id, id_str, sizeof id_str);
b_printf(
" [bold,magenta]At:[reset]%-20s [dark_grey]{%s}[reset]\n",
attribute->a_name, id_str);
}
static void mie_interface_definition_print(
const struct mie_interface_definition *interface)
{
char id_str[MIE_ID_STRING_MAX];
mie_id_to_string(&interface->if_id, id_str, sizeof id_str);
b_printf(
" [bold,cyan]If:[reset]%-20s [dark_grey]{%s}[reset]\n",
interface->if_name, id_str);
}
static void mie_pass_definition_print(const struct mie_pass_definition *interface)
{
char id_str[MIE_ID_STRING_MAX];
mie_id_to_string(&interface->p_id, id_str, sizeof id_str);
b_printf(
" [bold,cyan]Ps:[reset]%-20s [dark_grey]{%s}[reset]\n",
interface->p_name, id_str);
}
static void mie_dialect_print(const struct mie_dialect *dialect)
{
char id_str[MIE_ID_STRING_MAX];
@@ -198,10 +238,31 @@ static void mie_dialect_print(const struct mie_dialect *dialect)
mie_trait_definition_print(trait);
node = b_btree_next(node);
}
node = b_btree_first(&dialect->d_attributes.map_entries);
while (node) {
mie_id *id = b_unbox(mie_id, node, e_node);
struct mie_attribute_definition *attribute
= b_unbox(struct mie_attribute_definition, id, a_id);
mie_attribute_definition_print(attribute);
node = b_btree_next(node);
}
node = b_btree_first(&dialect->d_interfaces.map_entries);
while (node) {
mie_id *id = b_unbox(mie_id, node, e_node);
struct mie_interface_definition *interface = b_unbox(
struct mie_interface_definition, id, if_id);
mie_interface_definition_print(interface);
node = b_btree_next(node);
}
}
static void mie_ctx_print(const struct mie_ctx *ctx)
{
printf("Dialects:\n");
b_btree_node *node = b_btree_first(&ctx->ctx_dialects.map_entries);
while (node) {
mie_id *id = b_unbox(mie_id, node, e_node);
@@ -211,6 +272,17 @@ static void mie_ctx_print(const struct mie_ctx *ctx)
mie_dialect_print(dialect);
node = b_btree_next(node);
}
printf("\nPasses:\n");
node = b_btree_first(&ctx->ctx_passes.map_entries);
while (node) {
mie_id *id = b_unbox(mie_id, node, e_node);
struct mie_pass_definition *pass
= b_unbox(struct mie_pass_definition, id, p_id);
mie_pass_definition_print(pass);
node = b_btree_next(node);
}
}
static int validate_file(const char *path, const b_arglist *args)
@@ -236,14 +308,19 @@ static int validate_file(const char *path, const b_arglist *args)
mie_scf_dialect_create(ctx);
mie_index_dialect_create(ctx);
mie_builtin_passes_register(ctx);
mie_ctx_print(ctx);
struct mie_type *i32 = mie_arith_int_get_type(ctx, 32);
struct mie_type *i32 = mie_ctx_get_int_type(ctx, 32);
struct mie_type *str = mie_ctx_get_type(ctx, "builtin", "string");
struct mie_type *index = mie_ctx_get_type(ctx, "index", "index");
struct mie_value *i32_value = mie_ctx_get_int(ctx, 1024, 32);
struct mie_value *index_value = mie_ctx_get_index(ctx, 25000);
struct mie_value *str_value = mie_ctx_get_string(ctx, "Hello, world!");
struct mie_type *index = mie_ctx_get_type(ctx, "builtin", "index");
struct mie_attribute *i32_value = mie_ctx_get_int(ctx, 1024, 32);
struct mie_attribute *index_value = mie_ctx_get_index(ctx, 25000);
struct mie_attribute *str_value
= mie_ctx_get_string(ctx, "Hello, world!");
printf("%zu\n", sizeof(struct mie_op));
const struct mie_type *storage_type_parts[] = {i32, str, index};
struct mie_type *storage_type = mie_ctx_get_storage_type(
@@ -267,6 +344,9 @@ static int validate_file(const char *path, const b_arglist *args)
sizeof func_in_parts / sizeof *func_in_parts, func_out_parts,
sizeof func_out_parts / sizeof *func_out_parts));
struct mie_printer printer;
mie_printer_init(&printer, ctx, b_stdout, MIE_PRINT_F_ABBREVIATED);
char id_str[MIE_ID_STRING_MAX];
mie_id_to_string(&i32->ty_id, id_str, sizeof id_str);
printf("i32 type: {%s} %s (instance of %s.%s)\n", id_str, i32->ty_name,
@@ -279,24 +359,24 @@ static int validate_file(const char *path, const b_arglist *args)
index->ty_def->ty_parent->d_name, index->ty_def->ty_name);
mie_id_to_string(&storage_type->ty_id, id_str, sizeof id_str);
printf("storage type: {%s} ", id_str);
mie_type_print(storage_type, b_stdout);
mie_printer_print_type(&printer, storage_type);
printf("\n");
mie_id_to_string(&func_type->ty_id, id_str, sizeof id_str);
printf("function type: {%s} ", id_str);
mie_type_print(func_type, b_stdout);
mie_printer_print_type(&printer, func_type);
printf("\n");
printf("i32 value: ");
mie_value_print(i32_value, b_stdout);
mie_printer_print_attribute(&printer, i32_value);
printf("\n");
printf("index value: ");
mie_value_print(index_value, b_stdout);
mie_printer_print_attribute(&printer, index_value);
printf("\n");
printf("str value: ");
mie_value_print(str_value, b_stdout);
mie_printer_print_attribute(&printer, str_value);
printf("\n");
struct mie_lex *lex = mie_lex_create(file);
@@ -304,19 +384,52 @@ static int validate_file(const char *path, const b_arglist *args)
struct mie_name_map *names = mie_name_map_create(NULL);
struct mie_op op = {};
struct mie_op *root = mie_op_create();
if (!mie_parser_parse_op(parse, names, &op)) {
if (!mie_parser_parse_op(parse, NULL, root)) {
printf("parse failed\n");
return -1;
}
if (!mie_ctx_resolve_op(ctx, &op)) {
printf("op resolve failed\n");
struct mie_walker *walker = mie_walker_begin(
root, MIE_WALKER_F_INCLUDE_OPS | MIE_WALKER_F_PREORDER
| MIE_WALKER_F_FORWARD | MIE_WALKER_F_RECURSIVE);
do {
const struct mie_walker_item *item = mie_walker_get(walker);
for (size_t i = 0; i < item->i_depth; i++) {
fputs(" ", stdout);
}
printf("resolving %p %s... ", item->i_op, item->i_op->op_name);
bool ok = mie_ctx_resolve_op(ctx, item->i_op);
printf("%s\n", ok ? "OK" : "FAIL");
} while (mie_walker_step(walker) == MIE_SUCCESS);
struct mie_pass *prefix_func_with_underscore = NULL;
if (mie_ctx_get_pass(
ctx, "prefix-func-with-underscore", NULL,
&prefix_func_with_underscore)
!= MIE_SUCCESS) {
printf("cannot load pass prefix-func-with-underscore\n");
return -1;
}
mie_op_print(&op);
struct mie_pass_manager *pm = mie_pass_manager_create(ctx);
struct mie_pass_manager *module_pm = mie_pass_manager_nest(pm);
mie_pass_manager_filter_op(module_pm, "builtin", "module");
struct mie_pass_manager *func_pm = mie_pass_manager_nest(pm);
mie_pass_manager_filter_op(module_pm, "func", "func");
mie_pass_manager_add_pass(func_pm, prefix_func_with_underscore);
mie_pass_manager_parse(
pm, "builtin.module(func.func(prefix-func-with-underscore))");
mie_pass_manager_run(pm, root);
mie_printer_print_op(&printer, root);
printf("\n");
#if 0