[PATCH] Teach DeadArgElimination not to eliminate return values of functions with 'returned' arguments

Dan Gohman dan433584 at gmail.com
Mon Jun 24 11:04:33 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.

Dan
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130624/bfc5c114/attachment.html>


More information about the llvm-commits mailing list