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]

Re: Update pass manager to handle generate_summary/transform functions


I opened a bug report

http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36100


H.J.
On Thu, May 1, 2008 at 9:34 AM, H.J. Lu <hjl.tools@gmail.com> wrote:
> Hi Jan,
>
>  I think this patch breaks always_inline attribute at -O0:
>
>  [hjl@gnu-6 gcc]$ cat /tmp/y.c
>  #include <emmintrin.h>
>
>  int
>  main ()
>  {
>   __m128i x, y;
>   x = _mm_xor_si128 (x, y);
>   return 0;
>  }
>  [hjl@gnu-6 gcc]$ ./xgcc -B./ -m32 /tmp/y.c -msse2
>  /tmp/ccQGxyxs.o: In function `main':
>  y.c:(.text+0x24): undefined reference to `_mm_xor_si128'
>  collect2: ld returned 1 exit status
>  [hjl@gnu-6 gcc]$
>
>  H.J.
>  ---
>
>
>
>  On Fri, Apr 4, 2008 at 11:54 PM, Jan Hubicka <jh@suse.cz> wrote:
>  > Hi,
>  >  this patch updates PM to handle IPA_PASS with separate
>  >  generate_summary/transform hooks and update inliner to use new infrastructure.
>  >
>  >  Pass manager now execute generate_summary of all IPA_PASS passes in queue in
>  >  sequence on each function/variable before executing them and it adds their
>  >  transform functions into lists housed in cfun.  Those lists are executed before
>  >  next local pass is done.
>  >
>  >  I use private lists for each function since IPA passes might introduce new functions
>  >  during execution we don't want to run earlier transforms on.
>  >
>  >  This is meant to be initial implementation, I didn't add support for variables
>  >  yet and also PM should be smarter and couple summary generation with previous
>  >  local pass if available.  This is however enough so we can turn existing passes
>  >  to the scheme and I have followup for this ready.
>  >
>  >  Bootstrapped/regtested i686-linux, OK?
>  >
>  >         * tree-pass.h (opt_pass): Add IPA_PASS.
>  >         (varpool_node, cgraph_node): Forward declare.
>  >         (ipa_opt_pass): Define.
>  >         (pass_ipa_inline): Turn into ipa_opt_pass.
>  >         (pass_apply_inline): Remove.
>  >         * ipa-inline.c (pass_ipa_inline): Turn into ipa_opt_pass.
>  >         (apply_inline): Turn into ....
>  >         (inline_transform): ... this one.
>  >         (inline_generate_summary): New function.
>  >         (pass_apply_inline): Remove.
>  >         * function.h (ipa_opt_pass): Forward declare structure; typedef;
>  >         vector.
>  >         (struct function): Add ipa_transforms_to_apply.
>  >         * passes.c (register_one_dump_file): Work on IPA_PASS.
>  >         (init_optimization_passes): Remove pass_inline_parameters and
>  >         pass_apply_inline.
>  >         (pass_init_dump_file, pass_fini_dump_file): Break out from ....
>  >         (execute_one_pass) ... here; apply transforms when possible.
>  >         (add_ipa_transform_pass, execute_ipa_summary_asses,
>  >         execute_one_ipa_transform_pass): New.
>  >         (execute_ipa_pass_list): Update for IPA_PASS type.
>  >
>  >  Index: tree-pass.h
>  >  ===================================================================
>  >  *** tree-pass.h (revision 133930)
>  >  --- tree-pass.h (working copy)
>  >  *************** struct opt_pass
>  >  *** 96,102 ****
>  >     enum opt_pass_type {
>  >       GIMPLE_PASS,
>  >       RTL_PASS,
>  >  !     SIMPLE_IPA_PASS
>  >     } type;
>  >     /* Terse name of the pass used as a fragment of the dump file name.  */
>  >     const char *name;
>  >  --- 96,103 ----
>  >     enum opt_pass_type {
>  >       GIMPLE_PASS,
>  >       RTL_PASS,
>  >  !     SIMPLE_IPA_PASS,
>  >  !     IPA_PASS
>  >     } type;
>  >     /* Terse name of the pass used as a fragment of the dump file name.  */
>  >     const char *name;
>  >  *************** struct opt_pass
>  >  *** 133,139 ****
>  >     unsigned int todo_flags_finish;
>  >   };
>  >
>  >  ! /* Description or GIMPLE pass.  */
>  >   struct gimple_opt_pass
>  >   {
>  >     struct opt_pass pass;
>  >  --- 134,140 ----
>  >     unsigned int todo_flags_finish;
>  >   };
>  >
>  >  ! /* Description of GIMPLE pass.  */
>  >   struct gimple_opt_pass
>  >   {
>  >     struct opt_pass pass;
>  >  *************** struct rtl_opt_pass
>  >  *** 145,151 ****
>  >     struct opt_pass pass;
>  >   };
>  >
>  >  ! /* Description if simple IPA pass.  Simple IPA passes have just one execute
>  >      hook.  */
>  >   struct simple_ipa_opt_pass
>  >   {
>  >  --- 146,181 ----
>  >     struct opt_pass pass;
>  >   };
>  >
>  >  ! struct varpool_node;
>  >  ! struct cgraph_node;
>  >  !
>  >  ! /* Description of IPA pass with generate summary, write, execute, read and
>  >  !    transform stages.  */
>  >  ! struct ipa_opt_pass
>  >  ! {
>  >  !   struct opt_pass pass;
>  >  !
>  >  !   /* IPA passes can analyze function body and variable initializers using this
>  >  !       hook and produce summary.  */
>  >  !   void (*function_generate_summary) (struct cgraph_node *);
>  >  !   void (*variable_generate_summary) (struct varpool_node *);
>  >  !
>  >  !   /* These hooks will be used to serialize IPA summaries on disk.  For a moment
>  >  !       they are just placeholders.  */
>  >  !   void (*function_write_summary) (struct cgraph_node *);
>  >  !   void (*variable_write_summary) (struct varpool_node *);
>  >  !   void (*function_read_summary) (struct cgraph_node *);
>  >  !   void (*variable_read_summary) (struct varpool_node *);
>  >  !
>  >  !   /* Results of interprocedural propagation of an IPA pass is applied to
>  >  !      function body via this hook.  */
>  >  !   unsigned int function_transform_todo_flags_start;
>  >  !   unsigned int (*function_transform) (struct cgraph_node *);
>  >  !   void (*variable_transform) (struct varpool_node *);
>  >  !
>  >  ! };
>  >  !
>  >  ! /* Description of simple IPA pass.  Simple IPA passes have just one execute
>  >      hook.  */
>  >   struct simple_ipa_opt_pass
>  >   {
>  >  *************** extern struct gimple_opt_pass pass_build
>  >  *** 353,361 ****
>  >   extern struct gimple_opt_pass pass_reset_cc_flags;
>  >
>  >   /* IPA Passes */
>  >   extern struct simple_ipa_opt_pass pass_ipa_matrix_reorg;
>  >   extern struct simple_ipa_opt_pass pass_ipa_cp;
>  >  - extern struct simple_ipa_opt_pass pass_ipa_inline;
>  >   extern struct simple_ipa_opt_pass pass_ipa_early_inline;
>  >   extern struct simple_ipa_opt_pass pass_ipa_reference;
>  >   extern struct simple_ipa_opt_pass pass_ipa_pure_const;
>  >  --- 383,392 ----
>  >   extern struct gimple_opt_pass pass_reset_cc_flags;
>  >
>  >   /* IPA Passes */
>  >  + extern struct ipa_opt_pass pass_ipa_inline;
>  >  +
>  >   extern struct simple_ipa_opt_pass pass_ipa_matrix_reorg;
>  >   extern struct simple_ipa_opt_pass pass_ipa_cp;
>  >   extern struct simple_ipa_opt_pass pass_ipa_early_inline;
>  >   extern struct simple_ipa_opt_pass pass_ipa_reference;
>  >   extern struct simple_ipa_opt_pass pass_ipa_pure_const;
>  >  *************** extern struct rtl_opt_pass pass_rtl_seqa
>  >  *** 469,475 ****
>  >   extern struct gimple_opt_pass pass_release_ssa_names;
>  >   extern struct gimple_opt_pass pass_early_inline;
>  >   extern struct gimple_opt_pass pass_inline_parameters;
>  >  - extern struct gimple_opt_pass pass_apply_inline;
>  >   extern struct gimple_opt_pass pass_all_early_optimizations;
>  >   extern struct gimple_opt_pass pass_update_address_taken;
>  >
>  >  --- 500,505 ----
>  >  Index: ipa-inline.c
>  >  ===================================================================
>  >  *** ipa-inline.c        (revision 133930)
>  >  --- ipa-inline.c        (working copy)
>  >  *************** cgraph_gate_inlining (void)
>  >  *** 1426,1451 ****
>  >     return flag_inline_trees;
>  >   }
>  >
>  >  - struct simple_ipa_opt_pass pass_ipa_inline =
>  >  - {
>  >  -  {
>  >  -   SIMPLE_IPA_PASS,
>  >  -   "inline",                           /* name */
>  >  -   cgraph_gate_inlining,                       /* gate */
>  >  -   cgraph_decide_inlining,             /* execute */
>  >  -   NULL,                                       /* sub */
>  >  -   NULL,                                       /* next */
>  >  -   0,                                  /* static_pass_number */
>  >  -   TV_INLINE_HEURISTICS,                       /* tv_id */
>  >  -   0,                                  /* properties_required */
>  >  -   PROP_cfg,                           /* properties_provided */
>  >  -   0,                                  /* properties_destroyed */
>  >  -   TODO_remove_functions,              /* todo_flags_finish */
>  >  -   TODO_dump_cgraph | TODO_dump_func
>  >  -   | TODO_remove_functions             /* todo_flags_finish */
>  >  -  }
>  >  - };
>  >  -
>  >   /* Because inlining might remove no-longer reachable nodes, we need to
>  >      keep the array visible to garbage collector to avoid reading collected
>  >      out nodes.  */
>  >  --- 1426,1431 ----
>  >  *************** struct gimple_opt_pass pass_inline_param
>  >  *** 1579,1591 ****
>  >    }
>  >   };
>  >
>  >  ! /* Apply inline plan to the function.  */
>  >  ! static unsigned int
>  >  ! apply_inline (void)
>  >   {
>  >     unsigned int todo = 0;
>  >     struct cgraph_edge *e;
>  >  -   struct cgraph_node *node = cgraph_node (current_function_decl);
>  >
>  >     /* Even when not optimizing, ensure that always_inline functions get inlined.
>  >      */
>  >  --- 1559,1578 ----
>  >    }
>  >   };
>  >
>  >  ! /* Note function body size.  */
>  >  ! void
>  >  ! inline_generate_summary (struct cgraph_node *node ATTRIBUTE_UNUSED)
>  >  ! {
>  >  !   compute_inline_parameters ();
>  >  !   return;
>  >  ! }
>  >  !
>  >  ! /* Apply inline plan to function.  */
>  >  ! int
>  >  ! inline_transform (struct cgraph_node *node)
>  >   {
>  >     unsigned int todo = 0;
>  >     struct cgraph_edge *e;
>  >
>  >     /* Even when not optimizing, ensure that always_inline functions get inlined.
>  >      */
>  >  *************** apply_inline (void)
>  >  *** 1617,1629 ****
>  >     return todo | execute_fixup_cfg ();
>  >   }
>  >
>  >  ! struct gimple_opt_pass pass_apply_inline =
>  >   {
>  >    {
>  >  !   GIMPLE_PASS,
>  >  !   "apply_inline",                     /* name */
>  >  !   NULL,                                       /* gate */
>  >  !   apply_inline,                               /* execute */
>  >     NULL,                                       /* sub */
>  >     NULL,                                       /* next */
>  >     0,                                  /* static_pass_number */
>  >  --- 1604,1616 ----
>  >     return todo | execute_fixup_cfg ();
>  >   }
>  >
>  >  ! struct ipa_opt_pass pass_ipa_inline =
>  >   {
>  >    {
>  >  !   IPA_PASS,
>  >  !   "inline",                           /* name */
>  >  !   cgraph_gate_inlining,                       /* gate */
>  >  !   cgraph_decide_inlining,             /* execute */
>  >     NULL,                                       /* sub */
>  >     NULL,                                       /* next */
>  >     0,                                  /* static_pass_number */
>  >  *************** struct gimple_opt_pass pass_apply_inline
>  >  *** 1631,1640 ****
>  >     0,                                  /* properties_required */
>  >     PROP_cfg,                           /* properties_provided */
>  >     0,                                  /* properties_destroyed */
>  >  !   0,                                  /* todo_flags_start */
>  >  !   TODO_dump_func | TODO_verify_flow
>  >  !   | TODO_verify_stmts                 /* todo_flags_finish */
>  >  !  }
>  >   };
>  >
>  >   #include "gt-ipa-inline.h"
>  >  --- 1618,1636 ----
>  >     0,                                  /* properties_required */
>  >     PROP_cfg,                           /* properties_provided */
>  >     0,                                  /* properties_destroyed */
>  >  !   TODO_remove_functions,              /* todo_flags_finish */
>  >  !   TODO_dump_cgraph | TODO_dump_func
>  >  !   | TODO_remove_functions             /* todo_flags_finish */
>  >  !  },
>  >  !  inline_generate_summary,             /* function_generate_summary */
>  >  !  NULL,                                        /* variable_generate_summary */
>  >  !  NULL,                                        /* function_write_summary */
>  >  !  NULL,                                        /* variable_write_summary */
>  >  !  NULL,                                        /* function_read_summary */
>  >  !  NULL,                                        /* variable_read_summary */
>  >  !  0,                                   /* TODOs */
>  >  !  inline_transform,                    /* function_transform */
>  >  !  NULL,                                        /* variable_transform */
>  >   };
>  >
>  >   #include "gt-ipa-inline.h"
>  >  Index: function.h
>  >  ===================================================================
>  >  *** function.h  (revision 133930)
>  >  --- function.h  (working copy)
>  >  *************** typedef struct temp_slot *temp_slot_p;
>  >  *** 149,154 ****
>  >  --- 149,159 ----
>  >
>  >   DEF_VEC_P(temp_slot_p);
>  >   DEF_VEC_ALLOC_P(temp_slot_p,gc);
>  >  + struct ipa_opt_pass;
>  >  + typedef struct ipa_opt_pass *ipa_opt_pass;
>  >  +
>  >  + DEF_VEC_P(ipa_opt_pass);
>  >  + DEF_VEC_ALLOC_P(ipa_opt_pass,heap);
>  >
>  >   enum function_frequency {
>  >     /* This function most likely won't be executed at all.
>  >  *************** struct function GTY(())
>  >  *** 375,380 ****
>  >  --- 380,389 ----
>  >     /* Properties used by the pass manager.  */
>  >     unsigned int curr_properties;
>  >     unsigned int last_verified;
>  >  +   /* Interprocedural passes scheduled to have their transform functions
>  >  +      applied next time we execute local pass on them.  We maintain it
>  >  +      per-function in order to allow IPA passes to introduce new functions.  */
>  >  +   VEC(ipa_opt_pass,heap) * GTY((skip)) ipa_transforms_to_apply;
>  >
>  >     /* Collected bit flags.  */
>  >
>  >  Index: passes.c
>  >  ===================================================================
>  >  *** passes.c    (revision 133930)
>  >  --- passes.c    (working copy)
>  >  *************** register_one_dump_file (struct opt_pass
>  >  *** 352,358 ****
>  >                          ? 1 : pass->static_pass_number));
>  >
>  >     dot_name = concat (".", pass->name, num, NULL);
>  >  !   if (pass->type == SIMPLE_IPA_PASS)
>  >       prefix = "ipa-", flags = TDF_IPA;
>  >     else if (pass->type == GIMPLE_PASS)
>  >       prefix = "tree-", flags = TDF_TREE;
>  >  --- 352,358 ----
>  >                          ? 1 : pass->static_pass_number));
>  >
>  >     dot_name = concat (".", pass->name, num, NULL);
>  >  !   if (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS)
>  >       prefix = "ipa-", flags = TDF_IPA;
>  >     else if (pass->type == GIMPLE_PASS)
>  >       prefix = "tree-", flags = TDF_TREE;
>  >  *************** init_optimization_passes (void)
>  >  *** 538,544 ****
>  >           NEXT_PASS (pass_release_ssa_names);
>  >         }
>  >         NEXT_PASS (pass_rebuild_cgraph_edges);
>  >  -       NEXT_PASS (pass_inline_parameters);
>  >       }
>  >     NEXT_PASS (pass_ipa_increase_alignment);
>  >     NEXT_PASS (pass_ipa_matrix_reorg);
>  >  --- 538,543 ----
>  >  *************** init_optimization_passes (void)
>  >  *** 554,560 ****
>  >     /* These passes are run after IPA passes on every function that is being
>  >        output to the assembler file.  */
>  >     p = &all_passes;
>  >  -   NEXT_PASS (pass_apply_inline);
>  >     NEXT_PASS (pass_all_optimizations);
>  >       {
>  >         struct opt_pass **p = &pass_all_optimizations.pass.sub;
>  >  --- 553,558 ----
>  >  *************** verify_curr_properties (void *data)
>  >  *** 1053,1058 ****
>  >  --- 1051,1103 ----
>  >   }
>  >   #endif
>  >
>  >  + /* Initialize pass dump file.  */
>  >  + static bool
>  >  + pass_init_dump_file (struct opt_pass *pass)
>  >  + {
>  >  +   /* If a dump file name is present, open it if enabled.  */
>  >  +   if (pass->static_pass_number != -1)
>  >  +     {
>  >  +       bool initializing_dump = !dump_initialized_p (pass->static_pass_number);
>  >  +       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;
>  >  +         dname = lang_hooks.decl_printable_name (current_function_decl, 2);
>  >  +         aname = (IDENTIFIER_POINTER
>  >  +                  (DECL_ASSEMBLER_NAME (current_function_decl)));
>  >  +         fprintf (dump_file, "\n;; Appli transform to function %s (%s)%s\n\n", dname, aname,
>  >  +            cfun->function_frequency == FUNCTION_FREQUENCY_HOT
>  >  +            ? " (hot)"
>  >  +            : cfun->function_frequency == FUNCTION_FREQUENCY_UNLIKELY_EXECUTED
>  >  +            ? " (unlikely executed)"
>  >  +            : "");
>  >  +       }
>  >  +       return initializing_dump;
>  >  +     }
>  >  +   else
>  >  +     return false;
>  >  + }
>  >  +
>  >  + /* Flush pass dump file.  */
>  >  + static void
>  >  + pass_fini_dump_file (struct opt_pass *pass)
>  >  + {
>  >  +   /* Flush and close dump file.  */
>  >  +   if (dump_file_name)
>  >  +     {
>  >  +       free (CONST_CAST (char *, dump_file_name));
>  >  +       dump_file_name = NULL;
>  >  +     }
>  >  +
>  >  +   if (dump_file)
>  >  +     {
>  >  +       dump_end (pass->static_pass_number, dump_file);
>  >  +       dump_file = NULL;
>  >  +     }
>  >  + }
>  >  +
>  >   /* After executing the pass, apply expected changes to the function
>  >      properties. */
>  >   static void
>  >  *************** update_properties_after_pass (void *data
>  >  *** 1063,1068 ****
>  >  --- 1108,1183 ----
>  >                            & ~pass->properties_destroyed;
>  >   }
>  >
>  >  + /* Schedule IPA transform pass DATA for CFUN.  */
>  >  + static void
>  >  + add_ipa_transform_pass (void *data)
>  >  + {
>  >  +   struct ipa_opt_pass *ipa_pass = (struct ipa_opt_pass *) data;
>  >  +   VEC_safe_push (ipa_opt_pass, heap, cfun->ipa_transforms_to_apply, ipa_pass);
>  >  + }
>  >  +
>  >  + /* Execute IPA pass function summary generation.  */
>  >  + static void
>  >  + execute_ipa_summary_passes (void *data)
>  >  + {
>  >  +   struct ipa_opt_pass *ipa_pass = (struct ipa_opt_pass *)data;
>  >  +   struct cgraph_node *node = cgraph_node (cfun->decl);
>  >  +   while (ipa_pass && ipa_pass->pass.type == IPA_PASS)
>  >  +     {
>  >  +       struct opt_pass *pass = &ipa_pass->pass;
>  >  +       if (!pass->gate || pass->gate ())
>  >  +       {
>  >  +         pass_init_dump_file (pass);
>  >  +         ipa_pass->function_generate_summary (node);
>  >  +         pass_fini_dump_file (pass);
>  >  +       }
>  >  +       ipa_pass = (struct ipa_opt_pass *)ipa_pass->pass.next;
>  >  +     }
>  >  + }
>  >  +
>  >  + /* Execute IPA pass function transform.  */
>  >  + static void
>  >  + execute_one_ipa_transform_pass (struct cgraph_node *node,
>  >  +                               struct ipa_opt_pass *ipa_pass)
>  >  + {
>  >  +   struct opt_pass *pass = &ipa_pass->pass;
>  >  +   unsigned int todo_after = 0;
>  >  +
>  >  +   current_pass = pass;
>  >  +   if (!ipa_pass->function_transform)
>  >  +     return;
>  >  +
>  >  +   /* Note that the folders should only create gimple expressions.
>  >  +      This is a hack until the new folder is ready.  */
>  >  +   in_gimple_form = (cfun && (cfun->curr_properties & PROP_trees)) != 0;
>  >  +
>  >  +   pass_init_dump_file (pass);
>  >  +
>  >  +   /* Run pre-pass verification.  */
>  >  +   execute_todo (pass->todo_flags_start);
>  >  +
>  >  +   /* If a timevar is present, start it.  */
>  >  +   if (pass->tv_id)
>  >  +     timevar_push (pass->tv_id);
>  >  +
>  >  +   /* Do it!  */
>  >  +   todo_after = ipa_pass->function_transform (node);
>  >  +
>  >  +   /* Stop timevar.  */
>  >  +   if (pass->tv_id)
>  >  +     timevar_pop (pass->tv_id);
>  >  +
>  >  +   /* Run post-pass cleanup and verification.  */
>  >  +   execute_todo (todo_after);
>  >  +   verify_interpass_invariants ();
>  >  +
>  >  +   pass_fini_dump_file (pass);
>  >  +
>  >  +   current_pass = NULL;
>  >  +   /* Reset in_gimple_form to not break non-unit-at-a-time mode.  */
>  >  +   in_gimple_form = false;
>  >  + }
>  >  +
>  >   static bool
>  >   execute_one_pass (struct opt_pass *pass)
>  >   {
>  >  *************** execute_one_pass (struct opt_pass *pass)
>  >  *** 1071,1077 ****
>  >
>  >     /* IPA passes are executed on whole program, so cfun should be NULL.
>  >        Ohter passes needs function context set.  */
>  >  !   if (pass->type == SIMPLE_IPA_PASS)
>  >       gcc_assert (!cfun && !current_function_decl);
>  >     else
>  >       {
>  >  --- 1186,1192 ----
>  >
>  >     /* IPA passes are executed on whole program, so cfun should be NULL.
>  >        Ohter passes needs function context set.  */
>  >  !   if (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS)
>  >       gcc_assert (!cfun && !current_function_decl);
>  >     else
>  >       {
>  >  *************** execute_one_pass (struct opt_pass *pass)
>  >  *** 1080,1085 ****
>  >  --- 1195,1215 ----
>  >                   || pass->type != RTL_PASS);
>  >       }
>  >
>  >  +   if (cfun && cfun->ipa_transforms_to_apply)
>  >  +     {
>  >  +       unsigned int i;
>  >  +       struct cgraph_node *node = cgraph_node (current_function_decl);
>  >  +
>  >  +       for (i = 0; i < VEC_length (ipa_opt_pass, cfun->ipa_transforms_to_apply);
>  >  +          i++)
>  >  +       execute_one_ipa_transform_pass (node,
>  >  +                                       VEC_index (ipa_opt_pass,
>  >  +                                                  cfun->ipa_transforms_to_apply,
>  >  +                                                  i));
>  >  +       VEC_free (ipa_opt_pass, heap, cfun->ipa_transforms_to_apply);
>  >  +       cfun->ipa_transforms_to_apply = NULL;
>  >  +     }
>  >  +
>  >     current_pass = pass;
>  >     /* See if we're supposed to run this pass.  */
>  >     if (pass->gate && !pass->gate ())
>  >  *************** execute_one_pass (struct opt_pass *pass)
>  >  *** 1103,1130 ****
>  >                    (void *)(size_t)pass->properties_required);
>  >   #endif
>  >
>  >  !   /* If a dump file name is present, open it if enabled.  */
>  >  !   if (pass->static_pass_number != -1)
>  >  !     {
>  >  !       initializing_dump = !dump_initialized_p (pass->static_pass_number);
>  >  !       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;
>  >  !         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,
>  >  !            cfun->function_frequency == FUNCTION_FREQUENCY_HOT
>  >  !            ? " (hot)"
>  >  !            : cfun->function_frequency == FUNCTION_FREQUENCY_UNLIKELY_EXECUTED
>  >  !            ? " (unlikely executed)"
>  >  !            : "");
>  >  !       }
>  >  !     }
>  >  !   else
>  >  !     initializing_dump = false;
>  >
>  >     /* If a timevar is present, start it.  */
>  >     if (pass->tv_id)
>  >  --- 1233,1239 ----
>  >                    (void *)(size_t)pass->properties_required);
>  >   #endif
>  >
>  >  !   initializing_dump = pass_init_dump_file (pass);
>  >
>  >     /* If a timevar is present, start it.  */
>  >     if (pass->tv_id)
>  >  *************** execute_one_pass (struct opt_pass *pass)
>  >  *** 1157,1178 ****
>  >     /* Run post-pass cleanup and verification.  */
>  >     execute_todo (todo_after | pass->todo_flags_finish);
>  >     verify_interpass_invariants ();
>  >
>  >     if (!current_function_decl)
>  >       cgraph_process_new_functions ();
>  >
>  >  !   /* Flush and close dump file.  */
>  >  !   if (dump_file_name)
>  >  !     {
>  >  !       free (CONST_CAST (char *, dump_file_name));
>  >  !       dump_file_name = NULL;
>  >  !     }
>  >  !
>  >  !   if (dump_file)
>  >  !     {
>  >  !       dump_end (pass->static_pass_number, dump_file);
>  >  !       dump_file = NULL;
>  >  !     }
>  >
>  >     current_pass = NULL;
>  >     /* Reset in_gimple_form to not break non-unit-at-a-time mode.  */
>  >  --- 1266,1278 ----
>  >     /* Run post-pass cleanup and verification.  */
>  >     execute_todo (todo_after | pass->todo_flags_finish);
>  >     verify_interpass_invariants ();
>  >  +   if (pass->type == IPA_PASS)
>  >  +     do_per_function (add_ipa_transform_pass, pass);
>  >
>  >     if (!current_function_decl)
>  >       cgraph_process_new_functions ();
>  >
>  >  !   pass_fini_dump_file (pass);
>  >
>  >     current_pass = NULL;
>  >     /* Reset in_gimple_form to not break non-unit-at-a-time mode.  */
>  >  *************** execute_pass_list (struct opt_pass *pass
>  >  *** 1200,1216 ****
>  >   void
>  >   execute_ipa_pass_list (struct opt_pass *pass)
>  >   {
>  >     do
>  >       {
>  >         gcc_assert (!current_function_decl);
>  >         gcc_assert (!cfun);
>  >  !       gcc_assert (pass->type == SIMPLE_IPA_PASS);
>  >         if (execute_one_pass (pass) && pass->sub)
>  >         {
>  >           if (pass->sub->type == GIMPLE_PASS)
>  >             do_per_function_toporder ((void (*)(void *))execute_pass_list,
>  >                                       pass->sub);
>  >  !         else if (pass->sub->type == SIMPLE_IPA_PASS)
>  >             execute_ipa_pass_list (pass->sub);
>  >           else
>  >             gcc_unreachable ();
>  >  --- 1300,1330 ----
>  >   void
>  >   execute_ipa_pass_list (struct opt_pass *pass)
>  >   {
>  >  +   bool summaries_generated = false;
>  >     do
>  >       {
>  >         gcc_assert (!current_function_decl);
>  >         gcc_assert (!cfun);
>  >  !       gcc_assert (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS);
>  >  !       if (pass->type == IPA_PASS && (!pass->gate || pass->gate ()))
>  >  !       {
>  >  !         if (!summaries_generated)
>  >  !           {
>  >  !             if (!quiet_flag && !cfun)
>  >  !               fprintf (stderr, " <summary generate>");
>  >  !             do_per_function_toporder (execute_ipa_summary_passes, pass);
>  >  !           }
>  >  !         summaries_generated = true;
>  >  !       }
>  >  !       else
>  >  !       summaries_generated = false;
>  >         if (execute_one_pass (pass) && pass->sub)
>  >         {
>  >           if (pass->sub->type == GIMPLE_PASS)
>  >             do_per_function_toporder ((void (*)(void *))execute_pass_list,
>  >                                       pass->sub);
>  >  !         else if (pass->sub->type == SIMPLE_IPA_PASS
>  >  !                  || pass->sub->type == IPA_PASS)
>  >             execute_ipa_pass_list (pass->sub);
>  >           else
>  >             gcc_unreachable ();
>  >
>


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