From: Wolfgang (Blub) Bumiller Date: Fri, 30 Nov 2012 10:05:58 +0000 (+0100) Subject: -O now, additionally to taking a number, can work like -W and -f to take an actual... X-Git-Tag: 0.1.9~200 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=a890589031b1b62e249c71745b6a2182c4fc082a;p=xonotic%2Fgmqcc.git -O now, additionally to taking a number, can work like -W and -f to take an actual optimization name --- diff --git a/gmqcc.h b/gmqcc.h index 44095a0..459c2ff 100644 --- a/gmqcc.h +++ b/gmqcc.h @@ -877,6 +877,25 @@ static const opts_flag_def opts_warn_list[] = { { NULL, LONGBIT(0) } }; +enum { +# define GMQCC_TYPE_OPTIMIZATIONS +# define GMQCC_DEFINE_FLAG(NAME, MIN_O) OPTIM_##NAME, +# include "opts.def" + COUNT_OPTIMIZATIONS +}; +static const opts_flag_def opts_opt_list[] = { +# define GMQCC_TYPE_OPTIMIZATIONS +# define GMQCC_DEFINE_FLAG(NAME, MIN_O) { #NAME, LONGBIT(OPTIM_##NAME) }, +# include "opts.def" + { NULL, LONGBIT(0) } +}; +static const unsigned int opts_opt_oflag[] = { +# define GMQCC_TYPE_OPTIMIZATIONS +# define GMQCC_DEFINE_FLAG(NAME, MIN_O) MIN_O, +# include "opts.def" + 0 +}; + /* other options: */ enum { COMPILER_QCC, /* circa QuakeC */ @@ -902,5 +921,7 @@ extern size_t opts_max_array_size; extern uint32_t opts_flags[1 + (COUNT_FLAGS / 32)]; #define OPTS_WARN(i) (!! (opts_warn[(i)/32] & (1<< ((i)%32)))) extern uint32_t opts_warn[1 + (COUNT_WARNINGS / 32)]; +#define OPTS_OPTIMIZATION(i) (!! (opts_optimization[(i)/32] & (1<< ((i)%32)))) +extern uint32_t opts_optimization[1 + (COUNT_OPTIMIZATIONS / 32)]; #endif diff --git a/main.c b/main.c index b33b959..205cf04 100644 --- a/main.c +++ b/main.c @@ -25,6 +25,7 @@ #include "lexer.h" uint32_t opts_flags[1 + (COUNT_FLAGS / 32)]; +uint32_t opts_optimization[1 + (COUNT_OPTIMIZATIONS / 32)]; uint32_t opts_O = 1; const char *opts_output = "progs.dat"; @@ -111,6 +112,9 @@ static bool options_setflag(const char *name, bool on) { static bool options_setwarn(const char *name, bool on) { return options_setflag_all(name, on, opts_warn, opts_warn_list, COUNT_WARNINGS); } +static bool options_setoptim(const char *name, bool on) { + return options_setflag_all(name, on, opts_optimization, opts_opt_list, COUNT_OPTIMIZATIONS); +} static bool options_witharg(int *argc_, char ***argv_, char **out) { int argc = *argc_; @@ -178,6 +182,13 @@ static void options_set(uint32_t *flags, size_t idx, bool on) #endif } +static void set_optimizations(unsigned int level) +{ + size_t i; + for (i = 0; i < COUNT_OPTIMIZATIONS; ++i) + options_set(opts_optimization, i, level >= opts_opt_oflag[i]); +} + static bool options_parse(int argc, char **argv) { bool argend = false; size_t itr; @@ -352,10 +363,37 @@ static bool options_parse(int argc, char **argv) { case 'O': if (!options_witharg(&argc, &argv, &argarg)) { - con_out("option -O requires a numerical argument\n"); + con_out("option -O requires a numerical argument, or optimization name with an optional 'no-' prefix\n"); return false; } - opts_O = atoi(argarg); + if (isdigit(argarg[0])) { + opts_O = atoi(argarg); + set_optimizations(opts_O); + } else { + util_strtocmd(argarg, argarg, strlen(argarg)+1); + if (!strcmp(argarg, "HELP")) { + con_out("Possible optimizations:\n"); + for (itr = 0; itr < COUNT_OPTIMIZATIONS; ++itr) { + util_strtononcmd(opts_opt_list[itr].name, buffer, sizeof(buffer)); + con_out(" -O%s\n", buffer); + } + exit(0); + } + else if (!strcmp(argarg, "ALL")) + set_optimizations(opts_O = 9999); + else if (!strncmp(argarg, "NO_", 3)) { + if (!options_setoptim(argarg+3, false)) { + con_out("unknown optimization: %s\n", argarg+3); + return false; + } + } + else { + if (!options_setoptim(argarg, true)) { + con_out("unknown optimization: %s\n", argarg); + return false; + } + } + } break; case 'o': diff --git a/opts.def b/opts.def index 9779889..62da391 100644 --- a/opts.def +++ b/opts.def @@ -66,6 +66,12 @@ GMQCC_DEFINE_FLAG(MULTIBYTE_CHARACTER) #endif +#ifdef GMQCC_TYPE_OPTIMIZATIONS + GMQCC_DEFINE_FLAG(MINOR, 1) + GMQCC_DEFINE_FLAG(TAIL_RECURSION, 1) + GMQCC_DEFINE_FLAG(TAIL_CALLS, 2) +#endif + /* some cleanup so we don't have to */ #undef GMQCC_TYPE_FLAGS #undef GMQCC_TYPE_WARNS