[cfe-dev] Question about optimization of new and delete

Benjamin Kramer benny.kra at gmail.com
Mon Sep 30 05:58:36 PDT 2013


On 29.09.2013, at 19:04, Nicola Gigante <nicola.gigante at gmail.com> wrote:

> Hello.
> 
> Probably this is an old enough question, sorry in this case.
> 
> I was wondering which optimizations clang/llvm does (or can do, given restrictions from the standard)
> about the use of default new/delete operators.
> 
> In particular, I'm wondering about a couple of interesting cases:
> 
> 1) Can clang convert a call to default operator new to stack allocation, if it can prove that
> the lifetime of the allocated memory is the same as the enclosing scope?
> Would it be someway contrary to the standard or somewhat undesirable?
> 
> Trivial example:
> 
> void func() {
>    Class *obj = new Class(args);
>    obj->stuff();
>    delete obj;
> }
> 
> Trying to compile something simple like this, I see the couple of operator calls are elided, but in more complex cases in 
> my code this does not happen, and I would like to know why (is the effect of a tradeoff with the size of the allocated memory?)
> 
> 2) Can clang/llvm identify as a dead store a write to a piece of memory that will be delete?
> 
> void func(Class *obj) {
>    obj->member = 42; // Is this store removed?
>    delete obj;
> }
> 
> Compiling this exact code with -O3, I see the store still there.

I've been fighting similar patterns recently. The IR looks like this:

define void @_Z4funcP5Class(%struct.Class* %obj) #0 {
entry:
  %member = getelementptr inbounds %struct.Class* %obj, i64 0, i32 0
  store i32 42, i32* %member, align 4, !tbaa !0
  %isnull = icmp eq %struct.Class* %obj, null
  br i1 %isnull, label %delete.end, label %delete.notnull

delete.notnull:                                   ; preds = %entry
  %0 = bitcast %struct.Class* %obj to i8*
  tail call void @_ZdlPv(i8* %0) #2
  br label %delete.end

delete.end:                                       ; preds = %delete.notnull, %entry
  ret void
}

The superfluous NULL check here is preventing the elimination of the store. In my opinion we should optimize this based on the assumption that a pointer can't be NULL after a load/store to it. GCC does this and got some flak because it turned a crash into a security problem in the Linux kernel (-fno-delete-null-pointer-checks was introduced as a remedy). I'm not sure how to best implement that with our current VRP infrastructure.

- Ben



More information about the cfe-dev mailing list