summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbxgen.c89
1 files changed, 72 insertions, 17 deletions
diff --git a/bxgen.c b/bxgen.c
index 560c704..00bfb88 100755
--- a/bxgen.c
+++ b/bxgen.c
@@ -34,6 +34,7 @@ exit $?
// - Proper prefixes for identifiers
// - Effective entity allocation
// - Linked lists for large entities
+// - Static single-assignment
// - Sea of Nodes
// - Optimization layers
// - Multithreading
@@ -120,8 +121,8 @@ enum {
// Semantic node operations
//
- OP_I64 = 0,
- OP_RET,
+ DATA_I64 = 0,
+ CTRL_RET,
// Entity types
//
@@ -151,7 +152,7 @@ enum {
typedef struct {
i16 op;
- i8 flow; // `FLOW_DATA` or `FLOW_CONTROL`
+ i64 index_in_proc;
union {
u8 lit_bytes[MAX_LITERAL_SIZE]; // byte array literal
i64 lit_int; // integer literal
@@ -168,6 +169,8 @@ typedef struct {
c8 name[MAX_NAME_SIZE];
i64 node_count;
i64 nodes[MAX_NODE_COUNT];
+ i64 ret_index;
+ i64 index_in_unit;
} proc_t;
// A compilation unit is a collection of procedures.
@@ -299,6 +302,8 @@ void pool_remove(pool_t *pool, i64 entity, i16 type) {
}
i64 node_init(pool_t *pool, node_t data) {
+ data.index_in_proc = UNDEFINED;
+
return pool_add(pool, (entity_t) {
.type = TYPE_NODE,
.tail = UNDEFINED,
@@ -310,18 +315,16 @@ void node_destroy(pool_t *pool, i64 node) {
pool_remove(pool, node, TYPE_NODE);
}
-i64 node_op_i64(pool_t *pool, i64 value) {
+i64 node_data_i64(pool_t *pool, i64 value) {
return node_init(pool, (node_t) {
- .op = OP_I64,
- .flow = FLOW_DATA,
+ .op = DATA_I64,
.lit_int = value,
});
}
-i64 node_op_ret(pool_t *pool, i64 node_return_value) {
+i64 node_ctrl_ret(pool_t *pool, i64 node_return_value) {
return node_init(pool, (node_t) {
- .op = OP_RET,
- .flow = FLOW_CONTROL,
+ .op = CTRL_RET,
.ref_node = { node_return_value, 0, },
});
}
@@ -330,6 +333,10 @@ i64 proc_init(pool_t *pool) {
return pool_add(pool, (entity_t) {
.type = TYPE_PROC,
.tail = UNDEFINED,
+ .proc = (proc_t) {
+ .ret_index = UNDEFINED,
+ .index_in_unit = UNDEFINED,
+ },
});
}
@@ -360,12 +367,29 @@ void proc_node_add(pool_t *pool, i64 proc, i64 node) {
assert(pool->entities[node].type == TYPE_NODE);
proc_t *p = &pool->entities[proc].proc;
+ node_t *n = &pool->entities[node].node;
+
+ assert(n->index_in_proc == UNDEFINED);
// TODO
// Implement large entities.
- assert(p->node_count < MAX_NODE_COUNT);
- p->nodes[p->node_count++] = node;
+ i64 index = p->node_count;
+
+ if (n->op == CTRL_RET)
+ {
+ // Only one return node is allowed.
+ //
+
+ assert(p->ret_index == UNDEFINED);
+ p->ret_index = index;
+ }
+
+ assert(index < MAX_NODE_COUNT);
+
+ n->index_in_proc = index;
+ p->nodes[index] = node;
+ ++p->node_count;
}
void proc_node_remove(pool_t *pool, i64 proc, i64 node) {
@@ -374,7 +398,21 @@ void proc_node_remove(pool_t *pool, i64 proc, i64 node) {
assert(pool->entities[proc].type == TYPE_PROC);
assert(pool->entities[node].type == TYPE_NODE);
- pool->entities[proc].proc.nodes[node] = UNDEFINED;
+ proc_t *p = &pool->entities[proc].proc;
+ node_t *n = &pool->entities[node].node;
+
+ assert(n->index_in_proc != UNDEFINED);
+
+ if (n->op == CTRL_RET) {
+ assert(p->ret_index != UNDEFINED);
+ p->ret_index = UNDEFINED;
+ }
+
+ // TODO
+ // Implement large entities.
+
+ p->nodes[n->index_in_proc] = UNDEFINED;
+ n->index_in_proc = UNDEFINED;
}
i64 unit_init(pool_t *pool) {
@@ -399,12 +437,20 @@ void unit_proc_add(pool_t *pool, i64 unit, i64 proc) {
assert(pool->entities[proc].type == TYPE_PROC);
unit_t *u = &pool->entities[unit].unit;
+ proc_t *p = &pool->entities[proc].proc;
+
+ assert(p->index_in_unit == UNDEFINED);
// TODO
// Implement large entities.
- assert(u->proc_count < MAX_PROC_COUNT);
- u->procs[u->proc_count++] = proc;
+ i64 index = u->proc_count;
+
+ assert(index < MAX_PROC_COUNT);
+
+ p->index_in_unit = index;
+ u->procs[index] = proc;
+ ++u->proc_count;
}
void unit_proc_remove(pool_t *pool, i64 unit, i64 proc) {
@@ -413,7 +459,16 @@ void unit_proc_remove(pool_t *pool, i64 unit, i64 proc) {
assert(pool->entities[unit].type == TYPE_UNIT);
assert(pool->entities[proc].type == TYPE_PROC);
- pool->entities[unit].unit.procs[proc] = UNDEFINED;
+ unit_t *u = &pool->entities[unit].unit;
+ proc_t *p = &pool->entities[proc].proc;
+
+ assert(p->index_in_unit != UNDEFINED);
+
+ // TODO
+ // Implement large entities.
+
+ u->procs[p->index_in_unit] = UNDEFINED;
+ p->index_in_unit = UNDEFINED;
}
void unit_set_entry_point(pool_t *pool, i64 unit, i64 entry_point_proc) {
@@ -549,11 +604,11 @@ static pool_t g_pool = {
//
i64 n_i64(i64 value) {
- return node_op_i64(&g_pool, value);
+ return node_data_i64(&g_pool, value);
}
i64 n_ret(i64 node_return_value) {
- return node_op_ret(&g_pool, node_return_value);
+ return node_ctrl_ret(&g_pool, node_return_value);
}
i64 p_new(c8 const *name) {