diff options
Diffstat (limited to 'gcc/cfglayout.c')
-rw-r--r-- | gcc/cfglayout.c | 255 |
1 files changed, 113 insertions, 142 deletions
diff --git a/gcc/cfglayout.c b/gcc/cfglayout.c index 01784319c19..b40695fa306 100644 --- a/gcc/cfglayout.c +++ b/gcc/cfglayout.c @@ -48,7 +48,6 @@ static void record_effective_endpoints (void); static rtx label_for_bb (basic_block); static void fixup_reorder_chain (void); -static void set_block_levels (tree, int); static void change_scope (rtx, tree, tree); void verify_insn_chain (void); @@ -232,120 +231,111 @@ record_effective_endpoints (void) than the following one. Similarly for the other properties. */ static VEC(int,heap) *block_locators_locs; static GTY(()) VEC(tree,gc) *block_locators_blocks; -static VEC(int,heap) *line_locators_locs; -static VEC(int,heap) *line_locators_lines; -static VEC(int,heap) *file_locators_locs; -static GTY(()) varray_type file_locators_files; +static VEC(int,heap) *locations_locators_locs; +DEF_VEC_O(location_t); +DEF_VEC_ALLOC_O(location_t,heap); +static VEC(location_t,heap) *locations_locators_vals; int prologue_locator; int epilogue_locator; -/* During the RTL expansion the lexical blocks and line numbers are - represented via INSN_NOTEs. Replace them by representation using - INSN_LOCATORs. */ +/* Hold current location information and last location information, so the + datastructures are built lazilly only when some instructions in given + place are needed. */ +location_t curr_location, last_location; +static tree curr_block, last_block; +static int curr_rtl_loc = -1; -unsigned int -insn_locators_initialize (void) +/* Allocate insn locator datastructure. */ +void +insn_locators_alloc (void) { - tree block = NULL; - tree last_block = NULL; - rtx insn, next; - int loc = 0; - int line_number = 0, last_line_number = 0; - const char *file_name = NULL, *last_file_name = NULL; - prologue_locator = epilogue_locator = 0; block_locators_locs = VEC_alloc (int, heap, 32); block_locators_blocks = VEC_alloc (tree, gc, 32); - line_locators_locs = VEC_alloc (int, heap, 32); - line_locators_lines = VEC_alloc (int, heap, 32); - file_locators_locs = VEC_alloc (int, heap, 32); - VARRAY_CHAR_PTR_INIT (file_locators_files, 32, "file_locators_files"); - - for (insn = get_insns (); insn; insn = next) - { - int active = 0; - - next = NEXT_INSN (insn); - - if (NOTE_P (insn)) - { - gcc_assert (NOTE_LINE_NUMBER (insn) != NOTE_INSN_BLOCK_BEG - && NOTE_LINE_NUMBER (insn) != NOTE_INSN_BLOCK_END); - if (NOTE_LINE_NUMBER (insn) > 0) - { - expanded_location xloc; - NOTE_EXPANDED_LOCATION (xloc, insn); - line_number = xloc.line; - file_name = xloc.file; - delete_insn (insn); - } - } - else - active = (active_insn_p (insn) - && GET_CODE (PATTERN (insn)) != ADDR_VEC - && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC); - - check_block_change (insn, &block); + locations_locators_locs = VEC_alloc (int, heap, 32); + locations_locators_vals = VEC_alloc (location_t, heap, 32); + +#ifdef USE_MAPPED_LOCATION + last_location = -1; + curr_location = -1; +#else + last_location.line = -1; + curr_location.line = -1; +#endif + curr_block = NULL; + last_block = NULL; + curr_rtl_loc = 0; +} - if (active - || !next - || (!prologue_locator && file_name)) - { - if (last_block != block) - { - loc++; - VEC_safe_push (int, heap, block_locators_locs, loc); - VEC_safe_push (tree, gc, block_locators_blocks, block); - last_block = block; - } - if (last_line_number != line_number) - { - loc++; - VEC_safe_push (int, heap, line_locators_locs, loc); - VEC_safe_push (int, heap, line_locators_lines, line_number); - last_line_number = line_number; - } - if (last_file_name != file_name) - { - loc++; - VEC_safe_push (int, heap, file_locators_locs, loc); - VARRAY_PUSH_CHAR_PTR (file_locators_files, (char *) file_name); - last_file_name = file_name; - } - if (!prologue_locator && file_name) - prologue_locator = loc; - if (!next) - epilogue_locator = loc; - if (active) - INSN_LOCATOR (insn) = loc; - } - } +/* At the end of emit stage, clear current location. */ +void +insn_locators_finalize (void) +{ + if (curr_rtl_loc >= 0) + epilogue_locator = curr_insn_locator (); + curr_rtl_loc = -1; +} - /* Tag the blocks with a depth number so that change_scope can find - the common parent easily. */ - set_block_levels (DECL_INITIAL (cfun->decl), 0); +/* Set current location. */ +void +set_curr_insn_source_location (location_t location) +{ + /* IV opts calls into RTL expansion to compute costs of operations. At this + time locators are not initialized. */ + if (curr_rtl_loc == -1) + return; +#ifdef USE_MAPPED_LOCATION + if (location == last_location) + return; +#else + if (location.file && last_location.file + && !strcmp (location.file, last_location.file) + && location.line == last_location.line) + return; +#endif + curr_location = location; +} - free_block_changes (); - return 0; +/* Set current scope block. */ +void +set_curr_insn_block (tree b) +{ + /* IV opts calls into RTL expansion to compute costs of operations. At this + time locators are not initialized. */ + if (curr_rtl_loc == -1) + return; + if (b) + curr_block = b; } -struct tree_opt_pass pass_insn_locators_initialize = +/* Return current insn locator. */ +int +curr_insn_locator (void) { - "locators", /* name */ - NULL, /* gate */ - insn_locators_initialize, /* execute */ - NULL, /* sub */ - NULL, /* next */ - 0, /* static_pass_number */ - 0, /* tv_id */ - 0, /* properties_required */ - 0, /* properties_provided */ - 0, /* properties_destroyed */ - 0, /* todo_flags_start */ - TODO_dump_func, /* todo_flags_finish */ - 0 /* letter */ -}; + if (curr_rtl_loc == -1) + return 0; + if (last_block != curr_block) + { + curr_rtl_loc++; + VEC_safe_push (int, heap, block_locators_locs, curr_rtl_loc); + VEC_safe_push (tree, gc, block_locators_blocks, curr_block); + last_block = curr_block; + } +#ifdef USE_MAPPED_LOCATION + if (last_location != curr_location) +#else + if (last_location.file != curr_location.file + || last_location.line != curr_location.line) +#endif + { + curr_rtl_loc++; + VEC_safe_push (int, heap, locations_locators_locs, curr_rtl_loc); + VEC_safe_push (location_t, heap, locations_locators_vals, &curr_location); + last_location = curr_location; + } + return curr_rtl_loc; +} static unsigned int into_cfg_layout_mode (void) @@ -401,20 +391,6 @@ struct tree_opt_pass pass_outof_cfg_layout_mode = TODO_dump_func, /* todo_flags_finish */ 0 /* letter */ }; - -/* For each lexical block, set BLOCK_NUMBER to the depth at which it is - found in the block tree. */ - -static void -set_block_levels (tree block, int level) -{ - while (block) - { - BLOCK_NUMBER (block) = level; - set_block_levels (BLOCK_SUBBLOCKS (block), level + 1); - block = BLOCK_CHAIN (block); - } -} /* Return sope resulting from combination of S1 and S2. */ static tree @@ -514,18 +490,16 @@ insn_scope (rtx insn) } /* Return line number of the statement specified by the locator. */ -int -locator_line (int loc) +static location_t +locator_location (int loc) { - int max = VEC_length (int, line_locators_locs); + int max = VEC_length (int, locations_locators_locs); int min = 0; - if (!max || !loc) - return 0; while (1) { int pos = (min + max) / 2; - int tmp = VEC_index (int, line_locators_locs, pos); + int tmp = VEC_index (int, locations_locators_locs, pos); if (tmp <= loc && min != pos) min = pos; @@ -537,7 +511,19 @@ locator_line (int loc) break; } } - return VEC_index (int, line_locators_lines, min); + return *VEC_index (location_t, locations_locators_vals, min); +} + +/* Return source line of the statement that produced this insn. */ +int +locator_line (int loc) +{ + expanded_location xloc; + if (!loc) + return 0; + else + xloc = expand_location (locator_location (loc)); + return xloc.line; } /* Return line number of the statement that produced this insn. */ @@ -551,27 +537,12 @@ insn_line (rtx insn) const char * locator_file (int loc) { - int max = VEC_length (int, file_locators_locs); - int min = 0; - - if (!max || !loc) - return NULL; - while (1) - { - int pos = (min + max) / 2; - int tmp = VEC_index (int, file_locators_locs, pos); - - if (tmp <= loc && min != pos) - min = pos; - else if (tmp > loc && max != pos) - max = pos; - else - { - min = pos; - break; - } - } - return VARRAY_CHAR_PTR (file_locators_files, min); + expanded_location xloc; + if (!loc) + return 0; + else + xloc = expand_location (locator_location (loc)); + return xloc.file; } /* Return source file of the statement that produced this insn. */ |