-O now, additionally to taking a number, can work like -W and -f to take an actual optimization name

This commit is contained in:
Wolfgang (Blub) Bumiller 2012-11-30 11:05:58 +01:00
parent fef9303381
commit a890589031
3 changed files with 67 additions and 2 deletions

21
gmqcc.h
View file

@ -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

42
main.c
View file

@ -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':

View file

@ -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