OS/X headers expect __INTMAX_TYPE__ to be defined
[cparser] / driver / firm_cmdline.c
1 /**
2  * @file firm_cmdline.c -- Additional Firm generating backend parameters
3  *
4  * Compile when BACK_END_IS_CP_FIRM_BE is defined
5  *
6  * (C) 2005  Michael Beck  beck@ipd.info.uni-karlsruhe.de
7  *
8  * $Id$
9  */
10 #include <string.h>
11 #include "../adt/strutil.h"
12 #include "../adt/util.h"
13 #include "firm_cmdline.h"
14 #include "firm_opt.h"
15 #include <libfirm/firm.h>
16 #include <libfirm/be.h>
17
18 /* optimization settings */
19 struct a_firm_opt firm_opt = {
20   /* const_folding   = */ true,
21   /* cse             = */ true,
22   /* confirm         = */ true,
23   /* muls            = */ true,
24   /* divs            = */ true,
25   /* mods            = */ true,
26   /* alias_analysis  = */ true,
27   /* strict_alias    = */ false,
28   /* no_alias        = */ false,
29   /* fp_model        = */ fp_model_precise,
30   /* verify          = */ FIRM_VERIFICATION_ON,
31   /* check_all       = */ true,
32   /* clone_threshold = */ DEFAULT_CLONE_THRESHOLD,
33   /* inline_maxsize  = */ 750,
34   /* inline_threshold= */ 0,
35   /* verify_edges    = */ false,
36 };
37
38 /* dumping options */
39 struct a_firm_dump firm_dump = {
40   /* debug_print  = */ false,
41   /* all_types    = */ false,
42   /* no_blocks    = */ false,
43   /* extbb        = */ false,
44   /* ir_graph     = */ false,
45   /* all_phases   = */ false,
46   /* statistic    = */ STAT_NONE,
47   /* stat_pattern = */ 0,
48   /* stat_dag     = */ 0,
49   /* filter       = */ NULL
50 };
51
52 #define X(a)  a, sizeof(a)-1
53
54 /** Parameter description structure */
55 static const struct params {
56   const char *option;      /**< name of the option */
57   size_t     opt_len;      /**< length of the option string */
58   bool       *flag;        /**< address of variable to set/reset */
59   bool       set;          /**< iff true, variable will be set, else reset */
60   const char *description; /**< description of this option */
61 } firm_options[] = {
62   /* this must be first */
63   { X("help"),                   NULL,                       0, "print FCC related help options" },
64
65   /* firm optimization options */
66   { X("no-opt"),                 NULL,                       0, "firm: disable all FIRM optimizations" },
67   { X("cse"),                    &firm_opt.cse,              1, "firm: enable common subexpression elimination" },
68   { X("no-cse"),                 &firm_opt.cse,              0, "firm: disable common subexpression elimination" },
69   { X("const-fold"),             &firm_opt.const_folding,    1, "firm: enable constant folding" },
70   { X("no-const-fold"),          &firm_opt.const_folding,    0, "firm: disable constant folding" },
71   { X("inline-max-size=<size>"), NULL,                       0, "firm: set maximum size for function inlining" },
72   { X("inline-threshold=<size>"),NULL,                       0, "firm: set benefice threshold for function inlining" },
73   { X("confirm"),                &firm_opt.confirm,          1, "firm: enable Confirm optimization" },
74   { X("no-confirm"),             &firm_opt.confirm,          0, "firm: disable Confirm optimization" },
75   { X("opt-mul"),                &firm_opt.muls,             0, "firm: enable multiplication optimization" },
76   { X("no-opt-mul"),             &firm_opt.muls,             0, "firm: disable multiplication optimization" },
77   { X("opt-div"),                &firm_opt.divs,             0, "firm: enable division optimization" },
78   { X("no-opt-div"),             &firm_opt.divs,             0, "firm: disable division optimization" },
79   { X("opt-mod"),                &firm_opt.mods,             0, "firm: enable remainder optimization" },
80   { X("no-opt-mod"),             &firm_opt.mods,             0, "firm: disable remainder optimization" },
81   { X("opt-alias"),              &firm_opt.alias_analysis,   1, "firm: enable alias analysis" },
82   { X("no-opt-alias"),           &firm_opt.alias_analysis,   0, "firm: disable alias analysis" },
83   { X("alias"),                  &firm_opt.no_alias,         0, "firm: aliasing occurs" },
84   { X("no-alias"),               &firm_opt.no_alias,         1, "firm: no aliasing occurs" },
85   { X("strict-aliasing"),        &firm_opt.strict_alias,     1, "firm: strict alias rules" },
86   { X("no-strict-aliasing"),     &firm_opt.strict_alias,     0, "firm: strict alias rules" },
87   { X("clone-threshold=<value>"),NULL,                       0, "firm: set clone threshold to <value>" },
88   { X("fp-precise"),             &firm_opt.fp_model,         fp_model_precise, "firm: precise fp model" },
89   { X("fp-fast"),                &firm_opt.fp_model,         fp_model_fast,    "firm: fast fp model" },
90   { X("fp-strict"),              &firm_opt.fp_model,         fp_model_strict,  "firm: strict fp model" },
91
92   /* other firm regarding options */
93   { X("verify-off"),             &firm_opt.verify,           FIRM_VERIFICATION_OFF, "firm: disable node verification" },
94   { X("verify-on"),              &firm_opt.verify,           FIRM_VERIFICATION_ON, "firm: enable node verification" },
95   { X("verify-report"),          &firm_opt.verify,           FIRM_VERIFICATION_REPORT, "firm: node verification, report only" },
96   { X("check-all"),              &firm_opt.check_all,        1, "firm: enable checking all Firm phases" },
97   { X("no-check-all"),           &firm_opt.check_all,        0, "firm: disable checking all Firm phases" },
98   { X("verify-edges-on"),        &firm_opt.verify_edges,     1, "firm: enable out edge verification" },
99   { X("verify-edges-off"),       &firm_opt.verify_edges,     0, "firm: disable out edge verification" },
100
101   /* dumping */
102   { X("dump-ir"),                &firm_dump.ir_graph,        1, "firm: dump IR graph" },
103   { X("dump-all-types"),         &firm_dump.all_types,       1, "firm: dump graph of all types" },
104   { X("dump-no-blocks"),         &firm_dump.no_blocks,       1, "firm: dump non-blocked graph" },
105   { X("dump-extbb"),             &firm_dump.extbb,           1, "firm: dump extended basic blocks" },
106   { X("dump-all-phases"),        &firm_dump.all_phases,      1, "firm: dump graphs for all optimization phases" },
107
108   /* misc */
109   { X("stat-before-opt"),        &firm_dump.statistic,       STAT_BEFORE_OPT,  "misc: Firm statistic output before optimizations" },
110   { X("stat-after-opt"),         &firm_dump.statistic,       STAT_AFTER_OPT,   "misc: Firm statistic output after optimizations" },
111   { X("stat-after-lower"),       &firm_dump.statistic,       STAT_AFTER_LOWER, "misc: Firm statistic output after lowering" },
112   { X("stat-final-ir"),          &firm_dump.statistic,       STAT_FINAL_IR,    "misc: Firm statistic after final optimization" },
113   { X("stat-final"),             &firm_dump.statistic,       STAT_FINAL,       "misc: Firm statistic after code generation" },
114   { X("stat-pattern"),           &firm_dump.stat_pattern,    1, "misc: Firm statistic calculates most used pattern" },
115   { X("stat-dag"),               &firm_dump.stat_dag,        1, "misc: Firm calculates DAG statistics" },
116
117   /* string options */
118   { X("dump-filter=<string>"),   NULL,                       0, "misc: set dumper filter" },
119 };
120
121 #undef X
122
123 /** A strdup replacement */
124 static char *StrDup(const char *s) {
125   int   l = strlen(s);
126   char *r = malloc(l+1);
127
128   if (r != NULL)
129     memcpy(r, s, l+1);
130   return r;
131 }
132
133 /**
134  * Set a dumper filter.
135  */
136 static void set_dump_filter(const char *filter)
137 {
138   firm_dump.filter = StrDup(filter);
139 }  /* set_dump_filter */
140
141 /** Disable all optimizations. */
142 static void disable_opts(void) {
143   firm_opt.cse             = false;
144   firm_opt.confirm         = false;
145   firm_opt.muls            = false;
146   firm_opt.divs            = false;
147   firm_opt.mods            = false;
148   firm_opt.alias_analysis  = false;
149   firm_opt.strict_alias    = false;
150   firm_opt.no_alias        = false;
151   disable_all_opts();
152 }  /* disable_opts */
153
154 void print_option_help(const char *name, const char *description)
155 {
156         printf("-f %-20s %s\n", name, description);
157 }
158
159 /**
160  * Handles a firm option.
161  */
162 int firm_option(char const *const opt)
163 {
164         char const* val;
165   if ((val = strstart(opt, "dump-filter="))) {
166     set_dump_filter(val);
167     return 1;
168   } else if ((val = strstart(opt, "clone-threshold="))) {
169     sscanf(val, "%d", &firm_opt.clone_threshold);
170     return 1;
171   } else if ((val = strstart(opt, "inline-max-size="))) {
172     sscanf(val, "%u", &firm_opt.inline_maxsize);
173     return 1;
174   } else if ((val = strstart(opt, "inline-threshold="))) {
175     sscanf(val, "%u", &firm_opt.inline_threshold);
176     return 1;
177   } else if (streq(opt, "no-opt")) {
178     disable_opts();
179     return 1;
180   }
181
182   size_t const len = strlen(opt);
183   for (size_t i = lengthof(firm_options); i != 0;) {
184     struct params const* const o = &firm_options[--i];
185     if (len == o->opt_len && strncmp(opt, o->option, len) == 0) {
186       if (!o->flag) {
187         /* help option */
188         print_option_help(firm_options[0].option, firm_options[0].description);
189         firm_opt_option_help();
190         for (size_t k = 1; k != lengthof(firm_options); ++k) {
191           print_option_help(firm_options[k].option, firm_options[k].description);
192         }
193         return -1;
194       }
195
196       /* statistic options do accumulate */
197       if (o->flag == &firm_dump.statistic)
198         *o->flag = (bool) (*o->flag | o->set);
199       else
200         *o->flag = o->set;
201
202       return 1;
203     }
204   }
205
206   /* maybe this enables/disables optimisations */
207   if (firm_opt_option(opt))
208     return 1;
209
210   return 0;
211 }