Example #1
0
/* Output code for start of function; the decl of the function is in
    PREV_SAVED (as created by tree_code_create_function_prototype),
    the function is at line number LINENO in file FILENAME.  The
    parameter details are in the lists PARMS. Returns nothing.  */
void 
tree_code_create_function_initial (tree prev_saved, 
                                  unsigned char* filename,
                                  int lineno,
                                  struct prod_token_parm_item* parms)
{
  tree fn_decl;
  tree param_decl;
  tree next_param;
  tree first_param;
  tree parm_decl;
  tree parm_list;
  tree resultdecl;
  struct prod_token_parm_item* this_parm; 
  struct prod_token_parm_item* parm;

  fn_decl = prev_saved;
  if (!fn_decl)
    abort ();

  /* Output message if not -quiet.  */
  announce_function (fn_decl);

  /* This has something to do with forcing output also.  */
  pushdecl (fn_decl);

  /* Set current function for error msgs etc.  */
  current_function_decl = fn_decl;
  DECL_INITIAL (fn_decl) = error_mark_node;

  DECL_SOURCE_FILE (fn_decl) = (const char *)filename;
  DECL_SOURCE_LINE (fn_decl) = lineno;

  /* Prepare creation of rtl for a new function.  */
  
  resultdecl = DECL_RESULT (fn_decl) = build_decl (RESULT_DECL, NULL_TREE, TREE_TYPE (TREE_TYPE (fn_decl)));
  DECL_CONTEXT (DECL_RESULT (fn_decl)) = fn_decl;
  DECL_SOURCE_FILE (resultdecl) = (const char *)filename;
  DECL_SOURCE_LINE (resultdecl) = lineno;
  /* Work out the size. ??? is this needed.  */
  layout_decl (DECL_RESULT (fn_decl), 0);

  /* Make the argument variable decls.  */
  parm_list = NULL_TREE;
  for (parm = parms; parm; parm = parm->tp.par.next)
    {
      parm_decl = build_decl (PARM_DECL, get_identifier 
                              ((const char*) (parm->tp.par.variable_name)), 
                              get_type_for_numeric_type (parm->type));
      
      /* Some languages have different nominal and real types.  */
      DECL_ARG_TYPE (parm_decl) = TREE_TYPE (parm_decl);
      if (!DECL_ARG_TYPE (parm_decl))
        abort ();
      if (!fn_decl)
        abort ();
      DECL_CONTEXT (parm_decl) = fn_decl;
      DECL_SOURCE_FILE (parm_decl) = (const char *)filename;
      DECL_SOURCE_LINE (parm_decl) = lineno;
      parm_list = chainon (parm_decl, parm_list);
    }

  /* Back into reverse order as the back end likes them.  */
  parm_list = nreverse (parm_list);
  
  DECL_ARGUMENTS (fn_decl) = parm_list;

  /* Save the decls for use when the args are referred to.  */
  for (param_decl = DECL_ARGUMENTS (fn_decl),
         this_parm = parms;
       param_decl;
       param_decl = TREE_CHAIN (param_decl),
         this_parm = this_parm->tp.par.next)
    {
      if (!this_parm)
        abort (); /* Too few.  */
      *this_parm->tp.par.where_to_put_var_tree = param_decl;
    }
  if (this_parm)
    abort (); /* Too many.  */

  /* Output the decl rtl (not the rtl for the function code).  ???.
     If the function is not defined in this file, when should you
     execute this?  */
  make_decl_rtl (fn_decl, NULL);

  /* Use filename/lineno from above.  */
  init_function_start (fn_decl, (const char *)filename, lineno); 
  
  /* Create rtl for startup code of function, such as saving registers.  */
  
  expand_function_start (fn_decl, 0);
  
  /* Function.c requires a push at the start of the function. that
     looks like a bug to me but let's make it happy.  */
  
  (*lang_hooks.decls.pushlevel) (0);
  
  /* Create rtl for the start of a new scope.  */
  
  expand_start_bindings (2);

  /* Put the parameters into the symbol table.  */
  
  for (first_param = param_decl = nreverse (DECL_ARGUMENTS (fn_decl));
       param_decl;
       param_decl = next_param)
    {
      next_param = TREE_CHAIN (param_decl);
      TREE_CHAIN (param_decl) = NULL;
      /* layout_decl (param_decl, 0);  Already done in build_decl tej 13/4/2002.  */
      pushdecl (param_decl);
      if (DECL_CONTEXT (param_decl) != current_function_decl)
        abort ();
    }

  /* Store back the PARM_DECL nodes.  They appear in the right order.  */
  DECL_ARGUMENTS (fn_decl) = getdecls ();

  /* Force it to be output, else may be solely inlined.  */
  TREE_ADDRESSABLE (fn_decl) = 1;
  
  /* Stop -O3 from deleting it.  */
  TREE_USED (fn_decl) = 1;

  /* Add a new level to the debugger symbol table.  */
  
  (*lang_hooks.decls.pushlevel) (0);
  
  /* Create rtl for the start of a new scope.  */
  
  expand_start_bindings (0);
  
  emit_line_note ((const char *)filename, lineno); /* Output the line number information.  */
}
Example #2
0
static void
tree_expand_cfg (void)
{
  basic_block bb, init_block;
  sbitmap blocks;

  /* Some backends want to know that we are expanding to RTL.  */
  currently_expanding_to_rtl = 1;

  /* Prepare the rtl middle end to start recording block changes.  */
  reset_block_changes ();

  /* Expand the variables recorded during gimple lowering.  */
  expand_used_vars ();

#ifdef KEY
  // Run expand_used_vars above to set DECL_SECTION_NAME.  Bug 10876.
  if (flag_spin_file)
    return;
#endif

  /* Set up parameters and prepare for return, for the function.  */
  expand_function_start (current_function_decl);

  /* If this function is `main', emit a call to `__main'
     to run global initializers, etc.  */
  if (DECL_NAME (current_function_decl)
      && MAIN_NAME_P (DECL_NAME (current_function_decl))
      && DECL_FILE_SCOPE_P (current_function_decl))
    expand_main_function ();

  /* Register rtl specific functions for cfg.  */
  rtl_register_cfg_hooks ();

  init_block = construct_init_block ();

  FOR_BB_BETWEEN (bb, init_block->next_bb, EXIT_BLOCK_PTR, next_bb)
    bb = expand_gimple_basic_block (bb, dump_file);

  construct_exit_block ();

  /* We're done expanding trees to RTL.  */
  currently_expanding_to_rtl = 0;

  /* Convert tree EH labels to RTL EH labels, and clean out any unreachable
     EH regions.  */
  convert_from_eh_region_ranges ();

  rebuild_jump_labels (get_insns ());
  find_exception_handler_labels ();

  blocks = sbitmap_alloc (last_basic_block);
  sbitmap_ones (blocks);
  find_many_sub_basic_blocks (blocks);
  purge_all_dead_edges (0);
  sbitmap_free (blocks);

  compact_blocks ();
#ifdef ENABLE_CHECKING
  verify_flow_info();
#endif

  /* There's no need to defer outputting this function any more; we
     know we want to output it.  */
  DECL_DEFER_OUTPUT (current_function_decl) = 0;

  /* Now that we're done expanding trees to RTL, we shouldn't have any
     more CONCATs anywhere.  */
  generating_concat_p = 0;

  finalize_block_changes ();

  if (dump_file)
    {
      fprintf (dump_file,
	       "\n\n;;\n;; Full RTL generated for this function:\n;;\n");
      /* And the pass manager will dump RTL for us.  */
    }
}
Example #3
0
void
write_resource_constructor (void)
{
  tree init_name, init_type, init_decl;
  tree iter;
  location_t saved_loc = input_location;
  char *resource_ctor_name;

  /* Only do work if required.  */
  if (resources == NULL_TREE)
    return;

  resource_ctor_name = concat (IDENTIFIER_POINTER (get_file_function_name ('I')),
			       "_resource", NULL);
  init_name = get_identifier (resource_ctor_name);
  free (resource_ctor_name);
  init_type = build_function_type (void_type_node, end_params_node);

  init_decl = build_decl (FUNCTION_DECL, init_name, init_type);
  DECL_SOURCE_LINE (init_decl) = 0;
  SET_DECL_ASSEMBLER_NAME (init_decl, init_name);
  TREE_STATIC (init_decl) = 1;
  current_function_decl = init_decl;
  DECL_RESULT (init_decl) = build_decl (RESULT_DECL, 
					NULL_TREE, void_type_node);

  /* It can be a static function as long as collect2 does not have
     to scan the object file to find its ctor/dtor routine.  */
  TREE_PUBLIC (init_decl) = ! targetm.have_ctors_dtors;

  pushlevel (0);
  make_decl_rtl (init_decl, NULL);
  init_function_start (init_decl);
  expand_function_start (init_decl, 0);

  /* Write out entries in the same order in which they were defined.  */
  for (iter = nreverse (resources); iter != NULL_TREE;
       iter = TREE_CHAIN (iter))
    {
      emit_library_call (registerResource_libfunc, 0, VOIDmode, 1,
			 expand_expr (build_address_of (TREE_VALUE (iter)),
				      0, Pmode, 0),
			 Pmode);
    }

  input_location = DECL_SOURCE_LOCATION (init_decl);
  expand_function_end ();
  poplevel (1, 0, 1);
  { 
    /* Force generation, even with -O3 or deeper.  Gross hack.
       FIXME.  */
    int saved_flag = flag_inline_functions;
    flag_inline_functions = 0;	
    rest_of_compilation (init_decl);
    flag_inline_functions = saved_flag;
  }
  current_function_decl = NULL_TREE;
  (* targetm.asm_out.constructor) (XEXP (DECL_RTL (init_decl), 0),
				   DEFAULT_INIT_PRIORITY);
  input_location = saved_loc;
}