From 575bfb0052b008995fc992d0728f7bea2173391a Mon Sep 17 00:00:00 2001 From: Lawrence Crowl Date: Mon, 2 May 2011 22:19:48 +0000 Subject: [PATCH] Upgrade the utility of timevars. Index: gcc/ChangeLog 2011-04-27 Lawrence Crowl * timevar.h (timevar_cond_start): Remove unused POP_TIMEVAR_AND_RETURN. (timevar_cond_start): New for starting a timer only when it is not already running. (timevar_cond_stop): New for stopping a timer when it was not already running. * timevar.c (timevar_stop): Enable start/stop timers to start again. (timevar_cond_start): New as above. (timevar_cond_stop): New as above. * timevar.def: Add start/stop timers for compiler phases, TV_PHASE_SETUP, TV_PHASE_PARSING, TV_PHASE_DEFERRED, TV_PHASE_CGRAPH, TV_PHASE_DBGINFO (C), TV_PHASE_CHECK_DBGINFO (C++), TV_PHASE_GENERATE, and TV_PHASE_FINALIZE. Change push/pop timer TV_PARSE to TV_PARSE_GLOBAL. Add push/pop timers TV_PARSE_STRUCT, TV_PARSE_ENUM, TV_PARSE_FUNC, TV_PARSE_INLINE, TV_PARSE_INMETH, TV_TEMPLATE_INST. Change push/pop timer TV_NAME_LOOKUP into a start/stop timer. Make unused TV_OVERLOAD into a start/stop timer. Remove unused timers TV_OVERLOAD, TV_TEMPLATE_INSTANTIATION. Mark the strings for TV_NAME_LOOKUP and TV_OVERLOAD with a "|" to indicate that they are start/stop timers. * toplev.c (compile_file): Change TV_PARSE to TV_PARSE_GLOBAL. Add start/stop timers TV_PHASE_PARSING and TV_PHASE_GENERATE. Move initialization to do_compile. (do_compile): Add initialization from above. Add start/stop timers TV_PHASE_SETUP and TV_PHASE_FINALIZE. * c-decl.c (c_write_global_declarations): Add start/stop of TV_PHASE_DEFERRED, TV_PHASE_CGRAPH, TV_PHASE_DBGINFO. * c-parser.c (c_parser_declaration_or_fndef): Push/pop TV_PARSE_FUNC or TV_PARSE_INLINE, as appropriate. (c_parser_enum_specifier): Push/pop TV_PARSE_ENUM. (c_parser_struct_or_union_specifier): Push/pop TV_PARSE_STRUCT. Index: gcc/cp/ChangeLog 2011-04-27 Lawrence Crowl * decl.c: (push_local_name): Change TV_NAME_LOOKUP to start/stop. (poplevel): Refactor POP_TIMEVAR_AND_RETURN to plain code. Change TV_NAME_LOOKUP to start/stop. (define_label): Refactor timevar calls out to a wrapper function. Change TV_NAME_LOOKUP to start/stop. (xref_tag): Likewise. (lookup_label): Refactor timevar calls out to a wrapper function. Change TV_NAME_LOOKUP to start_cond/stop_cond. * pt.c: (instantiate_class_template): Add a wrapper to push/pop new TV_TEMPLATE_INST. (instantiate_template): Add a wrapper to push/pop new TV_TEMPLATE_INST. (lookup_template_class): Refactor timevar calls out to a wrapper function. Change use of TV_NAME_LOOKUP to TV_TEMPLATE_INST. (instantiate_decl): Change TV_PARSE to TV_TEMPLATE_INST. * name-lookup.c: (store_bindings): Change TV_NAME_LOOKUP to start/stop. (poplevel_class): Change TV_NAME_LOOKUP to start_cond/stop_cond. (push_namespace): Likewise. (pop_nested_namespace): Likewise. (pushdecl_namespace_level): Likewise. (store_class_bindings): Likewise. (push_to_top_level): Likewise. (identifier_type_value): Refactor timevar calls out to a wrapper function. Change TV_NAME_LOOKUP to start/stop. (find_binding): Likewise. (push_using_decl): Likewise. (lookup_arg_dependent): Likewise. (push_using_directive): Likewise. (qualified_lookup_using_namespace): Refactor POP_TIMEVAR_AND_RETURN to plain code. Change TV_NAME_LOOKUP to start/stop. (lookup_type_current_level): Likewise. Refactor inner return to break. (pushdecl_class_level): Refactor POP_TIMEVAR_AND_RETURN to plain code. Change TV_NAME_LOOKUP to start_cond/stop_cond. (pushdecl_top_level_1): Likewise. (lookup_using_namespace): Likewise. (pushdecl_with_scope): Refactor timevar calls out to a wrapper function. Change TV_NAME_LOOKUP to start_cond/stop_cond. (push_overloaded_decl): Likewise. (push_class_level_binding): Likewise. (namespace_binding): Likewise. (set_namespace_binding): Likewise. (supplement_binding): Likewise. (unqualified_namespace_lookup): Likewise. (lookup_name_real): Likewise. (lookup_type_scope): Likewise. (namespace_ancestor): Likewise. (lookup_name_innermost_nonclass_level): Likewise. (pushtag): Likewise. (pop_from_top_level): Likewise. (pushdecl_maybe_friend): Refactor timevar calls out to a wrapper function. Change TV_NAME_LOOKUP to start_cond/stop_cond. Wrap long lines. (add_using_namespace): Refactor timevar calls out to a wrapper function. Change TV_NAME_LOOKUP to start_cond/stop_cond. Bypass wrapper on call to self. * decl2.c: (cp_write_global_declarations): Add start/stop of new TV_PHASE_DEFERRED, TV_PHASE_CGRAPH, TV_PHASE_CHECK_DBGINFO. Remove push/pop calls to TV_VARCONST. * parser.c: Add include of "timevar.h". (cp_parser_explicit_instantiation): Add push/pop calls to TV_TEMPLATE_INST. (cp_parser_enum_specifier): Add push/pop calls to new TV_PARSE_ENUM. (cp_parser_class_specifier): Add wrapper to add push/pop calls to TV_PARSE_STRUCT. (cp_parser_function_definition_from_specifiers_and_declarator): Add push/pop calls to new TV_PARSE_FUNC or TV_PARSE_INLINE. (cp_parser_late_parsing_for_member): Add push/pop calls to new TV_PARSE_INMETH. * call.c: Add include of "timevar.h". (convert_class_to_reference): Wrap and add push/pop calls to TV_OVERLOAD. (build_op_call): Likewise. (build_conditional_expr): Likewise. (build_new_op): Likewise. (build_new_method_call): Likewise. (build_user_type_conversion): Reorganize to single return and add push/pop calls to TV_OVERLOAD. (perform_overload_resolution): Likewise. * Make-lang.in: Add dependence of call.o and parser.o on $(TIMEVAR_H). From-SVN: r173277 --- gcc/ChangeLog | 40 ++++ gcc/c-decl.c | 9 + gcc/c-parser.c | 23 +- gcc/cp/ChangeLog | 88 ++++++++ gcc/cp/Make-lang.in | 4 +- gcc/cp/call.c | 135 +++++++++--- gcc/cp/decl.c | 89 +++++--- gcc/cp/decl2.c | 14 +- gcc/cp/name-lookup.c | 515 ++++++++++++++++++++++++++++++------------- gcc/cp/parser.c | 32 ++- gcc/cp/pt.c | 85 ++++--- gcc/timevar.c | 55 +++++ gcc/timevar.def | 23 +- gcc/timevar.h | 5 +- gcc/toplev.c | 52 +++-- 15 files changed, 907 insertions(+), 262 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 10d30a91eee..026a90b5469 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,43 @@ +2011-05-02 Lawrence Crowl + + * timevar.h (timevar_cond_start): Remove unused POP_TIMEVAR_AND_RETURN. + (timevar_cond_start): New for starting a timer only when it is not + already running. + (timevar_cond_stop): New for stopping a timer when it was not already + running. + + * timevar.c (timevar_stop): Enable start/stop timers to start again. + (timevar_cond_start): New as above. + (timevar_cond_stop): New as above. + + * timevar.def: Add start/stop timers for compiler phases, + TV_PHASE_SETUP, TV_PHASE_PARSING, TV_PHASE_DEFERRED, TV_PHASE_CGRAPH, + TV_PHASE_DBGINFO (C), TV_PHASE_CHECK_DBGINFO (C++), TV_PHASE_GENERATE, + and TV_PHASE_FINALIZE. + Change push/pop timer TV_PARSE to TV_PARSE_GLOBAL. + Add push/pop timers TV_PARSE_STRUCT, TV_PARSE_ENUM, TV_PARSE_FUNC, + TV_PARSE_INLINE, TV_PARSE_INMETH, TV_TEMPLATE_INST. + Change push/pop timer TV_NAME_LOOKUP into a start/stop timer. + Make unused TV_OVERLOAD into a start/stop timer. + + Remove unused timers TV_OVERLOAD, TV_TEMPLATE_INSTANTIATION. + Mark the strings for TV_NAME_LOOKUP and TV_OVERLOAD with a "|" + to indicate that they are start/stop timers. + + * toplev.c (compile_file): Change TV_PARSE to TV_PARSE_GLOBAL. + Add start/stop timers TV_PHASE_PARSING and TV_PHASE_GENERATE. + Move initialization to do_compile. + (do_compile): Add initialization from above. + Add start/stop timers TV_PHASE_SETUP and TV_PHASE_FINALIZE. + + * c-decl.c (c_write_global_declarations): Add start/stop of + TV_PHASE_DEFERRED, TV_PHASE_CGRAPH, TV_PHASE_DBGINFO. + + * c-parser.c (c_parser_declaration_or_fndef): Push/pop TV_PARSE_FUNC + or TV_PARSE_INLINE, as appropriate. + (c_parser_enum_specifier): Push/pop TV_PARSE_ENUM. + (c_parser_struct_or_union_specifier): Push/pop TV_PARSE_STRUCT. + 2011-05-02 Jason Merrill PR c++/40975 diff --git a/gcc/c-decl.c b/gcc/c-decl.c index 3470a935d97..9c6cc90d11a 100644 --- a/gcc/c-decl.c +++ b/gcc/c-decl.c @@ -9837,6 +9837,8 @@ c_write_global_declarations (void) if (pch_file) return; + timevar_start (TV_PHASE_DEFERRED); + /* Do the Objective-C stuff. This is where all the Objective-C module stuff gets generated (symtab, class/protocol/selector lists etc). */ @@ -9878,10 +9880,16 @@ c_write_global_declarations (void) c_write_global_declarations_1 (BLOCK_VARS (DECL_INITIAL (t))); c_write_global_declarations_1 (BLOCK_VARS (ext_block)); + timevar_stop (TV_PHASE_DEFERRED); + timevar_start (TV_PHASE_CGRAPH); + /* We're done parsing; proceed to optimize and emit assembly. FIXME: shouldn't be the front end's responsibility to call this. */ cgraph_finalize_compilation_unit (); + timevar_stop (TV_PHASE_CGRAPH); + timevar_start (TV_PHASE_DBGINFO); + /* After cgraph has had a chance to emit everything that's going to be emitted, output debug information for globals. */ if (!seen_error ()) @@ -9894,6 +9902,7 @@ c_write_global_declarations (void) } ext_block = NULL; + timevar_stop (TV_PHASE_DBGINFO); } /* Register reserved keyword WORD as qualifier for address space AS. */ diff --git a/gcc/c-parser.c b/gcc/c-parser.c index b61ebdd1ea8..698a080d452 100644 --- a/gcc/c-parser.c +++ b/gcc/c-parser.c @@ -1570,6 +1570,7 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, { struct c_declarator *declarator; bool dummy = false; + timevar_id_t tv; tree fnbody; /* Declaring either one or more declarators (in which case we should diagnose if there were no declaration specifiers) or a @@ -1699,6 +1700,13 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, c_pop_function_context (); break; } + + if (DECL_DECLARED_INLINE_P (current_function_decl)) + tv = TV_PARSE_INLINE; + else + tv = TV_PARSE_FUNC; + timevar_push (tv); + /* Parse old-style parameter declarations. ??? Attributes are not allowed to start declaration specifiers here because of a syntax conflict between a function declaration with attribute @@ -1737,6 +1745,8 @@ c_parser_declaration_or_fndef (c_parser *parser, bool fndef_ok, add_stmt (fnbody); finish_function (); } + + timevar_pop (tv); break; } } @@ -2189,11 +2199,14 @@ c_parser_enum_specifier (c_parser *parser) { /* Parse an enum definition. */ struct c_enum_contents the_enum; - tree type = start_enum (enum_loc, &the_enum, ident); + tree type; tree postfix_attrs; /* We chain the enumerators in reverse order, then put them in forward order at the end. */ - tree values = NULL_TREE; + tree values; + timevar_push (TV_PARSE_ENUM); + type = start_enum (enum_loc, &the_enum, ident); + values = NULL_TREE; c_parser_consume_token (parser); while (true) { @@ -2257,6 +2270,7 @@ c_parser_enum_specifier (c_parser *parser) ret.kind = ctsk_tagdef; ret.expr = NULL_TREE; ret.expr_const_operands = true; + timevar_pop (TV_PARSE_ENUM); return ret; } else if (!ident) @@ -2370,7 +2384,9 @@ c_parser_struct_or_union_specifier (c_parser *parser) semicolon separated fields than comma separated fields, and so we'll be minimizing the number of node traversals required by chainon. */ - tree contents = NULL_TREE; + tree contents; + timevar_push (TV_PARSE_STRUCT); + contents = NULL_TREE; c_parser_consume_token (parser); /* Handle the Objective-C @defs construct, e.g. foo(sizeof(struct{ @defs(ClassName) }));. */ @@ -2457,6 +2473,7 @@ c_parser_struct_or_union_specifier (c_parser *parser) ret.kind = ctsk_tagdef; ret.expr = NULL_TREE; ret.expr_const_operands = true; + timevar_pop (TV_PARSE_STRUCT); return ret; } else if (!ident) diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 6cf07220a75..e44ff10d9fb 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,91 @@ +2011-05-02 Lawrence Crowl + + * decl.c: (push_local_name): Change TV_NAME_LOOKUP to start/stop. + (poplevel): Refactor POP_TIMEVAR_AND_RETURN to plain code. + Change TV_NAME_LOOKUP to start/stop. + (define_label): Refactor timevar calls out to a wrapper function. + Change TV_NAME_LOOKUP to start/stop. + (xref_tag): Likewise. + (lookup_label): Refactor timevar calls out to a wrapper function. + Change TV_NAME_LOOKUP to start_cond/stop_cond. + + * pt.c: (instantiate_class_template): Add a wrapper to push/pop new + TV_TEMPLATE_INST. + (instantiate_template): Add a wrapper to push/pop new TV_TEMPLATE_INST. + (lookup_template_class): Refactor timevar calls out to a wrapper + function. Change use of TV_NAME_LOOKUP to TV_TEMPLATE_INST. + (instantiate_decl): Change TV_PARSE to TV_TEMPLATE_INST. + + * name-lookup.c: (store_bindings): Change TV_NAME_LOOKUP to start/stop. + (poplevel_class): Change TV_NAME_LOOKUP to start_cond/stop_cond. + (push_namespace): Likewise. + (pop_nested_namespace): Likewise. + (pushdecl_namespace_level): Likewise. + (store_class_bindings): Likewise. + (push_to_top_level): Likewise. + (identifier_type_value): Refactor timevar calls out to a wrapper + function. Change TV_NAME_LOOKUP to start/stop. + (find_binding): Likewise. + (push_using_decl): Likewise. + (lookup_arg_dependent): Likewise. + (push_using_directive): Likewise. + (qualified_lookup_using_namespace): Refactor POP_TIMEVAR_AND_RETURN + to plain code. Change TV_NAME_LOOKUP to start/stop. + (lookup_type_current_level): Likewise. Refactor inner return to + break. + (pushdecl_class_level): Refactor POP_TIMEVAR_AND_RETURN to plain + code. Change TV_NAME_LOOKUP to start_cond/stop_cond. + (pushdecl_top_level_1): Likewise. + (lookup_using_namespace): Likewise. + (pushdecl_with_scope): Refactor timevar calls out to a wrapper + function. Change TV_NAME_LOOKUP to start_cond/stop_cond. + (push_overloaded_decl): Likewise. + (push_class_level_binding): Likewise. + (namespace_binding): Likewise. + (set_namespace_binding): Likewise. + (supplement_binding): Likewise. + (unqualified_namespace_lookup): Likewise. + (lookup_name_real): Likewise. + (lookup_type_scope): Likewise. + (namespace_ancestor): Likewise. + (lookup_name_innermost_nonclass_level): Likewise. + (pushtag): Likewise. + (pop_from_top_level): Likewise. + (pushdecl_maybe_friend): Refactor timevar calls out to a wrapper + function. Change TV_NAME_LOOKUP to start_cond/stop_cond. Wrap long + lines. + (add_using_namespace): Refactor timevar calls out to a wrapper + function. Change TV_NAME_LOOKUP to start_cond/stop_cond. Bypass + wrapper on call to self. + + * decl2.c: (cp_write_global_declarations): Add start/stop of + new TV_PHASE_DEFERRED, TV_PHASE_CGRAPH, TV_PHASE_CHECK_DBGINFO. + Remove push/pop calls to TV_VARCONST. + + * parser.c: Add include of "timevar.h". + (cp_parser_explicit_instantiation): Add push/pop calls to + TV_TEMPLATE_INST. + (cp_parser_enum_specifier): Add push/pop calls to new TV_PARSE_ENUM. + (cp_parser_class_specifier): Add wrapper to add push/pop calls to + TV_PARSE_STRUCT. + (cp_parser_function_definition_from_specifiers_and_declarator): Add + push/pop calls to new TV_PARSE_FUNC or TV_PARSE_INLINE. + (cp_parser_late_parsing_for_member): Add push/pop calls to + new TV_PARSE_INMETH. + + * call.c: Add include of "timevar.h". + (convert_class_to_reference): Wrap and add push/pop calls to + TV_OVERLOAD. + (build_op_call): Likewise. + (build_conditional_expr): Likewise. + (build_new_op): Likewise. + (build_new_method_call): Likewise. + (build_user_type_conversion): Reorganize to single return and add + push/pop calls to TV_OVERLOAD. + (perform_overload_resolution): Likewise. + + * Make-lang.in: Add dependence of call.o and parser.o on $(TIMEVAR_H). + 2011-05-02 Jason Merrill * tree.c (build_vec_init_expr): Take complain parm. diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in index 3aef055346c..22a58464560 100644 --- a/gcc/cp/Make-lang.in +++ b/gcc/cp/Make-lang.in @@ -287,7 +287,7 @@ cp/class.o: cp/class.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) toplev.h \ $(SPLAY_TREE_H) cp/call.o: cp/call.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) toplev.h \ $(DIAGNOSTIC_CORE_H) intl.h gt-cp-call.h convert.h $(TARGET_H) langhooks.h \ - c-family/c-objc.h + $(TIMEVAR_H) c-family/c-objc.h cp/friend.o: cp/friend.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) cp/init.o: cp/init.c $(CXX_TREE_H) $(TM_H) $(FLAGS_H) \ $(EXCEPT_H) $(TARGET_H) @@ -326,7 +326,7 @@ cp/mangle.o: cp/mangle.c $(CXX_TREE_H) $(TM_H) $(REAL_H) \ gt-cp-mangle.h $(TARGET_H) $(TM_P_H) $(CGRAPH_H) cp/parser.o: cp/parser.c $(CXX_TREE_H) $(TM_H) $(DIAGNOSTIC_CORE_H) \ gt-cp-parser.h output.h $(TARGET_H) $(PLUGIN_H) intl.h \ - c-family/c-objc.h tree-pretty-print.h $(CXX_PARSER_H) + c-family/c-objc.h tree-pretty-print.h $(CXX_PARSER_H) $(TIMEVAR.H) cp/cp-gimplify.o: cp/cp-gimplify.c $(CXX_TREE_H) $(C_COMMON_H) \ $(TM_H) coretypes.h pointer-set.h tree-iterator.h diff --git a/gcc/cp/call.c b/gcc/cp/call.c index b759c89ca5c..4dbcce922ee 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -39,6 +39,7 @@ along with GCC; see the file COPYING3. If not see #include "convert.h" #include "langhooks.h" #include "c-family/c-objc.h" +#include "timevar.h" /* The various kinds of conversion. */ @@ -1263,7 +1264,7 @@ reference_compatible_p (tree t1, tree t2) converted to T as in [over.match.ref]. */ static conversion * -convert_class_to_reference (tree reference_type, tree s, tree expr, int flags) +convert_class_to_reference_1 (tree reference_type, tree s, tree expr, int flags) { tree conversions; tree first_arg; @@ -1399,6 +1400,18 @@ convert_class_to_reference (tree reference_type, tree s, tree expr, int flags) return cand->second_conv; } +/* Wrapper for above. */ + +static conversion * +convert_class_to_reference (tree reference_type, tree s, tree expr, int flags) +{ + conversion *ret; + bool subtime = timevar_cond_start (TV_OVERLOAD); + ret = convert_class_to_reference_1 (reference_type, s, expr, flags); + timevar_cond_stop (TV_OVERLOAD, subtime); + return ret; +} + /* A reference of the indicated TYPE is being bound directly to the expression represented by the implicit conversion sequence CONV. Return a conversion sequence for this binding. */ @@ -3493,20 +3506,32 @@ build_user_type_conversion_1 (tree totype, tree expr, int flags) return cand; } +/* Wrapper for above. */ + tree build_user_type_conversion (tree totype, tree expr, int flags) { - struct z_candidate *cand - = build_user_type_conversion_1 (totype, expr, flags); + struct z_candidate *cand; + tree ret; + + timevar_start (TV_OVERLOAD); + cand = build_user_type_conversion_1 (totype, expr, flags); if (cand) { if (cand->second_conv->kind == ck_ambig) - return error_mark_node; - expr = convert_like (cand->second_conv, expr, tf_warning_or_error); - return convert_from_reference (expr); + ret = error_mark_node; + else + { + expr = convert_like (cand->second_conv, expr, tf_warning_or_error); + ret = convert_from_reference (expr); + } } - return NULL_TREE; + else + ret = NULL_TREE; + + timevar_stop (TV_OVERLOAD); + return ret; } /* Subroutine of convert_nontype_argument. @@ -3622,8 +3647,13 @@ perform_overload_resolution (tree fn, bool *any_viable_p) { struct z_candidate *cand; - tree explicit_targs = NULL_TREE; - int template_only = 0; + tree explicit_targs; + int template_only; + + bool subtime = timevar_cond_start (TV_OVERLOAD); + + explicit_targs = NULL_TREE; + template_only = 0; *candidates = NULL; *any_viable_p = true; @@ -3650,10 +3680,12 @@ perform_overload_resolution (tree fn, candidates); *candidates = splice_viable (*candidates, pedantic, any_viable_p); - if (!*any_viable_p) - return NULL; + if (*any_viable_p) + cand = tourney (*candidates); + else + cand = NULL; - cand = tourney (*candidates); + timevar_cond_stop (TV_OVERLOAD, subtime); return cand; } @@ -3852,8 +3884,8 @@ build_operator_new_call (tree fnname, VEC(tree,gc) **args, /* Build a new call to operator(). This may change ARGS. */ -tree -build_op_call (tree obj, VEC(tree,gc) **args, tsubst_flags_t complain) +static tree +build_op_call_1 (tree obj, VEC(tree,gc) **args, tsubst_flags_t complain) { struct z_candidate *candidates = 0, *cand; tree fns, convs, first_mem_arg = NULL_TREE; @@ -3984,6 +4016,18 @@ build_op_call (tree obj, VEC(tree,gc) **args, tsubst_flags_t complain) return result; } +/* Wrapper for above. */ + +tree +build_op_call (tree obj, VEC(tree,gc) **args, tsubst_flags_t complain) +{ + tree ret; + timevar_start (TV_OVERLOAD); + ret = build_op_call_1 (obj, args, complain); + timevar_stop (TV_OVERLOAD); + return ret; +} + static void op_error (enum tree_code code, enum tree_code code2, tree arg1, tree arg2, tree arg3, bool match) @@ -4121,9 +4165,9 @@ conditional_conversion (tree e1, tree e2) /* Implement [expr.cond]. ARG1, ARG2, and ARG3 are the three arguments to the conditional expression. */ -tree -build_conditional_expr (tree arg1, tree arg2, tree arg3, - tsubst_flags_t complain) +static tree +build_conditional_expr_1 (tree arg1, tree arg2, tree arg3, + tsubst_flags_t complain) { tree arg2_type; tree arg3_type; @@ -4552,6 +4596,19 @@ build_conditional_expr (tree arg1, tree arg2, tree arg3, return result; } +/* Wrapper for above. */ + +tree +build_conditional_expr (tree arg1, tree arg2, tree arg3, + tsubst_flags_t complain) +{ + tree ret; + bool subtime = timevar_cond_start (TV_OVERLOAD); + ret = build_conditional_expr_1 (arg1, arg2, arg3, complain); + timevar_cond_stop (TV_OVERLOAD, subtime); + return ret; +} + /* OPERAND is an operand to an expression. Perform necessary steps required before using it. If OPERAND is NULL_TREE, NULL_TREE is returned. */ @@ -4720,8 +4777,8 @@ avoid_sign_compare_warnings (tree orig_arg, tree arg) TREE_NO_WARNING (arg) = 1; } -tree -build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3, +static tree +build_new_op_1 (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3, bool *overloaded_p, tsubst_flags_t complain) { tree orig_arg1 = arg1; @@ -4888,8 +4945,8 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3, code = PREINCREMENT_EXPR; else code = PREDECREMENT_EXPR; - result = build_new_op (code, flags, arg1, NULL_TREE, NULL_TREE, - overloaded_p, complain); + result = build_new_op_1 (code, flags, arg1, NULL_TREE, NULL_TREE, + overloaded_p, complain); break; /* The caller will deal with these. */ @@ -5092,6 +5149,19 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3, return NULL_TREE; } +/* Wrapper for above. */ + +tree +build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3, + bool *overloaded_p, tsubst_flags_t complain) +{ + tree ret; + bool subtime = timevar_cond_start (TV_OVERLOAD); + ret = build_new_op_1 (code, flags, arg1, arg2, arg3, overloaded_p, complain); + timevar_cond_stop (TV_OVERLOAD, subtime); + return ret; +} + /* Returns true iff T, an element of an OVERLOAD chain, is a usual deallocation function (3.7.4.2 [basic.stc.dynamic.deallocation]). */ @@ -6862,10 +6932,10 @@ name_as_c_string (tree name, tree type, bool *free_p) be set, upon return, to the function called. ARGS may be NULL. This may change ARGS. */ -tree -build_new_method_call (tree instance, tree fns, VEC(tree,gc) **args, - tree conversion_path, int flags, - tree *fn_p, tsubst_flags_t complain) +static tree +build_new_method_call_1 (tree instance, tree fns, VEC(tree,gc) **args, + tree conversion_path, int flags, + tree *fn_p, tsubst_flags_t complain) { struct z_candidate *candidates = 0, *cand; tree explicit_targs = NULL_TREE; @@ -7171,6 +7241,21 @@ build_new_method_call (tree instance, tree fns, VEC(tree,gc) **args, return call; } +/* Wrapper for above. */ + +tree +build_new_method_call (tree instance, tree fns, VEC(tree,gc) **args, + tree conversion_path, int flags, + tree *fn_p, tsubst_flags_t complain) +{ + tree ret; + bool subtime = timevar_cond_start (TV_OVERLOAD); + ret = build_new_method_call_1 (instance, fns, args, conversion_path, flags, + fn_p, complain); + timevar_cond_stop (TV_OVERLOAD, subtime); + return ret; +} + /* Returns true iff standard conversion sequence ICS1 is a proper subsequence of ICS2. */ diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index f9dd6dec5f8..e489caefd0b 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -552,7 +552,7 @@ poplevel (int keep, int reverse, int functionbody) unsigned ix; cp_label_binding *label_bind; - timevar_push (TV_NAME_LOOKUP); + timevar_start (TV_NAME_LOOKUP); restart: block = NULL_TREE; @@ -815,7 +815,8 @@ poplevel (int keep, int reverse, int functionbody) if (kind == sk_cleanup) goto restart; - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, block); + timevar_stop (TV_NAME_LOOKUP); + return block; } /* Walk all the namespaces contained NAMESPACE, including NAMESPACE @@ -899,7 +900,7 @@ push_local_name (tree decl) size_t i, nelts; tree t, name; - timevar_push (TV_NAME_LOOKUP); + timevar_start (TV_NAME_LOOKUP); name = DECL_NAME (decl); @@ -918,13 +919,13 @@ push_local_name (tree decl) DECL_DISCRIMINATOR (decl) = 1; VEC_replace (tree, local_names, i, decl); - timevar_pop (TV_NAME_LOOKUP); + timevar_stop (TV_NAME_LOOKUP); return; } } VEC_safe_push (tree, gc, local_names, decl); - timevar_pop (TV_NAME_LOOKUP); + timevar_stop (TV_NAME_LOOKUP); } /* Subroutine of duplicate_decls: return truthvalue of whether @@ -2535,26 +2536,37 @@ make_label_decl (tree id, int local_p) be found, create one. (We keep track of used, but undefined, labels, and complain about them at the end of a function.) */ -tree -lookup_label (tree id) +static tree +lookup_label_1 (tree id) { tree decl; - timevar_push (TV_NAME_LOOKUP); /* You can't use labels at global scope. */ if (current_function_decl == NULL_TREE) { error ("label %qE referenced outside of any function", id); - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE); + return NULL_TREE; } /* See if we've already got this label. */ decl = IDENTIFIER_LABEL_VALUE (id); if (decl != NULL_TREE && DECL_CONTEXT (decl) == current_function_decl) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl); + return decl; decl = make_label_decl (id, /*local_p=*/0); - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl); + return decl; +} + +/* Wrapper for lookup_label_1. */ + +tree +lookup_label (tree id) +{ + tree ret; + bool subtime = timevar_cond_start (TV_NAME_LOOKUP); + ret = lookup_label_1 (id); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); + return ret; } /* Declare a local label named ID. */ @@ -2827,15 +2839,13 @@ check_omp_return (void) /* Define a label, specifying the location in the source file. Return the LABEL_DECL node for the label. */ -tree -define_label (location_t location, tree name) +static tree +define_label_1 (location_t location, tree name) { struct named_label_entry *ent, dummy; struct cp_binding_level *p; tree decl; - timevar_push (TV_NAME_LOOKUP); - decl = lookup_label (name); dummy.label_decl = decl; @@ -2855,7 +2865,7 @@ define_label (location_t location, tree name) if (DECL_INITIAL (decl) != NULL_TREE) { error ("duplicate label %qD", decl); - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); + return error_mark_node; } else { @@ -2874,9 +2884,22 @@ define_label (location_t location, tree name) ent->uses = NULL; } - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl); + return decl; } +/* Wrapper for define_label_1. */ + +tree +define_label (location_t location, tree name) +{ + tree ret; + timevar_start (TV_NAME_LOOKUP); + ret = define_label_1 (location, name); + timevar_stop (TV_NAME_LOOKUP); + return ret; +} + + struct cp_switch { struct cp_binding_level *level; @@ -11262,16 +11285,14 @@ lookup_and_check_tag (enum tag_types tag_code, tree name, TEMPLATE_HEADER_P is true when this declaration is preceded by a set of template parameters. */ -tree -xref_tag (enum tag_types tag_code, tree name, - tag_scope scope, bool template_header_p) +static tree +xref_tag_1 (enum tag_types tag_code, tree name, + tag_scope scope, bool template_header_p) { enum tree_code code; tree t; tree context = NULL_TREE; - timevar_push (TV_NAME_LOOKUP); - gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE); switch (tag_code) @@ -11299,7 +11320,7 @@ xref_tag (enum tag_types tag_code, tree name, scope, template_header_p); if (t == error_mark_node) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); + return error_mark_node; if (scope != ts_current && t && current_class_type && template_class_depth (current_class_type) @@ -11354,7 +11375,7 @@ xref_tag (enum tag_types tag_code, tree name, if (code == ENUMERAL_TYPE) { error ("use of enum %q#D without previous declaration", name); - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); + return error_mark_node; } else { @@ -11368,7 +11389,7 @@ xref_tag (enum tag_types tag_code, tree name, if (template_header_p && MAYBE_CLASS_TYPE_P (t)) { if (!redeclare_class_template (t, current_template_parms)) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); + return error_mark_node; } else if (!processing_template_decl && CLASS_TYPE_P (t) @@ -11376,7 +11397,7 @@ xref_tag (enum tag_types tag_code, tree name, { error ("redeclaration of %qT as a non-template", t); error ("previous declaration %q+D", t); - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); + return error_mark_node; } /* Make injected friend class visible. */ @@ -11394,9 +11415,23 @@ xref_tag (enum tag_types tag_code, tree name, } } - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t); + return t; +} + +/* Wrapper for xref_tag_1. */ + +tree +xref_tag (enum tag_types tag_code, tree name, + tag_scope scope, bool template_header_p) +{ + tree ret; + timevar_start (TV_NAME_LOOKUP); + ret = xref_tag_1 (tag_code, name, scope, template_header_p); + timevar_stop (TV_NAME_LOOKUP); + return ret; } + tree xref_tag_from_type (tree old, tree id, tag_scope scope) { diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index d1b252d58a8..ef8de31b807 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -3678,6 +3678,8 @@ cp_write_global_declarations (void) /* FIXME - huh? was input_line -= 1;*/ + timevar_start (TV_PHASE_DEFERRED); + /* We now have to write out all the stuff we put off writing out. These include: @@ -3694,8 +3696,6 @@ cp_write_global_declarations (void) generating the initializer for an object may cause templates to be instantiated, etc., etc. */ - timevar_push (TV_VARCONST); - emit_support_tinfos (); do @@ -4002,8 +4002,14 @@ cp_write_global_declarations (void) /* Collect candidates for Java hidden aliases. */ candidates = collect_candidates_for_java_method_aliases (); + timevar_stop (TV_PHASE_DEFERRED); + timevar_start (TV_PHASE_CGRAPH); + cgraph_finalize_compilation_unit (); + timevar_stop (TV_PHASE_CGRAPH); + timevar_start (TV_PHASE_CHECK_DBGINFO); + /* Now, issue warnings about static, but not defined, functions, etc., and emit debugging information. */ walk_namespaces (wrapup_globals_for_namespace, /*data=*/&reconsider); @@ -4039,8 +4045,6 @@ cp_write_global_declarations (void) } } - timevar_pop (TV_VARCONST); - if (flag_detailed_statistics) { dump_tree_statistics (); @@ -4051,6 +4055,8 @@ cp_write_global_declarations (void) #ifdef ENABLE_CHECKING validate_conversion_obstack (); #endif /* ENABLE_CHECKING */ + + timevar_stop (TV_PHASE_CHECK_DBGINFO); } /* FN is an OFFSET_REF, DOTSTAR_EXPR or MEMBER_REF indicating the diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c index b95dd7f2354..e1cf1cf0f1d 100644 --- a/gcc/cp/name-lookup.c +++ b/gcc/cp/name-lookup.c @@ -434,12 +434,11 @@ pop_binding (tree id, tree decl) was successful. */ static bool -supplement_binding (cxx_binding *binding, tree decl) +supplement_binding_1 (cxx_binding *binding, tree decl) { tree bval = binding->value; bool ok = true; - timevar_push (TV_NAME_LOOKUP); if (TREE_CODE (decl) == TYPE_DECL && DECL_ARTIFICIAL (decl)) /* The new name is the type name. */ binding->type = decl; @@ -526,7 +525,19 @@ supplement_binding (cxx_binding *binding, tree decl) ok = false; } - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ok); + return ok; +} + +/* Wrapper for supplement_binding_1. */ + +static bool +supplement_binding (cxx_binding *binding, tree decl) +{ + bool ret; + bool subtime = timevar_cond_start (TV_NAME_LOOKUP); + ret = supplement_binding_1 (binding, decl); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); + return ret; } /* Add DECL to the list of things declared in B. */ @@ -574,17 +585,15 @@ add_decl_to_level (tree decl, cxx_scope *b) If an old decl is returned, it may have been smashed to agree with what X says. */ -tree -pushdecl_maybe_friend (tree x, bool is_friend) +static tree +pushdecl_maybe_friend_1 (tree x, bool is_friend) { tree t; tree name; int need_new_binding; - timevar_push (TV_NAME_LOOKUP); - if (x == error_mark_node) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); + return error_mark_node; need_new_binding = 1; @@ -720,7 +729,7 @@ pushdecl_maybe_friend (tree x, bool is_friend) /* Check for duplicate params. */ tree d = duplicate_decls (x, t, is_friend); if (d) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, d); + return d; } else if ((DECL_EXTERN_C_FUNCTION_P (x) || DECL_FUNCTION_TEMPLATE_P (x)) @@ -733,7 +742,7 @@ pushdecl_maybe_friend (tree x, bool is_friend) TREE_TYPE (x)); /* Throw away the redeclaration. */ - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t); + return t; } else { @@ -742,14 +751,14 @@ pushdecl_maybe_friend (tree x, bool is_friend) /* If the redeclaration failed, we can stop at this point. */ if (olddecl == error_mark_node) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); + return error_mark_node; if (olddecl) { if (TREE_CODE (t) == TYPE_DECL) SET_IDENTIFIER_TYPE_VALUE (name, TREE_TYPE (t)); - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t); + return t; } else if (DECL_MAIN_P (x) && TREE_CODE (t) == FUNCTION_DECL) { @@ -763,7 +772,7 @@ pushdecl_maybe_friend (tree x, bool is_friend) error ("as %qD", x); /* We don't try to push this declaration since that causes a crash. */ - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x); + return x; } } } @@ -806,12 +815,15 @@ pushdecl_maybe_friend (tree x, bool is_friend) x_exception_spec, ce_normal)) { - pedwarn (input_location, 0, "declaration of %q#D with C language linkage", + pedwarn (input_location, 0, + "declaration of %q#D with C language linkage", x); - pedwarn (input_location, 0, "conflicts with previous declaration %q+#D", + pedwarn (input_location, 0, + "conflicts with previous declaration %q+#D", previous); - pedwarn (input_location, 0, "due to different exception specifications"); - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); + pedwarn (input_location, 0, + "due to different exception specifications"); + return error_mark_node; } } else @@ -856,7 +868,7 @@ pushdecl_maybe_friend (tree x, bool is_friend) check_default_args (t); if (t != x || DECL_FUNCTION_TEMPLATE_P (t)) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t); + return t; /* If declaring a type as a typedef, copy the type (unless we're at line 0), and install this TYPE_DECL as the new type's typedef @@ -1143,7 +1155,19 @@ pushdecl_maybe_friend (tree x, bool is_friend) ? NAMESPACE_LEVEL (CP_DECL_CONTEXT (x)) : current_binding_level); - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x); + return x; +} + +/* Wrapper for pushdecl_maybe_friend_1. */ + +tree +pushdecl_maybe_friend (tree x, bool is_friend) +{ + tree ret; + bool subtime = timevar_cond_start (TV_NAME_LOOKUP); + ret = pushdecl_maybe_friend_1 (x, is_friend); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); + return ret; } /* Record a decl-node X as belonging to the current lexical scope. */ @@ -1754,26 +1778,38 @@ print_binding_stack (void) print_binding_level (NAMESPACE_LEVEL (global_namespace)); } -/* Return the type associated with id. */ +/* Return the type associated with ID. */ -tree -identifier_type_value (tree id) +static tree +identifier_type_value_1 (tree id) { - timevar_push (TV_NAME_LOOKUP); /* There is no type with that name, anywhere. */ if (REAL_IDENTIFIER_TYPE_VALUE (id) == NULL_TREE) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE); + return NULL_TREE; /* This is not the type marker, but the real thing. */ if (REAL_IDENTIFIER_TYPE_VALUE (id) != global_type_node) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, REAL_IDENTIFIER_TYPE_VALUE (id)); + return REAL_IDENTIFIER_TYPE_VALUE (id); /* Have to search for it. It must be on the global level, now. Ask lookup_name not to return non-types. */ id = lookup_name_real (id, 2, 1, /*block_p=*/true, 0, LOOKUP_COMPLAIN); if (id) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, TREE_TYPE (id)); - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE); + return TREE_TYPE (id); + return NULL_TREE; } +/* Wrapper for identifier_type_value_1. */ + +tree +identifier_type_value (tree id) +{ + tree ret; + timevar_start (TV_NAME_LOOKUP); + ret = identifier_type_value_1 (id); + timevar_stop (TV_NAME_LOOKUP); + return ret; +} + + /* Return the IDENTIFIER_GLOBAL_VALUE of T, for use in common code, since the definition of IDENTIFIER_GLOBAL_VALUE is different for C and C++. */ @@ -1914,13 +1950,11 @@ make_lambda_name (void) static inline cxx_binding * find_binding (cxx_scope *scope, cxx_binding *binding) { - timevar_push (TV_NAME_LOOKUP); - for (; binding != NULL; binding = binding->previous) if (binding->scope == scope) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, binding); + return binding; - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, (cxx_binding *)0); + return (cxx_binding *)0; } /* Return the binding for NAME in SCOPE, if any. Otherwise, return NULL. */ @@ -1999,36 +2033,45 @@ lookup_extern_c_fun_binding_in_all_ns (tree function) scope, a using decl might extend any previous bindings). */ static tree -push_using_decl (tree scope, tree name) +push_using_decl_1 (tree scope, tree name) { tree decl; - timevar_push (TV_NAME_LOOKUP); gcc_assert (TREE_CODE (scope) == NAMESPACE_DECL); gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE); for (decl = current_binding_level->usings; decl; decl = DECL_CHAIN (decl)) if (USING_DECL_SCOPE (decl) == scope && DECL_NAME (decl) == name) break; if (decl) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, - namespace_bindings_p () ? decl : NULL_TREE); + return namespace_bindings_p () ? decl : NULL_TREE; decl = build_lang_decl (USING_DECL, name, NULL_TREE); USING_DECL_SCOPE (decl) = scope; DECL_CHAIN (decl) = current_binding_level->usings; current_binding_level->usings = decl; - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl); + return decl; +} + +/* Wrapper for push_using_decl_1. */ + +static tree +push_using_decl (tree scope, tree name) +{ + tree ret; + timevar_start (TV_NAME_LOOKUP); + ret = push_using_decl_1 (scope, name); + timevar_stop (TV_NAME_LOOKUP); + return ret; } /* Same as pushdecl, but define X in binding-level LEVEL. We rely on the caller to set DECL_CONTEXT properly. */ -tree -pushdecl_with_scope (tree x, cxx_scope *level, bool is_friend) +static tree +pushdecl_with_scope_1 (tree x, cxx_scope *level, bool is_friend) { struct cp_binding_level *b; tree function_decl = current_function_decl; - timevar_push (TV_NAME_LOOKUP); current_function_decl = NULL_TREE; if (level->kind == sk_class) { @@ -2045,8 +2088,21 @@ pushdecl_with_scope (tree x, cxx_scope *level, bool is_friend) current_binding_level = b; } current_function_decl = function_decl; - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x); + return x; } + +/* Wrapper for pushdecl_with_scope_1. */ + +tree +pushdecl_with_scope (tree x, cxx_scope *level, bool is_friend) +{ + tree ret; + bool subtime = timevar_cond_start (TV_NAME_LOOKUP); + ret = pushdecl_with_scope_1 (x, level, is_friend); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); + return ret; +} + /* DECL is a FUNCTION_DECL for a non-member function, which may have other definitions already in place. We get around this by making @@ -2070,14 +2126,13 @@ pushdecl_with_scope (tree x, cxx_scope *level, bool is_friend) it's always DECL (and never something that's not a _DECL). */ static tree -push_overloaded_decl (tree decl, int flags, bool is_friend) +push_overloaded_decl_1 (tree decl, int flags, bool is_friend) { tree name = DECL_NAME (decl); tree old; tree new_binding; int doing_global = (namespace_bindings_p () || !(flags & PUSH_LOCAL)); - timevar_push (TV_NAME_LOOKUP); if (doing_global) old = namespace_binding (name, DECL_CONTEXT (decl)); else @@ -2115,7 +2170,7 @@ push_overloaded_decl (tree decl, int flags, bool is_friend) /* If DECL was a redeclaration of FN -- even an invalid one -- pass that information along to our caller. */ if (dup == fn || dup == error_mark_node) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, dup); + return dup; } /* We don't overload implicit built-ins. duplicate_decls() @@ -2133,7 +2188,7 @@ push_overloaded_decl (tree decl, int flags, bool is_friend) { error ("previous non-function declaration %q+#D", old); error ("conflicts with function declaration %q#D", decl); - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl); + return decl; } } @@ -2185,7 +2240,7 @@ push_overloaded_decl (tree decl, int flags, bool is_friend) /* And update the cxx_binding node. */ IDENTIFIER_BINDING (name)->value = new_binding; - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl); + return decl; } /* We should always find a previous binding in this case. */ @@ -2196,7 +2251,19 @@ push_overloaded_decl (tree decl, int flags, bool is_friend) push_local_binding (name, new_binding, flags); } - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl); + return decl; +} + +/* Wrapper for push_overloaded_decl_1. */ + +static tree +push_overloaded_decl (tree decl, int flags, bool is_friend) +{ + tree ret; + bool subtime = timevar_cond_start (TV_NAME_LOOKUP); + ret = push_overloaded_decl_1 (decl, flags, is_friend); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); + return ret; } /* Check a non-member using-declaration. Return the name and scope @@ -2643,7 +2710,7 @@ poplevel_class (void) size_t i; tree shadowed; - timevar_push (TV_NAME_LOOKUP); + bool subtime = timevar_cond_start (TV_NAME_LOOKUP); gcc_assert (level != 0); /* If we're leaving a toplevel class, cache its binding level. */ @@ -2667,7 +2734,7 @@ poplevel_class (void) `pushlevel_class' routine. */ gcc_assert (current_binding_level == level); leave_scope (); - timevar_pop (TV_NAME_LOOKUP); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); } /* Set INHERITED_VALUE_BINDING_P on BINDING to true or false, as @@ -2711,13 +2778,14 @@ pushdecl_class_level (tree x) { tree name; bool is_valid = true; + bool subtime; /* Do nothing if we're adding to an outer lambda closure type, outer_binding will add it later if it's needed. */ if (current_class_type != class_binding_level->this_entity) return true; - timevar_push (TV_NAME_LOOKUP); + subtime = timevar_cond_start (TV_NAME_LOOKUP); /* Get the name of X. */ if (TREE_CODE (x) == OVERLOAD) name = DECL_NAME (get_first_fn (x)); @@ -2746,7 +2814,8 @@ pushdecl_class_level (tree x) input_location = save_location; } } - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, is_valid); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); + return is_valid; } /* Return the BINDING (if any) for NAME in SCOPE, which is a class @@ -2813,21 +2882,20 @@ get_class_binding (tree name, cxx_scope *scope) /* Make the declaration(s) of X appear in CLASS scope under the name NAME. Returns true if the binding is valid. */ -bool -push_class_level_binding (tree name, tree x) +static bool +push_class_level_binding_1 (tree name, tree x) { cxx_binding *binding; tree decl = x; bool ok; - timevar_push (TV_NAME_LOOKUP); /* The class_binding_level will be NULL if x is a template parameter name in a member template. */ if (!class_binding_level) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true); + return true; if (name == error_mark_node) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, false); + return false; /* Check for invalid member names. */ gcc_assert (TYPE_BEING_DEFINED (current_class_type)); @@ -2842,7 +2910,7 @@ push_class_level_binding (tree name, tree x) decl = TREE_VALUE (decl); if (!check_template_shadow (decl)) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, false); + return false; /* [class.mem] @@ -2876,7 +2944,7 @@ push_class_level_binding (tree name, tree x) error ("%qD has the same name as the class in which it is " "declared", x); - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, false); + return false; } } @@ -2927,11 +2995,11 @@ push_class_level_binding (tree name, tree x) else if (TREE_CODE (x) == OVERLOAD && is_overloaded_fn (bval)) old_decl = bval; else if (TREE_CODE (x) == USING_DECL && TREE_CODE (bval) == USING_DECL) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true); + return true; else if (TREE_CODE (x) == USING_DECL && is_overloaded_fn (bval)) old_decl = bval; else if (TREE_CODE (bval) == USING_DECL && is_overloaded_fn (x)) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true); + return true; if (old_decl && binding->scope == class_binding_level) { @@ -2940,7 +3008,7 @@ push_class_level_binding (tree name, tree x) here. This function is only used to register bindings from with the class definition itself. */ INHERITED_VALUE_BINDING_P (binding) = 0; - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, true); + return true; } } @@ -2962,7 +3030,19 @@ push_class_level_binding (tree name, tree x) ok = true; } - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ok); + return ok; +} + +/* Wrapper for push_class_level_binding_1. */ + +bool +push_class_level_binding (tree name, tree x) +{ + bool ret; + bool subtime = timevar_cond_start (TV_NAME_LOOKUP); + ret = push_class_level_binding_1 (name, x); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); + return ret; } /* Process "using SCOPE::NAME" in a class scope. Return the @@ -3080,8 +3160,9 @@ do_class_using_decl (tree scope, tree name) /* Return the binding value for name in scope. */ -tree -namespace_binding (tree name, tree scope) + +static tree +namespace_binding_1 (tree name, tree scope) { cxx_binding *binding; @@ -3096,14 +3177,23 @@ namespace_binding (tree name, tree scope) return binding ? binding->value : NULL_TREE; } +tree +namespace_binding (tree name, tree scope) +{ + tree ret; + bool subtime = timevar_cond_start (TV_NAME_LOOKUP); + ret = namespace_binding_1 (name, scope); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); + return ret; +} + /* Set the binding value for name in scope. */ -void -set_namespace_binding (tree name, tree scope, tree val) +static void +set_namespace_binding_1 (tree name, tree scope, tree val) { cxx_binding *b; - timevar_push (TV_NAME_LOOKUP); if (scope == NULL_TREE) scope = global_namespace; b = binding_for_name (NAMESPACE_LEVEL (scope), name); @@ -3111,7 +3201,16 @@ set_namespace_binding (tree name, tree scope, tree val) b->value = val; else supplement_binding (b, val); - timevar_pop (TV_NAME_LOOKUP); +} + +/* Wrapper for set_namespace_binding_1. */ + +void +set_namespace_binding (tree name, tree scope, tree val) +{ + bool subtime = timevar_cond_start (TV_NAME_LOOKUP); + set_namespace_binding_1 (name, scope, val); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); } /* Set the context of a declaration to scope. Complain if we are not @@ -3297,7 +3396,7 @@ push_namespace (tree name) int implicit_use = 0; bool anon = !name; - timevar_push (TV_NAME_LOOKUP); + bool subtime = timevar_cond_start (TV_NAME_LOOKUP); /* We should not get here if the global_namespace is not yet constructed nor if NAME designates the global namespace: The global scope is @@ -3357,7 +3456,7 @@ push_namespace (tree name) /* Enter the name space. */ current_namespace = d; - timevar_pop (TV_NAME_LOOKUP); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); } /* Pop from the scope of the current namespace. */ @@ -3392,7 +3491,7 @@ push_nested_namespace (tree ns) void pop_nested_namespace (tree ns) { - timevar_push (TV_NAME_LOOKUP); + bool subtime = timevar_cond_start (TV_NAME_LOOKUP); gcc_assert (current_namespace == ns); while (ns != global_namespace) { @@ -3401,7 +3500,7 @@ pop_nested_namespace (tree ns) } pop_from_top_level (); - timevar_pop (TV_NAME_LOOKUP); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); } /* Temporarily set the namespace for the current declaration. */ @@ -3426,13 +3525,26 @@ pop_decl_namespace (void) of two given namespaces. */ static tree -namespace_ancestor (tree ns1, tree ns2) +namespace_ancestor_1 (tree ns1, tree ns2) { - timevar_push (TV_NAME_LOOKUP); + tree nsr; if (is_ancestor (ns1, ns2)) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ns1); - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, - namespace_ancestor (CP_DECL_CONTEXT (ns1), ns2)); + nsr = ns1; + else + nsr = namespace_ancestor_1 (CP_DECL_CONTEXT (ns1), ns2); + return nsr; +} + +/* Wrapper for namespace_ancestor_1. */ + +static tree +namespace_ancestor (tree ns1, tree ns2) +{ + tree nsr; + bool subtime = timevar_cond_start (TV_NAME_LOOKUP); + nsr = namespace_ancestor_1 (ns1, ns2); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); + return nsr; } /* Process a namespace-alias declaration. */ @@ -3468,7 +3580,7 @@ pushdecl_namespace_level (tree x, bool is_friend) struct cp_binding_level *b = current_binding_level; tree t; - timevar_push (TV_NAME_LOOKUP); + bool subtime = timevar_cond_start (TV_NAME_LOOKUP); t = pushdecl_with_scope (x, NAMESPACE_LEVEL (current_namespace), is_friend); /* Now, the type_shadowed stack may screw us. Munge it so it does @@ -3502,23 +3614,21 @@ pushdecl_namespace_level (tree x, bool is_friend) *ptr = newval; } } - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); + return t; } /* Insert USED into the using list of USER. Set INDIRECT_flag if this directive is not directly from the source. Also find the common ancestor and let our users know about the new namespace */ + static void -add_using_namespace (tree user, tree used, bool indirect) +add_using_namespace_1 (tree user, tree used, bool indirect) { tree t; - timevar_push (TV_NAME_LOOKUP); /* Using oneself is a no-op. */ if (user == used) - { - timevar_pop (TV_NAME_LOOKUP); - return; - } + return; gcc_assert (TREE_CODE (user) == NAMESPACE_DECL); gcc_assert (TREE_CODE (used) == NAMESPACE_DECL); /* Check if we already have this. */ @@ -3528,7 +3638,6 @@ add_using_namespace (tree user, tree used, bool indirect) if (!indirect) /* Promote to direct usage. */ TREE_INDIRECT_USING (t) = 0; - timevar_pop (TV_NAME_LOOKUP); return; } @@ -3546,12 +3655,21 @@ add_using_namespace (tree user, tree used, bool indirect) /* Recursively add all namespaces used. */ for (t = DECL_NAMESPACE_USING (used); t; t = TREE_CHAIN (t)) /* indirect usage */ - add_using_namespace (user, TREE_PURPOSE (t), 1); + add_using_namespace_1 (user, TREE_PURPOSE (t), 1); /* Tell everyone using us about the new used namespaces. */ for (t = DECL_NAMESPACE_USERS (user); t; t = TREE_CHAIN (t)) - add_using_namespace (TREE_PURPOSE (t), used, 1); - timevar_pop (TV_NAME_LOOKUP); + add_using_namespace_1 (TREE_PURPOSE (t), used, 1); +} + +/* Wrapper for add_using_namespace_1. */ + +static void +add_using_namespace (tree user, tree used, bool indirect) +{ + bool subtime = timevar_cond_start (TV_NAME_LOOKUP); + add_using_namespace_1 (user, used, indirect); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); } /* Process a using-declaration not appearing in class or local scope. */ @@ -3658,13 +3776,14 @@ parse_using_directive (tree name_space, tree attribs) static tree pushdecl_top_level_1 (tree x, tree *init, bool is_friend) { - timevar_push (TV_NAME_LOOKUP); + bool subtime = timevar_cond_start (TV_NAME_LOOKUP); push_to_top_level (); x = pushdecl_namespace_level (x, is_friend); if (init) cp_finish_decl (x, *init, false, NULL_TREE, 0); pop_from_top_level (); - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); + return x; } /* Like pushdecl, only it places X in the global scope if appropriate. */ @@ -4000,7 +4119,7 @@ suggest_alternatives_for (location_t location, tree name) considering using-directives. */ static tree -unqualified_namespace_lookup (tree name, int flags) +unqualified_namespace_lookup_1 (tree name, int flags) { tree initial = current_decl_namespace (); tree scope = initial; @@ -4008,8 +4127,6 @@ unqualified_namespace_lookup (tree name, int flags) struct cp_binding_level *level; tree val = NULL_TREE; - timevar_push (TV_NAME_LOOKUP); - for (; !val; scope = CP_DECL_CONTEXT (scope)) { struct scope_binding binding = EMPTY_SCOPE_BINDING; @@ -4026,7 +4143,7 @@ unqualified_namespace_lookup (tree name, int flags) if (!lookup_using_namespace (name, &binding, level->using_directives, scope, flags)) /* Give up because of error. */ - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); + return error_mark_node; /* Add all _DECLs seen through global using-directives. */ /* XXX local and global using lists should work equally. */ @@ -4037,7 +4154,7 @@ unqualified_namespace_lookup (tree name, int flags) DECL_NAMESPACE_USING (siter), scope, flags)) /* Give up because of error. */ - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); + return error_mark_node; if (siter == scope) break; siter = CP_DECL_CONTEXT (siter); } @@ -4046,7 +4163,19 @@ unqualified_namespace_lookup (tree name, int flags) if (scope == global_namespace) break; } - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val); + return val; +} + +/* Wrapper for unqualified_namespace_lookup_1. */ + +static tree +unqualified_namespace_lookup (tree name, int flags) +{ + tree ret; + bool subtime = timevar_cond_start (TV_NAME_LOOKUP); + ret = unqualified_namespace_lookup_1 (name, flags); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); + return ret; } /* Look up NAME (an IDENTIFIER_NODE) in SCOPE (either a NAMESPACE_DECL @@ -4096,7 +4225,7 @@ lookup_using_namespace (tree name, struct scope_binding *val, tree usings, tree scope, int flags) { tree iter; - timevar_push (TV_NAME_LOOKUP); + bool subtime = timevar_cond_start (TV_NAME_LOOKUP); /* Iterate over all used namespaces in current, searching for using directives of scope. */ for (iter = usings; iter; iter = TREE_CHAIN (iter)) @@ -4109,7 +4238,8 @@ lookup_using_namespace (tree name, struct scope_binding *val, if (val1) ambiguous_decl (val, val1, flags); } - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val->value != error_mark_node); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); + return val->value != error_mark_node; } /* Returns true iff VEC contains TARGET. */ @@ -4142,7 +4272,7 @@ qualified_lookup_using_namespace (tree name, tree scope, VEC(tree,gc) *todo_maybe = NULL; VEC(tree,gc) *todo_inline = NULL; tree usings; - timevar_push (TV_NAME_LOOKUP); + timevar_start (TV_NAME_LOOKUP); /* Look through namespace aliases. */ scope = ORIGINAL_NAMESPACE (scope); @@ -4201,7 +4331,8 @@ qualified_lookup_using_namespace (tree name, tree scope, VEC_free (tree,gc,todo_inline); VEC_free (tree,gc,seen); VEC_free (tree,gc,seen_inline); - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, result->value != error_mark_node); + timevar_stop (TV_NAME_LOOKUP); + return result->value != error_mark_node; } /* Subroutine of outer_binding. @@ -4328,14 +4459,13 @@ innermost_non_namespace_value (tree name) If NONCLASS is nonzero, bindings in class scopes are ignored. If BLOCK_P is false, bindings in block scopes are ignored. */ -tree -lookup_name_real (tree name, int prefer_type, int nonclass, bool block_p, - int namespaces_only, int flags) +static tree +lookup_name_real_1 (tree name, int prefer_type, int nonclass, bool block_p, + int namespaces_only, int flags) { cxx_binding *iter; tree val = NULL_TREE; - timevar_push (TV_NAME_LOOKUP); /* Conversion operators are handled specially because ordinary unqualified name lookup will not find template conversion operators. */ @@ -4359,10 +4489,10 @@ lookup_name_real (tree name, int prefer_type, int nonclass, bool block_p, class_type = level->this_entity; operators = lookup_fnfields (class_type, name, /*protect=*/0); if (operators) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, operators); + return operators; } - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE); + return NULL_TREE; } flags |= lookup_flags (prefer_type, namespaces_only); @@ -4457,7 +4587,21 @@ lookup_name_real (tree name, int prefer_type, int nonclass, bool block_p, if (val && TREE_CODE (val) == OVERLOAD && !really_overloaded_fn (val)) val = OVL_FUNCTION (val); - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val); + return val; +} + +/* Wrapper for lookup_name_real_1. */ + +tree +lookup_name_real (tree name, int prefer_type, int nonclass, bool block_p, + int namespaces_only, int flags) +{ + tree ret; + bool subtime = timevar_cond_start (TV_NAME_LOOKUP); + ret = lookup_name_real_1 (name, prefer_type, nonclass, block_p, + namespaces_only, flags); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); + return ret; } tree @@ -4504,14 +4648,12 @@ lookup_name_prefer_type (tree name, int prefer_type) A TYPE_DECL best matching the NAME is returned. Catching error and issuing diagnostics are caller's responsibility. */ -tree -lookup_type_scope (tree name, tag_scope scope) +static tree +lookup_type_scope_1 (tree name, tag_scope scope) { cxx_binding *iter = NULL; tree val = NULL_TREE; - timevar_push (TV_NAME_LOOKUP); - /* Look in non-namespace scope first. */ if (current_binding_level->kind != sk_namespace) iter = outer_binding (name, NULL, /*class_p=*/ true); @@ -4566,7 +4708,7 @@ lookup_type_scope (tree name, tag_scope scope) while (b) { if (iter->scope == b) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val); + return val; if (b->kind == sk_cleanup || b->kind == sk_template_parms || b->kind == sk_function_parms) @@ -4579,19 +4721,31 @@ lookup_type_scope (tree name, tag_scope scope) } } - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE); + return NULL_TREE; } + +/* Wrapper for lookup_type_scope_1. */ + +tree +lookup_type_scope (tree name, tag_scope scope) +{ + tree ret; + bool subtime = timevar_cond_start (TV_NAME_LOOKUP); + ret = lookup_type_scope_1 (name, scope); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); + return ret; +} + /* Similar to `lookup_name' but look only in the innermost non-class binding level. */ -tree -lookup_name_innermost_nonclass_level (tree name) +static tree +lookup_name_innermost_nonclass_level_1 (tree name) { struct cp_binding_level *b; tree t = NULL_TREE; - timevar_push (TV_NAME_LOOKUP); b = innermost_nonclass_level (); if (b->kind == sk_namespace) @@ -4612,7 +4766,7 @@ lookup_name_innermost_nonclass_level (tree name) if (binding->scope == b && !(TREE_CODE (binding->value) == VAR_DECL && DECL_DEAD_FOR_LOCAL (binding->value))) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, binding->value); + return binding->value; if (b->kind == sk_cleanup) b = b->level_chain; @@ -4621,9 +4775,22 @@ lookup_name_innermost_nonclass_level (tree name) } } - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t); + return t; } +/* Wrapper for lookup_name_innermost_nonclass_level_1. */ + +tree +lookup_name_innermost_nonclass_level (tree name) +{ + tree ret; + bool subtime = timevar_cond_start (TV_NAME_LOOKUP); + ret = lookup_name_innermost_nonclass_level_1 (name); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); + return ret; +} + + /* Returns true iff DECL is a block-scope extern declaration of a function or variable. */ @@ -4659,7 +4826,7 @@ lookup_type_current_level (tree name) { tree t = NULL_TREE; - timevar_push (TV_NAME_LOOKUP); + timevar_start (TV_NAME_LOOKUP); gcc_assert (current_binding_level->kind != sk_namespace); if (REAL_IDENTIFIER_TYPE_VALUE (name) != NULL_TREE @@ -4669,8 +4836,10 @@ lookup_type_current_level (tree name) while (1) { if (purpose_member (name, b->type_shadowed)) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, - REAL_IDENTIFIER_TYPE_VALUE (name)); + { + t = REAL_IDENTIFIER_TYPE_VALUE (name); + break; + } if (b->kind == sk_cleanup) b = b->level_chain; else @@ -4678,7 +4847,8 @@ lookup_type_current_level (tree name) } } - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t); + timevar_stop (TV_NAME_LOOKUP); + return t; } /* [basic.lookup.koenig] */ @@ -5150,14 +5320,12 @@ arg_assoc (struct arg_lookup *k, tree n) /* Performs Koenig lookup depending on arguments, where fns are the functions found in normal lookup. */ -tree -lookup_arg_dependent (tree name, tree fns, VEC(tree,gc) *args, - bool include_std) +static tree +lookup_arg_dependent_1 (tree name, tree fns, VEC(tree,gc) *args, + bool include_std) { struct arg_lookup k; - timevar_push (TV_NAME_LOOKUP); - /* Remove any hidden friend functions from the list of functions found so far. They will be added back by arg_assoc_class as appropriate. */ @@ -5193,23 +5361,36 @@ lookup_arg_dependent (tree name, tree fns, VEC(tree,gc) *args, release_tree_vector (k.classes); release_tree_vector (k.namespaces); - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, fns); + return fns; } +/* Wrapper for lookup_arg_dependent_1. */ + +tree +lookup_arg_dependent (tree name, tree fns, VEC(tree,gc) *args, + bool include_std) +{ + tree ret; + timevar_start (TV_NAME_LOOKUP); + ret = lookup_arg_dependent_1 (name, fns, args, include_std); + timevar_stop (TV_NAME_LOOKUP); + return ret; +} + + /* Add namespace to using_directives. Return NULL_TREE if nothing was changed (i.e. there was already a directive), or the fresh TREE_LIST otherwise. */ static tree -push_using_directive (tree used) +push_using_directive_1 (tree used) { tree ud = current_binding_level->using_directives; tree iter, ancestor; - timevar_push (TV_NAME_LOOKUP); /* Check if we already have this. */ if (purpose_member (used, ud) != NULL_TREE) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE); + return NULL_TREE; ancestor = namespace_ancestor (current_decl_namespace (), used); ud = current_binding_level->using_directives; @@ -5220,7 +5401,19 @@ push_using_directive (tree used) for (iter = DECL_NAMESPACE_USING (used); iter; iter = TREE_CHAIN (iter)) push_using_directive (TREE_PURPOSE (iter)); - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ud); + return ud; +} + +/* Wrapper for push_using_directive_1. */ + +static tree +push_using_directive (tree used) +{ + tree ret; + timevar_start (TV_NAME_LOOKUP); + ret = push_using_directive_1 (used); + timevar_stop (TV_NAME_LOOKUP); + return ret; } /* The type TYPE is being declared. If it is a class template, or a @@ -5313,13 +5506,12 @@ maybe_process_template_type_declaration (tree type, int is_friend, Returns TYPE upon success and ERROR_MARK_NODE otherwise. */ -tree -pushtag (tree name, tree type, tag_scope scope) +static tree +pushtag_1 (tree name, tree type, tag_scope scope) { struct cp_binding_level *b; tree decl; - timevar_push (TV_NAME_LOOKUP); b = current_binding_level; while (/* Cleanup scopes are not scopes from the point of view of the language. */ @@ -5344,7 +5536,7 @@ pushtag (tree name, tree type, tag_scope scope) gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE); /* Do C++ gratuitous typedefing. */ - if (IDENTIFIER_TYPE_VALUE (name) != type) + if (identifier_type_value_1 (name) != type) { tree tdef; int in_class = 0; @@ -5390,12 +5582,12 @@ pushtag (tree name, tree type, tag_scope scope) decl = maybe_process_template_type_declaration (type, scope == ts_within_enclosing_non_class, b); if (decl == error_mark_node) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl); + return decl; if (b->kind == sk_class) { if (!TYPE_BEING_DEFINED (current_class_type)) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); + return error_mark_node; if (!PROCESSING_REAL_TEMPLATE_DECL_P ()) /* Put this TYPE_DECL on the TYPE_FIELDS list for the @@ -5408,9 +5600,9 @@ pushtag (tree name, tree type, tag_scope scope) } else if (b->kind != sk_template_parms) { - decl = pushdecl_with_scope (decl, b, /*is_friend=*/false); + decl = pushdecl_with_scope_1 (decl, b, /*is_friend=*/false); if (decl == error_mark_node) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl); + return decl; } if (! in_class) @@ -5449,7 +5641,19 @@ pushtag (tree name, tree type, tag_scope scope) TREE_PUBLIC (decl) = 1; determine_visibility (decl); - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, type); + return type; +} + +/* Wrapper for pushtag_1. */ + +tree +pushtag (tree name, tree type, tag_scope scope) +{ + tree ret; + bool subtime = timevar_cond_start (TV_NAME_LOOKUP); + ret = pushtag_1 (name, type, scope); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); + return ret; } /* Subroutines for reverting temporarily to top-level for instantiation @@ -5487,7 +5691,7 @@ store_bindings (tree names, VEC(cxx_saved_binding,gc) **old_bindings) { tree t; - timevar_push (TV_NAME_LOOKUP); + bool subtime = timevar_cond_start (TV_NAME_LOOKUP); for (t = names; t; t = TREE_CHAIN (t)) { tree id; @@ -5499,7 +5703,7 @@ store_bindings (tree names, VEC(cxx_saved_binding,gc) **old_bindings) store_binding (id, old_bindings); } - timevar_pop (TV_NAME_LOOKUP); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); } /* Like store_bindings, but NAMES is a vector of cp_class_binding @@ -5512,10 +5716,10 @@ store_class_bindings (VEC(cp_class_binding,gc) *names, size_t i; cp_class_binding *cb; - timevar_push (TV_NAME_LOOKUP); + bool subtime = timevar_cond_start (TV_NAME_LOOKUP); for (i = 0; VEC_iterate(cp_class_binding, names, i, cb); ++i) store_binding (cb->identifier, old_bindings); - timevar_pop (TV_NAME_LOOKUP); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); } void @@ -5527,7 +5731,7 @@ push_to_top_level (void) size_t i; bool need_pop; - timevar_push (TV_NAME_LOOKUP); + bool subtime = timevar_cond_start (TV_NAME_LOOKUP); s = ggc_alloc_cleared_saved_scope (); b = scope_chain ? current_binding_level : 0; @@ -5587,17 +5791,16 @@ push_to_top_level (void) push_class_stack (); cp_unevaluated_operand = 0; c_inhibit_evaluation_warnings = 0; - timevar_pop (TV_NAME_LOOKUP); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); } -void -pop_from_top_level (void) +static void +pop_from_top_level_1 (void) { struct saved_scope *s = scope_chain; cxx_saved_binding *saved; size_t i; - timevar_push (TV_NAME_LOOKUP); /* Clear out class-level bindings cache. */ if (previous_class_level) invalidate_class_lookup_cache (); @@ -5621,9 +5824,19 @@ pop_from_top_level (void) current_function_decl = s->function_decl; cp_unevaluated_operand = s->unevaluated_operand; c_inhibit_evaluation_warnings = s->inhibit_evaluation_warnings; - timevar_pop (TV_NAME_LOOKUP); } +/* Wrapper for pop_from_top_level_1. */ + +void +pop_from_top_level (void) +{ + bool subtime = timevar_cond_start (TV_NAME_LOOKUP); + pop_from_top_level_1 (); + timevar_cond_stop (TV_NAME_LOOKUP, subtime); +} + + /* Pop off extraneous binding levels left over due to syntax errors. We don't pop past namespaces, as they might be valid. */ diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 5e3ac70b107..9ec571e793c 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -23,6 +23,7 @@ along with GCC; see the file COPYING3. If not see #include "system.h" #include "coretypes.h" #include "tm.h" +#include "timevar.h" #include "cpplib.h" #include "tree.h" #include "cp-tree.h" @@ -12152,6 +12153,8 @@ cp_parser_explicit_instantiation (cp_parser* parser) cp_decl_specifier_seq decl_specifiers; tree extension_specifier = NULL_TREE; + timevar_push (TV_TEMPLATE_INST); + /* Look for an (optional) storage-class-specifier or function-specifier. */ if (cp_parser_allow_gnu_extensions_p (parser)) @@ -12235,6 +12238,8 @@ cp_parser_explicit_instantiation (cp_parser* parser) end_explicit_instantiation (); cp_parser_consume_semicolon_at_end_of_statement (parser); + + timevar_pop (TV_TEMPLATE_INST); } /* Parse an explicit-specialization. @@ -13446,6 +13451,7 @@ cp_parser_enum_specifier (cp_parser* parser) elaborated-type-specifier. */ if (cp_lexer_next_token_is (parser->lexer, CPP_OPEN_BRACE)) { + timevar_push (TV_PARSE_ENUM); if (nested_name_specifier) { /* The following catches invalid code such as: @@ -13507,6 +13513,7 @@ cp_parser_enum_specifier (cp_parser* parser) if (scoped_enum_p) finish_scope (); + timevar_pop (TV_PARSE_ENUM); } else { @@ -16742,7 +16749,7 @@ cp_parser_class_name (cp_parser *parser, Returns the TREE_TYPE representing the class. */ static tree -cp_parser_class_specifier (cp_parser* parser) +cp_parser_class_specifier_1 (cp_parser* parser) { tree type; tree attributes = NULL_TREE; @@ -17005,6 +17012,16 @@ cp_parser_class_specifier (cp_parser* parser) return type; } +static tree +cp_parser_class_specifier (cp_parser* parser) +{ + tree ret; + timevar_push (TV_PARSE_STRUCT); + ret = cp_parser_class_specifier_1 (parser); + timevar_pop (TV_PARSE_STRUCT); + return ret; +} + /* Parse a class-head. class-head: @@ -19650,8 +19667,17 @@ cp_parser_function_definition_from_specifiers_and_declarator pop_nested_class (); } else - fn = cp_parser_function_definition_after_declarator (parser, + { + timevar_id_t tv; + if (DECL_DECLARED_INLINE_P (current_function_decl)) + tv = TV_PARSE_INLINE; + else + tv = TV_PARSE_FUNC; + timevar_push (tv); + fn = cp_parser_function_definition_after_declarator (parser, /*inline_p=*/false); + timevar_pop (tv); + } return fn; } @@ -20268,6 +20294,7 @@ cp_parser_enclosed_template_argument_list (cp_parser* parser) static void cp_parser_late_parsing_for_member (cp_parser* parser, tree member_function) { + timevar_push (TV_PARSE_INMETH); /* If this member is a template, get the underlying FUNCTION_DECL. */ if (DECL_FUNCTION_TEMPLATE_P (member_function)) @@ -20334,6 +20361,7 @@ cp_parser_late_parsing_for_member (cp_parser* parser, tree member_function) /* Restore the queue. */ pop_unparsed_function_queues (parser); + timevar_pop (TV_PARSE_INMETH); } /* If DECL contains any default args, remember it on the unparsed diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 481306f5f7f..b56ab1f1abd 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -6682,13 +6682,9 @@ maybe_get_template_decl_from_type_decl (tree decl) that we want to avoid. It also causes some problems with argument coercion (see convert_nontype_argument for more information on this). */ -tree -lookup_template_class (tree d1, - tree arglist, - tree in_decl, - tree context, - int entering_scope, - tsubst_flags_t complain) +static tree +lookup_template_class_1 (tree d1, tree arglist, tree in_decl, tree context, + int entering_scope, tsubst_flags_t complain) { tree templ = NULL_TREE, parmlist; tree t; @@ -6697,8 +6693,6 @@ lookup_template_class (tree d1, spec_entry elt; hashval_t hash; - timevar_push (TV_NAME_LOOKUP); - if (TREE_CODE (d1) == IDENTIFIER_NODE) { tree value = innermost_non_namespace_value (d1); @@ -6751,7 +6745,7 @@ lookup_template_class (tree d1, { if (complain & tf_error) error ("%qT is not a template", d1); - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); + return error_mark_node; } if (TREE_CODE (templ) != TEMPLATE_DECL @@ -6766,7 +6760,7 @@ lookup_template_class (tree d1, if (in_decl) error ("for template declaration %q+D", in_decl); } - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); + return error_mark_node; } complain &= ~tf_user; @@ -6816,10 +6810,10 @@ lookup_template_class (tree d1, if (arglist2 == error_mark_node || (!uses_template_parms (arglist2) && check_instantiated_args (templ, arglist2, complain))) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); + return error_mark_node; parm = bind_template_template_parm (TREE_TYPE (templ), arglist2); - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, parm); + return parm; } else { @@ -6895,7 +6889,7 @@ lookup_template_class (tree d1, { /* Restore the ARGLIST to its full size. */ TREE_VEC_LENGTH (arglist) = saved_depth; - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); + return error_mark_node; } SET_TMPL_ARGS_LEVEL (bound_args, i, a); @@ -6923,7 +6917,7 @@ lookup_template_class (tree d1, if (arglist == error_mark_node) /* We were unable to bind the arguments. */ - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); + return error_mark_node; /* In the scope of a template class, explicit references to the template class refer to the type of the template, not any @@ -6939,7 +6933,7 @@ lookup_template_class (tree d1, /* comp_template_args is expensive, check it last. */ && comp_template_args (TYPE_TI_ARGS (template_type), arglist)) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, template_type); + return template_type; /* If we already have this specialization, return it. */ elt.tmpl = gen_tmpl; @@ -6949,7 +6943,7 @@ lookup_template_class (tree d1, &elt, hash); if (entry) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, entry->spec); + return entry->spec; is_dependent_type = uses_template_parms (arglist); @@ -6959,7 +6953,7 @@ lookup_template_class (tree d1, && check_instantiated_args (gen_tmpl, INNERMOST_TEMPLATE_ARGS (arglist), complain)) - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node); + return error_mark_node; if (!is_dependent_type && !PRIMARY_TEMPLATE_P (gen_tmpl) @@ -6969,7 +6963,7 @@ lookup_template_class (tree d1, found = xref_tag_from_type (TREE_TYPE (gen_tmpl), DECL_NAME (gen_tmpl), /*tag_scope=*/ts_global); - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, found); + return found; } context = tsubst (DECL_CONTEXT (gen_tmpl), arglist, @@ -7162,9 +7156,22 @@ lookup_template_class (tree d1, TREE_PUBLIC (type_decl) = 1; determine_visibility (type_decl); - POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t); + return t; } - timevar_pop (TV_NAME_LOOKUP); +} + +/* Wrapper for lookup_template_class_1. */ + +tree +lookup_template_class (tree d1, tree arglist, tree in_decl, tree context, + int entering_scope, tsubst_flags_t complain) +{ + tree ret; + timevar_push (TV_TEMPLATE_INST); + ret = lookup_template_class_1 (d1, arglist, in_decl, context, + entering_scope, complain); + timevar_pop (TV_TEMPLATE_INST); + return ret; } struct pair_fn_data @@ -8102,8 +8109,8 @@ perform_typedefs_access_check (tree tmpl, tree targs) input_location = saved_location; } -tree -instantiate_class_template (tree type) +static tree +instantiate_class_template_1 (tree type) { tree templ, args, pattern, t, member; tree typedecl; @@ -8597,6 +8604,18 @@ instantiate_class_template (tree type) return type; } +/* Wrapper for instantiate_class_template_1. */ + +tree +instantiate_class_template (tree type) +{ + tree ret; + timevar_push (TV_TEMPLATE_INST); + ret = instantiate_class_template_1 (type); + timevar_pop (TV_TEMPLATE_INST); + return ret; +} + static tree tsubst_template_arg (tree t, tree args, tsubst_flags_t complain, tree in_decl) { @@ -13505,8 +13524,8 @@ check_instantiated_args (tree tmpl, tree args, tsubst_flags_t complain) /* Instantiate the indicated variable or function template TMPL with the template arguments in TARG_PTR. */ -tree -instantiate_template (tree tmpl, tree orig_args, tsubst_flags_t complain) +static tree +instantiate_template_1 (tree tmpl, tree orig_args, tsubst_flags_t complain) { tree targ_ptr = orig_args; tree fndecl; @@ -13615,6 +13634,18 @@ instantiate_template (tree tmpl, tree orig_args, tsubst_flags_t complain) return fndecl; } +/* Wrapper for instantiate_template_1. */ + +tree +instantiate_template (tree tmpl, tree orig_args, tsubst_flags_t complain) +{ + tree ret; + timevar_push (TV_TEMPLATE_INST); + ret = instantiate_template_1 (tmpl, orig_args, complain); + timevar_pop (TV_TEMPLATE_INST); + return ret; +} + /* The FN is a TEMPLATE_DECL for a function. ARGS is an array with NARGS elements of the arguments that are being used when calling it. TARGS is a vector into which the deduced template arguments @@ -17204,7 +17235,7 @@ instantiate_decl (tree d, int defer_ok, if (! push_tinst_level (d)) return d; - timevar_push (TV_PARSE); + timevar_push (TV_TEMPLATE_INST); /* Set TD to the template whose DECL_TEMPLATE_RESULT is the pattern for the instantiation. */ @@ -17497,7 +17528,7 @@ out: pop_deferring_access_checks (); pop_tinst_level (); - timevar_pop (TV_PARSE); + timevar_pop (TV_TEMPLATE_INST); return d; } diff --git a/gcc/timevar.c b/gcc/timevar.c index f1d20e8d0c5..c87695bec82 100644 --- a/gcc/timevar.c +++ b/gcc/timevar.c @@ -361,11 +361,66 @@ timevar_stop (timevar_id_t timevar) /* TIMEVAR must have been started via timevar_start. */ gcc_assert (tv->standalone); + tv->standalone = 0; /* Enable a restart. */ get_time (&now); timevar_accumulate (&tv->elapsed, &tv->start_time, &now); } + +/* Conditionally start timing TIMEVAR independently of the timing stack. + If the timer is already running, leave it running and return true. + Otherwise, start the timer and return false. + Elapsed time until the corresponding timevar_cond_stop + is called for the same timing variable is attributed to TIMEVAR. */ + +bool +timevar_cond_start (timevar_id_t timevar) +{ + struct timevar_def *tv = &timevars[timevar]; + + if (!timevar_enable) + return false; + + /* Mark this timing variable as used. */ + tv->used = 1; + + if (tv->standalone) + return true; /* The timevar is already running. */ + + /* Don't allow the same timing variable + to be unconditionally started more than once. */ + tv->standalone = 1; + + get_time (&tv->start_time); + return false; /* The timevar was not already running. */ +} + +/* Conditionally stop timing TIMEVAR. The RUNNING parameter must come + from the return value of a dynamically matching timevar_cond_start. + If the timer had already been RUNNING, do nothing. Otherwise, time + elapsed since timevar_cond_start was called is attributed to it. */ + +void +timevar_cond_stop (timevar_id_t timevar, bool running) +{ + struct timevar_def *tv; + struct timevar_time_def now; + + if (!timevar_enable || running) + return; + + tv = &timevars[timevar]; + + /* TIMEVAR must have been started via timevar_cond_start. */ + gcc_assert (tv->standalone); + tv->standalone = 0; /* Enable a restart. */ + + get_time (&now); + timevar_accumulate (&tv->elapsed, &tv->start_time, &now); +} + + /* Summarize timing variables to FP. The timing variable TV_TOTAL has a special meaning -- it's considered to be the total elapsed time, for normalizing the others, and is displayed last. */ diff --git a/gcc/timevar.def b/gcc/timevar.def index cd306b83277..2921c9088bd 100644 --- a/gcc/timevar.def +++ b/gcc/timevar.def @@ -33,6 +33,18 @@ /* The total execution time. */ DEFTIMEVAR (TV_TOTAL , "total time") +DEFTIMEVAR (TV_PHASE_SETUP , "phase setup") +DEFTIMEVAR (TV_PHASE_PARSING , "phase parsing") +DEFTIMEVAR (TV_PHASE_DEFERRED , "phase lang. deferred") +DEFTIMEVAR (TV_PHASE_CGRAPH , "phase cgraph") +DEFTIMEVAR (TV_PHASE_DBGINFO , "phase debug info") +DEFTIMEVAR (TV_PHASE_CHECK_DBGINFO , "phase check & debug info") +DEFTIMEVAR (TV_PHASE_GENERATE , "phase generate") +DEFTIMEVAR (TV_PHASE_FINALIZE , "phase finalize") + +/* Concurrent timers, indicated by "|". */ +DEFTIMEVAR (TV_NAME_LOOKUP , "|name lookup") +DEFTIMEVAR (TV_OVERLOAD , "|overload resolution") /* Time spent garbage-collecting. */ DEFTIMEVAR (TV_GC , "garbage collection") @@ -102,8 +114,13 @@ DEFTIMEVAR (TV_REBUILD_JUMP , "rebuild jump labels") /* Timing in various stages of the compiler. */ DEFTIMEVAR (TV_CPP , "preprocessing") DEFTIMEVAR (TV_LEX , "lexical analysis") -DEFTIMEVAR (TV_PARSE , "parser") -DEFTIMEVAR (TV_NAME_LOOKUP , "name lookup") +DEFTIMEVAR (TV_PARSE_GLOBAL , "parser (global)") +DEFTIMEVAR (TV_PARSE_STRUCT , "parser struct body") +DEFTIMEVAR (TV_PARSE_ENUM , "parser enumerator list") +DEFTIMEVAR (TV_PARSE_FUNC , "parser function body") +DEFTIMEVAR (TV_PARSE_INLINE , "parser inl. func. body") +DEFTIMEVAR (TV_PARSE_INMETH , "parser inl. meth. body") +DEFTIMEVAR (TV_TEMPLATE_INST , "template instantiation") DEFTIMEVAR (TV_INLINE_HEURISTICS , "inline heuristics") DEFTIMEVAR (TV_INTEGRATION , "integration") DEFTIMEVAR (TV_TREE_GIMPLIFY , "tree gimplify") @@ -170,8 +187,6 @@ DEFTIMEVAR (TV_CGRAPH_VERIFY , "callgraph verifier") DEFTIMEVAR (TV_DOM_FRONTIERS , "dominance frontiers") DEFTIMEVAR (TV_DOMINANCE , "dominance computation") DEFTIMEVAR (TV_CONTROL_DEPENDENCES , "control dependences") -DEFTIMEVAR (TV_OVERLOAD , "overload resolution") -DEFTIMEVAR (TV_TEMPLATE_INSTANTIATION, "template instantiation") DEFTIMEVAR (TV_OUT_OF_SSA , "out of ssa") DEFTIMEVAR (TV_VAR_EXPAND , "expand vars") DEFTIMEVAR (TV_EXPAND , "expand") diff --git a/gcc/timevar.h b/gcc/timevar.h index 1df23300fa9..dad9dfdf2b0 100644 --- a/gcc/timevar.h +++ b/gcc/timevar.h @@ -87,14 +87,13 @@ extern bool timevar_enable; /* Total amount of memory allocated by garbage collector. */ extern size_t timevar_ggc_mem_total; -/* Execute the sequence: timevar_pop (TV), return (E); */ -#define POP_TIMEVAR_AND_RETURN(TV, E) do { timevar_pop (TV); return (E); }while(0) - extern void timevar_init (void); extern void timevar_push_1 (timevar_id_t); extern void timevar_pop_1 (timevar_id_t); extern void timevar_start (timevar_id_t); extern void timevar_stop (timevar_id_t); +extern bool timevar_cond_start (timevar_id_t); +extern void timevar_cond_stop (timevar_id_t, bool); extern void timevar_print (FILE *); /* Provided for backward compatibility. */ diff --git a/gcc/toplev.c b/gcc/toplev.c index 06014a938e5..d61addedfad 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -562,36 +562,34 @@ emit_debug_global_declarations (tree *vec, int len) static void compile_file (void) { - /* Initialize yet another pass. */ - - ggc_protect_identifiers = true; - - init_cgraph (); - init_final (main_input_filename); - coverage_init (aux_base_name); - statistics_init (); - invoke_plugin_callbacks (PLUGIN_START_UNIT, NULL); - - timevar_push (TV_PARSE); + timevar_start (TV_PHASE_PARSING); + timevar_push (TV_PARSE_GLOBAL); /* Call the parser, which parses the entire file (calling rest_of_compilation for each function). */ lang_hooks.parse_file (); + timevar_pop (TV_PARSE_GLOBAL); + timevar_stop (TV_PHASE_PARSING); + /* Compilation is now finished except for writing what's left of the symbol table output. */ - timevar_pop (TV_PARSE); if (flag_syntax_only || flag_wpa) return; + timevar_start (TV_PHASE_GENERATE); + ggc_protect_identifiers = false; /* This must also call cgraph_finalize_compilation_unit. */ lang_hooks.decls.final_write_globals (); if (seen_error ()) - return; + { + timevar_stop (TV_PHASE_GENERATE); + return; + } varpool_assemble_pending_decls (); finish_aliases_2 (); @@ -671,6 +669,8 @@ compile_file (void) into the assembly file here, and hence we can not output anything to the assembly file after this point. */ targetm.asm_out.file_end (); + + timevar_stop (TV_PHASE_GENERATE); } /* Indexed by enum debug_info_type. */ @@ -1899,6 +1899,8 @@ do_compile (void) /* Don't do any more if an error has already occurred. */ if (!seen_error ()) { + timevar_start (TV_PHASE_SETUP); + /* This must be run always, because it is needed to compute the FP predefined macros, such as __LDBL_MAX__, for targets using non default FP formats. */ @@ -1910,9 +1912,31 @@ do_compile (void) /* Language-dependent initialization. Returns true on success. */ if (lang_dependent_init (main_input_filename)) - compile_file (); + { + /* Initialize yet another pass. */ + + ggc_protect_identifiers = true; + + init_cgraph (); + init_final (main_input_filename); + coverage_init (aux_base_name); + statistics_init (); + invoke_plugin_callbacks (PLUGIN_START_UNIT, NULL); + + timevar_stop (TV_PHASE_SETUP); + + compile_file (); + } + else + { + timevar_stop (TV_PHASE_SETUP); + } + + timevar_start (TV_PHASE_FINALIZE); finalize (no_backend); + + timevar_stop (TV_PHASE_FINALIZE); } /* Stop timing and print the times. */ -- 2.30.2