Patchwork , PR 50341, Fix TOC load scheduling for powerpc on GCC 4.6 and 4.7 (patches included)

login
register
mail settings
Submitter Michael Meissner
Date Sept. 15, 2011, 6:04 p.m.
Message ID <20110915180429.GA6038@hungry-tiger.westford.ibm.com>
Download mbox | patch
Permalink /patch/114814/
State New
Headers show

Comments

Michael Meissner - Sept. 15, 2011, 6:04 p.m.
It would help if I included the patches:

[gcc-4.6]
2011-09-15  Alan Modra  <amodra@gmail.com>
	    Michael Meissner  <meissner@linux.vnet.ibm.com>

	PR target/50341
	* config/rs6000/rs6000.md (call_indirect_aix32): Do not split the
	load of the indirect function's TOC from the call to prevent the
	compiler from moving the load of the new TOC above code that
	references the current function's TOC.
	(call_indirect_aix64): Ditto.
	(call_value_indirect_aix32): Ditto.
	(call_value_indirect_aix64): Ditto.
	(call_indirect_nonlocal_aix32_internal): Ditto.
	(call_indirect_nonlocal_aix32): Ditto.
	(call_indirect_nonlocal_aix64_internal): Ditto.
	(call_indirect_nonlocal_aix64): Ditto.
	(call_value_indirect_nonlocal_aix32_internal): Ditto.
	(call_value_indirect_nonlocal_aix32): Ditto.
	(call_value_indirect_nonlocal_aix64_internal): Ditto.
	(call_value_indirect_nonlocal_aix64): Ditto.

[gcc-4.7]
2011-09-15  Alan Modra  <amodra@gmail.com>
	    Michael Meissner  <meissner@linux.vnet.ibm.com>

	PR target/50341
	* config/rs6000/rs6000.md (call_indirect_aix<ptrsize>): Do not
	split the load of the indirect function's TOC from the call to
	prevent the compiler from moving the load of the new TOC above
	code that references the current function's TOC.
	(call_indirect_aix<ptrsize>_internal): Ditto.
	(call_indirect_aix<ptrsize>_nor11): Ditto.
	(call_indirect_aix<ptrsize>_internal2): Ditto.
	(call_value_indirect_aix<ptrsize>): Ditto.
	(call_value_indirect_aix<ptrsize>_internal): Ditto.
	(call_value_indirect_aix<ptrsize>_nor11): Ditto.
	(call_value_indirect_aix<ptrsize>_internal2): Ditto.
David Edelsohn - Sept. 16, 2011, 5:25 a.m.
On Thu, Sep 15, 2011 at 2:04 PM, Michael Meissner
<meissner@linux.vnet.ibm.com> wrote:
> It would help if I included the patches:
>
> [gcc-4.6]
> 2011-09-15  Alan Modra  <amodra@gmail.com>
>            Michael Meissner  <meissner@linux.vnet.ibm.com>
>
>        PR target/50341
>        * config/rs6000/rs6000.md (call_indirect_aix32): Do not split the
>        load of the indirect function's TOC from the call to prevent the
>        compiler from moving the load of the new TOC above code that
>        references the current function's TOC.
>        (call_indirect_aix64): Ditto.
>        (call_value_indirect_aix32): Ditto.
>        (call_value_indirect_aix64): Ditto.
>        (call_indirect_nonlocal_aix32_internal): Ditto.
>        (call_indirect_nonlocal_aix32): Ditto.
>        (call_indirect_nonlocal_aix64_internal): Ditto.
>        (call_indirect_nonlocal_aix64): Ditto.
>        (call_value_indirect_nonlocal_aix32_internal): Ditto.
>        (call_value_indirect_nonlocal_aix32): Ditto.
>        (call_value_indirect_nonlocal_aix64_internal): Ditto.
>        (call_value_indirect_nonlocal_aix64): Ditto.
>
> [gcc-4.7]
> 2011-09-15  Alan Modra  <amodra@gmail.com>
>            Michael Meissner  <meissner@linux.vnet.ibm.com>
>
>        PR target/50341
>        * config/rs6000/rs6000.md (call_indirect_aix<ptrsize>): Do not
>        split the load of the indirect function's TOC from the call to
>        prevent the compiler from moving the load of the new TOC above
>        code that references the current function's TOC.
>        (call_indirect_aix<ptrsize>_internal): Ditto.
>        (call_indirect_aix<ptrsize>_nor11): Ditto.
>        (call_indirect_aix<ptrsize>_internal2): Ditto.
>        (call_value_indirect_aix<ptrsize>): Ditto.
>        (call_value_indirect_aix<ptrsize>_internal): Ditto.
>        (call_value_indirect_aix<ptrsize>_nor11): Ditto.
>        (call_value_indirect_aix<ptrsize>_internal2): Ditto.

Okay.

Thanks, David

Patch

Index: gcc/config/rs6000/rs6000.md
===================================================================
--- gcc/config/rs6000/rs6000.md	(revision 178888)
+++ gcc/config/rs6000/rs6000.md	(working copy)
@@ -12165,43 +12165,67 @@  (define_insn "largetoc_low"
 (define_expand "call_indirect_aix32"
   [(set (match_dup 2)
 	(mem:SI (match_operand:SI 0 "gpc_reg_operand" "")))
-   (set (mem:SI (plus:SI (reg:SI 1) (const_int 20)))
+   (set (match_dup 3)
 	(reg:SI 2))
    (set (reg:SI 11)
 	(mem:SI (plus:SI (match_dup 0)
 			 (const_int 8))))
    (parallel [(call (mem:SI (match_dup 2))
 		    (match_operand 1 "" ""))
-	      (use (mem:SI (plus:SI (match_dup 0) (const_int 4))))
+	      (use (match_dup 4))
+	      (set (reg:SI 2) (match_dup 3))
 	      (use (reg:SI 11))
-	      (use (mem:SI (plus:SI (reg:SI 1) (const_int 20))))
 	      (clobber (reg:SI LR_REGNO))])]
   "TARGET_32BIT"
   "
-{ operands[2] = gen_reg_rtx (SImode); }")
+{
+  operands[2] = gen_reg_rtx (SImode);
+  operands[3] = gen_rtx_MEM (SImode,
+			     gen_rtx_PLUS (SImode, stack_pointer_rtx,
+					   GEN_INT (20)));
+
+  operands[4] = gen_rtx_MEM (SImode,
+			     gen_rtx_PLUS (SImode, operands[0],
+					   GEN_INT (4)));
+
+  /* Make sure the compiler does not optimize away the store of the TOC.  */
+  MEM_VOLATILE_P (operands[3]) = 1;
+}")
 
 (define_expand "call_indirect_aix64"
   [(set (match_dup 2)
 	(mem:DI (match_operand:DI 0 "gpc_reg_operand" "")))
-   (set (mem:DI (plus:DI (reg:DI 1) (const_int 40)))
+   (set (match_dup 3)
 	(reg:DI 2))
    (set (reg:DI 11)
 	(mem:DI (plus:DI (match_dup 0)
 			 (const_int 16))))
    (parallel [(call (mem:SI (match_dup 2))
 		    (match_operand 1 "" ""))
-	      (use (mem:DI (plus:DI (match_dup 0) (const_int 8))))
+	      (use (match_dup 4))
+	      (set (reg:DI 2) (match_dup 3))
 	      (use (reg:DI 11))
-	      (use (mem:DI (plus:DI (reg:DI 1) (const_int 40))))
-	      (clobber (reg:SI LR_REGNO))])]
+	      (clobber (reg:DI LR_REGNO))])]
   "TARGET_64BIT"
   "
-{ operands[2] = gen_reg_rtx (DImode); }")
+{
+  operands[2] = gen_reg_rtx (DImode);
+  operands[3] = gen_rtx_MEM (DImode,
+			     gen_rtx_PLUS (DImode, stack_pointer_rtx,
+					   GEN_INT (40)));
+
+  operands[4] = gen_rtx_MEM (DImode,
+			     gen_rtx_PLUS (DImode, operands[0],
+					   GEN_INT (8)));
+
+  /* Make sure the compiler does not optimize away the store of the TOC.  */
+  MEM_VOLATILE_P (operands[3]) = 1;
+}")
 
 (define_expand "call_value_indirect_aix32"
   [(set (match_dup 3)
 	(mem:SI (match_operand:SI 1 "gpc_reg_operand" "")))
-   (set (mem:SI (plus:SI (reg:SI 1) (const_int 20)))
+   (set (match_dup 4)
 	(reg:SI 2))
    (set (reg:SI 11)
 	(mem:SI (plus:SI (match_dup 1)
@@ -12209,18 +12233,30 @@  (define_expand "call_value_indirect_aix3
    (parallel [(set (match_operand 0 "" "")
 		   (call (mem:SI (match_dup 3))
 			 (match_operand 2 "" "")))
-	      (use (mem:SI (plus:SI (match_dup 1) (const_int 4))))
+	      (use (match_dup 5))
+	      (set (reg:SI 2) (match_dup 4))
 	      (use (reg:SI 11))
-	      (use (mem:SI (plus:SI (reg:SI 1) (const_int 20))))
 	      (clobber (reg:SI LR_REGNO))])]
   "TARGET_32BIT"
   "
-{ operands[3] = gen_reg_rtx (SImode); }")
+{
+  operands[3] = gen_reg_rtx (SImode);
+  operands[4] = gen_rtx_MEM (DImode,
+			     gen_rtx_PLUS (DImode, stack_pointer_rtx,
+					   GEN_INT (20)));
+
+  operands[5] = gen_rtx_MEM (SImode,
+			     gen_rtx_PLUS (SImode, operands[1],
+					   GEN_INT (4)));
+
+  /* Make sure the compiler does not optimize away the store of the TOC.  */
+  MEM_VOLATILE_P (operands[4]) = 1;
+}")
 
 (define_expand "call_value_indirect_aix64"
   [(set (match_dup 3)
 	(mem:DI (match_operand:DI 1 "gpc_reg_operand" "")))
-   (set (mem:DI (plus:DI (reg:DI 1) (const_int 40)))
+   (set (match_dup 4)
 	(reg:DI 2))
    (set (reg:DI 11)
 	(mem:DI (plus:DI (match_dup 1)
@@ -12228,13 +12264,25 @@  (define_expand "call_value_indirect_aix6
    (parallel [(set (match_operand 0 "" "")
 		   (call (mem:SI (match_dup 3))
 			 (match_operand 2 "" "")))
-	      (use (mem:DI (plus:DI (match_dup 1) (const_int 8))))
+	      (use (match_dup 5))
+	      (set (reg:DI 2) (match_dup 4))
 	      (use (reg:DI 11))
-	      (use (mem:DI (plus:DI (reg:DI 1) (const_int 40))))
-	      (clobber (reg:SI LR_REGNO))])]
+	      (clobber (reg:DI LR_REGNO))])]
   "TARGET_64BIT"
   "
-{ operands[3] = gen_reg_rtx (DImode); }")
+{
+  operands[3] = gen_reg_rtx (DImode);
+  operands[4] = gen_rtx_MEM (DImode,
+			     gen_rtx_PLUS (DImode, stack_pointer_rtx,
+					   GEN_INT (40)));
+
+  operands[5] = gen_rtx_MEM (DImode,
+			     gen_rtx_PLUS (DImode, operands[1],
+					   GEN_INT (8)));
+
+  /* Make sure the compiler does not optimize away the store of the TOC.  */
+  MEM_VOLATILE_P (operands[4]) = 1;
+}")
 
 ;; Now the definitions for the call and call_value insns
 (define_expand "call"
@@ -12427,47 +12475,27 @@  (define_insn "*call_value_local64"
 
 ;; Call to function which may be in another module.  Restore the TOC
 ;; pointer (r2) after the call unless this is System V.
-;; Operand2 is nonzero if we are using the V.4 calling sequence and
+;; Operand1 is nonzero if we are using the V.4 calling sequence and
 ;; either the function was not prototyped, or it was prototyped as a
 ;; variable argument function.  It is > 0 if FP registers were passed
 ;; and < 0 if they were not.
+;; Operand2 is the address of the 3 word function pointer that offset 4 points
+;; to the value to be loaded in the TOC register.  Do not split the load from
+;; the call, as it may move the load of the TOC before any addresses using
+;; the TOC.
 
-(define_insn_and_split "*call_indirect_nonlocal_aix32_internal"
+(define_insn "*call_indirect_nonlocal_aix32"
   [(call (mem:SI (match_operand:SI 0 "register_operand" "c,*l"))
 		 (match_operand 1 "" "g,g"))
-   (use (mem:SI (plus:SI (match_operand:SI 2 "register_operand" "b,b") (const_int 4))))
+   (use (match_operand:SI 2 "memory_operand" "m,m"))
+   (set (reg:SI 2) (match_operand:SI 3 "memory_operand" "m,m"))
    (use (reg:SI 11))
-   (use (mem:SI (plus:SI (reg:SI 1) (const_int 20))))
    (clobber (reg:SI LR_REGNO))]
   "TARGET_32BIT && DEFAULT_ABI == ABI_AIX"
-  "#"
-  "&& reload_completed"
-  [(set (reg:SI 2)
-	(mem:SI (plus:SI (match_dup 2) (const_int 4))))
-   (parallel [(call (mem:SI (match_dup 0))
-		    (match_dup 1))
-	      (use (reg:SI 2))
-	      (use (reg:SI 11))
-	      (set (reg:SI 2)
-		   (mem:SI (plus:SI (reg:SI 1) (const_int 20))))
-	      (clobber (reg:SI LR_REGNO))])]
-  ""
+  "{l|lwz} 2,%2\;b%T0l\;{l|lwz} 2,%3"
   [(set_attr "type" "jmpreg")
    (set_attr "length" "12")])
 
-(define_insn "*call_indirect_nonlocal_aix32"
-  [(call (mem:SI (match_operand:SI 0 "register_operand" "c,*l"))
-	 (match_operand 1 "" "g,g"))
-   (use (reg:SI 2))
-   (use (reg:SI 11))
-   (set (reg:SI 2)
-	(mem:SI (plus:SI (reg:SI 1) (const_int 20))))
-   (clobber (reg:SI LR_REGNO))]
-  "TARGET_32BIT && DEFAULT_ABI == ABI_AIX && reload_completed"
-  "b%T0l\;{l|lwz} 2,20(1)"
-  [(set_attr "type" "jmpreg")
-   (set_attr "length" "8")])
-
 (define_insn "*call_nonlocal_aix32"
   [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "s"))
 	 (match_operand 1 "" "g"))
@@ -12480,43 +12508,18 @@  (define_insn "*call_nonlocal_aix32"
   [(set_attr "type" "branch")
    (set_attr "length" "8")])
    
-(define_insn_and_split "*call_indirect_nonlocal_aix64_internal"
+(define_insn "*call_indirect_nonlocal_aix64"
   [(call (mem:SI (match_operand:DI 0 "register_operand" "c,*l"))
 		 (match_operand 1 "" "g,g"))
-   (use (mem:DI (plus:DI (match_operand:DI 2 "register_operand" "b,b")
-			 (const_int 8))))
+   (use (match_operand:DI 2 "memory_operand" "m,m"))
+   (set (reg:DI 2) (match_operand:DI 3 "memory_operand" "m,m"))
    (use (reg:DI 11))
-   (use (mem:DI (plus:DI (reg:DI 1) (const_int 40))))
-   (clobber (reg:SI LR_REGNO))]
+   (clobber (reg:DI LR_REGNO))]
   "TARGET_64BIT && DEFAULT_ABI == ABI_AIX"
-  "#"
-  "&& reload_completed"
-  [(set (reg:DI 2)
-	(mem:DI (plus:DI (match_dup 2) (const_int 8))))
-   (parallel [(call (mem:SI (match_dup 0))
-		    (match_dup 1))
-	      (use (reg:DI 2))
-	      (use (reg:DI 11))
-	      (set (reg:DI 2)
-		   (mem:DI (plus:DI (reg:DI 1) (const_int 40))))
-	      (clobber (reg:SI LR_REGNO))])]
-  ""
+  "ld  2,%2\;b%T0l\;ld 2,%3"
   [(set_attr "type" "jmpreg")
    (set_attr "length" "12")])
 
-(define_insn "*call_indirect_nonlocal_aix64"
-  [(call (mem:SI (match_operand:DI 0 "register_operand" "c,*l"))
-	 (match_operand 1 "" "g,g"))
-   (use (reg:DI 2))
-   (use (reg:DI 11))
-   (set (reg:DI 2)
-	(mem:DI (plus:DI (reg:DI 1) (const_int 40))))
-   (clobber (reg:SI LR_REGNO))]
-  "TARGET_64BIT && DEFAULT_ABI == ABI_AIX && reload_completed"
-  "b%T0l\;ld 2,40(1)"
-  [(set_attr "type" "jmpreg")
-   (set_attr "length" "8")])
-
 (define_insn "*call_nonlocal_aix64"
   [(call (mem:SI (match_operand:DI 0 "symbol_ref_operand" "s"))
 	 (match_operand 1 "" "g"))
@@ -12529,44 +12532,18 @@  (define_insn "*call_nonlocal_aix64"
   [(set_attr "type" "branch")
    (set_attr "length" "8")])
 
-(define_insn_and_split "*call_value_indirect_nonlocal_aix32_internal"
-  [(set (match_operand 0 "" "")
-	(call (mem:SI (match_operand:SI 1 "register_operand" "c,*l"))
-		      (match_operand 2 "" "g,g")))
-	(use (mem:SI (plus:SI (match_operand:SI 3 "register_operand" "b,b")
-			      (const_int 4))))
-	(use (reg:SI 11))
-	(use (mem:SI (plus:SI (reg:SI 1) (const_int 20))))
-	(clobber (reg:SI LR_REGNO))]
-  "TARGET_32BIT && DEFAULT_ABI == ABI_AIX"
-  "#"
-  "&& reload_completed"
-  [(set (reg:SI 2)
-	(mem:SI (plus:SI (match_dup 3) (const_int 4))))
-   (parallel [(set (match_dup 0) (call (mem:SI (match_dup 1))
-				       (match_dup 2)))
-	      (use (reg:SI 2))
-	      (use (reg:SI 11))
-	      (set (reg:SI 2)
-		   (mem:SI (plus:SI (reg:SI 1) (const_int 20))))
-	      (clobber (reg:SI LR_REGNO))])]
-  ""
-  [(set_attr "type" "jmpreg")
-   (set_attr "length" "12")])
-
 (define_insn "*call_value_indirect_nonlocal_aix32"
   [(set (match_operand 0 "" "")
 	(call (mem:SI (match_operand:SI 1 "register_operand" "c,*l"))
-	      (match_operand 2 "" "g,g")))
-   (use (reg:SI 2))
+		      (match_operand 2 "" "g,g")))
+   (use (match_operand:SI 3 "memory_operand" "m,m"))
+   (set (reg:SI 2) (match_operand:SI 4 "memory_operand" "m,m"))
    (use (reg:SI 11))
-   (set (reg:SI 2)
-	(mem:SI (plus:SI (reg:SI 1) (const_int 20))))
    (clobber (reg:SI LR_REGNO))]
-  "TARGET_32BIT && DEFAULT_ABI == ABI_AIX && reload_completed"
-  "b%T1l\;{l|lwz} 2,20(1)"
+  "TARGET_32BIT && DEFAULT_ABI == ABI_AIX"
+  "{l|lwz} 2,%3\;b%T1l\;{l|lwz} 2,%4"
   [(set_attr "type" "jmpreg")
-   (set_attr "length" "8")])
+   (set_attr "length" "12")])
 
 (define_insn "*call_value_nonlocal_aix32"
   [(set (match_operand 0 "" "")
@@ -12581,45 +12558,19 @@  (define_insn "*call_value_nonlocal_aix32
   [(set_attr "type" "branch")
    (set_attr "length" "8")])
 
-(define_insn_and_split "*call_value_indirect_nonlocal_aix64_internal"
+(define_insn "*call_value_indirect_nonlocal_aix64"
   [(set (match_operand 0 "" "")
 	(call (mem:SI (match_operand:DI 1 "register_operand" "c,*l"))
 		      (match_operand 2 "" "g,g")))
-	(use (mem:DI (plus:DI (match_operand:DI 3 "register_operand" "b,b")
-			      (const_int 8))))
-	(use (reg:DI 11))
-	(use (mem:DI (plus:DI (reg:DI 1) (const_int 40))))
-	(clobber (reg:SI LR_REGNO))]
+   (use (match_operand:DI 3 "memory_operand" "m,m"))
+   (set (reg:DI 2) (match_operand:DI 4 "memory_operand" "m,m"))
+   (use (reg:DI 11))
+   (clobber (reg:DI LR_REGNO))]
   "TARGET_64BIT && DEFAULT_ABI == ABI_AIX"
-  "#"
-  "&& reload_completed"
-  [(set (reg:DI 2)
-	(mem:DI (plus:DI (match_dup 3) (const_int 8))))
-   (parallel [(set (match_dup 0) (call (mem:SI (match_dup 1))
-				       (match_dup 2)))
-	      (use (reg:DI 2))
-	      (use (reg:DI 11))
-	      (set (reg:DI 2)
-		   (mem:DI (plus:DI (reg:DI 1) (const_int 40))))
-	      (clobber (reg:SI LR_REGNO))])]
-  ""
+  "ld 2,%3\;b%T1l\;ld 2,%4"
   [(set_attr "type" "jmpreg")
    (set_attr "length" "12")])
 
-(define_insn "*call_value_indirect_nonlocal_aix64"
-  [(set (match_operand 0 "" "")
-	(call (mem:SI (match_operand:DI 1 "register_operand" "c,*l"))
-	      (match_operand 2 "" "g,g")))
-   (use (reg:DI 2))
-   (use (reg:DI 11))
-   (set (reg:DI 2)
-	(mem:DI (plus:DI (reg:DI 1) (const_int 40))))
-   (clobber (reg:SI LR_REGNO))]
-  "TARGET_64BIT && DEFAULT_ABI == ABI_AIX && reload_completed"
-  "b%T1l\;ld 2,40(1)"
-  [(set_attr "type" "jmpreg")
-   (set_attr "length" "8")])
-
 (define_insn "*call_value_nonlocal_aix64"
   [(set (match_operand 0 "" "")
 	(call (mem:SI (match_operand:DI 1 "symbol_ref_operand" "s"))