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

Hal Finkel hfinkel at anl.gov
Mon Sep 30 06:24:28 PDT 2013


----- Original Message -----
> 
> 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.

Interesting. Do you mean that the kernel will not internally fault if it stores to some place near 0x0? Or was the offset so large that it was going someplace valid?

In any case, I guess that we should probably do the same.

 -Hal

> 
> - Ben
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
> 

-- 
Hal Finkel
Assistant Computational Scientist
Leadership Computing Facility
Argonne National Laboratory



More information about the cfe-dev mailing list