From patchwork Thu Sep 15 18:04:29 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: , PR 50341, Fix TOC load scheduling for powerpc on GCC 4.6 and 4.7 (patches included) Date: Thu, 15 Sep 2011 08:04:29 -0000 From: Michael Meissner X-Patchwork-Id: 114814 Message-Id: <20110915180429.GA6038@hungry-tiger.westford.ibm.com> To: gcc-patches@gcc.gnu.org, dje.gcc@gmail.com It would help if I included the patches: [gcc-4.6] 2011-09-15 Alan Modra Michael Meissner 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 Michael Meissner PR target/50341 * config/rs6000/rs6000.md (call_indirect_aix): 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_internal): Ditto. (call_indirect_aix_nor11): Ditto. (call_indirect_aix_internal2): Ditto. (call_value_indirect_aix): Ditto. (call_value_indirect_aix_internal): Ditto. (call_value_indirect_aix_nor11): Ditto. (call_value_indirect_aix_internal2): Ditto. 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"))