From 3ff77a1d6fbcf08fc6964e8149d188c791cb7f16 Mon Sep 17 00:00:00 2001 From: Edmund Grimley Evans Date: Fri, 20 Nov 2015 23:33:49 +0000 Subject: [PATCH] Improve constant propagation with "&&" and "||". --- TODO | 1 - tccgen.c | 103 +++++++++++++++++++----------------- tests/tests2/78_vla_label.c | 6 ++- 3 files changed, 58 insertions(+), 52 deletions(-) diff --git a/TODO b/TODO index ea57823..ffe4ad1 100644 --- a/TODO +++ b/TODO @@ -68,7 +68,6 @@ Not critical: to suppress VT_LOCAL and use a base register instead). - interactive mode / integrated debugger - fix preprocessor symbol redefinition -- better constant opt (&&, ||, ?:) - add portable byte code generator and interpreter for other unsupported architectures. - C++: variable declaration in for, minimal 'class' support. diff --git a/tccgen.c b/tccgen.c index e2d9e21..3b5ad75 100644 --- a/tccgen.c +++ b/tccgen.c @@ -4453,80 +4453,83 @@ static void expr_or(void) } } -/* XXX: fix this mess */ -static void expr_land_const(void) -{ - expr_or(); - while (tok == TOK_LAND) { - next(); - expr_or(); - gen_op(TOK_LAND); - } -} - -/* XXX: fix this mess */ -static void expr_lor_const(void) -{ - expr_land_const(); - while (tok == TOK_LOR) { - next(); - expr_land_const(); - gen_op(TOK_LOR); - } -} - -/* only used if non constant */ static void expr_land(void) { - int t; - expr_or(); if (tok == TOK_LAND) { - t = 0; - save_regs(1); - for(;;) { - t = gvtst(1, t); - if (tok != TOK_LAND) { - vseti(VT_JMPI, t); - break; - } + if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { + CType ctb, cti; + ctb.t = VT_BOOL; + cti.t = VT_INT; next(); - expr_or(); + gen_cast(&ctb); + if (vtop->c.i) { + vpop(); + expr_land(); + gen_cast(&ctb); + } else { + expr_land(); + vpop(); + } + gen_cast(&cti); + } else { + int t = 0; + save_regs(1); + for(;;) { + t = gvtst(1, t); + if (tok != TOK_LAND) { + vseti(VT_JMPI, t); + break; + } + next(); + expr_or(); + } } } } static void expr_lor(void) { - int t; - expr_land(); if (tok == TOK_LOR) { - t = 0; - save_regs(1); - for(;;) { - t = gvtst(0, t); - if (tok != TOK_LOR) { - vseti(VT_JMP, t); - break; - } + if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { + CType ctb, cti; + ctb.t = VT_BOOL; + cti.t = VT_INT; next(); - expr_land(); + gen_cast(&ctb); + if (vtop->c.i) { + expr_lor(); + vpop(); + } else { + vpop(); + expr_lor(); + gen_cast(&ctb); + } + gen_cast(&cti); + } else { + int t = 0; + save_regs(1); + for(;;) { + t = gvtst(0, t); + if (tok != TOK_LOR) { + vseti(VT_JMP, t); + break; + } + next(); + expr_land(); + } } } } -/* XXX: better constant handling */ static void expr_cond(void) { int tt, u, r1, r2, rc, t1, t2, bt1, bt2; SValue sv; CType type, type1, type2; - if (const_wanted) - expr_lor_const(); - else - expr_lor(); + expr_lor(); if (tok == '?') { next(); if ((vtop->r & (VT_VALMASK | VT_LVAL | VT_SYM)) == VT_CONST) { diff --git a/tests/tests2/78_vla_label.c b/tests/tests2/78_vla_label.c index 93a8b08..39654c6 100644 --- a/tests/tests2/78_vla_label.c +++ b/tests/tests2/78_vla_label.c @@ -17,9 +17,13 @@ void f2(void) { goto start; { - int a[1 ? 1 : 1]; /* not a variable-length array */ + int a[1 && 1]; /* not a variable-length array */ + int b[1 || 1]; /* not a variable-length array */ + int c[1 ? 1 : 1]; /* not a variable-length array */ start: a[0] = 0; + b[0] = 0; + c[0] = 0; } }