+2012-09-19 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.
+ * lto-cgraph.c (output_node_opt_summary): 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.
+ * ipa-prop.c (ipa_set_jf_constant): Likewise.
+ (ipa_write_jump_function): Likewise.
+ * dwarf2out.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.
+
2012-09-19 Bernd Schmidt <bernds@codesourcery.com>
* dbgcnt.def (sched_breakdep): New counter.
/* Auxiliary info specific to a pass. */
PTR 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
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);
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;
&& 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
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;
}
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;
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;
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;
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;
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;
}
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))
{
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))
{
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). */
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);
}
}
}
- set_curr_insn_source_location (sloc);
- set_curr_insn_block (sblock);
+ set_curr_insn_location (sloc);
}
currently_expanding_gimple_stmt = stmt;
}
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 (;;)
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);
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;
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);
PAT_VAR_LOCATION_LOC (val) = (rtx)value;
}
- set_curr_insn_source_location (sloc);
- set_curr_insn_block (sblock);
+ set_curr_insn_location (sloc);
}
else
{
/* 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));
/* 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 ();
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 ();
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);
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. */
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;
}
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
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;
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;
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;
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);
}
/* 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)
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),
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);
/* 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);
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);
/* 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);
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);
/* 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);
the insns emitted. Note that use_thunk calls
assemble_start_function and assemble_end_function. */
- insn_locators_alloc ();
insns = get_insns ();
if (optimize > 0)
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);
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);
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);
{
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));
}
}
- 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)
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
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;
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;
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;
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);
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)
{
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);
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,
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)
{
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)
{
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)
{
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)
{
}
/* 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)
{
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)
{
}
/* 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)
{
/* 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,
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;
+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)
+insn_locations_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);
+ 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;
-}
-\f
-
-/* 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 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 LOCATION_FILE (INSN_LOCATION (insn));
}
-\f
/* Return true if memory model MODEL requires a pre-operation (release-style)
barrier or a post-operation (acquire-style) barrier. While not universal,
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;
}
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
{
insn_scope (XVECEXP (body, 0, i)));
}
if (! this_block)
- continue;
+ this_block = DECL_INITIAL (cfun->decl);
if (this_block != cur_block)
{
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;
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,
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;
\f
/* Stack of nested functions. */
/* Keep track of the cfun stack. */
f->cfg = NULL;
regno_reg_rtx = NULL;
- insn_locators_free ();
}
\f
/* Return size needed for stack frame based on slots so far allocated.
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;
}
/* 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
*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);
}
}
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
}
prologue_seq = get_insns ();
end_sequence ();
- set_insn_locators (prologue_seq, prologue_locator);
+ set_insn_locations (prologue_seq, prologue_location);
}
#endif
/* 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 ();
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);
}
streamer_write_bitpack (&bp);
/* Emit location information for the statement. */
- lto_output_location (ob, gimple_location (stmt));
+ lto_output_location (ob, LOCATION_LOCUS (gimple_location (stmt)));
/* Emit the lexical block holding STMT. */
stream_write_tree (ob, gimple_block (stmt), true);
gimple_debug_bind_set_var (p, var);
gimple_debug_bind_set_value (p, value);
if (stmt)
- {
- gimple_set_block (p, gimple_block (stmt));
- gimple_set_location (p, gimple_location (stmt));
- }
+ gimple_set_location (p, gimple_location (stmt));
return p;
}
gimple_debug_source_bind_set_var (p, var);
gimple_debug_source_bind_set_value (p, value);
if (stmt)
- {
- gimple_set_block (p, gimple_block (stmt));
- gimple_set_location (p, gimple_location (stmt));
- }
+ gimple_set_location (p, gimple_location (stmt));
return p;
}
gimple_set_vuse (new_stmt, gimple_vuse (stmt));
gimple_set_vdef (new_stmt, gimple_vdef (stmt));
- gimple_set_block (new_stmt, gimple_block (stmt));
if (gimple_has_location (stmt))
gimple_set_location (new_stmt, gimple_location (stmt));
gimple_call_copy_flags (new_stmt, stmt);
and the prev pointer being the last. */
gimple next;
gimple GTY((skip)) prev;
-
- /* [ WORD 6 ]
- Lexical block holding this statement. */
- tree block;
};
static inline tree
gimple_block (const_gimple g)
{
- return g->gsbase.block;
+ return LOCATION_BLOCK (g->gsbase.location);
}
static inline void
gimple_set_block (gimple g, tree block)
{
- g->gsbase.block = block;
+ if (block)
+ g->gsbase.location =
+ COMBINE_LOCATION_DATA (line_table, g->gsbase.location, block);
+ else
+ g->gsbase.location = LOCATION_LOCUS (g->gsbase.location);
}
static inline bool
gimple_has_location (const_gimple g)
{
- return gimple_location (g) != UNKNOWN_LOCATION;
+ return !IS_UNKNOWN_LOCATION (gimple_location (g));
}
= 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;
return FALSE;
emit_insn_before_setloc (seq, if_info->jump,
- INSN_LOCATOR (if_info->insn_a));
+ INSN_LOCATION (if_info->insn_a));
}
return TRUE;
}
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
return FALSE;
emit_insn_before_setloc (seq, if_info->jump,
- INSN_LOCATOR (if_info->insn_a));
+ INSN_LOCATION (if_info->insn_a));
return TRUE;
}
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 ();
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 ();
return FALSE;
emit_insn_before_setloc (seq, if_info->jump,
- INSN_LOCATOR (if_info->insn_a));
+ INSN_LOCATION (if_info->insn_a));
return TRUE;
}
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
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:
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;
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;
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;
}
return FALSE;
emit_insn_before_setloc (seq, if_info->jump,
- INSN_LOCATOR (if_info->insn_a));
+ INSN_LOCATION (if_info->insn_a));
}
return TRUE;
}
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
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)
{
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);
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));
xloc = linemap_expand_location (line_table, map, loc);
}
+ xloc.data = block;
if (loc <= BUILTINS_LOCATION)
xloc.file = loc == UNKNOWN_LOCATION ? NULL : _("<built-in>");
#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 (line_table, LOC) : (LOC))
+#define LOCATION_BLOCK(LOC) \
+ ((tree) ((IS_ADHOC_LOC (LOC)) ? get_data_from_adhoc_loc (line_table, (LOC)) \
+ : NULL))
+#define IS_UNKNOWN_LOCATION(LOC) \
+ ((IS_ADHOC_LOC (LOC)) ? get_location_from_adhoc_loc (line_table, LOC) == 0 \
+ : (LOC) == 0)
#define input_line LOCATION_LINE (input_location)
#define input_filename LOCATION_FILE (input_location)
static void
ipa_set_jf_constant (struct ipa_jump_func *jfunc, tree constant)
{
+ constant = unshare_expr (constant);
+ if (constant && EXPR_P (constant))
+ SET_EXPR_LOCATION (constant, UNKNOWN_LOCATION);
jfunc->type = IPA_JF_CONST;
jfunc->value.constant = constant;
}
stream_write_tree (ob, jump_func->value.known_type.component_type, true);
break;
case IPA_JF_CONST:
+ gcc_assert (
+ IS_UNKNOWN_LOCATION (EXPR_LOCATION (jump_func->value.constant)));
stream_write_tree (ob, jump_func->value.constant, true);
break;
case IPA_JF_PASS_THROUGH:
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;
}
mechanism to store function local declarations into summaries. */
gcc_assert (parm);
streamer_write_uhwi (ob, parm_num);
+ gcc_assert (IS_UNKNOWN_LOCATION (EXPR_LOCATION (map->new_tree)));
stream_write_tree (ob, map->new_tree, true);
bp = bitpack_create (ob->main_stream);
bp_pack_value (&bp, map->replace_p, 1);
{
expanded_location xloc;
+ loc = LOCATION_LOCUS (loc);
bp_pack_value (bp, loc == UNKNOWN_LOCATION, 1);
if (loc == UNKNOWN_LOCATION)
return;
+2012-09-19 Dehao Chen <dehao@google.com>
+
+ * lto/lto.c (lto_fixup_prevailing_decls): Remove tree.exp.block field.
+
2012-09-19 Jan Hubicka <jh@suse.cz>
* lto.c (lto_materialize_function): Update confused comment.
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));
}
/* 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)
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;
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;
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");
}
{
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)
{
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);
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)
{
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);
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
}
{
#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))
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))
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)
/* 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);
/* 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);
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++)
{
/* 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)
{
for (link = crtl->epilogue_delay_list;
link;
link = XEXP (link, 1))
- INSN_LOCATOR (XEXP (link, 0)) = 0;
+ INSN_LOCATION (XEXP (link, 0)) = 0;
}
#endif
#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;
#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;
#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)
/* 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. */
/* 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);
/* 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);
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. */
/* 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
invoke_plugin_callbacks (PLUGIN_FINISH, NULL);
finalize_plugins ();
+ location_adhoc_data_fini (line_table);
if (seen_error ())
return (FATAL_EXIT_CODE);
{
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;
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. */
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;
}
tree t = *tp;
if (EXPR_P (t))
- /* We should never have TREE_BLOCK set on non-statements. */
- gcc_assert (!TREE_BLOCK (t));
-
+ {
+ if (TREE_BLOCK (t))
+ TREE_SET_BLOCK (t, p->new_block);
+ }
else if (DECL_P (t) || TREE_CODE (t) == SSA_NAME)
{
if (TREE_CODE (t) == SSA_NAME)
}
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 = d->new_block ?
+ COMBINE_LOCATION_DATA (line_table, e->goto_locus, d->new_block) :
+ LOCATION_LOCUS (e->goto_locus);
#ifdef ENABLE_CHECKING
else if (block != d->new_block)
{
void
gt_ggc_mx (edge_def *e)
{
+ tree block = LOCATION_BLOCK (e->goto_locus);
gt_ggc_mx (e->src);
gt_ggc_mx (e->dest);
if (current_ir_type () == IR_GIMPLE)
gt_ggc_mx (e->insns.g);
else
gt_ggc_mx (e->insns.r);
- gt_ggc_mx (e->goto_block);
+ gt_ggc_mx (block);
}
/* PCH support for edge_def. */
void
gt_pch_nx (edge_def *e)
{
+ tree block = LOCATION_BLOCK (e->goto_locus);
gt_pch_nx (e->src);
gt_pch_nx (e->dest);
if (current_ir_type () == IR_GIMPLE)
gt_pch_nx (e->insns.g);
else
gt_pch_nx (e->insns.r);
- gt_pch_nx (e->goto_block);
+ gt_pch_nx (block);
}
void
gt_pch_nx (edge_def *e, gt_pointer_operator op, void *cookie)
{
+ tree block = LOCATION_BLOCK (e->goto_locus);
op (&(e->src), cookie);
op (&(e->dest), cookie);
if (current_ir_type () == IR_GIMPLE)
op (&(e->insns.g), cookie);
else
op (&(e->insns.r), cookie);
- op (&(e->goto_block), cookie);
+ op (&(block), cookie);
}
new_seq = copy_gimple_seq_and_replace_locals (seq);
for (gsi = gsi_start (new_seq); !gsi_end_p (gsi); gsi_next (&gsi))
- if (gimple_location (gsi_stmt (gsi)) == UNKNOWN_LOCATION)
+ if (IS_UNKNOWN_LOCATION (gimple_location (gsi_stmt (gsi))))
gimple_set_location (gsi_stmt (gsi), loc);
if (outer_state->tf)
}
else if (this_state)
finally = lower_try_finally_dup_block (finally, outer_state,
- UNKNOWN_LOCATION);
+ gimple_location (tf->try_finally_expr));
finally_may_fallthru = gimple_seq_may_fallthru (finally);
/* If this cleanup consists of a TRY_CATCH_EXPR with TRY_CATCH_IS_CLEANUP
/* 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);
{
/* 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,
}
}
+ /* 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;
}
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)
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
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. */
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));
+ 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, block ?
+ COMBINE_LOCATION_DATA (line_table, locus, block) :
+ LOCATION_LOCUS (locus));
}
}
}
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. */
{
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
{
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;
}
}
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],
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 ();
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
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,
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);
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;
walk_tree (expr_p, mark_all_vars_used_1, NULL, NULL);
}
+/* Helper function for clear_unused_block_pointer, called via walk_tree. */
+
+static tree
+clear_unused_block_pointer_1 (tree *tp, int *, void *)
+{
+ if (EXPR_P (*tp) && TREE_BLOCK (*tp)
+ && !TREE_USED (TREE_BLOCK (*tp)))
+ TREE_SET_BLOCK (*tp, NULL);
+ if (TREE_CODE (*tp) == VAR_DECL && DECL_DEBUG_EXPR_IS_FROM (*tp))
+ {
+ tree debug_expr = DECL_DEBUG_EXPR (*tp);
+ walk_tree (&debug_expr, clear_unused_block_pointer_1, NULL, NULL);
+ }
+ return NULL_TREE;
+}
+
+/* Set all block pointer in debug stmt to NULL if the block is unused,
+ so that they will not be streamed out. */
+
+static void
+clear_unused_block_pointer ()
+{
+ basic_block bb;
+ gimple_stmt_iterator gsi;
+ FOR_EACH_BB (bb)
+ for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
+ {
+ unsigned i;
+ tree b;
+ gimple stmt = gsi_stmt (gsi);
+
+ if (!is_gimple_debug (stmt))
+ continue;
+ b = gimple_block (stmt);
+ if (b && !TREE_USED (b))
+ gimple_set_block (stmt, NULL);
+ for (i = 0; i < gimple_num_ops (stmt); i++)
+ walk_tree (gimple_op_ptr (stmt, i), clear_unused_block_pointer_1,
+ NULL, NULL);
+ }
+}
/* Dump scope blocks starting at SCOPE to FILE. INDENT is the
indentation level and FLAGS is as in print_generic_expr. */
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);
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 (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
VEC_truncate (tree, cfun->local_decls, dstidx);
remove_unused_scope_block_p (DECL_INITIAL (current_function_decl));
+ clear_unused_block_pointer ();
BITMAP_FREE (usedvars);
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));
}
{
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)));
}
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);
}
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);
}
-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))
+ {
+ if (b)
+ t->exp.locus = COMBINE_LOCATION_DATA (line_table, t->exp.locus, b);
+ else
+ t->exp.locus = LOCATION_LOCUS (t->exp.locus);
+ }
+ 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. */
#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"
#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)
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.
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];
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
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);
+2012-09-19 Dehao Chen <dehao@google.com>
+
+ * include/line-map.h (MAX_SOURCE_LOCATION): New value.
+ (location_adhoc_data_fini): New.
+ (get_combined_adhoc_loc): New.
+ (get_data_from_adhoc_loc): New.
+ (get_location_from_adhoc_loc): New.
+ (location_adhoc_data_map): New.
+ (COMBINE_LOCATION_DATA): New.
+ (IS_ADHOC_LOC): New.
+ (expanded_location): New field.
+ (line_maps): New field.
+ * line-map.c (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_init): Initialize location_adhoc_data.
+ (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.
+ (linemap_line_start): Likewise.
+
2012-05-25 Dodji Seketeli <dodji@redhat.com>
PR preprocessor/53469
/* 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;
unsigned int cache;
};
+/* Data structure to associate an arbitrary data to a source location. */
+struct location_adhoc_data {
+ source_location locus;
+ void *data;
+};
+
+struct htab;
+
+/* 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 the location_adhoc_data array,
+ in which the locus and associated data is stored. */
+
+struct location_adhoc_data_map {
+ struct htab *htab;
+ source_location curr_loc;
+ struct location_adhoc_data *data;
+ unsigned int allocated;
+};
+
/* A set of chronological line_map structures. */
struct GTY(()) line_maps {
/* The allocators' function used to know the actual size it
allocated, for a certain allocation size requested. */
line_map_round_alloc_size_func round_alloc_size;
+
+ struct location_adhoc_data_map GTY((skip)) location_adhoc_data_map;
};
/* Returns the pointer to the memory region where information about
#define LINEMAPS_LAST_ALLOCATED_MACRO_MAP(SET) \
LINEMAPS_LAST_ALLOCATED_MAP (SET, true)
+extern void location_adhoc_data_fini (struct line_maps *);
+extern source_location get_combined_adhoc_loc (struct line_maps *,
+ source_location, void *);
+extern void *get_data_from_adhoc_loc (struct line_maps *, source_location);
+extern source_location get_location_from_adhoc_loc (struct line_maps *,
+ source_location);
+
+#define IS_ADHOC_LOC(LOC) (((LOC) & MAX_SOURCE_LOCATION) != (LOC))
+#define COMBINE_LOCATION_DATA(SET, LOC, BLOCK) \
+ get_combined_adhoc_loc ((SET), (LOC), (BLOCK))
+
/* Initialize a line map set. */
extern void linemap_init (struct line_maps *);
int column;
+ void *data;
+
/* In a system header?. */
bool sysp;
} expanded_location;
#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 *,
extern unsigned num_expanded_macros_counter;
extern unsigned num_macro_tokens_counter;
+/* 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) += *((long long *) data);
+ return 1;
+}
+
+/* Combine LOCUS and DATA to a combined adhoc loc. */
+
+source_location
+get_combined_adhoc_loc (struct line_maps *set,
+ source_location locus, void *data)
+{
+ struct location_adhoc_data lb;
+ struct location_adhoc_data **slot;
+
+ linemap_assert (data);
+
+ if (IS_ADHOC_LOC (locus))
+ locus =
+ set->location_adhoc_data_map.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 (set->location_adhoc_data_map.htab, &lb, INSERT);
+ if (*slot == NULL)
+ {
+ if (set->location_adhoc_data_map.curr_loc >=
+ set->location_adhoc_data_map.allocated)
+ {
+ char *orig_data = (char *) set->location_adhoc_data_map.data;
+ long long offset;
+ set->location_adhoc_data_map.allocated *= 2;
+ set->location_adhoc_data_map.data =
+ XRESIZEVEC (struct location_adhoc_data,
+ set->location_adhoc_data_map.data,
+ set->location_adhoc_data_map.allocated);
+ offset = (char *) (set->location_adhoc_data_map.data) - orig_data;
+ htab_traverse (set->location_adhoc_data_map.htab,
+ location_adhoc_data_update, &offset);
+ }
+ *slot = set->location_adhoc_data_map.data
+ + set->location_adhoc_data_map.curr_loc;
+ set->location_adhoc_data_map.data[
+ set->location_adhoc_data_map.curr_loc++] = lb;
+ }
+ return ((*slot) - set->location_adhoc_data_map.data) | 0x80000000;
+}
+
+/* Return the data for the adhoc loc. */
+
+void *
+get_data_from_adhoc_loc (struct line_maps *set, source_location loc)
+{
+ linemap_assert (IS_ADHOC_LOC (loc));
+ return set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].data;
+}
+
+/* Return the location for the adhoc loc. */
+
+source_location
+get_location_from_adhoc_loc (struct line_maps *set, source_location loc)
+{
+ linemap_assert (IS_ADHOC_LOC (loc));
+ return set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
+}
+
+/* Initialize the location_adhoc_data structure. */
+
+static void
+location_adhoc_data_init (struct line_maps *set)
+{
+ set->location_adhoc_data_map.htab =
+ htab_create (100, location_adhoc_data_hash, location_adhoc_data_eq, NULL);
+ set->location_adhoc_data_map.curr_loc = 0;
+ set->location_adhoc_data_map.allocated = 100;
+ set->location_adhoc_data_map.data = XNEWVEC (struct location_adhoc_data, 100);
+}
+
+/* Finalize the location_adhoc_data structure. */
+void
+location_adhoc_data_fini (struct line_maps *set)
+{
+ set->location_adhoc_data_map.allocated = 0;
+ XDELETEVEC (set->location_adhoc_data_map.data);
+ htab_delete (set->location_adhoc_data_map.htab);
+}
+
/* Initialize a line map set. */
void
memset (set, 0, sizeof (struct line_maps));
set->highest_location = RESERVED_LOCATION_COUNT - 1;
set->highest_line = RESERVED_LOCATION_COUNT - 1;
+ location_adhoc_data_init (set);
}
/* Check for and warn about line_maps entered but not exited. */
if (add_map)
{
int column_bits;
- if (max_column_hint > 100000 || highest > 0xC0000000)
+ if (max_column_hint > 100000 || highest > 0x60000000)
{
/* If the column number is ridiculous or we've allocated a huge
number of source_locations, give up on column numbers. */
max_column_hint = 0;
- if (highest >0xF0000000)
+ if (highest >0x70000000)
return 0;
column_bits = 0;
}
const struct line_map*
linemap_lookup (struct line_maps *set, source_location line)
{
+ if (IS_ADHOC_LOC (line))
+ line = set->location_adhoc_data_map.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);
unsigned int md, mn, mx;
const struct line_map *cached, *result;
+ if (IS_ADHOC_LOC (line))
+ line = set->location_adhoc_data_map.data[line & MAX_SOURCE_LOCATION].locus;
+
if (set == NULL || line < RESERVED_LOCATION_COUNT)
return NULL;
unsigned int md, mn, mx;
const struct line_map *cached, *result;
+ if (IS_ADHOC_LOC (line))
+ line = set->location_adhoc_data_map.data[line & MAX_SOURCE_LOCATION].locus;
+
linemap_assert (line >= LINEMAPS_MACRO_LOWEST_LOCATION (set));
if (set == NULL)
{
const struct line_map *map = NULL;
+ if (IS_ADHOC_LOC (location))
+ location = set->location_adhoc_data_map.data[
+ location & MAX_SOURCE_LOCATION].locus;
+
if (location < RESERVED_LOCATION_COUNT)
return 0;
{
const struct line_map *map = NULL;
+ if (IS_ADHOC_LOC (location))
+ location = set->location_adhoc_data_map.data[
+ location & MAX_SOURCE_LOCATION].locus;
+
if (location < RESERVED_LOCATION_COUNT)
return NULL;
{
const struct line_map *map = NULL;
+ if (IS_ADHOC_LOC (location))
+ location = set->location_adhoc_data_map.data[
+ location & MAX_SOURCE_LOCATION].locus;
+
if (location < RESERVED_LOCATION_COUNT)
return false;
linemap_location_from_macro_expansion_p (struct line_maps *set,
source_location location)
{
+ if (IS_ADHOC_LOC (location))
+ location = set->location_adhoc_data_map.data[
+ location & MAX_SOURCE_LOCATION].locus;
+
linemap_assert (location <= MAX_SOURCE_LOCATION
&& (set->highest_location
< LINEMAPS_MACRO_LOWEST_LOCATION (set)));
{
struct line_map *map;
+ if (IS_ADHOC_LOC (location))
+ location = set->location_adhoc_data_map.data[
+ location & MAX_SOURCE_LOCATION].locus;
+
linemap_assert (set && location >= RESERVED_LOCATION_COUNT);
while (true)
{
struct line_map *map;
+ if (IS_ADHOC_LOC (location))
+ location = set->location_adhoc_data_map.data[
+ location & MAX_SOURCE_LOCATION].locus;
+
linemap_assert (set && location >= RESERVED_LOCATION_COUNT);
while (true)
{
struct line_map *map;
+ if (IS_ADHOC_LOC (location))
+ location = set->location_adhoc_data_map.data[
+ location & MAX_SOURCE_LOCATION].locus;
+
linemap_assert (set && location >= RESERVED_LOCATION_COUNT);
while (true)
enum location_resolution_kind lrk,
const struct line_map **map)
{
+ if (IS_ADHOC_LOC (loc))
+ loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
+
if (loc < RESERVED_LOCATION_COUNT)
{
/* A reserved location wasn't encoded in a map. Let's return a
source_location resolved_location;
const struct line_map *resolved_map;
+ if (IS_ADHOC_LOC (loc))
+ loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
+
resolved_location =
linemap_macro_map_loc_unwind_toward_spelling (*map, loc);
resolved_map = linemap_lookup (set, resolved_location);
source_location resolved_loc;
const struct line_map *map0 = NULL, *map1 = NULL;
+ if (IS_ADHOC_LOC (loc))
+ loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
+
map0 = linemap_lookup (set, loc);
if (!linemap_macro_expansion_map_p (map0))
return loc;
expanded_location xloc;
memset (&xloc, 0, sizeof (xloc));
+ if (IS_ADHOC_LOC (loc))
+ {
+ loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
+ xloc.data = set->location_adhoc_data_map.data[
+ loc & MAX_SOURCE_LOCATION].data;
+ }
if (loc < RESERVED_LOCATION_COUNT)
/* The location for this token wasn't generated from a line map.
const char *path = "", *from = "";
int l = -1, c = -1, s = -1, e = -1;
+ if (IS_ADHOC_LOC (loc))
+ loc = set->location_adhoc_data_map.data[loc & MAX_SOURCE_LOCATION].locus;
+
if (loc == 0)
return;