mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 07:11:41 +00:00
[qfcc] Fold int constants more aggressively
This code now reaches into one level of the expression tree and rearranges the nodes to allow the constant folder to do its things, but only for ints, and only when the folding is trivially correct (* and *, +/- and +/-). There may be more opportunities, but these cover what I needed for now and anything more will need code generation or smarter tree manipulation as things are getting out of hand.
This commit is contained in:
parent
284fcd312d
commit
54e079ab75
3 changed files with 153 additions and 0 deletions
|
@ -80,6 +80,18 @@ cmp_result_expr (int result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
is_addsub (int op)
|
||||||
|
{
|
||||||
|
return op == '+' || op == '-';
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
inv_addsub (int op)
|
||||||
|
{
|
||||||
|
return op == '+' ? '-' : '+';
|
||||||
|
}
|
||||||
|
|
||||||
static expr_t *
|
static expr_t *
|
||||||
do_op_string (int op, expr_t *e, expr_t *e1, expr_t *e2)
|
do_op_string (int op, expr_t *e, expr_t *e1, expr_t *e2)
|
||||||
{
|
{
|
||||||
|
@ -819,6 +831,60 @@ do_op_int (int op, expr_t *e, expr_t *e1, expr_t *e2)
|
||||||
if (op == '-' && isval2 && val2 == 0)
|
if (op == '-' && isval2 && val2 == 0)
|
||||||
return e1;
|
return e1;
|
||||||
|
|
||||||
|
if (!isval1) {
|
||||||
|
if (e1->type == ex_expr) {
|
||||||
|
// at most one of the two sub-expressions is constant otherwise
|
||||||
|
// e1 would be a constant
|
||||||
|
if (is_constant (e1->e.expr.e1)) {
|
||||||
|
if ((op == '*' && e1->e.expr.op == '*')
|
||||||
|
|| (is_addsub (op) && is_addsub (e1->e.expr.op))) {
|
||||||
|
expr_t *c = binary_expr (op, e1->e.expr.e1, e2);
|
||||||
|
e = binary_expr (e1->e.expr.op, c, e1->e.expr.e2);
|
||||||
|
}
|
||||||
|
} else if (is_constant (e1->e.expr.e2)) {
|
||||||
|
if ((op == '*' && e1->e.expr.op == '*')
|
||||||
|
|| (is_addsub (op) && e1->e.expr.op == '+')) {
|
||||||
|
expr_t *c = binary_expr (op, e1->e.expr.e2, e2);
|
||||||
|
e = binary_expr (e1->e.expr.op, e1->e.expr.e1, c);
|
||||||
|
} else if (is_addsub (op) && e1->e.expr.op == '-') {
|
||||||
|
// must ivert op
|
||||||
|
expr_t *c = binary_expr (inv_addsub (op),
|
||||||
|
e1->e.expr.e2, e2);
|
||||||
|
e = binary_expr (e1->e.expr.op, e1->e.expr.e1, c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return e;
|
||||||
|
} else if (!isval2) {
|
||||||
|
if (e2->type == ex_expr) {
|
||||||
|
// at most one of the two sub-expressions is constant otherwise
|
||||||
|
// e2 would be a constant
|
||||||
|
if (is_constant (e2->e.expr.e1)) {
|
||||||
|
if ((op == '*' && e2->e.expr.op == '*')
|
||||||
|
|| (op == '+' && is_addsub (e2->e.expr.op))) {
|
||||||
|
expr_t *c = binary_expr (op, e1, e2->e.expr.e1);
|
||||||
|
e = binary_expr (e2->e.expr.op, c, e2->e.expr.e2);
|
||||||
|
} else if (op == '-' && is_addsub (e2->e.expr.op)) {
|
||||||
|
expr_t *c = binary_expr (op, e1, e2->e.expr.e1);
|
||||||
|
c = fold_constants (c);
|
||||||
|
e = binary_expr (inv_addsub (e2->e.expr.op),
|
||||||
|
c, e2->e.expr.e2);
|
||||||
|
}
|
||||||
|
} else if (is_constant (e2->e.expr.e2)) {
|
||||||
|
if ((op == '*' && e2->e.expr.op == '*')
|
||||||
|
|| (op == '+' && is_addsub (e2->e.expr.op))) {
|
||||||
|
expr_t *c = binary_expr (e2->e.expr.op,
|
||||||
|
e1, e2->e.expr.e2);
|
||||||
|
e = binary_expr (op, c, e2->e.expr.e1);
|
||||||
|
} else if (op == '-' && is_addsub (e2->e.expr.op)) {
|
||||||
|
expr_t *c = binary_expr (inv_addsub (e2->e.expr.op),
|
||||||
|
e1, e2->e.expr.e2);
|
||||||
|
e = binary_expr (op, c, e2->e.expr.e1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return e;
|
||||||
|
}
|
||||||
if (!isval1 || !isval2)
|
if (!isval1 || !isval2)
|
||||||
return e;
|
return e;
|
||||||
|
|
||||||
|
|
|
@ -16,6 +16,7 @@ test_progs_dat=\
|
||||||
tools/qfcc/test/chewed-return.dat \
|
tools/qfcc/test/chewed-return.dat \
|
||||||
tools/qfcc/test/comma-expr.dat \
|
tools/qfcc/test/comma-expr.dat \
|
||||||
tools/qfcc/test/compound.dat \
|
tools/qfcc/test/compound.dat \
|
||||||
|
tools/qfcc/test/const-fold-int.dat \
|
||||||
tools/qfcc/test/deadbool.dat \
|
tools/qfcc/test/deadbool.dat \
|
||||||
tools/qfcc/test/dealloc-nowarn.dat \
|
tools/qfcc/test/dealloc-nowarn.dat \
|
||||||
tools/qfcc/test/dealloc-nowarn2.dat \
|
tools/qfcc/test/dealloc-nowarn2.dat \
|
||||||
|
@ -195,6 +196,16 @@ tools/qfcc/test/compound.run: $(qfcc_test_run_deps)
|
||||||
include $(compound_dep) # am--include-marker
|
include $(compound_dep) # am--include-marker
|
||||||
r_depfiles_remade += $(compound_dep)
|
r_depfiles_remade += $(compound_dep)
|
||||||
|
|
||||||
|
tools_qfcc_test_const_fold_int_dat_SOURCES=tools/qfcc/test/const-fold-int.r
|
||||||
|
const_fold_int_obj=$(tools_qfcc_test_const_fold_int_dat_SOURCES:.r=.o)
|
||||||
|
const_fold_int_dep=$(call qcautodep,$(tools_qfcc_test_const_fold_int_dat_SOURCES))
|
||||||
|
tools/qfcc/test/const-fold-int.dat$(EXEEXT): $(const_fold_int_obj) $(QFCC_DEP)
|
||||||
|
$(V_QFCCLD)$(QLINK) -o $@ $(const_fold_int_obj)
|
||||||
|
tools/qfcc/test/const-fold-int.run: $(qfcc_test_run_deps)
|
||||||
|
@$(top_srcdir)/tools/qfcc/test/build-run $@
|
||||||
|
include $(const_fold_int_dep) # am--include-marker
|
||||||
|
r_depfiles_remade += $(const_fold_int_dep)
|
||||||
|
|
||||||
tools_qfcc_test_deadbool_dat_SOURCES=tools/qfcc/test/deadbool.r
|
tools_qfcc_test_deadbool_dat_SOURCES=tools/qfcc/test/deadbool.r
|
||||||
deadbool_obj=$(tools_qfcc_test_deadbool_dat_SOURCES:.r=.o)
|
deadbool_obj=$(tools_qfcc_test_deadbool_dat_SOURCES:.r=.o)
|
||||||
deadbool_dep=$(call qcautodep,$(tools_qfcc_test_deadbool_dat_SOURCES))
|
deadbool_dep=$(call qcautodep,$(tools_qfcc_test_deadbool_dat_SOURCES))
|
||||||
|
|
76
tools/qfcc/test/const-fold-int.r
Normal file
76
tools/qfcc/test/const-fold-int.r
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
int mul_e_c_t_c (int x) { return x * 6 * 7; }
|
||||||
|
int mul_c_e_t_c (int x) { return 6 * x * 7; }
|
||||||
|
int mul_c_c_t_e (int x) { return 6 * 7 * x; }
|
||||||
|
int mul_e_t_c_c (int x) { return x * (6 * 7); }
|
||||||
|
int mul_c_t_e_c (int x) { return 6 * (x * 7); }
|
||||||
|
int mul_c_t_c_e (int x) { return 6 * (7 * x); }
|
||||||
|
|
||||||
|
int addadd_e_c_t_c (int x) { return x + 6 + 7; }
|
||||||
|
int addadd_c_e_t_c (int x) { return 6 + x + 7; }
|
||||||
|
int addadd_c_c_t_e (int x) { return 6 + 7 + x; }
|
||||||
|
int addadd_e_t_c_c (int x) { return x + (6 + 7); }
|
||||||
|
int addadd_c_t_e_c (int x) { return 6 + (x + 7); }
|
||||||
|
int addadd_c_t_c_e (int x) { return 6 + (7 + x); }
|
||||||
|
|
||||||
|
int addsub_e_c_t_c (int x) { return x + 6 - 7; }
|
||||||
|
int addsub_c_e_t_c (int x) { return 6 + x - 7; }
|
||||||
|
int addsub_c_c_t_e (int x) { return 6 + 7 - x; }
|
||||||
|
int addsub_e_t_c_c (int x) { return x + (6 - 7); }
|
||||||
|
int addsub_c_t_e_c (int x) { return 6 + (x - 7); }
|
||||||
|
int addsub_c_t_c_e (int x) { return 6 + (7 - x); }
|
||||||
|
|
||||||
|
int subadd_e_c_t_c (int x) { return x - 6 + 7; }
|
||||||
|
int subadd_c_e_t_c (int x) { return 6 - x + 7; }
|
||||||
|
int subadd_c_c_t_e (int x) { return 6 - 7 + x; }
|
||||||
|
int subadd_e_t_c_c (int x) { return x - (6 + 7); }
|
||||||
|
int subadd_c_t_e_c (int x) { return 6 - (x + 7); }
|
||||||
|
int subadd_c_t_c_e (int x) { return 6 - (7 + x); }
|
||||||
|
|
||||||
|
int subsub_e_c_t_c (int x) { return x - 6 - 7; }
|
||||||
|
int subsub_c_e_t_c (int x) { return 6 - x - 7; }
|
||||||
|
int subsub_c_c_t_e (int x) { return 6 - 7 - x; }
|
||||||
|
int subsub_e_t_c_c (int x) { return x - (6 - 7); }
|
||||||
|
int subsub_c_t_e_c (int x) { return 6 - (x - 7); }
|
||||||
|
int subsub_c_t_c_e (int x) { return 6 - (7 - x); }
|
||||||
|
|
||||||
|
int
|
||||||
|
main ()
|
||||||
|
{
|
||||||
|
int fail = 0;
|
||||||
|
|
||||||
|
fail |= mul_e_c_t_c (10) != 420;
|
||||||
|
fail |= mul_c_e_t_c (10) != 420;
|
||||||
|
fail |= mul_c_c_t_e (10) != 420;
|
||||||
|
fail |= mul_e_t_c_c (10) != 420;
|
||||||
|
fail |= mul_c_t_e_c (10) != 420;
|
||||||
|
fail |= mul_c_t_c_e (10) != 420;
|
||||||
|
|
||||||
|
fail |= addadd_e_c_t_c (29) != 42;
|
||||||
|
fail |= addadd_c_e_t_c (29) != 42;
|
||||||
|
fail |= addadd_c_c_t_e (29) != 42;
|
||||||
|
fail |= addadd_e_t_c_c (29) != 42;
|
||||||
|
fail |= addadd_c_t_e_c (29) != 42;
|
||||||
|
fail |= addadd_c_t_c_e (29) != 42;
|
||||||
|
|
||||||
|
fail |= addsub_e_c_t_c (43) != 42;
|
||||||
|
fail |= addsub_c_e_t_c (43) != 42;
|
||||||
|
fail |= addsub_c_c_t_e (-29) != 42;
|
||||||
|
fail |= addsub_e_t_c_c (43) != 42;
|
||||||
|
fail |= addsub_c_t_e_c (43) != 42;
|
||||||
|
fail |= addsub_c_t_c_e (-29) != 42;
|
||||||
|
|
||||||
|
fail |= subadd_e_c_t_c (41) != 42;
|
||||||
|
fail |= subadd_c_e_t_c (-29) != 42;
|
||||||
|
fail |= subadd_c_c_t_e (43) != 42;
|
||||||
|
fail |= subadd_e_t_c_c (55) != 42;
|
||||||
|
fail |= subadd_c_t_e_c (-43) != 42;
|
||||||
|
fail |= subadd_c_t_c_e (-43) != 42;
|
||||||
|
|
||||||
|
fail |= subsub_e_c_t_c (55) != 42;
|
||||||
|
fail |= subsub_c_e_t_c (-43) != 42;
|
||||||
|
fail |= subsub_c_c_t_e (-43) != 42;
|
||||||
|
fail |= subsub_e_t_c_c (41) != 42;
|
||||||
|
fail |= subsub_c_t_e_c (-29) != 42;
|
||||||
|
fail |= subsub_c_t_c_e (43) != 42;
|
||||||
|
return fail;
|
||||||
|
}
|
Loading…
Reference in a new issue