Hi, On Tue, Aug 21, 2012 at 01:30:47PM +0200, Richard Guenther wrote: > On Tue, Aug 21, 2012 at 1:27 PM, Martin Jambor <mjam...@suse.cz> wrote: > > On Wed, Aug 15, 2012 at 05:21:04PM +0200, Martin Jambor wrote: > >> Hi, > >> > >> On Fri, Aug 10, 2012 at 04:57:41PM +0200, Eric Botcazou wrote: > >> > > - 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. > >> > > >> > If you think that calling dump_function from > >> > rest_of_subprog_body_compilation > >> > is a layering violation, I don't have a problem with replacing it with a > >> > more > >> > "manual" scheme like the one in c-family/c-gimplify.c:c_genericize, > >> > provided > >> > that this yields roughly the same output. > >> > >> Richi suggested on IRC that I remove the push/pop_cfun calls from > >> dump_function_to_file. The only problem seems to be > >> dump_histograms_for_stmt > > > > Yesterday I actually tried and it is not the only problem. Another > > one is dump_function_to_file->dump_bb->maybe_hot_bb_p which uses cfun > > to read profile_status. There may be others, this one just blew up > > first when I set cfun to NULL. And in future someone is quite likely > > to need cfun to dump something new too. > > > > At the same time, re-implementing dumping > > c-family/c-gimplify.c:c_genericize when dump_function suffices seems > > ugly to me. > > > > So I am going to declare dump_function a front-end interface and use > > set_cfun in my original patch in dump_function_to_file like we do in > > other such functions. > > > > I hope that will be OK. Thanks, > > Setting cfun has side-effects of switching target stuff which might have > code-generation side-effects because of implementation issues we have > with target/optimize attributes. So I don't think cfun should be changed > just for dumping. > > Can you instead just set current_function_decl and access > struct function via DECL_STRUCT_FUNCTION in the dumpers then? > After all, it it is a front-end interface, the frontend way of saying > "this is the current function" is to set current_function_decl, not the > middle-end cfun. >
Like the following? Tested and bootstrapped on x86_64-linux, it does help avoid the ada hunk in my previous patch. OK for trunk? Thanks, Martin 2012-08-21 Martin Jambor <mjam...@suse.cz> * predict.c (maybe_hot_frequency_p): New parameter fun. Use its decl instead of current_function_decl, use profile_status_for_function and ENTRY_BLOCK_PTR_FOR_FUNCTION with fun instead of their cfun variants. (maybe_hot_count_p): New parameter fun, use profile_status_for_function instead of its cfun_variant. (maybe_hot_bb_p): New parameter fun, checking-assert it, pass it to all callees. (maybe_hot_edge_p): Pass cfun to maybe_hot_count_p and maybe_hot_frequency_p. (probably_never_executed_bb_p): New parameter fun, use its decl instead of current_function_decl. (optimize_bb_for_size_p): Pass cfun to maybe_hot_bb_p. (rtl_profile_for_bb): Likewise. (compute_function_frequency): Pass cfun to maybe_hot_bb_p and probably_never_executed_bb_p. * tree-ssa-operands.c (ssa_operands_active): New operator fun. Use it instead of cfun. (update_stmt_operands): Pass cfun as an argument of ssa_operands_active. (swap_tree_operands): Likewise. * gimple-iterator.c (update_modified_stmt): Likewise. (update_modified_stmts): Likewise. * tree-flow-inline.h (delink_stmt_imm_use): Likewise. * tree-ssa.c (delete_tree_ssa): Likewise. * bb-reorder.c (bb_to_key): Pass cfun to probably_never_executed_bb_p. (push_to_next_round_p): Likewise. (find_rarely_executed_basic_blocks_and_crossing_edges ): Likewise. * cfg.c: Inlude tree.h. (check_bb_profile): Use profile_status_for_function, EXIT_BLOCK_PTR_FOR_FUNCTION and ENTRY_BLOCK_PTR_FOR_FUNCTION with DECL_STRUCT_FUNCTION (current_function_decl) instead of their cfun variants. (dump_bb_info): Pass DECL_STRUCT_FUNCTION (current_function_decl) to maybe_hot_bb_p and probably_never_executed_bb_p. * gimple-pretty-print.c (gimple_dump_bb_buff): Checking-assert that DECL_STRUCT_FUNCTION (current_function_decl) is not NULL. Pass it to dump_histograms_for_stmt. (dump_gimple_mem_ops): Pass DECL_STRUCT_FUNCTION (current_function_decl) as an argument to dump_gimple_mem_ops. * tree-cfg.c (dump_function_to_file): Rename parameter fn to fndecl. Do not change cfun. Change and restore current_function_decl. * Makefile.in (cfg.o): Include TREE_H in dependencies. *** /tmp/Hif6Ee_Makefile.in Wed Aug 22 15:02:30 2012 --- gcc/Makefile.in Wed Aug 22 11:53:02 2012 *************** auto-inc-dec.o : auto-inc-dec.c $(CONFIG *** 3047,3053 **** $(REGS_H) $(FLAGS_H) $(FUNCTION_H) $(EXCEPT_H) $(DIAGNOSTIC_CORE_H) $(RECOG_H) \ $(EXPR_H) $(TREE_PASS_H) $(DF_H) $(DBGCNT_H) $(TARGET_H) cfg.o : cfg.c $(CONFIG_H) $(SYSTEM_H) coretypes.h dumpfile.h $(DIAGNOSTIC_CORE_H) \ ! $(GGC_H) $(OBSTACK_H) alloc-pool.h $(HASHTAB_H) $(CFGLOOP_H) $(BASIC_BLOCK_H) cfghooks.o: cfghooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ $(TREE_H) $(BASIC_BLOCK_H) $(TREE_FLOW_H) $(TIMEVAR_H) toplev.h $(DIAGNOSTIC_CORE_H) $(CFGLOOP_H) cfgexpand.o : cfgexpand.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ --- 3047,3054 ---- $(REGS_H) $(FLAGS_H) $(FUNCTION_H) $(EXCEPT_H) $(DIAGNOSTIC_CORE_H) $(RECOG_H) \ $(EXPR_H) $(TREE_PASS_H) $(DF_H) $(DBGCNT_H) $(TARGET_H) cfg.o : cfg.c $(CONFIG_H) $(SYSTEM_H) coretypes.h dumpfile.h $(DIAGNOSTIC_CORE_H) \ ! $(GGC_H) $(OBSTACK_H) alloc-pool.h $(HASHTAB_H) $(CFGLOOP_H) $(TREE_H) \ ! $(BASIC_BLOCK_H) cfghooks.o: cfghooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) \ $(TREE_H) $(BASIC_BLOCK_H) $(TREE_FLOW_H) $(TIMEVAR_H) toplev.h $(DIAGNOSTIC_CORE_H) $(CFGLOOP_H) cfgexpand.o : cfgexpand.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \ *** /tmp/5C1Cob_basic-block.h Wed Aug 22 15:02:30 2012 --- gcc/basic-block.h Wed Aug 22 11:53:02 2012 *************** extern struct edge_list *pre_edge_rev_lc *** 693,701 **** extern void compute_available (sbitmap *, sbitmap *, sbitmap *, sbitmap *); /* In predict.c */ ! extern bool maybe_hot_bb_p (const_basic_block); extern bool maybe_hot_edge_p (edge); ! extern bool probably_never_executed_bb_p (const_basic_block); extern bool optimize_bb_for_size_p (const_basic_block); extern bool optimize_bb_for_speed_p (const_basic_block); extern bool optimize_edge_for_size_p (edge); --- 693,701 ---- extern void compute_available (sbitmap *, sbitmap *, sbitmap *, sbitmap *); /* In predict.c */ ! extern bool maybe_hot_bb_p (struct function *, const_basic_block); extern bool maybe_hot_edge_p (edge); ! extern bool probably_never_executed_bb_p (struct function *, const_basic_block); extern bool optimize_bb_for_size_p (const_basic_block); extern bool optimize_bb_for_speed_p (const_basic_block); extern bool optimize_edge_for_size_p (edge); *** /tmp/d7KhXa_bb-reorder.c Wed Aug 22 15:02:30 2012 --- gcc/bb-reorder.c Wed Aug 22 11:53:02 2012 *************** push_to_next_round_p (const_basic_block *** 226,232 **** block_not_hot_enough = (bb->frequency < exec_th || bb->count < count_th ! || probably_never_executed_bb_p (bb)); if (there_exists_another_round && block_not_hot_enough) --- 226,232 ---- block_not_hot_enough = (bb->frequency < exec_th || bb->count < count_th ! || probably_never_executed_bb_p (cfun, bb)); if (there_exists_another_round && block_not_hot_enough) *************** bb_to_key (basic_block bb) *** 823,829 **** /* Do not start in probably never executed blocks. */ if (BB_PARTITION (bb) == BB_COLD_PARTITION ! || probably_never_executed_bb_p (bb)) return BB_FREQ_MAX; /* Prefer blocks whose predecessor is an end of some trace --- 823,829 ---- /* Do not start in probably never executed blocks. */ if (BB_PARTITION (bb) == BB_COLD_PARTITION ! || probably_never_executed_bb_p (cfun, bb)) return BB_FREQ_MAX; /* Prefer blocks whose predecessor is an end of some trace *************** find_rarely_executed_basic_blocks_and_cr *** 1308,1314 **** /* Mark which partition (hot/cold) each basic block belongs in. */ FOR_EACH_BB (bb) { ! if (probably_never_executed_bb_p (bb)) BB_SET_PARTITION (bb, BB_COLD_PARTITION); else BB_SET_PARTITION (bb, BB_HOT_PARTITION); --- 1308,1314 ---- /* Mark which partition (hot/cold) each basic block belongs in. */ FOR_EACH_BB (bb) { ! if (probably_never_executed_bb_p (cfun, bb)) BB_SET_PARTITION (bb, BB_COLD_PARTITION); else BB_SET_PARTITION (bb, BB_HOT_PARTITION); *** /tmp/5erstd_cfg.c Wed Aug 22 15:02:30 2012 --- gcc/cfg.c Wed Aug 22 11:53:02 2012 *************** along with GCC; see the file COPYING3. *** 55,60 **** --- 55,61 ---- #include "ggc.h" #include "hashtab.h" #include "alloc-pool.h" + #include "tree.h" #include "basic-block.h" #include "df.h" #include "cfgloop.h" /* FIXME: For struct loop. */ *************** check_bb_profile (basic_block bb, FILE * *** 404,417 **** int sum = 0; gcov_type lsum; edge_iterator ei; char *s_indent = (char *) alloca ((size_t) indent + 1); memset ((void *) s_indent, ' ', (size_t) indent); s_indent[indent] = '\0'; ! if (profile_status == PROFILE_ABSENT) return; ! if (bb != EXIT_BLOCK_PTR) { FOR_EACH_EDGE (e, ei, bb->succs) sum += e->probability; --- 405,419 ---- int sum = 0; gcov_type lsum; edge_iterator ei; + struct function *fun = DECL_STRUCT_FUNCTION (current_function_decl); char *s_indent = (char *) alloca ((size_t) indent + 1); memset ((void *) s_indent, ' ', (size_t) indent); s_indent[indent] = '\0'; ! if (profile_status_for_function (fun) == PROFILE_ABSENT) return; ! if (bb != EXIT_BLOCK_PTR_FOR_FUNCTION (fun)) { FOR_EACH_EDGE (e, ei, bb->succs) sum += e->probability; *************** check_bb_profile (basic_block bb, FILE * *** 428,434 **** (flags & TDF_COMMENT) ? ";; " : "", s_indent, (int) lsum, (int) bb->count); } ! if (bb != ENTRY_BLOCK_PTR) { sum = 0; FOR_EACH_EDGE (e, ei, bb->preds) --- 430,436 ---- (flags & TDF_COMMENT) ? ";; " : "", s_indent, (int) lsum, (int) bb->count); } ! if (bb != ENTRY_BLOCK_PTR_FOR_FUNCTION (fun)) { sum = 0; FOR_EACH_EDGE (e, ei, bb->preds) *************** dump_bb_info (FILE *outf, basic_block bb *** 701,712 **** s_indent, bb->index, bb_loop_depth (bb)); if (flags & TDF_DETAILS) { fprintf (outf, ", count " HOST_WIDEST_INT_PRINT_DEC, (HOST_WIDEST_INT) bb->count); fprintf (outf, ", freq %i", bb->frequency); ! if (maybe_hot_bb_p (bb)) fputs (", maybe hot", outf); ! if (probably_never_executed_bb_p (bb)) fputs (", probably never executed", outf); } fputc ('\n', outf); --- 703,715 ---- s_indent, bb->index, bb_loop_depth (bb)); if (flags & TDF_DETAILS) { + struct function *fun = DECL_STRUCT_FUNCTION (current_function_decl); fprintf (outf, ", count " HOST_WIDEST_INT_PRINT_DEC, (HOST_WIDEST_INT) bb->count); fprintf (outf, ", freq %i", bb->frequency); ! if (maybe_hot_bb_p (fun, bb)) fputs (", maybe hot", outf); ! if (probably_never_executed_bb_p (fun, bb)) fputs (", probably never executed", outf); } fputc ('\n', outf); *** /tmp/Z3eGIa_gimple-iterator.c Wed Aug 22 15:02:30 2012 --- gcc/gimple-iterator.c Wed Aug 22 11:53:02 2012 *************** along with GCC; see the file COPYING3. *** 33,39 **** static inline void update_modified_stmt (gimple stmt) { ! if (!ssa_operands_active ()) return; update_stmt_if_modified (stmt); } --- 33,39 ---- static inline void update_modified_stmt (gimple stmt) { ! if (!ssa_operands_active (cfun)) return; update_stmt_if_modified (stmt); } *************** update_modified_stmts (gimple_seq seq) *** 46,52 **** { gimple_stmt_iterator gsi; ! if (!ssa_operands_active ()) return; for (gsi = gsi_start (seq); !gsi_end_p (gsi); gsi_next (&gsi)) update_stmt_if_modified (gsi_stmt (gsi)); --- 46,52 ---- { gimple_stmt_iterator gsi; ! if (!ssa_operands_active (cfun)) return; for (gsi = gsi_start (seq); !gsi_end_p (gsi); gsi_next (&gsi)) update_stmt_if_modified (gsi_stmt (gsi)); *** /tmp/1clpne_gimple-pretty-print.c Wed Aug 22 15:02:30 2012 --- gcc/gimple-pretty-print.c Wed Aug 22 11:53:02 2012 *************** dump_gimple_mem_ops (pretty_printer *buf *** 1817,1823 **** tree vdef = gimple_vdef (gs); tree vuse = gimple_vuse (gs); ! if (!ssa_operands_active () || !gimple_references_memory_p (gs)) return; if (vdef != NULL_TREE) --- 1817,1824 ---- tree vdef = gimple_vdef (gs); tree vuse = gimple_vuse (gs); ! if (!ssa_operands_active (DECL_STRUCT_FUNCTION (current_function_decl)) ! || !gimple_references_memory_p (gs)) return; if (vdef != NULL_TREE) *************** gimple_dump_bb_buff (pretty_printer *buf *** 2256,2262 **** INDENT (curr_indent); dump_gimple_stmt (buffer, stmt, curr_indent, flags); pp_newline_and_flush (buffer); ! dump_histograms_for_stmt (cfun, buffer->buffer->stream, stmt); } dump_implicit_edges (buffer, bb, indent, flags); --- 2257,2265 ---- INDENT (curr_indent); dump_gimple_stmt (buffer, stmt, curr_indent, flags); pp_newline_and_flush (buffer); ! gcc_checking_assert (DECL_STRUCT_FUNCTION (current_function_decl)); ! dump_histograms_for_stmt (DECL_STRUCT_FUNCTION (current_function_decl), ! buffer->buffer->stream, stmt); } dump_implicit_edges (buffer, bb, indent, flags); *** /tmp/nsrnlc_predict.c Wed Aug 22 15:02:30 2012 --- gcc/predict.c Wed Aug 22 11:53:02 2012 *************** static const struct predictor_info predi *** 108,116 **** /* Return TRUE if frequency FREQ is considered to be hot. */ static inline bool ! maybe_hot_frequency_p (int freq) { ! struct cgraph_node *node = cgraph_get_node (current_function_decl); if (!profile_info || !flag_branch_probabilities) { if (node->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED) --- 108,116 ---- /* Return TRUE if frequency FREQ is considered to be hot. */ static inline bool ! maybe_hot_frequency_p (struct function *fun, int freq) { ! struct cgraph_node *node = cgraph_get_node (fun->decl); if (!profile_info || !flag_branch_probabilities) { if (node->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED) *************** maybe_hot_frequency_p (int freq) *** 118,129 **** if (node->frequency == NODE_FREQUENCY_HOT) return true; } ! if (profile_status == PROFILE_ABSENT) return true; if (node->frequency == NODE_FREQUENCY_EXECUTED_ONCE ! && freq < (ENTRY_BLOCK_PTR->frequency * 2 / 3)) return false; ! if (freq < ENTRY_BLOCK_PTR->frequency / PARAM_VALUE (HOT_BB_FREQUENCY_FRACTION)) return false; return true; } --- 118,130 ---- if (node->frequency == NODE_FREQUENCY_HOT) return true; } ! if (profile_status_for_function (fun) == PROFILE_ABSENT) return true; if (node->frequency == NODE_FREQUENCY_EXECUTED_ONCE ! && freq < (ENTRY_BLOCK_PTR_FOR_FUNCTION (fun)->frequency * 2 / 3)) return false; ! if (freq < (ENTRY_BLOCK_PTR_FOR_FUNCTION (fun)->frequency ! / PARAM_VALUE (HOT_BB_FREQUENCY_FRACTION))) return false; return true; } *************** maybe_hot_frequency_p (int freq) *** 131,139 **** /* Return TRUE if frequency FREQ is considered to be hot. */ static inline bool ! maybe_hot_count_p (gcov_type count) { ! if (profile_status != PROFILE_READ) return true; /* Code executed at most once is not hot. */ if (profile_info->runs >= count) --- 132,140 ---- /* Return TRUE if frequency FREQ is considered to be hot. */ static inline bool ! maybe_hot_count_p (struct function *fun, gcov_type count) { ! if (profile_status_for_function (fun) != PROFILE_READ) return true; /* Code executed at most once is not hot. */ if (profile_info->runs >= count) *************** maybe_hot_count_p (gcov_type count) *** 146,158 **** for maximal performance. */ bool ! maybe_hot_bb_p (const_basic_block bb) { ! /* Make sure CFUN exists, for dump_bb_info. */ ! gcc_assert (cfun); ! if (profile_status == PROFILE_READ) ! return maybe_hot_count_p (bb->count); ! return maybe_hot_frequency_p (bb->frequency); } /* Return true if the call can be hot. */ --- 147,158 ---- for maximal performance. */ bool ! maybe_hot_bb_p (struct function *fun, const_basic_block bb) { ! gcc_checking_assert (fun); ! if (profile_status_for_function (fun) == PROFILE_READ) ! return maybe_hot_count_p (fun, bb->count); ! return maybe_hot_frequency_p (fun, bb->frequency); } /* Return true if the call can be hot. */ *************** bool *** 193,214 **** maybe_hot_edge_p (edge e) { if (profile_status == PROFILE_READ) ! return maybe_hot_count_p (e->count); ! return maybe_hot_frequency_p (EDGE_FREQUENCY (e)); } /* Return true in case BB is probably never executed. */ bool ! probably_never_executed_bb_p (const_basic_block bb) { ! /* Make sure CFUN exists, for dump_bb_info. */ ! gcc_assert (cfun); if (profile_info && flag_branch_probabilities) return ((bb->count + profile_info->runs / 2) / profile_info->runs) == 0; if ((!profile_info || !flag_branch_probabilities) ! && (cgraph_get_node (current_function_decl)->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED)) return true; return false; --- 193,213 ---- maybe_hot_edge_p (edge e) { if (profile_status == PROFILE_READ) ! return maybe_hot_count_p (cfun, e->count); ! return maybe_hot_frequency_p (cfun, EDGE_FREQUENCY (e)); } /* Return true in case BB is probably never executed. */ bool ! probably_never_executed_bb_p (struct function *fun, const_basic_block bb) { ! gcc_checking_assert (fun); if (profile_info && flag_branch_probabilities) return ((bb->count + profile_info->runs / 2) / profile_info->runs) == 0; if ((!profile_info || !flag_branch_probabilities) ! && (cgraph_get_node (fun->decl)->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED)) return true; return false; *************** optimize_function_for_speed_p (struct fu *** 252,258 **** bool optimize_bb_for_size_p (const_basic_block bb) { ! return optimize_function_for_size_p (cfun) || !maybe_hot_bb_p (bb); } /* Return TRUE when BB should be optimized for speed. */ --- 251,257 ---- bool optimize_bb_for_size_p (const_basic_block bb) { ! return optimize_function_for_size_p (cfun) || !maybe_hot_bb_p (cfun, bb); } /* Return TRUE when BB should be optimized for speed. */ *************** predictable_edge_p (edge e) *** 369,375 **** void rtl_profile_for_bb (basic_block bb) { ! crtl->maybe_hot_insn_p = maybe_hot_bb_p (bb); } /* Set RTL expansion for edge profile. */ --- 368,374 ---- void rtl_profile_for_bb (basic_block bb) { ! crtl->maybe_hot_insn_p = maybe_hot_bb_p (cfun, bb); } /* Set RTL expansion for edge profile. */ *************** compute_function_frequency (void) *** 2705,2716 **** node->frequency = NODE_FREQUENCY_UNLIKELY_EXECUTED; FOR_EACH_BB (bb) { ! if (maybe_hot_bb_p (bb)) { node->frequency = NODE_FREQUENCY_HOT; return; } ! if (!probably_never_executed_bb_p (bb)) node->frequency = NODE_FREQUENCY_NORMAL; } } --- 2704,2715 ---- node->frequency = NODE_FREQUENCY_UNLIKELY_EXECUTED; FOR_EACH_BB (bb) { ! if (maybe_hot_bb_p (cfun, bb)) { node->frequency = NODE_FREQUENCY_HOT; return; } ! if (!probably_never_executed_bb_p (cfun, bb)) node->frequency = NODE_FREQUENCY_NORMAL; } } *** /tmp/HcgoTd_tree-cfg.c Wed Aug 22 15:02:30 2012 --- gcc/tree-cfg.c Wed Aug 22 11:53:02 2012 *************** move_sese_region_to_fn (struct function *** 6632,6650 **** */ void ! dump_function_to_file (tree fn, FILE *file, int flags) { ! tree arg, var; struct function *dsf; bool ignore_topmost_bind = false, any_var = false; basic_block bb; tree chain; ! bool tmclone = TREE_CODE (fn) == FUNCTION_DECL && decl_is_tm_clone (fn); ! fprintf (file, "%s %s(", current_function_name (), ! tmclone ? "[tm-clone] " : ""); ! arg = DECL_ARGUMENTS (fn); while (arg) { print_generic_expr (file, TREE_TYPE (arg), dump_flags); --- 6632,6652 ---- */ void ! dump_function_to_file (tree fndecl, FILE *file, int flags) { ! tree arg, var, old_current_fndecl = current_function_decl; struct function *dsf; bool ignore_topmost_bind = false, any_var = false; basic_block bb; tree chain; ! bool tmclone = (TREE_CODE (fndecl) == FUNCTION_DECL ! && decl_is_tm_clone (fndecl)); ! struct function *fun = DECL_STRUCT_FUNCTION (fndecl); ! current_function_decl = fndecl; ! fprintf (file, "%s %s(", function_name (fun), tmclone ? "[tm-clone] " : ""); ! arg = DECL_ARGUMENTS (fndecl); while (arg) { print_generic_expr (file, TREE_TYPE (arg), dump_flags); *************** dump_function_to_file (tree fn, FILE *fi *** 6659,6689 **** fprintf (file, ")\n"); if (flags & TDF_VERBOSE) ! print_node (file, "", fn, 2); ! dsf = DECL_STRUCT_FUNCTION (fn); if (dsf && (flags & TDF_EH)) dump_eh_tree (file, dsf); ! if (flags & TDF_RAW && !gimple_has_body_p (fn)) { ! dump_node (fn, TDF_SLIM | flags, file); return; } - /* Switch CFUN to point to FN. */ - push_cfun (DECL_STRUCT_FUNCTION (fn)); - /* When GIMPLE is lowered, the variables are no longer available in BIND_EXPRs, so display them separately. */ ! if (cfun && cfun->decl == fn && (cfun->curr_properties & PROP_gimple_lcf)) { unsigned ix; ignore_topmost_bind = true; fprintf (file, "{\n"); ! if (!VEC_empty (tree, cfun->local_decls)) ! FOR_EACH_LOCAL_DECL (cfun, ix, var) { print_generic_decl (file, var, flags); if (flags & TDF_VERBOSE) --- 6661,6688 ---- fprintf (file, ")\n"); if (flags & TDF_VERBOSE) ! print_node (file, "", fndecl, 2); ! dsf = DECL_STRUCT_FUNCTION (fndecl); if (dsf && (flags & TDF_EH)) dump_eh_tree (file, dsf); ! if (flags & TDF_RAW && !gimple_has_body_p (fndecl)) { ! dump_node (fndecl, TDF_SLIM | flags, file); return; } /* When GIMPLE is lowered, the variables are no longer available in BIND_EXPRs, so display them separately. */ ! if (fun && fun->decl == fndecl && (fun->curr_properties & PROP_gimple_lcf)) { unsigned ix; ignore_topmost_bind = true; fprintf (file, "{\n"); ! if (!VEC_empty (tree, fun->local_decls)) ! FOR_EACH_LOCAL_DECL (fun, ix, var) { print_generic_decl (file, var, flags); if (flags & TDF_VERBOSE) *************** dump_function_to_file (tree fn, FILE *fi *** 6709,6734 **** } } ! if (cfun && cfun->decl == fn && cfun->cfg && basic_block_info) { /* If the CFG has been built, emit a CFG-based dump. */ if (!ignore_topmost_bind) fprintf (file, "{\n"); ! if (any_var && n_basic_blocks) fprintf (file, "\n"); ! FOR_EACH_BB (bb) dump_bb (file, bb, 2, flags | TDF_COMMENT); fprintf (file, "}\n"); } ! else if (DECL_SAVED_TREE (fn) == NULL) { /* The function is now in GIMPLE form but the CFG has not been built yet. Emit the single sequence of GIMPLE statements that make up its body. */ ! gimple_seq body = gimple_body (fn); if (gimple_seq_first_stmt (body) && gimple_seq_first_stmt (body) == gimple_seq_last_stmt (body) --- 6708,6734 ---- } } ! if (fun && fun->decl == fndecl && fun->cfg ! && basic_block_info_for_function (fun)) { /* If the CFG has been built, emit a CFG-based dump. */ if (!ignore_topmost_bind) fprintf (file, "{\n"); ! if (any_var && n_basic_blocks_for_function (fun)) fprintf (file, "\n"); ! FOR_EACH_BB_FN (bb, fun) dump_bb (file, bb, 2, flags | TDF_COMMENT); fprintf (file, "}\n"); } ! else if (DECL_SAVED_TREE (fndecl) == NULL) { /* The function is now in GIMPLE form but the CFG has not been built yet. Emit the single sequence of GIMPLE statements that make up its body. */ ! gimple_seq body = gimple_body (fndecl); if (gimple_seq_first_stmt (body) && gimple_seq_first_stmt (body) == gimple_seq_last_stmt (body) *************** dump_function_to_file (tree fn, FILE *fi *** 6751,6758 **** int indent; /* Make a tree based dump. */ ! chain = DECL_SAVED_TREE (fn); ! if (chain && TREE_CODE (chain) == BIND_EXPR) { if (ignore_topmost_bind) --- 6751,6757 ---- int indent; /* Make a tree based dump. */ ! chain = DECL_SAVED_TREE (fndecl); if (chain && TREE_CODE (chain) == BIND_EXPR) { if (ignore_topmost_bind) *************** dump_function_to_file (tree fn, FILE *fi *** 6782,6792 **** dump_enumerated_decls (file, flags); fprintf (file, "\n\n"); ! /* Restore CFUN. */ ! pop_cfun (); } - /* Dump FUNCTION_DECL FN to stderr using FLAGS (see TDF_* in tree.h) */ DEBUG_FUNCTION void --- 6781,6789 ---- dump_enumerated_decls (file, flags); fprintf (file, "\n\n"); ! current_function_decl = old_current_fndecl; } /* Dump FUNCTION_DECL FN to stderr using FLAGS (see TDF_* in tree.h) */ DEBUG_FUNCTION void *** /tmp/dtEITb_tree-flow-inline.h Wed Aug 22 15:02:30 2012 --- gcc/tree-flow-inline.h Wed Aug 22 11:53:02 2012 *************** delink_stmt_imm_use (gimple stmt) *** 798,804 **** ssa_op_iter iter; use_operand_p use_p; ! if (ssa_operands_active ()) FOR_EACH_PHI_OR_STMT_USE (use_p, stmt, iter, SSA_OP_ALL_USES) delink_imm_use (use_p); } --- 798,804 ---- ssa_op_iter iter; use_operand_p use_p; ! if (ssa_operands_active (cfun)) FOR_EACH_PHI_OR_STMT_USE (use_p, stmt, iter, SSA_OP_ALL_USES) delink_imm_use (use_p); } *** /tmp/BBEfSa_tree-ssa-operands.c Wed Aug 22 15:02:30 2012 --- gcc/tree-ssa-operands.c Wed Aug 22 11:53:02 2012 *************** static int n_initialized = 0; *** 130,145 **** /* Return true if the SSA operands cache is active. */ bool ! ssa_operands_active (void) { ! /* This function may be invoked from contexts where CFUN is NULL ! (IPA passes), return false for now. FIXME: operands may be ! active in each individual function, maybe this function should ! take CFUN as a parameter. */ ! if (cfun == NULL) return false; ! return cfun->gimple_df && gimple_ssa_operands (cfun)->ops_active; } --- 130,141 ---- /* Return true if the SSA operands cache is active. */ bool ! ssa_operands_active (struct function *fun) { ! if (fun == NULL) return false; ! return fun->gimple_df && gimple_ssa_operands (fun)->ops_active; } *************** update_stmt_operands (gimple stmt) *** 1211,1217 **** { /* If update_stmt_operands is called before SSA is initialized, do nothing. */ ! if (!ssa_operands_active ()) return; timevar_push (TV_TREE_OPS); --- 1207,1213 ---- { /* If update_stmt_operands is called before SSA is initialized, do nothing. */ ! if (!ssa_operands_active (cfun)) return; timevar_push (TV_TREE_OPS); *************** swap_tree_operands (gimple stmt, tree *e *** 1244,1250 **** positions of these two operands in their respective immediate use lists by adjusting their use pointer to point to the new operand position. */ ! if (ssa_operands_active () && op0 != op1) { use_optype_p use0, use1, ptr; use0 = use1 = NULL; --- 1240,1246 ---- positions of these two operands in their respective immediate use lists by adjusting their use pointer to point to the new operand position. */ ! if (ssa_operands_active (cfun) && op0 != op1) { use_optype_p use0, use1, ptr; use0 = use1 = NULL; *** /tmp/VXKTod_tree-ssa-operands.h Wed Aug 22 15:02:30 2012 --- gcc/tree-ssa-operands.h Wed Aug 22 11:53:02 2012 *************** extern void debug_immediate_uses_for (tr *** 114,120 **** extern void dump_decl_set (FILE *, bitmap); extern void debug_decl_set (bitmap); ! extern bool ssa_operands_active (void); extern bool virtual_operand_p (tree); extern void unlink_stmt_vdef (gimple); --- 114,120 ---- extern void dump_decl_set (FILE *, bitmap); extern void debug_decl_set (bitmap); ! extern bool ssa_operands_active (struct function *); extern bool virtual_operand_p (tree); extern void unlink_stmt_vdef (gimple); *** /tmp/NxZsCa_tree-ssa.c Wed Aug 22 15:02:30 2012 --- gcc/tree-ssa.c Wed Aug 22 11:53:02 2012 *************** delete_tree_ssa (void) *** 1157,1163 **** fini_ssanames (); /* We no longer maintain the SSA operand cache at this point. */ ! if (ssa_operands_active ()) fini_ssa_operands (); htab_delete (cfun->gimple_df->default_defs); --- 1157,1163 ---- fini_ssanames (); /* We no longer maintain the SSA operand cache at this point. */ ! if (ssa_operands_active (cfun)) fini_ssa_operands (); htab_delete (cfun->gimple_df->default_defs);