mirror of
https://github.com/DarkPlacesEngine/gmqcc.git
synced 2025-02-20 18:32:01 +00:00
Track constant folds in opts_optimization list .. this could be handled better I assume.
This commit is contained in:
parent
ade8626df7
commit
91c7209146
3 changed files with 44 additions and 24 deletions
64
fold.c
64
fold.c
|
@ -543,9 +543,10 @@ static GMQCC_INLINE ast_expression *fold_op_bnot(fold_t *fold, ast_value *a) {
|
|||
}
|
||||
|
||||
ast_expression *fold_op(fold_t *fold, const oper_info *info, ast_expression **opexprs) {
|
||||
ast_value *a = (ast_value*)opexprs[0];
|
||||
ast_value *b = (ast_value*)opexprs[1];
|
||||
ast_value *c = (ast_value*)opexprs[2];
|
||||
ast_value *a = (ast_value*)opexprs[0];
|
||||
ast_value *b = (ast_value*)opexprs[1];
|
||||
ast_value *c = (ast_value*)opexprs[2];
|
||||
ast_expression *e = NULL;
|
||||
|
||||
/* can a fold operation be applied to this operator usage? */
|
||||
if (!info->folds)
|
||||
|
@ -561,28 +562,45 @@ ast_expression *fold_op(fold_t *fold, const oper_info *info, ast_expression **op
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* we could use a boolean and default case but ironically gcc produces
|
||||
* invalid broken assembly from that operation. clang/tcc get it right,
|
||||
* but interestingly ignore compiling this to a jump-table when I do that,
|
||||
* this happens to be the most efficent method, since you have per-level
|
||||
* granularity on the pointer check happening only for the case you check
|
||||
* it in. Opposed to the default method which would involve a boolean and
|
||||
* pointer check after wards.
|
||||
*/
|
||||
#define fold_op_case(ARGS, ARGS_OPID, OP, ARGS_FOLD) \
|
||||
case opid##ARGS ARGS_OPID: \
|
||||
if ((e = fold_op_##OP ARGS_FOLD)) { \
|
||||
++opts_optimizationcount[OPTIM_CONST_FOLD]; \
|
||||
} \
|
||||
return e
|
||||
|
||||
switch(info->id) {
|
||||
case opid2('-','P'): return fold_op_neg (fold, a);
|
||||
case opid2('!','P'): return fold_op_not (fold, a);
|
||||
case opid1('+'): return fold_op_add (fold, a, b);
|
||||
case opid1('-'): return fold_op_sub (fold, a, b);
|
||||
case opid1('*'): return fold_op_mul (fold, a, b);
|
||||
case opid1('/'): return fold_op_div (fold, a, b);
|
||||
case opid1('%'): return fold_op_mod (fold, a, b);
|
||||
case opid1('|'): return fold_op_bor (fold, a, b);
|
||||
case opid1('&'): return fold_op_band (fold, a, b);
|
||||
case opid1('^'): return fold_op_xor (fold, a, b);
|
||||
case opid2('<','<'): return fold_op_lshift (fold, a, b);
|
||||
case opid2('>','>'): return fold_op_rshift (fold, a, b);
|
||||
case opid2('|','|'): return fold_op_andor (fold, a, b, true);
|
||||
case opid2('&','&'): return fold_op_andor (fold, a, b, false);
|
||||
case opid2('?',':'): return fold_op_tern (fold, a, b, c);
|
||||
case opid2('*','*'): return fold_op_exp (fold, a, b);
|
||||
case opid3('<','=','>'): return fold_op_lteqgt (fold, a, b);
|
||||
case opid2('!','='): return fold_op_cmp (fold, a, b, true);
|
||||
case opid2('=','='): return fold_op_cmp (fold, a, b, false);
|
||||
case opid2('~','P'): return fold_op_bnot (fold, a);
|
||||
fold_op_case(2, ('-', 'P'), neg, (fold, a));
|
||||
fold_op_case(2, ('!', 'P'), not, (fold, a));
|
||||
fold_op_case(1, ('+'), add, (fold, a, b));
|
||||
fold_op_case(1, ('-'), sub, (fold, a, b));
|
||||
fold_op_case(1, ('*'), mul, (fold, a, b));
|
||||
fold_op_case(1, ('/'), div, (fold, a, b));
|
||||
fold_op_case(1, ('%'), mod, (fold, a, b));
|
||||
fold_op_case(1, ('|'), bor, (fold, a, b));
|
||||
fold_op_case(1, ('&'), band, (fold, a, b));
|
||||
fold_op_case(1, ('^'), xor, (fold, a, b));
|
||||
fold_op_case(2, ('<', '<'), lshift, (fold, a, b));
|
||||
fold_op_case(2, ('>', '>'), rshift, (fold, a, b));
|
||||
fold_op_case(2, ('|', '|'), andor, (fold, a, b, true));
|
||||
fold_op_case(2, ('&', '&'), andor, (fold, a, b, false));
|
||||
fold_op_case(2, ('?', ':'), tern, (fold, a, b, c));
|
||||
fold_op_case(2, ('*', '*'), exp, (fold, a, b));
|
||||
fold_op_case(3, ('<','=','>'), lteqgt, (fold, a, b));
|
||||
fold_op_case(2, ('!', '='), cmp, (fold, a, b, true));
|
||||
fold_op_case(2, ('=', '='), cmp, (fold, a, b, false));
|
||||
fold_op_case(2, ('~', 'P'), bnot, (fold, a));
|
||||
}
|
||||
#undef fold_op_case
|
||||
compile_error(fold_ctx(fold), "internal error: attempted to constant-fold for unsupported operator");
|
||||
return NULL;
|
||||
}
|
||||
|
|
3
main.c
3
main.c
|
@ -426,7 +426,8 @@ static bool options_parse(int argc, char **argv) {
|
|||
else if (!strcmp(argarg, "ALL"))
|
||||
opts_setoptimlevel(OPTS_OPTION_U32(OPTION_O) = 9999);
|
||||
else if (!strncmp(argarg, "NO_", 3)) {
|
||||
if (!opts_setoptim(argarg+3, false)) {
|
||||
/* constant folding cannot be turned off for obvious reasons */
|
||||
if (!strcmp(argarg, "NO_CONST_FOLD") || !opts_setoptim(argarg+3, false)) {
|
||||
con_out("unknown optimization: %s\n", argarg+3);
|
||||
return false;
|
||||
}
|
||||
|
|
1
opts.def
1
opts.def
|
@ -106,6 +106,7 @@
|
|||
GMQCC_DEFINE_FLAG(VOID_RETURN, 1)
|
||||
GMQCC_DEFINE_FLAG(VECTOR_COMPONENTS, 1)
|
||||
GMQCC_DEFINE_FLAG(CONST_FOLD_DCE, 2)
|
||||
GMQCC_DEFINE_FLAG(CONST_FOLD, 0) /* cannot be turned off */
|
||||
#endif
|
||||
|
||||
#ifdef GMQCC_TYPE_OPTIONS
|
||||
|
|
Loading…
Reference in a new issue