[LLVMbugs] [Bug 13363] New: Missed optimization when arguments are passed in callee-saved registers
bugzilla-daemon at llvm.org
bugzilla-daemon at llvm.org
Sat Jul 14 17:10:19 PDT 2012
http://llvm.org/bugs/show_bug.cgi?id=13363
Bug #: 13363
Summary: Missed optimization when arguments are passed in
callee-saved registers
Product: libraries
Version: trunk
Platform: PC
OS/Version: Linux
Status: NEW
Severity: enhancement
Priority: P
Component: Common Code Generator Code
AssignedTo: unassignedbugs at nondot.org
ReportedBy: borja.ferav at gmail.com
CC: llvmbugs at cs.uiuc.edu
Classification: Unclassified
The following missed optimization is from an out of tree target and happens
when some of the input arguments of a function are being passed in callee saved
registers.
Consider the following piece of code:
(reg pairs and ints are 16bits wide)
extern void foo(int);
int bar(int a, int b, char c, float d, int e, char f)
{
foo(e);
return e;
}
Generates:
push r14
push r15
push r28
push r29
movw r29:r28, r15:r14 ; make a copy of e
movw r25:r24, r29:r28 ; move e to call foo
call foo
movw r25:r24, r29:r28 ; move copy of e to return
pop r29
pop r28
pop r15
pop r14
ret
Argument "e" comes in r15:r14 (a callee saved reg) and it's moved to r25:r24 to
pass it to foo. But notice it is also being copied to another CS reg (r29:r28)
to be restored after the function call so it can be returned by bar.
Since r15:r14 is a CS reg, it's guaranteed that the call won't modify its
contents, making the copy unncessary, with the result of needing to save and
restore a new CS reg.
Final code should look like this:
push r14
push r15
movw r25:r24, r15:r14 ; move e to make the call
call foo
movw r25:r24, r15:r14 ; move e to return reg
pop r15
pop r14
ret
If I don't pass "e" to foo then it gets optimized, but when the argument is
passed to a function this happens. Of course things get worse when more
arguments come to play, but this is simplified test case.
SSA code before regalloc is:
Function Live Ins: %R15R14 in %vreg5
Function Live Outs: %R25R24
BB#0: derived from LLVM BB %entry
Live Ins: %R15R14
%vreg5<def> = COPY %R15R14<kill>; DREGS:%vreg5
ADJCALLSTACKDOWN 0, %SP<imp-def>, %SREG<imp-def,dead>, %SP<imp-use>
%R25R24<def> = COPY %vreg5; DREGS:%vreg5
CALLk <ga:@foo>, %R25R24<kill>, <regmask>, %SP<imp-use>, %SP<imp-def>
ADJCALLSTACKUP 0, 0, %SP<imp-def>, %SREG<imp-def,dead>, %SP<imp-use>
%R25R24<def> = COPY %vreg5<kill>; DREGS:%vreg5
RET %R25R24<imp-use,kill>
notice how vreg5 is copied to R25:R24 before the ret.
However after regalloc:
%R29R28<def> = MOVWRdRr %R15R14<kill>
see that R15:R14 is marked as killed.
One more place of improvement is that although r15:r14 is a callee saved reg,
in this function it's not being written at all so the push+pop pairs are not
needed. If foo changed its value, it's responsible for saving and restoring its
contents, but the caller bar is safe to make this optimization.
So at the end it should be:
movw r25:r24, r15:r14 ; move e to make the call
call foo
movw r25:r24, r15:r14 ; move e to return reg
ret
--
Configure bugmail: http://llvm.org/bugs/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.
More information about the llvm-bugs
mailing list