X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;ds=sidebyside;f=main.c;h=0f2188edbf36791b4f61ebeac94ed09691225c8a;hb=296ba6e16420b89723d1a5b1217d6ecfc2fb0c7d;hp=e549ec6a7c0d14ba914c77ecca50bd1a5837b2f4;hpb=d85247150b70066777321f406a35c76dca96cc20;p=cparser diff --git a/main.c b/main.c index e549ec6..0f2188e 100644 --- a/main.c +++ b/main.c @@ -59,6 +59,7 @@ #include #include +#include #include "preprocessor.h" #include "token_t.h" @@ -77,6 +78,7 @@ #include "adt/array.h" #include "wrappergen/write_fluffy.h" #include "wrappergen/write_jna.h" +#include "wrappergen/write_compoundsizes.h" #include "revision.h" #include "warning.h" #include "help.h" @@ -85,7 +87,7 @@ #ifndef PREPROCESSOR #ifndef __WIN32__ -#define PREPROCESSOR "gcc -E -U__STRICT_ANSI__" +#define PREPROCESSOR "gcc -E -U__STRICT_ANSI__ -U__BLOCKS__" #else #define PREPROCESSOR "cpp -U__STRICT_ANSI__" #endif @@ -131,8 +133,10 @@ typedef enum lang_standard_t { STANDARD_C89, /* ISO C90 (sic) */ STANDARD_C89AMD1, /* ISO C90 as modified in amendment 1 */ STANDARD_C99, /* ISO C99 */ + STANDARD_C11, /* ISO C11 */ STANDARD_GNU89, /* ISO C90 plus GNU extensions (including some C99) */ STANDARD_GNU99, /* ISO C99 plus GNU extensions */ + STANDARD_GNU11, /* ISO C11 plus GNU extensions */ STANDARD_CXX98, /* ISO C++ 1998 plus amendments */ STANDARD_GNUXX98 /* ISO C++ 1998 plus amendments and GNU extensions */ } lang_standard_t; @@ -221,11 +225,11 @@ static void do_parsing(compilation_unit_t *unit) { ir_timer_t *t_parsing = ir_timer_new(); timer_register(t_parsing, "Frontend: Parsing"); - timer_push(t_parsing); + timer_start(t_parsing); start_parsing(); - switch_pp_input(unit->input, unit->name, NULL); + switch_pp_input(unit->input, unit->name, NULL, false); parse(); unit->ast = finish_parsing(); check_unclosed_conditionals(); @@ -236,7 +240,10 @@ static void do_parsing(compilation_unit_t *unit) unit->type = COMPILATION_UNIT_AST; unit->parse_errors = error_count > 0 || !res; - timer_pop(t_parsing); + timer_stop(t_parsing); + if (stat_ev_enabled) { + stat_ev_dbl("time_parsing", ir_timer_elapsed_sec(t_parsing)); + } } static void add_flag(struct obstack *obst, const char *format, ...) @@ -298,8 +305,10 @@ static char const* str_lang_standard(lang_standard_t const standard) case STANDARD_C89: return "c89"; case STANDARD_C89AMD1: return "iso9899:199409"; case STANDARD_C99: return "c99"; + case STANDARD_C11: return "c11"; case STANDARD_GNU89: return "gnu89"; case STANDARD_GNU99: return "gnu99"; + case STANDARD_GNU11: return "gnu11"; case STANDARD_CXX98: return "c++98"; case STANDARD_GNUXX98: return "gnu++98"; case STANDARD_ANSI: break; @@ -555,6 +564,9 @@ static FILE *make_temp_file(const char *prefix, const char **name_result) static void free_temp_files(void) { + if (temp_files == NULL) + return; + size_t n_temp_files = ARR_LEN(temp_files); size_t i; for (i = 0; i < n_temp_files; ++i) { @@ -576,7 +588,8 @@ typedef enum compile_mode_t { CompileAssembleLink, PrintAst, PrintFluffy, - PrintJna + PrintJna, + PrintCompoundSizes, } compile_mode_t; static void usage(const char *argv0) @@ -676,11 +689,13 @@ static void print_help_parser(void) put_choice("c99", "ISO C99 standard"); put_choice("c89", "ISO C89 standard"); put_choice("c90", "Same as -std=c89"); + put_choice("c11", "ISO C11 standard"); put_choice("c9x", "Deprecated"); put_choice("c++", "ISO C++ 98"); put_choice("c++98", "ISO C++ 98"); put_choice("gnu99", "ISO C99 + GNU extensions (default)"); put_choice("gnu89", "ISO C89 + GNU extensions"); + put_choice("gnu11", "ISO C11 + GNU extensions"); put_choice("gnu9x", "Deprecated"); put_choice("iso9899:1990", "ISO C89"); put_choice("iso9899:199409", "ISO C90"); @@ -770,6 +785,8 @@ static void print_help_debug(void) put_help("--print-parenthesis", ""); put_help("--benchmark", "Preprocess and parse, produces no output"); put_help("--time", "Measure time of compiler passes"); + put_help("--statev", "Produce statev output"); + put_help("--filtev=filter", "Set statev filter regex"); put_help("--dump-function func", "Preprocess, parse and output vcg graph of func"); put_help("--export-ir", "Preprocess, parse and output compiler intermediate representation"); } @@ -974,7 +991,7 @@ static void init_types_and_adjust(void) /* operating system ABI specifics */ if (firm_is_darwin_os(target_machine)) { - if (machine_size == 32) { + if (is_ia32_cpu(target_machine->cpu_type)) { props[ATOMIC_TYPE_LONGLONG].struct_alignment = 4; props[ATOMIC_TYPE_ULONGLONG].struct_alignment = 4; props[ATOMIC_TYPE_DOUBLE].struct_alignment = 4; @@ -983,7 +1000,11 @@ static void init_types_and_adjust(void) props[ATOMIC_TYPE_LONG_DOUBLE].struct_alignment = 16; } } else if (firm_is_windows_os(target_machine)) { - if (machine_size == 64) { + if (is_ia32_cpu(target_machine->cpu_type)) { + props[ATOMIC_TYPE_LONGLONG].struct_alignment = 8; + props[ATOMIC_TYPE_ULONGLONG].struct_alignment = 8; + props[ATOMIC_TYPE_DOUBLE].struct_alignment = 8; + } else if (machine_size == 64) { /* to ease porting of old c-code microsoft decided to use 32bits * even for long */ props[ATOMIC_TYPE_LONG] = props[ATOMIC_TYPE_INT]; @@ -994,8 +1015,6 @@ static void init_types_and_adjust(void) props[ATOMIC_TYPE_LONG_DOUBLE] = props[ATOMIC_TYPE_DOUBLE]; } else if (firm_is_unixish_os(target_machine)) { if (is_ia32_cpu(target_machine->cpu_type)) { - /* System V has a broken alignment for double so we have to add - * a hack here */ props[ATOMIC_TYPE_DOUBLE].struct_alignment = 4; props[ATOMIC_TYPE_LONGLONG].struct_alignment = 4; props[ATOMIC_TYPE_ULONGLONG].struct_alignment = 4; @@ -1064,11 +1083,13 @@ static void setup_cmode(const compilation_unit_t *unit) lang_standard_t standard = unit->standard; if (type == COMPILATION_UNIT_PREPROCESSED_C || type == COMPILATION_UNIT_C) { switch (standard) { - case STANDARD_C89: c_mode = _C89; break; + case STANDARD_C89: c_mode = _C89; break; /* TODO determine difference between these two */ - case STANDARD_C89AMD1: c_mode = _C89; break; - case STANDARD_C99: c_mode = _C89 | _C99; break; - case STANDARD_GNU89: c_mode = _C89 | _GNUC; break; + case STANDARD_C89AMD1: c_mode = _C89; break; + case STANDARD_C99: c_mode = _C89 | _C99; break; + case STANDARD_C11: c_mode = _C89 | _C99 | _C11; break; + case STANDARD_GNU89: c_mode = _C89 | _GNUC; break; + case STANDARD_GNU11: c_mode = _C89 | _C99 | _C11 | _GNUC; break; case STANDARD_ANSI: case STANDARD_CXX98: @@ -1087,8 +1108,10 @@ static void setup_cmode(const compilation_unit_t *unit) case STANDARD_C89: case STANDARD_C89AMD1: case STANDARD_C99: + case STANDARD_C11: case STANDARD_GNU89: case STANDARD_GNU99: + case STANDARD_GNU11: case STANDARD_DEFAULT: fprintf(stderr, "warning: command line option \"-std=%s\" is not valid for C++\n", str_lang_standard(standard)); /* FALLTHROUGH */ @@ -1148,7 +1171,7 @@ static bool output_preprocessor_tokens(compilation_unit_t *unit, FILE *out) fprintf(out, "# 1 \"\"\n"); set_preprocessor_output(out); - switch_pp_input(unit->input, unit->name, NULL); + switch_pp_input(unit->input, unit->name, NULL, false); for (;;) { next_preprocessing_token(); @@ -1193,6 +1216,25 @@ static bool open_input(compilation_unit_t *unit) return true; } +static void node_counter(ir_node *node, void *env) +{ + (void)node; + unsigned long long *count = (unsigned long long*)env; + ++(*count); +} + +static unsigned long long count_firm_nodes(void) +{ + unsigned long long count = 0; + + int n_irgs = get_irp_n_irgs(); + for (int i = 0; i < n_irgs; ++i) { + ir_graph *irg = get_irp_irg(i); + irg_walk_graph(irg, node_counter, NULL, &count); + } + return count; +} + static int compilation_loop(compile_mode_t mode, compilation_unit_t *units, lang_standard_t standard, FILE *out) { @@ -1204,20 +1246,22 @@ static int compilation_loop(compile_mode_t mode, compilation_unit_t *units, determine_unit_standard(unit, standard); setup_cmode(unit); + stat_ev_ctx_push_str("compilation_unit", inputname); + again: switch (unit->type) { case COMPILATION_UNIT_IR: { bool res = open_input(unit); if (!res) { result = EXIT_FAILURE; - continue; + break; } res = !ir_import_file(unit->input, unit->name); if (!res) { fprintf(stderr, "Import of firm graph from '%s' failed\n", inputname); result = EXIT_FAILURE; - continue; + break; } unit->type = COMPILATION_UNIT_INTERMEDIATE_REPRESENTATION; goto again; @@ -1230,7 +1274,7 @@ again: bool res = run_external_preprocessor(unit); if (!res) { result = EXIT_FAILURE; - continue; + break; } goto again; } @@ -1241,7 +1285,7 @@ again: bool res = open_input(unit); if (!res) { result = EXIT_FAILURE; - continue; + break; } init_tokens(); @@ -1249,9 +1293,9 @@ again: bool res = output_preprocessor_tokens(unit, out); if (!res) { result = EXIT_FAILURE; - continue; + break; } - continue; + break; } /* do the actual parsing */ @@ -1277,23 +1321,33 @@ again: } else if (mode == PrintJna) { write_jna_decls(out, unit->ast); break; + } else if (mode == PrintCompoundSizes) { + write_compoundsizes(out, unit->ast); + break; } /* build the firm graph */ ir_timer_t *t_construct = ir_timer_new(); timer_register(t_construct, "Frontend: Graph construction"); - timer_push(t_construct); + timer_start(t_construct); if (already_constructed_firm) { panic("compiling multiple files/translation units not possible"); } init_implicit_optimizations(); translation_unit_to_firm(unit->ast); already_constructed_firm = true; - timer_pop(t_construct); + timer_stop(t_construct); + if (stat_ev_enabled) { + stat_ev_dbl("time_graph_construction", ir_timer_elapsed_sec(t_construct)); + stat_ev_int("size_graph_construction", count_firm_nodes()); + } unit->type = COMPILATION_UNIT_INTERMEDIATE_REPRESENTATION; goto again; case COMPILATION_UNIT_INTERMEDIATE_REPRESENTATION: + if (mode == ParseOnly) + break; + if (mode == CompileDump) { /* find irg */ ident *id = new_id_from_str(dumpfunction); @@ -1334,7 +1388,14 @@ again: } else { asm_out = make_temp_file("ccs", &unit->name); } + ir_timer_t *t_opt_codegen = ir_timer_new(); + timer_register(t_opt_codegen, "Optimization and Codegeneration"); + timer_start(t_opt_codegen); generate_code(asm_out, inputname); + timer_stop(t_opt_codegen); + if (stat_ev_enabled) { + stat_ev_dbl("time_opt_codegen", ir_timer_elapsed_sec(t_opt_codegen)); + } if (asm_out != out) { fclose(asm_out); } @@ -1364,6 +1425,8 @@ again: case COMPILATION_UNIT_OBJECT: break; } + + stat_ev_ctx_pop("compilation_unit"); } return result; } @@ -1417,9 +1480,12 @@ int main(int argc, char **argv) compilation_unit_t *units = NULL; compilation_unit_t *last_unit = NULL; bool construct_dep_target = false; - bool do_timing = false; + bool produce_statev = false; + const char *filtev = NULL; bool profile_generate = false; bool profile_use = false; + bool do_timing = false; + bool print_timing = false; /* hack for now... */ if (strstr(argv[0], "pptest") != NULL) { @@ -1434,6 +1500,7 @@ int main(int argc, char **argv) obstack_init(&ldflags_obst); obstack_init(&asflags_obst); obstack_init(&file_obst); + init_include_paths(); #define GET_ARG_AFTER(def, args) \ do { \ @@ -1507,6 +1574,7 @@ int main(int argc, char **argv) const char *opt; GET_ARG_AFTER(opt, "-I"); add_flag(&cppflags_obst, "-I%s", opt); + append_include_path(&bracket_searchpath, opt); } else if (option[0] == 'D') { const char *opt; GET_ARG_AFTER(opt, "-D"); @@ -1558,11 +1626,24 @@ int main(int argc, char **argv) GET_ARG_AFTER(opt, "-include"); add_flag(&cppflags_obst, "-include"); add_flag(&cppflags_obst, "%s", opt); + } else if (streq(option, "idirafter")) { + const char *opt; + GET_ARG_AFTER(opt, "-idirafter"); + add_flag(&cppflags_obst, "-idirafter"); + add_flag(&cppflags_obst, "%s", opt); + append_include_path(&after_searchpath, opt); } else if (streq(option, "isystem")) { const char *opt; GET_ARG_AFTER(opt, "-isystem"); add_flag(&cppflags_obst, "-isystem"); add_flag(&cppflags_obst, "%s", opt); + append_include_path(&system_searchpath, opt); + } else if (streq(option, "iquote")) { + const char *opt; + GET_ARG_AFTER(opt, "-iquote"); + add_flag(&cppflags_obst, "-iquote"); + add_flag(&cppflags_obst, "%s", opt); + append_include_path("e_searchpath, opt); } else if (streq(option, "pthread")) { /* set flags for the preprocessor */ add_flag(&cppflags_obst, "-D_REENTRANT"); @@ -1662,7 +1743,6 @@ int main(int argc, char **argv) streq(opt, "align-loops") || streq(opt, "align-jumps") || streq(opt, "align-functions") || - streq(opt, "unroll-loops") || streq(opt, "PIC") || streq(opt, "stack-protector") || streq(opt, "stack-protector-all")) { @@ -1831,11 +1911,15 @@ int main(int argc, char **argv) standard = streq(o, "c++") ? STANDARD_CXX98 : streq(o, "c++98") ? STANDARD_CXX98 : + streq(o, "c11") ? STANDARD_C11 : + streq(o, "c1x") ? STANDARD_C11 : // deprecated streq(o, "c89") ? STANDARD_C89 : streq(o, "c90") ? STANDARD_C89 : streq(o, "c99") ? STANDARD_C99 : streq(o, "c9x") ? STANDARD_C99 : // deprecated streq(o, "gnu++98") ? STANDARD_GNUXX98 : + streq(o, "gnu11") ? STANDARD_GNU11 : + streq(o, "gnu1x") ? STANDARD_GNU11 : // deprecated streq(o, "gnu89") ? STANDARD_GNU89 : streq(o, "gnu99") ? STANDARD_GNU99 : streq(o, "gnu9x") ? STANDARD_GNU99 : // deprecated @@ -1843,6 +1927,7 @@ int main(int argc, char **argv) streq(o, "iso9899:199409") ? STANDARD_C89AMD1 : streq(o, "iso9899:1999") ? STANDARD_C99 : streq(o, "iso9899:199x") ? STANDARD_C99 : // deprecated + streq(o, "iso9899:2011") ? STANDARD_C11 : (fprintf(stderr, "warning: ignoring gcc option '%s'\n", arg), standard); } else if (streq(option, "version")) { print_cparser_version(); @@ -1880,6 +1965,8 @@ int main(int argc, char **argv) print_parenthesis = true; } else if (streq(option, "print-fluffy")) { mode = PrintFluffy; + } else if (streq(option, "print-compound-sizes")) { + mode = PrintCompoundSizes; } else if (streq(option, "print-jna")) { mode = PrintJna; } else if (streq(option, "jna-limit")) { @@ -1910,7 +1997,13 @@ int main(int argc, char **argv) } else if (streq(option, "no-external-pp")) { external_preprocessor = NULL; } else if (streq(option, "time")) { - do_timing = true; + do_timing = true; + print_timing = true; + } else if (streq(option, "statev")) { + do_timing = true; + produce_statev = true; + } else if (strstart(option, "filtev=")) { + GET_ARG_AFTER(filtev, "--filtev="); } else if (streq(option, "version")) { print_cparser_version(); return EXIT_SUCCESS; @@ -2070,6 +2163,7 @@ int main(int argc, char **argv) case PrintAst: case PrintFluffy: case PrintJna: + case PrintCompoundSizes: case PreprocessOnly: case ParseOnly: outname = "-"; @@ -2115,7 +2209,25 @@ int main(int argc, char **argv) } } + if (produce_statev && units != NULL) { + /* attempt to guess a good name for the file */ + const char *first_cup = units->name; + if (first_cup != NULL) { + const char *dot = strrchr(first_cup, '.'); + const char *pos = dot ? dot : first_cup + strlen(first_cup); + char buf[pos-first_cup+1]; + strncpy(buf, first_cup, pos-first_cup); + buf[pos-first_cup] = '\0'; + + stat_ev_begin(buf, filtev); + } + } + int result = compilation_loop(mode, units, standard, out); + if (stat_ev_enabled) { + stat_ev_end(); + } + if (result != EXIT_SUCCESS) { if (out != stdout) unlink(outname); @@ -2133,8 +2245,9 @@ int main(int argc, char **argv) } if (do_timing) - timer_term(stderr); + timer_term(print_timing ? stderr : NULL); + free_temp_files(); obstack_free(&cppflags_obst, NULL); obstack_free(&ldflags_obst, NULL); obstack_free(&asflags_obst, NULL);