[llvm] r322139 - LowerTypeTests: Add limited support for aliases

Vlad Tsyrklevich via llvm-commits llvm-commits at lists.llvm.org
Tue Jan 9 16:00:51 PST 2018


Author: vlad.tsyrklevich
Date: Tue Jan  9 16:00:51 2018
New Revision: 322139

URL: http://llvm.org/viewvc/llvm-project?rev=322139&view=rev
Log:
LowerTypeTests: Add limited support for aliases

Summary:
LowerTypeTests moves some function definitions from individual object
files to the merged module, leaving a stub to be called in the merged
module's jump table. If an alias was pointing to such a function
definition LowerTypeTests would fail because the alias would be left
without a definition to point to.

This change 1) emits information about aliases to the ThinLTO summary,
2) replaces aliases pointing to function definitions that are moved to
the merged module with function declarations, and 3) re-emits those
aliases in the merged module pointing to the correct function
definitions.

The patch does not correctly fix all possible mis-uses of aliases in
LowerTypeTests. For example, it does not handle aliases with a different
type from the pointed to function.

The addition of alias data increases the size of Chrome build artifacts
by less than 1%.

Reviewers: pcc

Reviewed By: pcc

Subscribers: mehdi_amini, eraman, mgrang, llvm-commits, eugenis, kcc

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

Added:
    llvm/trunk/test/Transforms/LowerTypeTests/Inputs/import-alias.yaml
    llvm/trunk/test/Transforms/LowerTypeTests/export-alias.ll
    llvm/trunk/test/Transforms/LowerTypeTests/import-alias.ll
    llvm/trunk/test/Transforms/ThinLTOBitcodeWriter/function-alias.ll
Modified:
    llvm/trunk/lib/Transforms/IPO/LowerTypeTests.cpp
    llvm/trunk/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp

Modified: llvm/trunk/lib/Transforms/IPO/LowerTypeTests.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/LowerTypeTests.cpp?rev=322139&r1=322138&r2=322139&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/LowerTypeTests.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/LowerTypeTests.cpp Tue Jan  9 16:00:51 2018
@@ -956,6 +956,21 @@ void LowerTypeTestsModule::importFunctio
     FDecl = Function::Create(F->getFunctionType(), GlobalValue::ExternalLinkage,
                              Name, &M);
     FDecl->setVisibility(Visibility);
+
+    // Delete aliases pointing to this function, they'll be re-created in the
+    // merged output
+    SmallVector<GlobalAlias*, 4> ToErase;
+    for (auto &U : F->uses()) {
+      if (auto *A = dyn_cast<GlobalAlias>(U.getUser())) {
+        Function *AliasDecl = Function::Create(
+            F->getFunctionType(), GlobalValue::ExternalLinkage, "", &M);
+        AliasDecl->takeName(A);
+        A->replaceAllUsesWith(AliasDecl);
+        ToErase.push_back(A);
+      }
+    }
+    for (auto *A : ToErase)
+      A->eraseFromParent();
   } else {
     // Function definition without type metadata, where some other translation
     // unit contained a declaration with type metadata. This normally happens
@@ -1804,6 +1819,49 @@ bool LowerTypeTestsModule::lower() {
 
   allocateByteArrays();
 
+  // Parse alias data to replace stand-in function declarations for aliases
+  // with an alias to the intended target.
+  if (ExportSummary) {
+    if (NamedMDNode *AliasesMD = M.getNamedMetadata("aliases")) {
+      for (auto AliasMD : AliasesMD->operands()) {
+        assert(AliasMD->getNumOperands() >= 4);
+        StringRef AliasName =
+            cast<MDString>(AliasMD->getOperand(0))->getString();
+        StringRef Aliasee = cast<MDString>(AliasMD->getOperand(1))->getString();
+
+        if (!ExportedFunctions.count(Aliasee) ||
+            ExportedFunctions[Aliasee].Linkage != CFL_Definition ||
+            !M.getNamedAlias(Aliasee))
+          continue;
+
+        GlobalValue::VisibilityTypes Visibility =
+            static_cast<GlobalValue::VisibilityTypes>(
+                cast<ConstantAsMetadata>(AliasMD->getOperand(2))
+                    ->getValue()
+                    ->getUniqueInteger()
+                    .getZExtValue());
+        bool Weak =
+            static_cast<bool>(cast<ConstantAsMetadata>(AliasMD->getOperand(3))
+                                  ->getValue()
+                                  ->getUniqueInteger()
+                                  .getZExtValue());
+
+        auto *Alias = GlobalAlias::create("", M.getNamedAlias(Aliasee));
+        Alias->setVisibility(Visibility);
+        if (Weak)
+          Alias->setLinkage(GlobalValue::WeakAnyLinkage);
+
+        if (auto *F = M.getFunction(AliasName)) {
+          Alias->takeName(F);
+          F->replaceAllUsesWith(Alias);
+          F->eraseFromParent();
+        } else {
+          Alias->setName(AliasName);
+        }
+      }
+    }
+  }
+
   return true;
 }
 

Modified: llvm/trunk/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp?rev=322139&r1=322138&r2=322139&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp Tue Jan  9 16:00:51 2018
@@ -357,6 +357,31 @@ void splitAndWriteThinLTOBitcode(
       NMD->addOperand(MD);
   }
 
+  SmallVector<MDNode *, 8> FunctionAliases;
+  for (auto &A : M.aliases()) {
+    if (!isa<Function>(A.getAliasee()))
+      continue;
+
+    auto *F = cast<Function>(A.getAliasee());
+    auto &Ctx = MergedM->getContext();
+    SmallVector<Metadata *, 4> Elts;
+
+    Elts.push_back(MDString::get(Ctx, A.getName()));
+    Elts.push_back(MDString::get(Ctx, F->getName()));
+    Elts.push_back(ConstantAsMetadata::get(
+        llvm::ConstantInt::get(Type::getInt8Ty(Ctx), A.getVisibility())));
+    Elts.push_back(ConstantAsMetadata::get(
+        llvm::ConstantInt::get(Type::getInt8Ty(Ctx), A.isWeakForLinker())));
+
+    FunctionAliases.push_back(MDTuple::get(Ctx, Elts));
+  }
+
+  if (!FunctionAliases.empty()) {
+    NamedMDNode *NMD = MergedM->getOrInsertNamedMetadata("aliases");
+    for (auto MD : FunctionAliases)
+      NMD->addOperand(MD);
+  }
+
   simplifyExternals(*MergedM);
 
   // FIXME: Try to re-use BSI and PFI from the original module here.

Added: llvm/trunk/test/Transforms/LowerTypeTests/Inputs/import-alias.yaml
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LowerTypeTests/Inputs/import-alias.yaml?rev=322139&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/LowerTypeTests/Inputs/import-alias.yaml (added)
+++ llvm/trunk/test/Transforms/LowerTypeTests/Inputs/import-alias.yaml Tue Jan  9 16:00:51 2018
@@ -0,0 +1,11 @@
+---
+TypeIdMap:
+  typeid1:
+    TTRes:
+      Kind:            AllOnes
+      SizeM1BitWidth:  7
+WithGlobalValueDeadStripping: false
+CfiFunctionDefs:
+  - f
+CfiFunctionDecls:
+...

Added: llvm/trunk/test/Transforms/LowerTypeTests/export-alias.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LowerTypeTests/export-alias.ll?rev=322139&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/LowerTypeTests/export-alias.ll (added)
+++ llvm/trunk/test/Transforms/LowerTypeTests/export-alias.ll Tue Jan  9 16:00:51 2018
@@ -0,0 +1,21 @@
+; RUN: opt -S %s -lowertypetests -lowertypetests-summary-action=export -lowertypetests-read-summary=%S/Inputs/use-typeid1-typeid2.yaml | FileCheck %s
+;
+; CHECK: @alias1 = weak alias void (), void ()* @f
+; CHECK: @alias2 = hidden alias void (), void ()* @f
+; CHECK: declare !type !1 void @alias3()
+; CHECK-NOT: @alias3 = alias
+
+target triple = "x86_64-unknown-linux"
+
+!cfi.functions = !{!0, !2, !3}
+!aliases = !{!4, !5, !6}
+
+!0 = !{!"f", i8 0, !1}
+!1 = !{i64 0, !"typeid1"}
+!2 = !{!"alias1", i8 1, !1}
+; alias2 not included here, this could happen if the only reference to alias2
+; is in a module compiled without cfi-icall
+!3 = !{!"alias3", i8 1, !1}
+!4 = !{!"alias1", !"f", i8 0, i8 1}
+!5 = !{!"alias2", !"f", i8 1, i8 0}
+!6 = !{!"alias3", !"not_present", i8 0, i8 0}

Added: llvm/trunk/test/Transforms/LowerTypeTests/import-alias.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/LowerTypeTests/import-alias.ll?rev=322139&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/LowerTypeTests/import-alias.ll (added)
+++ llvm/trunk/test/Transforms/LowerTypeTests/import-alias.ll Tue Jan  9 16:00:51 2018
@@ -0,0 +1,30 @@
+; RUN: opt -S %s -lowertypetests -lowertypetests-summary-action=import -lowertypetests-read-summary=%S/Inputs/import-alias.yaml | FileCheck %s
+;
+; Check that the definitions for @f and @f_alias are removed from this module
+; but @g_alias remains.
+;
+; CHECK: @g_alias = alias void (), void ()* @g
+; CHECK: define hidden void @f.cfi
+; CHECK: declare void @f()
+; CHECK: declare void @f_alias()
+
+target triple = "x86_64-unknown-linux"
+
+ at f_alias = alias void (), void ()* @f
+ at g_alias = alias void (), void ()* @g
+
+; Definition moved to the merged module
+define void @f() {
+  ret void
+}
+
+; Definition not moved to the merged module
+define void @g() {
+  ret void
+}
+
+define void @uses_aliases() {
+  call void @f_alias()
+  call void @g_alias()
+  ret void
+}

Added: llvm/trunk/test/Transforms/ThinLTOBitcodeWriter/function-alias.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/ThinLTOBitcodeWriter/function-alias.ll?rev=322139&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/ThinLTOBitcodeWriter/function-alias.ll (added)
+++ llvm/trunk/test/Transforms/ThinLTOBitcodeWriter/function-alias.ll Tue Jan  9 16:00:51 2018
@@ -0,0 +1,25 @@
+; RUN: opt -thinlto-bc -o %t %s
+; RUN: llvm-modextract -n 1 -o - %t | llvm-dis | FileCheck --check-prefix=CHECK1 %s
+
+target triple = "x86_64-unknown-linux-gnu"
+
+define hidden void @Func() !type !0 {
+  ret void
+}
+
+; CHECK1: !aliases = !{![[A1:[0-9]+]], ![[A2:[0-9]+]], ![[A3:[0-9]+]]}
+
+; CHECK1: ![[A1]] = !{!"Alias", !"Func", i8 1, i8 0}
+; CHECK1: ![[A2]] = !{!"Hidden_Alias", !"Func", i8 1, i8 0}
+; CHECK1: ![[A3]] = !{!"Weak_Alias", !"Func", i8 0, i8 1}
+ at Alias = hidden alias void (), void ()* @Func
+ at Hidden_Alias = hidden alias void (), void ()* @Func
+ at Weak_Alias = weak alias void (), void ()* @Func
+
+ at Variable = global i32 0
+
+; Only generate summary alias information for aliases to functions
+; CHECK1-NOT: Variable_Alias
+ at Variable_Alias = alias i32, i32* @Variable
+
+!0 = !{i64 0, !"_ZTSFvvE"}




More information about the llvm-commits mailing list