All: Please find the patch for optimized usage of instruction prefetch with the generation of microblaze instruction "wic". No regressions is seen in Deja GNU tests for microblaze.
[Patch,microblaze]: Optimized Instruction prefetch with the generation of wic instruction. The changes are made in the patch for optimized Instruction prefetch with the generation of wic microblaze instructions. The Wic microblaze instruction is the instruction prefetch instruction that optimizes the Instruction prefetch. The wic instruction is generated at the call site fall through path and is enabled with a flag mxl-prefetch. The purpose of adding the flags is that wic instruction selected for the particular FPGA design and is not enabled by default. ChangeLog: 2015-07-07 Ajit Agarwal <ajit...@xilinx.com> * config/microblaze/microblaze.c (get_branch_target): New. (insert_wic_for_ilb_runout): New. (insert_wic): New. (microblaze_machine_dependent_reorg): New. (TARGET_MACHINE_DEPENDENT_REORG): Define macro. * config/microblaze/microblaze.md (UNSPEC_IPREFETCH): Define. (iprefetch): New pattern * config/microblaze/microblaze.opt (mxl-prefetch): New flag. Signed-off-by:Ajit Agarwal ajit...@xilinx.com. --- gcc/config/microblaze/microblaze.c | 139 ++++++++++++++++++++++++++++++++++ gcc/config/microblaze/microblaze.md | 14 ++++ gcc/config/microblaze/microblaze.opt | 4 + 3 files changed, 157 insertions(+), 0 deletions(-) diff --git a/gcc/config/microblaze/microblaze.c b/gcc/config/microblaze/microblaze.c index 566b78c..eea2f67 100644 --- a/gcc/config/microblaze/microblaze.c +++ b/gcc/config/microblaze/microblaze.c @@ -71,6 +71,7 @@ #include "cgraph.h" #include "builtins.h" #include "rtl-iter.h" +#include "cfgloop.h" #define MICROBLAZE_VERSION_COMPARE(VA,VB) strcasecmp (VA, VB) @@ -3593,6 +3594,141 @@ microblaze_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x) return true; } +static rtx +get_branch_target (rtx branch) +{ + if (CALL_P (branch)) + { + rtx call; + + call = XVECEXP (PATTERN (branch), 0, 0); + if (GET_CODE (call) == SET) + call = SET_SRC (call); + if (GET_CODE (call) != CALL) + abort (); + return XEXP (XEXP (call, 0), 0); + } +} + +/* Heuristics to identify where to insert at the + fall through path of the caller function. If there + is a call after the caller branch delay slot then + we dont generate the instruction prefetch instruction. */ + +static void +insert_wic_for_ilb_runout (rtx_insn *first) +{ + rtx_insn *insn, *before_4 = 0, *before_16 = 0; + int addr = 0, length, first_addr = -1; + int wic_addr0 = 128 * 4, wic_addr1 = 128 * 4; + int insert_lnop_after = 0; + + for (insn = first; insn; insn = NEXT_INSN (insn)) + if (INSN_P (insn)) + { + if (first_addr == -1) + first_addr = INSN_ADDRESSES (INSN_UID (insn)); + + addr = INSN_ADDRESSES (INSN_UID (insn)) - first_addr; + length = get_attr_length (insn); + + if (before_4 == 0 && addr + length >= 4 * 4) + before_4 = insn; + + if (JUMP_P(insn)) + return; + if (before_16 == 0 && addr + length >= 14 * 4) + before_16 = insn; + if (CALL_P (insn) || tablejump_p (insn, 0, 0)) + return; + if (addr + length >= 32 * 4) + { + gcc_assert (before_4 && before_16); + if (wic_addr0 > 4 * 4) + { + insn = + emit_insn_before (gen_iprefetch + (gen_int_mode (addr, SImode)), + before_4); + recog_memoized (insn); + INSN_LOCATION (insn) = INSN_LOCATION (before_4); + INSN_ADDRESSES_NEW (insn, INSN_ADDRESSES (INSN_UID (before_4))); + return; + } + } + } +} + +/* Insert instruction prefetch instruction at the fall + through path of the function call. */ + +static void +insert_wic (void) +{ + rtx_insn *insn; + int i, j; + basic_block bb,prev = 0; + rtx branch_target = 0; + + shorten_branches (get_insns ()); + + for (i = 0; i < n_basic_blocks_for_fn (cfun) - 1; i++) + { + edge e; + edge_iterator ei; + bool simple_loop = false; + + bb = BASIC_BLOCK_FOR_FN (cfun, i); + + if (bb == NULL) + continue; + + if ((prev != 0) && (prev != bb)) + continue; + else + prev = 0; + + FOR_EACH_EDGE (e, ei, bb->preds) + if (e->src == bb) + { + simple_loop = true; + prev= e->dest; + break; + } + + for (insn = BB_END (bb); insn; insn = PREV_INSN (insn)) + { + if (INSN_P (insn) && !simple_loop + && CALL_P(insn)) + { + if ((branch_target = get_branch_target (insn))) + insert_wic_for_ilb_runout ( + next_active_insn (next_active_insn (insn))); + } + if (insn == BB_HEAD (bb)) + break; + } + } +} + +/* The reorg function defined through the macro + TARGET_MACHINE_DEPENDENT_REORG. */ + +static void +microblaze_machine_dependent_reorg (void) +{ + if (TARGET_PREFETCH) + { + compute_bb_for_insn (); + loop_optimizer_init (AVOID_CFG_MODIFICATIONS); + shorten_branches (get_insns ()); + insert_wic (); + loop_optimizer_finalize(); + free_bb_for_insn (); + return; + } +} + #undef TARGET_ENCODE_SECTION_INFO #define TARGET_ENCODE_SECTION_INFO microblaze_encode_section_info @@ -3685,6 +3821,9 @@ microblaze_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x) #undef TARGET_LEGITIMATE_CONSTANT_P #define TARGET_LEGITIMATE_CONSTANT_P microblaze_legitimate_constant_p +#undef TARGET_MACHINE_DEPENDENT_REORG +#define TARGET_MACHINE_DEPENDENT_REORG microblaze_machine_dependent_reorg + struct gcc_target targetm = TARGET_INITIALIZER; #include "gt-microblaze.h" diff --git a/gcc/config/microblaze/microblaze.md b/gcc/config/microblaze/microblaze.md index 67e509c..0365748 100644 --- a/gcc/config/microblaze/microblaze.md +++ b/gcc/config/microblaze/microblaze.md @@ -43,6 +43,9 @@ (UNSPEC_TLS 106) ;; jump table ]) +(define_c_enum "unspec" [ + UNSPEC_IPREFETCH +]) ;;---------------------------------------------------- ;; Instruction Attributes @@ -508,6 +511,17 @@ (set_attr "mode" "SI") (set_attr "length" "4,8")]) +(define_insn "iprefetch" + [(unspec [(match_operand:SI 0 "const_int_operand" "n")] UNSPEC_IPREFETCH) + (clobber (mem:BLK (scratch)))] + "TARGET_PREFETCH" + { + operands[2] = gen_rtx_REG (SImode, MB_ABI_ASM_TEMP_REGNUM); + return "mfs\t%2,rpc\n\twic\t%2,r0"; + } + [(set_attr "type" "arith") + (set_attr "mode" "SI") + (set_attr "length" "8")]) ;;---------------------------------------------------------------- ;; Double Precision Subtraction diff --git a/gcc/config/microblaze/microblaze.opt b/gcc/config/microblaze/microblaze.opt index a1447a5..10478d2 100644 --- a/gcc/config/microblaze/microblaze.opt +++ b/gcc/config/microblaze/microblaze.opt @@ -123,5 +123,9 @@ mxl-mode-novectors Target Mask(XL_MODE_NOVECTORS) Description for mxl-mode-novectors +mxl-prefetch +Target Mask(PREFETCH) +Use hardware prefetch instruction + mxl-mode-xilkernel Target -- 1.7.1 Thanks & Regards Ajit
0001-Patch-microblaze-Optimized-Instruction-prefetch-with.patch
Description: 0001-Patch-microblaze-Optimized-Instruction-prefetch-with.patch