http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56148



--- Comment #6 from Steven Bosscher <steven at gcc dot gnu.org> 2013-02-12 
00:14:47 UTC ---

In gcc 4.7.2, reload resolved this with a pair of moves.



>From the .197r.ira and 198r.reload dumps, with the asm_operands

split out and the insns before the asm condensed, for readability:



.197r.ira_gcc472 (.208r.ira_gcc480 is identical except for insn uids):

(insn 5 (set (reg:SI 67) (const_int -1)))

(insn 6 (set (reg/f:DI 68) // and clobber flags, irrelevant

            (plus:DI (reg/f:DI 20 frame) (const_int -16)))

(insn 17 6 18 2 (set (reg:DI 65 [ d ]) (reg/f:DI 68)))  

(insn 18 (set (reg:SI 69) (const_int 4)))  // 128>>5

(insn 10 18 0 2 (parallel [

            (set (reg:DI 63 [ a ])

                (asm_operands/v:DI ("") ("=d") 0 ...))

            (set (reg:DI 64 [ c ])

                (asm_operands/v:DI ("") ("=&c") 1 ...))

            (set (reg:DI 65 [ d ])

                (asm_operands/v:DI ("") ("=&D") 2 ...))

            (set (reg:DI 66 [ b ])

                (asm_operands/v:DI ("") ("=&a") 3 ...))

            (clobber (reg:QI 18 fpsr))

            (clobber (reg:QI 17 flags))

        ]) t.c:6 -1)



asm output operands:

                    [   

                        (reg:SI 67)

                        (reg:DI 65 [ d ])

                        (reg:SI 69)

                        (reg:DI 65 [ d ])

                        (reg:SI 67)

                    ]

asm input operands: 

                    [   

                        (asm_input:SI ("0") (null):0)

                        (asm_input:DI ("mr") (null):0)

                        (asm_input:SI ("1") (null):0)

                        (asm_input:DI ("2") (null):0)

                        (asm_input:SI ("3") (null):0)

                    ]





.198r.reload_gcc472 (no gcc480 equivalent due to ICE):

(insn 5 (set (reg:SI 0 ax [67]) (const_int -1)))             

(insn 17 (set (reg:DI 5 di [orig:65 d] [65])

        (plus:DI (reg/f:DI 7 sp) (const_int -24))))

(insn 18 (set (reg:SI 2 cx [69]) (const_int 4)))

(insn 21 (set (reg:SI 1 dx) (reg:SI 0 ax [67]))) // reload

(insn 22 (set (reg:DI 4 si) (reg:DI 5 di [orig:65 d] [65]))) // reload

(insn 10 22 19 2 (parallel [

            (set (reg:DI 1 dx [orig:63 a] [63])

                (asm_operands/v:DI ("") ("=d") 0 ...))

            (set (reg:DI 2 cx [orig:64 c] [64])

                (asm_operands/v:DI ("") ("=&c") 1 ...))

            (set (reg:DI 5 di [orig:65 d] [65])

                (asm_operands/v:DI ("") ("=&D") 2 ...))

            (set (reg:DI 0 ax [orig:66 b] [66])

                (asm_operands/v:DI ("") ("=&a") 3 ...))

            (clobber (reg:QI 18 fpsr))

            (clobber (reg:QI 17 flags))

        ]) t.c:6 -1)



asm output operands:

                    [

                        (reg:SI 1 dx)

                        (reg:DI 4 si)

                        (reg:SI 2 cx [69])

                        (reg:DI 5 di [orig:65 d ] [65])

                        (reg:SI 0 ax [67])

                    ]

asm input operands: 

                    [

                        (asm_input:SI ("0") (null):0)

                        (asm_input:DI ("mr") (null):0)

                        (asm_input:SI ("1") (null):0)

                        (asm_input:DI ("2") (null):0)

                        (asm_input:SI ("3") (null):0)

                    ]







LRA tries a *lot* more than just two moves:



Creates new registers:

         Choosing alt 0 in insn 10:  (0) =d  (1) =&c  (2) =&D  (3) =&a  (4) 0 

(5) mr  (6) 1  (7) 2  (8) 3

      Creating newreg=73 from oldreg=63, assigning class DREG to r73

      Creating newreg=74 from oldreg=65, assigning class DIREG to r74

      Creating newreg=75 from oldreg=66, assigning class AREG to r75

   10:

{r73:DI=asm_operands;r64:DI=asm_operands;r74:DI=asm_operands;r75:DI=asm_operands;clobber

fpsr:QI;clobber flags:QI;}

      REG_DEAD r69:SI

      REG_DEAD r67:SI

      REG_UNUSED r66:DI

      REG_UNUSED r65:DI

      REG_UNUSED r64:DI

      REG_UNUSED r63:DI

      REG_UNUSED fpsr:QI

      REG_UNUSED flags:QI

    Inserting insn reload before:

   20: clobber r73:DI

   21: r73:DI#0=r67:SI

   22: r74:DI=r65:DI

   23: clobber r75:DI

   24: r75:DI#0=r67:SI



The sets to the subregs of r73 and r75 are the loads of -1U which

is in r67:SI as per insn 5.



The first two of the new registers could be the same moves that reload

attempts to make, but it's difficult to tell because of the slim RTL

dumps. GDB will tell... In any case, if r64 is created for the second

move from reload (insn 22), then LRA is trying DIREG for it while reload

uses SIREG.







Next LRA tries and fails with some inheritance attempts:

         Assigning to 73 (cl=DREG, orig=63, freq=3000, tfirst=73,

tfreq=3000)...

           Assign 1 to reload r73 (freq=3000)

         Assigning to 75 (cl=AREG, orig=66, freq=3000, tfirst=75,

tfreq=3000)...

         Trying 0: spill 67(freq=3000)   Now best 0(cost=-1000)



      Spill r67(hr=0, freq=3000) for r75

           Assign 0 to reload r75 (freq=3000)

         Assigning to 74 (cl=DIREG, orig=65, freq=2000, tfirst=74,

tfreq=2000)...

         Trying 5: spill 65(freq=3000)   Now best 5(cost=1000)



      Spill r65(hr=5, freq=3000) for r74

           Assign 5 to reload r74 (freq=2000)

         Assigning to 72 (cl=GENERAL_REGS, orig=72, freq=2000, tfirst=72,

tfreq=2000)...

           Assign 5 to reload r72 (freq=2000)

  Reassigning non-reload pseudos

           Assign 4 to r65 (freq=3000)

           Assign 37 to r67 (freq=3000)



Creates some more new registers for the previous new registers:

         Choosing alt 0 in insn 10:  (0) =d  (1) =&c  (2) =&D  (3) =&a  (4) 0 

(5) mr  (6) 1  (7) 2  (8) 3

      Creating newreg=76 from oldreg=74, assigning class DIREG to r76

      Creating newreg=77 from oldreg=75, assigning class AREG to r77

   10:

{r73:DI=asm_operands;r64:DI=asm_operands;r76:DI=asm_operands;r77:DI=asm_operands;clobber

fpsr:QI;clobber flags:QI;}

      REG_UNUSED r74:DI

      REG_UNUSED r73:DI

      REG_UNUSED r75:DI

      REG_DEAD r65:DI

      REG_DEAD r69:SI

      REG_UNUSED r64:DI

    Inserting insn reload before:

   25: r76:DI=r74:DI

   26: clobber r77:DI

   27: r77:DI#0=r75:DI#0



Tries and fails again with some inheritance attempts, and gives up:

         Assigning to 77 (cl=AREG, orig=66, freq=3000, tfirst=77,

tfreq=3000)...

         Assigning to 76 (cl=DIREG, orig=65, freq=2000, tfirst=76,

tfreq=2000)...

           Assign 5 to reload r76 (freq=2000)

  2nd iter for reload pseudo assignments:

         Reload r77 assignment failure

          Spill reload r75(hr=0, freq=3000)

          Spill reload r73(hr=1, freq=3000)

          Spill reload r76(hr=5, freq=2000)

         Assigning to 73 (cl=DREG, orig=63, freq=3000, tfirst=73,

tfreq=3000)...

           Assign 1 to reload r73 (freq=3000)

         Assigning to 75 (cl=AREG, orig=66, freq=3000, tfirst=75,

tfreq=3000)...

           Assign 0 to reload r75 (freq=3000)

         Assigning to 77 (cl=AREG, orig=66, freq=3000, tfirst=77,

tfreq=3000)...

         Assigning to 76 (cl=DIREG, orig=65, freq=2000, tfirst=76,

tfreq=2000)...

           Assign 5 to reload r76 (freq=2000)

           Assign 0 to reload r77 (freq=3000)

deleting insn with uid = 10.

Reply via email to