Implement constant folding on ternary operations via fold_cond.
authorDale Weiler <killfieldengine@gmail.com>
Thu, 26 Sep 2013 10:51:49 +0000 (06:51 -0400)
committerDale Weiler <killfieldengine@gmail.com>
Thu, 26 Sep 2013 10:51:49 +0000 (06:51 -0400)
ast.c
fold.c
parser.h

diff --git a/ast.c b/ast.c
index 3531ada..9f33e22 100644 (file)
--- a/ast.c
+++ b/ast.c
@@ -2582,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) {
@@ -2666,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)
@@ -2690,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)
diff --git a/fold.c b/fold.c
index 4def3c0..d51b765 100644 (file)
--- a/fold.c
+++ b/fold.c
@@ -797,7 +797,7 @@ ast_expression *fold_intrin(fold_t *fold, const char *intrin, ast_expression **a
 /*#define fold_can_2(X,Y)         (fold_can_1(X) && fold_can_1(Y))*/
 
 
-int fold_cond(ir_value *condval, ast_function *func, ast_ifthen *branch) {
+static GMQCC_INLINE int fold_cond(ir_value *condval, ast_function *func, ast_ifthen *branch) {
     if (isfloat(condval) && fold_can_1(condval) && OPTS_OPTIMIZATION(OPTIM_CONST_FOLD_DCE)) {
         ast_expression_codegen *cgen;
         ir_block               *elide;
@@ -831,3 +831,11 @@ int fold_cond(ir_value *condval, ast_function *func, ast_ifthen *branch) {
     }
     return -1; /* nothing done */
 }
+
+int fold_cond_ternary(ir_value *condval, ast_function *func, ast_ternary *branch) {
+    return fold_cond(condval, func, (ast_ifthen*)branch);
+}
+
+int fold_cond_ifthen(ir_value *condval, ast_function *func, ast_ifthen *branch) {
+    return fold_cond(condval, func, branch);
+}
index c34d39b..54f93b2 100644 (file)
--- a/parser.h
+++ b/parser.h
@@ -133,7 +133,8 @@ bool            fold_generate       (fold_t *, ir_builder *);
 ast_expression *fold_op             (fold_t *, const oper_info *, ast_expression **);
 ast_expression *fold_intrin         (fold_t *, const char      *, ast_expression **);
 
-int             fold_cond           (ir_value *, ast_function *, ast_ifthen *);
+int             fold_cond_ifthen    (ir_value *, ast_function *, ast_ifthen  *);
+int             fold_cond_ternary   (ir_value *, ast_function *, ast_ternary *);
 
 /* intrin.c */
 intrin_t       *intrin_init            (parser_t *parser);