issue #98 more work on linearizer

parser
Dibyendu Majumdar 4 years ago
parent 6cb6ef838f
commit 0fe4d1a5b1

@ -301,7 +301,7 @@ DECLARE_PTR_LIST(proc_list, struct proc);
#define container_of(ptr, type, member) ((type *)((char *)(ptr)-offsetof(type, member)))
enum opcode { OP_NOP };
enum opcode { OP_NOP, OP_RET };
enum pseudo_type { PSEUDO_LOCAL, PSEUDO_TEMP, PSEUDO_TEMP_INT, PSEUDO_TEMP_ANY, PSEUDO_CONSTANT };
@ -310,13 +310,18 @@ struct pseudo {
unsigned type : 4, regnum : 16;
union {
struct lua_symbol *symbol; /* If local var this should be set */
struct constant *constant;
const struct constant *constant;
};
};
/* single instruction */
struct instruction {
unsigned opcode : 8;
union {
struct {
struct pseudo_list* expr_list;
} ret_instruction;
};
};
struct edge {

@ -67,18 +67,25 @@ static int compare_constants(const void *a, const void *b) {
if (c1->type != c2->type)
return 1;
if (c1->type == RAVI_TNUMINT)
return c1->i - c2->i;
return c1->i == c2->i;
else if (c1->type == RAVI_TNUMFLT)
return c1->n == c2->n ? 0 : (c1->n < c2->n ? -1 : 1);
return c1->n == c2->n;
else
return c1->s == c2->s;
}
static uint32_t hash_constant(const void *c) { return fnv1_hash_data(c, sizeof(struct constant)); }
static uint32_t hash_constant(const void *c) {
const struct constant *c1 = (const struct constant *)c;
if (c1->type == RAVI_TNUMINT)
return c1->i;
else if (c1->type == RAVI_TNUMFLT)
return (int)c1->n; // FIXME maybe use Lua's hash gen
else
return c1->s->hash;
}
static int allocate_constant(struct linearizer *linearizer, struct ast_node *node) {
static const struct constant *allocate_constant(struct proc *proc, struct ast_node *node) {
assert(node->type == AST_LITERAL_EXPR);
struct proc *proc = linearizer->current_proc;
struct constant c = {.type = node->literal_expr.type.type_code};
if (c.type == RAVI_TNUMINT)
c.i = node->literal_expr.u.i;
@ -89,16 +96,18 @@ static int allocate_constant(struct linearizer *linearizer, struct ast_node *nod
struct set_entry *entry = set_search(proc->constants, &c);
if (entry == NULL) {
int reg = proc->num_constants++;
struct constant *c1 = dmrC_allocator_allocate(&linearizer->constant_allocator, 0);
struct constant *c1 = dmrC_allocator_allocate(&proc->linearizer->constant_allocator, 0);
assert(c1);
memcpy(c1, &c, sizeof *c1);
c1->index = reg;
set_add(proc->constants, c1);
return reg;
printf("Created new constant and assigned reg %d\n", reg);
return c1;
}
else {
const struct constant *c1 = entry->key;
return c1->index;
printf("Found constant at reg %d\n", c1->index);
return c1;
}
}
@ -113,7 +122,7 @@ struct pseudo *allocate_local_pseudo(struct proc *proc, struct lua_symbol *sym,
return pseudo;
}
struct pseudo *allocate_constant_pseudo(struct proc *proc, struct constant *constant) {
struct pseudo *allocate_constant_pseudo(struct proc *proc, const struct constant *constant) {
struct pseudo *pseudo = dmrC_allocator_allocate(&proc->linearizer->pseudo_allocator, 0);
pseudo->type = PSEUDO_CONSTANT;
pseudo->constant = constant;
@ -160,14 +169,62 @@ static void linearize_function_args(struct linearizer *linearizer) {
END_FOR_EACH_PTR(sym);
}
static void linearize_statement(struct linearizer *linearizer, struct ast_node *node);
static void linearize_statement_list(struct linearizer *linearizer, struct ast_node_list *list) {
static void linearize_statement(struct proc *proc, struct ast_node *node);
static void linearize_statement_list(struct proc *proc, struct ast_node_list *list) {
struct ast_node *node;
FOR_EACH_PTR(list, node) { linearize_statement(linearizer, node); }
FOR_EACH_PTR(list, node) { linearize_statement(proc, node); }
END_FOR_EACH_PTR(node);
}
static void linearize_statement(struct linearizer *linearizer, struct ast_node *node) {
static struct instruction *alloc_instruction(struct proc *proc, enum opcode op) {
struct instruction *insn = dmrC_allocator_allocate(&proc->linearizer->instruction_allocator, 0);
insn->opcode = op;
return insn;
}
static struct pseudo *linearize_literal(struct proc *proc, struct ast_node *expr) {
assert(expr->type == AST_LITERAL_EXPR);
if (expr->literal_expr.type.type_code == RAVI_TNUMFLT || expr->literal_expr.type.type_code == RAVI_TNUMINT ||
expr->literal_expr.type.type_code == RAVI_TSTRING) {
return allocate_constant_pseudo(proc, allocate_constant(proc, expr));
}
else {
abort();
return NULL;
}
}
static struct pseudo *linearize_expr(struct proc *proc, struct ast_node *expr) {
switch (expr->type) {
case AST_LITERAL_EXPR: {
return linearize_literal(proc, expr);
} break;
default:
abort();
break;
}
assert(false);
return NULL;
}
static void linearize_expr_list(struct proc *proc, struct ast_node_list *expr_list, struct instruction *insn,
struct pseudo_list **pseudo_list) {
struct ast_node *expr;
FOR_EACH_PTR(expr_list, expr) {
struct pseudo *pseudo = linearize_expr(proc, expr);
ptrlist_add((struct ptr_list **)pseudo_list, pseudo, &proc->linearizer->ptrlist_allocator);
}
END_FOR_EACH_PTR(expr);
}
static void linearize_return(struct proc *proc, struct ast_node *node) {
assert(node->type == AST_RETURN_STMT);
struct instruction *insn = alloc_instruction(proc, OP_RET);
linearize_expr_list(proc, node->return_stmt.expr_list, insn, &insn->ret_instruction.expr_list);
}
static void linearize_statement(struct proc *proc, struct ast_node *node) {
switch (node->type) {
case AST_FUNCTION_EXPR: {
/* args need type assertions but those have no ast - i.e. code gen should do it */
@ -178,6 +235,7 @@ static void linearize_statement(struct linearizer *linearizer, struct ast_node *
break;
}
case AST_RETURN_STMT: {
linearize_return(proc, node);
// typecheck_ast_list(container, function, node->return_stmt.expr_list);
break;
}
@ -279,7 +337,8 @@ static void linearize_statement(struct linearizer *linearizer, struct ast_node *
static struct basic_block *create_block(struct proc *proc) {
if (proc->node_count >= proc->allocated) {
unsigned new_size = proc->allocated + 25;
struct node **new_data = dmrC_allocator_allocate(&proc->linearizer->unsized_allocator, new_size * sizeof(struct node *));
struct node **new_data =
dmrC_allocator_allocate(&proc->linearizer->unsized_allocator, new_size * sizeof(struct node *));
assert(new_data != NULL);
if (proc->node_count > 0) {
memcpy(new_data, proc->nodes, proc->allocated * sizeof(struct node *));
@ -297,9 +356,7 @@ static struct basic_block *create_block(struct proc *proc) {
* Takes a basic block as an argument and makes it the current block.
* All future instructions will be added to the end of this block
*/
static void start_block(struct proc *proc, struct basic_block *bb) {
proc->current_bb = bb;
}
static void start_block(struct proc *proc, struct basic_block *bb) { proc->current_bb = bb; }
/**
* Create the initial blocks entry and exit for the proc.
@ -356,7 +413,7 @@ static void linearize_function(struct linearizer *linearizer) {
initialize_graph(proc);
start_scope(linearizer, proc, func_expr->function_expr.main_block);
linearize_function_args(linearizer);
linearize_statement_list(linearizer, func_expr->function_expr.function_statement_list);
linearize_statement_list(proc, func_expr->function_expr.function_statement_list);
end_scope(linearizer, proc);
}
@ -367,4 +424,4 @@ void raviA_ast_linearize(struct linearizer *linearizer, struct ast_container *co
set_current_proc(linearizer, proc);
linearize_function(linearizer);
ravi_destroy_linearizer(linearizer);
}
}

@ -387,6 +387,7 @@ hash_table_next_entry(struct hash_table *ht, struct hash_entry *entry)
return NULL;
}
#ifndef _WIN32
/**
* Returns a random entry from the hash table.
*
@ -421,3 +422,4 @@ hash_table_random_entry(struct hash_table *ht,
return NULL;
}
#endif

@ -328,6 +328,7 @@ int_set_next_entry(struct int_set *set, struct int_set_entry *entry)
return NULL;
}
#ifndef _WIN32
struct int_set_entry *
int_set_random_entry(struct int_set *set,
int (*predicate)(struct int_set_entry *entry))
@ -354,3 +355,4 @@ int_set_random_entry(struct int_set *set,
return NULL;
}
#endif

@ -104,7 +104,7 @@ entry_is_present(const struct set_entry *entry)
struct set *
set_create(uint32_t (*hash_function)(const void *key),
int key_equals_function(const void *a,
int (*key_equals_function)(const void *a,
const void *b))
{
struct set *set;
@ -390,6 +390,7 @@ set_next_entry(struct set *set, struct set_entry *entry)
return NULL;
}
#ifndef _WIN32
struct set_entry *
set_random_entry(struct set *set,
int (*predicate)(struct set_entry *entry))
@ -416,3 +417,4 @@ set_random_entry(struct set *set,
return NULL;
}
#endif

Loading…
Cancel
Save