2 * @file firm_cmdline.c -- Additional Firm generating backend parameters
4 * Compile when BACK_END_IS_CP_FIRM_BE is defined
6 * (C) 2005 Michael Beck beck@ipd.info.uni-karlsruhe.de
11 #include "firm_cmdline.h"
12 #include <libfirm/firm.h>
13 #include <libfirm/be.h>
16 #define DEFAULT_OS OS_SUPPORT_MINGW
17 #elif defined(__APPLE__)
18 #define DEFAULT_OS OS_SUPPORT_MACHO
20 #define DEFAULT_OS OS_SUPPORT_LINUX
23 /* optimization settings */
24 struct a_firm_opt firm_opt = {
26 /* debug_mode = */ DBG_MODE_NONE,
27 /* const_folding = */ TRUE,
30 /* control_flow = */ TRUE,
33 /* gvn_pre = */ FALSE,
34 /* cond_eval = */ FALSE,
35 /* if_conversion = */ FALSE,
36 /* func_calls = */ TRUE,
37 /* do_inline = */ FALSE,
38 /* auto_inline = */ TRUE,
39 /* tail_rec = */ TRUE,
40 /* strength_red = */ TRUE,
41 /* scalar_replace = */ TRUE,
46 /* fragile_ops = */ TRUE,
47 /* load_store = */ TRUE,
49 /* precise_exc = */ FALSE, /* never needed for C */
50 /* use_DivMod = */ FALSE,
51 /* remove_unused = */ TRUE,
52 /* cloning = */ FALSE,
53 /* auto_sync = */ TRUE,
54 /* alias_analysis = */ TRUE,
55 /* strict_alias = */ FALSE,
56 /* no_alias = */ FALSE,
60 /* bool_opt = */ FALSE,
61 /* shape_blocks = */ FALSE,
62 /* freestanding; = */ FALSE,
63 /* fp_model = */ fp_model_precise,
64 /* lower_ll = */ FALSE,
65 /* vrfy = */ FIRM_VERIFICATION_ON,
66 /* check_all = */ FALSE,
68 /* os_support = */ DEFAULT_OS,
69 /* honor_restrict = */ TRUE,
70 /* lower_bitfields = */ TRUE,
72 /* ycomp_dbg = */ FALSE,
73 /* ycomp_host = */ FIRM_YCOMP_DEFAULT_HOST,
74 /* ycomp_port = */ FIRM_YCOMP_DEFAULT_PORT,
75 /* clone_threshold = */ DEFAULT_CLONE_THRESHOLD,
76 /* inline_maxsize = */ 750,
77 /* inline_threshold= */ 0,
78 /* vrfy_edges = */ FALSE,
79 /* grs_simd_opt = */ 0,
80 /* grs_create_pattern = */ 0,
81 /* spare_size = */ 128,
85 struct a_firm_dump firm_dump = {
86 /* debug_print = */ FALSE,
87 /* all_types = */ FALSE,
88 /* no_blocks = */ FALSE,
90 /* ir_graph = */ FALSE,
91 /* all_phases = */ FALSE,
92 /* edge_labels = */ FALSE,
93 /* statistic = */ STAT_NONE,
94 /* stat_pattern = */ 0,
96 /* gen_firm_asm = */ FALSE,
101 struct a_firm_ext_grs firm_ext_grs = {
102 /* simd_opt = */ FALSE,
103 /* create_pattern = */ FALSE
107 struct a_firm_be_opt firm_be_opt = {
108 /* selection = */ BE_FIRM_BE,
112 #define X(a) a, sizeof(a)-1
114 /** Parameter description structure */
115 static const struct params {
116 const char *option; /**< name of the option */
117 int opt_len; /**< length of the option string */
118 a_byte *flag; /**< address of variable to set/reset */
119 a_byte set; /**< iff true, variable will be set, else reset */
120 const char *description; /**< description of this option */
122 /* this must be first */
123 { X("help"), NULL, 0, "print FCC related help options" },
125 /* firm optimization options */
126 { X("pic"), &firm_opt.pic, 1, "firm: generate position independent code" },
127 { X("g0"), &firm_opt.debug_mode, DBG_MODE_BACKSTORE, "firm: Debug Mode: use back stores" },
128 { X("g1"), &firm_opt.debug_mode, DBG_MODE_FULL, "firm: Debug Mode: no register variables" },
129 { X("no-opt"), NULL, 0, "firm: disable all FIRM optimizations" },
130 { X("cse"), &firm_opt.cse, 1, "firm: enable common subexpression elimination" },
131 { X("no-cse"), &firm_opt.cse, 0, "firm: disable common subexpression elimination" },
132 { X("const-fold"), &firm_opt.const_folding, 1, "firm: enable constant folding" },
133 { X("no-const-fold"), &firm_opt.const_folding, 0, "firm: disable constant folding" },
134 { X("control_flow"), &firm_opt.control_flow, 1, "firm: enable control flow optimization" },
135 { X("no-control-flow"), &firm_opt.control_flow, 0, "firm: disable control flow optimization" },
136 { X("combo"), &firm_opt.combo, 1, "firm: enable combined CCE, UCE and GVN" },
137 { X("no-combo"), &firm_opt.combo, 0, "firm: disable combined CCE, UCE and GVN" },
138 { X("gcse"), &firm_opt.gcse, 1, "firm: enable global common subexpression elimination" },
139 { X("no-gcse"), &firm_opt.gcse, 0, "firm: disable global common subexpression elimination" },
140 { X("gvn-pre"), &firm_opt.gvn_pre, 1, "firm: enable GVN partial redundancy elimination" },
141 { X("no-gvn-pre"), &firm_opt.gvn_pre, 0, "firm: disable GVN partial redundancy elimination" },
142 { X("cond-eval"), &firm_opt.cond_eval, 1, "firm: enable partial condition evaluation optimization" },
143 { X("no-cond-eval"), &firm_opt.cond_eval, 0, "firm: disable partial condition evaluation optimization" },
144 { X("if-conv"), &firm_opt.if_conversion, 1, "firm: enable if-conversion optimization" },
145 { X("no-if-conv"), &firm_opt.if_conversion, 0, "firm: disable if-conversion optimization" },
146 { X("opt-func-call"), &firm_opt.func_calls, 1, "firm: enable function call optimization" },
147 { X("no-opt-func-call"), &firm_opt.func_calls, 0, "firm: disable function call optimization" },
148 { X("reassociation"), &firm_opt.reassoc, 1, "firm: enable reassociation" },
149 { X("no-reassociation"), &firm_opt.reassoc, 0, "firm: disable reassociation" },
150 { X("inline"), &firm_opt.do_inline, 1, "firm: enable FIRM inlining" },
151 { X("no-inline"), &firm_opt.do_inline, 0, "firm: disable FIRM inlining" },
152 { X("inline-max-size=<size>"), NULL, 0, "firm: set maximum size for function inlining" },
153 { X("inline-threshold=<size>"),NULL, 0, "firm: set benefice threshold for function inlining" },
154 { X("tail-rec"), &firm_opt.tail_rec, 1, "firm: enable tail-recursion optimization" },
155 { X("no-tail-rec"), &firm_opt.tail_rec, 0, "firm: disable tail-recursion optimization" },
156 { X("strength-red"), &firm_opt.strength_red, 1, "firm: enable strength reduction for loops" },
157 { X("no-strength-red"), &firm_opt.strength_red, 0, "firm: disable strength reduction for loops" },
158 { X("scalar-replace"), &firm_opt.scalar_replace, 1, "firm: enable scalar replacement" },
159 { X("no-scalar-replace"), &firm_opt.scalar_replace, 0, "firm: disable scalar replacement" },
160 { X("confirm"), &firm_opt.confirm, 1, "firm: enable Confirm optimization" },
161 { X("no-confirm"), &firm_opt.confirm, 0, "firm: disable Confirm optimization" },
162 { X("opt-mul"), &firm_opt.muls, 1, "firm: enable multiplication optimization" },
163 { X("no-opt-mul"), &firm_opt.muls, 0, "firm: disable multiplication optimization" },
164 { X("opt-div"), &firm_opt.divs, 1, "firm: enable division optimization" },
165 { X("no-opt-div"), &firm_opt.divs, 0, "firm: disable division optimization" },
166 { X("opt-mod"), &firm_opt.mods, 1, "firm: enable remainder optimization" },
167 { X("no-opt-mod"), &firm_opt.mods, 0, "firm: disable remainder optimization" },
168 { X("opt-fragile-ops"), &firm_opt.fragile_ops, 1, "firm: enable fragile ops optimization" },
169 { X("no-opt-fragile-ops"), &firm_opt.fragile_ops, 0, "firm: disable fragile ops optimization" },
170 { X("opt-load-store"), &firm_opt.load_store, 1, "firm: enable load store optimization" },
171 { X("no-opt-load-store"), &firm_opt.load_store, 0, "firm: disable load store optimization" },
172 { X("opt-modes"), &firm_opt.modes, 1, "firm: optimize integer modes" },
173 { X("no-opt-modes"), &firm_opt.modes, 0, "firm: disable integer modes optimization" },
174 { X("sync"), &firm_opt.auto_sync, 1, "firm: automatically create Sync nodes" },
175 { X("no-sync"), &firm_opt.auto_sync, 0, "firm: do not create Sync nodes" },
176 { X("opt-alias"), &firm_opt.alias_analysis, 1, "firm: enable alias analysis" },
177 { X("no-opt-alias"), &firm_opt.alias_analysis, 0, "firm: disable alias analysis" },
178 { X("alias"), &firm_opt.no_alias, 0, "firm: aliasing occurs" },
179 { X("no-alias"), &firm_opt.no_alias, 1, "firm: no aliasing occurs" },
180 { X("strict-aliasing"), &firm_opt.strict_alias, 1, "firm: strict alias rules" },
181 { X("no-strict-aliasing"), &firm_opt.strict_alias, 0, "firm: strict alias rules" },
182 { X("opt-proc-clone"), &firm_opt.cloning, 1, "firm: enable procedure cloning" },
183 { X("no-opt-proc-clone"), &firm_opt.cloning, 0, "firm: disable procedure cloning" },
184 { X("clone-threshold=<value>"),NULL, 0, "firm: set clone threshold to <value>" },
185 { X("DivMod"), &firm_opt.use_DivMod, 1, "firm: use DivMod nodes" },
186 { X("no-DivMod"), &firm_opt.use_DivMod, 0, "firm: don't use DivMod nodes" },
187 { X("precise-except"), &firm_opt.precise_exc, 1, "firm: precise exception context" },
188 { X("no-precise-except"), &firm_opt.precise_exc, 0, "firm: no precise exception context" },
189 { X("remove-unused"), &firm_opt.remove_unused, 1, "firm: remove unused functions" },
190 { X("no-remove-unused"), &firm_opt.remove_unused, 0, "firm: dont't remove unused functions" },
191 { X("fp-precise"), &firm_opt.fp_model, fp_model_precise, "firm: precise fp model" },
192 { X("fp-fast"), &firm_opt.fp_model, fp_model_fast, "firm: fast fp model" },
193 { X("fp-strict"), &firm_opt.fp_model, fp_model_strict, "firm: strict fp model" },
194 { X("sync"), &firm_opt.sync, 1, "firm: use Syncs to remove unnecessary memory dependencies" },
195 { X("no-sync"), &firm_opt.sync, 0, "firm: do not use Syncs to remove unnecessary memory dependencies" },
196 { X("deconv"), &firm_opt.deconv, 1, "firm: enable the conv node optimization" },
197 { X("no-deconv"), &firm_opt.deconv, 0, "firm: disable the conv node optimization" },
198 { X("opt-cc"), &firm_opt.cc_opt, 1, "firm: enable calling conventions optimization" },
199 { X("no-opt-cc"), &firm_opt.cc_opt, 0, "firm: disable calling conventions optimization" },
200 { X("bool"), &firm_opt.bool_opt, 1, "firm: enable bool simplification optimization" },
201 { X("no-bool"), &firm_opt.bool_opt, 0, "firm: disable bool simplification optimization" },
202 { X("shape-blocks"), &firm_opt.shape_blocks, 1, "firm: enable block shaping" },
203 { X("no-shape-blcoks"), &firm_opt.shape_blocks, 0, "firm: disable block shaping" },
204 { X("freestanding"), &firm_opt.freestanding, 1, "firm: freestanding environment" },
205 { X("hosted"), &firm_opt.freestanding, 0, "firm: hosted environment" },
207 /* other firm regarding options */
208 { X("restrict"), &firm_opt.honor_restrict, 1, "firm: honor restrict keyword" },
209 { X("no-restrict"), &firm_opt.honor_restrict, 1, "firm: restrict keyword is meaningless" },
210 { X("no-lower"), &firm_opt.lower, 0, "firm: disable lowering" },
211 { X("vrfy-off"), &firm_opt.vrfy, FIRM_VERIFICATION_OFF, "firm: disable node verification" },
212 { X("vrfy-on"), &firm_opt.vrfy, FIRM_VERIFICATION_ON, "firm: enable node verification" },
213 { X("vrfy-report"), &firm_opt.vrfy, FIRM_VERIFICATION_REPORT, "firm: node verification, report only" },
214 { X("check-all"), &firm_opt.check_all, 1, "firm: enable checking all Firm phases" },
215 { X("no-check-all"), &firm_opt.check_all, 0, "firm: disable checking all Firm phases" },
216 { X("vrfy-edges-on"), &firm_opt.vrfy_edges, 1, "firm: enable out edge verification" },
217 { X("vrfy-edges-off"), &firm_opt.vrfy_edges, 0, "firm: disable out edge verification" },
220 #if defined(_DEBUG) || defined(FIRM_DEBUG)
221 { X("debug"), &firm_dump.debug_print, 1, "firm: enable debug output" },
224 { X("dump-ir"), &firm_dump.ir_graph, 1, "firm: dump IR graph" },
225 { X("dump-all-types"), &firm_dump.all_types, 1, "firm: dump graph of all types" },
226 { X("dump-no-blocks"), &firm_dump.no_blocks, 1, "firm: dump non-blocked graph" },
227 { X("dump-extbb"), &firm_dump.extbb, 1, "firm: dump extended basic blocks" },
228 { X("dump-all-phases"), &firm_dump.all_phases, 1, "firm: dump graphs for all optimization phases" },
229 { X("dump-edge-labels"), &firm_dump.edge_labels, 1, "firm: dump edge labels" },
231 /* code generation */
232 { X("no-codegen"), &firm_be_opt.selection, BE_NONE, "cg: disable code generator" },
235 { X("grs-simd-opt"), &firm_ext_grs.simd_opt, 1, "firm: do simd optimization" },
236 { X("grs-create-pattern"), &firm_ext_grs.create_pattern, 1, "firm: create patterns for simd optimization" },
237 { X("no-grs-simd-opt"), &firm_ext_grs.simd_opt, 0, "firm: do simd optimization" },
238 { X("no-grs-create-pattern"), &firm_ext_grs.create_pattern, 0, "firm: create patterns for simd optimization" },
242 { X("be-firm"), &firm_be_opt.selection, BE_FIRM_BE, "backend: firm backend facility" },
243 #endif /* FIRM_BACKEND */
244 #ifdef FIRM2C_BACKEND
245 { X("be-firm2c"), &firm_be_opt.selection, BE_FIRM2C, "backend: firm2C" },
246 #endif /* FIRM2C_BACKEND */
249 { X("stat-before-opt"), &firm_dump.statistic, STAT_BEFORE_OPT, "misc: Firm statistic output before optimizations" },
250 { X("stat-after-opt"), &firm_dump.statistic, STAT_AFTER_OPT, "misc: Firm statistic output after optimizations" },
251 { X("stat-after-lower"), &firm_dump.statistic, STAT_AFTER_LOWER, "misc: Firm statistic output after lowering" },
252 { X("stat-final-ir"), &firm_dump.statistic, STAT_FINAL_IR, "misc: Firm statistic after final optimization" },
253 { X("stat-final"), &firm_dump.statistic, STAT_FINAL, "misc: Firm statistic after code generation" },
254 { X("stat-pattern"), &firm_dump.stat_pattern, 1, "misc: Firm statistic calculates most used pattern" },
255 { X("stat-dag"), &firm_dump.stat_dag, 1, "misc: Firm calculates DAG statistics" },
256 { X("firm-asm"), &firm_dump.gen_firm_asm, 1, "misc: output Firm assembler" },
257 { X("win32"), &firm_opt.os_support, OS_SUPPORT_MINGW, "misc: generate MinGW Win32 code" },
258 { X("mac"), &firm_opt.os_support, OS_SUPPORT_MACHO, "misc: generate MacOS code" },
259 { X("linux"), &firm_opt.os_support, OS_SUPPORT_LINUX, "misc: generate Linux-ELF code" },
260 { X("ycomp"), &firm_opt.ycomp_dbg, 1, "misc: enable yComp debugger extension" },
261 { X("ycomp-host=<hostname>"), NULL, 0, "misc: yComp host" },
262 { X("ycomp-port=<port>"), NULL, 0, "misc: yComp port" },
265 { X("dump-filter=<string>"), NULL, 0, "misc: set dumper filter" },
270 /** A strdup replacement */
271 static char *StrDup(const char *s) {
273 char *r = malloc(l+1);
281 * Set a dumper filter.
283 static void set_dump_filter(const char *filter)
285 firm_dump.filter = StrDup(filter);
286 } /* set_dump_filter */
291 static void set_ycomp_host(const char *host)
293 firm_opt.ycomp_host = StrDup(host);
294 } /* set_ycomp_host */
296 /** Disable all optimizations. */
297 static void disable_opts(void) {
298 /* firm_opt.const_folding */
299 firm_opt.reassoc = FALSE;
300 firm_opt.cse = FALSE;
301 /* firm_opt.control_flow */
302 firm_opt.gcse = FALSE;
303 firm_opt.gvn_pre = FALSE;
304 firm_opt.cond_eval = FALSE;
305 firm_opt.if_conversion = FALSE;
306 firm_opt.func_calls = FALSE;
307 firm_opt.do_inline = FALSE;
308 firm_opt.auto_inline = FALSE;
309 firm_opt.tail_rec = FALSE;
310 firm_opt.strength_red = FALSE;
311 firm_opt.scalar_replace = FALSE;
312 firm_opt.confirm = FALSE;
313 firm_opt.muls = FALSE;
314 firm_opt.divs = FALSE;
315 firm_opt.mods = FALSE;
316 firm_opt.fragile_ops = FALSE;
317 firm_opt.load_store = FALSE;
318 firm_opt.remove_unused = FALSE;
319 /* firm_opt.jmp_tbls */
320 firm_opt.cloning = FALSE;
321 /* firm_opt.auto_sync */
322 firm_opt.alias_analysis = FALSE;
323 firm_opt.strict_alias = FALSE;
324 firm_opt.no_alias = FALSE;
325 firm_opt.sync = FALSE;
326 firm_opt.deconv = FALSE;
327 firm_opt.cc_opt = FALSE;
328 firm_opt.bool_opt = FALSE;
329 firm_opt.shape_blocks = FALSE;
330 firm_opt.freestanding = TRUE;
334 * Handles a firm option.
336 int firm_option(const char *opt)
338 int i, len = strlen(opt);
342 if (strncmp("dump-filter=", opt, 12) == 0) {
344 set_dump_filter(opt);
347 else if (strncmp("clone-threshold=", opt, 16) == 0) {
348 sscanf(&opt[16], "%d", &firm_opt.clone_threshold);
349 firm_opt.cloning = TRUE;
352 else if (strncmp("inline-max-size=", opt, 16) == 0) {
353 sscanf(&opt[16], "%u", &firm_opt.inline_maxsize);
356 else if (strncmp("inline-threshold=", opt, 17) == 0) {
357 sscanf(&opt[17], "%u", &firm_opt.inline_threshold);
360 else if (strncmp("ycomp-host=", opt, 11) == 0) {
365 else if (strncmp("ycomp-port=", opt, 11) == 0) {
366 sscanf(&opt[11], "%d", &firm_opt.ycomp_port);
369 else if (strcmp("no-opt", opt) == 0) {
374 for (i = sizeof(firm_options) / sizeof(firm_options[0]) - 1; i >= 0; --i) {
375 if (len == firm_options[i].opt_len && strncmp(p, firm_options[i].option, len) == 0) {
376 if (!firm_options[i].flag) {
378 for (i = 0; i < (int) (sizeof(firm_options)/sizeof(firm_options[0])); ++i) {
379 printf("-f %-20s %s\n", firm_options[i].option,
380 firm_options[i].description);
384 /* statistic options do accumulate */
385 if (firm_options[i].flag == &firm_dump.statistic)
386 *firm_options[i].flag = (a_byte) (*firm_options[i].flag | firm_options[i].set);
388 *firm_options[i].flag = firm_options[i].set;
390 if (firm_options[i].flag == &firm_opt.debug_mode && firm_opt.debug_mode > DBG_MODE_NONE) {
391 if (firm_opt.debug_mode == DBG_MODE_FULL)
394 res &= firm_be_option("omitfp=0");
395 res &= firm_be_option("stabs");
408 * Handles a firm backend option.
410 * The options are here only checked for validity and later transmitted
411 * to the firm backend (in the hope they do not fail ...)
413 int firm_be_option(const char *opt) {
415 return be_parse_arg(opt);
418 #endif /* FIRM_BACKEND */
419 } /* firm_be_option */
422 * prints the firm version number
424 void print_firm_version(FILE *f) {
425 firm_version_t version;
427 firm_get_version(&version);
429 fprintf(f, "Firm C-Compiler using libFirm (%u.%u", version.major, version.minor);
430 if (version.revision[0] != 0) {
432 fputs(version.revision, f);
434 if(version.build[0] != 0) {
436 fputs(version.build, f);
439 "(C) 2005-2008 Michael Beck\n"
440 "(C) 1995-2008 University of Karlsruhe\n"
442 } /* print_firm_version */