+2011-05-02 Lawrence Crowl <crowl@google.com>
+
+ * 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 <jason@redhat.com>
PR c++/40975
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). */
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 ())
}
ext_block = NULL;
+ timevar_stop (TV_PHASE_DBGINFO);
}
/* Register reserved keyword WORD as qualifier for address space AS. */
{
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
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
add_stmt (fnbody);
finish_function ();
}
+
+ timevar_pop (tv);
break;
}
}
{
/* 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)
{
ret.kind = ctsk_tagdef;
ret.expr = NULL_TREE;
ret.expr_const_operands = true;
+ timevar_pop (TV_PARSE_ENUM);
return ret;
}
else if (!ident)
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) }));. */
ret.kind = ctsk_tagdef;
ret.expr = NULL_TREE;
ret.expr_const_operands = true;
+ timevar_pop (TV_PARSE_STRUCT);
return ret;
}
else if (!ident)
+2011-05-02 Lawrence Crowl <crowl@google.com>
+
+ * 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 <jason@redhat.com>
* tree.c (build_vec_init_expr): Take complain parm.
$(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)
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
#include "convert.h"
#include "langhooks.h"
#include "c-family/c-objc.h"
+#include "timevar.h"
/* The various kinds of conversion. */
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;
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. */
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.
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;
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;
}
/* 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;
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)
/* 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;
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. */
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;
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. */
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]). */
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;
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. */
unsigned ix;
cp_label_binding *label_bind;
- timevar_push (TV_NAME_LOOKUP);
+ timevar_start (TV_NAME_LOOKUP);
restart:
block = NULL_TREE;
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
size_t i, nelts;
tree t, name;
- timevar_push (TV_NAME_LOOKUP);
+ timevar_start (TV_NAME_LOOKUP);
name = DECL_NAME (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);
}
\f
/* Subroutine of duplicate_decls: return truthvalue of whether
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. */
/* 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;
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
{
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;
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)
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)
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
{
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)
{
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. */
}
}
- 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)
{
/* 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:
generating the initializer for an object may cause templates to be
instantiated, etc., etc. */
- timevar_push (TV_VARCONST);
-
emit_support_tinfos ();
do
/* 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);
}
}
- timevar_pop (TV_VARCONST);
-
if (flag_detailed_statistics)
{
dump_tree_statistics ();
#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
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;
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. */
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;
/* 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))
TREE_TYPE (x));
/* Throw away the redeclaration. */
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
+ return t;
}
else
{
/* 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)
{
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;
}
}
}
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
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
? 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. */
print_binding_level (NAMESPACE_LEVEL (global_namespace));
}
\f
-/* 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++. */
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. */
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)
{
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
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
/* 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()
{
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;
}
}
/* 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. */
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
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. */
`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
{
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));
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
/* 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));
decl = TREE_VALUE (decl);
if (!check_template_shadow (decl))
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, false);
+ return false;
/* [class.mem]
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;
}
}
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)
{
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;
}
}
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
\f
/* 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;
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);
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
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
/* 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. */
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)
{
}
pop_from_top_level ();
- timevar_pop (TV_NAME_LOOKUP);
+ timevar_cond_stop (TV_NAME_LOOKUP, subtime);
}
/* Temporarily set the namespace for the current declaration. */
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. */
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
*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. */
if (!indirect)
/* Promote to direct usage. */
TREE_INDIRECT_USING (t) = 0;
- timevar_pop (TV_NAME_LOOKUP);
return;
}
/* 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. */
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. */
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;
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;
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. */
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);
}
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
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))
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. */
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);
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.
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. */
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);
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
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);
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)
}
}
- 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)
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;
}
}
- 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. */
{
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
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
}
}
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
+ timevar_stop (TV_NAME_LOOKUP);
+ return t;
}
/* [basic.lookup.koenig] */
/* 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. */
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;
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
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. */
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;
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
}
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)
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;
}
\f
/* Subroutines for reverting temporarily to top-level for instantiation
{
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;
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
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
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;
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 ();
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. */
#include "system.h"
#include "coretypes.h"
#include "tm.h"
+#include "timevar.h"
#include "cpplib.h"
#include "tree.h"
#include "cp-tree.h"
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))
end_explicit_instantiation ();
cp_parser_consume_semicolon_at_end_of_statement (parser);
+
+ timevar_pop (TV_TEMPLATE_INST);
}
/* Parse an explicit-specialization.
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:
if (scoped_enum_p)
finish_scope ();
+ timevar_pop (TV_PARSE_ENUM);
}
else
{
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;
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:
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;
}
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))
/* Restore the queue. */
pop_unparsed_function_queues (parser);
+ timevar_pop (TV_PARSE_INMETH);
}
/* If DECL contains any default args, remember it on the unparsed
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;
spec_entry elt;
hashval_t hash;
- timevar_push (TV_NAME_LOOKUP);
-
if (TREE_CODE (d1) == IDENTIFIER_NODE)
{
tree value = innermost_non_namespace_value (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
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;
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
{
{
/* 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);
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
/* 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;
&elt, hash);
if (entry)
- POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, entry->spec);
+ return entry->spec;
is_dependent_type = uses_template_parms (arglist);
&& 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)
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,
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;
}
\f
struct pair_fn_data
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;
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)
{
/* 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;
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
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. */
pop_deferring_access_checks ();
pop_tinst_level ();
- timevar_pop (TV_PARSE);
+ timevar_pop (TV_TEMPLATE_INST);
return d;
}
/* 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. */
/* 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")
/* 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")
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")
/* 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. */
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 ();
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. */
/* 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. */
/* 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. */