This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Register allocation problem?


Lars Brinkhoff <lars@nocrew.org> writes:

> Hello,
>
> I have a problem I believe is related to register allocation in GCC.
> The RTL code for this function:
>
>   int foo (int x, int y) { return -y; }
>
> looks like this before register allocation (dump 18.regmove):
>
>   (insn 4 23 5 (set (reg/v:SI 23)
>           (reg:SI 2 2)) 48 {movsi} (nil)
>       (expr_list:REG_DEAD (reg:SI 2 2)
>           (nil)))
>   
>   (note 5 4 12 NOTE_INSN_FUNCTION_BEG)
>   
>   (insn 12 5 16 (set (reg:SI 24)
>           (neg:SI (reg/v:SI 23))) 87 {negsi2} (insn_list 4 (nil))
>       (expr_list:REG_DEAD (reg/v:SI 23)
>           (nil)))
>   
>   (note 16 12 19 NOTE_INSN_FUNCTION_END)
>   
>   (insn 19 16 22 (set (reg/i:SI 1 1)
>           (reg:SI 24)) 48 {movsi} (insn_list 12 (nil))
>       (expr_list:REG_DEAD (reg:SI 24)
>           (nil)))
>   
>   (insn 22 19 0 (use (reg/i:SI 1 1)) -1 (insn_list 19 (nil))
>       (nil))
>
> And after register allocation (dump 21.greg):
>
>   (insn 4 23 5 (set (reg/v:SI 1 1 [23])
>           (reg:SI 2 2)) 48 {movsi} (nil)
>       (nil))
>   
>   (note 5 4 12 NOTE_INSN_FUNCTION_BEG)
>   
>   (insn 12 5 16 (set (reg:SI 1 1 [24])
>           (neg:SI (reg/v:SI 1 1 [23]))) 87 {negsi2} (insn_list 4 (nil))
>       (nil))
>   
>   (note 16 12 19 NOTE_INSN_FUNCTION_END)
>   
>   (insn 19 16 22 (set (reg/i:SI 1 1)
>           (reg:SI 1 1 [24])) 48 {movsi} (insn_list 12 (nil))
>       (nil))
>   
>   (insn 22 19 26 (use (reg/i:SI 1 1)) -1 (insn_list 19 (nil))
>       (nil))
>
> In the end, there is an unnecessary move (insn 4) that wouldn't have
> been there is pseudo 23 was put in hard reg 2 instead of 1.
> Is there a way to improve this situation?
Yes.
Use a better register allocation algorithm.
The new-regalloc-branch gives the following rtl pre-cse-after-reload:

;; Function foo

;; Register dispositions:
86 in 4  87 in 3  

;; Hard regs used:  3 4

(note 2 0 27 NOTE_INSN_DELETED)

;; Start of basic block 0, registers live: 1 [1] 4 [4] 67 [ap]
(note 27 2 6 [bb 0] NOTE_INSN_BASIC_BLOCK)

(insn 6 27 7 (set (reg:SI 4 r4 [86])
        (reg:SI 4 r4)) 286 {*movsi_internal1} (nil)
    (nil))

(note 7 6 14 NOTE_INSN_FUNCTION_BEG)

(insn 14 7 19 (set (reg:SI 3 r3 [87])
        (neg:SI (reg:SI 4 r4 [86]))) 56 {negsi2} (insn_list 6 (nil))
    (nil))

(note 19 14 23 NOTE_INSN_FUNCTION_END)

(insn 23 19 26 (set (reg/i:SI 3 r3)
        (reg:SI 3 r3 [87])) 286 {*movsi_internal1} (insn_list 14 (nil))
    (nil))

(insn 26 23 30 (use (reg/i:SI 3 r3)) -1 (insn_list 23 (nil))
    (nil))
;; End of basic block 0, registers live:
 1 [1] 3 [3] 31 [31] 67 [ap]

(note 30 26 0 NOTE_INSN_DELETED)

It coalesces both regs to the same hard reg (It actually knows the
moves become noops, but because we still have reload, and it does
weird things at times, we don't flat out delete the noop moves we
create, since they'll get removed post reload anyway.)

Which the cse pass after reload turns into:

;; Function foo

(note 2 0 27 NOTE_INSN_DELETED)

;; Start of basic block 0, registers live: 1 [1] 4 [4] 67 [ap]
(note 27 2 6 [bb 0] NOTE_INSN_BASIC_BLOCK)

(note 6 27 7 NOTE_INSN_DELETED)

(note 7 6 14 NOTE_INSN_FUNCTION_BEG)

(insn 14 7 19 (set (reg:SI 3 r3 [87])
        (neg:SI (reg:SI 4 r4 [86]))) 56 {negsi2} (insn_list 6 (nil))
    (nil))

(note 19 14 23 NOTE_INSN_FUNCTION_END)

(insn 23 19 26 (use (reg/i:SI 3 r3)) -1 (insn_list 14 (nil))
    (nil))

(insn 26 23 30 (use (reg/i:SI 3 r3)) -1 (insn_list 23 (nil))
    (nil))
;; End of basic block 0, registers live:
 1 [1] 3 [3] 31 [31] 67 [ap]

(note 30 26 0 NOTE_INSN_DELETED)


Which is ideal code here.
--Dan

-- 
"I got up one morning and couldn't find my socks, so I called
Information.  She said, "Hello, Information."  I said, "I can't
find my socks."  She said, "They're behind the couch."  And they
were!
"-Steven Wright


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]