[patch] Split Parse Timevar (rev 2) (issue4433076)

Lawrence Crowl crowl@google.com
Wed Apr 27 19:16:00 GMT 2011


See the email thread "[patch] Split Parse Timevar (issue4378056)" for
the genesis of this patch and subsequent comments.

Jason, I believe this patch addresses all of your comments.  The
compiler builds all of its user libraries with -ftime-report.

Index: gcc/ChangeLog

2011-04-27  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.

Index: gcc/cp/ChangeLog

2011-04-27  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).


Index: gcc/toplev.c
===================================================================
--- gcc/toplev.c	(revision 172980)
+++ gcc/toplev.c	(working copy)
@@ -562,36 +562,34 @@ emit_debug_global_declarations (tree *ve
 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.  */
Index: gcc/cp/decl.c
===================================================================
--- gcc/cp/decl.c	(revision 172980)
+++ gcc/cp/decl.c	(working copy)
@@ -552,7 +552,7 @@ poplevel (int keep, int reverse, int fun
   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 fun
   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 
   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 
       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;
@@ -11193,16 +11216,14 @@ lookup_and_check_tag (enum tag_types tag
    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)
@@ -11230,7 +11251,7 @@ xref_tag (enum tag_types tag_code, tree 
 			       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)
@@ -11285,7 +11306,7 @@ xref_tag (enum tag_types tag_code, tree 
       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
 	{
@@ -11299,7 +11320,7 @@ xref_tag (enum tag_types tag_code, tree 
       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)
@@ -11307,7 +11328,7 @@ xref_tag (enum tag_types tag_code, tree 
 	{
 	  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.  */
@@ -11325,9 +11346,23 @@ xref_tag (enum tag_types tag_code, tree 
 	}
     }
 
-  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)
 {
Index: gcc/cp/Make-lang.in
===================================================================
--- gcc/cp/Make-lang.in	(revision 172980)
+++ gcc/cp/Make-lang.in	(working copy)
@@ -277,7 +277,7 @@ cp/class.o: cp/class.c $(CXX_TREE_H) $(T
   $(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)
@@ -316,7 +316,7 @@ cp/mangle.o: cp/mangle.c $(CXX_TREE_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
 
Index: gcc/cp/pt.c
===================================================================
--- gcc/cp/pt.c	(revision 172980)
+++ gcc/cp/pt.c	(working copy)
@@ -6682,13 +6682,9 @@ maybe_get_template_decl_from_type_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
     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)
 {
@@ -13504,8 +13523,8 @@ check_instantiated_args (tree tmpl, tree
 /* 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;
@@ -13614,6 +13633,18 @@ instantiate_template (tree tmpl, tree or
   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
@@ -17203,7 +17234,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.  */
@@ -17496,7 +17527,7 @@ out:
   pop_deferring_access_checks ();
   pop_tinst_level ();
 
-  timevar_pop (TV_PARSE);
+  timevar_pop (TV_TEMPLATE_INST);
 
   return d;
 }
Index: gcc/cp/decl2.c
===================================================================
--- gcc/cp/decl2.c	(revision 172980)
+++ gcc/cp/decl2.c	(working copy)
@@ -3675,6 +3675,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:
 
@@ -3691,8 +3693,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
@@ -3999,8 +3999,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);
@@ -4036,8 +4042,6 @@ cp_write_global_declarations (void)
       }
   }
 
-  timevar_pop (TV_VARCONST);
-
   if (flag_detailed_statistics)
     {
       dump_tree_statistics ();
@@ -4048,6 +4052,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
Index: gcc/cp/parser.c
===================================================================
--- gcc/cp/parser.c	(revision 172980)
+++ gcc/cp/parser.c	(working copy)
@@ -23,6 +23,7 @@ along with GCC; see the file COPYING3.  
 #include "system.h"
 #include "coretypes.h"
 #include "tm.h"
+#include "timevar.h"
 #include "cpplib.h"
 #include "tree.h"
 #include "cp-tree.h"
@@ -12145,6 +12146,8 @@ cp_parser_explicit_instantiation (cp_par
   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))
@@ -12228,6 +12231,8 @@ cp_parser_explicit_instantiation (cp_par
   end_explicit_instantiation ();
 
   cp_parser_consume_semicolon_at_end_of_statement (parser);
+
+  timevar_pop (TV_TEMPLATE_INST);
 }
 
 /* Parse an explicit-specialization.
@@ -13439,6 +13444,7 @@ cp_parser_enum_specifier (cp_parser* par
      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:
@@ -13500,6 +13506,7 @@ cp_parser_enum_specifier (cp_parser* par
 
       if (scoped_enum_p)
 	finish_scope ();
+      timevar_pop (TV_PARSE_ENUM);
     }
   else
     {
@@ -16735,7 +16742,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;
@@ -16998,6 +17005,16 @@ cp_parser_class_specifier (cp_parser* pa
   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:
@@ -19643,8 +19660,17 @@ cp_parser_function_definition_from_speci
 	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;
 }
@@ -20261,6 +20287,7 @@ cp_parser_enclosed_template_argument_lis
 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))
@@ -20327,6 +20354,7 @@ cp_parser_late_parsing_for_member (cp_pa
 
   /* Restore the queue.  */
   pop_unparsed_function_queues (parser);
+  timevar_pop (TV_PARSE_INMETH);
 }
 
 /* If DECL contains any default args, remember it on the unparsed
Index: gcc/cp/call.c
===================================================================
--- gcc/cp/call.c	(revision 172980)
+++ gcc/cp/call.c	(working copy)
@@ -39,6 +39,7 @@ along with GCC; see the file COPYING3.  
 #include "convert.h"
 #include "langhooks.h"
 #include "c-family/c-objc.h"
+#include "timevar.h"
 
 /* The various kinds of conversion.  */
 
@@ -1220,7 +1221,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;
@@ -1356,6 +1357,18 @@ convert_class_to_reference (tree referen
   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.  */
@@ -3442,20 +3455,32 @@ build_user_type_conversion_1 (tree totyp
   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.
@@ -3571,8 +3596,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;
@@ -3599,10 +3629,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;
 }
 
@@ -3792,8 +3824,8 @@ build_operator_new_call (tree fnname, VE
 
 /* 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;
@@ -3924,6 +3956,18 @@ build_op_call (tree obj, VEC(tree,gc) **
   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)
@@ -4061,9 +4105,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;
@@ -4484,6 +4528,19 @@ build_conditional_expr (tree arg1, tree 
   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.  */
@@ -4652,8 +4709,8 @@ avoid_sign_compare_warnings (tree orig_a
     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;
@@ -4820,8 +4877,8 @@ build_new_op (enum tree_code code, int f
 	    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.  */
@@ -5024,6 +5081,19 @@ build_new_op (enum tree_code code, int f
   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]).  */
 
@@ -6747,10 +6817,10 @@ name_as_c_string (tree name, tree type, 
    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;
@@ -7054,6 +7124,21 @@ build_new_method_call (tree instance, tr
   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.  */
 
Index: gcc/cp/name-lookup.c
===================================================================
--- gcc/cp/name-lookup.c	(revision 172980)
+++ gcc/cp/name-lookup.c	(working copy)
@@ -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
       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 
    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_f
 	      /* 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_f
 			 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_f
 	      /* 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_f
 		  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_f
 					  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_f
 	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_f
 		       ? 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 (t
    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,9 +2088,22 @@ pushdecl_with_scope (tree x, cxx_scope *
       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
    the value of the identifier point to a list of all the things that
@@ -2070,14 +2126,13 @@ pushdecl_with_scope (tree x, cxx_scope *
    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 fla
 	      /* 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 fla
 	{
 	  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 fla
 
 		/* 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 fla
       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 
 /* 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, tre
     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, tre
 	  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, tre
       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, tre
 	     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, tre
       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 na
 
 /* 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 s
     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 i
   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 i
 	  *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 use
       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 use
   /* 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, 
 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 loc
    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,
   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,
 	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,
 				       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,
       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, struc
 			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, struc
 	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 n
   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 n
   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_
 	  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_
   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 
    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 
       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 
 	}
     }
 
-  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 (tr
 	  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 (tr
 	}
     }
 
-  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 fn
   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 
 
    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
   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
       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
 	}
       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
   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_save
 {
   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_save
 
       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_bindi
   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.  */
Index: gcc/timevar.def
===================================================================
--- gcc/timevar.def	(revision 172980)
+++ gcc/timevar.def	(working copy)
@@ -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	     , "rebu
 /* 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         , "
 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")
Index: gcc/timevar.c
===================================================================
--- gcc/timevar.c	(revision 172980)
+++ gcc/timevar.c	(working copy)
@@ -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.  */
Index: gcc/timevar.h
===================================================================
--- gcc/timevar.h	(revision 172980)
+++ gcc/timevar.h	(working copy)
@@ -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.  */
Index: gcc/c-decl.c
===================================================================
--- gcc/c-decl.c	(revision 172980)
+++ gcc/c-decl.c	(working copy)
@@ -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.  */
Index: gcc/c-parser.c
===================================================================
--- gcc/c-parser.c	(revision 172980)
+++ gcc/c-parser.c	(working copy)
@@ -1570,6 +1570,7 @@ c_parser_declaration_or_fndef (c_parser 
     {
       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 
 	    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 
 	  add_stmt (fnbody);
 	  finish_function ();
 	}
+
+      timevar_pop (tv);
       break;
     }
 }
@@ -2189,11 +2199,14 @@ c_parser_enum_specifier (c_parser *parse
     {
       /* 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 *parse
       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_pa
 	 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_pa
       ret.kind = ctsk_tagdef;
       ret.expr = NULL_TREE;
       ret.expr_const_operands = true;
+      timevar_pop (TV_PARSE_STRUCT);
       return ret;
     }
   else if (!ident)

--
This patch is available for review at http://codereview.appspot.com/4433076



More information about the Gcc-patches mailing list