From d6ce740392049d769f96d81306b22d6ef6cbf1e7 Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Wed, 28 May 2014 15:48:25 -0400 Subject: [PATCH 3/5] Introduce rtx_base_insn and rtx_note classes gcc/ * coretypes.h (rtx_base_insn): Add forward declaration. (rtx_note): Likewise. Introduce indentation within the forward declarations to show the class hierarchy. * rtl.h (struct rtx_base_insn): New subclass of rtx_def, adding the invariant that INSN_UID/NEXT_INSN/PREV_INSN are usable. (struct rtx_code_label): Convert from a subclass of rtx_def to one of rtx_base_insn. (struct rtx_note): New subclass of rtx_base_insn (is_a_helper ::test): New. (NULL_RTX_NOTE): New. (emit_note_before): Strengthen return type from rtx to rtx_note. (emit_note_after): Likewise. (emit_note): Likewise. (emit_note_copy): Likewise. Require an rtx_note rather than an rtx. * basic-block.h (create_basic_block_structure): Strengthen 3rd param "bb_note" to require an rtx_note rather than an rtx. * function.h (struct rtl_data): Strengthen field "x_stack_check_probe_note" from rtx to rtx_note. * cfgexpand.c (expand_gimple_basic_block): Strengthen local "note" from rtx to rtx_note. * cfgrtl.c (create_basic_block_structure): Strengthen 3rd param "bb_note" to require an rtx_note rather than an rtx. (duplicate_insn_chain): Strengthen local "last" from rtx to rtx_note; add checked cast to rtx_node within NOTE case of switch. * emit-rtl.c (make_note_raw): Strengthen return type from rtx to rtx_note. (emit_note_after): Likewise. (emit_note_before): Likewise. (emit_note): Likewise. (emit_note_copy): Likewise. Require an rtx_note rather than an rtx. * except.c (convert_to_eh_region_ranges): Strengthen local "note" from rtx to rtx_note. * final.c (change_scope): Likewise. (reemit_insn_block_notes): Likewise. * haifa-sched.c (sched_extend_bb): Likewise. * reg-stack.c (compensate_edge): Likewise for local "after". * reload1.c (reload_as_needed): Likewise for local "marker". * sel-sched-ir.c (bb_note_pool): Strengthen from rtx_vec_t to vec. (get_bb_note_from_pool): Strengthen return type from rtx to rtx_note. (sel_create_basic_block): Strengthen local "new_bb_note" from rtx to rtx_note. * var-tracking.c (emit_note_insn_var_location): Likewise for local "note". (emit_notes_in_bb): Likewise. --- gcc/basic-block.h | 2 +- gcc/cfgexpand.c | 5 +++-- gcc/cfgrtl.c | 8 +++++--- gcc/coretypes.h | 9 ++++++--- gcc/emit-rtl.c | 22 +++++++++++----------- gcc/except.c | 3 ++- gcc/final.c | 7 ++++--- gcc/function.h | 2 +- gcc/haifa-sched.c | 2 +- gcc/reg-stack.c | 3 ++- gcc/reload1.c | 3 ++- gcc/rtl.h | 47 ++++++++++++++++++++++++++++++++++++++++++----- gcc/sel-sched-ir.c | 10 +++++----- gcc/var-tracking.c | 6 ++++-- 14 files changed, 89 insertions(+), 40 deletions(-) diff --git a/gcc/basic-block.h b/gcc/basic-block.h index 5d06822..cf02425 100644 --- a/gcc/basic-block.h +++ b/gcc/basic-block.h @@ -401,7 +401,7 @@ extern void remove_edge_raw (edge); extern void redirect_edge_succ (edge, basic_block); extern edge redirect_edge_succ_nodup (edge, basic_block); extern void redirect_edge_pred (edge, basic_block); -extern basic_block create_basic_block_structure (rtx, rtx, rtx, basic_block); +extern basic_block create_basic_block_structure (rtx, rtx, rtx_note *, basic_block); extern void clear_bb_flags (void); extern void dump_bb_info (FILE *, basic_block, int, int, bool, bool); extern void dump_edge_info (FILE *, edge, int, int); diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index b51894f..39f9895 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -4877,7 +4877,8 @@ expand_gimple_basic_block (basic_block bb, bool disable_tail_calls) gimple_stmt_iterator gsi; gimple_seq stmts; gimple stmt = NULL; - rtx note, last; + rtx_note *note; + rtx last; edge e; edge_iterator ei; rtx_code_label **elt; @@ -4949,7 +4950,7 @@ expand_gimple_basic_block (basic_block bb, bool disable_tail_calls) maybe_dump_rtl_for_gimple_stmt (stmt, last); } else - note = BB_HEAD (bb) = emit_note (NOTE_INSN_BASIC_BLOCK); + BB_HEAD (bb) = note = emit_note (NOTE_INSN_BASIC_BLOCK); NOTE_BASIC_BLOCK (note) = bb; diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c index fe42bb3..5a6275f 100644 --- a/gcc/cfgrtl.c +++ b/gcc/cfgrtl.c @@ -272,7 +272,8 @@ delete_insn_chain (rtx start, rtx finish, bool clear_bb) AFTER is the basic block we should be put after. */ basic_block -create_basic_block_structure (rtx head, rtx end, rtx bb_note, basic_block after) +create_basic_block_structure (rtx head, rtx end, rtx_note *bb_note, + basic_block after) { basic_block bb; @@ -4079,7 +4080,8 @@ cfg_layout_can_duplicate_bb_p (const_basic_block bb) rtx duplicate_insn_chain (rtx from, rtx to) { - rtx insn, next, last, copy; + rtx insn, next, copy; + rtx_note *last; /* Avoid updating of boundaries of previous basic block. The note will get removed from insn stream in fixup. */ @@ -4147,7 +4149,7 @@ duplicate_insn_chain (rtx from, rtx to) break; case NOTE_INSN_EPILOGUE_BEG: - emit_note_copy (insn); + emit_note_copy (as_a (insn)); break; default: diff --git a/gcc/coretypes.h b/gcc/coretypes.h index 6465281..7b40e00 100644 --- a/gcc/coretypes.h +++ b/gcc/coretypes.h @@ -62,9 +62,12 @@ struct hwivec_def; typedef struct hwivec_def *hwivec; typedef const struct hwivec_def *const_hwivec; -/* Subclasses of rtx_def. - Keep this list in the same order as in rtl.def. */ -class rtx_code_label; +/* Subclasses of rtx_def, using indentation to show the class + hierarchy. + Where possible, keep this list in the same order as in rtl.def. */ +class rtx_base_insn; + class rtx_code_label; + class rtx_note; union tree_node; typedef union tree_node *tree; diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index 5eb8190..2060f3a 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -3839,7 +3839,7 @@ make_call_insn_raw (rtx pattern) /* Like `make_insn_raw' but make a NOTE instead of an insn. */ -static rtx +static rtx_note * make_note_raw (enum insn_note subtype) { /* Some notes are never created this way at all. These notes are @@ -3847,7 +3847,7 @@ make_note_raw (enum insn_note subtype) gcc_assert (subtype != NOTE_INSN_DELETED_LABEL && subtype != NOTE_INSN_DELETED_DEBUG_LABEL); - rtx note = rtx_alloc (NOTE); + rtx_note *note = as_a (rtx_alloc (NOTE)); INSN_UID (note) = cur_insn_uid++; NOTE_KIND (note) = subtype; BLOCK_FOR_INSN (note) = NULL; @@ -4544,10 +4544,10 @@ note_outside_basic_block_p (enum insn_note subtype, bool on_bb_boundary_p) /* Emit a note of subtype SUBTYPE after the insn AFTER. */ -rtx +rtx_note * emit_note_after (enum insn_note subtype, rtx after) { - rtx note = make_note_raw (subtype); + rtx_note *note = make_note_raw (subtype); basic_block bb = BARRIER_P (after) ? NULL : BLOCK_FOR_INSN (after); bool on_bb_boundary_p = (bb != NULL && BB_END (bb) == after); @@ -4560,10 +4560,10 @@ emit_note_after (enum insn_note subtype, rtx after) /* Emit a note of subtype SUBTYPE before the insn BEFORE. */ -rtx +rtx_note * emit_note_before (enum insn_note subtype, rtx before) { - rtx note = make_note_raw (subtype); + rtx_note *note = make_note_raw (subtype); basic_block bb = BARRIER_P (before) ? NULL : BLOCK_FOR_INSN (before); bool on_bb_boundary_p = (bb != NULL && BB_HEAD (bb) == before); @@ -5010,11 +5010,11 @@ emit_barrier (void) /* Emit a copy of note ORIG. */ -rtx -emit_note_copy (rtx orig) +rtx_note * +emit_note_copy (rtx_note *orig) { enum insn_note kind = (enum insn_note) NOTE_KIND (orig); - rtx note = make_note_raw (kind); + rtx_note *note = make_note_raw (kind); NOTE_DATA (note) = NOTE_DATA (orig); add_insn (note); return note; @@ -5023,10 +5023,10 @@ emit_note_copy (rtx orig) /* Make an insn of code NOTE or type NOTE_NO and add it to the end of the doubly-linked list. */ -rtx +rtx_note * emit_note (enum insn_note kind) { - rtx note = make_note_raw (kind); + rtx_note *note = make_note_raw (kind); add_insn (note); return note; } diff --git a/gcc/except.c b/gcc/except.c index fe1de06..ec712a9 100644 --- a/gcc/except.c +++ b/gcc/except.c @@ -2479,7 +2479,8 @@ add_call_site (rtx landing_pad, int action, int section) static unsigned int convert_to_eh_region_ranges (void) { - rtx insn, iter, note; + rtx insn, iter; + rtx_note *note; action_hash_type ar_hash; int last_action = -3; rtx last_action_insn = NULL_RTX; diff --git a/gcc/final.c b/gcc/final.c index 3271430..378f4c7 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -1630,7 +1630,7 @@ change_scope (rtx orig_insn, tree s1, tree s2) s = s1; while (s != com) { - rtx note = emit_note_before (NOTE_INSN_BLOCK_END, insn); + rtx_note *note = emit_note_before (NOTE_INSN_BLOCK_END, insn); NOTE_BLOCK (note) = s; s = BLOCK_SUPERCONTEXT (s); } @@ -1652,7 +1652,8 @@ static void reemit_insn_block_notes (void) { tree cur_block = DECL_INITIAL (cfun->decl); - rtx insn, note; + rtx insn; + rtx_note *note; insn = get_insns (); for (; insn; insn = NEXT_INSN (insn)) @@ -1665,7 +1666,7 @@ reemit_insn_block_notes (void) for (tree s = cur_block; s != DECL_INITIAL (cfun->decl); s = BLOCK_SUPERCONTEXT (s)) { - rtx note = emit_note_before (NOTE_INSN_BLOCK_END, insn); + rtx_note *note = emit_note_before (NOTE_INSN_BLOCK_END, insn); NOTE_BLOCK (note) = s; note = emit_note_after (NOTE_INSN_BLOCK_BEG, insn); NOTE_BLOCK (note) = s; diff --git a/gcc/function.h b/gcc/function.h index b5480cc..810c614 100644 --- a/gcc/function.h +++ b/gcc/function.h @@ -286,7 +286,7 @@ struct GTY(()) rtl_data { struct frame_space *frame_space_list; /* Place after which to insert the tail_recursion_label if we need one. */ - rtx x_stack_check_probe_note; + rtx_note *x_stack_check_probe_note; /* Location at which to save the argument pointer if it will need to be referenced. There are two cases where this is done: if nonlocal gotos diff --git a/gcc/haifa-sched.c b/gcc/haifa-sched.c index 0e1800a..7c3525e 100644 --- a/gcc/haifa-sched.c +++ b/gcc/haifa-sched.c @@ -7549,7 +7549,7 @@ sched_extend_bb (void) /* Don't emit a NOTE if it would end up before a BARRIER. */ && !BARRIER_P (NEXT_INSN (end)))) { - rtx note = emit_note_after (NOTE_INSN_DELETED, end); + rtx_note *note = emit_note_after (NOTE_INSN_DELETED, end); /* Make note appear outside BB. */ set_block_for_insn (note, NULL); BB_END (EXIT_BLOCK_PTR_FOR_FN (cfun)->prev_bb) = end; diff --git a/gcc/reg-stack.c b/gcc/reg-stack.c index 692abc5..807c56b 100644 --- a/gcc/reg-stack.c +++ b/gcc/reg-stack.c @@ -2815,7 +2815,8 @@ compensate_edge (edge e) } else { - rtx seq, after; + rtx seq; + rtx_note *after; current_block = NULL; start_sequence (); diff --git a/gcc/reload1.c b/gcc/reload1.c index 9daafa4..940fa67 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -4586,7 +4586,8 @@ reload_as_needed (int live_known) #if defined (AUTO_INC_DEC) int i; #endif - rtx x, marker; + rtx x; + rtx_note *marker; memset (spill_reg_rtx, 0, sizeof spill_reg_rtx); memset (spill_reg_store, 0, sizeof spill_reg_store); diff --git a/gcc/rtl.h b/gcc/rtl.h index 6718c30..89b48a2 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -406,11 +406,30 @@ struct GTY((desc("0"), tag("0"), }; +struct GTY(()) rtx_base_insn : public rtx_def +{ + /* No extra fields, but adds this invariant: + + (INSN_P (X) + || NOTE_P (X) + || JUMP_TABLE_DATA_P (X) + || BARRIER_P (X) + || LABEL_P (X)) + + i.e. that we must be able to use the following: + INSN_UID () + NEXT_INSN () + PREV_INSN () + i.e. we have an rtx that has an INSN_UID field and can be part of + a linked list of insns. + */ +}; + /* An expression with the invariant that: GET_CODE (X) == CODE_LABEL i.e. a "code_label". */ -struct GTY(()) rtx_code_label : public rtx_def +struct GTY(()) rtx_code_label : public rtx_base_insn { /* No extra fields, but adds invariant: (GET_CODE (X) == CODE_LABEL). */ }; @@ -423,6 +442,23 @@ is_a_helper ::test (rtx rt) return rt->code == CODE_LABEL; } +/* An expression with the invariant that: + GET_CODE (X) == NOTE + i.e. a "note". */ + +struct GTY(()) rtx_note : public rtx_base_insn +{ + /* No extra fields, but adds invariant: (GET_CODE (X) == NOTE). */ +}; + +template <> +template <> +inline bool +is_a_helper ::test (rtx rt) +{ + return rt->code == NOTE; +} + /* The size in bytes of an rtx header (code, mode and flags). */ #define RTX_HDR_SIZE offsetof (struct rtx_def, u) @@ -431,6 +467,7 @@ is_a_helper ::test (rtx rt) #define NULL_RTX (rtx) 0 #define NULL_RTX_CODE_LABEL (rtx_code_label *) 0 +#define NULL_RTX_NOTE (rtx_note *) 0 /* The "next" and "previous" RTX, relative to this one. */ @@ -2113,7 +2150,7 @@ extern rtx emit_debug_insn_before_noloc (rtx, rtx); extern rtx emit_debug_insn_before_setloc (rtx, rtx, int); extern rtx emit_barrier_before (rtx); extern rtx_code_label *emit_label_before (rtx_code_label *, rtx); -extern rtx emit_note_before (enum insn_note, rtx); +extern rtx_note *emit_note_before (enum insn_note, rtx); extern rtx emit_insn_after (rtx, rtx); extern rtx emit_insn_after_noloc (rtx, rtx, basic_block); extern rtx emit_insn_after_setloc (rtx, rtx, int); @@ -2128,7 +2165,7 @@ extern rtx emit_debug_insn_after_noloc (rtx, rtx); extern rtx emit_debug_insn_after_setloc (rtx, rtx, int); extern rtx emit_barrier_after (rtx); extern rtx emit_label_after (rtx, rtx); -extern rtx emit_note_after (enum insn_note, rtx); +extern rtx_note *emit_note_after (enum insn_note, rtx); extern rtx emit_insn (rtx); extern rtx emit_debug_insn (rtx); extern rtx emit_jump_insn (rtx); @@ -2136,8 +2173,8 @@ extern rtx emit_call_insn (rtx); extern rtx emit_label (rtx); extern rtx emit_jump_table_data (rtx); extern rtx emit_barrier (void); -extern rtx emit_note (enum insn_note); -extern rtx emit_note_copy (rtx); +extern rtx_note *emit_note (enum insn_note); +extern rtx_note *emit_note_copy (rtx_note *); extern rtx gen_clobber (rtx); extern rtx emit_clobber (rtx); extern rtx gen_use (rtx); diff --git a/gcc/sel-sched-ir.c b/gcc/sel-sched-ir.c index 3cba326..40c9b31 100644 --- a/gcc/sel-sched-ir.c +++ b/gcc/sel-sched-ir.c @@ -126,7 +126,7 @@ static struct } nop_pool = { NULL, 0, 0 }; /* The pool for basic block notes. */ -static rtx_vec_t bb_note_pool; +static vec bb_note_pool; /* A NOP pattern used to emit placeholder insns. */ rtx nop_pattern = NULL_RTX; @@ -4981,14 +4981,14 @@ return_bb_to_pool (basic_block bb) } /* Get a bb_note from pool or return NULL_RTX if pool is empty. */ -static rtx +static rtx_note * get_bb_note_from_pool (void) { if (bb_note_pool.is_empty ()) - return NULL_RTX; + return NULL_RTX_NOTE; else { - rtx note = bb_note_pool.pop (); + rtx_note *note = bb_note_pool.pop (); PREV_INSN (note) = NULL_RTX; NEXT_INSN (note) = NULL_RTX; @@ -5346,7 +5346,7 @@ static basic_block sel_create_basic_block (void *headp, void *endp, basic_block after) { basic_block new_bb; - insn_t new_bb_note; + rtx_note *new_bb_note; gcc_assert (flag_sel_sched_pipelining_outer_loops || !last_added_blocks.exists ()); diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c index 9e71165..ed8abdc 100644 --- a/gcc/var-tracking.c +++ b/gcc/var-tracking.c @@ -8588,7 +8588,8 @@ emit_note_insn_var_location (variable_def **varp, emit_note_data *data) rtx insn = data->insn; enum emit_note_where where = data->where; variable_table_type vars = data->vars; - rtx note, note_vl; + rtx_note *note; + rtx note_vl; int i, j, n_var_parts; bool complete; enum var_init_status initialized = VAR_INIT_STATUS_UNINITIALIZED; @@ -9134,7 +9135,8 @@ emit_notes_in_bb (basic_block bb, dataflow_set *set) dataflow_set_clear_at_call (set); emit_notes_for_changes (insn, EMIT_NOTE_AFTER_CALL_INSN, set->vars); { - rtx arguments = mo->u.loc, *p = &arguments, note; + rtx arguments = mo->u.loc, *p = &arguments; + rtx_note *note; while (*p) { XEXP (XEXP (*p, 0), 1) -- 1.8.5.3