Please discard the previous one. This is the right one: David
On Tue, May 31, 2011 at 5:01 PM, Xinliang David Li <davi...@google.com> wrote: > The new patch is attached. The test (c,c++,fortran, java, ada) is on going. > > Thanks, > > David > > On Tue, May 31, 2011 at 9:06 AM, Xinliang David Li <davi...@google.com> wrote: >> On Tue, May 31, 2011 at 2:05 AM, Richard Guenther >> <richard.guent...@gmail.com> wrote: >>> On Mon, May 30, 2011 at 10:16 PM, Xinliang David Li <davi...@google.com> >>> wrote: >>>> The attached are two simple follow up patches >>>> >>>> 1) the first patch does some refactorization on function header >>>> dumping (with more information printed) >>>> >>>> 2) the second patch cleans up some pass names. Part of the cleanup >>>> results from a previous discussion with Honza -- a) rename >>>> 'tree_profile_ipa' into 'profile', and make 'ipa_profile' and >>>> 'profile' into 'profile_estimate'. The rest of cleanups are needed to >>>> make sure pass names are unique. >>>> >>>> Ok for trunk? >>> >>> + >>> +void >>> +pass_dump_function_header (FILE *dump_file, tree fdecl, struct function >>> *fun) >>> >>> This function needs documentation, the ChangeLog entry misses >>> the tree-pretty-print.h change. >>> >>> +struct function; >>> >>> instead of this please include coretypes.h from tree-pretty-print.h >>> and add the struct function forward declaration there if it isn't already >>> present. >>> >>> You change the output of the header, so please make sure you >>> have bootstrapped and tested with _all_ languages included >>> (and also watch for bugreports for target specific bugs). >>> >> >> Ok. >> >>> + fprintf (dump_file, "\n;; Function %s (%s, funcdef_no=%d, uid=%d)", >>> + dname, aname, fun->funcdef_no, node->uid); >>> >>> I see no point in dumping funcdef_no - it wasn't dumped before in >>> any place. Instead I miss dumping of the DECL_UID and thus >>> a more specific 'uid', like 'cgraph-uid'. >> >> Ok will add decl_uid. Funcdef_no is very useful for debugging FDO >> coverage mismatch related problems as it is the id used in profile >> hashing. >> >>> >>> + aname = (IDENTIFIER_POINTER >>> + (DECL_ASSEMBLER_NAME (fdecl))); >>> >>> using DECL_ASSEMBLER_NAME is bad - it might trigger computation >>> of DECL_ASSEMBLER_NAME which certainly shouldn't be done >>> only for dumping purposes. Instead do sth like >>> >>> if (DECL_ASSEMBLER_NAME_SET_P (fdecl)) >>> aname = DECL_ASSEMBLER_NAME (fdecl); >>> else >>> aname = '<unset-asm-name>'; >> >> Ok. >> >>> >>> and please also watch for cgraph_get_node returning NULL. >>> >>> Also please call the function dump_function_header instead of >>> pass_dump_function_header. >>> >> >> Ok. >> >> Thanks, >> >> David >>> Please re-post with appropriate changes. >>> >>> Thanks, >>> Richard. >>> >>>> Thanks, >>>> >>>> David >>>> >>>> On Fri, May 27, 2011 at 2:58 AM, Richard Guenther >>>> <richard.guent...@gmail.com> wrote: >>>>> On Fri, May 27, 2011 at 12:02 AM, Xinliang David Li <davi...@google.com> >>>>> wrote: >>>>>> The latest version that only exports 2 functions from passes.c. >>>>> >>>>> Ok with ... >>>>> >>>>> @@ -637,4 +637,8 @@ extern bool first_pass_instance; >>>>> /* Declare for plugins. */ >>>>> extern void do_per_function_toporder (void (*) (void *), void *); >>>>> >>>>> +extern void disable_pass (const char *); >>>>> +extern void enable_pass (const char *); >>>>> +struct function; >>>>> + >>>>> >>>>> struct function forward decl removed. >>>>> >>>>> + explicitly_enabled = is_pass_explicitly_enabled (pass, func); >>>>> + explicitly_disabled = is_pass_explicitly_disabled (pass, func); >>>>> >>>>> both functions inlined here and removed. >>>>> >>>>> +#define MAX_PASS_ID 512 >>>>> >>>>> this removed and instead a VEC_safe_grow_cleared () or VEC_length () >>>>> before the accesses. >>>>> >>>>> +-fenable-ipa-@var{pass} @gol >>>>> +-fenable-rtl-@var{pass} @gol >>>>> +-fenable-rtl-@var{pass}=@var{range-list} @gol >>>>> +-fenable-tree-@var{pass} @gol >>>>> +-fenable-tree-@var{pass}=@var{range-list} @gol >>>>> >>>>> -fenable-@var{kind}-@var{pass}, etc. >>>>> >>>>> +@item -fdisable-@var{ipa|tree|rtl}-@var{pass} >>>>> +@itemx -fenable-@var{ipa|tree|rtl}-@var{pass} >>>>> +@itemx -fdisable-@var{tree|rtl}-@var{pass}=@var{range-list} >>>>> +@itemx -fenable-@var{tree|rtl}-@var{pass}=@var{range-list} >>>>> >>>>> likewise. >>>>> >>>>> Thanks, >>>>> Richard. >>>>> >>>>>> David >>>>>> >>>>>> On Thu, May 26, 2011 at 2:04 PM, Xinliang David Li <davi...@google.com> >>>>>> wrote: >>>>>>> On Thu, May 26, 2011 at 2:04 AM, Richard Guenther >>>>>>> <richard.guent...@gmail.com> wrote: >>>>>>>> On Wed, May 25, 2011 at 6:53 PM, Joseph S. Myers >>>>>>>> <jos...@codesourcery.com> wrote: >>>>>>>>> On Wed, 25 May 2011, Xinliang David Li wrote: >>>>>>>>> >>>>>>>>>> Ping. The link to the message: >>>>>>>>>> >>>>>>>>>> http://gcc.gnu.org/ml/gcc-patches/2011-05/msg01303.html >>>>>>>>> >>>>>>>>> I don't consider this an option handling patch. Patches adding whole >>>>>>>>> new >>>>>>>>> features involving new options should be reviewed by maintainers for >>>>>>>>> the >>>>>>>>> part of the compiler relevant to those features (since there isn't a >>>>>>>>> pass >>>>>>>>> manager maintainer, I guess that means middle-end). >>>>>>>> >>>>>>>> Hmm, I suppose then you reviewed the option handling parts and they >>>>>>>> are ok? Those globbing options always cause headache to me. >>>>>>>> >>>>>>>> +-fenable-ipa-@var{pass} @gol >>>>>>>> +-fenable-rtl-@var{pass} @gol >>>>>>>> +-fenable-rtl-@var{pass}=@var{range-list} @gol >>>>>>>> +-fenable-tree-@var{pass} @gol >>>>>>>> >>>>>>>> so, no -fenable-tree-@var{pass}=@var{range-list}? >>>>>>>> >>>>>>> >>>>>>> Missed. Will add. >>>>>>> >>>>>>> >>>>>>>> Does the pass name match 1:1 with the dump file name? In which >>>>>>>> case >>>>>>> >>>>>>> Yes. >>>>>>> >>>>>>>> >>>>>>>> +Disable ipa pass @var{pass}. @var{pass} is the pass name. If the same >>>>>>>> pass is statically invoked in the compiler multiple times, the pass >>>>>>>> name should be appended with a sequential number starting from 1. >>>>>>>> >>>>>>>> isn't true as passes that are invoked only a single time lack the >>>>>>>> number >>>>>>>> suffix (yes, I'd really like that to be changed ...) >>>>>>> >>>>>>> Yes, pass with single static instance does not need number suffix. >>>>>>> >>>>>>>> >>>>>>>> Please break likes also in .texi files and stick to 80 columns. >>>>>>> >>>>>>> Done. >>>>>>> >>>>>>>> Please >>>>>>>> document that these options are debugging options and regular >>>>>>>> options for enabling/disabling passes should be used. I would suggest >>>>>>>> to group documentation differently and document -fenable-* and >>>>>>>> -fdisable-*, thus, >>>>>>>> >>>>>>>> + -fdisable-@var{kind}-@var{pass} >>>>>>>> + -fenable-@var{kind}-@var{pass} >>>>>>>> >>>>>>>> Even in .texi files please two spaces after a full-stop. >>>>>>> >>>>>>> Done >>>>>>> >>>>>>>> >>>>>>>> +extern void enable_disable_pass (const char *, bool); >>>>>>>> >>>>>>>> I'd rather have both enable_pass and disable_pass ;) >>>>>>> >>>>>>> Ok. >>>>>>> >>>>>>>> >>>>>>>> +struct function; >>>>>>>> +extern void pass_dump_function_header (FILE *, tree, struct function >>>>>>>> *); >>>>>>>> >>>>>>>> that's odd and probably should be split out, the function should >>>>>>>> maybe reside in tree-pretty-print.c. >>>>>>> >>>>>>> Ok. >>>>>>> >>>>>>>> >>>>>>>> Index: tree-ssa-loop-ivopts.c >>>>>>>> =================================================================== >>>>>>>> --- tree-ssa-loop-ivopts.c (revision 173837) >>>>>>>> +++ tree-ssa-loop-ivopts.c (working copy) >>>>>>>> @@ -3968,7 +3968,7 @@ get_computation_cost_at (struct ivopts_d >>>>>>>> >>>>>>>> well - doesn't belong here ;) >>>>>>> >>>>>>> Sorry -- many things in the same client -- not needed with your latest >>>>>>> change anyway. >>>>>>> >>>>>>>> >>>>>>>> +static hashval_t >>>>>>>> +passr_hash (const void *p) >>>>>>>> +{ >>>>>>>> + const struct pass_registry *const s = (const struct pass_registry >>>>>>>> *const) p; >>>>>>>> + return htab_hash_string (s->unique_name); >>>>>>>> +} >>>>>>>> + >>>>>>>> +/* Hash equal function */ >>>>>>>> + >>>>>>>> +static int >>>>>>>> +passr_eq (const void *p1, const void *p2) >>>>>>>> +{ >>>>>>>> + const struct pass_registry *const s1 = (const struct pass_registry >>>>>>>> *const) p1; >>>>>>>> + const struct pass_registry *const s2 = (const struct pass_registry >>>>>>>> *const) p2; >>>>>>>> + >>>>>>>> + return !strcmp (s1->unique_name, s2->unique_name); >>>>>>>> +} >>>>>>>> >>>>>>>> you can use htab_hash_string and strcmp directly, no need for these >>>>>>>> wrappers. >>>>>>> >>>>>>> The hashtable entry is not string in this case. It is pass_registry, >>>>>>> thus the wrapper. >>>>>>> >>>>>>>> >>>>>>>> +void >>>>>>>> +register_pass_name (struct opt_pass *pass, const char *name) >>>>>>>> >>>>>>>> doesn't seem to need exporting, so don't and make it static. >>>>>>> >>>>>>> Done. >>>>>>> >>>>>>>> >>>>>>>> + if (!pass_name_tab) >>>>>>>> + pass_name_tab = htab_create (10, passr_hash, passr_eq, NULL); >>>>>>>> >>>>>>>> see above, the initial size should be larger - we have 223 passes at >>>>>>>> the >>>>>>>> moment, so use 256. >>>>>>> >>>>>>> Done. >>>>>>> >>>>>>>> >>>>>>>> + else >>>>>>>> + return; /* Ignore plugin passes. */ >>>>>>>> >>>>>>>> ? You mean they might clash? >>>>>>> >>>>>>> Yes, name clash. >>>>>>> >>>>>>>> >>>>>>>> +struct opt_pass * >>>>>>>> +get_pass_by_name (const char *name) >>>>>>>> >>>>>>>> doesn't need exporting either. >>>>>>> >>>>>>> Done. >>>>>>> >>>>>>>> >>>>>>>> + if (is_enable) >>>>>>>> + error ("unrecognized option -fenable"); >>>>>>>> + else >>>>>>>> + error ("unrecognized option -fdisable"); >>>>>>>> >>>>>>>> I think that should be fatal_error - Joseph? >>>>>>>> >>>>>>>> + if (is_enable) >>>>>>>> + error ("unknown pass %s specified in -fenable", phase_name); >>>>>>>> + else >>>>>>>> + error ("unknown pass %s specified in -fdisble", phase_name); >>>>>>>> >>>>>>>> likewise. >>>>>>>> >>>>>>>> + if (!enabled_pass_uid_range_tab) >>>>>>>> + enabled_pass_uid_range_tab = htab_create (10, pass_hash, >>>>>>>> pass_eq, NULL); >>>>>>>> >>>>>>>> instead of using a hashtable here please use a VEC indexed by >>>>>>>> the static_pass_number which shoud speed up >>>>>>> >>>>>>> Ok. The reason I did not use it is because in most of the cases, the >>>>>>> htab will be very small -- it is determined by the number of passes >>>>>>> specified in the command line, while the VEC requires allocating const >>>>>>> size array. Not an issue as long as by default the array is not >>>>>>> allocated. >>>>>>> >>>>>>>> >>>>>>>> +static bool >>>>>>>> +is_pass_explicitly_enabled_or_disabled (struct opt_pass *pass, >>>>>>>> + tree func, htab_t tab) >>>>>>>> +{ >>>>>>>> + struct uid_range **slot, *range, key; >>>>>>>> + int cgraph_uid; >>>>>>>> + >>>>>>>> + if (!tab) >>>>>>>> + return false; >>>>>>>> + >>>>>>>> + key.pass = pass; >>>>>>>> + slot = (struct uid_range **) htab_find_slot (tab, &key, NO_INSERT); >>>>>>>> + if (!slot || !*slot) >>>>>>>> + return false; >>>>>>>> >>>>>>>> and simplify the code quite a bit. >>>>>>>> >>>>>>>> + cgraph_uid = func ? cgraph_get_node (func)->uid : 0; >>>>>>>> >>>>>>>> note that cgraph uids are recycled, so it might not be the best idea >>>>>>>> to use them as discriminator (though I don't have a good idea how >>>>>>>> to represent ranges without them). >>>>>>> >>>>>>> Yes. It is not a big problem as the blind search does not need to know >>>>>>> the id->name mapping. Once the id s found, it can be easily discovered >>>>>>> via dump. >>>>>>> >>>>>>>> >>>>>>>> + explicitly_enabled = is_pass_explicitly_enabled (pass, >>>>>>>> current_function_decl); >>>>>>>> + explicitly_disabled = is_pass_explicitly_disabled (pass, >>>>>>>> current_function_decl); >>>>>>>> + >>>>>>>> current_pass = pass; >>>>>>>> >>>>>>>> /* Check whether gate check should be avoided. >>>>>>>> User controls the value of the gate through the parameter >>>>>>>> "gate_status". */ >>>>>>>> gate_status = (pass->gate == NULL) ? true : pass->gate(); >>>>>>>> + gate_status = !explicitly_disabled && (gate_status || >>>>>>>> explicitly_enabled); >>>>>>>> >>>>>>>> so explicitly disabling wins over explicit enabling ;) I think this >>>>>>>> implementation detail and the fact that you always query both >>>>>>>> hints at that the interface should be like >>>>>>>> >>>>>>>> gate_status = override_gate_status (pass, current_function_decl, >>>>>>>> gate_status); >>>>>>> >>>>>>> Done. >>>>>>> >>>>>>>> >>>>>>>> instead. >>>>>>>> >>>>>>>> Thus, please split out the function header dumping changes and rework >>>>>>>> the rest of the patch as suggested. >>>>>>> >>>>>>> Split out. The new patch is attached. >>>>>>> >>>>>>> Ok after testing is done? >>>>>>> >>>>>>> Thanks, >>>>>>> >>>>>>> David >>>>>>> >>>>>>>> >>>>>>>> Thanks, >>>>>>>> Richard. >>>>>>>> >>>>>>>>> -- >>>>>>>>> Joseph S. Myers >>>>>>>>> jos...@codesourcery.com >>>>>>>>> >>>>>>>> >>>>>>> >>>>>> >>>>> >>>> >>> >> >
Index: tree-pretty-print.c =================================================================== --- tree-pretty-print.c (revision 174424) +++ tree-pretty-print.c (working copy) @@ -3013,3 +3013,36 @@ pp_base_tree_identifier (pretty_printer pp_append_text (pp, IDENTIFIER_POINTER (id), IDENTIFIER_POINTER (id) + IDENTIFIER_LENGTH (id)); } + +/* A helper function that is used to dump function information before the + function dump. */ + +void +dump_function_header (FILE *dump_file, tree fdecl, struct function *fun) +{ + const char *dname, *aname; + struct cgraph_node *node = cgraph_get_node (fdecl); + dname = lang_hooks.decl_printable_name (fdecl, 2); + + if (DECL_ASSEMBLER_NAME_SET_P (fdecl)) + aname = (IDENTIFIER_POINTER + (DECL_ASSEMBLER_NAME (fdecl))); + else + aname = "<unset-asm-name>"; + + if (node) + fprintf (dump_file, "\n;; Function %s (%s, funcdef_no=%d, decl_uid = %d, cgraph_uid=%d)", + dname, aname, fun->funcdef_no, DECL_UID(fdecl), node->uid); + else + fprintf (dump_file, "\n;; Function %s (%s, funcdef_no=%d, decl_uid = %d)", + dname, aname, fun->funcdef_no, DECL_UID(fdecl)); + + fprintf (dump_file, "%s\n\n", + node->frequency == NODE_FREQUENCY_HOT + ? " (hot)" + : node->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED + ? " (unlikely executed)" + : node->frequency == NODE_FREQUENCY_EXECUTED_ONCE + ? " (executed once)" + : ""); +} Index: tree-pretty-print.h =================================================================== --- tree-pretty-print.h (revision 174422) +++ tree-pretty-print.h (working copy) @@ -24,6 +24,7 @@ along with GCC; see the file COPYING3. #define GCC_TREE_PRETTY_PRINT_H #include "pretty-print.h" +#include "coretypes.h" #define pp_tree_identifier(PP, T) \ pp_base_tree_identifier (pp_base (PP), T) @@ -50,6 +51,7 @@ extern void debug_generic_expr (tree); extern void debug_generic_stmt (tree); extern void debug_tree_chain (tree); extern void percent_K_format (text_info *); +extern void dump_function_header (FILE *, tree, struct function *); /* In toplev.c */ extern bool default_tree_printer (pretty_printer *, text_info *, const char *, Index: tree-cfg.c =================================================================== --- tree-cfg.c (revision 174422) +++ tree-cfg.c (working copy) @@ -2052,11 +2052,7 @@ gimple_dump_cfg (FILE *file, int flags) { if (flags & TDF_DETAILS) { - const char *funcname - = lang_hooks.decl_printable_name (current_function_decl, 2); - - fputc ('\n', file); - fprintf (file, ";; Function %s\n\n", funcname); + dump_function_header (file, current_function_decl, cfun); fprintf (file, ";; \n%d basic blocks, %d edges, last basic block %d.\n\n", n_basic_blocks, n_edges, last_basic_block); @@ -7525,4 +7521,3 @@ struct gimple_opt_pass pass_warn_unused_ 0, /* todo_flags_finish */ } }; - Index: coretypes.h =================================================================== --- coretypes.h (revision 174422) +++ coretypes.h (working copy) @@ -75,6 +75,7 @@ typedef struct diagnostic_context diagno struct gimple_seq_d; typedef struct gimple_seq_d *gimple_seq; typedef const struct gimple_seq_d *const_gimple_seq; +struct function; /* Address space number for named address space support. */ typedef unsigned char addr_space_t; @@ -172,4 +173,3 @@ union _dont_use_tree_here_; #endif #endif /* coretypes.h */ - Index: final.c =================================================================== --- final.c (revision 174422) +++ final.c (working copy) @@ -83,6 +83,7 @@ along with GCC; see the file COPYING3. #include "ggc.h" #include "cfgloop.h" #include "params.h" +#include "tree-pretty-print.h" #ifdef XCOFF_DEBUGGING_INFO #include "xcoffout.h" /* Needed for external data @@ -4360,20 +4361,7 @@ rest_of_clean_state (void) } else { - const char *aname; - struct cgraph_node *node = cgraph_get_node (current_function_decl); - - aname = (IDENTIFIER_POINTER - (DECL_ASSEMBLER_NAME (current_function_decl))); - fprintf (final_output, "\n;; Function (%s) %s\n\n", aname, - node->frequency == NODE_FREQUENCY_HOT - ? " (hot)" - : node->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED - ? " (unlikely executed)" - : node->frequency == NODE_FREQUENCY_EXECUTED_ONCE - ? " (executed once)" - : ""); - + dump_function_header (final_output, current_function_decl, cfun); flag_dump_noaddr = flag_dump_unnumbered = 1; if (flag_compare_debug_opt || flag_compare_debug) dump_flags |= TDF_NOUID; Index: passes.c =================================================================== --- passes.c (revision 174423) +++ passes.c (working copy) @@ -74,6 +74,7 @@ along with GCC; see the file COPYING3. #include "lto-streamer.h" #include "plugin.h" #include "ipa-utils.h" +#include "tree-pretty-print.h" #if defined (DWARF2_UNWIND_INFO) || defined (DWARF2_DEBUGGING_INFO) #include "dwarf2out.h" @@ -1637,21 +1638,7 @@ pass_init_dump_file (struct opt_pass *pa dump_file_name = get_dump_file_name (pass->static_pass_number); dump_file = dump_begin (pass->static_pass_number, &dump_flags); if (dump_file && current_function_decl) - { - const char *dname, *aname; - struct cgraph_node *node = cgraph_get_node (current_function_decl); - dname = lang_hooks.decl_printable_name (current_function_decl, 2); - aname = (IDENTIFIER_POINTER - (DECL_ASSEMBLER_NAME (current_function_decl))); - fprintf (dump_file, "\n;; Function %s (%s)%s\n\n", dname, aname, - node->frequency == NODE_FREQUENCY_HOT - ? " (hot)" - : node->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED - ? " (unlikely executed)" - : node->frequency == NODE_FREQUENCY_EXECUTED_ONCE - ? " (executed once)" - : ""); - } + dump_function_header (dump_file, current_function_decl, cfun); return initializing_dump; } else