Files
mie/mie/ir/block.c

269 lines
5.7 KiB
C
Raw Normal View History

#include <mie/ir/block.h>
#include <mie/ir/op.h>
#include <mie/ir/register.h>
struct mie_op *mie_block_get_first_op(const struct mie_block *block)
{
b_queue_entry *entry = b_queue_first(&block->b_ops);
if (!entry) {
return NULL;
}
return b_unbox(struct mie_op, entry, op_entry);
}
struct mie_op *mie_block_get_prev_op(
const struct mie_block *block, const struct mie_op *before)
{
if (!before || before->op_container != block) {
return NULL;
}
b_queue_entry *entry = b_queue_prev(&before->op_entry);
if (!entry) {
return NULL;
}
return b_unbox(struct mie_op, entry, op_entry);
}
struct mie_op *mie_block_get_next_op(
const struct mie_block *block, const struct mie_op *after)
{
if (!after || after->op_container != block) {
return NULL;
}
b_queue_entry *entry = b_queue_next(&after->op_entry);
if (!entry) {
return NULL;
}
return b_unbox(struct mie_op, entry, op_entry);
}
struct mie_op *mie_block_get_last_op(const struct mie_block *block)
{
b_queue_entry *entry = b_queue_last(&block->b_ops);
if (!entry) {
return NULL;
}
return b_unbox(struct mie_op, entry, op_entry);
}
struct mie_op *mie_block_get_terminator(const struct mie_block *block)
{
b_queue_entry *op_entry = b_queue_last(&block->b_ops);
return b_unbox(struct mie_op, op_entry, op_entry);
}
struct mie_op_successor *mie_block_get_first_successor(const struct mie_block *block)
{
struct mie_op *op = mie_block_get_terminator(block);
if (!op) {
return NULL;
}
if (MIE_VECTOR_COUNT(op->op_successors) == 0) {
return NULL;
}
return &op->op_successors.items[0];
}
struct mie_op_successor *mie_block_get_prev_successor(
const struct mie_block *block, const struct mie_op_successor *before)
{
struct mie_op *op = mie_block_get_terminator(block);
if (!op) {
return NULL;
}
if (MIE_VECTOR_COUNT(op->op_successors) == 0) {
return NULL;
}
size_t i = before - &op->op_successors.items[0];
if (i == 0 || i >= MIE_VECTOR_COUNT(op->op_successors)) {
return NULL;
}
return &op->op_successors.items[i - 1];
}
struct mie_op_successor *mie_block_get_next_successor(
const struct mie_block *block, const struct mie_op_successor *after)
{
struct mie_op *op = mie_block_get_terminator(block);
if (!op) {
return NULL;
}
if (MIE_VECTOR_COUNT(op->op_successors) == 0) {
return NULL;
}
size_t i = after - &op->op_successors.items[0];
if (i >= MIE_VECTOR_COUNT(op->op_successors)) {
return NULL;
}
if (i + 1 >= MIE_VECTOR_COUNT(op->op_successors)) {
return NULL;
}
return &op->op_successors.items[i + 1];
}
struct mie_op_successor *mie_block_get_last_successor(const struct mie_block *block)
{
struct mie_op *op = mie_block_get_terminator(block);
if (!op) {
return NULL;
}
size_t nr_successors = MIE_VECTOR_COUNT(op->op_successors);
if (nr_successors == 0) {
return NULL;
}
return &op->op_successors.items[nr_successors - 1];
}
struct mie_block_predecessor *mie_block_get_first_predecessor(
const struct mie_block *block)
{
size_t nr_predecessors = MIE_VECTOR_COUNT(block->b_ipred);
if (nr_predecessors == 0) {
return NULL;
}
return &block->b_ipred.items[0];
}
struct mie_block_predecessor *mie_block_get_prev_predecessor(
const struct mie_block *block, const struct mie_block_predecessor *before)
{
if (MIE_VECTOR_COUNT(block->b_ipred) == 0) {
return NULL;
}
size_t i = before - &block->b_ipred.items[0];
if (i == 0) {
return NULL;
}
return &block->b_ipred.items[i - 1];
}
struct mie_block_predecessor *mie_block_get_next_predecessor(
const struct mie_block *block, const struct mie_block_predecessor *after)
{
if (MIE_VECTOR_COUNT(block->b_ipred) == 0) {
return NULL;
}
size_t i = after - &block->b_ipred.items[0];
if (i >= MIE_VECTOR_COUNT(block->b_ipred)) {
return NULL;
}
if (i + 1 >= MIE_VECTOR_COUNT(block->b_ipred)) {
return NULL;
}
return &block->b_ipred.items[i + 1];
}
struct mie_block_predecessor *mie_block_get_last_predecessor(
const struct mie_block *block)
{
size_t nr_predecessors = MIE_VECTOR_COUNT(block->b_ipred);
if (nr_predecessors == 0) {
return NULL;
}
return &block->b_ipred.items[nr_predecessors - 1];
}
struct mie_op *mie_block_add_op(struct mie_block *block)
{
struct mie_op *op = malloc(sizeof *op);
if (!op) {
return NULL;
}
mie_op_init(op);
op->op_container = block;
b_queue_push_back(&block->b_ops, &op->op_entry);
return op;
}
struct mie_op *mie_block_add_op_after(struct mie_block *block, struct mie_op *after)
{
if (after && after->op_container != block) {
return NULL;
}
struct mie_op *op = malloc(sizeof *op);
if (!op) {
return NULL;
}
mie_op_init(op);
op->op_container = block;
if (after) {
b_queue_insert_after(&block->b_ops, &op->op_entry, &after->op_entry);
} else {
b_queue_push_back(&block->b_ops, &op->op_entry);
}
return op;
}
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;
}
struct mie_register *mie_block_find_register(
const struct mie_block *block, const char *name,
const struct mie_op *start_point)
{
const b_queue_entry *entry = b_queue_last(&block->b_ops);
if (start_point) {
entry = &start_point->op_entry;
}
for (size_t i = 0; i < MIE_VECTOR_COUNT(block->b_params); i++) {
if (!strcmp(block->b_params.items[i].reg_name.n_str, name)) {
return &block->b_params.items[i];
}
}
while (entry) {
struct mie_op *op = b_unbox(struct mie_op, entry, op_entry);
struct mie_register *reg = mie_op_get_result_with_name(op, name);
if (reg) {
return reg;
}
entry = b_queue_prev(entry);
}
return NULL;
}