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 can I generate a new function at compile time?


Hi!

I want to uninline some basic blocks to a separate function to aid slp vectorization.
The new pass runs just before the slp vectorization pass.
As a first try I create an new and empty function.
Which in turn will be filled with some copies of basic blocks from the original function.
As an example I was looking at code in omp-low.c
The pass itself seem to be successful,
however I do not see the new function printed when using -fdump-tree-all-details.
Further more an ipa pass crashes with a segfault at an seemingly unrelated location.
I call gcc like this.

/home/bhuber/sandbox/gcc/install/bin/gcc -std=c99 -O3 -I . -S -fdump-tree-all-details -fdump-rtl-all-details -fdump-tree-vect=vec.out -fopt-info-vec-missed=missed.out -ftree-vectorizer-verbose=6 -funinline-innermost-loops -ftree-slp-vectorize -Wall -Wextra /home/bhuber/sandbox/try/vectorizable.c
/home/bhuber/sandbox/try/vectorizable.c: In function '_GLOBAL__N_foo':
/home/bhuber/sandbox/try/vectorizable.c:61:6: internal compiler error: Segmentation fault
 void foo ( int M
      ^
0x99be1f crash_signal
        ../../src/gcc/toplev.c:337
0x9cdaac execute_fixup_cfg()
        ../../src/gcc/tree-cfg.c:8413
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See <http://gcc.gnu.org/bugs.html> for instructions.
bhuber@android:~/sandbox/try/foo$

The function to generate the empty function looks like this:

static unsigned int 
make_empty_function (void)
{ 
  tree name, decl, type, t, block;
  gimple_seq body = NULL;
  gimple bind;

  type = build_function_type_list (void_type_node, NULL_TREE);
  name = get_file_function_name ("N");
  decl = build_decl (input_location,
                     FUNCTION_DECL, name, type);

  TREE_STATIC (decl) = 1;
  TREE_USED (decl) = 1;
  DECL_ARTIFICIAL (decl) = 1;
  DECL_NAMELESS (decl) = 0;
  DECL_IGNORED_P (decl) = 0;
  TREE_PUBLIC (decl) = 0;
  DECL_UNINLINABLE (decl) = 1;
  DECL_EXTERNAL (decl) = 0;
  DECL_CONTEXT (decl) = NULL_TREE;

  block = make_node (BLOCK);
  DECL_INITIAL (decl) = block;

  t = build_decl (DECL_SOURCE_LOCATION (decl),
                  RESULT_DECL, NULL_TREE, void_type_node);
  DECL_ARTIFICIAL (t) = 1;
  DECL_IGNORED_P (t) = 1;
  DECL_CONTEXT (t) = decl;
  DECL_RESULT (decl) = t;

  push_struct_function (decl);

  pop_cfun ();

  bind = gimple_build_bind (NULL, body, block);
  gimple_seq_add_stmt (&body, bind);
  gimple_set_body (decl, body);

  DECL_STRUCT_FUNCTION (decl)->curr_properties = cfun->curr_properties;

  cgraph_add_new_function (decl, true);

  return 0;
}

I am working on trunk.
Please note that this is experimental code to get to know gcc internals.
What am I doing wrong?

Thank you in advance and best regards,
Benedikt


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