On 21/03/14 17:30, Thomas Schwinge wrote:
> Hi!
> 
> Certain GIMPLE codes, such as OpenMP ones, have a structured block
> attached to them, for exmaple, gcc/gimple.def:GIMPLE_OMP_PARALLEL:
> 
>     /* GIMPLE_OMP_PARALLEL <BODY, CLAUSES, CHILD_FN, DATA_ARG> represents
>     
>        #pragma omp parallel [CLAUSES]
>        BODY
>     
>        BODY is a the sequence of statements to be executed by all threads.
>     [...]
>        CHILD_FN is set when outlining the body of the parallel region.
>        All the statements in BODY are moved into this newly created
>        function when converting OMP constructs into low-GIMPLE.
>     [...]
>     DEFGSCODE(GIMPLE_OMP_PARALLEL, "gimple_omp_parallel", 
> GSS_OMP_PARALLEL_LAYOUT)
> 
> Using -ftree-dump-all, I can see this structured block (BODY) getting
> dumped, but it then "disappears" in the ompexp pass', and "reappears" (as
> function main._omp_fn.0) in the next ssa pass' dump.
> 
> If I'm correctly understanding the GCC sources as well as operating GDB,
> in the gimple pass we get main._omp_fn.0 dumped because
> gcc/cgraphunit.c:analyze_functions iterates over all functions
> (analyze_function -> dump_function).  In the following passes,
> presumably, this is not done anymore: omplower, lower, eh, cfg.  In
> ompexp, the GIMPLE_OMP_PARALLEL is expanded into a
> »__builtin_GOMP_parallel (main._omp_fn.0)« call, but the main._omp_fn.0
> is not dumped (and there is no BODY anymore to dump).  In the next ssa
> pass, main._omp_fn.0 again is being dumped, by means of
> gcc/passes.c:do_per_function_toporder (execute_pass_list ->
> execute_one_pass -> execute_function_dump -> dump_function_to_file), as I
> understand it.  What do I need to modify to get main._omp_fn.0 included
> in the dumps before the ssa pass, too?

Hi Thomas,

I think the answer to your question lies in two pieces of code.

1. gcc/omp-low.c:expand_omp_taskreg:
...
      /* Inform the callgraph about the new function.  */
      DECL_STRUCT_FUNCTION (child_fn)->curr_properties = cfun->curr_properties;
      cgraph_add_new_function (child_fn, true);
...
Note, the second parameter of cgraph_add_new_function is 'lowered' and set to 
true:

2.  gcc/cgraphunit.c:analyze_function:
...
      /* Make sure to gimplify bodies only once.  During analyzing a
         function we lower it, which will require gimplified nested
         functions, so we can end up here with an already gimplified
         body.  */
      if (!gimple_has_body_p (decl))
        gimplify_function_tree (decl);
      dump_function (TDI_generic, decl);

      /* Lower the function.  */
      if (!node->lowered)
        {
          if (node->nested)
            lower_nested_functions (node->decl);
          gcc_assert (!node->nested);

          gimple_register_cfg_hooks ();
          bitmap_obstack_initialize (NULL);
          execute_pass_list (cfun, g->get_passes ()->all_lowering_passes);
          free_dominance_info (CDI_POST_DOMINATORS);
          free_dominance_info (CDI_DOMINATORS);
          compact_blocks ();
          bitmap_obstack_release (NULL);
          node->lowered = true;
        }
...

The code marked by the parallel directive travels through the passes omplower,
lower, eh, and cfg as a part of main.

In ompexp, it's split off into a new function in expand_omp_taskreg. That new
function is marked as already being lowered.

When encountering the new function in analyze_function (after running the
lowering passes on main), we don't lower the code again. The confusing thing is
that we dump the lowered code in the gimplify dump, which suggest that the
function goes 'missing' in the dumps for a while.

Perhaps it would make more sense in this scenario to dump the new function to
the expand_omp dump.

Thanks,
- Tom

Reply via email to