Add CommonLinkage; currently tentative definitions

are represented as "weak", but there are subtle differences
in some cases on Darwin, so we need both.  The intent
is that "common" will behave identically to "weak" unless
somebody changes their target to do something else.
No functional change as yet.

llvm-svn: 51118
This commit is contained in:
Dale Johannesen 2008-05-14 20:12:51 +00:00
parent e94e0f66cd
commit ce4396bc92
22 changed files with 70 additions and 31 deletions

View File

@ -38,7 +38,8 @@ public:
DLLImportLinkage, ///< Function to be imported from DLL
DLLExportLinkage, ///< Function to be accessible from DLL
ExternalWeakLinkage,///< ExternalWeak linkage description
GhostLinkage ///< Stand-in functions for streaming fns from BC files
GhostLinkage, ///< Stand-in functions for streaming fns from BC files
CommonLinkage ///< Tentative definitions
};
/// @brief An enumeration for the kinds of visibility of global values.
@ -100,6 +101,7 @@ public:
bool hasExternalLinkage() const { return Linkage == ExternalLinkage; }
bool hasLinkOnceLinkage() const { return Linkage == LinkOnceLinkage; }
bool hasWeakLinkage() const { return Linkage == WeakLinkage; }
bool hasCommonLinkage() const { return Linkage == CommonLinkage; }
bool hasAppendingLinkage() const { return Linkage == AppendingLinkage; }
bool hasInternalLinkage() const { return Linkage == InternalLinkage; }
bool hasDLLImportLinkage() const { return Linkage == DLLImportLinkage; }

View File

@ -451,6 +451,7 @@ int LLLexer::LexIdentifier() {
KEYWORD("appending", APPENDING);
KEYWORD("dllimport", DLLIMPORT);
KEYWORD("dllexport", DLLEXPORT);
KEYWORD("common", COMMON);
KEYWORD("hidden", HIDDEN);
KEYWORD("protected", PROTECTED);
KEYWORD("extern_weak", EXTERN_WEAK);

View File

@ -66,6 +66,7 @@ static GlobalValue::LinkageTypes GetDecodedLinkage(unsigned Val) {
case 5: return GlobalValue::DLLImportLinkage;
case 6: return GlobalValue::DLLExportLinkage;
case 7: return GlobalValue::ExternalWeakLinkage;
case 8: return GlobalValue::CommonLinkage;
}
}

View File

@ -270,6 +270,7 @@ static unsigned getEncodedLinkage(const GlobalValue *GV) {
case GlobalValue::DLLImportLinkage: return 5;
case GlobalValue::DLLExportLinkage: return 6;
case GlobalValue::ExternalWeakLinkage: return 7;
case GlobalValue::CommonLinkage: return 8;
}
}

View File

@ -282,7 +282,8 @@ void ELFWriter::EmitGlobal(GlobalVariable *GV) {
// If this global is part of the common block, add it now. Variables are
// part of the common block if they are zero initialized and allowed to be
// merged with other symbols.
if (GV->hasLinkOnceLinkage() || GV->hasWeakLinkage()) {
if (GV->hasLinkOnceLinkage() || GV->hasWeakLinkage() ||
GV->hasCommonLinkage()) {
ELFSym CommonSym(GV);
// Value for common symbols is the alignment required.
CommonSym.Value = Align;
@ -313,7 +314,7 @@ void ELFWriter::EmitGlobal(GlobalVariable *GV) {
BSSSym.SetType(ELFSym::STT_OBJECT);
switch (GV->getLinkage()) {
default: // weak/linkonce handled above
default: // weak/linkonce/common handled above
assert(0 && "Unexpected linkage type!");
case GlobalValue::AppendingLinkage: // FIXME: This should be improved!
case GlobalValue::ExternalLinkage:

View File

@ -403,7 +403,8 @@ void MachOWriter::EmitGlobal(GlobalVariable *GV) {
// If this global is part of the common block, add it now. Variables are
// part of the common block if they are zero initialized and allowed to be
// merged with other symbols.
if (NoInit || GV->hasLinkOnceLinkage() || GV->hasWeakLinkage()) {
if (NoInit || GV->hasLinkOnceLinkage() || GV->hasWeakLinkage() ||
GV->hasCommonLinkage()) {
MachOSym ExtOrCommonSym(GV, Mang->getValueName(GV), MachOSym::NO_SECT,TM);
// For undefined (N_UNDF) external (N_EXT) types, n_value is the size in
// bytes of the symbol.
@ -951,6 +952,7 @@ MachOSym::MachOSym(const GlobalValue *gv, std::string name, uint8_t sect,
break;
case GlobalValue::WeakLinkage:
case GlobalValue::LinkOnceLinkage:
case GlobalValue::CommonLinkage:
assert(!isa<Function>(gv) && "Unexpected linkage type for Function!");
case GlobalValue::ExternalLinkage:
GVName = TAI->getGlobalPrefix() + name;

View File

@ -884,7 +884,7 @@ void ExecutionEngine::emitGlobals() {
continue;
// Otherwise, we know it's linkonce/weak, replace it if this is a strong
// symbol.
// symbol. FIXME is this right for common?
if (GV->hasExternalLinkage() || GVEntry->hasExternalWeakLinkage())
GVEntry = GV;
}

View File

@ -410,10 +410,12 @@ static bool GetLinkageResult(GlobalValue *Dest, const GlobalValue *Src,
"': can only link appending global with another appending global!");
LinkFromSrc = true; // Special cased.
LT = Src->getLinkage();
} else if (Src->hasWeakLinkage() || Src->hasLinkOnceLinkage()) {
// At this point we know that Dest has LinkOnce, External*, Weak, or
// DLL* linkage.
if ((Dest->hasLinkOnceLinkage() && Src->hasWeakLinkage()) ||
} else if (Src->hasWeakLinkage() || Src->hasLinkOnceLinkage() ||
Src->hasCommonLinkage()) {
// At this point we know that Dest has LinkOnce, External*, Weak, Common,
// or DLL* linkage.
if ((Dest->hasLinkOnceLinkage() &&
(Src->hasWeakLinkage() || Src->hasCommonLinkage())) ||
Dest->hasExternalWeakLinkage()) {
LinkFromSrc = true;
LT = Src->getLinkage();
@ -421,7 +423,8 @@ static bool GetLinkageResult(GlobalValue *Dest, const GlobalValue *Src,
LinkFromSrc = false;
LT = Dest->getLinkage();
}
} else if (Dest->hasWeakLinkage() || Dest->hasLinkOnceLinkage()) {
} else if (Dest->hasWeakLinkage() || Dest->hasLinkOnceLinkage() ||
Dest->hasCommonLinkage()) {
// At this point we know that Src has External* or DLL* linkage.
if (Src->hasExternalWeakLinkage()) {
LinkFromSrc = false;
@ -792,10 +795,12 @@ static bool LinkGlobalInits(Module *Dest, const Module *Src,
if (DGV->getInitializer() != SInit)
return Error(Err, "Global Variable Collision on '" + SGV->getName() +
"': global variables have different initializers");
} else if (DGV->hasLinkOnceLinkage() || DGV->hasWeakLinkage()) {
} else if (DGV->hasLinkOnceLinkage() || DGV->hasWeakLinkage() ||
DGV->hasCommonLinkage()) {
// Nothing is required, mapped values will take the new global
// automatically.
} else if (SGV->hasLinkOnceLinkage() || SGV->hasWeakLinkage()) {
} else if (SGV->hasLinkOnceLinkage() || SGV->hasWeakLinkage() ||
SGV->hasCommonLinkage()) {
// Nothing is required, mapped values will take the new global
// automatically.
} else if (DGV->hasAppendingLinkage()) {
@ -916,16 +921,19 @@ static bool LinkFunctionProtos(Module *Dest, const Module *Src,
DF->setLinkage(SF->getLinkage());
// Visibility of prototype is overridden by vis of definition.
DF->setVisibility(SF->getVisibility());
} else if (SF->hasWeakLinkage() || SF->hasLinkOnceLinkage()) {
} else if (SF->hasWeakLinkage() || SF->hasLinkOnceLinkage() ||
SF->hasCommonLinkage()) {
// At this point we know that DF has LinkOnce, Weak, or External* linkage.
ValueMap[SF] = DF;
// Linkonce+Weak = Weak
// *+External Weak = *
if ((DF->hasLinkOnceLinkage() && SF->hasWeakLinkage()) ||
if ((DF->hasLinkOnceLinkage() &&
(SF->hasWeakLinkage() || SF->hasCommonLinkage())) ||
DF->hasExternalWeakLinkage())
DF->setLinkage(SF->getLinkage());
} else if (DF->hasWeakLinkage() || DF->hasLinkOnceLinkage()) {
} else if (DF->hasWeakLinkage() || DF->hasLinkOnceLinkage() ||
DF->hasCommonLinkage()) {
// At this point we know that SF has LinkOnce or External* linkage.
ValueMap[SF] = DF;
if (!SF->hasLinkOnceLinkage() && !SF->hasExternalWeakLinkage())

View File

@ -225,6 +225,7 @@ bool AlphaAsmPrinter::doFinalization(Module &M) {
switch (I->getLinkage()) {
case GlobalValue::LinkOnceLinkage:
case GlobalValue::WeakLinkage:
case GlobalValue::CommonLinkage:
O << TAI->getWeakRefDirective() << name << '\n';
break;
case GlobalValue::AppendingLinkage:

View File

@ -1604,7 +1604,8 @@ bool CWriter::doInitialization(Module &M) {
for (Module::global_iterator I = M.global_begin(), E = M.global_end();
I != E; ++I) {
if (I->hasExternalLinkage() || I->hasExternalWeakLinkage())
if (I->hasExternalLinkage() || I->hasExternalWeakLinkage() ||
I->hasCommonLinkage())
Out << "extern ";
else if (I->hasDLLImportLinkage())
Out << "__declspec(dllimport) ";
@ -1678,6 +1679,8 @@ bool CWriter::doInitialization(Module &M) {
if (I->hasLinkOnceLinkage())
Out << " __attribute__((common))";
else if (I->hasCommonLinkage()) // FIXME is this right?
Out << " __ATTRIBUTE_WEAK__";
else if (I->hasWeakLinkage())
Out << " __ATTRIBUTE_WEAK__";
else if (I->hasExternalWeakLinkage())
@ -1715,6 +1718,8 @@ bool CWriter::doInitialization(Module &M) {
Out << " __attribute__((common))";
else if (I->hasWeakLinkage())
Out << " __ATTRIBUTE_WEAK__";
else if (I->hasCommonLinkage())
Out << " __ATTRIBUTE_WEAK__";
if (I->hasHiddenVisibility())
Out << " __HIDDEN__";
@ -1724,6 +1729,7 @@ bool CWriter::doInitialization(Module &M) {
// this, however, occurs when the variable has weak linkage. In this
// case, the assembler will complain about the variable being both weak
// and common, so we disable this optimization.
// FIXME common linkage should avoid this problem.
if (!I->getInitializer()->isNullValue()) {
Out << " = " ;
writeOperand(I->getInitializer());

View File

@ -340,7 +340,7 @@ void SPUAsmPrinter::printOp(const MachineOperand &MO) {
// stubs
if (TM.getRelocationModel() != Reloc::Static) {
if (((GV->isDeclaration() || GV->hasWeakLinkage() ||
GV->hasLinkOnceLinkage()))) {
GV->hasLinkOnceLinkage() || GV->hasCommonLinkage()))) {
GVStubs.insert(Name);
O << "L" << Name << "$non_lazy_ptr";
return;
@ -510,7 +510,7 @@ bool LinuxAsmPrinter::doFinalization(Module &M) {
if (C->isNullValue() && /* FIXME: Verify correct */
(I->hasInternalLinkage() || I->hasWeakLinkage() ||
I->hasLinkOnceLinkage() ||
I->hasLinkOnceLinkage() || I->hasCommonLinkage() ||
(I->hasExternalLinkage() && !I->hasSection()))) {
if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
if (I->hasExternalLinkage()) {
@ -537,6 +537,7 @@ bool LinuxAsmPrinter::doFinalization(Module &M) {
switch (I->getLinkage()) {
case GlobalValue::LinkOnceLinkage:
case GlobalValue::WeakLinkage:
case GlobalValue::CommonLinkage:
O << "\t.global " << name << '\n'
<< "\t.weak_definition " << name << '\n';
SwitchToDataSection(".section __DATA,__datacoal_nt,coalesced", I);

View File

@ -301,6 +301,8 @@ namespace {
Out << "GlobalValue::ExternalWeakLinkage"; break;
case GlobalValue::GhostLinkage:
Out << "GlobalValue::GhostLinkage"; break;
case GlobalValue::CommonLinkage:
Out << "GlobalValue::CommonLinkage"; break;
}
}

View File

@ -275,6 +275,7 @@ bool IA64AsmPrinter::doFinalization(Module &M) {
if (C->isNullValue() &&
(I->hasLinkOnceLinkage() || I->hasInternalLinkage() ||
I->hasCommonLinkage() ||
I->hasWeakLinkage() /* FIXME: Verify correct */)) {
SwitchToDataSection(".data", I);
if (I->hasInternalLinkage()) {
@ -289,6 +290,7 @@ bool IA64AsmPrinter::doFinalization(Module &M) {
} else {
switch (I->getLinkage()) {
case GlobalValue::LinkOnceLinkage:
case GlobalValue::CommonLinkage:
case GlobalValue::WeakLinkage: // FIXME: Verify correct for weak.
// Nonnull linkonce -> weak
O << "\t.weak " << name << "\n";

View File

@ -461,7 +461,8 @@ doFinalization(Module &M)
// Is this correct ?
if (C->isNullValue() && (I->hasLinkOnceLinkage() ||
I->hasInternalLinkage() || I->hasWeakLinkage()))
I->hasInternalLinkage() || I->hasWeakLinkage() ||
I->hasCommonLinkage()))
{
if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
@ -487,7 +488,8 @@ doFinalization(Module &M)
switch (I->getLinkage())
{
case GlobalValue::LinkOnceLinkage:
case GlobalValue::WeakLinkage:
case GlobalValue::CommonLinkage:
case GlobalValue::WeakLinkage:
// FIXME: Verify correct for weak.
// Nonnull linkonce -> weak
O << "\t.weak " << name << "\n";

View File

@ -414,7 +414,7 @@ bool PIC16AsmPrinter::doFinalization(Module &M)
if (!I->hasSection() &&
(I->hasInternalLinkage() || I->hasWeakLinkage() ||
I->hasLinkOnceLinkage())) {
I->hasLinkOnceLinkage() || I->hasCommonLinkage())) {
if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
if (!NoZerosInBSS && TAI->getBSSSection())
SwitchToDataSection(M.getModuleIdentifier().c_str(), I);

View File

@ -185,7 +185,7 @@ namespace {
if (MO.getType() == MachineOperand::MO_GlobalAddress) {
GlobalValue *GV = MO.getGlobal();
if (((GV->isDeclaration() || GV->hasWeakLinkage() ||
GV->hasLinkOnceLinkage()))) {
GV->hasLinkOnceLinkage() || GV->hasCommonLinkage()))) {
// Dynamically-resolved functions need a stub for the function.
std::string Name = Mang->getValueName(GV);
FnStubs.insert(Name);
@ -390,7 +390,7 @@ void PPCAsmPrinter::printOp(const MachineOperand &MO) {
// External or weakly linked global variables need non-lazily-resolved stubs
if (TM.getRelocationModel() != Reloc::Static) {
if (((GV->isDeclaration() || GV->hasWeakLinkage() ||
GV->hasLinkOnceLinkage()))) {
GV->hasLinkOnceLinkage() || GV->hasCommonLinkage()))) {
GVStubs.insert(Name);
O << "L" << Name << "$non_lazy_ptr";
return;
@ -671,8 +671,8 @@ bool LinuxAsmPrinter::doFinalization(Module &M) {
unsigned Align = TD->getPreferredAlignmentLog(I);
if (C->isNullValue() && /* FIXME: Verify correct */
!I->hasSection() &&
(I->hasInternalLinkage() || I->hasWeakLinkage() ||
!I->hasSection() && (I->hasCommonLinkage() ||
I->hasInternalLinkage() || I->hasWeakLinkage() ||
I->hasLinkOnceLinkage() || I->hasExternalLinkage())) {
if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
if (I->hasExternalLinkage()) {
@ -696,6 +696,7 @@ bool LinuxAsmPrinter::doFinalization(Module &M) {
switch (I->getLinkage()) {
case GlobalValue::LinkOnceLinkage:
case GlobalValue::WeakLinkage:
case GlobalValue::CommonLinkage:
O << "\t.global " << name << '\n'
<< "\t.type " << name << ", @object\n"
<< "\t.weak " << name << '\n';
@ -936,8 +937,8 @@ bool DarwinAsmPrinter::doFinalization(Module &M) {
unsigned Align = TD->getPreferredAlignmentLog(I);
if (C->isNullValue() && /* FIXME: Verify correct */
!I->hasSection() &&
(I->hasInternalLinkage() || I->hasWeakLinkage() ||
!I->hasSection() && (I->hasCommonLinkage() ||
I->hasInternalLinkage() || I->hasWeakLinkage() ||
I->hasLinkOnceLinkage() || I->hasExternalLinkage())) {
if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
if (I->hasExternalLinkage()) {
@ -961,6 +962,7 @@ bool DarwinAsmPrinter::doFinalization(Module &M) {
switch (I->getLinkage()) {
case GlobalValue::LinkOnceLinkage:
case GlobalValue::WeakLinkage:
case GlobalValue::CommonLinkage:
O << "\t.globl " << name << '\n'
<< "\t.weak_definition " << name << '\n';
SwitchToDataSection("\t.section __DATA,__datacoal_nt,coalesced", I);

View File

@ -231,8 +231,8 @@ bool SparcAsmPrinter::doFinalization(Module &M) {
unsigned Size = TD->getABITypeSize(C->getType());
unsigned Align = TD->getPreferredAlignment(I);
if (C->isNullValue() &&
(I->hasLinkOnceLinkage() || I->hasInternalLinkage() ||
if (C->isNullValue() && (I->hasCommonLinkage() ||
I->hasLinkOnceLinkage() || I->hasInternalLinkage() ||
I->hasWeakLinkage() /* FIXME: Verify correct */)) {
SwitchToDataSection(".data", I);
if (I->hasInternalLinkage())
@ -243,6 +243,7 @@ bool SparcAsmPrinter::doFinalization(Module &M) {
O << "\n";
} else {
switch (I->getLinkage()) {
case GlobalValue::CommonLinkage:
case GlobalValue::LinkOnceLinkage:
case GlobalValue::WeakLinkage: // FIXME: Verify correct for weak.
// Nonnull linkonce -> weak

View File

@ -309,7 +309,8 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,
// non-lazily-resolved stubs
if (GV->isDeclaration() ||
GV->hasWeakLinkage() ||
GV->hasLinkOnceLinkage()) {
GV->hasLinkOnceLinkage() ||
GV->hasCommonLinkage()) {
// Dynamically-resolved functions need a stub for the function.
if (isCallOp && isa<Function>(GV)) {
FnStubs.insert(Name);

View File

@ -200,7 +200,7 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) {
if (!I->isThreadLocal() &&
(I->hasInternalLinkage() || I->hasWeakLinkage() ||
I->hasLinkOnceLinkage())) {
I->hasLinkOnceLinkage() || I->hasCommonLinkage())) {
if (Size == 0) Size = 1; // .comm Foo, 0 is undefined, avoid it.
if (!NoZerosInBSS && TAI->getBSSSection())
SwitchToDataSection(TAI->getBSSSection(), I);
@ -235,6 +235,7 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) {
}
switch (I->getLinkage()) {
case GlobalValue::CommonLinkage:
case GlobalValue::LinkOnceLinkage:
case GlobalValue::WeakLinkage:
if (Subtarget->isTargetDarwin()) {

View File

@ -373,6 +373,7 @@ bool X86IntelAsmPrinter::doFinalization(Module &M) {
bool bCustomSegment = false;
switch (I->getLinkage()) {
case GlobalValue::CommonLinkage:
case GlobalValue::LinkOnceLinkage:
case GlobalValue::WeakLinkage:
SwitchToDataSection("");

View File

@ -41,6 +41,7 @@ bool X86Subtarget::GVRequiresExtraLoad(const GlobalValue* GV,
if (isTargetDarwin()) {
return (!isDirectCall &&
(GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() ||
GV->hasCommonLinkage() ||
(GV->isDeclaration() && !GV->hasNotBeenReadFromBitcode())));
} else if (isTargetELF()) {
// Extra load is needed for all non-statics.

View File

@ -930,6 +930,7 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
} else {
switch (GV->getLinkage()) {
case GlobalValue::InternalLinkage: Out << "internal "; break;
case GlobalValue::CommonLinkage: Out << "common "; break;
case GlobalValue::LinkOnceLinkage: Out << "linkonce "; break;
case GlobalValue::WeakLinkage: Out << "weak "; break;
case GlobalValue::AppendingLinkage: Out << "appending "; break;
@ -1049,6 +1050,7 @@ void AssemblyWriter::printFunction(const Function *F) {
case GlobalValue::InternalLinkage: Out << "internal "; break;
case GlobalValue::LinkOnceLinkage: Out << "linkonce "; break;
case GlobalValue::WeakLinkage: Out << "weak "; break;
case GlobalValue::CommonLinkage: Out << "common "; break;
case GlobalValue::AppendingLinkage: Out << "appending "; break;
case GlobalValue::DLLImportLinkage: Out << "dllimport "; break;
case GlobalValue::DLLExportLinkage: Out << "dllexport "; break;