This is the mail archive of the gcc@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]

how to make sure an init routine is kept in the call graph?


Recently, we tried to merge the GCC trunk into the GUPC branch
and ran into an issue caused by a recent GCC update.
The last successful merge was trunk version 172359, fyi.

For certain UPC file scope static initializers,
a per file initialization routine is created, its address
is added to a global table (in its own section).
The UPC runtime will call all the routines listed in that
table before transferring control the user's main program.

After the recent trial merge, we see the following on
some of our test cases:

../../gcc/xupc -O2 -g -fdump-ipa-cgraph -fdump-tree-cfg test25.upc -o test25
/tmp/ccygQ8JN.o:(upc_init_array+0x0): undefined reference to `__upc_init_decls'

The call graph dump entry for `__upc_init_decls' is as follows:

__upc_init_decls/80(80) @0x7ffff1eb3de0 (asm: __upc_init_decls) body finalized
  called by:
  calls:
  References:
  Refering this function:

As expected, no explicit references have been recorded.

The compiler routine that creates this initialization routine is
called from c_common_parse_file():

      push_file_scope ();
      c_parse_file ();
      /* Generate UPC global initialization code, if required.  */
      if (c_dialect_upc ())
        upc_write_global_declarations ();
      pop_file_scope ();

The routine that builds the initialization function is
upc_build_init_func() in gcc/upc/upc-act.c (on the gupc branch).
This routine does the following to build the function,
mark it as used and referenced, and to then add its address
to the initialiaztion table:

  DECL_SOURCE_LOCATION (current_function_decl) = loc;
  TREE_PUBLIC (current_function_decl) = 0;
  TREE_USED (current_function_decl) = 1;
  DECL_SECTION_NAME (current_function_decl) =
     build_string (strlen (UPC_INIT_SECTION_NAME), UPC_INIT_SECTION_NAME);
  /* Swap the statement list that we've built up,
     for the current statement list.  */
  t_list = c_begin_compound_stmt (true);
  TREE_CHAIN (stmt_list) = TREE_CHAIN (t_list);
  cur_stmt_list = stmt_list;
  free_stmt_list (t_list);
  t_list = c_end_compound_stmt (loc, stmt_list, true);
  add_stmt (t_list);
  finish_function ();
  gcc_assert (DECL_RTL (init_func));
  upc_init_array_section = get_section (UPC_INIT_ARRAY_SECTION_NAME,
                                        0, NULL);
  mark_decl_referenced (init_func);
  init_func_symbol = XEXP (DECL_RTL (init_func), 0);
  assemble_addr_to_section (init_func_symbol, upc_init_array_section);

In the past, setting TREE_USED() and calling mark_decl_referenced()
was sufficient to make sure that this routine was not removed from the
call graph.

What is needed in the new scheme of things to ensure that this
initialization function stays in the call graph?

thanks,

- Gary


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