diff mbox

Combine location with block using block_locations

Message ID CAFiYyc0KmntyrbOReSCjLLL0Z-OeYn=6dZZ2AmV7JPgtEV6UbQ@mail.gmail.com
State New
Headers show

Commit Message

Richard Biener Aug. 2, 2012, 10:05 a.m. UTC
On Thu, Aug 2, 2012 at 5:23 AM, Dehao Chen <dehao@google.com> wrote:
> On Thu, Aug 2, 2012 at 2:07 AM, Richard Guenther
> <richard.guenther@gmail.com> wrote:
>> On Wed, Aug 1, 2012 at 7:35 AM, Dehao Chen <dehao@google.com> wrote:
>>> Hi,
>>>
>>> This patch:
>>>
>>> * Integrates location with block into an integrated index.
>>> * Removes gimple->gsbase.block and tree->exp.block fields.
>>> * Updates inline/clone as well as tree liveness analysis to ensure the
>>> associated blocks are updated correctly.
>>>
>>> With this patch, the association between source location and its block
>>> are greatly enhanced, which produces much better inline stack in the
>>> debug info.
>>>
>>> Bootstrapped and regression tested on x86.
>>>
>>> OK for trunk?
>>
>> Nice.  But the LTO changes mean that you simply drop all BLOCK
>> associations on the floor ...
>
> Why? I've invoked TREE_SET_BLOCK in tree-streamer-in.c to read in the
> block info. So it should at least provide the same info as the
> original impl.
>
>> they at least look very incomplete.  Did you actually run LTO tests?
>
> Thanks for the reminder, I've added the following change to this patch:
>
> Index: gcc/tree-streamer-out.c
> ===================================================================
> --- gcc/tree-streamer-out.c     (revision 189835)
> +++ gcc/tree-streamer-out.c     (working copy)
> @@ -471,7 +471,7 @@
>  {
>    stream_write_tree (ob, DECL_NAME (expr), ref_p);
>    stream_write_tree (ob, DECL_CONTEXT (expr), ref_p);
> -  lto_output_location (ob, DECL_SOURCE_LOCATION (expr));
> +  lto_output_location (ob, LOCATION_LOCUS (DECL_SOURCE_LOCATION (expr)));
>  }
>
> @@ -668,7 +668,7 @@
>    streamer_write_hwi (ob, TREE_OPERAND_LENGTH (expr));
>    for (i = 0; i < TREE_OPERAND_LENGTH (expr); i++)
>      stream_write_tree (ob, TREE_OPERAND (expr, i), ref_p);
> -  lto_output_location (ob, EXPR_LOCATION (expr));
> +  lto_output_location (ob, LOCATION_LOCUS (EXPR_LOCATION (expr)));
>    stream_write_tree (ob, TREE_BLOCK (expr), ref_p);
>  }

That doesn't match up with the change


(please remember to generate diffs with -p, so the function name is shown
in the diff hunk header)

> I think BLOCK associations works fine for LTO. I've run check-gcc, and
> there's no regression on LTO tests. I also manually write some tests,
> and the generated final assembly has block info as expected.

What about the lto_output_location calls in gimple-streamer-out.c?  As far as I
can see they will end up dropping the associated BLOCK on the floor (I cannot
see any change on the -input side).

>>
>> lto/ has its own ChangeLog
>
> Thanks, I'll update the ChangeLog accordingly.
>
>> and I wonder why no frontends are affected
>> by this patch?
>
> Which files are you referring to?

I was refering to the issue you brought up earlier - all the fold
routines losing
block associations.  Maybe you can elaborate some more how locator
is different from location, thus how you set up the machinery.

Thanks,
Richard.

> Thanks,
> Dehao
>
>>
>> Richard.
>>
>>> Thanks,
>>> Dehao
>>>
>>> You can also find the patch in http://codereview.appspot.com/6454077
>>>
>>> gcc/ChangeLog
>>> 2012-08-01  Dehao Chen  <dehao@google.com>
>>>
>>>         * toplev.c (general_init): Init block_locations.
>>>         * tree.c (tree_set_block): New.
>>>         (tree_block): Change to use LOCATION_BLOCK.
>>>         * tree.h (TREE_SET_BLOCK): New.
>>>         * final.c (reemit_insn_block_notes): Change to use LOCATION_BLOCK.
>>>         (final_start_function): Likewise.
>>>         * input.c (expand_location_1): Likewise.
>>>         * input.h (LOCATION_LOCUS): New.
>>>         (LOCATION_BLOCK): New.
>>>         (IS_UNKNOWN_LOCATION): New.
>>>         * fold-const.c (expr_location_or): Change to use new location.
>>>         * reorg.c (emit_delay_sequence): Likewise.
>>>         (try_merge_delay_insns): Likewise.
>>>         * modulo-sched.c (dump_insn_location): Likewise.
>>>         * lto-streamer-out.c (lto_output_location_bitpack): Likewise.
>>>         * jump.c (rtx_renumbered_equal_p): Likewise.
>>>         * ifcvt.c (noce_try_move): Likewise.
>>>         (noce_try_store_flag): Likewise.
>>>         (noce_try_store_flag_constants): Likewise.
>>>         (noce_try_addcc): Likewise.
>>>         (noce_try_store_flag_mask): Likewise.
>>>         (noce_try_cmove): Likewise.
>>>         (noce_try_cmove_arith): Likewise.
>>>         (noce_try_minmax): Likewise.
>>>         (noce_try_abs): Likewise.
>>>         (noce_try_sign_mask): Likewise.
>>>         (noce_try_bitop): Likewise.
>>>         (noce_process_if_block): Likewise.
>>>         (cond_move_process_if_block): Likewise.
>>>         (find_cond_trap): Likewise.
>>>         * dewarf2out.c (add_src_coords_attributes): Likewise.
>>>         * expr.c (expand_expr_real): Likewise.
>>>         * tree-parloops.c (create_loop_fn): Likewise.
>>>         * recog.c (peep2_attempt): Likewise.
>>>         * function.c (free_after_compilation): Likewise.
>>>         (expand_function_end): Likewise.
>>>         (set_insn_locations): Likewise.
>>>         (thread_prologue_and_epilogue_insns): Likewise.
>>>         * print-rtl.c (print_rtx): Likewise.
>>>         * profile.c (branch_prob): Likewise.
>>>         * trans-mem.c (ipa_tm_scan_irr_block): Likewise.
>>>         * gimplify.c (gimplify_call_expr): Likewise.
>>>         * except.c (duplicate_eh_regions_1): Likewise.
>>>         * emit-rtl.c (try_split): Likewise.
>>>         (make_insn_raw): Likewise.
>>>         (make_debug_insn_raw): Likewise.
>>>         (make_jump_insn_raw): Likewise.
>>>         (make_call_insn_raw): Likewise.
>>>         (emit_pattern_after_setloc): Likewise.
>>>         (emit_pattern_after): Likewise.
>>>         (emit_debug_insn_after): Likewise.
>>>         (emit_pattern_before): Likewise.
>>>         (emit_insn_before_setloc): Likewise.
>>>         (emit_jump_insn_before): Likewise.
>>>         (emit_call_insn_before_setloc): Likewise.
>>>         (emit_call_insn_before): Likeise.
>>>         (emit_debug_insn_before_setloc): Likewise.
>>>         (emit_copy_of_insn_after): Likewise.
>>>         (insn_locators_alloc): Remove.
>>>         (insn_locators_finalize): Remove.
>>>         (insn_locators_free): Remove.
>>>         (set_curr_insn_source_location): Remove.
>>>         (get_curr_insn_source_location): Remove.
>>>         (set_curr_insn_block): Remove.
>>>         (get_curr_insn_block): Remove.
>>>         (locator_scope): Remove.
>>>         (insn_scope): Change to use new location.
>>>         (locator_location): Remove.
>>>         (insn_line): Change to use new location.
>>>         (locator_file): Remove.
>>>         (insn_file): Change to use new location.
>>>         (locator_eq): Remove.
>>>         (insn_locations_init): New.
>>>         (insn_locations_finalize): New.
>>>         (set_curr_insn_location): New.
>>>         (curr_insn_location): New.
>>>         * cfgexpand.c (gimple_assign_rhs_to_tree): Change to use new location.
>>>         (expand_gimple_cond): Likewise.
>>>         (expand_call_stmt): Likewise.
>>>         (expand_gimple_stmt_1): Likewise.
>>>         (expand_gimple_basic_block): Likewise.
>>>         (construct_exit_block): Likewise.
>>>         (gimple_expand_cfg): Likewise.
>>>         * cfgcleanup.c (try_forward_edges): Likewise.
>>>         * tree-ssa-live.c (remove_unused_scope_block_p): Likewise.
>>>         (dump_scope_block): Likewise.
>>>         (remove_unused_locals): Likewise.
>>>         * lto/lto.c (lto_fixup_prevailing_decls): Likewise.
>>>         * rtl.c (rtx_equal_p_cb): Likewise.
>>>         (rtx_equal_p): Likewise.
>>>         * rtl.h (XUINT): New.
>>>         (INSN_LOCATOR): Remove.
>>>         (CURR_INSN_LOCATION): Remove.
>>>         (INSN_LOCATION): New.
>>>         (INSN_HAS_LOCATION): New.
>>>         * tree-inline.c (remap_gimple_op_r): Change to use new location.
>>>         (copy_tree_body_r): Likewise.
>>>         (copy_phis_for_bb): Likewise.
>>>         (expand_call_inline): Likewise.
>>>         * tree-streamer-in.c (lto_input_ts_exp_tree_pointers): Likewise.
>>>         * combine.c (try_combine): Likewise.
>>>         * tree-outof-ssa.c (set_location_for_edge): Likewise.
>>>         (insert_partition_copy_on_edge): Likewise.
>>>         (insert_value_copy_on_edge): Likewise.
>>>         (insert_rtx_to_part_on_edge): Likewise.
>>>         (insert_part_to_rtx_on_edge): Likewise.
>>>         * basic-block.h (edge_def): Remove field.
>>>         * gimple.h (gimple_statement_base): Remove field.
>>>         (gimple_bb): Change to use new location.
>>>         (gimple_set_block): Likewise.
>>>         (gimple_has_location): Likewise.
>>>         * tree-cfg.c (make_cond_expr_edges): Likewise.
>>>         (make_goto_expr_edges): Likewise.
>>>         (gimple_can_merge_blocks_p): Likewise.
>>>         (move_stmt_op): Likewise.
>>>         (move_block_to_fn): Likewise.
>>>         * config/alpha/alpha.c (alpha_output_mi_thunk_osf): Likewise.
>>>         * config/sparc/sparc.c (sparc_output_mi_thunk): Likewise.
>>>         * config/i386/i386.c (x86_output_mi_thunk): Likewise.
>>>         * config/tilegx/tilegx.c (tilegx_output_mi_thunk): Likewise.
>>>         * config/sh/sh.c (sh_output_mi_thunk): Likewise.
>>>         * config/ia64/ia64.c (ia64_output_mi_thunk): Likewise.
>>>         * config/rs6000/rs6000.c (rs6000_output_mi_thunk): Likewise.
>>>         * config/score/score.c (score_output_mi_thunk): Likewise.
>>>         * config/tilepro/tilepro.c (tilepro_asm_output_mi_thunk): Likewise.
>>>         * config/mips/mips.c (mips_output_mi_thunk): Likewise.
>>>         * cfgrtl.c (unique_locus_on_edge_between_p): Likewise.
>>>         (unique_locus_on_edge_between_p): Likewise.
>>>         (emit_nop_for_unique_locus_between): Likewise.
>>>         (force_nonfallthru_and_redirect): Likewise.
>>>         (fixup_reorder_chain): Likewise.
>>>         (cfg_layout_merge_blocks): Likewise.
>>>         * stmt.c (emit_case_nodes): Likewise.
>>>
>>> libcpp/ChangeLog
>>> 2012-08-01  Dehao Chen  <dehao@google.com>
>>>
>>>         * include/line-map.h (MAX_SOURCE_LOCATION): New value.
>>>         (location_block_init): New.
>>>         (location_block_fini): New.
>>>         (get_combine_location): New.
>>>         (get_block_from_location): New.
>>>         (get_locus_from_location): New.
>>>         (COMBINE_LOCATION): New.
>>>         (IS_COMBINED_LOCATION): New.
>>>         (expanded_location): New field.
>>>         * line-map.c (location_block): New.
>>>         (location_block_htab): New.
>>>         (curr_combined_location): New.
>>>         (location_blocks): New.
>>>         (allocated_location_blocks): New.
>>>         (location_block_hash): New.
>>>         (location_block_eq): New.
>>>         (location_block_update): New.
>>>         (get_combine_location): New.
>>>         (get_block_from_location): New.
>>>         (get_locus_from_location): New.
>>>         (location_block_init): New.
>>>         (location_block_fini): New.
>>>         (linemap_lookup): Change to use new location.
>>>         (linemap_ordinary_map_lookup): Likewise.
>>>         (linemap_macro_map_lookup): Likewise.
>>>         (linemap_macro_map_loc_to_def_point): Likewise.
>>>         (linemap_macro_map_loc_unwind_toward_spel): Likewise.
>>>         (linemap_get_expansion_line): Likewise.
>>>         (linemap_get_expansion_filename): Likewise.
>>>         (linemap_location_in_system_header_p): Likewise.
>>>         (linemap_location_from_macro_expansion_p): Likewise.
>>>         (linemap_macro_loc_to_spelling_point): Likewise.
>>>         (linemap_macro_loc_to_def_point): Likewise.
>>>         (linemap_macro_loc_to_exp_point): Likewise.
>>>         (linemap_resolve_location): Likewise.
>>>         (linemap_unwind_toward_expansion): Likewise.
>>>         (linemap_unwind_to_first_non_reserved_loc): Likewise.
>>>         (linemap_expand_location): Likewise.
>>>         (linemap_dump_location): Likewise.
>>>
>>> Index: gcc/tree.c
>>> ===================================================================
>>> --- gcc/tree.c  (revision 189835)
>>> +++ gcc/tree.c  (working copy)
>>> @@ -3765,7 +3765,6 @@
>>>    TREE_TYPE (t) = type;
>>>    SET_EXPR_LOCATION (t, UNKNOWN_LOCATION);
>>>    TREE_OPERAND (t, 0) = node;
>>> -  TREE_BLOCK (t) = NULL_TREE;
>>>    if (node && !TYPE_P (node))
>>>      {
>>>        TREE_SIDE_EFFECTS (t) = TREE_SIDE_EFFECTS (node);
>>> @@ -10867,17 +10866,28 @@
>>>  }
>>>
>>>
>>> -tree *
>>> +tree
>>>  tree_block (tree t)
>>>  {
>>>    char const c = TREE_CODE_CLASS (TREE_CODE (t));
>>>
>>>    if (IS_EXPR_CODE_CLASS (c))
>>> -    return &t->exp.block;
>>> +    return LOCATION_BLOCK (t->exp.locus);
>>>    gcc_unreachable ();
>>>    return NULL;
>>>  }
>>>
>>> +void
>>> +tree_set_block (tree t, tree b)
>>> +{
>>> +  char const c = TREE_CODE_CLASS (TREE_CODE (t));
>>> +
>>> +  if (IS_EXPR_CODE_CLASS (c))
>>> +    t->exp.locus = COMBINE_LOCATION (t->exp.locus, b);
>>> +  else
>>> +    gcc_unreachable ();
>>> +}
>>> +
>>>  /* Create a nameless artificial label and put it in the current
>>>     function context.  The label has a location of LOC.  Returns the
>>>     newly created label.  */
>>> Index: gcc/tree.h
>>> ===================================================================
>>> --- gcc/tree.h  (revision 189835)
>>> +++ gcc/tree.h  (working copy)
>>> @@ -999,7 +999,8 @@
>>>
>>>  #endif
>>>
>>> -#define TREE_BLOCK(NODE)               *(tree_block (NODE))
>>> +#define TREE_BLOCK(NODE)               (tree_block (NODE))
>>> +#define TREE_SET_BLOCK(T, B)           (tree_set_block ((T), (B)))
>>>
>>>  #include "tree-check.h"
>>>
>>> @@ -1702,7 +1703,7 @@
>>>  #define EXPR_LOCATION(NODE) \
>>>    (CAN_HAVE_LOCATION_P ((NODE)) ? (NODE)->exp.locus : UNKNOWN_LOCATION)
>>>  #define SET_EXPR_LOCATION(NODE, LOCUS) EXPR_CHECK ((NODE))->exp.locus = (LOCUS)
>>> -#define EXPR_HAS_LOCATION(NODE) (EXPR_LOCATION (NODE) != UNKNOWN_LOCATION)
>>> +#define EXPR_HAS_LOCATION(NODE) (!IS_UNKNOWN_LOCATION (EXPR_LOCATION (NODE)))
>>>  /* The location to be used in a diagnostic about this expression.  Do not
>>>     use this macro if the location will be assigned to other expressions.  */
>>>  #define EXPR_LOC_OR_HERE(NODE) (EXPR_HAS_LOCATION (NODE) ?
>>> (NODE)->exp.locus : input_location)
>>> @@ -1881,7 +1882,7 @@
>>>                                               OMP_CLAUSE_PRIVATE,       \
>>>                                               OMP_CLAUSE_COPYPRIVATE), 0)
>>>  #define OMP_CLAUSE_HAS_LOCATION(NODE) \
>>> -  ((OMP_CLAUSE_CHECK (NODE))->omp_clause.locus != UNKNOWN_LOCATION)
>>> +  (!IS_UNKNOWN_LOCATION ((OMP_CLAUSE_CHECK (NODE))->omp_clause.locus))
>>>  #define OMP_CLAUSE_LOCATION(NODE)  (OMP_CLAUSE_CHECK (NODE))->omp_clause.locus
>>>
>>>  /* True on an OMP_SECTION statement that was the last lexical member.
>>> @@ -1972,7 +1973,6 @@
>>>  struct GTY(()) tree_exp {
>>>    struct tree_typed typed;
>>>    location_t locus;
>>> -  tree block;
>>>    tree GTY ((special ("tree_exp"),
>>>              desc ("TREE_CODE ((tree) &%0)")))
>>>      operands[1];
>>> @@ -5164,7 +5164,7 @@
>>>  static inline bool
>>>  inlined_function_outer_scope_p (const_tree block)
>>>  {
>>> - return BLOCK_SOURCE_LOCATION (block) != UNKNOWN_LOCATION;
>>> + return !IS_UNKNOWN_LOCATION (BLOCK_SOURCE_LOCATION (block));
>>>  }
>>>
>>>  /* Loop over all function arguments of FNTYPE.  In each iteration, PTR is set
>>> @@ -5539,7 +5539,8 @@
>>>  extern HOST_WIDE_INT int_cst_value (const_tree);
>>>  extern HOST_WIDEST_INT widest_int_cst_value (const_tree);
>>>
>>> -extern tree *tree_block (tree);
>>> +extern tree tree_block (tree);
>>> +extern void tree_set_block (tree, tree);
>>>  extern location_t *block_nonartificial_location (tree);
>>>  extern location_t tree_nonartificial_location (tree);
>>>
>>> Index: gcc/final.c
>>> ===================================================================
>>> --- gcc/final.c (revision 189835)
>>> +++ gcc/final.c (working copy)
>>> @@ -1605,7 +1605,7 @@
>>>                                              insn_scope (XVECEXP (body, 0, i)));
>>>         }
>>>        if (! this_block)
>>> -       continue;
>>> +       this_block = DECL_INITIAL (cfun->decl);
>>>
>>>        if (this_block != cur_block)
>>>         {
>>> @@ -1640,8 +1640,8 @@
>>>
>>>    this_is_asm_operands = 0;
>>>
>>> -  last_filename = locator_file (prologue_locator);
>>> -  last_linenum = locator_line (prologue_locator);
>>> +  last_filename = LOCATION_FILE (prologue_location);
>>> +  last_linenum = LOCATION_LINE (prologue_location);
>>>    last_discriminator = discriminator = 0;
>>>
>>>    high_block_linenum = high_function_linenum = last_linenum;
>>> Index: gcc/input.c
>>> ===================================================================
>>> --- gcc/input.c (revision 189835)
>>> +++ gcc/input.c (working copy)
>>> @@ -51,6 +51,13 @@
>>>    expanded_location xloc;
>>>    const struct line_map *map;
>>>    enum location_resolution_kind lrk = LRK_MACRO_EXPANSION_POINT;
>>> +  tree block = NULL;
>>> +
>>> +  if (IS_COMBINED_LOCATION (loc))
>>> +    {
>>> +      block = LOCATION_BLOCK (loc);
>>> +      loc = LOCATION_LOCUS (loc);
>>> +    }
>>>
>>>    memset (&xloc, 0, sizeof (xloc));
>>>
>>> @@ -74,6 +81,7 @@
>>>        xloc = linemap_expand_location (line_table, map, loc);
>>>      }
>>>
>>> +  xloc.block = block;
>>>    if (loc <= BUILTINS_LOCATION)
>>>      xloc.file = loc == UNKNOWN_LOCATION ? NULL : _("<built-in>");
>>>
>>> Index: gcc/input.h
>>> ===================================================================
>>> --- gcc/input.h (revision 189835)
>>> +++ gcc/input.h (working copy)
>>> @@ -51,6 +51,14 @@
>>>  #define LOCATION_FILE(LOC) ((expand_location (LOC)).file)
>>>  #define LOCATION_LINE(LOC) ((expand_location (LOC)).line)
>>>  #define LOCATION_COLUMN(LOC)((expand_location (LOC)).column)
>>> +#define LOCATION_LOCUS(LOC) \
>>> +  ((IS_COMBINED_LOCATION(LOC)) ? get_locus_from_location (LOC) : (LOC))
>>> +#define LOCATION_BLOCK(LOC) \
>>> +  ((tree) ((IS_COMBINED_LOCATION (LOC)) ? get_block_from_location (LOC) \
>>> +  : NULL))
>>> +#define IS_UNKNOWN_LOCATION(LOC) \
>>> +  ((IS_COMBINED_LOCATION (LOC)) ? get_locus_from_location (LOC) == 0 \
>>> +  : (LOC) == 0)
>>>
>>>  #define input_line LOCATION_LINE (input_location)
>>>  #define input_filename LOCATION_FILE (input_location)
>>> Index: gcc/fold-const.c
>>> ===================================================================
>>> --- gcc/fold-const.c    (revision 189835)
>>> +++ gcc/fold-const.c    (working copy)
>>> @@ -145,7 +145,7 @@
>>>  expr_location_or (tree t, location_t loc)
>>>  {
>>>    location_t tloc = EXPR_LOCATION (t);
>>> -  return tloc != UNKNOWN_LOCATION ? tloc : loc;
>>> +  return IS_UNKNOWN_LOCATION (tloc) ? loc : tloc;
>>>  }
>>>
>>>  /* Similar to protected_set_expr_location, but never modify x in place,
>>> Index: gcc/toplev.c
>>> ===================================================================
>>> --- gcc/toplev.c        (revision 189835)
>>> +++ gcc/toplev.c        (working copy)
>>> @@ -1140,6 +1140,7 @@
>>>    linemap_init (line_table);
>>>    line_table->reallocator = realloc_for_line_map;
>>>    line_table->round_alloc_size = ggc_round_alloc_size;
>>> +  location_block_init ();
>>>    init_ttree ();
>>>
>>>    /* Initialize register usage now so switches may override.  */
>>> @@ -1946,6 +1947,7 @@
>>>    invoke_plugin_callbacks (PLUGIN_FINISH, NULL);
>>>
>>>    finalize_plugins ();
>>> +  location_block_fini ();
>>>    if (seen_error ())
>>>      return (FATAL_EXIT_CODE);
>>>
>>> Index: gcc/reorg.c
>>> ===================================================================
>>> --- gcc/reorg.c (revision 189835)
>>> +++ gcc/reorg.c (working copy)
>>> @@ -545,7 +545,7 @@
>>>    INSN_DELETED_P (delay_insn) = 0;
>>>    PREV_INSN (delay_insn) = PREV_INSN (seq_insn);
>>>
>>> -  INSN_LOCATOR (seq_insn) = INSN_LOCATOR (delay_insn);
>>> +  INSN_LOCATION (seq_insn) = INSN_LOCATION (delay_insn);
>>>
>>>    for (li = list; li; li = XEXP (li, 1), i++)
>>>      {
>>> @@ -561,9 +561,9 @@
>>>
>>>        /* SPARC assembler, for instance, emit warning when debug info is output
>>>           into the delay slot.  */
>>> -      if (INSN_LOCATOR (tem) && !INSN_LOCATOR (seq_insn))
>>> -       INSN_LOCATOR (seq_insn) = INSN_LOCATOR (tem);
>>> -      INSN_LOCATOR (tem) = 0;
>>> +      if (INSN_LOCATION (tem) && !INSN_LOCATION (seq_insn))
>>> +       INSN_LOCATION (seq_insn) = INSN_LOCATION (tem);
>>> +      INSN_LOCATION (tem) = 0;
>>>
>>>        for (note = REG_NOTES (tem); note; note = next)
>>>         {
>>> @@ -4087,7 +4087,7 @@
>>>      for (link = crtl->epilogue_delay_list;
>>>           link;
>>>           link = XEXP (link, 1))
>>> -      INSN_LOCATOR (XEXP (link, 0)) = 0;
>>> +      INSN_LOCATION (XEXP (link, 0)) = 0;
>>>    }
>>>
>>>  #endif
>>> Index: gcc/modulo-sched.c
>>> ===================================================================
>>> --- gcc/modulo-sched.c  (revision 189835)
>>> +++ gcc/modulo-sched.c  (working copy)
>>> @@ -1246,9 +1246,9 @@
>>>  /* Dump file:line from INSN's location info to dump_file.  */
>>>
>>>  static void
>>> -dump_insn_locator (rtx insn)
>>> +dump_insn_location (rtx insn)
>>>  {
>>> -  if (dump_file && INSN_LOCATOR (insn))
>>> +  if (dump_file && INSN_LOCATION (insn))
>>>      {
>>>        const char *file = insn_file (insn);
>>>        if (file)
>>> @@ -1282,7 +1282,7 @@
>>>           rtx insn = BB_END (loop->header);
>>>
>>>           fprintf (dump_file, "SMS loop many exits");
>>> -         dump_insn_locator (insn);
>>> +         dump_insn_location (insn);
>>>           fprintf (dump_file, "\n");
>>>         }
>>>        return false;
>>> @@ -1295,7 +1295,7 @@
>>>           rtx insn = BB_END (loop->header);
>>>
>>>           fprintf (dump_file, "SMS loop many BBs.");
>>> -         dump_insn_locator (insn);
>>> +         dump_insn_location (insn);
>>>           fprintf (dump_file, "\n");
>>>         }
>>>        return false;
>>> @@ -1421,7 +1421,7 @@
>>>           rtx insn = BB_END (loop->header);
>>>
>>>           fprintf (dump_file, "SMS loop num: %d", loop->num);
>>> -         dump_insn_locator (insn);
>>> +         dump_insn_location (insn);
>>>           fprintf (dump_file, "\n");
>>>         }
>>>
>>> @@ -1450,7 +1450,7 @@
>>>         {
>>>           if (dump_file)
>>>             {
>>> -             dump_insn_locator (tail);
>>> +             dump_insn_location (tail);
>>>               fprintf (dump_file, "\nSMS single-bb-loop\n");
>>>               if (profile_info && flag_branch_probabilities)
>>>                 {
>>> @@ -1556,7 +1556,7 @@
>>>           rtx insn = BB_END (loop->header);
>>>
>>>           fprintf (dump_file, "SMS loop num: %d", loop->num);
>>> -         dump_insn_locator (insn);
>>> +         dump_insn_location (insn);
>>>           fprintf (dump_file, "\n");
>>>
>>>           print_ddg (dump_file, g);
>>> @@ -1571,7 +1571,7 @@
>>>
>>>        if (dump_file)
>>>         {
>>> -         dump_insn_locator (tail);
>>> +         dump_insn_location (tail);
>>>           fprintf (dump_file, "\nSMS single-bb-loop\n");
>>>           if (profile_info && flag_branch_probabilities)
>>>             {
>>> @@ -1714,7 +1714,7 @@
>>>
>>>            if (dump_file)
>>>              {
>>> -             dump_insn_locator (tail);
>>> +             dump_insn_location (tail);
>>>               fprintf (dump_file, " SMS succeeded %d %d (with ii, sc)\n",
>>>                        ps->ii, stage_count);
>>>               print_partial_schedule (ps, dump_file);
>>> Index: gcc/lto-streamer-out.c
>>> ===================================================================
>>> --- gcc/lto-streamer-out.c      (revision 189835)
>>> +++ gcc/lto-streamer-out.c      (working copy)
>>> @@ -155,6 +155,7 @@
>>>  {
>>>    expanded_location xloc;
>>>
>>> +  loc = LOCATION_LOCUS (loc);
>>>    bp_pack_value (bp, loc == UNKNOWN_LOCATION, 1);
>>>    if (loc == UNKNOWN_LOCATION)
>>>      return;
>>> Index: gcc/jump.c
>>> ===================================================================
>>> --- gcc/jump.c  (revision 189835)
>>> +++ gcc/jump.c  (working copy)
>>> @@ -1818,8 +1818,7 @@
>>>           if (XINT (x, i) != XINT (y, i))
>>>             {
>>>               if (((code == ASM_OPERANDS && i == 6)
>>> -                  || (code == ASM_INPUT && i == 1))
>>> -                 && locator_eq (XINT (x, i), XINT (y, i)))
>>> +                  || (code == ASM_INPUT && i == 1)))
>>>                 break;
>>>               return 0;
>>>             }
>>> Index: gcc/ifcvt.c
>>> ===================================================================
>>> --- gcc/ifcvt.c (revision 189835)
>>> +++ gcc/ifcvt.c (working copy)
>>> @@ -1019,7 +1019,7 @@
>>>             return FALSE;
>>>
>>>           emit_insn_before_setloc (seq, if_info->jump,
>>> -                                  INSN_LOCATOR (if_info->insn_a));
>>> +                                  INSN_LOCATION (if_info->insn_a));
>>>         }
>>>        return TRUE;
>>>      }
>>> @@ -1064,7 +1064,7 @@
>>>         return FALSE;
>>>
>>>        emit_insn_before_setloc (seq, if_info->jump,
>>> -                              INSN_LOCATOR (if_info->insn_a));
>>> +                              INSN_LOCATION (if_info->insn_a));
>>>        return TRUE;
>>>      }
>>>    else
>>> @@ -1195,7 +1195,7 @@
>>>         return FALSE;
>>>
>>>        emit_insn_before_setloc (seq, if_info->jump,
>>> -                              INSN_LOCATOR (if_info->insn_a));
>>> +                              INSN_LOCATION (if_info->insn_a));
>>>        return TRUE;
>>>      }
>>>
>>> @@ -1243,7 +1243,7 @@
>>>                 return FALSE;
>>>
>>>               emit_insn_before_setloc (seq, if_info->jump,
>>> -                                      INSN_LOCATOR (if_info->insn_a));
>>> +                                      INSN_LOCATION (if_info->insn_a));
>>>               return TRUE;
>>>             }
>>>           end_sequence ();
>>> @@ -1283,7 +1283,7 @@
>>>                 return FALSE;
>>>
>>>               emit_insn_before_setloc (seq, if_info->jump,
>>> -                                      INSN_LOCATOR (if_info->insn_a));
>>> +                                      INSN_LOCATION (if_info->insn_a));
>>>               return TRUE;
>>>             }
>>>           end_sequence ();
>>> @@ -1332,7 +1332,7 @@
>>>             return FALSE;
>>>
>>>           emit_insn_before_setloc (seq, if_info->jump,
>>> -                                  INSN_LOCATOR (if_info->insn_a));
>>> +                                  INSN_LOCATION (if_info->insn_a));
>>>           return TRUE;
>>>         }
>>>
>>> @@ -1481,7 +1481,7 @@
>>>             return FALSE;
>>>
>>>           emit_insn_before_setloc (seq, if_info->jump,
>>> -                                  INSN_LOCATOR (if_info->insn_a));
>>> +                                  INSN_LOCATION (if_info->insn_a));
>>>           return TRUE;
>>>         }
>>>        else
>>> @@ -1682,7 +1682,7 @@
>>>    if (!tmp)
>>>      return FALSE;
>>>
>>> -  emit_insn_before_setloc (tmp, if_info->jump, INSN_LOCATOR (if_info->insn_a));
>>> +  emit_insn_before_setloc (tmp, if_info->jump, INSN_LOCATION
>>> (if_info->insn_a));
>>>    return TRUE;
>>>
>>>   end_seq_and_fail:
>>> @@ -1929,7 +1929,7 @@
>>>    if (!seq)
>>>      return FALSE;
>>>
>>> -  emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATOR (if_info->insn_a));
>>> +  emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION
>>> (if_info->insn_a));
>>>    if_info->cond = cond;
>>>    if_info->cond_earliest = earliest;
>>>
>>> @@ -2076,7 +2076,7 @@
>>>    if (!seq)
>>>      return FALSE;
>>>
>>> -  emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATOR (if_info->insn_a));
>>> +  emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION
>>> (if_info->insn_a));
>>>    if_info->cond = cond;
>>>    if_info->cond_earliest = earliest;
>>>
>>> @@ -2155,7 +2155,7 @@
>>>    if (!seq)
>>>      return FALSE;
>>>
>>> -  emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATOR (if_info->insn_a));
>>> +  emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION
>>> (if_info->insn_a));
>>>    return TRUE;
>>>  }
>>>
>>> @@ -2255,7 +2255,7 @@
>>>         return FALSE;
>>>
>>>        emit_insn_before_setloc (seq, if_info->jump,
>>> -                              INSN_LOCATOR (if_info->insn_a));
>>> +                              INSN_LOCATION (if_info->insn_a));
>>>      }
>>>    return TRUE;
>>>  }
>>> @@ -2656,7 +2656,7 @@
>>>        unshare_all_rtl_in_chain (seq);
>>>        end_sequence ();
>>>
>>> -      emit_insn_before_setloc (seq, BB_END (test_bb), INSN_LOCATOR (insn_a));
>>> +      emit_insn_before_setloc (seq, BB_END (test_bb), INSN_LOCATION (insn_a));
>>>      }
>>>
>>>    /* The original THEN and ELSE blocks may now be removed.  The test block
>>> @@ -2937,7 +2937,7 @@
>>>        loc_insn = first_active_insn (else_bb);
>>>        gcc_assert (loc_insn);
>>>      }
>>> -  emit_insn_before_setloc (seq, jump, INSN_LOCATOR (loc_insn));
>>> +  emit_insn_before_setloc (seq, jump, INSN_LOCATION (loc_insn));
>>>
>>>    if (else_bb)
>>>      {
>>> @@ -3655,7 +3655,7 @@
>>>      return FALSE;
>>>
>>>    /* Emit the new insns before cond_earliest.  */
>>> -  emit_insn_before_setloc (seq, cond_earliest, INSN_LOCATOR (trap));
>>> +  emit_insn_before_setloc (seq, cond_earliest, INSN_LOCATION (trap));
>>>
>>>    /* Delete the trap block if possible.  */
>>>    remove_edge (trap_bb == then_bb ? then_edge : else_edge);
>>> Index: gcc/dwarf2out.c
>>> ===================================================================
>>> --- gcc/dwarf2out.c     (revision 189835)
>>> +++ gcc/dwarf2out.c     (working copy)
>>> @@ -15506,7 +15506,7 @@
>>>  {
>>>    expanded_location s;
>>>
>>> -  if (DECL_SOURCE_LOCATION (decl) == UNKNOWN_LOCATION)
>>> +  if (IS_UNKNOWN_LOCATION (DECL_SOURCE_LOCATION (decl)))
>>>      return;
>>>    s = expand_location (DECL_SOURCE_LOCATION (decl));
>>>    add_AT_file (die, DW_AT_decl_file, lookup_filename (s.file));
>>> Index: gcc/expr.c
>>> ===================================================================
>>> --- gcc/expr.c  (revision 189835)
>>> +++ gcc/expr.c  (working copy)
>>> @@ -7802,19 +7802,14 @@
>>>    if (cfun && EXPR_HAS_LOCATION (exp))
>>>      {
>>>        location_t saved_location = input_location;
>>> -      location_t saved_curr_loc = get_curr_insn_source_location ();
>>> -      tree saved_block = get_curr_insn_block ();
>>> +      location_t saved_curr_loc = curr_insn_location ();
>>>        input_location = EXPR_LOCATION (exp);
>>> -      set_curr_insn_source_location (input_location);
>>> -
>>> -      /* Record where the insns produced belong.  */
>>> -      set_curr_insn_block (TREE_BLOCK (exp));
>>> +      set_curr_insn_location (input_location);
>>>
>>>        ret = expand_expr_real_1 (exp, target, tmode, modifier, alt_rtl);
>>>
>>>        input_location = saved_location;
>>> -      set_curr_insn_block (saved_block);
>>> -      set_curr_insn_source_location (saved_curr_loc);
>>> +      set_curr_insn_location (saved_curr_loc);
>>>      }
>>>    else
>>>      {
>>> Index: gcc/predict.c
>>> ===================================================================
>>> --- gcc/predict.c       (revision 189835)
>>> +++ gcc/predict.c       (working copy)
>>> @@ -2177,7 +2177,7 @@
>>>  {
>>>    unsigned nb_loops;
>>>
>>> -  loop_optimizer_init (0);
>>> +  loop_optimizer_init (LOOPS_NORMAL);
>>>    if (dump_file && (dump_flags & TDF_DETAILS))
>>>      flow_loops_dump (dump_file, NULL, 0);
>>>
>>> Index: gcc/tree-parloops.c
>>> ===================================================================
>>> --- gcc/tree-parloops.c (revision 189835)
>>> +++ gcc/tree-parloops.c (working copy)
>>> @@ -1415,6 +1415,7 @@
>>>    struct function *act_cfun = cfun;
>>>    static unsigned loopfn_num;
>>>
>>> +  loc = LOCATION_LOCUS (loc);
>>>    snprintf (buf, 100, "%s.$loopfn", current_function_name ());
>>>    ASM_FORMAT_PRIVATE_NAME (tname, buf, loopfn_num++);
>>>    clean_symbol_name (tname);
>>> Index: gcc/recog.c
>>> ===================================================================
>>> --- gcc/recog.c (revision 189835)
>>> +++ gcc/recog.c (working copy)
>>> @@ -3333,7 +3333,7 @@
>>>    /* Replace the old sequence with the new.  */
>>>    last = emit_insn_after_setloc (attempt,
>>>                                  peep2_insn_data[i].insn,
>>> -                                INSN_LOCATOR (peep2_insn_data[i].insn));
>>> +                                INSN_LOCATION (peep2_insn_data[i].insn));
>>>    before_try = PREV_INSN (insn);
>>>    delete_insn_chain (insn, peep2_insn_data[i].insn, false);
>>>
>>> Index: gcc/function.c
>>> ===================================================================
>>> --- gcc/function.c      (revision 189835)
>>> +++ gcc/function.c      (working copy)
>>> @@ -133,7 +133,7 @@
>>>  static void prepare_function_start (void);
>>>  static void do_clobber_return_reg (rtx, void *);
>>>  static void do_use_return_reg (rtx, void *);
>>> -static void set_insn_locators (rtx, int) ATTRIBUTE_UNUSED;
>>> +static void set_insn_locations (rtx, int) ATTRIBUTE_UNUSED;
>>>
>>>  /* Stack of nested functions.  */
>>>  /* Keep track of the cfun stack.  */
>>> @@ -200,7 +200,6 @@
>>>    f->cfg = NULL;
>>>
>>>    regno_reg_rtx = NULL;
>>> -  insn_locators_free ();
>>>  }
>>>
>>>  /* Return size needed for stack frame based on slots so far allocated.
>>> @@ -4979,7 +4978,7 @@
>>>               probe_stack_range (STACK_OLD_CHECK_PROTECT, max_frame_size);
>>>             seq = get_insns ();
>>>             end_sequence ();
>>> -           set_insn_locators (seq, prologue_locator);
>>> +           set_insn_locations (seq, prologue_location);
>>>             emit_insn_before (seq, stack_check_probe_note);
>>>             break;
>>>           }
>>> @@ -4994,7 +4993,7 @@
>>>
>>>    /* Output a linenumber for the end of the function.
>>>       SDB depends on this.  */
>>> -  set_curr_insn_source_location (input_location);
>>> +  set_curr_insn_location (input_location);
>>>
>>>    /* Before the return label (if any), clobber the return
>>>       registers so that they are not propagated live to the rest of
>>> @@ -5277,14 +5276,14 @@
>>>    *slot = copy;
>>>  }
>>>
>>> -/* Set the locator of the insn chain starting at INSN to LOC.  */
>>> +/* Set the location of the insn chain starting at INSN to LOC.  */
>>>  static void
>>> -set_insn_locators (rtx insn, int loc)
>>> +set_insn_locations (rtx insn, int loc)
>>>  {
>>>    while (insn != NULL_RTX)
>>>      {
>>>        if (INSN_P (insn))
>>> -       INSN_LOCATOR (insn) = loc;
>>> +       INSN_LOCATION (insn) = loc;
>>>        insn = NEXT_INSN (insn);
>>>      }
>>>  }
>>> @@ -5893,7 +5892,7 @@
>>>        end_sequence ();
>>>
>>>        record_insns (split_prologue_seq, NULL, &prologue_insn_hash);
>>> -      set_insn_locators (split_prologue_seq, prologue_locator);
>>> +      set_insn_locations (split_prologue_seq, prologue_location);
>>>  #endif
>>>      }
>>>
>>> @@ -5922,7 +5921,7 @@
>>>
>>>        prologue_seq = get_insns ();
>>>        end_sequence ();
>>> -      set_insn_locators (prologue_seq, prologue_locator);
>>> +      set_insn_locations (prologue_seq, prologue_location);
>>>      }
>>>  #endif
>>>
>>> @@ -6418,7 +6417,7 @@
>>>
>>>        /* Retain a map of the epilogue insns.  */
>>>        record_insns (seq, NULL, &epilogue_insn_hash);
>>> -      set_insn_locators (seq, epilogue_locator);
>>> +      set_insn_locations (seq, epilogue_location);
>>>
>>>        seq = get_insns ();
>>>        returnjump = get_last_insn ();
>>> @@ -6608,7 +6607,7 @@
>>>              avoid getting rid of sibcall epilogue insns.  Do this before we
>>>              actually emit the sequence.  */
>>>           record_insns (seq, NULL, &epilogue_insn_hash);
>>> -         set_insn_locators (seq, epilogue_locator);
>>> +         set_insn_locations (seq, epilogue_location);
>>>
>>>           emit_insn_before (seq, insn);
>>>         }
>>> Index: gcc/print-rtl.c
>>> ===================================================================
>>> --- gcc/print-rtl.c     (revision 189835)
>>> +++ gcc/print-rtl.c     (working copy)
>>> @@ -416,10 +416,10 @@
>>>         if (i == 5 && INSN_P (in_rtx))
>>>           {
>>>  #ifndef GENERATOR_FILE
>>> -           /*  Pretty-print insn locators.  Ignore scoping as it is mostly
>>> +           /*  Pretty-print insn locations.  Ignore scoping as it is mostly
>>>                 redundant with line number information and do not print anything
>>>                 when there is no location information available.  */
>>> -           if (INSN_LOCATOR (in_rtx) && insn_file (in_rtx))
>>> +           if (INSN_LOCATION (in_rtx) && insn_file (in_rtx))
>>>               fprintf(outfile, " %s:%i", insn_file (in_rtx), insn_line (in_rtx));
>>>  #endif
>>>           }
>>> @@ -427,16 +427,16 @@
>>>           {
>>>  #ifndef GENERATOR_FILE
>>>             fprintf (outfile, " %s:%i",
>>> -                    locator_file (ASM_OPERANDS_SOURCE_LOCATION (in_rtx)),
>>> -                    locator_line (ASM_OPERANDS_SOURCE_LOCATION (in_rtx)));
>>> +                    LOCATION_FILE (ASM_OPERANDS_SOURCE_LOCATION (in_rtx)),
>>> +                    LOCATION_LINE (ASM_OPERANDS_SOURCE_LOCATION (in_rtx)));
>>>  #endif
>>>           }
>>>         else if (i == 1 && GET_CODE (in_rtx) == ASM_INPUT)
>>>           {
>>>  #ifndef GENERATOR_FILE
>>>             fprintf (outfile, " %s:%i",
>>> -                    locator_file (ASM_INPUT_SOURCE_LOCATION (in_rtx)),
>>> -                    locator_line (ASM_INPUT_SOURCE_LOCATION (in_rtx)));
>>> +                    LOCATION_FILE (ASM_INPUT_SOURCE_LOCATION (in_rtx)),
>>> +                    LOCATION_LINE (ASM_INPUT_SOURCE_LOCATION (in_rtx)));
>>>  #endif
>>>           }
>>>         else if (i == 6 && NOTE_P (in_rtx))
>>> Index: gcc/profile.c
>>> ===================================================================
>>> --- gcc/profile.c       (revision 189835)
>>> +++ gcc/profile.c       (working copy)
>>> @@ -966,7 +966,7 @@
>>>              is not computed twice.  */
>>>           if (last
>>>               && gimple_has_location (last)
>>> -             && e->goto_locus != UNKNOWN_LOCATION
>>> +             && !IS_UNKNOWN_LOCATION (e->goto_locus)
>>>               && !single_succ_p (bb)
>>>               && (LOCATION_FILE (e->goto_locus)
>>>                   != LOCATION_FILE (gimple_location (last))
>>> @@ -976,7 +976,6 @@
>>>               basic_block new_bb = split_edge (e);
>>>               edge ne = single_succ_edge (new_bb);
>>>               ne->goto_locus = e->goto_locus;
>>> -             ne->goto_block = e->goto_block;
>>>             }
>>>           if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
>>>                && e->dest != EXIT_BLOCK_PTR)
>>> @@ -1188,7 +1187,7 @@
>>>
>>>           /* Notice GOTO expressions eliminated while constructing the CFG.  */
>>>           if (single_succ_p (bb)
>>> -             && single_succ_edge (bb)->goto_locus != UNKNOWN_LOCATION)
>>> +             && !IS_UNKNOWN_LOCATION (single_succ_edge (bb)->goto_locus))
>>>             {
>>>               expanded_location curr_location
>>>                 = expand_location (single_succ_edge (bb)->goto_locus);
>>> Index: gcc/trans-mem.c
>>> ===================================================================
>>> --- gcc/trans-mem.c     (revision 189835)
>>> +++ gcc/trans-mem.c     (working copy)
>>> @@ -3796,7 +3796,6 @@
>>>             {
>>>               tree t = build1 (NOP_EXPR, void_type_node, size_zero_node);
>>>               SET_EXPR_LOCATION (t, gimple_location (stmt));
>>> -             TREE_BLOCK (t) = gimple_block (stmt);
>>>               error ("%Kasm not allowed in %<transaction_safe%> function", t);
>>>             }
>>>           return true;
>>> Index: gcc/gimplify.c
>>> ===================================================================
>>> --- gcc/gimplify.c      (revision 189835)
>>> +++ gcc/gimplify.c      (working copy)
>>> @@ -2600,7 +2600,6 @@
>>>             = CALL_EXPR_RETURN_SLOT_OPT (call);
>>>           CALL_FROM_THUNK_P (*expr_p) = CALL_FROM_THUNK_P (call);
>>>           SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (call));
>>> -         TREE_BLOCK (*expr_p) = TREE_BLOCK (call);
>>>
>>>           /* Set CALL_EXPR_VA_ARG_PACK.  */
>>>           CALL_EXPR_VA_ARG_PACK (*expr_p) = 1;
>>> Index: gcc/except.c
>>> ===================================================================
>>> --- gcc/except.c        (revision 189835)
>>> +++ gcc/except.c        (working copy)
>>> @@ -526,7 +526,10 @@
>>>        break;
>>>
>>>      case ERT_MUST_NOT_THROW:
>>> -      new_r->u.must_not_throw = old_r->u.must_not_throw;
>>> +      new_r->u.must_not_throw.failure_loc =
>>> +       LOCATION_LOCUS (old_r->u.must_not_throw.failure_loc);
>>> +      new_r->u.must_not_throw.failure_decl =
>>> +       old_r->u.must_not_throw.failure_decl;
>>>        break;
>>>      }
>>>
>>> Index: gcc/emit-rtl.c
>>> ===================================================================
>>> --- gcc/emit-rtl.c      (revision 189835)
>>> +++ gcc/emit-rtl.c      (working copy)
>>> @@ -3634,7 +3634,7 @@
>>>         }
>>>      }
>>>
>>> -  tem = emit_insn_after_setloc (seq, trial, INSN_LOCATOR (trial));
>>> +  tem = emit_insn_after_setloc (seq, trial, INSN_LOCATION (trial));
>>>
>>>    delete_insn (trial);
>>>    if (has_barrier)
>>> @@ -3670,7 +3670,7 @@
>>>    PATTERN (insn) = pattern;
>>>    INSN_CODE (insn) = -1;
>>>    REG_NOTES (insn) = NULL;
>>> -  INSN_LOCATOR (insn) = curr_insn_locator ();
>>> +  INSN_LOCATION (insn) = curr_insn_location ();
>>>    BLOCK_FOR_INSN (insn) = NULL;
>>>
>>>  #ifdef ENABLE_RTL_CHECKING
>>> @@ -3703,7 +3703,7 @@
>>>    PATTERN (insn) = pattern;
>>>    INSN_CODE (insn) = -1;
>>>    REG_NOTES (insn) = NULL;
>>> -  INSN_LOCATOR (insn) = curr_insn_locator ();
>>> +  INSN_LOCATION (insn) = curr_insn_location ();
>>>    BLOCK_FOR_INSN (insn) = NULL;
>>>
>>>    return insn;
>>> @@ -3723,7 +3723,7 @@
>>>    INSN_CODE (insn) = -1;
>>>    REG_NOTES (insn) = NULL;
>>>    JUMP_LABEL (insn) = NULL;
>>> -  INSN_LOCATOR (insn) = curr_insn_locator ();
>>> +  INSN_LOCATION (insn) = curr_insn_location ();
>>>    BLOCK_FOR_INSN (insn) = NULL;
>>>
>>>    return insn;
>>> @@ -3743,7 +3743,7 @@
>>>    INSN_CODE (insn) = -1;
>>>    REG_NOTES (insn) = NULL;
>>>    CALL_INSN_FUNCTION_USAGE (insn) = NULL;
>>> -  INSN_LOCATOR (insn) = curr_insn_locator ();
>>> +  INSN_LOCATION (insn) = curr_insn_location ();
>>>    BLOCK_FOR_INSN (insn) = NULL;
>>>
>>>    return insn;
>>> @@ -4416,8 +4416,8 @@
>>>    after = NEXT_INSN (after);
>>>    while (1)
>>>      {
>>> -      if (active_insn_p (after) && !INSN_LOCATOR (after))
>>> -       INSN_LOCATOR (after) = loc;
>>> +      if (active_insn_p (after) && !INSN_LOCATION (after))
>>> +       INSN_LOCATION (after) = loc;
>>>        if (after == last)
>>>         break;
>>>        after = NEXT_INSN (after);
>>> @@ -4440,62 +4440,62 @@
>>>        prev = PREV_INSN (prev);
>>>
>>>    if (INSN_P (prev))
>>> -    return emit_pattern_after_setloc (pattern, after, INSN_LOCATOR (prev),
>>> +    return emit_pattern_after_setloc (pattern, after, INSN_LOCATION (prev),
>>>                                       make_raw);
>>>    else
>>>      return emit_pattern_after_noloc (pattern, after, NULL, make_raw);
>>>  }
>>>
>>> -/* Like emit_insn_after_noloc, but set INSN_LOCATOR according to LOC.  */
>>> +/* Like emit_insn_after_noloc, but set INSN_LOCATION according to LOC.  */
>>>  rtx
>>>  emit_insn_after_setloc (rtx pattern, rtx after, int loc)
>>>  {
>>>    return emit_pattern_after_setloc (pattern, after, loc, make_insn_raw);
>>>  }
>>>
>>> -/* Like emit_insn_after_noloc, but set INSN_LOCATOR according to AFTER.  */
>>> +/* Like emit_insn_after_noloc, but set INSN_LOCATION according to AFTER.  */
>>>  rtx
>>>  emit_insn_after (rtx pattern, rtx after)
>>>  {
>>>    return emit_pattern_after (pattern, after, true, make_insn_raw);
>>>  }
>>>
>>> -/* Like emit_jump_insn_after_noloc, but set INSN_LOCATOR according to LOC.  */
>>> +/* Like emit_jump_insn_after_noloc, but set INSN_LOCATION according to LOC.  */
>>>  rtx
>>>  emit_jump_insn_after_setloc (rtx pattern, rtx after, int loc)
>>>  {
>>>    return emit_pattern_after_setloc (pattern, after, loc, make_jump_insn_raw);
>>>  }
>>>
>>> -/* Like emit_jump_insn_after_noloc, but set INSN_LOCATOR according to
>>> AFTER.  */
>>> +/* Like emit_jump_insn_after_noloc, but set INSN_LOCATION according
>>> to AFTER.  */
>>>  rtx
>>>  emit_jump_insn_after (rtx pattern, rtx after)
>>>  {
>>>    return emit_pattern_after (pattern, after, true, make_jump_insn_raw);
>>>  }
>>>
>>> -/* Like emit_call_insn_after_noloc, but set INSN_LOCATOR according to LOC.  */
>>> +/* Like emit_call_insn_after_noloc, but set INSN_LOCATION according to LOC.  */
>>>  rtx
>>>  emit_call_insn_after_setloc (rtx pattern, rtx after, int loc)
>>>  {
>>>    return emit_pattern_after_setloc (pattern, after, loc, make_call_insn_raw);
>>>  }
>>>
>>> -/* Like emit_call_insn_after_noloc, but set INSN_LOCATOR according to
>>> AFTER.  */
>>> +/* Like emit_call_insn_after_noloc, but set INSN_LOCATION according
>>> to AFTER.  */
>>>  rtx
>>>  emit_call_insn_after (rtx pattern, rtx after)
>>>  {
>>>    return emit_pattern_after (pattern, after, true, make_call_insn_raw);
>>>  }
>>>
>>> -/* Like emit_debug_insn_after_noloc, but set INSN_LOCATOR according to LOC.  */
>>> +/* Like emit_debug_insn_after_noloc, but set INSN_LOCATION according
>>> to LOC.  */
>>>  rtx
>>>  emit_debug_insn_after_setloc (rtx pattern, rtx after, int loc)
>>>  {
>>>    return emit_pattern_after_setloc (pattern, after, loc, make_debug_insn_raw);
>>>  }
>>>
>>> -/* Like emit_debug_insn_after_noloc, but set INSN_LOCATOR according
>>> to AFTER.  */
>>> +/* Like emit_debug_insn_after_noloc, but set INSN_LOCATION according
>>> to AFTER.  */
>>>  rtx
>>>  emit_debug_insn_after (rtx pattern, rtx after)
>>>  {
>>> @@ -4525,8 +4525,8 @@
>>>      first = NEXT_INSN (first);
>>>    while (1)
>>>      {
>>> -      if (active_insn_p (first) && !INSN_LOCATOR (first))
>>> -       INSN_LOCATOR (first) = loc;
>>> +      if (active_insn_p (first) && !INSN_LOCATION (first))
>>> +       INSN_LOCATION (first) = loc;
>>>        if (first == last)
>>>         break;
>>>        first = NEXT_INSN (first);
>>> @@ -4550,7 +4550,7 @@
>>>        next = PREV_INSN (next);
>>>
>>>    if (INSN_P (next))
>>> -    return emit_pattern_before_setloc (pattern, before, INSN_LOCATOR (next),
>>> +    return emit_pattern_before_setloc (pattern, before, INSN_LOCATION (next),
>>>                                        insnp, make_raw);
>>>    else
>>>      return emit_pattern_before_noloc (pattern, before,
>>> @@ -4558,7 +4558,7 @@
>>>                                        NULL, make_raw);
>>>  }
>>>
>>> -/* Like emit_insn_before_noloc, but set INSN_LOCATOR according to LOC.  */
>>> +/* Like emit_insn_before_noloc, but set INSN_LOCATION according to LOC.  */
>>>  rtx
>>>  emit_insn_before_setloc (rtx pattern, rtx before, int loc)
>>>  {
>>> @@ -4566,14 +4566,14 @@
>>>                                      make_insn_raw);
>>>  }
>>>
>>> -/* Like emit_insn_before_noloc, but set INSN_LOCATOR according to BEFORE.  */
>>> +/* Like emit_insn_before_noloc, but set INSN_LOCATION according to BEFORE.  */
>>>  rtx
>>>  emit_insn_before (rtx pattern, rtx before)
>>>  {
>>>    return emit_pattern_before (pattern, before, true, true, make_insn_raw);
>>>  }
>>>
>>> -/* like emit_insn_before_noloc, but set INSN_LOCATOR according to LOC.  */
>>> +/* like emit_insn_before_noloc, but set INSN_LOCATION according to LOC.  */
>>>  rtx
>>>  emit_jump_insn_before_setloc (rtx pattern, rtx before, int loc)
>>>  {
>>> @@ -4581,7 +4581,7 @@
>>>                                      make_jump_insn_raw);
>>>  }
>>>
>>> -/* Like emit_jump_insn_before_noloc, but set INSN_LOCATOR according
>>> to BEFORE.  */
>>> +/* Like emit_jump_insn_before_noloc, but set INSN_LOCATION according
>>> to BEFORE.  */
>>>  rtx
>>>  emit_jump_insn_before (rtx pattern, rtx before)
>>>  {
>>> @@ -4589,7 +4589,7 @@
>>>                               make_jump_insn_raw);
>>>  }
>>>
>>> -/* Like emit_insn_before_noloc, but set INSN_LOCATOR according to LOC.  */
>>> +/* Like emit_insn_before_noloc, but set INSN_LOCATION according to LOC.  */
>>>  rtx
>>>  emit_call_insn_before_setloc (rtx pattern, rtx before, int loc)
>>>  {
>>> @@ -4598,7 +4598,7 @@
>>>  }
>>>
>>>  /* Like emit_call_insn_before_noloc,
>>> -   but set insn_locator according to BEFORE.  */
>>> +   but set insn_location according to BEFORE.  */
>>>  rtx
>>>  emit_call_insn_before (rtx pattern, rtx before)
>>>  {
>>> @@ -4606,7 +4606,7 @@
>>>                               make_call_insn_raw);
>>>  }
>>>
>>> -/* Like emit_insn_before_noloc, but set INSN_LOCATOR according to LOC.  */
>>> +/* Like emit_insn_before_noloc, but set INSN_LOCATION according to LOC.  */
>>>  rtx
>>>  emit_debug_insn_before_setloc (rtx pattern, rtx before, int loc)
>>>  {
>>> @@ -4615,7 +4615,7 @@
>>>  }
>>>
>>>  /* Like emit_debug_insn_before_noloc,
>>> -   but set insn_locator according to BEFORE.  */
>>> +   but set insn_location according to BEFORE.  */
>>>  rtx
>>>  emit_debug_insn_before (rtx pattern, rtx before)
>>>  {
>>> @@ -5865,7 +5865,7 @@
>>>    /* Update LABEL_NUSES.  */
>>>    mark_jump_label (PATTERN (new_rtx), new_rtx, 0);
>>>
>>> -  INSN_LOCATOR (new_rtx) = INSN_LOCATOR (insn);
>>> +  INSN_LOCATION (new_rtx) = INSN_LOCATION (insn);
>>>
>>>    /* If the old insn is frame related, then so is the new one.  This is
>>>       primarily needed for IA-64 unwind info which marks epilogue insns,
>>> @@ -5900,250 +5900,66 @@
>>>             gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (mode, regno)));
>>>  }
>>>
>>> -/* Data structures representing mapping of INSN_LOCATOR into scope blocks, line
>>> -   numbers and files.  In order to be GGC friendly we need to use separate
>>> -   varrays.  This also slightly improve the memory locality in binary search.
>>> -   The _locs array contains locators where the given property change.  The
>>> -   block_locators_blocks contains the scope block that is used for all insn
>>> -   locator greater than corresponding block_locators_locs value and smaller
>>> -   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) *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;
>>> +location_t prologue_location;
>>> +location_t epilogue_location;
>>>
>>>  /* Hold current location information and last location information, so the
>>>     datastructures are built lazily only when some instructions in given
>>>     place are needed.  */
>>>  static location_t curr_location, last_location;
>>> -static tree curr_block, last_block;
>>> -static int curr_rtl_loc = -1;
>>>
>>> -/* Allocate insn locator datastructure.  */
>>> +/* Allocate insn location datastructure.  */
>>>  void
>>> -insn_locators_alloc (void)
>>> +insn_locations_init (void)
>>>  {
>>> -  prologue_locator = epilogue_locator = 0;
>>> -
>>> -  block_locators_locs = VEC_alloc (int, heap, 32);
>>> -  block_locators_blocks = VEC_alloc (tree, gc, 32);
>>> -  locations_locators_locs = VEC_alloc (int, heap, 32);
>>> -  locations_locators_vals = VEC_alloc (location_t, heap, 32);
>>> -
>>> +  prologue_location = epilogue_location = 0;
>>>    curr_location = UNKNOWN_LOCATION;
>>>    last_location = UNKNOWN_LOCATION;
>>> -  curr_block = NULL;
>>> -  last_block = NULL;
>>> -  curr_rtl_loc = 0;
>>>  }
>>>
>>>  /* 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;
>>> -}
>>> -
>>> -/* Allocate insn locator datastructure.  */
>>> -void
>>> -insn_locators_free (void)
>>> +insn_locations_finalize (void)
>>>  {
>>> -  prologue_locator = epilogue_locator = 0;
>>> -
>>> -  VEC_free (int, heap, block_locators_locs);
>>> -  VEC_free (tree,gc, block_locators_blocks);
>>> -  VEC_free (int, heap, locations_locators_locs);
>>> -  VEC_free (location_t, heap, locations_locators_vals);
>>> +  epilogue_location = curr_location;
>>> +  curr_location = UNKNOWN_LOCATION;
>>>  }
>>>
>>>  /* Set current location.  */
>>>  void
>>> -set_curr_insn_source_location (location_t location)
>>> +set_curr_insn_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;
>>>    curr_location = location;
>>>  }
>>>
>>>  /* Get current location.  */
>>>  location_t
>>> -get_curr_insn_source_location (void)
>>> +curr_insn_location (void)
>>>  {
>>>    return curr_location;
>>>  }
>>>
>>> -/* 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;
>>> -}
>>> -
>>> -/* Get current scope block.  */
>>> -tree
>>> -get_curr_insn_block (void)
>>> -{
>>> -  return curr_block;
>>> -}
>>> -
>>> -/* Return current insn locator.  */
>>> -int
>>> -curr_insn_locator (void)
>>> -{
>>> -  if (curr_rtl_loc == -1 || curr_location == UNKNOWN_LOCATION)
>>> -    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;
>>> -    }
>>> -  if (last_location != curr_location)
>>> -    {
>>> -      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;
>>> -}
>>> -
>>> -
>>> -/* Return lexical scope block locator belongs to.  */
>>> -static tree
>>> -locator_scope (int loc)
>>> -{
>>> -  int max = VEC_length (int, block_locators_locs);
>>> -  int min = 0;
>>> -
>>> -  /* When block_locators_locs was initialized, the pro- and epilogue
>>> -     insns didn't exist yet and can therefore not be found this way.
>>> -     But we know that they belong to the outer most block of the
>>> -     current function.
>>> -     Without this test, the prologue would be put inside the block of
>>> -     the first valid instruction in the function and when that first
>>> -     insn is part of an inlined function then the low_pc of that
>>> -     inlined function is messed up.  Likewise for the epilogue and
>>> -     the last valid instruction.  */
>>> -  if (loc == prologue_locator || loc == epilogue_locator)
>>> -    return DECL_INITIAL (cfun->decl);
>>> -
>>> -  if (!max || !loc)
>>> -    return NULL;
>>> -  while (1)
>>> -    {
>>> -      int pos = (min + max) / 2;
>>> -      int tmp = VEC_index (int, block_locators_locs, pos);
>>> -
>>> -      if (tmp <= loc && min != pos)
>>> -       min = pos;
>>> -      else if (tmp > loc && max != pos)
>>> -       max = pos;
>>> -      else
>>> -       {
>>> -         min = pos;
>>> -         break;
>>> -       }
>>> -    }
>>> -  return VEC_index (tree, block_locators_blocks, min);
>>> -}
>>> -
>>>  /* Return lexical scope block insn belongs to.  */
>>>  tree
>>>  insn_scope (const_rtx insn)
>>>  {
>>> -  return locator_scope (INSN_LOCATOR (insn));
>>> -}
>>> -
>>> -/* Return line number of the statement specified by the locator.  */
>>> -location_t
>>> -locator_location (int loc)
>>> -{
>>> -  int max = VEC_length (int, locations_locators_locs);
>>> -  int min = 0;
>>> -
>>> -  while (1)
>>> -    {
>>> -      int pos = (min + max) / 2;
>>> -      int tmp = VEC_index (int, locations_locators_locs, pos);
>>> -
>>> -      if (tmp <= loc && min != pos)
>>> -       min = pos;
>>> -      else if (tmp > loc && max != pos)
>>> -       max = pos;
>>> -      else
>>> -       {
>>> -         min = pos;
>>> -         break;
>>> -       }
>>> -    }
>>> -  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 LOCATION_BLOCK (INSN_LOCATION (insn));
>>>  }
>>>
>>>  /* Return line number of the statement that produced this insn.  */
>>>  int
>>>  insn_line (const_rtx insn)
>>>  {
>>> -  return locator_line (INSN_LOCATOR (insn));
>>> -}
>>> -
>>> -/* Return source file of the statement specified by LOC.  */
>>> -const char *
>>> -locator_file (int loc)
>>> -{
>>> -  expanded_location xloc;
>>> -  if (!loc)
>>> -    return 0;
>>> -  else
>>> -    xloc = expand_location (locator_location (loc));
>>> -  return xloc.file;
>>> +  return LOCATION_LINE (INSN_LOCATION (insn));
>>>  }
>>>
>>>  /* Return source file of the statement that produced this insn.  */
>>>  const char *
>>>  insn_file (const_rtx insn)
>>>  {
>>> -  return locator_file (INSN_LOCATOR (insn));
>>> +  return LOCATION_FILE (INSN_LOCATION (insn));
>>>  }
>>>
>>> -/* Return true if LOC1 and LOC2 locators have the same location and scope.  */
>>> -bool
>>> -locator_eq (int loc1, int loc2)
>>> -{
>>> -  if (loc1 == loc2)
>>> -    return true;
>>> -  if (locator_location (loc1) != locator_location (loc2))
>>> -    return false;
>>> -  return locator_scope (loc1) == locator_scope (loc2);
>>> -}
>>> -
>>> -
>>>  /* Return true if memory model MODEL requires a pre-operation (release-style)
>>>     barrier or a post-operation (acquire-style) barrier.  While not universal,
>>>     this function matches behavior of several targets.  */
>>> Index: gcc/cfgexpand.c
>>> ===================================================================
>>> --- gcc/cfgexpand.c     (revision 189835)
>>> +++ gcc/cfgexpand.c     (working copy)
>>> @@ -92,8 +92,7 @@
>>>            && gimple_location (stmt) != EXPR_LOCATION (t))
>>>           || (gimple_block (stmt)
>>>               && currently_expanding_to_rtl
>>> -             && EXPR_P (t)
>>> -             && gimple_block (stmt) != TREE_BLOCK (t)))
>>> +             && EXPR_P (t)))
>>>         t = copy_node (t);
>>>      }
>>>    else
>>> @@ -101,8 +100,6 @@
>>>
>>>    if (gimple_has_location (stmt) && CAN_HAVE_LOCATION_P (t))
>>>      SET_EXPR_LOCATION (t, gimple_location (stmt));
>>> -  if (gimple_block (stmt) && currently_expanding_to_rtl && EXPR_P (t))
>>> -    TREE_BLOCK (t) = gimple_block (stmt);
>>>
>>>    return t;
>>>  }
>>> @@ -1804,8 +1801,7 @@
>>>    last2 = last = get_last_insn ();
>>>
>>>    extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
>>> -  set_curr_insn_source_location (gimple_location (stmt));
>>> -  set_curr_insn_block (gimple_block (stmt));
>>> +  set_curr_insn_location (gimple_location (stmt));
>>>
>>>    /* These flags have no purpose in RTL land.  */
>>>    true_edge->flags &= ~EDGE_TRUE_VALUE;
>>> @@ -1818,13 +1814,8 @@
>>>        jumpif_1 (code, op0, op1, label_rtx_for_bb (true_edge->dest),
>>>                 true_edge->probability);
>>>        maybe_dump_rtl_for_gimple_stmt (stmt, last);
>>> -      if (true_edge->goto_locus)
>>> -       {
>>> -         set_curr_insn_source_location (true_edge->goto_locus);
>>> -         set_curr_insn_block (true_edge->goto_block);
>>> -         true_edge->goto_locus = curr_insn_locator ();
>>> -       }
>>> -      true_edge->goto_block = NULL;
>>> +      if (!IS_UNKNOWN_LOCATION (true_edge->goto_locus))
>>> +       set_curr_insn_location (true_edge->goto_locus);
>>>        false_edge->flags |= EDGE_FALLTHRU;
>>>        maybe_cleanup_end_of_block (false_edge, last);
>>>        return NULL;
>>> @@ -1834,13 +1825,8 @@
>>>        jumpifnot_1 (code, op0, op1, label_rtx_for_bb (false_edge->dest),
>>>                    false_edge->probability);
>>>        maybe_dump_rtl_for_gimple_stmt (stmt, last);
>>> -      if (false_edge->goto_locus)
>>> -       {
>>> -         set_curr_insn_source_location (false_edge->goto_locus);
>>> -         set_curr_insn_block (false_edge->goto_block);
>>> -         false_edge->goto_locus = curr_insn_locator ();
>>> -       }
>>> -      false_edge->goto_block = NULL;
>>> +      if (!IS_UNKNOWN_LOCATION (false_edge->goto_locus))
>>> +       set_curr_insn_location (false_edge->goto_locus);
>>>        true_edge->flags |= EDGE_FALLTHRU;
>>>        maybe_cleanup_end_of_block (true_edge, last);
>>>        return NULL;
>>> @@ -1849,13 +1835,8 @@
>>>    jumpif_1 (code, op0, op1, label_rtx_for_bb (true_edge->dest),
>>>             true_edge->probability);
>>>    last = get_last_insn ();
>>> -  if (false_edge->goto_locus)
>>> -    {
>>> -      set_curr_insn_source_location (false_edge->goto_locus);
>>> -      set_curr_insn_block (false_edge->goto_block);
>>> -      false_edge->goto_locus = curr_insn_locator ();
>>> -    }
>>> -  false_edge->goto_block = NULL;
>>> +  if (!IS_UNKNOWN_LOCATION (false_edge->goto_locus))
>>> +    set_curr_insn_location (false_edge->goto_locus);
>>>    emit_jump (label_rtx_for_bb (false_edge->dest));
>>>
>>>    BB_END (bb) = last;
>>> @@ -1880,13 +1861,11 @@
>>>
>>>    maybe_dump_rtl_for_gimple_stmt (stmt, last2);
>>>
>>> -  if (true_edge->goto_locus)
>>> +  if (!IS_UNKNOWN_LOCATION (true_edge->goto_locus))
>>>      {
>>> -      set_curr_insn_source_location (true_edge->goto_locus);
>>> -      set_curr_insn_block (true_edge->goto_block);
>>> -      true_edge->goto_locus = curr_insn_locator ();
>>> +      set_curr_insn_location (true_edge->goto_locus);
>>> +      true_edge->goto_locus = curr_insn_location ();
>>>      }
>>> -  true_edge->goto_block = NULL;
>>>
>>>    return new_bb;
>>>  }
>>> @@ -1986,7 +1965,6 @@
>>>      CALL_FROM_THUNK_P (exp) = gimple_call_from_thunk_p (stmt);
>>>    CALL_EXPR_VA_ARG_PACK (exp) = gimple_call_va_arg_pack_p (stmt);
>>>    SET_EXPR_LOCATION (exp, gimple_location (stmt));
>>> -  TREE_BLOCK (exp) = gimple_block (stmt);
>>>
>>>    /* Ensure RTL is created for debug args.  */
>>>    if (decl && DECL_HAS_DEBUG_ARGS_P (decl))
>>> @@ -2021,8 +1999,7 @@
>>>  {
>>>    tree op0;
>>>
>>> -  set_curr_insn_source_location (gimple_location (stmt));
>>> -  set_curr_insn_block (gimple_block (stmt));
>>> +  set_curr_insn_location (gimple_location (stmt));
>>>
>>>    switch (gimple_code (stmt))
>>>      {
>>> @@ -3766,8 +3743,7 @@
>>>           tree op;
>>>           gimple def;
>>>
>>> -         location_t sloc = get_curr_insn_source_location ();
>>> -         tree sblock = get_curr_insn_block ();
>>> +         location_t sloc = curr_insn_location ();
>>>
>>>           /* Look for SSA names that have their last use here (TERed
>>>              names always have only one real use).  */
>>> @@ -3800,8 +3776,7 @@
>>>                     rtx val;
>>>                     enum machine_mode mode;
>>>
>>> -                   set_curr_insn_source_location (gimple_location (def));
>>> -                   set_curr_insn_block (gimple_block (def));
>>> +                   set_curr_insn_location (gimple_location (def));
>>>
>>>                     DECL_ARTIFICIAL (vexpr) = 1;
>>>                     TREE_TYPE (vexpr) = TREE_TYPE (value);
>>> @@ -3828,8 +3803,7 @@
>>>                       }
>>>                   }
>>>               }
>>> -         set_curr_insn_source_location (sloc);
>>> -         set_curr_insn_block (sblock);
>>> +         set_curr_insn_location (sloc);
>>>         }
>>>
>>>        currently_expanding_gimple_stmt = stmt;
>>> @@ -3844,8 +3818,7 @@
>>>         }
>>>        else if (gimple_debug_bind_p (stmt))
>>>         {
>>> -         location_t sloc = get_curr_insn_source_location ();
>>> -         tree sblock = get_curr_insn_block ();
>>> +         location_t sloc = curr_insn_location ();
>>>           gimple_stmt_iterator nsi = gsi;
>>>
>>>           for (;;)
>>> @@ -3867,8 +3840,7 @@
>>>
>>>               last = get_last_insn ();
>>>
>>> -             set_curr_insn_source_location (gimple_location (stmt));
>>> -             set_curr_insn_block (gimple_block (stmt));
>>> +             set_curr_insn_location (gimple_location (stmt));
>>>
>>>               if (DECL_P (var))
>>>                 mode = DECL_MODE (var);
>>> @@ -3906,13 +3878,11 @@
>>>                 break;
>>>             }
>>>
>>> -         set_curr_insn_source_location (sloc);
>>> -         set_curr_insn_block (sblock);
>>> +         set_curr_insn_location (sloc);
>>>         }
>>>        else if (gimple_debug_source_bind_p (stmt))
>>>         {
>>> -         location_t sloc = get_curr_insn_source_location ();
>>> -         tree sblock = get_curr_insn_block ();
>>> +         location_t sloc = curr_insn_location ();
>>>           tree var = gimple_debug_source_bind_get_var (stmt);
>>>           tree value = gimple_debug_source_bind_get_value (stmt);
>>>           rtx val;
>>> @@ -3920,8 +3890,7 @@
>>>
>>>           last = get_last_insn ();
>>>
>>> -         set_curr_insn_source_location (gimple_location (stmt));
>>> -         set_curr_insn_block (gimple_block (stmt));
>>> +         set_curr_insn_location (gimple_location (stmt));
>>>
>>>           mode = DECL_MODE (var);
>>>
>>> @@ -3939,8 +3908,7 @@
>>>               PAT_VAR_LOCATION_LOC (val) = (rtx)value;
>>>             }
>>>
>>> -         set_curr_insn_source_location (sloc);
>>> -         set_curr_insn_block (sblock);
>>> +         set_curr_insn_location (sloc);
>>>         }
>>>        else
>>>         {
>>> @@ -3981,13 +3949,8 @@
>>>    /* Expand implicit goto and convert goto_locus.  */
>>>    FOR_EACH_EDGE (e, ei, bb->succs)
>>>      {
>>> -      if (e->goto_locus && e->goto_block)
>>> -       {
>>> -         set_curr_insn_source_location (e->goto_locus);
>>> -         set_curr_insn_block (e->goto_block);
>>> -         e->goto_locus = curr_insn_locator ();
>>> -       }
>>> -      e->goto_block = NULL;
>>> +      if (!IS_UNKNOWN_LOCATION (e->goto_locus))
>>> +       set_curr_insn_location (e->goto_locus);
>>>        if ((e->flags & EDGE_FALLTHRU) && e->dest != bb->next_bb)
>>>         {
>>>           emit_jump (label_rtx_for_bb (e->dest));
>>> @@ -4107,12 +4070,9 @@
>>>
>>>    /* Make sure the locus is set to the end of the function, so that
>>>       epilogue line numbers and warnings are set properly.  */
>>> -  if (cfun->function_end_locus != UNKNOWN_LOCATION)
>>> +  if (!IS_UNKNOWN_LOCATION (cfun->function_end_locus))
>>>      input_location = cfun->function_end_locus;
>>>
>>> -  /* The following insns belong to the top scope.  */
>>> -  set_curr_insn_block (DECL_INITIAL (current_function_decl));
>>> -
>>>    /* Generate rtl for function exit.  */
>>>    expand_function_end ();
>>>
>>> @@ -4331,20 +4291,19 @@
>>>
>>>    rtl_profile_for_bb (ENTRY_BLOCK_PTR);
>>>
>>> -  insn_locators_alloc ();
>>> +  insn_locations_init ();
>>>    if (!DECL_IS_BUILTIN (current_function_decl))
>>>      {
>>>        /* Eventually, all FEs should explicitly set function_start_locus.  */
>>> -      if (cfun->function_start_locus == UNKNOWN_LOCATION)
>>> -       set_curr_insn_source_location
>>> +      if (IS_UNKNOWN_LOCATION (cfun->function_start_locus))
>>> +       set_curr_insn_location
>>>           (DECL_SOURCE_LOCATION (current_function_decl));
>>>        else
>>> -       set_curr_insn_source_location (cfun->function_start_locus);
>>> +       set_curr_insn_location (cfun->function_start_locus);
>>>      }
>>>    else
>>> -    set_curr_insn_source_location (UNKNOWN_LOCATION);
>>> -  set_curr_insn_block (DECL_INITIAL (current_function_decl));
>>> -  prologue_locator = curr_insn_locator ();
>>> +    set_curr_insn_location (UNKNOWN_LOCATION);
>>> +  prologue_location = curr_insn_location ();
>>>
>>>  #ifdef INSN_SCHEDULING
>>>    init_sched_attrs ();
>>> @@ -4514,8 +4473,7 @@
>>>    free_histograms ();
>>>
>>>    construct_exit_block ();
>>> -  set_curr_insn_block (DECL_INITIAL (current_function_decl));
>>> -  insn_locators_finalize ();
>>> +  insn_locations_finalize ();
>>>
>>>    /* Zap the tree EH table.  */
>>>    set_eh_throw_stmt_table (cfun, NULL);
>>> Index: gcc/cfgcleanup.c
>>> ===================================================================
>>> --- gcc/cfgcleanup.c    (revision 189835)
>>> +++ gcc/cfgcleanup.c    (working copy)
>>> @@ -481,13 +481,15 @@
>>>                   int new_locus = single_succ_edge (target)->goto_locus;
>>>                   int locus = goto_locus;
>>>
>>> -                 if (new_locus && locus && !locator_eq (new_locus, locus))
>>> +                 if (!IS_UNKNOWN_LOCATION (new_locus)
>>> +                     && !IS_UNKNOWN_LOCATION (locus)
>>> +                     && new_locus != locus)
>>>                     new_target = NULL;
>>>                   else
>>>                     {
>>>                       rtx last;
>>>
>>> -                     if (new_locus)
>>> +                     if (!IS_UNKNOWN_LOCATION (new_locus))
>>>                         locus = new_locus;
>>>
>>>                       last = BB_END (target);
>>> @@ -495,13 +497,15 @@
>>>                         last = prev_nondebug_insn (last);
>>>
>>>                       new_locus = last && INSN_P (last)
>>> -                                 ? INSN_LOCATOR (last) : 0;
>>> +                                 ? INSN_LOCATION (last) : 0;
>>>
>>> -                     if (new_locus && locus && !locator_eq (new_locus, locus))
>>> +                     if (!IS_UNKNOWN_LOCATION (new_locus)
>>> +                         && !IS_UNKNOWN_LOCATION (locus)
>>> +                         && new_locus != locus)
>>>                         new_target = NULL;
>>>                       else
>>>                         {
>>> -                         if (new_locus)
>>> +                         if (!IS_UNKNOWN_LOCATION (new_locus))
>>>                             locus = new_locus;
>>>
>>>                           goto_locus = locus;
>>> Index: gcc/tree-ssa-live.c
>>> ===================================================================
>>> --- gcc/tree-ssa-live.c (revision 189835)
>>> +++ gcc/tree-ssa-live.c (working copy)
>>> @@ -587,7 +587,7 @@
>>>     else
>>>     /* Verfify that only blocks with source location set
>>>        are entry points to the inlined functions.  */
>>> -     gcc_assert (BLOCK_SOURCE_LOCATION (scope) == UNKNOWN_LOCATION);
>>> +     gcc_assert (IS_UNKNOWN_LOCATION (BLOCK_SOURCE_LOCATION (scope)));
>>>
>>>     TREE_USED (scope) = !unused;
>>>     return unused;
>>> @@ -615,7 +615,7 @@
>>>    fprintf (file, "\n%*s{ Scope block #%i%s%s",indent, "" ,
>>> BLOCK_NUMBER (scope),
>>>            TREE_USED (scope) ? "" : " (unused)",
>>>            BLOCK_ABSTRACT (scope) ? " (abstract)": "");
>>> -  if (BLOCK_SOURCE_LOCATION (scope) != UNKNOWN_LOCATION)
>>> +  if (!IS_UNKNOWN_LOCATION (BLOCK_SOURCE_LOCATION (scope)))
>>>      {
>>>        expanded_location s = expand_location (BLOCK_SOURCE_LOCATION (scope));
>>>        fprintf (file, " %s:%i", s.file, s.line);
>>> @@ -765,13 +765,18 @@
>>>            FOR_EACH_PHI_ARG (arg_p, phi, i, SSA_OP_ALL_USES)
>>>              {
>>>               tree arg = USE_FROM_PTR (arg_p);
>>> +             int index = PHI_ARG_INDEX_FROM_USE (arg_p);
>>> +             tree block =
>>> +               LOCATION_BLOCK (gimple_phi_arg_location (phi, index));
>>> +             if (block != NULL)
>>> +               TREE_USED (block) = true;
>>>               mark_all_vars_used (&arg, global_unused_vars);
>>>              }
>>>          }
>>>
>>>        FOR_EACH_EDGE (e, ei, bb->succs)
>>>         if (e->goto_locus)
>>> -         TREE_USED (e->goto_block) = true;
>>> +         TREE_USED (LOCATION_BLOCK (e->goto_locus)) = true;
>>>      }
>>>
>>>    /* We do a two-pass approach about the out-of-scope clobbers.  We want
>>> Index: gcc/lto/lto.c
>>> ===================================================================
>>> --- gcc/lto/lto.c       (revision 189835)
>>> +++ gcc/lto/lto.c       (working copy)
>>> @@ -1603,7 +1603,6 @@
>>>    else if (EXPR_P (t))
>>>      {
>>>        int i;
>>> -      LTO_NO_PREVAIL (t->exp.block);
>>>        for (i = TREE_OPERAND_LENGTH (t) - 1; i >= 0; --i)
>>>         LTO_SET_PREVAIL (TREE_OPERAND (t, i));
>>>      }
>>> Index: gcc/rtl.c
>>> ===================================================================
>>> --- gcc/rtl.c   (revision 189835)
>>> +++ gcc/rtl.c   (working copy)
>>> @@ -440,7 +440,7 @@
>>>  #ifndef GENERATOR_FILE
>>>               if (((code == ASM_OPERANDS && i == 6)
>>>                    || (code == ASM_INPUT && i == 1))
>>> -                 && locator_eq (XINT (x, i), XINT (y, i)))
>>> +                 && XINT (x, i) == XINT (y, i))
>>>                 break;
>>>  #endif
>>>               return 0;
>>> @@ -579,7 +579,7 @@
>>>  #ifndef GENERATOR_FILE
>>>               if (((code == ASM_OPERANDS && i == 6)
>>>                    || (code == ASM_INPUT && i == 1))
>>> -                 && locator_eq (XINT (x, i), XINT (y, i)))
>>> +                 && XINT (x, i) == XINT (y, i))
>>>                 break;
>>>  #endif
>>>               return 0;
>>> Index: gcc/rtl.h
>>> ===================================================================
>>> --- gcc/rtl.h   (revision 189835)
>>> +++ gcc/rtl.h   (working copy)
>>> @@ -739,6 +739,7 @@
>>>  #endif
>>>
>>>  #define XINT(RTX, N)   (RTL_CHECK2 (RTX, N, 'i', 'n').rt_int)
>>> +#define XUINT(RTX, N)   (RTL_CHECK2 (RTX, N, 'i', 'n').rt_uint)
>>>  #define XSTR(RTX, N)   (RTL_CHECK2 (RTX, N, 's', 'S').rt_str)
>>>  #define XEXP(RTX, N)   (RTL_CHECK2 (RTX, N, 'e', 'u').rt_rtx)
>>>  #define XVEC(RTX, N)   (RTL_CHECK2 (RTX, N, 'E', 'V').rt_rtvec)
>>> @@ -802,13 +803,13 @@
>>>  /* The body of an insn.  */
>>>  #define PATTERN(INSN)  XEXP (INSN, 4)
>>>
>>> -#define INSN_LOCATOR(INSN) XINT (INSN, 5)
>>> +#define INSN_LOCATION(INSN) XUINT (INSN, 5)
>>> +
>>> +#define INSN_HAS_LOCATION(INSN) (!IS_UNKNOWN_LOCATION (INSN_LOCATION (INSN)))
>>> +
>>>  /* LOCATION of an RTX if relevant.  */
>>>  #define RTL_LOCATION(X) (INSN_P (X) ? \
>>> -                        locator_location (INSN_LOCATOR (X)) \
>>> -                        : UNKNOWN_LOCATION)
>>> -/* LOCATION of current INSN.  */
>>> -#define CURR_INSN_LOCATION (locator_location (curr_insn_locator ()))
>>> +                        INSN_LOCATION (X) : UNKNOWN_LOCATION)
>>>
>>>  /* Code number of instruction, from when it was recognized.
>>>     -1 means this instruction has not been recognized yet.  */
>>> @@ -1807,12 +1808,8 @@
>>>  /* In emit-rtl.c  */
>>>  extern int insn_line (const_rtx);
>>>  extern const char * insn_file (const_rtx);
>>> -extern location_t locator_location (int);
>>> -extern int locator_line (int);
>>> -extern const char * locator_file (int);
>>> -extern bool locator_eq (int, int);
>>> -extern int prologue_locator, epilogue_locator;
>>>  extern tree insn_scope (const_rtx);
>>> +extern location_t prologue_location, epilogue_location;
>>>
>>>  /* In jump.c */
>>>  extern enum rtx_code reverse_condition (enum rtx_code);
>>> @@ -2648,14 +2645,10 @@
>>>  /* Keep this for the nonce.  */
>>>  #define gen_lowpart rtl_hooks.gen_lowpart
>>>
>>> -extern void insn_locators_alloc (void);
>>> -extern void insn_locators_free (void);
>>> -extern void insn_locators_finalize (void);
>>> -extern void set_curr_insn_source_location (location_t);
>>> -extern location_t get_curr_insn_source_location (void);
>>> -extern void set_curr_insn_block (tree);
>>> -extern tree get_curr_insn_block (void);
>>> -extern int curr_insn_locator (void);
>>> +extern void insn_locations_init (void);
>>> +extern void insn_locations_finalize (void);
>>> +extern void set_curr_insn_location (location_t);
>>> +extern location_t curr_insn_location (void);
>>>  extern bool optimize_insn_for_size_p (void);
>>>  extern bool optimize_insn_for_speed_p (void);
>>>
>>> Index: gcc/tree-inline.c
>>> ===================================================================
>>> --- gcc/tree-inline.c   (revision 189835)
>>> +++ gcc/tree-inline.c   (working copy)
>>> @@ -852,10 +852,6 @@
>>>        /* Otherwise, just copy the node.  Note that copy_tree_r already
>>>          knows not to copy VAR_DECLs, etc., so this is safe.  */
>>>
>>> -      /* We should never have TREE_BLOCK set on non-statements.  */
>>> -      if (EXPR_P (*tp))
>>> -       gcc_assert (!TREE_BLOCK (*tp));
>>> -
>>>        if (TREE_CODE (*tp) == MEM_REF)
>>>         {
>>>           tree ptr = TREE_OPERAND (*tp, 0);
>>> @@ -901,13 +897,9 @@
>>>         {
>>>           /* Variable substitution need not be simple.  In particular,
>>>              the MEM_REF substitution above.  Make sure that
>>> -            TREE_CONSTANT and friends are up-to-date.  But make sure
>>> -            to not improperly set TREE_BLOCK on some sub-expressions.  */
>>> +            TREE_CONSTANT and friends are up-to-date.  */
>>>           int invariant = is_gimple_min_invariant (*tp);
>>> -         tree block = id->block;
>>> -         id->block = NULL_TREE;
>>>           walk_tree (&TREE_OPERAND (*tp, 0), remap_gimple_op_r, data, NULL);
>>> -         id->block = block;
>>>           recompute_tree_invariant_for_addr_expr (*tp);
>>>
>>>           /* If this used to be invariant, but is not any longer,
>>> @@ -919,6 +911,22 @@
>>>         }
>>>      }
>>>
>>> +  /* Update the TREE_BLOCK for the cloned expr.  */
>>> +  if (EXPR_P (*tp))
>>> +    {
>>> +      tree new_block = id->remapping_type_depth == 0 ? id->block : NULL;
>>> +      tree old_block = TREE_BLOCK (*tp);
>>> +      if (old_block)
>>> +       {
>>> +         tree *n;
>>> +         n = (tree *) pointer_map_contains (id->decl_map,
>>> +                                            TREE_BLOCK (*tp));
>>> +         if (n)
>>> +           new_block = *n;
>>> +       }
>>> +      TREE_SET_BLOCK (*tp, new_block);
>>> +    }
>>> +
>>>    /* Keep iterating.  */
>>>    return NULL_TREE;
>>>  }
>>> @@ -1144,11 +1152,10 @@
>>>               tree *n;
>>>               n = (tree *) pointer_map_contains (id->decl_map,
>>>                                                  TREE_BLOCK (*tp));
>>> -             gcc_assert (n || id->remapping_type_depth != 0);
>>>               if (n)
>>>                 new_block = *n;
>>>             }
>>> -         TREE_BLOCK (*tp) = new_block;
>>> +         TREE_SET_BLOCK (*tp, new_block);
>>>         }
>>>
>>>        if (TREE_CODE (*tp) != OMP_CLAUSE)
>>> @@ -2020,6 +2027,7 @@
>>>               tree new_arg;
>>>               tree block = id->block;
>>>               edge_iterator ei2;
>>> +             location_t locus;
>>>
>>>               /* When doing partial cloning, we allow PHIs on the entry block
>>>                  as long as all the arguments are the same.  Find any input
>>> @@ -2031,9 +2039,7 @@
>>>
>>>               arg = PHI_ARG_DEF_FROM_EDGE (phi, old_edge);
>>>               new_arg = arg;
>>> -             id->block = NULL_TREE;
>>>               walk_tree (&new_arg, copy_tree_body_r, id, NULL);
>>> -             id->block = block;
>>>               gcc_assert (new_arg);
>>>               /* With return slot optimization we can end up with
>>>                  non-gimple (foo *)&this->m, fix that here.  */
>>> @@ -2046,8 +2052,19 @@
>>>                   gsi_insert_seq_on_edge (new_edge, stmts);
>>>                   inserted = true;
>>>                 }
>>> +             locus = gimple_phi_arg_location_from_edge (phi, old_edge);
>>> +             block = id->block;
>>> +             if (LOCATION_BLOCK (locus))
>>> +               {
>>> +                 tree *n;
>>> +                 n = (tree *) pointer_map_contains (id->decl_map,
>>> +                       LOCATION_BLOCK (locus));
>>> +                 gcc_assert (n);
>>> +                 block = *n;
>>> +               }
>>> +
>>>               add_phi_arg (new_phi, new_arg, new_edge,
>>> -                          gimple_phi_arg_location_from_edge (phi, old_edge));
>>> +                          COMBINE_LOCATION (locus, block));
>>>             }
>>>         }
>>>      }
>>> @@ -3946,7 +3963,8 @@
>>>    id->block = make_node (BLOCK);
>>>    BLOCK_ABSTRACT_ORIGIN (id->block) = fn;
>>>    BLOCK_SOURCE_LOCATION (id->block) = input_location;
>>> -  prepend_lexical_block (gimple_block (stmt), id->block);
>>> +  if (gimple_block (stmt))
>>> +    prepend_lexical_block (gimple_block (stmt), id->block);
>>>
>>>    /* Local declarations will be replaced by their equivalents in this
>>>       map.  */
>>> Index: gcc/tree-streamer-in.c
>>> ===================================================================
>>> --- gcc/tree-streamer-in.c      (revision 189835)
>>> +++ gcc/tree-streamer-in.c      (working copy)
>>> @@ -776,7 +776,7 @@
>>>
>>>    loc = lto_input_location (ib, data_in);
>>>    SET_EXPR_LOCATION (expr, loc);
>>> -  TREE_BLOCK (expr) = stream_read_tree (ib, data_in);
>>> +  TREE_SET_BLOCK (expr, stream_read_tree (ib, data_in));
>>>  }
>>>
>>>
>>> Index: gcc/combine.c
>>> ===================================================================
>>> --- gcc/combine.c       (revision 189835)
>>> +++ gcc/combine.c       (working copy)
>>> @@ -2896,7 +2896,7 @@
>>>
>>>           i1 = gen_rtx_INSN (VOIDmode, INSN_UID (i2), NULL_RTX, i2,
>>>                              BLOCK_FOR_INSN (i2), XVECEXP (PATTERN (i2), 0, 1),
>>> -                            INSN_LOCATOR (i2), -1, NULL_RTX);
>>> +                            INSN_LOCATION (i2), -1, NULL_RTX);
>>>
>>>           SUBST (PATTERN (i2), XVECEXP (PATTERN (i2), 0, 0));
>>>           SUBST (XEXP (SET_SRC (PATTERN (i2)), 0),
>>> Index: gcc/tree-outof-ssa.c
>>> ===================================================================
>>> --- gcc/tree-outof-ssa.c        (revision 189835)
>>> +++ gcc/tree-outof-ssa.c        (working copy)
>>> @@ -108,8 +108,7 @@
>>>  {
>>>    if (e->goto_locus)
>>>      {
>>> -      set_curr_insn_source_location (e->goto_locus);
>>> -      set_curr_insn_block (e->goto_block);
>>> +      set_curr_insn_location (e->goto_locus);
>>>      }
>>>    else
>>>      {
>>> @@ -125,8 +124,7 @@
>>>                 continue;
>>>               if (gimple_has_location (stmt) || gimple_block (stmt))
>>>                 {
>>> -                 set_curr_insn_source_location (gimple_location (stmt));
>>> -                 set_curr_insn_block (gimple_block (stmt));
>>> +                 set_curr_insn_location (gimple_location (stmt));
>>>                   return;
>>>                 }
>>>             }
>>> @@ -191,7 +189,7 @@
>>>    set_location_for_edge (e);
>>>    /* If a locus is provided, override the default.  */
>>>    if (locus)
>>> -    set_curr_insn_source_location (locus);
>>> +    set_curr_insn_location (locus);
>>>
>>>    var = partition_to_var (SA.map, src);
>>>    seq = emit_partition_copy (SA.partition_to_pseudo[dest],
>>> @@ -228,7 +226,7 @@
>>>    set_location_for_edge (e);
>>>    /* If a locus is provided, override the default.  */
>>>    if (locus)
>>> -    set_curr_insn_source_location (locus);
>>> +    set_curr_insn_location (locus);
>>>
>>>    start_sequence ();
>>>
>>> @@ -284,7 +282,7 @@
>>>    set_location_for_edge (e);
>>>    /* If a locus is provided, override the default.  */
>>>    if (locus)
>>> -    set_curr_insn_source_location (locus);
>>> +    set_curr_insn_location (locus);
>>>
>>>    /* We give the destination as sizeexp in case src/dest are BLKmode
>>>       mems.  Usually we give the source.  As we result from SSA names
>>> @@ -320,7 +318,7 @@
>>>    set_location_for_edge (e);
>>>    /* If a locus is provided, override the default.  */
>>>    if (locus)
>>> -    set_curr_insn_source_location (locus);
>>> +    set_curr_insn_location (locus);
>>>
>>>    var = partition_to_var (SA.map, src);
>>>    seq = emit_partition_copy (dest,
>>> Index: gcc/basic-block.h
>>> ===================================================================
>>> --- gcc/basic-block.h   (revision 189835)
>>> +++ gcc/basic-block.h   (working copy)
>>> @@ -47,8 +47,7 @@
>>>    /* Auxiliary info specific to a pass.  */
>>>    PTR GTY ((skip (""))) aux;
>>>
>>> -  /* Location of any goto implicit in the edge and associated BLOCK.  */
>>> -  tree goto_block;
>>> +  /* Location of any goto implicit in the edge.  */
>>>    location_t goto_locus;
>>>
>>>    /* The index number corresponding to this edge in the edge vector
>>> Index: gcc/gimple.h
>>> ===================================================================
>>> --- gcc/gimple.h        (revision 189835)
>>> +++ gcc/gimple.h        (working copy)
>>> @@ -210,10 +210,6 @@
>>>       and the prev pointer being the last.  */
>>>    gimple next;
>>>    gimple GTY((skip)) prev;
>>> -
>>> -  /* [ WORD 6 ]
>>> -     Lexical block holding this statement.  */
>>> -  tree block;
>>>  };
>>>
>>>
>>> @@ -1198,7 +1194,7 @@
>>>  static inline tree
>>>  gimple_block (const_gimple g)
>>>  {
>>> -  return g->gsbase.block;
>>> +  return LOCATION_BLOCK (g->gsbase.location);
>>>  }
>>>
>>>
>>> @@ -1207,7 +1203,7 @@
>>>  static inline void
>>>  gimple_set_block (gimple g, tree block)
>>>  {
>>> -  g->gsbase.block = block;
>>> +  g->gsbase.location = COMBINE_LOCATION (g->gsbase.location, block);
>>>  }
>>>
>>>
>>> @@ -1242,7 +1238,7 @@
>>>  static inline bool
>>>  gimple_has_location (const_gimple g)
>>>  {
>>> -  return gimple_location (g) != UNKNOWN_LOCATION;
>>> +  return !IS_UNKNOWN_LOCATION (gimple_location (g));
>>>  }
>>>
>>>
>>> Index: gcc/tree-cfg.c
>>> ===================================================================
>>> --- gcc/tree-cfg.c      (revision 189835)
>>> +++ gcc/tree-cfg.c      (working copy)
>>> @@ -808,15 +808,11 @@
>>>    e = make_edge (bb, then_bb, EDGE_TRUE_VALUE);
>>>    assign_discriminator (entry_locus, then_bb);
>>>    e->goto_locus = gimple_location (then_stmt);
>>> -  if (e->goto_locus)
>>> -    e->goto_block = gimple_block (then_stmt);
>>>    e = make_edge (bb, else_bb, EDGE_FALSE_VALUE);
>>>    if (e)
>>>      {
>>>        assign_discriminator (entry_locus, else_bb);
>>>        e->goto_locus = gimple_location (else_stmt);
>>> -      if (e->goto_locus)
>>> -       e->goto_block = gimple_block (else_stmt);
>>>      }
>>>
>>>    /* We do not need the labels anymore.  */
>>> @@ -1026,8 +1022,6 @@
>>>        edge e = make_edge (bb, label_bb, EDGE_FALLTHRU);
>>>        e->goto_locus = gimple_location (goto_t);
>>>        assign_discriminator (e->goto_locus, label_bb);
>>> -      if (e->goto_locus)
>>> -       e->goto_block = gimple_block (goto_t);
>>>        gsi_remove (&last, true);
>>>        return;
>>>      }
>>> @@ -1501,7 +1495,7 @@
>>>
>>>    /* When not optimizing, don't merge if we'd lose goto_locus.  */
>>>    if (!optimize
>>> -      && single_succ_edge (a)->goto_locus != UNKNOWN_LOCATION)
>>> +      && single_succ_edge (a)->goto_locus)
>>>      {
>>>        location_t goto_locus = single_succ_edge (a)->goto_locus;
>>>        gimple_stmt_iterator prev, next;
>>> @@ -5987,9 +5981,7 @@
>>>    tree t = *tp;
>>>
>>>    if (EXPR_P (t))
>>> -    /* We should never have TREE_BLOCK set on non-statements.  */
>>> -    gcc_assert (!TREE_BLOCK (t));
>>> -
>>> +    ;
>>>    else if (DECL_P (t) || TREE_CODE (t) == SSA_NAME)
>>>      {
>>>        if (TREE_CODE (t) == SSA_NAME)
>>> @@ -6294,12 +6286,12 @@
>>>      }
>>>
>>>    FOR_EACH_EDGE (e, ei, bb->succs)
>>> -    if (e->goto_locus)
>>> +    if (!IS_UNKNOWN_LOCATION (e->goto_locus))
>>>        {
>>> -       tree block = e->goto_block;
>>> +       tree block = LOCATION_BLOCK (e->goto_locus);
>>>         if (d->orig_block == NULL_TREE
>>>             || block == d->orig_block)
>>> -         e->goto_block = d->new_block;
>>> +         e->goto_locus = COMBINE_LOCATION (e->goto_locus, d->new_block);
>>>  #ifdef ENABLE_CHECKING
>>>         else if (block != d->new_block)
>>>           {
>>> Index: gcc/config/alpha/alpha.c
>>> ===================================================================
>>> --- gcc/config/alpha/alpha.c    (revision 189835)
>>> +++ gcc/config/alpha/alpha.c    (working copy)
>>> @@ -8352,7 +8352,6 @@
>>>       instruction scheduling worth while.  Note that use_thunk calls
>>>       assemble_start_function and assemble_end_function.  */
>>>    insn = get_insns ();
>>> -  insn_locators_alloc ();
>>>    shorten_branches (insn);
>>>    final_start_function (insn, file, 1);
>>>    final (insn, file, 1);
>>> Index: gcc/config/sparc/sparc.c
>>> ===================================================================
>>> --- gcc/config/sparc/sparc.c    (revision 189835)
>>> +++ gcc/config/sparc/sparc.c    (working copy)
>>> @@ -10654,7 +10654,6 @@
>>>       instruction scheduling worth while.  Note that use_thunk calls
>>>       assemble_start_function and assemble_end_function.  */
>>>    insn = get_insns ();
>>> -  insn_locators_alloc ();
>>>    shorten_branches (insn);
>>>    final_start_function (insn, file, 1);
>>>    final (insn, file, 1);
>>> Index: gcc/config/i386/i386.c
>>> ===================================================================
>>> --- gcc/config/i386/i386.c      (revision 189835)
>>> +++ gcc/config/i386/i386.c      (working copy)
>>> @@ -33063,7 +33063,6 @@
>>>    /* Emit just enough of rest_of_compilation to get the insns emitted.
>>>       Note that use_thunk calls assemble_start_function et al.  */
>>>    tmp = get_insns ();
>>> -  insn_locators_alloc ();
>>>    shorten_branches (tmp);
>>>    final_start_function (tmp, file, 1);
>>>    final (tmp, file, 1);
>>> Index: gcc/config/tilegx/tilegx.c
>>> ===================================================================
>>> --- gcc/config/tilegx/tilegx.c  (revision 189835)
>>> +++ gcc/config/tilegx/tilegx.c  (working copy)
>>> @@ -4804,7 +4804,6 @@
>>>       serial except for the tail call, so we're only wasting one cycle.
>>>     */
>>>    insn = get_insns ();
>>> -  insn_locators_alloc ();
>>>    shorten_branches (insn);
>>>    final_start_function (insn, file, 1);
>>>    final (insn, file, 1);
>>> Index: gcc/config/sh/sh.c
>>> ===================================================================
>>> --- gcc/config/sh/sh.c  (revision 189835)
>>> +++ gcc/config/sh/sh.c  (working copy)
>>> @@ -11979,7 +11979,6 @@
>>>       the insns emitted.  Note that use_thunk calls
>>>       assemble_start_function and assemble_end_function.  */
>>>
>>> -  insn_locators_alloc ();
>>>    insns = get_insns ();
>>>
>>>    if (optimize > 0)
>>> Index: gcc/config/ia64/ia64.c
>>> ===================================================================
>>> --- gcc/config/ia64/ia64.c      (revision 189835)
>>> +++ gcc/config/ia64/ia64.c      (working copy)
>>> @@ -10848,7 +10848,6 @@
>>>       instruction scheduling worth while.  Note that use_thunk calls
>>>       assemble_start_function and assemble_end_function.  */
>>>
>>> -  insn_locators_alloc ();
>>>    emit_all_insn_group_barriers (NULL);
>>>    insn = get_insns ();
>>>    shorten_branches (insn);
>>> Index: gcc/config/rs6000/rs6000.c
>>> ===================================================================
>>> --- gcc/config/rs6000/rs6000.c  (revision 189835)
>>> +++ gcc/config/rs6000/rs6000.c  (working copy)
>>> @@ -21664,7 +21664,6 @@
>>>       instruction scheduling worth while.  Note that use_thunk calls
>>>       assemble_start_function and assemble_end_function.  */
>>>    insn = get_insns ();
>>> -  insn_locators_alloc ();
>>>    shorten_branches (insn);
>>>    final_start_function (insn, file, 1);
>>>    final (insn, file, 1);
>>> Index: gcc/config/score/score.c
>>> ===================================================================
>>> --- gcc/config/score/score.c    (revision 189835)
>>> +++ gcc/config/score/score.c    (working copy)
>>> @@ -505,7 +505,6 @@
>>>    /* Run just enough of rest_of_compilation.  This sequence was
>>>       "borrowed" from alpha.c.  */
>>>    insn = get_insns ();
>>> -  insn_locators_alloc ();
>>>    split_all_insns_noflow ();
>>>    shorten_branches (insn);
>>>    final_start_function (insn, file, 1);
>>> Index: gcc/config/tilepro/tilepro.c
>>> ===================================================================
>>> --- gcc/config/tilepro/tilepro.c        (revision 189835)
>>> +++ gcc/config/tilepro/tilepro.c        (working copy)
>>> @@ -4407,7 +4407,6 @@
>>>       serial except for the tail call, so we're only wasting one cycle.
>>>     */
>>>    insn = get_insns ();
>>> -  insn_locators_alloc ();
>>>    shorten_branches (insn);
>>>    final_start_function (insn, file, 1);
>>>    final (insn, file, 1);
>>> Index: gcc/config/mips/mips.c
>>> ===================================================================
>>> --- gcc/config/mips/mips.c      (revision 189835)
>>> +++ gcc/config/mips/mips.c      (working copy)
>>> @@ -15637,7 +15637,6 @@
>>>    /* Run just enough of rest_of_compilation.  This sequence was
>>>       "borrowed" from alpha.c.  */
>>>    insn = get_insns ();
>>> -  insn_locators_alloc ();
>>>    split_all_insns_noflow ();
>>>    mips16_lay_out_constants ();
>>>    shorten_branches (insn);
>>> Index: gcc/cfgrtl.c
>>> ===================================================================
>>> --- gcc/cfgrtl.c        (revision 189835)
>>> +++ gcc/cfgrtl.c        (working copy)
>>> @@ -720,19 +720,19 @@
>>>  static bool
>>>  unique_locus_on_edge_between_p (basic_block a, basic_block b)
>>>  {
>>> -  const int goto_locus = EDGE_SUCC (a, 0)->goto_locus;
>>> +  const location_t goto_locus = EDGE_SUCC (a, 0)->goto_locus;
>>>    rtx insn, end;
>>>
>>> -  if (!goto_locus)
>>> +  if (IS_UNKNOWN_LOCATION (goto_locus))
>>>      return false;
>>>
>>>    /* First scan block A backward.  */
>>>    insn = BB_END (a);
>>>    end = PREV_INSN (BB_HEAD (a));
>>> -  while (insn != end && (!NONDEBUG_INSN_P (insn) || INSN_LOCATOR (insn) == 0))
>>> +  while (insn != end && (!NONDEBUG_INSN_P (insn) || !INSN_HAS_LOCATION (insn)))
>>>      insn = PREV_INSN (insn);
>>>
>>> -  if (insn != end && locator_eq (INSN_LOCATOR (insn), goto_locus))
>>> +  if (insn != end && INSN_LOCATION (insn) == goto_locus)
>>>      return false;
>>>
>>>    /* Then scan block B forward.  */
>>> @@ -743,8 +743,8 @@
>>>        while (insn != end && !NONDEBUG_INSN_P (insn))
>>>         insn = NEXT_INSN (insn);
>>>
>>> -      if (insn != end && INSN_LOCATOR (insn) != 0
>>> -         && locator_eq (INSN_LOCATOR (insn), goto_locus))
>>> +      if (insn != end && INSN_HAS_LOCATION (insn)
>>> +         && INSN_LOCATION (insn) == goto_locus)
>>>         return false;
>>>      }
>>>
>>> @@ -761,7 +761,7 @@
>>>      return;
>>>
>>>    BB_END (a) = emit_insn_after_noloc (gen_nop (), BB_END (a), a);
>>> -  INSN_LOCATOR (BB_END (a)) = EDGE_SUCC (a, 0)->goto_locus;
>>> +  INSN_LOCATION (BB_END (a)) = EDGE_SUCC (a, 0)->goto_locus;
>>>  }
>>>
>>>  /* Blocks A and B are to be merged into a single block A.  The insns
>>> @@ -1478,7 +1478,7 @@
>>>    else
>>>      jump_block = e->src;
>>>
>>> -  if (e->goto_locus && e->goto_block == NULL)
>>> +  if (!IS_UNKNOWN_LOCATION (e->goto_locus))
>>>      loc = e->goto_locus;
>>>    else
>>>      loc = 0;
>>> @@ -3337,7 +3337,8 @@
>>>          edge_iterator ei;
>>>
>>>          FOR_EACH_EDGE (e, ei, bb->succs)
>>> -         if (e->goto_locus && !(e->flags & EDGE_ABNORMAL))
>>> +         if (!IS_UNKNOWN_LOCATION (e->goto_locus)
>>> +             && !(e->flags & EDGE_ABNORMAL))
>>>             {
>>>               edge e2;
>>>               edge_iterator ei2;
>>> @@ -3347,15 +3348,15 @@
>>>               insn = BB_END (e->src);
>>>               end = PREV_INSN (BB_HEAD (e->src));
>>>               while (insn != end
>>> -                    && (!NONDEBUG_INSN_P (insn) || INSN_LOCATOR (insn) == 0))
>>> +                    && (!NONDEBUG_INSN_P (insn) || !INSN_HAS_LOCATION (insn)))
>>>                 insn = PREV_INSN (insn);
>>>               if (insn != end
>>> -                 && locator_eq (INSN_LOCATOR (insn), (int) e->goto_locus))
>>> +                 && INSN_LOCATION (insn) == e->goto_locus)
>>>                 continue;
>>>               if (simplejump_p (BB_END (e->src))
>>> -                 && INSN_LOCATOR (BB_END (e->src)) == 0)
>>> +                 && !INSN_HAS_LOCATION (BB_END (e->src)))
>>>                 {
>>> -                 INSN_LOCATOR (BB_END (e->src)) = e->goto_locus;
>>> +                 INSN_LOCATION (BB_END (e->src)) = e->goto_locus;
>>>                   continue;
>>>                 }
>>>               dest = e->dest;
>>> @@ -3371,24 +3372,24 @@
>>>                   end = NEXT_INSN (BB_END (dest));
>>>                   while (insn != end && !NONDEBUG_INSN_P (insn))
>>>                     insn = NEXT_INSN (insn);
>>> -                 if (insn != end && INSN_LOCATOR (insn)
>>> -                     && locator_eq (INSN_LOCATOR (insn), (int) e->goto_locus))
>>> +                 if (insn != end && INSN_HAS_LOCATION (insn)
>>> +                     && INSN_LOCATION (insn) == e->goto_locus)
>>>                     continue;
>>>                 }
>>>               nb = split_edge (e);
>>>               if (!INSN_P (BB_END (nb)))
>>>                 BB_END (nb) = emit_insn_after_noloc (gen_nop (), BB_END (nb),
>>>                                                      nb);
>>> -             INSN_LOCATOR (BB_END (nb)) = e->goto_locus;
>>> +             INSN_LOCATION (BB_END (nb)) = e->goto_locus;
>>>
>>>               /* If there are other incoming edges to the destination block
>>>                  with the same goto locus, redirect them to the new block as
>>>                  well, this can prevent other such blocks from being created
>>>                  in subsequent iterations of the loop.  */
>>>               for (ei2 = ei_start (dest->preds); (e2 = ei_safe_edge (ei2)); )
>>> -               if (e2->goto_locus
>>> +               if (!IS_UNKNOWN_LOCATION (e2->goto_locus)
>>>                     && !(e2->flags & (EDGE_ABNORMAL | EDGE_FALLTHRU))
>>> -                   && locator_eq (e->goto_locus, e2->goto_locus))
>>> +                   && e->goto_locus == e2->goto_locus)
>>>                   redirect_edge_and_branch (e2, nb);
>>>                 else
>>>                   ei_next (&ei2);
>>> @@ -4088,7 +4089,7 @@
>>>      }
>>>
>>>    /* If B was a forwarder block, propagate the locus on the edge.  */
>>> -  if (forwarder_p && !EDGE_SUCC (b, 0)->goto_locus)
>>> +  if (forwarder_p && IS_UNKNOWN_LOCATION (EDGE_SUCC (b, 0)->goto_locus))
>>>      EDGE_SUCC (b, 0)->goto_locus = EDGE_SUCC (a, 0)->goto_locus;
>>>
>>>    if (dump_file)
>>> Index: gcc/stmt.c
>>> ===================================================================
>>> --- gcc/stmt.c  (revision 189835)
>>> +++ gcc/stmt.c  (working copy)
>>> @@ -2397,7 +2397,7 @@
>>>                  then emit the code for one side at a time.  */
>>>
>>>               tree test_label
>>> -               = build_decl (CURR_INSN_LOCATION,
>>> +               = build_decl (curr_insn_location (),
>>>                               LABEL_DECL, NULL_TREE, NULL_TREE);
>>>
>>>               /* See if the value is on the right.  */
>>> @@ -2521,7 +2521,7 @@
>>>               /* Right hand node requires testing.
>>>                  Branch to a label where we will handle it later.  */
>>>
>>> -             test_label = build_decl (CURR_INSN_LOCATION,
>>> +             test_label = build_decl (curr_insn_location (),
>>>                                        LABEL_DECL, NULL_TREE, NULL_TREE);
>>>               emit_cmp_and_jump_insns (index,
>>>                                        convert_modes
>>> Index: libcpp/include/line-map.h
>>> ===================================================================
>>> --- libcpp/include/line-map.h   (revision 189835)
>>> +++ libcpp/include/line-map.h   (working copy)
>>> @@ -89,7 +89,7 @@
>>>
>>>  /* This is the highest possible source location encoded within an
>>>     ordinary or macro map.  */
>>> -#define MAX_SOURCE_LOCATION 0xFFFFFFFF
>>> +#define MAX_SOURCE_LOCATION 0x7FFFFFFF
>>>
>>>  struct cpp_hashnode;
>>>
>>> @@ -408,6 +408,16 @@
>>>  #define LINEMAPS_LAST_ALLOCATED_MACRO_MAP(SET) \
>>>    LINEMAPS_LAST_ALLOCATED_MAP (SET, true)
>>>
>>> +extern void location_block_init (void);
>>> +extern void location_block_fini (void);
>>> +extern source_location get_combine_location (source_location, void *);
>>> +extern void *get_block_from_location (source_location);
>>> +extern source_location get_locus_from_location (source_location);
>>> +
>>> +#define COMBINE_LOCATION(LOC, BLOCK) \
>>> +  ((BLOCK) ? get_combine_location ((LOC), (BLOCK)) : (LOC))
>>> +#define IS_COMBINED_LOCATION(LOC) (((LOC) & MAX_SOURCE_LOCATION) != (LOC))
>>> +
>>>  /* Initialize a line map set.  */
>>>  extern void linemap_init (struct line_maps *);
>>>
>>> @@ -594,6 +604,8 @@
>>>
>>>    int column;
>>>
>>> +  void *block;
>>> +
>>>    /* In a system header?. */
>>>    bool sysp;
>>>  } expanded_location;
>>> Index: libcpp/line-map.c
>>> ===================================================================
>>> --- libcpp/line-map.c   (revision 189835)
>>> +++ libcpp/line-map.c   (working copy)
>>> @@ -25,6 +25,7 @@
>>>  #include "line-map.h"
>>>  #include "cpplib.h"
>>>  #include "internal.h"
>>> +#include "hashtab.h"
>>>
>>>  static void trace_include (const struct line_maps *, const struct line_map *);
>>>  static const struct line_map * linemap_ordinary_map_lookup (struct line_maps *,
>>> @@ -50,6 +51,121 @@
>>>  extern unsigned num_expanded_macros_counter;
>>>  extern unsigned num_macro_tokens_counter;
>>>
>>> +struct location_block {
>>> +  source_location locus;
>>> +  void *block;
>>> +};
>>> +
>>> +static htab_t location_block_htab;
>>> +static source_location curr_combined_location;
>>> +static struct location_block *location_blocks;
>>> +static unsigned int allocated_location_blocks;
>>> +
>>> +/* Hash function for location_block hashtable.  */
>>> +
>>> +static hashval_t
>>> +location_block_hash (const void *l)
>>> +{
>>> +  const struct location_block *lb = (const struct location_block *) l;
>>> +  return (hashval_t) lb->locus + (size_t) &lb->block;
>>> +}
>>> +
>>> +/* Compare function for location_block hashtable.  */
>>> +
>>> +static int
>>> +location_block_eq (const void *l1, const void *l2)
>>> +{
>>> +  const struct location_block *lb1 = (const struct location_block *) l1;
>>> +  const struct location_block *lb2 = (const struct location_block *) l2;
>>> +  return lb1->locus == lb2->locus && lb1->block == lb2->block;
>>> +}
>>> +
>>> +/* Update the hashtable when location_blocks is reallocated.  */
>>> +
>>> +static int
>>> +location_block_update (void **slot, void *data)
>>> +{
>>> +  *((char **) slot) += ((char *) location_blocks - (char *) data);
>>> +  return 1;
>>> +}
>>> +
>>> +/* Combine LOCUS and BLOCK to a combined location.  */
>>> +
>>> +source_location
>>> +get_combine_location (source_location locus, void *block)
>>> +{
>>> +  struct location_block lb;
>>> +  struct location_block **slot;
>>> +
>>> +  linemap_assert (block);
>>> +
>>> +  if (IS_COMBINED_LOCATION (locus))
>>> +    locus = location_blocks[locus & MAX_SOURCE_LOCATION].locus;
>>> +  if (locus == 0 && block == NULL)
>>> +    return 0;
>>> +  lb.locus = locus;
>>> +  lb.block = block;
>>> +  slot = (struct location_block **)
>>> +      htab_find_slot (location_block_htab, &lb, INSERT);
>>> +  if (*slot == NULL)
>>> +    {
>>> +      *slot = location_blocks + curr_combined_location;
>>> +      location_blocks[curr_combined_location] = lb;
>>> +      if (++curr_combined_location >= allocated_location_blocks)
>>> +       {
>>> +         char *orig_location_blocks = (char *) location_blocks;
>>> +         allocated_location_blocks *= 2;
>>> +         location_blocks = XRESIZEVEC (struct location_block,
>>> +                                       location_blocks,
>>> +                                       allocated_location_blocks);
>>> +         htab_traverse (location_block_htab, location_block_update,
>>> +                        orig_location_blocks);
>>> +       }
>>> +    }
>>> +  return ((*slot) - location_blocks) | 0x80000000;
>>> +}
>>> +
>>> +/* Return the block for LOCATION.  */
>>> +
>>> +void *
>>> +get_block_from_location (source_location location)
>>> +{
>>> +  linemap_assert (IS_COMBINED_LOCATION (location));
>>> +  return location_blocks[location & MAX_SOURCE_LOCATION].block;
>>> +}
>>> +
>>> +/* Return the locus for LOCATION.  */
>>> +
>>> +source_location
>>> +get_locus_from_location (source_location location)
>>> +{
>>> +  linemap_assert (IS_COMBINED_LOCATION (location));
>>> +  return location_blocks[location & MAX_SOURCE_LOCATION].locus;
>>> +}
>>> +
>>> +/* Initialize the location_block structure.  */
>>> +
>>> +void
>>> +location_block_init (void)
>>> +{
>>> +  location_block_htab = htab_create (100, location_block_hash,
>>> +                                    location_block_eq, NULL);
>>> +  curr_combined_location = 0;
>>> +  allocated_location_blocks = 100;
>>> +  location_blocks = XNEWVEC (struct location_block,
>>> +                            allocated_location_blocks);
>>> +}
>>> +
>>> +/* Finalize the location_block structure.  */
>>> +
>>> +void
>>> +location_block_fini (void)
>>> +{
>>> +  allocated_location_blocks = 0;
>>> +  XDELETEVEC (location_blocks);
>>> +  htab_delete (location_block_htab);
>>> +}
>>> +
>>>  /* Initialize a line map set.  */
>>>
>>>  void
>>> @@ -509,6 +625,8 @@
>>>  const struct line_map*
>>>  linemap_lookup (struct line_maps *set, source_location line)
>>>  {
>>> +  if (IS_COMBINED_LOCATION (line))
>>> +    line = location_blocks[line & MAX_SOURCE_LOCATION].locus;
>>>    if (linemap_location_from_macro_expansion_p (set, line))
>>>      return linemap_macro_map_lookup (set, line);
>>>    return linemap_ordinary_map_lookup (set, line);
>>> @@ -525,6 +643,9 @@
>>>    unsigned int md, mn, mx;
>>>    const struct line_map *cached, *result;
>>>
>>> +  if (IS_COMBINED_LOCATION (line))
>>> +    line = location_blocks[line & MAX_SOURCE_LOCATION].locus;
>>> +
>>>    if (set ==  NULL || line < RESERVED_LOCATION_COUNT)
>>>      return NULL;
>>>
>>> @@ -570,6 +691,9 @@
>>>    unsigned int md, mn, mx;
>>>    const struct line_map *cached, *result;
>>>
>>> +  if (IS_COMBINED_LOCATION (line))
>>> +    line = location_blocks[line & MAX_SOURCE_LOCATION].locus;
>>> +
>>>    linemap_assert (line >= LINEMAPS_MACRO_LOWEST_LOCATION (set));
>>>
>>>    if (set ==  NULL)
>>> @@ -648,6 +772,9 @@
>>>  {
>>>    unsigned token_no;
>>>
>>> +  if (IS_COMBINED_LOCATION (location))
>>> +    location = location_blocks[location & MAX_SOURCE_LOCATION].locus;
>>> +
>>>    linemap_assert (linemap_macro_expansion_map_p (map)
>>>                   && location >= MAP_START_LOCATION (map));
>>>    linemap_assert (location >= RESERVED_LOCATION_COUNT);
>>> @@ -672,6 +799,9 @@
>>>  {
>>>    unsigned token_no;
>>>
>>> +  if (IS_COMBINED_LOCATION (location))
>>> +    location = location_blocks[location & MAX_SOURCE_LOCATION].locus;
>>> +
>>>    linemap_assert (linemap_macro_expansion_map_p (map)
>>>                   && location >= MAP_START_LOCATION (map));
>>>    linemap_assert (location >= RESERVED_LOCATION_COUNT);
>>> @@ -696,6 +826,9 @@
>>>  {
>>>    const struct line_map *map = NULL;
>>>
>>> +  i
>> ...
>>
>> [Message clipped]

Comments

Dehao Chen Aug. 6, 2012, 6:35 p.m. UTC | #1
On Thu, Aug 2, 2012 at 6:05 PM, Richard Guenther
<richard.guenther@gmail.com> wrote:
> On Thu, Aug 2, 2012 at 5:23 AM, Dehao Chen <dehao@google.com> wrote:
>> On Thu, Aug 2, 2012 at 2:07 AM, Richard Guenther
>> <richard.guenther@gmail.com> wrote:
>>> On Wed, Aug 1, 2012 at 7:35 AM, Dehao Chen <dehao@google.com> wrote:
>>>> Hi,
>>>>
>>>> This patch:
>>>>
>>>> * Integrates location with block into an integrated index.
>>>> * Removes gimple->gsbase.block and tree->exp.block fields.
>>>> * Updates inline/clone as well as tree liveness analysis to ensure the
>>>> associated blocks are updated correctly.
>>>>
>>>> With this patch, the association between source location and its block
>>>> are greatly enhanced, which produces much better inline stack in the
>>>> debug info.
>>>>
>>>> Bootstrapped and regression tested on x86.
>>>>
>>>> OK for trunk?
>>>
>>> Nice.  But the LTO changes mean that you simply drop all BLOCK
>>> associations on the floor ...
>>
>> Why? I've invoked TREE_SET_BLOCK in tree-streamer-in.c to read in the
>> block info. So it should at least provide the same info as the
>> original impl.
>>
>>> they at least look very incomplete.  Did you actually run LTO tests?
>>
>> Thanks for the reminder, I've added the following change to this patch:
>>
>> Index: gcc/tree-streamer-out.c
>> ===================================================================
>> --- gcc/tree-streamer-out.c     (revision 189835)
>> +++ gcc/tree-streamer-out.c     (working copy)
>> @@ -471,7 +471,7 @@
>>  {
>>    stream_write_tree (ob, DECL_NAME (expr), ref_p);
>>    stream_write_tree (ob, DECL_CONTEXT (expr), ref_p);
>> -  lto_output_location (ob, DECL_SOURCE_LOCATION (expr));
>> +  lto_output_location (ob, LOCATION_LOCUS (DECL_SOURCE_LOCATION (expr)));
>>  }
>>
>> @@ -668,7 +668,7 @@
>>    streamer_write_hwi (ob, TREE_OPERAND_LENGTH (expr));
>>    for (i = 0; i < TREE_OPERAND_LENGTH (expr); i++)
>>      stream_write_tree (ob, TREE_OPERAND (expr, i), ref_p);
>> -  lto_output_location (ob, EXPR_LOCATION (expr));
>> +  lto_output_location (ob, LOCATION_LOCUS (EXPR_LOCATION (expr)));
>>    stream_write_tree (ob, TREE_BLOCK (expr), ref_p);
>>  }
>
> That doesn't match up with the change
>
> Index: gcc/lto-streamer-out.c
> ===================================================================
> --- gcc/lto-streamer-out.c      (revision 189835)
> +++ gcc/lto-streamer-out.c      (working copy)
> @@ -155,6 +155,7 @@
>  {
>    expanded_location xloc;
>
> +  loc = LOCATION_LOCUS (loc);
>    bp_pack_value (bp, loc == UNKNOWN_LOCATION, 1);
>    if (loc == UNKNOWN_LOCATION)
>      return;
>
> (please remember to generate diffs with -p, so the function name is shown
> in the diff hunk header)

I've attached the new patch with -p output in this mail. Also added
the change in gimple-stream-out.c

>
>> I think BLOCK associations works fine for LTO. I've run check-gcc, and
>> there's no regression on LTO tests. I also manually write some tests,
>> and the generated final assembly has block info as expected.
>
> What about the lto_output_location calls in gimple-streamer-out.c?  As far as I
> can see they will end up dropping the associated BLOCK on the floor (I cannot
> see any change on the -input side).

The beauty of this patch is that it does not need to change the input
side (except that we added tree_set_block instead of using
"tree_block(t)" as lvalue, more detail in the following illustration.

>
>>>
>>> lto/ has its own ChangeLog
>>
>> Thanks, I'll update the ChangeLog accordingly.
>>
>>> and I wonder why no frontends are affected
>>> by this patch?
>>
>> Which files are you referring to?
>
> I was refering to the issue you brought up earlier - all the fold
> routines losing
> block associations.  Maybe you can elaborate some more how locator
> is different from location, thus how you set up the machinery.

This patch defines the following terminology:
- locus: the original location_t in structures such as
gimple_location, EXPR_LOCATION, etc.
- locator: an index to the location_block array, as used in RTL in the
original implementation.
- location: an uint32 that represent the new location: if the highest
bit is 0, it serves as the locus, if the highest bit is 1, the lower
31 bits serves as the locator.

The macro LOCATION_LOCUS derives the locus from location.
The macro LOCATION_BLOCK derives the block from location.
And the gimple_set_block and tree_set_block are modified to set the
updated location for gimple/tree.

Because the interface of gimple_set_block/gimple_block does not
change, we kept frontend change minimal. Also, as we encode the block
into location, the block info can be passed without need to change the
fold_.* interface.

The downside of this approach is that we need to explicitly use
LOCATION_LOCUS when we mean to use the original locus. E.g. when LTO
streams out location, it actually streams out locus. Fortunately, only
a small portion of code need to use the locus. Most code just copy the
location from one place to one another.

Thanks,
Dehao

Updated patch:


Index: gcc/gimple-streamer-out.c
===================================================================
*** gcc/gimple-streamer-out.c	(revision 189835)
--- gcc/gimple-streamer-out.c	(working copy)
*************** output_gimple_stmt (struct output_block
*** 74,80 ****
    streamer_write_bitpack (&bp);

    /* Emit location information for the statement.  */
!   lto_output_location (ob, gimple_location (stmt));

    /* Emit the lexical block holding STMT.  */
    stream_write_tree (ob, gimple_block (stmt), true);
--- 74,80 ----
    streamer_write_bitpack (&bp);

    /* Emit location information for the statement.  */
!   lto_output_location (ob, LOCATION_LOCUS (gimple_location (stmt)));

    /* Emit the lexical block holding STMT.  */
    stream_write_tree (ob, gimple_block (stmt), true);
Index: gcc/tree.c
===================================================================
*** gcc/tree.c	(revision 189835)
--- gcc/tree.c	(working copy)
*************** build1_stat (enum tree_code code, tree t
*** 3765,3771 ****
    TREE_TYPE (t) = type;
    SET_EXPR_LOCATION (t, UNKNOWN_LOCATION);
    TREE_OPERAND (t, 0) = node;
-   TREE_BLOCK (t) = NULL_TREE;
    if (node && !TYPE_P (node))
      {
        TREE_SIDE_EFFECTS (t) = TREE_SIDE_EFFECTS (node);
--- 3765,3770 ----
*************** walk_tree_without_duplicates_1 (tree *tp
*** 10867,10883 ****
  }


! tree *
  tree_block (tree t)
  {
    char const c = TREE_CODE_CLASS (TREE_CODE (t));

    if (IS_EXPR_CODE_CLASS (c))
!     return &t->exp.block;
    gcc_unreachable ();
    return NULL;
  }

  /* Create a nameless artificial label and put it in the current
     function context.  The label has a location of LOC.  Returns the
     newly created label.  */
--- 10866,10893 ----
  }


! tree
  tree_block (tree t)
  {
    char const c = TREE_CODE_CLASS (TREE_CODE (t));

    if (IS_EXPR_CODE_CLASS (c))
!     return LOCATION_BLOCK (t->exp.locus);
    gcc_unreachable ();
    return NULL;
  }

+ void
+ tree_set_block (tree t, tree b)
+ {
+   char const c = TREE_CODE_CLASS (TREE_CODE (t));
+
+   if (IS_EXPR_CODE_CLASS (c))
+     t->exp.locus = COMBINE_LOCATION (t->exp.locus, b);
+   else
+     gcc_unreachable ();
+ }
+
  /* Create a nameless artificial label and put it in the current
     function context.  The label has a location of LOC.  Returns the
     newly created label.  */
Index: gcc/tree.h
===================================================================
*** gcc/tree.h	(revision 189835)
--- gcc/tree.h	(working copy)
*************** extern void omp_clause_range_check_faile
*** 999,1005 ****

  #endif

! #define TREE_BLOCK(NODE)		*(tree_block (NODE))

  #include "tree-check.h"

--- 999,1006 ----

  #endif

! #define TREE_BLOCK(NODE)		(tree_block (NODE))
! #define TREE_SET_BLOCK(T, B)		(tree_set_block ((T), (B)))

  #include "tree-check.h"

*************** struct GTY(()) tree_constructor {
*** 1702,1708 ****
  #define EXPR_LOCATION(NODE) \
    (CAN_HAVE_LOCATION_P ((NODE)) ? (NODE)->exp.locus : UNKNOWN_LOCATION)
  #define SET_EXPR_LOCATION(NODE, LOCUS) EXPR_CHECK
((NODE))->exp.locus = (LOCUS)
! #define EXPR_HAS_LOCATION(NODE) (EXPR_LOCATION (NODE) != UNKNOWN_LOCATION)
  /* The location to be used in a diagnostic about this expression.  Do not
     use this macro if the location will be assigned to other expressions.  */
  #define EXPR_LOC_OR_HERE(NODE) (EXPR_HAS_LOCATION (NODE) ?
(NODE)->exp.locus : input_location)
--- 1703,1709 ----
  #define EXPR_LOCATION(NODE) \
    (CAN_HAVE_LOCATION_P ((NODE)) ? (NODE)->exp.locus : UNKNOWN_LOCATION)
  #define SET_EXPR_LOCATION(NODE, LOCUS) EXPR_CHECK
((NODE))->exp.locus = (LOCUS)
! #define EXPR_HAS_LOCATION(NODE) (!IS_UNKNOWN_LOCATION (EXPR_LOCATION (NODE)))
  /* The location to be used in a diagnostic about this expression.  Do not
     use this macro if the location will be assigned to other expressions.  */
  #define EXPR_LOC_OR_HERE(NODE) (EXPR_HAS_LOCATION (NODE) ?
(NODE)->exp.locus : input_location)
*************** extern void protected_set_expr_location
*** 1881,1887 ****
  					      OMP_CLAUSE_PRIVATE,	\
  	                                      OMP_CLAUSE_COPYPRIVATE), 0)
  #define OMP_CLAUSE_HAS_LOCATION(NODE) \
!   ((OMP_CLAUSE_CHECK (NODE))->omp_clause.locus != UNKNOWN_LOCATION)
  #define OMP_CLAUSE_LOCATION(NODE)  (OMP_CLAUSE_CHECK (NODE))->omp_clause.locus

  /* True on an OMP_SECTION statement that was the last lexical member.
--- 1882,1888 ----
  					      OMP_CLAUSE_PRIVATE,	\
  	                                      OMP_CLAUSE_COPYPRIVATE), 0)
  #define OMP_CLAUSE_HAS_LOCATION(NODE) \
!   (!IS_UNKNOWN_LOCATION ((OMP_CLAUSE_CHECK (NODE))->omp_clause.locus))
  #define OMP_CLAUSE_LOCATION(NODE)  (OMP_CLAUSE_CHECK (NODE))->omp_clause.locus

  /* True on an OMP_SECTION statement that was the last lexical member.
*************** enum omp_clause_default_kind
*** 1972,1978 ****
  struct GTY(()) tree_exp {
    struct tree_typed typed;
    location_t locus;
-   tree block;
    tree GTY ((special ("tree_exp"),
  	     desc ("TREE_CODE ((tree) &%0)")))
      operands[1];
--- 1973,1978 ----
*************** function_args_iter_next (function_args_i
*** 5164,5170 ****
  static inline bool
  inlined_function_outer_scope_p (const_tree block)
  {
!  return BLOCK_SOURCE_LOCATION (block) != UNKNOWN_LOCATION;
  }

  /* Loop over all function arguments of FNTYPE.  In each iteration, PTR is set
--- 5164,5170 ----
  static inline bool
  inlined_function_outer_scope_p (const_tree block)
  {
!  return !IS_UNKNOWN_LOCATION (BLOCK_SOURCE_LOCATION (block));
  }

  /* Loop over all function arguments of FNTYPE.  In each iteration, PTR is set
*************** extern bool subrange_type_for_debug_p (c
*** 5539,5545 ****
  extern HOST_WIDE_INT int_cst_value (const_tree);
  extern HOST_WIDEST_INT widest_int_cst_value (const_tree);

! extern tree *tree_block (tree);
  extern location_t *block_nonartificial_location (tree);
  extern location_t tree_nonartificial_location (tree);

--- 5539,5546 ----
  extern HOST_WIDE_INT int_cst_value (const_tree);
  extern HOST_WIDEST_INT widest_int_cst_value (const_tree);

! extern tree tree_block (tree);
! extern void tree_set_block (tree, tree);
  extern location_t *block_nonartificial_location (tree);
  extern location_t tree_nonartificial_location (tree);

Index: gcc/final.c
===================================================================
*** gcc/final.c	(revision 189835)
--- gcc/final.c	(working copy)
*************** reemit_insn_block_notes (void)
*** 1605,1611 ****
  					     insn_scope (XVECEXP (body, 0, i)));
  	}
        if (! this_block)
! 	continue;

        if (this_block != cur_block)
  	{
--- 1605,1611 ----
  					     insn_scope (XVECEXP (body, 0, i)));
  	}
        if (! this_block)
! 	this_block = DECL_INITIAL (cfun->decl);

        if (this_block != cur_block)
  	{
*************** final_start_function (rtx first ATTRIBUT
*** 1640,1647 ****

    this_is_asm_operands = 0;

!   last_filename = locator_file (prologue_locator);
!   last_linenum = locator_line (prologue_locator);
    last_discriminator = discriminator = 0;

    high_block_linenum = high_function_linenum = last_linenum;
--- 1640,1647 ----

    this_is_asm_operands = 0;

!   last_filename = LOCATION_FILE (prologue_location);
!   last_linenum = LOCATION_LINE (prologue_location);
    last_discriminator = discriminator = 0;

    high_block_linenum = high_function_linenum = last_linenum;
Index: gcc/input.c
===================================================================
*** gcc/input.c	(revision 189835)
--- gcc/input.c	(working copy)
*************** expand_location_1 (source_location loc,
*** 51,56 ****
--- 51,63 ----
    expanded_location xloc;
    const struct line_map *map;
    enum location_resolution_kind lrk = LRK_MACRO_EXPANSION_POINT;
+   tree block = NULL;
+
+   if (IS_COMBINED_LOCATION (loc))
+     {
+       block = LOCATION_BLOCK (loc);
+       loc = LOCATION_LOCUS (loc);
+     }

    memset (&xloc, 0, sizeof (xloc));

*************** expand_location_1 (source_location loc,
*** 74,79 ****
--- 81,87 ----
        xloc = linemap_expand_location (line_table, map, loc);
      }

+   xloc.block = block;
    if (loc <= BUILTINS_LOCATION)
      xloc.file = loc == UNKNOWN_LOCATION ? NULL : _("<built-in>");

Index: gcc/input.h
===================================================================
*** gcc/input.h	(revision 189835)
--- gcc/input.h	(working copy)
*************** extern location_t input_location;
*** 51,56 ****
--- 51,64 ----
  #define LOCATION_FILE(LOC) ((expand_location (LOC)).file)
  #define LOCATION_LINE(LOC) ((expand_location (LOC)).line)
  #define LOCATION_COLUMN(LOC)((expand_location (LOC)).column)
+ #define LOCATION_LOCUS(LOC) \
+   ((IS_COMBINED_LOCATION(LOC)) ? get_locus_from_location (LOC) : (LOC))
+ #define LOCATION_BLOCK(LOC) \
+   ((tree) ((IS_COMBINED_LOCATION (LOC)) ? get_block_from_location (LOC) \
+   : NULL))
+ #define IS_UNKNOWN_LOCATION(LOC) \
+   ((IS_COMBINED_LOCATION (LOC)) ? get_locus_from_location (LOC) == 0 \
+   : (LOC) == 0)

  #define input_line LOCATION_LINE (input_location)
  #define input_filename LOCATION_FILE (input_location)
Index: gcc/fold-const.c
===================================================================
*** gcc/fold-const.c	(revision 189835)
--- gcc/fold-const.c	(working copy)
*************** static location_t
*** 145,151 ****
  expr_location_or (tree t, location_t loc)
  {
    location_t tloc = EXPR_LOCATION (t);
!   return tloc != UNKNOWN_LOCATION ? tloc : loc;
  }

  /* Similar to protected_set_expr_location, but never modify x in place,
--- 145,151 ----
  expr_location_or (tree t, location_t loc)
  {
    location_t tloc = EXPR_LOCATION (t);
!   return IS_UNKNOWN_LOCATION (tloc) ? loc : tloc;
  }

  /* Similar to protected_set_expr_location, but never modify x in place,
Index: gcc/toplev.c
===================================================================
*** gcc/toplev.c	(revision 189835)
--- gcc/toplev.c	(working copy)
*************** general_init (const char *argv0)
*** 1140,1145 ****
--- 1140,1146 ----
    linemap_init (line_table);
    line_table->reallocator = realloc_for_line_map;
    line_table->round_alloc_size = ggc_round_alloc_size;
+   location_block_init ();
    init_ttree ();

    /* Initialize register usage now so switches may override.  */
*************** toplev_main (int argc, char **argv)
*** 1946,1951 ****
--- 1947,1953 ----
    invoke_plugin_callbacks (PLUGIN_FINISH, NULL);

    finalize_plugins ();
+   location_block_fini ();
    if (seen_error ())
      return (FATAL_EXIT_CODE);

Index: gcc/reorg.c
===================================================================
*** gcc/reorg.c	(revision 189835)
--- gcc/reorg.c	(working copy)
*************** emit_delay_sequence (rtx insn, rtx list,
*** 545,551 ****
    INSN_DELETED_P (delay_insn) = 0;
    PREV_INSN (delay_insn) = PREV_INSN (seq_insn);

!   INSN_LOCATOR (seq_insn) = INSN_LOCATOR (delay_insn);

    for (li = list; li; li = XEXP (li, 1), i++)
      {
--- 545,551 ----
    INSN_DELETED_P (delay_insn) = 0;
    PREV_INSN (delay_insn) = PREV_INSN (seq_insn);

!   INSN_LOCATION (seq_insn) = INSN_LOCATION (delay_insn);

    for (li = list; li; li = XEXP (li, 1), i++)
      {
*************** emit_delay_sequence (rtx insn, rtx list,
*** 561,569 ****

        /* SPARC assembler, for instance, emit warning when debug info is output
           into the delay slot.  */
!       if (INSN_LOCATOR (tem) && !INSN_LOCATOR (seq_insn))
! 	INSN_LOCATOR (seq_insn) = INSN_LOCATOR (tem);
!       INSN_LOCATOR (tem) = 0;

        for (note = REG_NOTES (tem); note; note = next)
  	{
--- 561,569 ----

        /* SPARC assembler, for instance, emit warning when debug info is output
           into the delay slot.  */
!       if (INSN_LOCATION (tem) && !INSN_LOCATION (seq_insn))
! 	INSN_LOCATION (seq_insn) = INSN_LOCATION (tem);
!       INSN_LOCATION (tem) = 0;

        for (note = REG_NOTES (tem); note; note = next)
  	{
*************** dbr_schedule (rtx first)
*** 4087,4093 ****
      for (link = crtl->epilogue_delay_list;
           link;
           link = XEXP (link, 1))
!       INSN_LOCATOR (XEXP (link, 0)) = 0;
    }

  #endif
--- 4087,4093 ----
      for (link = crtl->epilogue_delay_list;
           link;
           link = XEXP (link, 1))
!       INSN_LOCATION (XEXP (link, 0)) = 0;
    }

  #endif
Index: gcc/modulo-sched.c
===================================================================
*** gcc/modulo-sched.c	(revision 189835)
--- gcc/modulo-sched.c	(working copy)
*************** loop_single_full_bb_p (struct loop *loop
*** 1246,1254 ****
  /* Dump file:line from INSN's location info to dump_file.  */

  static void
! dump_insn_locator (rtx insn)
  {
!   if (dump_file && INSN_LOCATOR (insn))
      {
        const char *file = insn_file (insn);
        if (file)
--- 1246,1254 ----
  /* Dump file:line from INSN's location info to dump_file.  */

  static void
! dump_insn_location (rtx insn)
  {
!   if (dump_file && INSN_LOCATION (insn))
      {
        const char *file = insn_file (insn);
        if (file)
*************** loop_canon_p (struct loop *loop)
*** 1282,1288 ****
  	  rtx insn = BB_END (loop->header);

  	  fprintf (dump_file, "SMS loop many exits");
! 	  dump_insn_locator (insn);
  	  fprintf (dump_file, "\n");
  	}
        return false;
--- 1282,1288 ----
  	  rtx insn = BB_END (loop->header);

  	  fprintf (dump_file, "SMS loop many exits");
! 	  dump_insn_location (insn);
  	  fprintf (dump_file, "\n");
  	}
        return false;
*************** loop_canon_p (struct loop *loop)
*** 1295,1301 ****
  	  rtx insn = BB_END (loop->header);

  	  fprintf (dump_file, "SMS loop many BBs.");
! 	  dump_insn_locator (insn);
  	  fprintf (dump_file, "\n");
  	}
        return false;
--- 1295,1301 ----
  	  rtx insn = BB_END (loop->header);

  	  fprintf (dump_file, "SMS loop many BBs.");
! 	  dump_insn_location (insn);
  	  fprintf (dump_file, "\n");
  	}
        return false;
*************** sms_schedule (void)
*** 1421,1427 ****
  	  rtx insn = BB_END (loop->header);

  	  fprintf (dump_file, "SMS loop num: %d", loop->num);
! 	  dump_insn_locator (insn);
  	  fprintf (dump_file, "\n");
  	}

--- 1421,1427 ----
  	  rtx insn = BB_END (loop->header);

  	  fprintf (dump_file, "SMS loop num: %d", loop->num);
! 	  dump_insn_location (insn);
  	  fprintf (dump_file, "\n");
  	}

*************** sms_schedule (void)
*** 1450,1456 ****
  	{
  	  if (dump_file)
  	    {
! 	      dump_insn_locator (tail);
  	      fprintf (dump_file, "\nSMS single-bb-loop\n");
  	      if (profile_info && flag_branch_probabilities)
  	    	{
--- 1450,1456 ----
  	{
  	  if (dump_file)
  	    {
! 	      dump_insn_location (tail);
  	      fprintf (dump_file, "\nSMS single-bb-loop\n");
  	      if (profile_info && flag_branch_probabilities)
  	    	{
*************** sms_schedule (void)
*** 1556,1562 ****
  	  rtx insn = BB_END (loop->header);

  	  fprintf (dump_file, "SMS loop num: %d", loop->num);
! 	  dump_insn_locator (insn);
  	  fprintf (dump_file, "\n");

  	  print_ddg (dump_file, g);
--- 1556,1562 ----
  	  rtx insn = BB_END (loop->header);

  	  fprintf (dump_file, "SMS loop num: %d", loop->num);
! 	  dump_insn_location (insn);
  	  fprintf (dump_file, "\n");

  	  print_ddg (dump_file, g);
*************** sms_schedule (void)
*** 1571,1577 ****

        if (dump_file)
  	{
! 	  dump_insn_locator (tail);
  	  fprintf (dump_file, "\nSMS single-bb-loop\n");
  	  if (profile_info && flag_branch_probabilities)
  	    {
--- 1571,1577 ----

        if (dump_file)
  	{
! 	  dump_insn_location (tail);
  	  fprintf (dump_file, "\nSMS single-bb-loop\n");
  	  if (profile_info && flag_branch_probabilities)
  	    {
*************** sms_schedule (void)
*** 1714,1720 ****

            if (dump_file)
              {
! 	      dump_insn_locator (tail);
  	      fprintf (dump_file, " SMS succeeded %d %d (with ii, sc)\n",
  		       ps->ii, stage_count);
  	      print_partial_schedule (ps, dump_file);
--- 1714,1720 ----

            if (dump_file)
              {
! 	      dump_insn_location (tail);
  	      fprintf (dump_file, " SMS succeeded %d %d (with ii, sc)\n",
  		       ps->ii, stage_count);
  	      print_partial_schedule (ps, dump_file);
Index: gcc/lto-streamer-out.c
===================================================================
*** gcc/lto-streamer-out.c	(revision 189835)
--- gcc/lto-streamer-out.c	(working copy)
*************** lto_output_location_bitpack (struct bitp
*** 155,160 ****
--- 155,161 ----
  {
    expanded_location xloc;

+   loc = LOCATION_LOCUS (loc);
    bp_pack_value (bp, loc == UNKNOWN_LOCATION, 1);
    if (loc == UNKNOWN_LOCATION)
      return;
Index: gcc/jump.c
===================================================================
*** gcc/jump.c	(revision 189835)
--- gcc/jump.c	(working copy)
*************** rtx_renumbered_equal_p (const_rtx x, con
*** 1818,1825 ****
  	  if (XINT (x, i) != XINT (y, i))
  	    {
  	      if (((code == ASM_OPERANDS && i == 6)
! 		   || (code == ASM_INPUT && i == 1))
! 		  && locator_eq (XINT (x, i), XINT (y, i)))
  		break;
  	      return 0;
  	    }
--- 1818,1824 ----
  	  if (XINT (x, i) != XINT (y, i))
  	    {
  	      if (((code == ASM_OPERANDS && i == 6)
! 		   || (code == ASM_INPUT && i == 1)))
  		break;
  	      return 0;
  	    }
Index: gcc/ifcvt.c
===================================================================
*** gcc/ifcvt.c	(revision 189835)
--- gcc/ifcvt.c	(working copy)
*************** noce_try_move (struct noce_if_info *if_i
*** 1019,1025 ****
  	    return FALSE;

  	  emit_insn_before_setloc (seq, if_info->jump,
! 				   INSN_LOCATOR (if_info->insn_a));
  	}
        return TRUE;
      }
--- 1019,1025 ----
  	    return FALSE;

  	  emit_insn_before_setloc (seq, if_info->jump,
! 				   INSN_LOCATION (if_info->insn_a));
  	}
        return TRUE;
      }
*************** noce_try_store_flag (struct noce_if_info
*** 1064,1070 ****
  	return FALSE;

        emit_insn_before_setloc (seq, if_info->jump,
! 			       INSN_LOCATOR (if_info->insn_a));
        return TRUE;
      }
    else
--- 1064,1070 ----
  	return FALSE;

        emit_insn_before_setloc (seq, if_info->jump,
! 			       INSN_LOCATION (if_info->insn_a));
        return TRUE;
      }
    else
*************** noce_try_store_flag_constants (struct no
*** 1195,1201 ****
  	return FALSE;

        emit_insn_before_setloc (seq, if_info->jump,
! 			       INSN_LOCATOR (if_info->insn_a));
        return TRUE;
      }

--- 1195,1201 ----
  	return FALSE;

        emit_insn_before_setloc (seq, if_info->jump,
! 			       INSN_LOCATION (if_info->insn_a));
        return TRUE;
      }

*************** noce_try_addcc (struct noce_if_info *if_
*** 1243,1249 ****
  		return FALSE;

  	      emit_insn_before_setloc (seq, if_info->jump,
! 				       INSN_LOCATOR (if_info->insn_a));
  	      return TRUE;
  	    }
  	  end_sequence ();
--- 1243,1249 ----
  		return FALSE;

  	      emit_insn_before_setloc (seq, if_info->jump,
! 				       INSN_LOCATION (if_info->insn_a));
  	      return TRUE;
  	    }
  	  end_sequence ();
*************** noce_try_addcc (struct noce_if_info *if_
*** 1283,1289 ****
  		return FALSE;

  	      emit_insn_before_setloc (seq, if_info->jump,
! 				       INSN_LOCATOR (if_info->insn_a));
  	      return TRUE;
  	    }
  	  end_sequence ();
--- 1283,1289 ----
  		return FALSE;

  	      emit_insn_before_setloc (seq, if_info->jump,
! 				       INSN_LOCATION (if_info->insn_a));
  	      return TRUE;
  	    }
  	  end_sequence ();
*************** noce_try_store_flag_mask (struct noce_if
*** 1332,1338 ****
  	    return FALSE;

  	  emit_insn_before_setloc (seq, if_info->jump,
! 				   INSN_LOCATOR (if_info->insn_a));
  	  return TRUE;
  	}

--- 1332,1338 ----
  	    return FALSE;

  	  emit_insn_before_setloc (seq, if_info->jump,
! 				   INSN_LOCATION (if_info->insn_a));
  	  return TRUE;
  	}

*************** noce_try_cmove (struct noce_if_info *if_
*** 1481,1487 ****
  	    return FALSE;

  	  emit_insn_before_setloc (seq, if_info->jump,
! 				   INSN_LOCATOR (if_info->insn_a));
  	  return TRUE;
  	}
        else
--- 1481,1487 ----
  	    return FALSE;

  	  emit_insn_before_setloc (seq, if_info->jump,
! 				   INSN_LOCATION (if_info->insn_a));
  	  return TRUE;
  	}
        else
*************** noce_try_cmove_arith (struct noce_if_inf
*** 1682,1688 ****
    if (!tmp)
      return FALSE;

!   emit_insn_before_setloc (tmp, if_info->jump, INSN_LOCATOR
(if_info->insn_a));
    return TRUE;

   end_seq_and_fail:
--- 1682,1688 ----
    if (!tmp)
      return FALSE;

!   emit_insn_before_setloc (tmp, if_info->jump, INSN_LOCATION
(if_info->insn_a));
    return TRUE;

   end_seq_and_fail:
*************** noce_try_minmax (struct noce_if_info *if
*** 1929,1935 ****
    if (!seq)
      return FALSE;

!   emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATOR
(if_info->insn_a));
    if_info->cond = cond;
    if_info->cond_earliest = earliest;

--- 1929,1935 ----
    if (!seq)
      return FALSE;

!   emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION
(if_info->insn_a));
    if_info->cond = cond;
    if_info->cond_earliest = earliest;

*************** noce_try_abs (struct noce_if_info *if_in
*** 2076,2082 ****
    if (!seq)
      return FALSE;

!   emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATOR
(if_info->insn_a));
    if_info->cond = cond;
    if_info->cond_earliest = earliest;

--- 2076,2082 ----
    if (!seq)
      return FALSE;

!   emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION
(if_info->insn_a));
    if_info->cond = cond;
    if_info->cond_earliest = earliest;

*************** noce_try_sign_mask (struct noce_if_info
*** 2155,2161 ****
    if (!seq)
      return FALSE;

!   emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATOR
(if_info->insn_a));
    return TRUE;
  }

--- 2155,2161 ----
    if (!seq)
      return FALSE;

!   emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION
(if_info->insn_a));
    return TRUE;
  }

*************** noce_try_bitop (struct noce_if_info *if_
*** 2255,2261 ****
  	return FALSE;

        emit_insn_before_setloc (seq, if_info->jump,
! 			       INSN_LOCATOR (if_info->insn_a));
      }
    return TRUE;
  }
--- 2255,2261 ----
  	return FALSE;

        emit_insn_before_setloc (seq, if_info->jump,
! 			       INSN_LOCATION (if_info->insn_a));
      }
    return TRUE;
  }
*************** noce_process_if_block (struct noce_if_in
*** 2656,2662 ****
        unshare_all_rtl_in_chain (seq);
        end_sequence ();

!       emit_insn_before_setloc (seq, BB_END (test_bb), INSN_LOCATOR (insn_a));
      }

    /* The original THEN and ELSE blocks may now be removed.  The test block
--- 2656,2662 ----
        unshare_all_rtl_in_chain (seq);
        end_sequence ();

!       emit_insn_before_setloc (seq, BB_END (test_bb), INSN_LOCATION (insn_a));
      }

    /* The original THEN and ELSE blocks may now be removed.  The test block
*************** cond_move_process_if_block (struct noce_
*** 2937,2943 ****
        loc_insn = first_active_insn (else_bb);
        gcc_assert (loc_insn);
      }
!   emit_insn_before_setloc (seq, jump, INSN_LOCATOR (loc_insn));

    if (else_bb)
      {
--- 2937,2943 ----
        loc_insn = first_active_insn (else_bb);
        gcc_assert (loc_insn);
      }
!   emit_insn_before_setloc (seq, jump, INSN_LOCATION (loc_insn));

    if (else_bb)
      {
*************** find_cond_trap (basic_block test_bb, edg
*** 3655,3661 ****
      return FALSE;

    /* Emit the new insns before cond_earliest.  */
!   emit_insn_before_setloc (seq, cond_earliest, INSN_LOCATOR (trap));

    /* Delete the trap block if possible.  */
    remove_edge (trap_bb == then_bb ? then_edge : else_edge);
--- 3655,3661 ----
      return FALSE;

    /* Emit the new insns before cond_earliest.  */
!   emit_insn_before_setloc (seq, cond_earliest, INSN_LOCATION (trap));

    /* Delete the trap block if possible.  */
    remove_edge (trap_bb == then_bb ? then_edge : else_edge);
Index: gcc/dwarf2out.c
===================================================================
*** gcc/dwarf2out.c	(revision 189835)
--- gcc/dwarf2out.c	(working copy)
*************** add_src_coords_attributes (dw_die_ref di
*** 15506,15512 ****
  {
    expanded_location s;

!   if (DECL_SOURCE_LOCATION (decl) == UNKNOWN_LOCATION)
      return;
    s = expand_location (DECL_SOURCE_LOCATION (decl));
    add_AT_file (die, DW_AT_decl_file, lookup_filename (s.file));
--- 15506,15512 ----
  {
    expanded_location s;

!   if (IS_UNKNOWN_LOCATION (DECL_SOURCE_LOCATION (decl)))
      return;
    s = expand_location (DECL_SOURCE_LOCATION (decl));
    add_AT_file (die, DW_AT_decl_file, lookup_filename (s.file));
Index: gcc/expr.c
===================================================================
*** gcc/expr.c	(revision 189835)
--- gcc/expr.c	(working copy)
*************** expand_expr_real (tree exp, rtx target,
*** 7802,7820 ****
    if (cfun && EXPR_HAS_LOCATION (exp))
      {
        location_t saved_location = input_location;
!       location_t saved_curr_loc = get_curr_insn_source_location ();
!       tree saved_block = get_curr_insn_block ();
        input_location = EXPR_LOCATION (exp);
!       set_curr_insn_source_location (input_location);
!
!       /* Record where the insns produced belong.  */
!       set_curr_insn_block (TREE_BLOCK (exp));

        ret = expand_expr_real_1 (exp, target, tmode, modifier, alt_rtl);

        input_location = saved_location;
!       set_curr_insn_block (saved_block);
!       set_curr_insn_source_location (saved_curr_loc);
      }
    else
      {
--- 7802,7815 ----
    if (cfun && EXPR_HAS_LOCATION (exp))
      {
        location_t saved_location = input_location;
!       location_t saved_curr_loc = curr_insn_location ();
        input_location = EXPR_LOCATION (exp);
!       set_curr_insn_location (input_location);

        ret = expand_expr_real_1 (exp, target, tmode, modifier, alt_rtl);

        input_location = saved_location;
!       set_curr_insn_location (saved_curr_loc);
      }
    else
      {
Index: gcc/predict.c
===================================================================
*** gcc/predict.c	(revision 189835)
--- gcc/predict.c	(working copy)
*************** tree_estimate_probability_driver (void)
*** 2177,2183 ****
  {
    unsigned nb_loops;

!   loop_optimizer_init (0);
    if (dump_file && (dump_flags & TDF_DETAILS))
      flow_loops_dump (dump_file, NULL, 0);

--- 2177,2183 ----
  {
    unsigned nb_loops;

!   loop_optimizer_init (LOOPS_NORMAL);
    if (dump_file && (dump_flags & TDF_DETAILS))
      flow_loops_dump (dump_file, NULL, 0);

Index: gcc/tree-parloops.c
===================================================================
*** gcc/tree-parloops.c	(revision 189835)
--- gcc/tree-parloops.c	(working copy)
*************** create_loop_fn (location_t loc)
*** 1415,1420 ****
--- 1415,1421 ----
    struct function *act_cfun = cfun;
    static unsigned loopfn_num;

+   loc = LOCATION_LOCUS (loc);
    snprintf (buf, 100, "%s.$loopfn", current_function_name ());
    ASM_FORMAT_PRIVATE_NAME (tname, buf, loopfn_num++);
    clean_symbol_name (tname);
Index: gcc/recog.c
===================================================================
*** gcc/recog.c	(revision 189835)
--- gcc/recog.c	(working copy)
*************** peep2_attempt (basic_block bb, rtx insn,
*** 3333,3339 ****
    /* Replace the old sequence with the new.  */
    last = emit_insn_after_setloc (attempt,
  				 peep2_insn_data[i].insn,
! 				 INSN_LOCATOR (peep2_insn_data[i].insn));
    before_try = PREV_INSN (insn);
    delete_insn_chain (insn, peep2_insn_data[i].insn, false);

--- 3333,3339 ----
    /* Replace the old sequence with the new.  */
    last = emit_insn_after_setloc (attempt,
  				 peep2_insn_data[i].insn,
! 				 INSN_LOCATION (peep2_insn_data[i].insn));
    before_try = PREV_INSN (insn);
    delete_insn_chain (insn, peep2_insn_data[i].insn, false);

Index: gcc/function.c
===================================================================
*** gcc/function.c	(revision 189835)
--- gcc/function.c	(working copy)
*************** static bool contains (const_rtx, htab_t)
*** 133,139 ****
  static void prepare_function_start (void);
  static void do_clobber_return_reg (rtx, void *);
  static void do_use_return_reg (rtx, void *);
! static void set_insn_locators (rtx, int) ATTRIBUTE_UNUSED;
  
  /* Stack of nested functions.  */
  /* Keep track of the cfun stack.  */
--- 133,139 ----
  static void prepare_function_start (void);
  static void do_clobber_return_reg (rtx, void *);
  static void do_use_return_reg (rtx, void *);
! static void set_insn_locations (rtx, int) ATTRIBUTE_UNUSED;
  
  /* Stack of nested functions.  */
  /* Keep track of the cfun stack.  */
*************** free_after_compilation (struct function
*** 200,206 ****
    f->cfg = NULL;

    regno_reg_rtx = NULL;
-   insn_locators_free ();
  }
  
  /* Return size needed for stack frame based on slots so far allocated.
--- 200,205 ----
*************** expand_function_end (void)
*** 4979,4985 ****
  	      probe_stack_range (STACK_OLD_CHECK_PROTECT, max_frame_size);
  	    seq = get_insns ();
  	    end_sequence ();
! 	    set_insn_locators (seq, prologue_locator);
  	    emit_insn_before (seq, stack_check_probe_note);
  	    break;
  	  }
--- 4978,4984 ----
  	      probe_stack_range (STACK_OLD_CHECK_PROTECT, max_frame_size);
  	    seq = get_insns ();
  	    end_sequence ();
! 	    set_insn_locations (seq, prologue_location);
  	    emit_insn_before (seq, stack_check_probe_note);
  	    break;
  	  }
*************** expand_function_end (void)
*** 4994,5000 ****

    /* Output a linenumber for the end of the function.
       SDB depends on this.  */
!   set_curr_insn_source_location (input_location);

    /* Before the return label (if any), clobber the return
       registers so that they are not propagated live to the rest of
--- 4993,4999 ----

    /* Output a linenumber for the end of the function.
       SDB depends on this.  */
!   set_curr_insn_location (input_location);

    /* Before the return label (if any), clobber the return
       registers so that they are not propagated live to the rest of
*************** maybe_copy_prologue_epilogue_insn (rtx i
*** 5277,5290 ****
    *slot = copy;
  }

! /* Set the locator of the insn chain starting at INSN to LOC.  */
  static void
! set_insn_locators (rtx insn, int loc)
  {
    while (insn != NULL_RTX)
      {
        if (INSN_P (insn))
! 	INSN_LOCATOR (insn) = loc;
        insn = NEXT_INSN (insn);
      }
  }
--- 5276,5289 ----
    *slot = copy;
  }

! /* Set the location of the insn chain starting at INSN to LOC.  */
  static void
! set_insn_locations (rtx insn, int loc)
  {
    while (insn != NULL_RTX)
      {
        if (INSN_P (insn))
! 	INSN_LOCATION (insn) = loc;
        insn = NEXT_INSN (insn);
      }
  }
*************** thread_prologue_and_epilogue_insns (void
*** 5893,5899 ****
        end_sequence ();

        record_insns (split_prologue_seq, NULL, &prologue_insn_hash);
!       set_insn_locators (split_prologue_seq, prologue_locator);
  #endif
      }

--- 5892,5898 ----
        end_sequence ();

        record_insns (split_prologue_seq, NULL, &prologue_insn_hash);
!       set_insn_locations (split_prologue_seq, prologue_location);
  #endif
      }

*************** thread_prologue_and_epilogue_insns (void
*** 5922,5928 ****

        prologue_seq = get_insns ();
        end_sequence ();
!       set_insn_locators (prologue_seq, prologue_locator);
      }
  #endif

--- 5921,5927 ----

        prologue_seq = get_insns ();
        end_sequence ();
!       set_insn_locations (prologue_seq, prologue_location);
      }
  #endif

*************** thread_prologue_and_epilogue_insns (void
*** 6418,6424 ****

        /* Retain a map of the epilogue insns.  */
        record_insns (seq, NULL, &epilogue_insn_hash);
!       set_insn_locators (seq, epilogue_locator);

        seq = get_insns ();
        returnjump = get_last_insn ();
--- 6417,6423 ----

        /* Retain a map of the epilogue insns.  */
        record_insns (seq, NULL, &epilogue_insn_hash);
!       set_insn_locations (seq, epilogue_location);

        seq = get_insns ();
        returnjump = get_last_insn ();
*************** epilogue_done:
*** 6608,6614 ****
  	     avoid getting rid of sibcall epilogue insns.  Do this before we
  	     actually emit the sequence.  */
  	  record_insns (seq, NULL, &epilogue_insn_hash);
! 	  set_insn_locators (seq, epilogue_locator);

  	  emit_insn_before (seq, insn);
  	}
--- 6607,6613 ----
  	     avoid getting rid of sibcall epilogue insns.  Do this before we
  	     actually emit the sequence.  */
  	  record_insns (seq, NULL, &epilogue_insn_hash);
! 	  set_insn_locations (seq, epilogue_location);

  	  emit_insn_before (seq, insn);
  	}
Index: gcc/print-rtl.c
===================================================================
*** gcc/print-rtl.c	(revision 189835)
--- gcc/print-rtl.c	(working copy)
*************** print_rtx (const_rtx in_rtx)
*** 416,425 ****
  	if (i == 5 && INSN_P (in_rtx))
  	  {
  #ifndef GENERATOR_FILE
! 	    /*  Pretty-print insn locators.  Ignore scoping as it is mostly
  		redundant with line number information and do not print anything
  		when there is no location information available.  */
! 	    if (INSN_LOCATOR (in_rtx) && insn_file (in_rtx))
  	      fprintf(outfile, " %s:%i", insn_file (in_rtx), insn_line (in_rtx));
  #endif
  	  }
--- 416,425 ----
  	if (i == 5 && INSN_P (in_rtx))
  	  {
  #ifndef GENERATOR_FILE
! 	    /*  Pretty-print insn locations.  Ignore scoping as it is mostly
  		redundant with line number information and do not print anything
  		when there is no location information available.  */
! 	    if (INSN_LOCATION (in_rtx) && insn_file (in_rtx))
  	      fprintf(outfile, " %s:%i", insn_file (in_rtx), insn_line (in_rtx));
  #endif
  	  }
*************** print_rtx (const_rtx in_rtx)
*** 427,442 ****
  	  {
  #ifndef GENERATOR_FILE
  	    fprintf (outfile, " %s:%i",
! 		     locator_file (ASM_OPERANDS_SOURCE_LOCATION (in_rtx)),
! 		     locator_line (ASM_OPERANDS_SOURCE_LOCATION (in_rtx)));
  #endif
  	  }
  	else if (i == 1 && GET_CODE (in_rtx) == ASM_INPUT)
  	  {
  #ifndef GENERATOR_FILE
  	    fprintf (outfile, " %s:%i",
! 		     locator_file (ASM_INPUT_SOURCE_LOCATION (in_rtx)),
! 		     locator_line (ASM_INPUT_SOURCE_LOCATION (in_rtx)));
  #endif
  	  }
  	else if (i == 6 && NOTE_P (in_rtx))
--- 427,442 ----
  	  {
  #ifndef GENERATOR_FILE
  	    fprintf (outfile, " %s:%i",
! 		     LOCATION_FILE (ASM_OPERANDS_SOURCE_LOCATION (in_rtx)),
! 		     LOCATION_LINE (ASM_OPERANDS_SOURCE_LOCATION (in_rtx)));
  #endif
  	  }
  	else if (i == 1 && GET_CODE (in_rtx) == ASM_INPUT)
  	  {
  #ifndef GENERATOR_FILE
  	    fprintf (outfile, " %s:%i",
! 		     LOCATION_FILE (ASM_INPUT_SOURCE_LOCATION (in_rtx)),
! 		     LOCATION_LINE (ASM_INPUT_SOURCE_LOCATION (in_rtx)));
  #endif
  	  }
  	else if (i == 6 && NOTE_P (in_rtx))
Index: gcc/profile.c
===================================================================
*** gcc/profile.c	(revision 189835)
--- gcc/profile.c	(working copy)
*************** branch_prob (void)
*** 966,972 ****
  	     is not computed twice.  */
  	  if (last
  	      && gimple_has_location (last)
! 	      && e->goto_locus != UNKNOWN_LOCATION
  	      && !single_succ_p (bb)
  	      && (LOCATION_FILE (e->goto_locus)
  	          != LOCATION_FILE (gimple_location (last))
--- 966,972 ----
  	     is not computed twice.  */
  	  if (last
  	      && gimple_has_location (last)
! 	      && !IS_UNKNOWN_LOCATION (e->goto_locus)
  	      && !single_succ_p (bb)
  	      && (LOCATION_FILE (e->goto_locus)
  	          != LOCATION_FILE (gimple_location (last))
*************** branch_prob (void)
*** 976,982 ****
  	      basic_block new_bb = split_edge (e);
  	      edge ne = single_succ_edge (new_bb);
  	      ne->goto_locus = e->goto_locus;
- 	      ne->goto_block = e->goto_block;
  	    }
  	  if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
  	       && e->dest != EXIT_BLOCK_PTR)
--- 976,981 ----
*************** branch_prob (void)
*** 1188,1194 ****

  	  /* Notice GOTO expressions eliminated while constructing the CFG.  */
  	  if (single_succ_p (bb)
! 	      && single_succ_edge (bb)->goto_locus != UNKNOWN_LOCATION)
  	    {
  	      expanded_location curr_location
  		= expand_location (single_succ_edge (bb)->goto_locus);
--- 1187,1193 ----

  	  /* Notice GOTO expressions eliminated while constructing the CFG.  */
  	  if (single_succ_p (bb)
! 	      && !IS_UNKNOWN_LOCATION (single_succ_edge (bb)->goto_locus))
  	    {
  	      expanded_location curr_location
  		= expand_location (single_succ_edge (bb)->goto_locus);
Index: gcc/trans-mem.c
===================================================================
*** gcc/trans-mem.c	(revision 189835)
--- gcc/trans-mem.c	(working copy)
*************** ipa_tm_scan_irr_block (basic_block bb)
*** 3796,3802 ****
  	    {
  	      tree t = build1 (NOP_EXPR, void_type_node, size_zero_node);
  	      SET_EXPR_LOCATION (t, gimple_location (stmt));
- 	      TREE_BLOCK (t) = gimple_block (stmt);
  	      error ("%Kasm not allowed in %<transaction_safe%> function", t);
  	    }
  	  return true;
--- 3796,3801 ----
Index: gcc/gimplify.c
===================================================================
*** gcc/gimplify.c	(revision 189835)
--- gcc/gimplify.c	(working copy)
*************** gimplify_call_expr (tree *expr_p, gimple
*** 2600,2606 ****
  	    = CALL_EXPR_RETURN_SLOT_OPT (call);
  	  CALL_FROM_THUNK_P (*expr_p) = CALL_FROM_THUNK_P (call);
  	  SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (call));
- 	  TREE_BLOCK (*expr_p) = TREE_BLOCK (call);

  	  /* Set CALL_EXPR_VA_ARG_PACK.  */
  	  CALL_EXPR_VA_ARG_PACK (*expr_p) = 1;
--- 2600,2605 ----
Index: gcc/except.c
===================================================================
*** gcc/except.c	(revision 189835)
--- gcc/except.c	(working copy)
*************** duplicate_eh_regions_1 (struct duplicate
*** 526,532 ****
        break;

      case ERT_MUST_NOT_THROW:
!       new_r->u.must_not_throw = old_r->u.must_not_throw;
        break;
      }

--- 526,535 ----
        break;

      case ERT_MUST_NOT_THROW:
!       new_r->u.must_not_throw.failure_loc =
! 	LOCATION_LOCUS (old_r->u.must_not_throw.failure_loc);
!       new_r->u.must_not_throw.failure_decl =
! 	old_r->u.must_not_throw.failure_decl;
        break;
      }

Index: gcc/emit-rtl.c
===================================================================
*** gcc/emit-rtl.c	(revision 189835)
--- gcc/emit-rtl.c	(working copy)
*************** try_split (rtx pat, rtx trial, int last)
*** 3634,3640 ****
  	}
      }

!   tem = emit_insn_after_setloc (seq, trial, INSN_LOCATOR (trial));

    delete_insn (trial);
    if (has_barrier)
--- 3634,3640 ----
  	}
      }

!   tem = emit_insn_after_setloc (seq, trial, INSN_LOCATION (trial));

    delete_insn (trial);
    if (has_barrier)
*************** make_insn_raw (rtx pattern)
*** 3670,3676 ****
    PATTERN (insn) = pattern;
    INSN_CODE (insn) = -1;
    REG_NOTES (insn) = NULL;
!   INSN_LOCATOR (insn) = curr_insn_locator ();
    BLOCK_FOR_INSN (insn) = NULL;

  #ifdef ENABLE_RTL_CHECKING
--- 3670,3676 ----
    PATTERN (insn) = pattern;
    INSN_CODE (insn) = -1;
    REG_NOTES (insn) = NULL;
!   INSN_LOCATION (insn) = curr_insn_location ();
    BLOCK_FOR_INSN (insn) = NULL;

  #ifdef ENABLE_RTL_CHECKING
*************** make_debug_insn_raw (rtx pattern)
*** 3703,3709 ****
    PATTERN (insn) = pattern;
    INSN_CODE (insn) = -1;
    REG_NOTES (insn) = NULL;
!   INSN_LOCATOR (insn) = curr_insn_locator ();
    BLOCK_FOR_INSN (insn) = NULL;

    return insn;
--- 3703,3709 ----
    PATTERN (insn) = pattern;
    INSN_CODE (insn) = -1;
    REG_NOTES (insn) = NULL;
!   INSN_LOCATION (insn) = curr_insn_location ();
    BLOCK_FOR_INSN (insn) = NULL;

    return insn;
*************** make_jump_insn_raw (rtx pattern)
*** 3723,3729 ****
    INSN_CODE (insn) = -1;
    REG_NOTES (insn) = NULL;
    JUMP_LABEL (insn) = NULL;
!   INSN_LOCATOR (insn) = curr_insn_locator ();
    BLOCK_FOR_INSN (insn) = NULL;

    return insn;
--- 3723,3729 ----
    INSN_CODE (insn) = -1;
    REG_NOTES (insn) = NULL;
    JUMP_LABEL (insn) = NULL;
!   INSN_LOCATION (insn) = curr_insn_location ();
    BLOCK_FOR_INSN (insn) = NULL;

    return insn;
*************** make_call_insn_raw (rtx pattern)
*** 3743,3749 ****
    INSN_CODE (insn) = -1;
    REG_NOTES (insn) = NULL;
    CALL_INSN_FUNCTION_USAGE (insn) = NULL;
!   INSN_LOCATOR (insn) = curr_insn_locator ();
    BLOCK_FOR_INSN (insn) = NULL;

    return insn;
--- 3743,3749 ----
    INSN_CODE (insn) = -1;
    REG_NOTES (insn) = NULL;
    CALL_INSN_FUNCTION_USAGE (insn) = NULL;
!   INSN_LOCATION (insn) = curr_insn_location ();
    BLOCK_FOR_INSN (insn) = NULL;

    return insn;
*************** emit_pattern_after_setloc (rtx pattern,
*** 4416,4423 ****
    after = NEXT_INSN (after);
    while (1)
      {
!       if (active_insn_p (after) && !INSN_LOCATOR (after))
! 	INSN_LOCATOR (after) = loc;
        if (after == last)
  	break;
        after = NEXT_INSN (after);
--- 4416,4423 ----
    after = NEXT_INSN (after);
    while (1)
      {
!       if (active_insn_p (after) && !INSN_LOCATION (after))
! 	INSN_LOCATION (after) = loc;
        if (after == last)
  	break;
        after = NEXT_INSN (after);
*************** emit_pattern_after (rtx pattern, rtx aft
*** 4440,4501 ****
        prev = PREV_INSN (prev);

    if (INSN_P (prev))
!     return emit_pattern_after_setloc (pattern, after, INSN_LOCATOR (prev),
  				      make_raw);
    else
      return emit_pattern_after_noloc (pattern, after, NULL, make_raw);
  }

! /* Like emit_insn_after_noloc, but set INSN_LOCATOR according to LOC.  */
  rtx
  emit_insn_after_setloc (rtx pattern, rtx after, int loc)
  {
    return emit_pattern_after_setloc (pattern, after, loc, make_insn_raw);
  }

! /* Like emit_insn_after_noloc, but set INSN_LOCATOR according to AFTER.  */
  rtx
  emit_insn_after (rtx pattern, rtx after)
  {
    return emit_pattern_after (pattern, after, true, make_insn_raw);
  }

! /* Like emit_jump_insn_after_noloc, but set INSN_LOCATOR according to LOC.  */
  rtx
  emit_jump_insn_after_setloc (rtx pattern, rtx after, int loc)
  {
    return emit_pattern_after_setloc (pattern, after, loc, make_jump_insn_raw);
  }

! /* Like emit_jump_insn_after_noloc, but set INSN_LOCATOR according
to AFTER.  */
  rtx
  emit_jump_insn_after (rtx pattern, rtx after)
  {
    return emit_pattern_after (pattern, after, true, make_jump_insn_raw);
  }

! /* Like emit_call_insn_after_noloc, but set INSN_LOCATOR according to LOC.  */
  rtx
  emit_call_insn_after_setloc (rtx pattern, rtx after, int loc)
  {
    return emit_pattern_after_setloc (pattern, after, loc, make_call_insn_raw);
  }

! /* Like emit_call_insn_after_noloc, but set INSN_LOCATOR according
to AFTER.  */
  rtx
  emit_call_insn_after (rtx pattern, rtx after)
  {
    return emit_pattern_after (pattern, after, true, make_call_insn_raw);
  }

! /* Like emit_debug_insn_after_noloc, but set INSN_LOCATOR according
to LOC.  */
  rtx
  emit_debug_insn_after_setloc (rtx pattern, rtx after, int loc)
  {
    return emit_pattern_after_setloc (pattern, after, loc, make_debug_insn_raw);
  }

! /* Like emit_debug_insn_after_noloc, but set INSN_LOCATOR according
to AFTER.  */
  rtx
  emit_debug_insn_after (rtx pattern, rtx after)
  {
--- 4440,4501 ----
        prev = PREV_INSN (prev);

    if (INSN_P (prev))
!     return emit_pattern_after_setloc (pattern, after, INSN_LOCATION (prev),
  				      make_raw);
    else
      return emit_pattern_after_noloc (pattern, after, NULL, make_raw);
  }

! /* Like emit_insn_after_noloc, but set INSN_LOCATION according to LOC.  */
  rtx
  emit_insn_after_setloc (rtx pattern, rtx after, int loc)
  {
    return emit_pattern_after_setloc (pattern, after, loc, make_insn_raw);
  }

! /* Like emit_insn_after_noloc, but set INSN_LOCATION according to AFTER.  */
  rtx
  emit_insn_after (rtx pattern, rtx after)
  {
    return emit_pattern_after (pattern, after, true, make_insn_raw);
  }

! /* Like emit_jump_insn_after_noloc, but set INSN_LOCATION according
to LOC.  */
  rtx
  emit_jump_insn_after_setloc (rtx pattern, rtx after, int loc)
  {
    return emit_pattern_after_setloc (pattern, after, loc, make_jump_insn_raw);
  }

! /* Like emit_jump_insn_after_noloc, but set INSN_LOCATION according
to AFTER.  */
  rtx
  emit_jump_insn_after (rtx pattern, rtx after)
  {
    return emit_pattern_after (pattern, after, true, make_jump_insn_raw);
  }

! /* Like emit_call_insn_after_noloc, but set INSN_LOCATION according
to LOC.  */
  rtx
  emit_call_insn_after_setloc (rtx pattern, rtx after, int loc)
  {
    return emit_pattern_after_setloc (pattern, after, loc, make_call_insn_raw);
  }

! /* Like emit_call_insn_after_noloc, but set INSN_LOCATION according
to AFTER.  */
  rtx
  emit_call_insn_after (rtx pattern, rtx after)
  {
    return emit_pattern_after (pattern, after, true, make_call_insn_raw);
  }

! /* Like emit_debug_insn_after_noloc, but set INSN_LOCATION according
to LOC.  */
  rtx
  emit_debug_insn_after_setloc (rtx pattern, rtx after, int loc)
  {
    return emit_pattern_after_setloc (pattern, after, loc, make_debug_insn_raw);
  }

! /* Like emit_debug_insn_after_noloc, but set INSN_LOCATION according
to AFTER.  */
  rtx
  emit_debug_insn_after (rtx pattern, rtx after)
  {
*************** emit_pattern_before_setloc (rtx pattern,
*** 4525,4532 ****
      first = NEXT_INSN (first);
    while (1)
      {
!       if (active_insn_p (first) && !INSN_LOCATOR (first))
! 	INSN_LOCATOR (first) = loc;
        if (first == last)
  	break;
        first = NEXT_INSN (first);
--- 4525,4532 ----
      first = NEXT_INSN (first);
    while (1)
      {
!       if (active_insn_p (first) && !INSN_LOCATION (first))
! 	INSN_LOCATION (first) = loc;
        if (first == last)
  	break;
        first = NEXT_INSN (first);
*************** emit_pattern_before (rtx pattern, rtx be
*** 4550,4556 ****
        next = PREV_INSN (next);

    if (INSN_P (next))
!     return emit_pattern_before_setloc (pattern, before, INSN_LOCATOR (next),
  				       insnp, make_raw);
    else
      return emit_pattern_before_noloc (pattern, before,
--- 4550,4556 ----
        next = PREV_INSN (next);

    if (INSN_P (next))
!     return emit_pattern_before_setloc (pattern, before, INSN_LOCATION (next),
  				       insnp, make_raw);
    else
      return emit_pattern_before_noloc (pattern, before,
*************** emit_pattern_before (rtx pattern, rtx be
*** 4558,4564 ****
                                        NULL, make_raw);
  }

! /* Like emit_insn_before_noloc, but set INSN_LOCATOR according to LOC.  */
  rtx
  emit_insn_before_setloc (rtx pattern, rtx before, int loc)
  {
--- 4558,4564 ----
                                        NULL, make_raw);
  }

! /* Like emit_insn_before_noloc, but set INSN_LOCATION according to LOC.  */
  rtx
  emit_insn_before_setloc (rtx pattern, rtx before, int loc)
  {
*************** emit_insn_before_setloc (rtx pattern, rt
*** 4566,4579 ****
  				     make_insn_raw);
  }

! /* Like emit_insn_before_noloc, but set INSN_LOCATOR according to BEFORE.  */
  rtx
  emit_insn_before (rtx pattern, rtx before)
  {
    return emit_pattern_before (pattern, before, true, true, make_insn_raw);
  }

! /* like emit_insn_before_noloc, but set INSN_LOCATOR according to LOC.  */
  rtx
  emit_jump_insn_before_setloc (rtx pattern, rtx before, int loc)
  {
--- 4566,4579 ----
  				     make_insn_raw);
  }

! /* Like emit_insn_before_noloc, but set INSN_LOCATION according to BEFORE.  */
  rtx
  emit_insn_before (rtx pattern, rtx before)
  {
    return emit_pattern_before (pattern, before, true, true, make_insn_raw);
  }

! /* like emit_insn_before_noloc, but set INSN_LOCATION according to LOC.  */
  rtx
  emit_jump_insn_before_setloc (rtx pattern, rtx before, int loc)
  {
*************** emit_jump_insn_before_setloc (rtx patter
*** 4581,4587 ****
  				     make_jump_insn_raw);
  }

! /* Like emit_jump_insn_before_noloc, but set INSN_LOCATOR according
to BEFORE.  */
  rtx
  emit_jump_insn_before (rtx pattern, rtx before)
  {
--- 4581,4587 ----
  				     make_jump_insn_raw);
  }

! /* Like emit_jump_insn_before_noloc, but set INSN_LOCATION according
to BEFORE.  */
  rtx
  emit_jump_insn_before (rtx pattern, rtx before)
  {
*************** emit_jump_insn_before (rtx pattern, rtx
*** 4589,4595 ****
  			      make_jump_insn_raw);
  }

! /* Like emit_insn_before_noloc, but set INSN_LOCATOR according to LOC.  */
  rtx
  emit_call_insn_before_setloc (rtx pattern, rtx before, int loc)
  {
--- 4589,4595 ----
  			      make_jump_insn_raw);
  }

! /* Like emit_insn_before_noloc, but set INSN_LOCATION according to LOC.  */
  rtx
  emit_call_insn_before_setloc (rtx pattern, rtx before, int loc)
  {
*************** emit_call_insn_before_setloc (rtx patter
*** 4598,4604 ****
  }

  /* Like emit_call_insn_before_noloc,
!    but set insn_locator according to BEFORE.  */
  rtx
  emit_call_insn_before (rtx pattern, rtx before)
  {
--- 4598,4604 ----
  }

  /* Like emit_call_insn_before_noloc,
!    but set insn_location according to BEFORE.  */
  rtx
  emit_call_insn_before (rtx pattern, rtx before)
  {
*************** emit_call_insn_before (rtx pattern, rtx
*** 4606,4612 ****
  			      make_call_insn_raw);
  }

! /* Like emit_insn_before_noloc, but set INSN_LOCATOR according to LOC.  */
  rtx
  emit_debug_insn_before_setloc (rtx pattern, rtx before, int loc)
  {
--- 4606,4612 ----
  			      make_call_insn_raw);
  }

! /* Like emit_insn_before_noloc, but set INSN_LOCATION according to LOC.  */
  rtx
  emit_debug_insn_before_setloc (rtx pattern, rtx before, int loc)
  {
*************** emit_debug_insn_before_setloc (rtx patte
*** 4615,4621 ****
  }

  /* Like emit_debug_insn_before_noloc,
!    but set insn_locator according to BEFORE.  */
  rtx
  emit_debug_insn_before (rtx pattern, rtx before)
  {
--- 4615,4621 ----
  }

  /* Like emit_debug_insn_before_noloc,
!    but set insn_location according to BEFORE.  */
  rtx
  emit_debug_insn_before (rtx pattern, rtx before)
  {
*************** emit_copy_of_insn_after (rtx insn, rtx a
*** 5865,5871 ****
    /* Update LABEL_NUSES.  */
    mark_jump_label (PATTERN (new_rtx), new_rtx, 0);

!   INSN_LOCATOR (new_rtx) = INSN_LOCATOR (insn);

    /* If the old insn is frame related, then so is the new one.  This is
       primarily needed for IA-64 unwind info which marks epilogue insns,
--- 5865,5871 ----
    /* Update LABEL_NUSES.  */
    mark_jump_label (PATTERN (new_rtx), new_rtx, 0);

!   INSN_LOCATION (new_rtx) = INSN_LOCATION (insn);

    /* If the old insn is frame related, then so is the new one.  This is
       primarily needed for IA-64 unwind info which marks epilogue insns,
*************** gen_hard_reg_clobber (enum machine_mode
*** 5900,6149 ****
  	    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (mode, regno)));
  }

! /* Data structures representing mapping of INSN_LOCATOR into scope
blocks, line
!    numbers and files.  In order to be GGC friendly we need to use separate
!    varrays.  This also slightly improve the memory locality in binary search.
!    The _locs array contains locators where the given property change.  The
!    block_locators_blocks contains the scope block that is used for all insn
!    locator greater than corresponding block_locators_locs value and smaller
!    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) *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;

  /* Hold current location information and last location information, so the
     datastructures are built lazily only when some instructions in given
     place are needed.  */
  static location_t curr_location, last_location;
- static tree curr_block, last_block;
- static int curr_rtl_loc = -1;

! /* Allocate insn locator datastructure.  */
  void
! insn_locators_alloc (void)
  {
!   prologue_locator = epilogue_locator = 0;
!
!   block_locators_locs = VEC_alloc (int, heap, 32);
!   block_locators_blocks = VEC_alloc (tree, gc, 32);
!   locations_locators_locs = VEC_alloc (int, heap, 32);
!   locations_locators_vals = VEC_alloc (location_t, heap, 32);
!
    curr_location = UNKNOWN_LOCATION;
    last_location = UNKNOWN_LOCATION;
-   curr_block = NULL;
-   last_block = NULL;
-   curr_rtl_loc = 0;
  }

  /* 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;
! }
!
! /* Allocate insn locator datastructure.  */
! void
! insn_locators_free (void)
  {
!   prologue_locator = epilogue_locator = 0;
!
!   VEC_free (int, heap, block_locators_locs);
!   VEC_free (tree,gc, block_locators_blocks);
!   VEC_free (int, heap, locations_locators_locs);
!   VEC_free (location_t, heap, locations_locators_vals);
  }

  /* 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;
    curr_location = location;
  }

  /* Get current location.  */
  location_t
! get_curr_insn_source_location (void)
  {
    return curr_location;
  }

- /* 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;
- }
-
- /* Get current scope block.  */
- tree
- get_curr_insn_block (void)
- {
-   return curr_block;
- }
-
- /* Return current insn locator.  */
- int
- curr_insn_locator (void)
- {
-   if (curr_rtl_loc == -1 || curr_location == UNKNOWN_LOCATION)
-     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;
-     }
-   if (last_location != curr_location)
-     {
-       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;
- }
- 
-
- /* Return lexical scope block locator belongs to.  */
- static tree
- locator_scope (int loc)
- {
-   int max = VEC_length (int, block_locators_locs);
-   int min = 0;
-
-   /* When block_locators_locs was initialized, the pro- and epilogue
-      insns didn't exist yet and can therefore not be found this way.
-      But we know that they belong to the outer most block of the
-      current function.
-      Without this test, the prologue would be put inside the block of
-      the first valid instruction in the function and when that first
-      insn is part of an inlined function then the low_pc of that
-      inlined function is messed up.  Likewise for the epilogue and
-      the last valid instruction.  */
-   if (loc == prologue_locator || loc == epilogue_locator)
-     return DECL_INITIAL (cfun->decl);
-
-   if (!max || !loc)
-     return NULL;
-   while (1)
-     {
-       int pos = (min + max) / 2;
-       int tmp = VEC_index (int, block_locators_locs, pos);
-
-       if (tmp <= loc && min != pos)
- 	min = pos;
-       else if (tmp > loc && max != pos)
- 	max = pos;
-       else
- 	{
- 	  min = pos;
- 	  break;
- 	}
-     }
-   return VEC_index (tree, block_locators_blocks, min);
- }
-
  /* Return lexical scope block insn belongs to.  */
  tree
  insn_scope (const_rtx insn)
  {
!   return locator_scope (INSN_LOCATOR (insn));
! }
!
! /* Return line number of the statement specified by the locator.  */
! location_t
! locator_location (int loc)
! {
!   int max = VEC_length (int, locations_locators_locs);
!   int min = 0;
!
!   while (1)
!     {
!       int pos = (min + max) / 2;
!       int tmp = VEC_index (int, locations_locators_locs, pos);
!
!       if (tmp <= loc && min != pos)
! 	min = pos;
!       else if (tmp > loc && max != pos)
! 	max = pos;
!       else
! 	{
! 	  min = pos;
! 	  break;
! 	}
!     }
!   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.  */
  int
  insn_line (const_rtx insn)
  {
!   return locator_line (INSN_LOCATOR (insn));
! }
!
! /* Return source file of the statement specified by LOC.  */
! const char *
! locator_file (int loc)
! {
!   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.  */
  const char *
  insn_file (const_rtx insn)
  {
!   return locator_file (INSN_LOCATOR (insn));
  }

- /* Return true if LOC1 and LOC2 locators have the same location and scope.  */
- bool
- locator_eq (int loc1, int loc2)
- {
-   if (loc1 == loc2)
-     return true;
-   if (locator_location (loc1) != locator_location (loc2))
-     return false;
-   return locator_scope (loc1) == locator_scope (loc2);
- }
- 
-
  /* Return true if memory model MODEL requires a pre-operation (release-style)
     barrier or a post-operation (acquire-style) barrier.  While not universal,
     this function matches behavior of several targets.  */
--- 5900,5965 ----
  	    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (mode, regno)));
  }

! location_t prologue_location;
! location_t epilogue_location;

  /* Hold current location information and last location information, so the
     datastructures are built lazily only when some instructions in given
     place are needed.  */
  static location_t curr_location, last_location;

! /* Allocate insn location datastructure.  */
  void
! insn_locations_init (void)
  {
!   prologue_location = epilogue_location = 0;
    curr_location = UNKNOWN_LOCATION;
    last_location = UNKNOWN_LOCATION;
  }

  /* At the end of emit stage, clear current location.  */
  void
! insn_locations_finalize (void)
  {
!   epilogue_location = curr_location;
!   curr_location = UNKNOWN_LOCATION;
  }

  /* Set current location.  */
  void
! set_curr_insn_location (location_t location)
  {
    curr_location = location;
  }

  /* Get current location.  */
  location_t
! curr_insn_location (void)
  {
    return curr_location;
  }

  /* Return lexical scope block insn belongs to.  */
  tree
  insn_scope (const_rtx insn)
  {
!   return LOCATION_BLOCK (INSN_LOCATION (insn));
  }

  /* Return line number of the statement that produced this insn.  */
  int
  insn_line (const_rtx insn)
  {
!   return LOCATION_LINE (INSN_LOCATION (insn));
  }

  /* Return source file of the statement that produced this insn.  */
  const char *
  insn_file (const_rtx insn)
  {
!   return LOCATION_FILE (INSN_LOCATION (insn));
  }

  /* Return true if memory model MODEL requires a pre-operation (release-style)
     barrier or a post-operation (acquire-style) barrier.  While not universal,
     this function matches behavior of several targets.  */
Index: gcc/cfgexpand.c
===================================================================
*** gcc/cfgexpand.c	(revision 189835)
--- gcc/cfgexpand.c	(working copy)
*************** gimple_assign_rhs_to_tree (gimple stmt)
*** 92,99 ****
  	   && gimple_location (stmt) != EXPR_LOCATION (t))
  	  || (gimple_block (stmt)
  	      && currently_expanding_to_rtl
! 	      && EXPR_P (t)
! 	      && gimple_block (stmt) != TREE_BLOCK (t)))
  	t = copy_node (t);
      }
    else
--- 92,98 ----
  	   && gimple_location (stmt) != EXPR_LOCATION (t))
  	  || (gimple_block (stmt)
  	      && currently_expanding_to_rtl
! 	      && EXPR_P (t)))
  	t = copy_node (t);
      }
    else
*************** gimple_assign_rhs_to_tree (gimple stmt)
*** 101,108 ****

    if (gimple_has_location (stmt) && CAN_HAVE_LOCATION_P (t))
      SET_EXPR_LOCATION (t, gimple_location (stmt));
-   if (gimple_block (stmt) && currently_expanding_to_rtl && EXPR_P (t))
-     TREE_BLOCK (t) = gimple_block (stmt);

    return t;
  }
--- 100,105 ----
*************** expand_gimple_cond (basic_block bb, gimp
*** 1804,1811 ****
    last2 = last = get_last_insn ();

    extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
!   set_curr_insn_source_location (gimple_location (stmt));
!   set_curr_insn_block (gimple_block (stmt));

    /* These flags have no purpose in RTL land.  */
    true_edge->flags &= ~EDGE_TRUE_VALUE;
--- 1801,1807 ----
    last2 = last = get_last_insn ();

    extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
!   set_curr_insn_location (gimple_location (stmt));

    /* These flags have no purpose in RTL land.  */
    true_edge->flags &= ~EDGE_TRUE_VALUE;
*************** expand_gimple_cond (basic_block bb, gimp
*** 1818,1830 ****
        jumpif_1 (code, op0, op1, label_rtx_for_bb (true_edge->dest),
  		true_edge->probability);
        maybe_dump_rtl_for_gimple_stmt (stmt, last);
!       if (true_edge->goto_locus)
! 	{
! 	  set_curr_insn_source_location (true_edge->goto_locus);
! 	  set_curr_insn_block (true_edge->goto_block);
! 	  true_edge->goto_locus = curr_insn_locator ();
! 	}
!       true_edge->goto_block = NULL;
        false_edge->flags |= EDGE_FALLTHRU;
        maybe_cleanup_end_of_block (false_edge, last);
        return NULL;
--- 1814,1821 ----
        jumpif_1 (code, op0, op1, label_rtx_for_bb (true_edge->dest),
  		true_edge->probability);
        maybe_dump_rtl_for_gimple_stmt (stmt, last);
!       if (!IS_UNKNOWN_LOCATION (true_edge->goto_locus))
! 	set_curr_insn_location (true_edge->goto_locus);
        false_edge->flags |= EDGE_FALLTHRU;
        maybe_cleanup_end_of_block (false_edge, last);
        return NULL;
*************** expand_gimple_cond (basic_block bb, gimp
*** 1834,1846 ****
        jumpifnot_1 (code, op0, op1, label_rtx_for_bb (false_edge->dest),
  		   false_edge->probability);
        maybe_dump_rtl_for_gimple_stmt (stmt, last);
!       if (false_edge->goto_locus)
! 	{
! 	  set_curr_insn_source_location (false_edge->goto_locus);
! 	  set_curr_insn_block (false_edge->goto_block);
! 	  false_edge->goto_locus = curr_insn_locator ();
! 	}
!       false_edge->goto_block = NULL;
        true_edge->flags |= EDGE_FALLTHRU;
        maybe_cleanup_end_of_block (true_edge, last);
        return NULL;
--- 1825,1832 ----
        jumpifnot_1 (code, op0, op1, label_rtx_for_bb (false_edge->dest),
  		   false_edge->probability);
        maybe_dump_rtl_for_gimple_stmt (stmt, last);
!       if (!IS_UNKNOWN_LOCATION (false_edge->goto_locus))
! 	set_curr_insn_location (false_edge->goto_locus);
        true_edge->flags |= EDGE_FALLTHRU;
        maybe_cleanup_end_of_block (true_edge, last);
        return NULL;
*************** expand_gimple_cond (basic_block bb, gimp
*** 1849,1861 ****
    jumpif_1 (code, op0, op1, label_rtx_for_bb (true_edge->dest),
  	    true_edge->probability);
    last = get_last_insn ();
!   if (false_edge->goto_locus)
!     {
!       set_curr_insn_source_location (false_edge->goto_locus);
!       set_curr_insn_block (false_edge->goto_block);
!       false_edge->goto_locus = curr_insn_locator ();
!     }
!   false_edge->goto_block = NULL;
    emit_jump (label_rtx_for_bb (false_edge->dest));

    BB_END (bb) = last;
--- 1835,1842 ----
    jumpif_1 (code, op0, op1, label_rtx_for_bb (true_edge->dest),
  	    true_edge->probability);
    last = get_last_insn ();
!   if (!IS_UNKNOWN_LOCATION (false_edge->goto_locus))
!     set_curr_insn_location (false_edge->goto_locus);
    emit_jump (label_rtx_for_bb (false_edge->dest));

    BB_END (bb) = last;
*************** expand_gimple_cond (basic_block bb, gimp
*** 1880,1892 ****

    maybe_dump_rtl_for_gimple_stmt (stmt, last2);

!   if (true_edge->goto_locus)
      {
!       set_curr_insn_source_location (true_edge->goto_locus);
!       set_curr_insn_block (true_edge->goto_block);
!       true_edge->goto_locus = curr_insn_locator ();
      }
-   true_edge->goto_block = NULL;

    return new_bb;
  }
--- 1861,1871 ----

    maybe_dump_rtl_for_gimple_stmt (stmt, last2);

!   if (!IS_UNKNOWN_LOCATION (true_edge->goto_locus))
      {
!       set_curr_insn_location (true_edge->goto_locus);
!       true_edge->goto_locus = curr_insn_location ();
      }

    return new_bb;
  }
*************** expand_call_stmt (gimple stmt)
*** 1986,1992 ****
      CALL_FROM_THUNK_P (exp) = gimple_call_from_thunk_p (stmt);
    CALL_EXPR_VA_ARG_PACK (exp) = gimple_call_va_arg_pack_p (stmt);
    SET_EXPR_LOCATION (exp, gimple_location (stmt));
-   TREE_BLOCK (exp) = gimple_block (stmt);

    /* Ensure RTL is created for debug args.  */
    if (decl && DECL_HAS_DEBUG_ARGS_P (decl))
--- 1965,1970 ----
*************** expand_gimple_stmt_1 (gimple stmt)
*** 2021,2028 ****
  {
    tree op0;

!   set_curr_insn_source_location (gimple_location (stmt));
!   set_curr_insn_block (gimple_block (stmt));

    switch (gimple_code (stmt))
      {
--- 1999,2005 ----
  {
    tree op0;

!   set_curr_insn_location (gimple_location (stmt));

    switch (gimple_code (stmt))
      {
*************** expand_gimple_basic_block (basic_block b
*** 3766,3773 ****
  	  tree op;
  	  gimple def;

! 	  location_t sloc = get_curr_insn_source_location ();
! 	  tree sblock = get_curr_insn_block ();

  	  /* Look for SSA names that have their last use here (TERed
  	     names always have only one real use).  */
--- 3743,3749 ----
  	  tree op;
  	  gimple def;

! 	  location_t sloc = curr_insn_location ();

  	  /* Look for SSA names that have their last use here (TERed
  	     names always have only one real use).  */
*************** expand_gimple_basic_block (basic_block b
*** 3800,3807 ****
  		    rtx val;
  		    enum machine_mode mode;

! 		    set_curr_insn_source_location (gimple_location (def));
! 		    set_curr_insn_block (gimple_block (def));

  		    DECL_ARTIFICIAL (vexpr) = 1;
  		    TREE_TYPE (vexpr) = TREE_TYPE (value);
--- 3776,3782 ----
  		    rtx val;
  		    enum machine_mode mode;

! 		    set_curr_insn_location (gimple_location (def));

  		    DECL_ARTIFICIAL (vexpr) = 1;
  		    TREE_TYPE (vexpr) = TREE_TYPE (value);
*************** expand_gimple_basic_block (basic_block b
*** 3828,3835 ****
  		      }
  		  }
  	      }
! 	  set_curr_insn_source_location (sloc);
! 	  set_curr_insn_block (sblock);
  	}

        currently_expanding_gimple_stmt = stmt;
--- 3803,3809 ----
  		      }
  		  }
  	      }
! 	  set_curr_insn_location (sloc);
  	}

        currently_expanding_gimple_stmt = stmt;
*************** expand_gimple_basic_block (basic_block b
*** 3844,3851 ****
  	}
        else if (gimple_debug_bind_p (stmt))
  	{
! 	  location_t sloc = get_curr_insn_source_location ();
! 	  tree sblock = get_curr_insn_block ();
  	  gimple_stmt_iterator nsi = gsi;

  	  for (;;)
--- 3818,3824 ----
  	}
        else if (gimple_debug_bind_p (stmt))
  	{
! 	  location_t sloc = curr_insn_location ();
  	  gimple_stmt_iterator nsi = gsi;

  	  for (;;)
*************** expand_gimple_basic_block (basic_block b
*** 3867,3874 ****

  	      last = get_last_insn ();

! 	      set_curr_insn_source_location (gimple_location (stmt));
! 	      set_curr_insn_block (gimple_block (stmt));

  	      if (DECL_P (var))
  		mode = DECL_MODE (var);
--- 3840,3846 ----

  	      last = get_last_insn ();

! 	      set_curr_insn_location (gimple_location (stmt));

  	      if (DECL_P (var))
  		mode = DECL_MODE (var);
*************** expand_gimple_basic_block (basic_block b
*** 3906,3918 ****
  		break;
  	    }

! 	  set_curr_insn_source_location (sloc);
! 	  set_curr_insn_block (sblock);
  	}
        else if (gimple_debug_source_bind_p (stmt))
  	{
! 	  location_t sloc = get_curr_insn_source_location ();
! 	  tree sblock = get_curr_insn_block ();
  	  tree var = gimple_debug_source_bind_get_var (stmt);
  	  tree value = gimple_debug_source_bind_get_value (stmt);
  	  rtx val;
--- 3878,3888 ----
  		break;
  	    }

! 	  set_curr_insn_location (sloc);
  	}
        else if (gimple_debug_source_bind_p (stmt))
  	{
! 	  location_t sloc = curr_insn_location ();
  	  tree var = gimple_debug_source_bind_get_var (stmt);
  	  tree value = gimple_debug_source_bind_get_value (stmt);
  	  rtx val;
*************** expand_gimple_basic_block (basic_block b
*** 3920,3927 ****

  	  last = get_last_insn ();

! 	  set_curr_insn_source_location (gimple_location (stmt));
! 	  set_curr_insn_block (gimple_block (stmt));

  	  mode = DECL_MODE (var);

--- 3890,3896 ----

  	  last = get_last_insn ();

! 	  set_curr_insn_location (gimple_location (stmt));

  	  mode = DECL_MODE (var);

*************** expand_gimple_basic_block (basic_block b
*** 3939,3946 ****
  	      PAT_VAR_LOCATION_LOC (val) = (rtx)value;
  	    }

! 	  set_curr_insn_source_location (sloc);
! 	  set_curr_insn_block (sblock);
  	}
        else
  	{
--- 3908,3914 ----
  	      PAT_VAR_LOCATION_LOC (val) = (rtx)value;
  	    }

! 	  set_curr_insn_location (sloc);
  	}
        else
  	{
*************** expand_gimple_basic_block (basic_block b
*** 3981,3993 ****
    /* Expand implicit goto and convert goto_locus.  */
    FOR_EACH_EDGE (e, ei, bb->succs)
      {
!       if (e->goto_locus && e->goto_block)
! 	{
! 	  set_curr_insn_source_location (e->goto_locus);
! 	  set_curr_insn_block (e->goto_block);
! 	  e->goto_locus = curr_insn_locator ();
! 	}
!       e->goto_block = NULL;
        if ((e->flags & EDGE_FALLTHRU) && e->dest != bb->next_bb)
  	{
  	  emit_jump (label_rtx_for_bb (e->dest));
--- 3949,3956 ----
    /* Expand implicit goto and convert goto_locus.  */
    FOR_EACH_EDGE (e, ei, bb->succs)
      {
!       if (!IS_UNKNOWN_LOCATION (e->goto_locus))
! 	set_curr_insn_location (e->goto_locus);
        if ((e->flags & EDGE_FALLTHRU) && e->dest != bb->next_bb)
  	{
  	  emit_jump (label_rtx_for_bb (e->dest));
*************** construct_exit_block (void)
*** 4107,4118 ****

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

-   /* The following insns belong to the top scope.  */
-   set_curr_insn_block (DECL_INITIAL (current_function_decl));
-
    /* Generate rtl for function exit.  */
    expand_function_end ();

--- 4070,4078 ----

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

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

*************** gimple_expand_cfg (void)
*** 4331,4350 ****

    rtl_profile_for_bb (ENTRY_BLOCK_PTR);

!   insn_locators_alloc ();
    if (!DECL_IS_BUILTIN (current_function_decl))
      {
        /* Eventually, all FEs should explicitly set function_start_locus.  */
!       if (cfun->function_start_locus == UNKNOWN_LOCATION)
!        set_curr_insn_source_location
           (DECL_SOURCE_LOCATION (current_function_decl));
        else
!        set_curr_insn_source_location (cfun->function_start_locus);
      }
    else
!     set_curr_insn_source_location (UNKNOWN_LOCATION);
!   set_curr_insn_block (DECL_INITIAL (current_function_decl));
!   prologue_locator = curr_insn_locator ();

  #ifdef INSN_SCHEDULING
    init_sched_attrs ();
--- 4291,4309 ----

    rtl_profile_for_bb (ENTRY_BLOCK_PTR);

!   insn_locations_init ();
    if (!DECL_IS_BUILTIN (current_function_decl))
      {
        /* Eventually, all FEs should explicitly set function_start_locus.  */
!       if (IS_UNKNOWN_LOCATION (cfun->function_start_locus))
!        set_curr_insn_location
           (DECL_SOURCE_LOCATION (current_function_decl));
        else
!        set_curr_insn_location (cfun->function_start_locus);
      }
    else
!     set_curr_insn_location (UNKNOWN_LOCATION);
!   prologue_location = curr_insn_location ();

  #ifdef INSN_SCHEDULING
    init_sched_attrs ();
*************** gimple_expand_cfg (void)
*** 4514,4521 ****
    free_histograms ();

    construct_exit_block ();
!   set_curr_insn_block (DECL_INITIAL (current_function_decl));
!   insn_locators_finalize ();

    /* Zap the tree EH table.  */
    set_eh_throw_stmt_table (cfun, NULL);
--- 4473,4479 ----
    free_histograms ();

    construct_exit_block ();
!   insn_locations_finalize ();

    /* Zap the tree EH table.  */
    set_eh_throw_stmt_table (cfun, NULL);
Index: gcc/cfgcleanup.c
===================================================================
*** gcc/cfgcleanup.c	(revision 189835)
--- gcc/cfgcleanup.c	(working copy)
*************** try_forward_edges (int mode, basic_block
*** 481,493 ****
  		  int new_locus = single_succ_edge (target)->goto_locus;
  		  int locus = goto_locus;

! 		  if (new_locus && locus && !locator_eq (new_locus, locus))
  		    new_target = NULL;
  		  else
  		    {
  		      rtx last;

! 		      if (new_locus)
  			locus = new_locus;

  		      last = BB_END (target);
--- 481,495 ----
  		  int new_locus = single_succ_edge (target)->goto_locus;
  		  int locus = goto_locus;

! 		  if (!IS_UNKNOWN_LOCATION (new_locus)
! 		      && !IS_UNKNOWN_LOCATION (locus)
! 		      && new_locus != locus)
  		    new_target = NULL;
  		  else
  		    {
  		      rtx last;

! 		      if (!IS_UNKNOWN_LOCATION (new_locus))
  			locus = new_locus;

  		      last = BB_END (target);
*************** try_forward_edges (int mode, basic_block
*** 495,507 ****
  			last = prev_nondebug_insn (last);

  		      new_locus = last && INSN_P (last)
! 				  ? INSN_LOCATOR (last) : 0;

! 		      if (new_locus && locus && !locator_eq (new_locus, locus))
  			new_target = NULL;
  		      else
  			{
! 			  if (new_locus)
  			    locus = new_locus;

  			  goto_locus = locus;
--- 497,511 ----
  			last = prev_nondebug_insn (last);

  		      new_locus = last && INSN_P (last)
! 				  ? INSN_LOCATION (last) : 0;

! 		      if (!IS_UNKNOWN_LOCATION (new_locus)
! 			  && !IS_UNKNOWN_LOCATION (locus)
! 			  && new_locus != locus)
  			new_target = NULL;
  		      else
  			{
! 			  if (!IS_UNKNOWN_LOCATION (new_locus))
  			    locus = new_locus;

  			  goto_locus = locus;
Index: gcc/tree-ssa-live.c
===================================================================
*** gcc/tree-ssa-live.c	(revision 189835)
--- gcc/tree-ssa-live.c	(working copy)
*************** remove_unused_scope_block_p (tree scope,
*** 587,593 ****
     else
     /* Verfify that only blocks with source location set
        are entry points to the inlined functions.  */
!      gcc_assert (BLOCK_SOURCE_LOCATION (scope) == UNKNOWN_LOCATION);

     TREE_USED (scope) = !unused;
     return unused;
--- 587,593 ----
     else
     /* Verfify that only blocks with source location set
        are entry points to the inlined functions.  */
!      gcc_assert (IS_UNKNOWN_LOCATION (BLOCK_SOURCE_LOCATION (scope)));

     TREE_USED (scope) = !unused;
     return unused;
*************** dump_scope_block (FILE *file, int indent
*** 615,621 ****
    fprintf (file, "\n%*s{ Scope block #%i%s%s",indent, "" ,
BLOCK_NUMBER (scope),
    	   TREE_USED (scope) ? "" : " (unused)",
  	   BLOCK_ABSTRACT (scope) ? " (abstract)": "");
!   if (BLOCK_SOURCE_LOCATION (scope) != UNKNOWN_LOCATION)
      {
        expanded_location s = expand_location (BLOCK_SOURCE_LOCATION (scope));
        fprintf (file, " %s:%i", s.file, s.line);
--- 615,621 ----
    fprintf (file, "\n%*s{ Scope block #%i%s%s",indent, "" ,
BLOCK_NUMBER (scope),
    	   TREE_USED (scope) ? "" : " (unused)",
  	   BLOCK_ABSTRACT (scope) ? " (abstract)": "");
!   if (!IS_UNKNOWN_LOCATION (BLOCK_SOURCE_LOCATION (scope)))
      {
        expanded_location s = expand_location (BLOCK_SOURCE_LOCATION (scope));
        fprintf (file, " %s:%i", s.file, s.line);
*************** remove_unused_locals (void)
*** 765,777 ****
            FOR_EACH_PHI_ARG (arg_p, phi, i, SSA_OP_ALL_USES)
              {
  	      tree arg = USE_FROM_PTR (arg_p);
  	      mark_all_vars_used (&arg, global_unused_vars);
              }
          }

        FOR_EACH_EDGE (e, ei, bb->succs)
  	if (e->goto_locus)
! 	  TREE_USED (e->goto_block) = true;
      }

    /* We do a two-pass approach about the out-of-scope clobbers.  We want
--- 765,782 ----
            FOR_EACH_PHI_ARG (arg_p, phi, i, SSA_OP_ALL_USES)
              {
  	      tree arg = USE_FROM_PTR (arg_p);
+ 	      int index = PHI_ARG_INDEX_FROM_USE (arg_p);
+ 	      tree block =
+ 		LOCATION_BLOCK (gimple_phi_arg_location (phi, index));
+ 	      if (block != NULL)
+ 		TREE_USED (block) = true;
  	      mark_all_vars_used (&arg, global_unused_vars);
              }
          }

        FOR_EACH_EDGE (e, ei, bb->succs)
  	if (e->goto_locus)
! 	  TREE_USED (LOCATION_BLOCK (e->goto_locus)) = true;
      }

    /* We do a two-pass approach about the out-of-scope clobbers.  We want
Index: gcc/lto/lto.c
===================================================================
*** gcc/lto/lto.c	(revision 189835)
--- gcc/lto/lto.c	(working copy)
*************** lto_fixup_prevailing_decls (tree t)
*** 1603,1609 ****
    else if (EXPR_P (t))
      {
        int i;
-       LTO_NO_PREVAIL (t->exp.block);
        for (i = TREE_OPERAND_LENGTH (t) - 1; i >= 0; --i)
  	LTO_SET_PREVAIL (TREE_OPERAND (t, i));
      }
--- 1603,1608 ----
Index: gcc/tree-streamer-out.c
===================================================================
*** gcc/tree-streamer-out.c	(revision 189835)
--- gcc/tree-streamer-out.c	(working copy)
*************** write_ts_decl_minimal_tree_pointers (str
*** 471,477 ****
  {
    stream_write_tree (ob, DECL_NAME (expr), ref_p);
    stream_write_tree (ob, DECL_CONTEXT (expr), ref_p);
!   lto_output_location (ob, DECL_SOURCE_LOCATION (expr));
  }


--- 471,477 ----
  {
    stream_write_tree (ob, DECL_NAME (expr), ref_p);
    stream_write_tree (ob, DECL_CONTEXT (expr), ref_p);
!   lto_output_location (ob, LOCATION_LOCUS (DECL_SOURCE_LOCATION (expr)));
  }


*************** write_ts_exp_tree_pointers (struct outpu
*** 668,674 ****
    streamer_write_hwi (ob, TREE_OPERAND_LENGTH (expr));
    for (i = 0; i < TREE_OPERAND_LENGTH (expr); i++)
      stream_write_tree (ob, TREE_OPERAND (expr, i), ref_p);
!   lto_output_location (ob, EXPR_LOCATION (expr));
    stream_write_tree (ob, TREE_BLOCK (expr), ref_p);
  }

--- 668,674 ----
    streamer_write_hwi (ob, TREE_OPERAND_LENGTH (expr));
    for (i = 0; i < TREE_OPERAND_LENGTH (expr); i++)
      stream_write_tree (ob, TREE_OPERAND (expr, i), ref_p);
!   lto_output_location (ob, LOCATION_LOCUS (EXPR_LOCATION (expr)));
    stream_write_tree (ob, TREE_BLOCK (expr), ref_p);
  }

Index: gcc/rtl.c
===================================================================
*** gcc/rtl.c	(revision 189835)
--- gcc/rtl.c	(working copy)
*************** rtx_equal_p_cb (const_rtx x, const_rtx y
*** 440,446 ****
  #ifndef GENERATOR_FILE
  	      if (((code == ASM_OPERANDS && i == 6)
  		   || (code == ASM_INPUT && i == 1))
! 		  && locator_eq (XINT (x, i), XINT (y, i)))
  		break;
  #endif
  	      return 0;
--- 440,446 ----
  #ifndef GENERATOR_FILE
  	      if (((code == ASM_OPERANDS && i == 6)
  		   || (code == ASM_INPUT && i == 1))
! 		  && XINT (x, i) == XINT (y, i))
  		break;
  #endif
  	      return 0;
*************** rtx_equal_p (const_rtx x, const_rtx y)
*** 579,585 ****
  #ifndef GENERATOR_FILE
  	      if (((code == ASM_OPERANDS && i == 6)
  		   || (code == ASM_INPUT && i == 1))
! 		  && locator_eq (XINT (x, i), XINT (y, i)))
  		break;
  #endif
  	      return 0;
--- 579,585 ----
  #ifndef GENERATOR_FILE
  	      if (((code == ASM_OPERANDS && i == 6)
  		   || (code == ASM_INPUT && i == 1))
! 		  && XINT (x, i) == XINT (y, i))
  		break;
  #endif
  	      return 0;
Index: gcc/rtl.h
===================================================================
*** gcc/rtl.h	(revision 189835)
--- gcc/rtl.h	(working copy)
*************** extern void rtl_check_failed_flag (const
*** 739,744 ****
--- 739,745 ----
  #endif

  #define XINT(RTX, N)	(RTL_CHECK2 (RTX, N, 'i', 'n').rt_int)
+ #define XUINT(RTX, N)   (RTL_CHECK2 (RTX, N, 'i', 'n').rt_uint)
  #define XSTR(RTX, N)	(RTL_CHECK2 (RTX, N, 's', 'S').rt_str)
  #define XEXP(RTX, N)	(RTL_CHECK2 (RTX, N, 'e', 'u').rt_rtx)
  #define XVEC(RTX, N)	(RTL_CHECK2 (RTX, N, 'E', 'V').rt_rtvec)
*************** extern void rtl_check_failed_flag (const
*** 802,814 ****
  /* The body of an insn.  */
  #define PATTERN(INSN)	XEXP (INSN, 4)

! #define INSN_LOCATOR(INSN) XINT (INSN, 5)
  /* LOCATION of an RTX if relevant.  */
  #define RTL_LOCATION(X) (INSN_P (X) ? \
! 			 locator_location (INSN_LOCATOR (X)) \
! 			 : UNKNOWN_LOCATION)
! /* LOCATION of current INSN.  */
! #define CURR_INSN_LOCATION (locator_location (curr_insn_locator ()))

  /* Code number of instruction, from when it was recognized.
     -1 means this instruction has not been recognized yet.  */
--- 803,815 ----
  /* The body of an insn.  */
  #define PATTERN(INSN)	XEXP (INSN, 4)

! #define INSN_LOCATION(INSN) XUINT (INSN, 5)
!
! #define INSN_HAS_LOCATION(INSN) (!IS_UNKNOWN_LOCATION (INSN_LOCATION (INSN)))
!
  /* LOCATION of an RTX if relevant.  */
  #define RTL_LOCATION(X) (INSN_P (X) ? \
! 			 INSN_LOCATION (X) : UNKNOWN_LOCATION)

  /* Code number of instruction, from when it was recognized.
     -1 means this instruction has not been recognized yet.  */
*************** extern rtx prev_cc0_setter (rtx);
*** 1807,1818 ****
  /* In emit-rtl.c  */
  extern int insn_line (const_rtx);
  extern const char * insn_file (const_rtx);
- extern location_t locator_location (int);
- extern int locator_line (int);
- extern const char * locator_file (int);
- extern bool locator_eq (int, int);
- extern int prologue_locator, epilogue_locator;
  extern tree insn_scope (const_rtx);

  /* In jump.c */
  extern enum rtx_code reverse_condition (enum rtx_code);
--- 1808,1815 ----
  /* In emit-rtl.c  */
  extern int insn_line (const_rtx);
  extern const char * insn_file (const_rtx);
  extern tree insn_scope (const_rtx);
+ extern location_t prologue_location, epilogue_location;

  /* In jump.c */
  extern enum rtx_code reverse_condition (enum rtx_code);
*************** extern const struct rtl_hooks general_rt
*** 2648,2661 ****
  /* Keep this for the nonce.  */
  #define gen_lowpart rtl_hooks.gen_lowpart

! extern void insn_locators_alloc (void);
! extern void insn_locators_free (void);
! extern void insn_locators_finalize (void);
! extern void set_curr_insn_source_location (location_t);
! extern location_t get_curr_insn_source_location (void);
! extern void set_curr_insn_block (tree);
! extern tree get_curr_insn_block (void);
! extern int curr_insn_locator (void);
  extern bool optimize_insn_for_size_p (void);
  extern bool optimize_insn_for_speed_p (void);

--- 2645,2654 ----
  /* Keep this for the nonce.  */
  #define gen_lowpart rtl_hooks.gen_lowpart

! extern void insn_locations_init (void);
! extern void insn_locations_finalize (void);
! extern void set_curr_insn_location (location_t);
! extern location_t curr_insn_location (void);
  extern bool optimize_insn_for_size_p (void);
  extern bool optimize_insn_for_speed_p (void);

Index: gcc/tree-inline.c
===================================================================
*** gcc/tree-inline.c	(revision 189835)
--- gcc/tree-inline.c	(working copy)
*************** remap_gimple_op_r (tree *tp, int *walk_s
*** 852,861 ****
        /* Otherwise, just copy the node.  Note that copy_tree_r already
  	 knows not to copy VAR_DECLs, etc., so this is safe.  */

-       /* We should never have TREE_BLOCK set on non-statements.  */
-       if (EXPR_P (*tp))
- 	gcc_assert (!TREE_BLOCK (*tp));
-
        if (TREE_CODE (*tp) == MEM_REF)
  	{
  	  tree ptr = TREE_OPERAND (*tp, 0);
--- 852,857 ----
*************** remap_gimple_op_r (tree *tp, int *walk_s
*** 901,913 ****
  	{
  	  /* Variable substitution need not be simple.  In particular,
  	     the MEM_REF substitution above.  Make sure that
! 	     TREE_CONSTANT and friends are up-to-date.  But make sure
! 	     to not improperly set TREE_BLOCK on some sub-expressions.  */
  	  int invariant = is_gimple_min_invariant (*tp);
- 	  tree block = id->block;
- 	  id->block = NULL_TREE;
  	  walk_tree (&TREE_OPERAND (*tp, 0), remap_gimple_op_r, data, NULL);
- 	  id->block = block;
  	  recompute_tree_invariant_for_addr_expr (*tp);

  	  /* If this used to be invariant, but is not any longer,
--- 897,905 ----
  	{
  	  /* Variable substitution need not be simple.  In particular,
  	     the MEM_REF substitution above.  Make sure that
! 	     TREE_CONSTANT and friends are up-to-date.  */
  	  int invariant = is_gimple_min_invariant (*tp);
  	  walk_tree (&TREE_OPERAND (*tp, 0), remap_gimple_op_r, data, NULL);
  	  recompute_tree_invariant_for_addr_expr (*tp);

  	  /* If this used to be invariant, but is not any longer,
*************** remap_gimple_op_r (tree *tp, int *walk_s
*** 919,924 ****
--- 911,932 ----
  	}
      }

+   /* Update the TREE_BLOCK for the cloned expr.  */
+   if (EXPR_P (*tp))
+     {
+       tree new_block = id->remapping_type_depth == 0 ? id->block : NULL;
+       tree old_block = TREE_BLOCK (*tp);
+       if (old_block)
+ 	{
+ 	  tree *n;
+ 	  n = (tree *) pointer_map_contains (id->decl_map,
+ 					     TREE_BLOCK (*tp));
+ 	  if (n)
+ 	    new_block = *n;
+ 	}
+       TREE_SET_BLOCK (*tp, new_block);
+     }
+
    /* Keep iterating.  */
    return NULL_TREE;
  }
*************** copy_tree_body_r (tree *tp, int *walk_su
*** 1144,1154 ****
  	      tree *n;
  	      n = (tree *) pointer_map_contains (id->decl_map,
  						 TREE_BLOCK (*tp));
- 	      gcc_assert (n || id->remapping_type_depth != 0);
  	      if (n)
  		new_block = *n;
  	    }
! 	  TREE_BLOCK (*tp) = new_block;
  	}

        if (TREE_CODE (*tp) != OMP_CLAUSE)
--- 1152,1161 ----
  	      tree *n;
  	      n = (tree *) pointer_map_contains (id->decl_map,
  						 TREE_BLOCK (*tp));
  	      if (n)
  		new_block = *n;
  	    }
! 	  TREE_SET_BLOCK (*tp, new_block);
  	}

        if (TREE_CODE (*tp) != OMP_CLAUSE)
*************** copy_phis_for_bb (basic_block bb, copy_b
*** 2020,2025 ****
--- 2027,2033 ----
  	      tree new_arg;
  	      tree block = id->block;
  	      edge_iterator ei2;
+ 	      location_t locus;

  	      /* When doing partial cloning, we allow PHIs on the entry block
  		 as long as all the arguments are the same.  Find any input
*************** copy_phis_for_bb (basic_block bb, copy_b
*** 2031,2039 ****

  	      arg = PHI_ARG_DEF_FROM_EDGE (phi, old_edge);
  	      new_arg = arg;
- 	      id->block = NULL_TREE;
  	      walk_tree (&new_arg, copy_tree_body_r, id, NULL);
- 	      id->block = block;
  	      gcc_assert (new_arg);
  	      /* With return slot optimization we can end up with
  	         non-gimple (foo *)&this->m, fix that here.  */
--- 2039,2045 ----
*************** copy_phis_for_bb (basic_block bb, copy_b
*** 2046,2053 ****
  		  gsi_insert_seq_on_edge (new_edge, stmts);
  		  inserted = true;
  		}
  	      add_phi_arg (new_phi, new_arg, new_edge,
! 			   gimple_phi_arg_location_from_edge (phi, old_edge));
  	    }
  	}
      }
--- 2052,2070 ----
  		  gsi_insert_seq_on_edge (new_edge, stmts);
  		  inserted = true;
  		}
+ 	      locus = gimple_phi_arg_location_from_edge (phi, old_edge);
+ 	      block = id->block;
+ 	      if (LOCATION_BLOCK (locus))
+ 		{
+ 		  tree *n;
+ 		  n = (tree *) pointer_map_contains (id->decl_map,
+ 			LOCATION_BLOCK (locus));
+ 		  gcc_assert (n);
+ 		  block = *n;
+ 		}
+
  	      add_phi_arg (new_phi, new_arg, new_edge,
! 			   COMBINE_LOCATION (locus, block));
  	    }
  	}
      }
*************** expand_call_inline (basic_block bb, gimp
*** 3946,3952 ****
    id->block = make_node (BLOCK);
    BLOCK_ABSTRACT_ORIGIN (id->block) = fn;
    BLOCK_SOURCE_LOCATION (id->block) = input_location;
!   prepend_lexical_block (gimple_block (stmt), id->block);

    /* Local declarations will be replaced by their equivalents in this
       map.  */
--- 3963,3970 ----
    id->block = make_node (BLOCK);
    BLOCK_ABSTRACT_ORIGIN (id->block) = fn;
    BLOCK_SOURCE_LOCATION (id->block) = input_location;
!   if (gimple_block (stmt))
!     prepend_lexical_block (gimple_block (stmt), id->block);

    /* Local declarations will be replaced by their equivalents in this
       map.  */
Index: gcc/tree-streamer-in.c
===================================================================
*** gcc/tree-streamer-in.c	(revision 189835)
--- gcc/tree-streamer-in.c	(working copy)
*************** lto_input_ts_exp_tree_pointers (struct l
*** 776,782 ****

    loc = lto_input_location (ib, data_in);
    SET_EXPR_LOCATION (expr, loc);
!   TREE_BLOCK (expr) = stream_read_tree (ib, data_in);
  }


--- 776,782 ----

    loc = lto_input_location (ib, data_in);
    SET_EXPR_LOCATION (expr, loc);
!   TREE_SET_BLOCK (expr, stream_read_tree (ib, data_in));
  }


Index: gcc/combine.c
===================================================================
*** gcc/combine.c	(revision 189835)
--- gcc/combine.c	(working copy)
*************** try_combine (rtx i3, rtx i2, rtx i1, rtx
*** 2896,2902 ****

  	  i1 = gen_rtx_INSN (VOIDmode, INSN_UID (i2), NULL_RTX, i2,
  			     BLOCK_FOR_INSN (i2), XVECEXP (PATTERN (i2), 0, 1),
! 			     INSN_LOCATOR (i2), -1, NULL_RTX);

  	  SUBST (PATTERN (i2), XVECEXP (PATTERN (i2), 0, 0));
  	  SUBST (XEXP (SET_SRC (PATTERN (i2)), 0),
--- 2896,2902 ----

  	  i1 = gen_rtx_INSN (VOIDmode, INSN_UID (i2), NULL_RTX, i2,
  			     BLOCK_FOR_INSN (i2), XVECEXP (PATTERN (i2), 0, 1),
! 			     INSN_LOCATION (i2), -1, NULL_RTX);

  	  SUBST (PATTERN (i2), XVECEXP (PATTERN (i2), 0, 0));
  	  SUBST (XEXP (SET_SRC (PATTERN (i2)), 0),
Index: gcc/tree-outof-ssa.c
===================================================================
*** gcc/tree-outof-ssa.c	(revision 189835)
--- gcc/tree-outof-ssa.c	(working copy)
*************** set_location_for_edge (edge e)
*** 108,115 ****
  {
    if (e->goto_locus)
      {
!       set_curr_insn_source_location (e->goto_locus);
!       set_curr_insn_block (e->goto_block);
      }
    else
      {
--- 108,114 ----
  {
    if (e->goto_locus)
      {
!       set_curr_insn_location (e->goto_locus);
      }
    else
      {
*************** set_location_for_edge (edge e)
*** 125,132 ****
  		continue;
  	      if (gimple_has_location (stmt) || gimple_block (stmt))
  		{
! 		  set_curr_insn_source_location (gimple_location (stmt));
! 		  set_curr_insn_block (gimple_block (stmt));
  		  return;
  		}
  	    }
--- 124,130 ----
  		continue;
  	      if (gimple_has_location (stmt) || gimple_block (stmt))
  		{
! 		  set_curr_insn_location (gimple_location (stmt));
  		  return;
  		}
  	    }
*************** insert_partition_copy_on_edge (edge e, i
*** 191,197 ****
    set_location_for_edge (e);
    /* If a locus is provided, override the default.  */
    if (locus)
!     set_curr_insn_source_location (locus);

    var = partition_to_var (SA.map, src);
    seq = emit_partition_copy (SA.partition_to_pseudo[dest],
--- 189,195 ----
    set_location_for_edge (e);
    /* If a locus is provided, override the default.  */
    if (locus)
!     set_curr_insn_location (locus);

    var = partition_to_var (SA.map, src);
    seq = emit_partition_copy (SA.partition_to_pseudo[dest],
*************** insert_value_copy_on_edge (edge e, int d
*** 228,234 ****
    set_location_for_edge (e);
    /* If a locus is provided, override the default.  */
    if (locus)
!     set_curr_insn_source_location (locus);

    start_sequence ();

--- 226,232 ----
    set_location_for_edge (e);
    /* If a locus is provided, override the default.  */
    if (locus)
!     set_curr_insn_location (locus);

    start_sequence ();

*************** insert_rtx_to_part_on_edge (edge e, int
*** 284,290 ****
    set_location_for_edge (e);
    /* If a locus is provided, override the default.  */
    if (locus)
!     set_curr_insn_source_location (locus);

    /* We give the destination as sizeexp in case src/dest are BLKmode
       mems.  Usually we give the source.  As we result from SSA names
--- 282,288 ----
    set_location_for_edge (e);
    /* If a locus is provided, override the default.  */
    if (locus)
!     set_curr_insn_location (locus);

    /* We give the destination as sizeexp in case src/dest are BLKmode
       mems.  Usually we give the source.  As we result from SSA names
*************** insert_part_to_rtx_on_edge (edge e, rtx
*** 320,326 ****
    set_location_for_edge (e);
    /* If a locus is provided, override the default.  */
    if (locus)
!     set_curr_insn_source_location (locus);

    var = partition_to_var (SA.map, src);
    seq = emit_partition_copy (dest,
--- 318,324 ----
    set_location_for_edge (e);
    /* If a locus is provided, override the default.  */
    if (locus)
!     set_curr_insn_location (locus);

    var = partition_to_var (SA.map, src);
    seq = emit_partition_copy (dest,
Index: gcc/basic-block.h
===================================================================
*** gcc/basic-block.h	(revision 189835)
--- gcc/basic-block.h	(working copy)
*************** struct GTY(()) edge_def {
*** 47,54 ****
    /* Auxiliary info specific to a pass.  */
    PTR GTY ((skip (""))) aux;

!   /* Location of any goto implicit in the edge and associated BLOCK.  */
!   tree goto_block;
    location_t goto_locus;

    /* The index number corresponding to this edge in the edge vector
--- 47,53 ----
    /* Auxiliary info specific to a pass.  */
    PTR GTY ((skip (""))) aux;

!   /* Location of any goto implicit in the edge.  */
    location_t goto_locus;

    /* The index number corresponding to this edge in the edge vector
Index: gcc/gimple.h
===================================================================
*** gcc/gimple.h	(revision 189835)
--- gcc/gimple.h	(working copy)
*************** struct GTY(()) gimple_statement_base {
*** 210,219 ****
       and the prev pointer being the last.  */
    gimple next;
    gimple GTY((skip)) prev;
-
-   /* [ WORD 6 ]
-      Lexical block holding this statement.  */
-   tree block;
  };


--- 210,215 ----
*************** gimple_bb (const_gimple g)
*** 1198,1204 ****
  static inline tree
  gimple_block (const_gimple g)
  {
!   return g->gsbase.block;
  }


--- 1194,1200 ----
  static inline tree
  gimple_block (const_gimple g)
  {
!   return LOCATION_BLOCK (g->gsbase.location);
  }


*************** gimple_block (const_gimple g)
*** 1207,1213 ****
  static inline void
  gimple_set_block (gimple g, tree block)
  {
!   g->gsbase.block = block;
  }


--- 1203,1209 ----
  static inline void
  gimple_set_block (gimple g, tree block)
  {
!   g->gsbase.location = COMBINE_LOCATION (g->gsbase.location, block);
  }


*************** gimple_set_location (gimple g, location_
*** 1242,1248 ****
  static inline bool
  gimple_has_location (const_gimple g)
  {
!   return gimple_location (g) != UNKNOWN_LOCATION;
  }


--- 1238,1244 ----
  static inline bool
  gimple_has_location (const_gimple g)
  {
!   return !IS_UNKNOWN_LOCATION (gimple_location (g));
  }


Index: gcc/tree-cfg.c
===================================================================
*** gcc/tree-cfg.c	(revision 189835)
--- gcc/tree-cfg.c	(working copy)
*************** make_cond_expr_edges (basic_block bb)
*** 808,822 ****
    e = make_edge (bb, then_bb, EDGE_TRUE_VALUE);
    assign_discriminator (entry_locus, then_bb);
    e->goto_locus = gimple_location (then_stmt);
-   if (e->goto_locus)
-     e->goto_block = gimple_block (then_stmt);
    e = make_edge (bb, else_bb, EDGE_FALSE_VALUE);
    if (e)
      {
        assign_discriminator (entry_locus, else_bb);
        e->goto_locus = gimple_location (else_stmt);
-       if (e->goto_locus)
- 	e->goto_block = gimple_block (else_stmt);
      }

    /* We do not need the labels anymore.  */
--- 808,818 ----
*************** make_goto_expr_edges (basic_block bb)
*** 1026,1033 ****
        edge e = make_edge (bb, label_bb, EDGE_FALLTHRU);
        e->goto_locus = gimple_location (goto_t);
        assign_discriminator (e->goto_locus, label_bb);
-       if (e->goto_locus)
- 	e->goto_block = gimple_block (goto_t);
        gsi_remove (&last, true);
        return;
      }
--- 1022,1027 ----
*************** gimple_can_merge_blocks_p (basic_block a
*** 1501,1507 ****

    /* When not optimizing, don't merge if we'd lose goto_locus.  */
    if (!optimize
!       && single_succ_edge (a)->goto_locus != UNKNOWN_LOCATION)
      {
        location_t goto_locus = single_succ_edge (a)->goto_locus;
        gimple_stmt_iterator prev, next;
--- 1495,1501 ----

    /* When not optimizing, don't merge if we'd lose goto_locus.  */
    if (!optimize
!       && single_succ_edge (a)->goto_locus)
      {
        location_t goto_locus = single_succ_edge (a)->goto_locus;
        gimple_stmt_iterator prev, next;
*************** move_stmt_op (tree *tp, int *walk_subtre
*** 5987,5995 ****
    tree t = *tp;

    if (EXPR_P (t))
!     /* We should never have TREE_BLOCK set on non-statements.  */
!     gcc_assert (!TREE_BLOCK (t));
!
    else if (DECL_P (t) || TREE_CODE (t) == SSA_NAME)
      {
        if (TREE_CODE (t) == SSA_NAME)
--- 5981,5987 ----
    tree t = *tp;

    if (EXPR_P (t))
!     ;
    else if (DECL_P (t) || TREE_CODE (t) == SSA_NAME)
      {
        if (TREE_CODE (t) == SSA_NAME)
*************** move_block_to_fn (struct function *dest_
*** 6294,6305 ****
      }

    FOR_EACH_EDGE (e, ei, bb->succs)
!     if (e->goto_locus)
        {
! 	tree block = e->goto_block;
  	if (d->orig_block == NULL_TREE
  	    || block == d->orig_block)
! 	  e->goto_block = d->new_block;
  #ifdef ENABLE_CHECKING
  	else if (block != d->new_block)
  	  {
--- 6286,6297 ----
      }

    FOR_EACH_EDGE (e, ei, bb->succs)
!     if (!IS_UNKNOWN_LOCATION (e->goto_locus))
        {
! 	tree block = LOCATION_BLOCK (e->goto_locus);
  	if (d->orig_block == NULL_TREE
  	    || block == d->orig_block)
! 	  e->goto_locus = COMBINE_LOCATION (e->goto_locus, d->new_block);
  #ifdef ENABLE_CHECKING
  	else if (block != d->new_block)
  	  {
Index: gcc/config/alpha/alpha.c
===================================================================
*** gcc/config/alpha/alpha.c	(revision 189835)
--- gcc/config/alpha/alpha.c	(working copy)
*************** alpha_output_mi_thunk_osf (FILE *file, t
*** 8352,8358 ****
       instruction scheduling worth while.  Note that use_thunk calls
       assemble_start_function and assemble_end_function.  */
    insn = get_insns ();
-   insn_locators_alloc ();
    shorten_branches (insn);
    final_start_function (insn, file, 1);
    final (insn, file, 1);
--- 8352,8357 ----
Index: gcc/config/sparc/sparc.c
===================================================================
*** gcc/config/sparc/sparc.c	(revision 189835)
--- gcc/config/sparc/sparc.c	(working copy)
*************** sparc_output_mi_thunk (FILE *file, tree
*** 10654,10660 ****
       instruction scheduling worth while.  Note that use_thunk calls
       assemble_start_function and assemble_end_function.  */
    insn = get_insns ();
-   insn_locators_alloc ();
    shorten_branches (insn);
    final_start_function (insn, file, 1);
    final (insn, file, 1);
--- 10654,10659 ----
Index: gcc/config/i386/i386.c
===================================================================
*** gcc/config/i386/i386.c	(revision 189835)
--- gcc/config/i386/i386.c	(working copy)
*************** x86_output_mi_thunk (FILE *file,
*** 33063,33069 ****
    /* Emit just enough of rest_of_compilation to get the insns emitted.
       Note that use_thunk calls assemble_start_function et al.  */
    tmp = get_insns ();
-   insn_locators_alloc ();
    shorten_branches (tmp);
    final_start_function (tmp, file, 1);
    final (tmp, file, 1);
--- 33063,33068 ----
Index: gcc/config/tilegx/tilegx.c
===================================================================
*** gcc/config/tilegx/tilegx.c	(revision 189835)
--- gcc/config/tilegx/tilegx.c	(working copy)
*************** tilegx_output_mi_thunk (FILE *file, tree
*** 4804,4810 ****
       serial except for the tail call, so we're only wasting one cycle.
     */
    insn = get_insns ();
-   insn_locators_alloc ();
    shorten_branches (insn);
    final_start_function (insn, file, 1);
    final (insn, file, 1);
--- 4804,4809 ----
Index: gcc/config/sh/sh.c
===================================================================
*** gcc/config/sh/sh.c	(revision 189835)
--- gcc/config/sh/sh.c	(working copy)
*************** sh_output_mi_thunk (FILE *file, tree thu
*** 11979,11985 ****
       the insns emitted.  Note that use_thunk calls
       assemble_start_function and assemble_end_function.  */

-   insn_locators_alloc ();
    insns = get_insns ();

    if (optimize > 0)
--- 11979,11984 ----
Index: gcc/config/ia64/ia64.c
===================================================================
*** gcc/config/ia64/ia64.c	(revision 189835)
--- gcc/config/ia64/ia64.c	(working copy)
*************** ia64_output_mi_thunk (FILE *file, tree t
*** 10848,10854 ****
       instruction scheduling worth while.  Note that use_thunk calls
       assemble_start_function and assemble_end_function.  */

-   insn_locators_alloc ();
    emit_all_insn_group_barriers (NULL);
    insn = get_insns ();
    shorten_branches (insn);
--- 10848,10853 ----
Index: gcc/config/rs6000/rs6000.c
===================================================================
*** gcc/config/rs6000/rs6000.c	(revision 189835)
--- gcc/config/rs6000/rs6000.c	(working copy)
*************** rs6000_output_mi_thunk (FILE *file, tree
*** 21664,21670 ****
       instruction scheduling worth while.  Note that use_thunk calls
       assemble_start_function and assemble_end_function.  */
    insn = get_insns ();
-   insn_locators_alloc ();
    shorten_branches (insn);
    final_start_function (insn, file, 1);
    final (insn, file, 1);
--- 21664,21669 ----
Index: gcc/config/score/score.c
===================================================================
*** gcc/config/score/score.c	(revision 189835)
--- gcc/config/score/score.c	(working copy)
*************** score_output_mi_thunk (FILE *file, tree
*** 505,511 ****
    /* Run just enough of rest_of_compilation.  This sequence was
       "borrowed" from alpha.c.  */
    insn = get_insns ();
-   insn_locators_alloc ();
    split_all_insns_noflow ();
    shorten_branches (insn);
    final_start_function (insn, file, 1);
--- 505,510 ----
Index: gcc/config/tilepro/tilepro.c
===================================================================
*** gcc/config/tilepro/tilepro.c	(revision 189835)
--- gcc/config/tilepro/tilepro.c	(working copy)
*************** tilepro_asm_output_mi_thunk (FILE *file,
*** 4407,4413 ****
       serial except for the tail call, so we're only wasting one cycle.
     */
    insn = get_insns ();
-   insn_locators_alloc ();
    shorten_branches (insn);
    final_start_function (insn, file, 1);
    final (insn, file, 1);
--- 4407,4412 ----
Index: gcc/config/mips/mips.c
===================================================================
*** gcc/config/mips/mips.c	(revision 189835)
--- gcc/config/mips/mips.c	(working copy)
*************** mips_output_mi_thunk (FILE *file, tree t
*** 15637,15643 ****
    /* Run just enough of rest_of_compilation.  This sequence was
       "borrowed" from alpha.c.  */
    insn = get_insns ();
-   insn_locators_alloc ();
    split_all_insns_noflow ();
    mips16_lay_out_constants ();
    shorten_branches (insn);
--- 15637,15642 ----
Index: gcc/cfgrtl.c
===================================================================
*** gcc/cfgrtl.c	(revision 189835)
--- gcc/cfgrtl.c	(working copy)
*************** rtl_split_block (basic_block bb, void *i
*** 720,738 ****
  static bool
  unique_locus_on_edge_between_p (basic_block a, basic_block b)
  {
!   const int goto_locus = EDGE_SUCC (a, 0)->goto_locus;
    rtx insn, end;

!   if (!goto_locus)
      return false;

    /* First scan block A backward.  */
    insn = BB_END (a);
    end = PREV_INSN (BB_HEAD (a));
!   while (insn != end && (!NONDEBUG_INSN_P (insn) || INSN_LOCATOR (insn) == 0))
      insn = PREV_INSN (insn);

!   if (insn != end && locator_eq (INSN_LOCATOR (insn), goto_locus))
      return false;

    /* Then scan block B forward.  */
--- 720,738 ----
  static bool
  unique_locus_on_edge_between_p (basic_block a, basic_block b)
  {
!   const location_t goto_locus = EDGE_SUCC (a, 0)->goto_locus;
    rtx insn, end;

!   if (IS_UNKNOWN_LOCATION (goto_locus))
      return false;

    /* First scan block A backward.  */
    insn = BB_END (a);
    end = PREV_INSN (BB_HEAD (a));
!   while (insn != end && (!NONDEBUG_INSN_P (insn) ||
!INSN_HAS_LOCATION (insn)))
      insn = PREV_INSN (insn);

!   if (insn != end && INSN_LOCATION (insn) == goto_locus)
      return false;

    /* Then scan block B forward.  */
*************** unique_locus_on_edge_between_p (basic_bl
*** 743,750 ****
        while (insn != end && !NONDEBUG_INSN_P (insn))
  	insn = NEXT_INSN (insn);

!       if (insn != end && INSN_LOCATOR (insn) != 0
! 	  && locator_eq (INSN_LOCATOR (insn), goto_locus))
  	return false;
      }

--- 743,750 ----
        while (insn != end && !NONDEBUG_INSN_P (insn))
  	insn = NEXT_INSN (insn);

!       if (insn != end && INSN_HAS_LOCATION (insn)
! 	  && INSN_LOCATION (insn) == goto_locus)
  	return false;
      }

*************** emit_nop_for_unique_locus_between (basic
*** 761,767 ****
      return;

    BB_END (a) = emit_insn_after_noloc (gen_nop (), BB_END (a), a);
!   INSN_LOCATOR (BB_END (a)) = EDGE_SUCC (a, 0)->goto_locus;
  }

  /* Blocks A and B are to be merged into a single block A.  The insns
--- 761,767 ----
      return;

    BB_END (a) = emit_insn_after_noloc (gen_nop (), BB_END (a), a);
!   INSN_LOCATION (BB_END (a)) = EDGE_SUCC (a, 0)->goto_locus;
  }

  /* Blocks A and B are to be merged into a single block A.  The insns
*************** force_nonfallthru_and_redirect (edge e,
*** 1478,1484 ****
    else
      jump_block = e->src;

!   if (e->goto_locus && e->goto_block == NULL)
      loc = e->goto_locus;
    else
      loc = 0;
--- 1478,1484 ----
    else
      jump_block = e->src;

!   if (!IS_UNKNOWN_LOCATION (e->goto_locus))
      loc = e->goto_locus;
    else
      loc = 0;
*************** fixup_reorder_chain (void)
*** 3337,3343 ****
          edge_iterator ei;

          FOR_EACH_EDGE (e, ei, bb->succs)
! 	  if (e->goto_locus && !(e->flags & EDGE_ABNORMAL))
  	    {
  	      edge e2;
  	      edge_iterator ei2;
--- 3337,3344 ----
          edge_iterator ei;

          FOR_EACH_EDGE (e, ei, bb->succs)
! 	  if (!IS_UNKNOWN_LOCATION (e->goto_locus)
! 	      && !(e->flags & EDGE_ABNORMAL))
  	    {
  	      edge e2;
  	      edge_iterator ei2;
*************** fixup_reorder_chain (void)
*** 3347,3361 ****
  	      insn = BB_END (e->src);
  	      end = PREV_INSN (BB_HEAD (e->src));
  	      while (insn != end
! 		     && (!NONDEBUG_INSN_P (insn) || INSN_LOCATOR (insn) == 0))
  		insn = PREV_INSN (insn);
  	      if (insn != end
! 		  && locator_eq (INSN_LOCATOR (insn), (int) e->goto_locus))
  		continue;
  	      if (simplejump_p (BB_END (e->src))
! 		  && INSN_LOCATOR (BB_END (e->src)) == 0)
  		{
! 		  INSN_LOCATOR (BB_END (e->src)) = e->goto_locus;
  		  continue;
  		}
  	      dest = e->dest;
--- 3348,3362 ----
  	      insn = BB_END (e->src);
  	      end = PREV_INSN (BB_HEAD (e->src));
  	      while (insn != end
! 		     && (!NONDEBUG_INSN_P (insn) || !INSN_HAS_LOCATION (insn)))
  		insn = PREV_INSN (insn);
  	      if (insn != end
! 		  && INSN_LOCATION (insn) == e->goto_locus)
  		continue;
  	      if (simplejump_p (BB_END (e->src))
! 		  && !INSN_HAS_LOCATION (BB_END (e->src)))
  		{
! 		  INSN_LOCATION (BB_END (e->src)) = e->goto_locus;
  		  continue;
  		}
  	      dest = e->dest;
*************** fixup_reorder_chain (void)
*** 3371,3394 ****
  		  end = NEXT_INSN (BB_END (dest));
  		  while (insn != end && !NONDEBUG_INSN_P (insn))
  		    insn = NEXT_INSN (insn);
! 		  if (insn != end && INSN_LOCATOR (insn)
! 		      && locator_eq (INSN_LOCATOR (insn), (int) e->goto_locus))
  		    continue;
  		}
  	      nb = split_edge (e);
  	      if (!INSN_P (BB_END (nb)))
  		BB_END (nb) = emit_insn_after_noloc (gen_nop (), BB_END (nb),
  						     nb);
! 	      INSN_LOCATOR (BB_END (nb)) = e->goto_locus;

  	      /* If there are other incoming edges to the destination block
  		 with the same goto locus, redirect them to the new block as
  		 well, this can prevent other such blocks from being created
  		 in subsequent iterations of the loop.  */
  	      for (ei2 = ei_start (dest->preds); (e2 = ei_safe_edge (ei2)); )
! 		if (e2->goto_locus
  		    && !(e2->flags & (EDGE_ABNORMAL | EDGE_FALLTHRU))
! 		    && locator_eq (e->goto_locus, e2->goto_locus))
  		  redirect_edge_and_branch (e2, nb);
  		else
  		  ei_next (&ei2);
--- 3372,3395 ----
  		  end = NEXT_INSN (BB_END (dest));
  		  while (insn != end && !NONDEBUG_INSN_P (insn))
  		    insn = NEXT_INSN (insn);
! 		  if (insn != end && INSN_HAS_LOCATION (insn)
! 		      && INSN_LOCATION (insn) == e->goto_locus)
  		    continue;
  		}
  	      nb = split_edge (e);
  	      if (!INSN_P (BB_END (nb)))
  		BB_END (nb) = emit_insn_after_noloc (gen_nop (), BB_END (nb),
  						     nb);
! 	      INSN_LOCATION (BB_END (nb)) = e->goto_locus;

  	      /* If there are other incoming edges to the destination block
  		 with the same goto locus, redirect them to the new block as
  		 well, this can prevent other such blocks from being created
  		 in subsequent iterations of the loop.  */
  	      for (ei2 = ei_start (dest->preds); (e2 = ei_safe_edge (ei2)); )
! 		if (!IS_UNKNOWN_LOCATION (e2->goto_locus)
  		    && !(e2->flags & (EDGE_ABNORMAL | EDGE_FALLTHRU))
! 		    && e->goto_locus == e2->goto_locus)
  		  redirect_edge_and_branch (e2, nb);
  		else
  		  ei_next (&ei2);
*************** cfg_layout_merge_blocks (basic_block a,
*** 4088,4094 ****
      }

    /* If B was a forwarder block, propagate the locus on the edge.  */
!   if (forwarder_p && !EDGE_SUCC (b, 0)->goto_locus)
      EDGE_SUCC (b, 0)->goto_locus = EDGE_SUCC (a, 0)->goto_locus;

    if (dump_file)
--- 4089,4095 ----
      }

    /* If B was a forwarder block, propagate the locus on the edge.  */
!   if (forwarder_p && IS_UNKNOWN_LOCATION (EDGE_SUCC (b, 0)->goto_locus))
      EDGE_SUCC (b, 0)->goto_locus = EDGE_SUCC (a, 0)->goto_locus;

    if (dump_file)
Index: gcc/stmt.c
===================================================================
*** gcc/stmt.c	(revision 189835)
--- gcc/stmt.c	(working copy)
*************** emit_case_nodes (rtx index, case_node_pt
*** 2397,2403 ****
  		 then emit the code for one side at a time.  */

  	      tree test_label
! 		= build_decl (CURR_INSN_LOCATION,
  			      LABEL_DECL, NULL_TREE, NULL_TREE);

  	      /* See if the value is on the right.  */
--- 2397,2403 ----
  		 then emit the code for one side at a time.  */

  	      tree test_label
! 		= build_decl (curr_insn_location (),
  			      LABEL_DECL, NULL_TREE, NULL_TREE);

  	      /* See if the value is on the right.  */
*************** emit_case_nodes (rtx index, case_node_pt
*** 2521,2527 ****
  	      /* Right hand node requires testing.
  		 Branch to a label where we will handle it later.  */

! 	      test_label = build_decl (CURR_INSN_LOCATION,
  				       LABEL_DECL, NULL_TREE, NULL_TREE);
  	      emit_cmp_and_jump_insns (index,
  				       convert_modes
--- 2521,2527 ----
  	      /* Right hand node requires testing.
  		 Branch to a label where we will handle it later.  */

! 	      test_label = build_decl (curr_insn_location (),
  				       LABEL_DECL, NULL_TREE, NULL_TREE);
  	      emit_cmp_and_jump_insns (index,
  				       convert_modes
Index: libcpp/include/line-map.h
===================================================================
*** libcpp/include/line-map.h	(revision 189835)
--- libcpp/include/line-map.h	(working copy)
*************** struct GTY(()) line_map_ordinary {
*** 89,95 ****

  /* This is the highest possible source location encoded within an
     ordinary or macro map.  */
! #define MAX_SOURCE_LOCATION 0xFFFFFFFF

  struct cpp_hashnode;

--- 89,95 ----

  /* This is the highest possible source location encoded within an
     ordinary or macro map.  */
! #define MAX_SOURCE_LOCATION 0x7FFFFFFF

  struct cpp_hashnode;

*************** struct GTY(()) line_maps {
*** 408,413 ****
--- 408,423 ----
  #define LINEMAPS_LAST_ALLOCATED_MACRO_MAP(SET) \
    LINEMAPS_LAST_ALLOCATED_MAP (SET, true)

+ extern void location_block_init (void);
+ extern void location_block_fini (void);
+ extern source_location get_combine_location (source_location, void *);
+ extern void *get_block_from_location (source_location);
+ extern source_location get_locus_from_location (source_location);
+
+ #define COMBINE_LOCATION(LOC, BLOCK) \
+   ((BLOCK) ? get_combine_location ((LOC), (BLOCK)) : (LOC))
+ #define IS_COMBINED_LOCATION(LOC) (((LOC) & MAX_SOURCE_LOCATION) != (LOC))
+
  /* Initialize a line map set.  */
  extern void linemap_init (struct line_maps *);

*************** typedef struct
*** 594,599 ****
--- 604,611 ----

    int column;

+   void *block;
+
    /* In a system header?. */
    bool sysp;
  } expanded_location;
Index: libcpp/line-map.c
===================================================================
*** libcpp/line-map.c	(revision 189835)
--- libcpp/line-map.c	(working copy)
*************** along with this program; see the file CO
*** 25,30 ****
--- 25,31 ----
  #include "line-map.h"
  #include "cpplib.h"
  #include "internal.h"
+ #include "hashtab.h"

  static void trace_include (const struct line_maps *, const struct line_map *);
  static const struct line_map * linemap_ordinary_map_lookup (struct
line_maps *,
*************** static source_location linemap_macro_loc
*** 50,55 ****
--- 51,171 ----
  extern unsigned num_expanded_macros_counter;
  extern unsigned num_macro_tokens_counter;

+ struct location_block {
+   source_location locus;
+   void *block;
+ };
+
+ static htab_t location_block_htab;
+ static source_location curr_combined_location;
+ static struct location_block *location_blocks;
+ static unsigned int allocated_location_blocks;
+
+ /* Hash function for location_block hashtable.  */
+
+ static hashval_t
+ location_block_hash (const void *l)
+ {
+   const struct location_block *lb = (const struct location_block *) l;
+   return (hashval_t) lb->locus + (size_t) &lb->block;
+ }
+
+ /* Compare function for location_block hashtable.  */
+
+ static int
+ location_block_eq (const void *l1, const void *l2)
+ {
+   const struct location_block *lb1 = (const struct location_block *) l1;
+   const struct location_block *lb2 = (const struct location_block *) l2;
+   return lb1->locus == lb2->locus && lb1->block == lb2->block;
+ }
+
+ /* Update the hashtable when location_blocks is reallocated.  */
+
+ static int
+ location_block_update (void **slot, void *data)
+ {
+   *((char **) slot) += ((char *) location_blocks - (char *) data);
+   return 1;
+ }
+
+ /* Combine LOCUS and BLOCK to a combined location.  */
+
+ source_location
+ get_combine_location (source_location locus, void *block)
+ {
+   struct location_block lb;
+   struct location_block **slot;
+
+   linemap_assert (block);
+
+   if (IS_COMBINED_LOCATION (locus))
+     locus = location_blocks[locus & MAX_SOURCE_LOCATION].locus;
+   if (locus == 0 && block == NULL)
+     return 0;
+   lb.locus = locus;
+   lb.block = block;
+   slot = (struct location_block **)
+       htab_find_slot (location_block_htab, &lb, INSERT);
+   if (*slot == NULL)
+     {
+       *slot = location_blocks + curr_combined_location;
+       location_blocks[curr_combined_location] = lb;
+       if (++curr_combined_location >= allocated_location_blocks)
+ 	{
+ 	  char *orig_location_blocks = (char *) location_blocks;
+ 	  allocated_location_blocks *= 2;
+ 	  location_blocks = XRESIZEVEC (struct location_block,
+ 				 	location_blocks,
+ 					allocated_location_blocks);
+ 	  htab_traverse (location_block_htab, location_block_update,
+ 			 orig_location_blocks);
+ 	}
+     }
+   return ((*slot) - location_blocks) | 0x80000000;
+ }
+
+ /* Return the block for LOCATION.  */
+
+ void *
+ get_block_from_location (source_location location)
+ {
+   linemap_assert (IS_COMBINED_LOCATION (location));
+   return location_blocks[location & MAX_SOURCE_LOCATION].block;
+ }
+
+ /* Return the locus for LOCATION.  */
+
+ source_location
+ get_locus_from_location (source_location location)
+ {
+   linemap_assert (IS_COMBINED_LOCATION (location));
+   return location_blocks[location & MAX_SOURCE_LOCATION].locus;
+ }
+
+ /* Initialize the location_block structure.  */
+
+ void
+ location_block_init (void)
+ {
+   location_block_htab = htab_create (100, location_block_hash,
+ 				     location_block_eq, NULL);
+   curr_combined_location = 0;
+   allocated_location_blocks = 100;
+   location_blocks = XNEWVEC (struct location_block,
+ 			     allocated_location_blocks);
+ }
+
+ /* Finalize the location_block structure.  */
+
+ void
+ location_block_fini (void)
+ {
+   allocated_location_blocks = 0;
+   XDELETEVEC (location_blocks);
+   htab_delete (location_block_htab);
+ }
+
  /* Initialize a line map set.  */

  void
*************** linemap_position_for_line_and_column (st
*** 509,514 ****
--- 625,632 ----
  const struct line_map*
  linemap_lookup (struct line_maps *set, source_location line)
  {
+   if (IS_COMBINED_LOCATION (line))
+     line = location_blocks[line & MAX_SOURCE_LOCATION].locus;
    if (linemap_location_from_macro_expansion_p (set, line))
      return linemap_macro_map_lookup (set, line);
    return linemap_ordinary_map_lookup (set, line);
*************** linemap_ordinary_map_lookup (struct line
*** 525,530 ****
--- 643,651 ----
    unsigned int md, mn, mx;
    const struct line_map *cached, *result;

+   if (IS_COMBINED_LOCATION (line))
+     line = location_blocks[line & MAX_SOURCE_LOCATION].locus;
+
    if (set ==  NULL || line < RESERVED_LOCATION_COUNT)
      return NULL;

*************** linemap_macro_map_lookup (struct line_ma
*** 570,575 ****
--- 691,699 ----
    unsigned int md, mn, mx;
    const struct line_map *cached, *result;

+   if (IS_COMBINED_LOCATION (line))
+     line = location_blocks[line & MAX_SOURCE_LOCATION].locus;
+
    linemap_assert (line >= LINEMAPS_MACRO_LOWEST_LOCATION (set));

    if (set ==  NULL)
*************** linemap_macro_map_loc_to_def_point (cons
*** 648,653 ****
--- 772,780 ----
  {
    unsigned token_no;

+   if (IS_COMBINED_LOCATION (location))
+     location = location_blocks[location & MAX_SOURCE_LOCATION].locus;
+
    linemap_assert (linemap_macro_expansion_map_p (map)
  		  && location >= MAP_START_LOCATION (map));
    linemap_assert (location >= RESERVED_LOCATION_COUNT);
*************** linemap_macro_map_loc_unwind_toward_spel
*** 672,677 ****
--- 799,807 ----
  {
    unsigned token_no;

+   if (IS_COMBINED_LOCATION (location))
+     location = location_blocks[location & MAX_SOURCE_LOCATION].locus;
+
    linemap_assert (linemap_macro_expansion_map_p (map)
  		  && location >= MAP_START_LOCATION (map));
    linemap_assert (location >= RESERVED_LOCATION_COUNT);
*************** linemap_get_expansion_line (struct line_
*** 696,701 ****
--- 826,834 ----
  {
    const struct line_map *map = NULL;

+   if (IS_COMBINED_LOCATION (location))
+     location = location_blocks[location & MAX_SOURCE_LOCATION].locus;
+
    if (location < RESERVED_LOCATION_COUNT)
      return 0;

*************** linemap_get_expansion_filename (struct l
*** 720,725 ****
--- 853,861 ----
  {
    const struct line_map *map = NULL;

+   if (IS_COMBINED_LOCATION (location))
+     location = location_blocks[location & MAX_SOURCE_LOCATION].locus;
+
    if (location < RESERVED_LOCATION_COUNT)
      return NULL;

*************** linemap_location_in_system_header_p (str
*** 754,759 ****
--- 890,898 ----
  {
    const struct line_map *map = NULL;

+   if (IS_COMBINED_LOCATION (location))
+     location = location_blocks[location & MAX_SOURCE_LOCATION].locus;
+
    if (location < RESERVED_LOCATION_COUNT)
      return false;

*************** bool
*** 793,798 ****
--- 932,940 ----
  linemap_location_from_macro_expansion_p (struct line_maps *set,
  					 source_location location)
  {
+   if (IS_COMBINED_LOCATION (location))
+     location = location_blocks[location & MAX_SOURCE_LOCATION].locus;
+
    linemap_assert (location <= MAX_SOURCE_LOCATION
  		  && (set->highest_location
  		      < LINEMAPS_MACRO_LOWEST_LOCATION (set)));
*************** linemap_macro_loc_to_spelling_point (str
*** 933,938 ****
--- 1075,1083 ----
  {
    struct line_map *map;

+   if (IS_COMBINED_LOCATION (location))
+     location = location_blocks[location & MAX_SOURCE_LOCATION].locus;
+
    linemap_assert (set && location >= RESERVED_LOCATION_COUNT);

    while (true)
*************** linemap_macro_loc_to_def_point (struct l
*** 967,972 ****
--- 1112,1120 ----
  {
    struct line_map *map;

+   if (IS_COMBINED_LOCATION (location))
+     location = location_blocks[location & MAX_SOURCE_LOCATION].locus;
+
    linemap_assert (set && location >= RESERVED_LOCATION_COUNT);

    while (true)
*************** linemap_macro_loc_to_exp_point (struct l
*** 1005,1010 ****
--- 1153,1161 ----
  {
    struct line_map *map;

+   if (IS_COMBINED_LOCATION (location))
+     location = location_blocks[location & MAX_SOURCE_LOCATION].locus;
+
    linemap_assert (set && location >= RESERVED_LOCATION_COUNT);

    while (true)
*************** linemap_resolve_location (struct line_ma
*** 1074,1079 ****
--- 1225,1233 ----
  			  enum location_resolution_kind lrk,
  			  const struct line_map **map)
  {
+   if (IS_COMBINED_LOCATION (loc))
+     loc = location_blocks[loc & MAX_SOURCE_LOCATION].locus;
+
    if (loc < RESERVED_LOCATION_COUNT)
      {
        /* A reserved location wasn't encoded in a map.  Let's return a
*************** linemap_unwind_toward_expansion (struct
*** 1121,1126 ****
--- 1275,1283 ----
    source_location resolved_location;
    const struct line_map *resolved_map;

+   if (IS_COMBINED_LOCATION (loc))
+     loc = location_blocks[loc & MAX_SOURCE_LOCATION].locus;
+
    resolved_location =
      linemap_macro_map_loc_unwind_toward_spelling (*map, loc);
    resolved_map = linemap_lookup (set, resolved_location);
*************** linemap_unwind_to_first_non_reserved_loc
*** 1157,1162 ****
--- 1314,1322 ----
    source_location resolved_loc;
    const struct line_map *map0 = NULL, *map1 = NULL;

+   if (IS_COMBINED_LOCATION (loc))
+     loc = location_blocks[loc & MAX_SOURCE_LOCATION].locus;
+
    map0 = linemap_lookup (set, loc);
    if (!linemap_macro_expansion_map_p (map0))
      return loc;
*************** linemap_expand_location (struct line_map
*** 1198,1203 ****
--- 1358,1368 ----
    expanded_location xloc;

    memset (&xloc, 0, sizeof (xloc));
+   if (IS_COMBINED_LOCATION (loc))
+     {
+       loc = location_blocks[loc & MAX_SOURCE_LOCATION].locus;
+       xloc.block = location_blocks[loc & MAX_SOURCE_LOCATION].block;
+     }

    if (loc < RESERVED_LOCATION_COUNT)
      /* The location for this token wasn't generated from a line map.
*************** linemap_dump_location (struct line_maps
*** 1290,1295 ****
--- 1455,1463 ----
    const char *path = "", *from = "";
    int l = -1, c = -1, s = -1, e = -1;

+   if (IS_COMBINED_LOCATION (loc))
+     loc = location_blocks[loc & MAX_SOURCE_LOCATION].locus;
+
    if (loc == 0)
      return;
Richard Biener Aug. 7, 2012, 3:15 p.m. UTC | #2
On Mon, Aug 6, 2012 at 8:35 PM, Dehao Chen <dehao@google.com> wrote:
> On Thu, Aug 2, 2012 at 6:05 PM, Richard Guenther
> <richard.guenther@gmail.com> wrote:
>> On Thu, Aug 2, 2012 at 5:23 AM, Dehao Chen <dehao@google.com> wrote:
>>> On Thu, Aug 2, 2012 at 2:07 AM, Richard Guenther
>>> <richard.guenther@gmail.com> wrote:
>>>> On Wed, Aug 1, 2012 at 7:35 AM, Dehao Chen <dehao@google.com> wrote:
>>>>> Hi,
>>>>>
>>>>> This patch:
>>>>>
>>>>> * Integrates location with block into an integrated index.
>>>>> * Removes gimple->gsbase.block and tree->exp.block fields.
>>>>> * Updates inline/clone as well as tree liveness analysis to ensure the
>>>>> associated blocks are updated correctly.
>>>>>
>>>>> With this patch, the association between source location and its block
>>>>> are greatly enhanced, which produces much better inline stack in the
>>>>> debug info.
>>>>>
>>>>> Bootstrapped and regression tested on x86.
>>>>>
>>>>> OK for trunk?
>>>>
>>>> Nice.  But the LTO changes mean that you simply drop all BLOCK
>>>> associations on the floor ...
>>>
>>> Why? I've invoked TREE_SET_BLOCK in tree-streamer-in.c to read in the
>>> block info. So it should at least provide the same info as the
>>> original impl.
>>>
>>>> they at least look very incomplete.  Did you actually run LTO tests?
>>>
>>> Thanks for the reminder, I've added the following change to this patch:
>>>
>>> Index: gcc/tree-streamer-out.c
>>> ===================================================================
>>> --- gcc/tree-streamer-out.c     (revision 189835)
>>> +++ gcc/tree-streamer-out.c     (working copy)
>>> @@ -471,7 +471,7 @@
>>>  {
>>>    stream_write_tree (ob, DECL_NAME (expr), ref_p);
>>>    stream_write_tree (ob, DECL_CONTEXT (expr), ref_p);
>>> -  lto_output_location (ob, DECL_SOURCE_LOCATION (expr));
>>> +  lto_output_location (ob, LOCATION_LOCUS (DECL_SOURCE_LOCATION (expr)));
>>>  }
>>>
>>> @@ -668,7 +668,7 @@
>>>    streamer_write_hwi (ob, TREE_OPERAND_LENGTH (expr));
>>>    for (i = 0; i < TREE_OPERAND_LENGTH (expr); i++)
>>>      stream_write_tree (ob, TREE_OPERAND (expr, i), ref_p);
>>> -  lto_output_location (ob, EXPR_LOCATION (expr));
>>> +  lto_output_location (ob, LOCATION_LOCUS (EXPR_LOCATION (expr)));
>>>    stream_write_tree (ob, TREE_BLOCK (expr), ref_p);
>>>  }
>>
>> That doesn't match up with the change
>>
>> Index: gcc/lto-streamer-out.c
>> ===================================================================
>> --- gcc/lto-streamer-out.c      (revision 189835)
>> +++ gcc/lto-streamer-out.c      (working copy)
>> @@ -155,6 +155,7 @@
>>  {
>>    expanded_location xloc;
>>
>> +  loc = LOCATION_LOCUS (loc);
>>    bp_pack_value (bp, loc == UNKNOWN_LOCATION, 1);
>>    if (loc == UNKNOWN_LOCATION)
>>      return;
>>
>> (please remember to generate diffs with -p, so the function name is shown
>> in the diff hunk header)
>
> I've attached the new patch with -p output in this mail. Also added
> the change in gimple-stream-out.c
>
>>
>>> I think BLOCK associations works fine for LTO. I've run check-gcc, and
>>> there's no regression on LTO tests. I also manually write some tests,
>>> and the generated final assembly has block info as expected.
>>
>> What about the lto_output_location calls in gimple-streamer-out.c?  As far as I
>> can see they will end up dropping the associated BLOCK on the floor (I cannot
>> see any change on the -input side).
>
> The beauty of this patch is that it does not need to change the input
> side (except that we added tree_set_block instead of using
> "tree_block(t)" as lvalue, more detail in the following illustration.
>
>>
>>>>
>>>> lto/ has its own ChangeLog
>>>
>>> Thanks, I'll update the ChangeLog accordingly.
>>>
>>>> and I wonder why no frontends are affected
>>>> by this patch?
>>>
>>> Which files are you referring to?
>>
>> I was refering to the issue you brought up earlier - all the fold
>> routines losing
>> block associations.  Maybe you can elaborate some more how locator
>> is different from location, thus how you set up the machinery.
>
> This patch defines the following terminology:
> - locus: the original location_t in structures such as
> gimple_location, EXPR_LOCATION, etc.
> - locator: an index to the location_block array, as used in RTL in the
> original implementation.
> - location: an uint32 that represent the new location: if the highest
> bit is 0, it serves as the locus, if the highest bit is 1, the lower
> 31 bits serves as the locator.
>
> The macro LOCATION_LOCUS derives the locus from location.
> The macro LOCATION_BLOCK derives the block from location.
> And the gimple_set_block and tree_set_block are modified to set the
> updated location for gimple/tree.
>
> Because the interface of gimple_set_block/gimple_block does not
> change, we kept frontend change minimal. Also, as we encode the block
> into location, the block info can be passed without need to change the
> fold_.* interface.
>
> The downside of this approach is that we need to explicitly use
> LOCATION_LOCUS when we mean to use the original locus. E.g. when LTO
> streams out location, it actually streams out locus. Fortunately, only
> a small portion of code need to use the locus. Most code just copy the
> location from one place to one another.

Ok, that makes sense.  Would a libccp maintainer please review the libcpp
bits (or say that they should be elsewhere)?

> Thanks,
> Dehao
>
> Updated patch:

Please always post a CHangeLog as well.

Thanks,
Richard.


>
> Index: gcc/gimple-streamer-out.c
> ===================================================================
> *** gcc/gimple-streamer-out.c   (revision 189835)
> --- gcc/gimple-streamer-out.c   (working copy)
> *************** output_gimple_stmt (struct output_block
> *** 74,80 ****
>     streamer_write_bitpack (&bp);
>
>     /* Emit location information for the statement.  */
> !   lto_output_location (ob, gimple_location (stmt));
>
>     /* Emit the lexical block holding STMT.  */
>     stream_write_tree (ob, gimple_block (stmt), true);
> --- 74,80 ----
>     streamer_write_bitpack (&bp);
>
>     /* Emit location information for the statement.  */
> !   lto_output_location (ob, LOCATION_LOCUS (gimple_location (stmt)));
>
>     /* Emit the lexical block holding STMT.  */
>     stream_write_tree (ob, gimple_block (stmt), true);
> Index: gcc/tree.c
> ===================================================================
> *** gcc/tree.c  (revision 189835)
> --- gcc/tree.c  (working copy)
> *************** build1_stat (enum tree_code code, tree t
> *** 3765,3771 ****
>     TREE_TYPE (t) = type;
>     SET_EXPR_LOCATION (t, UNKNOWN_LOCATION);
>     TREE_OPERAND (t, 0) = node;
> -   TREE_BLOCK (t) = NULL_TREE;
>     if (node && !TYPE_P (node))
>       {
>         TREE_SIDE_EFFECTS (t) = TREE_SIDE_EFFECTS (node);
> --- 3765,3770 ----
> *************** walk_tree_without_duplicates_1 (tree *tp
> *** 10867,10883 ****
>   }
>
>
> ! tree *
>   tree_block (tree t)
>   {
>     char const c = TREE_CODE_CLASS (TREE_CODE (t));
>
>     if (IS_EXPR_CODE_CLASS (c))
> !     return &t->exp.block;
>     gcc_unreachable ();
>     return NULL;
>   }
>
>   /* Create a nameless artificial label and put it in the current
>      function context.  The label has a location of LOC.  Returns the
>      newly created label.  */
> --- 10866,10893 ----
>   }
>
>
> ! tree
>   tree_block (tree t)
>   {
>     char const c = TREE_CODE_CLASS (TREE_CODE (t));
>
>     if (IS_EXPR_CODE_CLASS (c))
> !     return LOCATION_BLOCK (t->exp.locus);
>     gcc_unreachable ();
>     return NULL;
>   }
>
> + void
> + tree_set_block (tree t, tree b)
> + {
> +   char const c = TREE_CODE_CLASS (TREE_CODE (t));
> +
> +   if (IS_EXPR_CODE_CLASS (c))
> +     t->exp.locus = COMBINE_LOCATION (t->exp.locus, b);
> +   else
> +     gcc_unreachable ();
> + }
> +
>   /* Create a nameless artificial label and put it in the current
>      function context.  The label has a location of LOC.  Returns the
>      newly created label.  */
> Index: gcc/tree.h
> ===================================================================
> *** gcc/tree.h  (revision 189835)
> --- gcc/tree.h  (working copy)
> *************** extern void omp_clause_range_check_faile
> *** 999,1005 ****
>
>   #endif
>
> ! #define TREE_BLOCK(NODE)              *(tree_block (NODE))
>
>   #include "tree-check.h"
>
> --- 999,1006 ----
>
>   #endif
>
> ! #define TREE_BLOCK(NODE)              (tree_block (NODE))
> ! #define TREE_SET_BLOCK(T, B)          (tree_set_block ((T), (B)))
>
>   #include "tree-check.h"
>
> *************** struct GTY(()) tree_constructor {
> *** 1702,1708 ****
>   #define EXPR_LOCATION(NODE) \
>     (CAN_HAVE_LOCATION_P ((NODE)) ? (NODE)->exp.locus : UNKNOWN_LOCATION)
>   #define SET_EXPR_LOCATION(NODE, LOCUS) EXPR_CHECK
> ((NODE))->exp.locus = (LOCUS)
> ! #define EXPR_HAS_LOCATION(NODE) (EXPR_LOCATION (NODE) != UNKNOWN_LOCATION)
>   /* The location to be used in a diagnostic about this expression.  Do not
>      use this macro if the location will be assigned to other expressions.  */
>   #define EXPR_LOC_OR_HERE(NODE) (EXPR_HAS_LOCATION (NODE) ?
> (NODE)->exp.locus : input_location)
> --- 1703,1709 ----
>   #define EXPR_LOCATION(NODE) \
>     (CAN_HAVE_LOCATION_P ((NODE)) ? (NODE)->exp.locus : UNKNOWN_LOCATION)
>   #define SET_EXPR_LOCATION(NODE, LOCUS) EXPR_CHECK
> ((NODE))->exp.locus = (LOCUS)
> ! #define EXPR_HAS_LOCATION(NODE) (!IS_UNKNOWN_LOCATION (EXPR_LOCATION (NODE)))
>   /* The location to be used in a diagnostic about this expression.  Do not
>      use this macro if the location will be assigned to other expressions.  */
>   #define EXPR_LOC_OR_HERE(NODE) (EXPR_HAS_LOCATION (NODE) ?
> (NODE)->exp.locus : input_location)
> *************** extern void protected_set_expr_location
> *** 1881,1887 ****
>                                               OMP_CLAUSE_PRIVATE,       \
>                                               OMP_CLAUSE_COPYPRIVATE), 0)
>   #define OMP_CLAUSE_HAS_LOCATION(NODE) \
> !   ((OMP_CLAUSE_CHECK (NODE))->omp_clause.locus != UNKNOWN_LOCATION)
>   #define OMP_CLAUSE_LOCATION(NODE)  (OMP_CLAUSE_CHECK (NODE))->omp_clause.locus
>
>   /* True on an OMP_SECTION statement that was the last lexical member.
> --- 1882,1888 ----
>                                               OMP_CLAUSE_PRIVATE,       \
>                                               OMP_CLAUSE_COPYPRIVATE), 0)
>   #define OMP_CLAUSE_HAS_LOCATION(NODE) \
> !   (!IS_UNKNOWN_LOCATION ((OMP_CLAUSE_CHECK (NODE))->omp_clause.locus))
>   #define OMP_CLAUSE_LOCATION(NODE)  (OMP_CLAUSE_CHECK (NODE))->omp_clause.locus
>
>   /* True on an OMP_SECTION statement that was the last lexical member.
> *************** enum omp_clause_default_kind
> *** 1972,1978 ****
>   struct GTY(()) tree_exp {
>     struct tree_typed typed;
>     location_t locus;
> -   tree block;
>     tree GTY ((special ("tree_exp"),
>              desc ("TREE_CODE ((tree) &%0)")))
>       operands[1];
> --- 1973,1978 ----
> *************** function_args_iter_next (function_args_i
> *** 5164,5170 ****
>   static inline bool
>   inlined_function_outer_scope_p (const_tree block)
>   {
> !  return BLOCK_SOURCE_LOCATION (block) != UNKNOWN_LOCATION;
>   }
>
>   /* Loop over all function arguments of FNTYPE.  In each iteration, PTR is set
> --- 5164,5170 ----
>   static inline bool
>   inlined_function_outer_scope_p (const_tree block)
>   {
> !  return !IS_UNKNOWN_LOCATION (BLOCK_SOURCE_LOCATION (block));
>   }
>
>   /* Loop over all function arguments of FNTYPE.  In each iteration, PTR is set
> *************** extern bool subrange_type_for_debug_p (c
> *** 5539,5545 ****
>   extern HOST_WIDE_INT int_cst_value (const_tree);
>   extern HOST_WIDEST_INT widest_int_cst_value (const_tree);
>
> ! extern tree *tree_block (tree);
>   extern location_t *block_nonartificial_location (tree);
>   extern location_t tree_nonartificial_location (tree);
>
> --- 5539,5546 ----
>   extern HOST_WIDE_INT int_cst_value (const_tree);
>   extern HOST_WIDEST_INT widest_int_cst_value (const_tree);
>
> ! extern tree tree_block (tree);
> ! extern void tree_set_block (tree, tree);
>   extern location_t *block_nonartificial_location (tree);
>   extern location_t tree_nonartificial_location (tree);
>
> Index: gcc/final.c
> ===================================================================
> *** gcc/final.c (revision 189835)
> --- gcc/final.c (working copy)
> *************** reemit_insn_block_notes (void)
> *** 1605,1611 ****
>                                              insn_scope (XVECEXP (body, 0, i)));
>         }
>         if (! this_block)
> !       continue;
>
>         if (this_block != cur_block)
>         {
> --- 1605,1611 ----
>                                              insn_scope (XVECEXP (body, 0, i)));
>         }
>         if (! this_block)
> !       this_block = DECL_INITIAL (cfun->decl);
>
>         if (this_block != cur_block)
>         {
> *************** final_start_function (rtx first ATTRIBUT
> *** 1640,1647 ****
>
>     this_is_asm_operands = 0;
>
> !   last_filename = locator_file (prologue_locator);
> !   last_linenum = locator_line (prologue_locator);
>     last_discriminator = discriminator = 0;
>
>     high_block_linenum = high_function_linenum = last_linenum;
> --- 1640,1647 ----
>
>     this_is_asm_operands = 0;
>
> !   last_filename = LOCATION_FILE (prologue_location);
> !   last_linenum = LOCATION_LINE (prologue_location);
>     last_discriminator = discriminator = 0;
>
>     high_block_linenum = high_function_linenum = last_linenum;
> Index: gcc/input.c
> ===================================================================
> *** gcc/input.c (revision 189835)
> --- gcc/input.c (working copy)
> *************** expand_location_1 (source_location loc,
> *** 51,56 ****
> --- 51,63 ----
>     expanded_location xloc;
>     const struct line_map *map;
>     enum location_resolution_kind lrk = LRK_MACRO_EXPANSION_POINT;
> +   tree block = NULL;
> +
> +   if (IS_COMBINED_LOCATION (loc))
> +     {
> +       block = LOCATION_BLOCK (loc);
> +       loc = LOCATION_LOCUS (loc);
> +     }
>
>     memset (&xloc, 0, sizeof (xloc));
>
> *************** expand_location_1 (source_location loc,
> *** 74,79 ****
> --- 81,87 ----
>         xloc = linemap_expand_location (line_table, map, loc);
>       }
>
> +   xloc.block = block;
>     if (loc <= BUILTINS_LOCATION)
>       xloc.file = loc == UNKNOWN_LOCATION ? NULL : _("<built-in>");
>
> Index: gcc/input.h
> ===================================================================
> *** gcc/input.h (revision 189835)
> --- gcc/input.h (working copy)
> *************** extern location_t input_location;
> *** 51,56 ****
> --- 51,64 ----
>   #define LOCATION_FILE(LOC) ((expand_location (LOC)).file)
>   #define LOCATION_LINE(LOC) ((expand_location (LOC)).line)
>   #define LOCATION_COLUMN(LOC)((expand_location (LOC)).column)
> + #define LOCATION_LOCUS(LOC) \
> +   ((IS_COMBINED_LOCATION(LOC)) ? get_locus_from_location (LOC) : (LOC))
> + #define LOCATION_BLOCK(LOC) \
> +   ((tree) ((IS_COMBINED_LOCATION (LOC)) ? get_block_from_location (LOC) \
> +   : NULL))
> + #define IS_UNKNOWN_LOCATION(LOC) \
> +   ((IS_COMBINED_LOCATION (LOC)) ? get_locus_from_location (LOC) == 0 \
> +   : (LOC) == 0)
>
>   #define input_line LOCATION_LINE (input_location)
>   #define input_filename LOCATION_FILE (input_location)
> Index: gcc/fold-const.c
> ===================================================================
> *** gcc/fold-const.c    (revision 189835)
> --- gcc/fold-const.c    (working copy)
> *************** static location_t
> *** 145,151 ****
>   expr_location_or (tree t, location_t loc)
>   {
>     location_t tloc = EXPR_LOCATION (t);
> !   return tloc != UNKNOWN_LOCATION ? tloc : loc;
>   }
>
>   /* Similar to protected_set_expr_location, but never modify x in place,
> --- 145,151 ----
>   expr_location_or (tree t, location_t loc)
>   {
>     location_t tloc = EXPR_LOCATION (t);
> !   return IS_UNKNOWN_LOCATION (tloc) ? loc : tloc;
>   }
>
>   /* Similar to protected_set_expr_location, but never modify x in place,
> Index: gcc/toplev.c
> ===================================================================
> *** gcc/toplev.c        (revision 189835)
> --- gcc/toplev.c        (working copy)
> *************** general_init (const char *argv0)
> *** 1140,1145 ****
> --- 1140,1146 ----
>     linemap_init (line_table);
>     line_table->reallocator = realloc_for_line_map;
>     line_table->round_alloc_size = ggc_round_alloc_size;
> +   location_block_init ();
>     init_ttree ();
>
>     /* Initialize register usage now so switches may override.  */
> *************** toplev_main (int argc, char **argv)
> *** 1946,1951 ****
> --- 1947,1953 ----
>     invoke_plugin_callbacks (PLUGIN_FINISH, NULL);
>
>     finalize_plugins ();
> +   location_block_fini ();
>     if (seen_error ())
>       return (FATAL_EXIT_CODE);
>
> Index: gcc/reorg.c
> ===================================================================
> *** gcc/reorg.c (revision 189835)
> --- gcc/reorg.c (working copy)
> *************** emit_delay_sequence (rtx insn, rtx list,
> *** 545,551 ****
>     INSN_DELETED_P (delay_insn) = 0;
>     PREV_INSN (delay_insn) = PREV_INSN (seq_insn);
>
> !   INSN_LOCATOR (seq_insn) = INSN_LOCATOR (delay_insn);
>
>     for (li = list; li; li = XEXP (li, 1), i++)
>       {
> --- 545,551 ----
>     INSN_DELETED_P (delay_insn) = 0;
>     PREV_INSN (delay_insn) = PREV_INSN (seq_insn);
>
> !   INSN_LOCATION (seq_insn) = INSN_LOCATION (delay_insn);
>
>     for (li = list; li; li = XEXP (li, 1), i++)
>       {
> *************** emit_delay_sequence (rtx insn, rtx list,
> *** 561,569 ****
>
>         /* SPARC assembler, for instance, emit warning when debug info is output
>            into the delay slot.  */
> !       if (INSN_LOCATOR (tem) && !INSN_LOCATOR (seq_insn))
> !       INSN_LOCATOR (seq_insn) = INSN_LOCATOR (tem);
> !       INSN_LOCATOR (tem) = 0;
>
>         for (note = REG_NOTES (tem); note; note = next)
>         {
> --- 561,569 ----
>
>         /* SPARC assembler, for instance, emit warning when debug info is output
>            into the delay slot.  */
> !       if (INSN_LOCATION (tem) && !INSN_LOCATION (seq_insn))
> !       INSN_LOCATION (seq_insn) = INSN_LOCATION (tem);
> !       INSN_LOCATION (tem) = 0;
>
>         for (note = REG_NOTES (tem); note; note = next)
>         {
> *************** dbr_schedule (rtx first)
> *** 4087,4093 ****
>       for (link = crtl->epilogue_delay_list;
>            link;
>            link = XEXP (link, 1))
> !       INSN_LOCATOR (XEXP (link, 0)) = 0;
>     }
>
>   #endif
> --- 4087,4093 ----
>       for (link = crtl->epilogue_delay_list;
>            link;
>            link = XEXP (link, 1))
> !       INSN_LOCATION (XEXP (link, 0)) = 0;
>     }
>
>   #endif
> Index: gcc/modulo-sched.c
> ===================================================================
> *** gcc/modulo-sched.c  (revision 189835)
> --- gcc/modulo-sched.c  (working copy)
> *************** loop_single_full_bb_p (struct loop *loop
> *** 1246,1254 ****
>   /* Dump file:line from INSN's location info to dump_file.  */
>
>   static void
> ! dump_insn_locator (rtx insn)
>   {
> !   if (dump_file && INSN_LOCATOR (insn))
>       {
>         const char *file = insn_file (insn);
>         if (file)
> --- 1246,1254 ----
>   /* Dump file:line from INSN's location info to dump_file.  */
>
>   static void
> ! dump_insn_location (rtx insn)
>   {
> !   if (dump_file && INSN_LOCATION (insn))
>       {
>         const char *file = insn_file (insn);
>         if (file)
> *************** loop_canon_p (struct loop *loop)
> *** 1282,1288 ****
>           rtx insn = BB_END (loop->header);
>
>           fprintf (dump_file, "SMS loop many exits");
> !         dump_insn_locator (insn);
>           fprintf (dump_file, "\n");
>         }
>         return false;
> --- 1282,1288 ----
>           rtx insn = BB_END (loop->header);
>
>           fprintf (dump_file, "SMS loop many exits");
> !         dump_insn_location (insn);
>           fprintf (dump_file, "\n");
>         }
>         return false;
> *************** loop_canon_p (struct loop *loop)
> *** 1295,1301 ****
>           rtx insn = BB_END (loop->header);
>
>           fprintf (dump_file, "SMS loop many BBs.");
> !         dump_insn_locator (insn);
>           fprintf (dump_file, "\n");
>         }
>         return false;
> --- 1295,1301 ----
>           rtx insn = BB_END (loop->header);
>
>           fprintf (dump_file, "SMS loop many BBs.");
> !         dump_insn_location (insn);
>           fprintf (dump_file, "\n");
>         }
>         return false;
> *************** sms_schedule (void)
> *** 1421,1427 ****
>           rtx insn = BB_END (loop->header);
>
>           fprintf (dump_file, "SMS loop num: %d", loop->num);
> !         dump_insn_locator (insn);
>           fprintf (dump_file, "\n");
>         }
>
> --- 1421,1427 ----
>           rtx insn = BB_END (loop->header);
>
>           fprintf (dump_file, "SMS loop num: %d", loop->num);
> !         dump_insn_location (insn);
>           fprintf (dump_file, "\n");
>         }
>
> *************** sms_schedule (void)
> *** 1450,1456 ****
>         {
>           if (dump_file)
>             {
> !             dump_insn_locator (tail);
>               fprintf (dump_file, "\nSMS single-bb-loop\n");
>               if (profile_info && flag_branch_probabilities)
>                 {
> --- 1450,1456 ----
>         {
>           if (dump_file)
>             {
> !             dump_insn_location (tail);
>               fprintf (dump_file, "\nSMS single-bb-loop\n");
>               if (profile_info && flag_branch_probabilities)
>                 {
> *************** sms_schedule (void)
> *** 1556,1562 ****
>           rtx insn = BB_END (loop->header);
>
>           fprintf (dump_file, "SMS loop num: %d", loop->num);
> !         dump_insn_locator (insn);
>           fprintf (dump_file, "\n");
>
>           print_ddg (dump_file, g);
> --- 1556,1562 ----
>           rtx insn = BB_END (loop->header);
>
>           fprintf (dump_file, "SMS loop num: %d", loop->num);
> !         dump_insn_location (insn);
>           fprintf (dump_file, "\n");
>
>           print_ddg (dump_file, g);
> *************** sms_schedule (void)
> *** 1571,1577 ****
>
>         if (dump_file)
>         {
> !         dump_insn_locator (tail);
>           fprintf (dump_file, "\nSMS single-bb-loop\n");
>           if (profile_info && flag_branch_probabilities)
>             {
> --- 1571,1577 ----
>
>         if (dump_file)
>         {
> !         dump_insn_location (tail);
>           fprintf (dump_file, "\nSMS single-bb-loop\n");
>           if (profile_info && flag_branch_probabilities)
>             {
> *************** sms_schedule (void)
> *** 1714,1720 ****
>
>             if (dump_file)
>               {
> !             dump_insn_locator (tail);
>               fprintf (dump_file, " SMS succeeded %d %d (with ii, sc)\n",
>                        ps->ii, stage_count);
>               print_partial_schedule (ps, dump_file);
> --- 1714,1720 ----
>
>             if (dump_file)
>               {
> !             dump_insn_location (tail);
>               fprintf (dump_file, " SMS succeeded %d %d (with ii, sc)\n",
>                        ps->ii, stage_count);
>               print_partial_schedule (ps, dump_file);
> Index: gcc/lto-streamer-out.c
> ===================================================================
> *** gcc/lto-streamer-out.c      (revision 189835)
> --- gcc/lto-streamer-out.c      (working copy)
> *************** lto_output_location_bitpack (struct bitp
> *** 155,160 ****
> --- 155,161 ----
>   {
>     expanded_location xloc;
>
> +   loc = LOCATION_LOCUS (loc);
>     bp_pack_value (bp, loc == UNKNOWN_LOCATION, 1);
>     if (loc == UNKNOWN_LOCATION)
>       return;
> Index: gcc/jump.c
> ===================================================================
> *** gcc/jump.c  (revision 189835)
> --- gcc/jump.c  (working copy)
> *************** rtx_renumbered_equal_p (const_rtx x, con
> *** 1818,1825 ****
>           if (XINT (x, i) != XINT (y, i))
>             {
>               if (((code == ASM_OPERANDS && i == 6)
> !                  || (code == ASM_INPUT && i == 1))
> !                 && locator_eq (XINT (x, i), XINT (y, i)))
>                 break;
>               return 0;
>             }
> --- 1818,1824 ----
>           if (XINT (x, i) != XINT (y, i))
>             {
>               if (((code == ASM_OPERANDS && i == 6)
> !                  || (code == ASM_INPUT && i == 1)))
>                 break;
>               return 0;
>             }
> Index: gcc/ifcvt.c
> ===================================================================
> *** gcc/ifcvt.c (revision 189835)
> --- gcc/ifcvt.c (working copy)
> *************** noce_try_move (struct noce_if_info *if_i
> *** 1019,1025 ****
>             return FALSE;
>
>           emit_insn_before_setloc (seq, if_info->jump,
> !                                  INSN_LOCATOR (if_info->insn_a));
>         }
>         return TRUE;
>       }
> --- 1019,1025 ----
>             return FALSE;
>
>           emit_insn_before_setloc (seq, if_info->jump,
> !                                  INSN_LOCATION (if_info->insn_a));
>         }
>         return TRUE;
>       }
> *************** noce_try_store_flag (struct noce_if_info
> *** 1064,1070 ****
>         return FALSE;
>
>         emit_insn_before_setloc (seq, if_info->jump,
> !                              INSN_LOCATOR (if_info->insn_a));
>         return TRUE;
>       }
>     else
> --- 1064,1070 ----
>         return FALSE;
>
>         emit_insn_before_setloc (seq, if_info->jump,
> !                              INSN_LOCATION (if_info->insn_a));
>         return TRUE;
>       }
>     else
> *************** noce_try_store_flag_constants (struct no
> *** 1195,1201 ****
>         return FALSE;
>
>         emit_insn_before_setloc (seq, if_info->jump,
> !                              INSN_LOCATOR (if_info->insn_a));
>         return TRUE;
>       }
>
> --- 1195,1201 ----
>         return FALSE;
>
>         emit_insn_before_setloc (seq, if_info->jump,
> !                              INSN_LOCATION (if_info->insn_a));
>         return TRUE;
>       }
>
> *************** noce_try_addcc (struct noce_if_info *if_
> *** 1243,1249 ****
>                 return FALSE;
>
>               emit_insn_before_setloc (seq, if_info->jump,
> !                                      INSN_LOCATOR (if_info->insn_a));
>               return TRUE;
>             }
>           end_sequence ();
> --- 1243,1249 ----
>                 return FALSE;
>
>               emit_insn_before_setloc (seq, if_info->jump,
> !                                      INSN_LOCATION (if_info->insn_a));
>               return TRUE;
>             }
>           end_sequence ();
> *************** noce_try_addcc (struct noce_if_info *if_
> *** 1283,1289 ****
>                 return FALSE;
>
>               emit_insn_before_setloc (seq, if_info->jump,
> !                                      INSN_LOCATOR (if_info->insn_a));
>               return TRUE;
>             }
>           end_sequence ();
> --- 1283,1289 ----
>                 return FALSE;
>
>               emit_insn_before_setloc (seq, if_info->jump,
> !                                      INSN_LOCATION (if_info->insn_a));
>               return TRUE;
>             }
>           end_sequence ();
> *************** noce_try_store_flag_mask (struct noce_if
> *** 1332,1338 ****
>             return FALSE;
>
>           emit_insn_before_setloc (seq, if_info->jump,
> !                                  INSN_LOCATOR (if_info->insn_a));
>           return TRUE;
>         }
>
> --- 1332,1338 ----
>             return FALSE;
>
>           emit_insn_before_setloc (seq, if_info->jump,
> !                                  INSN_LOCATION (if_info->insn_a));
>           return TRUE;
>         }
>
> *************** noce_try_cmove (struct noce_if_info *if_
> *** 1481,1487 ****
>             return FALSE;
>
>           emit_insn_before_setloc (seq, if_info->jump,
> !                                  INSN_LOCATOR (if_info->insn_a));
>           return TRUE;
>         }
>         else
> --- 1481,1487 ----
>             return FALSE;
>
>           emit_insn_before_setloc (seq, if_info->jump,
> !                                  INSN_LOCATION (if_info->insn_a));
>           return TRUE;
>         }
>         else
> *************** noce_try_cmove_arith (struct noce_if_inf
> *** 1682,1688 ****
>     if (!tmp)
>       return FALSE;
>
> !   emit_insn_before_setloc (tmp, if_info->jump, INSN_LOCATOR
> (if_info->insn_a));
>     return TRUE;
>
>    end_seq_and_fail:
> --- 1682,1688 ----
>     if (!tmp)
>       return FALSE;
>
> !   emit_insn_before_setloc (tmp, if_info->jump, INSN_LOCATION
> (if_info->insn_a));
>     return TRUE;
>
>    end_seq_and_fail:
> *************** noce_try_minmax (struct noce_if_info *if
> *** 1929,1935 ****
>     if (!seq)
>       return FALSE;
>
> !   emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATOR
> (if_info->insn_a));
>     if_info->cond = cond;
>     if_info->cond_earliest = earliest;
>
> --- 1929,1935 ----
>     if (!seq)
>       return FALSE;
>
> !   emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION
> (if_info->insn_a));
>     if_info->cond = cond;
>     if_info->cond_earliest = earliest;
>
> *************** noce_try_abs (struct noce_if_info *if_in
> *** 2076,2082 ****
>     if (!seq)
>       return FALSE;
>
> !   emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATOR
> (if_info->insn_a));
>     if_info->cond = cond;
>     if_info->cond_earliest = earliest;
>
> --- 2076,2082 ----
>     if (!seq)
>       return FALSE;
>
> !   emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION
> (if_info->insn_a));
>     if_info->cond = cond;
>     if_info->cond_earliest = earliest;
>
> *************** noce_try_sign_mask (struct noce_if_info
> *** 2155,2161 ****
>     if (!seq)
>       return FALSE;
>
> !   emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATOR
> (if_info->insn_a));
>     return TRUE;
>   }
>
> --- 2155,2161 ----
>     if (!seq)
>       return FALSE;
>
> !   emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION
> (if_info->insn_a));
>     return TRUE;
>   }
>
> *************** noce_try_bitop (struct noce_if_info *if_
> *** 2255,2261 ****
>         return FALSE;
>
>         emit_insn_before_setloc (seq, if_info->jump,
> !                              INSN_LOCATOR (if_info->insn_a));
>       }
>     return TRUE;
>   }
> --- 2255,2261 ----
>         return FALSE;
>
>         emit_insn_before_setloc (seq, if_info->jump,
> !                              INSN_LOCATION (if_info->insn_a));
>       }
>     return TRUE;
>   }
> *************** noce_process_if_block (struct noce_if_in
> *** 2656,2662 ****
>         unshare_all_rtl_in_chain (seq);
>         end_sequence ();
>
> !       emit_insn_before_setloc (seq, BB_END (test_bb), INSN_LOCATOR (insn_a));
>       }
>
>     /* The original THEN and ELSE blocks may now be removed.  The test block
> --- 2656,2662 ----
>         unshare_all_rtl_in_chain (seq);
>         end_sequence ();
>
> !       emit_insn_before_setloc (seq, BB_END (test_bb), INSN_LOCATION (insn_a));
>       }
>
>     /* The original THEN and ELSE blocks may now be removed.  The test block
> *************** cond_move_process_if_block (struct noce_
> *** 2937,2943 ****
>         loc_insn = first_active_insn (else_bb);
>         gcc_assert (loc_insn);
>       }
> !   emit_insn_before_setloc (seq, jump, INSN_LOCATOR (loc_insn));
>
>     if (else_bb)
>       {
> --- 2937,2943 ----
>         loc_insn = first_active_insn (else_bb);
>         gcc_assert (loc_insn);
>       }
> !   emit_insn_before_setloc (seq, jump, INSN_LOCATION (loc_insn));
>
>     if (else_bb)
>       {
> *************** find_cond_trap (basic_block test_bb, edg
> *** 3655,3661 ****
>       return FALSE;
>
>     /* Emit the new insns before cond_earliest.  */
> !   emit_insn_before_setloc (seq, cond_earliest, INSN_LOCATOR (trap));
>
>     /* Delete the trap block if possible.  */
>     remove_edge (trap_bb == then_bb ? then_edge : else_edge);
> --- 3655,3661 ----
>       return FALSE;
>
>     /* Emit the new insns before cond_earliest.  */
> !   emit_insn_before_setloc (seq, cond_earliest, INSN_LOCATION (trap));
>
>     /* Delete the trap block if possible.  */
>     remove_edge (trap_bb == then_bb ? then_edge : else_edge);
> Index: gcc/dwarf2out.c
> ===================================================================
> *** gcc/dwarf2out.c     (revision 189835)
> --- gcc/dwarf2out.c     (working copy)
> *************** add_src_coords_attributes (dw_die_ref di
> *** 15506,15512 ****
>   {
>     expanded_location s;
>
> !   if (DECL_SOURCE_LOCATION (decl) == UNKNOWN_LOCATION)
>       return;
>     s = expand_location (DECL_SOURCE_LOCATION (decl));
>     add_AT_file (die, DW_AT_decl_file, lookup_filename (s.file));
> --- 15506,15512 ----
>   {
>     expanded_location s;
>
> !   if (IS_UNKNOWN_LOCATION (DECL_SOURCE_LOCATION (decl)))
>       return;
>     s = expand_location (DECL_SOURCE_LOCATION (decl));
>     add_AT_file (die, DW_AT_decl_file, lookup_filename (s.file));
> Index: gcc/expr.c
> ===================================================================
> *** gcc/expr.c  (revision 189835)
> --- gcc/expr.c  (working copy)
> *************** expand_expr_real (tree exp, rtx target,
> *** 7802,7820 ****
>     if (cfun && EXPR_HAS_LOCATION (exp))
>       {
>         location_t saved_location = input_location;
> !       location_t saved_curr_loc = get_curr_insn_source_location ();
> !       tree saved_block = get_curr_insn_block ();
>         input_location = EXPR_LOCATION (exp);
> !       set_curr_insn_source_location (input_location);
> !
> !       /* Record where the insns produced belong.  */
> !       set_curr_insn_block (TREE_BLOCK (exp));
>
>         ret = expand_expr_real_1 (exp, target, tmode, modifier, alt_rtl);
>
>         input_location = saved_location;
> !       set_curr_insn_block (saved_block);
> !       set_curr_insn_source_location (saved_curr_loc);
>       }
>     else
>       {
> --- 7802,7815 ----
>     if (cfun && EXPR_HAS_LOCATION (exp))
>       {
>         location_t saved_location = input_location;
> !       location_t saved_curr_loc = curr_insn_location ();
>         input_location = EXPR_LOCATION (exp);
> !       set_curr_insn_location (input_location);
>
>         ret = expand_expr_real_1 (exp, target, tmode, modifier, alt_rtl);
>
>         input_location = saved_location;
> !       set_curr_insn_location (saved_curr_loc);
>       }
>     else
>       {
> Index: gcc/predict.c
> ===================================================================
> *** gcc/predict.c       (revision 189835)
> --- gcc/predict.c       (working copy)
> *************** tree_estimate_probability_driver (void)
> *** 2177,2183 ****
>   {
>     unsigned nb_loops;
>
> !   loop_optimizer_init (0);
>     if (dump_file && (dump_flags & TDF_DETAILS))
>       flow_loops_dump (dump_file, NULL, 0);
>
> --- 2177,2183 ----
>   {
>     unsigned nb_loops;
>
> !   loop_optimizer_init (LOOPS_NORMAL);
>     if (dump_file && (dump_flags & TDF_DETAILS))
>       flow_loops_dump (dump_file, NULL, 0);
>
> Index: gcc/tree-parloops.c
> ===================================================================
> *** gcc/tree-parloops.c (revision 189835)
> --- gcc/tree-parloops.c (working copy)
> *************** create_loop_fn (location_t loc)
> *** 1415,1420 ****
> --- 1415,1421 ----
>     struct function *act_cfun = cfun;
>     static unsigned loopfn_num;
>
> +   loc = LOCATION_LOCUS (loc);
>     snprintf (buf, 100, "%s.$loopfn", current_function_name ());
>     ASM_FORMAT_PRIVATE_NAME (tname, buf, loopfn_num++);
>     clean_symbol_name (tname);
> Index: gcc/recog.c
> ===================================================================
> *** gcc/recog.c (revision 189835)
> --- gcc/recog.c (working copy)
> *************** peep2_attempt (basic_block bb, rtx insn,
> *** 3333,3339 ****
>     /* Replace the old sequence with the new.  */
>     last = emit_insn_after_setloc (attempt,
>                                  peep2_insn_data[i].insn,
> !                                INSN_LOCATOR (peep2_insn_data[i].insn));
>     before_try = PREV_INSN (insn);
>     delete_insn_chain (insn, peep2_insn_data[i].insn, false);
>
> --- 3333,3339 ----
>     /* Replace the old sequence with the new.  */
>     last = emit_insn_after_setloc (attempt,
>                                  peep2_insn_data[i].insn,
> !                                INSN_LOCATION (peep2_insn_data[i].insn));
>     before_try = PREV_INSN (insn);
>     delete_insn_chain (insn, peep2_insn_data[i].insn, false);
>
> Index: gcc/function.c
> ===================================================================
> *** gcc/function.c      (revision 189835)
> --- gcc/function.c      (working copy)
> *************** static bool contains (const_rtx, htab_t)
> *** 133,139 ****
>   static void prepare_function_start (void);
>   static void do_clobber_return_reg (rtx, void *);
>   static void do_use_return_reg (rtx, void *);
> ! static void set_insn_locators (rtx, int) ATTRIBUTE_UNUSED;
>
>   /* Stack of nested functions.  */
>   /* Keep track of the cfun stack.  */
> --- 133,139 ----
>   static void prepare_function_start (void);
>   static void do_clobber_return_reg (rtx, void *);
>   static void do_use_return_reg (rtx, void *);
> ! static void set_insn_locations (rtx, int) ATTRIBUTE_UNUSED;
>
>   /* Stack of nested functions.  */
>   /* Keep track of the cfun stack.  */
> *************** free_after_compilation (struct function
> *** 200,206 ****
>     f->cfg = NULL;
>
>     regno_reg_rtx = NULL;
> -   insn_locators_free ();
>   }
>
>   /* Return size needed for stack frame based on slots so far allocated.
> --- 200,205 ----
> *************** expand_function_end (void)
> *** 4979,4985 ****
>               probe_stack_range (STACK_OLD_CHECK_PROTECT, max_frame_size);
>             seq = get_insns ();
>             end_sequence ();
> !           set_insn_locators (seq, prologue_locator);
>             emit_insn_before (seq, stack_check_probe_note);
>             break;
>           }
> --- 4978,4984 ----
>               probe_stack_range (STACK_OLD_CHECK_PROTECT, max_frame_size);
>             seq = get_insns ();
>             end_sequence ();
> !           set_insn_locations (seq, prologue_location);
>             emit_insn_before (seq, stack_check_probe_note);
>             break;
>           }
> *************** expand_function_end (void)
> *** 4994,5000 ****
>
>     /* Output a linenumber for the end of the function.
>        SDB depends on this.  */
> !   set_curr_insn_source_location (input_location);
>
>     /* Before the return label (if any), clobber the return
>        registers so that they are not propagated live to the rest of
> --- 4993,4999 ----
>
>     /* Output a linenumber for the end of the function.
>        SDB depends on this.  */
> !   set_curr_insn_location (input_location);
>
>     /* Before the return label (if any), clobber the return
>        registers so that they are not propagated live to the rest of
> *************** maybe_copy_prologue_epilogue_insn (rtx i
> *** 5277,5290 ****
>     *slot = copy;
>   }
>
> ! /* Set the locator of the insn chain starting at INSN to LOC.  */
>   static void
> ! set_insn_locators (rtx insn, int loc)
>   {
>     while (insn != NULL_RTX)
>       {
>         if (INSN_P (insn))
> !       INSN_LOCATOR (insn) = loc;
>         insn = NEXT_INSN (insn);
>       }
>   }
> --- 5276,5289 ----
>     *slot = copy;
>   }
>
> ! /* Set the location of the insn chain starting at INSN to LOC.  */
>   static void
> ! set_insn_locations (rtx insn, int loc)
>   {
>     while (insn != NULL_RTX)
>       {
>         if (INSN_P (insn))
> !       INSN_LOCATION (insn) = loc;
>         insn = NEXT_INSN (insn);
>       }
>   }
> *************** thread_prologue_and_epilogue_insns (void
> *** 5893,5899 ****
>         end_sequence ();
>
>         record_insns (split_prologue_seq, NULL, &prologue_insn_hash);
> !       set_insn_locators (split_prologue_seq, prologue_locator);
>   #endif
>       }
>
> --- 5892,5898 ----
>         end_sequence ();
>
>         record_insns (split_prologue_seq, NULL, &prologue_insn_hash);
> !       set_insn_locations (split_prologue_seq, prologue_location);
>   #endif
>       }
>
> *************** thread_prologue_and_epilogue_insns (void
> *** 5922,5928 ****
>
>         prologue_seq = get_insns ();
>         end_sequence ();
> !       set_insn_locators (prologue_seq, prologue_locator);
>       }
>   #endif
>
> --- 5921,5927 ----
>
>         prologue_seq = get_insns ();
>         end_sequence ();
> !       set_insn_locations (prologue_seq, prologue_location);
>       }
>   #endif
>
> *************** thread_prologue_and_epilogue_insns (void
> *** 6418,6424 ****
>
>         /* Retain a map of the epilogue insns.  */
>         record_insns (seq, NULL, &epilogue_insn_hash);
> !       set_insn_locators (seq, epilogue_locator);
>
>         seq = get_insns ();
>         returnjump = get_last_insn ();
> --- 6417,6423 ----
>
>         /* Retain a map of the epilogue insns.  */
>         record_insns (seq, NULL, &epilogue_insn_hash);
> !       set_insn_locations (seq, epilogue_location);
>
>         seq = get_insns ();
>         returnjump = get_last_insn ();
> *************** epilogue_done:
> *** 6608,6614 ****
>              avoid getting rid of sibcall epilogue insns.  Do this before we
>              actually emit the sequence.  */
>           record_insns (seq, NULL, &epilogue_insn_hash);
> !         set_insn_locators (seq, epilogue_locator);
>
>           emit_insn_before (seq, insn);
>         }
> --- 6607,6613 ----
>              avoid getting rid of sibcall epilogue insns.  Do this before we
>              actually emit the sequence.  */
>           record_insns (seq, NULL, &epilogue_insn_hash);
> !         set_insn_locations (seq, epilogue_location);
>
>           emit_insn_before (seq, insn);
>         }
> Index: gcc/print-rtl.c
> ===================================================================
> *** gcc/print-rtl.c     (revision 189835)
> --- gcc/print-rtl.c     (working copy)
> *************** print_rtx (const_rtx in_rtx)
> *** 416,425 ****
>         if (i == 5 && INSN_P (in_rtx))
>           {
>   #ifndef GENERATOR_FILE
> !           /*  Pretty-print insn locators.  Ignore scoping as it is mostly
>                 redundant with line number information and do not print anything
>                 when there is no location information available.  */
> !           if (INSN_LOCATOR (in_rtx) && insn_file (in_rtx))
>               fprintf(outfile, " %s:%i", insn_file (in_rtx), insn_line (in_rtx));
>   #endif
>           }
> --- 416,425 ----
>         if (i == 5 && INSN_P (in_rtx))
>           {
>   #ifndef GENERATOR_FILE
> !           /*  Pretty-print insn locations.  Ignore scoping as it is mostly
>                 redundant with line number information and do not print anything
>                 when there is no location information available.  */
> !           if (INSN_LOCATION (in_rtx) && insn_file (in_rtx))
>               fprintf(outfile, " %s:%i", insn_file (in_rtx), insn_line (in_rtx));
>   #endif
>           }
> *************** print_rtx (const_rtx in_rtx)
> *** 427,442 ****
>           {
>   #ifndef GENERATOR_FILE
>             fprintf (outfile, " %s:%i",
> !                    locator_file (ASM_OPERANDS_SOURCE_LOCATION (in_rtx)),
> !                    locator_line (ASM_OPERANDS_SOURCE_LOCATION (in_rtx)));
>   #endif
>           }
>         else if (i == 1 && GET_CODE (in_rtx) == ASM_INPUT)
>           {
>   #ifndef GENERATOR_FILE
>             fprintf (outfile, " %s:%i",
> !                    locator_file (ASM_INPUT_SOURCE_LOCATION (in_rtx)),
> !                    locator_line (ASM_INPUT_SOURCE_LOCATION (in_rtx)));
>   #endif
>           }
>         else if (i == 6 && NOTE_P (in_rtx))
> --- 427,442 ----
>           {
>   #ifndef GENERATOR_FILE
>             fprintf (outfile, " %s:%i",
> !                    LOCATION_FILE (ASM_OPERANDS_SOURCE_LOCATION (in_rtx)),
> !                    LOCATION_LINE (ASM_OPERANDS_SOURCE_LOCATION (in_rtx)));
>   #endif
>           }
>         else if (i == 1 && GET_CODE (in_rtx) == ASM_INPUT)
>           {
>   #ifndef GENERATOR_FILE
>             fprintf (outfile, " %s:%i",
> !                    LOCATION_FILE (ASM_INPUT_SOURCE_LOCATION (in_rtx)),
> !                    LOCATION_LINE (ASM_INPUT_SOURCE_LOCATION (in_rtx)));
>   #endif
>           }
>         else if (i == 6 && NOTE_P (in_rtx))
> Index: gcc/profile.c
> ===================================================================
> *** gcc/profile.c       (revision 189835)
> --- gcc/profile.c       (working copy)
> *************** branch_prob (void)
> *** 966,972 ****
>              is not computed twice.  */
>           if (last
>               && gimple_has_location (last)
> !             && e->goto_locus != UNKNOWN_LOCATION
>               && !single_succ_p (bb)
>               && (LOCATION_FILE (e->goto_locus)
>                   != LOCATION_FILE (gimple_location (last))
> --- 966,972 ----
>              is not computed twice.  */
>           if (last
>               && gimple_has_location (last)
> !             && !IS_UNKNOWN_LOCATION (e->goto_locus)
>               && !single_succ_p (bb)
>               && (LOCATION_FILE (e->goto_locus)
>                   != LOCATION_FILE (gimple_location (last))
> *************** branch_prob (void)
> *** 976,982 ****
>               basic_block new_bb = split_edge (e);
>               edge ne = single_succ_edge (new_bb);
>               ne->goto_locus = e->goto_locus;
> -             ne->goto_block = e->goto_block;
>             }
>           if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
>                && e->dest != EXIT_BLOCK_PTR)
> --- 976,981 ----
> *************** branch_prob (void)
> *** 1188,1194 ****
>
>           /* Notice GOTO expressions eliminated while constructing the CFG.  */
>           if (single_succ_p (bb)
> !             && single_succ_edge (bb)->goto_locus != UNKNOWN_LOCATION)
>             {
>               expanded_location curr_location
>                 = expand_location (single_succ_edge (bb)->goto_locus);
> --- 1187,1193 ----
>
>           /* Notice GOTO expressions eliminated while constructing the CFG.  */
>           if (single_succ_p (bb)
> !             && !IS_UNKNOWN_LOCATION (single_succ_edge (bb)->goto_locus))
>             {
>               expanded_location curr_location
>                 = expand_location (single_succ_edge (bb)->goto_locus);
> Index: gcc/trans-mem.c
> ===================================================================
> *** gcc/trans-mem.c     (revision 189835)
> --- gcc/trans-mem.c     (working copy)
> *************** ipa_tm_scan_irr_block (basic_block bb)
> *** 3796,3802 ****
>             {
>               tree t = build1 (NOP_EXPR, void_type_node, size_zero_node);
>               SET_EXPR_LOCATION (t, gimple_location (stmt));
> -             TREE_BLOCK (t) = gimple_block (stmt);
>               error ("%Kasm not allowed in %<transaction_safe%> function", t);
>             }
>           return true;
> --- 3796,3801 ----
> Index: gcc/gimplify.c
> ===================================================================
> *** gcc/gimplify.c      (revision 189835)
> --- gcc/gimplify.c      (working copy)
> *************** gimplify_call_expr (tree *expr_p, gimple
> *** 2600,2606 ****
>             = CALL_EXPR_RETURN_SLOT_OPT (call);
>           CALL_FROM_THUNK_P (*expr_p) = CALL_FROM_THUNK_P (call);
>           SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (call));
> -         TREE_BLOCK (*expr_p) = TREE_BLOCK (call);
>
>           /* Set CALL_EXPR_VA_ARG_PACK.  */
>           CALL_EXPR_VA_ARG_PACK (*expr_p) = 1;
> --- 2600,2605 ----
> Index: gcc/except.c
> ===================================================================
> *** gcc/except.c        (revision 189835)
> --- gcc/except.c        (working copy)
> *************** duplicate_eh_regions_1 (struct duplicate
> *** 526,532 ****
>         break;
>
>       case ERT_MUST_NOT_THROW:
> !       new_r->u.must_not_throw = old_r->u.must_not_throw;
>         break;
>       }
>
> --- 526,535 ----
>         break;
>
>       case ERT_MUST_NOT_THROW:
> !       new_r->u.must_not_throw.failure_loc =
> !       LOCATION_LOCUS (old_r->u.must_not_throw.failure_loc);
> !       new_r->u.must_not_throw.failure_decl =
> !       old_r->u.must_not_throw.failure_decl;
>         break;
>       }
>
> Index: gcc/emit-rtl.c
> ===================================================================
> *** gcc/emit-rtl.c      (revision 189835)
> --- gcc/emit-rtl.c      (working copy)
> *************** try_split (rtx pat, rtx trial, int last)
> *** 3634,3640 ****
>         }
>       }
>
> !   tem = emit_insn_after_setloc (seq, trial, INSN_LOCATOR (trial));
>
>     delete_insn (trial);
>     if (has_barrier)
> --- 3634,3640 ----
>         }
>       }
>
> !   tem = emit_insn_after_setloc (seq, trial, INSN_LOCATION (trial));
>
>     delete_insn (trial);
>     if (has_barrier)
> *************** make_insn_raw (rtx pattern)
> *** 3670,3676 ****
>     PATTERN (insn) = pattern;
>     INSN_CODE (insn) = -1;
>     REG_NOTES (insn) = NULL;
> !   INSN_LOCATOR (insn) = curr_insn_locator ();
>     BLOCK_FOR_INSN (insn) = NULL;
>
>   #ifdef ENABLE_RTL_CHECKING
> --- 3670,3676 ----
>     PATTERN (insn) = pattern;
>     INSN_CODE (insn) = -1;
>     REG_NOTES (insn) = NULL;
> !   INSN_LOCATION (insn) = curr_insn_location ();
>     BLOCK_FOR_INSN (insn) = NULL;
>
>   #ifdef ENABLE_RTL_CHECKING
> *************** make_debug_insn_raw (rtx pattern)
> *** 3703,3709 ****
>     PATTERN (insn) = pattern;
>     INSN_CODE (insn) = -1;
>     REG_NOTES (insn) = NULL;
> !   INSN_LOCATOR (insn) = curr_insn_locator ();
>     BLOCK_FOR_INSN (insn) = NULL;
>
>     return insn;
> --- 3703,3709 ----
>     PATTERN (insn) = pattern;
>     INSN_CODE (insn) = -1;
>     REG_NOTES (insn) = NULL;
> !   INSN_LOCATION (insn) = curr_insn_location ();
>     BLOCK_FOR_INSN (insn) = NULL;
>
>     return insn;
> *************** make_jump_insn_raw (rtx pattern)
> *** 3723,3729 ****
>     INSN_CODE (insn) = -1;
>     REG_NOTES (insn) = NULL;
>     JUMP_LABEL (insn) = NULL;
> !   INSN_LOCATOR (insn) = curr_insn_locator ();
>     BLOCK_FOR_INSN (insn) = NULL;
>
>     return insn;
> --- 3723,3729 ----
>     INSN_CODE (insn) = -1;
>     REG_NOTES (insn) = NULL;
>     JUMP_LABEL (insn) = NULL;
> !   INSN_LOCATION (insn) = curr_insn_location ();
>     BLOCK_FOR_INSN (insn) = NULL;
>
>     return insn;
> *************** make_call_insn_raw (rtx pattern)
> *** 3743,3749 ****
>     INSN_CODE (insn) = -1;
>     REG_NOTES (insn) = NULL;
>     CALL_INSN_FUNCTION_USAGE (insn) = NULL;
> !   INSN_LOCATOR (insn) = curr_insn_locator ();
>     BLOCK_FOR_INSN (insn) = NULL;
>
>     return insn;
> --- 3743,3749 ----
>     INSN_CODE (insn) = -1;
>     REG_NOTES (insn) = NULL;
>     CALL_INSN_FUNCTION_USAGE (insn) = NULL;
> !   INSN_LOCATION (insn) = curr_insn_location ();
>     BLOCK_FOR_INSN (insn) = NULL;
>
>     return insn;
> *************** emit_pattern_after_setloc (rtx pattern,
> *** 4416,4423 ****
>     after = NEXT_INSN (after);
>     while (1)
>       {
> !       if (active_insn_p (after) && !INSN_LOCATOR (after))
> !       INSN_LOCATOR (after) = loc;
>         if (after == last)
>         break;
>         after = NEXT_INSN (after);
> --- 4416,4423 ----
>     after = NEXT_INSN (after);
>     while (1)
>       {
> !       if (active_insn_p (after) && !INSN_LOCATION (after))
> !       INSN_LOCATION (after) = loc;
>         if (after == last)
>         break;
>         after = NEXT_INSN (after);
> *************** emit_pattern_after (rtx pattern, rtx aft
> *** 4440,4501 ****
>         prev = PREV_INSN (prev);
>
>     if (INSN_P (prev))
> !     return emit_pattern_after_setloc (pattern, after, INSN_LOCATOR (prev),
>                                       make_raw);
>     else
>       return emit_pattern_after_noloc (pattern, after, NULL, make_raw);
>   }
>
> ! /* Like emit_insn_after_noloc, but set INSN_LOCATOR according to LOC.  */
>   rtx
>   emit_insn_after_setloc (rtx pattern, rtx after, int loc)
>   {
>     return emit_pattern_after_setloc (pattern, after, loc, make_insn_raw);
>   }
>
> ! /* Like emit_insn_after_noloc, but set INSN_LOCATOR according to AFTER.  */
>   rtx
>   emit_insn_after (rtx pattern, rtx after)
>   {
>     return emit_pattern_after (pattern, after, true, make_insn_raw);
>   }
>
> ! /* Like emit_jump_insn_after_noloc, but set INSN_LOCATOR according to LOC.  */
>   rtx
>   emit_jump_insn_after_setloc (rtx pattern, rtx after, int loc)
>   {
>     return emit_pattern_after_setloc (pattern, after, loc, make_jump_insn_raw);
>   }
>
> ! /* Like emit_jump_insn_after_noloc, but set INSN_LOCATOR according
> to AFTER.  */
>   rtx
>   emit_jump_insn_after (rtx pattern, rtx after)
>   {
>     return emit_pattern_after (pattern, after, true, make_jump_insn_raw);
>   }
>
> ! /* Like emit_call_insn_after_noloc, but set INSN_LOCATOR according to LOC.  */
>   rtx
>   emit_call_insn_after_setloc (rtx pattern, rtx after, int loc)
>   {
>     return emit_pattern_after_setloc (pattern, after, loc, make_call_insn_raw);
>   }
>
> ! /* Like emit_call_insn_after_noloc, but set INSN_LOCATOR according
> to AFTER.  */
>   rtx
>   emit_call_insn_after (rtx pattern, rtx after)
>   {
>     return emit_pattern_after (pattern, after, true, make_call_insn_raw);
>   }
>
> ! /* Like emit_debug_insn_after_noloc, but set INSN_LOCATOR according
> to LOC.  */
>   rtx
>   emit_debug_insn_after_setloc (rtx pattern, rtx after, int loc)
>   {
>     return emit_pattern_after_setloc (pattern, after, loc, make_debug_insn_raw);
>   }
>
> ! /* Like emit_debug_insn_after_noloc, but set INSN_LOCATOR according
> to AFTER.  */
>   rtx
>   emit_debug_insn_after (rtx pattern, rtx after)
>   {
> --- 4440,4501 ----
>         prev = PREV_INSN (prev);
>
>     if (INSN_P (prev))
> !     return emit_pattern_after_setloc (pattern, after, INSN_LOCATION (prev),
>                                       make_raw);
>     else
>       return emit_pattern_after_noloc (pattern, after, NULL, make_raw);
>   }
>
> ! /* Like emit_insn_after_noloc, but set INSN_LOCATION according to LOC.  */
>   rtx
>   emit_insn_after_setloc (rtx pattern, rtx after, int loc)
>   {
>     return emit_pattern_after_setloc (pattern, after, loc, make_insn_raw);
>   }
>
> ! /* Like emit_insn_after_noloc, but set INSN_LOCATION according to AFTER.  */
>   rtx
>   emit_insn_after (rtx pattern, rtx after)
>   {
>     return emit_pattern_after (pattern, after, true, make_insn_raw);
>   }
>
> ! /* Like emit_jump_insn_after_noloc, but set INSN_LOCATION according
> to LOC.  */
>   rtx
>   emit_jump_insn_after_setloc (rtx pattern, rtx after, int loc)
>   {
>     return emit_pattern_after_setloc (pattern, after, loc, make_jump_insn_raw);
>   }
>
> ! /* Like emit_jump_insn_after_noloc, but set INSN_LOCATION according
> to AFTER.  */
>   rtx
>   emit_jump_insn_after (rtx pattern, rtx after)
>   {
>     return emit_pattern_after (pattern, after, true, make_jump_insn_raw);
>   }
>
> ! /* Like emit_call_insn_after_noloc, but set INSN_LOCATION according
> to LOC.  */
>   rtx
>   emit_call_insn_after_setloc (rtx pattern, rtx after, int loc)
>   {
>     return emit_pattern_after_setloc (pattern, after, loc, make_call_insn_raw);
>   }
>
> ! /* Like emit_call_insn_after_noloc, but set INSN_LOCATION according
> to AFTER.  */
>   rtx
>   emit_call_insn_after (rtx pattern, rtx after)
>   {
>     return emit_pattern_after (pattern, after, true, make_call_insn_raw);
>   }
>
> ! /* Like emit_debug_insn_after_noloc, but set INSN_LOCATION according
> to LOC.  */
>   rtx
>   emit_debug_insn_after_setloc (rtx pattern, rtx after, int loc)
>   {
>     return emit_pattern_after_setloc (pattern, after, loc, make_debug_insn_raw);
>   }
>
> ! /* Like emit_debug_insn_after_noloc, but set INSN_LOCATION according
> to AFTER.  */
>   rtx
>   emit_debug_insn_after (rtx pattern, rtx after)
>   {
> *************** emit_pattern_before_setloc (rtx pattern,
> *** 4525,4532 ****
>       first = NEXT_INSN (first);
>     while (1)
>       {
> !       if (active_insn_p (first) && !INSN_LOCATOR (first))
> !       INSN_LOCATOR (first) = loc;
>         if (first == last)
>         break;
>         first = NEXT_INSN (first);
> --- 4525,4532 ----
>       first = NEXT_INSN (first);
>     while (1)
>       {
> !       if (active_insn_p (first) && !INSN_LOCATION (first))
> !       INSN_LOCATION (first) = loc;
>         if (first == last)
>         break;
>         first = NEXT_INSN (first);
> *************** emit_pattern_before (rtx pattern, rtx be
> *** 4550,4556 ****
>         next = PREV_INSN (next);
>
>     if (INSN_P (next))
> !     return emit_pattern_before_setloc (pattern, before, INSN_LOCATOR (next),
>                                        insnp, make_raw);
>     else
>       return emit_pattern_before_noloc (pattern, before,
> --- 4550,4556 ----
>         next = PREV_INSN (next);
>
>     if (INSN_P (next))
> !     return emit_pattern_before_setloc (pattern, before, INSN_LOCATION (next),
>                                        insnp, make_raw);
>     else
>       return emit_pattern_before_noloc (pattern, before,
> *************** emit_pattern_before (rtx pattern, rtx be
> *** 4558,4564 ****
>                                         NULL, make_raw);
>   }
>
> ! /* Like emit_insn_before_noloc, but set INSN_LOCATOR according to LOC.  */
>   rtx
>   emit_insn_before_setloc (rtx pattern, rtx before, int loc)
>   {
> --- 4558,4564 ----
>                                         NULL, make_raw);
>   }
>
> ! /* Like emit_insn_before_noloc, but set INSN_LOCATION according to LOC.  */
>   rtx
>   emit_insn_before_setloc (rtx pattern, rtx before, int loc)
>   {
> *************** emit_insn_before_setloc (rtx pattern, rt
> *** 4566,4579 ****
>                                      make_insn_raw);
>   }
>
> ! /* Like emit_insn_before_noloc, but set INSN_LOCATOR according to BEFORE.  */
>   rtx
>   emit_insn_before (rtx pattern, rtx before)
>   {
>     return emit_pattern_before (pattern, before, true, true, make_insn_raw);
>   }
>
> ! /* like emit_insn_before_noloc, but set INSN_LOCATOR according to LOC.  */
>   rtx
>   emit_jump_insn_before_setloc (rtx pattern, rtx before, int loc)
>   {
> --- 4566,4579 ----
>                                      make_insn_raw);
>   }
>
> ! /* Like emit_insn_before_noloc, but set INSN_LOCATION according to BEFORE.  */
>   rtx
>   emit_insn_before (rtx pattern, rtx before)
>   {
>     return emit_pattern_before (pattern, before, true, true, make_insn_raw);
>   }
>
> ! /* like emit_insn_before_noloc, but set INSN_LOCATION according to LOC.  */
>   rtx
>   emit_jump_insn_before_setloc (rtx pattern, rtx before, int loc)
>   {
> *************** emit_jump_insn_before_setloc (rtx patter
> *** 4581,4587 ****
>                                      make_jump_insn_raw);
>   }
>
> ! /* Like emit_jump_insn_before_noloc, but set INSN_LOCATOR according
> to BEFORE.  */
>   rtx
>   emit_jump_insn_before (rtx pattern, rtx before)
>   {
> --- 4581,4587 ----
>                                      make_jump_insn_raw);
>   }
>
> ! /* Like emit_jump_insn_before_noloc, but set INSN_LOCATION according
> to BEFORE.  */
>   rtx
>   emit_jump_insn_before (rtx pattern, rtx before)
>   {
> *************** emit_jump_insn_before (rtx pattern, rtx
> *** 4589,4595 ****
>                               make_jump_insn_raw);
>   }
>
> ! /* Like emit_insn_before_noloc, but set INSN_LOCATOR according to LOC.  */
>   rtx
>   emit_call_insn_before_setloc (rtx pattern, rtx before, int loc)
>   {
> --- 4589,4595 ----
>                               make_jump_insn_raw);
>   }
>
> ! /* Like emit_insn_before_noloc, but set INSN_LOCATION according to LOC.  */
>   rtx
>   emit_call_insn_before_setloc (rtx pattern, rtx before, int loc)
>   {
> *************** emit_call_insn_before_setloc (rtx patter
> *** 4598,4604 ****
>   }
>
>   /* Like emit_call_insn_before_noloc,
> !    but set insn_locator according to BEFORE.  */
>   rtx
>   emit_call_insn_before (rtx pattern, rtx before)
>   {
> --- 4598,4604 ----
>   }
>
>   /* Like emit_call_insn_before_noloc,
> !    but set insn_location according to BEFORE.  */
>   rtx
>   emit_call_insn_before (rtx pattern, rtx before)
>   {
> *************** emit_call_insn_before (rtx pattern, rtx
> *** 4606,4612 ****
>                               make_call_insn_raw);
>   }
>
> ! /* Like emit_insn_before_noloc, but set INSN_LOCATOR according to LOC.  */
>   rtx
>   emit_debug_insn_before_setloc (rtx pattern, rtx before, int loc)
>   {
> --- 4606,4612 ----
>                               make_call_insn_raw);
>   }
>
> ! /* Like emit_insn_before_noloc, but set INSN_LOCATION according to LOC.  */
>   rtx
>   emit_debug_insn_before_setloc (rtx pattern, rtx before, int loc)
>   {
> *************** emit_debug_insn_before_setloc (rtx patte
> *** 4615,4621 ****
>   }
>
>   /* Like emit_debug_insn_before_noloc,
> !    but set insn_locator according to BEFORE.  */
>   rtx
>   emit_debug_insn_before (rtx pattern, rtx before)
>   {
> --- 4615,4621 ----
>   }
>
>   /* Like emit_debug_insn_before_noloc,
> !    but set insn_location according to BEFORE.  */
>   rtx
>   emit_debug_insn_before (rtx pattern, rtx before)
>   {
> *************** emit_copy_of_insn_after (rtx insn, rtx a
> *** 5865,5871 ****
>     /* Update LABEL_NUSES.  */
>     mark_jump_label (PATTERN (new_rtx), new_rtx, 0);
>
> !   INSN_LOCATOR (new_rtx) = INSN_LOCATOR (insn);
>
>     /* If the old insn is frame related, then so is the new one.  This is
>        primarily needed for IA-64 unwind info which marks epilogue insns,
> --- 5865,5871 ----
>     /* Update LABEL_NUSES.  */
>     mark_jump_label (PATTERN (new_rtx), new_rtx, 0);
>
> !   INSN_LOCATION (new_rtx) = INSN_LOCATION (insn);
>
>     /* If the old insn is frame related, then so is the new one.  This is
>        primarily needed for IA-64 unwind info which marks epilogue insns,
> *************** gen_hard_reg_clobber (enum machine_mode
> *** 5900,6149 ****
>             gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (mode, regno)));
>   }
>
> ! /* Data structures representing mapping of INSN_LOCATOR into scope
> blocks, line
> !    numbers and files.  In order to be GGC friendly we need to use separate
> !    varrays.  This also slightly improve the memory locality in binary search.
> !    The _locs array contains locators where the given property change.  The
> !    block_locators_blocks contains the scope block that is used for all insn
> !    locator greater than corresponding block_locators_locs value and smaller
> !    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) *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;
>
>   /* Hold current location information and last location information, so the
>      datastructures are built lazily only when some instructions in given
>      place are needed.  */
>   static location_t curr_location, last_location;
> - static tree curr_block, last_block;
> - static int curr_rtl_loc = -1;
>
> ! /* Allocate insn locator datastructure.  */
>   void
> ! insn_locators_alloc (void)
>   {
> !   prologue_locator = epilogue_locator = 0;
> !
> !   block_locators_locs = VEC_alloc (int, heap, 32);
> !   block_locators_blocks = VEC_alloc (tree, gc, 32);
> !   locations_locators_locs = VEC_alloc (int, heap, 32);
> !   locations_locators_vals = VEC_alloc (location_t, heap, 32);
> !
>     curr_location = UNKNOWN_LOCATION;
>     last_location = UNKNOWN_LOCATION;
> -   curr_block = NULL;
> -   last_block = NULL;
> -   curr_rtl_loc = 0;
>   }
>
>   /* 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;
> ! }
> !
> ! /* Allocate insn locator datastructure.  */
> ! void
> ! insn_locators_free (void)
>   {
> !   prologue_locator = epilogue_locator = 0;
> !
> !   VEC_free (int, heap, block_locators_locs);
> !   VEC_free (tree,gc, block_locators_blocks);
> !   VEC_free (int, heap, locations_locators_locs);
> !   VEC_free (location_t, heap, locations_locators_vals);
>   }
>
>   /* 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;
>     curr_location = location;
>   }
>
>   /* Get current location.  */
>   location_t
> ! get_curr_insn_source_location (void)
>   {
>     return curr_location;
>   }
>
> - /* 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;
> - }
> -
> - /* Get current scope block.  */
> - tree
> - get_curr_insn_block (void)
> - {
> -   return curr_block;
> - }
> -
> - /* Return current insn locator.  */
> - int
> - curr_insn_locator (void)
> - {
> -   if (curr_rtl_loc == -1 || curr_location == UNKNOWN_LOCATION)
> -     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;
> -     }
> -   if (last_location != curr_location)
> -     {
> -       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;
> - }
> -
> -
> - /* Return lexical scope block locator belongs to.  */
> - static tree
> - locator_scope (int loc)
> - {
> -   int max = VEC_length (int, block_locators_locs);
> -   int min = 0;
> -
> -   /* When block_locators_locs was initialized, the pro- and epilogue
> -      insns didn't exist yet and can therefore not be found this way.
> -      But we know that they belong to the outer most block of the
> -      current function.
> -      Without this test, the prologue would be put inside the block of
> -      the first valid instruction in the function and when that first
> -      insn is part of an inlined function then the low_pc of that
> -      inlined function is messed up.  Likewise for the epilogue and
> -      the last valid instruction.  */
> -   if (loc == prologue_locator || loc == epilogue_locator)
> -     return DECL_INITIAL (cfun->decl);
> -
> -   if (!max || !loc)
> -     return NULL;
> -   while (1)
> -     {
> -       int pos = (min + max) / 2;
> -       int tmp = VEC_index (int, block_locators_locs, pos);
> -
> -       if (tmp <= loc && min != pos)
> -       min = pos;
> -       else if (tmp > loc && max != pos)
> -       max = pos;
> -       else
> -       {
> -         min = pos;
> -         break;
> -       }
> -     }
> -   return VEC_index (tree, block_locators_blocks, min);
> - }
> -
>   /* Return lexical scope block insn belongs to.  */
>   tree
>   insn_scope (const_rtx insn)
>   {
> !   return locator_scope (INSN_LOCATOR (insn));
> ! }
> !
> ! /* Return line number of the statement specified by the locator.  */
> ! location_t
> ! locator_location (int loc)
> ! {
> !   int max = VEC_length (int, locations_locators_locs);
> !   int min = 0;
> !
> !   while (1)
> !     {
> !       int pos = (min + max) / 2;
> !       int tmp = VEC_index (int, locations_locators_locs, pos);
> !
> !       if (tmp <= loc && min != pos)
> !       min = pos;
> !       else if (tmp > loc && max != pos)
> !       max = pos;
> !       else
> !       {
> !         min = pos;
> !         break;
> !       }
> !     }
> !   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.  */
>   int
>   insn_line (const_rtx insn)
>   {
> !   return locator_line (INSN_LOCATOR (insn));
> ! }
> !
> ! /* Return source file of the statement specified by LOC.  */
> ! const char *
> ! locator_file (int loc)
> ! {
> !   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.  */
>   const char *
>   insn_file (const_rtx insn)
>   {
> !   return locator_file (INSN_LOCATOR (insn));
>   }
>
> - /* Return true if LOC1 and LOC2 locators have the same location and scope.  */
> - bool
> - locator_eq (int loc1, int loc2)
> - {
> -   if (loc1 == loc2)
> -     return true;
> -   if (locator_location (loc1) != locator_location (loc2))
> -     return false;
> -   return locator_scope (loc1) == locator_scope (loc2);
> - }
> -
> -
>   /* Return true if memory model MODEL requires a pre-operation (release-style)
>      barrier or a post-operation (acquire-style) barrier.  While not universal,
>      this function matches behavior of several targets.  */
> --- 5900,5965 ----
>             gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (mode, regno)));
>   }
>
> ! location_t prologue_location;
> ! location_t epilogue_location;
>
>   /* Hold current location information and last location information, so the
>      datastructures are built lazily only when some instructions in given
>      place are needed.  */
>   static location_t curr_location, last_location;
>
> ! /* Allocate insn location datastructure.  */
>   void
> ! insn_locations_init (void)
>   {
> !   prologue_location = epilogue_location = 0;
>     curr_location = UNKNOWN_LOCATION;
>     last_location = UNKNOWN_LOCATION;
>   }
>
>   /* At the end of emit stage, clear current location.  */
>   void
> ! insn_locations_finalize (void)
>   {
> !   epilogue_location = curr_location;
> !   curr_location = UNKNOWN_LOCATION;
>   }
>
>   /* Set current location.  */
>   void
> ! set_curr_insn_location (location_t location)
>   {
>     curr_location = location;
>   }
>
>   /* Get current location.  */
>   location_t
> ! curr_insn_location (void)
>   {
>     return curr_location;
>   }
>
>   /* Return lexical scope block insn belongs to.  */
>   tree
>   insn_scope (const_rtx insn)
>   {
> !   return LOCATION_BLOCK (INSN_LOCATION (insn));
>   }
>
>   /* Return line number of the statement that produced this insn.  */
>   int
>   insn_line (const_rtx insn)
>   {
> !   return LOCATION_LINE (INSN_LOCATION (insn));
>   }
>
>   /* Return source file of the statement that produced this insn.  */
>   const char *
>   insn_file (const_rtx insn)
>   {
> !   return LOCATION_FILE (INSN_LOCATION (insn));
>   }
>
>   /* Return true if memory model MODEL requires a pre-operation (release-style)
>      barrier or a post-operation (acquire-style) barrier.  While not universal,
>      this function matches behavior of several targets.  */
> Index: gcc/cfgexpand.c
> ===================================================================
> *** gcc/cfgexpand.c     (revision 189835)
> --- gcc/cfgexpand.c     (working copy)
> *************** gimple_assign_rhs_to_tree (gimple stmt)
> *** 92,99 ****
>            && gimple_location (stmt) != EXPR_LOCATION (t))
>           || (gimple_block (stmt)
>               && currently_expanding_to_rtl
> !             && EXPR_P (t)
> !             && gimple_block (stmt) != TREE_BLOCK (t)))
>         t = copy_node (t);
>       }
>     else
> --- 92,98 ----
>            && gimple_location (stmt) != EXPR_LOCATION (t))
>           || (gimple_block (stmt)
>               && currently_expanding_to_rtl
> !             && EXPR_P (t)))
>         t = copy_node (t);
>       }
>     else
> *************** gimple_assign_rhs_to_tree (gimple stmt)
> *** 101,108 ****
>
>     if (gimple_has_location (stmt) && CAN_HAVE_LOCATION_P (t))
>       SET_EXPR_LOCATION (t, gimple_location (stmt));
> -   if (gimple_block (stmt) && currently_expanding_to_rtl && EXPR_P (t))
> -     TREE_BLOCK (t) = gimple_block (stmt);
>
>     return t;
>   }
> --- 100,105 ----
> *************** expand_gimple_cond (basic_block bb, gimp
> *** 1804,1811 ****
>     last2 = last = get_last_insn ();
>
>     extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
> !   set_curr_insn_source_location (gimple_location (stmt));
> !   set_curr_insn_block (gimple_block (stmt));
>
>     /* These flags have no purpose in RTL land.  */
>     true_edge->flags &= ~EDGE_TRUE_VALUE;
> --- 1801,1807 ----
>     last2 = last = get_last_insn ();
>
>     extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
> !   set_curr_insn_location (gimple_location (stmt));
>
>     /* These flags have no purpose in RTL land.  */
>     true_edge->flags &= ~EDGE_TRUE_VALUE;
> *************** expand_gimple_cond (basic_block bb, gimp
> *** 1818,1830 ****
>         jumpif_1 (code, op0, op1, label_rtx_for_bb (true_edge->dest),
>                 true_edge->probability);
>         maybe_dump_rtl_for_gimple_stmt (stmt, last);
> !       if (true_edge->goto_locus)
> !       {
> !         set_curr_insn_source_location (true_edge->goto_locus);
> !         set_curr_insn_block (true_edge->goto_block);
> !         true_edge->goto_locus = curr_insn_locator ();
> !       }
> !       true_edge->goto_block = NULL;
>         false_edge->flags |= EDGE_FALLTHRU;
>         maybe_cleanup_end_of_block (false_edge, last);
>         return NULL;
> --- 1814,1821 ----
>         jumpif_1 (code, op0, op1, label_rtx_for_bb (true_edge->dest),
>                 true_edge->probability);
>         maybe_dump_rtl_for_gimple_stmt (stmt, last);
> !       if (!IS_UNKNOWN_LOCATION (true_edge->goto_locus))
> !       set_curr_insn_location (true_edge->goto_locus);
>         false_edge->flags |= EDGE_FALLTHRU;
>         maybe_cleanup_end_of_block (false_edge, last);
>         return NULL;
> *************** expand_gimple_cond (basic_block bb, gimp
> *** 1834,1846 ****
>         jumpifnot_1 (code, op0, op1, label_rtx_for_bb (false_edge->dest),
>                    false_edge->probability);
>         maybe_dump_rtl_for_gimple_stmt (stmt, last);
> !       if (false_edge->goto_locus)
> !       {
> !         set_curr_insn_source_location (false_edge->goto_locus);
> !         set_curr_insn_block (false_edge->goto_block);
> !         false_edge->goto_locus = curr_insn_locator ();
> !       }
> !       false_edge->goto_block = NULL;
>         true_edge->flags |= EDGE_FALLTHRU;
>         maybe_cleanup_end_of_block (true_edge, last);
>         return NULL;
> --- 1825,1832 ----
>         jumpifnot_1 (code, op0, op1, label_rtx_for_bb (false_edge->dest),
>                    false_edge->probability);
>         maybe_dump_rtl_for_gimple_stmt (stmt, last);
> !       if (!IS_UNKNOWN_LOCATION (false_edge->goto_locus))
> !       set_curr_insn_location (false_edge->goto_locus);
>         true_edge->flags |= EDGE_FALLTHRU;
>         maybe_cleanup_end_of_block (true_edge, last);
>         return NULL;
> *************** expand_gimple_cond (basic_block bb, gimp
> *** 1849,1861 ****
>     jumpif_1 (code, op0, op1, label_rtx_for_bb (true_edge->dest),
>             true_edge->probability);
>     last = get_last_insn ();
> !   if (false_edge->goto_locus)
> !     {
> !       set_curr_insn_source_location (false_edge->goto_locus);
> !       set_curr_insn_block (false_edge->goto_block);
> !       false_edge->goto_locus = curr_insn_locator ();
> !     }
> !   false_edge->goto_block = NULL;
>     emit_jump (label_rtx_for_bb (false_edge->dest));
>
>     BB_END (bb) = last;
> --- 1835,1842 ----
>     jumpif_1 (code, op0, op1, label_rtx_for_bb (true_edge->dest),
>             true_edge->probability);
>     last = get_last_insn ();
> !   if (!IS_UNKNOWN_LOCATION (false_edge->goto_locus))
> !     set_curr_insn_location (false_edge->goto_locus);
>     emit_jump (label_rtx_for_bb (false_edge->dest));
>
>     BB_END (bb) = last;
> *************** expand_gimple_cond (basic_block bb, gimp
> *** 1880,1892 ****
>
>     maybe_dump_rtl_for_gimple_stmt (stmt, last2);
>
> !   if (true_edge->goto_locus)
>       {
> !       set_curr_insn_source_location (true_edge->goto_locus);
> !       set_curr_insn_block (true_edge->goto_block);
> !       true_edge->goto_locus = curr_insn_locator ();
>       }
> -   true_edge->goto_block = NULL;
>
>     return new_bb;
>   }
> --- 1861,1871 ----
>
>     maybe_dump_rtl_for_gimple_stmt (stmt, last2);
>
> !   if (!IS_UNKNOWN_LOCATION (true_edge->goto_locus))
>       {
> !       set_curr_insn_location (true_edge->goto_locus);
> !       true_edge->goto_locus = curr_insn_location ();
>       }
>
>     return new_bb;
>   }
> *************** expand_call_stmt (gimple stmt)
> *** 1986,1992 ****
>       CALL_FROM_THUNK_P (exp) = gimple_call_from_thunk_p (stmt);
>     CALL_EXPR_VA_ARG_PACK (exp) = gimple_call_va_arg_pack_p (stmt);
>     SET_EXPR_LOCATION (exp, gimple_location (stmt));
> -   TREE_BLOCK (exp) = gimple_block (stmt);
>
>     /* Ensure RTL is created for debug args.  */
>     if (decl && DECL_HAS_DEBUG_ARGS_P (decl))
> --- 1965,1970 ----
> *************** expand_gimple_stmt_1 (gimple stmt)
> *** 2021,2028 ****
>   {
>     tree op0;
>
> !   set_curr_insn_source_location (gimple_location (stmt));
> !   set_curr_insn_block (gimple_block (stmt));
>
>     switch (gimple_code (stmt))
>       {
> --- 1999,2005 ----
>   {
>     tree op0;
>
> !   set_curr_insn_location (gimple_location (stmt));
>
>     switch (gimple_code (stmt))
>       {
> *************** expand_gimple_basic_block (basic_block b
> *** 3766,3773 ****
>           tree op;
>           gimple def;
>
> !         location_t sloc = get_curr_insn_source_location ();
> !         tree sblock = get_curr_insn_block ();
>
>           /* Look for SSA names that have their last use here (TERed
>              names always have only one real use).  */
> --- 3743,3749 ----
>           tree op;
>           gimple def;
>
> !         location_t sloc = curr_insn_location ();
>
>           /* Look for SSA names that have their last use here (TERed
>              names always have only one real use).  */
> *************** expand_gimple_basic_block (basic_block b
> *** 3800,3807 ****
>                     rtx val;
>                     enum machine_mode mode;
>
> !                   set_curr_insn_source_location (gimple_location (def));
> !                   set_curr_insn_block (gimple_block (def));
>
>                     DECL_ARTIFICIAL (vexpr) = 1;
>                     TREE_TYPE (vexpr) = TREE_TYPE (value);
> --- 3776,3782 ----
>                     rtx val;
>                     enum machine_mode mode;
>
> !                   set_curr_insn_location (gimple_location (def));
>
>                     DECL_ARTIFICIAL (vexpr) = 1;
>                     TREE_TYPE (vexpr) = TREE_TYPE (value);
> *************** expand_gimple_basic_block (basic_block b
> *** 3828,3835 ****
>                       }
>                   }
>               }
> !         set_curr_insn_source_location (sloc);
> !         set_curr_insn_block (sblock);
>         }
>
>         currently_expanding_gimple_stmt = stmt;
> --- 3803,3809 ----
>                       }
>                   }
>               }
> !         set_curr_insn_location (sloc);
>         }
>
>         currently_expanding_gimple_stmt = stmt;
> *************** expand_gimple_basic_block (basic_block b
> *** 3844,3851 ****
>         }
>         else if (gimple_debug_bind_p (stmt))
>         {
> !         location_t sloc = get_curr_insn_source_location ();
> !         tree sblock = get_curr_insn_block ();
>           gimple_stmt_iterator nsi = gsi;
>
>           for (;;)
> --- 3818,3824 ----
>         }
>         else if (gimple_debug_bind_p (stmt))
>         {
> !         location_t sloc = curr_insn_location ();
>           gimple_stmt_iterator nsi = gsi;
>
>           for (;;)
> *************** expand_gimple_basic_block (basic_block b
> *** 3867,3874 ****
>
>               last = get_last_insn ();
>
> !             set_curr_insn_source_location (gimple_location (stmt));
> !             set_curr_insn_block (gimple_block (stmt));
>
>               if (DECL_P (var))
>                 mode = DECL_MODE (var);
> --- 3840,3846 ----
>
>               last = get_last_insn ();
>
> !             set_curr_insn_location (gimple_location (stmt));
>
>               if (DECL_P (var))
>                 mode = DECL_MODE (var);
> *************** expand_gimple_basic_block (basic_block b
> *** 3906,3918 ****
>                 break;
>             }
>
> !         set_curr_insn_source_location (sloc);
> !         set_curr_insn_block (sblock);
>         }
>         else if (gimple_debug_source_bind_p (stmt))
>         {
> !         location_t sloc = get_curr_insn_source_location ();
> !         tree sblock = get_curr_insn_block ();
>           tree var = gimple_debug_source_bind_get_var (stmt);
>           tree value = gimple_debug_source_bind_get_value (stmt);
>           rtx val;
> --- 3878,3888 ----
>                 break;
>             }
>
> !         set_curr_insn_location (sloc);
>         }
>         else if (gimple_debug_source_bind_p (stmt))
>         {
> !         location_t sloc = curr_insn_location ();
>           tree var = gimple_debug_source_bind_get_var (stmt);
>           tree value = gimple_debug_source_bind_get_value (stmt);
>           rtx val;
> *************** expand_gimple_basic_block (basic_block b
> *** 3920,3927 ****
>
>           last = get_last_insn ();
>
> !         set_curr_insn_source_location (gimple_location (stmt));
> !         set_curr_insn_block (gimple_block (stmt));
>
>           mode = DECL_MODE (var);
>
> --- 3890,3896 ----
>
>           last = get_last_insn ();
>
> !         set_curr_insn_location (gimple_location (stmt));
>
>           mode = DECL_MODE (var);
>
> *************** expand_gimple_basic_block (basic_block b
> *** 3939,3946 ****
>               PAT_VAR_LOCATION_LOC (val) = (rtx)value;
>             }
>
> !         set_curr_insn_source_location (sloc);
> !         set_curr_insn_block (sblock);
>         }
>         else
>         {
> --- 3908,3914 ----
>               PAT_VAR_LOCATION_LOC (val) = (rtx)value;
>             }
>
> !         set_curr_insn_location (sloc);
>         }
>         else
>         {
> *************** expand_gimple_basic_block (basic_block b
> *** 3981,3993 ****
>     /* Expand implicit goto and convert goto_locus.  */
>     FOR_EACH_EDGE (e, ei, bb->succs)
>       {
> !       if (e->goto_locus && e->goto_block)
> !       {
> !         set_curr_insn_source_location (e->goto_locus);
> !         set_curr_insn_block (e->goto_block);
> !         e->goto_locus = curr_insn_locator ();
> !       }
> !       e->goto_block = NULL;
>         if ((e->flags & EDGE_FALLTHRU) && e->dest != bb->next_bb)
>         {
>           emit_jump (label_rtx_for_bb (e->dest));
> --- 3949,3956 ----
>     /* Expand implicit goto and convert goto_locus.  */
>     FOR_EACH_EDGE (e, ei, bb->succs)
>       {
> !       if (!IS_UNKNOWN_LOCATION (e->goto_locus))
> !       set_curr_insn_location (e->goto_locus);
>         if ((e->flags & EDGE_FALLTHRU) && e->dest != bb->next_bb)
>         {
>           emit_jump (label_rtx_for_bb (e->dest));
> *************** construct_exit_block (void)
> *** 4107,4118 ****
>
>     /* Make sure the locus is set to the end of the function, so that
>        epilogue line numbers and warnings are set properly.  */
> !   if (cfun->function_end_locus != UNKNOWN_LOCATION)
>       input_location = cfun->function_end_locus;
>
> -   /* The following insns belong to the top scope.  */
> -   set_curr_insn_block (DECL_INITIAL (current_function_decl));
> -
>     /* Generate rtl for function exit.  */
>     expand_function_end ();
>
> --- 4070,4078 ----
>
>     /* Make sure the locus is set to the end of the function, so that
>        epilogue line numbers and warnings are set properly.  */
> !   if (!IS_UNKNOWN_LOCATION (cfun->function_end_locus))
>       input_location = cfun->function_end_locus;
>
>     /* Generate rtl for function exit.  */
>     expand_function_end ();
>
> *************** gimple_expand_cfg (void)
> *** 4331,4350 ****
>
>     rtl_profile_for_bb (ENTRY_BLOCK_PTR);
>
> !   insn_locators_alloc ();
>     if (!DECL_IS_BUILTIN (current_function_decl))
>       {
>         /* Eventually, all FEs should explicitly set function_start_locus.  */
> !       if (cfun->function_start_locus == UNKNOWN_LOCATION)
> !        set_curr_insn_source_location
>            (DECL_SOURCE_LOCATION (current_function_decl));
>         else
> !        set_curr_insn_source_location (cfun->function_start_locus);
>       }
>     else
> !     set_curr_insn_source_location (UNKNOWN_LOCATION);
> !   set_curr_insn_block (DECL_INITIAL (current_function_decl));
> !   prologue_locator = curr_insn_locator ();
>
>   #ifdef INSN_SCHEDULING
>     init_sched_attrs ();
> --- 4291,4309 ----
>
>     rtl_profile_for_bb (ENTRY_BLOCK_PTR);
>
> !   insn_locations_init ();
>     if (!DECL_IS_BUILTIN (current_function_decl))
>       {
>         /* Eventually, all FEs should explicitly set function_start_locus.  */
> !       if (IS_UNKNOWN_LOCATION (cfun->function_start_locus))
> !        set_curr_insn_location
>            (DECL_SOURCE_LOCATION (current_function_decl));
>         else
> !        set_curr_insn_location (cfun->function_start_locus);
>       }
>     else
> !     set_curr_insn_location (UNKNOWN_LOCATION);
> !   prologue_location = curr_insn_location ();
>
>   #ifdef INSN_SCHEDULING
>     init_sched_attrs ();
> *************** gimple_expand_cfg (void)
> *** 4514,4521 ****
>     free_histograms ();
>
>     construct_exit_block ();
> !   set_curr_insn_block (DECL_INITIAL (current_function_decl));
> !   insn_locators_finalize ();
>
>     /* Zap the tree EH table.  */
>     set_eh_throw_stmt_table (cfun, NULL);
> --- 4473,4479 ----
>     free_histograms ();
>
>     construct_exit_block ();
> !   insn_locations_finalize ();
>
>     /* Zap the tree EH table.  */
>     set_eh_throw_stmt_table (cfun, NULL);
> Index: gcc/cfgcleanup.c
> ===================================================================
> *** gcc/cfgcleanup.c    (revision 189835)
> --- gcc/cfgcleanup.c    (working copy)
> *************** try_forward_edges (int mode, basic_block
> *** 481,493 ****
>                   int new_locus = single_succ_edge (target)->goto_locus;
>                   int locus = goto_locus;
>
> !                 if (new_locus && locus && !locator_eq (new_locus, locus))
>                     new_target = NULL;
>                   else
>                     {
>                       rtx last;
>
> !                     if (new_locus)
>                         locus = new_locus;
>
>                       last = BB_END (target);
> --- 481,495 ----
>                   int new_locus = single_succ_edge (target)->goto_locus;
>                   int locus = goto_locus;
>
> !                 if (!IS_UNKNOWN_LOCATION (new_locus)
> !                     && !IS_UNKNOWN_LOCATION (locus)
> !                     && new_locus != locus)
>                     new_target = NULL;
>                   else
>                     {
>                       rtx last;
>
> !                     if (!IS_UNKNOWN_LOCATION (new_locus))
>                         locus = new_locus;
>
>                       last = BB_END (target);
> *************** try_forward_edges (int mode, basic_block
> *** 495,507 ****
>                         last = prev_nondebug_insn (last);
>
>                       new_locus = last && INSN_P (last)
> !                                 ? INSN_LOCATOR (last) : 0;
>
> !                     if (new_locus && locus && !locator_eq (new_locus, locus))
>                         new_target = NULL;
>                       else
>                         {
> !                         if (new_locus)
>                             locus = new_locus;
>
>                           goto_locus = locus;
> --- 497,511 ----
>                         last = prev_nondebug_insn (last);
>
>                       new_locus = last && INSN_P (last)
> !                                 ? INSN_LOCATION (last) : 0;
>
> !                     if (!IS_UNKNOWN_LOCATION (new_locus)
> !                         && !IS_UNKNOWN_LOCATION (locus)
> !                         && new_locus != locus)
>                         new_target = NULL;
>                       else
>                         {
> !                         if (!IS_UNKNOWN_LOCATION (new_locus))
>                             locus = new_locus;
>
>                           goto_locus = locus;
> Index: gcc/tree-ssa-live.c
> ===================================================================
> *** gcc/tree-ssa-live.c (revision 189835)
> --- gcc/tree-ssa-live.c (working copy)
> *************** remove_unused_scope_block_p (tree scope,
> *** 587,593 ****
>      else
>      /* Verfify that only blocks with source location set
>         are entry points to the inlined functions.  */
> !      gcc_assert (BLOCK_SOURCE_LOCATION (scope) == UNKNOWN_LOCATION);
>
>      TREE_USED (scope) = !unused;
>      return unused;
> --- 587,593 ----
>      else
>      /* Verfify that only blocks with source location set
>         are entry points to the inlined functions.  */
> !      gcc_assert (IS_UNKNOWN_LOCATION (BLOCK_SOURCE_LOCATION (scope)));
>
>      TREE_USED (scope) = !unused;
>      return unused;
> *************** dump_scope_block (FILE *file, int indent
> *** 615,621 ****
>     fprintf (file, "\n%*s{ Scope block #%i%s%s",indent, "" ,
> BLOCK_NUMBER (scope),
>            TREE_USED (scope) ? "" : " (unused)",
>            BLOCK_ABSTRACT (scope) ? " (abstract)": "");
> !   if (BLOCK_SOURCE_LOCATION (scope) != UNKNOWN_LOCATION)
>       {
>         expanded_location s = expand_location (BLOCK_SOURCE_LOCATION (scope));
>         fprintf (file, " %s:%i", s.file, s.line);
> --- 615,621 ----
>     fprintf (file, "\n%*s{ Scope block #%i%s%s",indent, "" ,
> BLOCK_NUMBER (scope),
>            TREE_USED (scope) ? "" : " (unused)",
>            BLOCK_ABSTRACT (scope) ? " (abstract)": "");
> !   if (!IS_UNKNOWN_LOCATION (BLOCK_SOURCE_LOCATION (scope)))
>       {
>         expanded_location s = expand_location (BLOCK_SOURCE_LOCATION (scope));
>         fprintf (file, " %s:%i", s.file, s.line);
> *************** remove_unused_locals (void)
> *** 765,777 ****
>             FOR_EACH_PHI_ARG (arg_p, phi, i, SSA_OP_ALL_USES)
>               {
>               tree arg = USE_FROM_PTR (arg_p);
>               mark_all_vars_used (&arg, global_unused_vars);
>               }
>           }
>
>         FOR_EACH_EDGE (e, ei, bb->succs)
>         if (e->goto_locus)
> !         TREE_USED (e->goto_block) = true;
>       }
>
>     /* We do a two-pass approach about the out-of-scope clobbers.  We want
> --- 765,782 ----
>             FOR_EACH_PHI_ARG (arg_p, phi, i, SSA_OP_ALL_USES)
>               {
>               tree arg = USE_FROM_PTR (arg_p);
> +             int index = PHI_ARG_INDEX_FROM_USE (arg_p);
> +             tree block =
> +               LOCATION_BLOCK (gimple_phi_arg_location (phi, index));
> +             if (block != NULL)
> +               TREE_USED (block) = true;
>               mark_all_vars_used (&arg, global_unused_vars);
>               }
>           }
>
>         FOR_EACH_EDGE (e, ei, bb->succs)
>         if (e->goto_locus)
> !         TREE_USED (LOCATION_BLOCK (e->goto_locus)) = true;
>       }
>
>     /* We do a two-pass approach about the out-of-scope clobbers.  We want
> Index: gcc/lto/lto.c
> ===================================================================
> *** gcc/lto/lto.c       (revision 189835)
> --- gcc/lto/lto.c       (working copy)
> *************** lto_fixup_prevailing_decls (tree t)
> *** 1603,1609 ****
>     else if (EXPR_P (t))
>       {
>         int i;
> -       LTO_NO_PREVAIL (t->exp.block);
>         for (i = TREE_OPERAND_LENGTH (t) - 1; i >= 0; --i)
>         LTO_SET_PREVAIL (TREE_OPERAND (t, i));
>       }
> --- 1603,1608 ----
> Index: gcc/tree-streamer-out.c
> ===================================================================
> *** gcc/tree-streamer-out.c     (revision 189835)
> --- gcc/tree-streamer-out.c     (working copy)
> *************** write_ts_decl_minimal_tree_pointers (str
> *** 471,477 ****
>   {
>     stream_write_tree (ob, DECL_NAME (expr), ref_p);
>     stream_write_tree (ob, DECL_CONTEXT (expr), ref_p);
> !   lto_output_location (ob, DECL_SOURCE_LOCATION (expr));
>   }
>
>
> --- 471,477 ----
>   {
>     stream_write_tree (ob, DECL_NAME (expr), ref_p);
>     stream_write_tree (ob, DECL_CONTEXT (expr), ref_p);
> !   lto_output_location (ob, LOCATION_LOCUS (DECL_SOURCE_LOCATION (expr)));
>   }
>
>
> *************** write_ts_exp_tree_pointers (struct outpu
> *** 668,674 ****
>     streamer_write_hwi (ob, TREE_OPERAND_LENGTH (expr));
>     for (i = 0; i < TREE_OPERAND_LENGTH (expr); i++)
>       stream_write_tree (ob, TREE_OPERAND (expr, i), ref_p);
> !   lto_output_location (ob, EXPR_LOCATION (expr));
>     stream_write_tree (ob, TREE_BLOCK (expr), ref_p);
>   }
>
> --- 668,674 ----
>     streamer_write_hwi (ob, TREE_OPERAND_LENGTH (expr));
>     for (i = 0; i < TREE_OPERAND_LENGTH (expr); i++)
>       stream_write_tree (ob, TREE_OPERAND (expr, i), ref_p);
> !   lto_output_location (ob, LOCATION_LOCUS (EXPR_LOCATION (expr)));
>     stream_write_tree (ob, TREE_BLOCK (expr), ref_p);
>   }
>
> Index: gcc/rtl.c
> ===================================================================
> *** gcc/rtl.c   (revision 189835)
> --- gcc/rtl.c   (working copy)
> *************** rtx_equal_p_cb (const_rtx x, const_rtx y
> *** 440,446 ****
>   #ifndef GENERATOR_FILE
>               if (((code == ASM_OPERANDS && i == 6)
>                    || (code == ASM_INPUT && i == 1))
> !                 && locator_eq (XINT (x, i), XINT (y, i)))
>                 break;
>   #endif
>               return 0;
> --- 440,446 ----
>   #ifndef GENERATOR_FILE
>               if (((code == ASM_OPERANDS && i == 6)
>                    || (code == ASM_INPUT && i == 1))
> !                 && XINT (x, i) == XINT (y, i))
>                 break;
>   #endif
>               return 0;
> *************** rtx_equal_p (const_rtx x, const_rtx y)
> *** 579,585 ****
>   #ifndef GENERATOR_FILE
>               if (((code == ASM_OPERANDS && i == 6)
>                    || (code == ASM_INPUT && i == 1))
> !                 && locator_eq (XINT (x, i), XINT (y, i)))
>                 break;
>   #endif
>               return 0;
> --- 579,585 ----
>   #ifndef GENERATOR_FILE
>               if (((code == ASM_OPERANDS && i == 6)
>                    || (code == ASM_INPUT && i == 1))
> !                 && XINT (x, i) == XINT (y, i))
>                 break;
>   #endif
>               return 0;
> Index: gcc/rtl.h
> ===================================================================
> *** gcc/rtl.h   (revision 189835)
> --- gcc/rtl.h   (working copy)
> *************** extern void rtl_check_failed_flag (const
> *** 739,744 ****
> --- 739,745 ----
>   #endif
>
>   #define XINT(RTX, N)  (RTL_CHECK2 (RTX, N, 'i', 'n').rt_int)
> + #define XUINT(RTX, N)   (RTL_CHECK2 (RTX, N, 'i', 'n').rt_uint)
>   #define XSTR(RTX, N)  (RTL_CHECK2 (RTX, N, 's', 'S').rt_str)
>   #define XEXP(RTX, N)  (RTL_CHECK2 (RTX, N, 'e', 'u').rt_rtx)
>   #define XVEC(RTX, N)  (RTL_CHECK2 (RTX, N, 'E', 'V').rt_rtvec)
> *************** extern void rtl_check_failed_flag (const
> *** 802,814 ****
>   /* The body of an insn.  */
>   #define PATTERN(INSN) XEXP (INSN, 4)
>
> ! #define INSN_LOCATOR(INSN) XINT (INSN, 5)
>   /* LOCATION of an RTX if relevant.  */
>   #define RTL_LOCATION(X) (INSN_P (X) ? \
> !                        locator_location (INSN_LOCATOR (X)) \
> !                        : UNKNOWN_LOCATION)
> ! /* LOCATION of current INSN.  */
> ! #define CURR_INSN_LOCATION (locator_location (curr_insn_locator ()))
>
>   /* Code number of instruction, from when it was recognized.
>      -1 means this instruction has not been recognized yet.  */
> --- 803,815 ----
>   /* The body of an insn.  */
>   #define PATTERN(INSN) XEXP (INSN, 4)
>
> ! #define INSN_LOCATION(INSN) XUINT (INSN, 5)
> !
> ! #define INSN_HAS_LOCATION(INSN) (!IS_UNKNOWN_LOCATION (INSN_LOCATION (INSN)))
> !
>   /* LOCATION of an RTX if relevant.  */
>   #define RTL_LOCATION(X) (INSN_P (X) ? \
> !                        INSN_LOCATION (X) : UNKNOWN_LOCATION)
>
>   /* Code number of instruction, from when it was recognized.
>      -1 means this instruction has not been recognized yet.  */
> *************** extern rtx prev_cc0_setter (rtx);
> *** 1807,1818 ****
>   /* In emit-rtl.c  */
>   extern int insn_line (const_rtx);
>   extern const char * insn_file (const_rtx);
> - extern location_t locator_location (int);
> - extern int locator_line (int);
> - extern const char * locator_file (int);
> - extern bool locator_eq (int, int);
> - extern int prologue_locator, epilogue_locator;
>   extern tree insn_scope (const_rtx);
>
>   /* In jump.c */
>   extern enum rtx_code reverse_condition (enum rtx_code);
> --- 1808,1815 ----
>   /* In emit-rtl.c  */
>   extern int insn_line (const_rtx);
>   extern const char * insn_file (const_rtx);
>   extern tree insn_scope (const_rtx);
> + extern location_t prologue_location, epilogue_location;
>
>   /* In jump.c */
>   extern enum rtx_code reverse_condition (enum rtx_code);
> *************** extern const struct rtl_hooks general_rt
> *** 2648,2661 ****
>   /* Keep this for the nonce.  */
>   #define gen_lowpart rtl_hooks.gen_lowpart
>
> ! extern void insn_locators_alloc (void);
> ! extern void insn_locators_free (void);
> ! extern void insn_locators_finalize (void);
> ! extern void set_curr_insn_source_location (location_t);
> ! extern location_t get_curr_insn_source_location (void);
> ! extern void set_curr_insn_block (tree);
> ! extern tree get_curr_insn_block (void);
> ! extern int curr_insn_locator (void);
>   extern bool optimize_insn_for_size_p (void);
>   extern bool optimize_insn_for_speed_p (void);
>
> --- 2645,2654 ----
>   /* Keep this for the nonce.  */
>   #define gen_lowpart rtl_hooks.gen_lowpart
>
> ! extern void insn_locations_init (void);
> ! extern void insn_locations_finalize (void);
> ! extern void set_curr_insn_location (location_t);
> ! extern location_t curr_insn_location (void);
>   extern bool optimize_insn_for_size_p (void);
>   extern bool optimize_insn_for_speed_p (void);
>
> Index: gcc/tree-inline.c
> ===================================================================
> *** gcc/tree-inline.c   (revision 189835)
> --- gcc/tree-inline.c   (working copy)
> *************** remap_gimple_op_r (tree *tp, int *walk_s
> *** 852,861 ****
>         /* Otherwise, just copy the node.  Note that copy_tree_r already
>          knows not to copy VAR_DECLs, etc., so this is safe.  */
>
> -       /* We should never have TREE_BLOCK set on non-statements.  */
> -       if (EXPR_P (*tp))
> -       gcc_assert (!TREE_BLOCK (*tp));
> -
>         if (TREE_CODE (*tp) == MEM_REF)
>         {
>           tree ptr = TREE_OPERAND (*tp, 0);
> --- 852,857 ----
> *************** remap_gimple_op_r (tree *tp, int *walk_s
> *** 901,913 ****
>         {
>           /* Variable substitution need not be simple.  In particular,
>              the MEM_REF substitution above.  Make sure that
> !            TREE_CONSTANT and friends are up-to-date.  But make sure
> !            to not improperly set TREE_BLOCK on some sub-expressions.  */
>           int invariant = is_gimple_min_invariant (*tp);
> -         tree block = id->block;
> -         id->block = NULL_TREE;
>           walk_tree (&TREE_OPERAND (*tp, 0), remap_gimple_op_r, data, NULL);
> -         id->block = block;
>           recompute_tree_invariant_for_addr_expr (*tp);
>
>           /* If this used to be invariant, but is not any longer,
> --- 897,905 ----
>         {
>           /* Variable substitution need not be simple.  In particular,
>              the MEM_REF substitution above.  Make sure that
> !            TREE_CONSTANT and friends are up-to-date.  */
>           int invariant = is_gimple_min_invariant (*tp);
>           walk_tree (&TREE_OPERAND (*tp, 0), remap_gimple_op_r, data, NULL);
>           recompute_tree_invariant_for_addr_expr (*tp);
>
>           /* If this used to be invariant, but is not any longer,
> *************** remap_gimple_op_r (tree *tp, int *walk_s
> *** 919,924 ****
> --- 911,932 ----
>         }
>       }
>
> +   /* Update the TREE_BLOCK for the cloned expr.  */
> +   if (EXPR_P (*tp))
> +     {
> +       tree new_block = id->remapping_type_depth == 0 ? id->block : NULL;
> +       tree old_block = TREE_BLOCK (*tp);
> +       if (old_block)
> +       {
> +         tree *n;
> +         n = (tree *) pointer_map_contains (id->decl_map,
> +                                            TREE_BLOCK (*tp));
> +         if (n)
> +           new_block = *n;
> +       }
> +       TREE_SET_BLOCK (*tp, new_block);
> +     }
> +
>     /* Keep iterating.  */
>     return NULL_TREE;
>   }
> *************** copy_tree_body_r (tree *tp, int *walk_su
> *** 1144,1154 ****
>               tree *n;
>               n = (tree *) pointer_map_contains (id->decl_map,
>                                                  TREE_BLOCK (*tp));
> -             gcc_assert (n || id->remapping_type_depth != 0);
>               if (n)
>                 new_block = *n;
>             }
> !         TREE_BLOCK (*tp) = new_block;
>         }
>
>         if (TREE_CODE (*tp) != OMP_CLAUSE)
> --- 1152,1161 ----
>               tree *n;
>               n = (tree *) pointer_map_contains (id->decl_map,
>                                                  TREE_BLOCK (*tp));
>               if (n)
>                 new_block = *n;
>             }
> !         TREE_SET_BLOCK (*tp, new_block);
>         }
>
>         if (TREE_CODE (*tp) != OMP_CLAUSE)
> *************** copy_phis_for_bb (basic_block bb, copy_b
> *** 2020,2025 ****
> --- 2027,2033 ----
>               tree new_arg;
>               tree block = id->block;
>               edge_iterator ei2;
> +             location_t locus;
>
>               /* When doing partial cloning, we allow PHIs on the entry block
>                  as long as all the arguments are the same.  Find any input
> *************** copy_phis_for_bb (basic_block bb, copy_b
> *** 2031,2039 ****
>
>               arg = PHI_ARG_DEF_FROM_EDGE (phi, old_edge);
>               new_arg = arg;
> -             id->block = NULL_TREE;
>               walk_tree (&new_arg, copy_tree_body_r, id, NULL);
> -             id->block = block;
>               gcc_assert (new_arg);
>               /* With return slot optimization we can end up with
>                  non-gimple (foo *)&this->m, fix that here.  */
> --- 2039,2045 ----
> *************** copy_phis_for_bb (basic_block bb, copy_b
> *** 2046,2053 ****
>                   gsi_insert_seq_on_edge (new_edge, stmts);
>                   inserted = true;
>                 }
>               add_phi_arg (new_phi, new_arg, new_edge,
> !                          gimple_phi_arg_location_from_edge (phi, old_edge));
>             }
>         }
>       }
> --- 2052,2070 ----
>                   gsi_insert_seq_on_edge (new_edge, stmts);
>                   inserted = true;
>                 }
> +             locus = gimple_phi_arg_location_from_edge (phi, old_edge);
> +             block = id->block;
> +             if (LOCATION_BLOCK (locus))
> +               {
> +                 tree *n;
> +                 n = (tree *) pointer_map_contains (id->decl_map,
> +                       LOCATION_BLOCK (locus));
> +                 gcc_assert (n);
> +                 block = *n;
> +               }
> +
>               add_phi_arg (new_phi, new_arg, new_edge,
> !                          COMBINE_LOCATION (locus, block));
>             }
>         }
>       }
> *************** expand_call_inline (basic_block bb, gimp
> *** 3946,3952 ****
>     id->block = make_node (BLOCK);
>     BLOCK_ABSTRACT_ORIGIN (id->block) = fn;
>     BLOCK_SOURCE_LOCATION (id->block) = input_location;
> !   prepend_lexical_block (gimple_block (stmt), id->block);
>
>     /* Local declarations will be replaced by their equivalents in this
>        map.  */
> --- 3963,3970 ----
>     id->block = make_node (BLOCK);
>     BLOCK_ABSTRACT_ORIGIN (id->block) = fn;
>     BLOCK_SOURCE_LOCATION (id->block) = input_location;
> !   if (gimple_block (stmt))
> !     prepend_lexical_block (gimple_block (stmt), id->block);
>
>     /* Local declarations will be replaced by their equivalents in this
>        map.  */
> Index: gcc/tree-streamer-in.c
> ===================================================================
> *** gcc/tree-streamer-in.c      (revision 189835)
> --- gcc/tree-streamer-in.c      (working copy)
> *************** lto_input_ts_exp_tree_pointers (struct l
> *** 776,782 ****
>
>     loc = lto_input_location (ib, data_in);
>     SET_EXPR_LOCATION (expr, loc);
> !   TREE_BLOCK (expr) = stream_read_tree (ib, data_in);
>   }
>
>
> --- 776,782 ----
>
>     loc = lto_input_location (ib, data_in);
>     SET_EXPR_LOCATION (expr, loc);
> !   TREE_SET_BLOCK (expr, stream_read_tree (ib, data_in));
>   }
>
>
> Index: gcc/combine.c
> ===================================================================
> *** gcc/combine.c       (revision 189835)
> --- gcc/combine.c       (working copy)
> *************** try_combine (rtx i3, rtx i2, rtx i1, rtx
> *** 2896,2902 ****
>
>           i1 = gen_rtx_INSN (VOIDmode, INSN_UID (i2), NULL_RTX, i2,
>                              BLOCK_FOR_INSN (i2), XVECEXP (PATTERN (i2), 0, 1),
> !                            INSN_LOCATOR (i2), -1, NULL_RTX);
>
>           SUBST (PATTERN (i2), XVECEXP (PATTERN (i2), 0, 0));
>           SUBST (XEXP (SET_SRC (PATTERN (i2)), 0),
> --- 2896,2902 ----
>
>           i1 = gen_rtx_INSN (VOIDmode, INSN_UID (i2), NULL_RTX, i2,
>                              BLOCK_FOR_INSN (i2), XVECEXP (PATTERN (i2), 0, 1),
> !                            INSN_LOCATION (i2), -1, NULL_RTX);
>
>           SUBST (PATTERN (i2), XVECEXP (PATTERN (i2), 0, 0));
>           SUBST (XEXP (SET_SRC (PATTERN (i2)), 0),
> Index: gcc/tree-outof-ssa.c
> ===================================================================
> *** gcc/tree-outof-ssa.c        (revision 189835)
> --- gcc/tree-outof-ssa.c        (working copy)
> *************** set_location_for_edge (edge e)
> *** 108,115 ****
>   {
>     if (e->goto_locus)
>       {
> !       set_curr_insn_source_location (e->goto_locus);
> !       set_curr_insn_block (e->goto_block);
>       }
>     else
>       {
> --- 108,114 ----
>   {
>     if (e->goto_locus)
>       {
> !       set_curr_insn_location (e->goto_locus);
>       }
>     else
>       {
> *************** set_location_for_edge (edge e)
> *** 125,132 ****
>                 continue;
>               if (gimple_has_location (stmt) || gimple_block (stmt))
>                 {
> !                 set_curr_insn_source_location (gimple_location (stmt));
> !                 set_curr_insn_block (gimple_block (stmt));
>                   return;
>                 }
>             }
> --- 124,130 ----
>                 continue;
>               if (gimple_has_location (stmt) || gimple_block (stmt))
>                 {
> !                 set_curr_insn_location (gimple_location (stmt));
>                   return;
>                 }
>             }
> *************** insert_partition_copy_on_edge (edge e, i
> *** 191,197 ****
>     set_location_for_edge (e);
>     /* If a locus is provided, override the default.  */
>     if (locus)
> !     set_curr_insn_source_location (locus);
>
>     var = partition_to_var (SA.map, src);
>     seq = emit_partition_copy (SA.partition_to_pseudo[dest],
> --- 189,195 ----
>     set_location_for_edge (e);
>     /* If a locus is provided, override the default.  */
>     if (locus)
> !     set_curr_insn_location (locus);
>
>     var = partition_to_var (SA.map, src);
>     seq = emit_partition_copy (SA.partition_to_pseudo[dest],
> *************** insert_value_copy_on_edge (edge e, int d
> *** 228,234 ****
>     set_location_for_edge (e);
>     /* If a locus is provided, override the default.  */
>     if (locus)
> !     set_curr_insn_source_location (locus);
>
>     start_sequence ();
>
> --- 226,232 ----
>     set_location_for_edge (e);
>     /* If a locus is provided, override the default.  */
>     if (locus)
> !     set_curr_insn_location (locus);
>
>     start_sequence ();
>
> *************** insert_rtx_to_part_on_edge (edge e, int
> *** 284,290 ****
>     set_location_for_edge (e);
>     /* If a locus is provided, override the default.  */
>     if (locus)
> !     set_curr_insn_source_location (locus);
>
>     /* We give the destination as sizeexp in case src/dest are BLKmode
>        mems.  Usually we give the source.  As we result from SSA names
> --- 282,288 ----
>     set_location_for_edge (e);
>     /* If a locus is provided, override the default.  */
>     if (locus)
> !     set_curr_insn_location (locus);
>
>     /* We give the destination as sizeexp in case src/dest are BLKmode
>        mems.  Usually we give the source.  As we result from SSA names
> *************** insert_part_to_rtx_on_edge (edge e, rtx
> *** 320,326 ****
>     set_location_for_edge (e);
>     /* If a locus is provided, override the default.  */
>     if (locus)
> !     set_curr_insn_source_location (locus);
>
>     var = partition_to_var (SA.map, src);
>     seq = emit_partition_copy (dest,
> --- 318,324 ----
>     set_location_for_edge (e);
>     /* If a locus is provided, override the default.  */
>     if (locus)
> !     set_curr_insn_location (locus);
>
>     var = partition_to_var (SA.map, src);
>     seq = emit_partition_copy (dest,
> Index: gcc/basic-block.h
> ===================================================================
> *** gcc/basic-block.h   (revision 189835)
> --- gcc/basic-block.h   (working copy)
> *************** struct GTY(()) edge_def {
> *** 47,54 ****
>     /* Auxiliary info specific to a pass.  */
>     PTR GTY ((skip (""))) aux;
>
> !   /* Location of any goto implicit in the edge and associated BLOCK.  */
> !   tree goto_block;
>     location_t goto_locus;
>
>     /* The index number corresponding to this edge in the edge vector
> --- 47,53 ----
>     /* Auxiliary info specific to a pass.  */
>     PTR GTY ((skip (""))) aux;
>
> !   /* Location of any goto implicit in the edge.  */
>     location_t goto_locus;
>
>     /* The index number corresponding to this edge in the edge vector
> Index: gcc/gimple.h
> ===================================================================
> *** gcc/gimple.h        (revision 189835)
> --- gcc/gimple.h        (working copy)
> *************** struct GTY(()) gimple_statement_base {
> *** 210,219 ****
>        and the prev pointer being the last.  */
>     gimple next;
>     gimple GTY((skip)) prev;
> -
> -   /* [ WORD 6 ]
> -      Lexical block holding this statement.  */
> -   tree block;
>   };
>
>
> --- 210,215 ----
> *************** gimple_bb (const_gimple g)
> *** 1198,1204 ****
>   static inline tree
>   gimple_block (const_gimple g)
>   {
> !   return g->gsbase.block;
>   }
>
>
> --- 1194,1200 ----
>   static inline tree
>   gimple_block (const_gimple g)
>   {
> !   return LOCATION_BLOCK (g->gsbase.location);
>   }
>
>
> *************** gimple_block (const_gimple g)
> *** 1207,1213 ****
>   static inline void
>   gimple_set_block (gimple g, tree block)
>   {
> !   g->gsbase.block = block;
>   }
>
>
> --- 1203,1209 ----
>   static inline void
>   gimple_set_block (gimple g, tree block)
>   {
> !   g->gsbase.location = COMBINE_LOCATION (g->gsbase.location, block);
>   }
>
>
> *************** gimple_set_location (gimple g, location_
> *** 1242,1248 ****
>   static inline bool
>   gimple_has_location (const_gimple g)
>   {
> !   return gimple_location (g) != UNKNOWN_LOCATION;
>   }
>
>
> --- 1238,1244 ----
>   static inline bool
>   gimple_has_location (const_gimple g)
>   {
> !   return !IS_UNKNOWN_LOCATION (gimple_location (g));
>   }
>
>
> Index: gcc/tree-cfg.c
> ===================================================================
> *** gcc/tree-cfg.c      (revision 189835)
> --- gcc/tree-cfg.c      (working copy)
> *************** make_cond_expr_edges (basic_block bb)
> *** 808,822 ****
>     e = make_edge (bb, then_bb, EDGE_TRUE_VALUE);
>     assign_discriminator (entry_locus, then_bb);
>     e->goto_locus = gimple_location (then_stmt);
> -   if (e->goto_locus)
> -     e->goto_block = gimple_block (then_stmt);
>     e = make_edge (bb, else_bb, EDGE_FALSE_VALUE);
>     if (e)
>       {
>         assign_discriminator (entry_locus, else_bb);
>         e->goto_locus = gimple_location (else_stmt);
> -       if (e->goto_locus)
> -       e->goto_block = gimple_block (else_stmt);
>       }
>
>     /* We do not need the labels anymore.  */
> --- 808,818 ----
> *************** make_goto_expr_edges (basic_block bb)
> *** 1026,1033 ****
>         edge e = make_edge (bb, label_bb, EDGE_FALLTHRU);
>         e->goto_locus = gimple_location (goto_t);
>         assign_discriminator (e->goto_locus, label_bb);
> -       if (e->goto_locus)
> -       e->goto_block = gimple_block (goto_t);
>         gsi_remove (&last, true);
>         return;
>       }
> --- 1022,1027 ----
> *************** gimple_can_merge_blocks_p (basic_block a
> *** 1501,1507 ****
>
>     /* When not optimizing, don't merge if we'd lose goto_locus.  */
>     if (!optimize
> !       && single_succ_edge (a)->goto_locus != UNKNOWN_LOCATION)
>       {
>         location_t goto_locus = single_succ_edge (a)->goto_locus;
>         gimple_stmt_iterator prev, next;
> --- 1495,1501 ----
>
>     /* When not optimizing, don't merge if we'd lose goto_locus.  */
>     if (!optimize
> !       && single_succ_edge (a)->goto_locus)
>       {
>         location_t goto_locus = single_succ_edge (a)->goto_locus;
>         gimple_stmt_iterator prev, next;
> *************** move_stmt_op (tree *tp, int *walk_subtre
> *** 5987,5995 ****
>     tree t = *tp;
>
>     if (EXPR_P (t))
> !     /* We should never have TREE_BLOCK set on non-statements.  */
> !     gcc_assert (!TREE_BLOCK (t));
> !
>     else if (DECL_P (t) || TREE_CODE (t) == SSA_NAME)
>       {
>         if (TREE_CODE (t) == SSA_NAME)
> --- 5981,5987 ----
>     tree t = *tp;
>
>     if (EXPR_P (t))
> !     ;
>     else if (DECL_P (t) || TREE_CODE (t) == SSA_NAME)
>       {
>         if (TREE_CODE (t) == SSA_NAME)
> *************** move_block_to_fn (struct function *dest_
> *** 6294,6305 ****
>       }
>
>     FOR_EACH_EDGE (e, ei, bb->succs)
> !     if (e->goto_locus)
>         {
> !       tree block = e->goto_block;
>         if (d->orig_block == NULL_TREE
>             || block == d->orig_block)
> !         e->goto_block = d->new_block;
>   #ifdef ENABLE_CHECKING
>         else if (block != d->new_block)
>           {
> --- 6286,6297 ----
>       }
>
>     FOR_EACH_EDGE (e, ei, bb->succs)
> !     if (!IS_UNKNOWN_LOCATION (e->goto_locus))
>         {
> !       tree block = LOCATION_BLOCK (e->goto_locus);
>         if (d->orig_block == NULL_TREE
>             || block == d->orig_block)
> !         e->goto_locus = COMBINE_LOCATION (e->goto_locus, d->new_block);
>   #ifdef ENABLE_CHECKING
>         else if (block != d->new_block)
>           {
> Index: gcc/config/alpha/alpha.c
> ===================================================================
> *** gcc/config/alpha/alpha.c    (revision 189835)
> --- gcc/config/alpha/alpha.c    (working copy)
> *************** alpha_output_mi_thunk_osf (FILE *file, t
> *** 8352,8358 ****
>        instruction scheduling worth while.  Note that use_thunk calls
>        assemble_start_function and assemble_end_function.  */
>     insn = get_insns ();
> -   insn_locators_alloc ();
>     shorten_branches (insn);
>     final_start_function (insn, file, 1);
>     final (insn, file, 1);
> --- 8352,8357 ----
> Index: gcc/config/sparc/sparc.c
> ===================================================================
> *** gcc/config/sparc/sparc.c    (revision 189835)
> --- gcc/config/sparc/sparc.c    (working copy)
> *************** sparc_output_mi_thunk (FILE *file, tree
> *** 10654,10660 ****
>        instruction scheduling worth while.  Note that use_thunk calls
>        assemble_start_function and assemble_end_function.  */
>     insn = get_insns ();
> -   insn_locators_alloc ();
>     shorten_branches (insn);
>     final_start_function (insn, file, 1);
>     final (insn, file, 1);
> --- 10654,10659 ----
> Index: gcc/config/i386/i386.c
> ===================================================================
> *** gcc/config/i386/i386.c      (revision 189835)
> --- gcc/config/i386/i386.c      (working copy)
> *************** x86_output_mi_thunk (FILE *file,
> *** 33063,33069 ****
>     /* Emit just enough of rest_of_compilation to get the insns emitted.
>        Note that use_thunk calls assemble_start_function et al.  */
>     tmp = get_insns ();
> -   insn_locators_alloc ();
>     shorten_branches (tmp);
>     final_start_function (tmp, file, 1);
>     final (tmp, file, 1);
> --- 33063,33068 ----
> Index: gcc/config/tilegx/tilegx.c
> ===================================================================
> *** gcc/config/tilegx/tilegx.c  (revision 189835)
> --- gcc/config/tilegx/tilegx.c  (working copy)
> *************** tilegx_output_mi_thunk (FILE *file, tree
> *** 4804,4810 ****
>        serial except for the tail call, so we're only wasting one cycle.
>      */
>     insn = get_insns ();
> -   insn_locators_alloc ();
>     shorten_branches (insn);
>     final_start_function (insn, file, 1);
>     final (insn, file, 1);
> --- 4804,4809 ----
> Index: gcc/config/sh/sh.c
> ===================================================================
> *** gcc/config/sh/sh.c  (revision 189835)
> --- gcc/config/sh/sh.c  (working copy)
> *************** sh_output_mi_thunk (FILE *file, tree thu
> *** 11979,11985 ****
>        the insns emitted.  Note that use_thunk calls
>        assemble_start_function and assemble_end_function.  */
>
> -   insn_locators_alloc ();
>     insns = get_insns ();
>
>     if (optimize > 0)
> --- 11979,11984 ----
> Index: gcc/config/ia64/ia64.c
> ===================================================================
> *** gcc/config/ia64/ia64.c      (revision 189835)
> --- gcc/config/ia64/ia64.c      (working copy)
> *************** ia64_output_mi_thunk (FILE *file, tree t
> *** 10848,10854 ****
>        instruction scheduling worth while.  Note that use_thunk calls
>        assemble_start_function and assemble_end_function.  */
>
> -   insn_locators_alloc ();
>     emit_all_insn_group_barriers (NULL);
>     insn = get_insns ();
>     shorten_branches (insn);
> --- 10848,10853 ----
> Index: gcc/config/rs6000/rs6000.c
> ===================================================================
> *** gcc/config/rs6000/rs6000.c  (revision 189835)
> --- gcc/config/rs6000/rs6000.c  (working copy)
> *************** rs6000_output_mi_thunk (FILE *file, tree
> *** 21664,21670 ****
>        instruction scheduling worth while.  Note that use_thunk calls
>        assemble_start_function and assemble_end_function.  */
>     insn = get_insns ();
> -   insn_locators_alloc ();
>     shorten_branches (insn);
>     final_start_function (insn, file, 1);
>     final (insn, file, 1);
> --- 21664,21669 ----
> Index: gcc/config/score/score.c
> ===================================================================
> *** gcc/config/score/score.c    (revision 189835)
> --- gcc/config/score/score.c    (working copy)
> *************** score_output_mi_thunk (FILE *file, tree
> *** 505,511 ****
>     /* Run just enough of rest_of_compilation.  This sequence was
>        "borrowed" from alpha.c.  */
>     insn = get_insns ();
> -   insn_locators_alloc ();
>     split_all_insns_noflow ();
>     shorten_branches (insn);
>     final_start_function (insn, file, 1);
> --- 505,510 ----
> Index: gcc/config/tilepro/tilepro.c
> ===================================================================
> *** gcc/config/tilepro/tilepro.c        (revision 189835)
> --- gcc/config/tilepro/tilepro.c        (working copy)
> *************** tilepro_asm_output_mi_thunk (FILE *file,
> *** 4407,4413 ****
>        serial except for the tail call, so we're only wasting one cycle.
>      */
>     insn = get_insns ();
> -   insn_locators_alloc ();
>     shorten_branches (insn);
>     final_start_function (insn, file, 1);
>     final (insn, file, 1);
> --- 4407,4412 ----
> Index: gcc/config/mips/mips.c
> ===================================================================
> *** gcc/config/mips/mips.c      (revision 189835)
> --- gcc/config/mips/mips.c      (working copy)
> *************** mips_output_mi_thunk (FILE *file, tree t
> *** 15637,15643 ****
>     /* Run just enough of rest_of_compilation.  This sequence was
>        "borrowed" from alpha.c.  */
>     insn = get_insns ();
> -   insn_locators_alloc ();
>     split_all_insns_noflow ();
>     mips16_lay_out_constants ();
>     shorten_branches (insn);
> --- 15637,15642 ----
> Index: gcc/cfgrtl.c
> ===================================================================
> *** gcc/cfgrtl.c        (revision 189835)
> --- gcc/cfgrtl.c        (working copy)
> *************** rtl_split_block (basic_block bb, void *i
> *** 720,738 ****
>   static bool
>   unique_locus_on_edge_between_p (basic_block a, basic_block b)
>   {
> !   const int goto_locus = EDGE_SUCC (a, 0)->goto_locus;
>     rtx insn, end;
>
> !   if (!goto_locus)
>       return false;
>
>     /* First scan block A backward.  */
>     insn = BB_END (a);
>     end = PREV_INSN (BB_HEAD (a));
> !   while (insn != end && (!NONDEBUG_INSN_P (insn) || INSN_LOCATOR (insn) == 0))
>       insn = PREV_INSN (insn);
>
> !   if (insn != end && locator_eq (INSN_LOCATOR (insn), goto_locus))
>       return false;
>
>     /* Then scan block B forward.  */
> --- 720,738 ----
>   static bool
>   unique_locus_on_edge_between_p (basic_block a, basic_block b)
>   {
> !   const location_t goto_locus = EDGE_SUCC (a, 0)->goto_locus;
>     rtx insn, end;
>
> !   if (IS_UNKNOWN_LOCATION (goto_locus))
>       return false;
>
>     /* First scan block A backward.  */
>     insn = BB_END (a);
>     end = PREV_INSN (BB_HEAD (a));
> !   while (insn != end && (!NONDEBUG_INSN_P (insn) ||
> !INSN_HAS_LOCATION (insn)))
>       insn = PREV_INSN (insn);
>
> !   if (insn != end && INSN_LOCATION (insn) == goto_locus)
>       return false;
>
>     /* Then scan block B forward.  */
> *************** unique_locus_on_edge_between_p (basic_bl
> *** 743,750 ****
>         while (insn != end && !NONDEBUG_INSN_P (insn))
>         insn = NEXT_INSN (insn);
>
> !       if (insn != end && INSN_LOCATOR (insn) != 0
> !         && locator_eq (INSN_LOCATOR (insn), goto_locus))
>         return false;
>       }
>
> --- 743,750 ----
>         while (insn != end && !NONDEBUG_INSN_P (insn))
>         insn = NEXT_INSN (insn);
>
> !       if (insn != end && INSN_HAS_LOCATION (insn)
> !         && INSN_LOCATION (insn) == goto_locus)
>         return false;
>       }
>
> *************** emit_nop_for_unique_locus_between (basic
> *** 761,767 ****
>       return;
>
>     BB_END (a) = emit_insn_after_noloc (gen_nop (), BB_END (a), a);
> !   INSN_LOCATOR (BB_END (a)) = EDGE_SUCC (a, 0)->goto_locus;
>   }
>
>   /* Blocks A and B are to be merged into a single block A.  The insns
> --- 761,767 ----
>       return;
>
>     BB_END (a) = emit_insn_after_noloc (gen_nop (), BB_END (a), a);
> !   INSN_LOCATION (BB_END (a)) = EDGE_SUCC (a, 0)->goto_locus;
>   }
>
>   /* Blocks A and B are to be merged into a single block A.  The insns
> *************** force_nonfallthru_and_redirect (edge e,
> *** 1478,1484 ****
>     else
>       jump_block = e->src;
>
> !   if (e->goto_locus && e->goto_block == NULL)
>       loc = e->goto_locus;
>     else
>       loc = 0;
> --- 1478,1484 ----
>     else
>       jump_block = e->src;
>
> !   if (!IS_UNKNOWN_LOCATION (e->goto_locus))
>       loc = e->goto_locus;
>     else
>       loc = 0;
> *************** fixup_reorder_chain (void)
> *** 3337,3343 ****
>           edge_iterator ei;
>
>           FOR_EACH_EDGE (e, ei, bb->succs)
> !         if (e->goto_locus && !(e->flags & EDGE_ABNORMAL))
>             {
>               edge e2;
>               edge_iterator ei2;
> --- 3337,3344 ----
>           edge_iterator ei;
>
>           FOR_EACH_EDGE (e, ei, bb->succs)
> !         if (!IS_UNKNOWN_LOCATION (e->goto_locus)
> !             && !(e->flags & EDGE_ABNORMAL))
>             {
>               edge e2;
>               edge_iterator ei2;
> *************** fixup_reorder_chain (void)
> *** 3347,3361 ****
>               insn = BB_END (e->src);
>               end = PREV_INSN (BB_HEAD (e->src));
>               while (insn != end
> !                    && (!NONDEBUG_INSN_P (insn) || INSN_LOCATOR (insn) == 0))
>                 insn = PREV_INSN (insn);
>               if (insn != end
> !                 && locator_eq (INSN_LOCATOR (insn), (int) e->goto_locus))
>                 continue;
>               if (simplejump_p (BB_END (e->src))
> !                 && INSN_LOCATOR (BB_END (e->src)) == 0)
>                 {
> !                 INSN_LOCATOR (BB_END (e->src)) = e->goto_locus;
>                   continue;
>                 }
>               dest = e->dest;
> --- 3348,3362 ----
>               insn = BB_END (e->src);
>               end = PREV_INSN (BB_HEAD (e->src));
>               while (insn != end
> !                    && (!NONDEBUG_INSN_P (insn) || !INSN_HAS_LOCATION (insn)))
>                 insn = PREV_INSN (insn);
>               if (insn != end
> !                 && INSN_LOCATION (insn) == e->goto_locus)
>                 continue;
>               if (simplejump_p (BB_END (e->src))
> !                 && !INSN_HAS_LOCATION (BB_END (e->src)))
>                 {
> !                 INSN_LOCATION (BB_END (e->src)) = e->goto_locus;
>                   continue;
>                 }
>               dest = e->dest;
> *************** fixup_reorder_chain (void)
> *** 3371,3394 ****
>                   end = NEXT_INSN (BB_END (dest));
>                   while (insn != end && !NONDEBUG_INSN_P (insn))
>                     insn = NEXT_INSN (insn);
> !                 if (insn != end && INSN_LOCATOR (insn)
> !                     && locator_eq (INSN_LOCATOR (insn), (int) e->goto_locus))
>                     continue;
>                 }
>               nb = split_edge (e);
>               if (!INSN_P (BB_END (nb)))
>                 BB_END (nb) = emit_insn_after_noloc (gen_nop (), BB_END (nb),
>                                                      nb);
> !             INSN_LOCATOR (BB_END (nb)) = e->goto_locus;
>
>               /* If there are other incoming edges to the destination block
>                  with the same goto locus, redirect them to the new block as
>                  well, this can prevent other such blocks from being created
>                  in subsequent iterations of the loop.  */
>               for (ei2 = ei_start (dest->preds); (e2 = ei_safe_edge (ei2)); )
> !               if (e2->goto_locus
>                     && !(e2->flags & (EDGE_ABNORMAL | EDGE_FALLTHRU))
> !                   && locator_eq (e->goto_locus, e2->goto_locus))
>                   redirect_edge_and_branch (e2, nb);
>                 else
>                   ei_next (&ei2);
> --- 3372,3395 ----
>                   end = NEXT_INSN (BB_END (dest));
>                   while (insn != end && !NONDEBUG_INSN_P (insn))
>                     insn = NEXT_INSN (insn);
> !                 if (insn != end && INSN_HAS_LOCATION (insn)
> !                     && INSN_LOCATION (insn) == e->goto_locus)
>                     continue;
>                 }
>               nb = split_edge (e);
>               if (!INSN_P (BB_END (nb)))
>                 BB_END (nb) = emit_insn_after_noloc (gen_nop (), BB_END (nb),
>                                                      nb);
> !             INSN_LOCATION (BB_END (nb)) = e->goto_locus;
>
>               /* If there are other incoming edges to the destination block
>                  with the same goto locus, redirect them to the new block as
>                  well, this can prevent other such blocks from being created
>                  in subsequent iterations of the loop.  */
>               for (ei2 = ei_start (dest->preds); (e2 = ei_safe_edge (ei2)); )
> !               if (!IS_UNKNOWN_LOCATION (e2->goto_locus)
>                     && !(e2->flags & (EDGE_ABNORMAL | EDGE_FALLTHRU))
> !                   && e->goto_locus == e2->goto_locus)
>                   redirect_edge_and_branch (e2, nb);
>                 else
>                   ei_next (&ei2);
> *************** cfg_layout_merge_blocks (basic_block a,
> *** 4088,4094 ****
>       }
>
>     /* If B was a forwarder block, propagate the locus on the edge.  */
> !   if (forwarder_p && !EDGE_SUCC (b, 0)->goto_locus)
>       EDGE_SUCC (b, 0)->goto_locus = EDGE_SUCC (a, 0)->goto_locus;
>
>     if (dump_file)
> --- 4089,4095 ----
>       }
>
>     /* If B was a forwarder block, propagate the locus on the edge.  */
> !   if (forwarder_p && IS_UNKNOWN_LOCATION (EDGE_SUCC (b, 0)->goto_locus))
>       EDGE_SUCC (b, 0)->goto_locus = EDGE_SUCC (a, 0)->goto_locus;
>
>     if (dump_file)
> Index: gcc/stmt.c
> ===================================================================
> *** gcc/stmt.c  (revision 189835)
> --- gcc/stmt.c  (working copy)
> *************** emit_case_nodes (rtx index, case_node_pt
> *** 2397,2403 ****
>                  then emit the code for one side at a time.  */
>
>               tree test_label
> !               = build_decl (CURR_INSN_LOCATION,
>                               LABEL_DECL, NULL_TREE, NULL_TREE);
>
>               /* See if the value is on the right.  */
> --- 2397,2403 ----
>                  then emit the code for one side at a time.  */
>
>               tree test_label
> !               = build_decl (curr_insn_location (),
>                               LABEL_DECL, NULL_TREE, NULL_TREE);
>
>               /* See if the value is on the right.  */
> *************** emit_case_nodes (rtx index, case_node_pt
> *** 2521,2527 ****
>               /* Right hand node requires testing.
>                  Branch to a label where we will handle it later.  */
>
> !             test_label = build_decl (CURR_INSN_LOCATION,
>                                        LABEL_DECL, NULL_TREE, NULL_TREE);
>               emit_cmp_and_jump_insns (index,
>                                        convert_modes
> --- 2521,2527 ----
>               /* Right hand node requires testing.
>                  Branch to a label where we will handle it later.  */
>
> !             test_label = build_decl (curr_insn_location (),
>                                        LABEL_DECL, NULL_TREE, NULL_TREE);
>               emit_cmp_and_jump_insns (index,
>                                        convert_modes
> Index: libcpp/include/line-map.h
> ===================================================================
> *** libcpp/include/line-map.h   (revision 189835)
> --- libcpp/include/line-map.h   (working copy)
> *************** struct GTY(()) line_map_ordinary {
> *** 89,95 ****
>
>   /* This is the highest possible source location encoded within an
>      ordinary or macro map.  */
> ! #define MAX_SOURCE_LOCATION 0xFFFFFFFF
>
>   struct cpp_hashnode;
>
> --- 89,95 ----
>
>   /* This is the highest possible source location encoded within an
>      ordinary or macro map.  */
> ! #define MAX_SOURCE_LOCATION 0x7FFFFFFF
>
>   struct cpp_hashnode;
>
> *************** struct GTY(()) line_maps {
> *** 408,413 ****
> --- 408,423 ----
>   #define LINEMAPS_LAST_ALLOCATED_MACRO_MAP(SET) \
>     LINEMAPS_LAST_ALLOCATED_MAP (SET, true)
>
> + extern void location_block_init (void);
> + extern void location_block_fini (void);
> + extern source_location get_combine_location (source_location, void *);
> + extern void *get_block_from_location (source_location);
> + extern source_location get_locus_from_location (source_location);
> +
> + #define COMBINE_LOCATION(LOC, BLOCK) \
> +   ((BLOCK) ? get_combine_location ((LOC), (BLOCK)) : (LOC))
> + #define IS_COMBINED_LOCATION(LOC) (((LOC) & MAX_SOURCE_LOCATION) != (LOC))
> +
>   /* Initialize a line map set.  */
>   extern void linemap_init (struct line_maps *);
>
> *************** typedef struct
> *** 594,599 ****
> --- 604,611 ----
>
>     int column;
>
> +   void *block;
> +
>     /* In a system header?. */
>     bool sysp;
>   } expanded_location;
> Index: libcpp/line-map.c
> ===================================================================
> *** libcpp/line-map.c   (revision 189835)
> --- libcpp/line-map.c   (working copy)
> *************** along with this program; see the file CO
> *** 25,30 ****
> --- 25,31 ----
>   #include "line-map.h"
>   #include "cpplib.h"
>   #include "internal.h"
> + #include "hashtab.h"
>
>   static void trace_include (const struct line_maps *, const struct line_map *);
>   static const struct line_map * linemap_ordinary_map_lookup (struct
> line_maps *,
> *************** static source_location linemap_macro_loc
> *** 50,55 ****
> --- 51,171 ----
>   extern unsigned num_expanded_macros_counter;
>   extern unsigned num_macro_tokens_counter;
>
> + struct location_block {
> +   source_location locus;
> +   void *block;
> + };
> +
> + static htab_t location_block_htab;
> + static source_location curr_combined_location;
> + static struct location_block *location_blocks;
> + static unsigned int allocated_location_blocks;
> +
> + /* Hash function for location_block hashtable.  */
> +
> + static hashval_t
> + location_block_hash (const void *l)
> + {
> +   const struct location_block *lb = (const struct location_block *) l;
> +   return (hashval_t) lb->locus + (size_t) &lb->block;
> + }
> +
> + /* Compare function for location_block hashtable.  */
> +
> + static int
> + location_block_eq (const void *l1, const void *l2)
> + {
> +   const struct location_block *lb1 = (const struct location_block *) l1;
> +   const struct location_block *lb2 = (const struct location_block *) l2;
> +   return lb1->locus == lb2->locus && lb1->block == lb2->block;
> + }
> +
> + /* Update the hashtable when location_blocks is reallocated.  */
> +
> + static int
> + location_block_update (void **slot, void *data)
> + {
> +   *((char **) slot) += ((char *) location_blocks - (char *) data);
> +   return 1;
> + }
> +
> + /* Combine LOCUS and BLOCK to a combined location.  */
> +
> + source_location
> + get_combine_location (source_location locus, void *block)
> + {
> +   struct location_block lb;
> +   struct location_block **slot;
> +
> +   linemap_assert (block);
> +
> +   if (IS_COMBINED_LOCATION (locus))
> +     locus = location_blocks[locus & MAX_SOURCE_LOCATION].locus;
> +   if (locus == 0 && block == NULL)
> +     return 0;
> +   lb.locus = locus;
> +   lb.block = block;
> +   slot = (struct location_block **)
> +       htab_find_slot (location_block_htab, &lb, INSERT);
> +   if (*slot == NULL)
> +     {
> +       *slot = location_blocks + curr_combined_location;
> +       location_blocks[curr_combined_location] = lb;
> +       if (++curr_combined_location >= allocated_location_blocks)
> +       {
> +         char *orig_location_blocks = (char *) location_blocks;
> +         allocated_location_blocks *= 2;
> +         location_blocks = XRESIZEVEC (struct location_block,
> +                                       location_blocks,
> +                                       allocated_location_blocks);
> +         htab_traverse (location_block_htab, location_block_update,
> +                        orig_location_blocks);
> +       }
> +     }
> +   return ((*slot) - location_blocks) | 0x80000000;
> + }
> +
> + /* Return the block for LOCATION.  */
> +
> + void *
> + get_block_from_location (source_location location)
> + {
> +   linemap_assert (IS_COMBINED_LOCATION (location));
> +   return location_blocks[location & MAX_SOURCE_LOCATION].block;
> + }
> +
> + /* Return the locus for LOCATION.  */
> +
> + source_location
> + get_locus_from_location (source_location location)
> + {
> +   linemap_assert (IS_COMBINED_LOCATION (location));
> +   return location_blocks[location & MAX_SOURCE_LOCATION].locus;
> + }
> +
> + /* Initialize the location_block structure.  */
> +
> + void
> + location_block_init (void)
> + {
> +   location_block_htab = htab_create (100, location_block_hash,
> +                                    location_block_eq, NULL);
> +   curr_combined_location = 0;
> +   allocated_location_blocks = 100;
> +   location_blocks = XNEWVEC (struct location_block,
> +                            allocated_location_blocks);
> + }
> +
> + /* Finalize the location_block structure.  */
> +
> + void
> + location_block_fini (void)
> + {
> +   allocated_location_blocks = 0;
> +   XDELETEVEC (location_blocks);
> +   htab_delete (location_block_htab);
> + }
> +
>   /* Initialize a line map set.  */
>
>   void
> *************** linemap_position_for_line_and_column (st
> *** 509,514 ****
> --- 625,632 ----
>   const struct line_map*
>   linemap_lookup (struct line_maps *set, source_location line)
>   {
> +   if (IS_COMBINED_LOCATION (line))
> +     line = location_blocks[line & MAX_SOURCE_LOCATION].locus;
>     if (linemap_location_from_macro_expansion_p (set, line))
>       return linemap_macro_map_lookup (set, line);
>     return linemap_ordinary_map_lookup (set, line);
> *************** linemap_ordinary_map_lookup (struct line
> *** 525,530 ****
> --- 643,651 ----
>     unsigned int md, mn, mx;
>     const struct line_map *cached, *result;
>
> +   if (IS_COMBINED_LOCATION (line))
> +     line = location_blocks[line & MAX_SOURCE_LOCATION].locus;
> +
>     if (set ==  NULL || line < RESERVED_LOCATION_COUNT)
>       return NULL;
>
> *************** linemap_macro_map_lookup (struct line_ma
> *** 570,575 ****
> --- 691,699 ----
>     unsigned int md, mn, mx;
>     const struct line_map *cached, *result;
>
> +   if (IS_COMBINED_LOCATION (line))
> +     line = location_blocks[line & MAX_SOURCE_LOCATION].locus;
> +
>     linemap_assert (line >= LINEMAPS_MACRO_LOWEST_LOCATION (set));
>
>     if (set ==  NULL)
> *************** linemap_macro_map_loc_to_def_point (cons
> *** 648,653 ****
> --- 772,780 ----
>   {
>     unsigned token_no;
>
> +   if (IS_COMBINED_LOCATION (location))
> +     location = location_blocks[location & MAX_SOURCE_LOCATION].locus;
> +
>     linemap_assert (linemap_macro_expansion_map_p (map)
>                   && location >= MAP_START_LOCATION (map));
>     linemap_assert (location >= RESERVED_LOCATION_COUNT);
> *************** linemap_macro_map_loc_unwind_toward_spel
> *** 672,677 ****
> --- 799,807 ----
>   {
>     unsigned token_no;
>
> +   if (IS_COMBINED_LOCATION (location))
> +     location = location_blocks[location & MAX_SOURCE_LOCATION].locus;
> +
>     linemap_assert (linemap_macro_expansion_map_p (map)
>                   && location >= MAP_START_LOCATION (map));
>     linemap_assert (location >= RESERVED_LOCATION_COUNT);
> *************** linemap_get_expansion_line (struct line_
> *** 696,701 ****
> --- 826,834 ----
>   {
>     const struct line_map *map = NULL;
>
> +   if (IS_COMBINED_LOCATION (location))
> +     location = location_blocks[location & MAX_SOURCE_LOCATION].locus;
> +
>     if (location < RESERVED_LOCATION_COUNT)
>       return 0;
>
> *************** linemap_get_expansion_filename (struct l
> *** 720,725 ****
> --- 853,861 ----
>   {
>     const struct line_map *map = NULL;
>
> +   if (IS_COMBINED_LOCATION (location))
> +     location = location_blocks[location & MAX_SOURCE_LOCATION].locus;
> +
>     if (location < RESERVED_LOCATION_COUNT)
>       return NULL;
>
> *************** linemap_location_in_system_header_p (str
> *** 754,759 ****
> --- 890,898 ----
>   {
>     const struct line_map *map = NULL;
>
> +   if (IS_COMBINED_LOCATION (location))
> +     location = location_blocks[location & MAX_SOURCE_LOCATION].locus;
> +
>     if (location < RESERVED_LOCATION_COUNT)
>       return false;
>
> *************** bool
> *** 793,798 ****
> --- 932,940 ----
>   linemap_location_from_macro_expansion_p (struct line_maps *set,
>                                          source_location location)
>   {
> +   if (IS_COMBINED_LOCATION (location))
> +     location = location_blocks[location & MAX_SOURCE_LOCATION].locus;
> +
>     linemap_assert (location <= MAX_SOURCE_LOCATION
>                   && (set->highest_location
>                       < LINEMAPS_MACRO_LOWEST_LOCATION (set)));
> *************** linemap_macro_loc_to_spelling_point (str
> *** 933,938 ****
> --- 1075,1083 ----
>   {
>     struct line_map *map;
>
> +   if (IS_COMBINED_LOCATION (location))
> +     location = location_blocks[location & MAX_SOURCE_LOCATION].locus;
> +
>     linemap_assert (set && location >= RESERVED_LOCATION_COUNT);
>
>     while (true)
> *************** linemap_macro_loc_to_def_point (struct l
> *** 967,972 ****
> --- 1112,1120 ----
>   {
>     struct line_map *map;
>
> +   if (IS_COMBINED_LOCATION (location))
> +     location = location_blocks[location & MAX_SOURCE_LOCATION].locus;
> +
>     linemap_assert (set && location >= RESERVED_LOCATION_COUNT);
>
>     while (true)
> *************** linemap_macro_loc_to_exp_point (struct l
> *** 1005,1010 ****
> --- 1153,1161 ----
>   {
>     struct line_map *map;
>
> +   if (IS_COMBINED_LOCATION (location))
> +     location = location_blocks[location & MAX_SOURCE_LOCATION].locus;
> +
>     linemap_assert (set && location >= RESERVED_LOCATION_COUNT);
>
>     while (true)
> *************** linemap_resolve_location (struct line_ma
> *** 1074,1079 ****
> --- 1225,1233 ----
>                           enum location_resolution_kind lrk,
>                           const struct line_map **map)
>   {
> +   if (IS_COMBINED_LOCATION (loc))
> +     loc = location_blocks[loc & MAX_SOURCE_LOCATION].locus;
> +
>     if (loc < RESERVED_LOCATION_COUNT)
>       {
>         /* A reserved location wasn't encoded in a map.  Let's return a
> *************** linemap_unwind_toward_expansion (struct
> *** 1121,1126 ****
> --- 1275,1283 ----
>     source_location resolved_location;
>     const struct line_map *resolved_map;
>
> +   if (IS_COMBINED_LOCATION (loc))
> +     loc = location_blocks[loc & MAX_SOURCE_LOCATION].locus;
> +
>     resolved_location =
>       linemap_macro_map_loc_unwind_toward_spelling (*map, loc);
>     resolved_map = linemap_lookup (set, resolved_location);
> *************** linemap_unwind_to_first_non_reserved_loc
> *** 1157,1162 ****
> --- 1314,1322 ----
>     source_location resolved_loc;
>     const struct line_map *map0 = NULL, *map1 = NULL;
>
> +   if (IS_COMBINED_LOCATION (loc))
> +     loc = location_blocks[loc & MAX_SOURCE_LOCATION].locus;
> +
>     map0 = linemap_lookup (set, loc);
>     if (!linemap_macro_expansion_map_p (map0))
>       return loc;
> *************** linemap_expand_location (struct line_map
> *** 1198,1203 ****
> --- 1358,1368 ----
>     expanded_location xloc;
>
>     memset (&xloc, 0, sizeof (xloc));
> +   if (IS_COMBINED_LOCATION (loc))
> +     {
> +       loc = location_blocks[loc & MAX_SOURCE_LOCATION].locus;
> +       xloc.block = location_blocks[loc & MAX_SOURCE_LOCATION].block;
> +     }
>
>     if (loc < RESERVED_LOCATION_COUNT)
>       /* The location for this token wasn't generated from a line map.
> *************** linemap_dump_location (struct line_maps
> *** 1290,1295 ****
> --- 1455,1463 ----
>     const char *path = "", *from = "";
>     int l = -1, c = -1, s = -1, e = -1;
>
> +   if (IS_COMBINED_LOCATION (loc))
> +     loc = location_blocks[loc & MAX_SOURCE_LOCATION].locus;
> +
>     if (loc == 0)
>       return;
Dehao Chen Aug. 7, 2012, 3:51 p.m. UTC | #3
Reattaching the ChangeLog with the patch.

Bootstrapped and passed regression tests on x86_64

gcc/ChangeLog:

2012-08-01  Dehao Chen  <dehao@google.com>

	* toplev.c (general_init): Init block_locations.
	* tree.c (tree_set_block): New.
	(tree_block): Change to use LOCATION_BLOCK.
	* tree.h (TREE_SET_BLOCK): New.
	* final.c (reemit_insn_block_notes): Change to use LOCATION_BLOCK.
	(final_start_function): Likewise.
	* input.c (expand_location_1): Likewise.
	* input.h (LOCATION_LOCUS): New.
	(LOCATION_BLOCK): New.
	(IS_UNKNOWN_LOCATION): New.
	* fold-const.c (expr_location_or): Change to use new location.
	* reorg.c (emit_delay_sequence): Likewise.
	(try_merge_delay_insns): Likewise.
	* modulo-sched.c (dump_insn_location): Likewise.
	* lto-streamer-out.c (lto_output_location_bitpack): Likewise.
	* jump.c (rtx_renumbered_equal_p): Likewise.
	* ifcvt.c (noce_try_move): Likewise.
	(noce_try_store_flag): Likewise.
	(noce_try_store_flag_constants): Likewise.
	(noce_try_addcc): Likewise.
	(noce_try_store_flag_mask): Likewise.
	(noce_try_cmove): Likewise.
	(noce_try_cmove_arith): Likewise.
	(noce_try_minmax): Likewise.
	(noce_try_abs): Likewise.
	(noce_try_sign_mask): Likewise.
	(noce_try_bitop): Likewise.
	(noce_process_if_block): Likewise.
	(cond_move_process_if_block): Likewise.
	(find_cond_trap): Likewise.
	* dewarf2out.c (add_src_coords_attributes): Likewise.
	* expr.c (expand_expr_real): Likewise.
	* tree-parloops.c (create_loop_fn): Likewise.
	* recog.c (peep2_attempt): Likewise.
	* function.c (free_after_compilation): Likewise.
	(expand_function_end): Likewise.
	(set_insn_locations): Likewise.
	(thread_prologue_and_epilogue_insns): Likewise.
	* print-rtl.c (print_rtx): Likewise.
	* profile.c (branch_prob): Likewise.
	* trans-mem.c (ipa_tm_scan_irr_block): Likewise.
	* gimplify.c (gimplify_call_expr): Likewise.
	* except.c (duplicate_eh_regions_1): Likewise.
	* emit-rtl.c (try_split): Likewise.
	(make_insn_raw): Likewise.
	(make_debug_insn_raw): Likewise.
	(make_jump_insn_raw): Likewise.
	(make_call_insn_raw): Likewise.
	(emit_pattern_after_setloc): Likewise.
	(emit_pattern_after): Likewise.
	(emit_debug_insn_after): Likewise.
	(emit_pattern_before): Likewise.
	(emit_insn_before_setloc): Likewise.
	(emit_jump_insn_before): Likewise.
	(emit_call_insn_before_setloc): Likewise.
	(emit_call_insn_before): Likeise.
	(emit_debug_insn_before_setloc): Likewise.
	(emit_copy_of_insn_after): Likewise.
	(insn_locators_alloc): Remove.
	(insn_locators_finalize): Remove.
	(insn_locators_free): Remove.
	(set_curr_insn_source_location): Remove.
	(get_curr_insn_source_location): Remove.
	(set_curr_insn_block): Remove.
	(get_curr_insn_block): Remove.
	(locator_scope): Remove.
	(insn_scope): Change to use new location.
	(locator_location): Remove.
	(insn_line): Change to use new location.
	(locator_file): Remove.
	(insn_file): Change to use new location.
	(locator_eq): Remove.
	(insn_locations_init): New.
	(insn_locations_finalize): New.
	(set_curr_insn_location): New.
	(curr_insn_location): New.
	* cfgexpand.c (gimple_assign_rhs_to_tree): Change to use new location.
	(expand_gimple_cond): Likewise.
	(expand_call_stmt): Likewise.
	(expand_gimple_stmt_1): Likewise.
	(expand_gimple_basic_block): Likewise.
	(construct_exit_block): Likewise.
	(gimple_expand_cfg): Likewise.
	* cfgcleanup.c (try_forward_edges): Likewise.
	* tree-ssa-live.c (remove_unused_scope_block_p): Likewise.
	(dump_scope_block): Likewise.
	(remove_unused_locals): Likewise.
	* rtl.c (rtx_equal_p_cb): Likewise.
	(rtx_equal_p): Likewise.
	* rtl.h (XUINT): New.
	(INSN_LOCATOR): Remove.
	(CURR_INSN_LOCATION): Remove.
	(INSN_LOCATION): New.
	(INSN_HAS_LOCATION): New.
	* tree-inline.c (remap_gimple_op_r): Change to use new location.
	(copy_tree_body_r): Likewise.
	(copy_phis_for_bb): Likewise.
	(expand_call_inline): Likewise.
	* tree-streamer-in.c (lto_input_ts_exp_tree_pointers): Likewise.
	* tree-streamer-out.c (): Likewise.
	* gimple-streamer-out.c (output_gimple_stmt): Likewise.
	* combine.c (try_combine): Likewise.
	* tree-outof-ssa.c (set_location_for_edge): Likewise.
	(insert_partition_copy_on_edge): Likewise.
	(insert_value_copy_on_edge): Likewise.
	(insert_rtx_to_part_on_edge): Likewise.
	(insert_part_to_rtx_on_edge): Likewise.
	* basic-block.h (edge_def): Remove field.
	* gimple.h (gimple_statement_base): Remove field.
	(gimple_bb): Change to use new location.
	(gimple_set_block): Likewise.
	(gimple_has_location): Likewise.
	* tree-cfg.c (make_cond_expr_edges): Likewise.
	(make_goto_expr_edges): Likewise.
	(gimple_can_merge_blocks_p): Likewise.
	(move_stmt_op): Likewise.
	(move_block_to_fn): Likewise.
	* config/alpha/alpha.c (alpha_output_mi_thunk_osf): Likewise.
	* config/sparc/sparc.c (sparc_output_mi_thunk): Likewise.
	* config/i386/i386.c (x86_output_mi_thunk): Likewise.
	* config/tilegx/tilegx.c (tilegx_output_mi_thunk): Likewise.
	* config/sh/sh.c (sh_output_mi_thunk): Likewise.
	* config/ia64/ia64.c (ia64_output_mi_thunk): Likewise.
	* config/rs6000/rs6000.c (rs6000_output_mi_thunk): Likewise.
	* config/score/score.c (score_output_mi_thunk): Likewise.
	* config/tilepro/tilepro.c (tilepro_asm_output_mi_thunk): Likewise.
	* config/mips/mips.c (mips_output_mi_thunk): Likewise.
	* cfgrtl.c (unique_locus_on_edge_between_p): Likewise.
	(unique_locus_on_edge_between_p): Likewise.
	(emit_nop_for_unique_locus_between): Likewise.
	(force_nonfallthru_and_redirect): Likewise.
	(fixup_reorder_chain): Likewise.
	(cfg_layout_merge_blocks): Likewise.
	* stmt.c (emit_case_nodes): Likewise.

gcc/lto/ChangeLog

2012-08-01  Dehao Chen  <dehao@google.com>

	* lto/lto.c (lto_fixup_prevailing_decls): Remove tree.exp.block field.

libcpp/ChangeLog

2012-08-01  Dehao Chen  <dehao@google.com>

	* include/line-map.h (MAX_SOURCE_LOCATION): New value.
	(location_block_init): New.
	(location_block_fini): New.
	(get_combine_location): New.
	(get_block_from_location): New.
	(get_locus_from_location): New.
	(COMBINE_LOCATION): New.
	(IS_COMBINED_LOCATION): New.
	(expanded_location): New field.
	* line-map.c (location_block): New.
	(location_block_htab): New.
	(curr_combined_location): New.
	(location_blocks): New.
	(allocated_location_blocks): New.
	(location_block_hash): New.
	(location_block_eq): New.
	(location_block_update): New.
	(get_combine_location): New.
	(get_block_from_location): New.
	(get_locus_from_location): New.
	(location_block_init): New.
	(location_block_fini): New.
	(linemap_lookup): Change to use new location.
	(linemap_ordinary_map_lookup): Likewise.
	(linemap_macro_map_lookup): Likewise.
	(linemap_macro_map_loc_to_def_point): Likewise.
	(linemap_macro_map_loc_unwind_toward_spel): Likewise.
	(linemap_get_expansion_line): Likewise.
	(linemap_get_expansion_filename): Likewise.
	(linemap_location_in_system_header_p): Likewise.
	(linemap_location_from_macro_expansion_p): Likewise.
	(linemap_macro_loc_to_spelling_point): Likewise.
	(linemap_macro_loc_to_def_point): Likewise.
	(linemap_macro_loc_to_exp_point): Likewise.
	(linemap_resolve_location): Likewise.
	(linemap_unwind_toward_expansion): Likewise.
	(linemap_unwind_to_first_non_reserved_loc): Likewise.
	(linemap_expand_location): Likewise.
	(linemap_dump_location): Likewise.

Index: gcc/gimple-streamer-out.c
===================================================================
*** gcc/gimple-streamer-out.c	(revision 189835)
--- gcc/gimple-streamer-out.c	(working copy)
*************** output_gimple_stmt (struct output_block
*** 74,80 ****
    streamer_write_bitpack (&bp);

    /* Emit location information for the statement.  */
!   lto_output_location (ob, gimple_location (stmt));

    /* Emit the lexical block holding STMT.  */
    stream_write_tree (ob, gimple_block (stmt), true);
--- 74,80 ----
    streamer_write_bitpack (&bp);

    /* Emit location information for the statement.  */
!   lto_output_location (ob, LOCATION_LOCUS (gimple_location (stmt)));

    /* Emit the lexical block holding STMT.  */
    stream_write_tree (ob, gimple_block (stmt), true);
Index: gcc/tree.c
===================================================================
*** gcc/tree.c	(revision 189835)
--- gcc/tree.c	(working copy)
*************** build1_stat (enum tree_code code, tree t
*** 3765,3771 ****
    TREE_TYPE (t) = type;
    SET_EXPR_LOCATION (t, UNKNOWN_LOCATION);
    TREE_OPERAND (t, 0) = node;
-   TREE_BLOCK (t) = NULL_TREE;
    if (node && !TYPE_P (node))
      {
        TREE_SIDE_EFFECTS (t) = TREE_SIDE_EFFECTS (node);
--- 3765,3770 ----
*************** walk_tree_without_duplicates_1 (tree *tp
*** 10867,10883 ****
  }


! tree *
  tree_block (tree t)
  {
    char const c = TREE_CODE_CLASS (TREE_CODE (t));

    if (IS_EXPR_CODE_CLASS (c))
!     return &t->exp.block;
    gcc_unreachable ();
    return NULL;
  }

  /* Create a nameless artificial label and put it in the current
     function context.  The label has a location of LOC.  Returns the
     newly created label.  */
--- 10866,10893 ----
  }


! tree
  tree_block (tree t)
  {
    char const c = TREE_CODE_CLASS (TREE_CODE (t));

    if (IS_EXPR_CODE_CLASS (c))
!     return LOCATION_BLOCK (t->exp.locus);
    gcc_unreachable ();
    return NULL;
  }

+ void
+ tree_set_block (tree t, tree b)
+ {
+   char const c = TREE_CODE_CLASS (TREE_CODE (t));
+
+   if (IS_EXPR_CODE_CLASS (c))
+     t->exp.locus = COMBINE_LOCATION (t->exp.locus, b);
+   else
+     gcc_unreachable ();
+ }
+
  /* Create a nameless artificial label and put it in the current
     function context.  The label has a location of LOC.  Returns the
     newly created label.  */
Index: gcc/tree.h
===================================================================
*** gcc/tree.h	(revision 189835)
--- gcc/tree.h	(working copy)
*************** extern void omp_clause_range_check_faile
*** 999,1005 ****

  #endif

! #define TREE_BLOCK(NODE)		*(tree_block (NODE))

  #include "tree-check.h"

--- 999,1006 ----

  #endif

! #define TREE_BLOCK(NODE)		(tree_block (NODE))
! #define TREE_SET_BLOCK(T, B)		(tree_set_block ((T), (B)))

  #include "tree-check.h"

*************** struct GTY(()) tree_constructor {
*** 1702,1708 ****
  #define EXPR_LOCATION(NODE) \
    (CAN_HAVE_LOCATION_P ((NODE)) ? (NODE)->exp.locus : UNKNOWN_LOCATION)
  #define SET_EXPR_LOCATION(NODE, LOCUS) EXPR_CHECK
((NODE))->exp.locus = (LOCUS)
! #define EXPR_HAS_LOCATION(NODE) (EXPR_LOCATION (NODE) != UNKNOWN_LOCATION)
  /* The location to be used in a diagnostic about this expression.  Do not
     use this macro if the location will be assigned to other expressions.  */
  #define EXPR_LOC_OR_HERE(NODE) (EXPR_HAS_LOCATION (NODE) ?
(NODE)->exp.locus : input_location)
--- 1703,1709 ----
  #define EXPR_LOCATION(NODE) \
    (CAN_HAVE_LOCATION_P ((NODE)) ? (NODE)->exp.locus : UNKNOWN_LOCATION)
  #define SET_EXPR_LOCATION(NODE, LOCUS) EXPR_CHECK
((NODE))->exp.locus = (LOCUS)
! #define EXPR_HAS_LOCATION(NODE) (!IS_UNKNOWN_LOCATION (EXPR_LOCATION (NODE)))
  /* The location to be used in a diagnostic about this expression.  Do not
     use this macro if the location will be assigned to other expressions.  */
  #define EXPR_LOC_OR_HERE(NODE) (EXPR_HAS_LOCATION (NODE) ?
(NODE)->exp.locus : input_location)
*************** extern void protected_set_expr_location
*** 1881,1887 ****
  					      OMP_CLAUSE_PRIVATE,	\
  	                                      OMP_CLAUSE_COPYPRIVATE), 0)
  #define OMP_CLAUSE_HAS_LOCATION(NODE) \
!   ((OMP_CLAUSE_CHECK (NODE))->omp_clause.locus != UNKNOWN_LOCATION)
  #define OMP_CLAUSE_LOCATION(NODE)  (OMP_CLAUSE_CHECK (NODE))->omp_clause.locus

  /* True on an OMP_SECTION statement that was the last lexical member.
--- 1882,1888 ----
  					      OMP_CLAUSE_PRIVATE,	\
  	                                      OMP_CLAUSE_COPYPRIVATE), 0)
  #define OMP_CLAUSE_HAS_LOCATION(NODE) \
!   (!IS_UNKNOWN_LOCATION ((OMP_CLAUSE_CHECK (NODE))->omp_clause.locus))
  #define OMP_CLAUSE_LOCATION(NODE)  (OMP_CLAUSE_CHECK (NODE))->omp_clause.locus

  /* True on an OMP_SECTION statement that was the last lexical member.
*************** enum omp_clause_default_kind
*** 1972,1978 ****
  struct GTY(()) tree_exp {
    struct tree_typed typed;
    location_t locus;
-   tree block;
    tree GTY ((special ("tree_exp"),
  	     desc ("TREE_CODE ((tree) &%0)")))
      operands[1];
--- 1973,1978 ----
*************** function_args_iter_next (function_args_i
*** 5164,5170 ****
  static inline bool
  inlined_function_outer_scope_p (const_tree block)
  {
!  return BLOCK_SOURCE_LOCATION (block) != UNKNOWN_LOCATION;
  }

  /* Loop over all function arguments of FNTYPE.  In each iteration, PTR is set
--- 5164,5170 ----
  static inline bool
  inlined_function_outer_scope_p (const_tree block)
  {
!  return !IS_UNKNOWN_LOCATION (BLOCK_SOURCE_LOCATION (block));
  }

  /* Loop over all function arguments of FNTYPE.  In each iteration, PTR is set
*************** extern bool subrange_type_for_debug_p (c
*** 5539,5545 ****
  extern HOST_WIDE_INT int_cst_value (const_tree);
  extern HOST_WIDEST_INT widest_int_cst_value (const_tree);

! extern tree *tree_block (tree);
  extern location_t *block_nonartificial_location (tree);
  extern location_t tree_nonartificial_location (tree);

--- 5539,5546 ----
  extern HOST_WIDE_INT int_cst_value (const_tree);
  extern HOST_WIDEST_INT widest_int_cst_value (const_tree);

! extern tree tree_block (tree);
! extern void tree_set_block (tree, tree);
  extern location_t *block_nonartificial_location (tree);
  extern location_t tree_nonartificial_location (tree);

Index: gcc/final.c
===================================================================
*** gcc/final.c	(revision 189835)
--- gcc/final.c	(working copy)
*************** reemit_insn_block_notes (void)
*** 1605,1611 ****
  					     insn_scope (XVECEXP (body, 0, i)));
  	}
        if (! this_block)
! 	continue;

        if (this_block != cur_block)
  	{
--- 1605,1611 ----
  					     insn_scope (XVECEXP (body, 0, i)));
  	}
        if (! this_block)
! 	this_block = DECL_INITIAL (cfun->decl);

        if (this_block != cur_block)
  	{
*************** final_start_function (rtx first ATTRIBUT
*** 1640,1647 ****

    this_is_asm_operands = 0;

!   last_filename = locator_file (prologue_locator);
!   last_linenum = locator_line (prologue_locator);
    last_discriminator = discriminator = 0;

    high_block_linenum = high_function_linenum = last_linenum;
--- 1640,1647 ----

    this_is_asm_operands = 0;

!   last_filename = LOCATION_FILE (prologue_location);
!   last_linenum = LOCATION_LINE (prologue_location);
    last_discriminator = discriminator = 0;

    high_block_linenum = high_function_linenum = last_linenum;
Index: gcc/input.c
===================================================================
*** gcc/input.c	(revision 189835)
--- gcc/input.c	(working copy)
*************** expand_location_1 (source_location loc,
*** 51,56 ****
--- 51,63 ----
    expanded_location xloc;
    const struct line_map *map;
    enum location_resolution_kind lrk = LRK_MACRO_EXPANSION_POINT;
+   tree block = NULL;
+
+   if (IS_COMBINED_LOCATION (loc))
+     {
+       block = LOCATION_BLOCK (loc);
+       loc = LOCATION_LOCUS (loc);
+     }

    memset (&xloc, 0, sizeof (xloc));

*************** expand_location_1 (source_location loc,
*** 74,79 ****
--- 81,87 ----
        xloc = linemap_expand_location (line_table, map, loc);
      }

+   xloc.block = block;
    if (loc <= BUILTINS_LOCATION)
      xloc.file = loc == UNKNOWN_LOCATION ? NULL : _("<built-in>");

Index: gcc/input.h
===================================================================
*** gcc/input.h	(revision 189835)
--- gcc/input.h	(working copy)
*************** extern location_t input_location;
*** 51,56 ****
--- 51,64 ----
  #define LOCATION_FILE(LOC) ((expand_location (LOC)).file)
  #define LOCATION_LINE(LOC) ((expand_location (LOC)).line)
  #define LOCATION_COLUMN(LOC)((expand_location (LOC)).column)
+ #define LOCATION_LOCUS(LOC) \
+   ((IS_COMBINED_LOCATION(LOC)) ? get_locus_from_location (LOC) : (LOC))
+ #define LOCATION_BLOCK(LOC) \
+   ((tree) ((IS_COMBINED_LOCATION (LOC)) ? get_block_from_location (LOC) \
+   : NULL))
+ #define IS_UNKNOWN_LOCATION(LOC) \
+   ((IS_COMBINED_LOCATION (LOC)) ? get_locus_from_location (LOC) == 0 \
+   : (LOC) == 0)

  #define input_line LOCATION_LINE (input_location)
  #define input_filename LOCATION_FILE (input_location)
Index: gcc/fold-const.c
===================================================================
*** gcc/fold-const.c	(revision 189835)
--- gcc/fold-const.c	(working copy)
*************** static location_t
*** 145,151 ****
  expr_location_or (tree t, location_t loc)
  {
    location_t tloc = EXPR_LOCATION (t);
!   return tloc != UNKNOWN_LOCATION ? tloc : loc;
  }

  /* Similar to protected_set_expr_location, but never modify x in place,
--- 145,151 ----
  expr_location_or (tree t, location_t loc)
  {
    location_t tloc = EXPR_LOCATION (t);
!   return IS_UNKNOWN_LOCATION (tloc) ? loc : tloc;
  }

  /* Similar to protected_set_expr_location, but never modify x in place,
Index: gcc/toplev.c
===================================================================
*** gcc/toplev.c	(revision 189835)
--- gcc/toplev.c	(working copy)
*************** general_init (const char *argv0)
*** 1140,1145 ****
--- 1140,1146 ----
    linemap_init (line_table);
    line_table->reallocator = realloc_for_line_map;
    line_table->round_alloc_size = ggc_round_alloc_size;
+   location_block_init ();
    init_ttree ();

    /* Initialize register usage now so switches may override.  */
*************** toplev_main (int argc, char **argv)
*** 1946,1951 ****
--- 1947,1953 ----
    invoke_plugin_callbacks (PLUGIN_FINISH, NULL);

    finalize_plugins ();
+   location_block_fini ();
    if (seen_error ())
      return (FATAL_EXIT_CODE);

Index: gcc/reorg.c
===================================================================
*** gcc/reorg.c	(revision 189835)
--- gcc/reorg.c	(working copy)
*************** emit_delay_sequence (rtx insn, rtx list,
*** 545,551 ****
    INSN_DELETED_P (delay_insn) = 0;
    PREV_INSN (delay_insn) = PREV_INSN (seq_insn);

!   INSN_LOCATOR (seq_insn) = INSN_LOCATOR (delay_insn);

    for (li = list; li; li = XEXP (li, 1), i++)
      {
--- 545,551 ----
    INSN_DELETED_P (delay_insn) = 0;
    PREV_INSN (delay_insn) = PREV_INSN (seq_insn);

!   INSN_LOCATION (seq_insn) = INSN_LOCATION (delay_insn);

    for (li = list; li; li = XEXP (li, 1), i++)
      {
*************** emit_delay_sequence (rtx insn, rtx list,
*** 561,569 ****

        /* SPARC assembler, for instance, emit warning when debug info is output
           into the delay slot.  */
!       if (INSN_LOCATOR (tem) && !INSN_LOCATOR (seq_insn))
! 	INSN_LOCATOR (seq_insn) = INSN_LOCATOR (tem);
!       INSN_LOCATOR (tem) = 0;

        for (note = REG_NOTES (tem); note; note = next)
  	{
--- 561,569 ----

        /* SPARC assembler, for instance, emit warning when debug info is output
           into the delay slot.  */
!       if (INSN_LOCATION (tem) && !INSN_LOCATION (seq_insn))
! 	INSN_LOCATION (seq_insn) = INSN_LOCATION (tem);
!       INSN_LOCATION (tem) = 0;

        for (note = REG_NOTES (tem); note; note = next)
  	{
*************** dbr_schedule (rtx first)
*** 4087,4093 ****
      for (link = crtl->epilogue_delay_list;
           link;
           link = XEXP (link, 1))
!       INSN_LOCATOR (XEXP (link, 0)) = 0;
    }

  #endif
--- 4087,4093 ----
      for (link = crtl->epilogue_delay_list;
           link;
           link = XEXP (link, 1))
!       INSN_LOCATION (XEXP (link, 0)) = 0;
    }

  #endif
Index: gcc/modulo-sched.c
===================================================================
*** gcc/modulo-sched.c	(revision 189835)
--- gcc/modulo-sched.c	(working copy)
*************** loop_single_full_bb_p (struct loop *loop
*** 1246,1254 ****
  /* Dump file:line from INSN's location info to dump_file.  */

  static void
! dump_insn_locator (rtx insn)
  {
!   if (dump_file && INSN_LOCATOR (insn))
      {
        const char *file = insn_file (insn);
        if (file)
--- 1246,1254 ----
  /* Dump file:line from INSN's location info to dump_file.  */

  static void
! dump_insn_location (rtx insn)
  {
!   if (dump_file && INSN_LOCATION (insn))
      {
        const char *file = insn_file (insn);
        if (file)
*************** loop_canon_p (struct loop *loop)
*** 1282,1288 ****
  	  rtx insn = BB_END (loop->header);

  	  fprintf (dump_file, "SMS loop many exits");
! 	  dump_insn_locator (insn);
  	  fprintf (dump_file, "\n");
  	}
        return false;
--- 1282,1288 ----
  	  rtx insn = BB_END (loop->header);

  	  fprintf (dump_file, "SMS loop many exits");
! 	  dump_insn_location (insn);
  	  fprintf (dump_file, "\n");
  	}
        return false;
*************** loop_canon_p (struct loop *loop)
*** 1295,1301 ****
  	  rtx insn = BB_END (loop->header);

  	  fprintf (dump_file, "SMS loop many BBs.");
! 	  dump_insn_locator (insn);
  	  fprintf (dump_file, "\n");
  	}
        return false;
--- 1295,1301 ----
  	  rtx insn = BB_END (loop->header);

  	  fprintf (dump_file, "SMS loop many BBs.");
! 	  dump_insn_location (insn);
  	  fprintf (dump_file, "\n");
  	}
        return false;
*************** sms_schedule (void)
*** 1421,1427 ****
  	  rtx insn = BB_END (loop->header);

  	  fprintf (dump_file, "SMS loop num: %d", loop->num);
! 	  dump_insn_locator (insn);
  	  fprintf (dump_file, "\n");
  	}

--- 1421,1427 ----
  	  rtx insn = BB_END (loop->header);

  	  fprintf (dump_file, "SMS loop num: %d", loop->num);
! 	  dump_insn_location (insn);
  	  fprintf (dump_file, "\n");
  	}

*************** sms_schedule (void)
*** 1450,1456 ****
  	{
  	  if (dump_file)
  	    {
! 	      dump_insn_locator (tail);
  	      fprintf (dump_file, "\nSMS single-bb-loop\n");
  	      if (profile_info && flag_branch_probabilities)
  	    	{
--- 1450,1456 ----
  	{
  	  if (dump_file)
  	    {
! 	      dump_insn_location (tail);
  	      fprintf (dump_file, "\nSMS single-bb-loop\n");
  	      if (profile_info && flag_branch_probabilities)
  	    	{
*************** sms_schedule (void)
*** 1556,1562 ****
  	  rtx insn = BB_END (loop->header);

  	  fprintf (dump_file, "SMS loop num: %d", loop->num);
! 	  dump_insn_locator (insn);
  	  fprintf (dump_file, "\n");

  	  print_ddg (dump_file, g);
--- 1556,1562 ----
  	  rtx insn = BB_END (loop->header);

  	  fprintf (dump_file, "SMS loop num: %d", loop->num);
! 	  dump_insn_location (insn);
  	  fprintf (dump_file, "\n");

  	  print_ddg (dump_file, g);
*************** sms_schedule (void)
*** 1571,1577 ****

        if (dump_file)
  	{
! 	  dump_insn_locator (tail);
  	  fprintf (dump_file, "\nSMS single-bb-loop\n");
  	  if (profile_info && flag_branch_probabilities)
  	    {
--- 1571,1577 ----

        if (dump_file)
  	{
! 	  dump_insn_location (tail);
  	  fprintf (dump_file, "\nSMS single-bb-loop\n");
  	  if (profile_info && flag_branch_probabilities)
  	    {
*************** sms_schedule (void)
*** 1714,1720 ****

            if (dump_file)
              {
! 	      dump_insn_locator (tail);
  	      fprintf (dump_file, " SMS succeeded %d %d (with ii, sc)\n",
  		       ps->ii, stage_count);
  	      print_partial_schedule (ps, dump_file);
--- 1714,1720 ----

            if (dump_file)
              {
! 	      dump_insn_location (tail);
  	      fprintf (dump_file, " SMS succeeded %d %d (with ii, sc)\n",
  		       ps->ii, stage_count);
  	      print_partial_schedule (ps, dump_file);
Index: gcc/lto-streamer-out.c
===================================================================
*** gcc/lto-streamer-out.c	(revision 189835)
--- gcc/lto-streamer-out.c	(working copy)
*************** lto_output_location_bitpack (struct bitp
*** 155,160 ****
--- 155,161 ----
  {
    expanded_location xloc;

+   loc = LOCATION_LOCUS (loc);
    bp_pack_value (bp, loc == UNKNOWN_LOCATION, 1);
    if (loc == UNKNOWN_LOCATION)
      return;
Index: gcc/jump.c
===================================================================
*** gcc/jump.c	(revision 189835)
--- gcc/jump.c	(working copy)
*************** rtx_renumbered_equal_p (const_rtx x, con
*** 1818,1825 ****
  	  if (XINT (x, i) != XINT (y, i))
  	    {
  	      if (((code == ASM_OPERANDS && i == 6)
! 		   || (code == ASM_INPUT && i == 1))
! 		  && locator_eq (XINT (x, i), XINT (y, i)))
  		break;
  	      return 0;
  	    }
--- 1818,1824 ----
  	  if (XINT (x, i) != XINT (y, i))
  	    {
  	      if (((code == ASM_OPERANDS && i == 6)
! 		   || (code == ASM_INPUT && i == 1)))
  		break;
  	      return 0;
  	    }
Index: gcc/ifcvt.c
===================================================================
*** gcc/ifcvt.c	(revision 189835)
--- gcc/ifcvt.c	(working copy)
*************** noce_try_move (struct noce_if_info *if_i
*** 1019,1025 ****
  	    return FALSE;

  	  emit_insn_before_setloc (seq, if_info->jump,
! 				   INSN_LOCATOR (if_info->insn_a));
  	}
        return TRUE;
      }
--- 1019,1025 ----
  	    return FALSE;

  	  emit_insn_before_setloc (seq, if_info->jump,
! 				   INSN_LOCATION (if_info->insn_a));
  	}
        return TRUE;
      }
*************** noce_try_store_flag (struct noce_if_info
*** 1064,1070 ****
  	return FALSE;

        emit_insn_before_setloc (seq, if_info->jump,
! 			       INSN_LOCATOR (if_info->insn_a));
        return TRUE;
      }
    else
--- 1064,1070 ----
  	return FALSE;

        emit_insn_before_setloc (seq, if_info->jump,
! 			       INSN_LOCATION (if_info->insn_a));
        return TRUE;
      }
    else
*************** noce_try_store_flag_constants (struct no
*** 1195,1201 ****
  	return FALSE;

        emit_insn_before_setloc (seq, if_info->jump,
! 			       INSN_LOCATOR (if_info->insn_a));
        return TRUE;
      }

--- 1195,1201 ----
  	return FALSE;

        emit_insn_before_setloc (seq, if_info->jump,
! 			       INSN_LOCATION (if_info->insn_a));
        return TRUE;
      }

*************** noce_try_addcc (struct noce_if_info *if_
*** 1243,1249 ****
  		return FALSE;

  	      emit_insn_before_setloc (seq, if_info->jump,
! 				       INSN_LOCATOR (if_info->insn_a));
  	      return TRUE;
  	    }
  	  end_sequence ();
--- 1243,1249 ----
  		return FALSE;

  	      emit_insn_before_setloc (seq, if_info->jump,
! 				       INSN_LOCATION (if_info->insn_a));
  	      return TRUE;
  	    }
  	  end_sequence ();
*************** noce_try_addcc (struct noce_if_info *if_
*** 1283,1289 ****
  		return FALSE;

  	      emit_insn_before_setloc (seq, if_info->jump,
! 				       INSN_LOCATOR (if_info->insn_a));
  	      return TRUE;
  	    }
  	  end_sequence ();
--- 1283,1289 ----
  		return FALSE;

  	      emit_insn_before_setloc (seq, if_info->jump,
! 				       INSN_LOCATION (if_info->insn_a));
  	      return TRUE;
  	    }
  	  end_sequence ();
*************** noce_try_store_flag_mask (struct noce_if
*** 1332,1338 ****
  	    return FALSE;

  	  emit_insn_before_setloc (seq, if_info->jump,
! 				   INSN_LOCATOR (if_info->insn_a));
  	  return TRUE;
  	}

--- 1332,1338 ----
  	    return FALSE;

  	  emit_insn_before_setloc (seq, if_info->jump,
! 				   INSN_LOCATION (if_info->insn_a));
  	  return TRUE;
  	}

*************** noce_try_cmove (struct noce_if_info *if_
*** 1481,1487 ****
  	    return FALSE;

  	  emit_insn_before_setloc (seq, if_info->jump,
! 				   INSN_LOCATOR (if_info->insn_a));
  	  return TRUE;
  	}
        else
--- 1481,1487 ----
  	    return FALSE;

  	  emit_insn_before_setloc (seq, if_info->jump,
! 				   INSN_LOCATION (if_info->insn_a));
  	  return TRUE;
  	}
        else
*************** noce_try_cmove_arith (struct noce_if_inf
*** 1682,1688 ****
    if (!tmp)
      return FALSE;

!   emit_insn_before_setloc (tmp, if_info->jump, INSN_LOCATOR
(if_info->insn_a));
    return TRUE;

   end_seq_and_fail:
--- 1682,1688 ----
    if (!tmp)
      return FALSE;

!   emit_insn_before_setloc (tmp, if_info->jump, INSN_LOCATION
(if_info->insn_a));
    return TRUE;

   end_seq_and_fail:
*************** noce_try_minmax (struct noce_if_info *if
*** 1929,1935 ****
    if (!seq)
      return FALSE;

!   emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATOR
(if_info->insn_a));
    if_info->cond = cond;
    if_info->cond_earliest = earliest;

--- 1929,1935 ----
    if (!seq)
      return FALSE;

!   emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION
(if_info->insn_a));
    if_info->cond = cond;
    if_info->cond_earliest = earliest;

*************** noce_try_abs (struct noce_if_info *if_in
*** 2076,2082 ****
    if (!seq)
      return FALSE;

!   emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATOR
(if_info->insn_a));
    if_info->cond = cond;
    if_info->cond_earliest = earliest;

--- 2076,2082 ----
    if (!seq)
      return FALSE;

!   emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION
(if_info->insn_a));
    if_info->cond = cond;
    if_info->cond_earliest = earliest;

*************** noce_try_sign_mask (struct noce_if_info
*** 2155,2161 ****
    if (!seq)
      return FALSE;

!   emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATOR
(if_info->insn_a));
    return TRUE;
  }

--- 2155,2161 ----
    if (!seq)
      return FALSE;

!   emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION
(if_info->insn_a));
    return TRUE;
  }

*************** noce_try_bitop (struct noce_if_info *if_
*** 2255,2261 ****
  	return FALSE;

        emit_insn_before_setloc (seq, if_info->jump,
! 			       INSN_LOCATOR (if_info->insn_a));
      }
    return TRUE;
  }
--- 2255,2261 ----
  	return FALSE;

        emit_insn_before_setloc (seq, if_info->jump,
! 			       INSN_LOCATION (if_info->insn_a));
      }
    return TRUE;
  }
*************** noce_process_if_block (struct noce_if_in
*** 2656,2662 ****
        unshare_all_rtl_in_chain (seq);
        end_sequence ();

!       emit_insn_before_setloc (seq, BB_END (test_bb), INSN_LOCATOR (insn_a));
      }

    /* The original THEN and ELSE blocks may now be removed.  The test block
--- 2656,2662 ----
        unshare_all_rtl_in_chain (seq);
        end_sequence ();

!       emit_insn_before_setloc (seq, BB_END (test_bb), INSN_LOCATION (insn_a));
      }

    /* The original THEN and ELSE blocks may now be removed.  The test block
*************** cond_move_process_if_block (struct noce_
*** 2937,2943 ****
        loc_insn = first_active_insn (else_bb);
        gcc_assert (loc_insn);
      }
!   emit_insn_before_setloc (seq, jump, INSN_LOCATOR (loc_insn));

    if (else_bb)
      {
--- 2937,2943 ----
        loc_insn = first_active_insn (else_bb);
        gcc_assert (loc_insn);
      }
!   emit_insn_before_setloc (seq, jump, INSN_LOCATION (loc_insn));

    if (else_bb)
      {
*************** find_cond_trap (basic_block test_bb, edg
*** 3655,3661 ****
      return FALSE;

    /* Emit the new insns before cond_earliest.  */
!   emit_insn_before_setloc (seq, cond_earliest, INSN_LOCATOR (trap));

    /* Delete the trap block if possible.  */
    remove_edge (trap_bb == then_bb ? then_edge : else_edge);
--- 3655,3661 ----
      return FALSE;

    /* Emit the new insns before cond_earliest.  */
!   emit_insn_before_setloc (seq, cond_earliest, INSN_LOCATION (trap));

    /* Delete the trap block if possible.  */
    remove_edge (trap_bb == then_bb ? then_edge : else_edge);
Index: gcc/dwarf2out.c
===================================================================
*** gcc/dwarf2out.c	(revision 189835)
--- gcc/dwarf2out.c	(working copy)
*************** add_src_coords_attributes (dw_die_ref di
*** 15506,15512 ****
  {
    expanded_location s;

!   if (DECL_SOURCE_LOCATION (decl) == UNKNOWN_LOCATION)
      return;
    s = expand_location (DECL_SOURCE_LOCATION (decl));
    add_AT_file (die, DW_AT_decl_file, lookup_filename (s.file));
--- 15506,15512 ----
  {
    expanded_location s;

!   if (IS_UNKNOWN_LOCATION (DECL_SOURCE_LOCATION (decl)))
      return;
    s = expand_location (DECL_SOURCE_LOCATION (decl));
    add_AT_file (die, DW_AT_decl_file, lookup_filename (s.file));
Index: gcc/expr.c
===================================================================
*** gcc/expr.c	(revision 189835)
--- gcc/expr.c	(working copy)
*************** expand_expr_real (tree exp, rtx target,
*** 7802,7820 ****
    if (cfun && EXPR_HAS_LOCATION (exp))
      {
        location_t saved_location = input_location;
!       location_t saved_curr_loc = get_curr_insn_source_location ();
!       tree saved_block = get_curr_insn_block ();
        input_location = EXPR_LOCATION (exp);
!       set_curr_insn_source_location (input_location);
!
!       /* Record where the insns produced belong.  */
!       set_curr_insn_block (TREE_BLOCK (exp));

        ret = expand_expr_real_1 (exp, target, tmode, modifier, alt_rtl);

        input_location = saved_location;
!       set_curr_insn_block (saved_block);
!       set_curr_insn_source_location (saved_curr_loc);
      }
    else
      {
--- 7802,7815 ----
    if (cfun && EXPR_HAS_LOCATION (exp))
      {
        location_t saved_location = input_location;
!       location_t saved_curr_loc = curr_insn_location ();
        input_location = EXPR_LOCATION (exp);
!       set_curr_insn_location (input_location);

        ret = expand_expr_real_1 (exp, target, tmode, modifier, alt_rtl);

        input_location = saved_location;
!       set_curr_insn_location (saved_curr_loc);
      }
    else
      {
Index: gcc/predict.c
===================================================================
*** gcc/predict.c	(revision 189835)
--- gcc/predict.c	(working copy)
*************** tree_estimate_probability_driver (void)
*** 2177,2183 ****
  {
    unsigned nb_loops;

!   loop_optimizer_init (0);
    if (dump_file && (dump_flags & TDF_DETAILS))
      flow_loops_dump (dump_file, NULL, 0);

--- 2177,2183 ----
  {
    unsigned nb_loops;

!   loop_optimizer_init (LOOPS_NORMAL);
    if (dump_file && (dump_flags & TDF_DETAILS))
      flow_loops_dump (dump_file, NULL, 0);

Index: gcc/tree-parloops.c
===================================================================
*** gcc/tree-parloops.c	(revision 189835)
--- gcc/tree-parloops.c	(working copy)
*************** create_loop_fn (location_t loc)
*** 1415,1420 ****
--- 1415,1421 ----
    struct function *act_cfun = cfun;
    static unsigned loopfn_num;

+   loc = LOCATION_LOCUS (loc);
    snprintf (buf, 100, "%s.$loopfn", current_function_name ());
    ASM_FORMAT_PRIVATE_NAME (tname, buf, loopfn_num++);
    clean_symbol_name (tname);
Index: gcc/recog.c
===================================================================
*** gcc/recog.c	(revision 189835)
--- gcc/recog.c	(working copy)
*************** peep2_attempt (basic_block bb, rtx insn,
*** 3333,3339 ****
    /* Replace the old sequence with the new.  */
    last = emit_insn_after_setloc (attempt,
  				 peep2_insn_data[i].insn,
! 				 INSN_LOCATOR (peep2_insn_data[i].insn));
    before_try = PREV_INSN (insn);
    delete_insn_chain (insn, peep2_insn_data[i].insn, false);

--- 3333,3339 ----
    /* Replace the old sequence with the new.  */
    last = emit_insn_after_setloc (attempt,
  				 peep2_insn_data[i].insn,
! 				 INSN_LOCATION (peep2_insn_data[i].insn));
    before_try = PREV_INSN (insn);
    delete_insn_chain (insn, peep2_insn_data[i].insn, false);

Index: gcc/function.c
===================================================================
*** gcc/function.c	(revision 189835)
--- gcc/function.c	(working copy)
*************** static bool contains (const_rtx, htab_t)
*** 133,139 ****
  static void prepare_function_start (void);
  static void do_clobber_return_reg (rtx, void *);
  static void do_use_return_reg (rtx, void *);
! static void set_insn_locators (rtx, int) ATTRIBUTE_UNUSED;
  
  /* Stack of nested functions.  */
  /* Keep track of the cfun stack.  */
--- 133,139 ----
  static void prepare_function_start (void);
  static void do_clobber_return_reg (rtx, void *);
  static void do_use_return_reg (rtx, void *);
! static void set_insn_locations (rtx, int) ATTRIBUTE_UNUSED;
  
  /* Stack of nested functions.  */
  /* Keep track of the cfun stack.  */
*************** free_after_compilation (struct function
*** 200,206 ****
    f->cfg = NULL;

    regno_reg_rtx = NULL;
-   insn_locators_free ();
  }
  
  /* Return size needed for stack frame based on slots so far allocated.
--- 200,205 ----
*************** expand_function_end (void)
*** 4979,4985 ****
  	      probe_stack_range (STACK_OLD_CHECK_PROTECT, max_frame_size);
  	    seq = get_insns ();
  	    end_sequence ();
! 	    set_insn_locators (seq, prologue_locator);
  	    emit_insn_before (seq, stack_check_probe_note);
  	    break;
  	  }
--- 4978,4984 ----
  	      probe_stack_range (STACK_OLD_CHECK_PROTECT, max_frame_size);
  	    seq = get_insns ();
  	    end_sequence ();
! 	    set_insn_locations (seq, prologue_location);
  	    emit_insn_before (seq, stack_check_probe_note);
  	    break;
  	  }
*************** expand_function_end (void)
*** 4994,5000 ****

    /* Output a linenumber for the end of the function.
       SDB depends on this.  */
!   set_curr_insn_source_location (input_location);

    /* Before the return label (if any), clobber the return
       registers so that they are not propagated live to the rest of
--- 4993,4999 ----

    /* Output a linenumber for the end of the function.
       SDB depends on this.  */
!   set_curr_insn_location (input_location);

    /* Before the return label (if any), clobber the return
       registers so that they are not propagated live to the rest of
*************** maybe_copy_prologue_epilogue_insn (rtx i
*** 5277,5290 ****
    *slot = copy;
  }

! /* Set the locator of the insn chain starting at INSN to LOC.  */
  static void
! set_insn_locators (rtx insn, int loc)
  {
    while (insn != NULL_RTX)
      {
        if (INSN_P (insn))
! 	INSN_LOCATOR (insn) = loc;
        insn = NEXT_INSN (insn);
      }
  }
--- 5276,5289 ----
    *slot = copy;
  }

! /* Set the location of the insn chain starting at INSN to LOC.  */
  static void
! set_insn_locations (rtx insn, int loc)
  {
    while (insn != NULL_RTX)
      {
        if (INSN_P (insn))
! 	INSN_LOCATION (insn) = loc;
        insn = NEXT_INSN (insn);
      }
  }
*************** thread_prologue_and_epilogue_insns (void
*** 5893,5899 ****
        end_sequence ();

        record_insns (split_prologue_seq, NULL, &prologue_insn_hash);
!       set_insn_locators (split_prologue_seq, prologue_locator);
  #endif
      }

--- 5892,5898 ----
        end_sequence ();

        record_insns (split_prologue_seq, NULL, &prologue_insn_hash);
!       set_insn_locations (split_prologue_seq, prologue_location);
  #endif
      }

*************** thread_prologue_and_epilogue_insns (void
*** 5922,5928 ****

        prologue_seq = get_insns ();
        end_sequence ();
!       set_insn_locators (prologue_seq, prologue_locator);
      }
  #endif

--- 5921,5927 ----

        prologue_seq = get_insns ();
        end_sequence ();
!       set_insn_locations (prologue_seq, prologue_location);
      }
  #endif

*************** thread_prologue_and_epilogue_insns (void
*** 6418,6424 ****

        /* Retain a map of the epilogue insns.  */
        record_insns (seq, NULL, &epilogue_insn_hash);
!       set_insn_locators (seq, epilogue_locator);

        seq = get_insns ();
        returnjump = get_last_insn ();
--- 6417,6423 ----

        /* Retain a map of the epilogue insns.  */
        record_insns (seq, NULL, &epilogue_insn_hash);
!       set_insn_locations (seq, epilogue_location);

        seq = get_insns ();
        returnjump = get_last_insn ();
*************** epilogue_done:
*** 6608,6614 ****
  	     avoid getting rid of sibcall epilogue insns.  Do this before we
  	     actually emit the sequence.  */
  	  record_insns (seq, NULL, &epilogue_insn_hash);
! 	  set_insn_locators (seq, epilogue_locator);

  	  emit_insn_before (seq, insn);
  	}
--- 6607,6613 ----
  	     avoid getting rid of sibcall epilogue insns.  Do this before we
  	     actually emit the sequence.  */
  	  record_insns (seq, NULL, &epilogue_insn_hash);
! 	  set_insn_locations (seq, epilogue_location);

  	  emit_insn_before (seq, insn);
  	}
Index: gcc/print-rtl.c
===================================================================
*** gcc/print-rtl.c	(revision 189835)
--- gcc/print-rtl.c	(working copy)
*************** print_rtx (const_rtx in_rtx)
*** 416,425 ****
  	if (i == 5 && INSN_P (in_rtx))
  	  {
  #ifndef GENERATOR_FILE
! 	    /*  Pretty-print insn locators.  Ignore scoping as it is mostly
  		redundant with line number information and do not print anything
  		when there is no location information available.  */
! 	    if (INSN_LOCATOR (in_rtx) && insn_file (in_rtx))
  	      fprintf(outfile, " %s:%i", insn_file (in_rtx), insn_line (in_rtx));
  #endif
  	  }
--- 416,425 ----
  	if (i == 5 && INSN_P (in_rtx))
  	  {
  #ifndef GENERATOR_FILE
! 	    /*  Pretty-print insn locations.  Ignore scoping as it is mostly
  		redundant with line number information and do not print anything
  		when there is no location information available.  */
! 	    if (INSN_LOCATION (in_rtx) && insn_file (in_rtx))
  	      fprintf(outfile, " %s:%i", insn_file (in_rtx), insn_line (in_rtx));
  #endif
  	  }
*************** print_rtx (const_rtx in_rtx)
*** 427,442 ****
  	  {
  #ifndef GENERATOR_FILE
  	    fprintf (outfile, " %s:%i",
! 		     locator_file (ASM_OPERANDS_SOURCE_LOCATION (in_rtx)),
! 		     locator_line (ASM_OPERANDS_SOURCE_LOCATION (in_rtx)));
  #endif
  	  }
  	else if (i == 1 && GET_CODE (in_rtx) == ASM_INPUT)
  	  {
  #ifndef GENERATOR_FILE
  	    fprintf (outfile, " %s:%i",
! 		     locator_file (ASM_INPUT_SOURCE_LOCATION (in_rtx)),
! 		     locator_line (ASM_INPUT_SOURCE_LOCATION (in_rtx)));
  #endif
  	  }
  	else if (i == 6 && NOTE_P (in_rtx))
--- 427,442 ----
  	  {
  #ifndef GENERATOR_FILE
  	    fprintf (outfile, " %s:%i",
! 		     LOCATION_FILE (ASM_OPERANDS_SOURCE_LOCATION (in_rtx)),
! 		     LOCATION_LINE (ASM_OPERANDS_SOURCE_LOCATION (in_rtx)));
  #endif
  	  }
  	else if (i == 1 && GET_CODE (in_rtx) == ASM_INPUT)
  	  {
  #ifndef GENERATOR_FILE
  	    fprintf (outfile, " %s:%i",
! 		     LOCATION_FILE (ASM_INPUT_SOURCE_LOCATION (in_rtx)),
! 		     LOCATION_LINE (ASM_INPUT_SOURCE_LOCATION (in_rtx)));
  #endif
  	  }
  	else if (i == 6 && NOTE_P (in_rtx))
Index: gcc/profile.c
===================================================================
*** gcc/profile.c	(revision 189835)
--- gcc/profile.c	(working copy)
*************** branch_prob (void)
*** 966,972 ****
  	     is not computed twice.  */
  	  if (last
  	      && gimple_has_location (last)
! 	      && e->goto_locus != UNKNOWN_LOCATION
  	      && !single_succ_p (bb)
  	      && (LOCATION_FILE (e->goto_locus)
  	          != LOCATION_FILE (gimple_location (last))
--- 966,972 ----
  	     is not computed twice.  */
  	  if (last
  	      && gimple_has_location (last)
! 	      && !IS_UNKNOWN_LOCATION (e->goto_locus)
  	      && !single_succ_p (bb)
  	      && (LOCATION_FILE (e->goto_locus)
  	          != LOCATION_FILE (gimple_location (last))
*************** branch_prob (void)
*** 976,982 ****
  	      basic_block new_bb = split_edge (e);
  	      edge ne = single_succ_edge (new_bb);
  	      ne->goto_locus = e->goto_locus;
- 	      ne->goto_block = e->goto_block;
  	    }
  	  if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
  	       && e->dest != EXIT_BLOCK_PTR)
--- 976,981 ----
*************** branch_prob (void)
*** 1188,1194 ****

  	  /* Notice GOTO expressions eliminated while constructing the CFG.  */
  	  if (single_succ_p (bb)
! 	      && single_succ_edge (bb)->goto_locus != UNKNOWN_LOCATION)
  	    {
  	      expanded_location curr_location
  		= expand_location (single_succ_edge (bb)->goto_locus);
--- 1187,1193 ----

  	  /* Notice GOTO expressions eliminated while constructing the CFG.  */
  	  if (single_succ_p (bb)
! 	      && !IS_UNKNOWN_LOCATION (single_succ_edge (bb)->goto_locus))
  	    {
  	      expanded_location curr_location
  		= expand_location (single_succ_edge (bb)->goto_locus);
Index: gcc/trans-mem.c
===================================================================
*** gcc/trans-mem.c	(revision 189835)
--- gcc/trans-mem.c	(working copy)
*************** ipa_tm_scan_irr_block (basic_block bb)
*** 3796,3802 ****
  	    {
  	      tree t = build1 (NOP_EXPR, void_type_node, size_zero_node);
  	      SET_EXPR_LOCATION (t, gimple_location (stmt));
- 	      TREE_BLOCK (t) = gimple_block (stmt);
  	      error ("%Kasm not allowed in %<transaction_safe%> function", t);
  	    }
  	  return true;
--- 3796,3801 ----
Index: gcc/gimplify.c
===================================================================
*** gcc/gimplify.c	(revision 189835)
--- gcc/gimplify.c	(working copy)
*************** gimplify_call_expr (tree *expr_p, gimple
*** 2600,2606 ****
  	    = CALL_EXPR_RETURN_SLOT_OPT (call);
  	  CALL_FROM_THUNK_P (*expr_p) = CALL_FROM_THUNK_P (call);
  	  SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (call));
- 	  TREE_BLOCK (*expr_p) = TREE_BLOCK (call);

  	  /* Set CALL_EXPR_VA_ARG_PACK.  */
  	  CALL_EXPR_VA_ARG_PACK (*expr_p) = 1;
--- 2600,2605 ----
Index: gcc/except.c
===================================================================
*** gcc/except.c	(revision 189835)
--- gcc/except.c	(working copy)
*************** duplicate_eh_regions_1 (struct duplicate
*** 526,532 ****
        break;

      case ERT_MUST_NOT_THROW:
!       new_r->u.must_not_throw = old_r->u.must_not_throw;
        break;
      }

--- 526,535 ----
        break;

      case ERT_MUST_NOT_THROW:
!       new_r->u.must_not_throw.failure_loc =
! 	LOCATION_LOCUS (old_r->u.must_not_throw.failure_loc);
!       new_r->u.must_not_throw.failure_decl =
! 	old_r->u.must_not_throw.failure_decl;
        break;
      }

Index: gcc/emit-rtl.c
===================================================================
*** gcc/emit-rtl.c	(revision 189835)
--- gcc/emit-rtl.c	(working copy)
*************** try_split (rtx pat, rtx trial, int last)
*** 3634,3640 ****
  	}
      }

!   tem = emit_insn_after_setloc (seq, trial, INSN_LOCATOR (trial));

    delete_insn (trial);
    if (has_barrier)
--- 3634,3640 ----
  	}
      }

!   tem = emit_insn_after_setloc (seq, trial, INSN_LOCATION (trial));

    delete_insn (trial);
    if (has_barrier)
*************** make_insn_raw (rtx pattern)
*** 3670,3676 ****
    PATTERN (insn) = pattern;
    INSN_CODE (insn) = -1;
    REG_NOTES (insn) = NULL;
!   INSN_LOCATOR (insn) = curr_insn_locator ();
    BLOCK_FOR_INSN (insn) = NULL;

  #ifdef ENABLE_RTL_CHECKING
--- 3670,3676 ----
    PATTERN (insn) = pattern;
    INSN_CODE (insn) = -1;
    REG_NOTES (insn) = NULL;
!   INSN_LOCATION (insn) = curr_insn_location ();
    BLOCK_FOR_INSN (insn) = NULL;

  #ifdef ENABLE_RTL_CHECKING
*************** make_debug_insn_raw (rtx pattern)
*** 3703,3709 ****
    PATTERN (insn) = pattern;
    INSN_CODE (insn) = -1;
    REG_NOTES (insn) = NULL;
!   INSN_LOCATOR (insn) = curr_insn_locator ();
    BLOCK_FOR_INSN (insn) = NULL;

    return insn;
--- 3703,3709 ----
    PATTERN (insn) = pattern;
    INSN_CODE (insn) = -1;
    REG_NOTES (insn) = NULL;
!   INSN_LOCATION (insn) = curr_insn_location ();
    BLOCK_FOR_INSN (insn) = NULL;

    return insn;
*************** make_jump_insn_raw (rtx pattern)
*** 3723,3729 ****
    INSN_CODE (insn) = -1;
    REG_NOTES (insn) = NULL;
    JUMP_LABEL (insn) = NULL;
!   INSN_LOCATOR (insn) = curr_insn_locator ();
    BLOCK_FOR_INSN (insn) = NULL;

    return insn;
--- 3723,3729 ----
    INSN_CODE (insn) = -1;
    REG_NOTES (insn) = NULL;
    JUMP_LABEL (insn) = NULL;
!   INSN_LOCATION (insn) = curr_insn_location ();
    BLOCK_FOR_INSN (insn) = NULL;

    return insn;
*************** make_call_insn_raw (rtx pattern)
*** 3743,3749 ****
    INSN_CODE (insn) = -1;
    REG_NOTES (insn) = NULL;
    CALL_INSN_FUNCTION_USAGE (insn) = NULL;
!   INSN_LOCATOR (insn) = curr_insn_locator ();
    BLOCK_FOR_INSN (insn) = NULL;

    return insn;
--- 3743,3749 ----
    INSN_CODE (insn) = -1;
    REG_NOTES (insn) = NULL;
    CALL_INSN_FUNCTION_USAGE (insn) = NULL;
!   INSN_LOCATION (insn) = curr_insn_location ();
    BLOCK_FOR_INSN (insn) = NULL;

    return insn;
*************** emit_pattern_after_setloc (rtx pattern,
*** 4416,4423 ****
    after = NEXT_INSN (after);
    while (1)
      {
!       if (active_insn_p (after) && !INSN_LOCATOR (after))
! 	INSN_LOCATOR (after) = loc;
        if (after == last)
  	break;
        after = NEXT_INSN (after);
--- 4416,4423 ----
    after = NEXT_INSN (after);
    while (1)
      {
!       if (active_insn_p (after) && !INSN_LOCATION (after))
! 	INSN_LOCATION (after) = loc;
        if (after == last)
  	break;
        after = NEXT_INSN (after);
*************** emit_pattern_after (rtx pattern, rtx aft
*** 4440,4501 ****
        prev = PREV_INSN (prev);

    if (INSN_P (prev))
!     return emit_pattern_after_setloc (pattern, after, INSN_LOCATOR (prev),
  				      make_raw);
    else
      return emit_pattern_after_noloc (pattern, after, NULL, make_raw);
  }

! /* Like emit_insn_after_noloc, but set INSN_LOCATOR according to LOC.  */
  rtx
  emit_insn_after_setloc (rtx pattern, rtx after, int loc)
  {
    return emit_pattern_after_setloc (pattern, after, loc, make_insn_raw);
  }

! /* Like emit_insn_after_noloc, but set INSN_LOCATOR according to AFTER.  */
  rtx
  emit_insn_after (rtx pattern, rtx after)
  {
    return emit_pattern_after (pattern, after, true, make_insn_raw);
  }

! /* Like emit_jump_insn_after_noloc, but set INSN_LOCATOR according to LOC.  */
  rtx
  emit_jump_insn_after_setloc (rtx pattern, rtx after, int loc)
  {
    return emit_pattern_after_setloc (pattern, after, loc, make_jump_insn_raw);
  }

! /* Like emit_jump_insn_after_noloc, but set INSN_LOCATOR according
to AFTER.  */
  rtx
  emit_jump_insn_after (rtx pattern, rtx after)
  {
    return emit_pattern_after (pattern, after, true, make_jump_insn_raw);
  }

! /* Like emit_call_insn_after_noloc, but set INSN_LOCATOR according to LOC.  */
  rtx
  emit_call_insn_after_setloc (rtx pattern, rtx after, int loc)
  {
    return emit_pattern_after_setloc (pattern, after, loc, make_call_insn_raw);
  }

! /* Like emit_call_insn_after_noloc, but set INSN_LOCATOR according
to AFTER.  */
  rtx
  emit_call_insn_after (rtx pattern, rtx after)
  {
    return emit_pattern_after (pattern, after, true, make_call_insn_raw);
  }

! /* Like emit_debug_insn_after_noloc, but set INSN_LOCATOR according
to LOC.  */
  rtx
  emit_debug_insn_after_setloc (rtx pattern, rtx after, int loc)
  {
    return emit_pattern_after_setloc (pattern, after, loc, make_debug_insn_raw);
  }

! /* Like emit_debug_insn_after_noloc, but set INSN_LOCATOR according
to AFTER.  */
  rtx
  emit_debug_insn_after (rtx pattern, rtx after)
  {
--- 4440,4501 ----
        prev = PREV_INSN (prev);

    if (INSN_P (prev))
!     return emit_pattern_after_setloc (pattern, after, INSN_LOCATION (prev),
  				      make_raw);
    else
      return emit_pattern_after_noloc (pattern, after, NULL, make_raw);
  }

! /* Like emit_insn_after_noloc, but set INSN_LOCATION according to LOC.  */
  rtx
  emit_insn_after_setloc (rtx pattern, rtx after, int loc)
  {
    return emit_pattern_after_setloc (pattern, after, loc, make_insn_raw);
  }

! /* Like emit_insn_after_noloc, but set INSN_LOCATION according to AFTER.  */
  rtx
  emit_insn_after (rtx pattern, rtx after)
  {
    return emit_pattern_after (pattern, after, true, make_insn_raw);
  }

! /* Like emit_jump_insn_after_noloc, but set INSN_LOCATION according
to LOC.  */
  rtx
  emit_jump_insn_after_setloc (rtx pattern, rtx after, int loc)
  {
    return emit_pattern_after_setloc (pattern, after, loc, make_jump_insn_raw);
  }

! /* Like emit_jump_insn_after_noloc, but set INSN_LOCATION according
to AFTER.  */
  rtx
  emit_jump_insn_after (rtx pattern, rtx after)
  {
    return emit_pattern_after (pattern, after, true, make_jump_insn_raw);
  }

! /* Like emit_call_insn_after_noloc, but set INSN_LOCATION according
to LOC.  */
  rtx
  emit_call_insn_after_setloc (rtx pattern, rtx after, int loc)
  {
    return emit_pattern_after_setloc (pattern, after, loc, make_call_insn_raw);
  }

! /* Like emit_call_insn_after_noloc, but set INSN_LOCATION according
to AFTER.  */
  rtx
  emit_call_insn_after (rtx pattern, rtx after)
  {
    return emit_pattern_after (pattern, after, true, make_call_insn_raw);
  }

! /* Like emit_debug_insn_after_noloc, but set INSN_LOCATION according
to LOC.  */
  rtx
  emit_debug_insn_after_setloc (rtx pattern, rtx after, int loc)
  {
    return emit_pattern_after_setloc (pattern, after, loc, make_debug_insn_raw);
  }

! /* Like emit_debug_insn_after_noloc, but set INSN_LOCATION according
to AFTER.  */
  rtx
  emit_debug_insn_after (rtx pattern, rtx after)
  {
*************** emit_pattern_before_setloc (rtx pattern,
*** 4525,4532 ****
      first = NEXT_INSN (first);
    while (1)
      {
!       if (active_insn_p (first) && !INSN_LOCATOR (first))
! 	INSN_LOCATOR (first) = loc;
        if (first == last)
  	break;
        first = NEXT_INSN (first);
--- 4525,4532 ----
      first = NEXT_INSN (first);
    while (1)
      {
!       if (active_insn_p (first) && !INSN_LOCATION (first))
! 	INSN_LOCATION (first) = loc;
        if (first == last)
  	break;
        first = NEXT_INSN (first);
*************** emit_pattern_before (rtx pattern, rtx be
*** 4550,4556 ****
        next = PREV_INSN (next);

    if (INSN_P (next))
!     return emit_pattern_before_setloc (pattern, before, INSN_LOCATOR (next),
  				       insnp, make_raw);
    else
      return emit_pattern_before_noloc (pattern, before,
--- 4550,4556 ----
        next = PREV_INSN (next);

    if (INSN_P (next))
!     return emit_pattern_before_setloc (pattern, before, INSN_LOCATION (next),
  				       insnp, make_raw);
    else
      return emit_pattern_before_noloc (pattern, before,
*************** emit_pattern_before (rtx pattern, rtx be
*** 4558,4564 ****
                                        NULL, make_raw);
  }

! /* Like emit_insn_before_noloc, but set INSN_LOCATOR according to LOC.  */
  rtx
  emit_insn_before_setloc (rtx pattern, rtx before, int loc)
  {
--- 4558,4564 ----
                                        NULL, make_raw);
  }

! /* Like emit_insn_before_noloc, but set INSN_LOCATION according to LOC.  */
  rtx
  emit_insn_before_setloc (rtx pattern, rtx before, int loc)
  {
*************** emit_insn_before_setloc (rtx pattern, rt
*** 4566,4579 ****
  				     make_insn_raw);
  }

! /* Like emit_insn_before_noloc, but set INSN_LOCATOR according to BEFORE.  */
  rtx
  emit_insn_before (rtx pattern, rtx before)
  {
    return emit_pattern_before (pattern, before, true, true, make_insn_raw);
  }

! /* like emit_insn_before_noloc, but set INSN_LOCATOR according to LOC.  */
  rtx
  emit_jump_insn_before_setloc (rtx pattern, rtx before, int loc)
  {
--- 4566,4579 ----
  				     make_insn_raw);
  }

! /* Like emit_insn_before_noloc, but set INSN_LOCATION according to BEFORE.  */
  rtx
  emit_insn_before (rtx pattern, rtx before)
  {
    return emit_pattern_before (pattern, before, true, true, make_insn_raw);
  }

! /* like emit_insn_before_noloc, but set INSN_LOCATION according to LOC.  */
  rtx
  emit_jump_insn_before_setloc (rtx pattern, rtx before, int loc)
  {
*************** emit_jump_insn_before_setloc (rtx patter
*** 4581,4587 ****
  				     make_jump_insn_raw);
  }

! /* Like emit_jump_insn_before_noloc, but set INSN_LOCATOR according
to BEFORE.  */
  rtx
  emit_jump_insn_before (rtx pattern, rtx before)
  {
--- 4581,4587 ----
  				     make_jump_insn_raw);
  }

! /* Like emit_jump_insn_before_noloc, but set INSN_LOCATION according
to BEFORE.  */
  rtx
  emit_jump_insn_before (rtx pattern, rtx before)
  {
*************** emit_jump_insn_before (rtx pattern, rtx
*** 4589,4595 ****
  			      make_jump_insn_raw);
  }

! /* Like emit_insn_before_noloc, but set INSN_LOCATOR according to LOC.  */
  rtx
  emit_call_insn_before_setloc (rtx pattern, rtx before, int loc)
  {
--- 4589,4595 ----
  			      make_jump_insn_raw);
  }

! /* Like emit_insn_before_noloc, but set INSN_LOCATION according to LOC.  */
  rtx
  emit_call_insn_before_setloc (rtx pattern, rtx before, int loc)
  {
*************** emit_call_insn_before_setloc (rtx patter
*** 4598,4604 ****
  }

  /* Like emit_call_insn_before_noloc,
!    but set insn_locator according to BEFORE.  */
  rtx
  emit_call_insn_before (rtx pattern, rtx before)
  {
--- 4598,4604 ----
  }

  /* Like emit_call_insn_before_noloc,
!    but set insn_location according to BEFORE.  */
  rtx
  emit_call_insn_before (rtx pattern, rtx before)
  {
*************** emit_call_insn_before (rtx pattern, rtx
*** 4606,4612 ****
  			      make_call_insn_raw);
  }

! /* Like emit_insn_before_noloc, but set INSN_LOCATOR according to LOC.  */
  rtx
  emit_debug_insn_before_setloc (rtx pattern, rtx before, int loc)
  {
--- 4606,4612 ----
  			      make_call_insn_raw);
  }

! /* Like emit_insn_before_noloc, but set INSN_LOCATION according to LOC.  */
  rtx
  emit_debug_insn_before_setloc (rtx pattern, rtx before, int loc)
  {
*************** emit_debug_insn_before_setloc (rtx patte
*** 4615,4621 ****
  }

  /* Like emit_debug_insn_before_noloc,
!    but set insn_locator according to BEFORE.  */
  rtx
  emit_debug_insn_before (rtx pattern, rtx before)
  {
--- 4615,4621 ----
  }

  /* Like emit_debug_insn_before_noloc,
!    but set insn_location according to BEFORE.  */
  rtx
  emit_debug_insn_before (rtx pattern, rtx before)
  {
*************** emit_copy_of_insn_after (rtx insn, rtx a
*** 5865,5871 ****
    /* Update LABEL_NUSES.  */
    mark_jump_label (PATTERN (new_rtx), new_rtx, 0);

!   INSN_LOCATOR (new_rtx) = INSN_LOCATOR (insn);

    /* If the old insn is frame related, then so is the new one.  This is
       primarily needed for IA-64 unwind info which marks epilogue insns,
--- 5865,5871 ----
    /* Update LABEL_NUSES.  */
    mark_jump_label (PATTERN (new_rtx), new_rtx, 0);

!   INSN_LOCATION (new_rtx) = INSN_LOCATION (insn);

    /* If the old insn is frame related, then so is the new one.  This is
       primarily needed for IA-64 unwind info which marks epilogue insns,
*************** gen_hard_reg_clobber (enum machine_mode
*** 5900,6149 ****
  	    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (mode, regno)));
  }

! /* Data structures representing mapping of INSN_LOCATOR into scope
blocks, line
!    numbers and files.  In order to be GGC friendly we need to use separate
!    varrays.  This also slightly improve the memory locality in binary search.
!    The _locs array contains locators where the given property change.  The
!    block_locators_blocks contains the scope block that is used for all insn
!    locator greater than corresponding block_locators_locs value and smaller
!    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) *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;

  /* Hold current location information and last location information, so the
     datastructures are built lazily only when some instructions in given
     place are needed.  */
  static location_t curr_location, last_location;
- static tree curr_block, last_block;
- static int curr_rtl_loc = -1;

! /* Allocate insn locator datastructure.  */
  void
! insn_locators_alloc (void)
  {
!   prologue_locator = epilogue_locator = 0;
!
!   block_locators_locs = VEC_alloc (int, heap, 32);
!   block_locators_blocks = VEC_alloc (tree, gc, 32);
!   locations_locators_locs = VEC_alloc (int, heap, 32);
!   locations_locators_vals = VEC_alloc (location_t, heap, 32);
!
    curr_location = UNKNOWN_LOCATION;
    last_location = UNKNOWN_LOCATION;
-   curr_block = NULL;
-   last_block = NULL;
-   curr_rtl_loc = 0;
  }

  /* 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;
! }
!
! /* Allocate insn locator datastructure.  */
! void
! insn_locators_free (void)
  {
!   prologue_locator = epilogue_locator = 0;
!
!   VEC_free (int, heap, block_locators_locs);
!   VEC_free (tree,gc, block_locators_blocks);
!   VEC_free (int, heap, locations_locators_locs);
!   VEC_free (location_t, heap, locations_locators_vals);
  }

  /* 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;
    curr_location = location;
  }

  /* Get current location.  */
  location_t
! get_curr_insn_source_location (void)
  {
    return curr_location;
  }

- /* 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;
- }
-
- /* Get current scope block.  */
- tree
- get_curr_insn_block (void)
- {
-   return curr_block;
- }
-
- /* Return current insn locator.  */
- int
- curr_insn_locator (void)
- {
-   if (curr_rtl_loc == -1 || curr_location == UNKNOWN_LOCATION)
-     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;
-     }
-   if (last_location != curr_location)
-     {
-       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;
- }
- 
-
- /* Return lexical scope block locator belongs to.  */
- static tree
- locator_scope (int loc)
- {
-   int max = VEC_length (int, block_locators_locs);
-   int min = 0;
-
-   /* When block_locators_locs was initialized, the pro- and epilogue
-      insns didn't exist yet and can therefore not be found this way.
-      But we know that they belong to the outer most block of the
-      current function.
-      Without this test, the prologue would be put inside the block of
-      the first valid instruction in the function and when that first
-      insn is part of an inlined function then the low_pc of that
-      inlined function is messed up.  Likewise for the epilogue and
-      the last valid instruction.  */
-   if (loc == prologue_locator || loc == epilogue_locator)
-     return DECL_INITIAL (cfun->decl);
-
-   if (!max || !loc)
-     return NULL;
-   while (1)
-     {
-       int pos = (min + max) / 2;
-       int tmp = VEC_index (int, block_locators_locs, pos);
-
-       if (tmp <= loc && min != pos)
- 	min = pos;
-       else if (tmp > loc && max != pos)
- 	max = pos;
-       else
- 	{
- 	  min = pos;
- 	  break;
- 	}
-     }
-   return VEC_index (tree, block_locators_blocks, min);
- }
-
  /* Return lexical scope block insn belongs to.  */
  tree
  insn_scope (const_rtx insn)
  {
!   return locator_scope (INSN_LOCATOR (insn));
! }
!
! /* Return line number of the statement specified by the locator.  */
! location_t
! locator_location (int loc)
! {
!   int max = VEC_length (int, locations_locators_locs);
!   int min = 0;
!
!   while (1)
!     {
!       int pos = (min + max) / 2;
!       int tmp = VEC_index (int, locations_locators_locs, pos);
!
!       if (tmp <= loc && min != pos)
! 	min = pos;
!       else if (tmp > loc && max != pos)
! 	max = pos;
!       else
! 	{
! 	  min = pos;
! 	  break;
! 	}
!     }
!   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.  */
  int
  insn_line (const_rtx insn)
  {
!   return locator_line (INSN_LOCATOR (insn));
! }
!
! /* Return source file of the statement specified by LOC.  */
! const char *
! locator_file (int loc)
! {
!   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.  */
  const char *
  insn_file (const_rtx insn)
  {
!   return locator_file (INSN_LOCATOR (insn));
  }

- /* Return true if LOC1 and LOC2 locators have the same location and scope.  */
- bool
- locator_eq (int loc1, int loc2)
- {
-   if (loc1 == loc2)
-     return true;
-   if (locator_location (loc1) != locator_location (loc2))
-     return false;
-   return locator_scope (loc1) == locator_scope (loc2);
- }
- 
-
  /* Return true if memory model MODEL requires a pre-operation (release-style)
     barrier or a post-operation (acquire-style) barrier.  While not universal,
     this function matches behavior of several targets.  */
--- 5900,5965 ----
  	    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (mode, regno)));
  }

! location_t prologue_location;
! location_t epilogue_location;

  /* Hold current location information and last location information, so the
     datastructures are built lazily only when some instructions in given
     place are needed.  */
  static location_t curr_location, last_location;

! /* Allocate insn location datastructure.  */
  void
! insn_locations_init (void)
  {
!   prologue_location = epilogue_location = 0;
    curr_location = UNKNOWN_LOCATION;
    last_location = UNKNOWN_LOCATION;
  }

  /* At the end of emit stage, clear current location.  */
  void
! insn_locations_finalize (void)
  {
!   epilogue_location = curr_location;
!   curr_location = UNKNOWN_LOCATION;
  }

  /* Set current location.  */
  void
! set_curr_insn_location (location_t location)
  {
    curr_location = location;
  }

  /* Get current location.  */
  location_t
! curr_insn_location (void)
  {
    return curr_location;
  }

  /* Return lexical scope block insn belongs to.  */
  tree
  insn_scope (const_rtx insn)
  {
!   return LOCATION_BLOCK (INSN_LOCATION (insn));
  }

  /* Return line number of the statement that produced this insn.  */
  int
  insn_line (const_rtx insn)
  {
!   return LOCATION_LINE (INSN_LOCATION (insn));
  }

  /* Return source file of the statement that produced this insn.  */
  const char *
  insn_file (const_rtx insn)
  {
!   return LOCATION_FILE (INSN_LOCATION (insn));
  }

  /* Return true if memory model MODEL requires a pre-operation (release-style)
     barrier or a post-operation (acquire-style) barrier.  While not universal,
     this function matches behavior of several targets.  */
Index: gcc/cfgexpand.c
===================================================================
*** gcc/cfgexpand.c	(revision 189835)
--- gcc/cfgexpand.c	(working copy)
*************** gimple_assign_rhs_to_tree (gimple stmt)
*** 92,99 ****
  	   && gimple_location (stmt) != EXPR_LOCATION (t))
  	  || (gimple_block (stmt)
  	      && currently_expanding_to_rtl
! 	      && EXPR_P (t)
! 	      && gimple_block (stmt) != TREE_BLOCK (t)))
  	t = copy_node (t);
      }
    else
--- 92,98 ----
  	   && gimple_location (stmt) != EXPR_LOCATION (t))
  	  || (gimple_block (stmt)
  	      && currently_expanding_to_rtl
! 	      && EXPR_P (t)))
  	t = copy_node (t);
      }
    else
*************** gimple_assign_rhs_to_tree (gimple stmt)
*** 101,108 ****

    if (gimple_has_location (stmt) && CAN_HAVE_LOCATION_P (t))
      SET_EXPR_LOCATION (t, gimple_location (stmt));
-   if (gimple_block (stmt) && currently_expanding_to_rtl && EXPR_P (t))
-     TREE_BLOCK (t) = gimple_block (stmt);

    return t;
  }
--- 100,105 ----
*************** expand_gimple_cond (basic_block bb, gimp
*** 1804,1811 ****
    last2 = last = get_last_insn ();

    extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
!   set_curr_insn_source_location (gimple_location (stmt));
!   set_curr_insn_block (gimple_block (stmt));

    /* These flags have no purpose in RTL land.  */
    true_edge->flags &= ~EDGE_TRUE_VALUE;
--- 1801,1807 ----
    last2 = last = get_last_insn ();

    extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
!   set_curr_insn_location (gimple_location (stmt));

    /* These flags have no purpose in RTL land.  */
    true_edge->flags &= ~EDGE_TRUE_VALUE;
*************** expand_gimple_cond (basic_block bb, gimp
*** 1818,1830 ****
        jumpif_1 (code, op0, op1, label_rtx_for_bb (true_edge->dest),
  		true_edge->probability);
        maybe_dump_rtl_for_gimple_stmt (stmt, last);
!       if (true_edge->goto_locus)
! 	{
! 	  set_curr_insn_source_location (true_edge->goto_locus);
! 	  set_curr_insn_block (true_edge->goto_block);
! 	  true_edge->goto_locus = curr_insn_locator ();
! 	}
!       true_edge->goto_block = NULL;
        false_edge->flags |= EDGE_FALLTHRU;
        maybe_cleanup_end_of_block (false_edge, last);
        return NULL;
--- 1814,1821 ----
        jumpif_1 (code, op0, op1, label_rtx_for_bb (true_edge->dest),
  		true_edge->probability);
        maybe_dump_rtl_for_gimple_stmt (stmt, last);
!       if (!IS_UNKNOWN_LOCATION (true_edge->goto_locus))
! 	set_curr_insn_location (true_edge->goto_locus);
        false_edge->flags |= EDGE_FALLTHRU;
        maybe_cleanup_end_of_block (false_edge, last);
        return NULL;
*************** expand_gimple_cond (basic_block bb, gimp
*** 1834,1846 ****
        jumpifnot_1 (code, op0, op1, label_rtx_for_bb (false_edge->dest),
  		   false_edge->probability);
        maybe_dump_rtl_for_gimple_stmt (stmt, last);
!       if (false_edge->goto_locus)
! 	{
! 	  set_curr_insn_source_location (false_edge->goto_locus);
! 	  set_curr_insn_block (false_edge->goto_block);
! 	  false_edge->goto_locus = curr_insn_locator ();
! 	}
!       false_edge->goto_block = NULL;
        true_edge->flags |= EDGE_FALLTHRU;
        maybe_cleanup_end_of_block (true_edge, last);
        return NULL;
--- 1825,1832 ----
        jumpifnot_1 (code, op0, op1, label_rtx_for_bb (false_edge->dest),
  		   false_edge->probability);
        maybe_dump_rtl_for_gimple_stmt (stmt, last);
!       if (!IS_UNKNOWN_LOCATION (false_edge->goto_locus))
! 	set_curr_insn_location (false_edge->goto_locus);
        true_edge->flags |= EDGE_FALLTHRU;
        maybe_cleanup_end_of_block (true_edge, last);
        return NULL;
*************** expand_gimple_cond (basic_block bb, gimp
*** 1849,1861 ****
    jumpif_1 (code, op0, op1, label_rtx_for_bb (true_edge->dest),
  	    true_edge->probability);
    last = get_last_insn ();
!   if (false_edge->goto_locus)
!     {
!       set_curr_insn_source_location (false_edge->goto_locus);
!       set_curr_insn_block (false_edge->goto_block);
!       false_edge->goto_locus = curr_insn_locator ();
!     }
!   false_edge->goto_block = NULL;
    emit_jump (label_rtx_for_bb (false_edge->dest));

    BB_END (bb) = last;
--- 1835,1842 ----
    jumpif_1 (code, op0, op1, label_rtx_for_bb (true_edge->dest),
  	    true_edge->probability);
    last = get_last_insn ();
!   if (!IS_UNKNOWN_LOCATION (false_edge->goto_locus))
!     set_curr_insn_location (false_edge->goto_locus);
    emit_jump (label_rtx_for_bb (false_edge->dest));

    BB_END (bb) = last;
*************** expand_gimple_cond (basic_block bb, gimp
*** 1880,1892 ****

    maybe_dump_rtl_for_gimple_stmt (stmt, last2);

!   if (true_edge->goto_locus)
      {
!       set_curr_insn_source_location (true_edge->goto_locus);
!       set_curr_insn_block (true_edge->goto_block);
!       true_edge->goto_locus = curr_insn_locator ();
      }
-   true_edge->goto_block = NULL;

    return new_bb;
  }
--- 1861,1871 ----

    maybe_dump_rtl_for_gimple_stmt (stmt, last2);

!   if (!IS_UNKNOWN_LOCATION (true_edge->goto_locus))
      {
!       set_curr_insn_location (true_edge->goto_locus);
!       true_edge->goto_locus = curr_insn_location ();
      }

    return new_bb;
  }
*************** expand_call_stmt (gimple stmt)
*** 1986,1992 ****
      CALL_FROM_THUNK_P (exp) = gimple_call_from_thunk_p (stmt);
    CALL_EXPR_VA_ARG_PACK (exp) = gimple_call_va_arg_pack_p (stmt);
    SET_EXPR_LOCATION (exp, gimple_location (stmt));
-   TREE_BLOCK (exp) = gimple_block (stmt);

    /* Ensure RTL is created for debug args.  */
    if (decl && DECL_HAS_DEBUG_ARGS_P (decl))
--- 1965,1970 ----
*************** expand_gimple_stmt_1 (gimple stmt)
*** 2021,2028 ****
  {
    tree op0;

!   set_curr_insn_source_location (gimple_location (stmt));
!   set_curr_insn_block (gimple_block (stmt));

    switch (gimple_code (stmt))
      {
--- 1999,2005 ----
  {
    tree op0;

!   set_curr_insn_location (gimple_location (stmt));

    switch (gimple_code (stmt))
      {
*************** expand_gimple_basic_block (basic_block b
*** 3766,3773 ****
  	  tree op;
  	  gimple def;

! 	  location_t sloc = get_curr_insn_source_location ();
! 	  tree sblock = get_curr_insn_block ();

  	  /* Look for SSA names that have their last use here (TERed
  	     names always have only one real use).  */
--- 3743,3749 ----
  	  tree op;
  	  gimple def;

! 	  location_t sloc = curr_insn_location ();

  	  /* Look for SSA names that have their last use here (TERed
  	     names always have only one real use).  */
*************** expand_gimple_basic_block (basic_block b
*** 3800,3807 ****
  		    rtx val;
  		    enum machine_mode mode;

! 		    set_curr_insn_source_location (gimple_location (def));
! 		    set_curr_insn_block (gimple_block (def));

  		    DECL_ARTIFICIAL (vexpr) = 1;
  		    TREE_TYPE (vexpr) = TREE_TYPE (value);
--- 3776,3782 ----
  		    rtx val;
  		    enum machine_mode mode;

! 		    set_curr_insn_location (gimple_location (def));

  		    DECL_ARTIFICIAL (vexpr) = 1;
  		    TREE_TYPE (vexpr) = TREE_TYPE (value);
*************** expand_gimple_basic_block (basic_block b
*** 3828,3835 ****
  		      }
  		  }
  	      }
! 	  set_curr_insn_source_location (sloc);
! 	  set_curr_insn_block (sblock);
  	}

        currently_expanding_gimple_stmt = stmt;
--- 3803,3809 ----
  		      }
  		  }
  	      }
! 	  set_curr_insn_location (sloc);
  	}

        currently_expanding_gimple_stmt = stmt;
*************** expand_gimple_basic_block (basic_block b
*** 3844,3851 ****
  	}
        else if (gimple_debug_bind_p (stmt))
  	{
! 	  location_t sloc = get_curr_insn_source_location ();
! 	  tree sblock = get_curr_insn_block ();
  	  gimple_stmt_iterator nsi = gsi;

  	  for (;;)
--- 3818,3824 ----
  	}
        else if (gimple_debug_bind_p (stmt))
  	{
! 	  location_t sloc = curr_insn_location ();
  	  gimple_stmt_iterator nsi = gsi;

  	  for (;;)
*************** expand_gimple_basic_block (basic_block b
*** 3867,3874 ****

  	      last = get_last_insn ();

! 	      set_curr_insn_source_location (gimple_location (stmt));
! 	      set_curr_insn_block (gimple_block (stmt));

  	      if (DECL_P (var))
  		mode = DECL_MODE (var);
--- 3840,3846 ----

  	      last = get_last_insn ();

! 	      set_curr_insn_location (gimple_location (stmt));

  	      if (DECL_P (var))
  		mode = DECL_MODE (var);
*************** expand_gimple_basic_block (basic_block b
*** 3906,3918 ****
  		break;
  	    }

! 	  set_curr_insn_source_location (sloc);
! 	  set_curr_insn_block (sblock);
  	}
        else if (gimple_debug_source_bind_p (stmt))
  	{
! 	  location_t sloc = get_curr_insn_source_location ();
! 	  tree sblock = get_curr_insn_block ();
  	  tree var = gimple_debug_source_bind_get_var (stmt);
  	  tree value = gimple_debug_source_bind_get_value (stmt);
  	  rtx val;
--- 3878,3888 ----
  		break;
  	    }

! 	  set_curr_insn_location (sloc);
  	}
        else if (gimple_debug_source_bind_p (stmt))
  	{
! 	  location_t sloc = curr_insn_location ();
  	  tree var = gimple_debug_source_bind_get_var (stmt);
  	  tree value = gimple_debug_source_bind_get_value (stmt);
  	  rtx val;
*************** expand_gimple_basic_block (basic_block b
*** 3920,3927 ****

  	  last = get_last_insn ();

! 	  set_curr_insn_source_location (gimple_location (stmt));
! 	  set_curr_insn_block (gimple_block (stmt));

  	  mode = DECL_MODE (var);

--- 3890,3896 ----

  	  last = get_last_insn ();

! 	  set_curr_insn_location (gimple_location (stmt));

  	  mode = DECL_MODE (var);

*************** expand_gimple_basic_block (basic_block b
*** 3939,3946 ****
  	      PAT_VAR_LOCATION_LOC (val) = (rtx)value;
  	    }

! 	  set_curr_insn_source_location (sloc);
! 	  set_curr_insn_block (sblock);
  	}
        else
  	{
--- 3908,3914 ----
  	      PAT_VAR_LOCATION_LOC (val) = (rtx)value;
  	    }

! 	  set_curr_insn_location (sloc);
  	}
        else
  	{
*************** expand_gimple_basic_block (basic_block b
*** 3981,3993 ****
    /* Expand implicit goto and convert goto_locus.  */
    FOR_EACH_EDGE (e, ei, bb->succs)
      {
!       if (e->goto_locus && e->goto_block)
! 	{
! 	  set_curr_insn_source_location (e->goto_locus);
! 	  set_curr_insn_block (e->goto_block);
! 	  e->goto_locus = curr_insn_locator ();
! 	}
!       e->goto_block = NULL;
        if ((e->flags & EDGE_FALLTHRU) && e->dest != bb->next_bb)
  	{
  	  emit_jump (label_rtx_for_bb (e->dest));
--- 3949,3956 ----
    /* Expand implicit goto and convert goto_locus.  */
    FOR_EACH_EDGE (e, ei, bb->succs)
      {
!       if (!IS_UNKNOWN_LOCATION (e->goto_locus))
! 	set_curr_insn_location (e->goto_locus);
        if ((e->flags & EDGE_FALLTHRU) && e->dest != bb->next_bb)
  	{
  	  emit_jump (label_rtx_for_bb (e->dest));
*************** construct_exit_block (void)
*** 4107,4118 ****

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

-   /* The following insns belong to the top scope.  */
-   set_curr_insn_block (DECL_INITIAL (current_function_decl));
-
    /* Generate rtl for function exit.  */
    expand_function_end ();

--- 4070,4078 ----

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

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

*************** gimple_expand_cfg (void)
*** 4331,4350 ****

    rtl_profile_for_bb (ENTRY_BLOCK_PTR);

!   insn_locators_alloc ();
    if (!DECL_IS_BUILTIN (current_function_decl))
      {
        /* Eventually, all FEs should explicitly set function_start_locus.  */
!       if (cfun->function_start_locus == UNKNOWN_LOCATION)
!        set_curr_insn_source_location
           (DECL_SOURCE_LOCATION (current_function_decl));
        else
!        set_curr_insn_source_location (cfun->function_start_locus);
      }
    else
!     set_curr_insn_source_location (UNKNOWN_LOCATION);
!   set_curr_insn_block (DECL_INITIAL (current_function_decl));
!   prologue_locator = curr_insn_locator ();

  #ifdef INSN_SCHEDULING
    init_sched_attrs ();
--- 4291,4309 ----

    rtl_profile_for_bb (ENTRY_BLOCK_PTR);

!   insn_locations_init ();
    if (!DECL_IS_BUILTIN (current_function_decl))
      {
        /* Eventually, all FEs should explicitly set function_start_locus.  */
!       if (IS_UNKNOWN_LOCATION (cfun->function_start_locus))
!        set_curr_insn_location
           (DECL_SOURCE_LOCATION (current_function_decl));
        else
!        set_curr_insn_location (cfun->function_start_locus);
      }
    else
!     set_curr_insn_location (UNKNOWN_LOCATION);
!   prologue_location = curr_insn_location ();

  #ifdef INSN_SCHEDULING
    init_sched_attrs ();
*************** gimple_expand_cfg (void)
*** 4514,4521 ****
    free_histograms ();

    construct_exit_block ();
!   set_curr_insn_block (DECL_INITIAL (current_function_decl));
!   insn_locators_finalize ();

    /* Zap the tree EH table.  */
    set_eh_throw_stmt_table (cfun, NULL);
--- 4473,4479 ----
    free_histograms ();

    construct_exit_block ();
!   insn_locations_finalize ();

    /* Zap the tree EH table.  */
    set_eh_throw_stmt_table (cfun, NULL);
Index: gcc/cfgcleanup.c
===================================================================
*** gcc/cfgcleanup.c	(revision 189835)
--- gcc/cfgcleanup.c	(working copy)
*************** try_forward_edges (int mode, basic_block
*** 481,493 ****
  		  int new_locus = single_succ_edge (target)->goto_locus;
  		  int locus = goto_locus;

! 		  if (new_locus && locus && !locator_eq (new_locus, locus))
  		    new_target = NULL;
  		  else
  		    {
  		      rtx last;

! 		      if (new_locus)
  			locus = new_locus;

  		      last = BB_END (target);
--- 481,495 ----
  		  int new_locus = single_succ_edge (target)->goto_locus;
  		  int locus = goto_locus;

! 		  if (!IS_UNKNOWN_LOCATION (new_locus)
! 		      && !IS_UNKNOWN_LOCATION (locus)
! 		      && new_locus != locus)
  		    new_target = NULL;
  		  else
  		    {
  		      rtx last;

! 		      if (!IS_UNKNOWN_LOCATION (new_locus))
  			locus = new_locus;

  		      last = BB_END (target);
*************** try_forward_edges (int mode, basic_block
*** 495,507 ****
  			last = prev_nondebug_insn (last);

  		      new_locus = last && INSN_P (last)
! 				  ? INSN_LOCATOR (last) : 0;

! 		      if (new_locus && locus && !locator_eq (new_locus, locus))
  			new_target = NULL;
  		      else
  			{
! 			  if (new_locus)
  			    locus = new_locus;

  			  goto_locus = locus;
--- 497,511 ----
  			last = prev_nondebug_insn (last);

  		      new_locus = last && INSN_P (last)
! 				  ? INSN_LOCATION (last) : 0;

! 		      if (!IS_UNKNOWN_LOCATION (new_locus)
! 			  && !IS_UNKNOWN_LOCATION (locus)
! 			  && new_locus != locus)
  			new_target = NULL;
  		      else
  			{
! 			  if (!IS_UNKNOWN_LOCATION (new_locus))
  			    locus = new_locus;

  			  goto_locus = locus;
Index: gcc/tree-ssa-live.c
===================================================================
*** gcc/tree-ssa-live.c	(revision 189835)
--- gcc/tree-ssa-live.c	(working copy)
*************** remove_unused_scope_block_p (tree scope,
*** 587,593 ****
     else
     /* Verfify that only blocks with source location set
        are entry points to the inlined functions.  */
!      gcc_assert (BLOCK_SOURCE_LOCATION (scope) == UNKNOWN_LOCATION);

     TREE_USED (scope) = !unused;
     return unused;
--- 587,593 ----
     else
     /* Verfify that only blocks with source location set
        are entry points to the inlined functions.  */
!      gcc_assert (IS_UNKNOWN_LOCATION (BLOCK_SOURCE_LOCATION (scope)));

     TREE_USED (scope) = !unused;
     return unused;
*************** dump_scope_block (FILE *file, int indent
*** 615,621 ****
    fprintf (file, "\n%*s{ Scope block #%i%s%s",indent, "" ,
BLOCK_NUMBER (scope),
    	   TREE_USED (scope) ? "" : " (unused)",
  	   BLOCK_ABSTRACT (scope) ? " (abstract)": "");
!   if (BLOCK_SOURCE_LOCATION (scope) != UNKNOWN_LOCATION)
      {
        expanded_location s = expand_location (BLOCK_SOURCE_LOCATION (scope));
        fprintf (file, " %s:%i", s.file, s.line);
--- 615,621 ----
    fprintf (file, "\n%*s{ Scope block #%i%s%s",indent, "" ,
BLOCK_NUMBER (scope),
    	   TREE_USED (scope) ? "" : " (unused)",
  	   BLOCK_ABSTRACT (scope) ? " (abstract)": "");
!   if (!IS_UNKNOWN_LOCATION (BLOCK_SOURCE_LOCATION (scope)))
      {
        expanded_location s = expand_location (BLOCK_SOURCE_LOCATION (scope));
        fprintf (file, " %s:%i", s.file, s.line);
*************** remove_unused_locals (void)
*** 765,777 ****
            FOR_EACH_PHI_ARG (arg_p, phi, i, SSA_OP_ALL_USES)
              {
  	      tree arg = USE_FROM_PTR (arg_p);
  	      mark_all_vars_used (&arg, global_unused_vars);
              }
          }

        FOR_EACH_EDGE (e, ei, bb->succs)
  	if (e->goto_locus)
! 	  TREE_USED (e->goto_block) = true;
      }

    /* We do a two-pass approach about the out-of-scope clobbers.  We want
--- 765,782 ----
            FOR_EACH_PHI_ARG (arg_p, phi, i, SSA_OP_ALL_USES)
              {
  	      tree arg = USE_FROM_PTR (arg_p);
+ 	      int index = PHI_ARG_INDEX_FROM_USE (arg_p);
+ 	      tree block =
+ 		LOCATION_BLOCK (gimple_phi_arg_location (phi, index));
+ 	      if (block != NULL)
+ 		TREE_USED (block) = true;
  	      mark_all_vars_used (&arg, global_unused_vars);
              }
          }

        FOR_EACH_EDGE (e, ei, bb->succs)
  	if (e->goto_locus)
! 	  TREE_USED (LOCATION_BLOCK (e->goto_locus)) = true;
      }

    /* We do a two-pass approach about the out-of-scope clobbers.  We want
Index: gcc/lto/lto.c
===================================================================
*** gcc/lto/lto.c	(revision 189835)
--- gcc/lto/lto.c	(working copy)
*************** lto_fixup_prevailing_decls (tree t)
*** 1603,1609 ****
    else if (EXPR_P (t))
      {
        int i;
-       LTO_NO_PREVAIL (t->exp.block);
        for (i = TREE_OPERAND_LENGTH (t) - 1; i >= 0; --i)
  	LTO_SET_PREVAIL (TREE_OPERAND (t, i));
      }
--- 1603,1608 ----
Index: gcc/tree-streamer-out.c
===================================================================
*** gcc/tree-streamer-out.c	(revision 189835)
--- gcc/tree-streamer-out.c	(working copy)
*************** write_ts_decl_minimal_tree_pointers (str
*** 471,477 ****
  {
    stream_write_tree (ob, DECL_NAME (expr), ref_p);
    stream_write_tree (ob, DECL_CONTEXT (expr), ref_p);
!   lto_output_location (ob, DECL_SOURCE_LOCATION (expr));
  }


--- 471,477 ----
  {
    stream_write_tree (ob, DECL_NAME (expr), ref_p);
    stream_write_tree (ob, DECL_CONTEXT (expr), ref_p);
!   lto_output_location (ob, LOCATION_LOCUS (DECL_SOURCE_LOCATION (expr)));
  }


*************** write_ts_exp_tree_pointers (struct outpu
*** 668,674 ****
    streamer_write_hwi (ob, TREE_OPERAND_LENGTH (expr));
    for (i = 0; i < TREE_OPERAND_LENGTH (expr); i++)
      stream_write_tree (ob, TREE_OPERAND (expr, i), ref_p);
!   lto_output_location (ob, EXPR_LOCATION (expr));
    stream_write_tree (ob, TREE_BLOCK (expr), ref_p);
  }

--- 668,674 ----
    streamer_write_hwi (ob, TREE_OPERAND_LENGTH (expr));
    for (i = 0; i < TREE_OPERAND_LENGTH (expr); i++)
      stream_write_tree (ob, TREE_OPERAND (expr, i), ref_p);
!   lto_output_location (ob, LOCATION_LOCUS (EXPR_LOCATION (expr)));
    stream_write_tree (ob, TREE_BLOCK (expr), ref_p);
  }

Index: gcc/rtl.c
===================================================================
*** gcc/rtl.c	(revision 189835)
--- gcc/rtl.c	(working copy)
*************** rtx_equal_p_cb (const_rtx x, const_rtx y
*** 440,446 ****
  #ifndef GENERATOR_FILE
  	      if (((code == ASM_OPERANDS && i == 6)
  		   || (code == ASM_INPUT && i == 1))
! 		  && locator_eq (XINT (x, i), XINT (y, i)))
  		break;
  #endif
  	      return 0;
--- 440,446 ----
  #ifndef GENERATOR_FILE
  	      if (((code == ASM_OPERANDS && i == 6)
  		   || (code == ASM_INPUT && i == 1))
! 		  && XINT (x, i) == XINT (y, i))
  		break;
  #endif
  	      return 0;
*************** rtx_equal_p (const_rtx x, const_rtx y)
*** 579,585 ****
  #ifndef GENERATOR_FILE
  	      if (((code == ASM_OPERANDS && i == 6)
  		   || (code == ASM_INPUT && i == 1))
! 		  && locator_eq (XINT (x, i), XINT (y, i)))
  		break;
  #endif
  	      return 0;
--- 579,585 ----
  #ifndef GENERATOR_FILE
  	      if (((code == ASM_OPERANDS && i == 6)
  		   || (code == ASM_INPUT && i == 1))
! 		  && XINT (x, i) == XINT (y, i))
  		break;
  #endif
  	      return 0;
Index: gcc/rtl.h
===================================================================
*** gcc/rtl.h	(revision 189835)
--- gcc/rtl.h	(working copy)
*************** extern void rtl_check_failed_flag (const
*** 739,744 ****
--- 739,745 ----
  #endif

  #define XINT(RTX, N)	(RTL_CHECK2 (RTX, N, 'i', 'n').rt_int)
+ #define XUINT(RTX, N)   (RTL_CHECK2 (RTX, N, 'i', 'n').rt_uint)
  #define XSTR(RTX, N)	(RTL_CHECK2 (RTX, N, 's', 'S').rt_str)
  #define XEXP(RTX, N)	(RTL_CHECK2 (RTX, N, 'e', 'u').rt_rtx)
  #define XVEC(RTX, N)	(RTL_CHECK2 (RTX, N, 'E', 'V').rt_rtvec)
*************** extern void rtl_check_failed_flag (const
*** 802,814 ****
  /* The body of an insn.  */
  #define PATTERN(INSN)	XEXP (INSN, 4)

! #define INSN_LOCATOR(INSN) XINT (INSN, 5)
  /* LOCATION of an RTX if relevant.  */
  #define RTL_LOCATION(X) (INSN_P (X) ? \
! 			 locator_location (INSN_LOCATOR (X)) \
! 			 : UNKNOWN_LOCATION)
! /* LOCATION of current INSN.  */
! #define CURR_INSN_LOCATION (locator_location (curr_insn_locator ()))

  /* Code number of instruction, from when it was recognized.
     -1 means this instruction has not been recognized yet.  */
--- 803,815 ----
  /* The body of an insn.  */
  #define PATTERN(INSN)	XEXP (INSN, 4)

! #define INSN_LOCATION(INSN) XUINT (INSN, 5)
!
! #define INSN_HAS_LOCATION(INSN) (!IS_UNKNOWN_LOCATION (INSN_LOCATION (INSN)))
!
  /* LOCATION of an RTX if relevant.  */
  #define RTL_LOCATION(X) (INSN_P (X) ? \
! 			 INSN_LOCATION (X) : UNKNOWN_LOCATION)

  /* Code number of instruction, from when it was recognized.
     -1 means this instruction has not been recognized yet.  */
*************** extern rtx prev_cc0_setter (rtx);
*** 1807,1818 ****
  /* In emit-rtl.c  */
  extern int insn_line (const_rtx);
  extern const char * insn_file (const_rtx);
- extern location_t locator_location (int);
- extern int locator_line (int);
- extern const char * locator_file (int);
- extern bool locator_eq (int, int);
- extern int prologue_locator, epilogue_locator;
  extern tree insn_scope (const_rtx);

  /* In jump.c */
  extern enum rtx_code reverse_condition (enum rtx_code);
--- 1808,1815 ----
  /* In emit-rtl.c  */
  extern int insn_line (const_rtx);
  extern const char * insn_file (const_rtx);
  extern tree insn_scope (const_rtx);
+ extern location_t prologue_location, epilogue_location;

  /* In jump.c */
  extern enum rtx_code reverse_condition (enum rtx_code);
*************** extern const struct rtl_hooks general_rt
*** 2648,2661 ****
  /* Keep this for the nonce.  */
  #define gen_lowpart rtl_hooks.gen_lowpart

! extern void insn_locators_alloc (void);
! extern void insn_locators_free (void);
! extern void insn_locators_finalize (void);
! extern void set_curr_insn_source_location (location_t);
! extern location_t get_curr_insn_source_location (void);
! extern void set_curr_insn_block (tree);
! extern tree get_curr_insn_block (void);
! extern int curr_insn_locator (void);
  extern bool optimize_insn_for_size_p (void);
  extern bool optimize_insn_for_speed_p (void);

--- 2645,2654 ----
  /* Keep this for the nonce.  */
  #define gen_lowpart rtl_hooks.gen_lowpart

! extern void insn_locations_init (void);
! extern void insn_locations_finalize (void);
! extern void set_curr_insn_location (location_t);
! extern location_t curr_insn_location (void);
  extern bool optimize_insn_for_size_p (void);
  extern bool optimize_insn_for_speed_p (void);

Index: gcc/tree-inline.c
===================================================================
*** gcc/tree-inline.c	(revision 189835)
--- gcc/tree-inline.c	(working copy)
*************** remap_gimple_op_r (tree *tp, int *walk_s
*** 852,861 ****
        /* Otherwise, just copy the node.  Note that copy_tree_r already
  	 knows not to copy VAR_DECLs, etc., so this is safe.  */

-       /* We should never have TREE_BLOCK set on non-statements.  */
-       if (EXPR_P (*tp))
- 	gcc_assert (!TREE_BLOCK (*tp));
-
        if (TREE_CODE (*tp) == MEM_REF)
  	{
  	  tree ptr = TREE_OPERAND (*tp, 0);
--- 852,857 ----
*************** remap_gimple_op_r (tree *tp, int *walk_s
*** 901,913 ****
  	{
  	  /* Variable substitution need not be simple.  In particular,
  	     the MEM_REF substitution above.  Make sure that
! 	     TREE_CONSTANT and friends are up-to-date.  But make sure
! 	     to not improperly set TREE_BLOCK on some sub-expressions.  */
  	  int invariant = is_gimple_min_invariant (*tp);
- 	  tree block = id->block;
- 	  id->block = NULL_TREE;
  	  walk_tree (&TREE_OPERAND (*tp, 0), remap_gimple_op_r, data, NULL);
- 	  id->block = block;
  	  recompute_tree_invariant_for_addr_expr (*tp);

  	  /* If this used to be invariant, but is not any longer,
--- 897,905 ----
  	{
  	  /* Variable substitution need not be simple.  In particular,
  	     the MEM_REF substitution above.  Make sure that
! 	     TREE_CONSTANT and friends are up-to-date.  */
  	  int invariant = is_gimple_min_invariant (*tp);
  	  walk_tree (&TREE_OPERAND (*tp, 0), remap_gimple_op_r, data, NULL);
  	  recompute_tree_invariant_for_addr_expr (*tp);

  	  /* If this used to be invariant, but is not any longer,
*************** remap_gimple_op_r (tree *tp, int *walk_s
*** 919,924 ****
--- 911,932 ----
  	}
      }

+   /* Update the TREE_BLOCK for the cloned expr.  */
+   if (EXPR_P (*tp))
+     {
+       tree new_block = id->remapping_type_depth == 0 ? id->block : NULL;
+       tree old_block = TREE_BLOCK (*tp);
+       if (old_block)
+ 	{
+ 	  tree *n;
+ 	  n = (tree *) pointer_map_contains (id->decl_map,
+ 					     TREE_BLOCK (*tp));
+ 	  if (n)
+ 	    new_block = *n;
+ 	}
+       TREE_SET_BLOCK (*tp, new_block);
+     }
+
    /* Keep iterating.  */
    return NULL_TREE;
  }
*************** copy_tree_body_r (tree *tp, int *walk_su
*** 1144,1154 ****
  	      tree *n;
  	      n = (tree *) pointer_map_contains (id->decl_map,
  						 TREE_BLOCK (*tp));
- 	      gcc_assert (n || id->remapping_type_depth != 0);
  	      if (n)
  		new_block = *n;
  	    }
! 	  TREE_BLOCK (*tp) = new_block;
  	}

        if (TREE_CODE (*tp) != OMP_CLAUSE)
--- 1152,1161 ----
  	      tree *n;
  	      n = (tree *) pointer_map_contains (id->decl_map,
  						 TREE_BLOCK (*tp));
  	      if (n)
  		new_block = *n;
  	    }
! 	  TREE_SET_BLOCK (*tp, new_block);
  	}

        if (TREE_CODE (*tp) != OMP_CLAUSE)
*************** copy_phis_for_bb (basic_block bb, copy_b
*** 2020,2025 ****
--- 2027,2033 ----
  	      tree new_arg;
  	      tree block = id->block;
  	      edge_iterator ei2;
+ 	      location_t locus;

  	      /* When doing partial cloning, we allow PHIs on the entry block
  		 as long as all the arguments are the same.  Find any input
*************** copy_phis_for_bb (basic_block bb, copy_b
*** 2031,2039 ****

  	      arg = PHI_ARG_DEF_FROM_EDGE (phi, old_edge);
  	      new_arg = arg;
- 	      id->block = NULL_TREE;
  	      walk_tree (&new_arg, copy_tree_body_r, id, NULL);
- 	      id->block = block;
  	      gcc_assert (new_arg);
  	      /* With return slot optimization we can end up with
  	         non-gimple (foo *)&this->m, fix that here.  */
--- 2039,2045 ----
*************** copy_phis_for_bb (basic_block bb, copy_b
*** 2046,2053 ****
  		  gsi_insert_seq_on_edge (new_edge, stmts);
  		  inserted = true;
  		}
  	      add_phi_arg (new_phi, new_arg, new_edge,
! 			   gimple_phi_arg_location_from_edge (phi, old_edge));
  	    }
  	}
      }
--- 2052,2070 ----
  		  gsi_insert_seq_on_edge (new_edge, stmts);
  		  inserted = true;
  		}
+ 	      locus = gimple_phi_arg_location_from_edge (phi, old_edge);
+ 	      block = id->block;
+ 	      if (LOCATION_BLOCK (locus))
+ 		{
+ 		  tree *n;
+ 		  n = (tree *) pointer_map_contains (id->decl_map,
+ 			LOCATION_BLOCK (locus));
+ 		  gcc_assert (n);
+ 		  block = *n;
+ 		}
+
  	      add_phi_arg (new_phi, new_arg, new_edge,
! 			   COMBINE_LOCATION (locus, block));
  	    }
  	}
      }
*************** expand_call_inline (basic_block bb, gimp
*** 3946,3952 ****
    id->block = make_node (BLOCK);
    BLOCK_ABSTRACT_ORIGIN (id->block) = fn;
    BLOCK_SOURCE_LOCATION (id->block) = input_location;
!   prepend_lexical_block (gimple_block (stmt), id->block);

    /* Local declarations will be replaced by their equivalents in this
       map.  */
--- 3963,3970 ----
    id->block = make_node (BLOCK);
    BLOCK_ABSTRACT_ORIGIN (id->block) = fn;
    BLOCK_SOURCE_LOCATION (id->block) = input_location;
!   if (gimple_block (stmt))
!     prepend_lexical_block (gimple_block (stmt), id->block);

    /* Local declarations will be replaced by their equivalents in this
       map.  */
Index: gcc/tree-streamer-in.c
===================================================================
*** gcc/tree-streamer-in.c	(revision 189835)
--- gcc/tree-streamer-in.c	(working copy)
*************** lto_input_ts_exp_tree_pointers (struct l
*** 776,782 ****

    loc = lto_input_location (ib, data_in);
    SET_EXPR_LOCATION (expr, loc);
!   TREE_BLOCK (expr) = stream_read_tree (ib, data_in);
  }


--- 776,782 ----

    loc = lto_input_location (ib, data_in);
    SET_EXPR_LOCATION (expr, loc);
!   TREE_SET_BLOCK (expr, stream_read_tree (ib, data_in));
  }


Index: gcc/combine.c
===================================================================
*** gcc/combine.c	(revision 189835)
--- gcc/combine.c	(working copy)
*************** try_combine (rtx i3, rtx i2, rtx i1, rtx
*** 2896,2902 ****

  	  i1 = gen_rtx_INSN (VOIDmode, INSN_UID (i2), NULL_RTX, i2,
  			     BLOCK_FOR_INSN (i2), XVECEXP (PATTERN (i2), 0, 1),
! 			     INSN_LOCATOR (i2), -1, NULL_RTX);

  	  SUBST (PATTERN (i2), XVECEXP (PATTERN (i2), 0, 0));
  	  SUBST (XEXP (SET_SRC (PATTERN (i2)), 0),
--- 2896,2902 ----

  	  i1 = gen_rtx_INSN (VOIDmode, INSN_UID (i2), NULL_RTX, i2,
  			     BLOCK_FOR_INSN (i2), XVECEXP (PATTERN (i2), 0, 1),
! 			     INSN_LOCATION (i2), -1, NULL_RTX);

  	  SUBST (PATTERN (i2), XVECEXP (PATTERN (i2), 0, 0));
  	  SUBST (XEXP (SET_SRC (PATTERN (i2)), 0),
Index: gcc/tree-outof-ssa.c
===================================================================
*** gcc/tree-outof-ssa.c	(revision 189835)
--- gcc/tree-outof-ssa.c	(working copy)
*************** set_location_for_edge (edge e)
*** 108,115 ****
  {
    if (e->goto_locus)
      {
!       set_curr_insn_source_location (e->goto_locus);
!       set_curr_insn_block (e->goto_block);
      }
    else
      {
--- 108,114 ----
  {
    if (e->goto_locus)
      {
!       set_curr_insn_location (e->goto_locus);
      }
    else
      {
*************** set_location_for_edge (edge e)
*** 125,132 ****
  		continue;
  	      if (gimple_has_location (stmt) || gimple_block (stmt))
  		{
! 		  set_curr_insn_source_location (gimple_location (stmt));
! 		  set_curr_insn_block (gimple_block (stmt));
  		  return;
  		}
  	    }
--- 124,130 ----
  		continue;
  	      if (gimple_has_location (stmt) || gimple_block (stmt))
  		{
! 		  set_curr_insn_location (gimple_location (stmt));
  		  return;
  		}
  	    }
*************** insert_partition_copy_on_edge (edge e, i
*** 191,197 ****
    set_location_for_edge (e);
    /* If a locus is provided, override the default.  */
    if (locus)
!     set_curr_insn_source_location (locus);

    var = partition_to_var (SA.map, src);
    seq = emit_partition_copy (SA.partition_to_pseudo[dest],
--- 189,195 ----
    set_location_for_edge (e);
    /* If a locus is provided, override the default.  */
    if (locus)
!     set_curr_insn_location (locus);

    var = partition_to_var (SA.map, src);
    seq = emit_partition_copy (SA.partition_to_pseudo[dest],
*************** insert_value_copy_on_edge (edge e, int d
*** 228,234 ****
    set_location_for_edge (e);
    /* If a locus is provided, override the default.  */
    if (locus)
!     set_curr_insn_source_location (locus);

    start_sequence ();

--- 226,232 ----
    set_location_for_edge (e);
    /* If a locus is provided, override the default.  */
    if (locus)
!     set_curr_insn_location (locus);

    start_sequence ();

*************** insert_rtx_to_part_on_edge (edge e, int
*** 284,290 ****
    set_location_for_edge (e);
    /* If a locus is provided, override the default.  */
    if (locus)
!     set_curr_insn_source_location (locus);

    /* We give the destination as sizeexp in case src/dest are BLKmode
       mems.  Usually we give the source.  As we result from SSA names
--- 282,288 ----
    set_location_for_edge (e);
    /* If a locus is provided, override the default.  */
    if (locus)
!     set_curr_insn_location (locus);

    /* We give the destination as sizeexp in case src/dest are BLKmode
       mems.  Usually we give the source.  As we result from SSA names
*************** insert_part_to_rtx_on_edge (edge e, rtx
*** 320,326 ****
    set_location_for_edge (e);
    /* If a locus is provided, override the default.  */
    if (locus)
!     set_curr_insn_source_location (locus);

    var = partition_to_var (SA.map, src);
    seq = emit_partition_copy (dest,
--- 318,324 ----
    set_location_for_edge (e);
    /* If a locus is provided, override the default.  */
    if (locus)
!     set_curr_insn_location (locus);

    var = partition_to_var (SA.map, src);
    seq = emit_partition_copy (dest,
Index: gcc/basic-block.h
===================================================================
*** gcc/basic-block.h	(revision 189835)
--- gcc/basic-block.h	(working copy)
*************** struct GTY(()) edge_def {
*** 47,54 ****
    /* Auxiliary info specific to a pass.  */
    PTR GTY ((skip (""))) aux;

!   /* Location of any goto implicit in the edge and associated BLOCK.  */
!   tree goto_block;
    location_t goto_locus;

    /* The index number corresponding to this edge in the edge vector
--- 47,53 ----
    /* Auxiliary info specific to a pass.  */
    PTR GTY ((skip (""))) aux;

!   /* Location of any goto implicit in the edge.  */
    location_t goto_locus;

    /* The index number corresponding to this edge in the edge vector
Index: gcc/gimple.h
===================================================================
*** gcc/gimple.h	(revision 189835)
--- gcc/gimple.h	(working copy)
*************** struct GTY(()) gimple_statement_base {
*** 210,219 ****
       and the prev pointer being the last.  */
    gimple next;
    gimple GTY((skip)) prev;
-
-   /* [ WORD 6 ]
-      Lexical block holding this statement.  */
-   tree block;
  };


--- 210,215 ----
*************** gimple_bb (const_gimple g)
*** 1198,1204 ****
  static inline tree
  gimple_block (const_gimple g)
  {
!   return g->gsbase.block;
  }


--- 1194,1200 ----
  static inline tree
  gimple_block (const_gimple g)
  {
!   return LOCATION_BLOCK (g->gsbase.location);
  }


*************** gimple_block (const_gimple g)
*** 1207,1213 ****
  static inline void
  gimple_set_block (gimple g, tree block)
  {
!   g->gsbase.block = block;
  }


--- 1203,1209 ----
  static inline void
  gimple_set_block (gimple g, tree block)
  {
!   g->gsbase.location = COMBINE_LOCATION (g->gsbase.location, block);
  }


*************** gimple_set_location (gimple g, location_
*** 1242,1248 ****
  static inline bool
  gimple_has_location (const_gimple g)
  {
!   return gimple_location (g) != UNKNOWN_LOCATION;
  }


--- 1238,1244 ----
  static inline bool
  gimple_has_location (const_gimple g)
  {
!   return !IS_UNKNOWN_LOCATION (gimple_location (g));
  }


Index: gcc/tree-cfg.c
===================================================================
*** gcc/tree-cfg.c	(revision 189835)
--- gcc/tree-cfg.c	(working copy)
*************** make_cond_expr_edges (basic_block bb)
*** 808,822 ****
    e = make_edge (bb, then_bb, EDGE_TRUE_VALUE);
    assign_discriminator (entry_locus, then_bb);
    e->goto_locus = gimple_location (then_stmt);
-   if (e->goto_locus)
-     e->goto_block = gimple_block (then_stmt);
    e = make_edge (bb, else_bb, EDGE_FALSE_VALUE);
    if (e)
      {
        assign_discriminator (entry_locus, else_bb);
        e->goto_locus = gimple_location (else_stmt);
-       if (e->goto_locus)
- 	e->goto_block = gimple_block (else_stmt);
      }

    /* We do not need the labels anymore.  */
--- 808,818 ----
*************** make_goto_expr_edges (basic_block bb)
*** 1026,1033 ****
        edge e = make_edge (bb, label_bb, EDGE_FALLTHRU);
        e->goto_locus = gimple_location (goto_t);
        assign_discriminator (e->goto_locus, label_bb);
-       if (e->goto_locus)
- 	e->goto_block = gimple_block (goto_t);
        gsi_remove (&last, true);
        return;
      }
--- 1022,1027 ----
*************** gimple_can_merge_blocks_p (basic_block a
*** 1501,1507 ****

    /* When not optimizing, don't merge if we'd lose goto_locus.  */
    if (!optimize
!       && single_succ_edge (a)->goto_locus != UNKNOWN_LOCATION)
      {
        location_t goto_locus = single_succ_edge (a)->goto_locus;
        gimple_stmt_iterator prev, next;
--- 1495,1501 ----

    /* When not optimizing, don't merge if we'd lose goto_locus.  */
    if (!optimize
!       && single_succ_edge (a)->goto_locus)
      {
        location_t goto_locus = single_succ_edge (a)->goto_locus;
        gimple_stmt_iterator prev, next;
*************** move_stmt_op (tree *tp, int *walk_subtre
*** 5987,5995 ****
    tree t = *tp;

    if (EXPR_P (t))
!     /* We should never have TREE_BLOCK set on non-statements.  */
!     gcc_assert (!TREE_BLOCK (t));
!
    else if (DECL_P (t) || TREE_CODE (t) == SSA_NAME)
      {
        if (TREE_CODE (t) == SSA_NAME)
--- 5981,5987 ----
    tree t = *tp;

    if (EXPR_P (t))
!     ;
    else if (DECL_P (t) || TREE_CODE (t) == SSA_NAME)
      {
        if (TREE_CODE (t) == SSA_NAME)
*************** move_block_to_fn (struct function *dest_
*** 6294,6305 ****
      }

    FOR_EACH_EDGE (e, ei, bb->succs)
!     if (e->goto_locus)
        {
! 	tree block = e->goto_block;
  	if (d->orig_block == NULL_TREE
  	    || block == d->orig_block)
! 	  e->goto_block = d->new_block;
  #ifdef ENABLE_CHECKING
  	else if (block != d->new_block)
  	  {
--- 6286,6297 ----
      }

    FOR_EACH_EDGE (e, ei, bb->succs)
!     if (!IS_UNKNOWN_LOCATION (e->goto_locus))
        {
! 	tree block = LOCATION_BLOCK (e->goto_locus);
  	if (d->orig_block == NULL_TREE
  	    || block == d->orig_block)
! 	  e->goto_locus = COMBINE_LOCATION (e->goto_locus, d->new_block);
  #ifdef ENABLE_CHECKING
  	else if (block != d->new_block)
  	  {
Index: gcc/config/alpha/alpha.c
===================================================================
*** gcc/config/alpha/alpha.c	(revision 189835)
--- gcc/config/alpha/alpha.c	(working copy)
*************** alpha_output_mi_thunk_osf (FILE *file, t
*** 8352,8358 ****
       instruction scheduling worth while.  Note that use_thunk calls
       assemble_start_function and assemble_end_function.  */
    insn = get_insns ();
-   insn_locators_alloc ();
    shorten_branches (insn);
    final_start_function (insn, file, 1);
    final (insn, file, 1);
--- 8352,8357 ----
Index: gcc/config/sparc/sparc.c
===================================================================
*** gcc/config/sparc/sparc.c	(revision 189835)
--- gcc/config/sparc/sparc.c	(working copy)
*************** sparc_output_mi_thunk (FILE *file, tree
*** 10654,10660 ****
       instruction scheduling worth while.  Note that use_thunk calls
       assemble_start_function and assemble_end_function.  */
    insn = get_insns ();
-   insn_locators_alloc ();
    shorten_branches (insn);
    final_start_function (insn, file, 1);
    final (insn, file, 1);
--- 10654,10659 ----
Index: gcc/config/i386/i386.c
===================================================================
*** gcc/config/i386/i386.c	(revision 189835)
--- gcc/config/i386/i386.c	(working copy)
*************** x86_output_mi_thunk (FILE *file,
*** 33063,33069 ****
    /* Emit just enough of rest_of_compilation to get the insns emitted.
       Note that use_thunk calls assemble_start_function et al.  */
    tmp = get_insns ();
-   insn_locators_alloc ();
    shorten_branches (tmp);
    final_start_function (tmp, file, 1);
    final (tmp, file, 1);
--- 33063,33068 ----
Index: gcc/config/tilegx/tilegx.c
===================================================================
*** gcc/config/tilegx/tilegx.c	(revision 189835)
--- gcc/config/tilegx/tilegx.c	(working copy)
*************** tilegx_output_mi_thunk (FILE *file, tree
*** 4804,4810 ****
       serial except for the tail call, so we're only wasting one cycle.
     */
    insn = get_insns ();
-   insn_locators_alloc ();
    shorten_branches (insn);
    final_start_function (insn, file, 1);
    final (insn, file, 1);
--- 4804,4809 ----
Index: gcc/config/sh/sh.c
===================================================================
*** gcc/config/sh/sh.c	(revision 189835)
--- gcc/config/sh/sh.c	(working copy)
*************** sh_output_mi_thunk (FILE *file, tree thu
*** 11979,11985 ****
       the insns emitted.  Note that use_thunk calls
       assemble_start_function and assemble_end_function.  */

-   insn_locators_alloc ();
    insns = get_insns ();

    if (optimize > 0)
--- 11979,11984 ----
Index: gcc/config/ia64/ia64.c
===================================================================
*** gcc/config/ia64/ia64.c	(revision 189835)
--- gcc/config/ia64/ia64.c	(working copy)
*************** ia64_output_mi_thunk (FILE *file, tree t
*** 10848,10854 ****
       instruction scheduling worth while.  Note that use_thunk calls
       assemble_start_function and assemble_end_function.  */

-   insn_locators_alloc ();
    emit_all_insn_group_barriers (NULL);
    insn = get_insns ();
    shorten_branches (insn);
--- 10848,10853 ----
Index: gcc/config/rs6000/rs6000.c
===================================================================
*** gcc/config/rs6000/rs6000.c	(revision 189835)
--- gcc/config/rs6000/rs6000.c	(working copy)
*************** rs6000_output_mi_thunk (FILE *file, tree
*** 21664,21670 ****
       instruction scheduling worth while.  Note that use_thunk calls
       assemble_start_function and assemble_end_function.  */
    insn = get_insns ();
-   insn_locators_alloc ();
    shorten_branches (insn);
    final_start_function (insn, file, 1);
    final (insn, file, 1);
--- 21664,21669 ----
Index: gcc/config/score/score.c
===================================================================
*** gcc/config/score/score.c	(revision 189835)
--- gcc/config/score/score.c	(working copy)
*************** score_output_mi_thunk (FILE *file, tree
*** 505,511 ****
    /* Run just enough of rest_of_compilation.  This sequence was
       "borrowed" from alpha.c.  */
    insn = get_insns ();
-   insn_locators_alloc ();
    split_all_insns_noflow ();
    shorten_branches (insn);
    final_start_function (insn, file, 1);
--- 505,510 ----
Index: gcc/config/tilepro/tilepro.c
===================================================================
*** gcc/config/tilepro/tilepro.c	(revision 189835)
--- gcc/config/tilepro/tilepro.c	(working copy)
*************** tilepro_asm_output_mi_thunk (FILE *file,
*** 4407,4413 ****
       serial except for the tail call, so we're only wasting one cycle.
     */
    insn = get_insns ();
-   insn_locators_alloc ();
    shorten_branches (insn);
    final_start_function (insn, file, 1);
    final (insn, file, 1);
--- 4407,4412 ----
Index: gcc/config/mips/mips.c
===================================================================
*** gcc/config/mips/mips.c	(revision 189835)
--- gcc/config/mips/mips.c	(working copy)
*************** mips_output_mi_thunk (FILE *file, tree t
*** 15637,15643 ****
    /* Run just enough of rest_of_compilation.  This sequence was
       "borrowed" from alpha.c.  */
    insn = get_insns ();
-   insn_locators_alloc ();
    split_all_insns_noflow ();
    mips16_lay_out_constants ();
    shorten_branches (insn);
--- 15637,15642 ----
Index: gcc/cfgrtl.c
===================================================================
*** gcc/cfgrtl.c	(revision 189835)
--- gcc/cfgrtl.c	(working copy)
*************** rtl_split_block (basic_block bb, void *i
*** 720,738 ****
  static bool
  unique_locus_on_edge_between_p (basic_block a, basic_block b)
  {
!   const int goto_locus = EDGE_SUCC (a, 0)->goto_locus;
    rtx insn, end;

!   if (!goto_locus)
      return false;

    /* First scan block A backward.  */
    insn = BB_END (a);
    end = PREV_INSN (BB_HEAD (a));
!   while (insn != end && (!NONDEBUG_INSN_P (insn) || INSN_LOCATOR (insn) == 0))
      insn = PREV_INSN (insn);

!   if (insn != end && locator_eq (INSN_LOCATOR (insn), goto_locus))
      return false;

    /* Then scan block B forward.  */
--- 720,738 ----
  static bool
  unique_locus_on_edge_between_p (basic_block a, basic_block b)
  {
!   const location_t goto_locus = EDGE_SUCC (a, 0)->goto_locus;
    rtx insn, end;

!   if (IS_UNKNOWN_LOCATION (goto_locus))
      return false;

    /* First scan block A backward.  */
    insn = BB_END (a);
    end = PREV_INSN (BB_HEAD (a));
!   while (insn != end && (!NONDEBUG_INSN_P (insn) ||
!INSN_HAS_LOCATION (insn)))
      insn = PREV_INSN (insn);

!   if (insn != end && INSN_LOCATION (insn) == goto_locus)
      return false;

    /* Then scan block B forward.  */
*************** unique_locus_on_edge_between_p (basic_bl
*** 743,750 ****
        while (insn != end && !NONDEBUG_INSN_P (insn))
  	insn = NEXT_INSN (insn);

!       if (insn != end && INSN_LOCATOR (insn) != 0
! 	  && locator_eq (INSN_LOCATOR (insn), goto_locus))
  	return false;
      }

--- 743,750 ----
        while (insn != end && !NONDEBUG_INSN_P (insn))
  	insn = NEXT_INSN (insn);

!       if (insn != end && INSN_HAS_LOCATION (insn)
! 	  && INSN_LOCATION (insn) == goto_locus)
  	return false;
      }

*************** emit_nop_for_unique_locus_between (basic
*** 761,767 ****
      return;

    BB_END (a) = emit_insn_after_noloc (gen_nop (), BB_END (a), a);
!   INSN_LOCATOR (BB_END (a)) = EDGE_SUCC (a, 0)->goto_locus;
  }

  /* Blocks A and B are to be merged into a single block A.  The insns
--- 761,767 ----
      return;

    BB_END (a) = emit_insn_after_noloc (gen_nop (), BB_END (a), a);
!   INSN_LOCATION (BB_END (a)) = EDGE_SUCC (a, 0)->goto_locus;
  }

  /* Blocks A and B are to be merged into a single block A.  The insns
*************** force_nonfallthru_and_redirect (edge e,
*** 1478,1484 ****
    else
      jump_block = e->src;

!   if (e->goto_locus && e->goto_block == NULL)
      loc = e->goto_locus;
    else
      loc = 0;
--- 1478,1484 ----
    else
      jump_block = e->src;

!   if (!IS_UNKNOWN_LOCATION (e->goto_locus))
      loc = e->goto_locus;
    else
      loc = 0;
*************** fixup_reorder_chain (void)
*** 3337,3343 ****
          edge_iterator ei;

          FOR_EACH_EDGE (e, ei, bb->succs)
! 	  if (e->goto_locus && !(e->flags & EDGE_ABNORMAL))
  	    {
  	      edge e2;
  	      edge_iterator ei2;
--- 3337,3344 ----
          edge_iterator ei;

          FOR_EACH_EDGE (e, ei, bb->succs)
! 	  if (!IS_UNKNOWN_LOCATION (e->goto_locus)
! 	      && !(e->flags & EDGE_ABNORMAL))
  	    {
  	      edge e2;
  	      edge_iterator ei2;
*************** fixup_reorder_chain (void)
*** 3347,3361 ****
  	      insn = BB_END (e->src);
  	      end = PREV_INSN (BB_HEAD (e->src));
  	      while (insn != end
! 		     && (!NONDEBUG_INSN_P (insn) || INSN_LOCATOR (insn) == 0))
  		insn = PREV_INSN (insn);
  	      if (insn != end
! 		  && locator_eq (INSN_LOCATOR (insn), (int) e->goto_locus))
  		continue;
  	      if (simplejump_p (BB_END (e->src))
! 		  && INSN_LOCATOR (BB_END (e->src)) == 0)
  		{
! 		  INSN_LOCATOR (BB_END (e->src)) = e->goto_locus;
  		  continue;
  		}
  	      dest = e->dest;
--- 3348,3362 ----
  	      insn = BB_END (e->src);
  	      end = PREV_INSN (BB_HEAD (e->src));
  	      while (insn != end
! 		     && (!NONDEBUG_INSN_P (insn) || !INSN_HAS_LOCATION (insn)))
  		insn = PREV_INSN (insn);
  	      if (insn != end
! 		  && INSN_LOCATION (insn) == e->goto_locus)
  		continue;
  	      if (simplejump_p (BB_END (e->src))
! 		  && !INSN_HAS_LOCATION (BB_END (e->src)))
  		{
! 		  INSN_LOCATION (BB_END (e->src)) = e->goto_locus;
  		  continue;
  		}
  	      dest = e->dest;
*************** fixup_reorder_chain (void)
*** 3371,3394 ****
  		  end = NEXT_INSN (BB_END (dest));
  		  while (insn != end && !NONDEBUG_INSN_P (insn))
  		    insn = NEXT_INSN (insn);
! 		  if (insn != end && INSN_LOCATOR (insn)
! 		      && locator_eq (INSN_LOCATOR (insn), (int) e->goto_locus))
  		    continue;
  		}
  	      nb = split_edge (e);
  	      if (!INSN_P (BB_END (nb)))
  		BB_END (nb) = emit_insn_after_noloc (gen_nop (), BB_END (nb),
  						     nb);
! 	      INSN_LOCATOR (BB_END (nb)) = e->goto_locus;

  	      /* If there are other incoming edges to the destination block
  		 with the same goto locus, redirect them to the new block as
  		 well, this can prevent other such blocks from being created
  		 in subsequent iterations of the loop.  */
  	      for (ei2 = ei_start (dest->preds); (e2 = ei_safe_edge (ei2)); )
! 		if (e2->goto_locus
  		    && !(e2->flags & (EDGE_ABNORMAL | EDGE_FALLTHRU))
! 		    && locator_eq (e->goto_locus, e2->goto_locus))
  		  redirect_edge_and_branch (e2, nb);
  		else
  		  ei_next (&ei2);
--- 3372,3395 ----
  		  end = NEXT_INSN (BB_END (dest));
  		  while (insn != end && !NONDEBUG_INSN_P (insn))
  		    insn = NEXT_INSN (insn);
! 		  if (insn != end && INSN_HAS_LOCATION (insn)
! 		      && INSN_LOCATION (insn) == e->goto_locus)
  		    continue;
  		}
  	      nb = split_edge (e);
  	      if (!INSN_P (BB_END (nb)))
  		BB_END (nb) = emit_insn_after_noloc (gen_nop (), BB_END (nb),
  						     nb);
! 	      INSN_LOCATION (BB_END (nb)) = e->goto_locus;

  	      /* If there are other incoming edges to the destination block
  		 with the same goto locus, redirect them to the new block as
  		 well, this can prevent other such blocks from being created
  		 in subsequent iterations of the loop.  */
  	      for (ei2 = ei_start (dest->preds); (e2 = ei_safe_edge (ei2)); )
! 		if (!IS_UNKNOWN_LOCATION (e2->goto_locus)
  		    && !(e2->flags & (EDGE_ABNORMAL | EDGE_FALLTHRU))
! 		    && e->goto_locus == e2->goto_locus)
  		  redirect_edge_and_branch (e2, nb);
  		else
  		  ei_next (&ei2);
*************** cfg_layout_merge_blocks (basic_block a,
*** 4088,4094 ****
      }

    /* If B was a forwarder block, propagate the locus on the edge.  */
!   if (forwarder_p && !EDGE_SUCC (b, 0)->goto_locus)
      EDGE_SUCC (b, 0)->goto_locus = EDGE_SUCC (a, 0)->goto_locus;

    if (dump_file)
--- 4089,4095 ----
      }

    /* If B was a forwarder block, propagate the locus on the edge.  */
!   if (forwarder_p && IS_UNKNOWN_LOCATION (EDGE_SUCC (b, 0)->goto_locus))
      EDGE_SUCC (b, 0)->goto_locus = EDGE_SUCC (a, 0)->goto_locus;

    if (dump_file)
Index: gcc/stmt.c
===================================================================
*** gcc/stmt.c	(revision 189835)
--- gcc/stmt.c	(working copy)
*************** emit_case_nodes (rtx index, case_node_pt
*** 2397,2403 ****
  		 then emit the code for one side at a time.  */

  	      tree test_label
! 		= build_decl (CURR_INSN_LOCATION,
  			      LABEL_DECL, NULL_TREE, NULL_TREE);

  	      /* See if the value is on the right.  */
--- 2397,2403 ----
  		 then emit the code for one side at a time.  */

  	      tree test_label
! 		= build_decl (curr_insn_location (),
  			      LABEL_DECL, NULL_TREE, NULL_TREE);

  	      /* See if the value is on the right.  */
*************** emit_case_nodes (rtx index, case_node_pt
*** 2521,2527 ****
  	      /* Right hand node requires testing.
  		 Branch to a label where we will handle it later.  */

! 	      test_label = build_decl (CURR_INSN_LOCATION,
  				       LABEL_DECL, NULL_TREE, NULL_TREE);
  	      emit_cmp_and_jump_insns (index,
  				       convert_modes
--- 2521,2527 ----
  	      /* Right hand node requires testing.
  		 Branch to a label where we will handle it later.  */

! 	      test_label = build_decl (curr_insn_location (),
  				       LABEL_DECL, NULL_TREE, NULL_TREE);
  	      emit_cmp_and_jump_insns (index,
  				       convert_modes
Index: libcpp/include/line-map.h
===================================================================
*** libcpp/include/line-map.h	(revision 189835)
--- libcpp/include/line-map.h	(working copy)
*************** struct GTY(()) line_map_ordinary {
*** 89,95 ****

  /* This is the highest possible source location encoded within an
     ordinary or macro map.  */
! #define MAX_SOURCE_LOCATION 0xFFFFFFFF

  struct cpp_hashnode;

--- 89,95 ----

  /* This is the highest possible source location encoded within an
     ordinary or macro map.  */
! #define MAX_SOURCE_LOCATION 0x7FFFFFFF

  struct cpp_hashnode;

*************** struct GTY(()) line_maps {
*** 408,413 ****
--- 408,423 ----
  #define LINEMAPS_LAST_ALLOCATED_MACRO_MAP(SET) \
    LINEMAPS_LAST_ALLOCATED_MAP (SET, true)

+ extern void location_block_init (void);
+ extern void location_block_fini (void);
+ extern source_location get_combine_location (source_location, void *);
+ extern void *get_block_from_location (source_location);
+ extern source_location get_locus_from_location (source_location);
+
+ #define COMBINE_LOCATION(LOC, BLOCK) \
+   ((BLOCK) ? get_combine_location ((LOC), (BLOCK)) : (LOC))
+ #define IS_COMBINED_LOCATION(LOC) (((LOC) & MAX_SOURCE_LOCATION) != (LOC))
+
  /* Initialize a line map set.  */
  extern void linemap_init (struct line_maps *);

*************** typedef struct
*** 594,599 ****
--- 604,611 ----

    int column;

+   void *block;
+
    /* In a system header?. */
    bool sysp;
  } expanded_location;
Index: libcpp/line-map.c
===================================================================
*** libcpp/line-map.c	(revision 189835)
--- libcpp/line-map.c	(working copy)
*************** along with this program; see the file CO
*** 25,30 ****
--- 25,31 ----
  #include "line-map.h"
  #include "cpplib.h"
  #include "internal.h"
+ #include "hashtab.h"

  static void trace_include (const struct line_maps *, const struct line_map *);
  static const struct line_map * linemap_ordinary_map_lookup (struct
line_maps *,
*************** static source_location linemap_macro_loc
*** 50,55 ****
--- 51,171 ----
  extern unsigned num_expanded_macros_counter;
  extern unsigned num_macro_tokens_counter;

+ struct location_block {
+   source_location locus;
+   void *block;
+ };
+
+ static htab_t location_block_htab;
+ static source_location curr_combined_location;
+ static struct location_block *location_blocks;
+ static unsigned int allocated_location_blocks;
+
+ /* Hash function for location_block hashtable.  */
+
+ static hashval_t
+ location_block_hash (const void *l)
+ {
+   const struct location_block *lb = (const struct location_block *) l;
+   return (hashval_t) lb->locus + (size_t) &lb->block;
+ }
+
+ /* Compare function for location_block hashtable.  */
+
+ static int
+ location_block_eq (const void *l1, const void *l2)
+ {
+   const struct location_block *lb1 = (const struct location_block *) l1;
+   const struct location_block *lb2 = (const struct location_block *) l2;
+   return lb1->locus == lb2->locus && lb1->block == lb2->block;
+ }
+
+ /* Update the hashtable when location_blocks is reallocated.  */
+
+ static int
+ location_block_update (void **slot, void *data)
+ {
+   *((char **) slot) += ((char *) location_blocks - (char *) data);
+   return 1;
+ }
+
+ /* Combine LOCUS and BLOCK to a combined location.  */
+
+ source_location
+ get_combine_location (source_location locus, void *block)
+ {
+   struct location_block lb;
+   struct location_block **slot;
+
+   linemap_assert (block);
+
+   if (IS_COMBINED_LOCATION (locus))
+     locus = location_blocks[locus & MAX_SOURCE_LOCATION].locus;
+   if (locus == 0 && block == NULL)
+     return 0;
+   lb.locus = locus;
+   lb.block = block;
+   slot = (struct location_block **)
+       htab_find_slot (location_block_htab, &lb, INSERT);
+   if (*slot == NULL)
+     {
+       *slot = location_blocks + curr_combined_location;
+       location_blocks[curr_combined_location] = lb;
+       if (++curr_combined_location >= allocated_location_blocks)
+ 	{
+ 	  char *orig_location_blocks = (char *) location_blocks;
+ 	  allocated_location_blocks *= 2;
+ 	  location_blocks = XRESIZEVEC (struct location_block,
+ 				 	location_blocks,
+ 					allocated_location_blocks);
+ 	  htab_traverse (location_block_htab, location_block_update,
+ 			 orig_location_blocks);
+ 	}
+     }
+   return ((*slot) - location_blocks) | 0x80000000;
+ }
+
+ /* Return the block for LOCATION.  */
+
+ void *
+ get_block_from_location (source_location location)
+ {
+   linemap_assert (IS_COMBINED_LOCATION (location));
+   return location_blocks[location & MAX_SOURCE_LOCATION].block;
+ }
+
+ /* Return the locus for LOCATION.  */
+
+ source_location
+ get_locus_from_location (source_location location)
+ {
+   linemap_assert (IS_COMBINED_LOCATION (location));
+   return location_blocks[location & MAX_SOURCE_LOCATION].locus;
+ }
+
+ /* Initialize the location_block structure.  */
+
+ void
+ location_block_init (void)
+ {
+   location_block_htab = htab_create (100, location_block_hash,
+ 				     location_block_eq, NULL);
+   curr_combined_location = 0;
+   allocated_location_blocks = 100;
+   location_blocks = XNEWVEC (struct location_block,
+ 			     allocated_location_blocks);
+ }
+
+ /* Finalize the location_block structure.  */
+
+ void
+ location_block_fini (void)
+ {
+   allocated_location_blocks = 0;
+   XDELETEVEC (location_blocks);
+   htab_delete (location_block_htab);
+ }
+
  /* Initialize a line map set.  */

  void
*************** linemap_position_for_line_and_column (st
*** 509,514 ****
--- 625,632 ----
  const struct line_map*
  linemap_lookup (struct line_maps *set, source_location line)
  {
+   if (IS_COMBINED_LOCATION (line))
+     line = location_blocks[line & MAX_SOURCE_LOCATION].locus;
    if (linemap_location_from_macro_expansion_p (set, line))
      return linemap_macro_map_lookup (set, line);
    return linemap_ordinary_map_lookup (set, line);
*************** linemap_ordinary_map_lookup (struct line
*** 525,530 ****
--- 643,651 ----
    unsigned int md, mn, mx;
    const struct line_map *cached, *result;

+   if (IS_COMBINED_LOCATION (line))
+     line = location_blocks[line & MAX_SOURCE_LOCATION].locus;
+
    if (set ==  NULL || line < RESERVED_LOCATION_COUNT)
      return NULL;

*************** linemap_macro_map_lookup (struct line_ma
*** 570,575 ****
--- 691,699 ----
    unsigned int md, mn, mx;
    const struct line_map *cached, *result;

+   if (IS_COMBINED_LOCATION (line))
+     line = location_blocks[line & MAX_SOURCE_LOCATION].locus;
+
    linemap_assert (line >= LINEMAPS_MACRO_LOWEST_LOCATION (set));

    if (set ==  NULL)
*************** linemap_macro_map_loc_to_def_point (cons
*** 648,653 ****
--- 772,780 ----
  {
    unsigned token_no;

+   if (IS_COMBINED_LOCATION (location))
+     location = location_blocks[location & MAX_SOURCE_LOCATION].locus;
+
    linemap_assert (linemap_macro_expansion_map_p (map)
  		  && location >= MAP_START_LOCATION (map));
    linemap_assert (location >= RESERVED_LOCATION_COUNT);
*************** linemap_macro_map_loc_unwind_toward_spel
*** 672,677 ****
--- 799,807 ----
  {
    unsigned token_no;

+   if (IS_COMBINED_LOCATION (location))
+     location = location_blocks[location & MAX_SOURCE_LOCATION].locus;
+
    linemap_assert (linemap_macro_expansion_map_p (map)
  		  && location >= MAP_START_LOCATION (map));
    linemap_assert (location >= RESERVED_LOCATION_COUNT);
*************** linemap_get_expansion_line (struct line_
*** 696,701 ****
--- 826,834 ----
  {
    const struct line_map *map = NULL;

+   if (IS_COMBINED_LOCATION (location))
+     location = location_blocks[location & MAX_SOURCE_LOCATION].locus;
+
    if (location < RESERVED_LOCATION_COUNT)
      return 0;

*************** linemap_get_expansion_filename (struct l
*** 720,725 ****
--- 853,861 ----
  {
    const struct line_map *map = NULL;

+   if (IS_COMBINED_LOCATION (location))
+     location = location_blocks[location & MAX_SOURCE_LOCATION].locus;
+
    if (location < RESERVED_LOCATION_COUNT)
      return NULL;

*************** linemap_location_in_system_header_p (str
*** 754,759 ****
--- 890,898 ----
  {
    const struct line_map *map = NULL;

+   if (IS_COMBINED_LOCATION (location))
+     location = location_blocks[location & MAX_SOURCE_LOCATION].locus;
+
    if (location < RESERVED_LOCATION_COUNT)
      return false;

*************** bool
*** 793,798 ****
--- 932,940 ----
  linemap_location_from_macro_expansion_p (struct line_maps *set,
  					 source_location location)
  {
+   if (IS_COMBINED_LOCATION (location))
+     location = location_blocks[location & MAX_SOURCE_LOCATION].locus;
+
    linemap_assert (location <= MAX_SOURCE_LOCATION
  		  && (set->highest_location
  		      < LINEMAPS_MACRO_LOWEST_LOCATION (set)));
*************** linemap_macro_loc_to_spelling_point (str
*** 933,938 ****
--- 1075,1083 ----
  {
    struct line_map *map;

+   if (IS_COMBINED_LOCATION (location))
+     location = location_blocks[location & MAX_SOURCE_LOCATION].locus;
+
    linemap_assert (set && location >= RESERVED_LOCATION_COUNT);

    while (true)
*************** linemap_macro_loc_to_def_point (struct l
*** 967,972 ****
--- 1112,1120 ----
  {
    struct line_map *map;

+   if (IS_COMBINED_LOCATION (location))
+     location = location_blocks[location & MAX_SOURCE_LOCATION].locus;
+
    linemap_assert (set && location >= RESERVED_LOCATION_COUNT);

    while (true)
*************** linemap_macro_loc_to_exp_point (struct l
*** 1005,1010 ****
--- 1153,1161 ----
  {
    struct line_map *map;

+   if (IS_COMBINED_LOCATION (location))
+     location = location_blocks[location & MAX_SOURCE_LOCATION].locus;
+
    linemap_assert (set && location >= RESERVED_LOCATION_COUNT);

    while (true)
*************** linemap_resolve_location (struct line_ma
*** 1074,1079 ****
--- 1225,1233 ----
  			  enum location_resolution_kind lrk,
  			  const struct line_map **map)
  {
+   if (IS_COMBINED_LOCATION (loc))
+     loc = location_blocks[loc & MAX_SOURCE_LOCATION].locus;
+
    if (loc < RESERVED_LOCATION_COUNT)
      {
        /* A reserved location wasn't encoded in a map.  Let's return a
*************** linemap_unwind_toward_expansion (struct
*** 1121,1126 ****
--- 1275,1283 ----
    source_location resolved_location;
    const struct line_map *resolved_map;

+   if (IS_COMBINED_LOCATION (loc))
+     loc = location_blocks[loc & MAX_SOURCE_LOCATION].locus;
+
    resolved_location =
      linemap_macro_map_loc_unwind_toward_spelling (*map, loc);
    resolved_map = linemap_lookup (set, resolved_location);
*************** linemap_unwind_to_first_non_reserved_loc
*** 1157,1162 ****
--- 1314,1322 ----
    source_location resolved_loc;
    const struct line_map *map0 = NULL, *map1 = NULL;

+   if (IS_COMBINED_LOCATION (loc))
+     loc = location_blocks[loc & MAX_SOURCE_LOCATION].locus;
+
    map0 = linemap_lookup (set, loc);
    if (!linemap_macro_expansion_map_p (map0))
      return loc;
*************** linemap_expand_location (struct line_map
*** 1198,1203 ****
--- 1358,1368 ----
    expanded_location xloc;

    memset (&xloc, 0, sizeof (xloc));
+   if (IS_COMBINED_LOCATION (loc))
+     {
+       loc = location_blocks[loc & MAX_SOURCE_LOCATION].locus;
+       xloc.block = location_blocks[loc & MAX_SOURCE_LOCATION].block;
+     }

    if (loc < RESERVED_LOCATION_COUNT)
      /* The location for this token wasn't generated from a line map.
*************** linemap_dump_location (struct line_maps
*** 1290,1295 ****
--- 1455,1463 ----
    const char *path = "", *from = "";
    int l = -1, c = -1, s = -1, e = -1;

+   if (IS_COMBINED_LOCATION (loc))
+     loc = location_blocks[loc & MAX_SOURCE_LOCATION].locus;
+
    if (loc == 0)
      return;
Dodji Seketeli Aug. 13, 2012, 6:34 p.m. UTC | #4
Hello Dehao,

I have mostly cosmetic comments to make about the libcpp parts.

Dehao Chen <dehao@google.com> writes:

> Index: libcpp/include/line-map.h
> ===================================================================
> *** libcpp/include/line-map.h	(revision 189835)
> --- libcpp/include/line-map.h	(working copy)
> *************** struct GTY(()) line_map_ordinary {
> *** 89,95 ****
>

Just to sum things up, here is what I understand from the libcpp
changes.

The integer space is now segmented like this:

    X  A  B  C
    [        ]  <--- integer space of source_location

C is the smallest possible source_location and X is the biggest
possible.

From X to A, we have instances of source_location encoded in an ad-hoc
client specific (from the point of view of libcpp/line-map) map.

From A to B, we have instances of source_location encoded in macro maps.

From B to C, we have instances of source_location encoded in ordinary
maps.

As of this patch, MAX_SOURCE_LOCATION is A.  X is 0xFFFFFFFF and is not
represented by any particular constant declaration.

From the point of view libcpp the goal of this patch is to 

1/ Provide functions to encode a pair of 
   {non-ad-hoc source_location, client specific data} and yield an
   integer for that (a new instance of source_location).

2/ modify the lookup routines of line-map to have them recognize
   instances of source_location encoded in the ad-hoc map.

If this description is correct, I think a high level comment like this
should be added to line-map.c or line-map.h to help people understand
this in the future, a bit like what has been done for ordinary and macro
maps.

[...]

> + extern void *get_block_from_location (source_location);

I'd call this function get_block_from_ad_hoc_location instead.  Or
something like that, to hint at the fact that the parameter is not an
actual source location.

> + extern source_location get_locus_from_location (source_location);

Likewise, I'd call this get_source_location_from_ad_hoc_loc.

> +
> + #define COMBINE_LOCATION(LOC, BLOCK) \
> +   ((BLOCK) ? get_combine_location ((LOC), (BLOCK)) : (LOC))
> + #define IS_COMBINED_LOCATION(LOC) (((LOC) & MAX_SOURCE_LOCATION) != (LOC))
> +
>   /* Initialize a line map set.  */
>   extern void linemap_init (struct line_maps *);
>
> *************** typedef struct
> *** 594,599 ****
> --- 604,611 ----
>
>     int column;
>
> +   void *block;
> +

I'd just call this 'data' or something like, and add I comment
explaining that its a client specific data that is not manipulated by
libcpp.

>     /* In a system header?. */
>     bool sysp;
>   } expanded_location;


> --- libcpp/line-map.c	(working copy)

[...]


> + struct location_block {
> +   source_location locus;
> +   void *block;
> + };

I think we should have a more general name than "block" here.  I am
thinking that other client code might be willing to associate entities
other than blocks to a given source_location in a scheme similar to this
one.  Also, it seems surprising to have the line-maps library deal with
blocks specifically.

So maybe something like this instead?:

    /* Data structure to associate an arbitrary data to a source location.  */
    struct location_ad_hoc_data {
      source_location locus;
      void *data;
    };


Subsequently, if you agree with this, all the occurrences of 'block' in
the new code (function, types, and variable names) you introduced should
be replaced with 'ad_hoc_data'.

> + source_location
> + get_combine_location (source_location locus, void *block)

Shouldn't this be get_combined_location instead?  Note the 'd' after the
combine.

> --- gcc/input.h	(working copy)

[...]

> + #define LOCATION_LOCUS(LOC) \
> +   ((IS_COMBINED_LOCATION(LOC)) ? get_locus_from_location (LOC) : (LOC))

I think this name sounds confusing.  Maybe something like
SOURCE_LOCATION_FROM_AD_HOC_LOC instead?  And please add a comment to
explain a little bit about this business of ad hoc location that
associates a block with an actual source location.

> + #define LOCATION_BLOCK(LOC) \
> +   ((tree) ((IS_COMBINED_LOCATION (LOC)) ? get_block_from_location (LOC) \
> +   : NULL))

And the name of this macro would then be something like BLOCK_FROM_AD_HOC_LOC.

> + #define IS_UNKNOWN_LOCATION(LOC) \
> +   ((IS_COMBINED_LOCATION (LOC)) ? get_locus_from_location (LOC) == 0 \
> +   : (LOC) == 0)
Dehao Chen Aug. 14, 2012, 4:57 a.m. UTC | #5
Hi, Dodji,

Thanks a lot for the review. I've updated the patch, which is attached.

Passed bootstrap and all regression tests.

Thanks,
Dehao

gcc/ChangeLog
2012-08-01  Dehao Chen  <dehao@google.com>

	* toplev.c (general_init): Init block_locations.
	* tree.c (tree_set_block): New.
	(tree_block): Change to use LOCATION_BLOCK.
	* tree.h (TREE_SET_BLOCK): New.
	* final.c (reemit_insn_block_notes): Change to use LOCATION_BLOCK.
	(final_start_function): Likewise.
	* input.c (expand_location_1): Likewise.
	* input.h (LOCATION_LOCUS): New.
	(LOCATION_BLOCK): New.
	(IS_UNKNOWN_LOCATION): New.
	* fold-const.c (expr_location_or): Change to use new location.
	* reorg.c (emit_delay_sequence): Likewise.
	(try_merge_delay_insns): Likewise.
	* modulo-sched.c (dump_insn_location): Likewise.
	* lto-streamer-out.c (lto_output_location_bitpack): Likewise.
	* jump.c (rtx_renumbered_equal_p): Likewise.
	* ifcvt.c (noce_try_move): Likewise.
	(noce_try_store_flag): Likewise.
	(noce_try_store_flag_constants): Likewise.
	(noce_try_addcc): Likewise.
	(noce_try_store_flag_mask): Likewise.
	(noce_try_cmove): Likewise.
	(noce_try_cmove_arith): Likewise.
	(noce_try_minmax): Likewise.
	(noce_try_abs): Likewise.
	(noce_try_sign_mask): Likewise.
	(noce_try_bitop): Likewise.
	(noce_process_if_block): Likewise.
	(cond_move_process_if_block): Likewise.
	(find_cond_trap): Likewise.
	* dewarf2out.c (add_src_coords_attributes): Likewise.
	* expr.c (expand_expr_real): Likewise.
	* tree-parloops.c (create_loop_fn): Likewise.
	* recog.c (peep2_attempt): Likewise.
	* function.c (free_after_compilation): Likewise.
	(expand_function_end): Likewise.
	(set_insn_locations): Likewise.
	(thread_prologue_and_epilogue_insns): Likewise.
	* print-rtl.c (print_rtx): Likewise.
	* profile.c (branch_prob): Likewise.
	* trans-mem.c (ipa_tm_scan_irr_block): Likewise.
	* gimplify.c (gimplify_call_expr): Likewise.
	* except.c (duplicate_eh_regions_1): Likewise.
	* emit-rtl.c (try_split): Likewise.
	(make_insn_raw): Likewise.
	(make_debug_insn_raw): Likewise.
	(make_jump_insn_raw): Likewise.
	(make_call_insn_raw): Likewise.
	(emit_pattern_after_setloc): Likewise.
	(emit_pattern_after): Likewise.
	(emit_debug_insn_after): Likewise.
	(emit_pattern_before): Likewise.
	(emit_insn_before_setloc): Likewise.
	(emit_jump_insn_before): Likewise.
	(emit_call_insn_before_setloc): Likewise.
	(emit_call_insn_before): Likeise.
	(emit_debug_insn_before_setloc): Likewise.
	(emit_copy_of_insn_after): Likewise.
	(insn_locators_alloc): Remove.
	(insn_locators_finalize): Remove.
	(insn_locators_free): Remove.
	(set_curr_insn_source_location): Remove.
	(get_curr_insn_source_location): Remove.
	(set_curr_insn_block): Remove.
	(get_curr_insn_block): Remove.
	(locator_scope): Remove.
	(insn_scope): Change to use new location.
	(locator_location): Remove.
	(insn_line): Change to use new location.
	(locator_file): Remove.
	(insn_file): Change to use new location.
	(locator_eq): Remove.
	(insn_locations_init): New.
	(insn_locations_finalize): New.
	(set_curr_insn_location): New.
	(curr_insn_location): New.
	* cfgexpand.c (gimple_assign_rhs_to_tree): Change to use new location.
	(expand_gimple_cond): Likewise.
	(expand_call_stmt): Likewise.
	(expand_gimple_stmt_1): Likewise.
	(expand_gimple_basic_block): Likewise.
	(construct_exit_block): Likewise.
	(gimple_expand_cfg): Likewise.
	* cfgcleanup.c (try_forward_edges): Likewise.
	* tree-ssa-live.c (remove_unused_scope_block_p): Likewise.
	(dump_scope_block): Likewise.
	(remove_unused_locals): Likewise.
	* rtl.c (rtx_equal_p_cb): Likewise.
	(rtx_equal_p): Likewise.
	* rtl.h (XUINT): New.
	(INSN_LOCATOR): Remove.
	(CURR_INSN_LOCATION): Remove.
	(INSN_LOCATION): New.
	(INSN_HAS_LOCATION): New.
	* tree-inline.c (remap_gimple_op_r): Change to use new location.
	(copy_tree_body_r): Likewise.
	(copy_phis_for_bb): Likewise.
	(expand_call_inline): Likewise.
	* tree-streamer-in.c (lto_input_ts_exp_tree_pointers): Likewise.
	* tree-streamer-out.c (write_ts_decl_minimal_tree_pointers): Likewise.
	* gimple-streamer-out.c (output_gimple_stmt): Likewise.
	* combine.c (try_combine): Likewise.
	* tree-outof-ssa.c (set_location_for_edge): Likewise.
	(insert_partition_copy_on_edge): Likewise.
	(insert_value_copy_on_edge): Likewise.
	(insert_rtx_to_part_on_edge): Likewise.
	(insert_part_to_rtx_on_edge): Likewise.
	* basic-block.h (edge_def): Remove field.
	* gimple.h (gimple_statement_base): Remove field.
	(gimple_bb): Change to use new location.
	(gimple_set_block): Likewise.
	(gimple_has_location): Likewise.
	* tree-cfg.c (make_cond_expr_edges): Likewise.
	(make_goto_expr_edges): Likewise.
	(gimple_can_merge_blocks_p): Likewise.
	(move_stmt_op): Likewise.
	(move_block_to_fn): Likewise.
	* config/alpha/alpha.c (alpha_output_mi_thunk_osf): Likewise.
	* config/sparc/sparc.c (sparc_output_mi_thunk): Likewise.
	* config/i386/i386.c (x86_output_mi_thunk): Likewise.
	* config/tilegx/tilegx.c (tilegx_output_mi_thunk): Likewise.
	* config/sh/sh.c (sh_output_mi_thunk): Likewise.
	* config/ia64/ia64.c (ia64_output_mi_thunk): Likewise.
	* config/rs6000/rs6000.c (rs6000_output_mi_thunk): Likewise.
	* config/score/score.c (score_output_mi_thunk): Likewise.
	* config/tilepro/tilepro.c (tilepro_asm_output_mi_thunk): Likewise.
	* config/mips/mips.c (mips_output_mi_thunk): Likewise.
	* cfgrtl.c (unique_locus_on_edge_between_p): Likewise.
	(unique_locus_on_edge_between_p): Likewise.
	(emit_nop_for_unique_locus_between): Likewise.
	(force_nonfallthru_and_redirect): Likewise.
	(fixup_reorder_chain): Likewise.
	(cfg_layout_merge_blocks): Likewise.
	* stmt.c (emit_case_nodes): Likewise.

gcc/lto/ChangeLog
2012-08-01  Dehao Chen  <dehao@google.com>

	* lto/lto.c (lto_fixup_prevailing_decls): Remove tree.exp.block field.

libcpp/ChangeLog
2012-08-01  Dehao Chen  <dehao@google.com>

	* include/line-map.h (MAX_SOURCE_LOCATION): New value.
	(location_adhoc_data_init): New.
	(location_adhoc_data_fini): New.
	(get_combined_adhoc_loc): New.
	(get_data_from_adhoc_loc): New.
	(get_location_from_adhoc_loc): New.
	(COMBINE_LOCATION_DATA): New.
	(IS_ADHOC_LOC): New.
	(expanded_location): New field.
	* line-map.c (location_adhoc_data): New.
	(location_adhoc_data_htab): New.
	(curr_adhoc_loc): New.
	(location_adhoc_data): New.
	(allocated_location_adhoc_data): New.
	(location_adhoc_data_hash): New.
	(location_adhoc_data_eq): New.
	(location_adhoc_data_update): New.
	(get_combined_adhoc_loc): New.
	(get_data_from_adhoc_loc): New.
	(get_location_from_adhoc_loc): New.
	(location_adhoc_data_init): New.
	(location_adhoc_data_fini): New.
	(linemap_lookup): Change to use new location.
	(linemap_ordinary_map_lookup): Likewise.
	(linemap_macro_map_lookup): Likewise.
	(linemap_macro_map_loc_to_def_point): Likewise.
	(linemap_macro_map_loc_unwind_toward_spel): Likewise.
	(linemap_get_expansion_line): Likewise.
	(linemap_get_expansion_filename): Likewise.
	(linemap_location_in_system_header_p): Likewise.
	(linemap_location_from_macro_expansion_p): Likewise.
	(linemap_macro_loc_to_spelling_point): Likewise.
	(linemap_macro_loc_to_def_point): Likewise.
	(linemap_macro_loc_to_exp_point): Likewise.
	(linemap_resolve_location): Likewise.
	(linemap_unwind_toward_expansion): Likewise.
	(linemap_unwind_to_first_non_reserved_loc): Likewise.
	(linemap_expand_location): Likewise.
	(linemap_dump_location): Likewise.

Index: gcc/gimple-streamer-out.c
===================================================================
*** gcc/gimple-streamer-out.c	(revision 190209)
--- gcc/gimple-streamer-out.c	(working copy)
*************** output_gimple_stmt (struct output_block
*** 74,80 ****
    streamer_write_bitpack (&bp);

    /* Emit location information for the statement.  */
!   lto_output_location (ob, gimple_location (stmt));

    /* Emit the lexical block holding STMT.  */
    stream_write_tree (ob, gimple_block (stmt), true);
--- 74,80 ----
    streamer_write_bitpack (&bp);

    /* Emit location information for the statement.  */
!   lto_output_location (ob, LOCATION_LOCUS (gimple_location (stmt)));

    /* Emit the lexical block holding STMT.  */
    stream_write_tree (ob, gimple_block (stmt), true);
Index: gcc/tree.c
===================================================================
*** gcc/tree.c	(revision 190209)
--- gcc/tree.c	(working copy)
*************** build1_stat (enum tree_code code, tree t
*** 3760,3766 ****
    TREE_TYPE (t) = type;
    SET_EXPR_LOCATION (t, UNKNOWN_LOCATION);
    TREE_OPERAND (t, 0) = node;
-   TREE_BLOCK (t) = NULL_TREE;
    if (node && !TYPE_P (node))
      {
        TREE_SIDE_EFFECTS (t) = TREE_SIDE_EFFECTS (node);
--- 3760,3765 ----
*************** walk_tree_without_duplicates_1 (tree *tp
*** 10831,10847 ****
  }


! tree *
  tree_block (tree t)
  {
    char const c = TREE_CODE_CLASS (TREE_CODE (t));

    if (IS_EXPR_CODE_CLASS (c))
!     return &t->exp.block;
    gcc_unreachable ();
    return NULL;
  }

  /* Create a nameless artificial label and put it in the current
     function context.  The label has a location of LOC.  Returns the
     newly created label.  */
--- 10830,10857 ----
  }


! tree
  tree_block (tree t)
  {
    char const c = TREE_CODE_CLASS (TREE_CODE (t));

    if (IS_EXPR_CODE_CLASS (c))
!     return LOCATION_BLOCK (t->exp.locus);
    gcc_unreachable ();
    return NULL;
  }

+ void
+ tree_set_block (tree t, tree b)
+ {
+   char const c = TREE_CODE_CLASS (TREE_CODE (t));
+
+   if (IS_EXPR_CODE_CLASS (c))
+     t->exp.locus = COMBINE_LOCATION_DATA (t->exp.locus, b);
+   else
+     gcc_unreachable ();
+ }
+
  /* Create a nameless artificial label and put it in the current
     function context.  The label has a location of LOC.  Returns the
     newly created label.  */
Index: gcc/tree.h
===================================================================
*** gcc/tree.h	(revision 190209)
--- gcc/tree.h	(working copy)
*************** extern void omp_clause_range_check_faile
*** 999,1005 ****

  #endif

! #define TREE_BLOCK(NODE)		*(tree_block (NODE))

  #include "tree-check.h"

--- 999,1006 ----

  #endif

! #define TREE_BLOCK(NODE)		(tree_block (NODE))
! #define TREE_SET_BLOCK(T, B)		(tree_set_block ((T), (B)))

  #include "tree-check.h"

*************** struct GTY(()) tree_constructor {
*** 1702,1708 ****
  #define EXPR_LOCATION(NODE) \
    (CAN_HAVE_LOCATION_P ((NODE)) ? (NODE)->exp.locus : UNKNOWN_LOCATION)
  #define SET_EXPR_LOCATION(NODE, LOCUS) EXPR_CHECK
((NODE))->exp.locus = (LOCUS)
! #define EXPR_HAS_LOCATION(NODE) (EXPR_LOCATION (NODE) != UNKNOWN_LOCATION)
  /* The location to be used in a diagnostic about this expression.  Do not
     use this macro if the location will be assigned to other expressions.  */
  #define EXPR_LOC_OR_HERE(NODE) (EXPR_HAS_LOCATION (NODE) ?
(NODE)->exp.locus : input_location)
--- 1703,1709 ----
  #define EXPR_LOCATION(NODE) \
    (CAN_HAVE_LOCATION_P ((NODE)) ? (NODE)->exp.locus : UNKNOWN_LOCATION)
  #define SET_EXPR_LOCATION(NODE, LOCUS) EXPR_CHECK
((NODE))->exp.locus = (LOCUS)
! #define EXPR_HAS_LOCATION(NODE) (!IS_UNKNOWN_LOCATION (EXPR_LOCATION (NODE)))
  /* The location to be used in a diagnostic about this expression.  Do not
     use this macro if the location will be assigned to other expressions.  */
  #define EXPR_LOC_OR_HERE(NODE) (EXPR_HAS_LOCATION (NODE) ?
(NODE)->exp.locus : input_location)
*************** extern void protected_set_expr_location
*** 1881,1887 ****
  					      OMP_CLAUSE_PRIVATE,	\
  	                                      OMP_CLAUSE_COPYPRIVATE), 0)
  #define OMP_CLAUSE_HAS_LOCATION(NODE) \
!   ((OMP_CLAUSE_CHECK (NODE))->omp_clause.locus != UNKNOWN_LOCATION)
  #define OMP_CLAUSE_LOCATION(NODE)  (OMP_CLAUSE_CHECK (NODE))->omp_clause.locus

  /* True on an OMP_SECTION statement that was the last lexical member.
--- 1882,1888 ----
  					      OMP_CLAUSE_PRIVATE,	\
  	                                      OMP_CLAUSE_COPYPRIVATE), 0)
  #define OMP_CLAUSE_HAS_LOCATION(NODE) \
!   (!IS_UNKNOWN_LOCATION ((OMP_CLAUSE_CHECK (NODE))->omp_clause.locus))
  #define OMP_CLAUSE_LOCATION(NODE)  (OMP_CLAUSE_CHECK (NODE))->omp_clause.locus

  /* True on an OMP_SECTION statement that was the last lexical member.
*************** enum omp_clause_default_kind
*** 1972,1978 ****
  struct GTY(()) tree_exp {
    struct tree_typed typed;
    location_t locus;
-   tree block;
    tree GTY ((special ("tree_exp"),
  	     desc ("TREE_CODE ((tree) &%0)")))
      operands[1];
--- 1973,1978 ----
*************** function_args_iter_next (function_args_i
*** 5136,5142 ****
  static inline bool
  inlined_function_outer_scope_p (const_tree block)
  {
!  return BLOCK_SOURCE_LOCATION (block) != UNKNOWN_LOCATION;
  }

  /* Loop over all function arguments of FNTYPE.  In each iteration, PTR is set
--- 5136,5142 ----
  static inline bool
  inlined_function_outer_scope_p (const_tree block)
  {
!  return !IS_UNKNOWN_LOCATION (BLOCK_SOURCE_LOCATION (block));
  }

  /* Loop over all function arguments of FNTYPE.  In each iteration, PTR is set
*************** extern bool subrange_type_for_debug_p (c
*** 5511,5517 ****
  extern HOST_WIDE_INT int_cst_value (const_tree);
  extern HOST_WIDEST_INT widest_int_cst_value (const_tree);

! extern tree *tree_block (tree);
  extern location_t *block_nonartificial_location (tree);
  extern location_t tree_nonartificial_location (tree);

--- 5511,5518 ----
  extern HOST_WIDE_INT int_cst_value (const_tree);
  extern HOST_WIDEST_INT widest_int_cst_value (const_tree);

! extern tree tree_block (tree);
! extern void tree_set_block (tree, tree);
  extern location_t *block_nonartificial_location (tree);
  extern location_t tree_nonartificial_location (tree);

Index: gcc/final.c
===================================================================
*** gcc/final.c	(revision 190209)
--- gcc/final.c	(working copy)
*************** reemit_insn_block_notes (void)
*** 1605,1611 ****
  					     insn_scope (XVECEXP (body, 0, i)));
  	}
        if (! this_block)
! 	continue;

        if (this_block != cur_block)
  	{
--- 1605,1611 ----
  					     insn_scope (XVECEXP (body, 0, i)));
  	}
        if (! this_block)
! 	this_block = DECL_INITIAL (cfun->decl);

        if (this_block != cur_block)
  	{
*************** final_start_function (rtx first ATTRIBUT
*** 1640,1647 ****

    this_is_asm_operands = 0;

!   last_filename = locator_file (prologue_locator);
!   last_linenum = locator_line (prologue_locator);
    last_discriminator = discriminator = 0;

    high_block_linenum = high_function_linenum = last_linenum;
--- 1640,1647 ----

    this_is_asm_operands = 0;

!   last_filename = LOCATION_FILE (prologue_location);
!   last_linenum = LOCATION_LINE (prologue_location);
    last_discriminator = discriminator = 0;

    high_block_linenum = high_function_linenum = last_linenum;
Index: gcc/input.c
===================================================================
*** gcc/input.c	(revision 190209)
--- gcc/input.c	(working copy)
*************** expand_location_1 (source_location loc,
*** 51,56 ****
--- 51,63 ----
    expanded_location xloc;
    const struct line_map *map;
    enum location_resolution_kind lrk = LRK_MACRO_EXPANSION_POINT;
+   tree block = NULL;
+
+   if (IS_ADHOC_LOC (loc))
+     {
+       block = LOCATION_BLOCK (loc);
+       loc = LOCATION_LOCUS (loc);
+     }

    memset (&xloc, 0, sizeof (xloc));

*************** expand_location_1 (source_location loc,
*** 74,79 ****
--- 81,87 ----
        xloc = linemap_expand_location (line_table, map, loc);
      }

+   xloc.data = block;
    if (loc <= BUILTINS_LOCATION)
      xloc.file = loc == UNKNOWN_LOCATION ? NULL : _("<built-in>");

Index: gcc/input.h
===================================================================
*** gcc/input.h	(revision 190209)
--- gcc/input.h	(working copy)
*************** extern location_t input_location;
*** 51,56 ****
--- 51,64 ----
  #define LOCATION_FILE(LOC) ((expand_location (LOC)).file)
  #define LOCATION_LINE(LOC) ((expand_location (LOC)).line)
  #define LOCATION_COLUMN(LOC)((expand_location (LOC)).column)
+ #define LOCATION_LOCUS(LOC) \
+   ((IS_ADHOC_LOC(LOC)) ? get_location_from_adhoc_loc (LOC) : (LOC))
+ #define LOCATION_BLOCK(LOC) \
+   ((tree) ((IS_ADHOC_LOC (LOC)) ? get_data_from_adhoc_loc (LOC) \
+   : NULL))
+ #define IS_UNKNOWN_LOCATION(LOC) \
+   ((IS_ADHOC_LOC (LOC)) ? get_location_from_adhoc_loc (LOC) == 0 \
+   : (LOC) == 0)

  #define input_line LOCATION_LINE (input_location)
  #define input_filename LOCATION_FILE (input_location)
Index: gcc/fold-const.c
===================================================================
*** gcc/fold-const.c	(revision 190209)
--- gcc/fold-const.c	(working copy)
*************** static location_t
*** 145,151 ****
  expr_location_or (tree t, location_t loc)
  {
    location_t tloc = EXPR_LOCATION (t);
!   return tloc != UNKNOWN_LOCATION ? tloc : loc;
  }

  /* Similar to protected_set_expr_location, but never modify x in place,
--- 145,151 ----
  expr_location_or (tree t, location_t loc)
  {
    location_t tloc = EXPR_LOCATION (t);
!   return IS_UNKNOWN_LOCATION (tloc) ? loc : tloc;
  }

  /* Similar to protected_set_expr_location, but never modify x in place,
Index: gcc/toplev.c
===================================================================
*** gcc/toplev.c	(revision 190209)
--- gcc/toplev.c	(working copy)
*************** general_init (const char *argv0)
*** 1140,1145 ****
--- 1140,1146 ----
    linemap_init (line_table);
    line_table->reallocator = realloc_for_line_map;
    line_table->round_alloc_size = ggc_round_alloc_size;
+   location_adhoc_data_init ();
    init_ttree ();

    /* Initialize register usage now so switches may override.  */
*************** toplev_main (int argc, char **argv)
*** 1946,1951 ****
--- 1947,1953 ----
    invoke_plugin_callbacks (PLUGIN_FINISH, NULL);

    finalize_plugins ();
+   location_adhoc_data_fini ();
    if (seen_error ())
      return (FATAL_EXIT_CODE);

Index: gcc/reorg.c
===================================================================
*** gcc/reorg.c	(revision 190209)
--- gcc/reorg.c	(working copy)
*************** emit_delay_sequence (rtx insn, rtx list,
*** 545,551 ****
    INSN_DELETED_P (delay_insn) = 0;
    PREV_INSN (delay_insn) = PREV_INSN (seq_insn);

!   INSN_LOCATOR (seq_insn) = INSN_LOCATOR (delay_insn);

    for (li = list; li; li = XEXP (li, 1), i++)
      {
--- 545,551 ----
    INSN_DELETED_P (delay_insn) = 0;
    PREV_INSN (delay_insn) = PREV_INSN (seq_insn);

!   INSN_LOCATION (seq_insn) = INSN_LOCATION (delay_insn);

    for (li = list; li; li = XEXP (li, 1), i++)
      {
*************** emit_delay_sequence (rtx insn, rtx list,
*** 561,569 ****

        /* SPARC assembler, for instance, emit warning when debug info is output
           into the delay slot.  */
!       if (INSN_LOCATOR (tem) && !INSN_LOCATOR (seq_insn))
! 	INSN_LOCATOR (seq_insn) = INSN_LOCATOR (tem);
!       INSN_LOCATOR (tem) = 0;

        for (note = REG_NOTES (tem); note; note = next)
  	{
--- 561,569 ----

        /* SPARC assembler, for instance, emit warning when debug info is output
           into the delay slot.  */
!       if (INSN_LOCATION (tem) && !INSN_LOCATION (seq_insn))
! 	INSN_LOCATION (seq_insn) = INSN_LOCATION (tem);
!       INSN_LOCATION (tem) = 0;

        for (note = REG_NOTES (tem); note; note = next)
  	{
*************** dbr_schedule (rtx first)
*** 4065,4071 ****
      for (link = crtl->epilogue_delay_list;
           link;
           link = XEXP (link, 1))
!       INSN_LOCATOR (XEXP (link, 0)) = 0;
    }

  #endif
--- 4065,4071 ----
      for (link = crtl->epilogue_delay_list;
           link;
           link = XEXP (link, 1))
!       INSN_LOCATION (XEXP (link, 0)) = 0;
    }

  #endif

Index: gcc/modulo-sched.c
===================================================================
*** gcc/modulo-sched.c	(revision 190209)
--- gcc/modulo-sched.c	(working copy)
*************** loop_single_full_bb_p (struct loop *loop
*** 1246,1254 ****
  /* Dump file:line from INSN's location info to dump_file.  */

  static void
! dump_insn_locator (rtx insn)
  {
!   if (dump_file && INSN_LOCATOR (insn))
      {
        const char *file = insn_file (insn);
        if (file)
--- 1246,1254 ----
  /* Dump file:line from INSN's location info to dump_file.  */

  static void
! dump_insn_location (rtx insn)
  {
!   if (dump_file && INSN_LOCATION (insn))
      {
        const char *file = insn_file (insn);
        if (file)
*************** loop_canon_p (struct loop *loop)
*** 1282,1288 ****
  	  rtx insn = BB_END (loop->header);

  	  fprintf (dump_file, "SMS loop many exits");
! 	  dump_insn_locator (insn);
  	  fprintf (dump_file, "\n");
  	}
        return false;
--- 1282,1288 ----
  	  rtx insn = BB_END (loop->header);

  	  fprintf (dump_file, "SMS loop many exits");
! 	  dump_insn_location (insn);
  	  fprintf (dump_file, "\n");
  	}
        return false;
*************** loop_canon_p (struct loop *loop)
*** 1295,1301 ****
  	  rtx insn = BB_END (loop->header);

  	  fprintf (dump_file, "SMS loop many BBs.");
! 	  dump_insn_locator (insn);
  	  fprintf (dump_file, "\n");
  	}
        return false;
--- 1295,1301 ----
  	  rtx insn = BB_END (loop->header);

  	  fprintf (dump_file, "SMS loop many BBs.");
! 	  dump_insn_location (insn);
  	  fprintf (dump_file, "\n");
  	}
        return false;
*************** sms_schedule (void)
*** 1421,1427 ****
  	  rtx insn = BB_END (loop->header);

  	  fprintf (dump_file, "SMS loop num: %d", loop->num);
! 	  dump_insn_locator (insn);
  	  fprintf (dump_file, "\n");
  	}

--- 1421,1427 ----
  	  rtx insn = BB_END (loop->header);

  	  fprintf (dump_file, "SMS loop num: %d", loop->num);
! 	  dump_insn_location (insn);
  	  fprintf (dump_file, "\n");
  	}

*************** sms_schedule (void)
*** 1450,1456 ****
  	{
  	  if (dump_file)
  	    {
! 	      dump_insn_locator (tail);
  	      fprintf (dump_file, "\nSMS single-bb-loop\n");
  	      if (profile_info && flag_branch_probabilities)
  	    	{
--- 1450,1456 ----
  	{
  	  if (dump_file)
  	    {
! 	      dump_insn_location (tail);
  	      fprintf (dump_file, "\nSMS single-bb-loop\n");
  	      if (profile_info && flag_branch_probabilities)
  	    	{
*************** sms_schedule (void)
*** 1556,1562 ****
  	  rtx insn = BB_END (loop->header);

  	  fprintf (dump_file, "SMS loop num: %d", loop->num);
! 	  dump_insn_locator (insn);
  	  fprintf (dump_file, "\n");

  	  print_ddg (dump_file, g);
--- 1556,1562 ----
  	  rtx insn = BB_END (loop->header);

  	  fprintf (dump_file, "SMS loop num: %d", loop->num);
! 	  dump_insn_location (insn);
  	  fprintf (dump_file, "\n");

  	  print_ddg (dump_file, g);
*************** sms_schedule (void)
*** 1571,1577 ****

        if (dump_file)
  	{
! 	  dump_insn_locator (tail);
  	  fprintf (dump_file, "\nSMS single-bb-loop\n");
  	  if (profile_info && flag_branch_probabilities)
  	    {
--- 1571,1577 ----

        if (dump_file)
  	{
! 	  dump_insn_location (tail);
  	  fprintf (dump_file, "\nSMS single-bb-loop\n");
  	  if (profile_info && flag_branch_probabilities)
  	    {
*************** sms_schedule (void)
*** 1714,1720 ****

            if (dump_file)
              {
! 	      dump_insn_locator (tail);
  	      fprintf (dump_file, " SMS succeeded %d %d (with ii, sc)\n",
  		       ps->ii, stage_count);
  	      print_partial_schedule (ps, dump_file);
--- 1714,1720 ----

            if (dump_file)
              {
! 	      dump_insn_location (tail);
  	      fprintf (dump_file, " SMS succeeded %d %d (with ii, sc)\n",
  		       ps->ii, stage_count);
  	      print_partial_schedule (ps, dump_file);
Index: gcc/lto-streamer-out.c
===================================================================
*** gcc/lto-streamer-out.c	(revision 190209)
--- gcc/lto-streamer-out.c	(working copy)
*************** lto_output_location_bitpack (struct bitp
*** 155,160 ****
--- 155,161 ----
  {
    expanded_location xloc;

+   loc = LOCATION_LOCUS (loc);
    bp_pack_value (bp, loc == UNKNOWN_LOCATION, 1);
    if (loc == UNKNOWN_LOCATION)
      return;
Index: gcc/jump.c
===================================================================
*** gcc/jump.c	(revision 190209)
--- gcc/jump.c	(working copy)
*************** rtx_renumbered_equal_p (const_rtx x, con
*** 1818,1825 ****
  	  if (XINT (x, i) != XINT (y, i))
  	    {
  	      if (((code == ASM_OPERANDS && i == 6)
! 		   || (code == ASM_INPUT && i == 1))
! 		  && locator_eq (XINT (x, i), XINT (y, i)))
  		break;
  	      return 0;
  	    }
--- 1818,1824 ----
  	  if (XINT (x, i) != XINT (y, i))
  	    {
  	      if (((code == ASM_OPERANDS && i == 6)
! 		   || (code == ASM_INPUT && i == 1)))
  		break;
  	      return 0;
  	    }
Index: gcc/ifcvt.c
===================================================================
*** gcc/ifcvt.c	(revision 190209)
--- gcc/ifcvt.c	(working copy)
*************** noce_try_move (struct noce_if_info *if_i
*** 1019,1025 ****
  	    return FALSE;

  	  emit_insn_before_setloc (seq, if_info->jump,
! 				   INSN_LOCATOR (if_info->insn_a));
  	}
        return TRUE;
      }
--- 1019,1025 ----
  	    return FALSE;

  	  emit_insn_before_setloc (seq, if_info->jump,
! 				   INSN_LOCATION (if_info->insn_a));
  	}
        return TRUE;
      }
*************** noce_try_store_flag (struct noce_if_info
*** 1064,1070 ****
  	return FALSE;

        emit_insn_before_setloc (seq, if_info->jump,
! 			       INSN_LOCATOR (if_info->insn_a));
        return TRUE;
      }
    else
--- 1064,1070 ----
  	return FALSE;

        emit_insn_before_setloc (seq, if_info->jump,
! 			       INSN_LOCATION (if_info->insn_a));
        return TRUE;
      }
    else
*************** noce_try_store_flag_constants (struct no
*** 1195,1201 ****
  	return FALSE;

        emit_insn_before_setloc (seq, if_info->jump,
! 			       INSN_LOCATOR (if_info->insn_a));
        return TRUE;
      }

--- 1195,1201 ----
  	return FALSE;

        emit_insn_before_setloc (seq, if_info->jump,
! 			       INSN_LOCATION (if_info->insn_a));
        return TRUE;
      }

*************** noce_try_addcc (struct noce_if_info *if_
*** 1243,1249 ****
  		return FALSE;

  	      emit_insn_before_setloc (seq, if_info->jump,
! 				       INSN_LOCATOR (if_info->insn_a));
  	      return TRUE;
  	    }
  	  end_sequence ();
--- 1243,1249 ----
  		return FALSE;

  	      emit_insn_before_setloc (seq, if_info->jump,
! 				       INSN_LOCATION (if_info->insn_a));
  	      return TRUE;
  	    }
  	  end_sequence ();
*************** noce_try_addcc (struct noce_if_info *if_
*** 1283,1289 ****
  		return FALSE;

  	      emit_insn_before_setloc (seq, if_info->jump,
! 				       INSN_LOCATOR (if_info->insn_a));
  	      return TRUE;
  	    }
  	  end_sequence ();
--- 1283,1289 ----
  		return FALSE;

  	      emit_insn_before_setloc (seq, if_info->jump,
! 				       INSN_LOCATION (if_info->insn_a));
  	      return TRUE;
  	    }
  	  end_sequence ();
*************** noce_try_store_flag_mask (struct noce_if
*** 1332,1338 ****
  	    return FALSE;

  	  emit_insn_before_setloc (seq, if_info->jump,
! 				   INSN_LOCATOR (if_info->insn_a));
  	  return TRUE;
  	}

--- 1332,1338 ----
  	    return FALSE;

  	  emit_insn_before_setloc (seq, if_info->jump,
! 				   INSN_LOCATION (if_info->insn_a));
  	  return TRUE;
  	}

*************** noce_try_cmove (struct noce_if_info *if_
*** 1481,1487 ****
  	    return FALSE;

  	  emit_insn_before_setloc (seq, if_info->jump,
! 				   INSN_LOCATOR (if_info->insn_a));
  	  return TRUE;
  	}
        else
--- 1481,1487 ----
  	    return FALSE;

  	  emit_insn_before_setloc (seq, if_info->jump,
! 				   INSN_LOCATION (if_info->insn_a));
  	  return TRUE;
  	}
        else
*************** noce_try_cmove_arith (struct noce_if_inf
*** 1682,1688 ****
    if (!tmp)
      return FALSE;

!   emit_insn_before_setloc (tmp, if_info->jump, INSN_LOCATOR
(if_info->insn_a));
    return TRUE;

   end_seq_and_fail:
--- 1682,1688 ----
    if (!tmp)
      return FALSE;

!   emit_insn_before_setloc (tmp, if_info->jump, INSN_LOCATION
(if_info->insn_a));
    return TRUE;

   end_seq_and_fail:
*************** noce_try_minmax (struct noce_if_info *if
*** 1929,1935 ****
    if (!seq)
      return FALSE;

!   emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATOR
(if_info->insn_a));
    if_info->cond = cond;
    if_info->cond_earliest = earliest;

--- 1929,1935 ----
    if (!seq)
      return FALSE;

!   emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION
(if_info->insn_a));
    if_info->cond = cond;
    if_info->cond_earliest = earliest;

*************** noce_try_abs (struct noce_if_info *if_in
*** 2076,2082 ****
    if (!seq)
      return FALSE;

!   emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATOR
(if_info->insn_a));
    if_info->cond = cond;
    if_info->cond_earliest = earliest;

--- 2076,2082 ----
    if (!seq)
      return FALSE;

!   emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION
(if_info->insn_a));
    if_info->cond = cond;
    if_info->cond_earliest = earliest;

*************** noce_try_sign_mask (struct noce_if_info
*** 2155,2161 ****
    if (!seq)
      return FALSE;

!   emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATOR
(if_info->insn_a));
    return TRUE;
  }

--- 2155,2161 ----
    if (!seq)
      return FALSE;

!   emit_insn_before_setloc (seq, if_info->jump, INSN_LOCATION
(if_info->insn_a));
    return TRUE;
  }

*************** noce_try_bitop (struct noce_if_info *if_
*** 2255,2261 ****
  	return FALSE;

        emit_insn_before_setloc (seq, if_info->jump,
! 			       INSN_LOCATOR (if_info->insn_a));
      }
    return TRUE;
  }
--- 2255,2261 ----
  	return FALSE;

        emit_insn_before_setloc (seq, if_info->jump,
! 			       INSN_LOCATION (if_info->insn_a));
      }
    return TRUE;
  }
*************** noce_process_if_block (struct noce_if_in
*** 2656,2662 ****
        unshare_all_rtl_in_chain (seq);
        end_sequence ();

!       emit_insn_before_setloc (seq, BB_END (test_bb), INSN_LOCATOR (insn_a));
      }

    /* The original THEN and ELSE blocks may now be removed.  The test block
--- 2656,2662 ----
        unshare_all_rtl_in_chain (seq);
        end_sequence ();

!       emit_insn_before_setloc (seq, BB_END (test_bb), INSN_LOCATION (insn_a));
      }

    /* The original THEN and ELSE blocks may now be removed.  The test block
*************** cond_move_process_if_block (struct noce_
*** 2937,2943 ****
        loc_insn = first_active_insn (else_bb);
        gcc_assert (loc_insn);
      }
!   emit_insn_before_setloc (seq, jump, INSN_LOCATOR (loc_insn));

    if (else_bb)
      {
--- 2937,2943 ----
        loc_insn = first_active_insn (else_bb);
        gcc_assert (loc_insn);
      }
!   emit_insn_before_setloc (seq, jump, INSN_LOCATION (loc_insn));

    if (else_bb)
      {
*************** find_cond_trap (basic_block test_bb, edg
*** 3655,3661 ****
      return FALSE;

    /* Emit the new insns before cond_earliest.  */
!   emit_insn_before_setloc (seq, cond_earliest, INSN_LOCATOR (trap));

    /* Delete the trap block if possible.  */
    remove_edge (trap_bb == then_bb ? then_edge : else_edge);
--- 3655,3661 ----
      return FALSE;

    /* Emit the new insns before cond_earliest.  */
!   emit_insn_before_setloc (seq, cond_earliest, INSN_LOCATION (trap));

    /* Delete the trap block if possible.  */
    remove_edge (trap_bb == then_bb ? then_edge : else_edge);
Index: gcc/dwarf2out.c
===================================================================
*** gcc/dwarf2out.c	(revision 190209)
--- gcc/dwarf2out.c	(working copy)
*************** add_src_coords_attributes (dw_die_ref di
*** 15506,15512 ****
  {
    expanded_location s;

!   if (DECL_SOURCE_LOCATION (decl) == UNKNOWN_LOCATION)
      return;
    s = expand_location (DECL_SOURCE_LOCATION (decl));
    add_AT_file (die, DW_AT_decl_file, lookup_filename (s.file));
--- 15506,15512 ----
  {
    expanded_location s;

!   if (IS_UNKNOWN_LOCATION (DECL_SOURCE_LOCATION (decl)))
      return;
    s = expand_location (DECL_SOURCE_LOCATION (decl));
    add_AT_file (die, DW_AT_decl_file, lookup_filename (s.file));
Index: gcc/expr.c
===================================================================
*** gcc/expr.c	(revision 190209)
--- gcc/expr.c	(working copy)
*************** expand_expr_real (tree exp, rtx target,
*** 7802,7820 ****
    if (cfun && EXPR_HAS_LOCATION (exp))
      {
        location_t saved_location = input_location;
!       location_t saved_curr_loc = get_curr_insn_source_location ();
!       tree saved_block = get_curr_insn_block ();
        input_location = EXPR_LOCATION (exp);
!       set_curr_insn_source_location (input_location);
!
!       /* Record where the insns produced belong.  */
!       set_curr_insn_block (TREE_BLOCK (exp));

        ret = expand_expr_real_1 (exp, target, tmode, modifier, alt_rtl);

        input_location = saved_location;
!       set_curr_insn_block (saved_block);
!       set_curr_insn_source_location (saved_curr_loc);
      }
    else
      {
--- 7802,7815 ----
    if (cfun && EXPR_HAS_LOCATION (exp))
      {
        location_t saved_location = input_location;
!       location_t saved_curr_loc = curr_insn_location ();
        input_location = EXPR_LOCATION (exp);
!       set_curr_insn_location (input_location);

        ret = expand_expr_real_1 (exp, target, tmode, modifier, alt_rtl);

        input_location = saved_location;
!       set_curr_insn_location (saved_curr_loc);
      }
    else
      {
Index: gcc/tree-parloops.c
===================================================================
*** gcc/tree-parloops.c	(revision 190209)
--- gcc/tree-parloops.c	(working copy)
*************** create_loop_fn (location_t loc)
*** 1404,1409 ****
--- 1404,1410 ----
    struct function *act_cfun = cfun;
    static unsigned loopfn_num;

+   loc = LOCATION_LOCUS (loc);
    snprintf (buf, 100, "%s.$loopfn", current_function_name ());
    ASM_FORMAT_PRIVATE_NAME (tname, buf, loopfn_num++);
    clean_symbol_name (tname);
Index: gcc/recog.c
===================================================================
*** gcc/recog.c	(revision 190209)
--- gcc/recog.c	(working copy)
*************** peep2_attempt (basic_block bb, rtx insn,
*** 3326,3332 ****
    /* Replace the old sequence with the new.  */
    last = emit_insn_after_setloc (attempt,
  				 peep2_insn_data[i].insn,
! 				 INSN_LOCATOR (peep2_insn_data[i].insn));
    before_try = PREV_INSN (insn);
    delete_insn_chain (insn, peep2_insn_data[i].insn, false);

--- 3326,3332 ----
    /* Replace the old sequence with the new.  */
    last = emit_insn_after_setloc (attempt,
  				 peep2_insn_data[i].insn,
! 				 INSN_LOCATION (peep2_insn_data[i].insn));
    before_try = PREV_INSN (insn);
    delete_insn_chain (insn, peep2_insn_data[i].insn, false);

Index: gcc/function.c
===================================================================
*** gcc/function.c	(revision 190209)
--- gcc/function.c	(working copy)
*************** static bool contains (const_rtx, htab_t)
*** 133,139 ****
  static void prepare_function_start (void);
  static void do_clobber_return_reg (rtx, void *);
  static void do_use_return_reg (rtx, void *);
! static void set_insn_locators (rtx, int) ATTRIBUTE_UNUSED;
  
  /* Stack of nested functions.  */
  /* Keep track of the cfun stack.  */
--- 133,139 ----
  static void prepare_function_start (void);
  static void do_clobber_return_reg (rtx, void *);
  static void do_use_return_reg (rtx, void *);
! static void set_insn_locations (rtx, int) ATTRIBUTE_UNUSED;
  
  /* Stack of nested functions.  */
  /* Keep track of the cfun stack.  */
*************** free_after_compilation (struct function
*** 200,206 ****
    f->cfg = NULL;

    regno_reg_rtx = NULL;
-   insn_locators_free ();
  }
  
  /* Return size needed for stack frame based on slots so far allocated.
--- 200,205 ----
*************** expand_function_end (void)
*** 4979,4985 ****
  	      probe_stack_range (STACK_OLD_CHECK_PROTECT, max_frame_size);
  	    seq = get_insns ();
  	    end_sequence ();
! 	    set_insn_locators (seq, prologue_locator);
  	    emit_insn_before (seq, stack_check_probe_note);
  	    break;
  	  }
--- 4978,4984 ----
  	      probe_stack_range (STACK_OLD_CHECK_PROTECT, max_frame_size);
  	    seq = get_insns ();
  	    end_sequence ();
! 	    set_insn_locations (seq, prologue_location);
  	    emit_insn_before (seq, stack_check_probe_note);
  	    break;
  	  }
*************** expand_function_end (void)
*** 4994,5000 ****

    /* Output a linenumber for the end of the function.
       SDB depends on this.  */
!   set_curr_insn_source_location (input_location);

    /* Before the return label (if any), clobber the return
       registers so that they are not propagated live to the rest of
--- 4993,4999 ----

    /* Output a linenumber for the end of the function.
       SDB depends on this.  */
!   set_curr_insn_location (input_location);

    /* Before the return label (if any), clobber the return
       registers so that they are not propagated live to the rest of
*************** maybe_copy_prologue_epilogue_insn (rtx i
*** 5277,5290 ****
    *slot = copy;
  }

! /* Set the locator of the insn chain starting at INSN to LOC.  */
  static void
! set_insn_locators (rtx insn, int loc)
  {
    while (insn != NULL_RTX)
      {
        if (INSN_P (insn))
! 	INSN_LOCATOR (insn) = loc;
        insn = NEXT_INSN (insn);
      }
  }
--- 5276,5289 ----
    *slot = copy;
  }

! /* Set the location of the insn chain starting at INSN to LOC.  */
  static void
! set_insn_locations (rtx insn, int loc)
  {
    while (insn != NULL_RTX)
      {
        if (INSN_P (insn))
! 	INSN_LOCATION (insn) = loc;
        insn = NEXT_INSN (insn);
      }
  }
*************** thread_prologue_and_epilogue_insns (void
*** 5893,5899 ****
        end_sequence ();

        record_insns (split_prologue_seq, NULL, &prologue_insn_hash);
!       set_insn_locators (split_prologue_seq, prologue_locator);
  #endif
      }

--- 5892,5898 ----
        end_sequence ();

        record_insns (split_prologue_seq, NULL, &prologue_insn_hash);
!       set_insn_locations (split_prologue_seq, prologue_location);
  #endif
      }

*************** thread_prologue_and_epilogue_insns (void
*** 5922,5928 ****

        prologue_seq = get_insns ();
        end_sequence ();
!       set_insn_locators (prologue_seq, prologue_locator);
      }
  #endif

--- 5921,5927 ----

        prologue_seq = get_insns ();
        end_sequence ();
!       set_insn_locations (prologue_seq, prologue_location);
      }
  #endif

*************** thread_prologue_and_epilogue_insns (void
*** 6418,6424 ****

        /* Retain a map of the epilogue insns.  */
        record_insns (seq, NULL, &epilogue_insn_hash);
!       set_insn_locators (seq, epilogue_locator);

        seq = get_insns ();
        returnjump = get_last_insn ();
--- 6417,6423 ----

        /* Retain a map of the epilogue insns.  */
        record_insns (seq, NULL, &epilogue_insn_hash);
!       set_insn_locations (seq, epilogue_location);

        seq = get_insns ();
        returnjump = get_last_insn ();
*************** epilogue_done:
*** 6608,6614 ****
  	     avoid getting rid of sibcall epilogue insns.  Do this before we
  	     actually emit the sequence.  */
  	  record_insns (seq, NULL, &epilogue_insn_hash);
! 	  set_insn_locators (seq, epilogue_locator);

  	  emit_insn_before (seq, insn);
  	}
--- 6607,6613 ----
  	     avoid getting rid of sibcall epilogue insns.  Do this before we
  	     actually emit the sequence.  */
  	  record_insns (seq, NULL, &epilogue_insn_hash);
! 	  set_insn_locations (seq, epilogue_location);

  	  emit_insn_before (seq, insn);
  	}
Index: gcc/print-rtl.c
===================================================================
*** gcc/print-rtl.c	(revision 190209)
--- gcc/print-rtl.c	(working copy)
*************** print_rtx (const_rtx in_rtx)
*** 416,425 ****
  	if (i == 5 && INSN_P (in_rtx))
  	  {
  #ifndef GENERATOR_FILE
! 	    /*  Pretty-print insn locators.  Ignore scoping as it is mostly
  		redundant with line number information and do not print anything
  		when there is no location information available.  */
! 	    if (INSN_LOCATOR (in_rtx) && insn_file (in_rtx))
  	      fprintf(outfile, " %s:%i", insn_file (in_rtx), insn_line (in_rtx));
  #endif
  	  }
--- 416,425 ----
  	if (i == 5 && INSN_P (in_rtx))
  	  {
  #ifndef GENERATOR_FILE
! 	    /*  Pretty-print insn locations.  Ignore scoping as it is mostly
  		redundant with line number information and do not print anything
  		when there is no location information available.  */
! 	    if (INSN_LOCATION (in_rtx) && insn_file (in_rtx))
  	      fprintf(outfile, " %s:%i", insn_file (in_rtx), insn_line (in_rtx));
  #endif
  	  }
*************** print_rtx (const_rtx in_rtx)
*** 427,442 ****
  	  {
  #ifndef GENERATOR_FILE
  	    fprintf (outfile, " %s:%i",
! 		     locator_file (ASM_OPERANDS_SOURCE_LOCATION (in_rtx)),
! 		     locator_line (ASM_OPERANDS_SOURCE_LOCATION (in_rtx)));
  #endif
  	  }
  	else if (i == 1 && GET_CODE (in_rtx) == ASM_INPUT)
  	  {
  #ifndef GENERATOR_FILE
  	    fprintf (outfile, " %s:%i",
! 		     locator_file (ASM_INPUT_SOURCE_LOCATION (in_rtx)),
! 		     locator_line (ASM_INPUT_SOURCE_LOCATION (in_rtx)));
  #endif
  	  }
  	else if (i == 6 && NOTE_P (in_rtx))
--- 427,442 ----
  	  {
  #ifndef GENERATOR_FILE
  	    fprintf (outfile, " %s:%i",
! 		     LOCATION_FILE (ASM_OPERANDS_SOURCE_LOCATION (in_rtx)),
! 		     LOCATION_LINE (ASM_OPERANDS_SOURCE_LOCATION (in_rtx)));
  #endif
  	  }
  	else if (i == 1 && GET_CODE (in_rtx) == ASM_INPUT)
  	  {
  #ifndef GENERATOR_FILE
  	    fprintf (outfile, " %s:%i",
! 		     LOCATION_FILE (ASM_INPUT_SOURCE_LOCATION (in_rtx)),
! 		     LOCATION_LINE (ASM_INPUT_SOURCE_LOCATION (in_rtx)));
  #endif
  	  }
  	else if (i == 6 && NOTE_P (in_rtx))
Index: gcc/profile.c
===================================================================
*** gcc/profile.c	(revision 190209)
--- gcc/profile.c	(working copy)
*************** branch_prob (void)
*** 966,972 ****
  	     is not computed twice.  */
  	  if (last
  	      && gimple_has_location (last)
! 	      && e->goto_locus != UNKNOWN_LOCATION
  	      && !single_succ_p (bb)
  	      && (LOCATION_FILE (e->goto_locus)
  	          != LOCATION_FILE (gimple_location (last))
--- 966,972 ----
  	     is not computed twice.  */
  	  if (last
  	      && gimple_has_location (last)
! 	      && !IS_UNKNOWN_LOCATION (e->goto_locus)
  	      && !single_succ_p (bb)
  	      && (LOCATION_FILE (e->goto_locus)
  	          != LOCATION_FILE (gimple_location (last))
*************** branch_prob (void)
*** 976,982 ****
  	      basic_block new_bb = split_edge (e);
  	      edge ne = single_succ_edge (new_bb);
  	      ne->goto_locus = e->goto_locus;
- 	      ne->goto_block = e->goto_block;
  	    }
  	  if ((e->flags & (EDGE_ABNORMAL | EDGE_ABNORMAL_CALL))
  	       && e->dest != EXIT_BLOCK_PTR)
--- 976,981 ----
*************** branch_prob (void)
*** 1188,1194 ****

  	  /* Notice GOTO expressions eliminated while constructing the CFG.  */
  	  if (single_succ_p (bb)
! 	      && single_succ_edge (bb)->goto_locus != UNKNOWN_LOCATION)
  	    {
  	      expanded_location curr_location
  		= expand_location (single_succ_edge (bb)->goto_locus);
--- 1187,1193 ----

  	  /* Notice GOTO expressions eliminated while constructing the CFG.  */
  	  if (single_succ_p (bb)
! 	      && !IS_UNKNOWN_LOCATION (single_succ_edge (bb)->goto_locus))
  	    {
  	      expanded_location curr_location
  		= expand_location (single_succ_edge (bb)->goto_locus);
Index: gcc/trans-mem.c
===================================================================
*** gcc/trans-mem.c	(revision 190209)
--- gcc/trans-mem.c	(working copy)
*************** ipa_tm_scan_irr_block (basic_block bb)
*** 3795,3801 ****
  	    {
  	      tree t = build1 (NOP_EXPR, void_type_node, size_zero_node);
  	      SET_EXPR_LOCATION (t, gimple_location (stmt));
- 	      TREE_BLOCK (t) = gimple_block (stmt);
  	      error ("%Kasm not allowed in %<transaction_safe%> function", t);
  	    }
  	  return true;
--- 3795,3800 ----
Index: gcc/gimplify.c
===================================================================
*** gcc/gimplify.c	(revision 190209)
--- gcc/gimplify.c	(working copy)
*************** gimplify_call_expr (tree *expr_p, gimple
*** 2591,2597 ****
  	    = CALL_EXPR_RETURN_SLOT_OPT (call);
  	  CALL_FROM_THUNK_P (*expr_p) = CALL_FROM_THUNK_P (call);
  	  SET_EXPR_LOCATION (*expr_p, EXPR_LOCATION (call));
- 	  TREE_BLOCK (*expr_p) = TREE_BLOCK (call);

  	  /* Set CALL_EXPR_VA_ARG_PACK.  */
  	  CALL_EXPR_VA_ARG_PACK (*expr_p) = 1;
--- 2591,2596 ----
Index: gcc/except.c
===================================================================
*** gcc/except.c	(revision 190209)
--- gcc/except.c	(working copy)
*************** duplicate_eh_regions_1 (struct duplicate
*** 526,532 ****
        break;

      case ERT_MUST_NOT_THROW:
!       new_r->u.must_not_throw = old_r->u.must_not_throw;
        break;
      }

--- 526,535 ----
        break;

      case ERT_MUST_NOT_THROW:
!       new_r->u.must_not_throw.failure_loc =
! 	LOCATION_LOCUS (old_r->u.must_not_throw.failure_loc);
!       new_r->u.must_not_throw.failure_decl =
! 	old_r->u.must_not_throw.failure_decl;
        break;
      }

Index: gcc/emit-rtl.c
===================================================================
*** gcc/emit-rtl.c	(revision 190209)
--- gcc/emit-rtl.c	(working copy)
*************** try_split (rtx pat, rtx trial, int last)
*** 3634,3640 ****
  	}
      }

!   tem = emit_insn_after_setloc (seq, trial, INSN_LOCATOR (trial));

    delete_insn (trial);
    if (has_barrier)
--- 3634,3640 ----
  	}
      }

!   tem = emit_insn_after_setloc (seq, trial, INSN_LOCATION (trial));

    delete_insn (trial);
    if (has_barrier)
*************** make_insn_raw (rtx pattern)
*** 3670,3676 ****
    PATTERN (insn) = pattern;
    INSN_CODE (insn) = -1;
    REG_NOTES (insn) = NULL;
!   INSN_LOCATOR (insn) = curr_insn_locator ();
    BLOCK_FOR_INSN (insn) = NULL;

  #ifdef ENABLE_RTL_CHECKING
--- 3670,3676 ----
    PATTERN (insn) = pattern;
    INSN_CODE (insn) = -1;
    REG_NOTES (insn) = NULL;
!   INSN_LOCATION (insn) = curr_insn_location ();
    BLOCK_FOR_INSN (insn) = NULL;

  #ifdef ENABLE_RTL_CHECKING
*************** make_debug_insn_raw (rtx pattern)
*** 3703,3709 ****
    PATTERN (insn) = pattern;
    INSN_CODE (insn) = -1;
    REG_NOTES (insn) = NULL;
!   INSN_LOCATOR (insn) = curr_insn_locator ();
    BLOCK_FOR_INSN (insn) = NULL;

    return insn;
--- 3703,3709 ----
    PATTERN (insn) = pattern;
    INSN_CODE (insn) = -1;
    REG_NOTES (insn) = NULL;
!   INSN_LOCATION (insn) = curr_insn_location ();
    BLOCK_FOR_INSN (insn) = NULL;

    return insn;
*************** make_jump_insn_raw (rtx pattern)
*** 3723,3729 ****
    INSN_CODE (insn) = -1;
    REG_NOTES (insn) = NULL;
    JUMP_LABEL (insn) = NULL;
!   INSN_LOCATOR (insn) = curr_insn_locator ();
    BLOCK_FOR_INSN (insn) = NULL;

    return insn;
--- 3723,3729 ----
    INSN_CODE (insn) = -1;
    REG_NOTES (insn) = NULL;
    JUMP_LABEL (insn) = NULL;
!   INSN_LOCATION (insn) = curr_insn_location ();
    BLOCK_FOR_INSN (insn) = NULL;

    return insn;
*************** make_call_insn_raw (rtx pattern)
*** 3743,3749 ****
    INSN_CODE (insn) = -1;
    REG_NOTES (insn) = NULL;
    CALL_INSN_FUNCTION_USAGE (insn) = NULL;
!   INSN_LOCATOR (insn) = curr_insn_locator ();
    BLOCK_FOR_INSN (insn) = NULL;

    return insn;
--- 3743,3749 ----
    INSN_CODE (insn) = -1;
    REG_NOTES (insn) = NULL;
    CALL_INSN_FUNCTION_USAGE (insn) = NULL;
!   INSN_LOCATION (insn) = curr_insn_location ();
    BLOCK_FOR_INSN (insn) = NULL;

    return insn;
*************** emit_pattern_after_setloc (rtx pattern,
*** 4416,4423 ****
    after = NEXT_INSN (after);
    while (1)
      {
!       if (active_insn_p (after) && !INSN_LOCATOR (after))
! 	INSN_LOCATOR (after) = loc;
        if (after == last)
  	break;
        after = NEXT_INSN (after);
--- 4416,4423 ----
    after = NEXT_INSN (after);
    while (1)
      {
!       if (active_insn_p (after) && !INSN_LOCATION (after))
! 	INSN_LOCATION (after) = loc;
        if (after == last)
  	break;
        after = NEXT_INSN (after);
*************** emit_pattern_after (rtx pattern, rtx aft
*** 4440,4501 ****
        prev = PREV_INSN (prev);

    if (INSN_P (prev))
!     return emit_pattern_after_setloc (pattern, after, INSN_LOCATOR (prev),
  				      make_raw);
    else
      return emit_pattern_after_noloc (pattern, after, NULL, make_raw);
  }

! /* Like emit_insn_after_noloc, but set INSN_LOCATOR according to LOC.  */
  rtx
  emit_insn_after_setloc (rtx pattern, rtx after, int loc)
  {
    return emit_pattern_after_setloc (pattern, after, loc, make_insn_raw);
  }

! /* Like emit_insn_after_noloc, but set INSN_LOCATOR according to AFTER.  */
  rtx
  emit_insn_after (rtx pattern, rtx after)
  {
    return emit_pattern_after (pattern, after, true, make_insn_raw);
  }

! /* Like emit_jump_insn_after_noloc, but set INSN_LOCATOR according to LOC.  */
  rtx
  emit_jump_insn_after_setloc (rtx pattern, rtx after, int loc)
  {
    return emit_pattern_after_setloc (pattern, after, loc, make_jump_insn_raw);
  }

! /* Like emit_jump_insn_after_noloc, but set INSN_LOCATOR according
to AFTER.  */
  rtx
  emit_jump_insn_after (rtx pattern, rtx after)
  {
    return emit_pattern_after (pattern, after, true, make_jump_insn_raw);
  }

! /* Like emit_call_insn_after_noloc, but set INSN_LOCATOR according to LOC.  */
  rtx
  emit_call_insn_after_setloc (rtx pattern, rtx after, int loc)
  {
    return emit_pattern_after_setloc (pattern, after, loc, make_call_insn_raw);
  }

! /* Like emit_call_insn_after_noloc, but set INSN_LOCATOR according
to AFTER.  */
  rtx
  emit_call_insn_after (rtx pattern, rtx after)
  {
    return emit_pattern_after (pattern, after, true, make_call_insn_raw);
  }

! /* Like emit_debug_insn_after_noloc, but set INSN_LOCATOR according
to LOC.  */
  rtx
  emit_debug_insn_after_setloc (rtx pattern, rtx after, int loc)
  {
    return emit_pattern_after_setloc (pattern, after, loc, make_debug_insn_raw);
  }

! /* Like emit_debug_insn_after_noloc, but set INSN_LOCATOR according
to AFTER.  */
  rtx
  emit_debug_insn_after (rtx pattern, rtx after)
  {
--- 4440,4501 ----
        prev = PREV_INSN (prev);

    if (INSN_P (prev))
!     return emit_pattern_after_setloc (pattern, after, INSN_LOCATION (prev),
  				      make_raw);
    else
      return emit_pattern_after_noloc (pattern, after, NULL, make_raw);
  }

! /* Like emit_insn_after_noloc, but set INSN_LOCATION according to LOC.  */
  rtx
  emit_insn_after_setloc (rtx pattern, rtx after, int loc)
  {
    return emit_pattern_after_setloc (pattern, after, loc, make_insn_raw);
  }

! /* Like emit_insn_after_noloc, but set INSN_LOCATION according to AFTER.  */
  rtx
  emit_insn_after (rtx pattern, rtx after)
  {
    return emit_pattern_after (pattern, after, true, make_insn_raw);
  }

! /* Like emit_jump_insn_after_noloc, but set INSN_LOCATION according
to LOC.  */
  rtx
  emit_jump_insn_after_setloc (rtx pattern, rtx after, int loc)
  {
    return emit_pattern_after_setloc (pattern, after, loc, make_jump_insn_raw);
  }

! /* Like emit_jump_insn_after_noloc, but set INSN_LOCATION according
to AFTER.  */
  rtx
  emit_jump_insn_after (rtx pattern, rtx after)
  {
    return emit_pattern_after (pattern, after, true, make_jump_insn_raw);
  }

! /* Like emit_call_insn_after_noloc, but set INSN_LOCATION according
to LOC.  */
  rtx
  emit_call_insn_after_setloc (rtx pattern, rtx after, int loc)
  {
    return emit_pattern_after_setloc (pattern, after, loc, make_call_insn_raw);
  }

! /* Like emit_call_insn_after_noloc, but set INSN_LOCATION according
to AFTER.  */
  rtx
  emit_call_insn_after (rtx pattern, rtx after)
  {
    return emit_pattern_after (pattern, after, true, make_call_insn_raw);
  }

! /* Like emit_debug_insn_after_noloc, but set INSN_LOCATION according
to LOC.  */
  rtx
  emit_debug_insn_after_setloc (rtx pattern, rtx after, int loc)
  {
    return emit_pattern_after_setloc (pattern, after, loc, make_debug_insn_raw);
  }

! /* Like emit_debug_insn_after_noloc, but set INSN_LOCATION according
to AFTER.  */
  rtx
  emit_debug_insn_after (rtx pattern, rtx after)
  {
*************** emit_pattern_before_setloc (rtx pattern,
*** 4525,4532 ****
      first = NEXT_INSN (first);
    while (1)
      {
!       if (active_insn_p (first) && !INSN_LOCATOR (first))
! 	INSN_LOCATOR (first) = loc;
        if (first == last)
  	break;
        first = NEXT_INSN (first);
--- 4525,4532 ----
      first = NEXT_INSN (first);
    while (1)
      {
!       if (active_insn_p (first) && !INSN_LOCATION (first))
! 	INSN_LOCATION (first) = loc;
        if (first == last)
  	break;
        first = NEXT_INSN (first);
*************** emit_pattern_before (rtx pattern, rtx be
*** 4550,4556 ****
        next = PREV_INSN (next);

    if (INSN_P (next))
!     return emit_pattern_before_setloc (pattern, before, INSN_LOCATOR (next),
  				       insnp, make_raw);
    else
      return emit_pattern_before_noloc (pattern, before,
--- 4550,4556 ----
        next = PREV_INSN (next);

    if (INSN_P (next))
!     return emit_pattern_before_setloc (pattern, before, INSN_LOCATION (next),
  				       insnp, make_raw);
    else
      return emit_pattern_before_noloc (pattern, before,
*************** emit_pattern_before (rtx pattern, rtx be
*** 4558,4564 ****
                                        NULL, make_raw);
  }

! /* Like emit_insn_before_noloc, but set INSN_LOCATOR according to LOC.  */
  rtx
  emit_insn_before_setloc (rtx pattern, rtx before, int loc)
  {
--- 4558,4564 ----
                                        NULL, make_raw);
  }

! /* Like emit_insn_before_noloc, but set INSN_LOCATION according to LOC.  */
  rtx
  emit_insn_before_setloc (rtx pattern, rtx before, int loc)
  {
*************** emit_insn_before_setloc (rtx pattern, rt
*** 4566,4579 ****
  				     make_insn_raw);
  }

! /* Like emit_insn_before_noloc, but set INSN_LOCATOR according to BEFORE.  */
  rtx
  emit_insn_before (rtx pattern, rtx before)
  {
    return emit_pattern_before (pattern, before, true, true, make_insn_raw);
  }

! /* like emit_insn_before_noloc, but set INSN_LOCATOR according to LOC.  */
  rtx
  emit_jump_insn_before_setloc (rtx pattern, rtx before, int loc)
  {
--- 4566,4579 ----
  				     make_insn_raw);
  }

! /* Like emit_insn_before_noloc, but set INSN_LOCATION according to BEFORE.  */
  rtx
  emit_insn_before (rtx pattern, rtx before)
  {
    return emit_pattern_before (pattern, before, true, true, make_insn_raw);
  }

! /* like emit_insn_before_noloc, but set INSN_LOCATION according to LOC.  */
  rtx
  emit_jump_insn_before_setloc (rtx pattern, rtx before, int loc)
  {
*************** emit_jump_insn_before_setloc (rtx patter
*** 4581,4587 ****
  				     make_jump_insn_raw);
  }

! /* Like emit_jump_insn_before_noloc, but set INSN_LOCATOR according
to BEFORE.  */
  rtx
  emit_jump_insn_before (rtx pattern, rtx before)
  {
--- 4581,4587 ----
  				     make_jump_insn_raw);
  }

! /* Like emit_jump_insn_before_noloc, but set INSN_LOCATION according
to BEFORE.  */
  rtx
  emit_jump_insn_before (rtx pattern, rtx before)
  {
*************** emit_jump_insn_before (rtx pattern, rtx
*** 4589,4595 ****
  			      make_jump_insn_raw);
  }

! /* Like emit_insn_before_noloc, but set INSN_LOCATOR according to LOC.  */
  rtx
  emit_call_insn_before_setloc (rtx pattern, rtx before, int loc)
  {
--- 4589,4595 ----
  			      make_jump_insn_raw);
  }

! /* Like emit_insn_before_noloc, but set INSN_LOCATION according to LOC.  */
  rtx
  emit_call_insn_before_setloc (rtx pattern, rtx before, int loc)
  {
*************** emit_call_insn_before_setloc (rtx patter
*** 4598,4604 ****
  }

  /* Like emit_call_insn_before_noloc,
!    but set insn_locator according to BEFORE.  */
  rtx
  emit_call_insn_before (rtx pattern, rtx before)
  {
--- 4598,4604 ----
  }

  /* Like emit_call_insn_before_noloc,
!    but set insn_location according to BEFORE.  */
  rtx
  emit_call_insn_before (rtx pattern, rtx before)
  {
*************** emit_call_insn_before (rtx pattern, rtx
*** 4606,4612 ****
  			      make_call_insn_raw);
  }

! /* Like emit_insn_before_noloc, but set INSN_LOCATOR according to LOC.  */
  rtx
  emit_debug_insn_before_setloc (rtx pattern, rtx before, int loc)
  {
--- 4606,4612 ----
  			      make_call_insn_raw);
  }

! /* Like emit_insn_before_noloc, but set INSN_LOCATION according to LOC.  */
  rtx
  emit_debug_insn_before_setloc (rtx pattern, rtx before, int loc)
  {
*************** emit_debug_insn_before_setloc (rtx patte
*** 4615,4621 ****
  }

  /* Like emit_debug_insn_before_noloc,
!    but set insn_locator according to BEFORE.  */
  rtx
  emit_debug_insn_before (rtx pattern, rtx before)
  {
--- 4615,4621 ----
  }

  /* Like emit_debug_insn_before_noloc,
!    but set insn_location according to BEFORE.  */
  rtx
  emit_debug_insn_before (rtx pattern, rtx before)
  {
*************** emit_copy_of_insn_after (rtx insn, rtx a
*** 5865,5871 ****
    /* Update LABEL_NUSES.  */
    mark_jump_label (PATTERN (new_rtx), new_rtx, 0);

!   INSN_LOCATOR (new_rtx) = INSN_LOCATOR (insn);

    /* If the old insn is frame related, then so is the new one.  This is
       primarily needed for IA-64 unwind info which marks epilogue insns,
--- 5865,5871 ----
    /* Update LABEL_NUSES.  */
    mark_jump_label (PATTERN (new_rtx), new_rtx, 0);

!   INSN_LOCATION (new_rtx) = INSN_LOCATION (insn);

    /* If the old insn is frame related, then so is the new one.  This is
       primarily needed for IA-64 unwind info which marks epilogue insns,
*************** gen_hard_reg_clobber (enum machine_mode
*** 5900,6149 ****
  	    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (mode, regno)));
  }

! /* Data structures representing mapping of INSN_LOCATOR into scope
blocks, line
!    numbers and files.  In order to be GGC friendly we need to use separate
!    varrays.  This also slightly improve the memory locality in binary search.
!    The _locs array contains locators where the given property change.  The
!    block_locators_blocks contains the scope block that is used for all insn
!    locator greater than corresponding block_locators_locs value and smaller
!    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) *locations_locators_locs;
! DEF_VEC_A(location_t);
! DEF_VEC_ALLOC_A(location_t,heap);
! static VEC(location_t,heap) *locations_locators_vals;
! int prologue_locator;
! int epilogue_locator;

  /* Hold current location information and last location information, so the
     datastructures are built lazily only when some instructions in given
     place are needed.  */
  static location_t curr_location, last_location;
- static tree curr_block, last_block;
- static int curr_rtl_loc = -1;

! /* Allocate insn locator datastructure.  */
  void
! insn_locators_alloc (void)
  {
!   prologue_locator = epilogue_locator = 0;
!
!   block_locators_locs = VEC_alloc (int, heap, 32);
!   block_locators_blocks = VEC_alloc (tree, gc, 32);
!   locations_locators_locs = VEC_alloc (int, heap, 32);
!   locations_locators_vals = VEC_alloc (location_t, heap, 32);
!
    curr_location = UNKNOWN_LOCATION;
    last_location = UNKNOWN_LOCATION;
-   curr_block = NULL;
-   last_block = NULL;
-   curr_rtl_loc = 0;
  }

  /* 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;
! }
!
! /* Allocate insn locator datastructure.  */
! void
! insn_locators_free (void)
  {
!   prologue_locator = epilogue_locator = 0;
!
!   VEC_free (int, heap, block_locators_locs);
!   VEC_free (tree,gc, block_locators_blocks);
!   VEC_free (int, heap, locations_locators_locs);
!   VEC_free (location_t, heap, locations_locators_vals);
  }

  /* 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;
    curr_location = location;
  }

  /* Get current location.  */
  location_t
! get_curr_insn_source_location (void)
  {
    return curr_location;
  }

- /* 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;
- }
-
- /* Get current scope block.  */
- tree
- get_curr_insn_block (void)
- {
-   return curr_block;
- }
-
- /* Return current insn locator.  */
- int
- curr_insn_locator (void)
- {
-   if (curr_rtl_loc == -1 || curr_location == UNKNOWN_LOCATION)
-     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;
-     }
-   if (last_location != curr_location)
-     {
-       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;
- }
- 
-
- /* Return lexical scope block locator belongs to.  */
- static tree
- locator_scope (int loc)
- {
-   int max = VEC_length (int, block_locators_locs);
-   int min = 0;
-
-   /* When block_locators_locs was initialized, the pro- and epilogue
-      insns didn't exist yet and can therefore not be found this way.
-      But we know that they belong to the outer most block of the
-      current function.
-      Without this test, the prologue would be put inside the block of
-      the first valid instruction in the function and when that first
-      insn is part of an inlined function then the low_pc of that
-      inlined function is messed up.  Likewise for the epilogue and
-      the last valid instruction.  */
-   if (loc == prologue_locator || loc == epilogue_locator)
-     return DECL_INITIAL (cfun->decl);
-
-   if (!max || !loc)
-     return NULL;
-   while (1)
-     {
-       int pos = (min + max) / 2;
-       int tmp = VEC_index (int, block_locators_locs, pos);
-
-       if (tmp <= loc && min != pos)
- 	min = pos;
-       else if (tmp > loc && max != pos)
- 	max = pos;
-       else
- 	{
- 	  min = pos;
- 	  break;
- 	}
-     }
-   return VEC_index (tree, block_locators_blocks, min);
- }
-
  /* Return lexical scope block insn belongs to.  */
  tree
  insn_scope (const_rtx insn)
  {
!   return locator_scope (INSN_LOCATOR (insn));
! }
!
! /* Return line number of the statement specified by the locator.  */
! location_t
! locator_location (int loc)
! {
!   int max = VEC_length (int, locations_locators_locs);
!   int min = 0;
!
!   while (1)
!     {
!       int pos = (min + max) / 2;
!       int tmp = VEC_index (int, locations_locators_locs, pos);
!
!       if (tmp <= loc && min != pos)
! 	min = pos;
!       else if (tmp > loc && max != pos)
! 	max = pos;
!       else
! 	{
! 	  min = pos;
! 	  break;
! 	}
!     }
!   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.  */
  int
  insn_line (const_rtx insn)
  {
!   return locator_line (INSN_LOCATOR (insn));
! }
!
! /* Return source file of the statement specified by LOC.  */
! const char *
! locator_file (int loc)
! {
!   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.  */
  const char *
  insn_file (const_rtx insn)
  {
!   return locator_file (INSN_LOCATOR (insn));
  }

- /* Return true if LOC1 and LOC2 locators have the same location and scope.  */
- bool
- locator_eq (int loc1, int loc2)
- {
-   if (loc1 == loc2)
-     return true;
-   if (locator_location (loc1) != locator_location (loc2))
-     return false;
-   return locator_scope (loc1) == locator_scope (loc2);
- }
- 
-
  /* Return true if memory model MODEL requires a pre-operation (release-style)
     barrier or a post-operation (acquire-style) barrier.  While not universal,
     this function matches behavior of several targets.  */
--- 5900,5965 ----
  	    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (mode, regno)));
  }

! location_t prologue_location;
! location_t epilogue_location;

  /* Hold current location information and last location information, so the
     datastructures are built lazily only when some instructions in given
     place are needed.  */
  static location_t curr_location, last_location;

! /* Allocate insn location datastructure.  */
  void
! insn_locations_init (void)
  {
!   prologue_location = epilogue_location = 0;
    curr_location = UNKNOWN_LOCATION;
    last_location = UNKNOWN_LOCATION;
  }

  /* At the end of emit stage, clear current location.  */
  void
! insn_locations_finalize (void)
  {
!   epilogue_location = curr_location;
!   curr_location = UNKNOWN_LOCATION;
  }

  /* Set current location.  */
  void
! set_curr_insn_location (location_t location)
  {
    curr_location = location;
  }

  /* Get current location.  */
  location_t
! curr_insn_location (void)
  {
    return curr_location;
  }

  /* Return lexical scope block insn belongs to.  */
  tree
  insn_scope (const_rtx insn)
  {
!   return LOCATION_BLOCK (INSN_LOCATION (insn));
  }

  /* Return line number of the statement that produced this insn.  */
  int
  insn_line (const_rtx insn)
  {
!   return LOCATION_LINE (INSN_LOCATION (insn));
  }

  /* Return source file of the statement that produced this insn.  */
  const char *
  insn_file (const_rtx insn)
  {
!   return LOCATION_FILE (INSN_LOCATION (insn));
  }

  /* Return true if memory model MODEL requires a pre-operation (release-style)
     barrier or a post-operation (acquire-style) barrier.  While not universal,
     this function matches behavior of several targets.  */
Index: gcc/cfgexpand.c
===================================================================
*** gcc/cfgexpand.c	(revision 190209)
--- gcc/cfgexpand.c	(working copy)
*************** gimple_assign_rhs_to_tree (gimple stmt)
*** 92,99 ****
  	   && gimple_location (stmt) != EXPR_LOCATION (t))
  	  || (gimple_block (stmt)
  	      && currently_expanding_to_rtl
! 	      && EXPR_P (t)
! 	      && gimple_block (stmt) != TREE_BLOCK (t)))
  	t = copy_node (t);
      }
    else
--- 92,98 ----
  	   && gimple_location (stmt) != EXPR_LOCATION (t))
  	  || (gimple_block (stmt)
  	      && currently_expanding_to_rtl
! 	      && EXPR_P (t)))
  	t = copy_node (t);
      }
    else
*************** gimple_assign_rhs_to_tree (gimple stmt)
*** 101,108 ****

    if (gimple_has_location (stmt) && CAN_HAVE_LOCATION_P (t))
      SET_EXPR_LOCATION (t, gimple_location (stmt));
-   if (gimple_block (stmt) && currently_expanding_to_rtl && EXPR_P (t))
-     TREE_BLOCK (t) = gimple_block (stmt);

    return t;
  }
--- 100,105 ----
*************** expand_gimple_cond (basic_block bb, gimp
*** 1807,1814 ****
    last2 = last = get_last_insn ();

    extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
!   set_curr_insn_source_location (gimple_location (stmt));
!   set_curr_insn_block (gimple_block (stmt));

    /* These flags have no purpose in RTL land.  */
    true_edge->flags &= ~EDGE_TRUE_VALUE;
--- 1804,1810 ----
    last2 = last = get_last_insn ();

    extract_true_false_edges_from_block (bb, &true_edge, &false_edge);
!   set_curr_insn_location (gimple_location (stmt));

    /* These flags have no purpose in RTL land.  */
    true_edge->flags &= ~EDGE_TRUE_VALUE;
*************** expand_gimple_cond (basic_block bb, gimp
*** 1821,1833 ****
        jumpif_1 (code, op0, op1, label_rtx_for_bb (true_edge->dest),
  		true_edge->probability);
        maybe_dump_rtl_for_gimple_stmt (stmt, last);
!       if (true_edge->goto_locus)
! 	{
! 	  set_curr_insn_source_location (true_edge->goto_locus);
! 	  set_curr_insn_block (true_edge->goto_block);
! 	  true_edge->goto_locus = curr_insn_locator ();
! 	}
!       true_edge->goto_block = NULL;
        false_edge->flags |= EDGE_FALLTHRU;
        maybe_cleanup_end_of_block (false_edge, last);
        return NULL;
--- 1817,1824 ----
        jumpif_1 (code, op0, op1, label_rtx_for_bb (true_edge->dest),
  		true_edge->probability);
        maybe_dump_rtl_for_gimple_stmt (stmt, last);
!       if (!IS_UNKNOWN_LOCATION (true_edge->goto_locus))
! 	set_curr_insn_location (true_edge->goto_locus);
        false_edge->flags |= EDGE_FALLTHRU;
        maybe_cleanup_end_of_block (false_edge, last);
        return NULL;
*************** expand_gimple_cond (basic_block bb, gimp
*** 1837,1849 ****
        jumpifnot_1 (code, op0, op1, label_rtx_for_bb (false_edge->dest),
  		   false_edge->probability);
        maybe_dump_rtl_for_gimple_stmt (stmt, last);
!       if (false_edge->goto_locus)
! 	{
! 	  set_curr_insn_source_location (false_edge->goto_locus);
! 	  set_curr_insn_block (false_edge->goto_block);
! 	  false_edge->goto_locus = curr_insn_locator ();
! 	}
!       false_edge->goto_block = NULL;
        true_edge->flags |= EDGE_FALLTHRU;
        maybe_cleanup_end_of_block (true_edge, last);
        return NULL;
--- 1828,1835 ----
        jumpifnot_1 (code, op0, op1, label_rtx_for_bb (false_edge->dest),
  		   false_edge->probability);
        maybe_dump_rtl_for_gimple_stmt (stmt, last);
!       if (!IS_UNKNOWN_LOCATION (false_edge->goto_locus))
! 	set_curr_insn_location (false_edge->goto_locus);
        true_edge->flags |= EDGE_FALLTHRU;
        maybe_cleanup_end_of_block (true_edge, last);
        return NULL;
*************** expand_gimple_cond (basic_block bb, gimp
*** 1852,1864 ****
    jumpif_1 (code, op0, op1, label_rtx_for_bb (true_edge->dest),
  	    true_edge->probability);
    last = get_last_insn ();
!   if (false_edge->goto_locus)
!     {
!       set_curr_insn_source_location (false_edge->goto_locus);
!       set_curr_insn_block (false_edge->goto_block);
!       false_edge->goto_locus = curr_insn_locator ();
!     }
!   false_edge->goto_block = NULL;
    emit_jump (label_rtx_for_bb (false_edge->dest));

    BB_END (bb) = last;
--- 1838,1845 ----
    jumpif_1 (code, op0, op1, label_rtx_for_bb (true_edge->dest),
  	    true_edge->probability);
    last = get_last_insn ();
!   if (!IS_UNKNOWN_LOCATION (false_edge->goto_locus))
!     set_curr_insn_location (false_edge->goto_locus);
    emit_jump (label_rtx_for_bb (false_edge->dest));

    BB_END (bb) = last;
*************** expand_gimple_cond (basic_block bb, gimp
*** 1883,1895 ****

    maybe_dump_rtl_for_gimple_stmt (stmt, last2);

!   if (true_edge->goto_locus)
      {
!       set_curr_insn_source_location (true_edge->goto_locus);
!       set_curr_insn_block (true_edge->goto_block);
!       true_edge->goto_locus = curr_insn_locator ();
      }
-   true_edge->goto_block = NULL;

    return new_bb;
  }
--- 1864,1874 ----

    maybe_dump_rtl_for_gimple_stmt (stmt, last2);

!   if (!IS_UNKNOWN_LOCATION (true_edge->goto_locus))
      {
!       set_curr_insn_location (true_edge->goto_locus);
!       true_edge->goto_locus = curr_insn_location ();
      }

    return new_bb;
  }
*************** expand_call_stmt (gimple stmt)
*** 1989,1995 ****
      CALL_FROM_THUNK_P (exp) = gimple_call_from_thunk_p (stmt);
    CALL_EXPR_VA_ARG_PACK (exp) = gimple_call_va_arg_pack_p (stmt);
    SET_EXPR_LOCATION (exp, gimple_location (stmt));
-   TREE_BLOCK (exp) = gimple_block (stmt);

    /* Ensure RTL is created for debug args.  */
    if (decl && DECL_HAS_DEBUG_ARGS_P (decl))
--- 1968,1973 ----
*************** expand_gimple_stmt_1 (gimple stmt)
*** 2024,2031 ****
  {
    tree op0;

!   set_curr_insn_source_location (gimple_location (stmt));
!   set_curr_insn_block (gimple_block (stmt));

    switch (gimple_code (stmt))
      {
--- 2002,2008 ----
  {
    tree op0;

!   set_curr_insn_location (gimple_location (stmt));

    switch (gimple_code (stmt))
      {
*************** expand_gimple_basic_block (basic_block b
*** 3769,3776 ****
  	  tree op;
  	  gimple def;

! 	  location_t sloc = get_curr_insn_source_location ();
! 	  tree sblock = get_curr_insn_block ();

  	  /* Look for SSA names that have their last use here (TERed
  	     names always have only one real use).  */
--- 3746,3752 ----
  	  tree op;
  	  gimple def;

! 	  location_t sloc = curr_insn_location ();

  	  /* Look for SSA names that have their last use here (TERed
  	     names always have only one real use).  */
*************** expand_gimple_basic_block (basic_block b
*** 3803,3810 ****
  		    rtx val;
  		    enum machine_mode mode;

! 		    set_curr_insn_source_location (gimple_location (def));
! 		    set_curr_insn_block (gimple_block (def));

  		    DECL_ARTIFICIAL (vexpr) = 1;
  		    TREE_TYPE (vexpr) = TREE_TYPE (value);
--- 3779,3785 ----
  		    rtx val;
  		    enum machine_mode mode;

! 		    set_curr_insn_location (gimple_location (def));

  		    DECL_ARTIFICIAL (vexpr) = 1;
  		    TREE_TYPE (vexpr) = TREE_TYPE (value);
*************** expand_gimple_basic_block (basic_block b
*** 3831,3838 ****
  		      }
  		  }
  	      }
! 	  set_curr_insn_source_location (sloc);
! 	  set_curr_insn_block (sblock);
  	}

        currently_expanding_gimple_stmt = stmt;
--- 3806,3812 ----
  		      }
  		  }
  	      }
! 	  set_curr_insn_location (sloc);
  	}

        currently_expanding_gimple_stmt = stmt;
*************** expand_gimple_basic_block (basic_block b
*** 3847,3854 ****
  	}
        else if (gimple_debug_bind_p (stmt))
  	{
! 	  location_t sloc = get_curr_insn_source_location ();
! 	  tree sblock = get_curr_insn_block ();
  	  gimple_stmt_iterator nsi = gsi;

  	  for (;;)
--- 3821,3827 ----
  	}
        else if (gimple_debug_bind_p (stmt))
  	{
! 	  location_t sloc = curr_insn_location ();
  	  gimple_stmt_iterator nsi = gsi;

  	  for (;;)
*************** expand_gimple_basic_block (basic_block b
*** 3870,3877 ****

  	      last = get_last_insn ();

! 	      set_curr_insn_source_location (gimple_location (stmt));
! 	      set_curr_insn_block (gimple_block (stmt));

  	      if (DECL_P (var))
  		mode = DECL_MODE (var);
--- 3843,3849 ----

  	      last = get_last_insn ();

! 	      set_curr_insn_location (gimple_location (stmt));

  	      if (DECL_P (var))
  		mode = DECL_MODE (var);
*************** expand_gimple_basic_block (basic_block b
*** 3909,3921 ****
  		break;
  	    }

! 	  set_curr_insn_source_location (sloc);
! 	  set_curr_insn_block (sblock);
  	}
        else if (gimple_debug_source_bind_p (stmt))
  	{
! 	  location_t sloc = get_curr_insn_source_location ();
! 	  tree sblock = get_curr_insn_block ();
  	  tree var = gimple_debug_source_bind_get_var (stmt);
  	  tree value = gimple_debug_source_bind_get_value (stmt);
  	  rtx val;
--- 3881,3891 ----
  		break;
  	    }

! 	  set_curr_insn_location (sloc);
  	}
        else if (gimple_debug_source_bind_p (stmt))
  	{
! 	  location_t sloc = curr_insn_location ();
  	  tree var = gimple_debug_source_bind_get_var (stmt);
  	  tree value = gimple_debug_source_bind_get_value (stmt);
  	  rtx val;
*************** expand_gimple_basic_block (basic_block b
*** 3923,3930 ****

  	  last = get_last_insn ();

! 	  set_curr_insn_source_location (gimple_location (stmt));
! 	  set_curr_insn_block (gimple_block (stmt));

  	  mode = DECL_MODE (var);

--- 3893,3899 ----

  	  last = get_last_insn ();

! 	  set_curr_insn_location (gimple_location (stmt));

  	  mode = DECL_MODE (var);

*************** expand_gimple_basic_block (basic_block b
*** 3942,3949 ****
  	      PAT_VAR_LOCATION_LOC (val) = (rtx)value;
  	    }

! 	  set_curr_insn_source_location (sloc);
! 	  set_curr_insn_block (sblock);
  	}
        else
  	{
--- 3911,3917 ----
  	      PAT_VAR_LOCATION_LOC (val) = (rtx)value;
  	    }

! 	  set_curr_insn_location (sloc);
  	}
        else
  	{
*************** expand_gimple_basic_block (basic_block b
*** 3984,3996 ****
    /* Expand implicit goto and convert goto_locus.  */
    FOR_EACH_EDGE (e, ei, bb->succs)
      {
!       if (e->goto_locus && e->goto_block)
! 	{
! 	  set_curr_insn_source_location (e->goto_locus);
! 	  set_curr_insn_block (e->goto_block);
! 	  e->goto_locus = curr_insn_locator ();
! 	}
!       e->goto_block = NULL;
        if ((e->flags & EDGE_FALLTHRU) && e->dest != bb->next_bb)
  	{
  	  emit_jump (label_rtx_for_bb (e->dest));
--- 3952,3959 ----
    /* Expand implicit goto and convert goto_locus.  */
    FOR_EACH_EDGE (e, ei, bb->succs)
      {
!       if (!IS_UNKNOWN_LOCATION (e->goto_locus))
! 	set_curr_insn_location (e->goto_locus);
        if ((e->flags & EDGE_FALLTHRU) && e->dest != bb->next_bb)
  	{
  	  emit_jump (label_rtx_for_bb (e->dest));
*************** construct_exit_block (void)
*** 4110,4121 ****

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

-   /* The following insns belong to the top scope.  */
-   set_curr_insn_block (DECL_INITIAL (current_function_decl));
-
    /* Generate rtl for function exit.  */
    expand_function_end ();

--- 4073,4081 ----

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

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

*************** gimple_expand_cfg (void)
*** 4334,4353 ****

    rtl_profile_for_bb (ENTRY_BLOCK_PTR);

!   insn_locators_alloc ();
    if (!DECL_IS_BUILTIN (current_function_decl))
      {
        /* Eventually, all FEs should explicitly set function_start_locus.  */
!       if (cfun->function_start_locus == UNKNOWN_LOCATION)
!        set_curr_insn_source_location
           (DECL_SOURCE_LOCATION (current_function_decl));
        else
!        set_curr_insn_source_location (cfun->function_start_locus);
      }
    else
!     set_curr_insn_source_location (UNKNOWN_LOCATION);
!   set_curr_insn_block (DECL_INITIAL (current_function_decl));
!   prologue_locator = curr_insn_locator ();

  #ifdef INSN_SCHEDULING
    init_sched_attrs ();
--- 4294,4312 ----

    rtl_profile_for_bb (ENTRY_BLOCK_PTR);

!   insn_locations_init ();
    if (!DECL_IS_BUILTIN (current_function_decl))
      {
        /* Eventually, all FEs should explicitly set function_start_locus.  */
!       if (IS_UNKNOWN_LOCATION (cfun->function_start_locus))
!        set_curr_insn_location
           (DECL_SOURCE_LOCATION (current_function_decl));
        else
!        set_curr_insn_location (cfun->function_start_locus);
      }
    else
!     set_curr_insn_location (UNKNOWN_LOCATION);
!   prologue_location = curr_insn_location ();

  #ifdef INSN_SCHEDULING
    init_sched_attrs ();
*************** gimple_expand_cfg (void)
*** 4517,4524 ****
    free_histograms ();

    construct_exit_block ();
!   set_curr_insn_block (DECL_INITIAL (current_function_decl));
!   insn_locators_finalize ();

    /* Zap the tree EH table.  */
    set_eh_throw_stmt_table (cfun, NULL);
--- 4476,4482 ----
    free_histograms ();

    construct_exit_block ();
!   insn_locations_finalize ();

    /* Zap the tree EH table.  */
    set_eh_throw_stmt_table (cfun, NULL);
Index: gcc/cfgcleanup.c
===================================================================
*** gcc/cfgcleanup.c	(revision 190209)
--- gcc/cfgcleanup.c	(working copy)
*************** try_forward_edges (int mode, basic_block
*** 481,493 ****
  		  int new_locus = single_succ_edge (target)->goto_locus;
  		  int locus = goto_locus;

! 		  if (new_locus && locus && !locator_eq (new_locus, locus))
  		    new_target = NULL;
  		  else
  		    {
  		      rtx last;

! 		      if (new_locus)
  			locus = new_locus;

  		      last = BB_END (target);
--- 481,495 ----
  		  int new_locus = single_succ_edge (target)->goto_locus;
  		  int locus = goto_locus;

! 		  if (!IS_UNKNOWN_LOCATION (new_locus)
! 		      && !IS_UNKNOWN_LOCATION (locus)
! 		      && new_locus != locus)
  		    new_target = NULL;
  		  else
  		    {
  		      rtx last;

! 		      if (!IS_UNKNOWN_LOCATION (new_locus))
  			locus = new_locus;

  		      last = BB_END (target);
*************** try_forward_edges (int mode, basic_block
*** 495,507 ****
  			last = prev_nondebug_insn (last);

  		      new_locus = last && INSN_P (last)
! 				  ? INSN_LOCATOR (last) : 0;

! 		      if (new_locus && locus && !locator_eq (new_locus, locus))
  			new_target = NULL;
  		      else
  			{
! 			  if (new_locus)
  			    locus = new_locus;

  			  goto_locus = locus;
--- 497,511 ----
  			last = prev_nondebug_insn (last);

  		      new_locus = last && INSN_P (last)
! 				  ? INSN_LOCATION (last) : 0;

! 		      if (!IS_UNKNOWN_LOCATION (new_locus)
! 			  && !IS_UNKNOWN_LOCATION (locus)
! 			  && new_locus != locus)
  			new_target = NULL;
  		      else
  			{
! 			  if (!IS_UNKNOWN_LOCATION (new_locus))
  			    locus = new_locus;

  			  goto_locus = locus;
Index: gcc/tree-ssa-live.c
===================================================================
*** gcc/tree-ssa-live.c	(revision 190209)
--- gcc/tree-ssa-live.c	(working copy)
*************** remove_unused_scope_block_p (tree scope)
*** 585,591 ****
     else
     /* Verfify that only blocks with source location set
        are entry points to the inlined functions.  */
!      gcc_assert (BLOCK_SOURCE_LOCATION (scope) == UNKNOWN_LOCATION);

     TREE_USED (scope) = !unused;
     return unused;
--- 585,591 ----
     else
     /* Verfify that only blocks with source location set
        are entry points to the inlined functions.  */
!      gcc_assert (IS_UNKNOWN_LOCATION (BLOCK_SOURCE_LOCATION (scope)));

     TREE_USED (scope) = !unused;
     return unused;
*************** dump_scope_block (FILE *file, int indent
*** 613,619 ****
    fprintf (file, "\n%*s{ Scope block #%i%s%s",indent, "" ,
BLOCK_NUMBER (scope),
    	   TREE_USED (scope) ? "" : " (unused)",
  	   BLOCK_ABSTRACT (scope) ? " (abstract)": "");
!   if (BLOCK_SOURCE_LOCATION (scope) != UNKNOWN_LOCATION)
      {
        expanded_location s = expand_location (BLOCK_SOURCE_LOCATION (scope));
        fprintf (file, " %s:%i", s.file, s.line);
--- 613,619 ----
    fprintf (file, "\n%*s{ Scope block #%i%s%s",indent, "" ,
BLOCK_NUMBER (scope),
    	   TREE_USED (scope) ? "" : " (unused)",
  	   BLOCK_ABSTRACT (scope) ? " (abstract)": "");
!   if (!IS_UNKNOWN_LOCATION (BLOCK_SOURCE_LOCATION (scope)))
      {
        expanded_location s = expand_location (BLOCK_SOURCE_LOCATION (scope));
        fprintf (file, " %s:%i", s.file, s.line);
*************** remove_unused_locals (void)
*** 746,758 ****
            FOR_EACH_PHI_ARG (arg_p, phi, i, SSA_OP_ALL_USES)
              {
  	      tree arg = USE_FROM_PTR (arg_p);
  	      mark_all_vars_used (&arg);
              }
          }

        FOR_EACH_EDGE (e, ei, bb->succs)
  	if (e->goto_locus)
! 	  TREE_USED (e->goto_block) = true;
      }

    /* We do a two-pass approach about the out-of-scope clobbers.  We want
--- 746,763 ----
            FOR_EACH_PHI_ARG (arg_p, phi, i, SSA_OP_ALL_USES)
              {
  	      tree arg = USE_FROM_PTR (arg_p);
+ 	      int index = PHI_ARG_INDEX_FROM_USE (arg_p);
+ 	      tree block =
+ 		LOCATION_BLOCK (gimple_phi_arg_location (phi, index));
+ 	      if (block != NULL)
+ 		TREE_USED (block) = true;
  	      mark_all_vars_used (&arg);
              }
          }

        FOR_EACH_EDGE (e, ei, bb->succs)
  	if (e->goto_locus)
! 	  TREE_USED (LOCATION_BLOCK (e->goto_locus)) = true;
      }

    /* We do a two-pass approach about the out-of-scope clobbers.  We want
Index: gcc/lto/lto.c
===================================================================
*** gcc/lto/lto.c	(revision 190209)
--- gcc/lto/lto.c	(working copy)
*************** lto_fixup_prevailing_decls (tree t)
*** 1603,1609 ****
    else if (EXPR_P (t))
      {
        int i;
-       LTO_NO_PREVAIL (t->exp.block);
        for (i = TREE_OPERAND_LENGTH (t) - 1; i >= 0; --i)
  	LTO_SET_PREVAIL (TREE_OPERAND (t, i));
      }
--- 1603,1608 ----
Index: gcc/tree-streamer-out.c
===================================================================
*** gcc/tree-streamer-out.c	(revision 190209)
--- gcc/tree-streamer-out.c	(working copy)
*************** write_ts_decl_minimal_tree_pointers (str
*** 471,477 ****
  {
    stream_write_tree (ob, DECL_NAME (expr), ref_p);
    stream_write_tree (ob, DECL_CONTEXT (expr), ref_p);
!   lto_output_location (ob, DECL_SOURCE_LOCATION (expr));
  }


--- 471,477 ----
  {
    stream_write_tree (ob, DECL_NAME (expr), ref_p);
    stream_write_tree (ob, DECL_CONTEXT (expr), ref_p);
!   lto_output_location (ob, LOCATION_LOCUS (DECL_SOURCE_LOCATION (expr)));
  }


*************** write_ts_exp_tree_pointers (struct outpu
*** 668,674 ****
    streamer_write_hwi (ob, TREE_OPERAND_LENGTH (expr));
    for (i = 0; i < TREE_OPERAND_LENGTH (expr); i++)
      stream_write_tree (ob, TREE_OPERAND (expr, i), ref_p);
!   lto_output_location (ob, EXPR_LOCATION (expr));
    stream_write_tree (ob, TREE_BLOCK (expr), ref_p);
  }

--- 668,674 ----
    streamer_write_hwi (ob, TREE_OPERAND_LENGTH (expr));
    for (i = 0; i < TREE_OPERAND_LENGTH (expr); i++)
      stream_write_tree (ob, TREE_OPERAND (expr, i), ref_p);
!   lto_output_location (ob, LOCATION_LOCUS (EXPR_LOCATION (expr)));
    stream_write_tree (ob, TREE_BLOCK (expr), ref_p);
  }

Index: gcc/rtl.c
===================================================================
*** gcc/rtl.c	(revision 190209)
--- gcc/rtl.c	(working copy)
*************** rtx_equal_p_cb (const_rtx x, const_rtx y
*** 440,446 ****
  #ifndef GENERATOR_FILE
  	      if (((code == ASM_OPERANDS && i == 6)
  		   || (code == ASM_INPUT && i == 1))
! 		  && locator_eq (XINT (x, i), XINT (y, i)))
  		break;
  #endif
  	      return 0;
--- 440,446 ----
  #ifndef GENERATOR_FILE
  	      if (((code == ASM_OPERANDS && i == 6)
  		   || (code == ASM_INPUT && i == 1))
! 		  && XINT (x, i) == XINT (y, i))
  		break;
  #endif
  	      return 0;
*************** rtx_equal_p (const_rtx x, const_rtx y)
*** 579,585 ****
  #ifndef GENERATOR_FILE
  	      if (((code == ASM_OPERANDS && i == 6)
  		   || (code == ASM_INPUT && i == 1))
! 		  && locator_eq (XINT (x, i), XINT (y, i)))
  		break;
  #endif
  	      return 0;
--- 579,585 ----
  #ifndef GENERATOR_FILE
  	      if (((code == ASM_OPERANDS && i == 6)
  		   || (code == ASM_INPUT && i == 1))
! 		  && XINT (x, i) == XINT (y, i))
  		break;
  #endif
  	      return 0;
Index: gcc/rtl.h
===================================================================
*** gcc/rtl.h	(revision 190209)
--- gcc/rtl.h	(working copy)
*************** extern void rtl_check_failed_flag (const
*** 747,752 ****
--- 747,753 ----
  #endif

  #define XINT(RTX, N)	(RTL_CHECK2 (RTX, N, 'i', 'n').rt_int)
+ #define XUINT(RTX, N)   (RTL_CHECK2 (RTX, N, 'i', 'n').rt_uint)
  #define XSTR(RTX, N)	(RTL_CHECK2 (RTX, N, 's', 'S').rt_str)
  #define XEXP(RTX, N)	(RTL_CHECK2 (RTX, N, 'e', 'u').rt_rtx)
  #define XVEC(RTX, N)	(RTL_CHECK2 (RTX, N, 'E', 'V').rt_rtvec)
*************** extern void rtl_check_failed_flag (const
*** 810,822 ****
  /* The body of an insn.  */
  #define PATTERN(INSN)	XEXP (INSN, 4)

! #define INSN_LOCATOR(INSN) XINT (INSN, 5)
  /* LOCATION of an RTX if relevant.  */
  #define RTL_LOCATION(X) (INSN_P (X) ? \
! 			 locator_location (INSN_LOCATOR (X)) \
! 			 : UNKNOWN_LOCATION)
! /* LOCATION of current INSN.  */
! #define CURR_INSN_LOCATION (locator_location (curr_insn_locator ()))

  /* Code number of instruction, from when it was recognized.
     -1 means this instruction has not been recognized yet.  */
--- 811,823 ----
  /* The body of an insn.  */
  #define PATTERN(INSN)	XEXP (INSN, 4)

! #define INSN_LOCATION(INSN) XUINT (INSN, 5)
!
! #define INSN_HAS_LOCATION(INSN) (!IS_UNKNOWN_LOCATION (INSN_LOCATION (INSN)))
!
  /* LOCATION of an RTX if relevant.  */
  #define RTL_LOCATION(X) (INSN_P (X) ? \
! 			 INSN_LOCATION (X) : UNKNOWN_LOCATION)

  /* Code number of instruction, from when it was recognized.
     -1 means this instruction has not been recognized yet.  */
*************** extern rtx prev_cc0_setter (rtx);
*** 1815,1826 ****
  /* In emit-rtl.c  */
  extern int insn_line (const_rtx);
  extern const char * insn_file (const_rtx);
- extern location_t locator_location (int);
- extern int locator_line (int);
- extern const char * locator_file (int);
- extern bool locator_eq (int, int);
- extern int prologue_locator, epilogue_locator;
  extern tree insn_scope (const_rtx);

  /* In jump.c */
  extern enum rtx_code reverse_condition (enum rtx_code);
--- 1816,1823 ----
  /* In emit-rtl.c  */
  extern int insn_line (const_rtx);
  extern const char * insn_file (const_rtx);
  extern tree insn_scope (const_rtx);
+ extern location_t prologue_location, epilogue_location;

  /* In jump.c */
  extern enum rtx_code reverse_condition (enum rtx_code);
*************** extern const struct rtl_hooks general_rt
*** 2657,2670 ****
  /* Keep this for the nonce.  */
  #define gen_lowpart rtl_hooks.gen_lowpart

! extern void insn_locators_alloc (void);
! extern void insn_locators_free (void);
! extern void insn_locators_finalize (void);
! extern void set_curr_insn_source_location (location_t);
! extern location_t get_curr_insn_source_location (void);
! extern void set_curr_insn_block (tree);
! extern tree get_curr_insn_block (void);
! extern int curr_insn_locator (void);
  extern bool optimize_insn_for_size_p (void);
  extern bool optimize_insn_for_speed_p (void);

--- 2654,2663 ----
  /* Keep this for the nonce.  */
  #define gen_lowpart rtl_hooks.gen_lowpart

! extern void insn_locations_init (void);
! extern void insn_locations_finalize (void);
! extern void set_curr_insn_location (location_t);
! extern location_t curr_insn_location (void);
  extern bool optimize_insn_for_size_p (void);
  extern bool optimize_insn_for_speed_p (void);

Index: gcc/tree-inline.c
===================================================================
*** gcc/tree-inline.c	(revision 190209)
--- gcc/tree-inline.c	(working copy)
*************** remap_gimple_op_r (tree *tp, int *walk_s
*** 799,808 ****
        /* Otherwise, just copy the node.  Note that copy_tree_r already
  	 knows not to copy VAR_DECLs, etc., so this is safe.  */

-       /* We should never have TREE_BLOCK set on non-statements.  */
-       if (EXPR_P (*tp))
- 	gcc_assert (!TREE_BLOCK (*tp));
-
        if (TREE_CODE (*tp) == MEM_REF)
  	{
  	  tree ptr = TREE_OPERAND (*tp, 0);
--- 799,804 ----
*************** remap_gimple_op_r (tree *tp, int *walk_s
*** 840,852 ****
  	{
  	  /* Variable substitution need not be simple.  In particular,
  	     the MEM_REF substitution above.  Make sure that
! 	     TREE_CONSTANT and friends are up-to-date.  But make sure
! 	     to not improperly set TREE_BLOCK on some sub-expressions.  */
  	  int invariant = is_gimple_min_invariant (*tp);
- 	  tree block = id->block;
- 	  id->block = NULL_TREE;
  	  walk_tree (&TREE_OPERAND (*tp, 0), remap_gimple_op_r, data, NULL);
- 	  id->block = block;
  	  recompute_tree_invariant_for_addr_expr (*tp);

  	  /* If this used to be invariant, but is not any longer,
--- 836,844 ----
  	{
  	  /* Variable substitution need not be simple.  In particular,
  	     the MEM_REF substitution above.  Make sure that
! 	     TREE_CONSTANT and friends are up-to-date.  */
  	  int invariant = is_gimple_min_invariant (*tp);
  	  walk_tree (&TREE_OPERAND (*tp, 0), remap_gimple_op_r, data, NULL);
  	  recompute_tree_invariant_for_addr_expr (*tp);

  	  /* If this used to be invariant, but is not any longer,
*************** remap_gimple_op_r (tree *tp, int *walk_s
*** 858,863 ****
--- 850,871 ----
  	}
      }

+   /* Update the TREE_BLOCK for the cloned expr.  */
+   if (EXPR_P (*tp))
+     {
+       tree new_block = id->remapping_type_depth == 0 ? id->block : NULL;
+       tree old_block = TREE_BLOCK (*tp);
+       if (old_block)
+ 	{
+ 	  tree *n;
+ 	  n = (tree *) pointer_map_contains (id->decl_map,
+ 					     TREE_BLOCK (*tp));
+ 	  if (n)
+ 	    new_block = *n;
+ 	}
+       TREE_SET_BLOCK (*tp, new_block);
+     }
+
    /* Keep iterating.  */
    return NULL_TREE;
  }
*************** copy_tree_body_r (tree *tp, int *walk_su
*** 1075,1085 ****
  	      tree *n;
  	      n = (tree *) pointer_map_contains (id->decl_map,
  						 TREE_BLOCK (*tp));
- 	      gcc_assert (n || id->remapping_type_depth != 0);
  	      if (n)
  		new_block = *n;
  	    }
! 	  TREE_BLOCK (*tp) = new_block;
  	}

        if (TREE_CODE (*tp) != OMP_CLAUSE)
--- 1083,1092 ----
  	      tree *n;
  	      n = (tree *) pointer_map_contains (id->decl_map,
  						 TREE_BLOCK (*tp));
  	      if (n)
  		new_block = *n;
  	    }
! 	  TREE_SET_BLOCK (*tp, new_block);
  	}

        if (TREE_CODE (*tp) != OMP_CLAUSE)
*************** copy_phis_for_bb (basic_block bb, copy_b
*** 1949,1954 ****
--- 1956,1962 ----
  	      tree new_arg;
  	      tree block = id->block;
  	      edge_iterator ei2;
+ 	      location_t locus;

  	      /* When doing partial cloning, we allow PHIs on the entry block
  		 as long as all the arguments are the same.  Find any input
*************** copy_phis_for_bb (basic_block bb, copy_b
*** 1960,1968 ****

  	      arg = PHI_ARG_DEF_FROM_EDGE (phi, old_edge);
  	      new_arg = arg;
- 	      id->block = NULL_TREE;
  	      walk_tree (&new_arg, copy_tree_body_r, id, NULL);
- 	      id->block = block;
  	      gcc_assert (new_arg);
  	      /* With return slot optimization we can end up with
  	         non-gimple (foo *)&this->m, fix that here.  */
--- 1968,1974 ----
*************** copy_phis_for_bb (basic_block bb, copy_b
*** 1975,1982 ****
  		  gsi_insert_seq_on_edge (new_edge, stmts);
  		  inserted = true;
  		}
  	      add_phi_arg (new_phi, new_arg, new_edge,
! 			   gimple_phi_arg_location_from_edge (phi, old_edge));
  	    }
  	}
      }
--- 1981,1999 ----
  		  gsi_insert_seq_on_edge (new_edge, stmts);
  		  inserted = true;
  		}
+ 	      locus = gimple_phi_arg_location_from_edge (phi, old_edge);
+ 	      block = id->block;
+ 	      if (LOCATION_BLOCK (locus))
+ 		{
+ 		  tree *n;
+ 		  n = (tree *) pointer_map_contains (id->decl_map,
+ 			LOCATION_BLOCK (locus));
+ 		  gcc_assert (n);
+ 		  block = *n;
+ 		}
+
  	      add_phi_arg (new_phi, new_arg, new_edge,
! 			   COMBINE_LOCATION_DATA (locus, block));
  	    }
  	}
      }
*************** expand_call_inline (basic_block bb, gimp
*** 3847,3853 ****
    id->block = make_node (BLOCK);
    BLOCK_ABSTRACT_ORIGIN (id->block) = fn;
    BLOCK_SOURCE_LOCATION (id->block) = input_location;
!   prepend_lexical_block (gimple_block (stmt), id->block);

    /* Local declarations will be replaced by their equivalents in this
       map.  */
--- 3864,3871 ----
    id->block = make_node (BLOCK);
    BLOCK_ABSTRACT_ORIGIN (id->block) = fn;
    BLOCK_SOURCE_LOCATION (id->block) = input_location;
!   if (gimple_block (stmt))
!     prepend_lexical_block (gimple_block (stmt), id->block);

    /* Local declarations will be replaced by their equivalents in this
       map.  */
Index: gcc/tree-streamer-in.c
===================================================================
*** gcc/tree-streamer-in.c	(revision 190209)
--- gcc/tree-streamer-in.c	(working copy)
*************** lto_input_ts_exp_tree_pointers (struct l
*** 776,782 ****

    loc = lto_input_location (ib, data_in);
    SET_EXPR_LOCATION (expr, loc);
!   TREE_BLOCK (expr) = stream_read_tree (ib, data_in);
  }


--- 776,782 ----

    loc = lto_input_location (ib, data_in);
    SET_EXPR_LOCATION (expr, loc);
!   TREE_SET_BLOCK (expr, stream_read_tree (ib, data_in));
  }


Index: gcc/combine.c
===================================================================
*** gcc/combine.c	(revision 190209)
--- gcc/combine.c	(working copy)
*************** try_combine (rtx i3, rtx i2, rtx i1, rtx
*** 2741,2747 ****

  	  i1 = gen_rtx_INSN (VOIDmode, INSN_UID (i2), NULL_RTX, i2,
  			     BLOCK_FOR_INSN (i2), XVECEXP (PATTERN (i2), 0, 1),
! 			     INSN_LOCATOR (i2), -1, NULL_RTX);

  	  SUBST (PATTERN (i2), XVECEXP (PATTERN (i2), 0, 0));
  	  SUBST (XEXP (SET_SRC (PATTERN (i2)), 0),
--- 2741,2747 ----

  	  i1 = gen_rtx_INSN (VOIDmode, INSN_UID (i2), NULL_RTX, i2,
  			     BLOCK_FOR_INSN (i2), XVECEXP (PATTERN (i2), 0, 1),
! 			     INSN_LOCATION (i2), -1, NULL_RTX);

  	  SUBST (PATTERN (i2), XVECEXP (PATTERN (i2), 0, 0));
  	  SUBST (XEXP (SET_SRC (PATTERN (i2)), 0),
Index: gcc/tree-outof-ssa.c
===================================================================
*** gcc/tree-outof-ssa.c	(revision 190209)
--- gcc/tree-outof-ssa.c	(working copy)
*************** set_location_for_edge (edge e)
*** 108,115 ****
  {
    if (e->goto_locus)
      {
!       set_curr_insn_source_location (e->goto_locus);
!       set_curr_insn_block (e->goto_block);
      }
    else
      {
--- 108,114 ----
  {
    if (e->goto_locus)
      {
!       set_curr_insn_location (e->goto_locus);
      }
    else
      {
*************** set_location_for_edge (edge e)
*** 125,132 ****
  		continue;
  	      if (gimple_has_location (stmt) || gimple_block (stmt))
  		{
! 		  set_curr_insn_source_location (gimple_location (stmt));
! 		  set_curr_insn_block (gimple_block (stmt));
  		  return;
  		}
  	    }
--- 124,130 ----
  		continue;
  	      if (gimple_has_location (stmt) || gimple_block (stmt))
  		{
! 		  set_curr_insn_location (gimple_location (stmt));
  		  return;
  		}
  	    }
*************** insert_partition_copy_on_edge (edge e, i
*** 191,197 ****
    set_location_for_edge (e);
    /* If a locus is provided, override the default.  */
    if (locus)
!     set_curr_insn_source_location (locus);

    var = partition_to_var (SA.map, src);
    seq = emit_partition_copy (SA.partition_to_pseudo[dest],
--- 189,195 ----
    set_location_for_edge (e);
    /* If a locus is provided, override the default.  */
    if (locus)
!     set_curr_insn_location (locus);

    var = partition_to_var (SA.map, src);
    seq = emit_partition_copy (SA.partition_to_pseudo[dest],
*************** insert_value_copy_on_edge (edge e, int d
*** 228,234 ****
    set_location_for_edge (e);
    /* If a locus is provided, override the default.  */
    if (locus)
!     set_curr_insn_source_location (locus);

    start_sequence ();

--- 226,232 ----
    set_location_for_edge (e);
    /* If a locus is provided, override the default.  */
    if (locus)
!     set_curr_insn_location (locus);

    start_sequence ();

*************** insert_rtx_to_part_on_edge (edge e, int
*** 284,290 ****
    set_location_for_edge (e);
    /* If a locus is provided, override the default.  */
    if (locus)
!     set_curr_insn_source_location (locus);

    /* We give the destination as sizeexp in case src/dest are BLKmode
       mems.  Usually we give the source.  As we result from SSA names
--- 282,288 ----
    set_location_for_edge (e);
    /* If a locus is provided, override the default.  */
    if (locus)
!     set_curr_insn_location (locus);

    /* We give the destination as sizeexp in case src/dest are BLKmode
       mems.  Usually we give the source.  As we result from SSA names
*************** insert_part_to_rtx_on_edge (edge e, rtx
*** 320,326 ****
    set_location_for_edge (e);
    /* If a locus is provided, override the default.  */
    if (locus)
!     set_curr_insn_source_location (locus);

    var = partition_to_var (SA.map, src);
    seq = emit_partition_copy (dest,
--- 318,324 ----
    set_location_for_edge (e);
    /* If a locus is provided, override the default.  */
    if (locus)
!     set_curr_insn_location (locus);

    var = partition_to_var (SA.map, src);
    seq = emit_partition_copy (dest,
Index: gcc/basic-block.h
===================================================================
*** gcc/basic-block.h	(revision 190209)
--- gcc/basic-block.h	(working copy)
*************** struct GTY(()) edge_def {
*** 47,54 ****
    /* Auxiliary info specific to a pass.  */
    PTR GTY ((skip (""))) aux;

!   /* Location of any goto implicit in the edge and associated BLOCK.  */
!   tree goto_block;
    location_t goto_locus;

    /* The index number corresponding to this edge in the edge vector
--- 47,53 ----
    /* Auxiliary info specific to a pass.  */
    PTR GTY ((skip (""))) aux;

!   /* Location of any goto implicit in the edge.  */
    location_t goto_locus;

    /* The index number corresponding to this edge in the edge vector
Index: gcc/gimple.h
===================================================================
*** gcc/gimple.h	(revision 190209)
--- gcc/gimple.h	(working copy)
*************** struct GTY(()) gimple_statement_base {
*** 210,219 ****
       and the prev pointer being the last.  */
    gimple next;
    gimple GTY((skip)) prev;
-
-   /* [ WORD 6 ]
-      Lexical block holding this statement.  */
-   tree block;
  };


--- 210,215 ----
*************** gimple_bb (const_gimple g)
*** 1198,1204 ****
  static inline tree
  gimple_block (const_gimple g)
  {
!   return g->gsbase.block;
  }


--- 1194,1200 ----
  static inline tree
  gimple_block (const_gimple g)
  {
!   return LOCATION_BLOCK (g->gsbase.location);
  }


*************** gimple_block (const_gimple g)
*** 1207,1213 ****
  static inline void
  gimple_set_block (gimple g, tree block)
  {
!   g->gsbase.block = block;
  }


--- 1203,1209 ----
  static inline void
  gimple_set_block (gimple g, tree block)
  {
!   g->gsbase.location = COMBINE_LOCATION_DATA (g->gsbase.location, block);
  }


*************** gimple_set_location (gimple g, location_
*** 1242,1248 ****
  static inline bool
  gimple_has_location (const_gimple g)
  {
!   return gimple_location (g) != UNKNOWN_LOCATION;
  }


--- 1238,1244 ----
  static inline bool
  gimple_has_location (const_gimple g)
  {
!   return !IS_UNKNOWN_LOCATION (gimple_location (g));
  }


Index: gcc/tree-cfg.c
===================================================================
*** gcc/tree-cfg.c	(revision 190209)
--- gcc/tree-cfg.c	(working copy)
*************** make_cond_expr_edges (basic_block bb)
*** 809,823 ****
    e = make_edge (bb, then_bb, EDGE_TRUE_VALUE);
    assign_discriminator (entry_locus, then_bb);
    e->goto_locus = gimple_location (then_stmt);
-   if (e->goto_locus)
-     e->goto_block = gimple_block (then_stmt);
    e = make_edge (bb, else_bb, EDGE_FALSE_VALUE);
    if (e)
      {
        assign_discriminator (entry_locus, else_bb);
        e->goto_locus = gimple_location (else_stmt);
-       if (e->goto_locus)
- 	e->goto_block = gimple_block (else_stmt);
      }

    /* We do not need the labels anymore.  */
--- 809,819 ----
*************** make_goto_expr_edges (basic_block bb)
*** 1027,1034 ****
        edge e = make_edge (bb, label_bb, EDGE_FALLTHRU);
        e->goto_locus = gimple_location (goto_t);
        assign_discriminator (e->goto_locus, label_bb);
-       if (e->goto_locus)
- 	e->goto_block = gimple_block (goto_t);
        gsi_remove (&last, true);
        return;
      }
--- 1023,1028 ----
*************** gimple_can_merge_blocks_p (basic_block a
*** 1504,1510 ****

    /* When not optimizing, don't merge if we'd lose goto_locus.  */
    if (!optimize
!       && single_succ_edge (a)->goto_locus != UNKNOWN_LOCATION)
      {
        location_t goto_locus = single_succ_edge (a)->goto_locus;
        gimple_stmt_iterator prev, next;
--- 1498,1504 ----

    /* When not optimizing, don't merge if we'd lose goto_locus.  */
    if (!optimize
!       && single_succ_edge (a)->goto_locus)
      {
        location_t goto_locus = single_succ_edge (a)->goto_locus;
        gimple_stmt_iterator prev, next;
*************** move_stmt_op (tree *tp, int *walk_subtre
*** 5993,6001 ****
    tree t = *tp;

    if (EXPR_P (t))
!     /* We should never have TREE_BLOCK set on non-statements.  */
!     gcc_assert (!TREE_BLOCK (t));
!
    else if (DECL_P (t) || TREE_CODE (t) == SSA_NAME)
      {
        if (TREE_CODE (t) == SSA_NAME)
--- 5987,5993 ----
    tree t = *tp;

    if (EXPR_P (t))
!     ;
    else if (DECL_P (t) || TREE_CODE (t) == SSA_NAME)
      {
        if (TREE_CODE (t) == SSA_NAME)
*************** move_block_to_fn (struct function *dest_
*** 6295,6306 ****
      }

    FOR_EACH_EDGE (e, ei, bb->succs)
!     if (e->goto_locus)
        {
! 	tree block = e->goto_block;
  	if (d->orig_block == NULL_TREE
  	    || block == d->orig_block)
! 	  e->goto_block = d->new_block;
  #ifdef ENABLE_CHECKING
  	else if (block != d->new_block)
  	  {
--- 6287,6298 ----
      }

    FOR_EACH_EDGE (e, ei, bb->succs)
!     if (!IS_UNKNOWN_LOCATION (e->goto_locus))
        {
! 	tree block = LOCATION_BLOCK (e->goto_locus);
  	if (d->orig_block == NULL_TREE
  	    || block == d->orig_block)
! 	  e->goto_locus = COMBINE_LOCATION_DATA (e->goto_locus, d->new_block);
  #ifdef ENABLE_CHECKING
  	else if (block != d->new_block)
  	  {
Index: gcc/config/alpha/alpha.c
===================================================================
*** gcc/config/alpha/alpha.c	(revision 190209)
--- gcc/config/alpha/alpha.c	(working copy)
*************** alpha_output_mi_thunk_osf (FILE *file, t
*** 8362,8368 ****
       instruction scheduling worth while.  Note that use_thunk calls
       assemble_start_function and assemble_end_function.  */
    insn = get_insns ();
-   insn_locators_alloc ();
    shorten_branches (insn);
    final_start_function (insn, file, 1);
    final (insn, file, 1);
--- 8362,8367 ----
Index: gcc/config/sparc/sparc.c
===================================================================
*** gcc/config/sparc/sparc.c	(revision 190209)
--- gcc/config/sparc/sparc.c	(working copy)
*************** sparc_output_mi_thunk (FILE *file, tree
*** 10654,10660 ****
       instruction scheduling worth while.  Note that use_thunk calls
       assemble_start_function and assemble_end_function.  */
    insn = get_insns ();
-   insn_locators_alloc ();
    shorten_branches (insn);
    final_start_function (insn, file, 1);
    final (insn, file, 1);
--- 10654,10659 ----
Index: gcc/config/i386/i386.c
===================================================================
*** gcc/config/i386/i386.c	(revision 190209)
--- gcc/config/i386/i386.c	(working copy)
*************** x86_output_mi_thunk (FILE *file,
*** 33227,33233 ****
    /* Emit just enough of rest_of_compilation to get the insns emitted.
       Note that use_thunk calls assemble_start_function et al.  */
    tmp = get_insns ();
-   insn_locators_alloc ();
    shorten_branches (tmp);
    final_start_function (tmp, file, 1);
    final (tmp, file, 1);
--- 33227,33232 ----
Index: gcc/config/tilegx/tilegx.c
===================================================================
*** gcc/config/tilegx/tilegx.c	(revision 190209)
--- gcc/config/tilegx/tilegx.c	(working copy)
*************** tilegx_output_mi_thunk (FILE *file, tree
*** 4804,4810 ****
       serial except for the tail call, so we're only wasting one cycle.
     */
    insn = get_insns ();
-   insn_locators_alloc ();
    shorten_branches (insn);
    final_start_function (insn, file, 1);
    final (insn, file, 1);
--- 4804,4809 ----
Index: gcc/config/sh/sh.c
===================================================================
*** gcc/config/sh/sh.c	(revision 190209)
--- gcc/config/sh/sh.c	(working copy)
*************** sh_output_mi_thunk (FILE *file, tree thu
*** 11991,11997 ****
       the insns emitted.  Note that use_thunk calls
       assemble_start_function and assemble_end_function.  */

-   insn_locators_alloc ();
    insns = get_insns ();

    if (optimize > 0)
--- 11991,11996 ----
Index: gcc/config/ia64/ia64.c
===================================================================
*** gcc/config/ia64/ia64.c	(revision 190209)
--- gcc/config/ia64/ia64.c	(working copy)
*************** ia64_output_mi_thunk (FILE *file, tree t
*** 10848,10854 ****
       instruction scheduling worth while.  Note that use_thunk calls
       assemble_start_function and assemble_end_function.  */

-   insn_locators_alloc ();
    emit_all_insn_group_barriers (NULL);
    insn = get_insns ();
    shorten_branches (insn);
--- 10848,10853 ----
Index: gcc/config/rs6000/rs6000.c
===================================================================
*** gcc/config/rs6000/rs6000.c	(revision 190209)
--- gcc/config/rs6000/rs6000.c	(working copy)
*************** rs6000_output_mi_thunk (FILE *file, tree
*** 21689,21695 ****
       instruction scheduling worth while.  Note that use_thunk calls
       assemble_start_function and assemble_end_function.  */
    insn = get_insns ();
-   insn_locators_alloc ();
    shorten_branches (insn);
    final_start_function (insn, file, 1);
    final (insn, file, 1);
--- 21689,21694 ----
Index: gcc/config/score/score.c
===================================================================
*** gcc/config/score/score.c	(revision 190209)
--- gcc/config/score/score.c	(working copy)
*************** score_output_mi_thunk (FILE *file, tree
*** 505,511 ****
    /* Run just enough of rest_of_compilation.  This sequence was
       "borrowed" from alpha.c.  */
    insn = get_insns ();
-   insn_locators_alloc ();
    split_all_insns_noflow ();
    shorten_branches (insn);
    final_start_function (insn, file, 1);
--- 505,510 ----
Index: gcc/config/tilepro/tilepro.c
===================================================================
*** gcc/config/tilepro/tilepro.c	(revision 190209)
--- gcc/config/tilepro/tilepro.c	(working copy)
*************** tilepro_asm_output_mi_thunk (FILE *file,
*** 4407,4413 ****
       serial except for the tail call, so we're only wasting one cycle.
     */
    insn = get_insns ();
-   insn_locators_alloc ();
    shorten_branches (insn);
    final_start_function (insn, file, 1);
    final (insn, file, 1);
--- 4407,4412 ----
Index: gcc/config/mips/mips.c
===================================================================
*** gcc/config/mips/mips.c	(revision 190209)
--- gcc/config/mips/mips.c	(working copy)
*************** mips_output_mi_thunk (FILE *file, tree t
*** 15746,15752 ****
    /* Run just enough of rest_of_compilation.  This sequence was
       "borrowed" from alpha.c.  */
    insn = get_insns ();
-   insn_locators_alloc ();
    split_all_insns_noflow ();
    mips16_lay_out_constants (true);
    shorten_branches (insn);
--- 15746,15751 ----
Index: gcc/cfgrtl.c
===================================================================
*** gcc/cfgrtl.c	(revision 190209)
--- gcc/cfgrtl.c	(working copy)
*************** rtl_split_block (basic_block bb, void *i
*** 720,738 ****
  static bool
  unique_locus_on_edge_between_p (basic_block a, basic_block b)
  {
!   const int goto_locus = EDGE_SUCC (a, 0)->goto_locus;
    rtx insn, end;

!   if (!goto_locus)
      return false;

    /* First scan block A backward.  */
    insn = BB_END (a);
    end = PREV_INSN (BB_HEAD (a));
!   while (insn != end && (!NONDEBUG_INSN_P (insn) || INSN_LOCATOR (insn) == 0))
      insn = PREV_INSN (insn);

!   if (insn != end && locator_eq (INSN_LOCATOR (insn), goto_locus))
      return false;

    /* Then scan block B forward.  */
--- 720,738 ----
  static bool
  unique_locus_on_edge_between_p (basic_block a, basic_block b)
  {
!   const location_t goto_locus = EDGE_SUCC (a, 0)->goto_locus;
    rtx insn, end;

!   if (IS_UNKNOWN_LOCATION (goto_locus))
      return false;

    /* First scan block A backward.  */
    insn = BB_END (a);
    end = PREV_INSN (BB_HEAD (a));
!   while (insn != end && (!NONDEBUG_INSN_P (insn) ||
!INSN_HAS_LOCATION (insn)))
      insn = PREV_INSN (insn);

!   if (insn != end && INSN_LOCATION (insn) == goto_locus)
      return false;

    /* Then scan block B forward.  */
*************** unique_locus_on_edge_between_p (basic_bl
*** 743,750 ****
        while (insn != end && !NONDEBUG_INSN_P (insn))
  	insn = NEXT_INSN (insn);

!       if (insn != end && INSN_LOCATOR (insn) != 0
! 	  && locator_eq (INSN_LOCATOR (insn), goto_locus))
  	return false;
      }

--- 743,750 ----
        while (insn != end && !NONDEBUG_INSN_P (insn))
  	insn = NEXT_INSN (insn);

!       if (insn != end && INSN_HAS_LOCATION (insn)
! 	  && INSN_LOCATION (insn) == goto_locus)
  	return false;
      }

*************** emit_nop_for_unique_locus_between (basic
*** 761,767 ****
      return;

    BB_END (a) = emit_insn_after_noloc (gen_nop (), BB_END (a), a);
!   INSN_LOCATOR (BB_END (a)) = EDGE_SUCC (a, 0)->goto_locus;
  }

  /* Blocks A and B are to be merged into a single block A.  The insns
--- 761,767 ----
      return;

    BB_END (a) = emit_insn_after_noloc (gen_nop (), BB_END (a), a);
!   INSN_LOCATION (BB_END (a)) = EDGE_SUCC (a, 0)->goto_locus;
  }

  /* Blocks A and B are to be merged into a single block A.  The insns
*************** force_nonfallthru_and_redirect (edge e,
*** 1478,1484 ****
    else
      jump_block = e->src;

!   if (e->goto_locus && e->goto_block == NULL)
      loc = e->goto_locus;
    else
      loc = 0;
--- 1478,1484 ----
    else
      jump_block = e->src;

!   if (!IS_UNKNOWN_LOCATION (e->goto_locus))
      loc = e->goto_locus;
    else
      loc = 0;
*************** fixup_reorder_chain (void)
*** 3336,3342 ****
          edge_iterator ei;

          FOR_EACH_EDGE (e, ei, bb->succs)
! 	  if (e->goto_locus && !(e->flags & EDGE_ABNORMAL))
  	    {
  	      edge e2;
  	      edge_iterator ei2;
--- 3336,3343 ----
          edge_iterator ei;

          FOR_EACH_EDGE (e, ei, bb->succs)
! 	  if (!IS_UNKNOWN_LOCATION (e->goto_locus)
! 	      && !(e->flags & EDGE_ABNORMAL))
  	    {
  	      edge e2;
  	      edge_iterator ei2;
*************** fixup_reorder_chain (void)
*** 3346,3360 ****
  	      insn = BB_END (e->src);
  	      end = PREV_INSN (BB_HEAD (e->src));
  	      while (insn != end
! 		     && (!NONDEBUG_INSN_P (insn) || INSN_LOCATOR (insn) == 0))
  		insn = PREV_INSN (insn);
  	      if (insn != end
! 		  && locator_eq (INSN_LOCATOR (insn), (int) e->goto_locus))
  		continue;
  	      if (simplejump_p (BB_END (e->src))
! 		  && INSN_LOCATOR (BB_END (e->src)) == 0)
  		{
! 		  INSN_LOCATOR (BB_END (e->src)) = e->goto_locus;
  		  continue;
  		}
  	      dest = e->dest;
--- 3347,3361 ----
  	      insn = BB_END (e->src);
  	      end = PREV_INSN (BB_HEAD (e->src));
  	      while (insn != end
! 		     && (!NONDEBUG_INSN_P (insn) || !INSN_HAS_LOCATION (insn)))
  		insn = PREV_INSN (insn);
  	      if (insn != end
! 		  && INSN_LOCATION (insn) == e->goto_locus)
  		continue;
  	      if (simplejump_p (BB_END (e->src))
! 		  && !INSN_HAS_LOCATION (BB_END (e->src)))
  		{
! 		  INSN_LOCATION (BB_END (e->src)) = e->goto_locus;
  		  continue;
  		}
  	      dest = e->dest;
*************** fixup_reorder_chain (void)
*** 3370,3393 ****
  		  end = NEXT_INSN (BB_END (dest));
  		  while (insn != end && !NONDEBUG_INSN_P (insn))
  		    insn = NEXT_INSN (insn);
! 		  if (insn != end && INSN_LOCATOR (insn)
! 		      && locator_eq (INSN_LOCATOR (insn), (int) e->goto_locus))
  		    continue;
  		}
  	      nb = split_edge (e);
  	      if (!INSN_P (BB_END (nb)))
  		BB_END (nb) = emit_insn_after_noloc (gen_nop (), BB_END (nb),
  						     nb);
! 	      INSN_LOCATOR (BB_END (nb)) = e->goto_locus;

  	      /* If there are other incoming edges to the destination block
  		 with the same goto locus, redirect them to the new block as
  		 well, this can prevent other such blocks from being created
  		 in subsequent iterations of the loop.  */
  	      for (ei2 = ei_start (dest->preds); (e2 = ei_safe_edge (ei2)); )
! 		if (e2->goto_locus
  		    && !(e2->flags & (EDGE_ABNORMAL | EDGE_FALLTHRU))
! 		    && locator_eq (e->goto_locus, e2->goto_locus))
  		  redirect_edge_and_branch (e2, nb);
  		else
  		  ei_next (&ei2);
--- 3371,3394 ----
  		  end = NEXT_INSN (BB_END (dest));
  		  while (insn != end && !NONDEBUG_INSN_P (insn))
  		    insn = NEXT_INSN (insn);
! 		  if (insn != end && INSN_HAS_LOCATION (insn)
! 		      && INSN_LOCATION (insn) == e->goto_locus)
  		    continue;
  		}
  	      nb = split_edge (e);
  	      if (!INSN_P (BB_END (nb)))
  		BB_END (nb) = emit_insn_after_noloc (gen_nop (), BB_END (nb),
  						     nb);
! 	      INSN_LOCATION (BB_END (nb)) = e->goto_locus;

  	      /* If there are other incoming edges to the destination block
  		 with the same goto locus, redirect them to the new block as
  		 well, this can prevent other such blocks from being created
  		 in subsequent iterations of the loop.  */
  	      for (ei2 = ei_start (dest->preds); (e2 = ei_safe_edge (ei2)); )
! 		if (!IS_UNKNOWN_LOCATION (e2->goto_locus)
  		    && !(e2->flags & (EDGE_ABNORMAL | EDGE_FALLTHRU))
! 		    && e->goto_locus == e2->goto_locus)
  		  redirect_edge_and_branch (e2, nb);
  		else
  		  ei_next (&ei2);
*************** cfg_layout_merge_blocks (basic_block a,
*** 4087,4093 ****
      }

    /* If B was a forwarder block, propagate the locus on the edge.  */
!   if (forwarder_p && !EDGE_SUCC (b, 0)->goto_locus)
      EDGE_SUCC (b, 0)->goto_locus = EDGE_SUCC (a, 0)->goto_locus;

    if (dump_file)
--- 4088,4094 ----
      }

    /* If B was a forwarder block, propagate the locus on the edge.  */
!   if (forwarder_p && IS_UNKNOWN_LOCATION (EDGE_SUCC (b, 0)->goto_locus))
      EDGE_SUCC (b, 0)->goto_locus = EDGE_SUCC (a, 0)->goto_locus;

    if (dump_file)
Index: gcc/stmt.c
===================================================================
*** gcc/stmt.c	(revision 190209)
--- gcc/stmt.c	(working copy)
*************** emit_case_nodes (rtx index, case_node_pt
*** 2397,2403 ****
  		 then emit the code for one side at a time.  */

  	      tree test_label
! 		= build_decl (CURR_INSN_LOCATION,
  			      LABEL_DECL, NULL_TREE, NULL_TREE);

  	      /* See if the value is on the right.  */
--- 2397,2403 ----
  		 then emit the code for one side at a time.  */

  	      tree test_label
! 		= build_decl (curr_insn_location (),
  			      LABEL_DECL, NULL_TREE, NULL_TREE);

  	      /* See if the value is on the right.  */
*************** emit_case_nodes (rtx index, case_node_pt
*** 2521,2527 ****
  	      /* Right hand node requires testing.
  		 Branch to a label where we will handle it later.  */

! 	      test_label = build_decl (CURR_INSN_LOCATION,
  				       LABEL_DECL, NULL_TREE, NULL_TREE);
  	      emit_cmp_and_jump_insns (index,
  				       convert_modes
--- 2521,2527 ----
  	      /* Right hand node requires testing.
  		 Branch to a label where we will handle it later.  */

! 	      test_label = build_decl (curr_insn_location (),
  				       LABEL_DECL, NULL_TREE, NULL_TREE);
  	      emit_cmp_and_jump_insns (index,
  				       convert_modes
Index: libcpp/line-map.c
===================================================================
*** libcpp/line-map.c	(revision 190209)
--- libcpp/line-map.c	(working copy)
*************** along with this program; see the file CO
*** 25,30 ****
--- 25,31 ----
  #include "line-map.h"
  #include "cpplib.h"
  #include "internal.h"
+ #include "hashtab.h"

  static void trace_include (const struct line_maps *, const struct line_map *);
  static const struct line_map * linemap_ordinary_map_lookup (struct
line_maps *,
*************** static source_location linemap_macro_loc
*** 50,55 ****
--- 51,185 ----
  extern unsigned num_expanded_macros_counter;
  extern unsigned num_macro_tokens_counter;

+ /* Data structure to associate an arbitrary data to a source location.  */
+ struct location_adhoc_data {
+   source_location locus;
+   void *data;
+ };
+
+ /* The following data structure encodes a location with some adhoc data,
+    and map it to a new unsigned integer, and replace it with the original
+    location to represent the mapping.
+
+    The new adhoc_loc uses the highest bit as the enabling bit, i.e. if the
+    highest bit is 1, then the number is adhoc_loc. Otherwise, it serves as
+    the original location. Once identified as the adhoc_loc, the lower 31
+    bits of the integer is used to index to the location_adhoc_data array,
+    in which the locus and associated data is stored.  */
+
+ static htab_t location_adhoc_data_htab;
+ static source_location curr_adhoc_loc;
+ static struct location_adhoc_data *location_adhoc_data;
+ static unsigned int allocated_location_adhoc_data;
+
+ /* Hash function for location_adhoc_data hashtable.  */
+
+ static hashval_t
+ location_adhoc_data_hash (const void *l)
+ {
+   const struct location_adhoc_data *lb =
+       (const struct location_adhoc_data *) l;
+   return (hashval_t) lb->locus + (size_t) &lb->data;
+ }
+
+ /* Compare function for location_adhoc_data hashtable.  */
+
+ static int
+ location_adhoc_data_eq (const void *l1, const void *l2)
+ {
+   const struct location_adhoc_data *lb1 =
+       (const struct location_adhoc_data *) l1;
+   const struct location_adhoc_data *lb2 =
+       (const struct location_adhoc_data *) l2;
+   return lb1->locus == lb2->locus && lb1->data == lb2->data;
+ }
+
+ /* Update the hashtable when location_adhoc_data is reallocated.  */
+
+ static int
+ location_adhoc_data_update (void **slot, void *data)
+ {
+   *((char **) slot) += ((char *) location_adhoc_data - (char *) data);
+   return 1;
+ }
+
+ /* Combine LOCUS and DATA to a combined adhoc loc.  */
+
+ source_location
+ get_combined_adhoc_loc (source_location locus, void *data)
+ {
+   struct location_adhoc_data lb;
+   struct location_adhoc_data **slot;
+
+   linemap_assert (data);
+
+   if (IS_ADHOC_LOC (locus))
+     locus = location_adhoc_data[locus & MAX_SOURCE_LOCATION].locus;
+   if (locus == 0 && data == NULL)
+     return 0;
+   lb.locus = locus;
+   lb.data = data;
+   slot = (struct location_adhoc_data **)
+       htab_find_slot (location_adhoc_data_htab, &lb, INSERT);
+   if (*slot == NULL)
+     {
+       *slot = location_adhoc_data + curr_adhoc_loc;
+       location_adhoc_data[curr_adhoc_loc] = lb;
+       if (++curr_adhoc_loc >= allocated_location_adhoc_data)
+ 	{
+ 	  char *orig_location_adhoc_data = (char *) location_adhoc_data;
+ 	  allocated_location_adhoc_data *= 2;
+ 	  location_adhoc_data = XRESIZEVEC (struct location_adhoc_data,
+ 				 	location_adhoc_data,
+ 					allocated_location_adhoc_data);
+ 	  htab_traverse (location_adhoc_data_htab, location_adhoc_data_update,
+ 			 orig_location_adhoc_data);
+ 	}
+     }
+   return ((*slot) - location_adhoc_data) | 0x80000000;
+ }
+
+ /* Return the data for the adhoc loc.  */
+
+ void *
+ get_data_from_adhoc_loc (source_location loc)
+ {
+   linemap_assert (IS_ADHOC_LOC (loc));
+   return location_adhoc_data[loc & MAX_SOURCE_LOCATION].data;
+ }
+
+ /* Return the location for the adhoc loc.  */
+
+ source_location
+ get_location_from_adhoc_loc (source_location loc)
+ {
+   linemap_assert (IS_ADHOC_LOC (loc));
+   return location_adhoc_data[loc & MAX_SOURCE_LOCATION].locus;
+ }
+
+ /* Initialize the location_adhoc_data structure.  */
+
+ void
+ location_adhoc_data_init (void)
+ {
+   location_adhoc_data_htab = htab_create (100, location_adhoc_data_hash,
+ 					  location_adhoc_data_eq, NULL);
+   curr_adhoc_loc = 0;
+   allocated_location_adhoc_data = 100;
+   location_adhoc_data = XNEWVEC (struct location_adhoc_data,
+ 			     allocated_location_adhoc_data);
+ }
+
+ /* Finalize the location_adhoc_data structure.  */
+
+ void
+ location_adhoc_data_fini (void)
+ {
+   allocated_location_adhoc_data = 0;
+   XDELETEVEC (location_adhoc_data);
+   htab_delete (location_adhoc_data_htab);
+ }
+
  /* Initialize a line map set.  */

  void
*************** linemap_position_for_line_and_column (st
*** 509,514 ****
--- 639,646 ----
  const struct line_map*
  linemap_lookup (struct line_maps *set, source_location line)
  {
+   if (IS_ADHOC_LOC (line))
+     line = location_adhoc_data[line & MAX_SOURCE_LOCATION].locus;
    if (linemap_location_from_macro_expansion_p (set, line))
      return linemap_macro_map_lookup (set, line);
    return linemap_ordinary_map_lookup (set, line);
*************** linemap_ordinary_map_lookup (struct line
*** 525,530 ****
--- 657,665 ----
    unsigned int md, mn, mx;
    const struct line_map *cached, *result;

+   if (IS_ADHOC_LOC (line))
+     line = location_adhoc_data[line & MAX_SOURCE_LOCATION].locus;
+
    if (set ==  NULL || line < RESERVED_LOCATION_COUNT)
      return NULL;

*************** linemap_macro_map_lookup (struct line_ma
*** 570,575 ****
--- 705,713 ----
    unsigned int md, mn, mx;
    const struct line_map *cached, *result;

+   if (IS_ADHOC_LOC (line))
+     line = location_adhoc_data[line & MAX_SOURCE_LOCATION].locus;
+
    linemap_assert (line >= LINEMAPS_MACRO_LOWEST_LOCATION (set));

    if (set ==  NULL)
*************** linemap_macro_map_loc_to_def_point (cons
*** 648,653 ****
--- 786,794 ----
  {
    unsigned token_no;

+   if (IS_ADHOC_LOC (location))
+     location = location_adhoc_data[location & MAX_SOURCE_LOCATION].locus;
+
    linemap_assert (linemap_macro_expansion_map_p (map)
  		  && location >= MAP_START_LOCATION (map));
    linemap_assert (location >= RESERVED_LOCATION_COUNT);
*************** linemap_macro_map_loc_unwind_toward_spel
*** 672,677 ****
--- 813,821 ----
  {
    unsigned token_no;

+   if (IS_ADHOC_LOC (location))
+     location = location_adhoc_data[location & MAX_SOURCE_LOCATION].locus;
+
    linemap_assert (linemap_macro_expansion_map_p (map)
  		  && location >= MAP_START_LOCATION (map));
    linemap_assert (location >= RESERVED_LOCATION_COUNT);
*************** linemap_get_expansion_line (struct line_
*** 696,701 ****
--- 840,848 ----
  {
    const struct line_map *map = NULL;

+   if (IS_ADHOC_LOC (location))
+     location = location_adhoc_data[location & MAX_SOURCE_LOCATION].locus;
+
    if (location < RESERVED_LOCATION_COUNT)
      return 0;

*************** linemap_get_expansion_filename (struct l
*** 720,725 ****
--- 867,875 ----
  {
    const struct line_map *map = NULL;

+   if (IS_ADHOC_LOC (location))
+     location = location_adhoc_data[location & MAX_SOURCE_LOCATION].locus;
+
    if (location < RESERVED_LOCATION_COUNT)
      return NULL;

*************** linemap_location_in_system_header_p (str
*** 754,759 ****
--- 904,912 ----
  {
    const struct line_map *map = NULL;

+   if (IS_ADHOC_LOC (location))
+     location = location_adhoc_data[location & MAX_SOURCE_LOCATION].locus;
+
    if (location < RESERVED_LOCATION_COUNT)
      return false;

*************** bool
*** 793,798 ****
--- 946,954 ----
  linemap_location_from_macro_expansion_p (struct line_maps *set,
  					 source_location location)
  {
+   if (IS_ADHOC_LOC (location))
+     location = location_adhoc_data[location & MAX_SOURCE_LOCATION].locus;
+
    linemap_assert (location <= MAX_SOURCE_LOCATION
  		  && (set->highest_location
  		      < LINEMAPS_MACRO_LOWEST_LOCATION (set)));
*************** linemap_macro_loc_to_spelling_point (str
*** 933,938 ****
--- 1089,1097 ----
  {
    struct line_map *map;

+   if (IS_ADHOC_LOC (location))
+     location = location_adhoc_data[location & MAX_SOURCE_LOCATION].locus;
+
    linemap_assert (set && location >= RESERVED_LOCATION_COUNT);

    while (true)
*************** linemap_macro_loc_to_def_point (struct l
*** 967,972 ****
--- 1126,1134 ----
  {
    struct line_map *map;

+   if (IS_ADHOC_LOC (location))
+     location = location_adhoc_data[location & MAX_SOURCE_LOCATION].locus;
+
    linemap_assert (set && location >= RESERVED_LOCATION_COUNT);

    while (true)
*************** linemap_macro_loc_to_exp_point (struct l
*** 1005,1010 ****
--- 1167,1175 ----
  {
    struct line_map *map;

+   if (IS_ADHOC_LOC (location))
+     location = location_adhoc_data[location & MAX_SOURCE_LOCATION].locus;
+
    linemap_assert (set && location >= RESERVED_LOCATION_COUNT);

    while (true)
*************** linemap_resolve_location (struct line_ma
*** 1074,1079 ****
--- 1239,1247 ----
  			  enum location_resolution_kind lrk,
  			  const struct line_map **map)
  {
+   if (IS_ADHOC_LOC (loc))
+     loc = location_adhoc_data[loc & MAX_SOURCE_LOCATION].locus;
+
    if (loc < RESERVED_LOCATION_COUNT)
      {
        /* A reserved location wasn't encoded in a map.  Let's return a
*************** linemap_unwind_toward_expansion (struct
*** 1121,1126 ****
--- 1289,1297 ----
    source_location resolved_location;
    const struct line_map *resolved_map;

+   if (IS_ADHOC_LOC (loc))
+     loc = location_adhoc_data[loc & MAX_SOURCE_LOCATION].locus;
+
    resolved_location =
      linemap_macro_map_loc_unwind_toward_spelling (*map, loc);
    resolved_map = linemap_lookup (set, resolved_location);
*************** linemap_unwind_to_first_non_reserved_loc
*** 1157,1162 ****
--- 1328,1336 ----
    source_location resolved_loc;
    const struct line_map *map0 = NULL, *map1 = NULL;

+   if (IS_ADHOC_LOC (loc))
+     loc = location_adhoc_data[loc & MAX_SOURCE_LOCATION].locus;
+
    map0 = linemap_lookup (set, loc);
    if (!linemap_macro_expansion_map_p (map0))
      return loc;
*************** linemap_expand_location (struct line_map
*** 1198,1203 ****
--- 1372,1382 ----
    expanded_location xloc;

    memset (&xloc, 0, sizeof (xloc));
+   if (IS_ADHOC_LOC (loc))
+     {
+       loc = location_adhoc_data[loc & MAX_SOURCE_LOCATION].locus;
+       xloc.data = location_adhoc_data[loc & MAX_SOURCE_LOCATION].data;
+     }

    if (loc < RESERVED_LOCATION_COUNT)
      /* The location for this token wasn't generated from a line map.
*************** linemap_dump_location (struct line_maps
*** 1290,1295 ****
--- 1469,1477 ----
    const char *path = "", *from = "";
    int l = -1, c = -1, s = -1, e = -1;

+   if (IS_ADHOC_LOC (loc))
+     loc = location_adhoc_data[loc & MAX_SOURCE_LOCATION].locus;
+
    if (loc == 0)
      return;

Index: libcpp/include/line-map.h
===================================================================
*** libcpp/include/line-map.h	(revision 190209)
--- libcpp/include/line-map.h	(working copy)
*************** struct GTY(()) line_map_ordinary {
*** 89,95 ****

  /* This is the highest possible source location encoded within an
     ordinary or macro map.  */
! #define MAX_SOURCE_LOCATION 0xFFFFFFFF

  struct cpp_hashnode;

--- 89,95 ----

  /* This is the highest possible source location encoded within an
     ordinary or macro map.  */
! #define MAX_SOURCE_LOCATION 0x7FFFFFFF

  struct cpp_hashnode;

*************** struct GTY(()) line_maps {
*** 408,413 ****
--- 408,423 ----
  #define LINEMAPS_LAST_ALLOCATED_MACRO_MAP(SET) \
    LINEMAPS_LAST_ALLOCATED_MAP (SET, true)

+ extern void location_adhoc_data_init (void);
+ extern void location_adhoc_data_fini (void);
+ extern source_location get_combined_adhoc_loc (source_location, void *);
+ extern void *get_data_from_adhoc_loc (source_location);
+ extern source_location get_location_from_adhoc_loc (source_location);
+
+ #define COMBINE_LOCATION_DATA(LOC, BLOCK) \
+   ((BLOCK) ? get_combined_adhoc_loc ((LOC), (BLOCK)) : (LOC))
+ #define IS_ADHOC_LOC(LOC) (((LOC) & MAX_SOURCE_LOCATION) != (LOC))
+
  /* Initialize a line map set.  */
  extern void linemap_init (struct line_maps *);

*************** typedef struct
*** 594,599 ****
--- 604,611 ----

    int column;

+   void *data;
+
    /* In a system header?. */
    bool sysp;
  } expanded_location;
Dodji Seketeli Aug. 14, 2012, 7:56 a.m. UTC | #6
Dehao Chen <dehao@google.com> writes:

> Index: libcpp/line-map.c

[...]

> + /* Data structure to associate an arbitrary data to a source location.  */
> + struct location_adhoc_data {
> +   source_location locus;
> +   void *data;
> + };
> +
> + /* The following data structure encodes a location with some adhoc data,
> +    and map it to a new unsigned integer, and replace it with the original

I think you should remove the words "it with".

> +    location to represent the mapping.

So it should read (so far):

    The following data structure encodes a location with some adhoc data
    and maps it to a new unsigned integer (called an adhoc location)
    that replaces the original location to represent the mapping.

> +
> +    The new adhoc_loc uses the highest bit as the enabling bit, i.e. if the
> +    highest bit is 1, then the number is adhoc_loc. Otherwise, it serves as
> +    the original location. Once identified as the adhoc_loc, the lower 31
> +    bits of the integer is used to index to the location_adhoc_data array,

s/index to/index/

> +    in which the locus and associated data is stored.  */

> + /* Combine LOCUS and DATA to a combined adhoc loc.  */
> +
> + source_location
> + get_combined_adhoc_loc (source_location locus, void *data)
> + {
> +   struct location_adhoc_data lb;
> +   struct location_adhoc_data **slot;
> +
> +   linemap_assert (data);
> +
> +   if (IS_ADHOC_LOC (locus))
> +     locus = location_adhoc_data[locus & MAX_SOURCE_LOCATION].locus;
> +   if (locus == 0 && data == NULL)
> +     return 0;
> +   lb.locus = locus;
> +   lb.data = data;
> +   slot = (struct location_adhoc_data **)
> +       htab_find_slot (location_adhoc_data_htab, &lb, INSERT);
> +   if (*slot == NULL)
> +     {
> +       *slot = location_adhoc_data + curr_adhoc_loc;
> +       location_adhoc_data[curr_adhoc_loc] = lb;
> +       if (++curr_adhoc_loc >= allocated_location_adhoc_data)
> + 	{
> + 	  char *orig_location_adhoc_data = (char *) location_adhoc_data;
> + 	  allocated_location_adhoc_data *= 2;
> + 	  location_adhoc_data = XRESIZEVEC (struct location_adhoc_data,
> + 				 	location_adhoc_data,
> + 					allocated_location_adhoc_data);
> + 	  htab_traverse (location_adhoc_data_htab, location_adhoc_data_update,
> + 			 orig_location_adhoc_data);
> + 	}
> +     }

I am wondering if there isn't an indentation issue here.

> +   return ((*slot) - location_adhoc_data) | 0x80000000;
> + }
> +

Other than that, I don't really have anything worthwhile to say.  I am
deferring to the maintainers now :-)

Thank you for bearing with me.
diff mbox

Patch

Index: gcc/lto-streamer-out.c
===================================================================
--- gcc/lto-streamer-out.c      (revision 189835)
+++ gcc/lto-streamer-out.c      (working copy)
@@ -155,6 +155,7 @@ 
 {
   expanded_location xloc;

+  loc = LOCATION_LOCUS (loc);
   bp_pack_value (bp, loc == UNKNOWN_LOCATION, 1);
   if (loc == UNKNOWN_LOCATION)
     return;