Compare commits
8 Commits
feature/ne
...
58bd336eb8
| Author | SHA1 | Date | |
|---|---|---|---|
| 58bd336eb8 | |||
| 008966e046 | |||
| 83343a5eea | |||
| 76166167c9 | |||
| f6f6131f52 | |||
| 33f9ccd871 | |||
| 0c4ebe7f39 | |||
| 72de4ce845 |
21
mie/ctx.c
21
mie/ctx.c
@@ -70,6 +70,27 @@ struct mie_ctx *mie_ctx_create(void)
|
||||
return out;
|
||||
}
|
||||
|
||||
struct mie_op *mie_ctx_create_op(
|
||||
const struct mie_ctx *ctx, const char *dialect, const char *op)
|
||||
{
|
||||
const struct mie_op_definition *def
|
||||
= mie_ctx_get_op_definition(ctx, dialect, op);
|
||||
if (!def) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct mie_op *out = mie_op_create();
|
||||
if (!out) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
out->op_flags |= MIE_OP_F_OP_RESOLVED;
|
||||
out->op_info = def;
|
||||
out->op_dialect = def->op_parent;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
bool mie_ctx_resolve_op(const struct mie_ctx *ctx, struct mie_op *op)
|
||||
{
|
||||
if (op->op_flags & MIE_OP_F_OP_RESOLVED) {
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
#include <mie/ctx.h>
|
||||
#include <mie/dialect/builtin.h>
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/ir/builder.h>
|
||||
#include <mie/ir/op-definition.h>
|
||||
#include <mie/ir/op.h>
|
||||
#include <mie/macros.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)
|
||||
{
|
||||
@@ -28,6 +32,24 @@ static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
struct mie_register *mie_arith_put_addi(
|
||||
struct mie_builder *builder, 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_builder_put_op(builder, "arith", "addi", args, nr_args);
|
||||
const struct mie_type *ty = left->reg_type;
|
||||
|
||||
struct mie_register *result = mie_op_add_result(op, ty);
|
||||
result->reg_block = mie_builder_get_current_block(builder);
|
||||
mie_builder_put_name(builder, &result->reg_name, name);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
MIE_OP_DEFINITION_BEGIN(mie_arith_addi, "addi")
|
||||
MIE_OP_DEFINITION_PRINT(print);
|
||||
MIE_OP_DEFINITION_PARSE(parse);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include <mie/attribute/attribute.h>
|
||||
#include <mie/dialect/builtin.h>
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/ir/builder.h>
|
||||
#include <mie/ir/op-definition.h>
|
||||
#include <mie/ir/op.h>
|
||||
#include <mie/macros.h>
|
||||
@@ -40,6 +41,44 @@ static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
struct mie_register *mie_arith_put_constant_i(
|
||||
struct mie_builder *builder, long long value, const char *name)
|
||||
{
|
||||
struct mie_op *op
|
||||
= mie_builder_put_op(builder, "arith", "constant", NULL, 0);
|
||||
const struct mie_type *ty
|
||||
= mie_ctx_get_int_type(mie_builder_get_ctx(builder), 32);
|
||||
struct mie_register *result = mie_op_add_result(op, ty);
|
||||
|
||||
result->reg_block = mie_builder_get_current_block(builder);
|
||||
mie_builder_put_name(builder, &result->reg_name, name);
|
||||
|
||||
struct mie_attribute *val
|
||||
= mie_ctx_get_int(mie_builder_get_ctx(builder), value, 32);
|
||||
mie_attribute_map_put(&op->op_attrib, "value", val, MIE_ATTRMAP_F_REPLACE);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
struct mie_register *mie_arith_put_constant_f(
|
||||
struct mie_builder *builder, long long value, const char *name)
|
||||
{
|
||||
struct mie_op *op
|
||||
= mie_builder_put_op(builder, "arith", "constant", NULL, 0);
|
||||
const struct mie_type *ty
|
||||
= mie_ctx_get_int_type(mie_builder_get_ctx(builder), 32);
|
||||
struct mie_register *result = mie_op_add_result(op, ty);
|
||||
|
||||
result->reg_block = mie_builder_get_current_block(builder);
|
||||
mie_builder_put_name(builder, &result->reg_name, name);
|
||||
|
||||
struct mie_attribute *val
|
||||
= mie_ctx_get_float(mie_builder_get_ctx(builder), value, 32);
|
||||
mie_attribute_map_put(&op->op_attrib, "value", val, MIE_ATTRMAP_F_REPLACE);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
MIE_OP_DEFINITION_BEGIN(mie_arith_constant, "constant")
|
||||
MIE_OP_DEFINITION_PRINT(print);
|
||||
MIE_OP_DEFINITION_PARSE(parse);
|
||||
|
||||
@@ -21,16 +21,25 @@ static enum mie_status print(
|
||||
b_stream_write_string(out->p_stream, "#builtin.int<", NULL);
|
||||
}
|
||||
|
||||
if (int_ty->i_width < 64 || !abbrev) {
|
||||
if (int_ty->i_width <= 64) {
|
||||
b_stream_write_fmt(
|
||||
out->p_stream, NULL, "%zu : i%zu",
|
||||
int_val->i_val.v_small, int_ty->i_width);
|
||||
} else if (int_ty->i_width == 64 && abbrev) {
|
||||
b_stream_write_fmt(
|
||||
out->p_stream, NULL, "%zu", int_val->i_val.v_small);
|
||||
out->p_stream, NULL, "%zu", int_val->i_val.v_small,
|
||||
int_ty->i_width);
|
||||
} else {
|
||||
b_stream_write_fmt(
|
||||
out->p_stream, NULL, "INF : i%zu", int_ty->i_width);
|
||||
b_stream_write_fmt(out->p_stream, NULL, "INF", int_ty->i_width);
|
||||
}
|
||||
|
||||
if (int_ty->i_width != 64 || !abbrev) {
|
||||
b_stream_write_string(out->p_stream, " : ", NULL);
|
||||
|
||||
if (abbrev) {
|
||||
b_stream_write_fmt(
|
||||
out->p_stream, NULL, "i%zu", int_ty->i_width);
|
||||
} else {
|
||||
b_stream_write_fmt(
|
||||
out->p_stream, NULL, "!builtin.int<%zu>",
|
||||
int_ty->i_width);
|
||||
}
|
||||
}
|
||||
|
||||
if (!abbrev) {
|
||||
|
||||
@@ -7,6 +7,23 @@
|
||||
#include <mie/parse/parser.h>
|
||||
#include <mie/print/printer.h>
|
||||
|
||||
struct mie_attribute *mie_type_attr_create(
|
||||
struct mie_ctx *ctx, const struct mie_type *ty)
|
||||
{
|
||||
struct mie_type_attr *out = malloc(sizeof *out);
|
||||
if (!out) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(out, 0x0, sizeof *out);
|
||||
|
||||
out->ty_base.a_def
|
||||
= mie_ctx_get_attribute_definition(ctx, "builtin", "type");
|
||||
out->ty_value = ty;
|
||||
|
||||
return (struct mie_attribute *)out;
|
||||
}
|
||||
|
||||
static enum mie_status print(
|
||||
const struct mie_attribute *value, struct mie_printer *out)
|
||||
{
|
||||
@@ -25,25 +42,11 @@ static enum mie_status print(
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
static struct mie_type_attr *type_attr_create(struct mie_ctx *ctx)
|
||||
{
|
||||
struct mie_type_attr *ty = malloc(sizeof *ty);
|
||||
if (!ty) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(ty, 0x0, sizeof *ty);
|
||||
|
||||
ty->ty_base.a_def
|
||||
= mie_ctx_get_attribute_definition(ctx, "builtin", "type");
|
||||
|
||||
return ty;
|
||||
}
|
||||
|
||||
static enum mie_status parse(
|
||||
struct mie_parser *ctx, const struct mie_attribute **out)
|
||||
{
|
||||
struct mie_type_attr *ty = type_attr_create(mie_parser_get_mie_ctx(ctx));
|
||||
struct mie_type_attr *ty = (struct mie_type_attr *)mie_type_attr_create(
|
||||
mie_parser_get_mie_ctx(ctx), NULL);
|
||||
if (!ty) {
|
||||
return MIE_ERR_NO_MEMORY;
|
||||
}
|
||||
|
||||
@@ -2,9 +2,11 @@
|
||||
#include <mie/ctx.h>
|
||||
#include <mie/dialect/builtin.h>
|
||||
#include <mie/dialect/dialect.h>
|
||||
#include <mie/dialect/func.h>
|
||||
#include <mie/interface/interface-definition.h>
|
||||
#include <mie/interface/interface.h>
|
||||
#include <mie/ir/block.h>
|
||||
#include <mie/ir/builder.h>
|
||||
#include <mie/ir/op-definition.h>
|
||||
#include <mie/ir/op.h>
|
||||
#include <mie/ir/region.h>
|
||||
@@ -72,6 +74,59 @@ static enum mie_status parse(struct mie_parser *parser, struct mie_op *out)
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
struct mie_op *mie_func_put_func(
|
||||
struct mie_builder *builder, const char *name,
|
||||
struct mie_func_parameter *params, size_t nr_params,
|
||||
const struct mie_type **ret_types, size_t nr_ret_types)
|
||||
{
|
||||
const struct mie_type **param_types
|
||||
= calloc(nr_params, sizeof *param_types);
|
||||
if (!param_types) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < nr_params; i++) {
|
||||
param_types[i] = params[i].param_type;
|
||||
}
|
||||
|
||||
const struct mie_type *func_type = mie_ctx_get_function_type(
|
||||
mie_builder_get_ctx(builder), param_types, nr_params, ret_types,
|
||||
nr_ret_types);
|
||||
free(param_types);
|
||||
|
||||
if (!func_type) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct mie_op *op = mie_builder_put_op(builder, "func", "func", NULL, 0);
|
||||
|
||||
struct mie_region *region = mie_op_add_region(op);
|
||||
struct mie_block *entry = mie_region_add_block(region);
|
||||
mie_name_map_put(region->r_names, &entry->b_name, "entry", 0);
|
||||
|
||||
for (size_t i = 0; i < nr_params; i++) {
|
||||
struct mie_register *param_reg = mie_block_add_param(entry);
|
||||
mie_name_map_put(
|
||||
region->r_names, ¶m_reg->reg_name,
|
||||
params[i].param_name, 0);
|
||||
param_reg->reg_type = params[i].param_type;
|
||||
params[i].param_reg = param_reg;
|
||||
}
|
||||
|
||||
struct mie_attribute *sym_name
|
||||
= mie_ctx_get_string(mie_builder_get_ctx(builder), name);
|
||||
struct mie_attribute *function_type
|
||||
= mie_type_attr_create(mie_builder_get_ctx(builder), func_type);
|
||||
|
||||
mie_attribute_map_put(
|
||||
&op->op_attrib, "sym_name", sym_name, MIE_ATTRMAP_F_REPLACE);
|
||||
mie_attribute_map_put(
|
||||
&op->op_attrib, "function_type", function_type,
|
||||
MIE_ATTRMAP_F_REPLACE);
|
||||
|
||||
return op;
|
||||
}
|
||||
|
||||
MIE_OP_DEFINITION_BEGIN(mie_func_func, "func")
|
||||
MIE_OP_DEFINITION_PRINT(print);
|
||||
MIE_OP_DEFINITION_PARSE(parse);
|
||||
|
||||
@@ -36,6 +36,8 @@ struct mie_ctx {
|
||||
MIE_API struct mie_ctx *mie_ctx_create(void);
|
||||
MIE_API void mie_ctx_destroy(struct mie_ctx *ctx);
|
||||
|
||||
MIE_API struct mie_op *mie_ctx_create_op(
|
||||
const struct mie_ctx *ctx, const char *dialect, const char *op);
|
||||
MIE_API bool mie_ctx_resolve_op(const struct mie_ctx *ctx, struct mie_op *op);
|
||||
|
||||
MIE_API struct mie_dialect *mie_ctx_get_dialect(
|
||||
|
||||
@@ -8,7 +8,19 @@
|
||||
|
||||
struct mie_ctx;
|
||||
struct mie_dialect;
|
||||
struct mie_builder;
|
||||
|
||||
MIE_API struct mie_dialect *mie_arith_dialect_create(struct mie_ctx *ctx);
|
||||
|
||||
MIE_API struct mie_register *mie_arith_put_constant_i(
|
||||
struct mie_builder *builder, long long value, const char *name);
|
||||
MIE_API struct mie_register *mie_arith_put_constant_f(
|
||||
struct mie_builder *builder, long long value, const char *name);
|
||||
MIE_API struct mie_register *mie_arith_put_addi(
|
||||
struct mie_builder *builder, struct mie_register *left,
|
||||
struct mie_register *right, const char *name);
|
||||
MIE_API struct mie_register *mie_arith_put_addf(
|
||||
struct mie_builder *builder, struct mie_register *left,
|
||||
struct mie_register *right, const char *name);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -121,6 +121,9 @@ MIE_API struct mie_type *mie_ctx_get_int_type(struct mie_ctx *ctx, size_t bit_wi
|
||||
MIE_API struct mie_type *mie_ctx_get_float_type(
|
||||
struct mie_ctx *ctx, size_t bit_width);
|
||||
|
||||
MIE_API struct mie_attribute *mie_type_attr_create(
|
||||
struct mie_ctx *ctx, const struct mie_type *ty);
|
||||
|
||||
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);
|
||||
|
||||
|
||||
@@ -2,10 +2,25 @@
|
||||
#define MIE_DIALECT_FUNC_H_
|
||||
|
||||
#include <mie/misc.h>
|
||||
#include <stddef.h>
|
||||
|
||||
struct mie_ctx;
|
||||
struct mie_type;
|
||||
struct mie_dialect;
|
||||
struct mie_register;
|
||||
struct mie_builder;
|
||||
|
||||
struct mie_func_parameter {
|
||||
const char *param_name;
|
||||
const struct mie_type *param_type;
|
||||
struct mie_register *param_reg;
|
||||
};
|
||||
|
||||
MIE_API struct mie_dialect *mie_func_dialect_create(struct mie_ctx *ctx);
|
||||
|
||||
MIE_API struct mie_op *mie_func_put_func(
|
||||
struct mie_builder *builder, const char *name,
|
||||
struct mie_func_parameter *params, size_t nr_params,
|
||||
const struct mie_type **ret_types, size_t nr_ret_types);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -20,5 +20,6 @@ struct mie_block {
|
||||
extern struct mie_vector_ops mie_block_vector_ops;
|
||||
|
||||
MIE_API struct mie_op *mie_block_add_op(struct mie_block *block);
|
||||
MIE_API struct mie_register *mie_block_add_param(struct mie_block *block);
|
||||
|
||||
#endif
|
||||
|
||||
38
mie/include/mie/ir/builder.h
Normal file
38
mie/include/mie/ir/builder.h
Normal file
@@ -0,0 +1,38 @@
|
||||
#ifndef MIE_IR_BUILDER_H_
|
||||
#define MIE_IR_BUILDER_H_
|
||||
|
||||
#include <mie/misc.h>
|
||||
#include <stddef.h>
|
||||
|
||||
struct mie_op;
|
||||
struct mie_ctx;
|
||||
struct mie_type;
|
||||
struct mie_name;
|
||||
struct mie_block;
|
||||
struct mie_region;
|
||||
struct mie_register;
|
||||
|
||||
struct mie_builder;
|
||||
|
||||
MIE_API struct mie_builder *mie_builder_create(
|
||||
struct mie_ctx *ctx, struct mie_op *root);
|
||||
MIE_API void mie_builder_destroy(struct mie_builder *builder);
|
||||
|
||||
MIE_API struct mie_ctx *mie_builder_get_ctx(struct mie_builder *builder);
|
||||
MIE_API struct mie_block *mie_builder_get_current_block(struct mie_builder *builder);
|
||||
|
||||
MIE_API void mie_builder_step_into_op(
|
||||
struct mie_builder *builder, struct mie_op *op);
|
||||
MIE_API void mie_builder_step_into_region(
|
||||
struct mie_builder *builder, struct mie_region *region);
|
||||
MIE_API void mie_builder_step_into_block(
|
||||
struct mie_builder *builder, struct mie_block *block);
|
||||
MIE_API void mie_builder_step_out(struct mie_builder *builder);
|
||||
|
||||
MIE_API struct mie_op *mie_builder_put_op(
|
||||
struct mie_builder *, const char *dialect, const char *op,
|
||||
struct mie_register **args, size_t nr_args);
|
||||
MIE_API enum mie_status mie_builder_put_name(
|
||||
struct mie_builder *, struct mie_name *name, const char *hint);
|
||||
|
||||
#endif
|
||||
@@ -72,6 +72,11 @@ MIE_API void mie_op_destroy(struct mie_op *op);
|
||||
MIE_API void mie_op_init(struct mie_op *op);
|
||||
MIE_API void mie_op_cleanup(struct mie_op *op);
|
||||
|
||||
MIE_API 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);
|
||||
MIE_API struct mie_region *mie_op_add_region(struct mie_op *op);
|
||||
|
||||
MIE_API bool mie_op_has_trait(
|
||||
const struct mie_op *op, const char *dialect_name, const char *trait_name);
|
||||
MIE_API bool mie_op_has_interface(
|
||||
|
||||
@@ -62,8 +62,13 @@ struct mie_register {
|
||||
};
|
||||
|
||||
extern struct mie_vector_ops mie_register_vector_ops;
|
||||
extern struct mie_vector_ops mie_register_use_vector_ops;
|
||||
|
||||
MIE_API void mie_register_move(struct mie_register *dest, struct mie_register *src);
|
||||
MIE_API void mie_register_cleanup(struct mie_register *reg);
|
||||
|
||||
MIE_API void mie_register_use_move(
|
||||
struct mie_register_use *dest, struct mie_register_use *src);
|
||||
MIE_API void mie_register_use_cleanup(struct mie_register_use *reg);
|
||||
|
||||
#endif
|
||||
|
||||
19
mie/ir/block.c
Normal file
19
mie/ir/block.c
Normal file
@@ -0,0 +1,19 @@
|
||||
#include <mie/ir/block.h>
|
||||
#include <mie/ir/op.h>
|
||||
#include <mie/ir/register.h>
|
||||
|
||||
struct mie_op *mie_block_add_op(struct mie_block *block)
|
||||
{
|
||||
return mie_vector_emplace_back(block->b_ops, NULL);
|
||||
}
|
||||
|
||||
struct mie_register *mie_block_add_param(struct mie_block *block)
|
||||
{
|
||||
struct mie_register *result = mie_vector_emplace_back(
|
||||
block->b_params, &mie_register_vector_ops);
|
||||
result->reg_flags = MIE_REGISTER_F_VIRTUAL | MIE_REGISTER_F_BLOCK_PARAM;
|
||||
result->reg_block = block;
|
||||
result->reg_op = NULL;
|
||||
|
||||
return result;
|
||||
}
|
||||
171
mie/ir/builder.c
Normal file
171
mie/ir/builder.c
Normal file
@@ -0,0 +1,171 @@
|
||||
#include <mie/ctx.h>
|
||||
#include <mie/ir/block.h>
|
||||
#include <mie/ir/builder.h>
|
||||
#include <mie/ir/op-definition.h>
|
||||
#include <mie/ir/op.h>
|
||||
#include <mie/ir/region.h>
|
||||
|
||||
struct builder_scope {
|
||||
b_queue_entry s_entry;
|
||||
struct mie_op *s_op;
|
||||
struct mie_region *s_region;
|
||||
struct mie_block *s_block;
|
||||
};
|
||||
|
||||
struct mie_builder {
|
||||
struct mie_ctx *b_ctx;
|
||||
b_queue b_scope_stack;
|
||||
struct mie_op *b_root;
|
||||
struct mie_op *b_prev_op;
|
||||
};
|
||||
|
||||
struct mie_builder *mie_builder_create(struct mie_ctx *ctx, struct mie_op *root)
|
||||
{
|
||||
struct mie_builder *out = malloc(sizeof *out);
|
||||
if (!out) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(out, 0x0, sizeof *out);
|
||||
|
||||
out->b_ctx = ctx;
|
||||
out->b_root = root;
|
||||
|
||||
mie_builder_step_into_op(out, root);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
struct mie_ctx *mie_builder_get_ctx(struct mie_builder *builder)
|
||||
{
|
||||
return builder->b_ctx;
|
||||
}
|
||||
|
||||
struct mie_block *mie_builder_get_current_block(struct mie_builder *builder)
|
||||
{
|
||||
b_queue_entry *entry = b_queue_last(&builder->b_scope_stack);
|
||||
if (!entry) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct builder_scope *scope
|
||||
= b_unbox(struct builder_scope, entry, s_entry);
|
||||
|
||||
return scope->s_block;
|
||||
}
|
||||
|
||||
void mie_builder_step_into_op(struct mie_builder *builder, struct mie_op *op)
|
||||
{
|
||||
struct mie_region *region = NULL;
|
||||
|
||||
if (MIE_VECTOR_COUNT(op->op_regions) == 0) {
|
||||
region = mie_op_add_region(op);
|
||||
} else {
|
||||
region = &op->op_regions.items[MIE_VECTOR_COUNT(op->op_regions) - 1];
|
||||
}
|
||||
|
||||
mie_builder_step_into_region(builder, region);
|
||||
}
|
||||
|
||||
void mie_builder_step_into_region(
|
||||
struct mie_builder *builder, struct mie_region *region)
|
||||
{
|
||||
struct mie_block *block = NULL;
|
||||
|
||||
if (MIE_VECTOR_COUNT(region->r_blocks) == 0) {
|
||||
block = mie_region_add_block(region);
|
||||
} else {
|
||||
block = ®ion->r_blocks.items[MIE_VECTOR_COUNT(region->r_blocks) - 1];
|
||||
}
|
||||
|
||||
mie_builder_step_into_block(builder, block);
|
||||
}
|
||||
|
||||
void mie_builder_step_into_block(struct mie_builder *builder, struct mie_block *block)
|
||||
{
|
||||
struct builder_scope *scope = malloc(sizeof *scope);
|
||||
if (!scope) {
|
||||
return;
|
||||
}
|
||||
|
||||
memset(scope, 0x0, sizeof *scope);
|
||||
|
||||
scope->s_block = block;
|
||||
scope->s_region = block->b_parent;
|
||||
scope->s_op = scope->s_region->r_parent;
|
||||
|
||||
b_queue_push_back(&builder->b_scope_stack, &scope->s_entry);
|
||||
}
|
||||
|
||||
void mie_builder_step_out(struct mie_builder *builder)
|
||||
{
|
||||
b_queue_entry *entry = b_queue_last(&builder->b_scope_stack);
|
||||
if (!entry) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct builder_scope *scope
|
||||
= b_unbox(struct builder_scope, entry, s_entry);
|
||||
b_queue_delete(&builder->b_scope_stack, entry);
|
||||
free(scope);
|
||||
}
|
||||
|
||||
static struct mie_block *create_current_block(struct mie_builder *builder)
|
||||
{
|
||||
struct mie_region *region = NULL;
|
||||
|
||||
if (MIE_VECTOR_COUNT(builder->b_root->op_regions) == 0) {
|
||||
region = mie_op_add_region(builder->b_root);
|
||||
} else {
|
||||
region = &builder->b_root->op_regions
|
||||
.items[MIE_VECTOR_COUNT(builder->b_root->op_result) - 1];
|
||||
}
|
||||
|
||||
struct mie_block *block = NULL;
|
||||
|
||||
if (MIE_VECTOR_COUNT(region->r_blocks) == 0) {
|
||||
block = mie_region_add_block(region);
|
||||
} else {
|
||||
block = ®ion->r_blocks.items[MIE_VECTOR_COUNT(region->r_blocks)];
|
||||
}
|
||||
|
||||
return block;
|
||||
}
|
||||
|
||||
struct mie_op *mie_builder_put_op(
|
||||
struct mie_builder *builder, const char *dialect, const char *op_name,
|
||||
struct mie_register **args, size_t nr_args)
|
||||
{
|
||||
struct mie_block *block = mie_builder_get_current_block(builder);
|
||||
|
||||
const struct mie_op_definition *op_def
|
||||
= mie_ctx_get_op_definition(builder->b_ctx, dialect, op_name);
|
||||
if (!op_def) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct mie_op *op = mie_block_add_op(block);
|
||||
op->op_flags = MIE_OP_F_OP_RESOLVED;
|
||||
op->op_info = op_def;
|
||||
op->op_dialect = op_def->op_parent;
|
||||
|
||||
for (size_t i = 0; i < nr_args; i++) {
|
||||
struct mie_op_arg *arg = mie_op_add_arg(op);
|
||||
arg->arg_flags = MIE_OP_F_ARG_RESOLVED;
|
||||
arg->arg_value.u_reg = args[i];
|
||||
arg->arg_value.u_user = op;
|
||||
b_queue_push_back(&args[i]->reg_use, &arg->arg_value.u_entry);
|
||||
}
|
||||
|
||||
return op;
|
||||
}
|
||||
|
||||
enum mie_status mie_builder_put_name(
|
||||
struct mie_builder *builder, struct mie_name *name, const char *hint)
|
||||
{
|
||||
struct mie_block *block = mie_builder_get_current_block(builder);
|
||||
struct mie_region *scope = block->b_parent;
|
||||
return mie_name_map_put(scope->r_names, name, hint, 0)
|
||||
? MIE_SUCCESS
|
||||
: MIE_ERR_NAME_EXISTS;
|
||||
}
|
||||
57
mie/ir/op.c
57
mie/ir/op.c
@@ -1,7 +1,39 @@
|
||||
#include <assert.h>
|
||||
#include <mie/ir/op-definition.h>
|
||||
#include <mie/ir/op.h>
|
||||
#include <mie/ir/region.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static enum mie_status op_arg_cleanup(void *p)
|
||||
{
|
||||
struct mie_op_arg *arg = p;
|
||||
|
||||
if (arg->arg_flags & MIE_OP_F_ARG_RESOLVED) {
|
||||
b_queue_delete(
|
||||
&arg->arg_value.u_reg->reg_use, &arg->arg_value.u_entry);
|
||||
}
|
||||
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
static enum mie_status op_arg_move(void *dst, void *src, size_t itemsz)
|
||||
{
|
||||
assert(itemsz == sizeof(struct mie_op_arg));
|
||||
struct mie_op_arg *dest_arg = dst, *src_arg = src;
|
||||
memmove(dest_arg, src_arg, sizeof *src_arg);
|
||||
|
||||
if (src_arg->arg_flags & MIE_OP_F_ARG_RESOLVED) {
|
||||
mie_register_use_move(&dest_arg->arg_value, &src_arg->arg_value);
|
||||
}
|
||||
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
struct mie_vector_ops op_arg_vector_ops = {
|
||||
.v_destroy = op_arg_cleanup,
|
||||
.v_move = op_arg_move,
|
||||
};
|
||||
|
||||
struct mie_op *mie_op_create(void)
|
||||
{
|
||||
struct mie_op *out = malloc(sizeof *out);
|
||||
@@ -32,6 +64,31 @@ void mie_op_cleanup(struct mie_op *op)
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
struct mie_op_arg *mie_op_add_arg(struct mie_op *op)
|
||||
{
|
||||
return mie_vector_emplace_back(op->op_args, &op_arg_vector_ops);
|
||||
}
|
||||
|
||||
struct mie_register *mie_op_add_result(struct mie_op *op, const struct mie_type *ty)
|
||||
{
|
||||
struct mie_register *result = mie_vector_emplace_back(
|
||||
op->op_result, &mie_register_vector_ops);
|
||||
result->reg_flags = MIE_REGISTER_F_VIRTUAL | MIE_REGISTER_F_OP_RESULT;
|
||||
result->reg_type = ty;
|
||||
result->reg_op = op;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
struct mie_region *mie_op_add_region(struct mie_op *op)
|
||||
{
|
||||
struct mie_region *region = mie_vector_emplace_back(op->op_regions, NULL);
|
||||
region->r_names = mie_name_map_create(NULL);
|
||||
region->r_parent = op;
|
||||
|
||||
return region;
|
||||
}
|
||||
|
||||
bool mie_op_has_trait(
|
||||
const struct mie_op *op, const char *dialect_name, const char *trait_name)
|
||||
{
|
||||
|
||||
@@ -1,13 +1,14 @@
|
||||
#include <assert.h>
|
||||
#include <blue/core/queue.h>
|
||||
#include <mie/ir/register.h>
|
||||
|
||||
static enum mie_status cleanup(void *p)
|
||||
static enum mie_status reg_cleanup(void *p)
|
||||
{
|
||||
mie_register_cleanup(p);
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
static enum mie_status move(void *dst, void *src, size_t itemsz)
|
||||
static enum mie_status reg_move(void *dst, void *src, size_t itemsz)
|
||||
{
|
||||
assert(itemsz == sizeof(struct mie_register));
|
||||
struct mie_register *dest_reg = dst, *src_reg = src;
|
||||
@@ -15,9 +16,23 @@ static enum mie_status move(void *dst, void *src, size_t itemsz)
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
static enum mie_status reg_use_cleanup(void *p)
|
||||
{
|
||||
mie_register_use_cleanup(p);
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
static enum mie_status reg_use_move(void *dst, void *src, size_t itemsz)
|
||||
{
|
||||
assert(itemsz == sizeof(struct mie_register_use));
|
||||
struct mie_register_use *dest_reg = dst, *src_reg = src;
|
||||
mie_register_use_move(dest_reg, src_reg);
|
||||
return MIE_SUCCESS;
|
||||
}
|
||||
|
||||
struct mie_vector_ops mie_register_vector_ops = {
|
||||
.v_destroy = cleanup,
|
||||
.v_move = move,
|
||||
.v_destroy = reg_cleanup,
|
||||
.v_move = reg_move,
|
||||
};
|
||||
|
||||
void mie_register_move(struct mie_register *dest, struct mie_register *src)
|
||||
@@ -35,3 +50,20 @@ void mie_register_cleanup(struct mie_register *reg)
|
||||
mie_name_destroy(®->reg_name);
|
||||
}
|
||||
}
|
||||
|
||||
void mie_register_use_move(
|
||||
struct mie_register_use *dest, struct mie_register_use *src)
|
||||
{
|
||||
memmove(dest, src, sizeof *dest);
|
||||
|
||||
if (src->u_reg) {
|
||||
b_queue_move(&src->u_reg->reg_use, &src->u_entry, &dest->u_entry);
|
||||
}
|
||||
}
|
||||
|
||||
void mie_register_use_cleanup(struct mie_register_use *use)
|
||||
{
|
||||
if (use->u_reg) {
|
||||
b_queue_delete(&use->u_reg->reg_use, &use->u_entry);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user