Example #1
0
/* Wrapup a function contained in file FILENAME, ending at line LINENO.  */
void 
tree_code_create_function_wrapup (unsigned char* filename,
                                 int lineno)
{
  tree block;
  tree fn_decl;

  fn_decl = current_function_decl;
  
  emit_line_note ((const char *)filename, lineno); /* Output the line number information.  */

  /* Get completely built level from debugger symbol table.  */
  
  block = (*lang_hooks.decls.poplevel) (1, 0, 0);
  
  /* Emit rtl for end of scope.  */
  
  expand_end_bindings (block, 0, 1);
  
  /* Emit rtl for end of function.  */
  
  expand_function_end ((const char *)filename, lineno, 0, fn_decl);
  
  /* Pop the level.  */

  block = (*lang_hooks.decls.poplevel) (1, 0, 1);

  /* And attach it to the function.  */
  
  DECL_INITIAL (fn_decl) = block;
  
  /* Emit rtl for end of scope.  */
  
  expand_end_bindings (block, 0, 1);
  
  /* Call optimization and convert optimized rtl to assembly code.  */
  
  rest_of_compilation (fn_decl);
  
  /* We are not inside of any scope now.  */
  
  current_function_decl = NULL_TREE;
}
Example #2
0
static void
construct_exit_block (void)
{
  rtx head = get_last_insn ();
  rtx end;
  basic_block exit_block;
  edge e, e2;
  unsigned ix;
  edge_iterator ei;

  /* Make sure the locus is set to the end of the function, so that
     epilogue line numbers and warnings are set properly.  */
#ifdef USE_MAPPED_LOCATION
  if (cfun->function_end_locus != UNKNOWN_LOCATION)
#else
  if (cfun->function_end_locus.file)
#endif
    input_location = cfun->function_end_locus;

  /* The following insns belong to the top scope.  */
  record_block_change (DECL_INITIAL (current_function_decl));

  /* Generate rtl for function exit.  */
  expand_function_end ();

  end = get_last_insn ();
  if (head == end)
    return;
  while (NEXT_INSN (head) && NOTE_P (NEXT_INSN (head)))
    head = NEXT_INSN (head);
  exit_block = create_basic_block (NEXT_INSN (head), end,
				   EXIT_BLOCK_PTR->prev_bb);
  exit_block->frequency = EXIT_BLOCK_PTR->frequency;
  exit_block->count = EXIT_BLOCK_PTR->count;

  ix = 0;
  while (ix < EDGE_COUNT (EXIT_BLOCK_PTR->preds))
    {
      e = EDGE_I (EXIT_BLOCK_PTR->preds, ix);
      if (!(e->flags & EDGE_ABNORMAL))
	redirect_edge_succ (e, exit_block);
      else
	ix++;
    }

  e = make_edge (exit_block, EXIT_BLOCK_PTR, EDGE_FALLTHRU);
  e->probability = REG_BR_PROB_BASE;
  e->count = EXIT_BLOCK_PTR->count;
  FOR_EACH_EDGE (e2, ei, EXIT_BLOCK_PTR->preds)
    if (e2 != e)
      {
        e->count -= e2->count;
	exit_block->count -= e2->count;
	exit_block->frequency -= EDGE_FREQUENCY (e2);
      }
  if (e->count < 0)
    e->count = 0;
  if (exit_block->count < 0)
    exit_block->count = 0;
  if (exit_block->frequency < 0)
    exit_block->frequency = 0;
  update_bb_for_insn (exit_block);
}
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;
}