From: Wolfgang (Blub) Bumiller Date: Wed, 21 Nov 2012 15:08:08 +0000 (+0100) Subject: experimental -fshort-logic, currently perl-like - might have to use NOT(NOT(x)) to... X-Git-Tag: 0.1.9~382 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=ca2b414c7c73f367472053b5a5c5fab17582cc14;p=xonotic%2Fgmqcc.git experimental -fshort-logic, currently perl-like - might have to use NOT(NOT(x)) to fix this --- diff --git a/ast.c b/ast.c index e7d5f09..7487e23 100644 --- a/ast.c +++ b/ast.c @@ -1513,13 +1513,58 @@ bool ast_binary_codegen(ast_binary *self, ast_function *func, bool lvalue, ir_va return true; } + if (OPTS_FLAG(SHORT_LOGIC) && + (self->op == INSTR_AND || self->op == INSTR_OR)) + { + /* short circuit evaluation */ + ir_block *other, *merge; + ir_block *from_left, *from_right; + ir_instr *phi; + size_t merge_id; + + merge_id = vec_size(func->blocks); + merge = ir_function_create_block(func->ir_func, ast_function_label(func, "sce_merge")); + + cgen = self->left->expression.codegen; + if (!(*cgen)((ast_expression*)(self->left), func, false, &left)) + return false; + + from_left = func->curblock; + other = ir_function_create_block(func->ir_func, ast_function_label(func, "sce_other")); + if (self->op == INSTR_AND) { + if (!ir_block_create_if(func->curblock, left, other, merge)) + return false; + } else { + if (!ir_block_create_if(func->curblock, left, merge, other)) + return false; + } + + func->curblock = other; + cgen = self->right->expression.codegen; + if (!(*cgen)((ast_expression*)(self->right), func, false, &right)) + return false; + from_right = func->curblock; + + if (!ir_block_create_jump(func->curblock, merge)) + return false; + + vec_remove(func->ir_func->blocks, merge_id, 1); + vec_push(func->ir_func->blocks, merge); + + func->curblock = merge; + phi = ir_block_create_phi(func->curblock, ast_function_label(func, "sce_value"), TYPE_FLOAT); + ir_phi_add(phi, from_left, left); + ir_phi_add(phi, from_right, right); + *out = ir_phi_value(phi); + self->expression.outr = *out; + return true; + } + cgen = self->left->expression.codegen; - /* lvalue! */ if (!(*cgen)((ast_expression*)(self->left), func, false, &left)) return false; cgen = self->right->expression.codegen; - /* rvalue! */ if (!(*cgen)((ast_expression*)(self->right), func, false, &right)) return false; diff --git a/opts.def b/opts.def index 705eb0c..46c7122 100644 --- a/opts.def +++ b/opts.def @@ -33,6 +33,7 @@ GMQCC_DEFINE_FLAG(ADJUST_VECTOR_FIELDS) GMQCC_DEFINE_FLAG(FTEPP) GMQCC_DEFINE_FLAG(RELAXED_SWITCH) + GMQCC_DEFINE_FLAG(SHORT_LOGIC) #endif /* warning flags */