a77ec876d3bbe7bc1e6fbb5539bcf69ab2cd3e54
[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 "firm_cmdline.h"
12 #include "firm_opt.h"
13 #include <libfirm/firm.h>
14 #include <libfirm/be.h>
15
16 #if defined(_WIN32) || defined(__CYGWIN__)
17 #define DEFAULT_OS OS_SUPPORT_MINGW
18 #elif defined(__APPLE__)
19 #define DEFAULT_OS OS_SUPPORT_MACHO
20 #else
21 #define DEFAULT_OS OS_SUPPORT_LINUX
22 #endif
23
24 /* optimization settings */
25 struct a_firm_opt firm_opt = {
26   /* enabled         = */ TRUE,
27   /* debug_mode      = */ DBG_MODE_NONE,
28   /* const_folding   = */ TRUE,
29   /* cse             = */ TRUE,
30   /* control_flow    = */ TRUE,
31   /* gcse            = */ TRUE,
32   /* confirm         = */ TRUE,
33   /* muls            = */ TRUE,
34   /* divs            = */ TRUE,
35   /* mods            = */ TRUE,
36   /* alias_analysis  = */ TRUE,
37   /* strict_alias    = */ FALSE,
38   /* no_alias        = */ FALSE,
39   /* cc_opt          = */ TRUE,
40   /* freestanding;   = */ FALSE,
41   /* fp_model        = */ fp_model_precise,
42   /* vrfy            = */ FIRM_VERIFICATION_ON,
43   /* check_all       = */ FALSE,
44   /* lower           = */ TRUE,
45   /* os_support      = */ DEFAULT_OS,
46   /* honor_restrict  = */ TRUE,
47   /* lower_bitfields = */ TRUE,
48   /* pic             = */ FALSE,
49   /* clone_threshold = */ DEFAULT_CLONE_THRESHOLD,
50   /* inline_maxsize  = */ 750,
51   /* inline_threshold= */ 0,
52   /* vrfy_edges      = */ FALSE,
53   /* grs_simd_opt    = */ 0,
54   /* grs_create_pattern = */ 0,
55   /* spare_size      = */ 128,
56   /* enable_statev   = */ FALSE,
57   /* statev_filter   = */ "",
58 };
59
60 /* dumping options */
61 struct a_firm_dump firm_dump = {
62   /* debug_print  = */ FALSE,
63   /* all_types    = */ FALSE,
64   /* no_blocks    = */ FALSE,
65   /* extbb        = */ FALSE,
66   /* ir_graph     = */ FALSE,
67   /* all_phases   = */ FALSE,
68   /* statistic    = */ STAT_NONE,
69   /* stat_pattern = */ 0,
70   /* stat_dag     = */ 0,
71   /* filter       = */ NULL
72 };
73
74 #ifdef FIRM_EXT_GRS
75 struct a_firm_ext_grs firm_ext_grs = {
76   /* simd_opt       = */ FALSE,
77   /* create_pattern = */ FALSE
78 };
79 #endif
80
81 struct a_firm_be_opt firm_be_opt = {
82   /* selection = */ BE_FIRM_BE,
83   /* node_stat = */ 0,
84 };
85
86 #define X(a)    a, sizeof(a)-1
87
88 /** Parameter description structure */
89 static const struct params {
90   const char *option;      /**< name of the option */
91   int        opt_len;      /**< length of the option string */
92   a_byte     *flag;        /**< address of variable to set/reset */
93   a_byte     set;          /**< iff true, variable will be set, else reset */
94   const char *description; /**< description of this option */
95 } firm_options[] = {
96   /* this must be first */
97   { X("help"),                   NULL,                       0, "print FCC related help options" },
98
99   /* firm optimization options */
100   { X("pic"),                    &firm_opt.pic,              1, "firm: generate position independent code" },
101   { X("g0"),                     &firm_opt.debug_mode,       DBG_MODE_BACKSTORE, "firm: Debug Mode: use back stores" },
102   { X("g1"),                     &firm_opt.debug_mode,       DBG_MODE_FULL,      "firm: Debug Mode: no register variables" },
103   { X("no-opt"),                 NULL,                       0, "firm: disable all FIRM optimizations" },
104   { X("cse"),                    &firm_opt.cse,              1, "firm: enable common subexpression elimination" },
105   { X("no-cse"),                 &firm_opt.cse,              0, "firm: disable common subexpression elimination" },
106   { X("const-fold"),             &firm_opt.const_folding,    1, "firm: enable constant folding" },
107   { X("no-const-fold"),          &firm_opt.const_folding,    0, "firm: disable constant folding" },
108   { X("control_flow"),           &firm_opt.control_flow,     1, "firm: enable control flow optimization" },
109   { X("no-control-flow"),        &firm_opt.control_flow,     0, "firm: disable control flow optimization" },
110   { X("gcse"),                   &firm_opt.gcse,             1, "firm: enable global common subexpression elimination" },
111   { X("no-gcse"),                &firm_opt.gcse,             0, "firm: disable global common subexpression elimination" },
112   { X("inline-max-size=<size>"), NULL,                       0, "firm: set maximum size for function inlining" },
113   { X("inline-threshold=<size>"),NULL,                       0, "firm: set benefice threshold for function inlining" },
114   { X("confirm"),                &firm_opt.confirm,          1, "firm: enable Confirm optimization" },
115   { X("no-confirm"),             &firm_opt.confirm,          0, "firm: disable Confirm optimization" },
116   { X("opt-mul"),                &firm_opt.muls,             0, "firm: enable multiplication optimization" },
117   { X("no-opt-mul"),             &firm_opt.muls,             0, "firm: disable multiplication optimization" },
118   { X("opt-div"),                &firm_opt.divs,             0, "firm: enable division optimization" },
119   { X("no-opt-div"),             &firm_opt.divs,             0, "firm: disable division optimization" },
120   { X("opt-mod"),                &firm_opt.mods,             0, "firm: enable remainder optimization" },
121   { X("no-opt-mod"),             &firm_opt.mods,             0, "firm: disable remainder optimization" },
122   { X("opt-alias"),              &firm_opt.alias_analysis,   1, "firm: enable alias analysis" },
123   { X("no-opt-alias"),           &firm_opt.alias_analysis,   0, "firm: disable alias analysis" },
124   { X("alias"),                  &firm_opt.no_alias,         0, "firm: aliasing occurs" },
125   { X("no-alias"),               &firm_opt.no_alias,         1, "firm: no aliasing occurs" },
126   { X("strict-aliasing"),        &firm_opt.strict_alias,     1, "firm: strict alias rules" },
127   { X("no-strict-aliasing"),     &firm_opt.strict_alias,     0, "firm: strict alias rules" },
128   { X("clone-threshold=<value>"),NULL,                       0, "firm: set clone threshold to <value>" },
129   { X("fp-precise"),             &firm_opt.fp_model,         fp_model_precise, "firm: precise fp model" },
130   { X("fp-fast"),                &firm_opt.fp_model,         fp_model_fast,    "firm: fast fp model" },
131   { X("fp-strict"),              &firm_opt.fp_model,         fp_model_strict,  "firm: strict fp model" },
132   { X("opt-cc"),                 &firm_opt.cc_opt,           1, "firm: enable calling conventions optimization" },
133   { X("no-opt-cc"),              &firm_opt.cc_opt,           0, "firm: disable calling conventions optimization" },
134   { X("freestanding"),           &firm_opt.freestanding,     1, "firm: freestanding environment" },
135   { X("hosted"),                 &firm_opt.freestanding,     0, "firm: hosted environment" },
136
137   /* other firm regarding options */
138   { X("restrict"),               &firm_opt.honor_restrict,   1, "firm: honor restrict keyword" },
139   { X("no-restrict"),            &firm_opt.honor_restrict,   1, "firm: restrict keyword is meaningless" },
140   { X("no-lower"),               &firm_opt.lower,            0, "firm: disable lowering" },
141   { X("vrfy-off"),               &firm_opt.vrfy,             FIRM_VERIFICATION_OFF, "firm: disable node verification" },
142   { X("vrfy-on"),                &firm_opt.vrfy,             FIRM_VERIFICATION_ON, "firm: enable node verification" },
143   { X("vrfy-report"),            &firm_opt.vrfy,             FIRM_VERIFICATION_REPORT, "firm: node verification, report only" },
144   { X("check-all"),              &firm_opt.check_all,        1, "firm: enable checking all Firm phases" },
145   { X("no-check-all"),           &firm_opt.check_all,        0, "firm: disable checking all Firm phases" },
146   { X("vrfy-edges-on"),          &firm_opt.vrfy_edges,       1, "firm: enable out edge verification" },
147   { X("vrfy-edges-off"),         &firm_opt.vrfy_edges,       0, "firm: disable out edge verification" },
148
149   /* dumping */
150 #if defined(_DEBUG) || defined(FIRM_DEBUG)
151   { X("debug"),                  &firm_dump.debug_print,     1, "firm: enable debug output" },
152 #endif
153
154   { X("dump-ir"),                &firm_dump.ir_graph,        1, "firm: dump IR graph" },
155   { X("dump-all-types"),         &firm_dump.all_types,       1, "firm: dump graph of all types" },
156   { X("dump-no-blocks"),         &firm_dump.no_blocks,       1, "firm: dump non-blocked graph" },
157   { X("dump-extbb"),             &firm_dump.extbb,           1, "firm: dump extended basic blocks" },
158   { X("dump-all-phases"),        &firm_dump.all_phases,      1, "firm: dump graphs for all optimization phases" },
159
160   /* code generation */
161   { X("no-codegen"),             &firm_be_opt.selection,     BE_NONE, "cg: disable code generator" },
162
163 #ifdef FIRM_EXT_GRS
164   { X("grs-simd-opt"),           &firm_ext_grs.simd_opt,       1, "firm: do simd optimization" },
165   { X("grs-create-pattern"),     &firm_ext_grs.create_pattern, 1, "firm: create patterns for simd optimization" },
166   { X("no-grs-simd-opt"),        &firm_ext_grs.simd_opt,       0, "firm: do simd optimization" },
167   { X("no-grs-create-pattern"),  &firm_ext_grs.create_pattern, 0, "firm: create patterns for simd optimization" },
168 #endif
169
170   { X("be-firm"),                &firm_be_opt.selection,     BE_FIRM_BE, "backend: firm backend facility" },
171 #ifdef FIRM2C_BACKEND
172   { X("be-firm2c"),              &firm_be_opt.selection,     BE_FIRM2C, "backend: firm2C" },
173 #endif /* FIRM2C_BACKEND */
174
175   /* misc */
176   { X("stat-before-opt"),        &firm_dump.statistic,       STAT_BEFORE_OPT,  "misc: Firm statistic output before optimizations" },
177   { X("stat-after-opt"),         &firm_dump.statistic,       STAT_AFTER_OPT,   "misc: Firm statistic output after optimizations" },
178   { X("stat-after-lower"),       &firm_dump.statistic,       STAT_AFTER_LOWER, "misc: Firm statistic output after lowering" },
179   { X("stat-final-ir"),          &firm_dump.statistic,       STAT_FINAL_IR,    "misc: Firm statistic after final optimization" },
180   { X("stat-final"),             &firm_dump.statistic,       STAT_FINAL,       "misc: Firm statistic after code generation" },
181   { X("stat-pattern"),           &firm_dump.stat_pattern,    1, "misc: Firm statistic calculates most used pattern" },
182   { X("stat-dag"),               &firm_dump.stat_dag,        1, "misc: Firm calculates DAG statistics" },
183   { X("win32"),                  &firm_opt.os_support,       OS_SUPPORT_MINGW, "misc: generate MinGW Win32 code" },
184   { X("mac"),                    &firm_opt.os_support,       OS_SUPPORT_MACHO, "misc: generate MacOS code" },
185   { X("linux"),                  &firm_opt.os_support,       OS_SUPPORT_LINUX, "misc: generate Linux-ELF code" },
186
187   /* string options */
188   { X("dump-filter=<string>"),   NULL,                       0, "misc: set dumper filter" },
189 };
190
191 #undef X
192
193 /** A strdup replacement */
194 static char *StrDup(const char *s) {
195   int   l = strlen(s);
196   char *r = malloc(l+1);
197
198   if (r != NULL)
199     memcpy(r, s, l+1);
200   return r;
201 }
202
203 /**
204  * Set a dumper filter.
205  */
206 static void set_dump_filter(const char *filter)
207 {
208   firm_dump.filter = StrDup(filter);
209 }  /* set_dump_filter */
210
211 /** Disable all optimizations. */
212 static void disable_opts(void) {
213   firm_opt.cse             = FALSE;
214   firm_opt.gcse            = FALSE;
215   firm_opt.confirm         = FALSE;
216   firm_opt.muls            = FALSE;
217   firm_opt.divs            = FALSE;
218   firm_opt.mods            = FALSE;
219   firm_opt.alias_analysis  = FALSE;
220   firm_opt.strict_alias    = FALSE;
221   firm_opt.no_alias        = FALSE;
222   firm_opt.cc_opt          = FALSE;
223   firm_opt.freestanding    = TRUE;
224   disable_all_opts();
225 }  /* disable_opts */
226
227 void print_option_help(const char *name, const char *description)
228 {
229         printf("-f %-20s %s\n", name, description);
230 }
231
232 /**
233  * Handles a firm option.
234  */
235 int firm_option(const char *opt)
236 {
237   int i, len    = strlen(opt);
238   const char *p = opt;
239   int res;
240
241   if (strncmp("dump-filter=", opt, 12) == 0) {
242     opt = &opt[12];
243     set_dump_filter(opt);
244     return 1;
245   }
246   else if (strncmp("clone-threshold=", opt, 16) == 0) {
247     sscanf(&opt[16], "%d", &firm_opt.clone_threshold);
248     return 1;
249   }
250   else if (strncmp("inline-max-size=", opt, 16) == 0) {
251     sscanf(&opt[16], "%u", &firm_opt.inline_maxsize);
252     return 1;
253   }
254   else if (strncmp("inline-threshold=", opt, 17) == 0) {
255     sscanf(&opt[17], "%u", &firm_opt.inline_threshold);
256     return 1;
257   }
258   else if (strcmp("no-opt", opt) == 0) {
259     disable_opts();
260     return 1;
261   }
262
263   for (i = sizeof(firm_options) / sizeof(firm_options[0]) - 1; i >= 0; --i) {
264     if (len == firm_options[i].opt_len && strncmp(p, firm_options[i].option, len) == 0) {
265       if (!firm_options[i].flag) {
266         /* help option */
267         print_option_help(firm_options[0].option, firm_options[0].description);
268         firm_opt_option_help();
269         for (i = 1; i < (int) (sizeof(firm_options)/sizeof(firm_options[0])); ++i) {
270           print_option_help(firm_options[i].option, firm_options[i].description);
271         }
272         return -1;
273       }
274       /* statistic options do accumulate */
275       if (firm_options[i].flag == &firm_dump.statistic)
276         *firm_options[i].flag = (a_byte) (*firm_options[i].flag | firm_options[i].set);
277       else
278         *firm_options[i].flag = firm_options[i].set;
279
280       if (firm_options[i].flag == &firm_opt.debug_mode && firm_opt.debug_mode > DBG_MODE_NONE) {
281         if (firm_opt.debug_mode == DBG_MODE_FULL)
282           disable_opts();
283         res = 1;
284         res &= be_parse_arg("omitfp=0");
285         res &= be_parse_arg("stabs");
286         return res;
287       }
288       break;
289     }
290   }
291
292   if (i >= 0)
293     return 1;
294
295   /* maybe this enables/disables an optimisations */
296   if (firm_opt_option(p))
297     return 1;
298
299   return 0;
300 }  /* firm_option */
301
302 /**
303  * prints the firm version number
304  */
305 void print_firm_version(FILE *f) {
306   const char *revision = ir_get_version_revision();
307   const char *build    = ir_get_version_build();
308
309   fprintf(f, "Firm C-Compiler using libFirm (%u.%u",
310           ir_get_version_major(), ir_get_version_minor());
311   if (revision[0] != 0) {
312         fputc(' ', f);
313     fputs(revision, f);
314   }
315    if(build[0] != 0) {
316         fputc(' ', f);
317     fputs(build, f);
318   }
319   fprintf(f, "}\n"
320                      "(C) 2005-2008 Michael Beck\n"
321              "(C) 1995-2008 University of Karlsruhe\n"
322              "Using ");
323 }  /* print_firm_version */