Issue wic prefetch instruction at call site.

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

From-SVN: r232683
This commit is contained in:
Ajit Agarwal 2016-01-21 17:15:52 +00:00 committed by Michael Eager
parent 128c78a6fb
commit b638c908a7
4 changed files with 183 additions and 0 deletions

View File

@ -1,3 +1,17 @@
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

View File

@ -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"

View File

@ -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

View File

@ -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