mirror of
https://github.com/DarkPlacesEngine/gmqcc.git
synced 2025-01-18 22:31:36 +00:00
Turned nearly every void-returning function into a bool-returning function, and checking return values wherever necessary to be able to properly exit on failures
This commit is contained in:
parent
8f290e7989
commit
86564686f3
2 changed files with 283 additions and 112 deletions
367
ir.c
367
ir.c
|
@ -37,7 +37,10 @@ ir_builder* ir_builder_new(const char *modulename)
|
||||||
MEM_VECTOR_INIT(self, functions);
|
MEM_VECTOR_INIT(self, functions);
|
||||||
MEM_VECTOR_INIT(self, globals);
|
MEM_VECTOR_INIT(self, globals);
|
||||||
self->name = NULL;
|
self->name = NULL;
|
||||||
ir_builder_set_name(self, modulename);
|
if (!ir_builder_set_name(self, modulename)) {
|
||||||
|
mem_d(self);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* globals which always exist */
|
/* globals which always exist */
|
||||||
|
|
||||||
|
@ -65,11 +68,12 @@ void ir_builder_delete(ir_builder* self)
|
||||||
mem_d(self);
|
mem_d(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ir_builder_set_name(ir_builder *self, const char *name)
|
bool ir_builder_set_name(ir_builder *self, const char *name)
|
||||||
{
|
{
|
||||||
if (self->name)
|
if (self->name)
|
||||||
mem_d((void*)self->name);
|
mem_d((void*)self->name);
|
||||||
self->name = util_strdup(name);
|
self->name = util_strdup(name);
|
||||||
|
return !!self->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
ir_function* ir_builder_get_function(ir_builder *self, const char *name)
|
ir_function* ir_builder_get_function(ir_builder *self, const char *name)
|
||||||
|
@ -90,8 +94,12 @@ ir_function* ir_builder_create_function(ir_builder *self, const char *name)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn = ir_function_new(self);
|
fn = ir_function_new(self);
|
||||||
ir_function_set_name(fn, name);
|
if (!ir_function_set_name(fn, name) ||
|
||||||
ir_builder_functions_add(self, fn);
|
!ir_builder_functions_add(self, fn) )
|
||||||
|
{
|
||||||
|
ir_function_delete(fn);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
return fn;
|
return fn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,7 +121,10 @@ ir_value* ir_builder_create_global(ir_builder *self, const char *name, int vtype
|
||||||
}
|
}
|
||||||
|
|
||||||
ve = ir_value_var(name, store_global, vtype);
|
ve = ir_value_var(name, store_global, vtype);
|
||||||
ir_builder_globals_add(self, ve);
|
if (!ir_builder_globals_add(self, ve)) {
|
||||||
|
ir_value_delete(ve);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
return ve;
|
return ve;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,14 +132,18 @@ ir_value* ir_builder_create_global(ir_builder *self, const char *name, int vtype
|
||||||
*IR Function
|
*IR Function
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void ir_function_naive_phi(ir_function*);
|
bool ir_function_naive_phi(ir_function*);
|
||||||
void ir_function_enumerate(ir_function*);
|
void ir_function_enumerate(ir_function*);
|
||||||
void ir_function_calculate_liferanges(ir_function*);
|
bool ir_function_calculate_liferanges(ir_function*);
|
||||||
|
|
||||||
ir_function* ir_function_new(ir_builder* owner)
|
ir_function* ir_function_new(ir_builder* owner)
|
||||||
{
|
{
|
||||||
ir_function *self;
|
ir_function *self;
|
||||||
self = (ir_function*)mem_a(sizeof(*self));
|
self = (ir_function*)mem_a(sizeof(*self));
|
||||||
|
if (!ir_function_set_name(self, "<@unnamed>")) {
|
||||||
|
mem_d(self);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
self->owner = owner;
|
self->owner = owner;
|
||||||
self->context.file = "<@no context>";
|
self->context.file = "<@no context>";
|
||||||
self->context.line = 0;
|
self->context.line = 0;
|
||||||
|
@ -137,7 +152,6 @@ ir_function* ir_function_new(ir_builder* owner)
|
||||||
MEM_VECTOR_INIT(self, blocks);
|
MEM_VECTOR_INIT(self, blocks);
|
||||||
MEM_VECTOR_INIT(self, values);
|
MEM_VECTOR_INIT(self, values);
|
||||||
MEM_VECTOR_INIT(self, locals);
|
MEM_VECTOR_INIT(self, locals);
|
||||||
ir_function_set_name(self, "<@unnamed>");
|
|
||||||
|
|
||||||
self->run_id = 0;
|
self->run_id = 0;
|
||||||
return self;
|
return self;
|
||||||
|
@ -146,11 +160,12 @@ MEM_VEC_FUNCTIONS(ir_function, ir_value*, values)
|
||||||
MEM_VEC_FUNCTIONS(ir_function, ir_block*, blocks)
|
MEM_VEC_FUNCTIONS(ir_function, ir_block*, blocks)
|
||||||
MEM_VEC_FUNCTIONS(ir_function, ir_value*, locals)
|
MEM_VEC_FUNCTIONS(ir_function, ir_value*, locals)
|
||||||
|
|
||||||
void ir_function_set_name(ir_function *self, const char *name)
|
bool ir_function_set_name(ir_function *self, const char *name)
|
||||||
{
|
{
|
||||||
if (self->name)
|
if (self->name)
|
||||||
mem_d((void*)self->name);
|
mem_d((void*)self->name);
|
||||||
self->name = util_strdup(name);
|
self->name = util_strdup(name);
|
||||||
|
return !!self->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ir_function_delete(ir_function *self)
|
void ir_function_delete(ir_function *self)
|
||||||
|
@ -175,24 +190,32 @@ void ir_function_delete(ir_function *self)
|
||||||
mem_d(self);
|
mem_d(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ir_function_collect_value(ir_function *self, ir_value *v)
|
bool GMQCC_WARN ir_function_collect_value(ir_function *self, ir_value *v)
|
||||||
{
|
{
|
||||||
ir_function_values_add(self, v);
|
return ir_function_values_add(self, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
ir_block* ir_function_create_block(ir_function *self, const char *label)
|
ir_block* ir_function_create_block(ir_function *self, const char *label)
|
||||||
{
|
{
|
||||||
ir_block* bn = ir_block_new(self, label);
|
ir_block* bn = ir_block_new(self, label);
|
||||||
memcpy(&bn->context, &self->context, sizeof(self->context));
|
memcpy(&bn->context, &self->context, sizeof(self->context));
|
||||||
ir_function_blocks_add(self, bn);
|
if (!ir_function_blocks_add(self, bn)) {
|
||||||
|
ir_block_delete(bn);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
return bn;
|
return bn;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ir_function_finalize(ir_function *self)
|
bool ir_function_finalize(ir_function *self)
|
||||||
{
|
{
|
||||||
ir_function_naive_phi(self);
|
if (!ir_function_naive_phi(self))
|
||||||
|
return false;
|
||||||
|
|
||||||
ir_function_enumerate(self);
|
ir_function_enumerate(self);
|
||||||
ir_function_calculate_liferanges(self);
|
|
||||||
|
if (!ir_function_calculate_liferanges(self))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ir_value* ir_function_get_local(ir_function *self, const char *name)
|
ir_value* ir_function_get_local(ir_function *self, const char *name)
|
||||||
|
@ -213,7 +236,10 @@ ir_value* ir_function_create_local(ir_function *self, const char *name, int vtyp
|
||||||
}
|
}
|
||||||
|
|
||||||
ve = ir_value_var(name, store_local, vtype);
|
ve = ir_value_var(name, store_local, vtype);
|
||||||
ir_function_locals_add(self, ve);
|
if (!ir_function_locals_add(self, ve)) {
|
||||||
|
ir_value_delete(ve);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
return ve;
|
return ve;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,6 +251,10 @@ ir_block* ir_block_new(ir_function* owner, const char *name)
|
||||||
{
|
{
|
||||||
ir_block *self;
|
ir_block *self;
|
||||||
self = (ir_block*)mem_a(sizeof(*self));
|
self = (ir_block*)mem_a(sizeof(*self));
|
||||||
|
if (!ir_block_set_label(self, name)) {
|
||||||
|
mem_d(self);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
self->owner = owner;
|
self->owner = owner;
|
||||||
self->context.file = "<@no context>";
|
self->context.file = "<@no context>";
|
||||||
self->context.line = 0;
|
self->context.line = 0;
|
||||||
|
@ -233,7 +263,6 @@ ir_block* ir_block_new(ir_function* owner, const char *name)
|
||||||
MEM_VECTOR_INIT(self, entries);
|
MEM_VECTOR_INIT(self, entries);
|
||||||
MEM_VECTOR_INIT(self, exits);
|
MEM_VECTOR_INIT(self, exits);
|
||||||
self->label = NULL;
|
self->label = NULL;
|
||||||
ir_block_set_label(self, name);
|
|
||||||
|
|
||||||
self->eid = 0;
|
self->eid = 0;
|
||||||
self->is_return = false;
|
self->is_return = false;
|
||||||
|
@ -259,11 +288,12 @@ void ir_block_delete(ir_block* self)
|
||||||
mem_d(self);
|
mem_d(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ir_block_set_label(ir_block *self, const char *name)
|
bool ir_block_set_label(ir_block *self, const char *name)
|
||||||
{
|
{
|
||||||
if (self->label)
|
if (self->label)
|
||||||
mem_d((void*)self->label);
|
mem_d((void*)self->label);
|
||||||
self->label = util_strdup(name);
|
self->label = util_strdup(name);
|
||||||
|
return !!self->label;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
@ -292,28 +322,53 @@ MEM_VEC_FUNCTIONS(ir_instr, ir_phi_entry_t, phi)
|
||||||
|
|
||||||
void ir_instr_delete(ir_instr *self)
|
void ir_instr_delete(ir_instr *self)
|
||||||
{
|
{
|
||||||
ir_instr_op(self, 0, NULL, false);
|
size_t i;
|
||||||
ir_instr_op(self, 1, NULL, false);
|
/* The following calls can only delete from
|
||||||
ir_instr_op(self, 2, NULL, false);
|
* vectors, we still want to delete this instruction
|
||||||
|
* so ignore the return value. Since with the warn_unused_result attribute
|
||||||
|
* gcc doesn't care about an explicit: (void)foo(); to ignore the result,
|
||||||
|
* I have to improvise here and use if(foo());
|
||||||
|
*/
|
||||||
|
for (i = 0; i < self->phi_count; ++i) {
|
||||||
|
size_t idx;
|
||||||
|
if (ir_value_writes_find(self->phi[i].value, self, &idx))
|
||||||
|
if (ir_value_writes_remove(self->phi[i].value, idx));
|
||||||
|
if (ir_value_reads_find(self->phi[i].value, self, &idx))
|
||||||
|
if (ir_value_reads_remove(self->phi[i].value, idx));
|
||||||
|
}
|
||||||
MEM_VECTOR_CLEAR(self, phi);
|
MEM_VECTOR_CLEAR(self, phi);
|
||||||
|
if (ir_instr_op(self, 0, NULL, false));
|
||||||
|
if (ir_instr_op(self, 1, NULL, false));
|
||||||
|
if (ir_instr_op(self, 2, NULL, false));
|
||||||
mem_d(self);
|
mem_d(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ir_instr_op(ir_instr *self, int op, ir_value *v, bool writing)
|
bool ir_instr_op(ir_instr *self, int op, ir_value *v, bool writing)
|
||||||
{
|
{
|
||||||
if (self->_ops[op]) {
|
if (self->_ops[op]) {
|
||||||
if (writing)
|
size_t idx;
|
||||||
ir_value_writes_add(self->_ops[op], self);
|
if (writing && ir_value_writes_find(self->_ops[op], self, &idx))
|
||||||
else
|
{
|
||||||
ir_value_reads_add(self->_ops[op], self);
|
if (!ir_value_writes_remove(self->_ops[op], idx))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (ir_value_reads_find(self->_ops[op], self, &idx))
|
||||||
|
{
|
||||||
|
if (!ir_value_reads_remove(self->_ops[op], idx))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (v) {
|
if (v) {
|
||||||
if (writing)
|
if (writing) {
|
||||||
ir_value_writes_add(v, self);
|
if (!ir_value_writes_add(v, self))
|
||||||
else
|
return false;
|
||||||
ir_value_reads_add(v, self);
|
} else {
|
||||||
|
if (!ir_value_reads_add(v, self))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
self->_ops[op] = v;
|
self->_ops[op] = v;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
@ -338,13 +393,19 @@ ir_value* ir_value_var(const char *name, int storetype, int vtype)
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
MEM_VEC_FUNCTIONS(ir_value, ir_life_entry_t, life)
|
MEM_VEC_FUNCTIONS(ir_value, ir_life_entry_t, life)
|
||||||
MEM_VEC_FUNCTIONS(ir_value, ir_instr*, reads)
|
MEM_VEC_FUNCTIONS_ALL(ir_value, ir_instr*, reads)
|
||||||
MEM_VEC_FUNCTIONS(ir_value, ir_instr*, writes)
|
MEM_VEC_FUNCTIONS_ALL(ir_value, ir_instr*, writes)
|
||||||
|
|
||||||
ir_value* ir_value_out(ir_function *owner, const char *name, int storetype, int vtype)
|
ir_value* ir_value_out(ir_function *owner, const char *name, int storetype, int vtype)
|
||||||
{
|
{
|
||||||
ir_value *v = ir_value_var(name, storetype, vtype);
|
ir_value *v = ir_value_var(name, storetype, vtype);
|
||||||
ir_function_collect_value(owner, v);
|
if (!v)
|
||||||
|
return NULL;
|
||||||
|
if (!ir_function_collect_value(owner, v))
|
||||||
|
{
|
||||||
|
ir_value_delete(v);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -419,13 +480,15 @@ bool ir_value_lives(ir_value *self, size_t at)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ir_value_life_insert(ir_value *self, size_t idx, ir_life_entry_t e)
|
bool ir_value_life_insert(ir_value *self, size_t idx, ir_life_entry_t e)
|
||||||
{
|
{
|
||||||
size_t k;
|
size_t k;
|
||||||
ir_value_life_add(self, e); /* naive... */
|
if (!ir_value_life_add(self, e)) /* naive... */
|
||||||
|
return false;
|
||||||
for (k = self->life_count-1; k > idx; --k)
|
for (k = self->life_count-1; k > idx; --k)
|
||||||
self->life[k] = self->life[k-1];
|
self->life[k] = self->life[k-1];
|
||||||
self->life[idx] = e;
|
self->life[idx] = e;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ir_value_life_merge(ir_value *self, size_t s)
|
bool ir_value_life_merge(ir_value *self, size_t s)
|
||||||
|
@ -455,7 +518,8 @@ bool ir_value_life_merge(ir_value *self, size_t s)
|
||||||
return false;
|
return false;
|
||||||
ir_life_entry_t e;
|
ir_life_entry_t e;
|
||||||
e.start = e.end = s;
|
e.start = e.end = s;
|
||||||
ir_value_life_add(self, e);
|
if (!ir_value_life_add(self, e))
|
||||||
|
return false; /* failing */
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
/* found */
|
/* found */
|
||||||
|
@ -466,7 +530,8 @@ bool ir_value_life_merge(ir_value *self, size_t s)
|
||||||
{
|
{
|
||||||
/* merge */
|
/* merge */
|
||||||
before->end = life->end;
|
before->end = life->end;
|
||||||
ir_value_life_remove(self, i);
|
if (!ir_value_life_remove(self, i))
|
||||||
|
return false; /* failing */
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (before->end + 1 == s)
|
if (before->end + 1 == s)
|
||||||
|
@ -487,8 +552,7 @@ bool ir_value_life_merge(ir_value *self, size_t s)
|
||||||
}
|
}
|
||||||
/* insert a new entry */
|
/* insert a new entry */
|
||||||
new_entry.start = new_entry.end = s;
|
new_entry.start = new_entry.end = s;
|
||||||
ir_value_life_insert(self, i, new_entry);
|
return ir_value_life_insert(self, i, new_entry);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
@ -502,9 +566,14 @@ bool ir_block_create_store_op(ir_block *self, int op, ir_value *target, ir_value
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
ir_instr *in = ir_instr_new(self, op);
|
ir_instr *in = ir_instr_new(self, op);
|
||||||
ir_instr_op(in, 0, target, true);
|
if (!in)
|
||||||
ir_instr_op(in, 1, what, false);
|
return false;
|
||||||
ir_block_instr_add(self, in);
|
if (!ir_instr_op(in, 0, target, true) ||
|
||||||
|
!ir_instr_op(in, 1, what, false) ||
|
||||||
|
!ir_block_instr_add(self, in) )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -555,72 +624,108 @@ bool ir_block_create_store(ir_block *self, ir_value *target, ir_value *what)
|
||||||
return ir_block_create_store_op(self, op, target, what);
|
return ir_block_create_store_op(self, op, target, what);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ir_block_create_return(ir_block *self, ir_value *v)
|
bool ir_block_create_return(ir_block *self, ir_value *v)
|
||||||
{
|
{
|
||||||
ir_instr *in;
|
ir_instr *in;
|
||||||
if (self->final) {
|
if (self->final) {
|
||||||
fprintf(stderr, "block already ended (%s)\n", self->label);
|
fprintf(stderr, "block already ended (%s)\n", self->label);
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
self->final = true;
|
self->final = true;
|
||||||
self->is_return = true;
|
self->is_return = true;
|
||||||
in = ir_instr_new(self, INSTR_RETURN);
|
in = ir_instr_new(self, INSTR_RETURN);
|
||||||
ir_instr_op(in, 0, v, false);
|
if (!in)
|
||||||
ir_block_instr_add(self, in);
|
return false;
|
||||||
|
|
||||||
|
if (!ir_instr_op(in, 0, v, false) ||
|
||||||
|
!ir_block_instr_add(self, in) )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ir_block_create_if(ir_block *self, ir_value *v,
|
bool ir_block_create_if(ir_block *self, ir_value *v,
|
||||||
ir_block *ontrue, ir_block *onfalse)
|
ir_block *ontrue, ir_block *onfalse)
|
||||||
{
|
{
|
||||||
ir_instr *in;
|
ir_instr *in;
|
||||||
if (self->final) {
|
if (self->final) {
|
||||||
fprintf(stderr, "block already ended (%s)\n", self->label);
|
fprintf(stderr, "block already ended (%s)\n", self->label);
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
self->final = true;
|
self->final = true;
|
||||||
//in = ir_instr_new(self, (v->vtype == qc_string ? INSTR_IF_S : INSTR_IF_F));
|
//in = ir_instr_new(self, (v->vtype == qc_string ? INSTR_IF_S : INSTR_IF_F));
|
||||||
in = ir_instr_new(self, VINSTR_COND);
|
in = ir_instr_new(self, VINSTR_COND);
|
||||||
ir_instr_op(in, 0, v, false);
|
if (!in)
|
||||||
in->bops[0] = ontrue;
|
return false;
|
||||||
in->bops[1] = onfalse;
|
|
||||||
ir_block_instr_add(self, in);
|
|
||||||
|
|
||||||
ir_block_exits_add(self, ontrue);
|
if (!ir_instr_op(in, 0, v, false)) {
|
||||||
ir_block_exits_add(self, onfalse);
|
ir_instr_delete(in);
|
||||||
ir_block_entries_add(ontrue, self);
|
return false;
|
||||||
ir_block_entries_add(onfalse, self);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ir_block_create_jump(ir_block *self, ir_block *to)
|
in->bops[0] = ontrue;
|
||||||
|
in->bops[1] = onfalse;
|
||||||
|
|
||||||
|
if (!ir_block_instr_add(self, in))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!ir_block_exits_add(self, ontrue) ||
|
||||||
|
!ir_block_exits_add(self, onfalse) ||
|
||||||
|
!ir_block_entries_add(ontrue, self) ||
|
||||||
|
!ir_block_entries_add(onfalse, self) )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ir_block_create_jump(ir_block *self, ir_block *to)
|
||||||
{
|
{
|
||||||
ir_instr *in;
|
ir_instr *in;
|
||||||
if (self->final) {
|
if (self->final) {
|
||||||
fprintf(stderr, "block already ended (%s)\n", self->label);
|
fprintf(stderr, "block already ended (%s)\n", self->label);
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
self->final = true;
|
self->final = true;
|
||||||
in = ir_instr_new(self, VINSTR_JUMP);
|
in = ir_instr_new(self, VINSTR_JUMP);
|
||||||
in->bops[0] = to;
|
if (!in)
|
||||||
ir_block_instr_add(self, in);
|
return false;
|
||||||
|
|
||||||
ir_block_exits_add(self, to);
|
in->bops[0] = to;
|
||||||
ir_block_entries_add(to, self);
|
if (!ir_block_instr_add(self, in))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!ir_block_exits_add(self, to) ||
|
||||||
|
!ir_block_entries_add(to, self) )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ir_block_create_goto(ir_block *self, ir_block *to)
|
bool ir_block_create_goto(ir_block *self, ir_block *to)
|
||||||
{
|
{
|
||||||
ir_instr *in;
|
ir_instr *in;
|
||||||
if (self->final) {
|
if (self->final) {
|
||||||
fprintf(stderr, "block already ended (%s)\n", self->label);
|
fprintf(stderr, "block already ended (%s)\n", self->label);
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
self->final = true;
|
self->final = true;
|
||||||
in = ir_instr_new(self, INSTR_GOTO);
|
in = ir_instr_new(self, INSTR_GOTO);
|
||||||
in->bops[0] = to;
|
if (!in)
|
||||||
ir_block_instr_add(self, in);
|
return false;
|
||||||
|
|
||||||
ir_block_exits_add(self, to);
|
in->bops[0] = to;
|
||||||
ir_block_entries_add(to, self);
|
if (!ir_block_instr_add(self, in))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!ir_block_exits_add(self, to) ||
|
||||||
|
!ir_block_entries_add(to, self) )
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ir_instr* ir_block_create_phi(ir_block *self, const char *label, int ot)
|
ir_instr* ir_block_create_phi(ir_block *self, const char *label, int ot)
|
||||||
|
@ -628,9 +733,23 @@ ir_instr* ir_block_create_phi(ir_block *self, const char *label, int ot)
|
||||||
ir_value *out;
|
ir_value *out;
|
||||||
ir_instr *in;
|
ir_instr *in;
|
||||||
in = ir_instr_new(self, VINSTR_PHI);
|
in = ir_instr_new(self, VINSTR_PHI);
|
||||||
|
if (!in)
|
||||||
|
return NULL;
|
||||||
out = ir_value_out(self->owner, label, store_local, ot);
|
out = ir_value_out(self->owner, label, store_local, ot);
|
||||||
ir_instr_op(in, 0, out, true);
|
if (!out) {
|
||||||
ir_block_instr_add(self, in);
|
ir_instr_delete(in);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (!ir_instr_op(in, 0, out, true)) {
|
||||||
|
ir_instr_delete(in);
|
||||||
|
ir_value_delete(out);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (!ir_block_instr_add(self, in)) {
|
||||||
|
ir_instr_delete(in);
|
||||||
|
ir_value_delete(out);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
return in;
|
return in;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -639,7 +758,7 @@ ir_value* ir_phi_value(ir_instr *self)
|
||||||
return self->_ops[0];
|
return self->_ops[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
void ir_phi_add(ir_instr* self, ir_block *b, ir_value *v)
|
bool ir_phi_add(ir_instr* self, ir_block *b, ir_value *v)
|
||||||
{
|
{
|
||||||
ir_phi_entry_t pe;
|
ir_phi_entry_t pe;
|
||||||
|
|
||||||
|
@ -653,8 +772,9 @@ void ir_phi_add(ir_instr* self, ir_block *b, ir_value *v)
|
||||||
|
|
||||||
pe.value = v;
|
pe.value = v;
|
||||||
pe.from = b;
|
pe.from = b;
|
||||||
ir_value_reads_add(v, self);
|
if (!ir_value_reads_add(v, self))
|
||||||
ir_instr_phi_add(self, pe);
|
return false;
|
||||||
|
return ir_instr_phi_add(self, pe);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* binary op related code */
|
/* binary op related code */
|
||||||
|
@ -745,16 +865,34 @@ ir_value* ir_block_create_binop(ir_block *self,
|
||||||
};
|
};
|
||||||
if (ot == qc_void) {
|
if (ot == qc_void) {
|
||||||
/* The AST or parser were supposed to check this! */
|
/* The AST or parser were supposed to check this! */
|
||||||
abort();
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ir_value *out = ir_value_out(self->owner, label, store_local, ot);
|
ir_value *out = ir_value_out(self->owner, label, store_local, ot);
|
||||||
|
if (!out)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
ir_instr *in = ir_instr_new(self, opcode);
|
ir_instr *in = ir_instr_new(self, opcode);
|
||||||
ir_instr_op(in, 0, out, true);
|
if (!in) {
|
||||||
ir_instr_op(in, 1, left, false);
|
ir_value_delete(out);
|
||||||
ir_instr_op(in, 2, right, false);
|
return NULL;
|
||||||
ir_block_instr_add(self, in);
|
}
|
||||||
|
|
||||||
|
if (!ir_instr_op(in, 0, out, true) ||
|
||||||
|
!ir_instr_op(in, 1, left, false) ||
|
||||||
|
!ir_instr_op(in, 2, right, false) )
|
||||||
|
{
|
||||||
|
goto on_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ir_block_instr_add(self, in))
|
||||||
|
goto on_error;
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
|
on_error:
|
||||||
|
ir_value_delete(out);
|
||||||
|
ir_instr_delete(in);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ir_value* ir_block_create_add(ir_block *self,
|
ir_value* ir_block_create_add(ir_block *self,
|
||||||
|
@ -915,16 +1053,20 @@ ir_value* ir_block_create_div(ir_block *self,
|
||||||
* step before life-range calculation.
|
* step before life-range calculation.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void ir_block_naive_phi(ir_block *self);
|
static bool ir_block_naive_phi(ir_block *self);
|
||||||
void ir_function_naive_phi(ir_function *self)
|
bool ir_function_naive_phi(ir_function *self)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
for (i = 0; i < self->blocks_count; ++i)
|
for (i = 0; i < self->blocks_count; ++i)
|
||||||
ir_block_naive_phi(self->blocks[i]);
|
{
|
||||||
|
if (!ir_block_naive_phi(self->blocks[i]))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ir_naive_phi_emit_store(ir_block *block, size_t iid, ir_value *old, ir_value *what)
|
static bool ir_naive_phi_emit_store(ir_block *block, size_t iid, ir_value *old, ir_value *what)
|
||||||
{
|
{
|
||||||
ir_instr *instr;
|
ir_instr *instr;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
@ -937,9 +1079,11 @@ static void ir_naive_phi_emit_store(ir_block *block, size_t iid, ir_value *old,
|
||||||
for (i = block->instr_count; i > iid; --i)
|
for (i = block->instr_count; i > iid; --i)
|
||||||
block->instr[i] = block->instr[i-1];
|
block->instr[i] = block->instr[i-1];
|
||||||
block->instr[i] = instr;
|
block->instr[i] = instr;
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ir_block_naive_phi(ir_block *self)
|
static bool ir_block_naive_phi(ir_block *self)
|
||||||
{
|
{
|
||||||
size_t i, p, w;
|
size_t i, p, w;
|
||||||
/* FIXME: optionally, create_phi can add the phis
|
/* FIXME: optionally, create_phi can add the phis
|
||||||
|
@ -952,7 +1096,8 @@ static void ir_block_naive_phi(ir_block *self)
|
||||||
if (instr->opcode != VINSTR_PHI)
|
if (instr->opcode != VINSTR_PHI)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ir_block_instr_remove(self, i);
|
if (!ir_block_instr_remove(self, i))
|
||||||
|
return false;
|
||||||
--i; /* NOTE: i+1 below */
|
--i; /* NOTE: i+1 below */
|
||||||
|
|
||||||
for (p = 0; p < instr->phi_count; ++p)
|
for (p = 0; p < instr->phi_count; ++p)
|
||||||
|
@ -1008,6 +1153,7 @@ static void ir_block_naive_phi(ir_block *self)
|
||||||
}
|
}
|
||||||
ir_instr_delete(instr);
|
ir_instr_delete(instr);
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
@ -1057,8 +1203,8 @@ void ir_function_enumerate(ir_function *self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ir_block_life_propagate(ir_block *b, ir_block *prev, bool *changed);
|
static bool ir_block_life_propagate(ir_block *b, ir_block *prev, bool *changed);
|
||||||
void ir_function_calculate_liferanges(ir_function *self)
|
bool ir_function_calculate_liferanges(ir_function *self)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
bool changed;
|
bool changed;
|
||||||
|
@ -1069,9 +1215,13 @@ void ir_function_calculate_liferanges(ir_function *self)
|
||||||
for (i = 0; i != self->blocks_count; ++i)
|
for (i = 0; i != self->blocks_count; ++i)
|
||||||
{
|
{
|
||||||
if (self->blocks[i]->is_return)
|
if (self->blocks[i]->is_return)
|
||||||
ir_block_life_propagate(self->blocks[i], NULL, &changed);
|
{
|
||||||
|
if (!ir_block_life_propagate(self->blocks[i], NULL, &changed))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} while (changed);
|
} while (changed);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get information about which operand
|
/* Get information about which operand
|
||||||
|
@ -1121,7 +1271,7 @@ static bool ir_block_living_add_instr(ir_block *self, size_t eid)
|
||||||
return changed;
|
return changed;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ir_block_life_prop_previous(ir_block* self, ir_block *prev, bool *changed)
|
static bool ir_block_life_prop_previous(ir_block* self, ir_block *prev, bool *changed)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
/* values which have been read in a previous iteration are now
|
/* values which have been read in a previous iteration are now
|
||||||
|
@ -1133,7 +1283,8 @@ static void ir_block_life_prop_previous(ir_block* self, ir_block *prev, bool *ch
|
||||||
for (i = 0; i < self->living_count; ++i)
|
for (i = 0; i < self->living_count; ++i)
|
||||||
{
|
{
|
||||||
if (!ir_block_living_find(prev, self->living[i], NULL)) {
|
if (!ir_block_living_find(prev, self->living[i], NULL)) {
|
||||||
ir_block_living_remove(self, i);
|
if (!ir_block_living_remove(self, i))
|
||||||
|
return false;
|
||||||
--i;
|
--i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1145,14 +1296,15 @@ static void ir_block_life_prop_previous(ir_block* self, ir_block *prev, bool *ch
|
||||||
{
|
{
|
||||||
if (ir_block_living_find(self, prev->living[i], NULL))
|
if (ir_block_living_find(self, prev->living[i], NULL))
|
||||||
continue;
|
continue;
|
||||||
ir_block_living_add(self, prev->living[i]);
|
if (!ir_block_living_add(self, prev->living[i]))
|
||||||
|
return false;
|
||||||
/*
|
/*
|
||||||
printf("%s got from prev: %s\n", self->label, prev->living[i]->_name);
|
printf("%s got from prev: %s\n", self->label, prev->living[i]->_name);
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ir_block_life_propagate(ir_block *self, ir_block *prev, bool *changed)
|
static bool ir_block_life_propagate(ir_block *self, ir_block *prev, bool *changed)
|
||||||
{
|
{
|
||||||
ir_instr *instr;
|
ir_instr *instr;
|
||||||
ir_value *value;
|
ir_value *value;
|
||||||
|
@ -1167,7 +1319,10 @@ static void ir_block_life_propagate(ir_block *self, ir_block *prev, bool *change
|
||||||
MEM_VECTOR_INIT(&new_reads, v);
|
MEM_VECTOR_INIT(&new_reads, v);
|
||||||
|
|
||||||
if (prev)
|
if (prev)
|
||||||
ir_block_life_prop_previous(self, prev, changed);
|
{
|
||||||
|
if (!ir_block_life_prop_previous(self, prev, changed))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
i = self->instr_count;
|
i = self->instr_count;
|
||||||
while (i)
|
while (i)
|
||||||
|
@ -1184,7 +1339,10 @@ static void ir_block_life_propagate(ir_block *self, ir_block *prev, bool *change
|
||||||
*/
|
*/
|
||||||
/* fprintf(stderr, "read: %s\n", value->_name); */
|
/* fprintf(stderr, "read: %s\n", value->_name); */
|
||||||
if (!new_reads_t_v_find(&new_reads, value, NULL))
|
if (!new_reads_t_v_find(&new_reads, value, NULL))
|
||||||
new_reads_t_v_add(&new_reads, value);
|
{
|
||||||
|
if (!new_reads_t_v_add(&new_reads, value))
|
||||||
|
goto on_error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* See which operands are read and write operands */
|
/* See which operands are read and write operands */
|
||||||
|
@ -1212,7 +1370,10 @@ static void ir_block_life_propagate(ir_block *self, ir_block *prev, bool *change
|
||||||
*/
|
*/
|
||||||
/* fprintf(stderr, "read: %s\n", value->_name); */
|
/* fprintf(stderr, "read: %s\n", value->_name); */
|
||||||
if (!new_reads_t_v_find(&new_reads, value, NULL))
|
if (!new_reads_t_v_find(&new_reads, value, NULL))
|
||||||
new_reads_t_v_add(&new_reads, value);
|
{
|
||||||
|
if (!new_reads_t_v_add(&new_reads, value))
|
||||||
|
goto on_error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* write operands */
|
/* write operands */
|
||||||
|
@ -1254,9 +1415,13 @@ static void ir_block_life_propagate(ir_block *self, ir_block *prev, bool *change
|
||||||
*/
|
*/
|
||||||
*changed = *changed || tempbool;
|
*changed = *changed || tempbool;
|
||||||
/* Then remove */
|
/* Then remove */
|
||||||
ir_block_living_remove(self, idx);
|
if (!ir_block_living_remove(self, idx))
|
||||||
|
goto on_error;
|
||||||
if (in_reads)
|
if (in_reads)
|
||||||
new_reads_t_v_remove(&new_reads, readidx);
|
{
|
||||||
|
if (!new_reads_t_v_remove(&new_reads, readidx))
|
||||||
|
goto on_error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1269,14 +1434,15 @@ static void ir_block_life_propagate(ir_block *self, ir_block *prev, bool *change
|
||||||
for (rd = 0; rd < new_reads.v_count; ++rd)
|
for (rd = 0; rd < new_reads.v_count; ++rd)
|
||||||
{
|
{
|
||||||
if (!ir_block_living_find(self, new_reads.v[rd], NULL)) {
|
if (!ir_block_living_find(self, new_reads.v[rd], NULL)) {
|
||||||
ir_block_living_add(self, new_reads.v[rd]);
|
if (!ir_block_living_add(self, new_reads.v[rd]))
|
||||||
|
goto on_error;
|
||||||
}
|
}
|
||||||
if (!i && !self->entries_count) {
|
if (!i && !self->entries_count) {
|
||||||
/* fix the top */
|
/* fix the top */
|
||||||
*changed = *changed || ir_value_life_merge(new_reads.v[rd], instr->eid);
|
*changed = *changed || ir_value_life_merge(new_reads.v[rd], instr->eid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
new_reads_t_v_clear(&new_reads);
|
MEM_VECTOR_CLEAR(&new_reads, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self->run_id == self->owner->run_id)
|
if (self->run_id == self->owner->run_id)
|
||||||
|
@ -1288,4 +1454,9 @@ static void ir_block_life_propagate(ir_block *self, ir_block *prev, bool *change
|
||||||
ir_block *entry = self->entries[i];
|
ir_block *entry = self->entries[i];
|
||||||
ir_block_life_propagate(entry, self, changed);
|
ir_block_life_propagate(entry, self, changed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
on_error:
|
||||||
|
MEM_VECTOR_CLEAR(&new_reads, v);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
32
ir.h
32
ir.h
|
@ -67,8 +67,8 @@ ir_value* ir_value_out(struct ir_function_s *owner, const char *name, int st, in
|
||||||
void ir_value_delete(ir_value*);
|
void ir_value_delete(ir_value*);
|
||||||
void ir_value_set_name(ir_value*, const char *name);
|
void ir_value_set_name(ir_value*, const char *name);
|
||||||
|
|
||||||
MEM_VECTOR_PROTO(ir_value, struct ir_instr_s*, reads)
|
MEM_VECTOR_PROTO_ALL(ir_value, struct ir_instr_s*, reads)
|
||||||
MEM_VECTOR_PROTO(ir_value, struct ir_instr_s*, writes)
|
MEM_VECTOR_PROTO_ALL(ir_value, struct ir_instr_s*, writes)
|
||||||
|
|
||||||
bool ir_value_set_float(ir_value*, float f);
|
bool ir_value_set_float(ir_value*, float f);
|
||||||
bool ir_value_set_int(ir_value*, int i);
|
bool ir_value_set_int(ir_value*, int i);
|
||||||
|
@ -113,7 +113,7 @@ ir_instr* ir_instr_new(struct ir_block_s *owner, int opcode);
|
||||||
void ir_instr_delete(ir_instr*);
|
void ir_instr_delete(ir_instr*);
|
||||||
|
|
||||||
MEM_VECTOR_PROTO(ir_value, ir_phi_entry_t, phi)
|
MEM_VECTOR_PROTO(ir_value, ir_phi_entry_t, phi)
|
||||||
void ir_instr_op(ir_instr*, int op, ir_value *value, bool writing);
|
bool GMQCC_WARN ir_instr_op(ir_instr*, int op, ir_value *value, bool writing);
|
||||||
|
|
||||||
void ir_instr_dump(ir_instr* in, char *ind, int (*oprintf)(const char*,...));
|
void ir_instr_dump(ir_instr* in, char *ind, int (*oprintf)(const char*,...));
|
||||||
|
|
||||||
|
@ -140,7 +140,7 @@ typedef struct ir_block_s
|
||||||
ir_block* ir_block_new(struct ir_function_s *owner, const char *label);
|
ir_block* ir_block_new(struct ir_function_s *owner, const char *label);
|
||||||
void ir_block_delete(ir_block*);
|
void ir_block_delete(ir_block*);
|
||||||
|
|
||||||
void ir_block_set_label(ir_block*, const char *label);
|
bool ir_block_set_label(ir_block*, const char *label);
|
||||||
|
|
||||||
MEM_VECTOR_PROTO(ir_block, ir_instr*, instr)
|
MEM_VECTOR_PROTO(ir_block, ir_instr*, instr)
|
||||||
MEM_VECTOR_PROTO_ALL(ir_block, ir_block*, exits)
|
MEM_VECTOR_PROTO_ALL(ir_block, ir_block*, exits)
|
||||||
|
@ -157,11 +157,11 @@ ir_value* ir_block_create_mul(ir_block*, const char *label, ir_value *l, ir_valu
|
||||||
ir_value* ir_block_create_div(ir_block*, const char *label, ir_value *l, ir_value *r);
|
ir_value* ir_block_create_div(ir_block*, const char *label, ir_value *l, ir_value *r);
|
||||||
ir_instr* ir_block_create_phi(ir_block*, const char *label, int vtype);
|
ir_instr* ir_block_create_phi(ir_block*, const char *label, int vtype);
|
||||||
ir_value* ir_phi_value(ir_instr*);
|
ir_value* ir_phi_value(ir_instr*);
|
||||||
void ir_phi_add(ir_instr*, ir_block *b, ir_value *v);
|
bool ir_phi_add(ir_instr*, ir_block *b, ir_value *v);
|
||||||
|
|
||||||
void ir_block_create_return(ir_block*, ir_value *opt_value);
|
bool ir_block_create_return(ir_block*, ir_value *opt_value);
|
||||||
|
|
||||||
void ir_block_create_if(ir_block*, ir_value *cond,
|
bool ir_block_create_if(ir_block*, ir_value *cond,
|
||||||
ir_block *ontrue, ir_block *onfalse);
|
ir_block *ontrue, ir_block *onfalse);
|
||||||
/* A 'goto' is an actual 'goto' coded in QC, whereas
|
/* A 'goto' is an actual 'goto' coded in QC, whereas
|
||||||
* a 'jump' is a virtual construct which simply names the
|
* a 'jump' is a virtual construct which simply names the
|
||||||
|
@ -169,8 +169,8 @@ void ir_block_create_if(ir_block*, ir_value *cond,
|
||||||
* A goto usually becomes an OP_GOTO in the resulting code,
|
* A goto usually becomes an OP_GOTO in the resulting code,
|
||||||
* whereas a 'jump' usually doesn't add any actual instruction.
|
* whereas a 'jump' usually doesn't add any actual instruction.
|
||||||
*/
|
*/
|
||||||
void ir_block_create_jump(ir_block*, ir_block *to);
|
bool ir_block_create_jump(ir_block*, ir_block *to);
|
||||||
void ir_block_create_goto(ir_block*, ir_block *to);
|
bool ir_block_create_goto(ir_block*, ir_block *to);
|
||||||
|
|
||||||
MEM_VECTOR_PROTO_ALL(ir_block, ir_value*, living)
|
MEM_VECTOR_PROTO_ALL(ir_block, ir_value*, living)
|
||||||
|
|
||||||
|
@ -208,20 +208,20 @@ typedef struct ir_function_s
|
||||||
ir_function* ir_function_new(struct ir_builder_s *owner);
|
ir_function* ir_function_new(struct ir_builder_s *owner);
|
||||||
void ir_function_delete(ir_function*);
|
void ir_function_delete(ir_function*);
|
||||||
|
|
||||||
void ir_function_collect_value(ir_function*, ir_value *value);
|
bool GMQCC_WARN ir_function_collect_value(ir_function*, ir_value *value);
|
||||||
|
|
||||||
void ir_function_set_name(ir_function*, const char *name);
|
bool ir_function_set_name(ir_function*, const char *name);
|
||||||
MEM_VECTOR_PROTO(ir_function, int, params)
|
MEM_VECTOR_PROTO(ir_function, int, params)
|
||||||
MEM_VECTOR_PROTO(ir_function, ir_block*, blocks)
|
MEM_VECTOR_PROTO(ir_function, ir_block*, blocks)
|
||||||
|
|
||||||
ir_value* ir_function_get_local(ir_function *self, const char *name);
|
ir_value* ir_function_get_local(ir_function *self, const char *name);
|
||||||
ir_value* ir_function_create_local(ir_function *self, const char *name, int vtype);
|
ir_value* ir_function_create_local(ir_function *self, const char *name, int vtype);
|
||||||
|
|
||||||
void ir_function_finalize(ir_function*);
|
bool ir_function_finalize(ir_function*);
|
||||||
/*
|
/*
|
||||||
void ir_function_naive_phi(ir_function*);
|
bool ir_function_naive_phi(ir_function*);
|
||||||
void ir_function_enumerate(ir_function*);
|
bool ir_function_enumerate(ir_function*);
|
||||||
void ir_function_calculate_liferanges(ir_function*);
|
bool ir_function_calculate_liferanges(ir_function*);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ir_block* ir_function_create_block(ir_function*, const char *label);
|
ir_block* ir_function_create_block(ir_function*, const char *label);
|
||||||
|
@ -239,7 +239,7 @@ typedef struct ir_builder_s
|
||||||
ir_builder* ir_builder_new(const char *modulename);
|
ir_builder* ir_builder_new(const char *modulename);
|
||||||
void ir_builder_delete(ir_builder*);
|
void ir_builder_delete(ir_builder*);
|
||||||
|
|
||||||
void ir_builder_set_name(ir_builder *self, const char *name);
|
bool ir_builder_set_name(ir_builder *self, const char *name);
|
||||||
|
|
||||||
MEM_VECTOR_PROTO(ir_builder, ir_function*, functions)
|
MEM_VECTOR_PROTO(ir_builder, ir_function*, functions)
|
||||||
MEM_VECTOR_PROTO(ir_builder, ir_value*, globals)
|
MEM_VECTOR_PROTO(ir_builder, ir_value*, globals)
|
||||||
|
|
Loading…
Reference in a new issue