From: Wolfgang Bumiller Date: Wed, 26 Dec 2012 21:09:54 +0000 (+0100) Subject: factoring out temp-slot-assignment and using it for the declared locals too, makes... X-Git-Tag: before-library~481 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=1cca992a8ee07a9c427b3a115864dffbaf8458a7;p=xonotic%2Fgmqcc.git factoring out temp-slot-assignment and using it for the declared locals too, makes -Olocal-temps more effective --- diff --git a/ir.c b/ir.c index 9a19a59..6145c07 100644 --- a/ir.c +++ b/ir.c @@ -2133,11 +2133,13 @@ typedef struct { bool *unique; } function_allocator; -static bool function_allocator_alloc(function_allocator *alloc, const ir_value *var) +static bool function_allocator_alloc(function_allocator *alloc, ir_value *var) { ir_value *slot; size_t vsize = ir_value_sizeof(var); + var->code.local = vec_size(alloc->locals); + slot = ir_value_var("reg", store_global, var->vtype); if (!slot) return false; @@ -2156,13 +2158,54 @@ localerror: return false; } +static bool ir_function_allocator_assign(ir_function *self, function_allocator *alloc, ir_value *v) +{ + size_t a; + ir_value *slot; + + for (a = 0; a < vec_size(alloc->locals); ++a) + { + /* if it's reserved for a unique liferange: skip */ + if (alloc->unique[a]) + continue; + + slot = alloc->locals[a]; + + /* never resize parameters + * will be required later when overlapping temps + locals + */ + if (a < vec_size(self->params) && + alloc->sizes[a] < ir_value_sizeof(v)) + { + continue; + } + + if (ir_values_overlap(v, slot)) + continue; + + if (!ir_value_life_merge_into(slot, v)) + return false; + + /* adjust size for this slot */ + if (alloc->sizes[a] < ir_value_sizeof(v)) + alloc->sizes[a] = ir_value_sizeof(v); + + v->code.local = a; + return true; + } + if (a >= vec_size(alloc->locals)) { + if (!function_allocator_alloc(alloc, v)) + return false; + } + return true; +} + bool ir_function_allocate_locals(ir_function *self) { - size_t i, a; + size_t i; bool retval = true; size_t pos; - ir_value *slot; ir_value *v; function_allocator alloc; @@ -2179,9 +2222,19 @@ bool ir_function_allocate_locals(ir_function *self) { if (!OPTS_OPTIMIZATION(OPTIM_LOCAL_TEMPS)) self->locals[i]->unique_life = true; + else if (i >= vec_size(self->params)) + break; if (!function_allocator_alloc(&alloc, self->locals[i])) goto error; } + for (; i < vec_size(self->locals); ++i) + { + v = self->locals[i]; + if (!vec_size(v->life)) + continue; + if (!ir_function_allocator_assign(self, &alloc, v)) + goto error; + } /* Allocate a slot for any value that still exists */ for (i = 0; i < vec_size(self->values); ++i) @@ -2233,41 +2286,8 @@ bool ir_function_allocate_locals(ir_function *self) } } - for (a = 0; a < vec_size(alloc.locals); ++a) - { - /* if it's reserved for a unique liferange: skip */ - if (alloc.unique[a]) - continue; - - slot = alloc.locals[a]; - - /* never resize parameters - * will be required later when overlapping temps + locals - */ - if (a < vec_size(self->params) && - alloc.sizes[a] < ir_value_sizeof(v)) - { - continue; - } - - if (ir_values_overlap(v, slot)) - continue; - - if (!ir_value_life_merge_into(slot, v)) - goto error; - - /* adjust size for this slot */ - if (alloc.sizes[a] < ir_value_sizeof(v)) - alloc.sizes[a] = ir_value_sizeof(v); - - self->values[i]->code.local = a; - break; - } - if (a >= vec_size(alloc.locals)) { - self->values[i]->code.local = vec_size(alloc.locals); - if (!function_allocator_alloc(&alloc, v)) - goto error; - } + if (!ir_function_allocator_assign(self, &alloc, v)) + goto error; } if (!alloc.sizes) { @@ -2291,7 +2311,7 @@ bool ir_function_allocate_locals(ir_function *self) /* Locals need to know their new position */ for (i = 0; i < vec_size(self->locals); ++i) { - self->locals[i]->code.local = alloc.positions[i]; + self->locals[i]->code.local = alloc.positions[self->locals[i]->code.local]; } /* Take over the actual slot positions on values */ for (i = 0; i < vec_size(self->values); ++i) {