This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[patch] Split Parse Timevar (issue4378056)


This patch provides more finer, more precise compile time information.
I sent an advisory mail some time ago, and it was good then.  Please
confirm for trunk.


The Problem

The current timevar structure tends to report times in a way that
obscures responsibility.  For example, time attributed to garbage
collection is never attributed to a pass, and hence passes that
generate lots of garbage look less expensive than they actually are.
One would really like the time in garbage collection to be reported
orthogonally to the functional algorithms.

Similarly, time attributed to C++ name lookup could occur in either
the parsing or in the C++ deferred processing.  The reported parsing
and deferred processing times should include the time they spend
in name lookup, and hence name lookup times should be reported
orthogonally.


The Solution

The solution shifts some of the time recording from push/pop timevar
to start/stop timevar.  Times collected with start/stop timevars
will not subtract their times from their context, and hence not
absolve the context of responsibility for that time.

To achieve this shift, we must do two things.  First, upgrade
the timevar mechanism to support more flexible use of start/stop.
Second, add/modify timevars to use the kind of timevar appropriate
to their purpose.


The Mechanism Upgrade

There were two changes necessary to timevars to provide the mechanism
needed.  First, make them restartable.  This change enables utilities
to record their time orthogonally to their calling context.  Second,
make them nestable.  That is, if a function is using a start/stop
timevar, and it may call a function that also wants to use the
same timevar, it should be easy for the inner function to neither
start nor stop the timer again.  The functions to do this are
timevar_cond_start and timevar_cond_stop that start and stop only
when the timer was not already running.  If the timer was already
running, it does nothing.  The programmer copies the return value
from timevar_cond_start to the argument of timevar_cond_stop to
coordinate their activities.


The Timevar Modification

The timevar modifications are fairly conservative; I did not modify
that which I did not understand.  Other folks may wish to make
modifications in a similar vein.

Add Timevars for Compiler Phases

I added several new start/stop timevars to time distict compiler
phases.  The phases are setup, parsing, C wrapup & check or C++
deferred processing, cgraph generation, (C) debug info write or
(C++) both checking and debug info write, code generation, and
compiler finalize.

Factor Parsing Timevar

The parsing timevar was much too coarse, at least for C++.  I have
factored it into separate timevars for global/namespace parsing,
function body parsing, enum body parsing, struct body parsing,
inline method body parsing, and template instantiation.  I did this
change for both C and C++.

Separate Name Lookup Timevar

C++ name lookup work is shared between the parsing phase and deferred
phase, which makes a clear separation difficult when name looup uses
push/pop.  So, for C++, I changed name lookup to use start/stop or
start_cond/stop_cond.  Now the name lookup time is orthogonal to its
contexts.  Summing this timevar with any others is not meaningful.

The conditional start/stop was added here to handle the nested
and recursive calls in the name lookup interface.  This change
constitutes the bulk of the patch because it involves refactoring
the timing in many functions out into a wrapper function.

Separate Garbage Collection Timevar

Likewise garbage collection is separated from the normal push/pop
hierarchy to allow purposeful code to be correctly accounted.
Now the garbage collection time is orthogonal to its contexts.
Summing this timevar with any others is not meaningful.

Add Overload Resolution Timevar

Add a start/stop timevar for overload resolution.  The overload
resoultion time is also orthogonal to its contexts.  Summing this
timevar with any others is not meaningful.


Index: gcc/ChangeLog

2011-04-11  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_print): Reduce time output to fit in an 80-column window.
	Factor out units to column headings.
	Conditionally compile column headings as well as column data.

        * timevar.def: Add start/stop timers for compiler phases,
        TV_PHASE_SETUP, TV_PHASE_PARSING, TV_PHASE_C_WRAPUP_CHECK,
        TV_PHASE_CP_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_INMETH, TV_INSTANTIATE_TEMPLATE.
	Change push/pop timers TV_GC and TV_NAME_LOOKUP into start/stop timers.
	Add start/stop timer TV_RESOLVE_OVERLOAD.
	Remove unused timers TV_OVERLOAD, TV_TEMPLATE_INSTANTIATION.
        Mark the strings for TV_GC, TV_NAME_LOOKUP, and
        TV_RESOLVE_OVERLOAD with a "|" to indicate that they are
        start/stop timers.

        * toplev.c (compile_file): Change TV_PARSE to TV_PARSE_GLOBAL.
	Start/stop timers TV_PHASE_PARSING and TV_PHASE_GENERATE.
	* (do_compile): Start/stop timers TV_PHASE_SETUP and TV_PHASE_FINALIZE.

        * c-decl.c (c_write_global_declarations): Add start/stop of
        TV_PHASE_C_WRAPUP_CHECK, TV_PHASE_CGRAPH, TV_PHASE_DBGINFO.

	* ggc-zone.c (ggc_collect): Change TV_GC to start/stop.
	* ggc-page.c (ggc_collect): Change TV_GC to start/stop.

	* c-parser.c (c_parser_declaration_or_fndef): Push/pop TV_PARSE_FUNC.
	* (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-11  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): Refactor timevar calls out to a
	wrapper function.  Add push/pop of new TV_INSTANTIATE_TEMPLATE.
	* (instantiate_template): Refactor timevar calls out to a wrapper
	function.  Add push/pop of new TV_INSTANTIATE_TEMPLATE.
	* (lookup_template_class): Refactor timevar calls out to a wrapper
	function.  Change TV_NAME_LOOKUP to start_cond/stop_cond.
	* (instantiate_decl): Change TV_PARSE to TV_PARSE_GLOBAL.

	* 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_1): 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_CP_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 new
        TV_INSTANTIATE_TEMPLATE.
	* (cp_parser_enum_specifier): Add push/pop calls to new TV_PARSE_ENUM.
        * (cp_parser_class_specifier): Add push/pop calls to new
        TV_PARSE_STRUCT.
	* (cp_parser_function_definition_from_specifiers_and_declarator): Add
	push/pop calls to new TV_PARSE_FUNC.
        * (cp_parser_late_parsing_for_member):  Add push/pop calls to
        new TV_PARSE_INMETH.

	* call.c: Add include of "timevar.h".
        * (perform_overload_resolution): Add push/pop calls to new
        TV_RESOLVE_OVERLOAD.

	* Make-lang.in: Add dependence of call.o and parser.o on $(TIMEVAR_H).



Index: gcc/toplev.c
===================================================================
*** gcc/toplev.c	(revision 172275)
--- gcc/toplev.c	(working copy)
*************** compile_file (void)
*** 564,569 ****
--- 564,571 ----
  {
    /* Initialize yet another pass.  */
  
+   timevar_start (TV_PHASE_PARSING);
+ 
    ggc_protect_identifiers = true;
  
    init_cgraph ();
*************** compile_file (void)
*** 572,578 ****
    statistics_init ();
    invoke_plugin_callbacks (PLUGIN_START_UNIT, NULL);
  
!   timevar_push (TV_PARSE);
  
    /* Call the parser, which parses the entire file (calling
       rest_of_compilation for each function).  */
--- 574,580 ----
    statistics_init ();
    invoke_plugin_callbacks (PLUGIN_START_UNIT, NULL);
  
!   timevar_push (TV_PARSE_GLOBAL);
  
    /* Call the parser, which parses the entire file (calling
       rest_of_compilation for each function).  */
*************** compile_file (void)
*** 580,586 ****
  
    /* 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;
--- 582,590 ----
  
    /* Compilation is now finished except for writing
       what's left of the symbol table output.  */
!   timevar_pop (TV_PARSE_GLOBAL);
! 
!   timevar_stop (TV_PHASE_PARSING);
  
    if (flag_syntax_only || flag_wpa)
      return;
*************** compile_file (void)
*** 593,598 ****
--- 597,604 ----
    if (seen_error ())
      return;
  
+   timevar_start (TV_PHASE_GENERATE);
+ 
    varpool_assemble_pending_decls ();
    finish_aliases_2 ();
  
*************** compile_file (void)
*** 671,676 ****
--- 677,684 ----
       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.  */
*************** do_compile (void)
*** 1890,1895 ****
--- 1898,1905 ----
    /* 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.  */
*************** do_compile (void)
*** 1899,1909 ****
--- 1909,1925 ----
        if (!no_backend)
  	backend_init ();
  
+       timevar_stop (TV_PHASE_SETUP);
+ 
        /* Language-dependent initialization.  Returns true on success.  */
        if (lang_dependent_init (main_input_filename))
  	compile_file ();
  
+       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 172275)
--- gcc/cp/decl.c	(working copy)
*************** poplevel (int keep, int reverse, int fun
*** 552,558 ****
    unsigned ix;
    cp_label_binding *label_bind;
  
!   timevar_push (TV_NAME_LOOKUP);
   restart:
  
    block = NULL_TREE;
--- 552,558 ----
    unsigned ix;
    cp_label_binding *label_bind;
  
!   timevar_start (TV_NAME_LOOKUP);
   restart:
  
    block = NULL_TREE;
*************** poplevel (int keep, int reverse, int fun
*** 815,821 ****
    if (kind == sk_cleanup)
      goto restart;
  
!   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, block);
  }
  
  /* Walk all the namespaces contained NAMESPACE, including NAMESPACE
--- 815,822 ----
    if (kind == sk_cleanup)
      goto restart;
  
!   timevar_stop (TV_NAME_LOOKUP);
!   return block;
  }
  
  /* Walk all the namespaces contained NAMESPACE, including NAMESPACE
*************** push_local_name (tree decl)
*** 899,905 ****
    size_t i, nelts;
    tree t, name;
  
!   timevar_push (TV_NAME_LOOKUP);
  
    name = DECL_NAME (decl);
  
--- 900,906 ----
    size_t i, nelts;
    tree t, name;
  
!   timevar_start (TV_NAME_LOOKUP);
  
    name = DECL_NAME (decl);
  
*************** push_local_name (tree decl)
*** 918,930 ****
  	    DECL_DISCRIMINATOR (decl) = 1;
  
  	  VEC_replace (tree, local_names, i, decl);
! 	  timevar_pop (TV_NAME_LOOKUP);
  	  return;
  	}
      }
  
    VEC_safe_push (tree, gc, local_names, decl);
!   timevar_pop (TV_NAME_LOOKUP);
  }
  
  /* Subroutine of duplicate_decls: return truthvalue of whether
--- 919,931 ----
  	    DECL_DISCRIMINATOR (decl) = 1;
  
  	  VEC_replace (tree, local_names, i, decl);
! 	  timevar_stop (TV_NAME_LOOKUP);
  	  return;
  	}
      }
  
    VEC_safe_push (tree, gc, local_names, decl);
!   timevar_stop (TV_NAME_LOOKUP);
  }
  
  /* Subroutine of duplicate_decls: return truthvalue of whether
*************** make_label_decl (tree id, int local_p)
*** 2522,2547 ****
     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)
  {
    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);
      }
  
    /* 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);
  
    decl = make_label_decl (id, /*local_p=*/0);
!   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
  }
  
  /* Declare a local label named ID.  */
--- 2523,2559 ----
     be found, create one.  (We keep track of used, but undefined,
     labels, and complain about them at the end of a function.)  */
  
! static tree
! lookup_label_1 (tree id)
  {
    tree decl;
  
    /* You can't use labels at global scope.  */
    if (current_function_decl == NULL_TREE)
      {
        error ("label %qE referenced outside of any function", id);
!       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)
!     return decl;
  
    decl = make_label_decl (id, /*local_p=*/0);
!   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.  */
*************** check_omp_return (void)
*** 2814,2828 ****
  /* 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)
  {
    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;
--- 2826,2838 ----
  /* Define a label, specifying the location in the source file.
     Return the LABEL_DECL node for the label.  */
  
! static tree
! define_label_1 (location_t location, tree name)
  {
    struct named_label_entry *ent, dummy;
    struct cp_binding_level *p;
    tree decl;
  
    decl = lookup_label (name);
  
    dummy.label_decl = decl;
*************** define_label (location_t location, tree 
*** 2842,2848 ****
    if (DECL_INITIAL (decl) != NULL_TREE)
      {
        error ("duplicate label %qD", decl);
!       POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
      }
    else
      {
--- 2852,2858 ----
    if (DECL_INITIAL (decl) != NULL_TREE)
      {
        error ("duplicate label %qD", decl);
!       return error_mark_node;
      }
    else
      {
*************** define_label (location_t location, tree 
*** 2861,2869 ****
        ent->uses = NULL;
      }
  
!   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
  }
  
  struct cp_switch
  {
    struct cp_binding_level *level;
--- 2871,2892 ----
        ent->uses = NULL;
      }
  
!   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;
*************** lookup_and_check_tag (enum tag_types tag
*** 11124,11139 ****
     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)
  {
    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)
--- 11147,11160 ----
     TEMPLATE_HEADER_P is true when this declaration is preceded by
     a set of template parameters.  */
  
! 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;
  
    gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
  
    switch (tag_code)
*************** xref_tag (enum tag_types tag_code, tree 
*** 11161,11167 ****
  			       scope, template_header_p);
  
    if (t == error_mark_node)
!     POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
  
    if (scope != ts_current && t && current_class_type
        && template_class_depth (current_class_type)
--- 11182,11188 ----
  			       scope, template_header_p);
  
    if (t == error_mark_node)
!     return error_mark_node;
  
    if (scope != ts_current && t && current_class_type
        && template_class_depth (current_class_type)
*************** xref_tag (enum tag_types tag_code, tree 
*** 11216,11222 ****
        if (code == ENUMERAL_TYPE)
  	{
  	  error ("use of enum %q#D without previous declaration", name);
! 	  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
  	}
        else
  	{
--- 11237,11243 ----
        if (code == ENUMERAL_TYPE)
  	{
  	  error ("use of enum %q#D without previous declaration", name);
! 	  return error_mark_node;
  	}
        else
  	{
*************** xref_tag (enum tag_types tag_code, tree 
*** 11230,11236 ****
        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);
          }
        else if (!processing_template_decl
  	       && CLASS_TYPE_P (t)
--- 11251,11257 ----
        if (template_header_p && MAYBE_CLASS_TYPE_P (t))
          {
  	  if (!redeclare_class_template (t, current_template_parms))
!             return error_mark_node;
          }
        else if (!processing_template_decl
  	       && CLASS_TYPE_P (t)
*************** xref_tag (enum tag_types tag_code, tree 
*** 11238,11244 ****
  	{
  	  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);
  	}
  
        /* Make injected friend class visible.  */
--- 11259,11265 ----
  	{
  	  error ("redeclaration of %qT as a non-template", t);
  	  error ("previous declaration %q+D", t);
! 	  return error_mark_node;
  	}
  
        /* Make injected friend class visible.  */
*************** xref_tag (enum tag_types tag_code, tree 
*** 11256,11264 ****
  	}
      }
  
!   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
  }
  
  tree
  xref_tag_from_type (tree old, tree id, tag_scope scope)
  {
--- 11277,11299 ----
  	}
      }
  
!   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 172275)
--- gcc/cp/Make-lang.in	(working copy)
*************** cp/class.o: cp/class.c $(CXX_TREE_H) $(T
*** 277,283 ****
    $(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
  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)
--- 277,283 ----
    $(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 \
!   $(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)
*************** cp/mangle.o: cp/mangle.c $(CXX_TREE_H) $
*** 316,322 ****
    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)
  cp/cp-gimplify.o: cp/cp-gimplify.c $(CXX_TREE_H) $(C_COMMON_H) \
  	$(TM_H) coretypes.h pointer-set.h tree-iterator.h
  
--- 316,322 ----
    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) $(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 172275)
--- gcc/cp/pt.c	(working copy)
*************** maybe_get_template_decl_from_type_decl (
*** 6682,6694 ****
     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)
  {
    tree templ = NULL_TREE, parmlist;
    tree t;
--- 6682,6690 ----
     that we want to avoid. It also causes some problems with argument
     coercion (see convert_nontype_argument for more information on this).  */
  
! 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;
*************** lookup_template_class (tree d1,
*** 6697,6704 ****
    spec_entry elt;
    hashval_t hash;
  
-   timevar_push (TV_NAME_LOOKUP);
- 
    if (TREE_CODE (d1) == IDENTIFIER_NODE)
      {
        tree value = innermost_non_namespace_value (d1);
--- 6693,6698 ----
*************** lookup_template_class (tree d1,
*** 6751,6757 ****
      {
        if (complain & tf_error)
  	error ("%qT is not a template", d1);
!       POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
      }
  
    if (TREE_CODE (templ) != TEMPLATE_DECL
--- 6745,6751 ----
      {
        if (complain & tf_error)
  	error ("%qT is not a template", d1);
!       return error_mark_node;
      }
  
    if (TREE_CODE (templ) != TEMPLATE_DECL
*************** lookup_template_class (tree d1,
*** 6766,6772 ****
  	  if (in_decl)
  	    error ("for template declaration %q+D", in_decl);
  	}
!       POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
      }
  
    complain &= ~tf_user;
--- 6760,6766 ----
  	  if (in_decl)
  	    error ("for template declaration %q+D", in_decl);
  	}
!       return error_mark_node;
      }
  
    complain &= ~tf_user;
*************** lookup_template_class (tree d1,
*** 6816,6825 ****
        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);
  
        parm = bind_template_template_parm (TREE_TYPE (templ), arglist2);
!       POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, parm);
      }
    else
      {
--- 6810,6819 ----
        if (arglist2 == error_mark_node
  	  || (!uses_template_parms (arglist2)
  	      && check_instantiated_args (templ, arglist2, complain)))
! 	return error_mark_node;
  
        parm = bind_template_template_parm (TREE_TYPE (templ), arglist2);
!       return parm;
      }
    else
      {
*************** lookup_template_class (tree d1,
*** 6895,6901 ****
  		{
  		  /* Restore the ARGLIST to its full size.  */
  		  TREE_VEC_LENGTH (arglist) = saved_depth;
! 		  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
  		}
  
  	      SET_TMPL_ARGS_LEVEL (bound_args, i, a);
--- 6889,6895 ----
  		{
  		  /* Restore the ARGLIST to its full size.  */
  		  TREE_VEC_LENGTH (arglist) = saved_depth;
! 		  return error_mark_node;
  		}
  
  	      SET_TMPL_ARGS_LEVEL (bound_args, i, a);
*************** lookup_template_class (tree d1,
*** 6923,6929 ****
  
        if (arglist == error_mark_node)
  	/* We were unable to bind the arguments.  */
! 	POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, 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
--- 6917,6923 ----
  
        if (arglist == error_mark_node)
  	/* We were unable to bind the arguments.  */
! 	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
*************** lookup_template_class (tree d1,
*** 6939,6945 ****
  	  /* 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);
  
        /* If we already have this specialization, return it.  */
        elt.tmpl = gen_tmpl;
--- 6933,6939 ----
  	  /* comp_template_args is expensive, check it last.  */
  	  && comp_template_args (TYPE_TI_ARGS (template_type),
  				 arglist))
! 	return template_type;
  
        /* If we already have this specialization, return it.  */
        elt.tmpl = gen_tmpl;
*************** lookup_template_class (tree d1,
*** 6949,6955 ****
  						  &elt, hash);
  
        if (entry)
! 	POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, entry->spec);
  
        is_dependent_type = uses_template_parms (arglist);
  
--- 6943,6949 ----
  						  &elt, hash);
  
        if (entry)
! 	return entry->spec;
  
        is_dependent_type = uses_template_parms (arglist);
  
*************** lookup_template_class (tree d1,
*** 6959,6965 ****
  	  && check_instantiated_args (gen_tmpl,
  				      INNERMOST_TEMPLATE_ARGS (arglist),
  				      complain))
! 	POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
  
        if (!is_dependent_type
  	  && !PRIMARY_TEMPLATE_P (gen_tmpl)
--- 6953,6959 ----
  	  && check_instantiated_args (gen_tmpl,
  				      INNERMOST_TEMPLATE_ARGS (arglist),
  				      complain))
! 	return error_mark_node;
  
        if (!is_dependent_type
  	  && !PRIMARY_TEMPLATE_P (gen_tmpl)
*************** lookup_template_class (tree d1,
*** 6969,6975 ****
  	  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);
  	}
  
        context = tsubst (DECL_CONTEXT (gen_tmpl), arglist,
--- 6963,6969 ----
  	  found = xref_tag_from_type (TREE_TYPE (gen_tmpl),
  				      DECL_NAME (gen_tmpl),
  				      /*tag_scope=*/ts_global);
! 	  return found;
  	}
  
        context = tsubst (DECL_CONTEXT (gen_tmpl), arglist,
*************** lookup_template_class (tree d1,
*** 7162,7170 ****
        TREE_PUBLIC (type_decl) = 1;
        determine_visibility (type_decl);
  
!       POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
      }
!   timevar_pop (TV_NAME_LOOKUP);
  }
  
  struct pair_fn_data
--- 7156,7177 ----
        TREE_PUBLIC (type_decl) = 1;
        determine_visibility (type_decl);
  
!       return t;
      }
! }
! 
! /* 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;
!   bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
!   ret = lookup_template_class_1 (d1, arglist, in_decl, context,
!                                 entering_scope, complain);
!   timevar_cond_stop (TV_NAME_LOOKUP, subtime);
!   return ret;
  }
  
  struct pair_fn_data
*************** perform_typedefs_access_check (tree tmpl
*** 8101,8108 ****
      input_location = saved_location;
  }
  
! tree
! instantiate_class_template (tree type)
  {
    tree templ, args, pattern, t, member;
    tree typedecl;
--- 8108,8115 ----
      input_location = saved_location;
  }
  
! static tree
! instantiate_class_template_1 (tree type)
  {
    tree templ, args, pattern, t, member;
    tree typedecl;
*************** instantiate_class_template (tree type)
*** 8596,8601 ****
--- 8603,8620 ----
    return type;
  }
  
+ /* Wrapper for instantiate_class_template_1.  */
+ 
+ tree
+ instantiate_class_template (tree type)
+ {
+   tree ret;
+   timevar_push (TV_INSTANTIATE_TEMPLATE);
+   ret = instantiate_class_template_1 (type);
+   timevar_pop (TV_INSTANTIATE_TEMPLATE);
+   return ret;
+ }
+ 
  static tree
  tsubst_template_arg (tree t, tree args, tsubst_flags_t complain, tree in_decl)
  {
*************** check_instantiated_args (tree tmpl, tree
*** 13495,13502 ****
  /* 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)
  {
    tree targ_ptr = orig_args;
    tree fndecl;
--- 13514,13521 ----
  /* Instantiate the indicated variable or function template TMPL with
     the template arguments in TARG_PTR.  */
  
! static tree
! instantiate_template_1 (tree tmpl, tree orig_args, tsubst_flags_t complain)
  {
    tree targ_ptr = orig_args;
    tree fndecl;
*************** instantiate_template (tree tmpl, tree or
*** 13605,13610 ****
--- 13624,13641 ----
    return fndecl;
  }
  
+ /* Wrapper for instantiate_template_1.  */
+ 
+ tree
+ instantiate_template (tree tmpl, tree orig_args, tsubst_flags_t complain)
+ {
+   tree ret;
+   timevar_push (TV_INSTANTIATE_TEMPLATE);
+   ret = instantiate_template_1 (tmpl, orig_args,  complain);
+   timevar_pop (TV_INSTANTIATE_TEMPLATE);
+   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
*************** instantiate_decl (tree d, int defer_ok,
*** 17193,17199 ****
    if (! push_tinst_level (d))
      return d;
  
!   timevar_push (TV_PARSE);
  
    /* Set TD to the template whose DECL_TEMPLATE_RESULT is the pattern
       for the instantiation.  */
--- 17224,17230 ----
    if (! push_tinst_level (d))
      return d;
  
!   timevar_push (TV_PARSE_GLOBAL);
  
    /* Set TD to the template whose DECL_TEMPLATE_RESULT is the pattern
       for the instantiation.  */
*************** out:
*** 17486,17492 ****
    pop_deferring_access_checks ();
    pop_tinst_level ();
  
!   timevar_pop (TV_PARSE);
  
    return d;
  }
--- 17517,17523 ----
    pop_deferring_access_checks ();
    pop_tinst_level ();
  
!   timevar_pop (TV_PARSE_GLOBAL);
  
    return d;
  }
Index: gcc/cp/decl2.c
===================================================================
*** gcc/cp/decl2.c	(revision 172275)
--- gcc/cp/decl2.c	(working copy)
*************** cp_write_global_declarations (void)
*** 3673,3678 ****
--- 3673,3680 ----
  
    /* FIXME - huh?  was  input_line -= 1;*/
  
+   timevar_start (TV_PHASE_CP_DEFERRED);
+ 
    /* We now have to write out all the stuff we put off writing out.
       These include:
  
*************** cp_write_global_declarations (void)
*** 3689,3696 ****
       generating the initializer for an object may cause templates to be
       instantiated, etc., etc.  */
  
-   timevar_push (TV_VARCONST);
- 
    emit_support_tinfos ();
  
    do
--- 3691,3696 ----
*************** cp_write_global_declarations (void)
*** 3997,4004 ****
--- 3997,4010 ----
    /* Collect candidates for Java hidden aliases.  */
    candidates = collect_candidates_for_java_method_aliases ();
  
+   timevar_stop (TV_PHASE_CP_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);
*************** cp_write_global_declarations (void)
*** 4034,4041 ****
        }
    }
  
-   timevar_pop (TV_VARCONST);
- 
    if (flag_detailed_statistics)
      {
        dump_tree_statistics ();
--- 4040,4045 ----
*************** cp_write_global_declarations (void)
*** 4046,4051 ****
--- 4050,4057 ----
  #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 172275)
--- gcc/cp/parser.c	(working copy)
*************** along with GCC; see the file COPYING3.  
*** 23,28 ****
--- 23,29 ----
  #include "system.h"
  #include "coretypes.h"
  #include "tm.h"
+ #include "timevar.h"
  #include "cpplib.h"
  #include "tree.h"
  #include "cp-tree.h"
*************** cp_parser_explicit_instantiation (cp_par
*** 12046,12051 ****
--- 12047,12054 ----
    cp_decl_specifier_seq decl_specifiers;
    tree extension_specifier = NULL_TREE;
  
+   timevar_push (TV_INSTANTIATE_TEMPLATE);
+ 
    /* Look for an (optional) storage-class-specifier or
       function-specifier.  */
    if (cp_parser_allow_gnu_extensions_p (parser))
*************** cp_parser_explicit_instantiation (cp_par
*** 12129,12134 ****
--- 12132,12139 ----
    end_explicit_instantiation ();
  
    cp_parser_consume_semicolon_at_end_of_statement (parser);
+ 
+   timevar_pop (TV_INSTANTIATE_TEMPLATE);
  }
  
  /* Parse an explicit-specialization.
*************** cp_parser_enum_specifier (cp_parser* par
*** 13329,13334 ****
--- 13334,13340 ----
       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:
*************** cp_parser_enum_specifier (cp_parser* par
*** 13390,13395 ****
--- 13396,13402 ----
  
        if (scoped_enum_p)
  	finish_scope ();
+       timevar_pop (TV_PARSE_ENUM);
      }
    else
      {
*************** cp_parser_class_specifier (cp_parser* pa
*** 16638,16643 ****
--- 16645,16651 ----
    tree bases;
    cp_token *closing_brace;
  
+   timevar_push (TV_PARSE_STRUCT);
    push_deferring_access_checks (dk_no_deferred);
  
    /* Parse the class-head.  */
*************** cp_parser_class_specifier (cp_parser* pa
*** 16651,16656 ****
--- 16659,16665 ----
      {
        cp_parser_skip_to_end_of_block_or_statement (parser);
        pop_deferring_access_checks ();
+       timevar_pop (TV_PARSE_STRUCT);
        return error_mark_node;
      }
  
*************** cp_parser_class_specifier (cp_parser* pa
*** 16658,16663 ****
--- 16667,16673 ----
    if (!cp_parser_require (parser, CPP_OPEN_BRACE, RT_OPEN_BRACE))
      {
        pop_deferring_access_checks ();
+       timevar_pop (TV_PARSE_STRUCT);
        return error_mark_node;
      }
  
*************** cp_parser_class_specifier (cp_parser* pa
*** 16670,16675 ****
--- 16680,16686 ----
        if (cp_parser_skip_to_closing_brace (parser))
  	cp_lexer_consume_token (parser->lexer);
        pop_deferring_access_checks ();
+       timevar_pop (TV_PARSE_STRUCT);
        return error_mark_node;
      }
  
*************** cp_parser_class_specifier (cp_parser* pa
*** 16885,16890 ****
--- 16896,16902 ----
    parser->in_unbraced_linkage_specification_p
      = saved_in_unbraced_linkage_specification_p;
  
+   timevar_pop (TV_PARSE_STRUCT);
    return type;
  }
  
*************** cp_parser_function_definition_from_speci
*** 19502,19507 ****
--- 19514,19520 ----
  {
    tree fn;
    bool success_p;
+   timevar_push (TV_PARSE_FUNC);
  
    /* Begin the function-definition.  */
    success_p = start_function (decl_specifiers, declarator, attributes);
*************** cp_parser_function_definition_from_speci
*** 19536,19541 ****
--- 19549,19555 ----
      fn = cp_parser_function_definition_after_declarator (parser,
  							 /*inline_p=*/false);
  
+   timevar_pop (TV_PARSE_FUNC);
    return fn;
  }
  
*************** cp_parser_enclosed_template_argument_lis
*** 20150,20155 ****
--- 20164,20170 ----
  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))
*************** cp_parser_late_parsing_for_member (cp_pa
*** 20216,20221 ****
--- 20231,20237 ----
  
    /* 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 172275)
--- gcc/cp/call.c	(working copy)
*************** along with GCC; see the file COPYING3.  
*** 39,44 ****
--- 39,45 ----
  #include "convert.h"
  #include "langhooks.h"
  #include "c-family/c-objc.h"
+ #include "timevar.h"
  
  /* The various kinds of conversion.  */
  
*************** perform_overload_resolution (tree fn,
*** 3569,3576 ****
  			     bool *any_viable_p)
  {
    struct z_candidate *cand;
!   tree explicit_targs = NULL_TREE;
!   int template_only = 0;
  
    *candidates = NULL;
    *any_viable_p = true;
--- 3570,3582 ----
  			     bool *any_viable_p)
  {
    struct z_candidate *cand;
!   tree explicit_targs;
!   int template_only;
! 
!   timevar_start (TV_RESOLVE_OVERLOAD);
! 
!   explicit_targs = NULL_TREE;
!   template_only = 0;
  
    *candidates = NULL;
    *any_viable_p = true;
*************** perform_overload_resolution (tree fn,
*** 3597,3606 ****
  		  candidates);
  
    *candidates = splice_viable (*candidates, pedantic, any_viable_p);
!   if (!*any_viable_p)
!     return NULL;
  
!   cand = tourney (*candidates);
    return cand;
  }
  
--- 3603,3614 ----
  		  candidates);
  
    *candidates = splice_viable (*candidates, pedantic, any_viable_p);
!   if (*any_viable_p)
!     cand = tourney (*candidates);
!   else
!     cand = NULL;
  
!   timevar_stop (TV_RESOLVE_OVERLOAD);
    return cand;
  }
  
Index: gcc/cp/name-lookup.c
===================================================================
*** gcc/cp/name-lookup.c	(revision 172275)
--- gcc/cp/name-lookup.c	(working copy)
*************** pop_binding (tree id, tree decl)
*** 434,445 ****
     was successful.  */
  
  static bool
! supplement_binding (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;
--- 434,444 ----
     was successful.  */
  
  static bool
! supplement_binding_1 (cxx_binding *binding, tree decl)
  {
    tree bval = binding->value;
    bool ok = true;
  
    if (TREE_CODE (decl) == TYPE_DECL && DECL_ARTIFICIAL (decl))
      /* The new name is the type name.  */
      binding->type = decl;
*************** supplement_binding (cxx_binding *binding
*** 526,532 ****
        ok = false;
      }
  
!   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ok);
  }
  
  /* Add DECL to the list of things declared in B.  */
--- 525,543 ----
        ok = false;
      }
  
!   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.  */
*************** add_decl_to_level (tree decl, cxx_scope 
*** 574,590 ****
     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)
  {
    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);
  
    need_new_binding = 1;
  
--- 585,599 ----
     If an old decl is returned, it may have been smashed
     to agree with what X says.  */
  
! static tree
! pushdecl_maybe_friend_1 (tree x, bool is_friend)
  {
    tree t;
    tree name;
    int need_new_binding;
  
    if (x == error_mark_node)
!     return error_mark_node;
  
    need_new_binding = 1;
  
*************** pushdecl_maybe_friend (tree x, bool is_f
*** 720,726 ****
  	      /* Check for duplicate params.  */
  	      tree d = duplicate_decls (x, t, is_friend);
  	      if (d)
! 		POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, d);
  	    }
  	  else if ((DECL_EXTERN_C_FUNCTION_P (x)
  		    || DECL_FUNCTION_TEMPLATE_P (x))
--- 729,735 ----
  	      /* Check for duplicate params.  */
  	      tree d = duplicate_decls (x, t, is_friend);
  	      if (d)
! 		return d;
  	    }
  	  else if ((DECL_EXTERN_C_FUNCTION_P (x)
  		    || DECL_FUNCTION_TEMPLATE_P (x))
*************** pushdecl_maybe_friend (tree x, bool is_f
*** 733,739 ****
  			 TREE_TYPE (x));
  	      
  	      /* Throw away the redeclaration.  */
! 	      POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
  	    }
  	  else
  	    {
--- 742,748 ----
  			 TREE_TYPE (x));
  	      
  	      /* Throw away the redeclaration.  */
! 	      return t;
  	    }
  	  else
  	    {
*************** pushdecl_maybe_friend (tree x, bool is_f
*** 742,755 ****
  	      /* 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);
  
  	      if (olddecl)
  		{
  		  if (TREE_CODE (t) == TYPE_DECL)
  		    SET_IDENTIFIER_TYPE_VALUE (name, TREE_TYPE (t));
  
! 		  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
  		}
  	      else if (DECL_MAIN_P (x) && TREE_CODE (t) == FUNCTION_DECL)
  		{
--- 751,764 ----
  	      /* If the redeclaration failed, we can stop at this
  		 point.  */
  	      if (olddecl == error_mark_node)
! 		return error_mark_node;
  
  	      if (olddecl)
  		{
  		  if (TREE_CODE (t) == TYPE_DECL)
  		    SET_IDENTIFIER_TYPE_VALUE (name, TREE_TYPE (t));
  
! 		  return t;
  		}
  	      else if (DECL_MAIN_P (x) && TREE_CODE (t) == FUNCTION_DECL)
  		{
*************** pushdecl_maybe_friend (tree x, bool is_f
*** 763,769 ****
  		  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);
  		}
  	    }
  	}
--- 772,778 ----
  		  error ("as %qD", x);
  		  /* We don't try to push this declaration since that
  		     causes a crash.  */
! 		  return x;
  		}
  	    }
  	}
*************** pushdecl_maybe_friend (tree x, bool is_f
*** 806,817 ****
  					  x_exception_spec,
  					  ce_normal))
  		    {
! 		      pedwarn (input_location, 0, "declaration of %q#D with C language linkage",
  			       x);
! 		      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);
  		    }
  		}
  	      else
--- 815,829 ----
  					  x_exception_spec,
  					  ce_normal))
  		    {
! 		      pedwarn (input_location, 0,
!                                "declaration of %q#D with C language linkage",
  			       x);
! 		      pedwarn (input_location, 0,
!                                "conflicts with previous declaration %q+#D",
  			       previous);
! 		      pedwarn (input_location, 0,
!                                "due to different exception specifications");
! 		      return error_mark_node;
  		    }
  		}
  	      else
*************** pushdecl_maybe_friend (tree x, bool is_f
*** 856,862 ****
  	check_default_args (t);
  
        if (t != x || DECL_FUNCTION_TEMPLATE_P (t))
! 	POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, 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
--- 868,874 ----
  	check_default_args (t);
  
        if (t != x || DECL_FUNCTION_TEMPLATE_P (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
*************** pushdecl_maybe_friend (tree x, bool is_f
*** 1143,1149 ****
  		       ? NAMESPACE_LEVEL (CP_DECL_CONTEXT (x))
  		       : current_binding_level);
  
!   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);
  }
  
  /* Record a decl-node X as belonging to the current lexical scope.  */
--- 1155,1173 ----
  		       ? NAMESPACE_LEVEL (CP_DECL_CONTEXT (x))
  		       : current_binding_level);
  
!   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_stack (void)
*** 1754,1779 ****
    print_binding_level (NAMESPACE_LEVEL (global_namespace));
  }
  
! /* Return the type associated with id.  */
  
! tree
! identifier_type_value (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);
    /* 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));
    /* 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 the IDENTIFIER_GLOBAL_VALUE of T, for use in common code, since
     the definition of IDENTIFIER_GLOBAL_VALUE is different for C and C++.  */
  
--- 1778,1815 ----
    print_binding_level (NAMESPACE_LEVEL (global_namespace));
  }
  
! /* Return the type associated with ID.  */
  
! static tree
! identifier_type_value_1 (tree id)
  {
    /* There is no type with that name, anywhere.  */
    if (REAL_IDENTIFIER_TYPE_VALUE (id) == NULL_TREE)
!     return NULL_TREE;
    /* This is not the type marker, but the real thing.  */
    if (REAL_IDENTIFIER_TYPE_VALUE (id) != global_type_node)
!     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)
!     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++.  */
  
*************** make_lambda_name (void)
*** 1914,1926 ****
  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);
  
!   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, (cxx_binding *)0);
  }
  
  /* Return the binding for NAME in SCOPE, if any.  Otherwise, return NULL.  */
--- 1950,1960 ----
  static inline cxx_binding *
  find_binding (cxx_scope *scope, cxx_binding *binding)
  {
    for (; binding != NULL; binding = binding->previous)
      if (binding->scope == scope)
!       return binding;
  
!   return (cxx_binding *)0;
  }
  
  /* Return the binding for NAME in SCOPE, if any.  Otherwise, return NULL.  */
*************** lookup_extern_c_fun_binding_in_all_ns (t
*** 1999,2034 ****
     scope, a using decl might extend any previous bindings).  */
  
  static tree
! push_using_decl (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);
    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);
  }
  
  /* 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)
  {
    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)
      {
--- 2033,2077 ----
     scope, a using decl might extend any previous bindings).  */
  
  static tree
! push_using_decl_1 (tree scope, tree name)
  {
    tree decl;
  
    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)
!     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;
!   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.  */
  
! 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;
  
    current_function_decl = NULL_TREE;
    if (level->kind == sk_class)
      {
*************** pushdecl_with_scope (tree x, cxx_scope *
*** 2045,2052 ****
        current_binding_level = b;
      }
    current_function_decl = function_decl;
!   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, x);
  }
  
  /* DECL is a FUNCTION_DECL for a non-member function, which may have
     other definitions already in place.  We get around this by making
--- 2088,2108 ----
        current_binding_level = b;
      }
    current_function_decl = function_decl;
!   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
*************** pushdecl_with_scope (tree x, cxx_scope *
*** 2070,2083 ****
     it's always DECL (and never something that's not a _DECL).  */
  
  static tree
! push_overloaded_decl (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
--- 2126,2138 ----
     it's always DECL (and never something that's not a _DECL).  */
  
  static tree
! 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));
  
    if (doing_global)
      old = namespace_binding (name, DECL_CONTEXT (decl));
    else
*************** push_overloaded_decl (tree decl, int fla
*** 2115,2121 ****
  	      /* 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);
  	    }
  
  	  /* We don't overload implicit built-ins.  duplicate_decls()
--- 2170,2176 ----
  	      /* 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)
! 		return dup;
  	    }
  
  	  /* We don't overload implicit built-ins.  duplicate_decls()
*************** push_overloaded_decl (tree decl, int fla
*** 2133,2139 ****
  	{
  	  error ("previous non-function declaration %q+#D", old);
  	  error ("conflicts with function declaration %q#D", decl);
! 	  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
  	}
      }
  
--- 2188,2194 ----
  	{
  	  error ("previous non-function declaration %q+#D", old);
  	  error ("conflicts with function declaration %q#D", decl);
! 	  return decl;
  	}
      }
  
*************** push_overloaded_decl (tree decl, int fla
*** 2185,2191 ****
  
  		/* And update the cxx_binding node.  */
  		IDENTIFIER_BINDING (name)->value = new_binding;
! 		POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
  	      }
  
  	  /* We should always find a previous binding in this case.  */
--- 2240,2246 ----
  
  		/* And update the cxx_binding node.  */
  		IDENTIFIER_BINDING (name)->value = new_binding;
! 		return decl;
  	      }
  
  	  /* We should always find a previous binding in this case.  */
*************** push_overloaded_decl (tree decl, int fla
*** 2196,2202 ****
        push_local_binding (name, new_binding, flags);
      }
  
!   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
  }
  
  /* Check a non-member using-declaration. Return the name and scope
--- 2251,2269 ----
        push_local_binding (name, new_binding, flags);
      }
  
!   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
*************** poplevel_class (void)
*** 2643,2649 ****
    size_t i;
    tree shadowed;
  
!   timevar_push (TV_NAME_LOOKUP);
    gcc_assert (level != 0);
  
    /* If we're leaving a toplevel class, cache its binding level.  */
--- 2710,2716 ----
    size_t i;
    tree shadowed;
  
!   bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
    gcc_assert (level != 0);
  
    /* If we're leaving a toplevel class, cache its binding level.  */
*************** poplevel_class (void)
*** 2667,2673 ****
       `pushlevel_class' routine.  */
    gcc_assert (current_binding_level == level);
    leave_scope ();
!   timevar_pop (TV_NAME_LOOKUP);
  }
  
  /* Set INHERITED_VALUE_BINDING_P on BINDING to true or false, as
--- 2734,2740 ----
       `pushlevel_class' routine.  */
    gcc_assert (current_binding_level == level);
    leave_scope ();
!   timevar_cond_stop (TV_NAME_LOOKUP, subtime);
  }
  
  /* Set INHERITED_VALUE_BINDING_P on BINDING to true or false, as
*************** pushdecl_class_level (tree x)
*** 2711,2723 ****
  {
    tree name;
    bool is_valid = true;
  
    /* 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);
    /* Get the name of X.  */
    if (TREE_CODE (x) == OVERLOAD)
      name = DECL_NAME (get_first_fn (x));
--- 2778,2791 ----
  {
    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;
  
!   subtime = timevar_cond_start (TV_NAME_LOOKUP);
    /* Get the name of X.  */
    if (TREE_CODE (x) == OVERLOAD)
      name = DECL_NAME (get_first_fn (x));
*************** pushdecl_class_level (tree x)
*** 2746,2752 ****
  	  input_location = save_location;
  	}
      }
!   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, is_valid);
  }
  
  /* Return the BINDING (if any) for NAME in SCOPE, which is a class
--- 2814,2821 ----
  	  input_location = save_location;
  	}
      }
!   timevar_cond_stop (TV_NAME_LOOKUP, subtime);
!   return is_valid;
  }
  
  /* Return the BINDING (if any) for NAME in SCOPE, which is a class
*************** get_class_binding (tree name, cxx_scope 
*** 2813,2833 ****
  /* 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)
  {
    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);
  
    if (name == error_mark_node)
!     POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, false);
  
    /* Check for invalid member names.  */
    gcc_assert (TYPE_BEING_DEFINED (current_class_type));
--- 2882,2901 ----
  /* Make the declaration(s) of X appear in CLASS scope under the name
     NAME.  Returns true if the binding is valid.  */
  
! static bool
! push_class_level_binding_1 (tree name, tree x)
  {
    cxx_binding *binding;
    tree decl = x;
    bool ok;
  
    /* The class_binding_level will be NULL if x is a template
       parameter name in a member template.  */
    if (!class_binding_level)
!     return true;
  
    if (name == error_mark_node)
!     return false;
  
    /* Check for invalid member names.  */
    gcc_assert (TYPE_BEING_DEFINED (current_class_type));
*************** push_class_level_binding (tree name, tre
*** 2842,2848 ****
      decl = TREE_VALUE (decl);
  
    if (!check_template_shadow (decl))
!     POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, false);
  
    /* [class.mem]
  
--- 2910,2916 ----
      decl = TREE_VALUE (decl);
  
    if (!check_template_shadow (decl))
!     return false;
  
    /* [class.mem]
  
*************** push_class_level_binding (tree name, tre
*** 2876,2882 ****
  	  error ("%qD has the same name as the class in which it is "
  		 "declared",
  		 x);
! 	  POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, false);
  	}
      }
  
--- 2944,2950 ----
  	  error ("%qD has the same name as the class in which it is "
  		 "declared",
  		 x);
! 	  return false;
  	}
      }
  
*************** push_class_level_binding (tree name, tre
*** 2927,2937 ****
        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);
        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);
  
        if (old_decl && binding->scope == class_binding_level)
  	{
--- 2995,3005 ----
        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)
! 	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))
! 	return true;
  
        if (old_decl && binding->scope == class_binding_level)
  	{
*************** push_class_level_binding (tree name, tre
*** 2940,2946 ****
  	     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);
  	}
      }
  
--- 3008,3014 ----
  	     here.  This function is only used to register bindings
  	     from with the class definition itself.  */
  	  INHERITED_VALUE_BINDING_P (binding) = 0;
! 	  return true;
  	}
      }
  
*************** push_class_level_binding (tree name, tre
*** 2962,2968 ****
        ok = true;
      }
  
!   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, ok);
  }
  
  /* Process "using SCOPE::NAME" in a class scope.  Return the
--- 3030,3048 ----
        ok = true;
      }
  
!   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
*************** do_class_using_decl (tree scope, tree na
*** 3080,3087 ****
  
  /* Return the binding value for name in scope.  */
  
! tree
! namespace_binding (tree name, tree scope)
  {
    cxx_binding *binding;
  
--- 3160,3168 ----
  
  /* Return the binding value for name in scope.  */
  
! 
! static tree
! namespace_binding_1 (tree name, tree scope)
  {
    cxx_binding *binding;
  
*************** namespace_binding (tree name, tree scope
*** 3096,3109 ****
    return binding ? binding->value : NULL_TREE;
  }
  
  /* Set the binding value for name in scope.  */
  
! void
! set_namespace_binding (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);
--- 3177,3199 ----
    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.  */
  
! static void
! set_namespace_binding_1 (tree name, tree scope, tree val)
  {
    cxx_binding *b;
  
    if (scope == NULL_TREE)
      scope = global_namespace;
    b = binding_for_name (NAMESPACE_LEVEL (scope), name);
*************** set_namespace_binding (tree name, tree s
*** 3111,3117 ****
      b->value = val;
    else
      supplement_binding (b, val);
!   timevar_pop (TV_NAME_LOOKUP);
  }
  
  /* Set the context of a declaration to scope. Complain if we are not
--- 3201,3216 ----
      b->value = val;
    else
      supplement_binding (b, val);
! }
! 
! /* 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
*************** push_namespace (tree name)
*** 3297,3303 ****
    int implicit_use = 0;
    bool anon = !name;
  
!   timevar_push (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
--- 3396,3402 ----
    int implicit_use = 0;
    bool anon = !name;
  
!   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
*************** push_namespace (tree name)
*** 3357,3363 ****
    /* Enter the name space.  */
    current_namespace = d;
  
!   timevar_pop (TV_NAME_LOOKUP);
  }
  
  /* Pop from the scope of the current namespace.  */
--- 3456,3462 ----
    /* Enter the name space.  */
    current_namespace = d;
  
!   timevar_cond_stop (TV_NAME_LOOKUP, subtime);
  }
  
  /* Pop from the scope of the current namespace.  */
*************** push_nested_namespace (tree ns)
*** 3392,3398 ****
  void
  pop_nested_namespace (tree ns)
  {
!   timevar_push (TV_NAME_LOOKUP);
    gcc_assert (current_namespace == ns);
    while (ns != global_namespace)
      {
--- 3491,3497 ----
  void
  pop_nested_namespace (tree ns)
  {
!   bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
    gcc_assert (current_namespace == ns);
    while (ns != global_namespace)
      {
*************** pop_nested_namespace (tree ns)
*** 3401,3407 ****
      }
  
    pop_from_top_level ();
!   timevar_pop (TV_NAME_LOOKUP);
  }
  
  /* Temporarily set the namespace for the current declaration.  */
--- 3500,3506 ----
      }
  
    pop_from_top_level ();
!   timevar_cond_stop (TV_NAME_LOOKUP, subtime);
  }
  
  /* Temporarily set the namespace for the current declaration.  */
*************** pop_decl_namespace (void)
*** 3426,3438 ****
     of two given namespaces.  */
  
  static tree
! namespace_ancestor (tree ns1, tree ns2)
  {
!   timevar_push (TV_NAME_LOOKUP);
    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));
  }
  
  /* Process a namespace-alias declaration.  */
--- 3525,3550 ----
     of two given namespaces.  */
  
  static tree
! namespace_ancestor_1 (tree ns1, tree ns2)
  {
!   tree nsr;
    if (is_ancestor (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.  */
*************** pushdecl_namespace_level (tree x, bool i
*** 3468,3474 ****
    struct cp_binding_level *b = current_binding_level;
    tree t;
  
!   timevar_push (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
--- 3580,3586 ----
    struct cp_binding_level *b = current_binding_level;
    tree t;
  
!   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
*************** pushdecl_namespace_level (tree x, bool i
*** 3502,3524 ****
  	  *ptr = newval;
  	}
      }
!   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, 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)
  {
    tree t;
-   timevar_push (TV_NAME_LOOKUP);
    /* Using oneself is a no-op.  */
    if (user == used)
!     {
!       timevar_pop (TV_NAME_LOOKUP);
!       return;
!     }
    gcc_assert (TREE_CODE (user) == NAMESPACE_DECL);
    gcc_assert (TREE_CODE (used) == NAMESPACE_DECL);
    /* Check if we already have this.  */
--- 3614,3634 ----
  	  *ptr = newval;
  	}
      }
!   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_1 (tree user, tree used, bool indirect)
  {
    tree t;
    /* Using oneself is a no-op.  */
    if (user == used)
!     return;
    gcc_assert (TREE_CODE (user) == NAMESPACE_DECL);
    gcc_assert (TREE_CODE (used) == NAMESPACE_DECL);
    /* Check if we already have this.  */
*************** add_using_namespace (tree user, tree use
*** 3528,3534 ****
        if (!indirect)
  	/* Promote to direct usage.  */
  	TREE_INDIRECT_USING (t) = 0;
-       timevar_pop (TV_NAME_LOOKUP);
        return;
      }
  
--- 3638,3643 ----
*************** add_using_namespace (tree user, tree use
*** 3546,3557 ****
    /* 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);
  
    /* 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);
  }
  
  /* Process a using-declaration not appearing in class or local scope.  */
--- 3655,3675 ----
    /* Recursively add all namespaces used.  */
    for (t = DECL_NAMESPACE_USING (used); t; t = TREE_CHAIN (t))
      /* indirect usage */
!     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_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.  */
*************** parse_using_directive (tree name_space, 
*** 3658,3670 ****
  static tree
  pushdecl_top_level_1 (tree x, tree *init, bool is_friend)
  {
!   timevar_push (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);
  }
  
  /* Like pushdecl, only it places X in the global scope if appropriate.  */
--- 3776,3789 ----
  static tree
  pushdecl_top_level_1 (tree x, tree *init, bool is_friend)
  {
!   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 ();
!   timevar_cond_stop (TV_NAME_LOOKUP, subtime);
!   return x;
  }
  
  /* Like pushdecl, only it places X in the global scope if appropriate.  */
*************** suggest_alternatives_for (location_t loc
*** 4000,4006 ****
     considering using-directives.  */
  
  static tree
! unqualified_namespace_lookup (tree name, int flags)
  {
    tree initial = current_decl_namespace ();
    tree scope = initial;
--- 4119,4125 ----
     considering using-directives.  */
  
  static tree
! unqualified_namespace_lookup_1 (tree name, int flags)
  {
    tree initial = current_decl_namespace ();
    tree scope = initial;
*************** unqualified_namespace_lookup (tree name,
*** 4008,4015 ****
    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;
--- 4127,4132 ----
*************** unqualified_namespace_lookup (tree name,
*** 4026,4032 ****
  	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);
  
        /* Add all _DECLs seen through global using-directives.  */
        /* XXX local and global using lists should work equally.  */
--- 4143,4149 ----
  	if (!lookup_using_namespace (name, &binding, level->using_directives,
  				     scope, flags))
  	  /* Give up because of error.  */
! 	  return error_mark_node;
  
        /* Add all _DECLs seen through global using-directives.  */
        /* XXX local and global using lists should work equally.  */
*************** unqualified_namespace_lookup (tree name,
*** 4037,4043 ****
  				       DECL_NAMESPACE_USING (siter),
  				       scope, flags))
  	    /* Give up because of error.  */
! 	    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
  	  if (siter == scope) break;
  	  siter = CP_DECL_CONTEXT (siter);
  	}
--- 4154,4160 ----
  				       DECL_NAMESPACE_USING (siter),
  				       scope, flags))
  	    /* Give up because of error.  */
! 	    return error_mark_node;
  	  if (siter == scope) break;
  	  siter = CP_DECL_CONTEXT (siter);
  	}
*************** unqualified_namespace_lookup (tree name,
*** 4046,4052 ****
        if (scope == global_namespace)
  	break;
      }
!   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
  }
  
  /* Look up NAME (an IDENTIFIER_NODE) in SCOPE (either a NAMESPACE_DECL
--- 4163,4181 ----
        if (scope == global_namespace)
  	break;
      }
!   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
*************** lookup_using_namespace (tree name, struc
*** 4096,4102 ****
  			tree usings, tree scope, int flags)
  {
    tree iter;
!   timevar_push (TV_NAME_LOOKUP);
    /* Iterate over all used namespaces in current, searching for using
       directives of scope.  */
    for (iter = usings; iter; iter = TREE_CHAIN (iter))
--- 4225,4231 ----
  			tree usings, tree scope, int flags)
  {
    tree iter;
!   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))
*************** lookup_using_namespace (tree name, struc
*** 4109,4115 ****
  	if (val1)
  	  ambiguous_decl (val, val1, flags);
        }
!   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val->value != error_mark_node);
  }
  
  /* Returns true iff VEC contains TARGET.  */
--- 4238,4245 ----
  	if (val1)
  	  ambiguous_decl (val, val1, flags);
        }
!   timevar_cond_stop (TV_NAME_LOOKUP, subtime);
!   return val->value != error_mark_node;
  }
  
  /* Returns true iff VEC contains TARGET.  */
*************** qualified_lookup_using_namespace (tree n
*** 4142,4148 ****
    VEC(tree,gc) *todo_maybe = NULL;
    VEC(tree,gc) *todo_inline = NULL;
    tree usings;
!   timevar_push (TV_NAME_LOOKUP);
    /* Look through namespace aliases.  */
    scope = ORIGINAL_NAMESPACE (scope);
  
--- 4272,4278 ----
    VEC(tree,gc) *todo_maybe = NULL;
    VEC(tree,gc) *todo_inline = NULL;
    tree usings;
!   timevar_start (TV_NAME_LOOKUP);
    /* Look through namespace aliases.  */
    scope = ORIGINAL_NAMESPACE (scope);
  
*************** qualified_lookup_using_namespace (tree n
*** 4201,4207 ****
    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);
  }
  
  /* Subroutine of outer_binding.
--- 4331,4338 ----
    VEC_free (tree,gc,todo_inline);
    VEC_free (tree,gc,seen);
    VEC_free (tree,gc,seen_inline);
!   timevar_stop (TV_NAME_LOOKUP);
!   return result->value != error_mark_node;
  }
  
  /* Subroutine of outer_binding.
*************** innermost_non_namespace_value (tree name
*** 4328,4341 ****
     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)
  {
    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.  */
--- 4459,4471 ----
     If NONCLASS is nonzero, bindings in class scopes are ignored.  If
     BLOCK_P is false, bindings in block scopes are ignored.  */
  
! 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;
  
    /* Conversion operators are handled specially because ordinary
       unqualified name lookup will not find template conversion
       operators.  */
*************** lookup_name_real (tree name, int prefer_
*** 4359,4368 ****
  	  class_type = level->this_entity;
  	  operators = lookup_fnfields (class_type, name, /*protect=*/0);
  	  if (operators)
! 	    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, operators);
  	}
  
!       POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
      }
  
    flags |= lookup_flags (prefer_type, namespaces_only);
--- 4489,4498 ----
  	  class_type = level->this_entity;
  	  operators = lookup_fnfields (class_type, name, /*protect=*/0);
  	  if (operators)
! 	    return operators;
  	}
  
!       return NULL_TREE;
      }
  
    flags |= lookup_flags (prefer_type, namespaces_only);
*************** lookup_name_real (tree name, int prefer_
*** 4457,4463 ****
    if (val && TREE_CODE (val) == OVERLOAD && !really_overloaded_fn (val))
      val = OVL_FUNCTION (val);
  
!   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
  }
  
  tree
--- 4587,4607 ----
    if (val && TREE_CODE (val) == OVERLOAD && !really_overloaded_fn (val))
      val = OVL_FUNCTION (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
*************** lookup_name_prefer_type (tree name, int 
*** 4504,4517 ****
     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)
  {
    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);
--- 4648,4659 ----
     A TYPE_DECL best matching the NAME is returned.  Catching error
     and issuing diagnostics are caller's responsibility.  */
  
! static tree
! lookup_type_scope_1 (tree name, tag_scope scope)
  {
    cxx_binding *iter = NULL;
    tree val = NULL_TREE;
  
    /* Look in non-namespace scope first.  */
    if (current_binding_level->kind != sk_namespace)
      iter = outer_binding (name, NULL, /*class_p=*/ true);
*************** lookup_type_scope (tree name, tag_scope 
*** 4566,4572 ****
        while (b)
  	{
  	  if (iter->scope == b)
! 	    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, val);
  
  	  if (b->kind == sk_cleanup || b->kind == sk_template_parms
  	      || b->kind == sk_function_parms)
--- 4708,4714 ----
        while (b)
  	{
  	  if (iter->scope == b)
! 	    return val;
  
  	  if (b->kind == sk_cleanup || b->kind == sk_template_parms
  	      || b->kind == sk_function_parms)
*************** lookup_type_scope (tree name, tag_scope 
*** 4579,4597 ****
  	}
      }
  
!   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, NULL_TREE);
  }
  
  /* Similar to `lookup_name' but look only in the innermost non-class
     binding level.  */
  
! tree
! lookup_name_innermost_nonclass_level (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)
--- 4721,4751 ----
  	}
      }
  
!   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.  */
  
! static tree
! lookup_name_innermost_nonclass_level_1 (tree name)
  {
    struct cp_binding_level *b;
    tree t = NULL_TREE;
  
    b = innermost_nonclass_level ();
  
    if (b->kind == sk_namespace)
*************** lookup_name_innermost_nonclass_level (tr
*** 4612,4618 ****
  	  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);
  
  	  if (b->kind == sk_cleanup)
  	    b = b->level_chain;
--- 4766,4772 ----
  	  if (binding->scope == b
  	      && !(TREE_CODE (binding->value) == VAR_DECL
  		   && DECL_DEAD_FOR_LOCAL (binding->value)))
! 	    return binding->value;
  
  	  if (b->kind == sk_cleanup)
  	    b = b->level_chain;
*************** lookup_name_innermost_nonclass_level (tr
*** 4621,4629 ****
  	}
      }
  
!   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
  }
  
  /* Returns true iff DECL is a block-scope extern declaration of a function
     or variable.  */
  
--- 4775,4796 ----
  	}
      }
  
!   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.  */
  
*************** lookup_type_current_level (tree name)
*** 4659,4665 ****
  {
    tree t = NULL_TREE;
  
!   timevar_push (TV_NAME_LOOKUP);
    gcc_assert (current_binding_level->kind != sk_namespace);
  
    if (REAL_IDENTIFIER_TYPE_VALUE (name) != NULL_TREE
--- 4826,4832 ----
  {
    tree t = NULL_TREE;
  
!   timevar_start (TV_NAME_LOOKUP);
    gcc_assert (current_binding_level->kind != sk_namespace);
  
    if (REAL_IDENTIFIER_TYPE_VALUE (name) != NULL_TREE
*************** lookup_type_current_level (tree name)
*** 4669,4676 ****
        while (1)
  	{
  	  if (purpose_member (name, b->type_shadowed))
! 	    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP,
! 				    REAL_IDENTIFIER_TYPE_VALUE (name));
  	  if (b->kind == sk_cleanup)
  	    b = b->level_chain;
  	  else
--- 4836,4845 ----
        while (1)
  	{
  	  if (purpose_member (name, b->type_shadowed))
! 	    {
! 	      t = REAL_IDENTIFIER_TYPE_VALUE (name);
! 	      break;
! 	    }
  	  if (b->kind == sk_cleanup)
  	    b = b->level_chain;
  	  else
*************** lookup_type_current_level (tree name)
*** 4678,4684 ****
  	}
      }
  
!   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, t);
  }
  
  /* [basic.lookup.koenig] */
--- 4847,4854 ----
  	}
      }
  
!   timevar_stop (TV_NAME_LOOKUP);
!   return t;
  }
  
  /* [basic.lookup.koenig] */
*************** arg_assoc (struct arg_lookup *k, tree n)
*** 5150,5163 ****
  /* 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)
  {
    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.  */
--- 5320,5331 ----
  /* Performs Koenig lookup depending on arguments, where fns
     are the functions found in normal lookup.  */
  
! static tree
! lookup_arg_dependent_1 (tree name, tree fns, VEC(tree,gc) *args,
! 			bool include_std)
  {
    struct arg_lookup k;
  
    /* Remove any hidden friend functions from the list of functions
       found so far.  They will be added back by arg_assoc_class as
       appropriate.  */
*************** lookup_arg_dependent (tree name, tree fn
*** 5193,5215 ****
    release_tree_vector (k.classes);
    release_tree_vector (k.namespaces);
      
!   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, fns);
  }
  
  /* 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)
  {
    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);
  
    ancestor = namespace_ancestor (current_decl_namespace (), used);
    ud = current_binding_level->using_directives;
--- 5361,5396 ----
    release_tree_vector (k.classes);
    release_tree_vector (k.namespaces);
      
!   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_1 (tree used)
  {
    tree ud = current_binding_level->using_directives;
    tree iter, ancestor;
  
    /* Check if we already have this.  */
    if (purpose_member (used, ud) != NULL_TREE)
!     return NULL_TREE;
  
    ancestor = namespace_ancestor (current_decl_namespace (), used);
    ud = current_binding_level->using_directives;
*************** push_using_directive (tree used)
*** 5220,5226 ****
    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);
  }
  
  /* The type TYPE is being declared.  If it is a class template, or a
--- 5401,5419 ----
    for (iter = DECL_NAMESPACE_USING (used); iter; iter = TREE_CHAIN (iter))
      push_using_directive (TREE_PURPOSE (iter));
  
!   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
*************** maybe_process_template_type_declaration 
*** 5313,5325 ****
  
     Returns TYPE upon success and ERROR_MARK_NODE otherwise.  */
  
! tree
! pushtag (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.  */
--- 5506,5517 ----
  
     Returns TYPE upon success and ERROR_MARK_NODE otherwise.  */
  
! static tree
! pushtag_1 (tree name, tree type, tag_scope scope)
  {
    struct cp_binding_level *b;
    tree decl;
  
    b = current_binding_level;
    while (/* Cleanup scopes are not scopes from the point of view of
  	    the language.  */
*************** pushtag (tree name, tree type, tag_scope
*** 5344,5350 ****
    gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
  
    /* Do C++ gratuitous typedefing.  */
!   if (IDENTIFIER_TYPE_VALUE (name) != type)
      {
        tree tdef;
        int in_class = 0;
--- 5536,5542 ----
    gcc_assert (TREE_CODE (name) == IDENTIFIER_NODE);
  
    /* Do C++ gratuitous typedefing.  */
!   if (identifier_type_value_1 (name) != type)
      {
        tree tdef;
        int in_class = 0;
*************** pushtag (tree name, tree type, tag_scope
*** 5390,5401 ****
        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);
  
        if (b->kind == sk_class)
  	{
  	  if (!TYPE_BEING_DEFINED (current_class_type))
! 	    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, error_mark_node);
  
  	  if (!PROCESSING_REAL_TEMPLATE_DECL_P ())
  	    /* Put this TYPE_DECL on the TYPE_FIELDS list for the
--- 5582,5593 ----
        decl = maybe_process_template_type_declaration
  	(type, scope == ts_within_enclosing_non_class, b);
        if (decl == error_mark_node)
! 	return decl;
  
        if (b->kind == sk_class)
  	{
  	  if (!TYPE_BEING_DEFINED (current_class_type))
! 	    return error_mark_node;
  
  	  if (!PROCESSING_REAL_TEMPLATE_DECL_P ())
  	    /* Put this TYPE_DECL on the TYPE_FIELDS list for the
*************** pushtag (tree name, tree type, tag_scope
*** 5408,5416 ****
  	}
        else if (b->kind != sk_template_parms)
  	{
! 	  decl = pushdecl_with_scope (decl, b, /*is_friend=*/false);
  	  if (decl == error_mark_node)
! 	    POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, decl);
  	}
  
        if (! in_class)
--- 5600,5608 ----
  	}
        else if (b->kind != sk_template_parms)
  	{
! 	  decl = pushdecl_with_scope_1 (decl, b, /*is_friend=*/false);
  	  if (decl == error_mark_node)
! 	    return decl;
  	}
  
        if (! in_class)
*************** pushtag (tree name, tree type, tag_scope
*** 5449,5455 ****
    TREE_PUBLIC (decl) = 1;
    determine_visibility (decl);
  
!   POP_TIMEVAR_AND_RETURN (TV_NAME_LOOKUP, type);
  }
  
  /* Subroutines for reverting temporarily to top-level for instantiation
--- 5641,5659 ----
    TREE_PUBLIC (decl) = 1;
    determine_visibility (decl);
  
!   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
*************** store_bindings (tree names, VEC(cxx_save
*** 5487,5493 ****
  {
    tree t;
  
!   timevar_push (TV_NAME_LOOKUP);
    for (t = names; t; t = TREE_CHAIN (t))
      {
        tree id;
--- 5691,5697 ----
  {
    tree t;
  
!   bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
    for (t = names; t; t = TREE_CHAIN (t))
      {
        tree id;
*************** store_bindings (tree names, VEC(cxx_save
*** 5499,5505 ****
  
        store_binding (id, old_bindings);
      }
!   timevar_pop (TV_NAME_LOOKUP);
  }
  
  /* Like store_bindings, but NAMES is a vector of cp_class_binding
--- 5703,5709 ----
  
        store_binding (id, old_bindings);
      }
!   timevar_cond_stop (TV_NAME_LOOKUP, subtime);
  }
  
  /* Like store_bindings, but NAMES is a vector of cp_class_binding
*************** store_class_bindings (VEC(cp_class_bindi
*** 5512,5521 ****
    size_t i;
    cp_class_binding *cb;
  
!   timevar_push (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);
  }
  
  void
--- 5716,5725 ----
    size_t i;
    cp_class_binding *cb;
  
!   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_cond_stop (TV_NAME_LOOKUP, subtime);
  }
  
  void
*************** push_to_top_level (void)
*** 5527,5533 ****
    size_t i;
    bool need_pop;
  
!   timevar_push (TV_NAME_LOOKUP);
    s = ggc_alloc_cleared_saved_scope ();
  
    b = scope_chain ? current_binding_level : 0;
--- 5731,5737 ----
    size_t i;
    bool need_pop;
  
!   bool subtime = timevar_cond_start (TV_NAME_LOOKUP);
    s = ggc_alloc_cleared_saved_scope ();
  
    b = scope_chain ? current_binding_level : 0;
*************** push_to_top_level (void)
*** 5587,5603 ****
    push_class_stack ();
    cp_unevaluated_operand = 0;
    c_inhibit_evaluation_warnings = 0;
!   timevar_pop (TV_NAME_LOOKUP);
  }
  
! void
! pop_from_top_level (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 ();
--- 5791,5806 ----
    push_class_stack ();
    cp_unevaluated_operand = 0;
    c_inhibit_evaluation_warnings = 0;
!   timevar_cond_stop (TV_NAME_LOOKUP, subtime);
  }
  
! static void
! pop_from_top_level_1 (void)
  {
    struct saved_scope *s = scope_chain;
    cxx_saved_binding *saved;
    size_t i;
  
    /* Clear out class-level bindings cache.  */
    if (previous_class_level)
      invalidate_class_lookup_cache ();
*************** pop_from_top_level (void)
*** 5621,5629 ****
    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);
  }
  
  /* Pop off extraneous binding levels left over due to syntax errors.
  
     We don't pop past namespaces, as they might be valid.  */
--- 5824,5842 ----
    current_function_decl = s->function_decl;
    cp_unevaluated_operand = s->unevaluated_operand;
    c_inhibit_evaluation_warnings = s->inhibit_evaluation_warnings;
  }
  
+ /* 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 172275)
--- gcc/timevar.def	(working copy)
***************
*** 33,41 ****
  
  /* The total execution time.  */
  DEFTIMEVAR (TV_TOTAL                 , "total time")
  
  /* Time spent garbage-collecting.  */
! DEFTIMEVAR (TV_GC                    , "garbage collection")
  
  /* Time spent generating dump files.  */
  DEFTIMEVAR (TV_DUMP                  , "dump files")
--- 33,50 ----
  
  /* The total execution time.  */
  DEFTIMEVAR (TV_TOTAL                 , "total time")
+ DEFTIMEVAR (TV_PHASE_SETUP           , "phase setup")
+ DEFTIMEVAR (TV_PHASE_PARSING         , "phase parsing")
+ DEFTIMEVAR (TV_PHASE_C_WRAPUP_CHECK  , "phase C wrapup & check")
+ DEFTIMEVAR (TV_PHASE_CP_DEFERRED     , "phase C++ 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")
  
  /* Time spent garbage-collecting.  */
! DEFTIMEVAR (TV_GC                    , "|garbage collection")
  
  /* Time spent generating dump files.  */
  DEFTIMEVAR (TV_DUMP                  , "dump files")
*************** DEFTIMEVAR (TV_REBUILD_JUMP	     , "rebu
*** 102,109 ****
  /* 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_INLINE_HEURISTICS     , "inline heuristics")
  DEFTIMEVAR (TV_INTEGRATION           , "integration")
  DEFTIMEVAR (TV_TREE_GIMPLIFY	     , "tree gimplify")
--- 111,124 ----
  /* Timing in various stages of the compiler.  */
  DEFTIMEVAR (TV_CPP		     , "preprocessing")
  DEFTIMEVAR (TV_LEX		     , "lexical analysis")
! 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_INMETH          , "parser inl. meth. body")
! DEFTIMEVAR (TV_INSTANTIATE_TEMPLATE  , "instantiate template")
! DEFTIMEVAR (TV_NAME_LOOKUP           , "|name lookup")
! DEFTIMEVAR (TV_RESOLVE_OVERLOAD      , "|overload resolution")
  DEFTIMEVAR (TV_INLINE_HEURISTICS     , "inline heuristics")
  DEFTIMEVAR (TV_INTEGRATION           , "integration")
  DEFTIMEVAR (TV_TREE_GIMPLIFY	     , "tree gimplify")
*************** DEFTIMEVAR (TV_CGRAPH_VERIFY         , "
*** 170,177 ****
  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")
--- 185,190 ----
Index: gcc/timevar.c
===================================================================
*** gcc/timevar.c	(revision 172275)
--- gcc/timevar.c	(working copy)
*************** timevar_stop (timevar_id_t timevar)
*** 361,366 ****
--- 361,419 ----
  
    /* 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);
Index: gcc/timevar.h
===================================================================
*** gcc/timevar.h	(revision 172275)
--- gcc/timevar.h	(working copy)
*************** extern bool timevar_enable;
*** 87,100 ****
  /* 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 void timevar_print (FILE *);
  
  /* Provided for backward compatibility.  */
--- 87,99 ----
  /* Total amount of memory allocated by garbage collector.  */
  extern size_t timevar_ggc_mem_total;
  
  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 172275)
--- gcc/c-decl.c	(working copy)
*************** c_write_global_declarations (void)
*** 9833,9838 ****
--- 9833,9840 ----
    if (pch_file)
      return;
  
+   timevar_start (TV_PHASE_C_WRAPUP_CHECK);
+ 
    /* 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 (void)
*** 9874,9883 ****
--- 9876,9891 ----
      c_write_global_declarations_1 (BLOCK_VARS (DECL_INITIAL (t)));
    c_write_global_declarations_1 (BLOCK_VARS (ext_block));
  
+   timevar_stop (TV_PHASE_C_WRAPUP_CHECK);
+   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 ())
*************** c_write_global_declarations (void)
*** 9890,9895 ****
--- 9898,9904 ----
      }
  
    ext_block = NULL;
+   timevar_stop (TV_PHASE_DBGINFO);
  }
  
  /* Register reserved keyword WORD as qualifier for address space AS.  */
Index: gcc/ggc-zone.c
===================================================================
*** gcc/ggc-zone.c	(revision 172275)
--- gcc/ggc-zone.c	(working copy)
*************** ggc_collect (void)
*** 1984,1990 ****
    struct alloc_zone *zone;
    bool marked = false;
  
!   timevar_push (TV_GC);
  
    if (!ggc_force_collect)
      {
--- 1984,1990 ----
    struct alloc_zone *zone;
    bool marked = false;
  
!   timevar_start (TV_GC);
  
    if (!ggc_force_collect)
      {
*************** ggc_collect (void)
*** 2003,2009 ****
  
        if (allocated < allocated_last_gc + min_expand)
  	{
! 	  timevar_pop (TV_GC);
  	  return;
  	}
      }
--- 2003,2009 ----
  
        if (allocated < allocated_last_gc + min_expand)
  	{
! 	  timevar_stop (TV_GC);
  	  return;
  	}
      }
*************** ggc_collect (void)
*** 2076,2082 ****
  
    invoke_plugin_callbacks (PLUGIN_GGC_END, NULL);
  
!   timevar_pop (TV_GC);
  }
  
  /* Print allocation statistics.  */
--- 2076,2082 ----
  
    invoke_plugin_callbacks (PLUGIN_GGC_END, NULL);
  
!   timevar_stop (TV_GC);
  }
  
  /* Print allocation statistics.  */
Index: gcc/ggc-page.c
===================================================================
*** gcc/ggc-page.c	(revision 172275)
--- gcc/ggc-page.c	(working copy)
*************** ggc_collect (void)
*** 1911,1917 ****
    if (G.allocated < allocated_last_gc + min_expand && !ggc_force_collect)
      return;
  
!   timevar_push (TV_GC);
    if (!quiet_flag)
      fprintf (stderr, " {GC %luk -> ", (unsigned long) G.allocated / 1024);
    if (GGC_DEBUG_LEVEL >= 2)
--- 1911,1917 ----
    if (G.allocated < allocated_last_gc + min_expand && !ggc_force_collect)
      return;
  
!   timevar_start (TV_GC);
    if (!quiet_flag)
      fprintf (stderr, " {GC %luk -> ", (unsigned long) G.allocated / 1024);
    if (GGC_DEBUG_LEVEL >= 2)
*************** ggc_collect (void)
*** 1943,1949 ****
  
    invoke_plugin_callbacks (PLUGIN_GGC_END, NULL);
  
!   timevar_pop (TV_GC);
  
    if (!quiet_flag)
      fprintf (stderr, "%luk}", (unsigned long) G.allocated / 1024);
--- 1943,1949 ----
  
    invoke_plugin_callbacks (PLUGIN_GGC_END, NULL);
  
!   timevar_stop (TV_GC);
  
    if (!quiet_flag)
      fprintf (stderr, "%luk}", (unsigned long) G.allocated / 1024);
Index: gcc/c-parser.c
===================================================================
*** gcc/c-parser.c	(revision 172275)
--- gcc/c-parser.c	(working copy)
*************** c_parser_declaration_or_fndef (c_parser 
*** 1684,1689 ****
--- 1684,1690 ----
  	  return;
  	}
        /* Function definition (nested or otherwise).  */
+       timevar_push (TV_PARSE_FUNC);
        if (nested)
  	{
  	  pedwarn (here, OPT_pedantic, "ISO C forbids nested functions");
*************** c_parser_declaration_or_fndef (c_parser 
*** 1738,1743 ****
--- 1739,1745 ----
  	  add_stmt (fnbody);
  	  finish_function ();
  	}
+       timevar_pop (TV_PARSE_FUNC);
        break;
      }
  }
*************** c_parser_enum_specifier (c_parser *parse
*** 2190,2200 ****
      {
        /* Parse an enum definition.  */
        struct c_enum_contents the_enum;
!       tree type = start_enum (enum_loc, &the_enum, ident);
        tree postfix_attrs;
        /* We chain the enumerators in reverse order, then put them in
  	 forward order at the end.  */
!       tree values = NULL_TREE;
        c_parser_consume_token (parser);
        while (true)
  	{
--- 2192,2205 ----
      {
        /* Parse an enum definition.  */
        struct c_enum_contents the_enum;
!       tree type;
        tree postfix_attrs;
        /* We chain the enumerators in reverse order, then put them in
  	 forward order at the end.  */
!       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)
  	{
*************** c_parser_enum_specifier (c_parser *parse
*** 2258,2263 ****
--- 2263,2269 ----
        ret.kind = ctsk_tagdef;
        ret.expr = NULL_TREE;
        ret.expr_const_operands = true;
+       timevar_pop (TV_PARSE_ENUM);
        return ret;
      }
    else if (!ident)
*************** c_parser_struct_or_union_specifier (c_pa
*** 2371,2377 ****
  	 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;
        c_parser_consume_token (parser);
        /* Handle the Objective-C @defs construct,
  	 e.g. foo(sizeof(struct{ @defs(ClassName) }));.  */
--- 2377,2385 ----
  	 semicolon separated fields than comma separated fields, and
  	 so we'll be minimizing the number of node traversals required
  	 by chainon.  */
!       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) }));.  */
*************** c_parser_struct_or_union_specifier (c_pa
*** 2458,2463 ****
--- 2466,2472 ----
        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/4378056


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]