X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=ir.c;h=5d8085a18947e6fddbf3998b565afe71394c5eaa;hb=8e1cd4b1df819081c342f5fa341d6de942d2f476;hp=a641310644dc950712894eef33cfe9965c9c1d09;hpb=7fc88cfe5b53e6c9740f48335206d5a2b7d03bcb;p=xonotic%2Fgmqcc.git diff --git a/ir.c b/ir.c index a641310..5d8085a 100644 --- a/ir.c +++ b/ir.c @@ -83,11 +83,11 @@ uint16_t type_store_instr[TYPE_COUNT] = { INSTR_STORE_V, /* variant, should never be accessed */ - AINSTR_END, /* struct */ - AINSTR_END, /* union */ - AINSTR_END, /* array */ - AINSTR_END, /* nil */ - AINSTR_END, /* noexpr */ + VINSTR_END, /* struct */ + VINSTR_END, /* union */ + VINSTR_END, /* array */ + VINSTR_END, /* nil */ + VINSTR_END, /* noexpr */ }; uint16_t field_store_instr[TYPE_COUNT] = { @@ -107,11 +107,11 @@ uint16_t field_store_instr[TYPE_COUNT] = { INSTR_STORE_V, /* variant, should never be accessed */ - AINSTR_END, /* struct */ - AINSTR_END, /* union */ - AINSTR_END, /* array */ - AINSTR_END, /* nil */ - AINSTR_END, /* noexpr */ + VINSTR_END, /* struct */ + VINSTR_END, /* union */ + VINSTR_END, /* array */ + VINSTR_END, /* nil */ + VINSTR_END, /* noexpr */ }; uint16_t type_storep_instr[TYPE_COUNT] = { @@ -131,11 +131,11 @@ uint16_t type_storep_instr[TYPE_COUNT] = { INSTR_STOREP_V, /* variant, should never be accessed */ - AINSTR_END, /* struct */ - AINSTR_END, /* union */ - AINSTR_END, /* array */ - AINSTR_END, /* nil */ - AINSTR_END, /* noexpr */ + VINSTR_END, /* struct */ + VINSTR_END, /* union */ + VINSTR_END, /* array */ + VINSTR_END, /* nil */ + VINSTR_END, /* noexpr */ }; uint16_t type_eq_instr[TYPE_COUNT] = { @@ -155,11 +155,11 @@ uint16_t type_eq_instr[TYPE_COUNT] = { INSTR_EQ_V, /* variant, should never be accessed */ - AINSTR_END, /* struct */ - AINSTR_END, /* union */ - AINSTR_END, /* array */ - AINSTR_END, /* nil */ - AINSTR_END, /* noexpr */ + VINSTR_END, /* struct */ + VINSTR_END, /* union */ + VINSTR_END, /* array */ + VINSTR_END, /* nil */ + VINSTR_END, /* noexpr */ }; uint16_t type_ne_instr[TYPE_COUNT] = { @@ -179,11 +179,11 @@ uint16_t type_ne_instr[TYPE_COUNT] = { INSTR_NE_V, /* variant, should never be accessed */ - AINSTR_END, /* struct */ - AINSTR_END, /* union */ - AINSTR_END, /* array */ - AINSTR_END, /* nil */ - AINSTR_END, /* noexpr */ + VINSTR_END, /* struct */ + VINSTR_END, /* union */ + VINSTR_END, /* array */ + VINSTR_END, /* nil */ + VINSTR_END, /* noexpr */ }; uint16_t type_not_instr[TYPE_COUNT] = { @@ -203,11 +203,11 @@ uint16_t type_not_instr[TYPE_COUNT] = { INSTR_NOT_V, /* variant, should never be accessed */ - AINSTR_END, /* struct */ - AINSTR_END, /* union */ - AINSTR_END, /* array */ - AINSTR_END, /* nil */ - AINSTR_END, /* noexpr */ + VINSTR_END, /* struct */ + VINSTR_END, /* union */ + VINSTR_END, /* array */ + VINSTR_END, /* nil */ + VINSTR_END, /* noexpr */ }; /* protos */ @@ -600,6 +600,13 @@ bool ir_function_pass_peephole(ir_function *self) if (!instr_is_operation(oper->opcode)) continue; + if (OPTS_FLAG(LEGACY_VECTOR_MATHS)) { + if (oper->opcode == INSTR_MUL_VF && oper->_ops[2]->memberof == oper->_ops[1]) + continue; + if (oper->opcode == INSTR_MUL_FV && oper->_ops[1]->memberof == oper->_ops[2]) + continue; + } + value = oper->_ops[0]; /* only do it for SSA values */ @@ -1258,12 +1265,13 @@ bool ir_value_life_insert(ir_value *self, size_t idx, ir_life_entry_t e) bool ir_value_life_merge(ir_value *self, size_t s) { size_t i; + const size_t vs = vec_size(self->life); ir_life_entry_t *life = NULL; ir_life_entry_t *before = NULL; ir_life_entry_t new_entry; /* Find the first range >= s */ - for (i = 0; i < vec_size(self->life); ++i) + for (i = 0; i < vs; ++i) { before = life; life = &self->life[i]; @@ -1271,7 +1279,7 @@ bool ir_value_life_merge(ir_value *self, size_t s) break; } /* nothing found? append */ - if (i == vec_size(self->life)) { + if (i == vs) { ir_life_entry_t e; if (life && life->end+1 == s) { @@ -2249,18 +2257,22 @@ bool ir_function_allocate_locals(ir_function *self) irerror(call->context, "internal error: unlocked parameter %s not found", v->name); goto error; } - ++opts_optimizationcount[OPTIM_CALL_STORES]; v->callparam = true; 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 (vec_size(self->owner->extparam_protos) <= param) - ep = ir_gen_extparam_proto(self->owner); - else + 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_instr_op(v->writes[0], 0, ep, true); call->params[param+8] = ep; } @@ -2385,13 +2397,13 @@ static void ir_op_read_write(int op, size_t *read, size_t *write) static bool ir_block_living_add_instr(ir_block *self, size_t eid) { - size_t i; - bool changed = false; - bool tempbool; - for (i = 0; i != vec_size(self->living); ++i) + size_t i; + const size_t vs = vec_size(self->living); + bool changed = false; + for (i = 0; i != vs; ++i) { - tempbool = ir_value_life_merge(self->living[i], eid); - changed = changed || tempbool; + if (ir_value_life_merge(self->living[i], eid)) + changed = true; } return changed; } @@ -2449,7 +2461,6 @@ static bool ir_block_life_propagate(ir_block *self, ir_block *prev, bool *change { ir_instr *instr; ir_value *value; - bool tempbool; size_t i, o, p, mem; /* bitmasks which operands are read from or written to */ size_t read, write; @@ -2509,23 +2520,23 @@ static bool ir_block_life_propagate(ir_block *self, ir_block *prev, bool *change * since this function is run multiple times. */ /* con_err( "Value only written %s\n", value->name); */ - tempbool = ir_value_life_merge(value, instr->eid); - *changed = *changed || tempbool; + if (ir_value_life_merge(value, instr->eid)) + *changed = true; } else { /* since 'living' won't contain it * anymore, merge the value, since * (A) doesn't. */ - tempbool = ir_value_life_merge(value, instr->eid); - *changed = *changed || tempbool; + if (ir_value_life_merge(value, instr->eid)) + *changed = true; /* Then remove */ vec_remove(self->living, idx, 1); } /* Removing a vector removes all members */ for (mem = 0; mem < 3; ++mem) { if (value->members[mem] && vec_ir_value_find(self->living, value->members[mem], &idx)) { - tempbool = ir_value_life_merge(value->members[mem], instr->eid); - *changed = *changed || tempbool; + if (ir_value_life_merge(value->members[mem], instr->eid)) + *changed = true; vec_remove(self->living, idx, 1); } } @@ -2537,8 +2548,8 @@ static bool ir_block_life_propagate(ir_block *self, ir_block *prev, bool *change break; } if (mem == 3 && vec_ir_value_find(self->living, value, &idx)) { - tempbool = ir_value_life_merge(value, instr->eid); - *changed = *changed || tempbool; + if (ir_value_life_merge(value, instr->eid)) + *changed = true; vec_remove(self->living, idx, 1); } } @@ -2554,7 +2565,7 @@ static bool ir_block_life_propagate(ir_block *self, ir_block *prev, bool *change if (value->memberof && ir_value_life_merge(value->memberof, instr->eid+1)) *changed = true; } - else if (instr->opcode == INSTR_MUL_FV) + else if (instr->opcode == INSTR_MUL_FV || instr->opcode == INSTR_LOAD_V) { value = instr->_ops[1]; /* the float source will get an additional lifetime */ @@ -2629,13 +2640,12 @@ static bool ir_block_life_propagate(ir_block *self, ir_block *prev, bool *change } /* (A) */ - tempbool = ir_block_living_add_instr(self, instr->eid); - /*con_err( "living added values\n");*/ - *changed = *changed || tempbool; + if (ir_block_living_add_instr(self, instr->eid)) + *changed = true; } /* the "entry" instruction ID */ - tempbool = ir_block_living_add_instr(self, self->entry_id); - *changed = *changed || tempbool; + if (ir_block_living_add_instr(self, self->entry_id)) + *changed = true; if (self->run_id == self->owner->run_id) return true; @@ -3107,7 +3117,7 @@ static ir_value* ir_gen_extparam_proto(ir_builder *ir) ir_value *global; char name[128]; - snprintf(name, sizeof(name), "EXTPARM#%i", (int)(vec_size(ir->extparam_protos)+8)); + snprintf(name, sizeof(name), "EXTPARM#%i", (int)(vec_size(ir->extparam_protos))); global = ir_value_var(name, store_global, TYPE_VECTOR); vec_push(ir->extparam_protos, global); @@ -3194,7 +3204,7 @@ static bool gen_function_varargs_copy(ir_function *self) code_push_statement(&stmt, self->context.line); continue; } - ext = i - 8; + ext = i - 9; if (ext >= vec_size(ir->extparams)) ir_gen_extparam(ir); @@ -3218,9 +3228,12 @@ static bool gen_function_locals(ir_builder *ir, ir_value *global) irfun = global->constval.vfunc; def = code_functions + irfun->code_function_def; - if (opts.g || !OPTS_OPTIMIZATION(OPTIM_OVERLAP_LOCALS) || (irfun->flags & IR_FLAG_MASK_NO_OVERLAP)) + if (OPTS_OPTION_BOOL(OPTION_G) || + !OPTS_OPTIMIZATION(OPTIM_OVERLAP_LOCALS) || + (irfun->flags & IR_FLAG_MASK_NO_OVERLAP)) + { firstlocal = def->firstlocal = vec_size(code_globals); - else { + } else { firstlocal = def->firstlocal = ir->first_common_local; ++opts_optimizationcount[OPTIM_OVERLAP_LOCALS]; } @@ -3366,7 +3379,7 @@ static bool ir_builder_gen_global(ir_builder *self, ir_value *global, bool isloc def.type = global->vtype; def.offset = vec_size(code_globals); def.name = 0; - if (opts.g || !islocal) + if (OPTS_OPTION_BOOL(OPTION_G) || !islocal) { pushdef = true; @@ -3542,7 +3555,7 @@ static bool ir_builder_gen_field(ir_builder *self, ir_value *field) def.offset = (uint16_t)vec_size(code_globals); /* create a global named the same as the field */ - if (opts.standard == COMPILER_GMQCC) { + if (OPTS_OPTION_U32(OPTION_STANDARD) == COMPILER_GMQCC) { /* in our standard, the global gets a dot prefix */ size_t len = strlen(field->name); char name[1024]; @@ -3680,7 +3693,7 @@ bool ir_builder_generate(ir_builder *self, const char *filename) code_push_statement(&stmt, vec_last(code_linenums)); } - if (opts.pp_only) + if (OPTS_OPTION_BOOL(OPTION_PP_ONLY)) return true; if (vec_size(code_statements) != vec_size(code_linenums)) { @@ -3701,7 +3714,7 @@ bool ir_builder_generate(ir_builder *self, const char *filename) memcpy(vec_add(lnofile, 5), ".lno", 5); } - if (!opts.quiet) { + if (!OPTS_OPTION_BOOL(OPTION_QUIET)) { if (lnofile) con_out("writing '%s' and '%s'...\n", filename, lnofile); else