Query on optimizing away function calls.

Hi Duncan,

Message: 15
Date: Thu, 18 Jun 2009 10:58:47 +0200
From: Duncan Sands <baldrick@free.fr>
Subject: Re: [LLVMdev] Query on optimizing away function calls.
To: LLVM Developers Mailing List <llvmdev@cs.uiuc.edu>
Message-ID: <4A3A01C7.8020707@free.fr>
Content-Type: text/plain; charset=ISO-8859-1; format=flowed

Hi,

> Consider the following code:
>
> ------------
> define void @func() {
> %a = alloca i32
> store i32 42, i32* %a
> call void @func2(i32* %a) nounwind
> ret void
> }
>
> define void @func2(i32* %a) nounwind {
> store i32 43, i32* %a
> ret void
> }
> ------------
>
> It is possible to optimize this to:
>
> ------------
> define void @func() {
> ret void
> }
>
> define void @func2(i32* %a) nounwind {
> store i32 43, i32* %a
> ret void
> }
> ------------
>
> which is just what I want. However, if @func2 is implemented in an external C
> library, is this not possible? Specifically, while optimizing:
>
> ------------
> define void @func() {
> %a = alloca i32
> store i32 42, i32* %a
> call void @func2(i32* %a) nounwind
> ret void
> }
>
> declare void @func2(i32* %a) nounwind
> ------------
>
> is there some way to specify that @func2 only modifies values accessible via %a,
> so that if all those values are ultimately discarded then the call to @func2
> itself can be discarded?

no, there is currently no way. There was some discussion of adding
attributes for this, but I think the conclusion was that there were
too many hairy details for not enough gain.

> The "readonly" function attribute looks to be too strict for this.

It is possible to put "readonly" on the call, rather than on func2
itself. So if your front-end somehow knows that this use of func2
has no real effect it could mark the call this way.

Here's where this question comes from, may be this use case inspires
someone :-). I've a "big.int", that should behave like an i32. The
big.int routines are provided by a C runtime. To illustrate:

Hi,

Here's where this question comes from, may be this use case inspires
someone :-). I've a "big.int", that should behave like an i32. The
big.int routines are provided by a C runtime. To illustrate:

----------------------
; int func(int a, int b) { int c = a; return b; }

; using a regular int
define i32 @func1(i32 %a, i32 %b) {
    %cp = alloca i32
    store i32 %a, i32* %cp
    ret i32 %b
}

%big.int = type { i32, i32, i32* }

; using this big.int
define %big.int* @func2(%big.int* %a, %big.int* %b) {
    %cp = alloca %big.int
    call void @big.int.copy.ctor(%big.int* %cp, %big.int* %b) nounwind
    call void @big.int.dtor(%big.int* %cp) nounwind
    ret %big.int* %b
}

declare void @big.int.copy.ctor(%big.int*, %big.int*) nounwind
declare void @big.int.dtor(%big.int*) nounwind
----------------------

LLVM being able to optimize away the unnecessary temp object would be a
big win here.

I don't see how it can be. Presumably the @big.int.dtor really does
something, like freeing memory. It has to be run, no?

Ciao,

Duncan.