mie: select: add support for target-specific nodes and lowering operations

This commit is contained in:
2025-09-08 15:42:22 +01:00
parent 5ca045fd5b
commit eb260fb35c
15 changed files with 277 additions and 76 deletions

View File

@@ -8,12 +8,14 @@
#include <mie/select/builder.h>
#include <mie/select/graph.h>
#include <mie/select/node.h>
#include <mie/target/target.h>
#include <stdlib.h>
#include <string.h>
struct mie_select_builder {
struct mie_ctx *b_ctx;
struct mie_select_graph *b_graph;
const struct mie_target *b_target;
/* map of mie_instr* to mie_select_value*, defining the graph node that
* corresponds to each value-producing instruction */
b_hashmap *b_nodes;
@@ -22,7 +24,8 @@ struct mie_select_builder {
b_hashmap *b_mem_access;
};
struct mie_select_builder *mie_select_builder_create(struct mie_ctx *ctx)
struct mie_select_builder *mie_select_builder_create(
struct mie_ctx *ctx, const struct mie_target *target)
{
struct mie_select_builder *out = malloc(sizeof *out);
if (!out) {
@@ -32,6 +35,7 @@ struct mie_select_builder *mie_select_builder_create(struct mie_ctx *ctx)
memset(out, 0x0, sizeof *out);
out->b_ctx = ctx;
out->b_target = target;
out->b_graph = mie_select_graph_create(ctx);
if (!out->b_graph) {
free(out);
@@ -66,7 +70,10 @@ void mie_select_builder_destroy(struct mie_select_builder *builder)
b_hashmap_release(builder->b_mem_access);
}
mie_select_graph_destroy(builder->b_graph);
if (builder->b_graph) {
mie_select_graph_destroy(builder->b_graph);
}
free(builder);
}
@@ -81,6 +88,12 @@ struct mie_ctx *mie_select_builder_get_ctx(struct mie_select_builder *builder)
return builder->b_ctx;
}
const struct mie_target *mie_select_builder_get_target(
struct mie_select_builder *builder)
{
return builder->b_target;
}
static void clear_node_map(struct mie_select_builder *builder)
{
b_hashmap_iterator it;
@@ -107,8 +120,8 @@ struct mie_select_graph *mie_select_builder_finish(struct mie_select_builder *bu
}
status = mie_select_graph_get_node(
graph, MIE_SELECT_OP_ROOT, root_operands, nr_root_operands,
NULL, 0, &graph->g_root);
graph, mie_target_builtin(), MIE_SELECT_OP_ROOT, root_operands,
nr_root_operands, NULL, 0, &graph->g_root);
if (status != MIE_SUCCESS) {
return NULL;
@@ -121,6 +134,53 @@ struct mie_select_graph *mie_select_builder_finish(struct mie_select_builder *bu
return graph;
}
enum mie_status mie_select_builder_get_const(
struct mie_select_builder *builder, long long value,
struct mie_select_value *out)
{
const struct mie_target *builtin = mie_target_builtin();
struct mie_type *ctype = mie_ctx_get_int_type(builder->b_ctx, 32);
struct mie_select_node *node = NULL;
b_queue_iterator it;
b_queue_foreach (&it, &builder->b_graph->g_nodes) {
node = b_unbox(struct mie_select_node, it.entry, n_entry);
if (node->n_target != builtin) {
continue;
}
if (node->n_opcode != MIE_SELECT_OP_CONSTANT) {
continue;
}
if (!(node->n_flags & MIE_SELECT_NODE_F_IVALUE)) {
continue;
}
if (node->n_value.i != value) {
continue;
}
mie_select_node_get_value(node, ctype, 0, out);
return MIE_SUCCESS;
}
enum mie_status status = mie_select_graph_get_node(
builder->b_graph, builtin, MIE_SELECT_OP_CONSTANT, NULL, 0,
&ctype, 1, &node);
if (status != MIE_SUCCESS) {
return status;
}
node->n_flags |= MIE_SELECT_NODE_F_IVALUE;
node->n_value.i = value;
mie_select_node_get_value(node, ctype, 0, out);
return MIE_SUCCESS;
}
enum mie_status mie_select_builder_push_instr(
struct mie_select_builder *builder, struct mie_instr *instr)
{
@@ -138,15 +198,18 @@ static enum mie_status get_const_node(
struct mie_select_value *out)
{
struct mie_const *c = (struct mie_const *)ir_val;
struct mie_select_node *node;
enum mie_status status = mie_select_graph_get_node(
builder->b_graph, MIE_SELECT_OP_CONSTANT, NULL, 0, &c->c_type,
1, out);
builder->b_graph, mie_target_builtin(), MIE_SELECT_OP_CONSTANT,
NULL, 0, &c->c_type, 1, &node);
if (status != MIE_SUCCESS) {
return status;
}
out->v_node->n_flags = MIE_SELECT_NODE_F_PVALUE;
out->v_node->n_value_p = ir_val;
node->n_flags = MIE_SELECT_NODE_F_PVALUE;
node->n_value.v = ir_val;
mie_select_node_get_value(node, c->c_type, 0, out);
return MIE_SUCCESS;
}
@@ -168,19 +231,23 @@ static enum mie_status get_data_node(
return MIE_ERR_INVALID_VALUE;
}
struct mie_select_node *node;
enum mie_status status = mie_select_graph_get_node(
builder->b_graph, opcode, NULL, 0, &type, 1, out);
builder->b_graph, mie_target_builtin(), opcode, NULL, 0, &type,
1, &node);
if (status != MIE_SUCCESS) {
return status;
}
out->v_node->n_flags = MIE_SELECT_NODE_F_PVALUE;
out->v_node->n_value_p = ir_val;
node->n_flags = MIE_SELECT_NODE_F_PVALUE;
node->n_value.v = ir_val;
mie_select_node_get_value(node, type, 0, out);
return MIE_SUCCESS;
}
struct mie_select_value *select_builder_get_value(
struct mie_select_value *mie_select_builder_get_value(
struct mie_select_builder *builder, struct mie_value *ir_val)
{
b_hashmap_key key = {
@@ -228,7 +295,7 @@ struct mie_select_value *select_builder_get_value(
return select_val;
}
enum mie_status select_builder_set_value(
enum mie_status mie_select_builder_set_value(
struct mie_select_builder *builder, struct mie_value *ir_val,
struct mie_select_value *graph_val)
{
@@ -254,7 +321,7 @@ enum mie_status select_builder_set_value(
return MIE_SUCCESS;
}
struct mie_select_value *select_builder_get_mem_access(
struct mie_select_value *mie_select_builder_get_mem_access(
struct mie_select_builder *builder, struct mie_value *ir_val)
{
b_hashmap_key key = {
@@ -271,7 +338,7 @@ struct mie_select_value *select_builder_get_mem_access(
return NULL;
}
enum mie_status select_builder_set_mem_access(
enum mie_status mie_select_builder_set_mem_access(
struct mie_select_builder *builder, struct mie_value *ir_val,
struct mie_select_value *graph_val)
{
@@ -296,3 +363,21 @@ enum mie_status select_builder_set_mem_access(
b_hashmap_put(builder->b_mem_access, &key, &hashmap_val);
return MIE_SUCCESS;
}
struct mie_select_node *mie_select_builder_find_node_with_ivalue(
struct mie_select_builder *builder, const struct mie_target *target,
unsigned int opcode, long long val)
{
b_queue_iterator it;
b_queue_foreach (&it, &builder->b_graph->g_nodes) {
struct mie_select_node *node
= b_unbox(struct mie_select_node, it.entry, n_entry);
if (node->n_target == target && node->n_opcode == opcode
&& node->n_value.i == val) {
return node;
}
}
return NULL;
}