From 475bbb3984ed133b020b344eebc2d4d3bf8ce52f Mon Sep 17 00:00:00 2001 From: Andrea Corallo Date: Thu, 16 Jul 2020 09:21:38 +0100 Subject: [PATCH 1/2] Add new RTX instruction class FILLER_INSN gcc/ChangeLog 2020-07-17 Andrea Corallo Carey Williams * cfgbuild.c (inside_basic_block_p): Handle FILLER_INSN. * cfgrtl.c (rtl_verify_bb_layout): Whitelist FILLER_INSN outside basic blocks. * coretypes.h: New rtx class. * emit-rtl.c (emit_filler_after): New function. * rtl.def (FILLER_INSN): New rtl define. * rtl.h (rtx_filler_insn): Define new structure. (FILLER_INSN_P): New macro. (is_a_helper ::test): New test helper for rtx_filler_insn. (emit_filler_after): New extern. * target-insns.def: Add target insn definition. --- gcc/cfgbuild.c | 1 + gcc/cfgrtl.c | 16 +++++++++++++++- gcc/coretypes.h | 1 + gcc/emit-rtl.c | 14 ++++++++++++++ gcc/rtl.def | 4 ++++ gcc/rtl.h | 23 +++++++++++++++++++++++ gcc/target-insns.def | 1 + 7 files changed, 59 insertions(+), 1 deletion(-) diff --git a/gcc/cfgbuild.c b/gcc/cfgbuild.c index 478afa5fe91c..07cb06afba07 100644 --- a/gcc/cfgbuild.c +++ b/gcc/cfgbuild.c @@ -58,6 +58,7 @@ inside_basic_block_p (const rtx_insn *insn) case JUMP_TABLE_DATA: case BARRIER: + case FILLER_INSN: case NOTE: return false; diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c index 827e84a44ddd..02139aaa268d 100644 --- a/gcc/cfgrtl.c +++ b/gcc/cfgrtl.c @@ -61,6 +61,7 @@ along with GCC; see the file COPYING3. If not see #include "cfgloop.h" #include "tree-pass.h" #include "print-rtl.h" +#include "rtl-iter.h" /* Disable warnings about missing quoting in GCC diagnostics. */ #if __GNUC__ >= 10 @@ -3033,7 +3034,20 @@ rtl_verify_bb_layout (void) break; default: - fatal_insn ("insn outside basic block", x); + /* Allow nops after branches, via FILLER_INSN. */ + bool fail = true; + subrtx_iterator::array_type array; + FOR_EACH_SUBRTX (iter, array, x, ALL) + { + const_rtx rtx = *iter; + if (GET_CODE (rtx) == FILLER_INSN) + { + fail = false; + break; + } + } + if (fail) + fatal_insn ("insn outside basic block", x); } } diff --git a/gcc/coretypes.h b/gcc/coretypes.h index 6b6cfcdf210d..5c6633a815c5 100644 --- a/gcc/coretypes.h +++ b/gcc/coretypes.h @@ -84,6 +84,7 @@ struct rtx_def; struct rtx_call_insn; /* CALL_P (X) */ struct rtx_jump_table_data; /* JUMP_TABLE_DATA_P (X) */ struct rtx_barrier; /* BARRIER_P (X) */ + struct rtx_filler_insn; /* FILLER_INSN_P (X) */ struct rtx_code_label; /* LABEL_P (X) */ struct rtx_note; /* NOTE_P (X) */ diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index f9b0e9714d9e..76f25c011b2a 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -4746,6 +4746,20 @@ emit_barrier_after (rtx_insn *after) return insn; } +/* Make an insn of code FILLER_INSN to + pad out the instruction stream. + PATTERN should be from gen_filler_insn (). + AFTER will typically be an unconditional + branch at the end of a basic block. */ + +rtx_insn * +emit_filler_after (rtx pattern, rtx_insn *after) +{ + rtx_insn* i = make_insn_raw (pattern); + add_insn_after_nobb (i, after); + return i; +} + /* Emit the label LABEL after the insn AFTER. */ rtx_insn * diff --git a/gcc/rtl.def b/gcc/rtl.def index 9754333eafba..0e0040eaa1cf 100644 --- a/gcc/rtl.def +++ b/gcc/rtl.def @@ -328,6 +328,10 @@ DEF_RTL_EXPR(RETURN, "return", "", RTX_EXTRA) conditional jumps. */ DEF_RTL_EXPR(SIMPLE_RETURN, "simple_return", "", RTX_EXTRA) +/* Special filler type, used to pad the instruction stream. */ + +DEF_RTL_EXPR(FILLER_INSN, "filler_insn", "", RTX_INSN) + /* Special for EH return from subroutine. */ DEF_RTL_EXPR(EH_RETURN, "eh_return", "", RTX_EXTRA) diff --git a/gcc/rtl.h b/gcc/rtl.h index 0872cc408eb1..60abd609007f 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -674,6 +674,17 @@ struct GTY(()) rtx_barrier : public rtx_insn from rtl.def. */ }; +struct GTY(()) rtx_filler_insn : public rtx_insn +{ + /* No extra fields, but adds the invariant: + FILLER_INSN_P (X) aka (GET_CODE (X) == FILLER_INSN) + i.e. a marker that indicates the INSN stream should be padded. + + This is an instance of: + DEF_RTL_EXPR(FILLER_INSN, "filler_insn", "", RTX_INSN) + from rtl.def. */ +}; + struct GTY(()) rtx_code_label : public rtx_insn { /* No extra fields, but adds the invariant: @@ -865,6 +876,9 @@ struct GTY(()) rtvec_def { /* Predicate yielding nonzero iff X is a barrier insn. */ #define BARRIER_P(X) (GET_CODE (X) == BARRIER) +/* Predicate yielding nonzero iff X is a filler insn. */ +#define FILLER_INSN_P(X) (GET_CODE (X) == FILLER_INSN) + /* Predicate yielding nonzero iff X is a data for a jump table. */ #define JUMP_TABLE_DATA_P(INSN) (GET_CODE (INSN) == JUMP_TABLE_DATA) @@ -970,6 +984,14 @@ is_a_helper ::test (rtx rt) return BARRIER_P (rt); } +template <> +template <> +inline bool +is_a_helper ::test (rtx rt) +{ + return FILLER_INSN_P (rt); +} + template <> template <> inline bool @@ -3300,6 +3322,7 @@ extern rtx_insn *emit_debug_insn_after (rtx, rtx_insn *); extern rtx_insn *emit_debug_insn_after_noloc (rtx, rtx_insn *); extern rtx_insn *emit_debug_insn_after_setloc (rtx, rtx_insn *, location_t); extern rtx_barrier *emit_barrier_after (rtx_insn *); +extern rtx_insn *emit_filler_after (rtx, rtx_insn *); extern rtx_insn *emit_label_after (rtx_insn *, rtx_insn *); extern rtx_note *emit_note_after (enum insn_note, rtx_insn *); extern rtx_insn *emit_insn (rtx); diff --git a/gcc/target-insns.def b/gcc/target-insns.def index 4d7eb92cf68c..dfdf0273edc1 100644 --- a/gcc/target-insns.def +++ b/gcc/target-insns.def @@ -94,6 +94,7 @@ DEF_TARGET_INSN (sibcall_epilogue, (void)) DEF_TARGET_INSN (sibcall_value, (rtx x0, rtx x1, rtx opt2, rtx opt3, rtx opt4)) DEF_TARGET_INSN (simple_return, (void)) +DEF_TARGET_INSN (filler_insn, (void)) DEF_TARGET_INSN (split_stack_prologue, (void)) DEF_TARGET_INSN (split_stack_space_check, (rtx x0, rtx x1)) DEF_TARGET_INSN (stack_protect_combined_set, (rtx x0, rtx x1)) -- 2.17.1