Commit b638c908 by Ajit Agarwal Committed by Michael Eager

Issue wic prefetch instruction at call site.

This optimization is enabled with  microblaze target flag mxl-prefetch.

From-SVN: r232683
parent 128c78a6
2016-01-21 Ajit Agarwal <ajitkum@xilinx.com> 2016-01-21 Ajit Agarwal <ajitkum@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.
2016-01-21 Ajit Agarwal <ajitkum@xilinx.com>
* config/microblaze/microblaze.h * config/microblaze/microblaze.h
(FIXED_REGISTERS): Update in macro. (FIXED_REGISTERS): Update in macro.
(CALL_USED_REGISTERS): Update in macro. (CALL_USED_REGISTERS): Update in macro.
......
...@@ -43,6 +43,9 @@ ...@@ -43,6 +43,9 @@
#include "output.h" #include "output.h"
#include "builtins.h" #include "builtins.h"
#include "rtl-iter.h" #include "rtl-iter.h"
#include "cfgloop.h"
#include "insn-addr.h"
#include "cfgrtl.h"
/* This file should be included last. */ /* This file should be included last. */
#include "target-def.h" #include "target-def.h"
...@@ -3607,6 +3610,151 @@ microblaze_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x) ...@@ -3607,6 +3610,151 @@ microblaze_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
return true; 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 #undef TARGET_ENCODE_SECTION_INFO
#define TARGET_ENCODE_SECTION_INFO microblaze_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) ...@@ -3699,6 +3847,9 @@ microblaze_legitimate_constant_p (machine_mode mode ATTRIBUTE_UNUSED, rtx x)
#undef TARGET_LEGITIMATE_CONSTANT_P #undef TARGET_LEGITIMATE_CONSTANT_P
#define TARGET_LEGITIMATE_CONSTANT_P microblaze_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; struct gcc_target targetm = TARGET_INITIALIZER;
#include "gt-microblaze.h" #include "gt-microblaze.h"
...@@ -43,6 +43,9 @@ ...@@ -43,6 +43,9 @@
(UNSPEC_TLS 106) ;; jump table (UNSPEC_TLS 106) ;; jump table
]) ])
(define_c_enum "unspec" [
UNSPEC_IPREFETCH
])
;;---------------------------------------------------- ;;----------------------------------------------------
;; Instruction Attributes ;; Instruction Attributes
...@@ -508,6 +511,17 @@ ...@@ -508,6 +511,17 @@
(set_attr "mode" "SI") (set_attr "mode" "SI")
(set_attr "length" "4,8")]) (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 ;; Double Precision Subtraction
......
...@@ -123,5 +123,9 @@ mxl-mode-novectors ...@@ -123,5 +123,9 @@ mxl-mode-novectors
Target Mask(XL_MODE_NOVECTORS) Target Mask(XL_MODE_NOVECTORS)
Description for mxl-mode-novectors. Description for mxl-mode-novectors.
mxl-prefetch
Target Mask(PREFETCH)
Use hardware prefetch instruction
mxl-mode-xilkernel mxl-mode-xilkernel
Target Target
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment