Compare commits

...

26 Commits

Author SHA1 Message Date
73b4b77816 doc: sample: update sample ir files 2026-03-16 12:09:37 +00:00
a29779aa83 tool: diag: output formatting fixes 2026-03-16 12:09:11 +00:00
778835032d tool: validate: resolve ops and references; report any diagnostics 2026-03-16 12:08:41 +00:00
540c8e6d8b tool: optimise: add flags to control ir output format 2026-03-16 12:07:36 +00:00
1c44c3e5c8 tool: optimise: resolve ops; report any diagnostic messages 2026-03-16 12:07:17 +00:00
28b72cbf1e tool: add resolution helper functions 2026-03-16 12:05:58 +00:00
8c9cab7408 pass: convert-scf-to-cf: implement for-loop rewriting 2026-03-16 12:05:14 +00:00
4d315d6abe pass: handle null items in schedule_passes 2026-03-16 12:04:48 +00:00
a99610ac02 dialect: select: update parse callback prototype 2026-03-16 12:04:00 +00:00
6bebcbfdf6 scf: implement print/parse for for, if, yield 2026-03-16 12:03:02 +00:00
ab7ccfcfef dialect: meta: update parse callback prototype 2026-03-16 12:02:45 +00:00
a27375ac2e func: implement print/parse for func, return 2026-03-16 12:02:19 +00:00
ef4349b732 cf: implement print/parse for br, br-cond 2026-03-16 12:01:50 +00:00
639652b083 arith: implement print/parse for addf, addi, cmpi, constant 2026-03-16 12:00:59 +00:00
fc610a6605 memref: implement print/parse for memref.load() 2026-03-16 12:00:10 +00:00
f88d537043 ptr: update parse callback prototypes 2026-03-16 11:59:30 +00:00
fe1e7d81c4 builtin: add diag definitions and parser callbacks 2026-03-16 11:58:56 +00:00
000a9c2671 vector: add a macro to forward a vector-ref to another function 2026-03-16 11:57:48 +00:00
8a50445dd8 memref: move memref type to builtin dialect 2026-03-16 11:56:51 +00:00
81fde5d43b rewrite: add functions to add new args to ops 2026-03-16 11:55:28 +00:00
06101b6316 print: add nullptr handling 2026-03-16 11:54:55 +00:00
7b729c49fa type: add functions to determine what kind of type a type is 2026-03-16 11:54:07 +00:00
51c8d2744c parse: generate diags to report parse errors 2026-03-16 11:53:35 +00:00
2858323eca diag: add function to append a simple string to a diag 2026-03-16 11:51:14 +00:00
fed4cad7e8 id: add missing functions to header 2026-03-16 11:41:41 +00:00
a107964e2b ir: add some manipulation functions 2026-03-16 11:38:37 +00:00
68 changed files with 3336 additions and 373 deletions

View File

@@ -0,0 +1,30 @@
~func.func() ({
^R:
%0 = ~arith.constant() {value = 0 : i32} : () -> i32
~cf.br-cond(%0) [ ^A, ^B, ^C ] : (i32) -> ()
^A:
~cf.br() [ ^D ] : () -> ()
^B:
~cf.br-cond(%0) [ ^D, ^A, ^E ] : (i32) -> ()
^C:
~cf.br-cond(%0) [ ^G, ^F ] : (i32) -> ()
^D:
~cf.br() [ ^L ] : () -> ()
^E:
~cf.br() [ ^H ] : () -> ()
^F:
~cf.br() [ ^I ] : () -> ()
^G:
~cf.br-cond(%0) [ ^I, ^J ] : (i32) -> ()
^H:
~cf.br-cond(%0) [ ^E, ^K ] : (i32) -> ()
^I:
~cf.br() [ ^K ] : () -> ()
^J:
~cf.br() [ ^I ] : () -> ()
^K:
~cf.br-cond(%0) [ ^R, ^I ] : (i32) -> ()
^L:
~cf.br() [ ^H ] : () -> ()
}) {sym_name = "test", function_type = () -> () } : () -> ()

View File

@@ -1,9 +1,10 @@
; Comment
module {
func.func @reduce(%buffer: memref<1024*f32>, %lb: index, %ub: index, %step: index) -> f32 {
; Initial sum set to 0.
%sum.0 = f32.constant 0.0
%sum.0 = arith.constant 0.0 : f32
; iter_args binds initial values to the loop's region arguments.
%sum = scf.for %iv = %lb to %ub step %step iter-args(%sum.iter = %sum.0) -> (f32) {
%sum = scf.for %iv = %lb to %ub step %step iter-args(%sum.iter = %sum.0) -> f32 {
%t = memref.load %buffer[%iv] : memref<1024*f32>
%sum.next = arith.addf %sum.iter, %t : f32
; Yield current iteration sum to next iteration %sum.iter or to %sum
@@ -13,3 +14,4 @@ func.func @reduce(%buffer: memref<1024*f32>, %lb: index, %ub: index, %step: inde
func.return %sum : f32
}
}

View File

@@ -1,25 +1,16 @@
~func.func() ({
^entry(%buffer: memref<1024*f32>, %lb: index, %ub: index, %step: index):
; Initial sum set to 0.
%sum.0 = ~f32.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) ] : () -> ()
module {
func.func @_reduce(%buffer: memref<1024*f32>, %lb: index, %ub: index, %step: index) -> f32 {
%sum.0 = arith.constant 0 : f32
cf.br ^for.entry(%lb: index, %sum.0: f32)
^for.entry(%iv: index, %sum.iter: f32):
%t = ~memref.load(%buffer, %iv) : (memref<1024*f32>, index) -> f32
%sum.next = ~arith.addf(%sum.iter, %t) : (f32, f32) -> f32
~cf.br [ ^for.cond:(%iv: index, %sum.next: f32) ] : () -> ()
^for.cond(%iv: index, %sum.next: 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 : i64} : (index, index) -> i1
~cf.br-cond(%stop) [ ^for.end, ^for.entry:(%iv.next: index, %sum.next: f32) ] : () -> ()
%t = memref.load %buffer[%iv] : memref<1024*f32>
%sum.next = arith.addf %sum.iter, %t : f32
cf.br ^for.cond(%iv: index, %sum.next: f32)
^for.cond(%iv.0: index, %sum.iter.0: index):
%iv.next = arith.addi %iv.0, %step : index
%stop = arith.cmpi uge %iv.next, %ub : index
cf.br-cond %stop, ^for.end(%sum.iter.0: index), ^for.entry(%iv.next: index, %sum.iter.0: index)
^for.end(%sum: f32):
~func.return(%sum) : (f32) -> ()
}) {sym_name = "reduce"} : (memref<1024*f32>, index, index, index) -> f32
func.return %sum : f32
}
}

View File

@@ -0,0 +1,26 @@
~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

@@ -1,26 +1,25 @@
~builtin.module() ({
~func.func() ({
^entry(%buffer: i32, %lb: index, %ub: index, %step: index):
module {
func.func @reduce(%buffer: memref<?*f32>, %lb: index, %ub: index, %step: index) -> f32 {
; Initial sum set to 0.
%sum.0 = ~arith.constant() {value = 0.0 : f32} : () -> f32
%sum.0 = arith.constant 0.0 : 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) ] : () -> ()
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
%t = memref.load %buffer[%iv] : memref<?*f32>
%sum.next = arith.addf %sum.iter, %t : f32
~cf.br() [ ^for.cond:(%iv: index, %sum.next: 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) -> ()
%iv.next = arith.addi %iv, %step : index
%stop = arith.cmpi uge %iv.next, %ub : index
cf.br-cond %stop, ^for.end, ^for.entry(%iv.next: index, %sum.next: f32)
^for.end(%sum: f32):
~func.return(%sum) : (f32) -> ()
}) {sym_name = "reduce", function_type = (i32, index, index, index) -> f32 } : () -> ()
}) : () -> ()
func.return %sum : f32
}
}

View File

@@ -76,7 +76,11 @@ void mie_diag_push_msg(
return;
}
if (msg >= dialect->d_nr_diag_msgs) {
if (msg >= dialect->d_nr_diag_msgs
|| !dialect->d_diag_msgs[msg].msg_content) {
fprintf(stderr, "FATAL: %lu is not a valid %s diag msg\n", msg,
dialect_name);
abort();
return;
}
@@ -90,6 +94,20 @@ void mie_diag_push_msg(
b_queue_push_back(&diag->diag_components, &c_msg->msg_base.c_entry);
}
void mie_diag_push_string(struct mie_diag *diag, const char *str)
{
struct mie_diag_c_msg *c_msg = malloc(sizeof *c_msg);
if (!c_msg) {
return;
}
memset(c_msg, 0x0, sizeof *c_msg);
c_msg->msg_base.c_type = MIE_DIAG_COMPONENT_MSG;
c_msg->msg_content = b_strdup(str);
b_queue_push_back(&diag->diag_components, &c_msg->msg_base.c_entry);
}
void mie_diag_push_snippet(
struct mie_diag *diag, unsigned long first_line, unsigned long last_line,
const struct mie_diag_amendment *amendments, size_t nr_amendments,

View File

@@ -1,9 +1,16 @@
#include <mie/ctx.h>
#include <mie/diag/class.h>
#include <mie/diag/msg.h>
#include <mie/dialect/arith.h>
#include <mie/dialect/dialect.h>
#include <mie/macros.h>
MIE_DIAG_CLASS_LIST_EXTERN(mie_arith_diag);
MIE_DIAG_MSG_LIST_EXTERN(mie_arith_msg);
MIE_DIALECT_BEGIN(mie_arith, struct mie_dialect, "arith")
MIE_DIALECT_DIAG_CLASS_LIST(mie_arith_diag);
MIE_DIALECT_DIAG_MSG_LIST(mie_arith_msg);
MIE_DIALECT_ADD_OP(mie_arith_addi);
MIE_DIALECT_ADD_OP(mie_arith_cmpi);
MIE_DIALECT_ADD_OP(mie_arith_addf);

29
mie/dialect/arith/diag.c Normal file
View File

@@ -0,0 +1,29 @@
#include <mie/diag/class.h>
#include <mie/diag/msg.h>
#include <mie/dialect/arith.h>
#include <mie/macros.h>
#define MIE_DIAG_CLASS_PREFIX MIE_ARITH_E
#define MIE_DIAG_MSG_PREFIX MIE_ARITH_MSG
MIE_DIAG_CLASS_LIST_BEGIN(mie_arith_diag)
MIE_DIAG_CLASS(INVALID_INTEGER_TYPE, ERROR, "Invalid integer type")
MIE_DIAG_CLASS(INVALID_FLOAT_TYPE, ERROR, "Invalid floating-point type")
MIE_DIAG_CLASS(
INVALID_COMPARISON_PREDICATE, ERROR,
"Invalid comparison predicate")
MIE_DIAG_CLASS_LIST_END(mie_arith_diag)
MIE_DIAG_MSG_LIST_BEGIN(mie_arith_msg)
MIE_DIAG_MSG(EXPECTED_INTEGER_TYPE, "expected an integer or index type.")
MIE_DIAG_MSG(EXPECTED_FLOAT_TYPE, "expected a floating-point type.")
MIE_DIAG_MSG(
INVALID_COMPARISON_PREDICATE,
"this is not a valid comparison predicate.")
MIE_DIAG_MSG(
VALID_COMPARISON_PREDICATES,
"valid comparison predicates include: [blue]eq[reset], "
"[blue]ne[reset], [blue]slt[reset], [blue]sle[reset], "
"[blue]sgt[reset], [blue]sge[reset], [blue]ult[reset], "
"[blue]ule[reset], [blue]ugt[reset], [blue]uge[reset]")
MIE_DIAG_MSG_LIST_END(mie_arith_msg)

View File

@@ -1,8 +1,12 @@
#include <mie/dialect/arith.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/parse/parser.h>
#include <mie/print/printer.h>
#include <mie/type/type.h>
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
{
@@ -23,8 +27,60 @@ static enum mie_status print(struct mie_printer *printer, const struct mie_op *o
return MIE_SUCCESS;
}
static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
static enum mie_status parse(
struct mie_parser *parser, struct mie_parser_scope *scope,
struct mie_op *out)
{
struct mie_file_span span;
if (MIE_VECTOR_COUNT(out->op_result) != 1) {
mie_op_get_results_span(out, &span);
mie_parser_report_error_simple(
parser, "builtin",
MIE_BUILTIN_E_INCORRECT_NUMBER_OF_RESULTS,
MIE_BUILTIN_MSG_OP_INCORRECT_NUMBER_OF_RESULTS, &span);
return MIE_ERR_BAD_SYNTAX;
}
if (!mie_parser_parse_parameter_list(
parser, false, MIE_VECTOR_REF(out->op_args),
"arithmetic operation arguments")) {
return MIE_ERR_BAD_SYNTAX;
}
if (MIE_VECTOR_COUNT(out->op_args) != 2) {
mie_op_get_args_span(out, &span);
mie_parser_report_error_simple(
parser, "builtin",
MIE_BUILTIN_E_INCORRECT_NUMBER_OF_ARGUMENTS,
MIE_BUILTIN_MSG_OP_INCORRECT_NUMBER_OF_ARGS, &span);
return MIE_ERR_BAD_SYNTAX;
}
if (!mie_parser_parse_symbol(parser, MIE_SYM_COLON)) {
mie_parser_report_unexpected_token(
parser, MIE_SYM_COLON, "arithmetic operation type");
return MIE_ERR_BAD_SYNTAX;
}
const struct mie_type *type = NULL;
if (!mie_parser_parse_type(
parser, "arithmetic operation type", &type, &span)) {
return MIE_ERR_BAD_SYNTAX;
}
if (!mie_type_is(type, "builtin", "float")) {
mie_parser_report_error_simple(
parser, "arith", MIE_ARITH_E_INVALID_FLOAT_TYPE,
MIE_ARITH_MSG_EXPECTED_FLOAT_TYPE, &span);
return MIE_ERR_BAD_SYNTAX;
}
for (size_t i = 0; i < MIE_VECTOR_COUNT(out->op_args); i++) {
out->op_args.items[i].arg_unresolved.reg_type = type;
}
out->op_result.items[0].reg_type = type;
return MIE_SUCCESS;
}

View File

@@ -1,10 +1,12 @@
#include <mie/ctx.h>
#include <mie/dialect/arith.h>
#include <mie/dialect/builtin.h>
#include <mie/dialect/dialect.h>
#include <mie/ir/emit.h>
#include <mie/ir/op-definition.h>
#include <mie/ir/op.h>
#include <mie/macros.h>
#include <mie/parse/parser.h>
#include <mie/print/printer.h>
#include <mie/type/type.h>
@@ -27,8 +29,63 @@ static enum mie_status print(struct mie_printer *printer, const struct mie_op *o
return MIE_SUCCESS;
}
static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
static enum mie_status parse(
struct mie_parser *parser, struct mie_parser_scope *scope,
struct mie_op *out)
{
struct mie_file_span span;
if (MIE_VECTOR_COUNT(out->op_result) != 1) {
mie_op_get_results_span(out, &span);
mie_parser_report_error_simple(
parser, "builtin",
MIE_BUILTIN_E_INCORRECT_NUMBER_OF_RESULTS,
MIE_BUILTIN_MSG_OP_INCORRECT_NUMBER_OF_RESULTS, &span);
return MIE_ERR_BAD_SYNTAX;
}
if (!mie_parser_parse_parameter_list(
parser, false, MIE_VECTOR_REF(out->op_args),
"arithmetic operation arguments")) {
return MIE_ERR_BAD_SYNTAX;
}
if (MIE_VECTOR_COUNT(out->op_args) != 2) {
mie_op_get_args_span(out, &span);
mie_parser_report_error_simple(
parser, "builtin",
MIE_BUILTIN_E_INCORRECT_NUMBER_OF_ARGUMENTS,
MIE_BUILTIN_MSG_OP_INCORRECT_NUMBER_OF_ARGS, &span);
return MIE_ERR_BAD_SYNTAX;
}
if (!mie_parser_parse_symbol(parser, MIE_SYM_COLON)) {
mie_parser_report_unexpected_token(
parser, MIE_SYM_COLON, "arithmetic operation type");
return MIE_ERR_BAD_SYNTAX;
}
const struct mie_type *type = NULL;
if (!mie_parser_parse_type(
parser, "arithmetic operation type", &type, &span)) {
return MIE_ERR_BAD_SYNTAX;
}
bool is_int_type = mie_type_is(type, "builtin", "int")
|| mie_type_is(type, "builtin", "index");
if (!is_int_type) {
mie_parser_report_error_simple(
parser, "arith", MIE_ARITH_E_INVALID_INTEGER_TYPE,
MIE_ARITH_MSG_EXPECTED_INTEGER_TYPE, &span);
return MIE_ERR_BAD_SYNTAX;
}
for (size_t i = 0; i < MIE_VECTOR_COUNT(out->op_args); i++) {
out->op_args.items[i].arg_unresolved.reg_type = type;
}
out->op_result.items[0].reg_type = type;
return MIE_SUCCESS;
}

View File

@@ -1,9 +1,34 @@
#include <mie/diag/diag.h>
#include <mie/dialect/arith.h>
#include <mie/dialect/builtin.h>
#include <mie/dialect/dialect.h>
#include <mie/ir/emit.h>
#include <mie/ir/op-definition.h>
#include <mie/ir/op.h>
#include <mie/macros.h>
#include <mie/parse/parser.h>
#include <mie/print/printer.h>
#include <mie/type/type.h>
#define PREDICATE(id, str) [MIE_ARITH_CMPI_##id] = str
static const char *predicates[] = {
PREDICATE(EQ, "eq"), PREDICATE(NE, "ne"), PREDICATE(SLT, "slt"),
PREDICATE(SLE, "sle"), PREDICATE(SGT, "sgt"), PREDICATE(SGE, "sge"),
PREDICATE(ULT, "ult"), PREDICATE(ULE, "ule"), PREDICATE(UGT, "ugt"),
PREDICATE(UGE, "uge"),
};
static const size_t nr_predicates = sizeof predicates / sizeof predicates[0];
static int find_predicate(const char *pred)
{
for (size_t i = 0; i < nr_predicates; i++) {
if (!strcmp(pred, predicates[i])) {
return i;
}
}
return -1;
}
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
{
@@ -24,41 +49,12 @@ static enum mie_status print(struct mie_printer *printer, const struct mie_op *o
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;
if (pred < 0 || pred >= nr_predicates) {
return MIE_ERR_BAD_STATE;
}
b_stream_write_string(printer->p_stream, predicates[pred], NULL);
b_stream_write_char(printer->p_stream, ' ');
mie_printer_print_op_arg(printer, left, false);
b_stream_write_string(printer->p_stream, ", ", NULL);
@@ -69,11 +65,111 @@ static enum mie_status print(struct mie_printer *printer, const struct mie_op *o
return MIE_SUCCESS;
}
static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
static enum mie_status parse(
struct mie_parser *parser, struct mie_parser_scope *scope,
struct mie_op *out)
{
struct mie_file_span span;
if (MIE_VECTOR_COUNT(out->op_result) != 1) {
mie_op_get_results_span(out, &span);
mie_parser_report_error_simple(
parser, "builtin",
MIE_BUILTIN_E_INCORRECT_NUMBER_OF_RESULTS,
MIE_BUILTIN_MSG_OP_INCORRECT_NUMBER_OF_RESULTS, &span);
return MIE_ERR_BAD_SYNTAX;
}
b_string *tmp = mie_parser_get_tempstr(parser);
if (!mie_parser_parse_word(parser, tmp, &span)) {
mie_parser_report_unexpected_token_s(
parser, "predicate word", "comparison operation");
return MIE_ERR_BAD_SYNTAX;
}
int pred = find_predicate(b_string_ptr(tmp));
if (pred == -1) {
struct mie_diag *diag = mie_parser_report_error_simple(
parser, "arith", MIE_ARITH_E_INVALID_COMPARISON_PREDICATE,
MIE_ARITH_MSG_INVALID_COMPARISON_PREDICATE, &span);
mie_diag_push_msg(
diag, mie_parser_get_mie_ctx(parser), "arith",
MIE_ARITH_MSG_VALID_COMPARISON_PREDICATES);
return MIE_ERR_BAD_SYNTAX;
}
if (!mie_parser_parse_parameter_list(
parser, false, MIE_VECTOR_REF(out->op_args),
"comparison operands")) {
return MIE_ERR_BAD_SYNTAX;
}
if (MIE_VECTOR_COUNT(out->op_args) != 2) {
mie_op_get_args_span(out, &span);
mie_parser_report_error_simple(
parser, "builtin",
MIE_BUILTIN_E_INCORRECT_NUMBER_OF_ARGUMENTS,
MIE_BUILTIN_MSG_OP_INCORRECT_NUMBER_OF_ARGS, &span);
return MIE_ERR_BAD_SYNTAX;
}
if (!mie_parser_parse_symbol(parser, MIE_SYM_COLON)) {
mie_parser_report_unexpected_token(
parser, MIE_SYM_COLON, "comparison operand type");
return MIE_ERR_BAD_SYNTAX;
}
const struct mie_type *type;
if (!mie_parser_parse_type(parser, "comparison operand type", &type, &span)) {
return MIE_ERR_BAD_SYNTAX;
}
bool is_int_type = mie_type_is(type, "builtin", "int")
|| mie_type_is(type, "builtin", "index");
if (!is_int_type) {
mie_parser_report_error_simple(
parser, "arith", MIE_ARITH_E_INVALID_INTEGER_TYPE,
MIE_ARITH_MSG_EXPECTED_INTEGER_TYPE, &span);
return MIE_ERR_BAD_SYNTAX;
}
for (size_t i = 0; i < MIE_VECTOR_COUNT(out->op_args); i++) {
out->op_args.items[i].arg_unresolved.reg_type = type;
}
out->op_result.items[0].reg_type
= mie_ctx_get_int_type(mie_parser_get_mie_ctx(parser), 1);
struct mie_attribute *pred_attribute
= mie_ctx_get_int(mie_parser_get_mie_ctx(parser), pred, 64);
mie_attribute_map_put(
&out->op_attrib, "predicate", pred_attribute,
MIE_ATTRMAP_F_REPLACE);
return MIE_SUCCESS;
}
struct mie_register *mie_arith_cmpi_put(
struct mie_emitter *e, enum mie_arith_cmpi_predicate pred,
struct mie_register *left, struct mie_register *right, const char *name)
{
struct mie_register *args[] = {left, right};
const size_t nr_args = sizeof args / sizeof args[0];
struct mie_op *op = mie_emitter_put_op(e, "arith", "cmpi", args, nr_args);
const struct mie_type *ty = left->reg_type;
struct mie_register *result = mie_op_add_result(op, ty);
mie_emitter_put_name(e, &result->reg_name, name);
struct mie_attribute *pred_attribute
= mie_ctx_get_int(mie_emitter_get_ctx(e), pred, 64);
mie_attribute_map_put(
&op->op_attrib, "predicate", pred_attribute, MIE_ATTRMAP_F_REPLACE);
return result;
}
MIE_OP_DEFINITION_BEGIN(mie_arith_cmpi, "cmpi")
MIE_OP_DEFINITION_PRINT(print);
MIE_OP_DEFINITION_PARSE(parse);

View File

@@ -1,11 +1,14 @@
#include <mie/attribute/attribute.h>
#include <mie/dialect/arith.h>
#include <mie/dialect/builtin.h>
#include <mie/dialect/dialect.h>
#include <mie/ir/emit.h>
#include <mie/ir/op-definition.h>
#include <mie/ir/op.h>
#include <mie/macros.h>
#include <mie/parse/parser.h>
#include <mie/print/printer.h>
#include <mie/type/type.h>
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
{
@@ -36,11 +39,126 @@ static enum mie_status print(struct mie_printer *printer, const struct mie_op *o
return MIE_SUCCESS;
}
static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
static enum mie_status parse_int(
struct mie_parser *parser, long long i, struct mie_file_span *loc,
struct mie_op *out)
{
if (!mie_parser_parse_symbol(parser, MIE_SYM_COLON)) {
mie_parser_report_unexpected_token(
parser, MIE_SYM_COLON, "arithmetic constant type");
return MIE_ERR_BAD_SYNTAX;
}
const struct mie_type *type = NULL;
struct mie_file_span type_span;
if (!mie_parser_parse_type(
parser, "arithmetic constant type", &type, &type_span)) {
mie_parser_report_unexpected_token(
parser, MIE_TOK_TYPENAME, "arithmetic constant type");
return MIE_ERR_BAD_SYNTAX;
}
struct mie_attribute *value = NULL;
if (mie_type_is(type, "builtin", "int")) {
value = mie_ctx_get_int(
mie_parser_get_mie_ctx(parser), i,
mie_int_type_get_width(type));
} else if (mie_type_is(type, "builtin", "index")) {
value = mie_ctx_get_index(mie_parser_get_mie_ctx(parser), i);
} else {
mie_parser_report_error_simple(
parser, "arith", MIE_ARITH_E_INVALID_INTEGER_TYPE,
MIE_ARITH_MSG_EXPECTED_INTEGER_TYPE, &type_span);
}
if (MIE_VECTOR_COUNT(out->op_result) != 1) {
mie_parser_report_error_simple(
parser, "builtin",
MIE_BUILTIN_E_INCORRECT_NUMBER_OF_RESULTS,
MIE_BUILTIN_MSG_OP_EXPECTS_X_RESULTS, &type_span);
return MIE_ERR_BAD_SYNTAX;
}
mie_attribute_map_put(
&out->op_attrib, "value", value, MIE_ATTRMAP_F_REPLACE);
out->op_result.items[0].reg_type = type;
return MIE_SUCCESS;
}
static enum mie_status parse_float(
struct mie_parser *parser, double d, struct mie_file_span *loc,
struct mie_op *out)
{
if (!mie_parser_parse_symbol(parser, MIE_SYM_COLON)) {
mie_parser_report_unexpected_token(
parser, MIE_SYM_COLON, "arithmetic constant type");
return MIE_ERR_BAD_SYNTAX;
}
const struct mie_type *type = NULL;
struct mie_file_span type_span;
if (!mie_parser_parse_type(
parser, "arithmetic constant type", &type, &type_span)) {
mie_parser_report_unexpected_token(
parser, MIE_TOK_TYPENAME, "arithmetic constant type");
return MIE_ERR_BAD_SYNTAX;
}
struct mie_attribute *value = NULL;
if (mie_type_is(type, "builtin", "float")) {
value = mie_ctx_get_float(
mie_parser_get_mie_ctx(parser), d,
mie_float_type_get_width(type));
} else {
mie_parser_report_error_simple(
parser, "arith", MIE_ARITH_E_INVALID_FLOAT_TYPE,
MIE_ARITH_MSG_EXPECTED_FLOAT_TYPE, &type_span);
return MIE_ERR_BAD_SYNTAX;
}
if (MIE_VECTOR_COUNT(out->op_result) != 1) {
mie_parser_report_error_simple(
parser, "builtin",
MIE_BUILTIN_E_INCORRECT_NUMBER_OF_RESULTS,
MIE_BUILTIN_MSG_OP_EXPECTS_X_RESULTS, &type_span);
return MIE_ERR_BAD_SYNTAX;
}
mie_attribute_map_put(
&out->op_attrib, "value", value, MIE_ATTRMAP_F_REPLACE);
out->op_result.items[0].reg_type = type;
return MIE_SUCCESS;
}
static enum mie_status parse(
struct mie_parser *parser, struct mie_parser_scope *scope,
struct mie_op *out)
{
double d;
long long i;
struct mie_file_span span;
if (mie_parser_parse_int(parser, &i, &span)) {
return parse_int(parser, i, &span, out);
} else if (mie_parser_parse_float(parser, &d, &span)) {
return parse_float(parser, d, &span, out);
} else {
struct mie_parser_item required[] = {
MIE_PARSE_ITEM_TOKEN(MIE_TOK_INT),
MIE_PARSE_ITEM_TOKEN(MIE_TOK_FLOAT),
MIE_PARSE_ITEM_NONE,
};
mie_parser_report_unexpected_token_v(
parser, required, "arithmetic constant");
return MIE_ERR_BAD_SYNTAX;
}
}
struct mie_register *mie_arith_constant_i_put(
struct mie_emitter *e, long long value, const char *name)
{

View File

@@ -59,7 +59,7 @@ static enum mie_status parse(
}
const struct mie_type *type = NULL;
if (!mie_parser_parse_type(ctx, &type)) {
if (!mie_parser_parse_type(ctx, NULL, &type, NULL)) {
return MIE_ERR_BAD_SYNTAX;
}

View File

@@ -64,7 +64,7 @@ static enum mie_status parse(
if (!mie_parser_parse_symbol(ctx, MIE_SYM_COLON)) {
width = 64;
} else if (!mie_parser_parse_type(ctx, &type)) {
} else if (!mie_parser_parse_type(ctx, NULL, &type, NULL)) {
return false;
} else {
width = mie_int_type_get_width(type);

View File

@@ -53,7 +53,7 @@ static enum mie_status parse(
const struct mie_type *type = NULL;
if (!mie_parser_parse_type(ctx, &type)) {
if (!mie_parser_parse_type(ctx, NULL, &type, NULL)) {
free(ty);
return MIE_ERR_BAD_FORMAT;
}

View File

@@ -97,6 +97,7 @@ MIE_DIALECT_BEGIN(mie_builtin, struct builtin_dialect, "builtin")
MIE_DIALECT_ADD_TYPE(mie_builtin_float);
MIE_DIALECT_ADD_TYPE(mie_builtin_index);
MIE_DIALECT_ADD_TYPE(mie_builtin_string);
MIE_DIALECT_ADD_TYPE(mie_builtin_memref);
MIE_DIALECT_ADD_ATTRIBUTE(mie_builtin_int);
MIE_DIALECT_ADD_ATTRIBUTE(mie_builtin_float);
MIE_DIALECT_ADD_ATTRIBUTE(mie_builtin_type);

View File

@@ -8,13 +8,36 @@
MIE_DIAG_CLASS_LIST_BEGIN(mie_builtin_diag)
MIE_DIAG_CLASS(UNRECOGNISED_TOKEN, ERROR, "Unrecognised token")
MIE_DIAG_CLASS(UNEXPECTED_TOKEN, ERROR, "Unexpected token")
MIE_DIAG_CLASS(UNRESOLVED_TYPE, ERROR, "Unresolved type")
MIE_DIAG_CLASS(UNRESOLVED_VALUE, ERROR, "Unresolved value")
MIE_DIAG_CLASS(UNRESOLVED_SUCCESSOR, ERROR, "Unresolved successor")
MIE_DIAG_CLASS(UNKNOWN_OP, ERROR, "Unknown op")
MIE_DIAG_CLASS(
OP_REQUIRES_PARENT_SCOPE, ERROR, "Op requires parent scope")
MIE_DIAG_CLASS(
INCORRECT_NUMBER_OF_RESULTS, ERROR,
"Incorrect number of results")
MIE_DIAG_CLASS(
INCORRECT_NUMBER_OF_ARGUMENTS, ERROR,
"Incorrect number of arguments")
MIE_DIAG_CLASS(
INCORRECT_NUMBER_OF_TYPES, ERROR, "Incorrect number of types")
MIE_DIAG_CLASS(INCORRECT_TYPE, ERROR, "Incorrect type")
MIE_DIAG_CLASS(INVALID_TYPE, ERROR, "Invalid type")
MIE_DIAG_CLASS(NAME_ALREADY_IN_USE, ERROR, "Name already in use")
MIE_DIAG_CLASS(INTERNAL_ERROR, ERROR, "Internal error")
MIE_DIAG_CLASS_LIST_END(mie_builtin_diag)
MIE_DIAG_MSG_LIST_BEGIN(mie_builtin_msg)
MIE_DIAG_MSG(UNRECOGNISED_TOKEN, "encountered an unrecognised token.")
MIE_DIAG_MSG(UNRESOLVED_VALUE, "cannot resolve this value reference.")
MIE_DIAG_MSG(
UNRESOLVED_BUILTIN_TYPE,
"cannot resolve this builtin type reference.")
MIE_DIAG_MSG(
UNRESOLVED_DIALECT_TYPE,
"cannot resolve this dialect type reference.")
MIE_DIAG_MSG(
CANNOT_FIND_BLOCK,
"cannot find a block with this name in this region.")
@@ -33,4 +56,43 @@ MIE_DIAG_MSG_LIST_BEGIN(mie_builtin_msg)
"outside of this region.")
MIE_DIAG_MSG(
VALUE_DEFINED_IN_BLOCK, "the value is defined in this block.")
MIE_DIAG_MSG(UNKNOWN_OP, "encountered an unknown operation.")
MIE_DIAG_MSG(
OP_REQUIRES_PARENT_SCOPE,
"this operation requires a parent scope.")
MIE_DIAG_MSG(
OP_PARENT_SCOPE_EXAMPLE,
"operations that require a parent scope cannot be used as a "
"top-level operation. try wrapping this operation in a "
"[blue]module[reset].")
MIE_DIAG_MSG(
USE_GENERIC_OP_SYNTAX,
"if this op belongs to an unknown dialect, you can use generic "
"op syntax to represent it.")
MIE_DIAG_MSG(
OP_HAS_NO_PARSER,
"this operation has no associated parser functionality.")
MIE_DIAG_MSG(
DIALECT_INTERNAL_ERROR,
"this error is caused by an internal problem with the relevant "
"dialect. please report the issue to the dialect vendor.")
MIE_DIAG_MSG(
COMPILER_INTERNAL_ERROR,
"this error is caused by an internal compiler issue. please "
"report the issue to the compiler vendor.")
MIE_DIAG_MSG(
NR_RESULT_NAME_OUTPUT_MISMATCH,
"the number of [red]output value names[reset] does not match "
"the number of results.")
MIE_DIAG_MSG(
OP_INCORRECT_NUMBER_OF_ARGS,
"this operation does not have the correct number of arguments.")
MIE_DIAG_MSG(
OP_NR_TYPES_DOESNT_MATCH_NR_ARGS,
"the number of types specified does not match the number of "
"arguments.")
MIE_DIAG_MSG(
OP_NR_TYPES_DOESNT_MATCH_NR_RESULTS,
"the number of types specified does not match the number of "
"results.")
MIE_DIAG_MSG_LIST_END(mie_builtin_msg)

View File

@@ -4,6 +4,7 @@
#include <mie/ir/op.h>
#include <mie/ir/region.h>
#include <mie/macros.h>
#include <mie/parse/parser.h>
#include <mie/print/printer.h>
static enum mie_status print(struct mie_printer *out, const struct mie_op *op)
@@ -18,8 +19,21 @@ static enum mie_status print(struct mie_printer *out, const struct mie_op *op)
return MIE_SUCCESS;
}
static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
static enum mie_status parse(
struct mie_parser *parser, struct mie_parser_scope *scope,
struct mie_op *out)
{
struct mie_region *region = mie_op_add_region(out);
if (mie_parser_peek_symbol(parser) != MIE_SYM_LEFT_BRACE) {
mie_parser_report_unexpected_token_s(
parser, "region", "module body");
return MIE_ERR_BAD_SYNTAX;
}
if (!mie_parser_parse_region(parser, out, region, NULL)) {
return MIE_ERR_BAD_SYNTAX;
}
return MIE_SUCCESS;
}

View File

@@ -0,0 +1,290 @@
#include <blue/core/bstr.h>
#include <mie/ctx.h>
#include <mie/dialect/builtin.h>
#include <mie/dialect/dialect.h>
#include <mie/dialect/memref.h>
#include <mie/macros.h>
#include <mie/parse/parser.h>
#include <mie/print/printer.h>
#include <mie/type/type-definition.h>
#include <mie/type/type.h>
struct memref_type {
struct mie_type m_base;
MIE_VECTOR_DECLARE(struct mie_memref_rank, m_rank);
};
struct mie_type *mie_ctx_get_memref_type(
struct mie_ctx *ctx, const struct mie_memref_rank *ranks, size_t nr_ranks)
{
struct mie_type_definition *type_info
= mie_ctx_get_type_definition(ctx, "builtin", "memref");
if (!type_info) {
return NULL;
}
struct mie_id_builder id_ctx;
mie_id_builder_begin(&id_ctx, mie_id_map_get_ns(&ctx->ctx_types));
mie_id_builder_add_cstr(&id_ctx, "memref");
for (size_t i = 0; i < nr_ranks; i++) {
switch (ranks[i].r_ranktype) {
case MIE_MEMREF_RANK_UNKNOWN:
mie_id_builder_add_char(&id_ctx, '?');
break;
case MIE_MEMREF_RANK_TYPE:
mie_id_builder_add_id(&id_ctx, &ranks[i].r_type->ty_id);
break;
case MIE_MEMREF_RANK_STATIC:
mie_id_builder_add_int(&id_ctx, ranks[i].r_static);
break;
default:
return NULL;
}
}
mie_id id;
mie_id_builder_end(&id_ctx, &id);
mie_id *target = mie_id_map_get(&ctx->ctx_types, &id);
if (target) {
return b_unbox(struct mie_type, target, ty_id);
}
struct memref_type *type
= (struct memref_type *)mie_type_create(type_info);
if (!type) {
return NULL;
}
b_bstr type_name;
b_bstr_begin_dynamic(&type_name);
b_bstr_write_cstr(&type_name, "builtin.memref<", NULL);
struct mie_printer printer;
mie_printer_init(
&printer, ctx, (b_stream *)&type_name, MIE_PRINT_F_ABBREVIATED);
for (size_t i = 0; i < nr_ranks; i++) {
mie_vector_push_back(type->m_rank, &ranks[i], NULL);
if (i > 0) {
b_bstr_write_char(&type_name, '*');
}
switch (ranks[i].r_ranktype) {
case MIE_MEMREF_RANK_UNKNOWN:
b_bstr_write_char(&type_name, '?');
break;
case MIE_MEMREF_RANK_TYPE:
mie_printer_print_type(&printer, ranks[i].r_type);
break;
case MIE_MEMREF_RANK_STATIC:
b_bstr_write_fmt(&type_name, NULL, "%zu", ranks[i].r_static);
break;
default:
break;
}
}
b_bstr_write_char(&type_name, '>');
type->m_base.ty_name = b_bstr_end(&type_name);
type->m_base.ty_instance_size = 0;
b_rope name_rope = B_ROPE_CSTR(type->m_base.ty_name);
mie_id_map_put(&ctx->ctx_types, &type->m_base.ty_id, &name_rope);
return (struct mie_type *)type;
}
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)
{
const struct memref_type *memref_ty = (const struct memref_type *)ty;
b_stream_write_string(
out->p_stream,
(out->p_flags & MIE_PRINT_F_ABBREVIATED) ? "memref"
: "builtin.memref",
NULL);
b_stream_write_char(out->p_stream, '<');
for (size_t i = 0; i < MIE_VECTOR_COUNT(memref_ty->m_rank); i++) {
const struct mie_memref_rank *rank = &memref_ty->m_rank.items[i];
if (i > 0) {
b_stream_write_char(out->p_stream, '*');
}
switch (rank->r_ranktype) {
case MIE_MEMREF_RANK_UNKNOWN:
b_stream_write_char(out->p_stream, '?');
break;
case MIE_MEMREF_RANK_TYPE:
mie_printer_print_type(out, rank->r_type);
break;
case MIE_MEMREF_RANK_STATIC:
b_stream_write_fmt(
out->p_stream, NULL, "%zu", rank->r_static);
break;
default:
break;
}
}
b_stream_write_char(out->p_stream, '>');
return MIE_SUCCESS;
}
static bool parse_rank(struct mie_parser *parser, struct mie_memref_rank *out)
{
enum mie_token_type tok_type = mie_parser_peek_type(parser);
struct mie_parser_item expected_tokens[] = {
MIE_PARSE_ITEM_TOKEN(MIE_TOK_TYPENAME),
MIE_PARSE_ITEM_TOKEN(MIE_TOK_INT),
MIE_PARSE_ITEM_TOKEN(MIE_SYM_QUESTION),
MIE_PARSE_ITEM_NONE,
};
long long v;
switch (tok_type) {
case MIE_TOK_INT:
out->r_ranktype = MIE_MEMREF_RANK_STATIC;
out->r_type = mie_ctx_get_type(
mie_parser_get_mie_ctx(parser), "builtin", "index");
mie_parser_parse_int(parser, &v, &out->r_span);
out->r_static = v;
break;
case MIE_TOK_SYMBOL:
switch (mie_parser_peek_symbol(parser)) {
case MIE_SYM_QUESTION:
out->r_span = mie_parser_peek(parser)->tok_location;
mie_parser_parse_symbol(parser, MIE_SYM_QUESTION);
out->r_ranktype = MIE_MEMREF_RANK_UNKNOWN;
break;
case MIE_SYM_LEFT_PAREN:
out->r_ranktype = MIE_MEMREF_RANK_TYPE;
if (!mie_parser_parse_type(
parser, "memref type rank", &out->r_type,
&out->r_span)) {
return false;
}
break;
default:
mie_parser_report_unexpected_token_v(
parser, expected_tokens, "memref rank");
return false;
}
break;
case MIE_TOK_WORD:
case MIE_TOK_TYPENAME:
out->r_ranktype = MIE_MEMREF_RANK_TYPE;
if (!mie_parser_parse_type(
parser, "memref type rank", &out->r_type, &out->r_span)) {
return false;
}
break;
default:
mie_parser_report_unexpected_token_v(
parser, expected_tokens, "memref rank");
return false;
}
return true;
}
static bool parse_ranks(
struct mie_parser *parser,
MIE_VECTOR_REF_PARAM(struct mie_memref_rank, ranks))
{
struct mie_memref_rank rank;
if (!parse_rank(parser, &rank)) {
return false;
}
mie_vector_ref_push_back(ranks, &rank, NULL);
while (1) {
if (mie_parser_peek_symbol(parser) == MIE_SYM_RIGHT_ANGLE) {
break;
}
if (!mie_parser_parse_symbol(parser, MIE_SYM_ASTERISK)) {
mie_parser_report_unexpected_token(
parser, MIE_SYM_ASTERISK, "memref rank list");
return false;
}
if (!parse_rank(parser, &rank)) {
return false;
}
mie_vector_ref_push_back(ranks, &rank, NULL);
}
return true;
}
static enum mie_status parse(struct mie_parser *parser, const struct mie_type **out)
{
if (!mie_parser_parse_symbol(parser, MIE_SYM_LEFT_ANGLE)) {
mie_parser_report_unexpected_token(
parser, MIE_SYM_LEFT_ANGLE, "memref type");
return MIE_ERR_BAD_SYNTAX;
}
MIE_VECTOR_DEFINE(struct mie_memref_rank, ranks);
if (!parse_ranks(parser, MIE_VECTOR_REF(ranks))) {
return MIE_ERR_BAD_SYNTAX;
}
if (!mie_parser_parse_symbol(parser, MIE_SYM_RIGHT_ANGLE)) {
mie_parser_report_unexpected_token(
parser, MIE_SYM_RIGHT_ANGLE, "memref type");
return MIE_ERR_BAD_SYNTAX;
}
const struct mie_type *type = mie_ctx_get_memref_type(
mie_parser_get_mie_ctx(parser), ranks.items, ranks.count);
mie_vector_destroy(ranks, NULL);
*out = type;
return MIE_SUCCESS;
}
size_t mie_memref_type_get_nr_ranks(const struct mie_type *type)
{
if (!mie_type_is(type, "builtin", "memref")) {
return 0;
}
const struct memref_type *memref = (const struct memref_type *)type;
return MIE_VECTOR_COUNT(memref->m_rank);
}
const struct mie_memref_rank *mie_memref_type_get_rank(
const struct mie_type *type, size_t i)
{
if (!mie_type_is(type, "builtin", "memref")) {
return 0;
}
const struct memref_type *memref = (const struct memref_type *)type;
if (i >= MIE_VECTOR_COUNT(memref->m_rank)) {
return NULL;
}
return &memref->m_rank.items[i];
}
const struct mie_memref_rank *mie_memref_type_get_rank(
const struct mie_type *type, size_t i);
MIE_TYPE_DEFINITION_BEGIN(mie_builtin_memref, "memref")
MIE_TYPE_DEFINITION_INIT(type_init);
MIE_TYPE_DEFINITION_STRUCT(struct memref_type);
MIE_TYPE_DEFINITION_PRINT(print);
MIE_TYPE_DEFINITION_PARSE(parse);
MIE_TYPE_DEFINITION_END()

View File

@@ -1,8 +1,10 @@
#include <mie/dialect/builtin.h>
#include <mie/dialect/dialect.h>
#include <mie/ir/emit.h>
#include <mie/ir/op-definition.h>
#include <mie/ir/op.h>
#include <mie/macros.h>
#include <mie/parse/parser.h>
#include <mie/print/printer.h>
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
@@ -29,8 +31,104 @@ static enum mie_status print(struct mie_printer *printer, const struct mie_op *o
return MIE_SUCCESS;
}
static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
static bool parse_successor(struct mie_parser *ctx, struct mie_op_successor *out)
{
memset(out, 0x0, sizeof *out);
b_string *str = mie_parser_get_tempstr(ctx);
bool result = false;
if (!mie_parser_parse_blockname(ctx, str, &out->s_name_span)) {
mie_parser_report_unexpected_token(
ctx, MIE_TOK_BLOCKNAME, "branch destination");
return false;
}
out->s_block_name = b_string_steal(str);
if (mie_parser_peek_type(ctx) == MIE_TOK_LINEFEED
|| mie_parser_peek_symbol(ctx) == MIE_SYM_COMMA) {
goto ok;
}
if (!mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_PAREN)) {
struct mie_parser_item expected[] = {
MIE_PARSE_ITEM_TOKEN(MIE_SYM_COMMA),
MIE_PARSE_ITEM_TOKEN(MIE_SYM_LEFT_PAREN),
MIE_PARSE_ITEM_TOKEN(MIE_TOK_LINEFEED),
MIE_PARSE_ITEM_NONE,
};
mie_parser_report_unexpected_token_v(
ctx, expected, "branch destination/arguments");
goto fail;
}
if (!mie_parser_parse_parameter_list(
ctx, true, MIE_VECTOR_REF(out->s_args),
"branch successor arguments")) {
goto fail;
}
if (!mie_parser_parse_symbol(ctx, MIE_SYM_RIGHT_PAREN)) {
mie_parser_report_unexpected_token(
ctx, MIE_SYM_RIGHT_PAREN, "branch arguments");
goto fail;
}
ok:
return true;
fail:
if (out->s_block_name) {
free(out->s_block_name);
out->s_block_name = NULL;
}
if (MIE_VECTOR_MAX(out->s_args) > 0) {
mie_vector_destroy(out->s_args, NULL);
}
return false;
}
static enum mie_status parse(
struct mie_parser *parser, struct mie_parser_scope *scope,
struct mie_op *out)
{
struct mie_op_arg *cond = mie_op_add_arg(out);
struct mie_file_span span;
if (!mie_parser_parse_parameter(
parser, false, cond, "branch condition")) {
return MIE_ERR_BAD_SYNTAX;
}
if (!mie_parser_parse_symbol(parser, MIE_SYM_COMMA)) {
mie_parser_report_unexpected_token(
parser, MIE_SYM_COMMA, "branch destination list");
return MIE_ERR_BAD_SYNTAX;
}
struct mie_op_successor *true_branch
= mie_vector_emplace_back(out->op_successors, NULL);
if (!parse_successor(parser, true_branch)) {
return MIE_ERR_BAD_SYNTAX;
}
if (!mie_parser_parse_symbol(parser, MIE_SYM_COMMA)) {
mie_parser_report_unexpected_token(
parser, MIE_SYM_COMMA, "branch destination list");
return MIE_ERR_BAD_SYNTAX;
}
struct mie_op_successor *false_branch
= mie_vector_emplace_back(out->op_successors, NULL);
if (!parse_successor(parser, false_branch)) {
return MIE_ERR_BAD_SYNTAX;
}
cond->arg_unresolved.reg_type
= mie_ctx_get_int_type(mie_parser_get_mie_ctx(parser), 1);
return MIE_SUCCESS;
}

View File

@@ -4,6 +4,7 @@
#include <mie/ir/op-definition.h>
#include <mie/ir/op.h>
#include <mie/macros.h>
#include <mie/parse/parser.h>
#include <mie/print/printer.h>
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
@@ -16,8 +17,78 @@ static enum mie_status print(struct mie_printer *printer, const struct mie_op *o
return MIE_SUCCESS;
}
static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
static bool parse_successor(struct mie_parser *ctx, struct mie_op_successor *out)
{
memset(out, 0x0, sizeof *out);
b_string *str = mie_parser_get_tempstr(ctx);
bool result = false;
if (!mie_parser_parse_blockname(ctx, str, &out->s_name_span)) {
mie_parser_report_unexpected_token(
ctx, MIE_TOK_BLOCKNAME, "branch destination");
return false;
}
out->s_block_name = b_string_steal(str);
if (mie_parser_peek_type(ctx) == MIE_TOK_LINEFEED) {
goto ok;
}
if (!mie_parser_parse_symbol(ctx, MIE_SYM_LEFT_PAREN)) {
struct mie_parser_item expected[] = {
MIE_PARSE_ITEM_TOKEN(MIE_TOK_LINEFEED),
MIE_PARSE_ITEM_TOKEN(MIE_SYM_LEFT_PAREN),
MIE_PARSE_ITEM_NONE,
};
mie_parser_report_unexpected_token_v(
ctx, expected, "branch destination/arguments");
goto fail;
}
if (!mie_parser_parse_parameter_list(
ctx, true, MIE_VECTOR_REF(out->s_args),
"branch successor arguments")) {
goto fail;
}
if (!mie_parser_parse_symbol(ctx, MIE_SYM_RIGHT_PAREN)) {
mie_parser_report_unexpected_token(
ctx, MIE_SYM_RIGHT_PAREN, "branch arguments");
goto fail;
}
ok:
return true;
fail:
if (out->s_block_name) {
free(out->s_block_name);
out->s_block_name = NULL;
}
if (MIE_VECTOR_MAX(out->s_args) > 0) {
mie_vector_destroy(out->s_args, NULL);
}
return false;
}
static enum mie_status parse(
struct mie_parser *parser, struct mie_parser_scope *scope,
struct mie_op *out)
{
struct mie_op_successor *s
= mie_vector_emplace_back(out->op_successors, NULL);
if (!s) {
return MIE_ERR_NO_MEMORY;
}
if (!parse_successor(parser, s)) {
return MIE_ERR_BAD_SYNTAX;
}
return MIE_SUCCESS;
}

View File

@@ -1,5 +1,6 @@
#include <mie/attribute/attribute-map.h>
#include <mie/ctx.h>
#include <mie/diag/diag.h>
#include <mie/dialect/builtin.h>
#include <mie/dialect/dialect.h>
#include <mie/dialect/func.h>
@@ -11,6 +12,7 @@
#include <mie/ir/op.h>
#include <mie/ir/region.h>
#include <mie/macros.h>
#include <mie/parse/parser.h>
#include <mie/print/printer.h>
#include <mie/type/function.h>
@@ -69,8 +71,126 @@ static enum mie_status print(struct mie_printer *printer, const struct mie_op *o
return MIE_SUCCESS;
}
static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
static enum mie_status parse_return_type(
struct mie_parser *parser,
MIE_VECTOR_REF_PARAM(const struct mie_type *, out))
{
bool ok = true;
if (mie_parser_peek_symbol(parser) == MIE_SYM_LEFT_PAREN) {
ok = mie_parser_parse_type_list(
parser, "function return type", MIE_VECTOR_REF2(out), NULL);
} else {
const struct mie_type *tmp;
ok = mie_parser_parse_type(
parser, "function return type", &tmp, NULL);
if (ok) {
mie_vector_ref_push_back(out, &tmp, NULL);
}
}
return ok ? MIE_SUCCESS : MIE_ERR_BAD_SYNTAX;
}
static enum mie_status parse(
struct mie_parser *parser, struct mie_parser_scope *scope,
struct mie_op *out)
{
if (!scope) {
struct mie_diag *diag = mie_parser_report_error_simple(
parser, "builtin", MIE_BUILTIN_E_OP_REQUIRES_PARENT_SCOPE,
MIE_BUILTIN_MSG_OP_REQUIRES_PARENT_SCOPE,
&out->op_name_span);
mie_diag_push_msg(
diag, mie_parser_get_mie_ctx(parser), "builtin",
MIE_BUILTIN_MSG_OP_PARENT_SCOPE_EXAMPLE);
return MIE_ERR_BAD_SYNTAX;
}
b_string *temp = mie_parser_get_tempstr(parser);
if (!mie_parser_parse_symname(parser, temp, NULL)) {
mie_parser_report_unexpected_token(
parser, MIE_TOK_SYMNAME, "function signature");
return MIE_ERR_BAD_SYNTAX;
}
struct mie_attribute *sym_name = mie_ctx_get_string(
mie_parser_get_mie_ctx(parser), b_string_ptr(temp));
if (!mie_parser_parse_symbol(parser, MIE_SYM_LEFT_PAREN)) {
mie_parser_report_unexpected_token(
parser, MIE_SYM_LEFT_PAREN, "function parameter list");
return MIE_ERR_BAD_SYNTAX;
}
MIE_VECTOR_DEFINE(struct mie_op_arg, block_params);
MIE_VECTOR_DEFINE(const struct mie_type *, in_types);
MIE_VECTOR_DEFINE(const struct mie_type *, out_types);
if (!mie_parser_parse_parameter_list(
parser, true, MIE_VECTOR_REF(block_params),
"function parameter list")) {
return MIE_ERR_BAD_SYNTAX;
}
if (!mie_parser_parse_symbol(parser, MIE_SYM_RIGHT_PAREN)) {
mie_parser_report_unexpected_token(
parser, MIE_SYM_LEFT_PAREN, "function parameter list");
return MIE_ERR_BAD_SYNTAX;
}
struct mie_region *body = mie_op_add_region(out);
struct mie_block *entry = mie_region_add_block(body);
for (size_t i = 0; i < MIE_VECTOR_COUNT(block_params); i++) {
struct mie_register *param_reg = mie_vector_emplace_back(
entry->b_params, &mie_register_vector_ops);
param_reg->reg_flags = block_params.items[i].arg_unresolved.reg_flags
| MIE_REGISTER_F_BLOCK_PARAM;
param_reg->reg_type = block_params.items[i].arg_unresolved.reg_type;
param_reg->reg_block = entry;
if (!mie_parser_scope_put_name(
scope, &param_reg->reg_name,
block_params.items[i].arg_unresolved.reg_name,
MIE_NAME_MAP_F_STRICT)) {
return false;
}
mie_vector_push_back(in_types, &param_reg->reg_type, NULL);
}
if (!mie_parser_parse_symbol(parser, MIE_SYM_HYPHEN_RIGHT_ANGLE)) {
mie_parser_report_unexpected_token(
parser, MIE_SYM_HYPHEN_RIGHT_ANGLE,
"function signature");
return MIE_ERR_BAD_SYNTAX;
}
if (parse_return_type(parser, MIE_VECTOR_REF(out_types)) != MIE_SUCCESS) {
return MIE_ERR_BAD_SYNTAX;
}
const struct mie_type *func_type = mie_ctx_get_function_type(
mie_parser_get_mie_ctx(parser), in_types.items, in_types.count,
out_types.items, out_types.count);
mie_vector_destroy(in_types, NULL);
mie_vector_destroy(out_types, NULL);
struct mie_attribute *function_type
= mie_type_attr_create(mie_parser_get_mie_ctx(parser), func_type);
mie_attribute_map_put(
&out->op_attrib, "sym_name", sym_name, MIE_ATTRMAP_F_REPLACE);
mie_attribute_map_put(
&out->op_attrib, "function_type", function_type,
MIE_ATTRMAP_F_REPLACE);
if (!mie_parser_parse_region(parser, out, body, entry)) {
return MIE_ERR_BAD_SYNTAX;
}
return MIE_SUCCESS;
}

View File

@@ -9,6 +9,7 @@
#include <mie/ir/op.h>
#include <mie/ir/region.h>
#include <mie/macros.h>
#include <mie/parse/parser.h>
#include <mie/print/printer.h>
#include <mie/type/function.h>
@@ -38,8 +39,81 @@ static enum mie_status print(struct mie_printer *printer, const struct mie_op *o
return MIE_SUCCESS;
}
static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
static enum mie_status parse(
struct mie_parser *parser, struct mie_parser_scope *scope,
struct mie_op *out)
{
if (!mie_parser_parse_parameter_list(
parser, false, MIE_VECTOR_REF(out->op_args),
"function return values")) {
return MIE_ERR_BAD_SYNTAX;
}
if (!mie_parser_parse_symbol(parser, MIE_SYM_COLON)) {
mie_parser_report_unexpected_token(
parser, MIE_SYM_COLON, "function return type");
return MIE_ERR_BAD_SYNTAX;
}
MIE_VECTOR_DEFINE(const struct mie_type *, types);
const struct mie_type *tmp = NULL;
struct mie_file_span first_span, last_span;
if (!mie_parser_parse_type(
parser, "function return type", &tmp, &first_span)) {
return MIE_ERR_BAD_SYNTAX;
}
mie_vector_push_back(types, &tmp, NULL);
bool ok = true;
while (1) {
if (mie_parser_peek_type(parser) == MIE_TOK_LINEFEED) {
break;
}
if (!mie_parser_parse_symbol(parser, MIE_SYM_COMMA)) {
struct mie_parser_item expected[] = {
MIE_PARSE_ITEM_TOKEN(MIE_SYM_COMMA),
MIE_PARSE_ITEM_TOKEN(MIE_TOK_LINEFEED),
MIE_PARSE_ITEM_NONE,
};
mie_parser_report_unexpected_token_v(
parser, expected, "function return type list");
ok = false;
break;
}
if (!mie_parser_parse_type(
parser, "function return type", &tmp, &last_span)) {
ok = false;
break;
}
mie_vector_push_back(types, &tmp, NULL);
}
if (!ok) {
mie_vector_destroy(types, NULL);
return MIE_ERR_BAD_SYNTAX;
}
if (MIE_VECTOR_COUNT(types) != MIE_VECTOR_COUNT(out->op_args)) {
struct mie_file_span span = {
.s_start = first_span.s_start,
.s_end = last_span.s_end,
};
mie_parser_report_error_simple(
parser, "builtin", MIE_BUILTIN_E_INCORRECT_NUMBER_OF_TYPES,
MIE_BUILTIN_MSG_OP_NR_TYPES_DOESNT_MATCH_NR_ARGS, &span);
return MIE_ERR_BAD_SYNTAX;
}
for (size_t i = 0; i < MIE_VECTOR_COUNT(types); i++) {
out->op_args.items[i].arg_unresolved.reg_type = types.items[i];
}
return MIE_SUCCESS;
}

27
mie/dialect/memref/diag.c Normal file
View File

@@ -0,0 +1,27 @@
#include <mie/diag/class.h>
#include <mie/diag/msg.h>
#include <mie/dialect/memref.h>
#include <mie/macros.h>
#define MIE_DIAG_CLASS_PREFIX MIE_MEMREF_E
#define MIE_DIAG_MSG_PREFIX MIE_MEMREF_MSG
MIE_DIAG_CLASS_LIST_BEGIN(mie_memref_diag)
MIE_DIAG_CLASS_LIST_END(mie_memref_diag)
MIE_DIAG_MSG_LIST_BEGIN(mie_memref_msg)
MIE_DIAG_MSG(
OP_EXPECTS_MEMREF_ARGUMENT,
"this operation requires a memref parameter.")
MIE_DIAG_MSG(
LAST_MEMREF_RANK_MUST_BE_TYPE,
"the last rank of a memref type must be a type.")
MIE_DIAG_MSG(
MEMREF_MUST_HAVE_AT_LEAST_ONE_RANK,
"memref type must have at least one rank.")
MIE_DIAG_MSG(
OP_RESULT_DETERMINED_BY_LAST_MEMREF_RANK,
"the number and type of operation results is determined by "
"[blue]the "
"type of the last memref rank[reset].")
MIE_DIAG_MSG_LIST_END(mie_memref_msg)

View File

@@ -1,3 +1,5 @@
#include <mie/diag/class.h>
#include <mie/diag/msg.h>
#include <mie/dialect/dialect.h>
#include <mie/dialect/memref.h>
#include <mie/macros.h>
@@ -5,7 +7,11 @@
#include <mie/type/type-definition.h>
#include <mie/type/type.h>
MIE_DIAG_CLASS_LIST_EXTERN(mie_memref_diag);
MIE_DIAG_MSG_LIST_EXTERN(mie_memref_msg);
MIE_DIALECT_BEGIN(mie_memref, struct mie_dialect, "memref")
MIE_DIALECT_ADD_TYPE(mie_memref_memref);
MIE_DIALECT_DIAG_CLASS_LIST(mie_memref_diag);
MIE_DIALECT_DIAG_MSG_LIST(mie_memref_msg);
MIE_DIALECT_ADD_OP(mie_memref_load);
MIE_DIALECT_END()

View File

@@ -1,14 +1,210 @@
#include <mie/ctx.h>
#include <mie/diag/diag.h>
#include <mie/diag/highlight.h>
#include <mie/dialect/builtin.h>
#include <mie/dialect/memref.h>
#include <mie/ir/op-definition.h>
#include <mie/ir/op.h>
#include <mie/macros.h>
#include <mie/parse/parser.h>
#include <mie/print/printer.h>
#include <mie/type/storage.h>
#include <mie/type/type.h>
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
{
b_stream_write_char(printer->p_stream, ' ');
const struct mie_type *memref_type = NULL;
if (MIE_VECTOR_COUNT(op->op_args) > 0) {
mie_printer_print_op_arg(printer, &op->op_args.items[0], false);
memref_type = mie_op_arg_get_type(&op->op_args.items[0]);
}
b_stream_write_char(printer->p_stream, '[');
for (size_t i = 1; i < MIE_VECTOR_COUNT(op->op_args); i++) {
if (i > 1) {
b_stream_write_string(printer->p_stream, ", ", NULL);
}
mie_printer_print_op_arg(printer, &op->op_args.items[i], false);
}
b_stream_write_char(printer->p_stream, ']');
if (memref_type) {
b_stream_write_string(printer->p_stream, " : ", NULL);
mie_printer_print_type(printer, memref_type);
}
return MIE_SUCCESS;
}
static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
static bool parse_param_name(
struct mie_parser *ctx, struct mie_op_arg *out, const char *context)
{
memset(out, 0x0, sizeof *out);
b_string *str = mie_parser_get_tempstr(ctx);
struct mie_file_span loc;
if (mie_parser_parse_vregname(ctx, str, &loc)) {
out->arg_unresolved.reg_name = b_string_steal(str);
out->arg_unresolved.reg_flags = MIE_REGISTER_F_VIRTUAL;
} else if (mie_parser_parse_mregname(ctx, str, &loc)) {
out->arg_unresolved.reg_name = b_string_steal(str);
out->arg_unresolved.reg_flags = MIE_REGISTER_F_MACHINE;
} else {
struct mie_parser_item required[] = {
MIE_PARSE_ITEM_TOKEN(MIE_TOK_VREGNAME),
MIE_PARSE_ITEM_TOKEN(MIE_TOK_MREGNAME),
MIE_PARSE_ITEM_NONE,
};
mie_parser_report_unexpected_token_v(ctx, required, context);
return false;
}
out->arg_span = loc;
return true;
}
static bool apply_op_result_types(
const struct mie_op *op, const struct mie_type *result_type)
{
size_t nr_results = 0;
if (!mie_type_is_storage(result_type)) {
if (MIE_VECTOR_COUNT(op->op_result) != 1) {
return false;
}
op->op_result.items[0].reg_type = result_type;
return true;
}
const struct mie_storage_type *storage
= (const struct mie_storage_type *)result_type;
nr_results = mie_storage_type_get_nr_parts(storage);
if (MIE_VECTOR_COUNT(op->op_result) != nr_results) {
return false;
}
for (size_t i = 0; i < nr_results; i++) {
op->op_result.items[i].reg_type = storage->st_parts.items[i];
}
return true;
}
static enum mie_status parse(
struct mie_parser *parser, struct mie_parser_scope *scope,
struct mie_op *out)
{
struct mie_op_arg *buf_arg = mie_op_add_arg(out);
if (!mie_parser_parse_parameter(
parser, false, buf_arg, "memref load source")) {
return MIE_ERR_BAD_SYNTAX;
}
if (!mie_parser_parse_symbol(parser, MIE_SYM_LEFT_BRACKET)) {
mie_parser_report_unexpected_token(
parser, MIE_SYM_LEFT_BRACKET, "memref load index list");
return MIE_ERR_BAD_SYNTAX;
}
if (!mie_parser_parse_parameter_list(
parser, false, MIE_VECTOR_REF(out->op_args),
"memref load index")) {
return MIE_ERR_BAD_SYNTAX;
}
#if 0
while (1) {
if (mie_parser_parse_symbol(parser, MIE_SYM_RIGHT_BRACKET)) {
break;
}
if (!mie_parser_parse_symbol(parser, MIE_SYM_COMMA)) {
unsigned int expected[] = {
MIE_SYM_COMMA,
MIE_SYM_RIGHT_BRACKET,
MIE_TOK_NONE,
};
mie_parser_report_unexpected_token_v(
parser, expected, "memref load index list");
return MIE_ERR_BAD_SYNTAX;
}
struct mie_op_arg *index_arg = mie_op_add_arg(out);
if (!parse_param_name(parser, index_arg, "memref load index")) {
return MIE_ERR_BAD_SYNTAX;
}
}
#endif
if (!mie_parser_parse_symbol(parser, MIE_SYM_RIGHT_BRACKET)) {
mie_parser_report_unexpected_token(
parser, MIE_SYM_RIGHT_BRACKET, "memref load index list");
return MIE_ERR_BAD_SYNTAX;
}
if (!mie_parser_parse_symbol(parser, MIE_SYM_COLON)) {
mie_parser_report_unexpected_token(
parser, MIE_SYM_COLON, "memref type");
return MIE_ERR_BAD_SYNTAX;
}
const struct mie_type *type = NULL;
struct mie_file_span type_span;
if (!mie_parser_parse_type(parser, "memref type", &type, &type_span)) {
return MIE_ERR_BAD_SYNTAX;
}
if (!mie_type_is(type, "builtin", "memref")) {
mie_parser_report_error_simple(
parser, "builtin", MIE_BUILTIN_E_INCORRECT_TYPE,
MIE_MEMREF_MSG_OP_EXPECTS_MEMREF_ARGUMENT, &type_span);
return MIE_ERR_BAD_SYNTAX;
}
size_t nr_ranks = mie_memref_type_get_nr_ranks(type);
if (!nr_ranks) {
mie_parser_report_error_simple(
parser, "builtin", MIE_BUILTIN_E_INVALID_TYPE,
MIE_MEMREF_MSG_MEMREF_MUST_HAVE_AT_LEAST_ONE_RANK,
&type_span);
return MIE_ERR_BAD_SYNTAX;
}
const struct mie_memref_rank *type_rank
= mie_memref_type_get_rank(type, nr_ranks - 1);
if (type_rank->r_ranktype != MIE_MEMREF_RANK_TYPE) {
mie_parser_report_error_simple(
parser, "builtin", MIE_BUILTIN_E_INVALID_TYPE,
MIE_MEMREF_MSG_LAST_MEMREF_RANK_MUST_BE_TYPE,
&type_rank->r_span);
return MIE_ERR_BAD_SYNTAX;
}
if (!apply_op_result_types(out, type_rank->r_type)) {
struct mie_file_span results_span;
mie_op_get_results_span(out, &results_span);
struct mie_diag *diag = mie_parser_report_error_simple(
parser, "builtin",
MIE_BUILTIN_E_INCORRECT_NUMBER_OF_RESULTS,
MIE_BUILTIN_MSG_NR_RESULT_NAME_OUTPUT_MISMATCH,
&results_span);
mie_diag_push_msg(
diag, mie_parser_get_mie_ctx(parser), "memref",
MIE_MEMREF_MSG_OP_RESULT_DETERMINED_BY_LAST_MEMREF_RANK);
struct mie_diag_highlight hl[] = {
MIE_DIAG_HL(HINT, type_rank->r_span),
};
mie_diag_push_snippet(
diag, type_rank->r_span.s_start.c_row,
type_rank->r_span.s_end.c_row, NULL, 0, hl, 1);
return MIE_ERR_BAD_SYNTAX;
}
return MIE_SUCCESS;
}

View File

@@ -1,52 +0,0 @@
#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

@@ -7,7 +7,9 @@ static enum mie_status print(struct mie_printer *printer, const struct mie_op *o
return MIE_SUCCESS;
}
static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
static enum mie_status parse(
struct mie_parser *parser, struct mie_parser_scope *scope,
struct mie_op *out)
{
return MIE_SUCCESS;
}

View File

@@ -7,7 +7,9 @@ static enum mie_status print(struct mie_printer *printer, const struct mie_op *o
return MIE_SUCCESS;
}
static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
static enum mie_status parse(
struct mie_parser *parser, struct mie_parser_scope *scope,
struct mie_op *out)
{
return MIE_SUCCESS;
}

View File

@@ -7,7 +7,9 @@ static enum mie_status print(struct mie_printer *printer, const struct mie_op *o
return MIE_SUCCESS;
}
static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
static enum mie_status parse(
struct mie_parser *parser, struct mie_parser_scope *names,
struct mie_op *out)
{
return MIE_SUCCESS;
}

View File

@@ -1,14 +1,281 @@
#include <mie/ctx.h>
#include <mie/dialect/builtin.h>
#include <mie/dialect/dialect.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/parse/parser.h>
#include <mie/print/printer.h>
#include <mie/type/function.h>
#include <mie/type/storage.h>
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
{
struct mie_region *body = mie_op_get_first_region(op);
struct mie_block *entry = NULL;
struct mie_register *iv = NULL;
struct mie_op_arg *lb = NULL, *ub = NULL, *step = NULL;
if (!body) {
return MIE_ERR_BAD_STATE;
}
entry = mie_region_get_first_block(body);
if (!entry) {
return MIE_ERR_BAD_STATE;
}
if (MIE_VECTOR_COUNT(op->op_args) < 3) {
return MIE_ERR_BAD_STATE;
}
if (MIE_VECTOR_COUNT(entry->b_params) < 1) {
return MIE_ERR_BAD_STATE;
}
iv = &entry->b_params.items[0];
lb = &op->op_args.items[0];
ub = &op->op_args.items[1];
step = &op->op_args.items[2];
b_stream_write_char(printer->p_stream, ' ');
mie_printer_print_register(printer, iv, 0);
b_stream_write_string(printer->p_stream, " = ", NULL);
mie_printer_print_op_arg(printer, lb, 0);
b_stream_write_string(printer->p_stream, " to ", NULL);
mie_printer_print_op_arg(printer, ub, 0);
b_stream_write_string(printer->p_stream, " step ", NULL);
mie_printer_print_op_arg(printer, step, 0);
if (MIE_VECTOR_COUNT(entry->b_params) > 1) {
b_stream_write_string(printer->p_stream, " iter-args(", NULL);
for (size_t i = 1; i < MIE_VECTOR_COUNT(entry->b_params); i++) {
if (i > 1) {
b_stream_write_string(printer->p_stream, ", ", NULL);
}
mie_printer_print_register(
printer, &entry->b_params.items[i], 0);
b_stream_write_string(printer->p_stream, " = ", NULL);
mie_printer_print_op_arg(
printer, &op->op_args.items[i + 2], false);
}
b_stream_write_char(printer->p_stream, ')');
}
if (MIE_VECTOR_COUNT(op->op_result) > 0) {
b_stream_write_string(printer->p_stream, " -> ", NULL);
if (MIE_VECTOR_COUNT(op->op_result) > 1) {
b_stream_write_char(printer->p_stream, '(');
}
for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_result); i++) {
mie_printer_print_type(
printer, op->op_result.items[i].reg_type);
}
if (MIE_VECTOR_COUNT(op->op_result) > 1) {
b_stream_write_char(printer->p_stream, ')');
}
}
b_stream_write_char(printer->p_stream, ' ');
mie_printer_print_region(
printer, body, MIE_PRINT_F_EXCLUDE_FIRST_BLOCK_HEADER);
return MIE_SUCCESS;
}
static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
static bool parse_result_type(
struct mie_parser *parser, struct mie_parser_scope *scope,
struct mie_op *out, struct mie_block *entry)
{
const struct mie_type *type = NULL;
struct mie_file_span span;
if (!mie_parser_parse_type(parser, "loop result type", &type, &span)) {
return false;
}
const struct mie_type **types;
size_t nr_types;
if (mie_type_is_storage(type)) {
const struct mie_storage_type *storage
= (const struct mie_storage_type *)type;
types = storage->st_parts.items;
nr_types = storage->st_parts.count;
} else if (!mie_type_is_function(type)) {
types = &type;
nr_types = 1;
} else {
mie_parser_report_error_simple(
parser, "builtin", MIE_BUILTIN_E_INVALID_TYPE,
MIE_BUILTIN_MSG_CANNOT_USE_FUNCTION_TYPE_HERE, &span);
}
if (MIE_VECTOR_COUNT(out->op_result) != nr_types) {
mie_parser_report_error_simple(
parser, "builtin", MIE_BUILTIN_E_INCORRECT_NUMBER_OF_TYPES,
MIE_BUILTIN_MSG_OP_NR_TYPES_DOESNT_MATCH_NR_RESULTS,
&span);
return false;
}
for (size_t i = 0; i < nr_types; i++) {
out->op_result.items[i].reg_type = types[i];
}
return true;
}
static bool parse_iter_arg(
struct mie_parser *parser, struct mie_parser_scope *scope,
struct mie_op *out, struct mie_block *entry)
{
struct mie_register *reg = mie_block_add_param(entry);
struct mie_op_arg *arg = mie_op_add_arg(out);
if (!mie_parser_parse_register(
parser, scope, "iterator parameter name", reg)) {
return false;
}
if (!mie_parser_parse_symbol(parser, MIE_SYM_EQUAL)) {
mie_parser_report_unexpected_token(
parser, MIE_SYM_EQUAL, "iterator parameter");
return false;
}
if (!mie_parser_parse_parameter(
parser, false, arg, "iterator parameter value")) {
return false;
}
struct mie_register *value = mie_parser_scope_find_value(
scope, arg->arg_unresolved.reg_name);
if (value) {
reg->reg_type = value->reg_type;
}
return true;
}
static bool parse_iter_args(
struct mie_parser *parser, struct mie_parser_scope *scope,
struct mie_op *out, struct mie_block *entry)
{
if (!mie_parser_parse_keyword(parser, "iter-args", NULL)) {
return true;
}
if (!mie_parser_parse_symbol(parser, MIE_SYM_LEFT_PAREN)) {
mie_parser_report_unexpected_token(
parser, MIE_SYM_LEFT_PAREN, "iterator parameter list");
return false;
}
if (!parse_iter_arg(parser, scope, out, entry)) {
return false;
}
while (1) {
if (mie_parser_parse_symbol(parser, MIE_SYM_RIGHT_PAREN)) {
break;
}
if (!mie_parser_parse_symbol(parser, MIE_SYM_COMMA)) {
struct mie_parser_item expected[] = {
MIE_PARSE_ITEM_TOKEN(MIE_SYM_COMMA),
MIE_PARSE_ITEM_TOKEN(MIE_SYM_RIGHT_PAREN),
MIE_PARSE_ITEM_NONE,
};
mie_parser_report_unexpected_token_v(
parser, expected, "iterator parameter list");
return false;
}
if (!parse_iter_arg(parser, scope, out, entry)) {
return false;
}
}
return true;
}
static enum mie_status parse(
struct mie_parser *parser, struct mie_parser_scope *scope,
struct mie_op *out)
{
struct mie_region *body = mie_op_add_region(out);
struct mie_block *entry = mie_region_add_block(body);
struct mie_register *iv = mie_block_add_param(entry);
mie_parser_scope_put_name(scope, &entry->b_name, "for.entry", 0);
if (!mie_parser_parse_register(parser, scope, "induction variable", iv)) {
return MIE_ERR_BAD_SYNTAX;
}
iv->reg_type = mie_ctx_get_type(
mie_parser_get_mie_ctx(parser), "builtin", "index");
if (!mie_parser_parse_symbol(parser, MIE_SYM_EQUAL)) {
mie_parser_report_unexpected_token(
parser, MIE_SYM_EQUAL, "for-loop");
return MIE_ERR_BAD_SYNTAX;
}
struct mie_op_arg *lb = mie_op_add_arg(out);
if (!mie_parser_parse_parameter(parser, false, lb, "lower bound")) {
return MIE_ERR_BAD_SYNTAX;
}
if (!mie_parser_parse_keyword(parser, "to", NULL)) {
mie_parser_report_unexpected_token_s(parser, "to", "for-loop");
return MIE_ERR_BAD_SYNTAX;
}
struct mie_op_arg *ub = mie_op_add_arg(out);
if (!mie_parser_parse_parameter(parser, false, ub, "upper bound")) {
return MIE_ERR_BAD_SYNTAX;
}
if (!mie_parser_parse_keyword(parser, "step", NULL)) {
mie_parser_report_unexpected_token_s(parser, "step", "for-loop");
return MIE_ERR_BAD_SYNTAX;
}
struct mie_op_arg *step = mie_op_add_arg(out);
if (!mie_parser_parse_parameter(parser, false, step, "step")) {
return MIE_ERR_BAD_SYNTAX;
}
if (!parse_iter_args(parser, scope, out, entry)) {
return MIE_ERR_BAD_SYNTAX;
}
if (mie_parser_parse_symbol(parser, MIE_SYM_HYPHEN_RIGHT_ANGLE)) {
if (!parse_result_type(parser, scope, out, entry)) {
return MIE_ERR_BAD_SYNTAX;
}
} else if (MIE_VECTOR_COUNT(out->op_result) > 0) {
struct mie_file_span span;
mie_op_get_results_span(out, &span);
mie_parser_report_error_simple(
parser, "builtin",
MIE_BUILTIN_E_INCORRECT_NUMBER_OF_RESULTS,
MIE_BUILTIN_MSG_OP_NR_TYPES_DOESNT_MATCH_NR_RESULTS,
&span);
return MIE_ERR_BAD_SYNTAX;
}
if (!mie_parser_parse_region(parser, out, body, entry)) {
return MIE_ERR_BAD_SYNTAX;
}
return MIE_SUCCESS;
}

View File

@@ -46,7 +46,9 @@ static enum mie_status print(struct mie_printer *printer, const struct mie_op *o
return MIE_SUCCESS;
}
static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
static enum mie_status parse(
struct mie_parser *parser, struct mie_parser_scope *names,
struct mie_op *out)
{
return MIE_SUCCESS;
}

View File

@@ -1,8 +1,10 @@
#include <mie/dialect/builtin.h>
#include <mie/dialect/dialect.h>
#include <mie/ir/emit.h>
#include <mie/ir/op-definition.h>
#include <mie/ir/op.h>
#include <mie/macros.h>
#include <mie/parse/parser.h>
#include <mie/print/printer.h>
static enum mie_status print(struct mie_printer *printer, const struct mie_op *op)
@@ -30,8 +32,81 @@ static enum mie_status print(struct mie_printer *printer, const struct mie_op *o
return MIE_SUCCESS;
}
static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
static enum mie_status parse(
struct mie_parser *parser, struct mie_parser_scope *scope,
struct mie_op *out)
{
if (!mie_parser_parse_parameter_list(
parser, false, MIE_VECTOR_REF(out->op_args),
"yield value(s)")) {
return MIE_ERR_BAD_SYNTAX;
}
if (!mie_parser_parse_symbol(parser, MIE_SYM_COLON)) {
mie_parser_report_unexpected_token(
parser, MIE_SYM_COLON, "yield value type(s)");
return MIE_ERR_BAD_SYNTAX;
}
MIE_VECTOR_DEFINE(const struct mie_type *, types);
const struct mie_type *tmp = NULL;
struct mie_file_span first_span, last_span;
if (!mie_parser_parse_type(
parser, "yield value type(s)", &tmp, &first_span)) {
return MIE_ERR_BAD_SYNTAX;
}
mie_vector_push_back(types, &tmp, NULL);
bool ok = true;
while (1) {
if (mie_parser_peek_type(parser) == MIE_TOK_LINEFEED) {
break;
}
if (!mie_parser_parse_symbol(parser, MIE_SYM_COMMA)) {
struct mie_parser_item expected[] = {
MIE_PARSE_ITEM_TOKEN(MIE_SYM_COMMA),
MIE_PARSE_ITEM_TOKEN(MIE_TOK_LINEFEED),
MIE_PARSE_ITEM_NONE,
};
mie_parser_report_unexpected_token_v(
parser, expected, "yield value type list");
ok = false;
break;
}
if (!mie_parser_parse_type(
parser, "yield value type", &tmp, &last_span)) {
ok = false;
break;
}
mie_vector_push_back(types, &tmp, NULL);
}
if (!ok) {
mie_vector_destroy(types, NULL);
return MIE_ERR_BAD_SYNTAX;
}
if (MIE_VECTOR_COUNT(types) != MIE_VECTOR_COUNT(out->op_args)) {
struct mie_file_span span = {
.s_start = first_span.s_start,
.s_end = last_span.s_end,
};
mie_parser_report_error_simple(
parser, "builtin", MIE_BUILTIN_E_INCORRECT_NUMBER_OF_TYPES,
MIE_BUILTIN_MSG_OP_NR_TYPES_DOESNT_MATCH_NR_ARGS, &span);
return MIE_ERR_BAD_SYNTAX;
}
for (size_t i = 0; i < MIE_VECTOR_COUNT(types); i++) {
out->op_args.items[i].arg_unresolved.reg_type = types.items[i];
}
return MIE_SUCCESS;
}

View File

@@ -9,7 +9,9 @@ static enum mie_status print(struct mie_printer *printer, const struct mie_op *o
return MIE_SUCCESS;
}
static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
static enum mie_status parse(
struct mie_parser *parser, struct mie_parser_scope *scope,
struct mie_op *out)
{
return MIE_SUCCESS;
}

View File

@@ -4,6 +4,39 @@
#include <blue/core/queue.h>
#include <mie/parse/file-span.h>
#define MIE_DIAG_HL(type, span) \
{ \
.hl_type = MIE_DIAG_HIGHLIGHT_##type, \
.hl_span = (span), \
}
#define MIE_DIAG_ADD(str, loc) \
{ \
.a_type = MIE_DIAG_AMENDMENT_ADD, .__x = strlen(str), \
.a_add = { \
.a_loc = (loc), \
.a_str = (str), \
}, \
}
#define MIE_DIAG_REMOVE(len, llc) \
{ \
.a_type = MIE_DIAG_AMENDMENT_REMOVE, \
.a_remove = { \
.a_loc = (loc), \
.a_length = (len), \
}, \
}
#define MIE_DIAG_REPLACE(len, str, loc) \
{ \
.a_type = MIE_DIAG_AMENDMENT_REPLACE, .__x = strlen(str), \
.a_replace = { \
.a_loc = (loc), \
.a_length = (len), \
.a_str = (str), \
}, \
}
struct mie_ctx;
struct mie_diag_class;
struct mie_diag_amendment;
@@ -31,6 +64,7 @@ MIE_API void mie_diag_set_location(
MIE_API void mie_diag_push_msg(
struct mie_diag *diag, struct mie_ctx *ctx, const char *dialect,
unsigned long msg, ...);
MIE_API void mie_diag_push_string(struct mie_diag *diag, const char *str);
MIE_API void mie_diag_push_snippet(
struct mie_diag *diag, unsigned long first_line, unsigned long last_line,
const struct mie_diag_amendment *amendmends, size_t nr_amendments,

View File

@@ -10,6 +10,32 @@ struct mie_ctx;
struct mie_dialect;
struct mie_emitter;
enum mie_arith_diag {
MIE_ARITH_E_INVALID_INTEGER_TYPE,
MIE_ARITH_E_INVALID_FLOAT_TYPE,
MIE_ARITH_E_INVALID_COMPARISON_PREDICATE,
};
enum mie_arith_msg {
MIE_ARITH_MSG_EXPECTED_INTEGER_TYPE,
MIE_ARITH_MSG_EXPECTED_FLOAT_TYPE,
MIE_ARITH_MSG_INVALID_COMPARISON_PREDICATE,
MIE_ARITH_MSG_VALID_COMPARISON_PREDICATES,
};
enum mie_arith_cmpi_predicate {
MIE_ARITH_CMPI_EQ = 0,
MIE_ARITH_CMPI_NE = 1,
MIE_ARITH_CMPI_SLT = 2,
MIE_ARITH_CMPI_SLE = 3,
MIE_ARITH_CMPI_SGT = 4,
MIE_ARITH_CMPI_SGE = 5,
MIE_ARITH_CMPI_ULT = 6,
MIE_ARITH_CMPI_ULE = 7,
MIE_ARITH_CMPI_UGT = 8,
MIE_ARITH_CMPI_UGE = 9,
};
MIE_API struct mie_dialect *mie_arith_dialect_create(struct mie_ctx *ctx);
MIE_API struct mie_register *mie_arith_constant_i_put(
@@ -19,6 +45,9 @@ MIE_API struct mie_register *mie_arith_constant_f_put(
MIE_API struct mie_register *mie_arith_addi_put(
struct mie_emitter *e, struct mie_register *left,
struct mie_register *right, const char *name);
MIE_API struct mie_register *mie_arith_cmpi_put(
struct mie_emitter *e, enum mie_arith_cmpi_predicate pred,
struct mie_register *left, struct mie_register *right, const char *name);
MIE_API struct mie_register *mie_arith_addf_put(
struct mie_emitter *e, struct mie_register *left,
struct mie_register *right, const char *name);

View File

@@ -5,6 +5,7 @@
#include <mie/attribute/attribute.h>
#include <mie/interface/interface.h>
#include <mie/misc.h>
#include <mie/parse/file-span.h>
#include <mie/trait/trait.h>
#include <mie/vector.h>
@@ -17,18 +18,51 @@ struct mie_float_type;
enum mie_builtin_diag {
MIE_BUILTIN_E_UNRECOGNISED_TOKEN,
MIE_BUILTIN_E_UNEXPECTED_TOKEN,
MIE_BUILTIN_E_UNRESOLVED_TYPE,
MIE_BUILTIN_E_UNRESOLVED_VALUE,
MIE_BUILTIN_E_UNRESOLVED_SUCCESSOR,
MIE_BUILTIN_E_UNKNOWN_OP,
MIE_BUILTIN_E_OP_REQUIRES_PARENT_SCOPE,
MIE_BUILTIN_E_INCORRECT_NUMBER_OF_ARGUMENTS,
MIE_BUILTIN_E_INCORRECT_NUMBER_OF_RESULTS,
MIE_BUILTIN_E_INCORRECT_NUMBER_OF_TYPES,
MIE_BUILTIN_E_INCORRECT_TYPE,
MIE_BUILTIN_E_INVALID_TYPE,
MIE_BUILTIN_E_NAME_ALREADY_IN_USE,
MIE_BUILTIN_E_INTERNAL_ERROR,
};
enum mie_builtin_msg {
MIE_BUILTIN_MSG_UNRECOGNISED_TOKEN,
MIE_BUILTIN_MSG_UNEXPECTED_TOKEN,
MIE_BUILTIN_MSG_UNRESOLVED_VALUE,
MIE_BUILTIN_MSG_UNRESOLVED_BUILTIN_TYPE,
MIE_BUILTIN_MSG_UNRESOLVED_DIALECT_TYPE,
MIE_BUILTIN_MSG_CANNOT_FIND_BLOCK,
MIE_BUILTIN_MSG_VALUE_DEFINED_IN_NON_DOMINANT_BLOCK,
MIE_BUILTIN_MSG_VALUE_DEFINED_AFTER_USE,
MIE_BUILTIN_MSG_VALUE_DEFINED_OUTSIDE_ISOLATED_REGION,
MIE_BUILTIN_MSG_VALUE_DEFINED_IN_BLOCK,
MIE_BUILTIN_MSG_UNKNOWN_OP,
MIE_BUILTIN_MSG_OP_REQUIRES_PARENT_SCOPE,
MIE_BUILTIN_MSG_OP_PARENT_SCOPE_EXAMPLE,
MIE_BUILTIN_MSG_USE_GENERIC_OP_SYNTAX,
MIE_BUILTIN_MSG_OP_HAS_NO_PARSER,
MIE_BUILTIN_MSG_DIALECT_INTERNAL_ERROR,
MIE_BUILTIN_MSG_COMPILER_INTERNAL_ERROR,
MIE_BUILTIN_MSG_OP_INCORRECT_NUMBER_OF_ARGS,
MIE_BUILTIN_MSG_OP_INCORRECT_NUMBER_OF_RESULTS,
MIE_BUILTIN_MSG_OP_NR_TYPES_DOESNT_MATCH_NR_ARGS,
MIE_BUILTIN_MSG_OP_NR_TYPES_DOESNT_MATCH_NR_RESULTS,
MIE_BUILTIN_MSG_OP_EXPECTS_X_RESULTS,
MIE_BUILTIN_MSG_NR_RESULT_NAME_OUTPUT_MISMATCH,
MIE_BUILTIN_MSG_NAME_ALREADY_IN_USE,
MIE_BUILTIN_MSG_NAME_ALREADY_USED_HERE,
MIE_BUILTIN_MSG_CANNOT_USE_FUNCTION_TYPE_HERE,
MIE_BUILTIN_MSG_CANNOT_USE_STORAGE_TYPE_HERE,
MIE_BUILTIN_MSG_MUST_USE_FUNCTION_TYPE_HERE,
MIE_BUILTIN_MSG_MUST_USE_STORAGE_TYPE_HERE,
};
enum mie_float_width {
@@ -36,6 +70,12 @@ enum mie_float_width {
MIE_FLOAT_64 = 64,
};
enum mie_memref_rank_type {
MIE_MEMREF_RANK_UNKNOWN = 0,
MIE_MEMREF_RANK_STATIC,
MIE_MEMREF_RANK_TYPE,
};
struct mie_string {
struct mie_attribute str_base;
char *str_val;
@@ -90,6 +130,15 @@ struct mie_symbol_table {
struct mie_trait tab_base;
};
struct mie_memref_rank {
enum mie_memref_rank_type r_ranktype;
struct mie_file_span r_span;
union {
size_t r_static;
const struct mie_type *r_type;
};
};
struct mie_int_cache;
struct mie_float_cache;
struct mie_string_cache;
@@ -136,6 +185,8 @@ 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);
MIE_API struct mie_type *mie_ctx_get_memref_type(
struct mie_ctx *ctx, const struct mie_memref_rank *ranks, size_t nr_ranks);
MIE_API struct mie_attribute *mie_type_attr_create(
struct mie_ctx *ctx, const struct mie_type *ty);
@@ -143,4 +194,8 @@ MIE_API struct mie_attribute *mie_type_attr_create(
MIE_API size_t mie_int_type_get_width(const struct mie_type *type);
MIE_API size_t mie_float_type_get_width(const struct mie_type *type);
MIE_API size_t mie_memref_type_get_nr_ranks(const struct mie_type *type);
MIE_API const struct mie_memref_rank *mie_memref_type_get_rank(
const struct mie_type *type, size_t i);
#endif

View File

@@ -8,6 +8,13 @@
struct mie_ctx;
struct mie_dialect;
enum mie_memref_msg {
MIE_MEMREF_MSG_OP_EXPECTS_MEMREF_ARGUMENT,
MIE_MEMREF_MSG_LAST_MEMREF_RANK_MUST_BE_TYPE,
MIE_MEMREF_MSG_MEMREF_MUST_HAVE_AT_LEAST_ONE_RANK,
MIE_MEMREF_MSG_OP_RESULT_DETERMINED_BY_LAST_MEMREF_RANK,
};
MIE_API struct mie_dialect *mie_memref_dialect_create(struct mie_ctx *ctx);
#endif

View File

@@ -86,6 +86,18 @@ static inline void mie_id_builder_add_cstr(
{
mie_id_builder_add(builder, s, strlen(s));
}
static inline void mie_id_builder_add_id(
struct mie_id_builder *builder, const mie_id *id)
{
mie_id_builder_add(builder, id->id_bytes, sizeof id->id_bytes);
}
static inline void mie_id_builder_add_int(
struct mie_id_builder *builder, long long v)
{
char s[32];
size_t len = snprintf(s, sizeof s, "%lld", v);
mie_id_builder_add(builder, s, len);
}
MIE_API void mie_id_builder_add_rope(
struct mie_id_builder *builder, const b_rope *rope);
MIE_API void mie_id_builder_add_marker(

View File

@@ -15,6 +15,7 @@ struct mie_op;
struct mie_printer;
struct mie_parser;
struct mie_dialect;
struct mie_parser_scope;
#if 0
enum mie_op_trait {
@@ -103,7 +104,8 @@ struct mie_op_definition {
const struct mie_op_result op_results[MIE_OP_MAX_RESULTS];
enum mie_status (*op_print)(struct mie_printer *, const struct mie_op *);
enum mie_status (*op_parse)(struct mie_parser *, struct mie_op *);
enum mie_status (*op_parse)(
struct mie_parser *, struct mie_parser_scope *, struct mie_op *);
};
MIE_API struct mie_op_definition *mie_op_definition_create(

View File

@@ -79,10 +79,6 @@ MIE_API void mie_op_cleanup(struct mie_op *op);
MIE_API size_t mie_op_get_name(const struct mie_op *op, char *out, size_t max);
MIE_API bool mie_op_resolve_self(struct mie_op *op, struct mie_ctx *ctx);
MIE_API bool mie_op_resolve_args(struct mie_op *op, struct mie_ctx *ctx);
MIE_API bool mie_op_resolve_successors(struct mie_op *op, struct mie_ctx *ctx);
MIE_API struct mie_op_arg *mie_op_add_arg(struct mie_op *op);
MIE_API struct mie_register *mie_op_add_result(
struct mie_op *op, const struct mie_type *ty);
@@ -110,6 +106,11 @@ MIE_API struct mie_register *mie_op_get_arg(const struct mie_op *op, size_t inde
MIE_API struct mie_register *mie_op_get_result_with_name(
const struct mie_op *op, const char *name);
MIE_API void mie_op_get_args_span(
const struct mie_op *op, struct mie_file_span *result);
MIE_API void mie_op_get_results_span(
const struct mie_op *op, struct mie_file_span *result);
MIE_API struct mie_op *mie_op_get_first_child_op(const struct mie_op *op);
MIE_API struct mie_op *mie_op_get_last_child_op(const struct mie_op *op);

View File

@@ -32,6 +32,8 @@ MIE_API struct mie_block *mie_region_get_next_block(
MIE_API struct mie_block *mie_region_get_last_block(const struct mie_region *region);
MIE_API struct mie_block *mie_region_add_block(struct mie_region *region);
MIE_API struct mie_block *mie_region_add_block_before(
struct mie_region *region, struct mie_block *before);
MIE_API struct mie_block *mie_region_add_block_after(
struct mie_region *region, struct mie_block *after);
MIE_API struct mie_block *mie_region_find_block(

View File

@@ -17,6 +17,7 @@ MIE_API void mie_lex_destroy(struct mie_lex *lex);
MIE_API enum mie_status mie_lex_get_status(const struct mie_lex *lex);
MIE_API struct mie_line_source *mie_lex_get_line_source(const struct mie_lex *lex);
MIE_API const struct mie_file_cell *mie_lex_get_cursor(const struct mie_lex *lex);
MIE_API struct mie_token *mie_lex_peek(struct mie_lex *lex);
MIE_API void mie_lex_advance(struct mie_lex *lex);

View File

@@ -25,6 +25,30 @@ struct mie_register;
struct mie_attribute_map;
struct mie_attribute;
#define MIE_PARSE_ITEM_NONE {.i_type = MIE_PARSER_ITEM_NONE}
#define MIE_PARSE_ITEM_TOKEN(tok) \
{.i_type = MIE_PARSER_ITEM_TOK, .i_tok = (tok)}
#define MIE_PARSE_ITEM_CSTR(s) {.i_type = MIE_PARSER_ITEM_CSTR, .i_cstr = (s)}
struct mie_parser_scope {
struct mie_region *s_region;
struct mie_name_map *s_names;
};
enum mie_parser_item_type {
MIE_PARSER_ITEM_NONE = 0,
MIE_PARSER_ITEM_TOK,
MIE_PARSER_ITEM_CSTR,
};
struct mie_parser_item {
enum mie_parser_item_type i_type;
union {
unsigned int i_tok;
const char *i_cstr;
};
};
MIE_API struct mie_parser *mie_parser_create(
struct mie_ctx *ctx, struct mie_lex *lex);
MIE_API void mie_parser_destroy(struct mie_parser *ctx);
@@ -51,6 +75,8 @@ MIE_API bool mie_parser_parse_float(
struct mie_parser *ctx, double *out, struct mie_file_span *loc);
MIE_API bool mie_parser_parse_word(
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
MIE_API bool mie_parser_parse_name(
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
MIE_API bool mie_parser_parse_instname(
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
MIE_API bool mie_parser_parse_graphname(
@@ -71,17 +97,22 @@ MIE_API bool mie_parser_parse_symname(
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
MIE_API bool mie_parser_parse_string(
struct mie_parser *ctx, b_string *out, struct mie_file_span *loc);
MIE_API bool mie_parser_parse_keyword(struct mie_parser *ctx, const char *kw);
MIE_API bool mie_parser_parse_keyword(
struct mie_parser *ctx, const char *kw, struct mie_file_span *loc);
MIE_API bool mie_parser_parse_symbol(
struct mie_parser *ctx, enum mie_token_symbol sym);
MIE_API bool mie_parser_parse_linefeed(struct mie_parser *ctx);
MIE_API bool mie_parser_parse_type(
struct mie_parser *ctx, const struct mie_type **out);
struct mie_parser *ctx, const char *context,
const struct mie_type **out, struct mie_file_span *out_span);
MIE_API bool mie_parser_parse_type_list(
struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(const struct mie_type *, out));
struct mie_parser *ctx, const char *context,
MIE_VECTOR_REF_PARAM(const struct mie_type *, out),
struct mie_file_span *out_span);
MIE_API bool mie_parser_parse_function_type(
struct mie_parser *ctx, struct mie_type **out);
struct mie_parser *ctx, const char *context, struct mie_type **out,
struct mie_file_span *out_span);
MIE_API bool mie_parser_parse_operand(
struct mie_parser *ctx, struct mie_op_arg *out);
@@ -89,30 +120,33 @@ MIE_API bool mie_parser_parse_operand_list(
struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_op_arg, out));
MIE_API bool mie_parser_parse_parameter(
struct mie_parser *ctx, struct mie_op_arg *out);
struct mie_parser *ctx, bool include_type, struct mie_op_arg *out,
const char *context);
MIE_API bool mie_parser_parse_parameter_list(
struct mie_parser *ctx, MIE_VECTOR_REF_PARAM(struct mie_op_arg, out));
struct mie_parser *ctx, bool include_type,
MIE_VECTOR_REF_PARAM(struct mie_op_arg, out), const char *context);
MIE_API bool mie_parser_parse_unknown_keyword(struct mie_parser *ctx, b_string *out);
MIE_API bool mie_parser_parse_unknown_symbol(
struct mie_parser *ctx, enum mie_token_symbol sym);
MIE_API bool mie_parser_parse_register(
struct mie_parser *ctx, struct mie_name_map *names,
struct mie_register *out);
struct mie_parser *ctx, struct mie_parser_scope *scope,
const char *context, 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));
struct mie_parser *ctx, struct mie_parser_scope *scope,
const char *context, MIE_VECTOR_REF_PARAM(struct mie_register, out));
MIE_API bool mie_parser_parse_region(
struct mie_parser *ctx, struct mie_op *parent, struct mie_region *region);
struct mie_parser *ctx, struct mie_op *parent,
struct mie_region *region, struct mie_block *first_block);
MIE_API bool mie_parser_parse_region_list(
struct mie_parser *ctx, struct mie_op *parent);
MIE_API bool mie_parser_parse_anonymous_block(
struct mie_parser *ctx, struct mie_name_map *names,
struct mie_parser *ctx, struct mie_parser_scope *scope,
struct mie_block *block);
MIE_API bool mie_parser_parse_block(
struct mie_parser *ctx, struct mie_name_map *names,
struct mie_parser *ctx, struct mie_parser_scope *scope,
struct mie_block *block);
MIE_API bool mie_parser_parse_successor(
@@ -122,11 +156,34 @@ MIE_API bool mie_parser_parse_successor_list(
MIE_API bool mie_parser_parse_module(struct mie_parser *ctx, struct mie_module *mod);
MIE_API bool mie_parser_parse_op(
struct mie_parser *ctx, struct mie_name_map *names, struct mie_op *dest);
struct mie_parser *ctx, struct mie_parser_scope *scope,
struct mie_op *dest);
MIE_API bool mie_parser_parse_attribute(
struct mie_parser *ctx, const struct mie_attribute **dest);
MIE_API bool mie_parser_parse_attribute_map(
struct mie_parser *ctx, struct mie_attribute_map *out);
MIE_API struct mie_diag *mie_parser_report_error_simple(
struct mie_parser *parser, const char *dialect, unsigned int diag_class,
unsigned int msg, const struct mie_file_span *loc);
MIE_API void mie_parser_report_unexpected_token_v(
struct mie_parser *parser,
const struct mie_parser_item expected_tokens[], const char *context);
MIE_API void mie_parser_report_unexpected_token_s(
struct mie_parser *parser, const char *expected_token, const char *context);
static inline void mie_parser_report_unexpected_token(
struct mie_parser *parser, unsigned int expected_token, const char *context)
{
struct mie_parser_item t[]
= {MIE_PARSE_ITEM_TOKEN(expected_token), MIE_PARSE_ITEM_NONE};
mie_parser_report_unexpected_token_v(parser, t, context);
}
MIE_API struct mie_name *mie_parser_scope_put_name(
struct mie_parser_scope *scope, struct mie_name *entry,
const char *hint, enum mie_name_map_flags flags);
MIE_API struct mie_register *mie_parser_scope_find_value(
struct mie_parser_scope *scope, const char *name);
#endif

View File

@@ -39,6 +39,7 @@ enum mie_token_type {
MIE_TOK_TYPENAME = 0x4000u,
/* word or name, prefixed with a # hash */
MIE_TOK_ATTRIBNAME = 0x8000u,
__MIE_TOK_UBOUND = 0x9000u,
};
enum mie_token_value_type {
@@ -51,7 +52,7 @@ enum mie_token_value_type {
enum mie_token_symbol {
MIE_SYM_NONE = 0,
MIE_SYM_COLON,
MIE_SYM_COLON = __MIE_TOK_UBOUND,
MIE_SYM_EQUAL,
MIE_SYM_COMMA,
MIE_SYM_HYPHEN,
@@ -64,6 +65,7 @@ enum mie_token_symbol {
MIE_SYM_TILDE,
MIE_SYM_BANG,
MIE_SYM_ATSIGN,
MIE_SYM_QUESTION,
MIE_SYM_LEFT_BRACE,
MIE_SYM_RIGHT_BRACE,
MIE_SYM_LEFT_BRACKET,

View File

@@ -9,6 +9,7 @@
struct mie_op;
struct mie_ctx;
struct mie_type;
struct mie_region;
struct mie_register;
struct mie_op_successor;
@@ -41,6 +42,9 @@ MIE_API struct mie_block *mie_rewriter_split_block(
const char *name);
MIE_API struct mie_block *mie_rewriter_create_block(
struct mie_rewriter *rw, struct mie_block *insert_before, const char *name);
MIE_API struct mie_register *mie_rewriter_add_block_parameter(
struct mie_rewriter *rw, struct mie_block *block, const char *name,
const struct mie_type *type);
MIE_API enum mie_status mie_rewriter_move_block_to_start(
struct mie_rewriter *rw, struct mie_block *block,
@@ -91,6 +95,11 @@ MIE_API struct mie_op *mie_rewriter_replace_op(
MIE_API struct mie_op_successor *mie_rewriter_add_op_successor(
struct mie_rewriter *rw, struct mie_op *op, struct mie_block *dest,
struct mie_register **args, size_t nr_args);
MIE_API struct mie_op_arg *mie_rewriter_add_op_successor_arg(
struct mie_rewriter *rw, struct mie_op *op, struct mie_op_successor *s,
struct mie_register *reg);
MIE_API struct mie_op_arg *mie_rewriter_add_op_arg(
struct mie_rewriter *rw, struct mie_op *op, struct mie_register *reg);
MIE_API enum mie_status mie_rewriter_erase_op(
struct mie_rewriter *rw, struct mie_op *op);
MIE_API enum mie_status mie_rewriter_move_op_args_to_successor(

View File

@@ -23,4 +23,6 @@ MIE_API void mie_function_type_build_id(
size_t nr_in_types, const struct mie_type **out_types,
size_t nr_out_types);
MIE_API bool mie_type_is_function(const struct mie_type *ty);
#endif

View File

@@ -14,9 +14,12 @@ struct mie_storage_type {
MIE_API struct mie_storage_type *mie_storage_type_create(void);
MIE_API void mie_storage_type_add_part(
struct mie_storage_type *ty, const struct mie_type *part);
MIE_API size_t mie_storage_type_get_nr_parts(const struct mie_storage_type *ty);
MIE_API void mie_storage_type_build_id(
struct mie_id_builder *builder, const struct mie_type **parts,
size_t nr_parts);
MIE_API bool mie_type_is_storage(const struct mie_type *ty);
#endif

View File

@@ -47,4 +47,7 @@ MIE_API void mie_type_build_id(
MIE_API void mie_type_generate_id(
const struct mie_type *type, const mie_id *ns, mie_id *out);
MIE_API bool mie_type_is(
const struct mie_type *ty, const char *dialect_name, const char *type_name);
#endif

View File

@@ -40,7 +40,7 @@ struct mie_vector_ops {
/* use this macro to forward your reference to a vector (which you got via
* MIE_VECTOR_REF_PARAM in your function prototype), to another function whose
* prototype also uses MIE_VECTOR_REF_PARAM */
#define MIE_VECTOR_REF2(name) &(name.items), &(name.count), &(name.max)
#define MIE_VECTOR_REF2(name) name, name##_count, name##_max
/* use these functions if you're accessing a vector directly. */
#define mie_vector_push_back(vector, ptr, ops) \

View File

@@ -276,6 +276,38 @@ struct mie_register *mie_op_get_result_with_name(
return NULL;
}
void mie_op_get_args_span(const struct mie_op *op, struct mie_file_span *result)
{
memset(result, 0x0, sizeof *result);
size_t nr = MIE_VECTOR_COUNT(op->op_args);
if (!nr) {
return;
}
const struct mie_op_arg *first = &op->op_args.items[0];
const struct mie_op_arg *last = &op->op_args.items[nr - 1];
result->s_start = first->arg_span.s_start;
result->s_end = last->arg_span.s_end;
}
void mie_op_get_results_span(const struct mie_op *op, struct mie_file_span *result)
{
memset(result, 0x0, sizeof *result);
size_t nr = MIE_VECTOR_COUNT(op->op_result);
if (!nr) {
return;
}
const struct mie_register *first = &op->op_result.items[0];
const struct mie_register *last = &op->op_result.items[nr - 1];
result->s_start = first->reg_span.s_start;
result->s_end = last->reg_span.s_end;
}
struct mie_op *mie_op_get_first_child_op(const struct mie_op *op)
{
struct mie_region *first_region = mie_op_get_first_region(op);

View File

@@ -75,6 +75,27 @@ struct mie_block *mie_region_add_block(struct mie_region *region)
return block;
}
struct mie_block *mie_region_add_block_before(
struct mie_region *region, struct mie_block *before)
{
if (before->b_parent != region) {
return NULL;
}
struct mie_block *block = malloc(sizeof *block);
if (!block) {
return NULL;
}
memset(block, 0x0, sizeof *block);
block->b_parent = region;
b_queue_insert_before(&region->r_blocks, &block->b_entry, &before->b_entry);
return block;
}
struct mie_block *mie_region_add_block_after(
struct mie_region *region, struct mie_block *after)
{
@@ -102,7 +123,8 @@ struct mie_block *mie_region_find_block(
b_queue_entry *cur = b_queue_first(&region->r_blocks);
while (cur) {
struct mie_block *block = b_unbox(struct mie_block, cur, b_entry);
if (!strcmp(block->b_name.n_str, name)) {
const char *block_name = block->b_name.n_str;
if (block_name && !strcmp(block_name, name)) {
return block;
}

View File

@@ -15,7 +15,7 @@ enum register_find_result {
REG_FIND_ISOLATED,
};
bool mie_op_resolve_self(struct mie_op *op, struct mie_ctx *ctx)
bool mie_resolve_op_self(struct mie_op *op, struct mie_ctx *ctx)
{
if (op->op_flags & MIE_OP_F_OP_RESOLVED) {
return true;
@@ -101,6 +101,7 @@ static bool resolve_arg(
struct mie_block *block = op->op_container;
struct mie_op *search_start = op;
struct mie_register *reg = NULL;
bool cfg = (block->b_idom != NULL);
while (block) {
reg = mie_block_find_register(block, arg_name, search_start);
@@ -126,6 +127,18 @@ static bool resolve_arg(
enum register_find_result find_result
= find_register_wide(op, arg_name, &reg);
if (!cfg && REG_FIND_UNDOMINATED) {
/* this isn't a cfg (yet), so ignore dominance-relaced resolution issues */
free(arg->arg_unresolved.reg_name);
arg->arg_flags |= MIE_OP_F_ARG_RESOLVED;
memset(&arg->arg_value, 0x0, sizeof arg->arg_value);
arg->arg_value.u_reg = reg;
arg->arg_value.u_user = op;
b_queue_push_back(&reg->reg_use, &arg->arg_value.u_entry);
return true;
}
struct mie_diag *diag = mie_ctx_push_diag(
ctx, op->op_src, &arg->arg_span.s_start, "builtin",
MIE_BUILTIN_E_UNRESOLVED_VALUE);
@@ -228,7 +241,7 @@ static bool resolve_successor(
return true;
}
bool mie_op_resolve_args(struct mie_op *op, struct mie_ctx *ctx)
bool mie_resolve_op_args(struct mie_op *op, struct mie_ctx *ctx)
{
bool ok = true;
@@ -250,7 +263,7 @@ bool mie_op_resolve_args(struct mie_op *op, struct mie_ctx *ctx)
return ok;
}
bool mie_op_resolve_successors(struct mie_op *op, struct mie_ctx *ctx)
bool mie_resolve_op_successors(struct mie_op *op, struct mie_ctx *ctx)
{
bool ok = true;

View File

@@ -40,6 +40,7 @@ static struct lex_token_def symbols[] = {
LEX_TOKEN_DEF(MIE_SYM_HASH, "#"),
LEX_TOKEN_DEF(MIE_SYM_ATSIGN, "@"),
LEX_TOKEN_DEF(MIE_SYM_BANG, "!"),
LEX_TOKEN_DEF(MIE_SYM_QUESTION, "?"),
LEX_TOKEN_DEF(MIE_SYM_TILDE, "~"),
LEX_TOKEN_DEF(MIE_SYM_LEFT_BRACE, "{"),
LEX_TOKEN_DEF(MIE_SYM_RIGHT_BRACE, "}"),
@@ -216,6 +217,11 @@ struct mie_line_source *mie_lex_get_line_source(const struct mie_lex *lex)
return lex->lex_source;
}
const struct mie_file_cell *mie_lex_get_cursor(const struct mie_lex *lex)
{
return &lex->lex_source->s_cursor;
}
static bool char_can_begin_symbol(char c)
{
for (size_t i = 0; i < nr_symbols; i++) {
@@ -526,6 +532,7 @@ static enum mie_status read_ident(struct mie_lex *lex, enum mie_token_type type)
return push_string_token(lex, type, s);
} else {
push_symbol(lex, MIE_SYM_ASTERISK);
lex->lex_token_start.c_col++;
return push_string_token(lex, MIE_TOK_WORD, s);
}
break;

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,5 @@
#include <mie/ctx.h>
#include <mie/dialect/arith.h>
#include <mie/dialect/builtin.h>
#include <mie/dialect/cf.h>
#include <mie/dialect/dialect.h>
@@ -101,12 +102,144 @@ static struct mie_rewrite_result if_rewrite(
return MIE_REWRITE_RESULT(MIE_REWRITE_SUCCESS, MIE_SUCCESS);
}
static enum mie_match_result for_match(const struct mie_op *op)
{
if (!mie_op_is(op, "scf", "for")) {
return MIE_NO_MATCH_FOUND;
}
return MIE_MATCH_FOUND;
}
static struct mie_rewrite_result for_rewrite(
struct mie_op *op, struct mie_rewriter *rewriter)
{
printf("for: rewriting %p %s.%s\n", op, op->op_info->op_parent->d_name,
op->op_info->op_name);
struct mie_region *parent_region = op->op_container->b_parent;
struct mie_region *for_body = mie_op_get_first_region(op);
struct mie_block *for_entry = mie_region_get_first_block(for_body);
struct mie_block *pre_block = op->op_container;
struct mie_block *end_block
= mie_rewriter_split_block(rewriter, pre_block, op, "for.end");
struct mie_register *entry_iv = &for_entry->b_params.items[0];
struct mie_register *lb = op->op_args.items[0].arg_value.u_reg;
struct mie_register *ub = op->op_args.items[1].arg_value.u_reg;
struct mie_register *step = op->op_args.items[2].arg_value.u_reg;
MIE_VECTOR_DEFINE(struct mie_register *, initial_args);
mie_vector_push_back(initial_args, &lb, NULL);
for (size_t i = 3; i < MIE_VECTOR_COUNT(op->op_args); i++) {
struct mie_register *arg = op->op_args.items[i].arg_value.u_reg;
mie_vector_push_back(initial_args, &arg, NULL);
}
mie_rewriter_set_insertion_block(rewriter, pre_block);
mie_cf_br_put(
MIE_EMITTER(rewriter), for_entry, initial_args.items,
initial_args.count);
char iv_next_name[64];
snprintf(
iv_next_name, sizeof iv_next_name, "%s.next",
entry_iv->reg_name.n_str);
mie_rewriter_set_insertion_block(rewriter, for_entry);
struct mie_block *for_cond
= mie_rewriter_create_block(rewriter, end_block, "for.cond");
for (size_t i = 0; i < MIE_VECTOR_COUNT(for_entry->b_params); i++) {
const char *var_name = for_entry->b_params.items[i].reg_name.n_str;
const struct mie_type *var_type
= for_entry->b_params.items[i].reg_type;
mie_rewriter_add_block_parameter(
rewriter, for_cond, var_name, entry_iv->reg_type);
}
for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_result); i++) {
struct mie_register *old_reg = &op->op_result.items[i];
struct mie_register *new_reg = mie_block_add_param(end_block);
new_reg->reg_type = old_reg->reg_type;
char *name = b_strdup(old_reg->reg_name.n_str);
mie_name_destroy(&old_reg->reg_name);
mie_rewriter_rename_register(rewriter, new_reg, name);
mie_rewriter_replace_register(rewriter, old_reg, new_reg);
free(name);
}
struct mie_walker walker;
mie_walker_begin(&walker, op, MIE_WALKER_F_INCLUDE_OPS);
do {
const struct mie_walk_item *item = mie_walker_get(&walker);
if (!mie_op_is(item->i_op, "scf", "yield")) {
continue;
}
printf("for: found scf.yield %p\n", item->i_op);
struct mie_op *br = mie_rewriter_replace_op(
rewriter, item->i_op, "cf", "br");
struct mie_op_successor *s = mie_rewriter_add_op_successor(
rewriter, br, for_cond, NULL, 0);
struct mie_op_arg *iv_arg = mie_rewriter_add_op_successor_arg(
rewriter, br, s, entry_iv);
mie_rewriter_move_op_args_to_successor(rewriter, br, s);
} while (mie_walker_step(&walker) == MIE_SUCCESS);
mie_walker_end(&walker);
mie_rewriter_move_blocks_after(rewriter, for_body, parent_region, pre_block);
mie_rewriter_set_insertion_block(rewriter, for_cond);
struct mie_register *cond_iv = &for_cond->b_params.items[0];
struct mie_register *iv_next = mie_arith_addi_put(
MIE_EMITTER(rewriter), cond_iv, step, iv_next_name);
struct mie_register *iv_cmp = mie_arith_cmpi_put(
MIE_EMITTER(rewriter), MIE_ARITH_CMPI_UGE, iv_next, ub, "stop");
MIE_VECTOR_DEFINE(struct mie_register *, true_args);
MIE_VECTOR_DEFINE(struct mie_register *, false_args);
mie_vector_push_back(false_args, &iv_next, NULL);
for (size_t i = 1; i < MIE_VECTOR_COUNT(for_cond->b_params); i++) {
struct mie_register *param = &for_cond->b_params.items[i];
mie_vector_push_back(true_args, &param, NULL);
mie_vector_push_back(false_args, &param, NULL);
}
mie_cf_br_cond_put(
MIE_EMITTER(rewriter), iv_cmp, end_block, true_args.items,
true_args.count, for_entry, false_args.items, false_args.count);
mie_vector_destroy(true_args, NULL);
mie_vector_destroy(false_args, NULL);
mie_rewriter_erase_op(rewriter, op);
return MIE_REWRITE_RESULT(MIE_REWRITE_SUCCESS, MIE_SUCCESS);
}
MIE_REWRITE_PATTERN_BEGIN(if_pattern)
MIE_REWRITE_PATTERN_ROOT("scf", "if");
MIE_REWRITE_PATTERN_MATCH(if_match);
MIE_REWRITE_PATTERN_REWRITE(if_rewrite);
MIE_REWRITE_PATTERN_END()
MIE_REWRITE_PATTERN_BEGIN(for_pattern)
MIE_REWRITE_PATTERN_ROOT("scf", "for");
MIE_REWRITE_PATTERN_MATCH(for_match);
MIE_REWRITE_PATTERN_REWRITE(for_rewrite);
MIE_REWRITE_PATTERN_END()
static struct mie_pass_result transform(
struct mie_pass *pass, struct mie_op *op, struct mie_pass_args *args)
{
@@ -115,9 +248,11 @@ static struct mie_pass_result transform(
struct mie_convert_config *cfg = mie_convert_config_create(args->p_ctx);
mie_convert_config_add_illegal_op(cfg, "scf", "if");
mie_convert_config_add_illegal_op(cfg, "scf", "for");
struct mie_pattern_set patterns = {};
if_pattern_create(&patterns);
for_pattern_create(&patterns);
mie_convert_apply(op, cfg, &patterns);
mie_pattern_set_cleanup(&patterns);

View File

@@ -211,7 +211,10 @@ static void schedule_passes(
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_walk_item *item = mie_walker_get(&walker);
schedule_passes(nested, schedule, item->i_op, depth + 1);
if (item) {
schedule_passes(
nested, schedule, item->i_op, depth + 1);
}
}
} while (mie_walker_step(&walker) == MIE_SUCCESS);

View File

@@ -38,6 +38,10 @@ void mie_printer_print_op_arg(
b_stream_write_char(printer->p_stream, '%');
}
if (!arg_name) {
arg_name = "<NO-NAME>";
}
b_stream_write_string(printer->p_stream, arg_name, NULL);
if (!resolved
@@ -62,15 +66,20 @@ void mie_printer_print_op_successor(
b_stream_write_char(printer->p_stream, '^');
bool resolved = false;
const char *name = NULL;
if (successor->s_flags & MIE_OP_F_SUCCESSOR_RESOLVED) {
b_stream_write_string(
printer->p_stream, successor->s_block->b_name.n_str, NULL);
name = successor->s_block->b_name.n_str;
resolved = true;
} else {
b_stream_write_string(
printer->p_stream, successor->s_block_name, NULL);
name = successor->s_block_name;
}
if (!name) {
name = "<NO-NAME>";
}
b_stream_write_string(printer->p_stream, name, NULL);
if (!resolved
&& MIE_TEST_FLAGS(
printer->p_flags, MIE_PRINT_F_MARK_UNRESOLVED_ELEMENTS)) {

View File

@@ -12,6 +12,11 @@
void mie_printer_print_type(struct mie_printer *printer, const struct mie_type *type)
{
if (!type) {
b_stream_write_string(printer->p_stream, "<NULL-TYPE>", NULL);
return;
}
if (TYPE_HAS_PRINT_CALLBACK(type)) {
type->ty_def->ty_print(type, printer);
} else if (TYPE_IS_BUILTIN(type)) {

View File

@@ -41,6 +41,7 @@ struct mie_block *mie_rewriter_set_insertion_block(
struct mie_rewriter *rw, struct mie_block *block)
{
rw->r_insert_block = block;
rw->r_insert_point = NULL;
return block;
}
@@ -109,9 +110,30 @@ struct mie_block *mie_rewriter_split_block(
struct mie_block *mie_rewriter_create_block(
struct mie_rewriter *rw, struct mie_block *insert_before, const char *name)
{
struct mie_region *parent = insert_before->b_parent;
struct mie_block *block
= mie_region_add_block_before(parent, insert_before);
mie_rewriter_put_name(rw, &block->b_name, name);
return block;
}
struct mie_register *mie_rewriter_add_block_parameter(
struct mie_rewriter *rw, struct mie_block *block, const char *name,
const struct mie_type *type)
{
struct mie_register *reg = mie_block_add_param(block);
if (mie_rewriter_put_name(rw, &reg->reg_name, name) != MIE_SUCCESS) {
return NULL;
}
reg->reg_flags = MIE_REGISTER_F_VIRTUAL | MIE_REGISTER_F_BLOCK_PARAM;
reg->reg_block = block;
reg->reg_type = type;
return reg;
}
enum mie_status mie_rewriter_move_block_to_start(
struct mie_rewriter *rw, struct mie_block *block,
struct mie_region *from, struct mie_region *to)
@@ -410,6 +432,31 @@ struct mie_op *mie_rewriter_replace_op(
return op;
}
struct mie_op_arg *mie_rewriter_add_op_arg(
struct mie_rewriter *rw, struct mie_op *op, struct mie_register *value)
{
struct mie_op_arg *arg = mie_op_add_arg(op);
arg->arg_flags = MIE_OP_F_ARG_RESOLVED;
arg->arg_value.u_reg = value;
arg->arg_value.u_user = op;
b_queue_push_back(&value->reg_use, &arg->arg_value.u_entry);
return arg;
}
MIE_API struct mie_op_arg *mie_rewriter_add_op_successor_arg(
struct mie_rewriter *rw, struct mie_op *op, struct mie_op_successor *s,
struct mie_register *value)
{
struct mie_op_arg *arg = mie_vector_emplace_back(s->s_args, NULL);
arg->arg_flags = MIE_OP_F_ARG_RESOLVED;
arg->arg_value.u_reg = value;
arg->arg_value.u_user = op;
b_queue_push_back(&value->reg_use, &arg->arg_value.u_entry);
return arg;
}
struct mie_op_successor *mie_rewriter_add_op_successor(
struct mie_rewriter *rw, struct mie_op *op, struct mie_block *dest,
struct mie_register **args, size_t nr_args)

View File

@@ -4,6 +4,8 @@
#include <stdlib.h>
#include <string.h>
#define FUNCTION_TYPE_NAME "*function"
static void build_id(const struct mie_type *type, struct mie_id_builder *ctx)
{
const struct mie_function_type *function
@@ -51,7 +53,7 @@ static enum mie_status type_print(
}
static struct mie_type_definition function_type = {
.ty_name = "*function",
.ty_name = FUNCTION_TYPE_NAME,
.ty_data_size = sizeof(struct mie_type),
.ty_build_id = build_id,
.ty_print = type_print,
@@ -104,3 +106,15 @@ void mie_function_type_build_id(
}
mie_id_builder_add_marker(ctx, MIE_ID_BUILDER_FUNCTION_OUT_END);
}
bool mie_type_is_function(const struct mie_type *ty)
{
const struct mie_type_definition *ty_def = ty->ty_def;
if (!ty_def) {
return false;
}
return (!ty_def->ty_parent)
&& !strcmp(ty_def->ty_name, FUNCTION_TYPE_NAME);
}

View File

@@ -4,6 +4,8 @@
#include <stdlib.h>
#include <string.h>
#define STORAGE_TYPE_NAME "*storage"
static void build_id(const struct mie_type *type, struct mie_id_builder *ctx)
{
const struct mie_storage_type *storage
@@ -33,7 +35,7 @@ static enum mie_status type_print(
}
static struct mie_type_definition storage_type = {
.ty_name = "*storage",
.ty_name = STORAGE_TYPE_NAME,
.ty_data_size = sizeof(struct mie_type),
.ty_build_id = build_id,
.ty_print = type_print,
@@ -59,6 +61,11 @@ void mie_storage_type_add_part(
mie_vector_push_back(ty->st_parts, &part, NULL);
}
size_t mie_storage_type_get_nr_parts(const struct mie_storage_type *ty)
{
return MIE_VECTOR_COUNT(ty->st_parts);
}
void mie_storage_type_build_id(
struct mie_id_builder *ctx, const struct mie_type **parts, size_t nr_parts)
{
@@ -68,3 +75,14 @@ void mie_storage_type_build_id(
}
mie_id_builder_add_marker(ctx, MIE_ID_BUILDER_STORAGE_END);
}
bool mie_type_is_storage(const struct mie_type *ty)
{
const struct mie_type_definition *ty_def = ty->ty_def;
if (!ty_def) {
return false;
}
return (!ty_def->ty_parent) && !strcmp(ty_def->ty_name, STORAGE_TYPE_NAME);
}

View File

@@ -1,3 +1,4 @@
#include <mie/dialect/dialect.h>
#include <mie/type/function.h>
#include <mie/type/storage.h>
#include <mie/type/type-definition.h>
@@ -44,3 +45,25 @@ void mie_type_generate_id(const struct mie_type *type, const mie_id *ns, mie_id
mie_type_build_id(type, &ctx);
mie_id_builder_end(&ctx, out);
}
bool mie_type_is(
const struct mie_type *ty, const char *dialect_name, const char *type_name)
{
if (!ty->ty_def) {
return false;
}
if (strcmp(ty->ty_def->ty_name, type_name) != 0) {
return false;
}
if (!ty->ty_def->ty_parent) {
return false;
}
if (strcmp(ty->ty_def->ty_parent->d_name, dialect_name) != 0) {
return false;
}
return true;
}

View File

@@ -1,3 +1,5 @@
#include "../diag/diag.h"
#include "../resolve.h"
#include "cmd.h"
#include <assert.h>
@@ -13,6 +15,7 @@
#include <mie/dialect/dialect.h>
#include <mie/dialect/func.h>
#include <mie/dialect/index.h>
#include <mie/dialect/memref.h>
#include <mie/dialect/meta.h>
#include <mie/dialect/ptr.h>
#include <mie/dialect/scf.h>
@@ -23,6 +26,7 @@
#include <mie/ir/op.h>
#include <mie/ir/region.h>
#include <mie/ir/register.h>
#include <mie/ir/resolve.h>
#include <mie/ir/walk.h>
#include <mie/name.h>
#include <mie/parse/lex.h>
@@ -43,9 +47,22 @@
enum {
ARG_FILEPATH,
OPT_GENERIC,
OPT_NO_ABBREV,
OPT_PASS_OFFSET = 200,
};
static void report_diag(struct mie_ctx *ctx)
{
struct mie_diag *diag = mie_ctx_pop_diag(ctx);
while (diag) {
mie_diag_write_pretty(diag, b_stdtty_err);
/* TODO cleanup */
diag = mie_ctx_pop_diag(ctx);
}
}
static int optimise_file(
const b_command *cmd, const char *path, const b_arglist *args)
{
@@ -59,25 +76,11 @@ static int optimise_file(
printf("File OK\n");
b_arglist_iterator it;
b_arglist_foreach(&it, args)
{
if (it.opt_id < OPT_PASS_OFFSET) {
continue;
}
const b_command_option *opt = b_command_get_option(cmd, it.opt_id);
if (!opt) {
continue;
}
printf("running pass %s\n", b_command_option_get_long_name(opt));
}
struct mie_ctx *ctx = mie_ctx_create();
mie_builtin_dialect_create(ctx);
mie_meta_dialect_create(ctx);
mie_select_dialect_create(ctx);
mie_memref_dialect_create(ctx);
mie_ptr_dialect_create(ctx);
mie_arith_dialect_create(ctx);
mie_func_dialect_create(ctx);
@@ -98,27 +101,11 @@ static int optimise_file(
struct mie_op *root = mie_op_create();
if (!mie_parser_parse_op(parse, NULL, root)) {
report_diag(ctx);
printf("parse failed\n");
return -1;
}
enum mie_walker_flags flags = MIE_WALKER_F_INCLUDE_OPS
| MIE_WALKER_F_PREORDER | MIE_WALKER_F_FORWARD
| MIE_WALKER_F_RECURSIVE;
struct mie_walker walker;
mie_walker_begin(&walker, root, flags);
do {
const struct mie_walk_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,
@@ -128,6 +115,11 @@ static int optimise_file(
return -1;
}
if (!resolve_op(root, ctx)) {
report_diag(ctx);
return -1;
}
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");
@@ -137,14 +129,47 @@ static int optimise_file(
mie_pass_manager_add_pass(func_pm, prefix_func_with_underscore);
b_arglist_iterator it;
b_arglist_foreach(&it, args)
{
if (it.opt_id < OPT_PASS_OFFSET) {
continue;
}
const b_command_option *opt = b_command_get_option(cmd, it.opt_id);
if (!opt) {
continue;
}
const char *pass_name = b_command_option_get_long_name(opt);
struct mie_pass *pass = NULL;
enum mie_status status
= mie_ctx_get_pass(ctx, pass_name, NULL, &pass);
if (status != MIE_SUCCESS) {
printf("cannot load pass %s\n", pass_name);
return -1;
}
mie_pass_manager_add_pass(func_pm, pass);
}
#if 0
mie_pass_manager_parse(
pm, "builtin.module(func.func(prefix-func-with-underscore))");
#endif
mie_pass_manager_run(pm, root);
enum mie_print_flags flags = 0;
if (b_arglist_get_count(args, OPT_GENERIC, B_COMMAND_INVALID_ID) > 0) {
flags |= MIE_PRINT_F_GENERIC;
}
if (b_arglist_get_count(args, OPT_NO_ABBREV, B_COMMAND_INVALID_ID) == 0) {
flags |= MIE_PRINT_F_ABBREVIATED;
}
struct mie_printer printer;
mie_printer_init(&printer, ctx, b_stdout, MIE_PRINT_F_ABBREVIATED);
mie_printer_init(&printer, ctx, b_stdout, flags);
mie_printer_print_op(&printer, root);
printf("\n");
@@ -227,6 +252,21 @@ B_COMMAND(CMD_OPTIMISE, CMD_ROOT)
B_ARG_NR_VALUES(1);
}
B_COMMAND_OPTION(OPT_GENERIC)
{
B_OPTION_LONG_NAME("generic");
B_OPTION_SHORT_NAME('g');
B_OPTION_DESC("print operations in generic format.");
}
B_COMMAND_OPTION(OPT_NO_ABBREV)
{
B_OPTION_LONG_NAME("no-abbrev");
B_OPTION_SHORT_NAME('n');
B_OPTION_DESC(
"don't use abbreviations for builtin types and ops.");
}
struct mie_ctx *ctx = mie_ctx_create();
mie_builtin_passes_register(ctx);
@@ -237,12 +277,13 @@ B_COMMAND(CMD_OPTIMISE, CMD_ROOT)
struct mie_pass_definition *pass
= b_unbox(struct mie_pass_definition, id, p_id);
B_COMMAND_OPTION_GEN(OPT_PASS_OFFSET + 1)
B_COMMAND_OPTION_GEN(OPT_PASS_OFFSET + i)
{
B_OPTION_LONG_NAME(pass->p_name);
B_OPTION_DESC(pass->p_description);
}
node = b_btree_next(node);
i++;
}
}

View File

@@ -1,4 +1,5 @@
#include "../diag/diag.h"
#include "../resolve.h"
#include "cmd.h"
#include <assert.h>
@@ -14,6 +15,7 @@
#include <mie/dialect/dialect.h>
#include <mie/dialect/func.h>
#include <mie/dialect/index.h>
#include <mie/dialect/memref.h>
#include <mie/dialect/meta.h>
#include <mie/dialect/ptr.h>
#include <mie/dialect/scf.h>
@@ -45,6 +47,16 @@ enum {
ARG_FILEPATH,
};
static void report_diag(struct mie_ctx *ctx)
{
struct mie_diag *diag = mie_ctx_pop_diag(ctx);
while (diag) {
mie_diag_write_pretty(diag, b_stdtty_err);
/* TODO cleanup */
diag = mie_ctx_pop_diag(ctx);
}
}
static int validate_file(const char *path, const b_arglist *args)
{
b_file *file = NULL;
@@ -61,6 +73,7 @@ static int validate_file(const char *path, const b_arglist *args)
mie_builtin_dialect_create(ctx);
mie_meta_dialect_create(ctx);
mie_select_dialect_create(ctx);
mie_memref_dialect_create(ctx);
mie_ptr_dialect_create(ctx);
mie_arith_dialect_create(ctx);
mie_func_dialect_create(ctx);
@@ -81,50 +94,16 @@ static int validate_file(const char *path, const b_arglist *args)
struct mie_op *root = mie_op_create();
if (!mie_parser_parse_op(parse, NULL, root)) {
struct mie_diag *diag = mie_ctx_pop_diag(ctx);
while (diag) {
mie_diag_write_pretty(diag, b_stdtty_err);
/* TODO cleanup */
diag = mie_ctx_pop_diag(ctx);
}
report_diag(ctx);
printf("parse failed\n");
return -1;
}
enum mie_walker_flags walk_flags
= MIE_WALKER_F_INCLUDE_OPS | MIE_WALKER_F_PREORDER
| MIE_WALKER_F_FORWARD | MIE_WALKER_F_RECURSIVE;
struct mie_walker walker;
mie_walker_begin(&walker, root, walk_flags);
do {
const struct mie_walk_item *item = mie_walker_get(&walker);
for (size_t i = 0; i < item->i_depth; i++) {
fputs(" ", stdout);
if (!resolve_op(root, ctx)) {
report_diag(ctx);
return -1;
}
switch (item->i_type) {
case MIE_WALK_ITEM_REGION:
printf("looking at region %p...\n", item->i_region);
continue;
case MIE_WALK_ITEM_BLOCK:
printf("looking at block %p %s...\n", item->i_block,
item->i_block->b_name.n_str);
continue;
case MIE_WALK_ITEM_OP:
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");
break;
default:
break;
}
} while (mie_walker_step(&walker) == MIE_SUCCESS);
mie_walker_end(&walker);
struct mie_pass *prefix_func_with_underscore = NULL;
enum mie_status status = mie_ctx_get_pass(
ctx, "prefix-func-with-underscore", NULL,
@@ -150,44 +129,52 @@ static int validate_file(const char *path, const b_arglist *args)
mie_pass_manager_run(pm, root);
struct mie_printer printer;
mie_printer_init(&printer, ctx, b_stdout, MIE_PRINT_F_ABBREVIATED);
mie_printer_init(
&printer, ctx, b_stdout,
MIE_PRINT_F_ABBREVIATED | MIE_PRINT_F_MARK_UNRESOLVED_ELEMENTS);
mie_printer_print_op(&printer, root);
printf("\n");
struct mie_op *func = mie_op_get_first_child_op(root);
walk_flags = MIE_WALKER_F_INCLUDE_OPS | MIE_WALKER_F_PREORDER
#if 0
struct mie_walker walker;
enum mie_walker_flags walk_flags = MIE_WALKER_F_INCLUDE_BLOCKS
| MIE_WALKER_F_PREORDER
| MIE_WALKER_F_FORWARD;
mie_walker_begin(&walker, func, walk_flags);
mie_walker_begin(&walker, root, walk_flags);
do {
const struct mie_walk_item *item = mie_walker_get(&walker);
for (size_t i = 0; i < item->i_depth; i++) {
fputs(" ", stdout);
}
switch (item->i_type) {
case MIE_WALK_ITEM_REGION:
printf("looking at region %p...\n", item->i_region);
break;
case MIE_WALK_ITEM_BLOCK:
printf("looking at block %p %s...\n", item->i_block,
item->i_block->b_name.n_str);
break;
case MIE_WALK_ITEM_OP:
if (item->i_op->op_flags & MIE_OP_F_OP_RESOLVED) {
printf("looking at %p %s.%s...\n", item->i_op,
item->i_op->op_dialect->d_name,
item->i_op->op_info->op_name);
} else {
printf("looking at %p %s...\n", item->i_op,
item->i_op->op_name);
}
break;
default:
break;
printf(" id=%u\n", item->i_block->b_id);
const char *idom = item->i_block->b_idom
? item->i_block->b_idom->b_name.n_str
: "Unk";
printf(" idom=%s\n", idom);
#if 0
const char *sdom = item->i_block->b_sdom
? item->i_block->b_sdom->b_name.n_str
: "Unk";
const char *dfs_parent
= item->i_block->b_dfs_parent
? item->i_block->b_dfs_parent->b_name.n_str
: "Unk";
printf(" sdom=%s\n", sdom);
printf(" dfs_parent=%s\n", dfs_parent);
#endif
printf(" preds=");
struct mie_block_predecessor *pred
= mie_block_get_first_predecessor(item->i_block);
while (pred) {
printf(" %s", pred->p_block->b_name.n_str);
pred = mie_block_get_next_predecessor(item->i_block, pred);
}
printf("\n");
} while (mie_walker_step(&walker) == MIE_SUCCESS);
mie_walker_end(&walker);
#endif
#if 0

View File

@@ -19,8 +19,9 @@ struct snippet_print_ctx {
struct mie_line_source *ctx_line_source;
size_t ctx_row, ctx_col;
size_t ctx_indent_offset;
bool ctx_has_underline;
bool ctx_has_underline, ctx_in_content;
b_stringstream *ctx_underline;
const b_string *ctx_linebuf;
const b_iterator *ctx_linebuf_ptr;
@@ -224,18 +225,22 @@ static void update_amendment(struct snippet_print_ctx *ctx)
{
if (ctx->ctx_amendment
&& amendment_contains_cell(
ctx->ctx_amendment, ctx->ctx_row, ctx->ctx_col)) {
ctx->ctx_amendment, ctx->ctx_row,
ctx->ctx_col + ctx->ctx_indent_offset)) {
return;
}
ctx->ctx_amendment
= find_amendment(ctx->ctx_snippet, ctx->ctx_row, ctx->ctx_col);
ctx->ctx_amendment = find_amendment(
ctx->ctx_snippet, ctx->ctx_row,
ctx->ctx_col + ctx->ctx_indent_offset);
}
static void update_highlighting(struct snippet_print_ctx *ctx)
{
if (ctx->ctx_hl
&& highlight_contains_cell(ctx->ctx_hl, ctx->ctx_row, ctx->ctx_col)) {
&& highlight_contains_cell(
ctx->ctx_hl, ctx->ctx_row,
ctx->ctx_col + ctx->ctx_indent_offset)) {
return;
}
@@ -243,8 +248,9 @@ static void update_highlighting(struct snippet_print_ctx *ctx)
STREAM_COLOUR_RESET(ctx->ctx_stream);
const struct mie_diag_highlight *new_hl
= find_highlight(ctx->ctx_snippet, ctx->ctx_row, ctx->ctx_col);
const struct mie_diag_highlight *new_hl = find_highlight(
ctx->ctx_snippet, ctx->ctx_row,
ctx->ctx_col + ctx->ctx_indent_offset);
if (!new_hl) {
return;
@@ -299,7 +305,8 @@ static int get_char_amendment(struct snippet_print_ctx *ctx)
switch (a->a_type) {
case MIE_DIAG_AMENDMENT_ADD:
i = ctx->ctx_col - a->a_add.a_loc.c_row;
i = ctx->ctx_col - ctx->ctx_indent_offset - a->a_add.a_loc.c_row
- 1;
return a->a_add.a_str[i];
case MIE_DIAG_AMENDMENT_REMOVE:
b_iterator_move_next(ctx->ctx_linebuf_ptr);
@@ -334,14 +341,25 @@ static int get_char(struct snippet_print_ctx *ctx)
return get_char_amendment(ctx);
}
b_wchar c = b_iterator_get_cvalue(ctx->ctx_linebuf_ptr).v_int;
b_wchar c = B_WCHAR_INVALID;
while (1) {
c = b_iterator_get_cvalue(ctx->ctx_linebuf_ptr).v_int;
if (c == B_WCHAR_INVALID) {
return GET_CHAR_STOP;
};
}
b_iterator_move_next(ctx->ctx_linebuf_ptr);
if (isspace(c) && !ctx->ctx_in_content) {
ctx->ctx_indent_offset++;
continue;
}
ctx->ctx_in_content = true;
return c;
}
}
static void update_underline(struct snippet_print_ctx *ctx)
{
@@ -414,6 +432,10 @@ static void print_snippet(
update_highlighting(&printer);
if (c == '[') {
b_tty_putc(stream, 0, c);
}
b_tty_putc(stream, 0, c);
update_underline(&printer);

130
tool/resolve.c Normal file
View File

@@ -0,0 +1,130 @@
#include <mie/ctx.h>
#include <mie/ir/op.h>
#include <mie/ir/region.h>
#include <mie/ir/resolve.h>
#include <mie/ir/walk.h>
#include <stdbool.h>
#if 0
static bool resolve_op(struct mie_op *op, struct mie_ctx *ctx)
{
if (mie_op_has_trait(op, "func", "function-like")) {
struct mie_region *region = mie_op_get_first_region(op);
mie_region_refresh_dominance(region);
}
if (!mie_op_resolve_references(op, ctx)) {
return false;
}
return true;
}
#endif
static bool resolve_self_and_successors(struct mie_op *op, struct mie_ctx *ctx)
{
char op_name[128];
enum mie_walker_flags walk_flags
= MIE_WALKER_F_INCLUDE_OPS | MIE_WALKER_F_PREORDER
| MIE_WALKER_F_FORWARD | MIE_WALKER_F_RECURSIVE;
struct mie_walker walker;
mie_walker_begin(&walker, op, walk_flags);
bool result = true;
do {
const struct mie_walk_item *item = mie_walker_get(&walker);
struct mie_op *op = item->i_op;
mie_op_get_name(op, op_name, sizeof op_name);
// printf("resolving op: %p %s... ", item->i_op, op_name);
bool ok = mie_resolve_op_self(op, ctx);
// printf("%s\n", ok ? "OK" : "FAIL");
ok = mie_resolve_op_successors(item->i_op, ctx);
if (!ok) {
result = false;
}
} while (mie_walker_step(&walker) == MIE_SUCCESS);
mie_walker_end(&walker);
return result;
}
static bool resolve_args(struct mie_op *op, struct mie_ctx *ctx)
{
char op_name[128];
enum mie_walker_flags walk_flags
= MIE_WALKER_F_INCLUDE_OPS | MIE_WALKER_F_PREORDER
| MIE_WALKER_F_FORWARD | MIE_WALKER_F_RECURSIVE;
struct mie_walker walker;
mie_walker_begin(&walker, op, walk_flags);
bool result = true;
do {
const struct mie_walk_item *item = mie_walker_get(&walker);
struct mie_op *op = item->i_op;
mie_op_get_name(op, op_name, sizeof op_name);
// printf("resolving args: %p %s... ", item->i_op, op_name);
bool ok = mie_resolve_op_args(op, ctx);
// printf("%s\n", ok ? "OK" : "FAIL");
if (!ok) {
result = false;
}
} while (mie_walker_step(&walker) == MIE_SUCCESS);
mie_walker_end(&walker);
return result;
}
static bool refresh_function_dominance_trees(struct mie_op *op, struct mie_ctx *ctx)
{
char op_name[128];
enum mie_walker_flags walk_flags
= MIE_WALKER_F_INCLUDE_OPS | MIE_WALKER_F_POSTORDER
| MIE_WALKER_F_FORWARD | MIE_WALKER_F_RECURSIVE;
struct mie_walker walker;
mie_walker_begin(&walker, op, walk_flags);
bool result = true;
do {
const struct mie_walk_item *item = mie_walker_get(&walker);
struct mie_op *op = item->i_op;
if (!mie_op_has_trait(op, "func", "function-like")) {
continue;
}
mie_op_get_name(op, op_name, sizeof op_name);
// printf("calculating dom-tree: %p %s...\n", item->i_op, op_name);
struct mie_region *region = mie_op_get_first_region(op);
if (!region) {
/* TODO diagnostic message */
return false;
}
mie_region_refresh_dominance(region);
} while (mie_walker_step(&walker) == MIE_SUCCESS);
mie_walker_end(&walker);
return result;
}
bool resolve_op(struct mie_op *op, struct mie_ctx *ctx)
{
/* first, resolve the op-definitions and block references */
if (!resolve_self_and_successors(op, ctx)) {
return false;
}
/* next, calculation the block dominator tree for all function-like
* ops. */
refresh_function_dominance_trees(op, ctx);
/* next, resolve all op arguments */
if (!resolve_args(op, ctx)) {
return false;
}
return true;
}

14
tool/resolve.h Normal file
View File

@@ -0,0 +1,14 @@
#ifndef TOOL_RESOLVE_H_
#define TOOL_RESOLVE_H_
#include <stdbool.h>
struct mie_op;
struct mie_ctx;
extern bool resolve_op_self(struct mie_op *op, struct mie_ctx *ctx);
extern bool resolve_op_successors(struct mie_op *op, struct mie_ctx *ctx);
extern bool resolve_op(struct mie_op *op, struct mie_ctx *ctx);
#endif