[llvm-commits] [llvm] r58142 - in /llvm/trunk: include/llvm/ExecutionEngine/ExecutionEngine.h include/llvm/Target/TargetJITInfo.h lib/ExecutionEngine/ExecutionEngine.cpp lib/ExecutionEngine/JIT/JIT.cpp lib/ExecutionEngine/JIT/JIT.h lib/Target/X86/X86JITInfo.cpp lib/Target/X86/X86JITInfo.h

Nicolas Geoffray nicolas.geoffray at lip6.fr
Sat Oct 25 08:41:44 PDT 2008


Author: geoffray
Date: Sat Oct 25 10:41:43 2008
New Revision: 58142

URL: http://llvm.org/viewvc/llvm-project?rev=58142&view=rev
Log:
Support for allocation of TLS variables in the JIT. Allocation of a global
variable is moved to the execution engine. The JIT calls the TargetJITInfo
to allocate thread local storage. Currently, only linux/x86 knows how to
allocate thread local global variables.


Modified:
    llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h
    llvm/trunk/include/llvm/Target/TargetJITInfo.h
    llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp
    llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp
    llvm/trunk/lib/ExecutionEngine/JIT/JIT.h
    llvm/trunk/lib/Target/X86/X86JITInfo.cpp
    llvm/trunk/lib/Target/X86/X86JITInfo.h

Modified: llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h?rev=58142&r1=58141&r2=58142&view=diff

==============================================================================
--- llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h (original)
+++ llvm/trunk/include/llvm/ExecutionEngine/ExecutionEngine.h Sat Oct 25 10:41:43 2008
@@ -76,6 +76,9 @@
   void setTargetData(const TargetData *td) {
     TD = td;
   }
+  
+  /// getMemoryforGV - Allocate memory for a global variable.
+  virtual char* getMemoryForGV(const GlobalVariable* GV);
 
   // To avoid having libexecutionengine depend on the JIT and interpreter
   // libraries, the JIT and Interpreter set these functions to ctor pointers

Modified: llvm/trunk/include/llvm/Target/TargetJITInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetJITInfo.h?rev=58142&r1=58141&r2=58142&view=diff

==============================================================================
--- llvm/trunk/include/llvm/Target/TargetJITInfo.h (original)
+++ llvm/trunk/include/llvm/Target/TargetJITInfo.h Sat Oct 25 10:41:43 2008
@@ -93,6 +93,14 @@
                           unsigned NumRelocs, unsigned char* GOTBase) {
       assert(NumRelocs == 0 && "This target does not have relocations!");
     }
+    
+
+    /// allocateThreadLocalMemory - Each target has its own way of
+    /// handling thread local variables. This method returns a value only
+    /// meaningful to the target.
+    virtual char* allocateThreadLocalMemory(size_t size) {
+      assert(0 && "This target does not implement thread local storage!");
+    }
 
     /// needsGOT - Allows a target to specify that it would like the
     // JIT to manage a GOT for it.

Modified: llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp?rev=58142&r1=58141&r2=58142&view=diff

==============================================================================
--- llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/ExecutionEngine.cpp Sat Oct 25 10:41:43 2008
@@ -52,6 +52,12 @@
     delete Modules[i];
 }
 
+char* ExecutionEngine::getMemoryForGV(const GlobalVariable* GV) {
+  const Type *ElTy = GV->getType()->getElementType();
+  size_t GVSize = (size_t)getTargetData()->getABITypeSize(ElTy);
+  return new char[GVSize];
+}
+
 /// removeModuleProvider - Remove a ModuleProvider from the list of modules.
 /// Release module from ModuleProvider.
 Module* ExecutionEngine::removeModuleProvider(ModuleProvider *P, 
@@ -873,7 +879,6 @@
 /// their initializers into the memory.
 ///
 void ExecutionEngine::emitGlobals() {
-  const TargetData *TD = getTargetData();
 
   // Loop over all of the global variables in the program, allocating the memory
   // to hold them.  If there is more than one module, do a prepass over globals
@@ -934,12 +939,7 @@
       }
       
       if (!I->isDeclaration()) {
-        // Get the type of the global.
-        const Type *Ty = I->getType()->getElementType();
-
-        // Allocate some memory for it!
-        unsigned Size = TD->getABITypeSize(Ty);
-        addGlobalMapping(I, new char[Size]);
+        addGlobalMapping(I, getMemoryForGV(I));
       } else {
         // External variable reference. Try to use the dynamic loader to
         // get a pointer to it.
@@ -991,15 +991,18 @@
   void *GA = getPointerToGlobalIfAvailable(GV);
   DOUT << "Global '" << GV->getName() << "' -> " << GA << "\n";
 
-  const Type *ElTy = GV->getType()->getElementType();
-  size_t GVSize = (size_t)getTargetData()->getABITypeSize(ElTy);
   if (GA == 0) {
     // If it's not already specified, allocate memory for the global.
-    GA = new char[GVSize];
+    GA = getMemoryForGV(GV);
     addGlobalMapping(GV, GA);
   }
-
-  InitializeMemory(GV->getInitializer(), GA);
+  
+  // Don't initialize if it's thread local, let the client do it.
+  if (!GV->isThreadLocal())
+    InitializeMemory(GV->getInitializer(), GA);
+  
+  const Type *ElTy = GV->getType()->getElementType();
+  size_t GVSize = (size_t)getTargetData()->getABITypeSize(ElTy);
   NumInitBytes += (unsigned)GVSize;
   ++NumGlobals;
 }

Modified: llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp?rev=58142&r1=58141&r2=58142&view=diff

==============================================================================
--- llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp (original)
+++ llvm/trunk/lib/ExecutionEngine/JIT/JIT.cpp Sat Oct 25 10:41:43 2008
@@ -562,7 +562,12 @@
     const Type *GlobalType = GV->getType()->getElementType();
     size_t S = getTargetData()->getABITypeSize(GlobalType);
     size_t A = getTargetData()->getPreferredAlignment(GV);
-    Ptr = MCE->allocateSpace(S, A);
+    if (GV->isThreadLocal()) {
+      MutexGuard locked(lock);
+      Ptr = TJI.allocateThreadLocalMemory(S);
+    } else {
+      Ptr = MCE->allocateSpace(S, A);
+    }
     addGlobalMapping(GV, Ptr);
     EmitGlobalVariable(GV);
   }
@@ -594,3 +599,17 @@
   return Addr;
 }
 
+/// getMemoryForGV - This method abstracts memory allocation of global
+/// variable so that the JIT can allocate thread local variables depending
+/// on the target.
+///
+char* JIT::getMemoryForGV(const GlobalVariable* GV) {
+  const Type *ElTy = GV->getType()->getElementType();
+  size_t GVSize = (size_t)getTargetData()->getABITypeSize(ElTy);
+  if (GV->isThreadLocal()) {
+    MutexGuard locked(lock);
+    return TJI.allocateThreadLocalMemory(GVSize);
+  } else {
+    return new char[GVSize];
+  }
+}

Modified: llvm/trunk/lib/ExecutionEngine/JIT/JIT.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/ExecutionEngine/JIT/JIT.h?rev=58142&r1=58141&r2=58142&view=diff

==============================================================================
--- llvm/trunk/lib/ExecutionEngine/JIT/JIT.h (original)
+++ llvm/trunk/lib/ExecutionEngine/JIT/JIT.h Sat Oct 25 10:41:43 2008
@@ -134,6 +134,12 @@
 private:
   static MachineCodeEmitter *createEmitter(JIT &J, JITMemoryManager *JMM);
   void runJITOnFunction (Function *F);
+  
+protected:
+
+  /// getMemoryforGV - Allocate memory for a global variable.
+  virtual char* getMemoryForGV(const GlobalVariable* GV);
+
 };
 
 } // End llvm namespace

Modified: llvm/trunk/lib/Target/X86/X86JITInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86JITInfo.cpp?rev=58142&r1=58141&r2=58142&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86JITInfo.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86JITInfo.cpp Sat Oct 25 10:41:43 2008
@@ -518,3 +518,13 @@
     }
   }
 }
+
+char* X86JITInfo::allocateThreadLocalMemory(size_t size) {
+#if defined(X86_32_JIT) && !defined(__APPLE__) && !defined(_MSC_VER)
+  TLSOffset -= size;
+  return TLSOffset;
+#else
+  assert(0 && "Cannot allocate thread local storage on this arch!\n");
+  return 0;
+#endif
+}

Modified: llvm/trunk/lib/Target/X86/X86JITInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86JITInfo.h?rev=58142&r1=58141&r2=58142&view=diff

==============================================================================
--- llvm/trunk/lib/Target/X86/X86JITInfo.h (original)
+++ llvm/trunk/lib/Target/X86/X86JITInfo.h Sat Oct 25 10:41:43 2008
@@ -23,8 +23,12 @@
   class X86JITInfo : public TargetJITInfo {
     X86TargetMachine &TM;
     intptr_t PICBase;
+    char* TLSOffset;
   public:
-    explicit X86JITInfo(X86TargetMachine &tm) : TM(tm) {useGOT = 0;}
+    explicit X86JITInfo(X86TargetMachine &tm) : TM(tm) {
+      useGOT = 0;
+      TLSOffset = 0;
+    }
 
     /// replaceMachineCodeForFunction - Make it so that calling the function
     /// whose machine code is at OLD turns into a call to NEW, perhaps by
@@ -56,6 +60,11 @@
     /// referenced global symbols.
     virtual void relocate(void *Function, MachineRelocation *MR,
                           unsigned NumRelocs, unsigned char* GOTBase);
+    
+    /// allocateThreadLocalMemory - Each target has its own way of
+    /// handling thread local variables. This method returns a value only
+    /// meaningful to the target.
+    virtual char* allocateThreadLocalMemory(size_t size);
 
     /// setPICBase / getPICBase - Getter / setter of PICBase, used to compute
     /// PIC jumptable entry.





More information about the llvm-commits mailing list