Introduce MCCodeGenInfo, which keeps information that can affect codegen
(including compilation, assembly). Move relocation model Reloc::Model from
TargetMachine to MCCodeGenInfo so it's accessible even without TargetMachine.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@135468 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/llvm-c/Target.h b/include/llvm-c/Target.h
index d216440..fbaf0d5 100644
--- a/include/llvm-c/Target.h
+++ b/include/llvm-c/Target.h
@@ -46,6 +46,11 @@
 #include "llvm/Config/Targets.def"
 #undef LLVM_TARGET  /* Explicit undef to make SWIG happier */
   
+#define LLVM_TARGET(TargetName) \
+  void LLVMInitialize##TargetName##MCCodeGenInfo(void);
+#include "llvm/Config/Targets.def"
+#undef LLVM_TARGET  /* Explicit undef to make SWIG happier */
+  
 /** LLVMInitializeAllTargetInfos - The main program should call this function if
     it wants access to all available targets that LLVM is configured to
     support. */
@@ -73,6 +78,7 @@
   LLVM_NATIVE_TARGETINFO();
   LLVM_NATIVE_TARGET();
   LLVM_NATIVE_MCASMINFO();
+  LLVM_NATIVE_MCCODEGENINFO();
   return 0;
 #else
   return 1;
diff --git a/include/llvm/Config/config.h.cmake b/include/llvm/Config/config.h.cmake
index 0b8a0ad..82ebc56 100644
--- a/include/llvm/Config/config.h.cmake
+++ b/include/llvm/Config/config.h.cmake
@@ -560,6 +560,9 @@
 /* LLVM name for the native MCAsmInfo init function, if available */
 #cmakedefine LLVM_NATIVE_MCASMINFO LLVMInitialize${LLVM_NATIVE_ARCH}MCAsmInfo
 
+/* LLVM name for the native MCCodeGenInfo init function, if available */
+#cmakedefine LLVM_NATIVE_MCCODEGENINFO LLVMInitialize${LLVM_NATIVE_ARCH}MCCodeGenInfo
+
 /* Define if this is Unixish platform */
 #cmakedefine LLVM_ON_UNIX ${LLVM_ON_UNIX}
 
diff --git a/include/llvm/Config/config.h.in b/include/llvm/Config/config.h.in
index 0a716ea..6042d93 100644
--- a/include/llvm/Config/config.h.in
+++ b/include/llvm/Config/config.h.in
@@ -576,6 +576,9 @@
 /* LLVM name for the native MCAsmInfo init function, if available */
 #undef LLVM_NATIVE_MCASMINFO
 
+/* LLVM name for the native MCCODEGENInfo init function, if available */
+#undef LLVM_NATIVE_MCCODEGENINFO
+
 /* LLVM name for the native Target init function, if available */
 #undef LLVM_NATIVE_TARGET
 
diff --git a/include/llvm/Config/llvm-config.h.cmake b/include/llvm/Config/llvm-config.h.cmake
index 5f948a2..63d2b3f 100644
--- a/include/llvm/Config/llvm-config.h.cmake
+++ b/include/llvm/Config/llvm-config.h.cmake
@@ -61,6 +61,9 @@
 /* LLVM name for the native MCAsmInfo init function, if available */
 #cmakedefine LLVM_NATIVE_MCASMINFO LLVMInitialize${LLVM_NATIVE_ARCH}MCAsmInfo
 
+/* LLVM name for the native MCCodeGenInfo init function, if available */
+#cmakedefine LLVM_NATIVE_MCCODEGENINFO LLVMInitialize${LLVM_NATIVE_ARCH}MCCodeGenInfo
+
 /* LLVM name for the native AsmPrinter init function, if available */
 #cmakedefine LLVM_NATIVE_ASMPRINTER LLVMInitialize${LLVM_NATIVE_ARCH}AsmPrinter
 
diff --git a/include/llvm/Config/llvm-config.h.in b/include/llvm/Config/llvm-config.h.in
index bc8ddce..980096a 100644
--- a/include/llvm/Config/llvm-config.h.in
+++ b/include/llvm/Config/llvm-config.h.in
@@ -61,6 +61,9 @@
 /* LLVM name for the native MCAsmInfo init function, if available */
 #undef LLVM_NATIVE_MCASMINFO
 
+/* LLVM name for the native MCCodeGenInfo init function, if available */
+#undef LLVM_NATIVE_MCCODEGENINFO
+
 /* LLVM name for the native AsmPrinter init function, if available */
 #undef LLVM_NATIVE_ASMPRINTER
 
diff --git a/include/llvm/ExecutionEngine/ExecutionEngine.h b/include/llvm/ExecutionEngine/ExecutionEngine.h
index f66f9ec..2afa791 100644
--- a/include/llvm/ExecutionEngine/ExecutionEngine.h
+++ b/include/llvm/ExecutionEngine/ExecutionEngine.h
@@ -18,6 +18,7 @@
 #include <vector>
 #include <map>
 #include <string>
+#include "llvm/MC/MCCodeGenInfo.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/ValueMap.h"
@@ -201,6 +202,7 @@
                                     CodeGenOpt::Level OptLevel =
                                       CodeGenOpt::Default,
                                     bool GVsWithCode = true,
+                                    Reloc::Model RM = Reloc::Default,
                                     CodeModel::Model CMM =
                                       CodeModel::Default);
 
@@ -463,6 +465,7 @@
   CodeGenOpt::Level OptLevel;
   JITMemoryManager *JMM;
   bool AllocateGVsWithCode;
+  Reloc::Model RelocModel;
   CodeModel::Model CMModel;
   std::string MArch;
   std::string MCPU;
@@ -476,6 +479,7 @@
     OptLevel = CodeGenOpt::Default;
     JMM = NULL;
     AllocateGVsWithCode = false;
+    RelocModel = Reloc::Default;
     CMModel = CodeModel::Default;
     UseMCJIT = false;
   }
@@ -517,6 +521,13 @@
     return *this;
   }
 
+  /// setRelocationModel - Set the relocation model that the ExecutionEngine
+  /// target is using. Defaults to target specific default "Reloc::Default".
+  EngineBuilder &setRelocationModel(Reloc::Model RM) {
+    RelocModel = RM;
+    return *this;
+  }
+
   /// setCodeModel - Set the CodeModel that the ExecutionEngine target
   /// data is using. Defaults to target specific default "CodeModel::Default".
   EngineBuilder &setCodeModel(CodeModel::Model M) {
@@ -569,6 +580,7 @@
                                      StringRef MArch,
                                      StringRef MCPU,
                                      const SmallVectorImpl<std::string>& MAttrs,
+                                     Reloc::Model RM,
                                      std::string *Err);
 
   ExecutionEngine *create();
diff --git a/include/llvm/MC/MCCodeGenInfo.h b/include/llvm/MC/MCCodeGenInfo.h
new file mode 100644
index 0000000..908922a
--- /dev/null
+++ b/include/llvm/MC/MCCodeGenInfo.h
@@ -0,0 +1,36 @@
+//===-- llvm/MC/MCCodeGenInfo.h - Target CodeGen Info -----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file tracks information about the target which can affect codegen,
+// asm parsing, and asm printing. For example, relocation model.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MC_MCCODEGENINFO_H
+#define LLVM_MC_MCCODEGENINFO_H
+
+namespace llvm {
+  // Relocation model types.
+  namespace Reloc {
+    enum Model { Default, Static, PIC_, DynamicNoPIC };
+  }
+
+  class MCCodeGenInfo {
+    /// RelocationModel - Relocation model: statcic, pic, etc.
+    ///
+    Reloc::Model RelocationModel;
+
+  public:
+    void InitMCCodeGenInfo(Reloc::Model RM = Reloc::Default);
+
+    Reloc::Model getRelocationModel() const { return RelocationModel; }
+  };
+} // namespace llvm
+
+#endif
diff --git a/include/llvm/Target/TargetMachine.h b/include/llvm/Target/TargetMachine.h
index ac41a58..f4c845a 100644
--- a/include/llvm/Target/TargetMachine.h
+++ b/include/llvm/Target/TargetMachine.h
@@ -14,6 +14,7 @@
 #ifndef LLVM_TARGET_TARGETMACHINE_H
 #define LLVM_TARGET_TARGETMACHINE_H
 
+#include "llvm/MC/MCCodeGenInfo.h"
 #include "llvm/ADT/StringRef.h"
 #include <cassert>
 #include <string>
@@ -23,6 +24,7 @@
 class InstrItineraryData;
 class JITCodeEmitter;
 class MCAsmInfo;
+class MCCodeGenInfo;
 class MCContext;
 class Pass;
 class PassManager;
@@ -41,16 +43,6 @@
 class formatted_raw_ostream;
 class raw_ostream;
 
-// Relocation model types.
-namespace Reloc {
-  enum Model {
-    Default,
-    Static,
-    PIC_,         // Cannot be named PIC due to collision with -DPIC
-    DynamicNoPIC
-  };
-}
-
 // Code model types.
 namespace CodeModel {
   enum Model {
@@ -108,6 +100,10 @@
   std::string TargetCPU;
   std::string TargetFS;
 
+  /// CodeGenInfo - Low level target information such as relocation model.
+  ///
+  const MCCodeGenInfo *CodeGenInfo;
+
   /// AsmInfo - Contains target specific asm information.
   ///
   const MCAsmInfo *AsmInfo;
@@ -214,11 +210,7 @@
 
   /// getRelocationModel - Returns the code generation relocation model. The
   /// choices are static, PIC, and dynamic-no-pic, and target default.
-  static Reloc::Model getRelocationModel();
-
-  /// setRelocationModel - Sets the code generation relocation model.
-  ///
-  static void setRelocationModel(Reloc::Model Model);
+  Reloc::Model getRelocationModel() const;
 
   /// getCodeModel - Returns the code model. The choices are small, kernel,
   /// medium, large, and target default.
@@ -309,7 +301,7 @@
 class LLVMTargetMachine : public TargetMachine {
 protected: // Can only create subclasses.
   LLVMTargetMachine(const Target &T, StringRef TargetTriple,
-                    StringRef CPU, StringRef FS);
+                    StringRef CPU, StringRef FS, Reloc::Model RM);
 
 private:
   /// addCommonCodeGenPasses - Add standard LLVM codegen passes used for
diff --git a/include/llvm/Target/TargetRegistry.h b/include/llvm/Target/TargetRegistry.h
index a33d17b..7d63d56 100644
--- a/include/llvm/Target/TargetRegistry.h
+++ b/include/llvm/Target/TargetRegistry.h
@@ -19,6 +19,7 @@
 #ifndef LLVM_TARGET_TARGETREGISTRY_H
 #define LLVM_TARGET_TARGETREGISTRY_H
 
+#include "llvm/MC/MCCodeGenInfo.h"
 #include "llvm/ADT/Triple.h"
 #include <string>
 #include <cassert>
@@ -37,6 +38,7 @@
   class MCRegisterInfo;
   class MCStreamer;
   class MCSubtargetInfo;
+  class MCCodeGenInfo;
   class TargetAsmBackend;
   class TargetAsmLexer;
   class TargetAsmParser;
@@ -68,15 +70,17 @@
 
     typedef MCAsmInfo *(*MCAsmInfoCtorFnTy)(const Target &T,
                                             StringRef TT);
+    typedef MCCodeGenInfo *(*MCCodeGenInfoCtorFnTy)(StringRef TT, Reloc::Model M);
     typedef MCInstrInfo *(*MCInstrInfoCtorFnTy)(void);
     typedef MCRegisterInfo *(*MCRegInfoCtorFnTy)(StringRef TT);
     typedef MCSubtargetInfo *(*MCSubtargetInfoCtorFnTy)(StringRef TT,
                                                         StringRef CPU,
                                                         StringRef Features);
     typedef TargetMachine *(*TargetMachineCtorTy)(const Target &T,
-                                                  const std::string &TT,
-                                                  const std::string &CPU,
-                                                  const std::string &Features);
+                                                  StringRef TT,
+                                                  StringRef CPU,
+                                                  StringRef Features,
+                                                  Reloc::Model RM);
     typedef AsmPrinter *(*AsmPrinterCtorTy)(TargetMachine &TM,
                                             MCStreamer &Streamer);
     typedef TargetAsmBackend *(*AsmBackendCtorTy)(const Target &T,
@@ -132,6 +136,10 @@
     /// registered.
     MCAsmInfoCtorFnTy MCAsmInfoCtorFn;
 
+    /// MCCodeGenInfoCtorFn - Constructor function for this target's MCCodeGenInfo,
+    /// if registered.
+    MCCodeGenInfoCtorFnTy MCCodeGenInfoCtorFn;
+
     /// MCInstrInfoCtorFn - Constructor function for this target's MCInstrInfo,
     /// if registered.
     MCInstrInfoCtorFnTy MCInstrInfoCtorFn;
@@ -253,6 +261,14 @@
       return MCAsmInfoCtorFn(*this, Triple);
     }
 
+    /// createMCCodeGenInfo - Create a MCCodeGenInfo implementation.
+    ///
+    MCCodeGenInfo *createMCCodeGenInfo(StringRef Triple, Reloc::Model M) const {
+      if (!MCCodeGenInfoCtorFn)
+        return 0;
+      return MCCodeGenInfoCtorFn(Triple, M);
+    }
+
     /// createMCInstrInfo - Create a MCInstrInfo implementation.
     ///
     MCInstrInfo *createMCInstrInfo() const {
@@ -292,12 +308,12 @@
     /// feature set; it should always be provided. Generally this should be
     /// either the target triple from the module, or the target triple of the
     /// host if that does not exist.
-    TargetMachine *createTargetMachine(const std::string &Triple,
-                                       const std::string &CPU,
-                                       const std::string &Features) const {
+    TargetMachine *createTargetMachine(StringRef Triple, StringRef CPU,
+                                       StringRef Features,
+                                       Reloc::Model RM = Reloc::Default) const {
       if (!TargetMachineCtorFn)
         return 0;
-      return TargetMachineCtorFn(*this, Triple, CPU, Features);
+      return TargetMachineCtorFn(*this, Triple, CPU, Features, RM);
     }
 
     /// createAsmBackend - Create a target specific assembly parser.
@@ -500,6 +516,22 @@
         T.MCAsmInfoCtorFn = Fn;
     }
 
+    /// RegisterMCCodeGenInfo - Register a MCCodeGenInfo implementation for the
+    /// given target.
+    ///
+    /// Clients are responsible for ensuring that registration doesn't occur
+    /// while another thread is attempting to access the registry. Typically
+    /// this is done by initializing all targets at program startup.
+    ///
+    /// @param T - The target being registered.
+    /// @param Fn - A function to construct a MCCodeGenInfo for the target.
+    static void RegisterMCCodeGenInfo(Target &T,
+                                     Target::MCCodeGenInfoCtorFnTy Fn) {
+      // Ignore duplicate registration.
+      if (!T.MCCodeGenInfoCtorFn)
+        T.MCCodeGenInfoCtorFn = Fn;
+    }
+
     /// RegisterMCInstrInfo - Register a MCInstrInfo implementation for the
     /// given target.
     ///
@@ -756,6 +788,39 @@
     }
   };
 
+  /// RegisterMCCodeGenInfo - Helper template for registering a target codegen info
+  /// implementation.  This invokes the static "Create" method on the class
+  /// to actually do the construction.  Usage:
+  ///
+  /// extern "C" void LLVMInitializeFooTarget() {
+  ///   extern Target TheFooTarget;
+  ///   RegisterMCCodeGenInfo<FooMCCodeGenInfo> X(TheFooTarget);
+  /// }
+  template<class MCCodeGenInfoImpl>
+  struct RegisterMCCodeGenInfo {
+    RegisterMCCodeGenInfo(Target &T) {
+      TargetRegistry::RegisterMCCodeGenInfo(T, &Allocator);
+    }
+  private:
+    static MCCodeGenInfo *Allocator(StringRef TT, Reloc::Model M) {
+      return new MCCodeGenInfoImpl();
+    }
+  };
+
+  /// RegisterMCCodeGenInfoFn - Helper template for registering a target codegen
+  /// info implementation.  This invokes the specified function to do the
+  /// construction.  Usage:
+  ///
+  /// extern "C" void LLVMInitializeFooTarget() {
+  ///   extern Target TheFooTarget;
+  ///   RegisterMCCodeGenInfoFn X(TheFooTarget, TheFunction);
+  /// }
+  struct RegisterMCCodeGenInfoFn {
+    RegisterMCCodeGenInfoFn(Target &T, Target::MCCodeGenInfoCtorFnTy Fn) {
+      TargetRegistry::RegisterMCCodeGenInfo(T, Fn);
+    }
+  };
+
   /// RegisterMCInstrInfo - Helper template for registering a target instruction
   /// info implementation.  This invokes the static "Create" method on the class
   /// to actually do the construction.  Usage:
@@ -871,10 +936,10 @@
     }
 
   private:
-    static TargetMachine *Allocator(const Target &T, const std::string &TT,
-                                    const std::string &CPU,
-                                    const std::string &FS) {
-      return new TargetMachineImpl(T, TT, CPU, FS);
+    static TargetMachine *Allocator(const Target &T, StringRef TT,
+                                    StringRef CPU, StringRef FS,
+                                    Reloc::Model RM) {
+      return new TargetMachineImpl(T, TT, CPU, FS, RM);
     }
   };
 
diff --git a/include/llvm/Target/TargetSelect.h b/include/llvm/Target/TargetSelect.h
index 3cccaa8..81fd9c9 100644
--- a/include/llvm/Target/TargetSelect.h
+++ b/include/llvm/Target/TargetSelect.h
@@ -31,6 +31,10 @@
 #include "llvm/Config/Targets.def"
 
 #define LLVM_TARGET(TargetName) \
+  void LLVMInitialize##TargetName##MCCodeGenInfo();
+#include "llvm/Config/Targets.def"
+
+#define LLVM_TARGET(TargetName) \
   void LLVMInitialize##TargetName##MCInstrInfo();
 #include "llvm/Config/Targets.def"
 
@@ -91,6 +95,16 @@
 #include "llvm/Config/Targets.def"
   }
   
+  /// InitializeAllMCCodeGenInfos - The main program should call this function
+  /// if it wants access to all targets machines that LLVM is configured to
+  /// support, to make them available via the TargetRegistry.
+  ///
+  /// It is legal for a client to make multiple calls to this function.
+  inline void InitializeAllMCCodeGenInfos() {
+#define LLVM_TARGET(TargetName) LLVMInitialize##TargetName##MCCodeGenInfo();
+#include "llvm/Config/Targets.def"
+  }
+  
   /// InitializeAllMCInstrInfos - The main program should call this function
   /// if it wants access to all available instruction infos for targets that
   /// LLVM is configured to support, to make them available via the
@@ -164,6 +178,7 @@
     LLVM_NATIVE_TARGETINFO();
     LLVM_NATIVE_TARGET();
     LLVM_NATIVE_MCASMINFO();
+    LLVM_NATIVE_MCCODEGENINFO();
     return false;
 #else
     return true;