Hi, I've always found it silly that in order to change the current function one has to call push_cfun and pop_cfun which conveniently set and restore the value of cfun and in addition to that also set current_function_decl and usually also cache its old value to restore it back afterwards. I also think that, at least throughout the middle-end, we should strive to have current_function_decl consistent with cfun->decl. There are quite a few places where we are not consistent and I think such situations are prone to nasty surprises as various functions rely on cfun and others on current_function_decl and it's easy to be unaware that one of the two is incorrect at the moment.
This week I have therefore decided to try and make push_cfun, pop_cfun and push_struct_function also set the current_function_decl. Being afraid of opening a giant can of worms I only a mid-sized hole and left various set_cfuns for later as well as places where we set current_function_decl without bothering with cfun. After a few debugging sessions I came up with the patch below. The changes are mostly mechanical, let me try and explain some of the difficult or not-quite-nice ones, most of which come from calls from front-ends which generally do not care about cfun all that much. - In order to ensure that pop_cfun will reliable restore the old current_function_decl, push_cfun asserts that cfun and current_function_decl match. pop_cfun then simply restores current_function_decl to new_cfun->decl or NULL_TREE if new_cfun is NULL. To check that the two remain consistent, pop_cfun has a similar (albeit checking) assert. - I had to allow push_cfun(NULL) because in gfc_get_extern_function_decl in fortran/trans-decl.c we momentarily emulate top-level context by doing: current_function_decl = NULL_TREE; push_cfun (cfun); do_something () pop_cfun (); current_function_decl = save_fn_decl; and to keep current_function_decl consistent with cfun, cfun had to be made NULL too. Co I converted the above to push_cfun (NULL) which also sets current_function_decl to NULL_TREE. - I also had to allow push_cfun(NULL) because dwarf2out_abstract_function does just that, just it looks like: push_cfun (DECL_STRUCT_FUNCTION (decl)); but DECL_STRUCT_FUNCTION is usually (always?) NULL for abstract origin functions. But this also means that changed push_cfun sets current_function_decl to NULL, which means the abstract function is not dwarf2outed as it should be. Thus, in perhaps the most awful thunk in this patch I re-set current_function_decl after calling push_cfun. If someone has a better idea how to deal with this, I'm certainly interested. For the same reason I do not assert that current_function matches cfun->decl in pop_cfun if cfun is NULL. - each cfun change also triggers a pair of init_dummy_function_start and expand_dummy_function_end which invoke push_struct_function and pop_cfun respectively. Because we may be in the middle of another push/pop_cfun, the current_function_decl may not match and so the asserts are disabled in these cases, fortunately we can recognize them by looking at value of in_dummy_function. - ada/gcc-interface/utils.c:rest_of_subprog_body_compilation calls dump_function which in turns calls dump_function_to_file which calls push_cfun. But Ada front end has its idea of the current_function_decl and there is no cfun which is an inconsistency which makes push_cfun assert fail. I "solved" it by temporarily setting current_function_decl to NULL_TREE. It's just dumping and I thought that dump_function should be considered middle-end and thus middle-end invariants should apply. The patch passes bootstrap and testing on x86_64-linux (all languages + ada + obj-c++) and ia64-linux (c,c++,fortran,objc,obj-c++). There is some confusing jitter in the go testing results which I have not yet looked at (perhaps compare_tests just can't deal with it, there are tests reported both as newly failing and newly working etc...) but I thought that I'd send the patch now anyway to get some feedback in case I was doing something else wrong (I also do not know whether anyone but Ian can modify the go front-end). I have also LTO-built Mozilla Firefox with the patch. Well, what do you think? Martin 2012-08-08 Martin Jambor <mjam...@suse.cz> * function.c (push_cfun): Check old current_function_decl matches old cfun, set new current_function_decl to the decl of the new cfun. (push_struct_function): Likewise. (pop_cfun): Likewise. (allocate_struct_function): Move call to invoke_set_current_function_hook to the end of the function. * cfgexpand.c (estimated_stack_frame_size): Do not set and restore current_function_decl. * cgraph.c (cgraph_release_function_body): Likewise. * cgraphunit.c (cgraph_process_new_functions): Likewise. (cgraph_add_new_function): Likewise. (cgraph_analyze_function): Likewise. (assemble_thunk): Set cfun to NULL at the end. (expand_function): Move call to set_cfun downwards. * dwarf2out.c (dwarf2out_abstract_function): Do not restore current_function_decl. * gimple-low.c (record_vars_into): Only check current_function_decl before possibly doing push_cfun. * gimplify.c (gimplify_function_tree): Do not set and restore current_function_decl. * ipa-inline-analysis.c (compute_inline_parameters): Likewise. (inline_analyze_function): Likewise. * ipa-prop.c (ipa_analyze_node): Likewise. * ipa-pure-const.c (analyze_function): Likewise. * lto-streamer-in.c (lto_input_function_body): Do not set current_function_decl. * lto-streamer-out.c (output_function): Do not set and restore current_function_decl. * matrix-reorg.c (transform_allocation_sites): Likewise, also use push/pop_cfun instead of set_cfun. (matrix_reorg): Do not set and restore current_function_decl. * omp-low.c (finalize_task_copyfn): Likewise. (expand_omp_taskreg): Likewise. (create_task_copyfn): Likewise, move push_cfun up quite a bit. * passes.c (dump_passes): Do not set and restore current_function_decl. (do_per_function): Likewise. (do_per_function_toporder): Likewise. * trans-mem.c (ipa_tm_scan_irr_function): Likewise. (ipa_tm_transform_transaction): Likewise. (ipa_tm_transform_clone): Likewise. (ipa_tm_execute): Likewise. * tree-emutls.c (lower_emutls_function_body): Likewise. * tree-inline.c (initialize_cfun): Do not call pop_cfun. (tree_function_versioning): Do not call push_cfun, do not set and restore current_function_decl. Remove assert checking consistency of cfun and current_function_decl. * tree-profile.c (tree_profiling): Do not set and restore current_function_decl. * tree-sra.c (convert_callers_for_node): Do not set current_function_decl. (convert_callers): Do not restore current_function_decl. (modify_function): Do not set current_function_decl. * tree-ssa-structalias.c (ipa_pta_execute): Do not set and restore current_function_decl. * fortran/trans-decl.c (gfc_get_extern_function_decl): Do not set and restore current_function_decl, push NULL cfun. (gfc_init_coarray_decl): Do not set and restore current_function_decl. * go/gofrontend/gogo-tree.cc (write_initialization_function): Do not set and restore current_function_decl. (write_globals): Likewise. (get_tree): Likewise. * lto/lto.c (lto_materialize_function): Call push_struct_function instead of allocate_struct_function and also call pop_cfun. * ada/gcc-interface/utils.c (rest_of_subprog_body_compilation): Set current_function_decl to NULL before calling dump_function and then restore it. *** /tmp/KDyIva_utils.c Thu Aug 9 15:21:47 2012 --- gcc/ada/gcc-interface/utils.c Thu Aug 9 13:44:00 2012 *************** end_subprog_body (tree body) *** 2740,2746 **** void rest_of_subprog_body_compilation (tree subprog_decl) { ! /* We cannot track the location of errors past this point. */ error_gnat_node = Empty; /* If we're only annotating types, don't actually compile this function. */ --- 2740,2748 ---- void rest_of_subprog_body_compilation (tree subprog_decl) { ! tree saved_current_function_decl = current_function_decl; ! ! /* We cannot track the location of errors past this point. */ error_gnat_node = Empty; /* If we're only annotating types, don't actually compile this function. */ *************** rest_of_subprog_body_compilation (tree s *** 2748,2754 **** --- 2750,2758 ---- return; /* Dump functions before gimplification. */ + current_function_decl = NULL_TREE; dump_function (TDI_original, subprog_decl); + current_function_decl = saved_current_function_decl; if (!decl_function_context (subprog_decl)) cgraph_finalize_function (subprog_decl, false); *** /tmp/wurZNc_cfgexpand.c Thu Aug 9 15:21:47 2012 --- gcc/cfgexpand.c Tue Aug 7 13:15:12 2012 *************** estimated_stack_frame_size (struct cgrap *** 1422,1433 **** HOST_WIDE_INT size = 0; size_t i; tree var; - tree old_cur_fun_decl = current_function_decl; struct function *fn = DECL_STRUCT_FUNCTION (node->symbol.decl); - current_function_decl = node->symbol.decl; push_cfun (fn); - FOR_EACH_LOCAL_DECL (fn, i, var) if (auto_var_in_fn_p (var, fn->decl)) size += expand_one_var (var, true, false); --- 1422,1430 ---- *************** estimated_stack_frame_size (struct cgrap *** 1442,1448 **** fini_vars_expansion (); } pop_cfun (); - current_function_decl = old_cur_fun_decl; return size; } --- 1439,1444 ---- *** /tmp/8XER7b_cgraph.c Thu Aug 9 15:21:47 2012 --- gcc/cgraph.c Tue Aug 7 13:17:24 2012 *************** cgraph_release_function_body (struct cgr *** 1128,1134 **** { if (DECL_STRUCT_FUNCTION (node->symbol.decl)) { - tree old_decl = current_function_decl; push_cfun (DECL_STRUCT_FUNCTION (node->symbol.decl)); if (cfun->cfg && current_loops) --- 1128,1133 ---- *************** cgraph_release_function_body (struct cgr *** 1138,1148 **** } if (cfun->gimple_df) { - current_function_decl = node->symbol.decl; delete_tree_ssa (); delete_tree_cfg_annotations (); cfun->eh = NULL; - current_function_decl = old_decl; } if (cfun->cfg) { --- 1137,1145 ---- *** /tmp/WL9Mge_cgraphunit.c Thu Aug 9 15:21:47 2012 --- gcc/cgraphunit.c Wed Aug 8 15:54:56 2012 *************** cgraph_process_new_functions (void) *** 313,319 **** if (!node->analyzed) cgraph_analyze_function (node); push_cfun (DECL_STRUCT_FUNCTION (fndecl)); - current_function_decl = fndecl; if ((cgraph_state == CGRAPH_STATE_IPA_SSA && !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl))) /* When not optimizing, be sure we run early local passes anyway --- 313,318 ---- *************** cgraph_process_new_functions (void) *** 325,331 **** free_dominance_info (CDI_POST_DOMINATORS); free_dominance_info (CDI_DOMINATORS); pop_cfun (); - current_function_decl = NULL; cgraph_call_function_insertion_hooks (node); break; --- 324,329 ---- *************** cgraph_add_new_function (tree fndecl, bo *** 495,508 **** if (!lowered && cgraph_state == CGRAPH_STATE_EXPANSION) { push_cfun (DECL_STRUCT_FUNCTION (fndecl)); - current_function_decl = fndecl; gimple_register_cfg_hooks (); bitmap_obstack_initialize (NULL); execute_pass_list (all_lowering_passes); execute_pass_list (pass_early_local_passes.pass.sub); bitmap_obstack_release (NULL); pop_cfun (); - current_function_decl = NULL; lowered = true; } --- 493,504 ---- *************** cgraph_add_new_function (tree fndecl, bo *** 521,527 **** node->lowered = true; cgraph_analyze_function (node); push_cfun (DECL_STRUCT_FUNCTION (fndecl)); - current_function_decl = fndecl; gimple_register_cfg_hooks (); bitmap_obstack_initialize (NULL); if (!gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl))) --- 517,522 ---- *************** cgraph_add_new_function (tree fndecl, bo *** 529,535 **** bitmap_obstack_release (NULL); pop_cfun (); expand_function (node); - current_function_decl = NULL; break; default: --- 524,529 ---- *************** fixup_same_cpp_alias_visibility (symtab_ *** 597,603 **** static void cgraph_analyze_function (struct cgraph_node *node) { - tree save = current_function_decl; tree decl = node->symbol.decl; location_t saved_loc = input_location; input_location = DECL_SOURCE_LOCATION (decl); --- 591,596 ---- *************** cgraph_analyze_function (struct cgraph_n *** 638,644 **** } else { - current_function_decl = decl; push_cfun (DECL_STRUCT_FUNCTION (decl)); assign_assembler_name_if_neeeded (node->symbol.decl); --- 631,636 ---- *************** cgraph_analyze_function (struct cgraph_n *** 672,678 **** } node->analyzed = true; - current_function_decl = save; input_location = saved_loc; } --- 664,669 ---- *************** assemble_thunk (struct cgraph_node *node *** 1520,1525 **** --- 1511,1517 ---- bitmap_obstack_release (NULL); } current_function_decl = NULL; + set_cfun (NULL); } *************** expand_function (struct cgraph_node *nod *** 1612,1619 **** /* Release the default bitmap obstack. */ bitmap_obstack_release (NULL); - set_cfun (NULL); - /* If requested, warn about function definitions where the function will return a value (usually of some struct or union type) which itself will take up a lot of stack space. */ --- 1604,1609 ---- *************** expand_function (struct cgraph_node *nod *** 1658,1663 **** --- 1648,1654 ---- /* Make sure that BE didn't give up on compiling. */ gcc_assert (TREE_ASM_WRITTEN (decl)); + set_cfun (NULL); current_function_decl = NULL; /* It would make a lot more sense to output thunks before function body to get more *** /tmp/edrpua_dwarf2out.c Thu Aug 9 15:21:47 2012 --- gcc/dwarf2out.c Wed Aug 8 18:12:07 2012 *************** static void *** 16673,16679 **** dwarf2out_abstract_function (tree decl) { dw_die_ref old_die; - tree save_fn; tree context; int was_abstract; htab_t old_decl_loc_table; --- 16673,16678 ---- *************** dwarf2out_abstract_function (tree decl) *** 16714,16736 **** } /* Pretend we've just finished compiling this function. */ - save_fn = current_function_decl; - current_function_decl = decl; push_cfun (DECL_STRUCT_FUNCTION (decl)); ! was_abstract = DECL_ABSTRACT (decl); set_decl_abstract_flags (decl, 1); dwarf2out_decl (decl); if (! was_abstract) set_decl_abstract_flags (decl, 0); ! current_function_decl = save_fn; decl_loc_table = old_decl_loc_table; cached_dw_loc_list_table = old_cached_dw_loc_list_table; call_arg_locations = old_call_arg_locations; call_site_count = old_call_site_count; tail_call_site_count = old_tail_call_site_count; - pop_cfun (); } /* Helper function of premark_used_types() which gets called through --- 16713,16735 ---- } /* Pretend we've just finished compiling this function. */ push_cfun (DECL_STRUCT_FUNCTION (decl)); ! /* DECL_STRUCT_FUNCTION can be NULL and in that case push_cfun has set ! current_function_decl to NULL which is not what we want. Re-set it ! again. */ ! current_function_decl = decl; was_abstract = DECL_ABSTRACT (decl); set_decl_abstract_flags (decl, 1); dwarf2out_decl (decl); if (! was_abstract) set_decl_abstract_flags (decl, 0); ! pop_cfun (); decl_loc_table = old_decl_loc_table; cached_dw_loc_list_table = old_cached_dw_loc_list_table; call_arg_locations = old_call_arg_locations; call_site_count = old_call_site_count; tail_call_site_count = old_tail_call_site_count; } /* Helper function of premark_used_types() which gets called through *** /tmp/yrx7vc_trans-decl.c Thu Aug 9 15:21:47 2012 --- gcc/fortran/trans-decl.c Tue Aug 7 16:02:30 2012 *************** gfc_get_extern_function_decl (gfc_symbol *** 1624,1640 **** /* By construction, the external function cannot be a contained procedure. */ locus old_loc; - tree save_fn_decl = current_function_decl; - current_function_decl = NULL_TREE; gfc_save_backend_locus (&old_loc); ! push_cfun (cfun); gfc_create_function_decl (gsym->ns, true); pop_cfun (); gfc_restore_backend_locus (&old_loc); - current_function_decl = save_fn_decl; } /* If the namespace has entries, the proc_name is the --- 1624,1637 ---- /* By construction, the external function cannot be a contained procedure. */ locus old_loc; gfc_save_backend_locus (&old_loc); ! push_cfun (NULL); gfc_create_function_decl (gsym->ns, true); pop_cfun (); gfc_restore_backend_locus (&old_loc); } /* If the namespace has entries, the proc_name is the *************** add_argument_checking (stmtblock_t *bloc *** 4849,4864 **** void gfc_init_coarray_decl (bool main_tu) { - tree save_fn_decl; - if (gfc_option.coarray != GFC_FCOARRAY_LIB) return; if (gfort_gvar_caf_this_image || gfort_gvar_caf_num_images) return; - save_fn_decl = current_function_decl; - current_function_decl = NULL_TREE; push_cfun (cfun); gfort_gvar_caf_this_image --- 4846,4857 ---- *************** gfc_init_coarray_decl (bool main_tu) *** 4894,4900 **** pushdecl_top_level (gfort_gvar_caf_num_images); pop_cfun (); - current_function_decl = save_fn_decl; } --- 4887,4892 ---- *** /tmp/ccrTha_function.c Thu Aug 9 15:21:47 2012 --- gcc/function.c Wed Aug 8 18:06:40 2012 *************** set_cfun (struct function *new_cfun) *** 4413,4434 **** static VEC(function_p,heap) *cfun_stack; ! /* Push the current cfun onto the stack, and set cfun to new_cfun. */ void push_cfun (struct function *new_cfun) { VEC_safe_push (function_p, heap, cfun_stack, cfun); set_cfun (new_cfun); } ! /* Pop cfun from the stack. */ void pop_cfun (void) { struct function *new_cfun = VEC_pop (function_p, cfun_stack); set_cfun (new_cfun); } /* Return value of funcdef and increase it. */ --- 4413,4445 ---- static VEC(function_p,heap) *cfun_stack; ! /* Push the current cfun onto the stack, and set cfun to new_cfun. Also set ! current_function_decl accordingly. */ void push_cfun (struct function *new_cfun) { + gcc_assert ((!cfun && !current_function_decl) + || (cfun && current_function_decl == cfun->decl)); VEC_safe_push (function_p, heap, cfun_stack, cfun); + current_function_decl = new_cfun ? new_cfun->decl : NULL_TREE; set_cfun (new_cfun); } ! /* Pop cfun from the stack. Also set current_function_decl accordingly. */ void pop_cfun (void) { struct function *new_cfun = VEC_pop (function_p, cfun_stack); + /* When in_dummy_function, we do have a cfun but current_function_decl is + NULL. OTOH, dwarf2out can push a function of an abstract origin decl + which is NULL but needs non-null current_function_decl. */ + gcc_checking_assert (in_dummy_function + || !cfun + || current_function_decl == cfun->decl); set_cfun (new_cfun); + current_function_decl = new_cfun ? new_cfun->decl : NULL_TREE; } /* Return value of funcdef and increase it. */ *************** allocate_struct_function (tree fndecl, b *** 4475,4482 **** OVERRIDE_ABI_FORMAT (fndecl); #endif - invoke_set_current_function_hook (fndecl); - if (fndecl != NULL_TREE) { DECL_STRUCT_FUNCTION (fndecl) = cfun; --- 4486,4491 ---- *************** allocate_struct_function (tree fndecl, b *** 4502,4507 **** --- 4511,4518 ---- but is this worth the hassle? */ cfun->can_throw_non_call_exceptions = flag_non_call_exceptions; } + + invoke_set_current_function_hook (fndecl); } /* This is like allocate_struct_function, but pushes a new cfun for FNDECL *************** allocate_struct_function (tree fndecl, b *** 4510,4516 **** --- 4521,4533 ---- void push_struct_function (tree fndecl) { + /* When in_dummy_function we might be in the middle of a pop_cfun and + current_function_decl and cfun may not match. */ + gcc_assert (in_dummy_function + || (!cfun && !current_function_decl) + || (cfun && current_function_decl == cfun->decl)); VEC_safe_push (function_p, heap, cfun_stack, cfun); + current_function_decl = fndecl; allocate_struct_function (fndecl, false); } *** /tmp/apOtwc_gimple-low.c Thu Aug 9 15:21:47 2012 --- gcc/gimple-low.c Tue Aug 7 13:31:20 2012 *************** lower_builtin_setjmp (gimple_stmt_iterat *** 991,997 **** void record_vars_into (tree vars, tree fn) { ! if (fn != current_function_decl) push_cfun (DECL_STRUCT_FUNCTION (fn)); for (; vars; vars = DECL_CHAIN (vars)) --- 991,999 ---- void record_vars_into (tree vars, tree fn) { ! bool change_cfun = fn != current_function_decl; ! ! if (change_cfun) push_cfun (DECL_STRUCT_FUNCTION (fn)); for (; vars; vars = DECL_CHAIN (vars)) *************** record_vars_into (tree vars, tree fn) *** 1011,1017 **** add_local_decl (cfun, var); } ! if (fn != current_function_decl) pop_cfun (); } --- 1013,1019 ---- add_local_decl (cfun, var); } ! if (change_cfun) pop_cfun (); } *** /tmp/uvszca_gimplify.c Thu Aug 9 15:21:47 2012 --- gcc/gimplify.c Tue Aug 7 13:33:19 2012 *************** flag_instrument_functions_exclude_p (tre *** 8258,8271 **** void gimplify_function_tree (tree fndecl) { ! tree oldfn, parm, ret; gimple_seq seq; gimple bind; gcc_assert (!gimple_body (fndecl)); - oldfn = current_function_decl; - current_function_decl = fndecl; if (DECL_STRUCT_FUNCTION (fndecl)) push_cfun (DECL_STRUCT_FUNCTION (fndecl)); else --- 8258,8269 ---- void gimplify_function_tree (tree fndecl) { ! tree parm, ret; gimple_seq seq; gimple bind; gcc_assert (!gimple_body (fndecl)); if (DECL_STRUCT_FUNCTION (fndecl)) push_cfun (DECL_STRUCT_FUNCTION (fndecl)); else *************** gimplify_function_tree (tree fndecl) *** 8350,8356 **** DECL_SAVED_TREE (fndecl) = NULL_TREE; cfun->curr_properties = PROP_gimple_any; - current_function_decl = oldfn; pop_cfun (); } --- 8348,8353 ---- *** /tmp/gISRxc_gogo-tree.cc Thu Aug 9 15:21:47 2012 --- gcc/go/gofrontend/gogo-tree.cc Tue Aug 7 16:13:51 2012 *************** Gogo::write_initialization_function(tree *** 483,489 **** DECL_SAVED_TREE(fndecl) = init_stmt_list; - current_function_decl = fndecl; if (DECL_STRUCT_FUNCTION(fndecl) == NULL) push_struct_function(fndecl); else --- 483,488 ---- *************** Gogo::write_initialization_function(tree *** 494,500 **** cgraph_add_new_function(fndecl, false); - current_function_decl = NULL_TREE; pop_cfun(); } --- 493,498 ---- *************** Gogo::write_globals() *** 871,877 **** // means that we need an fndecl. if (init_fndecl == NULL_TREE) init_fndecl = this->initialization_function_decl(); - current_function_decl = init_fndecl; if (DECL_STRUCT_FUNCTION(init_fndecl) == NULL) push_struct_function(init_fndecl); else --- 869,874 ---- *************** Gogo::write_globals() *** 881,887 **** var_init_tree = no->var_value()->get_init_block(this, NULL, var_decl); - current_function_decl = NULL_TREE; pop_cfun(); } --- 878,883 ---- *************** Named_object::get_tree(Gogo* gogo, Named *** 1123,1137 **** cfun->function_end_locus = func->block()->end_location().gcc_location(); - current_function_decl = decl; - func->build_tree(gogo, this); gimplify_function_tree(decl); cgraph_finalize_function(decl, true); - current_function_decl = NULL_TREE; pop_cfun(); } } --- 1119,1130 ---- *** /tmp/2SvTGa_ipa-inline-analysis.c Thu Aug 9 15:21:47 2012 --- gcc/ipa-inline-analysis.c Tue Aug 7 13:35:39 2012 *************** compute_inline_parameters (struct cgraph *** 2068,2074 **** HOST_WIDE_INT self_stack_size; struct cgraph_edge *e; struct inline_summary *info; - tree old_decl = current_function_decl; gcc_assert (!node->global.inlined_to); --- 2068,2073 ---- *************** compute_inline_parameters (struct cgraph *** 2095,2101 **** } /* Even is_gimple_min_invariant rely on current_function_decl. */ - current_function_decl = node->symbol.decl; push_cfun (DECL_STRUCT_FUNCTION (node->symbol.decl)); /* Estimate the stack size for the function if we're optimizing. */ --- 2094,2099 ---- *************** compute_inline_parameters (struct cgraph *** 2137,2143 **** info->size = info->self_size; info->stack_frame_offset = 0; info->estimated_stack_size = info->estimated_self_stack_size; - current_function_decl = old_decl; pop_cfun (); } --- 2135,2140 ---- *************** static void *** 2924,2930 **** inline_analyze_function (struct cgraph_node *node) { push_cfun (DECL_STRUCT_FUNCTION (node->symbol.decl)); - current_function_decl = node->symbol.decl; if (dump_file) fprintf (dump_file, "\nAnalyzing function: %s/%u\n", --- 2921,2926 ---- *************** inline_analyze_function (struct cgraph_n *** 2933,2939 **** inline_indirect_intraprocedural_analysis (node); compute_inline_parameters (node, false); - current_function_decl = NULL; pop_cfun (); } --- 2929,2934 ---- *** /tmp/6WwhXc_ipa-prop.c Thu Aug 9 15:21:47 2012 --- gcc/ipa-prop.c Tue Aug 7 13:36:13 2012 *************** ipa_analyze_node (struct cgraph_node *no *** 1674,1680 **** ipa_check_create_edge_args (); info = IPA_NODE_REF (node); push_cfun (DECL_STRUCT_FUNCTION (node->symbol.decl)); - current_function_decl = node->symbol.decl; ipa_initialize_node_params (node); param_count = ipa_get_param_count (info); --- 1674,1679 ---- *************** ipa_analyze_node (struct cgraph_node *no *** 1688,1694 **** if (parms_ainfo[i].visited_statements) BITMAP_FREE (parms_ainfo[i].visited_statements); - current_function_decl = NULL; pop_cfun (); } --- 1687,1692 ---- *** /tmp/QSIQac_ipa-pure-const.c Thu Aug 9 15:21:47 2012 --- gcc/ipa-pure-const.c Tue Aug 7 13:37:57 2012 *************** static funct_state *** 724,730 **** analyze_function (struct cgraph_node *fn, bool ipa) { tree decl = fn->symbol.decl; - tree old_decl = current_function_decl; funct_state l; basic_block this_block; --- 724,729 ---- *************** analyze_function (struct cgraph_node *fn *** 752,758 **** } push_cfun (DECL_STRUCT_FUNCTION (decl)); - current_function_decl = decl; FOR_EACH_BB (this_block) { --- 751,756 ---- *************** end: *** 820,826 **** l->can_throw = false; pop_cfun (); - current_function_decl = old_decl; if (dump_file) { if (l->looping) --- 818,823 ---- *** /tmp/mNj9je_lto-streamer-in.c Thu Aug 9 15:21:47 2012 --- gcc/lto-streamer-in.c Tue Aug 7 13:44:16 2012 *************** void *** 1036,1042 **** lto_input_function_body (struct lto_file_decl_data *file_data, tree fn_decl, const char *data) { - current_function_decl = fn_decl; lto_read_body (file_data, fn_decl, data, LTO_section_function_body); } --- 1036,1041 ---- *** /tmp/Mmj3jc_lto-streamer-out.c Thu Aug 9 15:21:47 2012 --- gcc/lto-streamer-out.c Tue Aug 7 13:46:04 2012 *************** output_function (struct cgraph_node *nod *** 793,799 **** gcc_assert (current_function_decl == NULL_TREE && cfun == NULL); /* Set current_function_decl and cfun. */ - current_function_decl = function; push_cfun (fn); /* Make string 0 be a NULL string. */ --- 793,798 ---- *************** output_function (struct cgraph_node *nod *** 847,853 **** destroy_output_block (ob); - current_function_decl = NULL; pop_cfun (); } --- 846,851 ---- *** /tmp/iXBLWd_lto.c Thu Aug 9 15:21:47 2012 --- gcc/lto/lto.c Wed Aug 8 12:14:32 2012 *************** lto_materialize_function (struct cgraph_ *** 221,227 **** gcc_assert (DECL_STRUCT_FUNCTION (decl) == NULL); ! allocate_struct_function (decl, false); announce_function (decl); lto_input_function_body (file_data, decl, data); if (DECL_FUNCTION_PERSONALITY (decl) && !first_personality_decl) --- 221,227 ---- gcc_assert (DECL_STRUCT_FUNCTION (decl) == NULL); ! push_struct_function (decl); announce_function (decl); lto_input_function_body (file_data, decl, data); if (DECL_FUNCTION_PERSONALITY (decl) && !first_personality_decl) *************** lto_materialize_function (struct cgraph_ *** 229,234 **** --- 229,235 ---- lto_stats.num_function_bodies++; lto_free_section_data (file_data, LTO_section_function_body, name, data, len); + pop_cfun (); ggc_collect (); } } *** /tmp/mJnAqb_matrix-reorg.c Thu Aug 9 15:21:47 2012 --- gcc/matrix-reorg.c Tue Aug 7 13:50:23 2012 *************** transform_allocation_sites (void **slot, *** 1985,1991 **** { int i; struct matrix_info *mi; ! tree type, oldfn, prev_dim_size; gimple call_stmt_0, use_stmt; struct cgraph_node *c_node; struct cgraph_edge *e; --- 1985,1991 ---- { int i; struct matrix_info *mi; ! tree type, prev_dim_size; gimple call_stmt_0, use_stmt; struct cgraph_node *c_node; struct cgraph_edge *e; *************** transform_allocation_sites (void **slot, *** 2102,2109 **** We add the assignment to the global before the malloc of level 0. */ /* To be able to produce gimple temporaries. */ - oldfn = current_function_decl; - current_function_decl = mi->allocation_function_decl; push_cfun (DECL_STRUCT_FUNCTION (mi->allocation_function_decl)); /* Set the dimension sizes as follows: --- 2102,2107 ---- *************** transform_allocation_sites (void **slot, *** 2213,2225 **** e = cgraph_edge (c_node, mi->free_stmts[i].stmt); gcc_assert (e); cgraph_remove_edge (e); ! current_function_decl = mi->free_stmts[i].func; ! set_cfun (DECL_STRUCT_FUNCTION (mi->free_stmts[i].func)); gsi = gsi_for_stmt (mi->free_stmts[i].stmt); gsi_remove (&gsi, true); } /* Return to the previous situation. */ - current_function_decl = oldfn; pop_cfun (); return 1; --- 2211,2222 ---- e = cgraph_edge (c_node, mi->free_stmts[i].stmt); gcc_assert (e); cgraph_remove_edge (e); ! push_cfun (DECL_STRUCT_FUNCTION (mi->free_stmts[i].func)); gsi = gsi_for_stmt (mi->free_stmts[i].stmt); gsi_remove (&gsi, true); + pop_cfun (); } /* Return to the previous situation. */ pop_cfun (); return 1; *************** matrix_reorg (void) *** 2265,2274 **** /* Analyze the accesses of the matrices (escaping analysis). */ FOR_EACH_DEFINED_FUNCTION (node) { - tree temp_fn; - - temp_fn = current_function_decl; - current_function_decl = node->symbol.decl; push_cfun (DECL_STRUCT_FUNCTION (node->symbol.decl)); bitmap_obstack_initialize (NULL); gimple_register_cfg_hooks (); --- 2262,2267 ---- *************** matrix_reorg (void) *** 2278,2284 **** free_dominance_info (CDI_DOMINATORS); free_dominance_info (CDI_POST_DOMINATORS); pop_cfun (); - current_function_decl = temp_fn; bitmap_obstack_release (NULL); return 0; --- 2271,2276 ---- *************** matrix_reorg (void) *** 2293,2299 **** free_dominance_info (CDI_DOMINATORS); free_dominance_info (CDI_POST_DOMINATORS); pop_cfun (); - current_function_decl = temp_fn; bitmap_obstack_release (NULL); return 0; --- 2285,2290 ---- *************** matrix_reorg (void) *** 2324,2330 **** free_dominance_info (CDI_DOMINATORS); free_dominance_info (CDI_POST_DOMINATORS); pop_cfun (); - current_function_decl = temp_fn; bitmap_obstack_release (NULL); } htab_traverse (matrices_to_reorg, transform_allocation_sites, NULL); --- 2315,2320 ---- *************** matrix_reorg (void) *** 2332,2341 **** FOR_EACH_DEFINED_FUNCTION (node) { /* Remember that allocation sites have been handled. */ - tree temp_fn; - - temp_fn = current_function_decl; - current_function_decl = node->symbol.decl; push_cfun (DECL_STRUCT_FUNCTION (node->symbol.decl)); bitmap_obstack_initialize (NULL); gimple_register_cfg_hooks (); --- 2322,2327 ---- *************** matrix_reorg (void) *** 2345,2351 **** free_dominance_info (CDI_DOMINATORS); free_dominance_info (CDI_POST_DOMINATORS); pop_cfun (); - current_function_decl = temp_fn; bitmap_obstack_release (NULL); } htab_traverse (matrices_to_reorg, dump_matrix_reorg_analysis, NULL); --- 2331,2336 ---- *** /tmp/EQo3Md_omp-low.c Thu Aug 9 15:21:47 2012 --- gcc/omp-low.c Tue Aug 7 13:54:21 2012 *************** static void *** 1243,1249 **** finalize_task_copyfn (gimple task_stmt) { struct function *child_cfun; ! tree child_fn, old_fn; gimple_seq seq = NULL, new_seq; gimple bind; --- 1243,1249 ---- finalize_task_copyfn (gimple task_stmt) { struct function *child_cfun; ! tree child_fn; gimple_seq seq = NULL, new_seq; gimple bind; *************** finalize_task_copyfn (gimple task_stmt) *** 1257,1265 **** DECL_STRUCT_FUNCTION (child_fn)->curr_properties = cfun->curr_properties & ~PROP_loops; - old_fn = current_function_decl; push_cfun (child_cfun); - current_function_decl = child_fn; bind = gimplify_body (child_fn, false); gimple_seq_add_stmt (&seq, bind); new_seq = maybe_catch_exception (seq); --- 1257,1263 ---- *************** finalize_task_copyfn (gimple task_stmt) *** 1271,1277 **** } gimple_set_body (child_fn, seq); pop_cfun (); - current_function_decl = old_fn; cgraph_add_new_function (child_fn, false); } --- 1269,1274 ---- *************** expand_omp_taskreg (struct omp_region *r *** 3389,3395 **** basic_block entry_bb, exit_bb, new_bb; struct function *child_cfun; tree child_fn, block, t; - tree save_current; gimple_stmt_iterator gsi; gimple entry_stmt, stmt; edge e; --- 3386,3391 ---- *************** expand_omp_taskreg (struct omp_region *r *** 3589,3596 **** /* Fix the callgraph edges for child_cfun. Those for cfun will be fixed in a following pass. */ push_cfun (child_cfun); - save_current = current_function_decl; - current_function_decl = child_fn; if (optimize) optimize_omp_library_calls (entry_stmt); rebuild_cgraph_edges (); --- 3585,3590 ---- *************** expand_omp_taskreg (struct omp_region *r *** 3611,3617 **** } if (gimple_in_ssa_p (cfun)) update_ssa (TODO_update_ssa); - current_function_decl = save_current; pop_cfun (); } --- 3605,3610 ---- *************** create_task_copyfn (gimple task_stmt, om *** 6460,6466 **** /* Populate the function. */ push_gimplify_context (&gctx); ! current_function_decl = child_fn; bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL); TREE_SIDE_EFFECTS (bind) = 1; --- 6453,6459 ---- /* Populate the function. */ push_gimplify_context (&gctx); ! push_cfun (child_cfun); bind = build3 (BIND_EXPR, void_type_node, NULL, NULL, NULL); TREE_SIDE_EFFECTS (bind) = 1; *************** create_task_copyfn (gimple task_stmt, om *** 6507,6514 **** else tcctx.cb.decl_map = NULL; - push_cfun (child_cfun); - arg = DECL_ARGUMENTS (child_fn); TREE_TYPE (arg) = build_pointer_type (record_type); sarg = DECL_CHAIN (arg); --- 6500,6505 ---- *************** create_task_copyfn (gimple task_stmt, om *** 6666,6672 **** pop_gimplify_context (NULL); BIND_EXPR_BODY (bind) = list; pop_cfun (); ! current_function_decl = ctx->cb.src_fn; } /* Lower the OpenMP parallel or task directive in the current statement --- 6657,6664 ---- pop_gimplify_context (NULL); BIND_EXPR_BODY (bind) = list; pop_cfun (); ! /* !!! Remove after testing. */ ! gcc_assert (current_function_decl == ctx->cb.src_fn); } /* Lower the OpenMP parallel or task directive in the current statement *** /tmp/qpEqgc_passes.c Thu Aug 9 15:21:47 2012 --- gcc/passes.c Tue Aug 7 13:56:40 2012 *************** void *** 679,685 **** dump_passes (void) { struct cgraph_node *n, *node = NULL; - tree save_fndecl = current_function_decl; create_pass_tab(); --- 679,684 ---- *************** dump_passes (void) *** 694,700 **** return; push_cfun (DECL_STRUCT_FUNCTION (node->symbol.decl)); - current_function_decl = node->symbol.decl; dump_pass_list (all_lowering_passes, 1); dump_pass_list (all_small_ipa_passes, 1); --- 693,698 ---- *************** dump_passes (void) *** 704,710 **** dump_pass_list (all_passes, 1); pop_cfun (); - current_function_decl = save_fndecl; } --- 702,707 ---- *************** do_per_function (void (*callback) (void *** 1651,1664 **** && (!node->clone_of || node->symbol.decl != node->clone_of->symbol.decl)) { push_cfun (DECL_STRUCT_FUNCTION (node->symbol.decl)); - current_function_decl = node->symbol.decl; callback (data); if (!flag_wpa) { free_dominance_info (CDI_DOMINATORS); free_dominance_info (CDI_POST_DOMINATORS); } - current_function_decl = NULL; pop_cfun (); ggc_collect (); } --- 1648,1659 ---- *************** do_per_function_toporder (void (*callbac *** 1699,1709 **** if (cgraph_function_with_gimple_body_p (node)) { push_cfun (DECL_STRUCT_FUNCTION (node->symbol.decl)); - current_function_decl = node->symbol.decl; callback (data); free_dominance_info (CDI_DOMINATORS); free_dominance_info (CDI_POST_DOMINATORS); - current_function_decl = NULL; pop_cfun (); ggc_collect (); } --- 1694,1702 ---- *** /tmp/GR8iVd_trans-mem.c Thu Aug 9 15:21:47 2012 --- gcc/trans-mem.c Tue Aug 7 13:59:14 2012 *************** ipa_tm_scan_irr_function (struct cgraph_ *** 3980,3986 **** || DECL_STRUCT_FUNCTION (node->symbol.decl)->cfg == NULL) return false; - current_function_decl = node->symbol.decl; push_cfun (DECL_STRUCT_FUNCTION (node->symbol.decl)); calculate_dominance_info (CDI_DOMINATORS); --- 3980,3985 ---- *************** ipa_tm_scan_irr_function (struct cgraph_ *** 4052,4058 **** VEC_free (basic_block, heap, queue); pop_cfun (); - current_function_decl = NULL; return ret; } --- 4051,4056 ---- *************** ipa_tm_transform_transaction (struct cgr *** 4690,4696 **** d = get_cg_data (&node, true); - current_function_decl = node->symbol.decl; push_cfun (DECL_STRUCT_FUNCTION (node->symbol.decl)); calculate_dominance_info (CDI_DOMINATORS); --- 4688,4693 ---- *************** ipa_tm_transform_transaction (struct cgr *** 4715,4721 **** update_ssa (TODO_update_ssa_only_virtuals); pop_cfun (); - current_function_decl = NULL; } /* Transform the calls within the transactional clone of NODE. */ --- 4712,4717 ---- *************** ipa_tm_transform_clone (struct cgraph_no *** 4734,4741 **** if (!node->callees && !node->indirect_calls && !d->irrevocable_blocks_clone) return; ! current_function_decl = d->clone->symbol.decl; ! push_cfun (DECL_STRUCT_FUNCTION (current_function_decl)); calculate_dominance_info (CDI_DOMINATORS); need_ssa_rename = --- 4730,4736 ---- if (!node->callees && !node->indirect_calls && !d->irrevocable_blocks_clone) return; ! push_cfun (DECL_STRUCT_FUNCTION (d->clone->symbol.decl)); calculate_dominance_info (CDI_DOMINATORS); need_ssa_rename = *************** ipa_tm_transform_clone (struct cgraph_no *** 4746,4752 **** update_ssa (TODO_update_ssa_only_virtuals); pop_cfun (); - current_function_decl = NULL; } /* Main entry point for the transactional memory IPA pass. */ --- 4741,4746 ---- *************** ipa_tm_execute (void) *** 4793,4799 **** continue; } - current_function_decl = node->symbol.decl; push_cfun (DECL_STRUCT_FUNCTION (node->symbol.decl)); calculate_dominance_info (CDI_DOMINATORS); --- 4787,4792 ---- *************** ipa_tm_execute (void) *** 4813,4819 **** } pop_cfun (); - current_function_decl = NULL; } /* For every local function on the callee list, scan as if we will be --- 4806,4811 ---- *** /tmp/wwqagc_tree-emutls.c Thu Aug 9 15:21:47 2012 --- gcc/tree-emutls.c Tue Aug 7 14:48:01 2012 *************** lower_emutls_function_body (struct cgrap *** 618,624 **** struct lower_emutls_data d; bool any_edge_inserts = false; - current_function_decl = node->symbol.decl; push_cfun (DECL_STRUCT_FUNCTION (node->symbol.decl)); d.cfun_node = node; --- 618,623 ---- *************** lower_emutls_function_body (struct cgrap *** 689,695 **** gsi_commit_edge_inserts (); pop_cfun (); - current_function_decl = NULL; } /* Create emutls variable for VAR, DATA is pointer to static --- 688,693 ---- *** /tmp/C7R3Td_tree-inline.c Thu Aug 9 15:21:47 2012 --- gcc/tree-inline.c Tue Aug 7 14:56:44 2012 *************** remap_decl_1 (tree decl, void *data) *** 1998,2004 **** } /* Build struct function and associated datastructures for the new clone ! NEW_FNDECL to be build. CALLEE_FNDECL is the original */ static void initialize_cfun (tree new_fndecl, tree callee_fndecl, gcov_type count) --- 1998,2005 ---- } /* Build struct function and associated datastructures for the new clone ! NEW_FNDECL to be build. CALLEE_FNDECL is the original. Function changes ! the cfun to the function of new_fndecl (and current_function_decl too). */ static void initialize_cfun (tree new_fndecl, tree callee_fndecl, gcov_type count) *************** initialize_cfun (tree new_fndecl, tree c *** 2063,2069 **** cfun->gimple_df->in_ssa_p = true; init_ssa_operands (cfun); } - pop_cfun (); } /* Helper function for copy_cfg_body. Move debug stmts from the end --- 2064,2069 ---- *************** tree_function_versioning (tree old_decl, *** 5002,5009 **** struct ipa_replace_map *replace_info; basic_block old_entry_block, bb; VEC (gimple, heap) *init_stmts = VEC_alloc (gimple, heap, 10); - - tree old_current_function_decl = current_function_decl; tree vars = NULL_TREE; gcc_assert (TREE_CODE (old_decl) == FUNCTION_DECL --- 5002,5007 ---- *************** tree_function_versioning (tree old_decl, *** 5073,5086 **** id.transform_return_to_modify = false; id.transform_lang_insert_block = NULL; - current_function_decl = new_decl; old_entry_block = ENTRY_BLOCK_PTR_FOR_FUNCTION (DECL_STRUCT_FUNCTION (old_decl)); initialize_cfun (new_decl, old_decl, old_entry_block->count); DECL_STRUCT_FUNCTION (new_decl)->gimple_df->ipa_pta = id.src_cfun->gimple_df->ipa_pta; - push_cfun (DECL_STRUCT_FUNCTION (new_decl)); /* Copy the function's static chain. */ p = DECL_STRUCT_FUNCTION (old_decl)->static_chain_decl; --- 5071,5082 ---- *************** tree_function_versioning (tree old_decl, *** 5234,5242 **** gcc_assert (!id.debug_stmts); VEC_free (gimple, heap, init_stmts); pop_cfun (); - current_function_decl = old_current_function_decl; - gcc_assert (!current_function_decl - || DECL_STRUCT_FUNCTION (current_function_decl) == cfun); return; } --- 5230,5235 ---- *** /tmp/QSouyb_tree-profile.c Thu Aug 9 15:21:47 2012 --- gcc/tree-profile.c Tue Aug 7 14:59:02 2012 *************** tree_profiling (void) *** 479,485 **** continue; push_cfun (DECL_STRUCT_FUNCTION (node->symbol.decl)); - current_function_decl = node->symbol.decl; /* Re-set global shared temporary variable for edge-counters. */ gcov_type_tmp_var = NULL_TREE; --- 479,484 ---- *************** tree_profiling (void) *** 504,511 **** easy to adjust it, if and when there is some. */ free_dominance_info (CDI_DOMINATORS); free_dominance_info (CDI_POST_DOMINATORS); - - current_function_decl = NULL; pop_cfun (); } --- 503,508 ---- *************** tree_profiling (void) *** 540,546 **** continue; push_cfun (DECL_STRUCT_FUNCTION (node->symbol.decl)); - current_function_decl = node->symbol.decl; FOR_EACH_BB (bb) { --- 537,542 ---- *************** tree_profiling (void) *** 557,563 **** rebuild_cgraph_edges (); - current_function_decl = NULL; pop_cfun (); } --- 553,558 ---- *** /tmp/2E21Od_tree-sra.c Thu Aug 9 15:21:47 2012 --- gcc/tree-sra.c Tue Aug 7 15:01:55 2012 *************** convert_callers_for_node (struct cgraph_ *** 4612,4618 **** for (cs = node->callers; cs; cs = cs->next_caller) { - current_function_decl = cs->caller->symbol.decl; push_cfun (DECL_STRUCT_FUNCTION (cs->caller->symbol.decl)); if (dump_file) --- 4612,4617 ---- *************** static void *** 4641,4654 **** convert_callers (struct cgraph_node *node, tree old_decl, ipa_parm_adjustment_vec adjustments) { - tree old_cur_fndecl = current_function_decl; basic_block this_block; cgraph_for_node_and_aliases (node, convert_callers_for_node, adjustments, false); - current_function_decl = old_cur_fndecl; - if (!encountered_recursive_call) return; --- 4640,4650 ---- *************** modify_function (struct cgraph_node *nod *** 4689,4699 **** rebuild_cgraph_edges (); free_dominance_info (CDI_DOMINATORS); pop_cfun (); - current_function_decl = NULL_TREE; new_node = cgraph_function_versioning (node, redirect_callers, NULL, NULL, false, NULL, NULL, "isra"); - current_function_decl = new_node->symbol.decl; push_cfun (DECL_STRUCT_FUNCTION (new_node->symbol.decl)); ipa_modify_formal_parameters (current_function_decl, adjustments, "ISRA"); --- 4685,4693 ---- *** /tmp/60W3rb_tree-ssa-structalias.c Thu Aug 9 15:21:47 2012 --- gcc/tree-ssa-structalias.c Tue Aug 7 15:42:56 2012 *************** ipa_pta_execute (void) *** 6891,6897 **** { struct function *func; basic_block bb; - tree old_func_decl; /* Nodes without a body are not interesting. */ if (!cgraph_function_with_gimple_body_p (node)) --- 6891,6896 ---- *************** ipa_pta_execute (void) *** 6909,6917 **** } func = DECL_STRUCT_FUNCTION (node->symbol.decl); - old_func_decl = current_function_decl; push_cfun (func); - current_function_decl = node->symbol.decl; /* For externally visible or attribute used annotated functions use local constraints for their arguments. --- 6908,6914 ---- *************** ipa_pta_execute (void) *** 6968,6974 **** } } - current_function_decl = old_func_decl; pop_cfun (); if (dump_file) --- 6965,6970 ----