target.def (can_use_doloop_p): New hook.
gcc/ * target.def (can_use_doloop_p): New hook. * doc/tm.texi.in (TARGET_CAN_USE_DOLOOP_P): Add. * doc/tm.texi: Regenerate. * doc/md.texi (doloop_begin, doloop_end): Update documentation. * hooks.h (hook_bool_dint_dint_uint_true): Declare. * hooks.c (hook_bool_dint_dint_uint_true): New function. * targhooks.h (can_use_doloop_if_innermost): Declare. * targhooks.c (can_use_doloop_if_innermost): New function. * target.h: Include double-int.h. * loop-doloop.c (doloop_optimize): Call targetm.can_use_doloop_p. Remove iteration count, maximum iteration count, loop depth and enter-at-top inputs from doloop_begin and doloop_end. * config/arc/arc.md (doloop_begin, doloop_end): Update for new interface. * config/arc/arc.c (arc_can_use_doloop_p): New function. (TARGET_CAN_USE_DOLOOP_P): Define. * config/arm/thumb2.md (doloop_end): Update for new interface. * config/arm/arm.c (TARGET_CAN_USE_DOLOOP_P): Define. * config/bfin/bfin.md (doloop_end): Update for new interface. * config/bfin/bfin.c (bfin_can_use_doloop_p): New function. (TARGET_CAN_USE_DOLOOP_P): Define. * config/c6x/c6x.md (doloop_end): Update for new interface. * config/ia64/ia64.md (doloop_end): Update for new interface. * config/ia64/ia64.c (TARGET_CAN_USE_DOLOOP_P): Define. * config/mep/mep.md (doloop_begin, doloop_end): Update for new interface. * config/mep/mep.c (mep_emit_doloop): Likewise. (TARGET_CAN_USE_DOLOOP_P): Define. * config/rs6000/rs6000.md (doloop_end): Update for new interface. * config/rs6000/rs6000.c (TARGET_CAN_USE_DOLOOP_P): Define. * config/s390/s390.md (doloop_end): Update for new interface. * config/sh/sh.md (doloop_end): Likewise. * config/spu/spu.md (doloop_end): Likewise. * config/spu/spu.c (TARGET_CAN_USE_DOLOOP_P): Define. * config/tilegx/tilegx.md (doloop_end): Update for new interface. * config/tilegx/tilegx.c (TARGET_CAN_USE_DOLOOP_P): Define. * config/tilepro/tilepro.md (doloop_end): Update for new interface. * config/tilepro/tilepro.c (TARGET_CAN_USE_DOLOOP_P): Define. * config/v850/v850.md (doloop_begin, doloop_end): Update for new interface. * config/v850/v850.c (TARGET_CAN_USE_DOLOOP_P): Define. From-SVN: r204614
This commit is contained in:
parent
12929715b1
commit
1d0216c8b7
@ -1,3 +1,47 @@
|
||||
2013-11-09 Richard Sandiford <rdsandiford@googlemail.com>
|
||||
|
||||
* target.def (can_use_doloop_p): New hook.
|
||||
* doc/tm.texi.in (TARGET_CAN_USE_DOLOOP_P): Add.
|
||||
* doc/tm.texi: Regenerate.
|
||||
* doc/md.texi (doloop_begin, doloop_end): Update documentation.
|
||||
* hooks.h (hook_bool_dint_dint_uint_true): Declare.
|
||||
* hooks.c (hook_bool_dint_dint_uint_true): New function.
|
||||
* targhooks.h (can_use_doloop_if_innermost): Declare.
|
||||
* targhooks.c (can_use_doloop_if_innermost): New function.
|
||||
* target.h: Include double-int.h.
|
||||
* loop-doloop.c (doloop_optimize): Call targetm.can_use_doloop_p.
|
||||
Remove iteration count, maximum iteration count, loop depth and
|
||||
enter-at-top inputs from doloop_begin and doloop_end.
|
||||
* config/arc/arc.md (doloop_begin, doloop_end): Update for new
|
||||
interface.
|
||||
* config/arc/arc.c (arc_can_use_doloop_p): New function.
|
||||
(TARGET_CAN_USE_DOLOOP_P): Define.
|
||||
* config/arm/thumb2.md (doloop_end): Update for new interface.
|
||||
* config/arm/arm.c (TARGET_CAN_USE_DOLOOP_P): Define.
|
||||
* config/bfin/bfin.md (doloop_end): Update for new interface.
|
||||
* config/bfin/bfin.c (bfin_can_use_doloop_p): New function.
|
||||
(TARGET_CAN_USE_DOLOOP_P): Define.
|
||||
* config/c6x/c6x.md (doloop_end): Update for new interface.
|
||||
* config/ia64/ia64.md (doloop_end): Update for new interface.
|
||||
* config/ia64/ia64.c (TARGET_CAN_USE_DOLOOP_P): Define.
|
||||
* config/mep/mep.md (doloop_begin, doloop_end): Update for new
|
||||
interface.
|
||||
* config/mep/mep.c (mep_emit_doloop): Likewise.
|
||||
(TARGET_CAN_USE_DOLOOP_P): Define.
|
||||
* config/rs6000/rs6000.md (doloop_end): Update for new interface.
|
||||
* config/rs6000/rs6000.c (TARGET_CAN_USE_DOLOOP_P): Define.
|
||||
* config/s390/s390.md (doloop_end): Update for new interface.
|
||||
* config/sh/sh.md (doloop_end): Likewise.
|
||||
* config/spu/spu.md (doloop_end): Likewise.
|
||||
* config/spu/spu.c (TARGET_CAN_USE_DOLOOP_P): Define.
|
||||
* config/tilegx/tilegx.md (doloop_end): Update for new interface.
|
||||
* config/tilegx/tilegx.c (TARGET_CAN_USE_DOLOOP_P): Define.
|
||||
* config/tilepro/tilepro.md (doloop_end): Update for new interface.
|
||||
* config/tilepro/tilepro.c (TARGET_CAN_USE_DOLOOP_P): Define.
|
||||
* config/v850/v850.md (doloop_begin, doloop_end): Update for new
|
||||
interface.
|
||||
* config/v850/v850.c (TARGET_CAN_USE_DOLOOP_P): Define.
|
||||
|
||||
2013-11-08 H.J. Lu <hongjiu.lu@intel.com>
|
||||
|
||||
PR other/59055
|
||||
|
@ -388,6 +388,7 @@ static bool arc_return_in_memory (const_tree, const_tree);
|
||||
static void arc_init_simd_builtins (void);
|
||||
static bool arc_vector_mode_supported_p (enum machine_mode);
|
||||
|
||||
static bool arc_can_use_doloop_p (double_int, double_int, unsigned int, bool);
|
||||
static const char *arc_invalid_within_doloop (const_rtx);
|
||||
|
||||
static void output_short_suffix (FILE *file);
|
||||
@ -493,6 +494,9 @@ static void arc_finalize_pic (void);
|
||||
#undef TARGET_VECTOR_MODE_SUPPORTED_P
|
||||
#define TARGET_VECTOR_MODE_SUPPORTED_P arc_vector_mode_supported_p
|
||||
|
||||
#undef TARGET_CAN_USE_DOLOOP_P
|
||||
#define TARGET_CAN_USE_DOLOOP_P arc_can_use_doloop_p
|
||||
|
||||
#undef TARGET_INVALID_WITHIN_DOLOOP
|
||||
#define TARGET_INVALID_WITHIN_DOLOOP arc_invalid_within_doloop
|
||||
|
||||
@ -5638,6 +5642,23 @@ arc_pass_by_reference (cumulative_args_t ca_v ATTRIBUTE_UNUSED,
|
||||
|| TREE_ADDRESSABLE (type)));
|
||||
}
|
||||
|
||||
/* Implement TARGET_CAN_USE_DOLOOP_P. */
|
||||
|
||||
static bool
|
||||
arc_can_use_doloop_p (double_int iterations, double_int,
|
||||
unsigned int loop_depth, bool entered_at_top)
|
||||
{
|
||||
if (loop_depth > 1)
|
||||
return false;
|
||||
/* Setting up the loop with two sr instructions costs 6 cycles. */
|
||||
if (TARGET_ARC700
|
||||
&& !entered_at_top
|
||||
&& iterations.high == 0
|
||||
&& iterations.low > 0
|
||||
&& iterations.low <= (flag_pic ? 6 : 3))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* NULL if INSN insn is valid within a low-overhead loop.
|
||||
Otherwise return why doloop cannot be applied. */
|
||||
|
@ -4706,16 +4706,10 @@
|
||||
})
|
||||
|
||||
; operand 0 is the loop count pseudo register
|
||||
; operand 1 is the number of loop iterations or 0 if it is unknown
|
||||
; operand 2 is the maximum number of loop iterations
|
||||
; operand 3 is the number of levels of enclosed loops
|
||||
; operand 4 is the loop end pattern
|
||||
; operand 1 is the loop end pattern
|
||||
(define_expand "doloop_begin"
|
||||
[(use (match_operand 0 "register_operand" ""))
|
||||
(use (match_operand:QI 1 "const_int_operand" ""))
|
||||
(use (match_operand:QI 2 "const_int_operand" ""))
|
||||
(use (match_operand:QI 3 "const_int_operand" ""))
|
||||
(use (match_operand 4 "" ""))]
|
||||
(use (match_operand 1 "" ""))]
|
||||
""
|
||||
{
|
||||
/* Using the INSN_UID of the loop end pattern to identify it causes
|
||||
@ -4725,10 +4719,8 @@
|
||||
still be able to tell what kind of number this is. */
|
||||
static HOST_WIDE_INT loop_end_id = 0;
|
||||
|
||||
if (INTVAL (operands[3]) > 1)
|
||||
FAIL;
|
||||
rtx id = GEN_INT (--loop_end_id);
|
||||
XEXP (XVECEXP (PATTERN (operands[4]), 0, 4), 0) = id;
|
||||
XEXP (XVECEXP (PATTERN (operands[1]), 0, 4), 0) = id;
|
||||
emit_insn (gen_doloop_begin_i (operands[0], const0_rtx, id,
|
||||
const0_rtx, const0_rtx));
|
||||
DONE;
|
||||
@ -4907,11 +4899,7 @@
|
||||
)
|
||||
|
||||
; operand 0 is the loop count pseudo register
|
||||
; operand 1 is the number of loop iterations or 0 if it is unknown
|
||||
; operand 2 is the maximum number of loop iterations
|
||||
; operand 3 is the number of levels of enclosed loops
|
||||
; operand 4 is the label to jump to at the top of the loop
|
||||
; operand 5 is nonzero if the loop is entered at its top.
|
||||
; operand 1 is the label to jump to at the top of the loop
|
||||
; Use this for the ARC600 and ARC700. For ARCtangent-A5, this is unsafe
|
||||
; without further checking for nearby branches etc., and without proper
|
||||
; annotation of shift patterns that clobber lp_count
|
||||
@ -4919,24 +4907,14 @@
|
||||
; single insn - loop setup is expensive then.
|
||||
(define_expand "doloop_end"
|
||||
[(use (match_operand 0 "register_operand" ""))
|
||||
(use (match_operand:QI 1 "const_int_operand" ""))
|
||||
(use (match_operand:QI 2 "const_int_operand" ""))
|
||||
(use (match_operand:QI 3 "const_int_operand" ""))
|
||||
(use (label_ref (match_operand 4 "" "")))
|
||||
(use (match_operand:QI 5 "const_int_operand" ""))]
|
||||
(use (label_ref (match_operand 1 "" "")))]
|
||||
"TARGET_ARC600 || TARGET_ARC700"
|
||||
{
|
||||
if (INTVAL (operands[3]) > 1)
|
||||
FAIL;
|
||||
/* Setting up the loop with two sr isntructions costs 6 cycles. */
|
||||
if (TARGET_ARC700 && !INTVAL (operands[5])
|
||||
&& INTVAL (operands[1]) && INTVAL (operands[1]) <= (flag_pic ? 6 : 3))
|
||||
FAIL;
|
||||
/* We could do smaller bivs with biv widening, and wider bivs by having
|
||||
a high-word counter in an outer loop - but punt on this for now. */
|
||||
if (GET_MODE (operands[0]) != SImode)
|
||||
FAIL;
|
||||
emit_jump_insn (gen_doloop_end_i (operands[0], operands[4], const0_rtx));
|
||||
emit_jump_insn (gen_doloop_end_i (operands[0], operands[1], const0_rtx));
|
||||
DONE;
|
||||
})
|
||||
|
||||
|
@ -667,6 +667,8 @@ static const struct attribute_spec arm_attribute_table[] =
|
||||
#undef MAX_INSN_PER_IT_BLOCK
|
||||
#define MAX_INSN_PER_IT_BLOCK (arm_restrict_it ? 1 : 4)
|
||||
|
||||
#undef TARGET_CAN_USE_DOLOOP_P
|
||||
#define TARGET_CAN_USE_DOLOOP_P can_use_doloop_if_innermost
|
||||
|
||||
struct gcc_target targetm = TARGET_INITIALIZER;
|
||||
|
||||
|
@ -1449,11 +1449,7 @@
|
||||
;; knows what to generate.
|
||||
(define_expand "doloop_end"
|
||||
[(use (match_operand 0 "" "")) ; loop pseudo
|
||||
(use (match_operand 1 "" "")) ; iterations; zero if unknown
|
||||
(use (match_operand 2 "" "")) ; max iterations
|
||||
(use (match_operand 3 "" "")) ; loop level
|
||||
(use (match_operand 4 "" "")) ; label
|
||||
(use (match_operand 5 "" ""))] ; flag: 1 if loop entered at top, else 0
|
||||
(use (match_operand 1 "" ""))] ; label
|
||||
"TARGET_32BIT"
|
||||
"
|
||||
{
|
||||
@ -1472,10 +1468,6 @@
|
||||
rtx insn;
|
||||
rtx cmp;
|
||||
|
||||
/* Only use this on innermost loops. */
|
||||
if (INTVAL (operands[3]) > 1)
|
||||
FAIL;
|
||||
|
||||
if (GET_MODE (operands[0]) != SImode)
|
||||
FAIL;
|
||||
|
||||
@ -1488,7 +1480,7 @@
|
||||
cmp = XVECEXP (PATTERN (insn), 0, 0);
|
||||
cc_reg = SET_DEST (cmp);
|
||||
bcomp = gen_rtx_NE (VOIDmode, cc_reg, const0_rtx);
|
||||
loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands [4]);
|
||||
loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands [1]);
|
||||
emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
|
||||
gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
|
||||
loc_ref, pc_rtx)));
|
||||
|
@ -3366,6 +3366,22 @@ find_prev_insn_start (rtx insn)
|
||||
return insn;
|
||||
}
|
||||
|
||||
/* Implement TARGET_CAN_USE_DOLOOP_P. */
|
||||
|
||||
static bool
|
||||
bfin_can_use_doloop_p (double_int, double_int iterations_max,
|
||||
unsigned int, bool)
|
||||
{
|
||||
/* Due to limitations in the hardware (an initial loop count of 0
|
||||
does not loop 2^32 times) we must avoid to generate a hardware
|
||||
loops when we cannot rule out this case. */
|
||||
if (!flag_unsafe_loop_optimizations
|
||||
&& (iterations_max.high != 0
|
||||
|| iterations_max.low >= 0xFFFFFFFF))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Increment the counter for the number of loop instructions in the
|
||||
current function. */
|
||||
|
||||
@ -5810,4 +5826,7 @@ bfin_conditional_register_usage (void)
|
||||
#undef TARGET_DELAY_VARTRACK
|
||||
#define TARGET_DELAY_VARTRACK true
|
||||
|
||||
#undef TARGET_CAN_USE_DOLOOP_P
|
||||
#define TARGET_CAN_USE_DOLOOP_P bfin_can_use_doloop_p
|
||||
|
||||
struct gcc_target targetm = TARGET_INITIALIZER;
|
||||
|
@ -1929,35 +1929,25 @@
|
||||
;; Hardware loop
|
||||
|
||||
; operand 0 is the loop count pseudo register
|
||||
; operand 1 is the number of loop iterations or 0 if it is unknown
|
||||
; operand 2 is the maximum number of loop iterations
|
||||
; operand 3 is the number of levels of enclosed loops
|
||||
; operand 4 is the label to jump to at the top of the loop
|
||||
; operand 5 indicates if the loop is entered at the top
|
||||
; operand 1 is the label to jump to at the top of the loop
|
||||
(define_expand "doloop_end"
|
||||
[(parallel [(set (pc) (if_then_else
|
||||
(ne (match_operand:SI 0 "" "")
|
||||
(const_int 1))
|
||||
(label_ref (match_operand 4 "" ""))
|
||||
(label_ref (match_operand 1 "" ""))
|
||||
(pc)))
|
||||
(set (match_dup 0)
|
||||
(plus:SI (match_dup 0)
|
||||
(const_int -1)))
|
||||
(unspec [(const_int 0)] UNSPEC_LSETUP_END)
|
||||
(clobber (match_operand 5 ""))])] ; match_scratch
|
||||
(clobber (match_dup 2))])] ; match_scratch
|
||||
""
|
||||
{
|
||||
/* The loop optimizer doesn't check the predicates... */
|
||||
if (GET_MODE (operands[0]) != SImode)
|
||||
FAIL;
|
||||
/* Due to limitations in the hardware (an initial loop count of 0
|
||||
does not loop 2^32 times) we must avoid to generate a hardware
|
||||
loops when we cannot rule out this case. */
|
||||
if (!flag_unsafe_loop_optimizations
|
||||
&& (unsigned HOST_WIDE_INT) INTVAL (operands[2]) >= 0xFFFFFFFF)
|
||||
FAIL;
|
||||
bfin_hardware_loop ();
|
||||
operands[5] = gen_rtx_SCRATCH (SImode);
|
||||
operands[2] = gen_rtx_SCRATCH (SImode);
|
||||
})
|
||||
|
||||
(define_insn "loop_end"
|
||||
|
@ -1421,27 +1421,23 @@
|
||||
;; -------------------------------------------------------------------------
|
||||
|
||||
; operand 0 is the loop count pseudo register
|
||||
; operand 1 is the number of loop iterations or 0 if it is unknown
|
||||
; operand 2 is the maximum number of loop iterations
|
||||
; operand 3 is the number of levels of enclosed loops
|
||||
; operand 4 is the label to jump to at the top of the loop
|
||||
; operand 5 indicates if the loop is entered at the top
|
||||
; operand 1 is the label to jump to at the top of the loop
|
||||
(define_expand "doloop_end"
|
||||
[(parallel [(set (pc) (if_then_else
|
||||
(ne (match_operand:SI 0 "" "")
|
||||
(const_int 1))
|
||||
(label_ref (match_operand 4 "" ""))
|
||||
(label_ref (match_operand 1 "" ""))
|
||||
(pc)))
|
||||
(set (match_dup 0)
|
||||
(plus:SI (match_dup 0)
|
||||
(const_int -1)))
|
||||
(clobber (match_operand 5 ""))])] ; match_scratch
|
||||
(clobber (match_dup 2))])] ; match_scratch
|
||||
"TARGET_INSNS_64PLUS && optimize"
|
||||
{
|
||||
/* The loop optimizer doesn't check the predicates... */
|
||||
if (GET_MODE (operands[0]) != SImode)
|
||||
FAIL;
|
||||
operands[5] = gen_rtx_SCRATCH (SImode);
|
||||
operands[2] = gen_rtx_SCRATCH (SImode);
|
||||
})
|
||||
|
||||
(define_insn "mvilc"
|
||||
|
@ -620,6 +620,8 @@ static const struct attribute_spec ia64_attribute_table[] =
|
||||
#undef TARGET_TRAMPOLINE_INIT
|
||||
#define TARGET_TRAMPOLINE_INIT ia64_trampoline_init
|
||||
|
||||
#undef TARGET_CAN_USE_DOLOOP_P
|
||||
#define TARGET_CAN_USE_DOLOOP_P can_use_doloop_if_innermost
|
||||
#undef TARGET_INVALID_WITHIN_DOLOOP
|
||||
#define TARGET_INVALID_WITHIN_DOLOOP hook_constcharptr_const_rtx_null
|
||||
|
||||
|
@ -3956,18 +3956,11 @@
|
||||
|
||||
(define_expand "doloop_end"
|
||||
[(use (match_operand 0 "" "")) ; loop pseudo
|
||||
(use (match_operand 1 "" "")) ; iterations; zero if unknown
|
||||
(use (match_operand 2 "" "")) ; max iterations
|
||||
(use (match_operand 3 "" "")) ; loop level
|
||||
(use (match_operand 4 "" "")) ; label
|
||||
(use (match_operand 5 "" ""))] ; flag: 1 if loop entered at top, else 0
|
||||
(use (match_operand 1 "" ""))] ; label
|
||||
""
|
||||
{
|
||||
/* Only use cloop on innermost loops. */
|
||||
if (INTVAL (operands[3]) > 1)
|
||||
FAIL;
|
||||
emit_jump_insn (gen_doloop_end_internal (gen_rtx_REG (DImode, AR_LC_REGNUM),
|
||||
operands[4]));
|
||||
operands[1]));
|
||||
DONE;
|
||||
})
|
||||
|
||||
|
@ -5103,7 +5103,7 @@ mep_emit_doloop (rtx *operands, int is_end)
|
||||
|
||||
tag = GEN_INT (cfun->machine->doloop_tags - 1);
|
||||
if (is_end)
|
||||
emit_jump_insn (gen_doloop_end_internal (operands[0], operands[4], tag));
|
||||
emit_jump_insn (gen_doloop_end_internal (operands[0], operands[1], tag));
|
||||
else
|
||||
emit_insn (gen_doloop_begin_internal (operands[0], operands[0], tag));
|
||||
}
|
||||
@ -7280,6 +7280,8 @@ mep_asm_init_sections (void)
|
||||
#define TARGET_TRAMPOLINE_INIT mep_trampoline_init
|
||||
#undef TARGET_LEGITIMATE_CONSTANT_P
|
||||
#define TARGET_LEGITIMATE_CONSTANT_P mep_legitimate_constant_p
|
||||
#undef TARGET_CAN_USE_DOLOOP_P
|
||||
#define TARGET_CAN_USE_DOLOOP_P can_use_doloop_if_innermost
|
||||
|
||||
struct gcc_target targetm = TARGET_INITIALIZER;
|
||||
|
||||
|
@ -2076,14 +2076,9 @@
|
||||
|
||||
(define_expand "doloop_begin"
|
||||
[(use (match_operand 0 "register_operand" ""))
|
||||
(use (match_operand:QI 1 "const_int_operand" ""))
|
||||
(use (match_operand:QI 2 "const_int_operand" ""))
|
||||
(use (match_operand:QI 3 "const_int_operand" ""))
|
||||
(use (match_operand 4 "" ""))]
|
||||
(use (match_operand 1 "" ""))]
|
||||
"!profile_arc_flag && TARGET_OPT_REPEAT"
|
||||
"if (INTVAL (operands[3]) > 1)
|
||||
FAIL;
|
||||
mep_emit_doloop (operands, 0);
|
||||
"mep_emit_doloop (operands, 0);
|
||||
DONE;
|
||||
")
|
||||
|
||||
@ -2112,15 +2107,9 @@
|
||||
|
||||
(define_expand "doloop_end"
|
||||
[(use (match_operand 0 "nonimmediate_operand" ""))
|
||||
(use (match_operand:QI 1 "const_int_operand" ""))
|
||||
(use (match_operand:QI 2 "const_int_operand" ""))
|
||||
(use (match_operand:QI 3 "const_int_operand" ""))
|
||||
(use (label_ref (match_operand 4 "" "")))
|
||||
(use (match_operand 5 "" ""))]
|
||||
(use (label_ref (match_operand 1 "" "")))]
|
||||
"!profile_arc_flag && TARGET_OPT_REPEAT"
|
||||
"if (INTVAL (operands[3]) > 1)
|
||||
FAIL;
|
||||
if (GET_CODE (operands[0]) == REG && GET_MODE (operands[0]) != SImode)
|
||||
"if (GET_CODE (operands[0]) == REG && GET_MODE (operands[0]) != SImode)
|
||||
FAIL;
|
||||
mep_emit_doloop (operands, 1);
|
||||
DONE;
|
||||
|
@ -1593,6 +1593,9 @@ static const struct attribute_spec rs6000_attribute_table[] =
|
||||
|
||||
#undef TARGET_VECTORIZE_VEC_PERM_CONST_OK
|
||||
#define TARGET_VECTORIZE_VEC_PERM_CONST_OK rs6000_vectorize_vec_perm_const_ok
|
||||
|
||||
#undef TARGET_CAN_USE_DOLOOP_P
|
||||
#define TARGET_CAN_USE_DOLOOP_P can_use_doloop_if_innermost
|
||||
|
||||
|
||||
/* Processor table. */
|
||||
|
@ -14791,28 +14791,21 @@
|
||||
|
||||
(define_expand "doloop_end"
|
||||
[(use (match_operand 0 "" "")) ; loop pseudo
|
||||
(use (match_operand 1 "" "")) ; iterations; zero if unknown
|
||||
(use (match_operand 2 "" "")) ; max iterations
|
||||
(use (match_operand 3 "" "")) ; loop level
|
||||
(use (match_operand 4 "" "")) ; label
|
||||
(use (match_operand 5 "" ""))] ; flag: 1 if loop entered at top, else 0
|
||||
(use (match_operand 1 "" ""))] ; label
|
||||
""
|
||||
"
|
||||
{
|
||||
/* Only use this on innermost loops. */
|
||||
if (INTVAL (operands[3]) > 1)
|
||||
FAIL;
|
||||
if (TARGET_64BIT)
|
||||
{
|
||||
if (GET_MODE (operands[0]) != DImode)
|
||||
FAIL;
|
||||
emit_jump_insn (gen_ctrdi (operands[0], operands[4]));
|
||||
emit_jump_insn (gen_ctrdi (operands[0], operands[1]));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (GET_MODE (operands[0]) != SImode)
|
||||
FAIL;
|
||||
emit_jump_insn (gen_ctrsi (operands[0], operands[4]));
|
||||
emit_jump_insn (gen_ctrsi (operands[0], operands[1]));
|
||||
}
|
||||
DONE;
|
||||
}")
|
||||
|
@ -8412,19 +8412,15 @@
|
||||
|
||||
(define_expand "doloop_end"
|
||||
[(use (match_operand 0 "" "")) ; loop pseudo
|
||||
(use (match_operand 1 "" "")) ; iterations; zero if unknown
|
||||
(use (match_operand 2 "" "")) ; max iterations
|
||||
(use (match_operand 3 "" "")) ; loop level
|
||||
(use (match_operand 4 "" "")) ; label
|
||||
(use (match_operand 5 "" ""))] ; flag: 1 if loop entered at top, else 0
|
||||
(use (match_operand 1 "" ""))] ; label
|
||||
""
|
||||
{
|
||||
if (GET_MODE (operands[0]) == SImode && !TARGET_CPU_ZARCH)
|
||||
emit_jump_insn (gen_doloop_si31 (operands[4], operands[0], operands[0]));
|
||||
emit_jump_insn (gen_doloop_si31 (operands[1], operands[0], operands[0]));
|
||||
else if (GET_MODE (operands[0]) == SImode && TARGET_CPU_ZARCH)
|
||||
emit_jump_insn (gen_doloop_si64 (operands[4], operands[0], operands[0]));
|
||||
emit_jump_insn (gen_doloop_si64 (operands[1], operands[0], operands[0]));
|
||||
else if (GET_MODE (operands[0]) == DImode && TARGET_ZARCH)
|
||||
emit_jump_insn (gen_doloop_di (operands[4], operands[0], operands[0]));
|
||||
emit_jump_insn (gen_doloop_di (operands[1], operands[0], operands[0]));
|
||||
else
|
||||
FAIL;
|
||||
|
||||
|
@ -8776,25 +8776,21 @@ label:
|
||||
})
|
||||
|
||||
; operand 0 is the loop count pseudo register
|
||||
; operand 1 is the number of loop iterations or 0 if it is unknown
|
||||
; operand 2 is the maximum number of loop iterations
|
||||
; operand 3 is the number of levels of enclosed loops
|
||||
; operand 4 is the label to jump to at the top of the loop
|
||||
; operand 1 is the label to jump to at the top of the loop
|
||||
(define_expand "doloop_end"
|
||||
[(parallel [(set (pc)
|
||||
(if_then_else (ne:SI (match_operand:SI 0 "" "")
|
||||
(const_int 1))
|
||||
(label_ref (match_operand 4 "" ""))
|
||||
(label_ref (match_operand 1 "" ""))
|
||||
(pc)))
|
||||
(set (match_dup 0)
|
||||
(plus:SI (match_dup 0) (const_int -1)))
|
||||
(clobber (reg:SI T_REG))])
|
||||
(match_operand 5 "" "")]
|
||||
(clobber (reg:SI T_REG))])]
|
||||
"TARGET_SH2"
|
||||
{
|
||||
if (GET_MODE (operands[0]) != SImode)
|
||||
FAIL;
|
||||
emit_jump_insn (gen_doloop_end_split (operands[0], operands[4], operands[0]));
|
||||
emit_jump_insn (gen_doloop_end_split (operands[0], operands[1], operands[0]));
|
||||
DONE;
|
||||
})
|
||||
|
||||
|
@ -7328,6 +7328,9 @@ static const struct attribute_spec spu_attribute_table[] =
|
||||
#undef TARGET_CANONICALIZE_COMPARISON
|
||||
#define TARGET_CANONICALIZE_COMPARISON spu_canonicalize_comparison
|
||||
|
||||
#undef TARGET_CAN_USE_DOLOOP_P
|
||||
#define TARGET_CAN_USE_DOLOOP_P can_use_doloop_if_innermost
|
||||
|
||||
struct gcc_target targetm = TARGET_INITIALIZER;
|
||||
|
||||
#include "gt-spu.h"
|
||||
|
@ -4487,11 +4487,7 @@ selb\t%0,%4,%0,%3"
|
||||
;; knows what to generate.
|
||||
(define_expand "doloop_end"
|
||||
[(use (match_operand 0 "" "")) ; loop pseudo
|
||||
(use (match_operand 1 "" "")) ; iterations; zero if unknown
|
||||
(use (match_operand 2 "" "")) ; max iterations
|
||||
(use (match_operand 3 "" "")) ; loop level
|
||||
(use (match_operand 4 "" "")) ; label
|
||||
(match_operand 5 "" "")]
|
||||
(use (match_operand 1 "" ""))] ; label
|
||||
""
|
||||
"
|
||||
{
|
||||
@ -4507,16 +4503,13 @@ selb\t%0,%4,%0,%3"
|
||||
rtx bcomp;
|
||||
rtx loc_ref;
|
||||
|
||||
/* Only use this on innermost loops. */
|
||||
if (INTVAL (operands[3]) > 1)
|
||||
FAIL;
|
||||
if (GET_MODE (operands[0]) != SImode)
|
||||
FAIL;
|
||||
|
||||
s0 = operands [0];
|
||||
emit_move_insn (s0, gen_rtx_PLUS (SImode, s0, GEN_INT (-1)));
|
||||
bcomp = gen_rtx_NE(SImode, s0, const0_rtx);
|
||||
loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands [4]);
|
||||
loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands [1]);
|
||||
emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
|
||||
gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
|
||||
loc_ref, pc_rtx)));
|
||||
|
@ -5578,6 +5578,8 @@ tilegx_file_end (void)
|
||||
#undef TARGET_ASM_ALIGNED_DI_OP
|
||||
#define TARGET_ASM_ALIGNED_DI_OP "\t.quad\t"
|
||||
|
||||
#undef TARGET_CAN_USE_DOLOOP_P
|
||||
#define TARGET_CAN_USE_DOLOOP_P can_use_doloop_if_innermost
|
||||
|
||||
struct gcc_target targetm = TARGET_INITIALIZER;
|
||||
|
||||
|
@ -2414,11 +2414,7 @@
|
||||
;; generate.
|
||||
(define_expand "doloop_end"
|
||||
[(use (match_operand 0 "" "")) ;; loop pseudo
|
||||
(use (match_operand 1 "" "")) ;; iterations; zero if unknown
|
||||
(use (match_operand 2 "" "")) ;; max iterations
|
||||
(use (match_operand 3 "" "")) ;; loop level
|
||||
(use (match_operand 4 "" "")) ;; label
|
||||
(use (match_operand 5 "" ""))] ;; flag: 1 if loop entered at top, else 0
|
||||
(use (match_operand 1 "" ""))] ;; label
|
||||
""
|
||||
{
|
||||
if (optimize > 0 && flag_modulo_sched)
|
||||
@ -2428,9 +2424,6 @@
|
||||
rtx loc_ref;
|
||||
enum machine_mode mode = GET_MODE (operands[0]);
|
||||
|
||||
/* only do inner loop */
|
||||
if (INTVAL (operands[3]) > 1)
|
||||
FAIL;
|
||||
/* only deal with loop counters in SImode or DImode */
|
||||
if (mode != SImode && mode != DImode)
|
||||
FAIL;
|
||||
@ -2438,7 +2431,7 @@
|
||||
s0 = operands [0];
|
||||
emit_move_insn (s0, gen_rtx_PLUS (mode, s0, GEN_INT (-1)));
|
||||
bcomp = gen_rtx_NE(mode, s0, const0_rtx);
|
||||
loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands [4]);
|
||||
loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands [1]);
|
||||
emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
|
||||
gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
|
||||
loc_ref, pc_rtx)));
|
||||
|
@ -5067,6 +5067,8 @@ tilepro_file_end (void)
|
||||
#undef TARGET_ASM_FILE_END
|
||||
#define TARGET_ASM_FILE_END tilepro_file_end
|
||||
|
||||
#undef TARGET_CAN_USE_DOLOOP_P
|
||||
#define TARGET_CAN_USE_DOLOOP_P can_use_doloop_if_innermost
|
||||
|
||||
struct gcc_target targetm = TARGET_INITIALIZER;
|
||||
|
||||
|
@ -1318,11 +1318,7 @@
|
||||
;; generate.
|
||||
(define_expand "doloop_end"
|
||||
[(use (match_operand 0 "" "")) ;; loop pseudo
|
||||
(use (match_operand 1 "" "")) ;; iterations; zero if unknown
|
||||
(use (match_operand 2 "" "")) ;; max iterations
|
||||
(use (match_operand 3 "" "")) ;; loop level
|
||||
(use (match_operand 4 "" "")) ;; label
|
||||
(use (match_operand 5 "" ""))] ;; flag: 1 if loop entered at top, else 0
|
||||
(use (match_operand 1 "" ""))] ;; label
|
||||
""
|
||||
{
|
||||
if (optimize > 0)
|
||||
@ -1331,9 +1327,6 @@
|
||||
rtx bcomp;
|
||||
rtx loc_ref;
|
||||
|
||||
/* only do inner loop */
|
||||
if (INTVAL (operands[3]) > 1)
|
||||
FAIL;
|
||||
/* only deal with loop counters in SImode */
|
||||
if (GET_MODE (operands[0]) != SImode)
|
||||
FAIL;
|
||||
@ -1342,7 +1335,7 @@
|
||||
|
||||
emit_move_insn (s0, gen_rtx_PLUS (SImode, s0, GEN_INT (-1)));
|
||||
bcomp = gen_rtx_NE(SImode, s0, const0_rtx);
|
||||
loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands [4]);
|
||||
loc_ref = gen_rtx_LABEL_REF (VOIDmode, operands [1]);
|
||||
emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx,
|
||||
gen_rtx_IF_THEN_ELSE (VOIDmode, bcomp,
|
||||
loc_ref, pc_rtx)));
|
||||
|
@ -3269,6 +3269,9 @@ v850_gen_movdi (rtx * operands)
|
||||
#undef TARGET_LEGITIMATE_CONSTANT_P
|
||||
#define TARGET_LEGITIMATE_CONSTANT_P v850_legitimate_constant_p
|
||||
|
||||
#undef TARGET_CAN_USE_DOLOOP_P
|
||||
#define TARGET_CAN_USE_DOLOOP_P can_use_doloop_if_innermost
|
||||
|
||||
struct gcc_target targetm = TARGET_INITIALIZER;
|
||||
|
||||
#include "gt-v850.h"
|
||||
|
@ -1357,20 +1357,11 @@
|
||||
|
||||
(define_expand "doloop_begin"
|
||||
[(use (match_operand 0 "" "")) ; loop pseudo
|
||||
(use (match_operand 1 "" "")) ; iterations; zero if unknown
|
||||
(use (match_operand 2 "" "")) ; max iterations
|
||||
(use (match_operand 3 "" "")) ; loop level
|
||||
(use (match_operand 4 "" ""))] ; condition
|
||||
(use (match_operand 1 "" ""))] ; doloop_end pattern
|
||||
"TARGET_V850E3V5_UP && TARGET_LOOP"
|
||||
{
|
||||
rtx loop_cnt = operands[0];
|
||||
rtx loop_level = operands[3];
|
||||
|
||||
if (INTVAL (loop_level) > 1)
|
||||
FAIL;
|
||||
if (GET_MODE (loop_cnt) != SImode)
|
||||
FAIL;
|
||||
|
||||
rtx loop_cnt = operands[0];
|
||||
gcc_assert (GET_MODE (loop_cnt) == SImode);
|
||||
emit_insn (gen_fix_loop_counter (loop_cnt));
|
||||
DONE;
|
||||
}
|
||||
@ -1394,19 +1385,12 @@
|
||||
|
||||
(define_expand "doloop_end"
|
||||
[(use (match_operand 0 "" "")) ; loop pseudo
|
||||
(use (match_operand 1 "" "")) ; iterations; zero if unknown
|
||||
(use (match_operand 2 "" "")) ; max iterations
|
||||
(use (match_operand 3 "" "")) ; loop level
|
||||
(use (match_operand 4 "" "")) ; label
|
||||
(use (match_operand 5 "" ""))] ; entered at top
|
||||
(use (match_operand 1 "" ""))] ; label
|
||||
"TARGET_V850E3V5_UP && TARGET_LOOP"
|
||||
{
|
||||
rtx loop_cnt = operands[0];
|
||||
rtx loop_level = operands[3];
|
||||
rtx label = operands[4];
|
||||
rtx loop_cnt = operands[0];
|
||||
rtx label = operands[1];
|
||||
|
||||
if (INTVAL (loop_level) > 1)
|
||||
FAIL;
|
||||
if (GET_MODE (loop_cnt) != SImode)
|
||||
FAIL;
|
||||
|
||||
|
@ -5857,34 +5857,27 @@ reduction is enabled.
|
||||
|
||||
@cindex @code{doloop_end} instruction pattern
|
||||
@item @samp{doloop_end}
|
||||
Conditional branch instruction that decrements a register and jumps if
|
||||
the register is nonzero. This instruction takes five operands: Operand
|
||||
0 is the register to decrement and test; operand 1 is the number of loop
|
||||
iterations as a @code{const_int} or @code{const0_rtx} if this cannot be
|
||||
determined until run-time; operand 2 is the actual or estimated maximum
|
||||
number of iterations as a @code{const_int}; operand 3 is the number of
|
||||
enclosed loops as a @code{const_int} (an innermost loop has a value of
|
||||
1); operand 4 is the label to jump to if the register is nonzero;
|
||||
operand 5 is const1_rtx if the loop in entered at its top, const0_rtx
|
||||
otherwise.
|
||||
Conditional branch instruction that decrements a register and
|
||||
jumps if the register is nonzero. Operand 0 is the register to
|
||||
decrement and test; operand 1 is the label to jump to if the
|
||||
register is nonzero.
|
||||
@xref{Looping Patterns}.
|
||||
|
||||
This optional instruction pattern should be defined for machines with
|
||||
low-overhead looping instructions as the loop optimizer will try to
|
||||
modify suitable loops to utilize it. If nested low-overhead looping is
|
||||
not supported, use a @code{define_expand} (@pxref{Expander Definitions})
|
||||
and make the pattern fail if operand 3 is not @code{const1_rtx}.
|
||||
Similarly, if the actual or estimated maximum number of iterations is
|
||||
too large for this instruction, make it fail.
|
||||
modify suitable loops to utilize it. The target hook
|
||||
@code{TARGET_CAN_USE_DOLOOP_P} controls the conditions under which
|
||||
low-overhead loops can be used.
|
||||
|
||||
@cindex @code{doloop_begin} instruction pattern
|
||||
@item @samp{doloop_begin}
|
||||
Companion instruction to @code{doloop_end} required for machines that
|
||||
need to perform some initialization, such as loading special registers
|
||||
used by a low-overhead looping instruction. If initialization insns do
|
||||
not always need to be emitted, use a @code{define_expand}
|
||||
(@pxref{Expander Definitions}) and make it fail.
|
||||
need to perform some initialization, such as loading a special counter
|
||||
register. Operand 1 is the associated @code{doloop_end} pattern and
|
||||
operand 0 is the register that it decrements.
|
||||
|
||||
If initialization insns do not always need to be emitted, use a
|
||||
@code{define_expand} (@pxref{Expander Definitions}) and make it fail.
|
||||
|
||||
@cindex @code{canonicalize_funcptr_for_compare} instruction pattern
|
||||
@item @samp{canonicalize_funcptr_for_compare}
|
||||
|
@ -11091,6 +11091,20 @@ function version at run-time for a given set of function versions.
|
||||
body must be generated.
|
||||
@end deftypefn
|
||||
|
||||
@deftypefn {Target Hook} bool TARGET_CAN_USE_DOLOOP_P (double_int @var{iterations}, double_int @var{iterations_max}, unsigned int @var{loop_depth}, bool @var{entered_at_top})
|
||||
Return true if it is possible to use low-overhead loops (@code{doloop_end}
|
||||
and @code{doloop_begin}) for a particular loop. @var{iterations} gives the
|
||||
exact number of iterations, or 0 if not known. @var{iterations_max} gives
|
||||
the maximum number of iterations, or 0 if not known. @var{loop_depth} is
|
||||
the nesting depth of the loop, with 1 for innermost loops, 2 for loops that
|
||||
contain innermost loops, and so on. @var{entered_at_top} is true if the
|
||||
loop is only entered from the top.
|
||||
|
||||
This hook is only used if @code{doloop_end} is available. The default
|
||||
implementation returns true. You can use @code{can_use_doloop_if_innermost}
|
||||
if the loop must be the innermost, and if there are no other restrictions.
|
||||
@end deftypefn
|
||||
|
||||
@deftypefn {Target Hook} {const char *} TARGET_INVALID_WITHIN_DOLOOP (const_rtx @var{insn})
|
||||
|
||||
Take an instruction in @var{insn} and return NULL if it is valid within a
|
||||
|
@ -8212,6 +8212,8 @@ to by @var{ce_info}.
|
||||
|
||||
@hook TARGET_GENERATE_VERSION_DISPATCHER_BODY
|
||||
|
||||
@hook TARGET_CAN_USE_DOLOOP_P
|
||||
|
||||
@hook TARGET_INVALID_WITHIN_DOLOOP
|
||||
|
||||
@hook TARGET_LEGITIMATE_COMBINED_INSN
|
||||
|
@ -331,6 +331,12 @@ hook_bool_rtx_int_int_int_intp_bool_false (rtx a ATTRIBUTE_UNUSED,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
hook_bool_dint_dint_uint_bool_true (double_int, double_int, unsigned int, bool)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Generic hook that takes an rtx and returns it. */
|
||||
rtx
|
||||
hook_rtx_rtx_identity (rtx x)
|
||||
|
@ -23,6 +23,7 @@
|
||||
#define GCC_HOOKS_H
|
||||
|
||||
#include "machmode.h"
|
||||
#include "double-int.h"
|
||||
|
||||
extern bool hook_bool_void_false (void);
|
||||
extern bool hook_bool_void_true (void);
|
||||
@ -60,6 +61,8 @@ extern bool hook_bool_rtx_int_int_int_intp_bool_false (rtx, int, int, int,
|
||||
extern bool hook_bool_tree_tree_false (tree, tree);
|
||||
extern bool hook_bool_tree_tree_true (tree, tree);
|
||||
extern bool hook_bool_tree_bool_false (tree, bool);
|
||||
extern bool hook_bool_dint_dint_uint_bool_true (double_int, double_int,
|
||||
unsigned int, bool);
|
||||
|
||||
extern void hook_void_void (void);
|
||||
extern void hook_void_constcharptr (const char *);
|
||||
|
@ -548,20 +548,8 @@ doloop_modify (struct loop *loop, struct niter_desc *desc,
|
||||
#ifdef HAVE_doloop_begin
|
||||
{
|
||||
rtx init;
|
||||
unsigned level = get_loop_level (loop) + 1;
|
||||
double_int iter;
|
||||
rtx iter_rtx;
|
||||
|
||||
if (!get_max_loop_iterations (loop, &iter)
|
||||
|| !iter.fits_shwi ())
|
||||
iter_rtx = const0_rtx;
|
||||
else
|
||||
iter_rtx = GEN_INT (iter.to_shwi ());
|
||||
init = gen_doloop_begin (counter_reg,
|
||||
desc->const_iter ? desc->niter_expr : const0_rtx,
|
||||
iter_rtx,
|
||||
GEN_INT (level),
|
||||
doloop_seq);
|
||||
init = gen_doloop_begin (counter_reg, doloop_seq);
|
||||
if (init)
|
||||
{
|
||||
start_sequence ();
|
||||
@ -608,8 +596,8 @@ doloop_optimize (struct loop *loop)
|
||||
{
|
||||
enum machine_mode mode;
|
||||
rtx doloop_seq, doloop_pat, doloop_reg;
|
||||
rtx iterations, count;
|
||||
rtx iterations_max;
|
||||
rtx count;
|
||||
double_int iterations, iterations_max;
|
||||
rtx start_label;
|
||||
rtx condition;
|
||||
unsigned level, est_niter;
|
||||
@ -617,7 +605,6 @@ doloop_optimize (struct loop *loop)
|
||||
struct niter_desc *desc;
|
||||
unsigned word_mode_size;
|
||||
unsigned HOST_WIDE_INT word_mode_max;
|
||||
double_int iter;
|
||||
int entered_at_top;
|
||||
|
||||
if (dump_file)
|
||||
@ -667,25 +654,30 @@ doloop_optimize (struct loop *loop)
|
||||
return false;
|
||||
}
|
||||
|
||||
count = copy_rtx (desc->niter_expr);
|
||||
iterations = desc->const_iter ? desc->niter_expr : const0_rtx;
|
||||
if (!get_max_loop_iterations (loop, &iter)
|
||||
|| !iter.fits_shwi ())
|
||||
iterations_max = const0_rtx;
|
||||
if (desc->const_iter)
|
||||
iterations = rtx_to_double_int (desc->niter_expr);
|
||||
else
|
||||
iterations_max = GEN_INT (iter.to_shwi ());
|
||||
iterations = double_int_zero;
|
||||
if (!get_max_loop_iterations (loop, &iterations_max))
|
||||
iterations_max = double_int_zero;
|
||||
level = get_loop_level (loop) + 1;
|
||||
entered_at_top = (loop->latch == desc->in_edge->dest
|
||||
&& contains_no_active_insn_p (loop->latch));
|
||||
if (!targetm.can_use_doloop_p (iterations, iterations_max, level,
|
||||
entered_at_top))
|
||||
{
|
||||
if (dump_file)
|
||||
fprintf (dump_file, "Loop rejected by can_use_doloop_p.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Generate looping insn. If the pattern FAILs then give up trying
|
||||
to modify the loop since there is some aspect the back-end does
|
||||
not like. */
|
||||
count = copy_rtx (desc->niter_expr);
|
||||
start_label = block_label (desc->in_edge->dest);
|
||||
doloop_reg = gen_reg_rtx (mode);
|
||||
entered_at_top = (loop->latch == desc->in_edge->dest
|
||||
&& contains_no_active_insn_p (loop->latch));
|
||||
doloop_seq = gen_doloop_end (doloop_reg, iterations, iterations_max,
|
||||
GEN_INT (level), start_label,
|
||||
GEN_INT (entered_at_top));
|
||||
doloop_seq = gen_doloop_end (doloop_reg, start_label);
|
||||
|
||||
word_mode_size = GET_MODE_PRECISION (word_mode);
|
||||
word_mode_max
|
||||
@ -696,27 +688,14 @@ doloop_optimize (struct loop *loop)
|
||||
computed, we must be sure that the number of iterations fits into
|
||||
the new mode. */
|
||||
&& (word_mode_size >= GET_MODE_PRECISION (mode)
|
||||
|| iter.ule (double_int::from_shwi (word_mode_max))))
|
||||
|| iterations_max.ule (double_int::from_shwi (word_mode_max))))
|
||||
{
|
||||
if (word_mode_size > GET_MODE_PRECISION (mode))
|
||||
{
|
||||
count = simplify_gen_unary (ZERO_EXTEND, word_mode,
|
||||
count, mode);
|
||||
iterations = simplify_gen_unary (ZERO_EXTEND, word_mode,
|
||||
iterations, mode);
|
||||
iterations_max = simplify_gen_unary (ZERO_EXTEND, word_mode,
|
||||
iterations_max, mode);
|
||||
}
|
||||
count = simplify_gen_unary (ZERO_EXTEND, word_mode, count, mode);
|
||||
else
|
||||
{
|
||||
count = lowpart_subreg (word_mode, count, mode);
|
||||
iterations = lowpart_subreg (word_mode, iterations, mode);
|
||||
iterations_max = lowpart_subreg (word_mode, iterations_max, mode);
|
||||
}
|
||||
count = lowpart_subreg (word_mode, count, mode);
|
||||
PUT_MODE (doloop_reg, word_mode);
|
||||
doloop_seq = gen_doloop_end (doloop_reg, iterations, iterations_max,
|
||||
GEN_INT (level), start_label,
|
||||
GEN_INT (entered_at_top));
|
||||
doloop_seq = gen_doloop_end (doloop_reg, start_label);
|
||||
}
|
||||
if (! doloop_seq)
|
||||
{
|
||||
|
@ -3597,6 +3597,23 @@ normally defined in @file{libgcc2.c}.",
|
||||
tree, (void),
|
||||
default_external_stack_protect_fail)
|
||||
|
||||
DEFHOOK
|
||||
(can_use_doloop_p,
|
||||
"Return true if it is possible to use low-overhead loops (@code{doloop_end}\n\
|
||||
and @code{doloop_begin}) for a particular loop. @var{iterations} gives the\n\
|
||||
exact number of iterations, or 0 if not known. @var{iterations_max} gives\n\
|
||||
the maximum number of iterations, or 0 if not known. @var{loop_depth} is\n\
|
||||
the nesting depth of the loop, with 1 for innermost loops, 2 for loops that\n\
|
||||
contain innermost loops, and so on. @var{entered_at_top} is true if the\n\
|
||||
loop is only entered from the top.\n\
|
||||
\n\
|
||||
This hook is only used if @code{doloop_end} is available. The default\n\
|
||||
implementation returns true. You can use @code{can_use_doloop_if_innermost}\n\
|
||||
if the loop must be the innermost, and if there are no other restrictions.",
|
||||
bool, (double_int iterations, double_int iterations_max,
|
||||
unsigned int loop_depth, bool entered_at_top),
|
||||
hook_bool_dint_dint_uint_bool_true)
|
||||
|
||||
/* Returns NULL if target supports the insn within a doloop block,
|
||||
otherwise it returns an error message. */
|
||||
DEFHOOK
|
||||
|
@ -50,6 +50,7 @@
|
||||
|
||||
#include "insn-modes.h"
|
||||
#include "insn-codes.h"
|
||||
#include "double-int.h"
|
||||
|
||||
#ifdef ENABLE_CHECKING
|
||||
|
||||
|
@ -1738,5 +1738,14 @@ default_builtin_chkp_function (unsigned int fcode ATTRIBUTE_UNUSED)
|
||||
return NULL_TREE;
|
||||
}
|
||||
|
||||
/* An implementation of TARGET_CAN_USE_DOLOOP_P for targets that do
|
||||
not support nested low-overhead loops. */
|
||||
|
||||
bool
|
||||
can_use_doloop_if_innermost (double_int, double_int,
|
||||
unsigned int loop_depth, bool)
|
||||
{
|
||||
return loop_depth == 1;
|
||||
}
|
||||
|
||||
#include "gt-targhooks.h"
|
||||
|
@ -213,3 +213,5 @@ extern tree default_fn_abi_va_list_bounds_size (tree);
|
||||
extern tree default_chkp_bound_type (void);
|
||||
extern enum machine_mode default_chkp_bound_mode (void);
|
||||
extern tree default_builtin_chkp_function (unsigned int);
|
||||
extern bool can_use_doloop_if_innermost (double_int, double_int,
|
||||
unsigned int, bool);
|
||||
|
Loading…
Reference in New Issue
Block a user