This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR optimization/9888 (part #3)
- From: Eric Botcazou <ebotcazou at libertysurf dot fr>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sun, 9 Mar 2003 23:32:10 +0100
- Subject: [PATCH] Fix PR optimization/9888 (part #3)
Hi,
The purpose of this part is to let the immediate jump instructions be
recognized as variable length instructions. This is currently not the case
because the computation of the "length" attribute is done through two
indirections
length <- length_immediate <- type
and the attribute machinery is not smart enough to detect that the "length"
ultimately depends upon an if-then-else.
It turns out that this was fixed on 3.3 and mainline by Jan back in November:
Tue Nov 19 23:50:56 CET 2002 Jan Hubicka <jh at suse dot cz>
* i386.md (length_immediate): Do not refer to insn address.
(jcc*, jmp patterns): Compute length explicitly.
The ChangeLog entry is actually incomplete, it lacks:
(doloop_end_internal pattern): Unconditionally set the type to "ibr".
According to the comments in the patch (I couldn't locate the related message
in the gcc-patches mailling-list), the purpose was probably to improve
scheduling only. But, as a side-effect, the patch does turn the immediate
jump instructions into variable length instructions. And the others bits are
pretty safe.
Bootstrapped/regtested on k6-redhat-linux-gnu (c,c++,objc,f77). Ok for the
3.2 branch?
With this patch, 35 out of 35 insns are now given the right length for the
loop in the PR (again manually verified). But this is still not sufficient
to let the testcase pass because the condition used to switch between short
and long branches is too permissive.
--
Eric Botcazou
2003-03-09 Eric Botcazou <ebotcazou at libertysurf dot fr>
PR optimization/9888
Backport patch from mainline:
Tue Nov 19 23:50:56 CET 2002 Jan Hubicka <jh at suse dot cz>
* i386.md (length_immediate): Do not refer to insn address.
(jcc*, jmp patterns): Compute length explicitly.
(doloop_end_internal pattern): Unconditionally set the type to "ibr".
Index: config/i386/i386.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.md,v
retrieving revision 1.339.2.13.2.3
diff -u -r1.339.2.13.2.3 i386.md
--- config/i386/i386.md 9 Mar 2003 15:51:39 -0000 1.339.2.13.2.3
+++ config/i386/i386.md 9 Mar 2003 17:09:38 -0000
@@ -147,13 +147,10 @@
(if_then_else (match_operand 1 "constant_call_address_operand" "")
(const_int 4)
(const_int 0))
+ ;; We don't know the size before shorten_branches. Expect
+ ;; the instruction to fit for better scheduling.
(eq_attr "type" "ibr")
- (if_then_else (and (ge (minus (match_dup 0) (pc))
- (const_int -128))
- (lt (minus (match_dup 0) (pc))
- (const_int 124)))
- (const_int 1)
- (const_int 4))
+ (const_int 1)
]
(symbol_ref "/* Update immediate_length and other attributes! */ abort(),1")))
@@ -12968,13 +12965,13 @@
"%+j%C1\t%l0"
[(set_attr "type" "ibr")
(set_attr "modrm" "0")
- (set (attr "prefix_0f")
+ (set (attr "length")
(if_then_else (and (ge (minus (match_dup 0) (pc))
(const_int -128))
(lt (minus (match_dup 0) (pc))
(const_int 124)))
- (const_int 0)
- (const_int 1)))])
+ (const_int 2)
+ (const_int 6)))])
(define_insn "*jcc_2"
[(set (pc)
@@ -12986,13 +12983,13 @@
"%+j%c1\t%l0"
[(set_attr "type" "ibr")
(set_attr "modrm" "0")
- (set (attr "prefix_0f")
+ (set (attr "length")
(if_then_else (and (ge (minus (match_dup 0) (pc))
(const_int -128))
(lt (minus (match_dup 0) (pc))
(const_int 124)))
- (const_int 0)
- (const_int 1)))])
+ (const_int 2)
+ (const_int 6)))])
;; In general it is not safe to assume too much about CCmode registers,
;; so simplify-rtx stops when it sees a second one. Under certain
@@ -13253,6 +13250,13 @@
""
"jmp\t%l0"
[(set_attr "type" "ibr")
+ (set (attr "length")
+ (if_then_else (and (ge (minus (match_dup 0) (pc))
+ (const_int -128))
+ (lt (minus (match_dup 0) (pc))
+ (const_int 124)))
+ (const_int 2)
+ (const_int 5)))
(set_attr "modrm" "0")])
(define_expand "indirect_jump"
@@ -13374,14 +13378,9 @@
(const_int 124))))
(const_int 2)
(const_int 16)))
- (set (attr "type")
- (if_then_else (and (eq_attr "alternative" "0")
- (and (ge (minus (match_dup 0) (pc))
- (const_int -128))
- (lt (minus (match_dup 0) (pc))
- (const_int 124))))
- (const_string "ibr")
- (const_string "multi")))])
+ ;; We don't know the type before shorten branches. Optimistically expect
+ ;; the loop instruction to match.
+ (set (attr "type") (const_string "ibr"))])
(define_split
[(set (pc)