[llvm-dev] Help required regarding IPRA and Local Function optimization

vivek pandya via llvm-dev llvm-dev at lists.llvm.org
Thu Jun 30 01:51:31 PDT 2016


Hello Mentors,

I am currently finding bug in Local Function related optimization due to
which runtime failures are observed in some test cases, as those test cases
are containing very large function with recursion and object oriented code
so I am not able to find a pattern which is causing failure. So I tried
following simple case to understand expected behavior from this
optimization.

Consider following code :

define void @bar() #0 {
  call void asm sideeffect "movl %ecx, %r15d", "~{r15}"() #0
  call void @foo()
  call void asm sideeffect "movl %r15d, %ebx", "~{rbx}"() #0
  ret void
}

define internal void @foo() #0 {
  call void asm sideeffect "movl %r14d, %r15d", "~{r15}"() #0
  ret void
}

and its generated assembly code when IPRA enabled:

.section __TEXT,__text,regular,pure_instructions
.macosx_version_min 10, 12
.p2align 4, 0x90
_foo:                                   ## @foo
.cfi_startproc
## BB#0:
## InlineAsm Start
movl %r14d, %r15d
## InlineAsm End
retq
.cfi_endproc

.globl _bar
.p2align 4, 0x90
_bar:                                   ## @bar
.cfi_startproc
## BB#0:
pushq %r15
Ltmp0:
.cfi_def_cfa_offset 16
pushq %rbx
Ltmp1:
.cfi_def_cfa_offset 24
pushq %rax
Ltmp2:
.cfi_def_cfa_offset 32
Ltmp3:
.cfi_offset %rbx, -24
Ltmp4:
.cfi_offset %r15, -16
## InlineAsm Start
movl %ecx, %r15d
## InlineAsm End
callq _foo
## InlineAsm Start
movl %r15d, %ebx
## InlineAsm End
addq $8, %rsp
popq %rbx
popq %r15
retq
.cfi_endproc


.subsections_via_symbols

now foo clobbers R15 (which is callee saved) but as foo is local function
IPRA will mark R15 as clobbered and foo will not have save/restore for R15
in prologue/epilog . Now for above function code to work correctly in call
site of foo in bar save and restore of R15 is expected but I am not able to
find a pass in llvm which does that in fact if I am not wrong RegMasks of
call site will be used by reg allocators
by LiveIntervals::checkRegMaskInterference and due to that if R15 is marked
clobbered  by call _foo then R15 will not be used for live-range which is
spanned across call _foo. ( that it self is other concerns because it may
result in virtual reg spill due to lack of available regs, as while setting
callee saved regs none it will be propagated through regmaks)

Here are my questions related to this example:
1) Is there any pass or code in LLVM which is responsible for caller saved
register for Physical Registers? By looking at InlineSpiller.cpp it is
responsible for VReg spilling.
2) If such pass exists then why R15 is not saved around call __foo?
3) Why _bar is saving %rax in above code?

Please help!

Sincerely,
Vivek
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20160630/64436cd3/attachment.html>


More information about the llvm-dev mailing list