* patch applied to sh port: fix alignments / insn length problem
@ 2003-03-03 19:57 Joern Rennecke
2003-03-05 21:49 ` Joern Rennecke
0 siblings, 1 reply; 2+ messages in thread
From: Joern Rennecke @ 2003-03-03 19:57 UTC (permalink / raw)
To: gcc-patches
[-- Attachment #1: Type: text/plain, Size: 606 bytes --]
This patch makes the sh port honour the align_jumps / align_loops
settings, and when relaxing, it makes the align_function setting
large enough so that no alignment inside a function emitted by gcc
is larger than the alignment of the function as a whole.
I've also fixed an insn size bug where the compiler found a scratch
register for a far jump and thus knew that the jump would take only
6 bytes + delay slot, but lost track of the scratch register as
INSN_SCOPE notes were emitted.
--
--------------------------
SuperH (UK) Ltd.
2410 Aztec West / Almondsbury / BRISTOL / BS32 4QX
T:+44 1454 465658
[-- Attachment #2: align-patch --]
[-- Type: text/plain, Size: 10449 bytes --]
Mon Mar 3 19:47:26 2003 J"orn Rennecke <joern.rennecke@superh.com>
* sh.h (OVERRIDE_OPTIONS): Set default values for align_loops
and align_jumps if not set.
Force align_jumps to be at least 2.
When relaxing, force align_functions to be at least the maximum of
align_loops, align_jumps and 4.
* sh.c (find_barrier, barrier_align): Honour align_jumps_log.
(sh_loop_align): Honour align_loops_log.
* sh.md (length attribute): Use prev_nonnote_insn instead of PREV_INSN
to check for indirect_jump_scratch.
(indirect_jump_scratch): Add second set.
* sh.c (output_far_jump): Use prev_nonnote_insn instead of PREV_INSN
when looking for indirect_jump_scratch.
Extract scratch register taking new structure of indirect_jump_scratch
into account.
(gen_block_redirect): Set INSN_SCOPE for indirect_jump_scratch.
Index: config/sh/sh.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sh/sh.c,v
retrieving revision 1.200
diff -p -r1.200 sh.c
*** config/sh/sh.c 24 Feb 2003 02:44:01 -0000 1.200
--- config/sh/sh.c 3 Mar 2003 19:25:05 -0000
*************** output_far_jump (insn, op)
*** 1048,1053 ****
--- 1048,1054 ----
const char *jump;
int far;
int offset = branch_dest (insn) - INSN_ADDRESSES (INSN_UID (insn));
+ rtx prev;
this.lab = gen_label_rtx ();
*************** output_far_jump (insn, op)
*** 1072,1081 ****
jump = "mov.l %O0,%1; jmp @%1";
}
/* If we have a scratch register available, use it. */
! if (GET_CODE (PREV_INSN (insn)) == INSN
! && INSN_CODE (PREV_INSN (insn)) == CODE_FOR_indirect_jump_scratch)
{
! this.reg = SET_DEST (PATTERN (PREV_INSN (insn)));
if (REGNO (this.reg) == R0_REG && flag_pic && ! TARGET_SH2)
jump = "mov.l r1,@-r15; mova %O0,r0; mov.l @r0,r1; add r1,r0; mov.l @r15+,r1; jmp @%1";
output_asm_insn (jump, &this.lab);
--- 1073,1082 ----
jump = "mov.l %O0,%1; jmp @%1";
}
/* If we have a scratch register available, use it. */
! if (GET_CODE ((prev = prev_nonnote_insn (insn))) == INSN
! && INSN_CODE (prev) == CODE_FOR_indirect_jump_scratch)
{
! this.reg = SET_DEST (XVECEXP (PATTERN (prev), 0, 0));
if (REGNO (this.reg) == R0_REG && flag_pic && ! TARGET_SH2)
jump = "mov.l r1,@-r15; mova %O0,r0; mov.l @r0,r1; add r1,r0; mov.l @r15+,r1; jmp @%1";
output_asm_insn (jump, &this.lab);
*************** find_barrier (num_mova, mova, from)
*** 3016,3022 ****
{
if (num_mova)
num_mova--;
! if (barrier_align (next_real_insn (from)) == CACHE_LOG)
{
/* We have just passed the barrier in front of the
ADDR_DIFF_VEC, which is stored in found_barrier. Since
--- 3017,3023 ----
{
if (num_mova)
num_mova--;
! if (barrier_align (next_real_insn (from)) == align_jumps_log)
{
/* We have just passed the barrier in front of the
ADDR_DIFF_VEC, which is stored in found_barrier. Since
*************** gen_block_redirect (jump, addr, need_blo
*** 3454,3459 ****
--- 3455,3467 ----
rtx insn = emit_insn_before (gen_indirect_jump_scratch
(reg, GEN_INT (INSN_UID (JUMP_LABEL (jump))))
, jump);
+ /* ??? We would like this to have the scope of the jump, but that
+ scope will change when a delay slot insn of an inner scope is added.
+ Hence, after delay slot scheduling, we'll have to expect
+ NOTE_INSN_BLOCK_END notes between the indirect_jump_scratch and
+ the jump. */
+
+ INSN_SCOPE (insn) = INSN_SCOPE (jump);
INSN_CODE (insn) = CODE_FOR_indirect_jump_scratch;
return insn;
}
*************** barrier_align (barrier_or_label)
*** 3596,3609 ****
return ((TARGET_SMALLCODE
|| ((unsigned) XVECLEN (pat, 1) * GET_MODE_SIZE (GET_MODE (pat))
<= (unsigned)1 << (CACHE_LOG - 2)))
! ? 1 << TARGET_SHMEDIA : CACHE_LOG);
}
if (TARGET_SMALLCODE)
return 0;
if (! TARGET_SH2 || ! optimize)
! return CACHE_LOG;
/* When fixing up pcloads, a constant table might be inserted just before
the basic block that ends with the barrier. Thus, we can't trust the
--- 3604,3617 ----
return ((TARGET_SMALLCODE
|| ((unsigned) XVECLEN (pat, 1) * GET_MODE_SIZE (GET_MODE (pat))
<= (unsigned)1 << (CACHE_LOG - 2)))
! ? 1 << TARGET_SHMEDIA : align_jumps_log);
}
if (TARGET_SMALLCODE)
return 0;
if (! TARGET_SH2 || ! optimize)
! return align_jumps_log;
/* When fixing up pcloads, a constant table might be inserted just before
the basic block that ends with the barrier. Thus, we can't trust the
*************** barrier_align (barrier_or_label)
*** 3679,3685 ****
}
}
! return CACHE_LOG;
}
/* If we are inside a phony loop, almost any kind of label can turn up as the
--- 3687,3693 ----
}
}
! return align_jumps_log;
}
/* If we are inside a phony loop, almost any kind of label can turn up as the
*************** sh_loop_align (label)
*** 3704,3713 ****
|| recog_memoized (next) == CODE_FOR_consttable_2)
return 0;
! if (TARGET_SH5)
! return 3;
!
! return 2;
}
/* Exported to toplev.c.
--- 3712,3718 ----
|| recog_memoized (next) == CODE_FOR_consttable_2)
return 0;
! return align_loops_log;
}
/* Exported to toplev.c.
*************** split_branches (first)
*** 4417,4425 ****
If relaxing, output the label and pseudo-ops used to link together
calls and the instruction which set the registers. */
-
- /* ??? This is unnecessary, and probably should be deleted. This makes
- the insn_addresses declaration above unnecessary. */
/* ??? The addresses printed by this routine for insns are nonsense for
insns which are inside of a sequence where none of the inner insns have
--- 4422,4427 ----
Index: config/sh/sh.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sh/sh.h,v
retrieving revision 1.191
diff -p -r1.191 sh.h
*** config/sh/sh.h 24 Feb 2003 02:44:01 -0000 1.191
--- config/sh/sh.h 3 Mar 2003 19:25:05 -0000
*************** do { \
*** 489,494 ****
--- 489,501 ----
flag_schedule_insns = 0; \
} \
\
+ if (align_loops == 0) \
+ align_loops = 1 << (TARGET_SH5 ? 3 : 2); \
+ if (align_jumps == 0) \
+ align_jumps = 1 << CACHE_LOG; \
+ else if (align_jumps <= 1) \
+ align_jumps = 2; \
+ \
/* Allocation boundary (in *bytes*) for the code of a function. \
SH1: 32 bit alignment is faster, because instructions are always \
fetched as a pair from a longword boundary. \
*************** do { \
*** 496,501 ****
--- 503,522 ----
if (align_functions == 0) \
align_functions \
= TARGET_SMALLCODE ? FUNCTION_BOUNDARY/8 : (1 << CACHE_LOG); \
+ /* The linker relaxation code breaks when a function contains \
+ alignments that are larger than that at the start of a \
+ compilation unit. */ \
+ if (TARGET_RELAX) \
+ { \
+ int min_align \
+ = align_loops > align_jumps ? align_loops : align_jumps; \
+ \
+ /* Also take possible .long constants / mova tables int account. */\
+ if (min_align < 4) \
+ min_align = 4; \
+ if (align_functions < min_align) \
+ align_functions = min_align; \
+ } \
} while (0)
\f
/* Target machine storage layout. */
Index: config/sh/sh.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sh/sh.md,v
retrieving revision 1.140
diff -p -r1.140 sh.md
*** config/sh/sh.md 24 Feb 2003 02:44:02 -0000 1.140
--- config/sh/sh.md 3 Mar 2003 19:25:05 -0000
***************
*** 391,399 ****
(eq_attr "type" "jump")
(cond [(eq_attr "med_branch_p" "yes")
(const_int 2)
! (and (eq (symbol_ref "GET_CODE (PREV_INSN (insn))")
(symbol_ref "INSN"))
! (eq (symbol_ref "INSN_CODE (PREV_INSN (insn))")
(symbol_ref "code_for_indirect_jump_scratch")))
(if_then_else (eq_attr "braf_branch_p" "yes")
(const_int 6)
--- 391,399 ----
(eq_attr "type" "jump")
(cond [(eq_attr "med_branch_p" "yes")
(const_int 2)
! (and (eq (symbol_ref "GET_CODE (prev_nonnote_insn (insn))")
(symbol_ref "INSN"))
! (eq (symbol_ref "INSN_CODE (prev_nonnote_insn (insn))")
(symbol_ref "code_for_indirect_jump_scratch")))
(if_then_else (eq_attr "braf_branch_p" "yes")
(const_int 6)
***************
*** 5035,5043 ****
;; This one has the additional purpose to record a possible scratch register
;; for the following branch.
(define_insn "indirect_jump_scratch"
[(set (match_operand:SI 0 "register_operand" "=r")
! (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))]
"TARGET_SH1"
""
[(set_attr "length" "0")])
--- 5035,5048 ----
;; This one has the additional purpose to record a possible scratch register
;; for the following branch.
+ ;; ??? Unfortunately, just setting the scratch register is not good enough,
+ ;; because the insn then might be deemed dead and deleted. And we can't
+ ;; make the use in the jump insn explicit because that would disable
+ ;; delay slot scheduling from the target.
(define_insn "indirect_jump_scratch"
[(set (match_operand:SI 0 "register_operand" "=r")
! (unspec:SI [(match_operand 1 "const_int_operand" "")] UNSPEC_BBR))
! (set (pc) (unspec [(const_int 0)] UNSPEC_BBR))]
"TARGET_SH1"
""
[(set_attr "length" "0")])
***************
*** 5474,5479 ****
--- 5479,5497 ----
}"
[(set_attr "type" "jump")
(set_attr "needs_delay_slot" "yes")])
+
+ ;; ??? It would be much saner to explicitly use the scratch register
+ ;; in the jump insn, and have indirect_jump_scratch only set it,
+ ;; but fill_simple_delay_slots would refuse to do delay slot filling
+ ;; from the target then, as it uses simplejump_p.
+ ;;(define_insn "jump_compact_far"
+ ;; [(set (pc)
+ ;; (label_ref (match_operand 0 "" "")))
+ ;; (use (match_operand 1 "register_operand" "r")]
+ ;; "TARGET_SH1"
+ ;; "* return output_far_jump(insn, operands[0], operands[1]);"
+ ;; [(set_attr "type" "jump")
+ ;; (set_attr "needs_delay_slot" "yes")])
(define_insn "jump_media"
[(set (pc)
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: patch applied to sh port: fix alignments / insn length problem
2003-03-03 19:57 patch applied to sh port: fix alignments / insn length problem Joern Rennecke
@ 2003-03-05 21:49 ` Joern Rennecke
0 siblings, 0 replies; 2+ messages in thread
From: Joern Rennecke @ 2003-03-05 21:49 UTC (permalink / raw)
To: gcc-patches
[-- Attachment #1: Type: text/plain, Size: 533 bytes --]
> Mon Mar 3 19:47:26 2003 J"orn Rennecke <joern.rennecke@superh.com>
>
> * sh.h (OVERRIDE_OPTIONS): Set default values for align_loops
> and align_jumps if not set.
> Force align_jumps to be at least 2.
Well, SHmedia needs 4...
SECONDARY_INPUT_RELOAD_CLASS also wasn't quite prepared for the bad taste
of the register allocator to load a PLUS into FPUL.
Tested for sh-elf and sh64-elf.
--
--------------------------
SuperH (UK) Ltd.
2410 Aztec West / Almondsbury / BRISTOL / BS32 4QX
T:+44 1454 465658
[-- Attachment #2: tmp --]
[-- Type: text/plain, Size: 2187 bytes --]
Wed Mar 5 21:40:57 2003 J"orn Rennecke <joern.rennecke@superh.com>
* sh.h (OVERRIDE_OPTIONS): For TARGET_SHMEDIA, the minimum value
for align_jumps is 4.
(SECONDARY_INPUT_RELOAD_CLASS): If reloading a PLUS into FPUL,
use GENERAL_REGS.
Index: config/sh/sh.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/sh/sh.h,v
retrieving revision 1.193
diff -p -r1.193 sh.h
*** config/sh/sh.h 3 Mar 2003 20:57:17 -0000 1.193
--- config/sh/sh.h 5 Mar 2003 21:44:05 -0000
*************** do { \
*** 507,514 ****
align_loops = 1 << (TARGET_SH5 ? 3 : 2); \
if (align_jumps == 0) \
align_jumps = 1 << CACHE_LOG; \
! else if (align_jumps <= 1) \
! align_jumps = 2; \
\
/* Allocation boundary (in *bytes*) for the code of a function. \
SH1: 32 bit alignment is faster, because instructions are always \
--- 507,514 ----
align_loops = 1 << (TARGET_SH5 ? 3 : 2); \
if (align_jumps == 0) \
align_jumps = 1 << CACHE_LOG; \
! else if (align_jumps < (TARGET_SHMEDIA ? 4 : 2)) \
! align_jumps = TARGET_SHMEDIA ? 4 : 2; \
\
/* Allocation boundary (in *bytes*) for the code of a function. \
SH1: 32 bit alignment is faster, because instructions are always \
*************** extern enum reg_class reg_class_from_let
*** 1395,1402 ****
? R0_REGS \
: (CLASS == FPUL_REGS \
&& ((GET_CODE (X) == REG \
! && (REGNO (X) == MACL_REG || REGNO (X) == MACH_REG \
! || REGNO (X) == T_REG)))) \
? GENERAL_REGS \
: CLASS == FPUL_REGS && immediate_operand ((X), (MODE)) \
? (GET_CODE (X) == CONST_INT && CONST_OK_FOR_I (INTVAL (X)) \
--- 1395,1403 ----
? R0_REGS \
: (CLASS == FPUL_REGS \
&& ((GET_CODE (X) == REG \
! && (REGNO (X) == MACL_REG || REGNO (X) == MACH_REG \
! || REGNO (X) == T_REG)) \
! || GET_CODE (X) == PLUS)) \
? GENERAL_REGS \
: CLASS == FPUL_REGS && immediate_operand ((X), (MODE)) \
? (GET_CODE (X) == CONST_INT && CONST_OK_FOR_I (INTVAL (X)) \
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2003-03-05 21:49 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-03-03 19:57 patch applied to sh port: fix alignments / insn length problem Joern Rennecke
2003-03-05 21:49 ` Joern Rennecke
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).