ast_call_codegen, ir_block_create_call plus call-related functions, ir_value->outtype TODO: fill outtype in ir_value

This commit is contained in:
Wolfgang (Blub) Bumiller 2012-06-28 17:21:26 +02:00
parent 7363e88cd7
commit 01b3f5ef58
3 changed files with 106 additions and 0 deletions

47
ast.c
View file

@ -1177,5 +1177,52 @@ bool ast_loop_codegen(ast_loop *self, ast_function *func, bool lvalue, ir_value
bool ast_call_codegen(ast_call *self, ast_function *func, bool lvalue, ir_value **out)
{
/* TODO: call ir codegen */
ast_expression_codegen *cgen;
ir_value_vector params;
ir_instr *callinstr;
size_t i;
ir_value *funval = NULL;
/* return values are never rvalues */
(void)lvalue;
cgen = self->func->expression.codegen;
if (!(*cgen)((ast_expression*)(self->func), func, false, &funval))
return false;
if (!funval)
return false;
MEM_VECTOR_INIT(&params, v);
/* parameters */
for (i = 0; i < self->params_count; ++i)
{
ir_value *param;
ast_expression *expr = self->params[i];
cgen = expr->expression.codegen;
if (!(*cgen)(expr, func, false, &param))
goto error;
if (!param)
goto error;
if (!ir_value_vector_v_add(&params, param))
goto error;
}
callinstr = ir_block_create_call(func->curblock, ast_function_label(func, "call"), funval, funval->outtype);
if (!callinstr)
goto error;
for (i = 0; i < params.v_count; ++i) {
if (!ir_call_param(callinstr, params.v[i]))
goto error;
}
*out = ir_call_value(callinstr);
return true;
error:
MEM_VECTOR_CLEAR(&params, v);
return false;
}

45
ir.c
View file

@ -44,6 +44,8 @@ size_t type_sizeof[TYPE_COUNT] = {
3, /* TYPE_VARIANT */
};
MEM_VEC_FUNCTIONS(ir_value_vector, ir_value*, v)
/***********************************************************************
*IR Builder
*/
@ -362,6 +364,7 @@ ir_instr* ir_instr_new(ir_block* owner, int op)
return self;
}
MEM_VEC_FUNCTIONS(ir_instr, ir_phi_entry_t, phi)
MEM_VEC_FUNCTIONS(ir_instr, ir_value*, params)
void ir_instr_delete(ir_instr *self)
{
@ -432,6 +435,7 @@ ir_value* ir_value_var(const char *name, int storetype, int vtype)
self = (ir_value*)mem_a(sizeof(*self));
self->vtype = vtype;
self->fieldtype = TYPE_VOID;
self->outtype = TYPE_VOID;
self->store = storetype;
MEM_VECTOR_INIT(self, reads);
MEM_VECTOR_INIT(self, writes);
@ -1026,6 +1030,47 @@ bool ir_phi_add(ir_instr* self, ir_block *b, ir_value *v)
return ir_instr_phi_add(self, pe);
}
/* call related code */
ir_instr* ir_block_create_call(ir_block *self, const char *label, ir_value *func, int ot)
{
ir_value *out;
ir_instr *in;
in = ir_instr_new(self, INSTR_CALL0);
if (!in)
return NULL;
out = ir_value_out(self->owner, label, store_value, ot);
if (!out) {
ir_instr_delete(in);
return NULL;
}
if (!ir_instr_op(in, 0, out, true) ||
!ir_instr_op(in, 1, func, false) ||
!ir_block_instr_add(self, in))
{
ir_instr_delete(in);
ir_value_delete(out);
return NULL;
}
return in;
}
ir_value* ir_call_value(ir_instr *self)
{
return self->_ops[0];
}
bool ir_call_param(ir_instr* self, ir_value *v)
{
if (!ir_instr_params_add(self, v))
return false;
if (!ir_value_reads_add(v, self)) {
if (!ir_instr_params_remove(self, self->params_count-1))
GMQCC_SUPRESS_EMPTY_BODY;
return false;
}
return true;
}
/* binary op related code */
ir_value* ir_block_create_binop(ir_block *self,

14
ir.h
View file

@ -40,6 +40,8 @@ typedef struct ir_value_s {
lex_ctx context;
/* even the IR knows the subtype of a field */
int fieldtype;
/* and the output type of a function */
int outtype;
MEM_VECTOR_MAKE(struct ir_instr_s*, reads);
MEM_VECTOR_MAKE(struct ir_instr_s*, writes);
@ -100,6 +102,13 @@ bool ir_values_overlap(const ir_value*, const ir_value*);
void ir_value_dump(ir_value*, int (*oprintf)(const char*,...));
void ir_value_dump_life(ir_value *self, int (*oprintf)(const char*,...));
/* A vector of IR values */
typedef struct {
MEM_VECTOR_MAKE(ir_value*, v);
} ir_value_vector;
MEM_VECTOR_PROTO(ir_value_vector, ir_value*, v);
/* PHI data */
typedef struct ir_phi_entry_s
{
ir_value *value;
@ -129,6 +138,8 @@ void ir_instr_delete(ir_instr*);
MEM_VECTOR_PROTO(ir_value, ir_phi_entry_t, phi);
bool GMQCC_WARN ir_instr_op(ir_instr*, int op, ir_value *value, bool writing);
MEM_VECTOR_PROTO(ir_value, ir_value*, params);
void ir_instr_dump(ir_instr* in, char *ind, int (*oprintf)(const char*,...));
/* block */
@ -187,6 +198,9 @@ ir_value* ir_block_create_div(ir_block*, const char *label, ir_value *l, ir_valu
ir_instr* ir_block_create_phi(ir_block*, const char *label, int vtype);
ir_value* ir_phi_value(ir_instr*);
bool GMQCC_WARN ir_phi_add(ir_instr*, ir_block *b, ir_value *v);
ir_instr* ir_block_create_call(ir_block*, const char *label, ir_value *func, int otype);
ir_value* ir_call_value(ir_instr*);
bool GMQCC_WARN ir_call_param(ir_instr*, ir_value*);
bool GMQCC_WARN ir_block_create_return(ir_block*, ir_value *opt_value);