From 32a520e21020844412182fd5b3547157c1c592ef Mon Sep 17 00:00:00 2001 From: Max Wash Date: Mon, 8 Sep 2025 15:34:58 +0100 Subject: [PATCH] mie: ir: implement generation and text output of phi instruction --- mie/include/mie/ir/builder.h | 5 ++-- mie/include/mie/ir/phi.h | 8 ++++++- mie/ir/builder.c | 45 +++++++++++++++++++++++++++++++++--- mie/ir/convert/text-write.c | 24 ++++++++++++++++--- mie/ir/instr.c | 5 ++++ mie/ir/phi.c | 19 +++++++++++++++ 6 files changed, 97 insertions(+), 9 deletions(-) create mode 100644 mie/ir/phi.c diff --git a/mie/include/mie/ir/builder.h b/mie/include/mie/ir/builder.h index a45986b..ccec2dd 100644 --- a/mie/include/mie/ir/builder.h +++ b/mie/include/mie/ir/builder.h @@ -14,6 +14,7 @@ struct mie_module; struct mie_data; struct mie_type; struct mie_phi; +struct mie_phi_edge; struct mie_ctx; struct mie_builder { @@ -111,8 +112,8 @@ extern struct mie_value *mie_builder_getelementptr( extern struct mie_value *mie_builder_setelementptr( struct mie_builder *builder, struct mie_type *container_type, struct mie_value *container, struct mie_value *index); -extern struct mie_phi *mie_builder_phi( +extern struct mie_value *mie_builder_phi( struct mie_builder *builder, struct mie_type *type, - unsigned int nr_edges, const char *name); + struct mie_phi_edge *edges, unsigned int nr_edges, const char *name); #endif diff --git a/mie/include/mie/ir/phi.h b/mie/include/mie/ir/phi.h index bea4870..eae09d3 100644 --- a/mie/include/mie/ir/phi.h +++ b/mie/include/mie/ir/phi.h @@ -1,9 +1,12 @@ #ifndef MIE_PHI_H_ #define MIE_PHI_H_ -#include +#include +#include +#include struct mie_phi_edge { + b_queue_entry e_entry; struct mie_block *e_incoming_block; struct mie_value *e_value; }; @@ -16,4 +19,7 @@ struct mie_phi { struct mie_phi_edge *p_edges; }; +MIE_API struct mie_phi_edge *mie_phi_edge_create( + struct mie_block *incoming_block, struct mie_value *value); + #endif diff --git a/mie/ir/builder.c b/mie/ir/builder.c index 3de017c..241ddff 100644 --- a/mie/ir/builder.c +++ b/mie/ir/builder.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -785,9 +786,47 @@ struct mie_value *mie_builder_setelementptr( return NULL; } -struct mie_phi *mie_builder_phi( +struct mie_value *mie_builder_phi( struct mie_builder *builder, struct mie_type *type, - unsigned int nr_edges, const char *name) + struct mie_phi_edge *edges, unsigned int nr_edges, const char *name) { - return NULL; + struct mie_block *block = builder->b_current_block; + + if (!block) { + return NULL; + } + + if (block->b_terminator || !b_queue_empty(&block->b_instr)) { + return NULL; + } + + struct mie_phi *phi = malloc(sizeof *phi); + if (!phi) { + return NULL; + } + + memset(phi, 0x0, sizeof *phi); + + mie_instr_init(&phi->p_base, MIE_INSTR_PHI); + + phi->p_type = type; + phi->p_nr_edges = nr_edges; + phi->p_edges = calloc(nr_edges, sizeof(struct mie_phi_edge)); + if (!phi->p_edges) { + free(phi); + return NULL; + } + + memcpy(phi->p_edges, edges, nr_edges * sizeof(struct mie_phi_edge)); + + if (!mie_block_add_instr(builder->b_current_block, &phi->p_base)) { + free(phi); + free(phi->p_edges); + return NULL; + } + + mie_func_generate_value_name( + builder->b_current_block->b_parent, MIE_VALUE(phi), name); + + return MIE_VALUE(phi); } diff --git a/mie/ir/convert/text-write.c b/mie/ir/convert/text-write.c index e48783d..420422d 100644 --- a/mie/ir/convert/text-write.c +++ b/mie/ir/convert/text-write.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -138,7 +139,7 @@ static b_status write_operand_const( case MIE_TYPE_SELECTOR: { struct mie_selector *v = MIE_SELECTOR(c); - write_string_f(converter, "\"%s\"", v->sel_value); + write_string_f(converter, "@%s", v->sel_value); break; } case MIE_TYPE_CLASS: @@ -648,9 +649,26 @@ static b_status write_instr( case MIE_INSTR_SETELEMENTPTR: write_string(converter, "setelementptr"); break; - case MIE_INSTR_PHI: - write_string(converter, "phi"); + case MIE_INSTR_PHI: { + struct mie_phi *phi = (struct mie_phi *)instr; + mie_type_to_string(phi->p_type, type, sizeof type); + write_string_f(converter, "phi %s ", type); + + for (size_t i = 0; i < phi->p_nr_edges; i++) { + if (i > 0) { + write_string(converter, ", "); + } + + write_string(converter, "[ "); + write_operand( + converter, + MIE_VALUE(phi->p_edges[i].e_incoming_block), 0); + write_string(converter, ", "); + write_operand(converter, phi->p_edges[i].e_value, 0); + write_string(converter, " ]"); + } break; + } default: write_string_f(converter, ""); break; diff --git a/mie/ir/instr.c b/mie/ir/instr.c index df8fe71..98cf409 100644 --- a/mie/ir/instr.c +++ b/mie/ir/instr.c @@ -2,6 +2,7 @@ #include #include #include +#include #include void mie_instr_init(struct mie_instr *instr, enum mie_instr_type type) @@ -44,6 +45,10 @@ static struct mie_type *get_type(struct mie_value *v, struct mie_ctx *ctx) struct mie_msg *msg = (struct mie_msg *)instr; return msg->msg_ret_type; } + case MIE_INSTR_PHI: { + struct mie_phi *phi = (struct mie_phi *)instr; + return phi->p_type; + } default: return NULL; } diff --git a/mie/ir/phi.c b/mie/ir/phi.c new file mode 100644 index 0000000..0a6efe9 --- /dev/null +++ b/mie/ir/phi.c @@ -0,0 +1,19 @@ +#include +#include +#include + +struct mie_phi_edge *mie_phi_edge_create( + struct mie_block *incoming_block, struct mie_value *value) +{ + struct mie_phi_edge *out = malloc(sizeof *out); + if (!out) { + return NULL; + } + + memset(out, 0x0, sizeof *out); + + out->e_incoming_block = incoming_block; + out->e_value = value; + + return out; +}