mie: implement a printer system for converting IR to textual form
This commit is contained in:
61
mie/print/block.c
Normal file
61
mie/print/block.c
Normal 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
12
mie/print/module.c
Normal 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
220
mie/print/op.c
Normal 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
18
mie/print/printer.c
Normal 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
16
mie/print/region.c
Normal 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
17
mie/print/register.c
Normal 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
17
mie/print/type.c
Normal 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
11
mie/print/value.c
Normal 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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user