From e96eb8f62c5310ad53e6b8881e80527d65dc5f30 Mon Sep 17 00:00:00 2001 From: Wolfgang Bumiller Date: Wed, 17 Apr 2013 17:38:34 +0200 Subject: [PATCH] generate extparam protos before finalizing functions - not adding immediates/globals to liferange calc in MUL_VF/FV/params anymore --- ir.c | 68 ++++++++++++++++++++++++++++++++++++++------------------ ir.h | 4 ++++ parser.c | 6 +++++ 3 files changed, 56 insertions(+), 22 deletions(-) diff --git a/ir.c b/ir.c index 772ad1b..b178d3e 100644 --- a/ir.c +++ b/ir.c @@ -211,7 +211,6 @@ uint16_t type_not_instr[TYPE_COUNT] = { }; /* protos */ -static ir_value* ir_gen_extparam_proto(ir_builder *ir); static void ir_gen_extparam (ir_builder *ir); /* error functions */ @@ -309,6 +308,7 @@ ir_builder* ir_builder_new(const char *modulename) self->max_globaltemps = 0; self->first_common_local = 0; self->max_locals = 0; + self->max_used_params = 0; self->str_immediate = 0; self->name = NULL; @@ -1706,8 +1706,14 @@ ir_value* ir_call_value(ir_instr *self) void ir_call_param(ir_instr* self, ir_value *v) { + size_t *maxparams, param; vec_push(self->params, v); vec_push(v->reads, self); + + param = vec_size(self->params); + maxparams = &self->owner->owner->owner->max_used_params; + if (param > *maxparams) + *maxparams = param; } /* binary op related code */ @@ -2182,17 +2188,7 @@ bool ir_function_allocate_locals(ir_function *self) if (param < 8) ir_value_code_setaddr(v, OFS_PARM0 + 3*param); else { - size_t nprotos = vec_size(self->owner->extparam_protos); - ir_value *ep; - param -= 8; - if (nprotos > param) - ep = self->owner->extparam_protos[param]; - else - { - ep = ir_gen_extparam_proto(self->owner); - while (++nprotos <= param) - ep = ir_gen_extparam_proto(self->owner); - } + ir_value *ep = self->owner->extparam_protos[param-=8]; ir_instr_op(v->writes[0], 0, ep, true); call->params[param+8] = ep; } @@ -2450,20 +2446,30 @@ static bool ir_block_life_propagate(ir_block *self, bool *changed) if (instr->opcode == INSTR_MUL_VF) { value = instr->_ops[2]; - /* the float source will get an additional lifetime */ - if (ir_value_life_merge(value, instr->eid+1)) - *changed = true; - if (value->memberof && ir_value_life_merge(value->memberof, instr->eid+1)) - *changed = true; + if (value->store == store_value || + value->store == store_local || + value->store == store_param) + { + /* the float source will get an additional lifetime */ + if (ir_value_life_merge(value, instr->eid+1)) + *changed = true; + if (value->memberof && ir_value_life_merge(value->memberof, instr->eid+1)) + *changed = true; + } } else if (instr->opcode == INSTR_MUL_FV || instr->opcode == INSTR_LOAD_V) { value = instr->_ops[1]; - /* the float source will get an additional lifetime */ - if (ir_value_life_merge(value, instr->eid+1)) - *changed = true; - if (value->memberof && ir_value_life_merge(value->memberof, instr->eid+1)) - *changed = true; + if (value->store == store_value || + value->store == store_local || + value->store == store_param) + { + /* the float source will get an additional lifetime */ + if (ir_value_life_merge(value, instr->eid+1)) + *changed = true; + if (value->memberof && ir_value_life_merge(value->memberof, instr->eid+1)) + *changed = true; + } } for (o = 0; o < 3; ++o) @@ -2499,6 +2505,10 @@ static bool ir_block_life_propagate(ir_block *self, bool *changed) for (p = 0; p < vec_size(instr->phi); ++p) { value = instr->phi[p].value; + if (value->store != store_value && + value->store != store_local && + value->store != store_param) + continue; if (!vec_ir_value_find(self->living, value, NULL)) vec_push(self->living, value); /* reading adds the full vector */ @@ -2519,6 +2529,10 @@ static bool ir_block_life_propagate(ir_block *self, bool *changed) for (p = 0; p < vec_size(instr->params); ++p) { value = instr->params[p]; + if (value->store != store_value && + value->store != store_local && + value->store != store_param) + continue; if (!vec_ir_value_find(self->living, value, NULL)) vec_push(self->living, value); /* reading adds the full vector */ @@ -3571,6 +3585,16 @@ static bool ir_builder_gen_field(ir_builder *self, ir_value *field) return field->code.globaladdr >= 0; } +bool ir_builder_prepare(ir_builder *self) +{ + size_t extparams = self->max_used_params; + if (extparams > 8) { + for (extparams -= 8; extparams; --extparams) + ir_gen_extparam_proto(self); + } + return true; +} + bool ir_builder_generate(ir_builder *self, const char *filename) { prog_section_statement stmt; diff --git a/ir.h b/ir.h index bce85f4..49da889 100644 --- a/ir.h +++ b/ir.h @@ -325,6 +325,9 @@ typedef struct ir_builder_s uint32_t first_common_local; uint32_t first_common_globaltemp; + /* highest number of parameters */ + size_t max_used_params; + const char **filenames; qcint *filestrings; /* we cache the #IMMEDIATE string here */ @@ -349,6 +352,7 @@ ir_value* ir_builder_create_field(ir_builder*, const char *name, int vtype); ir_value* ir_builder_get_va_count(ir_builder*); +bool ir_builder_prepare(ir_builder *self); bool ir_builder_generate(ir_builder *self, const char *filename); void ir_builder_dump(ir_builder*, int (*oprintf)(const char*, ...)); diff --git a/parser.c b/parser.c index db94289..174c3ad 100644 --- a/parser.c +++ b/parser.c @@ -6334,6 +6334,12 @@ bool parser_finish(parser_t *parser, const char *output) } if (OPTS_OPTION_BOOL(OPTION_DUMP)) ir_builder_dump(ir, con_out); + + if (!ir_builder_prepare(ir)) { + con_out("failed to prepare builder for output\n"); + ir_builder_delete(ir); + return false; + } #if 0 for (i = 0; i < vec_size(parser->functions); ++i) { if (!ir_function_finalize(parser->functions[i]->ir_func)) { -- 2.39.5