Refactored JIT codegen for mingw32. Now we're using standart relocation
type for distinguish JIT & non-JIT instead of "dirty" hacks :)


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@32745 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Target/X86/X86ISelLowering.cpp b/lib/Target/X86/X86ISelLowering.cpp
index ae379cd..d92c699 100644
--- a/lib/Target/X86/X86ISelLowering.cpp
+++ b/lib/Target/X86/X86ISelLowering.cpp
@@ -664,8 +664,10 @@
   // If the callee is a GlobalAddress node (quite common, every direct call is)
   // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
   if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
-    // We should use extra load for direct calls to dllimported functions
-    if (!Subtarget->GVRequiresExtraLoad(G->getGlobal(), true))
+    // We should use extra load for direct calls to dllimported functions in
+    // non-JIT mode.
+    if (!Subtarget->GVRequiresExtraLoad(G->getGlobal(),
+                                        getTargetMachine(), true))
       Callee = DAG.getTargetGlobalAddress(G->getGlobal(), getPointerTy());
   } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee))
     Callee = DAG.getTargetExternalSymbol(S->getSymbol(), getPointerTy());
@@ -1201,8 +1203,10 @@
   // If the callee is a GlobalAddress node (quite common, every direct call is)
   // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
   if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
-    // We should use extra load for direct calls to dllimported functions
-    if (!Subtarget->GVRequiresExtraLoad(G->getGlobal(), true))
+    // We should use extra load for direct calls to dllimported functions in
+    // non-JIT mode.
+    if (!Subtarget->GVRequiresExtraLoad(G->getGlobal(),
+                                        getTargetMachine(), true))
       Callee = DAG.getTargetGlobalAddress(G->getGlobal(), getPointerTy());
   } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee))
     Callee = DAG.getTargetExternalSymbol(S->getSymbol(), getPointerTy());
@@ -1698,8 +1702,10 @@
   // If the callee is a GlobalAddress node (quite common, every direct call is)
   // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
   if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
-    // We should use extra load for direct calls to dllimported functions
-    if (!Subtarget->GVRequiresExtraLoad(G->getGlobal(), true))
+    // We should use extra load for direct calls to dllimported functions in
+    // non-JIT mode.
+    if (!Subtarget->GVRequiresExtraLoad(G->getGlobal(),
+                                        getTargetMachine(), true))
       Callee = DAG.getTargetGlobalAddress(G->getGlobal(), getPointerTy());
   } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee))
     Callee = DAG.getTargetExternalSymbol(S->getSymbol(), getPointerTy());
@@ -1996,8 +2002,10 @@
   // If the callee is a GlobalAddress node (quite common, every direct call is)
   // turn it into a TargetGlobalAddress node so that legalize doesn't hack it.
   if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) {
-    // We should use extra load for direct calls to dllimported functions
-    if (!Subtarget->GVRequiresExtraLoad(G->getGlobal(), true))
+    // We should use extra load for direct calls to dllimported functions in
+    // non-JIT mode.
+    if (!Subtarget->GVRequiresExtraLoad(G->getGlobal(),
+                                        getTargetMachine(), true))
       Callee = DAG.getTargetGlobalAddress(G->getGlobal(), getPointerTy());
   } else if (ExternalSymbolSDNode *S = dyn_cast<ExternalSymbolSDNode>(Callee))
     Callee = DAG.getTargetExternalSymbol(S->getSymbol(), getPointerTy());
@@ -3868,17 +3876,14 @@
       Result = DAG.getNode(ISD::ADD, getPointerTy(),
                            DAG.getNode(X86ISD::GlobalBaseReg, getPointerTy()),
                            Result);
-
-    // For Darwin, external and weak symbols are indirect, so we want to load
-    // the value at address GV, not the 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.
-    if (getTargetMachine().getRelocationModel() != Reloc::Static &&
-        Subtarget->GVRequiresExtraLoad(GV, false))
-      Result = DAG.getLoad(getPointerTy(), DAG.getEntryNode(), Result, NULL, 0);
-  } else if (Subtarget->GVRequiresExtraLoad(GV, false)) {
-    Result = DAG.getLoad(getPointerTy(), DAG.getEntryNode(), Result, NULL, 0);
   }
+  
+  // For Darwin & Mingw32, external and weak symbols are indirect, so we want to
+  // load the value at address GV, not the 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. Platform check is inside GVRequiresExtraLoad() call
+  if (Subtarget->GVRequiresExtraLoad(GV, getTargetMachine(), false))
+    Result = DAG.getLoad(getPointerTy(), DAG.getEntryNode(), Result, NULL, 0);
 
   return Result;
 }
@@ -5010,9 +5015,8 @@
   if (Subtarget->is64Bit() &&
       getTargetMachine().getCodeModel() != CodeModel::Small)
     return false;
-  Reloc::Model RModel = getTargetMachine().getRelocationModel();
-  return (RModel == Reloc::Static) ||
-    !Subtarget->GVRequiresExtraLoad(GV, false);
+  
+  return (!Subtarget->GVRequiresExtraLoad(GV, getTargetMachine(), false));
 }
 
 /// isShuffleMaskLegal - Targets can use this to indicate that they only
diff --git a/lib/Target/X86/X86Subtarget.cpp b/lib/Target/X86/X86Subtarget.cpp
index 4ab8713..05965c2 100644
--- a/lib/Target/X86/X86Subtarget.cpp
+++ b/lib/Target/X86/X86Subtarget.cpp
@@ -15,6 +15,7 @@
 #include "X86GenSubtarget.inc"
 #include "llvm/Module.h"
 #include "llvm/Support/CommandLine.h"
+#include "llvm/Target/TargetMachine.h"
 using namespace llvm;
 
 cl::opt<X86Subtarget::AsmWriterFlavorTy>
@@ -31,9 +32,10 @@
 /// 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 X86Subtarget::GVRequiresExtraLoad(const GlobalValue* GV,
+                                       const TargetMachine& TM,
                                        bool isDirectCall) const
 {
-  if (GenerateExtraLoadsForGVs)
+  if (TM.getRelocationModel() != Reloc::Static)
     if (isTargetDarwin()) {
       return (!isDirectCall &&
               (GV->hasWeakLinkage() || GV->hasLinkOnceLinkage() ||
@@ -208,16 +210,6 @@
   }
 }
 
-/// 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)
@@ -226,7 +218,6 @@
   // 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/lib/Target/X86/X86Subtarget.h b/lib/Target/X86/X86Subtarget.h
index 4a3bc34..ba43e38 100644
--- a/lib/Target/X86/X86Subtarget.h
+++ b/lib/Target/X86/X86Subtarget.h
@@ -21,6 +21,7 @@
 namespace llvm {
 class Module;
 class GlobalValue;
+class TargetMachine;
 
 class X86Subtarget : public TargetSubtarget {
 public:
@@ -61,9 +62,6 @@
   /// 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
@@ -114,11 +112,9 @@
   /// symbols are indirect, loading the value at address GV rather then the
   /// 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;
+  bool GVRequiresExtraLoad(const GlobalValue* GV, const TargetMachine& TM,
+                           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/lib/Target/X86/X86TargetMachine.cpp b/lib/Target/X86/X86TargetMachine.cpp
index ad0bf55..9dee7c8 100644
--- a/lib/Target/X86/X86TargetMachine.cpp
+++ b/lib/Target/X86/X86TargetMachine.cpp
@@ -115,7 +115,7 @@
               Subtarget.getStackAlignment(), Subtarget.is64Bit() ? -8 : -4),
     InstrInfo(*this), JITInfo(*this), TLInfo(*this) {
   if (getRelocationModel() == Reloc::Default)
-    if (Subtarget.isTargetDarwin())
+    if (Subtarget.isTargetDarwin() || Subtarget.isTargetCygwin())
       setRelocationModel(Reloc::DynamicNoPIC);
     else
       setRelocationModel(Reloc::Static);
@@ -167,9 +167,6 @@
   if (Subtarget.is64Bit())
     setCodeModel(CodeModel::Large);
 
-  // Inform the subtarget that we are in JIT mode.
-  Subtarget.SetJITMode(); 
-  
   PM.add(createX86CodeEmitterPass(*this, MCE));
   return false;
 }