r194095 - Produce direct calls instead of alias to linkonce_odr functions.
Timur Iskhodzhanov
timurrrr at google.com
Wed Nov 6 01:11:15 PST 2013
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.
> + // 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