X-Git-Url: https://git.xonotic.org/?p=xonotic%2Fgmqcc.git;a=blobdiff_plain;f=ast.c;h=e10bbed51712ecea27d544b466517ecf5ec99749;hp=3c70a73721e49e726c1e010b3bbc0b77e94bc225;hb=4d4851e17903a5e8b66a2eef027354594e391559;hpb=065a870e7a81b10b58f0332af8a6ced0a7a7dcd3 diff --git a/ast.c b/ast.c index 3c70a73..e10bbed 100644 --- a/ast.c +++ b/ast.c @@ -441,6 +441,24 @@ ast_binary* ast_binary_new(lex_ctx_t ctx, int op, ast_instantiate(ast_binary, ctx, ast_binary_delete); ast_expression_init((ast_expression*)self, (ast_expression_codegen*)&ast_binary_codegen); + if (ast_istype(right, ast_unary) && OPTS_OPTIMIZATION(OPTIM_PEEPHOLE)) { + ast_unary *unary = ((ast_unary*)right); + ast_expression *normal = unary->operand; + + /* make a-(-b) => a + b */ + if (unary->op == VINSTR_NEG_F || unary->op == VINSTR_NEG_V) { + if (op == INSTR_SUB_F) { + op = INSTR_ADD_F; + right = normal; + ++opts_optimizationcount[OPTIM_PEEPHOLE]; + } else if (op == INSTR_SUB_V) { + op = INSTR_ADD_V; + right = normal; + ++opts_optimizationcount[OPTIM_PEEPHOLE]; + } + } + } + self->op = op; self->left = left; self->right = right; @@ -1177,7 +1195,6 @@ ast_function* ast_function_new(lex_ctx_t ctx, const char *name, ast_value *vtype if (!vtype) { compile_error(ast_ctx(self), "internal error: ast_function_new condition 0"); goto cleanup; - } else if (vtype->hasvalue || vtype->expression.vtype != TYPE_FUNCTION) { } else if (vtype->hasvalue || vtype->expression.vtype != TYPE_FUNCTION) { compile_error(ast_ctx(self), "internal error: ast_function_new condition %i %i type=%i (probably 2 bodies?)", (int)!vtype, @@ -1207,6 +1224,9 @@ ast_function* ast_function_new(lex_ctx_t ctx, const char *name, ast_value *vtype self->fixedparams = NULL; self->return_value = NULL; + self->static_names = NULL; + self->static_count = 0; + return self; cleanup: @@ -1228,6 +1248,9 @@ void ast_function_delete(ast_function *self) */ ast_unref(self->vtype); } + for (i = 0; i < vec_size(self->static_names); ++i) + mem_d(self->static_names[i]); + vec_free(self->static_names); for (i = 0; i < vec_size(self->blocks); ++i) ast_delete(self->blocks[i]); vec_free(self->blocks);