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