[opengtl-commits] [445] implement a smarter linker

[ Thread Index | Date Index | More lists.tuxfamily.org/opengtl-commits Archives ]


Revision: 445
Author:   cyrille
Date:     2008-10-11 13:39:29 +0200 (Sat, 11 Oct 2008)

Log Message:
-----------
implement a smarter linker

Modified Paths:
--------------
    trunk/OpenGTL/OpenCTL/OpenCTL/Module.cpp
    trunk/OpenGTL/OpenCTL/OpenCTL/compiler/Compiler.cpp
    trunk/OpenGTL/OpenGTL/GTLCore/AST/FunctionDeclaration.cpp
    trunk/OpenGTL/OpenGTL/GTLCore/CompilerBase_p.cpp
    trunk/OpenGTL/OpenGTL/GTLCore/Function_p.cpp
    trunk/OpenGTL/OpenGTL/GTLCore/Function_p.h
    trunk/OpenGTL/OpenGTL/GTLCore/ModuleData_p.cpp
    trunk/OpenGTL/OpenGTL/GTLCore/ModuleData_p.h
    trunk/OpenGTL/OpenShiva/OpenShiva/Wrapper_p.cpp
    trunk/OpenGTL/OpenShiva/OpenShiva/Wrapper_p.h


Modified: trunk/OpenGTL/OpenCTL/OpenCTL/Module.cpp
===================================================================
--- trunk/OpenGTL/OpenCTL/OpenCTL/Module.cpp	2008-10-10 07:17:28 UTC (rev 444)
+++ trunk/OpenGTL/OpenCTL/OpenCTL/Module.cpp	2008-10-11 11:39:29 UTC (rev 445)
@@ -127,6 +127,7 @@
     d->compiled = true;
     d->moduleProvider = new llvm::ExistingModuleProvider( d->moduleData->llvmModule() );
     GTLCore::VirtualMachine::instance()->registerModule( d->moduleProvider );
+    d->moduleData->doLink();
   } else {
     delete d->moduleData;
     d->moduleData = 0;

Modified: trunk/OpenGTL/OpenCTL/OpenCTL/compiler/Compiler.cpp
===================================================================
--- trunk/OpenGTL/OpenCTL/OpenCTL/compiler/Compiler.cpp	2008-10-10 07:17:28 UTC (rev 444)
+++ trunk/OpenGTL/OpenCTL/OpenCTL/compiler/Compiler.cpp	2008-10-11 11:39:29 UTC (rev 445)
@@ -28,10 +28,10 @@
 
 // LLVM
 #include <llvm/InstrTypes.h>
-#include <llvm/Linker.h>
+// #include <llvm/Linker.h>
 #include <llvm/DerivedTypes.h>
 #include <llvm/Module.h>
-#include <llvm/Transforms/Utils/Cloning.h>
+// #include <llvm/Transforms/Utils/Cloning.h>
 // Library Loader
 #include <llvm/System/DynamicLibrary.h>
 // Passes
@@ -221,6 +221,16 @@
         return false;
       }
     }
+    d->moduleData->linkWith( m->data()->llvmModule() );
+    // Append the function coming from the imported module
+    std::list<GTLCore::Function*> functions = m->functions();
+    foreach( GTLCore::Function* function, functions )
+    {
+      GTLCore::Function* newFunction = GTLCore::Function::Private::createExternalFunction( d->moduleData, function );
+      declareFunction( newFunction->name(), newFunction );
+      functionsToDelete().push_back( newFunction );
+    }
+#if 0
     // Link a copy of the module
     llvm::Module* clone = llvm::CloneModule( m->data()->llvmModule() );
     llvm::Linker linker("", d->module);
@@ -261,6 +271,7 @@
       declareFunction( (*it)->name(), function );
       functionsToDelete().push_back( function );
     }
+#endif
   }
   return m;
 }

Modified: trunk/OpenGTL/OpenGTL/GTLCore/AST/FunctionDeclaration.cpp
===================================================================
--- trunk/OpenGTL/OpenGTL/GTLCore/AST/FunctionDeclaration.cpp	2008-10-10 07:17:28 UTC (rev 444)
+++ trunk/OpenGTL/OpenGTL/GTLCore/AST/FunctionDeclaration.cpp	2008-10-11 11:39:29 UTC (rev 445)
@@ -86,7 +86,7 @@
 void FunctionDeclaration::generate( ModuleData* _module, GTLCore::CodeGenerator* _codeGenerator)
 {
   GTL_DEBUG("Generate function " << m_function->name() );
-  m_functionData->setModule( _module->llvmModule() );
+  m_functionData->setModule( _module );
   // Create the list of parameters as in llvm
   std::vector<const llvm::Type*> params;
   for(std::vector< Parameter >::const_iterator it = m_function->parameters().begin();

Modified: trunk/OpenGTL/OpenGTL/GTLCore/CompilerBase_p.cpp
===================================================================
--- trunk/OpenGTL/OpenGTL/GTLCore/CompilerBase_p.cpp	2008-10-10 07:17:28 UTC (rev 444)
+++ trunk/OpenGTL/OpenGTL/GTLCore/CompilerBase_p.cpp	2008-10-11 11:39:29 UTC (rev 445)
@@ -41,7 +41,7 @@
   std::map< GTLCore::ScopedName, GTLCore::Function* > functions;
   std::list<GTLCore::Function*> functionsToDelete;
   ConvertCenter* convertCenter;
-  llvm::Module* module;
+  ModuleData* moduleData;
 };
 
 CompilerBase::CompilerBase() : d(new Private)
@@ -141,7 +141,7 @@
     arguments.push_back(GTLCore::Parameter("", type, false, false, GTLCore::Value() ) );
   }
   va_end(argp);
-  GTLCore::Function* function = GTLCore::Function::Private::createExternalFunction( d->module, _name, _symbolName, retType, arguments );
+  GTLCore::Function* function = GTLCore::Function::Private::createExternalFunction( d->moduleData, _name, _symbolName, retType, arguments );
   bool success = declareFunction(GTLCore::ScopedName("", _name), function);
   GTL_ASSERT( success );
   UNUSED( success );
@@ -150,5 +150,5 @@
 
 void CompilerBase::setModuleData( ModuleData* moduleData )
 {
-  d->module = moduleData->llvmModule();
+  d->moduleData = moduleData;
 }

Modified: trunk/OpenGTL/OpenGTL/GTLCore/Function_p.cpp
===================================================================
--- trunk/OpenGTL/OpenGTL/GTLCore/Function_p.cpp	2008-10-10 07:17:28 UTC (rev 444)
+++ trunk/OpenGTL/OpenGTL/GTLCore/Function_p.cpp	2008-10-11 11:39:29 UTC (rev 445)
@@ -28,6 +28,7 @@
 #include "Parameter.h"
 
 #include "Debug.h"
+#include "ModuleData_p.h"
 #include "ScopedName.h"
 #include "Value.h"
 #include "Type.h"
@@ -55,7 +56,7 @@
   }
 #endif
 }
-void Function::Data::setModule( llvm::Module* _module )
+void Function::Data::setModule( ModuleData* _module )
 {
   m_module = _module;
 }
@@ -76,8 +77,27 @@
   return _functionName.nameSpace() + "_" + _functionName.name() + GTLCore::String::number( (int)_parameters.size() );
 }
 
-GTLCore::Function* Function::Private::createExternalFunction(llvm::Module* _module, const GTLCore::String& _name, const GTLCore::String& _symbolName, const GTLCore::Type* retType, int _count, ...)
+Function* Function::Private::createExternalFunction(ModuleData* _module, const Function* _functionToCopy )
 {
+  int min = _functionToCopy->d->data->minimumParameters();
+  int max = _functionToCopy->d->data->maximumParameters();
+  std::vector<llvm::Function*> functions(max + 1);
+  for(int i = min; i <= max; ++i)
+  {
+    GTLCore::String _symbolName = GTLCore::Function::Data::symbolName( _functionToCopy->name(), _functionToCopy->parameters() ); // FIXME I have a doubt that it works for functions with default argument
+    const llvm::Function* func = _functionToCopy->d->data->function( i );
+    const llvm::FunctionType *FTy =
+    llvm::cast<llvm::FunctionType>(llvm::cast<llvm::PointerType>(func->getType())->getElementType());
+    functions[i] = dynamic_cast<llvm::Function*>( _module->llvmModule()->getOrInsertFunction( _symbolName, FTy) );
+  }
+  GTLCore::Function::Data* data = new GTLCore::Function::Data( _functionToCopy->parameters(), min );
+  data->setFunctions( functions );
+  data->setModule( _module );
+  return new GTLCore::Function( _functionToCopy->name(), _functionToCopy->returnType(), data);
+}
+
+GTLCore::Function* Function::Private::createExternalFunction(ModuleData* _module, const GTLCore::String& _name, const GTLCore::String& _symbolName, const GTLCore::Type* retType, int _count, ...)
+{
   std::vector<GTLCore::Parameter> arguments;
   va_list argp;
   va_start(argp, _count);
@@ -90,7 +110,7 @@
   return createExternalFunction(_module, _name, _symbolName, retType, arguments );
 }
 
-GTLCore::Function* Function::Private::createExternalFunction(llvm::Module* _module, const GTLCore::String& _name, const GTLCore::String& _symbolName, const GTLCore::Type* retType, const std::vector<GTLCore::Parameter>& arguments)
+GTLCore::Function* Function::Private::createExternalFunction(ModuleData* _module, const GTLCore::String& _name, const GTLCore::String& _symbolName, const GTLCore::Type* retType, const std::vector<GTLCore::Parameter>& arguments)
 {
   std::vector<const llvm::Type*> llvmArguments;
   for(unsigned int i = 0; i < arguments.size(); ++i)
@@ -98,14 +118,14 @@
     llvmArguments.push_back( Type::Private::d( arguments[i].type() )->asArgumentType() );
   }
   std::vector<llvm::Function*> functions(arguments.size() + 1);
-  functions[arguments.size() ] = dynamic_cast<llvm::Function*>( _module->getOrInsertFunction( _symbolName, llvm::FunctionType::get( Type::Private::d( retType )->type(), llvmArguments, false ) ) );
+  functions[arguments.size() ] = dynamic_cast<llvm::Function*>( _module->llvmModule()->getOrInsertFunction( _symbolName, llvm::FunctionType::get( Type::Private::d( retType )->type(), llvmArguments, false ) ) );
   GTLCore::Function::Data* data = new GTLCore::Function::Data(arguments, arguments.size() );
   data->setFunctions( functions );
   data->setModule( _module );
   return new GTLCore::Function( GTLCore::ScopedName("", _name), retType, data );
 }
 
-GTLCore::Function* Function::Private::createInternalFunction(llvm::Module* _module, const GTLCore::String& _name, llvm::Function* _function, const GTLCore::Type* retType, int _count, ...)
+GTLCore::Function* Function::Private::createInternalFunction(ModuleData* _module, const GTLCore::String& _name, llvm::Function* _function, const GTLCore::Type* retType, int _count, ...)
 {
   GTL_ASSERT( _function );
   std::vector<GTLCore::Parameter> arguments;

Modified: trunk/OpenGTL/OpenGTL/GTLCore/Function_p.h
===================================================================
--- trunk/OpenGTL/OpenGTL/GTLCore/Function_p.h	2008-10-10 07:17:28 UTC (rev 444)
+++ trunk/OpenGTL/OpenGTL/GTLCore/Function_p.h	2008-10-11 11:39:29 UTC (rev 445)
@@ -32,6 +32,7 @@
 
 namespace GTLCore {
   class FunctionCaller;
+  class ModuleData;
   /**
    * @internal
    * This class is not part of the public API of OpenCTL.
@@ -39,13 +40,14 @@
    */
   struct Function::Private
   {
-    GTLCore::ScopedName name;
-    const GTLCore::Type* returnType;
+    ScopedName name;
+    const Type* returnType;
     Function::Data* data;
     std::vector<FunctionCaller*> functionsCaller;
-    static GTLCore::Function* createExternalFunction(llvm::Module* _module, const GTLCore::String& _name, const GTLCore::String& _symbolName, const GTLCore::Type* retType, const std::vector<GTLCore::Parameter>& arguments);
-    static GTLCore::Function* createExternalFunction(llvm::Module* _module, const GTLCore::String& _name, const GTLCore::String& _symbolName, const GTLCore::Type* retType, int _count, ...);
-    static GTLCore::Function* createInternalFunction(llvm::Module* _module, const GTLCore::String& _name, llvm::Function* _function, const GTLCore::Type* retType, int _count, ...);
+    static Function* createExternalFunction(ModuleData* _module, const Function* _functionToCopy );
+    static Function* createExternalFunction(ModuleData* _module, const String& _name, const String& _symbolName, const Type* retType, const std::vector<Parameter>& arguments);
+    static Function* createExternalFunction(ModuleData* _module, const String& _name, const String& _symbolName, const Type* retType, int _count, ...);
+    static Function* createInternalFunction(ModuleData* _module, const String& _name, llvm::Function* _function, const Type* retType, int _count, ...);
   };
   /**
    * @internal
@@ -59,7 +61,7 @@
     public:
       Data( const std::vector< Parameter >& _parameters, int minimumParameters);
       void setFunctions( const std::vector<llvm::Function*>& _functions );
-      void setModule( llvm::Module* module );
+      void setModule( ModuleData* module );
       /**
        * @param count the number of parameters
        * @return the llvm function corresponding to the number of parameters, or 0 if no
@@ -72,18 +74,18 @@
        *         function exist for the given number of parameters
        */
       llvm::Function* function(unsigned int count) const;
-      llvm::Module* module() { return m_module; }
+      ModuleData* module() { return m_module; }
       unsigned int minimumParameters() const { return m_minimumParameters; }
       unsigned int maximumParameters() const { return m_maximumParameters; }
       const std::vector< Parameter >& parameters() { return m_parameters; }
       /**
        * @return the symbol name for the function with the given scoped name and parameters
        */
-      static GTLCore::String symbolName( const ScopedName& _functionName, const std::vector< Parameter >& _parameters );
+      static String symbolName( const ScopedName& _functionName, const std::vector< Parameter >& _parameters );
     private:
       std::vector< Parameter > m_parameters;
       std::vector<llvm::Function*> m_functions;
-      llvm::Module* m_module;
+      ModuleData* m_module;
       unsigned int m_minimumParameters;
       unsigned int m_maximumParameters;
   };

Modified: trunk/OpenGTL/OpenGTL/GTLCore/ModuleData_p.cpp
===================================================================
--- trunk/OpenGTL/OpenGTL/GTLCore/ModuleData_p.cpp	2008-10-10 07:17:28 UTC (rev 444)
+++ trunk/OpenGTL/OpenGTL/GTLCore/ModuleData_p.cpp	2008-10-11 11:39:29 UTC (rev 445)
@@ -32,10 +32,12 @@
 #include <llvm/Target/TargetMachine.h>
 #include <llvm/Target/TargetMachineRegistry.h>
 #include <llvm/Analysis/Verifier.h>
+#include <llvm/Transforms/Utils/Cloning.h>
+#include <llvm/Linker.h>
 
 using namespace GTLCore;
 
-ModuleData::ModuleData( llvm::Module* llvmModule) : m_llvmModule(llvmModule), m_typeManager(new TypeManager)
+ModuleData::ModuleData( llvm::Module* llvmModule) : m_llvmModule(llvmModule), m_llvmLinkedModule(0), m_typeManager(new TypeManager)
 {
   
 }
@@ -131,3 +133,29 @@
   
   return os.str();
 }
+
+void ModuleData::linkWith( const llvm::Module* _module )
+{
+  foreach( const llvm::Module* mod, m_linkModuleWith )
+  {
+    if( mod == _module ) return;
+  }
+  m_linkModuleWith.push_back( _module );
+}
+
+void ModuleData::doLink()
+{
+  GTL_ASSERT( not m_llvmLinkedModule );
+  m_llvmLinkedModule = m_llvmModule;
+  m_llvmModule = llvm::CloneModule( m_llvmModule );
+  llvm::Linker linker("", m_llvmLinkedModule);
+  GTLCore::String errorMessage;
+  foreach( const llvm::Module* mod, m_linkModuleWith )
+  {
+    llvm::Module* clone = llvm::CloneModule( mod );
+    linker.LinkInModule( clone, &errorMessage );
+    GTL_DEBUG("Linking error: " << errorMessage );
+    delete clone;
+  }
+  linker.releaseModule();
+}

Modified: trunk/OpenGTL/OpenGTL/GTLCore/ModuleData_p.h
===================================================================
--- trunk/OpenGTL/OpenGTL/GTLCore/ModuleData_p.h	2008-10-10 07:17:28 UTC (rev 444)
+++ trunk/OpenGTL/OpenGTL/GTLCore/ModuleData_p.h	2008-10-11 11:39:29 UTC (rev 445)
@@ -50,8 +50,12 @@
       {
         m_constants[_scopedName] = _constant;
       }
+      void linkWith( const llvm::Module* _module );
+      void doLink();
       llvm::Module* llvmModule() { return m_llvmModule; }
       const llvm::Module* llvmModule() const { return m_llvmModule; }
+      llvm::Module* llvmLinkedModule() { return m_llvmLinkedModule; }
+      const llvm::Module* llvmLinkedModule() const { return m_llvmLinkedModule; }
       TypeManager* typeManager() { return m_typeManager; }
       const TypeManager* typeManager() const { return m_typeManager; }
       /**
@@ -60,9 +64,11 @@
       GTLCore::String asCCode() const;
     private:
       llvm::Module* m_llvmModule;
+      llvm::Module* m_llvmLinkedModule;
       std::map<ScopedName, Function*> m_functions;
       TypeManager* m_typeManager;
       std::map< ScopedName, llvm::Constant* > m_constants;
+      std::list< const llvm::Module* > m_linkModuleWith;
   };
 }
 

Modified: trunk/OpenGTL/OpenShiva/OpenShiva/Wrapper_p.cpp
===================================================================
--- trunk/OpenGTL/OpenShiva/OpenShiva/Wrapper_p.cpp	2008-10-10 07:17:28 UTC (rev 444)
+++ trunk/OpenGTL/OpenShiva/OpenShiva/Wrapper_p.cpp	2008-10-11 11:39:29 UTC (rev 445)
@@ -108,15 +108,15 @@
   for( int i = 1; i <= 5; ++i)
   {
     // Create Image type
-    const GTLCore::Type* pixelType = createPixelType( _module->llvmModule(), _typeManager, _convertCenter, GTLCore::String::number( i ), i );
+    const GTLCore::Type* pixelType = createPixelType( _module, _typeManager, _convertCenter, GTLCore::String::number( i ), i );
     createImageType( _module, _typeManager, GTLCore::String::number( i ), i, pixelType );
   }
-  const GTLCore::Type* pixelType = createPixelType( _module->llvmModule(), _typeManager, _convertCenter, "", _channels );
+  const GTLCore::Type* pixelType = createPixelType( _module, _typeManager, _convertCenter, "", _channels );
   createImageType( _module, _typeManager, "", _channels, pixelType );
-  createRegionType( _module->llvmModule(), _typeManager );
+  createRegionType( _module, _typeManager );
 }
 
-const GTLCore::Type* Wrapper::createPixelType( llvm::Module* _module, GTLCore::TypeManager* _typeManager, GTLCore::ConvertCenter* _convertCenter, const GTLCore::String& _suffix, int _channels )
+const GTLCore::Type* Wrapper::createPixelType( GTLCore::ModuleData* _module, GTLCore::TypeManager* _typeManager, GTLCore::ConvertCenter* _convertCenter, const GTLCore::String& _suffix, int _channels )
 {
   //---------------------- WARNING ----------------------//
   // Whenever the following structure is edited,         //
@@ -138,7 +138,7 @@
   return type;
 }
 
-void Wrapper::createRegionType( llvm::Module* _module, GTLCore::TypeManager* _typeManager )
+void Wrapper::createRegionType( GTLCore::ModuleData* _module, GTLCore::TypeManager* _typeManager )
 {
   //---------------------- WARNING ----------------------//
   // Whenever the following structure is edited,         //
@@ -241,7 +241,7 @@
   
   type->d->addFunctionMember( GTLCore::Type::StructFunctionMember(
           GTLCore::Function::Private::createInternalFunction(
-                _moduleData->llvmModule(), "sampleNearest",
+                _moduleData, "sampleNearest",
                 CodeGenerator::generateImageSampleNearest( _moduleData, type, _pixelType ),
                 _pixelType, 2,
                 type, _moduleData->typeManager()->getVector( GTLCore::Type::Float, 2 ) ) ) );

Modified: trunk/OpenGTL/OpenShiva/OpenShiva/Wrapper_p.h
===================================================================
--- trunk/OpenGTL/OpenShiva/OpenShiva/Wrapper_p.h	2008-10-10 07:17:28 UTC (rev 444)
+++ trunk/OpenGTL/OpenShiva/OpenShiva/Wrapper_p.h	2008-10-11 11:39:29 UTC (rev 445)
@@ -65,8 +65,8 @@
        */
       static const GTLCore::Type* vectorType( GTLCore::TypeManager* _typeManager, int _channels );
     private:
-      static void createRegionType( llvm::Module* _module, GTLCore::TypeManager* _typeManager );
-      static const GTLCore::Type* createPixelType( llvm::Module* _module, GTLCore::TypeManager* _typeManager, GTLCore::ConvertCenter* _convertCenter, const GTLCore::String& _suffix, int _channels );
+      static void createRegionType( GTLCore::ModuleData* _module, GTLCore::TypeManager* _typeManager );
+      static const GTLCore::Type* createPixelType( GTLCore::ModuleData* _module, GTLCore::TypeManager* _typeManager, GTLCore::ConvertCenter* _convertCenter, const GTLCore::String& _suffix, int _channels );
       static void createImageType( GTLCore::ModuleData* _moduleData, GTLCore::TypeManager* _typeManager, const GTLCore::String& _suffix, int _channels, const GTLCore::Type* _pixelType );
   };
 }


Mail converted by MHonArc 2.6.19+ http://listengine.tuxfamily.org/