mie: implement a printer system for converting IR to textual form

This commit is contained in:
2026-01-12 10:33:08 +00:00
parent 826380ea34
commit 49df8616a8
24 changed files with 511 additions and 108 deletions

61
mie/print/block.c Normal file
View File

@@ -0,0 +1,61 @@
#include <mie/ir/block.h>
#include <mie/ir/op.h>
#include <mie/ir/register.h>
#include <mie/print/printer.h>
static void print_block_header_params(
struct mie_printer *printer, const struct mie_block *block)
{
if (!MIE_VECTOR_COUNT(block->b_params)) {
return;
}
b_stream_write_char(printer->p_stream, '(');
for (size_t i = 0; i < MIE_VECTOR_COUNT(block->b_params); i++) {
if (i > 0) {
b_stream_write_string(printer->p_stream, ", ", NULL);
}
mie_printer_print_register(printer, block->b_params.items[i]);
b_stream_write_string(printer->p_stream, ": ", NULL);
mie_printer_print_type(printer, block->b_params.items[i]->reg_type);
}
b_stream_write_char(printer->p_stream, ')');
}
static void print_block_header(
struct mie_printer *printer, const struct mie_block *block)
{
if (!block->b_name.n_str && !MIE_VECTOR_COUNT(block->b_params)) {
return;
}
b_stream_write_char(printer->p_stream, '^');
if (block->b_name.n_str) {
b_stream_write_string(printer->p_stream, block->b_name.n_str, NULL);
}
print_block_header_params(printer, block);
b_stream_write_string(printer->p_stream, ":\n", NULL);
}
void mie_printer_print_block(
struct mie_printer *printer, const struct mie_block *block)
{
print_block_header(printer, block);
b_stream_push_indent(printer->p_stream, 4);
for (size_t i = 0; i < MIE_VECTOR_COUNT(block->b_ops); i++) {
const struct mie_op *op = &block->b_ops.items[i];
mie_printer_print_op(printer, op);
b_stream_write_char(printer->p_stream, '\n');
}
b_stream_pop_indent(printer->p_stream);
}

12
mie/print/module.c Normal file
View File

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

220
mie/print/op.c Normal file
View File

@@ -0,0 +1,220 @@
#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/print/printer.h>
static void print_op_arg(
struct mie_printer *printer, const struct mie_op_arg *arg, bool include_type)
{
enum mie_register_flags arg_flags = 0;
const char *arg_name = NULL;
const struct mie_type *arg_type = NULL;
if (MIE_TEST_FLAGS(arg->arg_flags, MIE_OP_F_ARG_RESOLVED)) {
arg_flags = arg->arg_value->reg_flags;
arg_name = arg->arg_value->reg_name.n_str;
arg_type = arg->arg_value->reg_type;
} else {
arg_flags = arg->arg_unresolved.reg_flags;
arg_name = arg->arg_unresolved.reg_name;
arg_type = arg->arg_unresolved.reg_type;
}
if (arg_flags & MIE_REGISTER_F_MACHINE) {
b_stream_write_char(printer->p_stream, '$');
} else {
b_stream_write_char(printer->p_stream, '%');
}
b_stream_write_string(printer->p_stream, arg_name, NULL);
if (!include_type) {
return;
}
b_stream_write_string(printer->p_stream, ": ", NULL);
mie_printer_print_type(printer, arg_type);
}
static void print_successor(
struct mie_printer *printer, const struct mie_op_successor *successor)
{
b_stream_write_char(printer->p_stream, '^');
if (successor->s_flags & MIE_OP_F_SUCCESSOR_RESOLVED) {
b_stream_write_string(
printer->p_stream, successor->s_block->b_name.n_str, NULL);
} else {
b_stream_write_string(
printer->p_stream, successor->s_block_name, NULL);
}
if (MIE_VECTOR_COUNT(successor->s_args) == 0) {
return;
}
b_stream_write_string(printer->p_stream, ":(", NULL);
for (size_t i = 0; i < MIE_VECTOR_COUNT(successor->s_args); i++) {
if (i > 0) {
b_stream_write_string(printer->p_stream, ", ", NULL);
}
print_op_arg(printer, &successor->s_args.items[i], true);
}
b_stream_write_char(printer->p_stream, ')');
}
static void print_successor_list(
struct mie_printer *printer, const struct mie_op *op)
{
if (!MIE_VECTOR_COUNT(op->op_successors)) {
return;
}
b_stream_write_string(printer->p_stream, " [ ", NULL);
for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_successors); i++) {
if (i > 0) {
b_stream_write_string(printer->p_stream, ", ", NULL);
}
print_successor(printer, &op->op_successors.items[i]);
}
b_stream_write_string(printer->p_stream, " ]", NULL);
}
static void print_region_list(struct mie_printer *printer, const struct mie_op *op)
{
if (!MIE_VECTOR_COUNT(op->op_regions)) {
return;
}
b_stream_write_string(printer->p_stream, " (", NULL);
for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_regions); i++) {
if (i > 0) {
b_stream_write_string(printer->p_stream, ", ", NULL);
}
mie_printer_print_region(printer, &op->op_regions.items[i]);
}
b_stream_write_string(printer->p_stream, ")", NULL);
}
static void print_attribute(
struct mie_printer *printer, const struct mie_op_attribute *attrib)
{
b_stream_write_fmt(printer->p_stream, NULL, "%s = ", attrib->attrib_name);
mie_printer_print_value(printer, attrib->attrib_value);
}
static void print_attribute_list(
struct mie_printer *printer, const struct mie_op *op)
{
if (!MIE_VECTOR_COUNT(op->op_attrib)) {
return;
}
b_stream_write_string(printer->p_stream, " { ", NULL);
for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_attrib); i++) {
if (i > 0) {
b_stream_write_string(printer->p_stream, ", ", NULL);
}
print_attribute(printer, &op->op_attrib.items[i]);
}
b_stream_write_string(printer->p_stream, " }", NULL);
}
static void print_type_signature(
struct mie_printer *printer, const struct mie_op *op)
{
const struct mie_type *type = NULL;
b_stream_write_string(printer->p_stream, " : (", NULL);
for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_args); i++) {
if (i > 0) {
b_stream_write_string(printer->p_stream, ", ", NULL);
}
const struct mie_op_arg *arg = &op->op_args.items[i];
if (arg->arg_flags & MIE_OP_F_ARG_RESOLVED) {
type = arg->arg_value->reg_type;
} else {
type = arg->arg_unresolved.reg_type;
}
mie_printer_print_type(printer, type);
}
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++) {
if (i > 0) {
b_stream_write_string(printer->p_stream, ", ", NULL);
}
type = op->op_result.items[i]->reg_type;
mie_printer_print_type(printer, type);
}
if (MIE_VECTOR_COUNT(op->op_result) != 1) {
b_stream_write_char(printer->p_stream, ')');
}
}
void mie_printer_print_op(struct mie_printer *printer, const struct mie_op *op)
{
for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_result); i++) {
if (i > 0) {
b_stream_write_string(printer->p_stream, ", ", NULL);
}
mie_printer_print_register(printer, op->op_result.items[i]);
}
if (MIE_VECTOR_COUNT(op->op_result) > 0) {
b_stream_write_string(printer->p_stream, " = ", NULL);
}
if (printer->p_flags & MIE_PRINT_F_GENERIC) {
b_stream_write_char(printer->p_stream, '~');
}
if (op->op_flags & MIE_OP_F_OP_RESOLVED) {
b_stream_write_fmt(
printer->p_stream, NULL, "%s.%s",
op->op_dialect->d_name, op->op_info->op_name);
} else {
b_stream_write_string(printer->p_stream, op->op_name, NULL);
}
b_stream_write_char(printer->p_stream, '(');
for (size_t i = 0; i < MIE_VECTOR_COUNT(op->op_args); i++) {
if (i > 0) {
b_stream_write_string(printer->p_stream, ", ", NULL);
}
print_op_arg(printer, &op->op_args.items[i], false);
}
b_stream_write_char(printer->p_stream, ')');
print_successor_list(printer, op);
print_region_list(printer, op);
print_attribute_list(printer, op);
print_type_signature(printer, op);
}

18
mie/print/printer.c Normal file
View File

@@ -0,0 +1,18 @@
#include <mie/print/printer.h>
enum mie_status mie_printer_init(
struct mie_printer *printer, struct mie_ctx *ctx, b_stream *out,
enum mie_print_flags flags)
{
memset(printer, 0x0, sizeof *printer);
if (!(flags & MIE_PRINT_F_GENERIC) && !ctx) {
return MIE_ERR_INVALID_ARGUMENT;
}
printer->p_mie = ctx;
printer->p_stream = out;
printer->p_flags = flags;
return MIE_SUCCESS;
}

16
mie/print/region.c Normal file
View File

@@ -0,0 +1,16 @@
#include <mie/ir/block.h>
#include <mie/ir/region.h>
#include <mie/print/printer.h>
void mie_printer_print_region(
struct mie_printer *printer, const struct mie_region *region)
{
b_stream_write_string(printer->p_stream, "{\n", NULL);
for (size_t i = 0; i < MIE_VECTOR_COUNT(region->r_blocks); i++) {
const struct mie_block *block = region->r_blocks.items[i];
mie_printer_print_block(printer, block);
}
b_stream_write_string(printer->p_stream, "}", NULL);
}

17
mie/print/register.c Normal file
View File

@@ -0,0 +1,17 @@
#include <mie/ir/register.h>
#include <mie/print/printer.h>
void mie_printer_print_register(
struct mie_printer *printer, const struct mie_register *reg)
{
if (reg->reg_flags & MIE_REGISTER_F_VIRTUAL) {
b_stream_write_fmt(
printer->p_stream, NULL, "%%%s", reg->reg_name.n_str);
} else if (reg->reg_flags & MIE_REGISTER_F_MACHINE) {
// TODO this shouldnt use reg_name
b_stream_write_fmt(
printer->p_stream, NULL, "$%s", reg->reg_name.n_str);
} else {
b_stream_write_string(printer->p_stream, "?REG", NULL);
}
}

17
mie/print/type.c Normal file
View File

@@ -0,0 +1,17 @@
#include <mie/print/printer.h>
#include <mie/type/type-definition.h>
#include <mie/type/type.h>
void mie_printer_print_type(struct mie_printer *printer, const struct mie_type *type)
{
if (type->ty_def && type->ty_def->ty_print) {
type->ty_def->ty_print(type, printer);
} else if (type->ty_name) {
b_stream_write_string(printer->p_stream, type->ty_name, NULL);
} else if (type->ty_def && type->ty_def->ty_name) {
b_stream_write_string(
printer->p_stream, type->ty_def->ty_name, NULL);
} else {
b_stream_write_string(printer->p_stream, "<UNNAMED-TYPE>", NULL);
}
}

11
mie/print/value.c Normal file
View File

@@ -0,0 +1,11 @@
#include <mie/type/type-definition.h>
#include <mie/type/type.h>
#include <mie/value.h>
void mie_printer_print_value(
struct mie_printer *printer, const struct mie_value *value)
{
if (value->v_type && value->v_type->ty_def->ty_value_print) {
value->v_type->ty_def->ty_value_print(value, printer);
}
}