[PATCH] -Wprofile-instr-out-of-date warnings due to certain destructor types not being assigned increment intrinsics

Betul Buyukkurt betulb at codeaurora.org
Tue May 19 17:03:48 PDT 2015


> Betul Buyukkurt <betulb at codeaurora.org> writes:
>> Hi bogner, dsule, davidxl,
>>
>> -fprofile-instr-generate does not emit counter increment intrinsics
>> for Dtor_Deleting and Dtor_Complete destructors with assigned
>> counters. This causes unnecessary [-Wprofile-instr-out-of-date]
>> warnings during profile-use runs even if the source has never been
>> modified since profile collection.
>>
>> http://reviews.llvm.org/D9861
>>
>> Files:
>>   lib/CodeGen/CGClass.cpp
>>   test/Profile/cxx-virtual-destructor-calls.cpp
>>
>> Index: lib/CodeGen/CGClass.cpp
>> ===================================================================
>> --- lib/CodeGen/CGClass.cpp
>> +++ lib/CodeGen/CGClass.cpp
>> @@ -1366,6 +1366,10 @@
>>    const CXXDestructorDecl *Dtor =
>> cast<CXXDestructorDecl>(CurGD.getDecl());
>>    CXXDtorType DtorType = CurGD.getDtorType();
>>
>> +  Stmt *Body = Dtor->getBody();
>> +  if (Body)
>> +    incrementProfileCounter(Body);
>> +
>
> I think it makes more sense to do this after the delegation and entering
> the try body, like we do in constructors, no?

I've been observing plenty warnings emitted from C++ codes. Tracking the
issue I saw that the Dtor_Deleting and other Dtor types have counters
assigned to them but no counter increment code is emitted. This causes no
profile data structures to be emitted for those functions as well. In
CodeGenPGO.cpp line 649, it says that:

" Clang emits several functions for the constructor and the destructor of
a class. Every function is instrumented, but we only want to provide
coverage for one of them. Because of that we only emit the coverage
mapping for the base constructor/destructor. "

I also see that the counter increment is currently done for base
destructor only. This patch removes all the [-Wprofile-instr-out-of-date]
warnings from the spec2000/2006 benchmarks.

>
>>    // The call to operator delete in a deleting destructor happens
>>    // outside of the function-try-block, which means it's always
>>    // possible to delegate the destructor body to the complete
>> @@ -1378,8 +1382,6 @@
>>      return;
>>    }
>>
>> -  Stmt *Body = Dtor->getBody();
>> -
>>    // If the body is a function-try-block, enter the try before
>>    // anything else.
>>    bool isTryBody = (Body && isa<CXXTryStmt>(Body));
>> @@ -1389,11 +1391,10 @@
>>
>>    // Enter the epilogue cleanups.
>>    RunCleanupsScope DtorEpilogue(*this);
>> -
>>    // If this is the complete variant, just invoke the base variant;
>>    // the epilogue will destruct the virtual bases.  But we can't do
>>    // this optimization if the body is a function-try-block, because
>> -  // we'd introduce *two* handler blocks.  In the Microsoft ABI, we
>> +  // we'd introduce *two* handler blocks.  In the Microsoft ABI, we
>>    // always delegate because we might not have a definition in this TU.
>>    switch (DtorType) {
>>    case Dtor_Comdat:
>> @@ -1414,12 +1415,9 @@
>>        break;
>>      }
>>      // Fallthrough: act like we're in the base variant.
>> -
>>    case Dtor_Base:
>>      assert(Body);
>>
>> -    incrementProfileCounter(Body);
>> -
>>      // Enter the cleanup scopes for fields and non-virtual bases.
>>      EnterDtorCleanups(Dtor, Dtor_Base);
>>
>> Index: test/Profile/cxx-virtual-destructor-calls.cpp
>> ===================================================================
>> --- /dev/null
>> +++ test/Profile/cxx-virtual-destructor-calls.cpp
>> @@ -0,0 +1,31 @@
>> +// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9.0 -emit-llvm
>> -main-file-name cxx-virtual-destructor-calls.cpp %s -o -
>> -fprofile-instr-generate | FileCheck %s
>> +
>> +struct Member {
>> +  ~Member();
>> +};
>> +
>> +struct A {
>> +  virtual ~A();
>> +};
>> +
>> +struct B : A {
>> +  Member m;
>> +  virtual ~B();
>> +};
>> +
>> +// Complete dtor
>> +// CHECK: @__llvm_profile_name__ZN1BD1Ev = private constant [9 x i8]
>> c"_ZN1BD1Ev", section "__DATA,__llvm_prf_names", align 1
>> +
>> +// Deleting dtor
>> +// CHECK: @__llvm_profile_name__ZN1BD0Ev = private constant [9 x i8]
>> c"_ZN1BD0Ev", section "__DATA,__llvm_prf_names", align 1
>> +
>> +// Complete dtor counters and profile data
>> +// CHECK: @__llvm_profile_counters__ZN1BD1Ev = private global [1 x i64]
>> zeroinitializer, section "__DATA,__llvm_prf_cnts", align 8
>> +// CHECK: @__llvm_profile_data__ZN1BD1Ev =
>> +
>> +// Deleting dtor counters and profile data
>> +// CHECK: @__llvm_profile_counters__ZN1BD0Ev = private global [1 x i64]
>> zeroinitializer, section "__DATA,__llvm_prf_cnts", align 8
>> +// CHECK: @__llvm_profile_data__ZN1BD0Ev =
>> +
>> +B::~B() { }
>> +
>>
>> EMAIL PREFERENCES
>>   http://reviews.llvm.org/settings/panel/emailpreferences/
>





More information about the cfe-commits mailing list