102 lines
2.4 KiB
C
102 lines
2.4 KiB
C
#include <assert.h>
|
|
#include <mie/ctx.h>
|
|
#include <mie/select/graph.h>
|
|
#include <mie/select/node.h>
|
|
#include <mie/select/opcode.h>
|
|
#include <mie/status.h>
|
|
#include <mie/target/target.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
struct mie_select_graph *mie_select_graph_create(struct mie_ctx *ctx)
|
|
{
|
|
struct mie_select_graph *out = malloc(sizeof *out);
|
|
if (!out) {
|
|
return NULL;
|
|
}
|
|
|
|
memset(out, 0x0, sizeof *out);
|
|
|
|
enum mie_status status = MIE_SUCCESS;
|
|
struct mie_select_node *entry;
|
|
|
|
struct mie_type *entry_values[] = {
|
|
mie_ctx_get_type(ctx, MIE_TYPE_OTHER),
|
|
mie_ctx_get_type(ctx, MIE_TYPE_GLUE),
|
|
};
|
|
const size_t nr_entry_values
|
|
= sizeof entry_values / sizeof entry_values[0];
|
|
|
|
status = mie_select_graph_get_node(
|
|
out, mie_target_builtin(), MIE_SELECT_OP_ENTRY, NULL, 0,
|
|
entry_values, nr_entry_values, &entry);
|
|
if (status != MIE_SUCCESS) {
|
|
free(out);
|
|
return NULL;
|
|
}
|
|
|
|
mie_select_node_get_value(entry, entry_values[0], 0, &out->g_entry);
|
|
|
|
return out;
|
|
}
|
|
|
|
void mie_select_graph_destroy(struct mie_select_graph *graph)
|
|
{
|
|
b_queue_entry *entry = b_queue_first(&graph->g_nodes);
|
|
while (entry) {
|
|
struct mie_select_node *node
|
|
= b_unbox(struct mie_select_node, entry, n_entry);
|
|
b_queue_entry *next = b_queue_next(entry);
|
|
b_queue_delete(&graph->g_nodes, entry);
|
|
|
|
#if 0
|
|
if (node->n_value) {
|
|
mie_value_destroy(node->n_value);
|
|
}
|
|
#endif
|
|
|
|
free(node);
|
|
entry = next;
|
|
}
|
|
|
|
free(graph);
|
|
}
|
|
|
|
enum mie_status mie_select_graph_get_node(
|
|
struct mie_select_graph *graph, const struct mie_target *target,
|
|
unsigned int op, struct mie_select_value **operands, size_t nr_operands,
|
|
struct mie_type **values, size_t nr_values, struct mie_select_node **out)
|
|
{
|
|
struct mie_select_node *node = mie_select_node_create(
|
|
mie_target_builtin(), op, values, nr_values);
|
|
if (!node) {
|
|
return MIE_ERR_NO_MEMORY;
|
|
}
|
|
|
|
struct mie_select_value *operands2
|
|
= calloc(nr_operands, sizeof *operands2);
|
|
for (size_t i = 0; i < nr_operands; i++) {
|
|
assert(operands[i]);
|
|
memcpy(&operands2[i], operands[i], sizeof *operands2);
|
|
}
|
|
|
|
mie_select_node_set_operands(node, operands2, nr_operands);
|
|
free(operands2);
|
|
|
|
node->n_id = graph->g_node_id++;
|
|
node->n_target = target;
|
|
|
|
for (size_t i = 0; i < nr_values; i++) {
|
|
if (values[i]->t_id == MIE_TYPE_OTHER) {
|
|
graph->g_last_chain.v_node = node;
|
|
graph->g_last_chain.v_index = i;
|
|
}
|
|
}
|
|
|
|
b_queue_push_back(&graph->g_nodes, &node->n_entry);
|
|
|
|
*out = node;
|
|
|
|
return MIE_SUCCESS;
|
|
}
|