[CodeGen] Disable aggressive structor optimizations at -O0
authorPavel Labath <labath@google.com>
Mon, 14 May 2018 11:02:23 +0000 (11:02 +0000)
committerPavel Labath <labath@google.com>
Mon, 14 May 2018 11:02:23 +0000 (11:02 +0000)
Summary:
Removing the full structor and replacing all usages with the base one
can degrade debug quality as it will leave the debugger unable to locate
the full object structor. This is apparent when evaluating an expression
in the debugger which requires constructing an object of class which has
had this optimization applied to it.  When compiling the expression, we
pretend that the class and its methods have been defined in another
compilation unit, so the expression compiler assumes the structor
definition must be available. This didn't use to be the case for
structors with internal linkage. Less aggressive optimizations like
emitting the full structor as an alias remain in place, as they do not
cause the structor symbol to disappear completely.

This improves debug quality on non-darwin platforms (darwin does not
have -mconstructor-aliases on by default, so it is spared these
problems) and enable us to remove some workarounds from LLDB which attempt to
mitigate this issue.

Reviewers: rjmccall, aprantl

Subscribers: cfe-commits

Differential Revision: https://reviews.llvm.org/D46685

llvm-svn: 332228

clang/lib/CodeGen/ItaniumCXXABI.cpp
clang/test/CodeGenCXX/ctor-dtor-alias.cpp
clang/test/CodeGenCXX/float16-declarations.cpp

index e7d4d8a..89a0576 100644 (file)
@@ -3630,12 +3630,16 @@ static StructorCodegen getCodegenToUse(CodeGenModule &CGM,
   }
   llvm::GlobalValue::LinkageTypes Linkage = CGM.getFunctionLinkage(AliasDecl);
 
-  if (llvm::GlobalValue::isDiscardableIfUnused(Linkage))
-    return StructorCodegen::RAUW;
-
-  // FIXME: Should we allow available_externally aliases?
-  if (!llvm::GlobalAlias::isValidLinkage(Linkage))
-    return StructorCodegen::RAUW;
+  // Only use RAUW in optimized code, as it makes the complete structor symbol
+  // disappear completely, which degrades debugging experience.
+  if (CGM.getCodeGenOpts().OptimizationLevel > 0) {
+    if (llvm::GlobalValue::isDiscardableIfUnused(Linkage))
+      return StructorCodegen::RAUW;
+
+    // FIXME: Should we allow available_externally aliases?
+    if (!llvm::GlobalAlias::isValidLinkage(Linkage))
+      return StructorCodegen::RAUW;
+  }
 
   if (llvm::GlobalValue::isWeakForLinker(Linkage)) {
     // Only ELF and wasm support COMDATs with arbitrary names (C5/D5).
index d72c5b4..4e830c1 100644 (file)
@@ -77,11 +77,12 @@ namespace test4 {
   // CHECK1: call i32 @__cxa_atexit{{.*}}_ZN5test41AD2Ev
   // CHECK1: define linkonce_odr void @_ZN5test41AD2Ev({{.*}} comdat align
 
-  // test that we don't do this optimization at -O0 so that the debugger can
-  // see both destructors.
+  // test that we don't do this optimization at -O0 and call the complete
+  // destructor for B instead. This enables the debugger to see both
+  // destructors.
+  // NOOPT: @_ZN5test41BD1Ev = linkonce_odr alias void {{.*}} @_ZN5test41BD2Ev
   // NOOPT: define internal void @__cxx_global_var_init.2()
-  // NOOPT: call i32 @__cxa_atexit{{.*}}@_ZN5test41BD2Ev
-  // NOOPT: define linkonce_odr void @_ZN5test41BD2Ev({{.*}} comdat align
+  // NOOPT: call i32 @__cxa_atexit{{.*}}@_ZN5test41BD1Ev
   struct A {
     virtual ~A() {}
   };
index e82c05e..1d6999f 100644 (file)
@@ -103,7 +103,7 @@ int main(void) {
 
   C1 c1(f1l);
 // CHECK-DAG:  [[F1L:%[a-z0-9]+]] = load half, half* %{{.*}}, align 2
-// CHECK-DAG:  call void @_ZN2C1C2EDF16_(%class.C1* %{{.*}}, half %{{.*}})
+// CHECK-DAG:  call void @_ZN2C1C1EDF16_(%class.C1* %{{.*}}, half %{{.*}})
 
   S1<_Float16> s1 = { 132.f16 };
 // CHECK-DAG: @_ZZ4mainE2s1 = private unnamed_addr constant %struct.S1 { half 0xH5820 }, align 2