X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=ir.c;h=2ac7ff1bdc7500a5090785b45206dc8edf13af71;hb=5bc815c63f4b0ba0fd500f359a7b2e379c6b7fbb;hp=5161108c80dfe6d6600d2831bb7db50bfd5b1364;hpb=3119a95a89e991e42cd52c8ce2c17ab78542c1c2;p=xonotic%2Fgmqcc.git diff --git a/ir.c b/ir.c index 5161108..2ac7ff1 100644 --- a/ir.c +++ b/ir.c @@ -45,7 +45,7 @@ const char *type_name[TYPE_COUNT] = { "array" }; -size_t type_sizeof[TYPE_COUNT] = { +size_t type_sizeof_[TYPE_COUNT] = { 1, /* TYPE_VOID */ 1, /* TYPE_STRING */ 1, /* TYPE_FLOAT */ @@ -527,7 +527,8 @@ static bool instr_is_operation(uint16_t op) (op >= INSTR_LOAD_F && op <= INSTR_LOAD_FNC) || (op == INSTR_ADDRESS) || (op >= INSTR_NOT_F && op <= INSTR_NOT_FNC) || - (op >= INSTR_AND && op <= INSTR_BITOR) ); + (op >= INSTR_AND && op <= INSTR_BITOR) || + (op >= INSTR_CALL0 && op <= INSTR_CALL8) ); } bool ir_function_pass_peephole(ir_function *self) @@ -638,7 +639,7 @@ bool ir_function_pass_peephole(ir_function *self) return true; } -bool ir_function_pass_tailcall(ir_function *self) +bool ir_function_pass_tailrecursion(ir_function *self) { size_t b, p; @@ -738,8 +739,8 @@ bool ir_function_finalize(ir_function *self) } if (OPTS_OPTIMIZATION(OPTIM_TAIL_RECURSION)) { - if (!ir_function_pass_tailcall(self)) { - irerror(self->context, "tailcall optimization pass broke something in `%s`", self->name); + if (!ir_function_pass_tailrecursion(self)) { + irerror(self->context, "tail-recursion optimization pass broke something in `%s`", self->name); return false; } } @@ -1038,6 +1039,13 @@ ir_value* ir_value_vector_member(ir_value *self, unsigned int member) return m; } +static GMQCC_INLINE size_t ir_value_sizeof(const ir_value *self) +{ + if (self->vtype == TYPE_FIELD && self->fieldtype == TYPE_VECTOR) + return type_sizeof_[TYPE_VECTOR]; + return type_sizeof_[self->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); @@ -1115,7 +1123,7 @@ static char *ir_strdup(const char *str) { if (str && !*str) { /* actually dup empty strings */ - char *out = mem_a(1); + char *out = (char*)mem_a(1); *out = 0; return out; } @@ -1535,7 +1543,7 @@ ir_instr* ir_block_create_phi(ir_block *self, lex_ctx ctx, const char *label, in ir_value *out; ir_instr *in; if (!ir_check_unreachable(self)) - return false; + return NULL; in = ir_instr_new(ctx, self, VINSTR_PHI); if (!in) return NULL; @@ -1582,7 +1590,7 @@ ir_instr* ir_block_create_call(ir_block *self, lex_ctx ctx, const char *label, i ir_value *out; ir_instr *in; if (!ir_check_unreachable(self)) - return false; + return NULL; in = ir_instr_new(ctx, self, (noreturn ? VINSTR_NRCALL : INSTR_CALL0)); if (!in) return NULL; @@ -1603,6 +1611,15 @@ ir_instr* ir_block_create_call(ir_block *self, lex_ctx ctx, const char *label, i return NULL; } vec_push(self->instr, in); + /* + if (noreturn) { + if (!ir_block_create_return(self, ctx, NULL)) { + compile_error(ctx, "internal error: failed to generate dummy-return instruction"); + ir_instr_delete(in); + return NULL; + } + } + */ return in; } @@ -2233,7 +2250,7 @@ typedef struct { static bool function_allocator_alloc(function_allocator *alloc, const ir_value *var) { ir_value *slot; - size_t vsize = type_sizeof[var->vtype]; + size_t vsize = ir_value_sizeof(var); slot = ir_value_var("reg", store_global, var->vtype); if (!slot) @@ -2274,7 +2291,9 @@ bool ir_function_allocate_locals(ir_function *self) for (i = 0; i < vec_size(self->locals); ++i) { +#if 0 if (!OPTS_OPTIMIZATION(OPTIM_LOCALTEMPS)) +#endif self->locals[i]->unique_life = true; if (!function_allocator_alloc(&alloc, self->locals[i])) goto error; @@ -2300,7 +2319,7 @@ bool ir_function_allocate_locals(ir_function *self) * will be required later when overlapping temps + locals */ if (a < vec_size(self->params) && - alloc.sizes[a] < type_sizeof[v->vtype]) + alloc.sizes[a] < ir_value_sizeof(v)) { continue; } @@ -2312,8 +2331,8 @@ bool ir_function_allocate_locals(ir_function *self) goto error; /* adjust size for this slot */ - if (alloc.sizes[a] < type_sizeof[v->vtype]) - alloc.sizes[a] = type_sizeof[v->vtype]; + if (alloc.sizes[a] < ir_value_sizeof(v)) + alloc.sizes[a] = ir_value_sizeof(v); self->values[i]->code.local = a; break; @@ -2360,6 +2379,7 @@ error: cleanup: for (i = 0; i < vec_size(alloc.locals); ++i) ir_value_delete(alloc.locals[i]); + vec_free(alloc.unique); vec_free(alloc.locals); vec_free(alloc.sizes); vec_free(alloc.positions); @@ -2891,11 +2911,11 @@ tailcall: code_push_statement(&stmt, instr->context.line); retvalue = instr->_ops[0]; - if (retvalue && retvalue->store != store_return && vec_size(retvalue->life)) + if (retvalue && retvalue->store != store_return && (vec_size(retvalue->life) || retvalue->store == store_global)) { /* not to be kept in OFS_RETURN */ - if (retvalue->vtype == TYPE_FIELD) - stmt.opcode = field_store_instr[retvalue->vtype]; + if (retvalue->vtype == TYPE_FIELD && OPTS_FLAG(ADJUST_VECTOR_FIELDS)) + stmt.opcode = field_store_instr[retvalue->fieldtype]; else stmt.opcode = type_store_instr[retvalue->vtype]; stmt.o1.u1 = OFS_RETURN; @@ -3012,9 +3032,6 @@ static bool gen_global_function(ir_builder *ir, ir_value *global) ir_function *irfun; size_t i; -#ifndef NEW_ALLOC_STRAT - size_t local_var_end; -#endif if (!global->hasvalue || (!global->constval.vfunc)) { @@ -3035,40 +3052,11 @@ static bool gen_global_function(ir_builder *ir, ir_value *global) if ((int32_t)i >= fun.nargs) fun.argsize[i] = 0; else - fun.argsize[i] = type_sizeof[irfun->params[i]]; + fun.argsize[i] = type_sizeof_[irfun->params[i]]; } fun.firstlocal = vec_size(code_globals); -#ifndef NEW_ALLOC_STRAT - local_var_end = fun.firstlocal; - 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; - } - } - if (vec_size(irfun->locals)) { - ir_value *last = vec_last(irfun->locals); - local_var_end = last->code.globaladdr; - if (last->vtype == TYPE_FIELD && last->fieldtype == TYPE_VECTOR) - local_var_end += type_sizeof[TYPE_VECTOR]; - else - local_var_end += type_sizeof[last->vtype]; - } - 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, local_var_end + v->code.local); - } - for (i = 0; i < irfun->allocated_locals; ++i) { - /* fill the locals with zeros */ - vec_push(code_globals, 0); - } - - fun.locals = vec_size(code_globals) - fun.firstlocal; -#else fun.locals = irfun->allocated_locals; for (i = 0; i < vec_size(irfun->locals); ++i) { if (!ir_builder_gen_global(ir, irfun->locals[i], true)) { @@ -3077,16 +3065,14 @@ static bool gen_global_function(ir_builder *ir, ir_value *global) } ir_value_code_setaddr(irfun->locals[i], fun.firstlocal + irfun->locals[i]->code.local); } - for (i = vec_size(code_globals) - fun.firstlocal; i < fun.locals; ++i) { - vec_push(code_globals, 0); - } 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); } -#endif + for (i = vec_size(code_globals); i < fun.firstlocal + irfun->allocated_locals; ++i) + vec_push(code_globals, 0); if (irfun->builtin) fun.entry = irfun->builtin+1; @@ -3342,14 +3328,14 @@ static bool ir_builder_gen_global(ir_builder *self, ir_value *global, bool isloc vec_push(code_globals, iptr[0]); if (global->code.globaladdr < 0) return false; - for (d = 1; d < type_sizeof[global->vtype]; ++d) { + for (d = 1; d < type_sizeof_[global->vtype]; ++d) { vec_push(code_globals, iptr[d]); } } else { vec_push(code_globals, 0); if (global->code.globaladdr < 0) return false; - for (d = 1; d < type_sizeof[global->vtype]; ++d) { + for (d = 1; d < type_sizeof_[global->vtype]; ++d) { vec_push(code_globals, 0); } } @@ -3380,7 +3366,7 @@ static bool ir_builder_gen_global(ir_builder *self, ir_value *global, bool isloc /* assume biggest type */ ir_value_code_setaddr(global, vec_size(code_globals)); vec_push(code_globals, 0); - for (i = 1; i < type_sizeof[TYPE_VARIANT]; ++i) + for (i = 1; i < type_sizeof_[TYPE_VARIANT]; ++i) vec_push(code_globals, 0); return true; default: @@ -3393,7 +3379,7 @@ static bool ir_builder_gen_global(ir_builder *self, ir_value *global, bool isloc static void ir_builder_prepare_field(ir_value *field) { - field->code.fieldaddr = code_alloc_field(type_sizeof[field->fieldtype]); + field->code.fieldaddr = code_alloc_field(type_sizeof_[field->fieldtype]); } static bool ir_builder_gen_field(ir_builder *self, ir_value *field)