From 15b0555546a64bb208fbb72b3edabc51c0b60085 Mon Sep 17 00:00:00 2001 From: Dale Weiler Date: Thu, 26 Sep 2013 06:51:49 -0400 Subject: [PATCH] Implement constant folding on ternary operations via fold_cond. --- ast.c | 9 +++++++-- fold.c | 10 +++++++++- parser.h | 3 ++- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/ast.c b/ast.c index 3531ada..9f33e22 100644 --- 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 --- 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); +} diff --git a/parser.h b/parser.h index c34d39b..54f93b2 100644 --- 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); -- 2.39.2