r194095 - Produce direct calls instead of alias to linkonce_odr functions.

Timur Iskhodzhanov timurrrr at google.com
Wed Nov 6 06:00:27 PST 2013


2013/11/6 Timur Iskhodzhanov <timurrrr at google.com>:
> 2013/11/6 Rafael Espindola <rafael.espindola at gmail.com>:
>> Author: rafael
>> Date: Tue Nov  5 15:37:29 2013
>> New Revision: 194095
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=194095&view=rev
>> Log:
>> Produce direct calls instead of alias to linkonce_odr functions.
>>
>> This is a small optimization on linux, but should help more on windows
>> where msvc only outputs one destructor if there would be two identical ones.
>>
>> Modified:
>>     cfe/trunk/lib/CodeGen/CGCXX.cpp
>>     cfe/trunk/lib/CodeGen/CodeGenModule.cpp
>>     cfe/trunk/lib/CodeGen/CodeGenModule.h
>>     cfe/trunk/test/CodeGenCXX/ctor-dtor-alias.cpp
>>     cfe/trunk/test/CodeGenCXX/destructors.cpp
>>
>> Modified: cfe/trunk/lib/CodeGen/CGCXX.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXX.cpp?rev=194095&r1=194094&r2=194095&view=diff
>> ==============================================================================
>> --- cfe/trunk/lib/CodeGen/CGCXX.cpp (original)
>> +++ cfe/trunk/lib/CodeGen/CGCXX.cpp Tue Nov  5 15:37:29 2013
>> @@ -112,33 +112,20 @@ bool CodeGenModule::TryEmitDefinitionAsA
>>    // 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);
>>    if (Entry && !Entry->isDeclaration())
>>      return false;
>> +  if (Replacements.count(MangledName))
>> +    return false;
>>
>>    // Derive the type for the alias.
>>    llvm::PointerType *AliasType
>> @@ -152,6 +139,22 @@ bool CodeGenModule::TryEmitDefinitionAsA
>>    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);
>
> FYI this assertion fires when building ICU on Windows.
> I'll try to come up with a small test case.

Here we go:
-----
template<typename T> class A {
~A() {}
};
template class A<char>;
-----

>> +    // Instead of creating as alias to a linkonce_odr, replace all of the uses
>> +    // of the aliassee.
>> +    if (TargetLinkage == llvm::GlobalValue::LinkOnceODRLinkage) {
>> +      Replacements[MangledName] = Aliasee;
>> +      return false;
>> +    }
>> +  }
>> +
>>    // Create the alias with no name.
>>    llvm::GlobalAlias *Alias =
>>      new llvm::GlobalAlias(AliasType, Linkage, "", Aliasee, &getModule());
>>
>> Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=194095&r1=194094&r2=194095&view=diff
>> ==============================================================================
>> --- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
>> +++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Tue Nov  5 15:37:29 2013
>> @@ -172,6 +172,20 @@ void CodeGenModule::createCUDARuntime()
>>    CUDARuntime = CreateNVCUDARuntime(*this);
>>  }
>>
>> +void CodeGenModule::applyReplacements() {
>> +  for (ReplacementsTy::iterator I = Replacements.begin(),
>> +                                E = Replacements.end();
>> +       I != E; ++I) {
>> +    StringRef MangledName = I->first();
>> +    llvm::Constant *Replacement = I->second;
>> +    llvm::GlobalValue *Entry = GetGlobalValue(MangledName);
>> +    if (!Entry)
>> +      continue;
>> +    Entry->replaceAllUsesWith(Replacement);
>> +    Entry->eraseFromParent();
>> +  }
>> +}
>> +
>>  void CodeGenModule::checkAliases() {
>>    bool Error = false;
>>    for (std::vector<GlobalDecl>::iterator I = Aliases.begin(),
>> @@ -207,6 +221,7 @@ void CodeGenModule::checkAliases() {
>>
>>  void CodeGenModule::Release() {
>>    EmitDeferred();
>> +  applyReplacements();
>>    checkAliases();
>>    EmitCXXGlobalInitFunc();
>>    EmitCXXGlobalDtorFunc();
>>
>> Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=194095&r1=194094&r2=194095&view=diff
>> ==============================================================================
>> --- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
>> +++ cfe/trunk/lib/CodeGen/CodeGenModule.h Tue Nov  5 15:37:29 2013
>> @@ -279,6 +279,9 @@ class CodeGenModule : public CodeGenType
>>    /// is defined once we get to the end of the of the translation unit.
>>    std::vector<GlobalDecl> Aliases;
>>
>> +  typedef llvm::StringMap<llvm::TrackingVH<llvm::Constant> > ReplacementsTy;
>> +  ReplacementsTy Replacements;
>> +
>>    /// DeferredVTables - A queue of (optional) vtables to consider emitting.
>>    std::vector<const CXXRecordDecl*> DeferredVTables;
>>
>> @@ -1082,6 +1085,9 @@ private:
>>    /// was deferred.
>>    void EmitDeferred();
>>
>> +  /// Call replaceAllUsesWith on all pairs in Replacements.
>> +  void applyReplacements();
>> +
>>    void checkAliases();
>>
>>    /// EmitDeferredVTables - Emit any vtables which we deferred and
>>
>> Modified: cfe/trunk/test/CodeGenCXX/ctor-dtor-alias.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/ctor-dtor-alias.cpp?rev=194095&r1=194094&r2=194095&view=diff
>> ==============================================================================
>> --- cfe/trunk/test/CodeGenCXX/ctor-dtor-alias.cpp (original)
>> +++ cfe/trunk/test/CodeGenCXX/ctor-dtor-alias.cpp Tue Nov  5 15:37:29 2013
>> @@ -13,12 +13,11 @@ template struct foobar<void>;
>>  }
>>
>>  namespace test2 {
>> -// 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.
>> +// test that when the destrucor is linkonce_odr we just replace every use of
>> +// C1 with C2.
>>
>> -// 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(); }
>> @@ -48,9 +47,7 @@ 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() {}
>>
>> Modified: cfe/trunk/test/CodeGenCXX/destructors.cpp
>> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/destructors.cpp?rev=194095&r1=194094&r2=194095&view=diff
>> ==============================================================================
>> --- cfe/trunk/test/CodeGenCXX/destructors.cpp (original)
>> +++ cfe/trunk/test/CodeGenCXX/destructors.cpp Tue Nov  5 15:37:29 2013
>> @@ -9,8 +9,6 @@
>>  // 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
>> -// CHECK-DAG: @_ZN6test106OptionD1Ev = alias weak_odr void (%"struct.test10::Option"*)* @_ZN6test106OptionD2Ev
>>
>>  struct A {
>>    int a;
>> @@ -46,6 +44,9 @@ 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;
>>    }
>> @@ -367,14 +368,15 @@ namespace test9 {
>>
>>  namespace test10 {
>>    // We used to crash trying to replace _ZN6test106OptionD1Ev with
>> -  // _ZN6test106OptionD2Ev twice. For now check that we don't try and produce
>> -  // an alias instead (check at the top of the file).
>> +  // _ZN6test106OptionD2Ev twice.
>>    struct Option {
>>      virtual ~Option() {}
>>    };
>>    template <class DataType> class opt : public Option {};
>>    template class opt<int>;
>> +  // CHECK-LABEL: define zeroext i1 @_ZN6test1016handleOccurrenceEv(
>>    bool handleOccurrence() {
>> +    // CHECK: call void @_ZN6test106OptionD2Ev(
>>      Option x;
>>      return true;
>>    }
>>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits



More information about the cfe-commits mailing list