From: Ajit Agarwal Date: Thu, 21 Jan 2016 17:15:52 +0000 (+0000) Subject: Issue wic prefetch instruction at call site. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=b638c908a7f43892dfe69f58d83cff2ca0a5872b;p=gcc.git Issue wic prefetch instruction at call site. This optimization is enabled with microblaze target flag mxl-prefetch. From-SVN: r232683 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a275bfd6898..c72db017bae 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,17 @@ +2016-01-21 Ajit Agarwal + + * 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. + 2016-01-21 Ajit Agarwal * config/microblaze/microblaze.h diff --git a/gcc/config/microblaze/microblaze.c b/gcc/config/microblaze/microblaze.c index 4e778e7d762..baff67a89c9 100644 --- a/gcc/config/microblaze/microblaze.c +++ b/gcc/config/microblaze/microblaze.c @@ -43,6 +43,9 @@ #include "output.h" #include "builtins.h" #include "rtl-iter.h" +#include "cfgloop.h" +#include "insn-addr.h" +#include "cfgrtl.h" /* This file should be included last. */ #include "target-def.h" @@ -3607,6 +3610,151 @@ 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. + + Scan up to 32 instructions after the call and checks + for the JUMP and call instruction . If there is a call + or JUMP instruction in the range of 32 instruction "wic" + instruction wont be generated. Otherwise insert the "wic" + instruction in the fall through of the call instruction + four instruction after the call. before_4 is used for + the position to insert "wic" instructions. before_16 is + used to check for call and JUMP instruction for first + 15 insns. */ + +static void +insert_wic_for_ilb_runout (rtx_insn *first) +{ + rtx_insn *insn; + rtx_insn *before_4 = 0; + rtx_insn *before_16 = 0; + int addr_offset = 0; + int length; + int wic_addr0 = 128 * 4; + int wic_addr1 = 128 * 4; + + int first_addr = INSN_ADDRESSES (INSN_UID (first)); + + for (insn = first; insn; insn = NEXT_INSN (insn)) + if (INSN_P (insn)) + { + addr_offset = INSN_ADDRESSES (INSN_UID (insn)) - first_addr; + length = get_attr_length (insn); + if (before_4 == 0 && addr_offset + length >= 4 * 4) + before_4 = insn; + + if (JUMP_P(insn)) + return; + if (before_16 == 0 && addr_offset + length >= 14 * 4) + before_16 = insn; + if (CALL_P (insn) || tablejump_p (insn, 0, 0)) + return; + if (addr_offset + length >= 32 * 4) + { + gcc_assert (before_4 && before_16); + if (wic_addr0 > 4 * 4) + { + insn = + emit_insn_before (gen_iprefetch + (gen_int_mode (addr_offset, 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 @@ -3699,6 +3847,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 287c5c97a99..85776237c1a 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 039ae96c850..51734b4ed8f 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