This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Optimizing away deletion of null pointers with g++


When compiling the following code:

int* ptr = nullptr;
delete ptr;

GCC 7.1 on x86_64 generates a delete-operator-related call instruction in the resulting program with both -O2 and -O3 optimization flags. This is a nonsense piece of code, indeed, but imagine a class that has an owning raw pointer (please, don't tell me to use unique_ptr, there are such classes in the real world). Then, this class needs to call delete in its move assignment operator and destructor:

class X {
  T* ptr_;
public:
  X() ptr_(nullptr) { }
  X& operator=(X&& rhs) {
    delete ptr_;
    ptr_ = rhs.ptr_;
    rhs.ptr_ = nullptr;
    return *this;
  }
  ~X() { delete ptr_; }
  ...
};
Invoking std::swap with objects of class X then yields deletion of null pointer 3 times (2 times within move assignment operator and once within destructor). Since GCC doesn't optimize out these null-pointer deletions and generate corresponding call instructions, whole swapping has some performance penalty.

I found out that if I change 'delete ptr_;' to 'if (ptr_) delete ptr_;', then no call instructions are generated. So, I did a benchmark that sorted 100M randomly-shuffled objects of class X (where T was int) with std::sort. Here are measured sorting times:

1) 40.8 seconds with plain 'delete ptr_;',
2) 31.5 seconds with 'if (ptr_) delete ptr_;',
3) 31.3 seconds with additional custom swap free function for class X.

This is quite a big performance difference between first two cases. Wouldn't be nice if g++ was able to optimize out deletion of null pointers? I guess in cases such as above mentioned one the null pointers can be recognized by static analysis. (As far as I know omitting delete operator calls is standard-compliant. Both Clang and Intel compilers did this in my tests.)

Cheers,
Daniel


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]