269 lines
5.7 KiB
C
269 lines
5.7 KiB
C
#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;
|
|
}
|