diff --git a/llvm/lib/Target/X86/X86Subtarget.cpp b/llvm/lib/Target/X86/X86Subtarget.cpp index ff88fdbca265..5281dcda7aab 100644 --- a/llvm/lib/Target/X86/X86Subtarget.cpp +++ b/llvm/lib/Target/X86/X86Subtarget.cpp @@ -32,13 +32,14 @@ AsmWriterFlavor("x86-asm-syntax", cl::init(X86Subtarget::unset), /// or index register of the address, not the GV offset field. bool X86Subtarget::GVRequiresExtraLoad(const GlobalValue* GV, bool isDirectCall) const { - if (isTargetDarwin()) { - return (!isDirectCall && - (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() || - (GV->isExternal() && !GV->hasNotBeenReadFromBytecode()))); - } else if (isTargetCygwin() || isTargetWindows()) { - return (GV->hasDLLImportLinkage()); - } + if (GenerateExtraLoadsForGVs) + if (isTargetDarwin()) { + return (!isDirectCall && + (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() || + (GV->isExternal() && !GV->hasNotBeenReadFromBytecode()))); + } else if (isTargetCygwin() || isTargetWindows()) { + return (GV->hasDLLImportLinkage()); + } return false; } @@ -206,6 +207,15 @@ static const char *GetCurrentX86CPU() { } } +/// SetJITMode - This is called to inform the subtarget info that we are +/// producing code for the JIT. +void X86Subtarget::SetJITMode() { + // JIT mode doesn't want extra loads for dllimported symbols, it knows exactly + // where everything is. + if (isTargetCygwin()) + GenerateExtraLoadsForGVs = false; +} + X86Subtarget::X86Subtarget(const Module &M, const std::string &FS, bool is64Bit) : AsmFlavor(AsmWriterFlavor) , X86SSELevel(NoMMXSSE) @@ -214,6 +224,7 @@ X86Subtarget::X86Subtarget(const Module &M, const std::string &FS, bool is64Bit) // FIXME: this is a known good value for Yonah. How about others? , MinRepStrSizeThreshold(128) , Is64Bit(is64Bit) + , GenerateExtraLoadsForGVs(true) , TargetType(isELF) { // Default to ELF unless otherwise specified. // Determine default and user specified characteristics diff --git a/llvm/lib/Target/X86/X86Subtarget.h b/llvm/lib/Target/X86/X86Subtarget.h index 70e70e901108..4a3bc342ee26 100644 --- a/llvm/lib/Target/X86/X86Subtarget.h +++ b/llvm/lib/Target/X86/X86Subtarget.h @@ -61,6 +61,9 @@ private: /// pointer size is 64 bit. bool Is64Bit; + /// GenerateExtraLoadsForGVs - True if we should generate extra loads for + /// indirect symbols (e.g. dllimported symbols on windows). + bool GenerateExtraLoadsForGVs; public: enum { isELF, isCygwin, isDarwin, isWindows @@ -112,6 +115,10 @@ public: /// value of GV itself. This means that the GlobalAddress must be in the base /// or index register of the address, not the GV offset field. bool GVRequiresExtraLoad(const GlobalValue* GV, bool isDirectCall) const; + + /// SetJITMode - This is called to inform the subtarget info that we are + /// producing code for the JIT. + void SetJITMode(); }; namespace X86 { diff --git a/llvm/lib/Target/X86/X86TargetMachine.cpp b/llvm/lib/Target/X86/X86TargetMachine.cpp index 2d48056caa95..ad0bf5510c1c 100644 --- a/llvm/lib/Target/X86/X86TargetMachine.cpp +++ b/llvm/lib/Target/X86/X86TargetMachine.cpp @@ -166,6 +166,9 @@ bool X86TargetMachine::addCodeEmitter(FunctionPassManager &PM, bool Fast, // JIT cannot ensure globals are placed in the lower 4G of address. if (Subtarget.is64Bit()) setCodeModel(CodeModel::Large); + + // Inform the subtarget that we are in JIT mode. + Subtarget.SetJITMode(); PM.add(createX86CodeEmitterPass(*this, MCE)); return false;