summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafael Espindola <rafael.espindola@gmail.com>2013-10-30 22:08:11 +0000
committerRafael Espindola <rafael.espindola@gmail.com>2013-10-30 22:08:11 +0000
commit2cc546db188d5e4d4537681cab3d52781125518c (patch)
tree82d4b69f91bc14eebc0663452c579b100a270633
parent1d36113c05e611c0fba9b872b5f03eca9848bd69 (diff)
downloadllvm-2cc546db188d5e4d4537681cab3d52781125518c.tar.gz
llvm-2cc546db188d5e4d4537681cab3d52781125518c.tar.bz2
llvm-2cc546db188d5e4d4537681cab3d52781125518c.tar.xz
Produce .weak_def_can_be_hidden for some linkonce_odr values
With this patch llvm produces a weak_def_can_be_hidden for linkonce_odr if they are also unnamed_addr or don't have their address taken. There is not a lot of documentation about .weak_def_can_be_hidden, but from the old discussion about linkonce_odr_auto_hide and the name of the directive this looks correct: these symbols can be hidden. Testing this with the ld64 in Xcode 5 linking clang reduces the number of exported symbols from 21053 to 19049. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@193718 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/CodeGen/AsmPrinter.h2
-rw-r--r--lib/CodeGen/AsmPrinter/AsmPrinter.cpp27
-rw-r--r--test/CodeGen/X86/weak_def_can_be_hidden.ll26
3 files changed, 47 insertions, 8 deletions
diff --git a/include/llvm/CodeGen/AsmPrinter.h b/include/llvm/CodeGen/AsmPrinter.h
index d66665c85c..4bda0f1603 100644
--- a/include/llvm/CodeGen/AsmPrinter.h
+++ b/include/llvm/CodeGen/AsmPrinter.h
@@ -486,7 +486,7 @@ namespace llvm {
void EmitVisibility(MCSymbol *Sym, unsigned Visibility,
bool IsDefinition = true) const;
- void EmitLinkage(unsigned Linkage, MCSymbol *GVSym) const;
+ void EmitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const;
void EmitJumpTableEntry(const MachineJumpTableInfo *MJTI,
const MachineBasicBlock *MBB, unsigned uid) const;
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 41d83beb5f..9a02462165 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -48,6 +48,7 @@
#include "llvm/Target/TargetLoweringObjectFile.h"
#include "llvm/Target/TargetOptions.h"
#include "llvm/Target/TargetRegisterInfo.h"
+#include "llvm/Transforms/Utils/GlobalStatus.h"
using namespace llvm;
static const char *const DWARFGroupName = "DWARF Emission";
@@ -212,9 +213,8 @@ bool AsmPrinter::doInitialization(Module &M) {
llvm_unreachable("Unknown exception type.");
}
-void AsmPrinter::EmitLinkage(unsigned L, MCSymbol *GVSym) const {
- GlobalValue::LinkageTypes Linkage = (GlobalValue::LinkageTypes)L;
-
+void AsmPrinter::EmitLinkage(const GlobalValue *GV, MCSymbol *GVSym) const {
+ GlobalValue::LinkageTypes Linkage = GV->getLinkage();
switch (Linkage) {
case GlobalValue::CommonLinkage:
case GlobalValue::LinkOnceAnyLinkage:
@@ -227,7 +227,20 @@ void AsmPrinter::EmitLinkage(unsigned L, MCSymbol *GVSym) const {
// .globl _foo
OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global);
- if (Linkage != GlobalValue::LinkOnceODRAutoHideLinkage)
+
+ bool CanBeHidden = Linkage == GlobalValue::LinkOnceODRAutoHideLinkage;
+
+ if (!CanBeHidden && Linkage == GlobalValue::LinkOnceODRLinkage) {
+ if (GV->hasUnnamedAddr()) {
+ CanBeHidden = true;
+ } else {
+ GlobalStatus GS;
+ if (!GlobalStatus::analyzeGlobal(GV, GS) && !GS.IsCompared)
+ CanBeHidden = true;
+ }
+ }
+
+ if (!CanBeHidden)
// .weak_definition _foo
OutStreamer.EmitSymbolAttribute(GVSym, MCSA_WeakDefinition);
else
@@ -399,7 +412,7 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
OutStreamer.SwitchSection(TLVSect);
// Emit the linkage here.
- EmitLinkage(GV->getLinkage(), GVSym);
+ EmitLinkage(GV, GVSym);
OutStreamer.EmitLabel(GVSym);
// Three pointers in size:
@@ -418,7 +431,7 @@ void AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
OutStreamer.SwitchSection(TheSection);
- EmitLinkage(GV->getLinkage(), GVSym);
+ EmitLinkage(GV, GVSym);
EmitAlignment(AlignLog, GV);
OutStreamer.EmitLabel(GVSym);
@@ -444,7 +457,7 @@ void AsmPrinter::EmitFunctionHeader() {
OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F, Mang, TM));
EmitVisibility(CurrentFnSym, F->getVisibility());
- EmitLinkage(F->getLinkage(), CurrentFnSym);
+ EmitLinkage(F, CurrentFnSym);
EmitAlignment(MF->getAlignment(), F);
if (MAI->hasDotTypeDotSizeDirective())
diff --git a/test/CodeGen/X86/weak_def_can_be_hidden.ll b/test/CodeGen/X86/weak_def_can_be_hidden.ll
new file mode 100644
index 0000000000..f78f3571ce
--- /dev/null
+++ b/test/CodeGen/X86/weak_def_can_be_hidden.ll
@@ -0,0 +1,26 @@
+; RUN: llc -mtriple=x86_64-apple-darwin -O0 < %s | FileCheck %s
+
+@v1 = linkonce_odr global i32 32
+; CHECK: .globl _v1
+; CHECK: .weak_def_can_be_hidden _v1
+
+define i32 @f1() {
+ %x = load i32 * @v1
+ ret i32 %x
+}
+
+@v2 = linkonce_odr global i32 32
+; CHECK: .globl _v2
+; CHECK: .weak_definition _v2
+
+@v3 = linkonce_odr unnamed_addr global i32 32
+; CHECK: .globl _v3
+; CHECK: .weak_def_can_be_hidden _v3
+
+define i32* @f2() {
+ ret i32* @v2
+}
+
+define i32* @f3() {
+ ret i32* @v3
+}