/* 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; }
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); }
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; }