]> de.git.xonotic.org Git - xonotic/gmqcc.git/blobdiff - ast.c
Implement constant folding on ternary operations via fold_cond.
[xonotic/gmqcc.git] / ast.c
diff --git a/ast.c b/ast.c
index 2f1566bfc5700a26f7fb51f923b46c0a7ecdc700..9f33e22fc21cffe2e50a3569e0497a2a45fb5c15 100644 (file)
--- a/ast.c
+++ b/ast.c
@@ -1877,6 +1877,17 @@ bool ast_function_codegen(ast_function *self, ir_builder *ir)
     return true;
 }
 
+static bool starts_a_label(ast_expression *ex)
+{
+    while (ex && ast_istype(ex, ast_block)) {
+        ast_block *b = (ast_block*)ex;
+        ex = b->exprs[0];
+    }
+    if (!ex)
+        return false;
+    return ast_istype(ex, ast_label);
+}
+
 /* Note, you will not see ast_block_codegen generate ir_blocks.
  * To the AST and the IR, blocks are 2 different things.
  * In the AST it represents a block of code, usually enclosed in
@@ -1922,7 +1933,7 @@ bool ast_block_codegen(ast_block *self, ast_function *func, bool lvalue, ir_valu
     for (i = 0; i < vec_size(self->exprs); ++i)
     {
         ast_expression_codegen *gen;
-        if (func->curblock->final && !ast_istype(self->exprs[i], ast_label)) {
+        if (func->curblock->final && !starts_a_label(self->exprs[i])) {
             if (compile_warning(ast_ctx(self->exprs[i]), WARN_UNREACHABLE_CODE, "unreachable statement"))
                 return false;
             continue;
@@ -2571,8 +2582,8 @@ bool ast_ifthen_codegen(ast_ifthen *self, ast_function *func, bool lvalue, ir_va
     /* update the block which will get the jump - because short-logic or ternaries may have changed this */
     cond = func->curblock;
 
-    /* try constant folding away the if */
-    if ((fold = fold_cond(condval, func, self)) != -1)
+    /* try constant folding away the condition */
+    if ((fold = fold_cond_ifthen(condval, func, self)) != -1)
         return fold;
 
     if (self->on_true) {
@@ -2655,6 +2666,7 @@ bool ast_ternary_codegen(ast_ternary *self, ast_function *func, bool lvalue, ir_
     ir_block *ontrue, *ontrue_out = NULL;
     ir_block *onfalse, *onfalse_out = NULL;
     ir_block *merge;
+    int       fold  = 0;
 
     /* Ternary can never create an lvalue... */
     if (lvalue)
@@ -2679,6 +2691,10 @@ bool ast_ternary_codegen(ast_ternary *self, ast_function *func, bool lvalue, ir_
         return false;
     cond_out = func->curblock;
 
+    /* try constant folding away the condition */
+    if ((fold = fold_cond_ternary(condval, func, self)) != -1)
+        return fold;
+
     /* create on-true block */
     ontrue = ir_function_create_block(ast_ctx(self), func->ir_func, ast_function_label(func, "tern_T"));
     if (!ontrue)