[PATCH] Teach DeadArgElimination not to eliminate return valuesof functions with 'returned' arguments
Nuno Lopes
nunoplopes at sapo.pt
Mon Jun 24 14:43:43 PDT 2013
> On Sun, Jun 23, 2013 at 10:57 AM, Stephen Lin
> <swlin at post.harvard.edu>wrote:
>
>> > This does conflict with the theoretical separation of concerns between
>> > optimizer and codegen in LLVM though. This patch does not promote
>> subsequent
>> > mid-level optimization opportunities; treating values as live when they
>> are
>> > actually unused may actually obscure other mid-level optimization
>> > opportunities.
>> >
>> > Dan
>> >
>>
>> I understand, and I'm not thrilled about it either, but is there an
>> alternative course of action you can think of? The problem is that the
>> return value provides potentially valuable information, and there's no
>> good way (as far as I can tell) to get it back at the CodeGen level if
>> it's dropped from the IR because it would require interprocedural
>> coordination of code generation.
>>
>
> No, I don't have any alternatives, other than interprocedural coordination
> of code generation. Do you have any alternatives?
>
>
>> Also, in theory, some mid level optimization could be done, even if it
>> is not done now. A 'returned' argument implies the argument and return
>> value are aliases of each other in all code dominated by the function
>> call, so IR optimizers would be free to replace one with the other. As
>> mentioned in other e-mails, it is, the problem is that, in the general
>> case, it is difficult to know which alternative to pick; however, an
>> IR pass could, at a minimum, canonicalize this:
>>
>> %struct.A = type { i32 }
>>
>> declare %struct.A* @a_ctor(%struct.A* returned)
>> declare void @bar(%struct.A*)
>>
>> define %struct.A* @foo() {
>> entry:
>> %a = alloca %struct.A, align 4
>> %b = call %struct.A* @a_ctor(%struct.A* %a)
>> call void @bar(%struct.A* %a)
>> ret %struct.A* %b
>> }
>>
>
> The canonical form would be:
>
> %struct.A = type { i32 }
>
> declare %struct.A* @a_ctor(%struct.A* returned)
> declare void @bar(%struct.A*)
>
> define %struct.A* @foo() {
> entry:
> %a = alloca %struct.A, align 4
> %b = call %struct.A* @a_ctor(%struct.A* %a)
> call void @bar(%struct.A* %a)
> ret %struct.A* %a
> }
>
> In other words, it's advantageous to see the actual value, and there's no
> mid-level optimizer benefit to seeing the return value.
The problem is this canonical form inhibits tail calls, which is an
important optimization. We could have a smarter tail call pass to recover
the information later on, though.
(I must confess I only skimmed through this thread, so sorry if this comment
has been made before. Just wanted to make sure you remembered of this
detail).
Nuno
More information about the llvm-commits
mailing list