[AsmPrinter] Print aliases in topological order
authorTim Shen <timshen91@gmail.com>
Thu, 31 Mar 2016 22:08:19 +0000 (22:08 +0000)
committerTim Shen <timshen91@gmail.com>
Thu, 31 Mar 2016 22:08:19 +0000 (22:08 +0000)
Print aliases in topological order, that is, for any alias a = b,
b must be printed before a. This is because on some targets (e.g. PowerPC)
linker expects aliases in such an order to generate correct TOC information.

GCC also prints aliases in topological order.

llvm-svn: 265064

llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
llvm/test/CodeGen/Generic/asm-printer-topological-order.ll [new file with mode: 0644]

index 67153d1..0559a3c 100644 (file)
@@ -1148,7 +1148,7 @@ bool AsmPrinter::doFinalization(Module &M) {
   }
 
   OutStreamer->AddBlankLine();
-  for (const auto &Alias : M.aliases()) {
+  const auto printAlias = [this, &M](const GlobalAlias &Alias) {
     MCSymbol *Name = getSymbol(&Alias);
 
     if (Alias.hasExternalLinkage() || !MAI->getWeakRefDirective())
@@ -1186,6 +1186,23 @@ bool AsmPrinter::doFinalization(Module &M) {
       OutStreamer->emitELFSize(cast<MCSymbolELF>(Name),
                                MCConstantExpr::create(Size, OutContext));
     }
+  };
+  // Print aliases in topological order, that is, for each alias a = b,
+  // b must be printed before a.
+  // This is because on some targets (e.g. PowerPC) linker expects aliases in
+  // such an order to generate correct TOC information.
+  SmallVector<const GlobalAlias *, 16> AliasStack;
+  SmallPtrSet<const GlobalAlias *, 16> AliasVisited;
+  for (const auto &Alias : M.aliases()) {
+    for (const GlobalAlias *Cur = &Alias; Cur;
+         Cur = dyn_cast<GlobalAlias>(Cur->getAliasee())) {
+      if (!AliasVisited.insert(Cur).second)
+        break;
+      AliasStack.push_back(Cur);
+    }
+    for (const GlobalAlias *AncestorAlias : reverse(AliasStack))
+      printAlias(*AncestorAlias);
+    AliasStack.clear();
   }
 
   GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>();
diff --git a/llvm/test/CodeGen/Generic/asm-printer-topological-order.ll b/llvm/test/CodeGen/Generic/asm-printer-topological-order.ll
new file mode 100644 (file)
index 0000000..18516b2
--- /dev/null
@@ -0,0 +1,15 @@
+; RUN: llc < %s | FileCheck %s
+
+@TestA = alias void (), void ()* @TestC
+@TestB = alias void (), void ()* @TestC
+@TestC = alias void (), void ()* @TestD
+
+define void @TestD() {
+entry:
+  ret void
+}
+
+; CHECK-LABEL: TestD:
+; CHECK: TestC = TestD
+; CHECK-DAG: TestB = TestC
+; CHECK-DAG: TestA = TestC