[llvm-dev] alloca combining, not (yet) possible ?
Nat! via llvm-dev
llvm-dev at lists.llvm.org
Mon Aug 31 06:21:51 PDT 2015
Caldarale, Charles R schrieb:
> You have not provided us with the declaration for f(). Unless its argument is marked with the nocapture attribute, the compilation of g() cannot assume that f() has not retained a pointer to the x struct and is using it in the second call.
>
thanks a lot for the input. Yes, I forgot to that. The C function
declaration would have been
void f( struct a_b *p);
which compiled into
declare void @f(%struct.a_b*) #2
with
attributes #2 = { "disable-tail-calls"="false"
"less-precise-fpmad"="false" "no-frame-pointer-elim"="true"
"no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false"
"no-nans-fp-math"="false" "stack-protector-buffer-size"="8"
"target-cpu"="core2" "target-features"="+cx16,+sse,+sse2,+sse3,+ssse3"
"unsafe-fp-math"="false" "use-soft-float"="false" }
---
I could not figure out how to decorate my C code to emit the nocapture
attribute, __attribute(( nocapture) is unknown. So I tried to modify the
IR code by hand to read thusly:
declare void @f(%struct.a_b* nocapture) #1
But in the end, it didn't make a difference, when I compiled it with
../llvm-build.d/bin/llc -O3 -o test-combine-alloca.s test-combine-alloca.ir
it still used two allocas.
From a C perspective, I find it weird, that it should concern the
caller if the called function "mistakenly" holds onto an alloca buffer,
that will be invalid soon anyway. But I guess that's C++ magic somehow :)
Ciao
Nat!
----
; ModuleID = 'test-combine-alloca.c'
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
target triple = "x86_64-apple-macosx10.10.0"
%struct.a_b = type { i32, i32 }
declare void @f(%struct.a_b* nocapture) #1
; Function Attrs: nounwind ssp uwtable
define void @g() #0 {
entry:
%x = alloca %struct.a_b, align 4
%y = alloca %struct.a_b, align 4
%a = getelementptr inbounds %struct.a_b, %struct.a_b* %x, i32 0, i32 0
store i32 1, i32* %a, align 4
%b = getelementptr inbounds %struct.a_b, %struct.a_b* %x, i32 0, i32 1
store i32 2, i32* %b, align 4
call void @f(%struct.a_b* %x)
%a1 = getelementptr inbounds %struct.a_b, %struct.a_b* %y, i32 0, i32 0
store i32 1, i32* %a1, align 4
%b2 = getelementptr inbounds %struct.a_b, %struct.a_b* %y, i32 0, i32 1
store i32 3, i32* %b2, align 4
call void @f(%struct.a_b* %y)
ret void
}
attributes #0 = { nounwind ssp uwtable "disable-tail-calls"="false"
"less-precise-fpmad"="false" "no-frame-pointer-elim"="true"
"no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false"
"no-nans-fp-math"="false" "stack-protector-buffer-size"="8"
"target-cpu"="core2" "target-features"="+cx16,+sse,+sse2,+sse3,+ssse3"
"unsafe-fp-math"="false" "use-soft-float"="false" }
attributes #1 = { "disable-tail-calls"="false"
"less-precise-fpmad"="false" "no-frame-pointer-elim"="true"
"no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false"
"no-nans-fp-math"="false" "stack-protector-buffer-size"="8"
"target-cpu"="core2" "target-features"="+cx16,+sse,+sse2,+sse3,+ssse3"
"unsafe-fp-math"="false" "use-soft-float"="false" }
!llvm.module.flags = !{!0}
!llvm.ident = !{!1}
!0 = !{i32 1, !"PIC Level", i32 2}
!1 = !{!"clang version 3.7.0 (http://llvm.org/git/clang.git
36ba449caa88f710520cdce148457e5a75e9dabc) (http://llvm.org/git/llvm.git
dccade93466c50834dbaa5f4dabb81e90d768c40)"}
----
More information about the llvm-dev
mailing list