From d47fa0fc89a85dcdb704ed60790de461d8a6e068 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 1 Dec 2012 11:13:45 +0900 Subject: [PATCH] Make the new optimizations optional. The usual -O :) (no numbers yet, though). Alternatively, -C [no-]optimize may be used. --- tools/qfcc/include/options.h | 1 + tools/qfcc/include/statements.h | 2 ++ tools/qfcc/source/function.c | 14 +++++++++----- tools/qfcc/source/options.c | 7 +++++++ tools/qfcc/source/statements.c | 26 ++++++++++++++++++++++++++ 5 files changed, 45 insertions(+), 5 deletions(-) diff --git a/tools/qfcc/include/options.h b/tools/qfcc/include/options.h index 9c8d10724..14cf8cb8c 100644 --- a/tools/qfcc/include/options.h +++ b/tools/qfcc/include/options.h @@ -38,6 +38,7 @@ typedef struct { qboolean crc; // Write progsdef.h crc to progs.dat qboolean debug; // Generate debug info for the engine qboolean short_circuit; // short circuit logic for && and || + qboolean optimize; // perform optimizations qboolean fast_float; // use floats directly in ifs qboolean vector_calls; // use floats instead of vectors for constant function args qboolean local_merging; // merge function locals into one block diff --git a/tools/qfcc/include/statements.h b/tools/qfcc/include/statements.h index 133e397c1..f401fb909 100644 --- a/tools/qfcc/include/statements.h +++ b/tools/qfcc/include/statements.h @@ -122,6 +122,8 @@ sblock_t *statement_get_target (statement_t *s); sblock_t **statement_get_targetlist (statement_t *s); void sblock_add_statement (sblock_t *sblock, statement_t *statement); sblock_t *make_statements (struct expr_s *expr); +void statements_count_temps (sblock_t *sblock); + void print_statement (statement_t *s); void dump_dot_sblock (void *data, const char *fname); void print_sblock (sblock_t *sblock, const char *filename); diff --git a/tools/qfcc/source/function.c b/tools/qfcc/source/function.c index 99cfa760f..5bdfe6cd7 100644 --- a/tools/qfcc/source/function.c +++ b/tools/qfcc/source/function.c @@ -643,11 +643,15 @@ emit_function (function_t *f, expr_t *e) f->code = pr.code->size; lineno_base = f->def->line; f->sblock = make_statements (e); - flow_build_vars (f); - f->graph = flow_build_graph (f->sblock, f); - f->graph->func = f; - flow_data_flow (f->graph); - f->sblock = flow_generate (f->graph); + if (options.code.optimize) { + flow_build_vars (f); + f->graph = flow_build_graph (f->sblock, f); + f->graph->func = f; + flow_data_flow (f->graph); + f->sblock = flow_generate (f->graph); + } else { + statements_count_temps (f->sblock); + } emit_statements (f->sblock); } diff --git a/tools/qfcc/source/options.c b/tools/qfcc/source/options.c index 448fbb97e..325d3e81f 100644 --- a/tools/qfcc/source/options.c +++ b/tools/qfcc/source/options.c @@ -114,6 +114,7 @@ static const char *short_options = "M::" "N:" // notice options "o:" // output file + "O" // optimize "P:" // progs.src name "p:" // strip path "q" // quiet @@ -194,6 +195,7 @@ code_usage (void) " [no-]fast-float Use float values directly in \"if\" statements.\n" " help Display his text.\n" " [no-]local-merging Merge the local variable blocks into one.\n" +" [no-]optimize Perform various optimizations on the code.\n" " [no-]short-circuit Generate short circuit code for logical\n" " operators.\n" " [no-]single-cpp Convert progs.src to cpp input file.\n" @@ -354,6 +356,9 @@ DecodeArgs (int argc, char **argv) case 'g': // debug options.code.debug = true; break; + case 'O': // optimize + options.code.optimize = true; + break; case OPT_EXTENDED: options.traditional = 1; options.advanced = false; @@ -446,6 +451,8 @@ DecodeArgs (int argc, char **argv) code_usage (); } else if (!(strcasecmp (temp, "local-merging"))) { options.code.local_merging = flag; + } else if (!(strcasecmp (temp, "optimize"))) { + options.code.optimize = flag; } else if (!(strcasecmp (temp, "short-circuit"))) { options.code.short_circuit = flag; } else if (!(strcasecmp (temp, "single-cpp"))) { diff --git a/tools/qfcc/source/statements.c b/tools/qfcc/source/statements.c index 3d456f0b4..20a08722d 100644 --- a/tools/qfcc/source/statements.c +++ b/tools/qfcc/source/statements.c @@ -1526,3 +1526,29 @@ make_statements (expr_t *e) return sblock; } + +static void +count_temp (operand_t *op) +{ + if (!op) + return; + while (op->op_type == op_alias) + op = op->o.alias; + if (op->op_type == op_temp) + op->o.tempop.users++; +} + +void +statements_count_temps (sblock_t *sblock) +{ + statement_t *st; + + while (sblock) { + for (st = sblock->statements; st; st = st->next) { + count_temp (st->opa); + count_temp (st->opb); + count_temp (st->opc); + } + sblock = sblock->next; + } +}