diff options
Diffstat (limited to 'llvm/lib')
| -rw-r--r-- | llvm/lib/AsmParser/llvmAsmParser.y | 2 | ||||
| -rw-r--r-- | llvm/lib/ExecutionEngine/ExecutionEngine.cpp | 2 | ||||
| -rw-r--r-- | llvm/lib/Linker/LinkModules.cpp | 36 | ||||
| -rw-r--r-- | llvm/lib/Target/CBackend/Writer.cpp | 15 | ||||
| -rwxr-xr-x | llvm/lib/Target/X86/X86ATTAsmPrinter.cpp | 4 | ||||
| -rw-r--r-- | llvm/lib/Target/X86/X86AsmPrinter.cpp | 35 | ||||
| -rwxr-xr-x | llvm/lib/Target/X86/X86AsmPrinter.h | 3 | ||||
| -rw-r--r-- | llvm/lib/VMCore/ConstantFolding.cpp | 7 | 
8 files changed, 78 insertions, 26 deletions
diff --git a/llvm/lib/AsmParser/llvmAsmParser.y b/llvm/lib/AsmParser/llvmAsmParser.y index a6f6c2e19b1..1d1558eb6be 100644 --- a/llvm/lib/AsmParser/llvmAsmParser.y +++ b/llvm/lib/AsmParser/llvmAsmParser.y @@ -2201,7 +2201,7 @@ Function : BasicBlockList END {  FnDeclareLinkage: /*default*/ |                    DLLIMPORT   { CurFun.Linkage = GlobalValue::DLLImportLinkage; } | -                  EXTERN_WEAK { CurFun.Linkage = GlobalValue::DLLImportLinkage; }; +                  EXTERN_WEAK { CurFun.Linkage = GlobalValue::ExternalWeakLinkage; };  FunctionProto : DECLARE { CurFun.isDeclare = true; } FnDeclareLinkage FunctionHeaderH {      $$ = CurFun.CurrentFunction; diff --git a/llvm/lib/ExecutionEngine/ExecutionEngine.cpp b/llvm/lib/ExecutionEngine/ExecutionEngine.cpp index 683b4c75176..8447acf0e53 100644 --- a/llvm/lib/ExecutionEngine/ExecutionEngine.cpp +++ b/llvm/lib/ExecutionEngine/ExecutionEngine.cpp @@ -681,7 +681,7 @@ void ExecutionEngine::emitGlobals() {          // Otherwise, we know it's linkonce/weak, replace it if this is a strong          // symbol. -        if (GV->hasExternalLinkage()) +        if (GV->hasExternalLinkage() || GVEntry->hasExternalWeakLinkage())            GVEntry = GV;        }      } diff --git a/llvm/lib/Linker/LinkModules.cpp b/llvm/lib/Linker/LinkModules.cpp index 46f74359874..b09fd656f2e 100644 --- a/llvm/lib/Linker/LinkModules.cpp +++ b/llvm/lib/Linker/LinkModules.cpp @@ -360,6 +360,7 @@ static bool GetLinkageResult(GlobalValue *Dest, GlobalValue *Src,      // If Src is external or if both Src & Drc are external..  Just link the      // external globals, we aren't adding anything.      if (Src->hasDLLImportLinkage()) { +      // If one of GVs has DLLImport linkage, result should be dllimport'ed.        if (Dest->isExternal()) {          LinkFromSrc = true;          LT = Src->getLinkage(); @@ -379,8 +380,9 @@ static bool GetLinkageResult(GlobalValue *Dest, GlobalValue *Src,      LinkFromSrc = true; // Special cased.      LT = Src->getLinkage();    } else if (Src->hasWeakLinkage() || Src->hasLinkOnceLinkage()) { -    // At this point we know that Dest has LinkOnce, External, Weak, DLL* linkage. -    if (Dest->hasLinkOnceLinkage() && Src->hasWeakLinkage()) { +    // At this point we know that Dest has LinkOnce, External*, Weak, DLL* linkage. +    if ((Dest->hasLinkOnceLinkage() && Src->hasWeakLinkage()) || +        Dest->hasExternalWeakLinkage()) {        LinkFromSrc = true;        LT = Src->getLinkage();      } else { @@ -388,16 +390,23 @@ static bool GetLinkageResult(GlobalValue *Dest, GlobalValue *Src,        LT = Dest->getLinkage();      }    } else if (Dest->hasWeakLinkage() || Dest->hasLinkOnceLinkage()) { -    // At this point we know that Src has External or DLL* linkage. -    LinkFromSrc = true; -    LT = GlobalValue::ExternalLinkage; +    // At this point we know that Src has External* or DLL* linkage. +    if (Src->hasExternalWeakLinkage()) { +      LinkFromSrc = false; +      LT = Dest->getLinkage(); +    } else { +      LinkFromSrc = true; +      LT = GlobalValue::ExternalLinkage; +    }    } else {      assert((Dest->hasExternalLinkage() ||              Dest->hasDLLImportLinkage() || -            Dest->hasDLLExportLinkage()) && +            Dest->hasDLLExportLinkage() || +            Dest->hasExternalWeakLinkage()) &&             (Src->hasExternalLinkage() ||              Src->hasDLLImportLinkage() || -            Src->hasDLLExportLinkage()) && +            Src->hasDLLExportLinkage() || +            Src->hasExternalWeakLinkage()) &&             "Unexpected linkage type!");      return Error(Err, "Linking globals named '" + Src->getName() +                   "': symbol multiply defined!"); @@ -631,19 +640,22 @@ static bool LinkFunctionProtos(Module *Dest, const Module *Src,        ValueMap.insert(std::make_pair(SF, DF));        DF->setLinkage(SF->getLinkage());      } else if (SF->hasWeakLinkage() || SF->hasLinkOnceLinkage()) { -      // At this point we know that DF has LinkOnce, Weak, or External linkage. +      // At this point we know that DF has LinkOnce, Weak, or External* linkage.        ValueMap.insert(std::make_pair(SF, DF));        // Linkonce+Weak = Weak -      if (DF->hasLinkOnceLinkage() && SF->hasWeakLinkage()) +      // *+External Weak = * +      if ((DF->hasLinkOnceLinkage() && SF->hasWeakLinkage()) || +          DF->hasExternalWeakLinkage())          DF->setLinkage(SF->getLinkage()); +      } else if (DF->hasWeakLinkage() || DF->hasLinkOnceLinkage()) { -      // At this point we know that SF has LinkOnce or External linkage. +      // At this point we know that SF has LinkOnce or External* linkage.        ValueMap.insert(std::make_pair(SF, DF)); -      if (!SF->hasLinkOnceLinkage())   // Don't inherit linkonce linkage +      if (!SF->hasLinkOnceLinkage() && !SF->hasExternalWeakLinkage()) +        // Don't inherit linkonce & external weak linkage          DF->setLinkage(SF->getLinkage()); -      } else if (SF->getLinkage() != DF->getLinkage()) {        return Error(Err, "Functions named '" + SF->getName() +                     "' have different linkage specifiers!"); diff --git a/llvm/lib/Target/CBackend/Writer.cpp b/llvm/lib/Target/CBackend/Writer.cpp index fa869db6aa3..6d83aeb85db 100644 --- a/llvm/lib/Target/CBackend/Writer.cpp +++ b/llvm/lib/Target/CBackend/Writer.cpp @@ -1157,8 +1157,6 @@ static void generateCompilerSpecificCode(std::ostream& Out) {        << "#define __attribute__(X)\n"        << "#endif\n\n"; -#if 0 -  // At some point, we should support "external weak" vs. "weak" linkages.    // On Mac OS X, "external weak" is spelled "__attribute__((weak_import))".    Out << "#if defined(__GNUC__) && defined(__APPLE_CC__)\n"        << "#define __EXTERNAL_WEAK__ __attribute__((weak_import))\n" @@ -1167,7 +1165,6 @@ static void generateCompilerSpecificCode(std::ostream& Out) {        << "#else\n"        << "#define __EXTERNAL_WEAK__\n"        << "#endif\n\n"; -#endif    // For now, turn off the weak linkage attribute on Mac OS X. (See above.)    Out << "#if defined(__GNUC__) && defined(__APPLE_CC__)\n" @@ -1357,7 +1354,11 @@ bool CWriter::doInitialization(Module &M) {          Out << "__declspec(dllimport) ";          printType(Out, I->getType()->getElementType(), Mang->getValueName(I));          Out << ";\n";         -      }       +      } else if (I->hasExternalWeakLinkage()) { +        Out << "extern "; +        printType(Out, I->getType()->getElementType(), Mang->getValueName(I)); +        Out << " __EXTERNAL_WEAK__ ;\n"; +      }      }    } @@ -1370,9 +1371,13 @@ bool CWriter::doInitialization(Module &M) {      // Don't print declarations for intrinsic functions.      if (!I->getIntrinsicID() && I->getName() != "setjmp" &&           I->getName() != "longjmp" && I->getName() != "_setjmp") { +      if (I->hasExternalWeakLinkage()) +        Out << "extern ";        printFunctionSignature(I, true);        if (I->hasWeakLinkage() || I->hasLinkOnceLinkage())           Out << " __ATTRIBUTE_WEAK__"; +      if (I->hasExternalWeakLinkage()) +        Out << " __EXTERNAL_WEAK__";        if (StaticCtors.count(I))          Out << " __ATTRIBUTE_CTOR__";        if (StaticDtors.count(I)) @@ -1405,6 +1410,8 @@ bool CWriter::doInitialization(Module &M) {            Out << " __attribute__((common))";          else if (I->hasWeakLinkage())            Out << " __ATTRIBUTE_WEAK__"; +        else if (I->hasExternalWeakLinkage()) +          Out << " __EXTERNAL_WEAK__";          Out << ";\n";        }    } diff --git a/llvm/lib/Target/X86/X86ATTAsmPrinter.cpp b/llvm/lib/Target/X86/X86ATTAsmPrinter.cpp index 7784f621ae8..88d0c7c16fe 100755 --- a/llvm/lib/Target/X86/X86ATTAsmPrinter.cpp +++ b/llvm/lib/Target/X86/X86ATTAsmPrinter.cpp @@ -255,6 +255,10 @@ void X86ATTAsmPrinter::printOperand(const MachineInstr *MI, unsigned OpNo,        }               O << Name;      } + +    if (GV->hasExternalWeakLinkage()) { +      ExtWeakSymbols.insert(Name); +    }      int Offset = MO.getOffset();      if (Offset > 0) diff --git a/llvm/lib/Target/X86/X86AsmPrinter.cpp b/llvm/lib/Target/X86/X86AsmPrinter.cpp index 2c53b72bd2a..cb792ad1ce0 100644 --- a/llvm/lib/Target/X86/X86AsmPrinter.cpp +++ b/llvm/lib/Target/X86/X86AsmPrinter.cpp @@ -128,11 +128,12 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) {    // from how MASM does things.  When making changes here don't forget to look    // at X86IntelAsmPrinter::doFinalization().    const TargetData *TD = TM.getTargetData(); - +      // Print out module-level global variables here.    for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();         I != E; ++I) { -    if (!I->hasInitializer()) continue;   // External global require no code +    if (!I->hasInitializer() && !I->hasExternalWeakLinkage()) +      continue;   // External global require no code      // Check to see if this is a special global used by LLVM, if so, emit it.      if (EmitSpecialLLVMGlobal(I)) @@ -176,6 +177,17 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) {        O << "\t\t" << TAI->getCommentString() << " " << I->getName() << "\n";      } else {        switch (I->getLinkage()) { +      case GlobalValue::ExternalWeakLinkage: +       if (Subtarget->isTargetDarwin()) { +         assert(0 && "External weak linkage for Darwin not implemented yet"); +       } else if (Subtarget->isTargetCygwin()) { +         // There is no external weak linkage on Mingw32 platform. +         // Defaulting just to external +         O << "\t.globl " << name << "\n"; +       } else { +         O << "\t.weak " << name << "\n"; +         break; +       }        case GlobalValue::LinkOnceLinkage:        case GlobalValue::WeakLinkage:          if (Subtarget->isTargetDarwin()) { @@ -270,7 +282,24 @@ bool X86SharedAsmPrinter::doFinalization(Module &M) {           i != e; ++i) {      O << "\t.ascii \" -export:" << *i << "\"\n";    }     -  + +  if (Subtarget->isTargetDarwin()) { +    if (ExtWeakSymbols.begin() != ExtWeakSymbols.end()) +      assert(0 && "External weak linkage for Darwin not implemented yet"); +  } else if (Subtarget->isTargetCygwin()) { +    // There is no external weak linkage on Mingw32 platform. +    // Defaulting to external +  } else { +    if (ExtWeakSymbols.begin() != ExtWeakSymbols.end()) +      SwitchToDataSection(""); + +    for (std::set<std::string>::iterator i = ExtWeakSymbols.begin(), +         e = ExtWeakSymbols.end(); +         i != e; ++i) { +      O << "\t.weak " << *i << "\n"; +    } +  } +      if (Subtarget->isTargetDarwin()) {      SwitchToDataSection(""); diff --git a/llvm/lib/Target/X86/X86AsmPrinter.h b/llvm/lib/Target/X86/X86AsmPrinter.h index 3503e37c0bc..8dad733bb28 100755 --- a/llvm/lib/Target/X86/X86AsmPrinter.h +++ b/llvm/lib/Target/X86/X86AsmPrinter.h @@ -84,6 +84,9 @@ struct VISIBILITY_HIDDEN X86SharedAsmPrinter : public AsmPrinter {    // Necessary for dllexport support    std::set<std::string> DLLExportedFns, DLLExportedGVs; + +  // Necessary for external weak linkage support +  std::set<std::string> ExtWeakSymbols;    inline static bool isScale(const MachineOperand &MO) {      return MO.isImmediate() && diff --git a/llvm/lib/VMCore/ConstantFolding.cpp b/llvm/lib/VMCore/ConstantFolding.cpp index 9974071385b..fd6ad108a9c 100644 --- a/llvm/lib/VMCore/ConstantFolding.cpp +++ b/llvm/lib/VMCore/ConstantFolding.cpp @@ -894,11 +894,8 @@ Constant *llvm::ConstantFoldCastInstruction(unsigned opc, const Constant *V,    case Instruction::PtrToInt:      // Cast of a global address to boolean is always true. -    if (isa<GlobalValue>(V)) { -      if (DestTy == Type::BoolTy) -        // FIXME: When we support 'external weak' references, we have to  -        // prevent this transformation from happening.  This code will need  -        // to be updated to ignore external weak symbols when we support it. +    if (const GlobalValue *GV = dyn_cast<GlobalValue>(V)) { +      if (DestTy == Type::BoolTy && !GV->hasExternalWeakLinkage())          return ConstantBool::getTrue();      }      break;  | 

