]> granicus.if.org Git - clang/commitdiff
Revert "Produce direct calls instead of alias to linkonce_odr functions."
authorRafael Espindola <rafael.espindola@gmail.com>
Tue, 5 Nov 2013 05:29:54 +0000 (05:29 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Tue, 5 Nov 2013 05:29:54 +0000 (05:29 +0000)
This reverts commit r194046.
Debugging a bootstrap issue.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@194047 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGCXX.cpp
test/CodeGenCXX/ctor-dtor-alias.cpp
test/CodeGenCXX/destructors.cpp

index ab45e321cbb92aa10da572acb4897baf5fb79768..25f3e6f4daa3f443728298c4abb8a576d7ba686e 100644 (file)
@@ -112,13 +112,28 @@ bool CodeGenModule::TryEmitDefinitionAsAlias(GlobalDecl AliasDecl,
   // support aliases with that linkage, fail.
   llvm::GlobalValue::LinkageTypes Linkage = getFunctionLinkage(AliasDecl);
 
+  llvm::GlobalValue::LinkageTypes TargetLinkage
+    = getFunctionLinkage(TargetDecl);
+
+  // Don't create an alias to a linker weak symbol unless we know we can do
+  // that in every TU. This avoids producing different COMDATs in different
+  // TUs.
+  if (llvm::GlobalValue::isWeakForLinker(TargetLinkage)) {
+    if (!InEveryTU)
+      return true;
+
+    // In addition to making sure we produce it in every TU, we have to make
+    // sure llvm keeps it.
+    // FIXME: Instead of outputting an alias we could just replace every use of
+    // AliasDecl with TargetDecl.
+    assert(Linkage == TargetLinkage);
+    Linkage = llvm::GlobalValue::WeakODRLinkage;
+  }
+
   // We can't use an alias if the linkage is not valid for one.
   if (!llvm::GlobalAlias::isValidLinkage(Linkage))
     return true;
 
-  llvm::GlobalValue::LinkageTypes TargetLinkage =
-      getFunctionLinkage(TargetDecl);
-
   // Check if we have it already.
   StringRef MangledName = getMangledName(AliasDecl);
   llvm::GlobalValue *Entry = GetGlobalValue(MangledName);
@@ -137,26 +152,6 @@ bool CodeGenModule::TryEmitDefinitionAsAlias(GlobalDecl AliasDecl,
   if (Ref->getType() != AliasType)
     Aliasee = llvm::ConstantExpr::getBitCast(Ref, AliasType);
 
-  // Don't create an alias to a linker weak symbol unless we know we can do
-  // that in every TU. This avoids producing different COMDATs in different
-  // TUs.
-  if (llvm::GlobalValue::isWeakForLinker(TargetLinkage)) {
-    if (!InEveryTU)
-      return true;
-
-    assert(Linkage == TargetLinkage);
-    // Instead of creating as alias to a linkonce_odr, replace all of the uses
-    // of the aliassee.
-    if (TargetLinkage == llvm::GlobalValue::LinkOnceODRLinkage) {
-      if (!Entry)
-        return false;
-
-      Entry->replaceAllUsesWith(Aliasee);
-      Entry->eraseFromParent();
-      return false;
-    }
-  }
-
   // Create the alias with no name.
   llvm::GlobalAlias *Alias = 
     new llvm::GlobalAlias(AliasType, Linkage, "", Aliasee, &getModule());
index ff9bd7c5c5cede4539da649f20476891100bbd0f..e658522d799a6d2b9dba61158ac5d704ed23ea98 100644 (file)
@@ -13,11 +13,12 @@ template struct foobar<void>;
 }
 
 namespace test2 {
-// test that when the destrucor is linkonce_odr we just replace every use of
-// C1 with C2.
+// test that we produce an alias when the destrucor is linkonce_odr. Note that
+// the alias itself is weak_odr to make sure we don't get a translation unit
+// with just _ZN5test26foobarIvEC2Ev in it.
 
+// CHECK-DAG: @_ZN5test26foobarIvEC1Ev = alias weak_odr void (%"struct.test2::foobar"*)* @_ZN5test26foobarIvEC2Ev
 // CHECK-DAG: define linkonce_odr void @_ZN5test26foobarIvEC2Ev(
-// CHECK-DAG: call void @_ZN5test26foobarIvEC2Ev
 void g();
 template <typename T> struct foobar {
   foobar() { g(); }
@@ -47,7 +48,9 @@ namespace test4 {
   // Test that we don't produce aliases from B to A. We cannot because we cannot
   // guarantee that they will be present in every TU.
 
+  // CHECK-DAG: @_ZN5test41BD1Ev = alias weak_odr void (%"struct.test4::B"*)* @_ZN5test41BD2Ev
   // CHECK-DAG: define linkonce_odr void @_ZN5test41BD2Ev(
+  // CHECK-DAG: @_ZN5test41AD1Ev = alias weak_odr void (%"struct.test4::A"*)* @_ZN5test41AD2Ev
   // CHECK-DAG: define linkonce_odr void @_ZN5test41AD2Ev(
   struct A {
     virtual ~A() {}
index fa7df1babf8eb693a8e022ca04488817a357a501..0030aae92edd4353870d2e294d40743042dd31ea 100644 (file)
@@ -9,6 +9,7 @@
 // CHECK-DAG: @_ZN5test312_GLOBAL__N_11DD1Ev = alias internal {{.*}} @_ZN5test312_GLOBAL__N_11DD2Ev
 // CHECK-DAG: @_ZN5test312_GLOBAL__N_11DD2Ev = alias internal bitcast {{.*}} @_ZN5test312_GLOBAL__N_11CD2Ev
 // CHECK-DAG: @_ZN5test312_GLOBAL__N_11CD1Ev = alias internal {{.*}} @_ZN5test312_GLOBAL__N_11CD2Ev
+// CHECK-DAG: @_ZN6PR752617allocator_derivedD1Ev = alias weak_odr void (%"struct.PR7526::allocator_derived"*)* @_ZN6PR752617allocator_derivedD2Ev
 
 struct A {
   int a;
@@ -44,9 +45,6 @@ namespace PR7526 {
   // CHECK: call void @__cxa_call_unexpected
   allocator::~allocator() throw() { foo(); }
 
-  // CHECK-LABEL: define void @_ZN6PR75263fooEv()
-  // CHECK: call void @_ZN6PR752617allocator_derivedD2Ev
-
   void foo() {
     allocator_derived ad;
   }