mirror of
https://github.com/DarkPlacesEngine/gmqcc.git
synced 2025-03-22 10:41:43 +00:00
Try generating the function-locals in a later pass; with the option to overlap them.
This commit is contained in:
parent
67bc99223d
commit
b8c61f2f88
2 changed files with 66 additions and 24 deletions
89
ir.c
89
ir.c
|
@ -2632,7 +2632,7 @@ static bool ir_block_life_propagate(ir_block *self, ir_block *prev, bool *change
|
|||
*
|
||||
* Breaking conventions is annoying...
|
||||
*/
|
||||
static bool ir_builder_gen_global(ir_builder *self, ir_value *global, bool islocal);
|
||||
static bool ir_builder_gen_global(ir_builder *self, ir_value *global, bool islocal, bool defs_only);
|
||||
|
||||
static bool gen_global_field(ir_value *global)
|
||||
{
|
||||
|
@ -3055,24 +3055,8 @@ static bool gen_global_function(ir_builder *ir, ir_value *global)
|
|||
fun.argsize[i] = type_sizeof_[irfun->params[i]];
|
||||
}
|
||||
|
||||
fun.firstlocal = vec_size(code_globals);
|
||||
|
||||
fun.locals = irfun->allocated_locals;
|
||||
for (i = 0; i < vec_size(irfun->locals); ++i) {
|
||||
if (!ir_builder_gen_global(ir, irfun->locals[i], true)) {
|
||||
irerror(irfun->locals[i]->context, "Failed to generate local %s", irfun->locals[i]->name);
|
||||
return false;
|
||||
}
|
||||
ir_value_code_setaddr(irfun->locals[i], fun.firstlocal + irfun->locals[i]->code.local);
|
||||
}
|
||||
for (i = 0; i < vec_size(irfun->values); ++i)
|
||||
{
|
||||
/* generate code.globaladdr for ssa values */
|
||||
ir_value *v = irfun->values[i];
|
||||
ir_value_code_setaddr(v, fun.firstlocal + v->code.local);
|
||||
}
|
||||
for (i = vec_size(code_globals); i < fun.firstlocal + irfun->allocated_locals; ++i)
|
||||
vec_push(code_globals, 0);
|
||||
fun.firstlocal = 0;
|
||||
fun.locals = irfun->allocated_locals;
|
||||
|
||||
if (irfun->builtin)
|
||||
fun.entry = irfun->builtin+1;
|
||||
|
@ -3142,6 +3126,38 @@ static bool gen_function_extparam_copy(ir_function *self)
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool gen_function_locals(ir_builder *ir, ir_value *global)
|
||||
{
|
||||
prog_section_function *def;
|
||||
ir_function *irfun;
|
||||
size_t i;
|
||||
uint32_t firstlocal;
|
||||
|
||||
irfun = global->constval.vfunc;
|
||||
def = code_functions + irfun->code_function_def;
|
||||
|
||||
if (opts.g || (irfun->flags & IR_FLAG_MASK_NO_OVERLAP))
|
||||
firstlocal = def->firstlocal = vec_size(code_globals);
|
||||
else
|
||||
firstlocal = def->firstlocal = ir->first_common_local;
|
||||
|
||||
for (i = vec_size(code_globals); i < firstlocal + irfun->allocated_locals; ++i)
|
||||
vec_push(code_globals, 0);
|
||||
for (i = 0; i < vec_size(irfun->locals); ++i) {
|
||||
ir_value_code_setaddr(irfun->locals[i], firstlocal + irfun->locals[i]->code.local);
|
||||
if (!ir_builder_gen_global(ir, irfun->locals[i], true, true)) {
|
||||
irerror(irfun->locals[i]->context, "failed to generate local %s", irfun->locals[i]->name);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < vec_size(irfun->values); ++i)
|
||||
{
|
||||
ir_value *v = irfun->values[i];
|
||||
ir_value_code_setaddr(v, firstlocal + v->code.local);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool gen_global_function_code(ir_builder *ir, ir_value *global)
|
||||
{
|
||||
prog_section_function *fundef;
|
||||
|
@ -3169,6 +3185,10 @@ static bool gen_global_function_code(ir_builder *ir, ir_value *global)
|
|||
fundef = &code_functions[irfun->code_function_def];
|
||||
|
||||
fundef->entry = vec_size(code_statements);
|
||||
if (!gen_function_locals(ir, global)) {
|
||||
irerror(irfun->context, "Failed to generate locals for function %s", irfun->name);
|
||||
return false;
|
||||
}
|
||||
if (!gen_function_extparam_copy(irfun)) {
|
||||
irerror(irfun->context, "Failed to generate extparam-copy code for function %s", irfun->name);
|
||||
return false;
|
||||
|
@ -3236,7 +3256,7 @@ static void gen_vector_fields(prog_section_field fld, const char *name)
|
|||
}
|
||||
}
|
||||
|
||||
static bool ir_builder_gen_global(ir_builder *self, ir_value *global, bool islocal)
|
||||
static bool ir_builder_gen_global(ir_builder *self, ir_value *global, bool islocal, bool defs_only)
|
||||
{
|
||||
size_t i;
|
||||
int32_t *iptr;
|
||||
|
@ -3260,7 +3280,18 @@ static bool ir_builder_gen_global(ir_builder *self, ir_value *global, bool isloc
|
|||
}
|
||||
else
|
||||
def.name = 0;
|
||||
if (defs_only) {
|
||||
def.offset = ir_value_code_addr(global);
|
||||
vec_push(code_defs, def);
|
||||
if (global->vtype == TYPE_VECTOR)
|
||||
gen_vector_defs(def, global->name);
|
||||
else if (global->vtype == TYPE_FIELD && global->fieldtype == TYPE_VECTOR)
|
||||
gen_vector_defs(def, global->name);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (defs_only)
|
||||
return true;
|
||||
|
||||
switch (global->vtype)
|
||||
{
|
||||
|
@ -3293,7 +3324,8 @@ static bool ir_builder_gen_global(ir_builder *self, ir_value *global, bool isloc
|
|||
case TYPE_FIELD:
|
||||
if (pushdef) {
|
||||
vec_push(code_defs, def);
|
||||
gen_vector_defs(def, global->name);
|
||||
if (global->fieldtype == TYPE_VECTOR)
|
||||
gen_vector_defs(def, global->name);
|
||||
}
|
||||
return gen_global_field(global);
|
||||
case TYPE_ENTITY:
|
||||
|
@ -3465,7 +3497,7 @@ bool ir_builder_generate(ir_builder *self, const char *filename)
|
|||
{
|
||||
prog_section_statement stmt;
|
||||
size_t i;
|
||||
char *lnofile = NULL;
|
||||
char *lnofile = NULL;
|
||||
|
||||
code_init();
|
||||
|
||||
|
@ -3476,13 +3508,16 @@ bool ir_builder_generate(ir_builder *self, const char *filename)
|
|||
|
||||
for (i = 0; i < vec_size(self->globals); ++i)
|
||||
{
|
||||
if (!ir_builder_gen_global(self, self->globals[i], false)) {
|
||||
if (!ir_builder_gen_global(self, self->globals[i], false, false)) {
|
||||
return false;
|
||||
}
|
||||
if (self->globals[i]->vtype == TYPE_FUNCTION) {
|
||||
ir_function *func = self->globals[i]->constval.vfunc;
|
||||
if (func && self->max_locals < func->allocated_locals)
|
||||
if (func && self->max_locals < func->allocated_locals &&
|
||||
!(func->flags & IR_FLAG_MASK_NO_OVERLAP))
|
||||
{
|
||||
self->max_locals = func->allocated_locals;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3493,6 +3528,12 @@ bool ir_builder_generate(ir_builder *self, const char *filename)
|
|||
}
|
||||
}
|
||||
|
||||
/* generate common locals */
|
||||
self->first_common_local = vec_size(code_globals);
|
||||
for (i = 0; i < self->max_locals; ++i) {
|
||||
vec_push(code_globals, 0);
|
||||
}
|
||||
|
||||
/* generate function code */
|
||||
for (i = 0; i < vec_size(self->globals); ++i)
|
||||
{
|
||||
|
|
1
ir.h
1
ir.h
|
@ -314,6 +314,7 @@ typedef struct ir_builder_s
|
|||
|
||||
/* the highest func->allocated_locals */
|
||||
size_t max_locals;
|
||||
uint32_t first_common_local;
|
||||
|
||||
const char **filenames;
|
||||
qcint *filestrings;
|
||||
|
|
Loading…
Reference in a new issue