Files
ivy/mie/ir/block.c

105 lines
2.2 KiB
C
Raw Normal View History

#include <mie/ctx.h>
#include <mie/ir/block.h>
#include <mie/ir/func.h>
#include <mie/ir/instr.h>
#include <mie/type.h>
#include <stdlib.h>
struct mie_block *mie_block_create(struct mie_func *parent, const char *name)
{
struct mie_block *out = malloc(sizeof *out);
if (!out) {
return NULL;
}
memset(out, 0x0, sizeof *out);
mie_value_init(&out->b_base, MIE_VALUE_BLOCK);
struct mie_value *block = MIE_VALUE(out);
if (parent) {
block = mie_func_generate_value_name(parent, block, name);
if (!block) {
free(out);
return NULL;
}
b_queue_push_back(&parent->f_blocks, &block->v_entry);
out->b_parent = parent;
}
return out;
}
bool mie_block_add_instr(struct mie_block *block, struct mie_instr *instr)
{
switch (instr->i_type) {
case MIE_INSTR_PHI:
if (!b_queue_empty(&block->b_instr) || block->b_terminator) {
return false;
}
b_queue_push_back(&block->b_phi, &instr->i_base.v_entry);
return true;
case MIE_INSTR_RET:
case MIE_INSTR_BR:
case MIE_INSTR_SWITCH:
if (block->b_terminator) {
return false;
}
block->b_terminator = instr;
return true;
default:
if (block->b_terminator) {
return false;
}
b_queue_push_back(&block->b_instr, &instr->i_base.v_entry);
return true;
}
}
static struct mie_type *get_type(struct mie_value *v, struct mie_ctx *ctx)
{
return mie_ctx_get_type(ctx, MIE_TYPE_LABEL);
}
2025-04-13 19:25:23 +01:00
static void cleanup(struct mie_value *value)
{
struct mie_block *block = MIE_BLOCK(value);
2025-11-06 10:38:50 +00:00
b_queue_entry *entry = b_queue_first(&block->b_phi);
b_queue_entry *next = NULL;
while (entry) {
struct mie_value *v = b_unbox(struct mie_value, entry, v_entry);
next = b_queue_next(entry);
b_queue_delete(&block->b_phi, entry);
2025-04-13 19:25:23 +01:00
mie_value_destroy(v);
2025-11-06 10:38:50 +00:00
entry = next;
2025-04-13 19:25:23 +01:00
}
2025-11-06 10:38:50 +00:00
entry = b_queue_first(&block->b_instr);
while (entry) {
struct mie_value *v = b_unbox(struct mie_value, entry, v_entry);
next = b_queue_next(entry);
b_queue_delete(&block->b_instr, entry);
2025-04-13 19:25:23 +01:00
mie_value_destroy(v);
2025-11-06 10:38:50 +00:00
entry = next;
2025-04-13 19:25:23 +01:00
}
if (block->b_terminator) {
mie_value_destroy(MIE_VALUE(block->b_terminator));
}
}
const struct mie_value_type block_value_type = {
.t_id = MIE_VALUE_BLOCK,
.t_get_type = get_type,
2025-04-13 19:25:23 +01:00
.t_cleanup = cleanup,
};