[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 );
};
}