Now I am debugging a function named RAGreedy::selectOrSplit(). Two functions called by it, “trySplit()” and “spill()”. I am lost in them long time.
I am very confused why it must split VirtReg’s LiveRange, and where I can delete the redundant COPY? Or is there any function estimates if a COPY is redundant?
For example, one IR after trySplit():
ST_dword_ri32_reg %vreg203, <fi#10>, 0, 0; GR32:%vreg203
%vreg24 = SHR_ri7 %vreg203, 31; GR32:%vreg24, %vreg203
%vreg202 = COPY %vreg203; GR32:%vreg202, %vreg203
%vreg23 = LD_dword_ri32 %vreg43, ga:wn32, 0; mem:LD4%real15 GR32:%vreg23, %vreg43
I consider the COPY is redundant.
Any advice will be appreciated. Thanks in advance.
I don’t think there’s enough information in this snippet to follow the specific decisions that the register allocator is making.
Live range splitting inserts copy instructions to break up live intervals in an effort to relax the constraints on the register allocation problem. The copies that are introduced could be removed again, but only by fusing the interval back together, which would re-introduce the constraints that the splitter was trying to remove. The allocator plays it safe: it splits to remove constraints when it needs to (i.e it runs out of registers that satisfy the current constraints), then it removes copies only if it is able to assign the same register to both the source and destination (i.e. only after it knows it has a solution that satisfies the constraints it is re-introducing).
So to answer your question (I hope): The copy was introduced to relax constraints. Removing it would re-introduce the constraints, which you don’t want to do. Hopefully it will be eliminated later by an opportunistic coloring, but this cannot be guaranteed.