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"
13 #include <libfirm/firm.h>
14 #include <libfirm/be.h>
16 /* optimization settings */
17 struct a_firm_opt firm_opt = {
19 /* debug_mode = */ DBG_MODE_NONE,
20 /* const_folding = */ TRUE,
27 /* alias_analysis = */ TRUE,
28 /* strict_alias = */ FALSE,
29 /* no_alias = */ FALSE,
31 /* fp_model = */ fp_model_precise,
32 /* verify = */ FIRM_VERIFICATION_ON,
33 /* check_all = */ FALSE,
35 /* honor_restrict = */ TRUE,
36 /* lower_bitfields = */ TRUE,
38 /* clone_threshold = */ DEFAULT_CLONE_THRESHOLD,
39 /* inline_maxsize = */ 750,
40 /* inline_threshold= */ 0,
41 /* verify_edges = */ FALSE,
42 /* grs_simd_opt = */ 0,
43 /* grs_create_pattern = */ 0,
44 /* enable_statev = */ FALSE,
45 /* statev_filter = */ "",
49 struct a_firm_dump firm_dump = {
50 /* debug_print = */ FALSE,
51 /* all_types = */ FALSE,
52 /* no_blocks = */ FALSE,
54 /* ir_graph = */ FALSE,
55 /* all_phases = */ FALSE,
56 /* statistic = */ STAT_NONE,
57 /* stat_pattern = */ 0,
63 struct a_firm_ext_grs firm_ext_grs = {
64 /* simd_opt = */ FALSE,
65 /* create_pattern = */ FALSE
69 struct a_firm_be_opt firm_be_opt = {
70 /* selection = */ BE_FIRM_BE,
74 #define X(a) a, sizeof(a)-1
76 /** Parameter description structure */
77 static const struct params {
78 const char *option; /**< name of the option */
79 int opt_len; /**< length of the option string */
80 a_byte *flag; /**< address of variable to set/reset */
81 a_byte set; /**< iff true, variable will be set, else reset */
82 const char *description; /**< description of this option */
84 /* this must be first */
85 { X("help"), NULL, 0, "print FCC related help options" },
87 /* firm optimization options */
88 { X("pic"), &firm_opt.pic, 1, "firm: generate position independent code" },
89 { X("g0"), &firm_opt.debug_mode, DBG_MODE_BACKSTORE, "firm: Debug Mode: use back stores" },
90 { X("g1"), &firm_opt.debug_mode, DBG_MODE_FULL, "firm: Debug Mode: no register variables" },
91 { X("no-opt"), NULL, 0, "firm: disable all FIRM optimizations" },
92 { X("cse"), &firm_opt.cse, 1, "firm: enable common subexpression elimination" },
93 { X("no-cse"), &firm_opt.cse, 0, "firm: disable common subexpression elimination" },
94 { X("const-fold"), &firm_opt.const_folding, 1, "firm: enable constant folding" },
95 { X("no-const-fold"), &firm_opt.const_folding, 0, "firm: disable constant folding" },
96 { X("gcse"), &firm_opt.gcse, 1, "firm: enable global common subexpression elimination" },
97 { X("no-gcse"), &firm_opt.gcse, 0, "firm: disable global common subexpression elimination" },
98 { X("inline-max-size=<size>"), NULL, 0, "firm: set maximum size for function inlining" },
99 { X("inline-threshold=<size>"),NULL, 0, "firm: set benefice threshold for function inlining" },
100 { X("confirm"), &firm_opt.confirm, 1, "firm: enable Confirm optimization" },
101 { X("no-confirm"), &firm_opt.confirm, 0, "firm: disable Confirm optimization" },
102 { X("opt-mul"), &firm_opt.muls, 0, "firm: enable multiplication optimization" },
103 { X("no-opt-mul"), &firm_opt.muls, 0, "firm: disable multiplication optimization" },
104 { X("opt-div"), &firm_opt.divs, 0, "firm: enable division optimization" },
105 { X("no-opt-div"), &firm_opt.divs, 0, "firm: disable division optimization" },
106 { X("opt-mod"), &firm_opt.mods, 0, "firm: enable remainder optimization" },
107 { X("no-opt-mod"), &firm_opt.mods, 0, "firm: disable remainder optimization" },
108 { X("opt-alias"), &firm_opt.alias_analysis, 1, "firm: enable alias analysis" },
109 { X("no-opt-alias"), &firm_opt.alias_analysis, 0, "firm: disable alias analysis" },
110 { X("alias"), &firm_opt.no_alias, 0, "firm: aliasing occurs" },
111 { X("no-alias"), &firm_opt.no_alias, 1, "firm: no aliasing occurs" },
112 { X("strict-aliasing"), &firm_opt.strict_alias, 1, "firm: strict alias rules" },
113 { X("no-strict-aliasing"), &firm_opt.strict_alias, 0, "firm: strict alias rules" },
114 { X("clone-threshold=<value>"),NULL, 0, "firm: set clone threshold to <value>" },
115 { X("fp-precise"), &firm_opt.fp_model, fp_model_precise, "firm: precise fp model" },
116 { X("fp-fast"), &firm_opt.fp_model, fp_model_fast, "firm: fast fp model" },
117 { X("fp-strict"), &firm_opt.fp_model, fp_model_strict, "firm: strict fp model" },
118 { X("opt-cc"), &firm_opt.cc_opt, 1, "firm: enable calling conventions optimization" },
119 { X("no-opt-cc"), &firm_opt.cc_opt, 0, "firm: disable calling conventions optimization" },
121 /* other firm regarding options */
122 { X("restrict"), &firm_opt.honor_restrict, 1, "firm: honor restrict keyword" },
123 { X("no-restrict"), &firm_opt.honor_restrict, 1, "firm: restrict keyword is meaningless" },
124 { X("no-lower"), &firm_opt.lower, 0, "firm: disable lowering" },
125 { X("verify-off"), &firm_opt.verify, FIRM_VERIFICATION_OFF, "firm: disable node verification" },
126 { X("verify-on"), &firm_opt.verify, FIRM_VERIFICATION_ON, "firm: enable node verification" },
127 { X("verify-report"), &firm_opt.verify, FIRM_VERIFICATION_REPORT, "firm: node verification, report only" },
128 { X("check-all"), &firm_opt.check_all, 1, "firm: enable checking all Firm phases" },
129 { X("no-check-all"), &firm_opt.check_all, 0, "firm: disable checking all Firm phases" },
130 { X("verify-edges-on"), &firm_opt.verify_edges, 1, "firm: enable out edge verification" },
131 { X("verify-edges-off"), &firm_opt.verify_edges, 0, "firm: disable out edge verification" },
134 #if defined(_DEBUG) || defined(FIRM_DEBUG)
135 { X("debug"), &firm_dump.debug_print, 1, "firm: enable debug output" },
138 { X("dump-ir"), &firm_dump.ir_graph, 1, "firm: dump IR graph" },
139 { X("dump-all-types"), &firm_dump.all_types, 1, "firm: dump graph of all types" },
140 { X("dump-no-blocks"), &firm_dump.no_blocks, 1, "firm: dump non-blocked graph" },
141 { X("dump-extbb"), &firm_dump.extbb, 1, "firm: dump extended basic blocks" },
142 { X("dump-all-phases"), &firm_dump.all_phases, 1, "firm: dump graphs for all optimization phases" },
144 /* code generation */
145 { X("no-codegen"), &firm_be_opt.selection, BE_NONE, "cg: disable code generator" },
148 { X("grs-simd-opt"), &firm_ext_grs.simd_opt, 1, "firm: do simd optimization" },
149 { X("grs-create-pattern"), &firm_ext_grs.create_pattern, 1, "firm: create patterns for simd optimization" },
150 { X("no-grs-simd-opt"), &firm_ext_grs.simd_opt, 0, "firm: do simd optimization" },
151 { X("no-grs-create-pattern"), &firm_ext_grs.create_pattern, 0, "firm: create patterns for simd optimization" },
154 { X("be-firm"), &firm_be_opt.selection, BE_FIRM_BE, "backend: firm backend facility" },
155 #ifdef FIRM2C_BACKEND
156 { X("be-firm2c"), &firm_be_opt.selection, BE_FIRM2C, "backend: firm2C" },
157 #endif /* FIRM2C_BACKEND */
160 { X("stat-before-opt"), &firm_dump.statistic, STAT_BEFORE_OPT, "misc: Firm statistic output before optimizations" },
161 { X("stat-after-opt"), &firm_dump.statistic, STAT_AFTER_OPT, "misc: Firm statistic output after optimizations" },
162 { X("stat-after-lower"), &firm_dump.statistic, STAT_AFTER_LOWER, "misc: Firm statistic output after lowering" },
163 { X("stat-final-ir"), &firm_dump.statistic, STAT_FINAL_IR, "misc: Firm statistic after final optimization" },
164 { X("stat-final"), &firm_dump.statistic, STAT_FINAL, "misc: Firm statistic after code generation" },
165 { X("stat-pattern"), &firm_dump.stat_pattern, 1, "misc: Firm statistic calculates most used pattern" },
166 { X("stat-dag"), &firm_dump.stat_dag, 1, "misc: Firm calculates DAG statistics" },
169 { X("dump-filter=<string>"), NULL, 0, "misc: set dumper filter" },
174 /** A strdup replacement */
175 static char *StrDup(const char *s) {
177 char *r = malloc(l+1);
185 * Set a dumper filter.
187 static void set_dump_filter(const char *filter)
189 firm_dump.filter = StrDup(filter);
190 } /* set_dump_filter */
192 /** Disable all optimizations. */
193 static void disable_opts(void) {
194 firm_opt.cse = FALSE;
195 firm_opt.gcse = FALSE;
196 firm_opt.confirm = FALSE;
197 firm_opt.muls = FALSE;
198 firm_opt.divs = FALSE;
199 firm_opt.mods = FALSE;
200 firm_opt.alias_analysis = FALSE;
201 firm_opt.strict_alias = FALSE;
202 firm_opt.no_alias = FALSE;
203 firm_opt.cc_opt = FALSE;
207 void print_option_help(const char *name, const char *description)
209 printf("-f %-20s %s\n", name, description);
213 * Handles a firm option.
215 int firm_option(const char *opt)
217 int i, len = strlen(opt);
221 if (strncmp("dump-filter=", opt, 12) == 0) {
223 set_dump_filter(opt);
226 else if (strncmp("clone-threshold=", opt, 16) == 0) {
227 sscanf(&opt[16], "%d", &firm_opt.clone_threshold);
230 else if (strncmp("inline-max-size=", opt, 16) == 0) {
231 sscanf(&opt[16], "%u", &firm_opt.inline_maxsize);
234 else if (strncmp("inline-threshold=", opt, 17) == 0) {
235 sscanf(&opt[17], "%u", &firm_opt.inline_threshold);
238 else if (strcmp("no-opt", opt) == 0) {
243 for (i = sizeof(firm_options) / sizeof(firm_options[0]) - 1; i >= 0; --i) {
244 if (len == firm_options[i].opt_len && strncmp(p, firm_options[i].option, len) == 0) {
245 if (!firm_options[i].flag) {
247 print_option_help(firm_options[0].option, firm_options[0].description);
248 firm_opt_option_help();
249 for (i = 1; i < (int) (sizeof(firm_options)/sizeof(firm_options[0])); ++i) {
250 print_option_help(firm_options[i].option, firm_options[i].description);
254 /* statistic options do accumulate */
255 if (firm_options[i].flag == &firm_dump.statistic)
256 *firm_options[i].flag = (a_byte) (*firm_options[i].flag | firm_options[i].set);
258 *firm_options[i].flag = firm_options[i].set;
260 if (firm_options[i].flag == &firm_opt.debug_mode && firm_opt.debug_mode > DBG_MODE_NONE) {
261 if (firm_opt.debug_mode == DBG_MODE_FULL)
264 res &= be_parse_arg("omitfp=0");
265 res &= be_parse_arg("stabs");
275 /* maybe this enables/disables an optimisations */
276 if (firm_opt_option(p))
283 * prints the firm version number
285 void print_firm_version(FILE *f) {
286 const char *revision = ir_get_version_revision();
287 const char *build = ir_get_version_build();
289 fprintf(f, "Firm C-Compiler using libFirm (%u.%u",
290 ir_get_version_major(), ir_get_version_minor());
291 if (revision[0] != 0) {
300 "(C) 2005-2008 Michael Beck\n"
301 "(C) 1995-2008 University of Karlsruhe\n"
303 } /* print_firm_version */