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:
parent
128c78a6fb
commit
b638c908a7
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue