mie: select: add support for target-specific nodes and lowering operations
This commit is contained in:
@@ -10,18 +10,43 @@ struct mie_value;
|
|||||||
struct mie_select_builder;
|
struct mie_select_builder;
|
||||||
struct mie_select_node;
|
struct mie_select_node;
|
||||||
struct mie_select_graph;
|
struct mie_select_graph;
|
||||||
|
struct mie_select_value;
|
||||||
|
struct mie_target;
|
||||||
|
|
||||||
MIE_API struct mie_select_builder *mie_select_builder_create(struct mie_ctx *ctx);
|
MIE_API struct mie_select_builder *mie_select_builder_create(
|
||||||
|
struct mie_ctx *ctx, const struct mie_target *target);
|
||||||
MIE_API void mie_select_builder_destroy(struct mie_select_builder *builder);
|
MIE_API void mie_select_builder_destroy(struct mie_select_builder *builder);
|
||||||
|
|
||||||
MIE_API struct mie_select_graph *mie_select_builder_get_graph(
|
MIE_API struct mie_select_graph *mie_select_builder_get_graph(
|
||||||
struct mie_select_builder *builder);
|
struct mie_select_builder *builder);
|
||||||
MIE_API struct mie_ctx *mie_select_builder_get_ctx(
|
MIE_API struct mie_ctx *mie_select_builder_get_ctx(
|
||||||
struct mie_select_builder *builder);
|
struct mie_select_builder *builder);
|
||||||
|
MIE_API const struct mie_target *mie_select_builder_get_target(
|
||||||
|
struct mie_select_builder *builder);
|
||||||
MIE_API struct mie_select_graph *mie_select_builder_finish(
|
MIE_API struct mie_select_graph *mie_select_builder_finish(
|
||||||
struct mie_select_builder *builder);
|
struct mie_select_builder *builder);
|
||||||
|
|
||||||
|
MIE_API enum mie_status mie_select_builder_get_const(
|
||||||
|
struct mie_select_builder *builder, long long value,
|
||||||
|
struct mie_select_value *out);
|
||||||
|
|
||||||
MIE_API enum mie_status mie_select_builder_push_instr(
|
MIE_API enum mie_status mie_select_builder_push_instr(
|
||||||
struct mie_select_builder *builder, struct mie_instr *instr);
|
struct mie_select_builder *builder, struct mie_instr *instr);
|
||||||
|
|
||||||
|
MIE_API 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);
|
||||||
|
|
||||||
|
MIE_API struct mie_select_value *mie_select_builder_get_value(
|
||||||
|
struct mie_select_builder *builder, struct mie_value *ir_val);
|
||||||
|
MIE_API enum mie_status mie_select_builder_set_value(
|
||||||
|
struct mie_select_builder *builder, struct mie_value *ir_val,
|
||||||
|
struct mie_select_value *graph_val);
|
||||||
|
|
||||||
|
MIE_API struct mie_select_value *mie_select_builder_get_mem_access(
|
||||||
|
struct mie_select_builder *builder, struct mie_value *ir_val);
|
||||||
|
MIE_API 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);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include <blue/core/btree.h>
|
#include <blue/core/btree.h>
|
||||||
#include <blue/core/queue.h>
|
#include <blue/core/queue.h>
|
||||||
#include <mie/misc.h>
|
#include <mie/misc.h>
|
||||||
|
#include <mie/target/target.h>
|
||||||
|
|
||||||
struct mie_ctx;
|
struct mie_ctx;
|
||||||
struct mie_type;
|
struct mie_type;
|
||||||
@@ -22,7 +23,7 @@ struct mie_select_use {
|
|||||||
|
|
||||||
struct mie_select_graph {
|
struct mie_select_graph {
|
||||||
b_queue g_nodes;
|
b_queue g_nodes;
|
||||||
struct mie_select_value g_root;
|
struct mie_select_node *g_root;
|
||||||
struct mie_select_value g_entry;
|
struct mie_select_value g_entry;
|
||||||
struct mie_select_value g_last_chain;
|
struct mie_select_value g_last_chain;
|
||||||
size_t g_frame_index;
|
size_t g_frame_index;
|
||||||
@@ -48,9 +49,9 @@ MIE_API struct mie_select_graph *mie_select_graph_create(struct mie_ctx *ctx);
|
|||||||
MIE_API void mie_select_graph_destroy(struct mie_select_graph *graph);
|
MIE_API void mie_select_graph_destroy(struct mie_select_graph *graph);
|
||||||
|
|
||||||
MIE_API enum mie_status mie_select_graph_get_node(
|
MIE_API enum mie_status mie_select_graph_get_node(
|
||||||
struct mie_select_graph *graph, unsigned int op,
|
struct mie_select_graph *graph, const struct mie_target *target,
|
||||||
struct mie_select_value **operands, size_t nr_operands,
|
unsigned int op, struct mie_select_value **operands, size_t nr_operands,
|
||||||
struct mie_type **values, size_t nr_values, struct mie_select_value *out);
|
struct mie_type **values, size_t nr_values, struct mie_select_node **out);
|
||||||
|
|
||||||
MIE_API void mie_select_graph_dump_text(struct mie_select_graph *graph);
|
MIE_API void mie_select_graph_dump_text(struct mie_select_graph *graph);
|
||||||
MIE_API void mie_select_graph_dump_dot(struct mie_select_graph *graph);
|
MIE_API void mie_select_graph_dump_dot(struct mie_select_graph *graph);
|
||||||
|
|||||||
@@ -21,9 +21,14 @@ struct mie_select_node {
|
|||||||
unsigned long n_opcode;
|
unsigned long n_opcode;
|
||||||
enum mie_select_node_flags n_flags;
|
enum mie_select_node_flags n_flags;
|
||||||
|
|
||||||
|
char *n_description;
|
||||||
|
|
||||||
/* certain "builtin" parameters that can be used by opcodes */
|
/* certain "builtin" parameters that can be used by opcodes */
|
||||||
struct mie_value *n_value_p;
|
struct {
|
||||||
long long n_value_i;
|
struct mie_value *v;
|
||||||
|
long long i;
|
||||||
|
void *p;
|
||||||
|
} n_value;
|
||||||
|
|
||||||
/* queue entry, links to mie_select_graph.g_nodes */
|
/* queue entry, links to mie_select_graph.g_nodes */
|
||||||
b_queue_entry n_entry;
|
b_queue_entry n_entry;
|
||||||
@@ -84,6 +89,13 @@ MIE_API void mie_select_node_get_users(
|
|||||||
MIE_API void mie_select_node_get_uses(
|
MIE_API void mie_select_node_get_uses(
|
||||||
struct mie_select_node *node, struct mie_select_node_iterator *it);
|
struct mie_select_node *node, struct mie_select_node_iterator *it);
|
||||||
|
|
||||||
|
MIE_API enum mie_status mie_select_node_get_value(
|
||||||
|
struct mie_select_node *node, struct mie_type *type, size_t index,
|
||||||
|
struct mie_select_value *out);
|
||||||
|
|
||||||
|
MIE_API enum mie_status mie_select_node_set_description(
|
||||||
|
struct mie_select_node *node, const char *format, ...);
|
||||||
|
|
||||||
MIE_API struct mie_select_node *mie_select_node_get_glued_node(
|
MIE_API struct mie_select_node *mie_select_node_get_glued_node(
|
||||||
struct mie_select_node *node);
|
struct mie_select_node *node);
|
||||||
MIE_API struct mie_select_node *mie_select_node_get_glued_user(
|
MIE_API struct mie_select_node *mie_select_node_get_glued_user(
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ enum mie_select_opcode {
|
|||||||
MIE_SELECT_OP_COPY_FROM_REG,
|
MIE_SELECT_OP_COPY_FROM_REG,
|
||||||
MIE_SELECT_OP_COPY_TO_REG,
|
MIE_SELECT_OP_COPY_TO_REG,
|
||||||
MIE_SELECT_OP_GLOBAL_ADDRESS,
|
MIE_SELECT_OP_GLOBAL_ADDRESS,
|
||||||
|
MIE_SELECT_OP_CHAIN_GROUP,
|
||||||
MIE_SELECT_OP_LOAD,
|
MIE_SELECT_OP_LOAD,
|
||||||
MIE_SELECT_OP_STORE,
|
MIE_SELECT_OP_STORE,
|
||||||
MIE_SELECT_OP_ADD,
|
MIE_SELECT_OP_ADD,
|
||||||
|
|||||||
@@ -13,19 +13,23 @@ static enum mie_status push(
|
|||||||
|
|
||||||
struct mie_type *ptr_type = mie_ctx_get_type(
|
struct mie_type *ptr_type = mie_ctx_get_type(
|
||||||
mie_select_builder_get_ctx(builder), MIE_TYPE_PTR);
|
mie_select_builder_get_ctx(builder), MIE_TYPE_PTR);
|
||||||
struct mie_select_value frame_index;
|
struct mie_select_node *frame_index;
|
||||||
enum mie_status status = mie_select_graph_get_node(
|
enum mie_status status = mie_select_graph_get_node(
|
||||||
graph, MIE_SELECT_OP_FRAME_INDEX, NULL, 0, &ptr_type, 1,
|
graph, mie_target_builtin(), MIE_SELECT_OP_FRAME_INDEX, NULL, 0,
|
||||||
&frame_index);
|
&ptr_type, 1, &frame_index);
|
||||||
|
|
||||||
if (status != MIE_SUCCESS) {
|
if (status != MIE_SUCCESS) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
frame_index.v_node->n_flags = MIE_SELECT_NODE_F_IVALUE;
|
frame_index->n_flags = MIE_SELECT_NODE_F_IVALUE;
|
||||||
frame_index.v_node->n_value_i = graph->g_frame_index++;
|
frame_index->n_value.i = graph->g_frame_index++;
|
||||||
|
|
||||||
return select_builder_set_value(builder, MIE_VALUE(instr), &frame_index);
|
struct mie_select_value frame_index_value;
|
||||||
|
mie_select_node_get_value(frame_index, ptr_type, 0, &frame_index_value);
|
||||||
|
|
||||||
|
return mie_select_builder_set_value(
|
||||||
|
builder, MIE_VALUE(instr), &frame_index_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct select_instr_type select_alloca = {
|
struct select_instr_type select_alloca = {
|
||||||
|
|||||||
@@ -22,8 +22,8 @@ static enum mie_status push_op(
|
|||||||
struct mie_binary_op *op = (struct mie_binary_op *)instr;
|
struct mie_binary_op *op = (struct mie_binary_op *)instr;
|
||||||
|
|
||||||
struct mie_select_value *operands[] = {
|
struct mie_select_value *operands[] = {
|
||||||
select_builder_get_value(builder, op->op_left),
|
mie_select_builder_get_value(builder, op->op_left),
|
||||||
select_builder_get_value(builder, op->op_right),
|
mie_select_builder_get_value(builder, op->op_right),
|
||||||
};
|
};
|
||||||
size_t nr_operands = sizeof operands / sizeof operands[0];
|
size_t nr_operands = sizeof operands / sizeof operands[0];
|
||||||
|
|
||||||
@@ -32,15 +32,18 @@ static enum mie_status push_op(
|
|||||||
};
|
};
|
||||||
size_t nr_results = sizeof result / sizeof result[0];
|
size_t nr_results = sizeof result / sizeof result[0];
|
||||||
|
|
||||||
struct mie_select_value node = {0};
|
struct mie_select_node *node;
|
||||||
enum mie_status status = mie_select_graph_get_node(
|
enum mie_status status = mie_select_graph_get_node(
|
||||||
mie_select_builder_get_graph(builder), opcode, operands,
|
mie_select_builder_get_graph(builder), mie_target_builtin(),
|
||||||
nr_operands, result, nr_results, &node);
|
opcode, operands, nr_operands, result, nr_results, &node);
|
||||||
if (status != MIE_SUCCESS) {
|
if (status != MIE_SUCCESS) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
return select_builder_set_value(builder, MIE_VALUE(instr), &node);
|
struct mie_select_value value;
|
||||||
|
mie_select_node_get_value(node, op->op_type, 0, &value);
|
||||||
|
|
||||||
|
return mie_select_builder_set_value(builder, MIE_VALUE(instr), &value);
|
||||||
}
|
}
|
||||||
|
|
||||||
DEFINE_PUSH_FUNCTION(add, MIE_SELECT_OP_ADD);
|
DEFINE_PUSH_FUNCTION(add, MIE_SELECT_OP_ADD);
|
||||||
|
|||||||
@@ -8,12 +8,14 @@
|
|||||||
#include <mie/select/builder.h>
|
#include <mie/select/builder.h>
|
||||||
#include <mie/select/graph.h>
|
#include <mie/select/graph.h>
|
||||||
#include <mie/select/node.h>
|
#include <mie/select/node.h>
|
||||||
|
#include <mie/target/target.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
struct mie_select_builder {
|
struct mie_select_builder {
|
||||||
struct mie_ctx *b_ctx;
|
struct mie_ctx *b_ctx;
|
||||||
struct mie_select_graph *b_graph;
|
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
|
/* map of mie_instr* to mie_select_value*, defining the graph node that
|
||||||
* corresponds to each value-producing instruction */
|
* corresponds to each value-producing instruction */
|
||||||
b_hashmap *b_nodes;
|
b_hashmap *b_nodes;
|
||||||
@@ -22,7 +24,8 @@ struct mie_select_builder {
|
|||||||
b_hashmap *b_mem_access;
|
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);
|
struct mie_select_builder *out = malloc(sizeof *out);
|
||||||
if (!out) {
|
if (!out) {
|
||||||
@@ -32,6 +35,7 @@ struct mie_select_builder *mie_select_builder_create(struct mie_ctx *ctx)
|
|||||||
memset(out, 0x0, sizeof *out);
|
memset(out, 0x0, sizeof *out);
|
||||||
|
|
||||||
out->b_ctx = ctx;
|
out->b_ctx = ctx;
|
||||||
|
out->b_target = target;
|
||||||
out->b_graph = mie_select_graph_create(ctx);
|
out->b_graph = mie_select_graph_create(ctx);
|
||||||
if (!out->b_graph) {
|
if (!out->b_graph) {
|
||||||
free(out);
|
free(out);
|
||||||
@@ -66,7 +70,10 @@ void mie_select_builder_destroy(struct mie_select_builder *builder)
|
|||||||
b_hashmap_release(builder->b_mem_access);
|
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);
|
free(builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,6 +88,12 @@ struct mie_ctx *mie_select_builder_get_ctx(struct mie_select_builder *builder)
|
|||||||
return builder->b_ctx;
|
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)
|
static void clear_node_map(struct mie_select_builder *builder)
|
||||||
{
|
{
|
||||||
b_hashmap_iterator it;
|
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(
|
status = mie_select_graph_get_node(
|
||||||
graph, MIE_SELECT_OP_ROOT, root_operands, nr_root_operands,
|
graph, mie_target_builtin(), MIE_SELECT_OP_ROOT, root_operands,
|
||||||
NULL, 0, &graph->g_root);
|
nr_root_operands, NULL, 0, &graph->g_root);
|
||||||
|
|
||||||
if (status != MIE_SUCCESS) {
|
if (status != MIE_SUCCESS) {
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -121,6 +134,53 @@ struct mie_select_graph *mie_select_builder_finish(struct mie_select_builder *bu
|
|||||||
return graph;
|
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(
|
enum mie_status mie_select_builder_push_instr(
|
||||||
struct mie_select_builder *builder, struct mie_instr *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_select_value *out)
|
||||||
{
|
{
|
||||||
struct mie_const *c = (struct mie_const *)ir_val;
|
struct mie_const *c = (struct mie_const *)ir_val;
|
||||||
|
struct mie_select_node *node;
|
||||||
enum mie_status status = mie_select_graph_get_node(
|
enum mie_status status = mie_select_graph_get_node(
|
||||||
builder->b_graph, MIE_SELECT_OP_CONSTANT, NULL, 0, &c->c_type,
|
builder->b_graph, mie_target_builtin(), MIE_SELECT_OP_CONSTANT,
|
||||||
1, out);
|
NULL, 0, &c->c_type, 1, &node);
|
||||||
if (status != MIE_SUCCESS) {
|
if (status != MIE_SUCCESS) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
out->v_node->n_flags = MIE_SELECT_NODE_F_PVALUE;
|
node->n_flags = MIE_SELECT_NODE_F_PVALUE;
|
||||||
out->v_node->n_value_p = ir_val;
|
node->n_value.v = ir_val;
|
||||||
|
|
||||||
|
mie_select_node_get_value(node, c->c_type, 0, out);
|
||||||
|
|
||||||
return MIE_SUCCESS;
|
return MIE_SUCCESS;
|
||||||
}
|
}
|
||||||
@@ -168,19 +231,23 @@ static enum mie_status get_data_node(
|
|||||||
return MIE_ERR_INVALID_VALUE;
|
return MIE_ERR_INVALID_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct mie_select_node *node;
|
||||||
enum mie_status status = mie_select_graph_get_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) {
|
if (status != MIE_SUCCESS) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
out->v_node->n_flags = MIE_SELECT_NODE_F_PVALUE;
|
node->n_flags = MIE_SELECT_NODE_F_PVALUE;
|
||||||
out->v_node->n_value_p = ir_val;
|
node->n_value.v = ir_val;
|
||||||
|
|
||||||
|
mie_select_node_get_value(node, type, 0, out);
|
||||||
|
|
||||||
return MIE_SUCCESS;
|
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)
|
struct mie_select_builder *builder, struct mie_value *ir_val)
|
||||||
{
|
{
|
||||||
b_hashmap_key key = {
|
b_hashmap_key key = {
|
||||||
@@ -228,7 +295,7 @@ struct mie_select_value *select_builder_get_value(
|
|||||||
return select_val;
|
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_builder *builder, struct mie_value *ir_val,
|
||||||
struct mie_select_value *graph_val)
|
struct mie_select_value *graph_val)
|
||||||
{
|
{
|
||||||
@@ -254,7 +321,7 @@ enum mie_status select_builder_set_value(
|
|||||||
return MIE_SUCCESS;
|
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)
|
struct mie_select_builder *builder, struct mie_value *ir_val)
|
||||||
{
|
{
|
||||||
b_hashmap_key key = {
|
b_hashmap_key key = {
|
||||||
@@ -271,7 +338,7 @@ struct mie_select_value *select_builder_get_mem_access(
|
|||||||
return NULL;
|
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_builder *builder, struct mie_value *ir_val,
|
||||||
struct mie_select_value *graph_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);
|
b_hashmap_put(builder->b_mem_access, &key, &hashmap_val);
|
||||||
return MIE_SUCCESS;
|
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;
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
#include <mie/ir/instr.h>
|
#include <mie/ir/instr.h>
|
||||||
#include <mie/select/builder.h>
|
#include <mie/select/builder.h>
|
||||||
|
#include <mie/select/node.h>
|
||||||
#include <mie/select/opcode.h>
|
#include <mie/select/opcode.h>
|
||||||
#include <mie/status.h>
|
#include <mie/status.h>
|
||||||
|
|
||||||
@@ -21,16 +22,4 @@ extern const struct select_instr_type *select_type_for_instr(
|
|||||||
extern const struct select_node_type *select_type_for_node(
|
extern const struct select_node_type *select_type_for_node(
|
||||||
enum mie_select_opcode node);
|
enum mie_select_opcode node);
|
||||||
|
|
||||||
extern struct mie_select_value *select_builder_get_value(
|
|
||||||
struct mie_select_builder *builder, struct mie_value *ir_val);
|
|
||||||
extern enum mie_status select_builder_set_value(
|
|
||||||
struct mie_select_builder *builder, struct mie_value *ir_val,
|
|
||||||
struct mie_select_value *graph_val);
|
|
||||||
|
|
||||||
extern struct mie_select_value *select_builder_get_mem_access(
|
|
||||||
struct mie_select_builder *builder, struct mie_value *ir_val);
|
|
||||||
extern enum mie_status select_builder_set_mem_access(
|
|
||||||
struct mie_select_builder *builder, struct mie_value *ir_val,
|
|
||||||
struct mie_select_value *graph_val);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -103,12 +103,16 @@ static void node_dump_text(struct mie_select_node *node)
|
|||||||
mie_target_select_node_name(node->n_target, node->n_opcode, tmp, sizeof tmp);
|
mie_target_select_node_name(node->n_target, node->n_opcode, tmp, sizeof tmp);
|
||||||
printf("%s", tmp);
|
printf("%s", tmp);
|
||||||
|
|
||||||
|
if (node->n_description) {
|
||||||
|
printf(" %s", node->n_description);
|
||||||
|
}
|
||||||
|
|
||||||
if (node->n_flags & (MIE_SELECT_NODE_F_IVALUE | MIE_SELECT_NODE_F_PVALUE)) {
|
if (node->n_flags & (MIE_SELECT_NODE_F_IVALUE | MIE_SELECT_NODE_F_PVALUE)) {
|
||||||
printf("<");
|
printf("<");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node->n_flags & MIE_SELECT_NODE_F_IVALUE) {
|
if (node->n_flags & MIE_SELECT_NODE_F_IVALUE) {
|
||||||
printf("%lld", node->n_value_i);
|
printf("%lld", node->n_value.i);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((node->n_flags & MIE_SELECT_NODE_F_IVALUE)
|
if ((node->n_flags & MIE_SELECT_NODE_F_IVALUE)
|
||||||
@@ -117,7 +121,7 @@ static void node_dump_text(struct mie_select_node *node)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (node->n_flags & MIE_SELECT_NODE_F_PVALUE) {
|
if (node->n_flags & MIE_SELECT_NODE_F_PVALUE) {
|
||||||
write_operand(node->n_value_p, b_stdout);
|
write_operand(node->n_value.v, b_stdout);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node->n_flags & (MIE_SELECT_NODE_F_IVALUE | MIE_SELECT_NODE_F_PVALUE)) {
|
if (node->n_flags & (MIE_SELECT_NODE_F_IVALUE | MIE_SELECT_NODE_F_PVALUE)) {
|
||||||
@@ -168,12 +172,16 @@ static void node_dump_dot(struct mie_select_node *node, b_stream *out)
|
|||||||
mie_target_select_node_name(node->n_target, node->n_opcode, tmp, sizeof tmp);
|
mie_target_select_node_name(node->n_target, node->n_opcode, tmp, sizeof tmp);
|
||||||
b_stream_write_fmt(out, NULL, "<Name> %s", tmp);
|
b_stream_write_fmt(out, NULL, "<Name> %s", tmp);
|
||||||
|
|
||||||
|
if (node->n_description) {
|
||||||
|
b_stream_write_fmt(out, NULL, " %s", node->n_description);
|
||||||
|
}
|
||||||
|
|
||||||
if (node->n_flags & (MIE_SELECT_NODE_F_IVALUE | MIE_SELECT_NODE_F_PVALUE)) {
|
if (node->n_flags & (MIE_SELECT_NODE_F_IVALUE | MIE_SELECT_NODE_F_PVALUE)) {
|
||||||
b_stream_write_string(out, "\\<", NULL);
|
b_stream_write_string(out, "\\<", NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node->n_flags & MIE_SELECT_NODE_F_IVALUE) {
|
if (node->n_flags & MIE_SELECT_NODE_F_IVALUE) {
|
||||||
b_stream_write_fmt(out, NULL, "%lld", node->n_value_i);
|
b_stream_write_fmt(out, NULL, "%lld", node->n_value.i);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((node->n_flags & MIE_SELECT_NODE_F_IVALUE)
|
if ((node->n_flags & MIE_SELECT_NODE_F_IVALUE)
|
||||||
@@ -182,7 +190,7 @@ static void node_dump_dot(struct mie_select_node *node, b_stream *out)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (node->n_flags & MIE_SELECT_NODE_F_PVALUE) {
|
if (node->n_flags & MIE_SELECT_NODE_F_PVALUE) {
|
||||||
write_operand(node->n_value_p, out);
|
write_operand(node->n_value.v, out);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node->n_flags & (MIE_SELECT_NODE_F_IVALUE | MIE_SELECT_NODE_F_PVALUE)) {
|
if (node->n_flags & (MIE_SELECT_NODE_F_IVALUE | MIE_SELECT_NODE_F_PVALUE)) {
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ struct mie_select_graph *mie_select_graph_create(struct mie_ctx *ctx)
|
|||||||
memset(out, 0x0, sizeof *out);
|
memset(out, 0x0, sizeof *out);
|
||||||
|
|
||||||
enum mie_status status = MIE_SUCCESS;
|
enum mie_status status = MIE_SUCCESS;
|
||||||
struct mie_select_value entry;
|
struct mie_select_node *entry;
|
||||||
|
|
||||||
struct mie_type *entry_values[] = {
|
struct mie_type *entry_values[] = {
|
||||||
mie_ctx_get_type(ctx, MIE_TYPE_OTHER),
|
mie_ctx_get_type(ctx, MIE_TYPE_OTHER),
|
||||||
@@ -28,14 +28,14 @@ struct mie_select_graph *mie_select_graph_create(struct mie_ctx *ctx)
|
|||||||
= sizeof entry_values / sizeof entry_values[0];
|
= sizeof entry_values / sizeof entry_values[0];
|
||||||
|
|
||||||
status = mie_select_graph_get_node(
|
status = mie_select_graph_get_node(
|
||||||
out, MIE_SELECT_OP_ENTRY, NULL, 0, entry_values,
|
out, mie_target_builtin(), MIE_SELECT_OP_ENTRY, NULL, 0,
|
||||||
nr_entry_values, &entry);
|
entry_values, nr_entry_values, &entry);
|
||||||
if (status != MIE_SUCCESS) {
|
if (status != MIE_SUCCESS) {
|
||||||
free(out);
|
free(out);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
out->g_entry.v_node = entry.v_node;
|
mie_select_node_get_value(entry, entry_values[0], 0, &out->g_entry);
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
@@ -62,9 +62,9 @@ void mie_select_graph_destroy(struct mie_select_graph *graph)
|
|||||||
}
|
}
|
||||||
|
|
||||||
enum mie_status mie_select_graph_get_node(
|
enum mie_status mie_select_graph_get_node(
|
||||||
struct mie_select_graph *graph, unsigned int op,
|
struct mie_select_graph *graph, const struct mie_target *target,
|
||||||
struct mie_select_value **operands, size_t nr_operands,
|
unsigned int op, struct mie_select_value **operands, size_t nr_operands,
|
||||||
struct mie_type **values, size_t nr_values, struct mie_select_value *out)
|
struct mie_type **values, size_t nr_values, struct mie_select_node **out)
|
||||||
{
|
{
|
||||||
struct mie_select_node *node = mie_select_node_create(
|
struct mie_select_node *node = mie_select_node_create(
|
||||||
mie_target_builtin(), op, values, nr_values);
|
mie_target_builtin(), op, values, nr_values);
|
||||||
@@ -83,6 +83,7 @@ enum mie_status mie_select_graph_get_node(
|
|||||||
free(operands2);
|
free(operands2);
|
||||||
|
|
||||||
node->n_id = graph->g_node_id++;
|
node->n_id = graph->g_node_id++;
|
||||||
|
node->n_target = target;
|
||||||
|
|
||||||
for (size_t i = 0; i < nr_values; i++) {
|
for (size_t i = 0; i < nr_values; i++) {
|
||||||
if (values[i]->t_id == MIE_TYPE_OTHER) {
|
if (values[i]->t_id == MIE_TYPE_OTHER) {
|
||||||
@@ -93,8 +94,7 @@ enum mie_status mie_select_graph_get_node(
|
|||||||
|
|
||||||
b_queue_push_back(&graph->g_nodes, &node->n_entry);
|
b_queue_push_back(&graph->g_nodes, &node->n_entry);
|
||||||
|
|
||||||
out->v_node = node;
|
*out = node;
|
||||||
out->v_index = 0;
|
|
||||||
|
|
||||||
return MIE_SUCCESS;
|
return MIE_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,12 +13,13 @@ DECLARE_INSTR_TYPE(mul);
|
|||||||
DECLARE_INSTR_TYPE(div);
|
DECLARE_INSTR_TYPE(div);
|
||||||
DECLARE_INSTR_TYPE(load);
|
DECLARE_INSTR_TYPE(load);
|
||||||
DECLARE_INSTR_TYPE(store);
|
DECLARE_INSTR_TYPE(store);
|
||||||
|
DECLARE_INSTR_TYPE(msg);
|
||||||
|
|
||||||
static const struct select_instr_type *instr_types[] = {
|
static const struct select_instr_type *instr_types[] = {
|
||||||
INSTR_TYPE_ENTRY(ALLOCA, alloca), INSTR_TYPE_ENTRY(ADD, add),
|
INSTR_TYPE_ENTRY(ALLOCA, alloca), INSTR_TYPE_ENTRY(ADD, add),
|
||||||
INSTR_TYPE_ENTRY(SUB, sub), INSTR_TYPE_ENTRY(MUL, mul),
|
INSTR_TYPE_ENTRY(SUB, sub), INSTR_TYPE_ENTRY(MUL, mul),
|
||||||
INSTR_TYPE_ENTRY(DIV, div), INSTR_TYPE_ENTRY(LOAD, load),
|
INSTR_TYPE_ENTRY(DIV, div), INSTR_TYPE_ENTRY(LOAD, load),
|
||||||
INSTR_TYPE_ENTRY(STORE, store),
|
INSTR_TYPE_ENTRY(STORE, store), INSTR_TYPE_ENTRY(MSG, msg),
|
||||||
};
|
};
|
||||||
static const size_t nr_instr_types = sizeof instr_types / sizeof instr_types[0];
|
static const size_t nr_instr_types = sizeof instr_types / sizeof instr_types[0];
|
||||||
|
|
||||||
|
|||||||
23
mie/select/msg.c
Normal file
23
mie/select/msg.c
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
#include "builder.h"
|
||||||
|
|
||||||
|
#include <mie/ctx.h>
|
||||||
|
#include <mie/ir/ptr.h>
|
||||||
|
#include <mie/select/graph.h>
|
||||||
|
#include <mie/target/select.h>
|
||||||
|
|
||||||
|
static enum mie_status push(
|
||||||
|
struct mie_select_builder *builder, struct mie_instr *instr)
|
||||||
|
{
|
||||||
|
const struct mie_target *target = mie_select_builder_get_target(builder);
|
||||||
|
struct mie_msg *msg = (struct mie_msg *)instr;
|
||||||
|
|
||||||
|
struct mie_select_value result;
|
||||||
|
enum mie_status status
|
||||||
|
= mie_target_select_lower_msg(target, builder, msg, &result);
|
||||||
|
|
||||||
|
return mie_select_builder_set_value(builder, MIE_VALUE(instr), &result);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct select_instr_type select_msg = {
|
||||||
|
.i_push = push,
|
||||||
|
};
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
#include "builder.h"
|
#include "builder.h"
|
||||||
|
|
||||||
|
#include <blue/core/stringstream.h>
|
||||||
#include <mie/select/graph.h>
|
#include <mie/select/graph.h>
|
||||||
#include <mie/select/node.h>
|
#include <mie/select/node.h>
|
||||||
#include <mie/select/opcode.h>
|
#include <mie/select/opcode.h>
|
||||||
@@ -129,6 +130,43 @@ void mie_select_node_get_uses(
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum mie_status mie_select_node_get_value(
|
||||||
|
struct mie_select_node *node, struct mie_type *type, size_t index,
|
||||||
|
struct mie_select_value *out)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < node->n_nr_results; i++) {
|
||||||
|
if (!mie_type_compare(node->n_results[i], type)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (index > 0) {
|
||||||
|
index--;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
out->v_node = node;
|
||||||
|
out->v_index = i;
|
||||||
|
return MIE_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(out, 0x0, sizeof *out);
|
||||||
|
return MIE_ERR_NO_ENTRY;
|
||||||
|
}
|
||||||
|
|
||||||
|
enum mie_status mie_select_node_set_description(
|
||||||
|
struct mie_select_node *node, const char *format, ...)
|
||||||
|
{
|
||||||
|
va_list arg;
|
||||||
|
va_start(arg, format);
|
||||||
|
b_stringstream str;
|
||||||
|
b_stringstream_begin_dynamic(&str);
|
||||||
|
b_stringstream_addvf(&str, format, arg);
|
||||||
|
va_end(arg);
|
||||||
|
|
||||||
|
node->n_description = b_stringstream_end(&str);
|
||||||
|
return node->n_description ? MIE_SUCCESS : MIE_ERR_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
struct mie_select_node *mie_select_node_get_glued_node(struct mie_select_node *node)
|
struct mie_select_node *mie_select_node_get_glued_node(struct mie_select_node *node)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|||||||
@@ -9,35 +9,42 @@ static enum mie_status push_load(
|
|||||||
{
|
{
|
||||||
struct mie_select_graph *graph = mie_select_builder_get_graph(builder);
|
struct mie_select_graph *graph = mie_select_builder_get_graph(builder);
|
||||||
struct mie_load *load = (struct mie_load *)instr;
|
struct mie_load *load = (struct mie_load *)instr;
|
||||||
|
struct mie_type *chain_type = mie_ctx_get_type(
|
||||||
|
mie_select_builder_get_ctx(builder), MIE_TYPE_OTHER);
|
||||||
|
|
||||||
struct mie_select_value *chain
|
struct mie_select_value *chain
|
||||||
= select_builder_get_mem_access(builder, load->l_src);
|
= mie_select_builder_get_mem_access(builder, load->l_src);
|
||||||
if (!chain) {
|
if (!chain) {
|
||||||
chain = &graph->g_entry;
|
chain = &graph->g_entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct mie_select_value *operands[] = {
|
struct mie_select_value *operands[] = {
|
||||||
chain,
|
chain,
|
||||||
select_builder_get_value(builder, load->l_src),
|
mie_select_builder_get_value(builder, load->l_src),
|
||||||
};
|
};
|
||||||
size_t nr_operands = sizeof operands / sizeof operands[0];
|
size_t nr_operands = sizeof operands / sizeof operands[0];
|
||||||
|
|
||||||
struct mie_type *result[] = {
|
struct mie_type *result[] = {
|
||||||
load->l_type,
|
load->l_type,
|
||||||
mie_ctx_get_type(mie_select_builder_get_ctx(builder), MIE_TYPE_OTHER),
|
chain_type,
|
||||||
};
|
};
|
||||||
size_t nr_results = sizeof result / sizeof result[0];
|
size_t nr_results = sizeof result / sizeof result[0];
|
||||||
|
|
||||||
struct mie_select_value node = {0};
|
struct mie_select_node *node;
|
||||||
enum mie_status status = mie_select_graph_get_node(
|
enum mie_status status = mie_select_graph_get_node(
|
||||||
graph, MIE_SELECT_OP_LOAD, operands, nr_operands, result,
|
graph, mie_target_builtin(), MIE_SELECT_OP_LOAD, operands,
|
||||||
nr_results, &node);
|
nr_operands, result, nr_results, &node);
|
||||||
if (status != MIE_SUCCESS) {
|
if (status != MIE_SUCCESS) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
select_builder_set_mem_access(builder, load->l_src, &node);
|
struct mie_select_value value_result, chain_result;
|
||||||
return select_builder_set_value(builder, MIE_VALUE(instr), &node);
|
mie_select_node_get_value(node, load->l_type, 0, &value_result);
|
||||||
|
mie_select_node_get_value(node, chain_type, 0, &chain_result);
|
||||||
|
|
||||||
|
mie_select_builder_set_mem_access(builder, load->l_src, &chain_result);
|
||||||
|
return mie_select_builder_set_value(
|
||||||
|
builder, MIE_VALUE(instr), &value_result);
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum mie_status push_store(
|
static enum mie_status push_store(
|
||||||
@@ -47,15 +54,15 @@ static enum mie_status push_store(
|
|||||||
struct mie_select_graph *graph = mie_select_builder_get_graph(builder);
|
struct mie_select_graph *graph = mie_select_builder_get_graph(builder);
|
||||||
|
|
||||||
struct mie_select_value *chain
|
struct mie_select_value *chain
|
||||||
= select_builder_get_mem_access(builder, store->s_dest);
|
= mie_select_builder_get_mem_access(builder, store->s_dest);
|
||||||
if (!chain) {
|
if (!chain) {
|
||||||
chain = &graph->g_entry;
|
chain = &graph->g_entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct mie_select_value *operands[] = {
|
struct mie_select_value *operands[] = {
|
||||||
chain,
|
chain,
|
||||||
select_builder_get_value(builder, store->s_val),
|
mie_select_builder_get_value(builder, store->s_val),
|
||||||
select_builder_get_value(builder, store->s_dest),
|
mie_select_builder_get_value(builder, store->s_dest),
|
||||||
};
|
};
|
||||||
size_t nr_operands = sizeof operands / sizeof operands[0];
|
size_t nr_operands = sizeof operands / sizeof operands[0];
|
||||||
|
|
||||||
@@ -64,16 +71,19 @@ static enum mie_status push_store(
|
|||||||
};
|
};
|
||||||
size_t nr_results = sizeof result / sizeof result[0];
|
size_t nr_results = sizeof result / sizeof result[0];
|
||||||
|
|
||||||
struct mie_select_value node = {0};
|
struct mie_select_node *node;
|
||||||
enum mie_status status = mie_select_graph_get_node(
|
enum mie_status status = mie_select_graph_get_node(
|
||||||
graph, MIE_SELECT_OP_STORE, operands, nr_operands, result,
|
graph, mie_target_builtin(), MIE_SELECT_OP_STORE, operands,
|
||||||
nr_results, &node);
|
nr_operands, result, nr_results, &node);
|
||||||
if (status != MIE_SUCCESS) {
|
if (status != MIE_SUCCESS) {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
select_builder_set_mem_access(builder, store->s_dest, &node);
|
struct mie_select_value value;
|
||||||
return select_builder_set_value(builder, MIE_VALUE(instr), &node);
|
mie_select_node_get_value(node, result[0], 0, &value);
|
||||||
|
|
||||||
|
mie_select_builder_set_mem_access(builder, store->s_dest, &value);
|
||||||
|
return mie_select_builder_set_value(builder, MIE_VALUE(instr), &value);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct select_instr_type select_load = {
|
struct select_instr_type select_load = {
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ static size_t node_name(
|
|||||||
NODE_NAME(COPY_FROM_REG, "CopyFromReg");
|
NODE_NAME(COPY_FROM_REG, "CopyFromReg");
|
||||||
NODE_NAME(COPY_TO_REG, "CopyToReg");
|
NODE_NAME(COPY_TO_REG, "CopyToReg");
|
||||||
NODE_NAME(GLOBAL_ADDRESS, "GlobalAddress");
|
NODE_NAME(GLOBAL_ADDRESS, "GlobalAddress");
|
||||||
|
NODE_NAME(CHAIN_GROUP, "ChainGroup");
|
||||||
NODE_NAME(LOAD, "Load");
|
NODE_NAME(LOAD, "Load");
|
||||||
NODE_NAME(STORE, "Store");
|
NODE_NAME(STORE, "Store");
|
||||||
NODE_NAME(ADD, "Add");
|
NODE_NAME(ADD, "Add");
|
||||||
|
|||||||
Reference in New Issue
Block a user