First stage of Jitting the AST. The creation of positive floats and addition of posit...
Peter Senna Tschudin [Wed, 5 Jun 2013 12:55:43 +0000 (14:55 +0200)]
When on the console type: runVMKit

This will change to the JIT mode, you can try additions after that.

scilab/modules/ast/includes/JITvisitor.hxx [new file with mode: 0644]
scilab/modules/core/Makefile.am
scilab/modules/core/includes/jitter.hxx [new file with mode: 0644]
scilab/modules/core/src/cpp/jitter.cpp [new file with mode: 0644]
scilab/modules/core/src/cpp/tasks.cpp

diff --git a/scilab/modules/ast/includes/JITvisitor.hxx b/scilab/modules/ast/includes/JITvisitor.hxx
new file mode 100644 (file)
index 0000000..3ad171f
--- /dev/null
@@ -0,0 +1,408 @@
+/*
+ *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ *  Copyright (C) 2008-2008 - DIGITEO - Bruno JOFRET
+ *
+ *  This file must be used under the terms of the CeCILL.
+ *  This source file is licensed as described in the file COPYING, which
+ *  you should have received as part of this distribution.  The terms
+ *  are also available at
+ *  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
+ *
+ */
+
+#ifndef AST_JITVISITOR_HXX
+#define AST_JITVISITOR_HXX
+
+#include <time.h>
+#include <string>
+#include <iostream>
+#include <sstream>
+#include <cstdio>
+#include <iostream>
+
+#include "visitor_common.hxx"
+//#include "runvisitor.hxx"
+//#include "execvisitor.hxx"
+//#include "timedvisitor.hxx"
+#include "shortcutvisitor.hxx"
+#include "printvisitor.hxx"
+#include "mutevisitor.hxx"
+
+// Needed by visitprivate(const OpExp &)
+// Needed by visitprivate(const LogicalOpExp &)
+#include "generic_operations.hxx"
+#include "types_or_and.hxx"
+#include "configvariable.hxx"
+#include "overload.hxx"
+#include "scilabexception.hxx"
+
+//#include "matrix_transpose_int.hxx"
+
+extern "C" {
+#include "doublecomplex.h"
+#include "matrix_transpose.h"
+#include "os_swprintf.h"
+#include "more.h"
+#include "sciprint.h"
+    //#include "HandleManagement.h"
+}
+
+#include "timer.hxx"
+#include "localization.h"
+
+#include "scilabWrite.hxx"
+#include "context.hxx"
+
+#include "all.hxx"
+#include "types.hxx"
+#include "alltypes.hxx"
+
+#undef ID
+#undef LT
+
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/IRBuilder.h"
+#include "llvm/LLVMContext.h"
+#include "llvm/Module.h"
+#include "llvm/Analysis/Verifier.h"
+#include "llvm/Support/TargetSelect.h"
+#include "llvm/ExecutionEngine/ExecutionEngine.h"
+#include "llvm/ExecutionEngine/JIT.h"
+#include "llvm/PassManager.h"
+#include "llvm/DataLayout.h"
+#include "vmkit_core.h"
+
+namespace ast
+{
+       typedef double (*jitptr_t) ();
+
+       class JITVisitor : public ConstVisitor
+       {
+       private:
+               /*
+                * Attributes
+                */
+               llvm::Value* _result;
+               bool m_bSingleResult;
+               llvm::LLVMContext *context;
+               llvm::Module *TheModule;
+               llvm::IRBuilder<> *Builder;
+               llvm::ExecutionEngine* ee;
+               llvm::FunctionPassManager* pm;
+
+
+        void visit (const SeqExp  &e)
+        {
+            visitprivate(e);
+        }
+
+        void visit (const IntExp &e)
+        {
+            visitprivate(e);
+        }
+
+        void visit (const FloatExp &e)
+        {
+            visitprivate(e);
+        }
+
+        void visit (const DoubleExp &e)
+        {
+            visitprivate(e);
+        }
+
+        void visit (const OpExp &e)
+        {
+            visitprivate(e);
+        }
+
+        void visit (const SimpleVar &e)
+        {
+           visitprivate(e);
+        }
+
+
+       public:
+        JITVisitor() : ConstVisitor() {
+               llvm::InitializeNativeTarget();
+               context = &llvm::getGlobalContext();
+               Builder = new llvm::IRBuilder<> (*context);
+               _result = NULL;
+               m_bSingleResult = false;
+               TheModule = new llvm::Module("scilab jit", *context);
+
+               std::string err;
+               llvm::EngineBuilder engine (TheModule);
+               llvm::TargetOptions options;
+               options.NoFramePointerElim = true;
+               engine.setTargetOptions(options);
+               engine.setEngineKind(llvm::EngineKind::JIT);
+               engine.setErrorStr(&err);
+
+               ee = engine.create();
+               if (!ee) {
+                       fprintf(stderr, "Could not create ExecutionEngine: %s\n", err.c_str());
+                       exit(1);
+               }
+               ee->DisableLazyCompilation(0);
+               ee->addModule(TheModule);
+               TheModule->setDataLayout(ee->getDataLayout()->getStringRepresentation());
+               pm = NULL; /* TODO : init */
+        }
+
+        void result_set(llvm::Value* const gtVal)
+        {
+            m_bSingleResult = true;
+            _result = gtVal;
+        }
+
+        llvm::Value* result_get()
+        {
+               return  _result;
+        }
+
+        void visitprivate(const DoubleExp &e) {
+               if (e.getBigDouble() == NULL)
+               {
+                       Double *pdbl = new Double(e.value_get());
+                       (const_cast<DoubleExp *>(&e))->setBigDouble(pdbl);
+               }
+               llvm::Value* res = llvm::ConstantFP::get(llvm::getGlobalContext(), llvm::APFloat(e.getBigDouble()->get(0)));
+               result_set(res);
+               _result->dump();
+        }
+
+       void visitprivate(const FloatExp &e) {
+       }
+
+       void visitprivate(const IntExp &e) {
+       }
+
+       void visitprivate(const SeqExp &e) {
+            //T execMe;
+            std::list<Exp *>::const_iterator   itExp;
+
+            for (itExp = e.exps_get().begin (); itExp != e.exps_get().end (); ++itExp)
+            {
+               //reset default values
+               result_set(NULL);
+               llvm::FunctionType *FT = llvm::FunctionType::get(llvm::Type::getDoubleTy(*context), false);
+               llvm::Function *TheFunction = llvm::Function::Create(FT, llvm::Function::ExternalLinkage, "TheFunction", TheModule);
+               llvm::BasicBlock *BB = llvm::BasicBlock::Create(llvm::getGlobalContext(), "entry", TheFunction);
+               Builder->SetInsertPoint(BB);
+
+               (*itExp)->accept(*this);
+
+
+                if (result_get() != NULL)
+                {
+                       Builder->CreateRet(result_get());
+                       TheFunction->dump();
+                       void* res = ee->getPointerToFunction(TheFunction);
+                       jitptr_t myJit = (jitptr_t) res;
+                       double result = myJit();
+                       std::cout << "result : " << result << std::endl;
+                }
+            }
+       }
+
+       void visitprivate(const OpExp &e) {
+               /*getting what to assign*/
+               e.left_get().accept(*this);
+               llvm::Value *pITL = result_get();
+
+            /*getting what to assign*/
+            e.right_get().accept(*this);
+            llvm::Value *pITR = result_get();
+
+            llvm::Value *pResult = NULL;
+
+            switch (e.oper_get())
+            {
+               case OpExp::plus :
+               {
+//                     pResult = GenericPlus(pITL, pITR);
+                       //Sum
+                       pResult = Builder->CreateFAdd(pITL, pITR, "addtmp");
+                       break;
+               }
+               default:
+               {
+                       std::cout << "Operation not supported, returning 42..." << std::endl;
+                       break;
+               }
+            }
+
+            if(pResult == NULL) {
+               result_set(llvm::ConstantFP::get(llvm::getGlobalContext(), llvm::APFloat(42.0)));
+            }
+            result_set(pResult);
+       }
+
+       void visitprivate (const SimpleVar &e)
+       {
+             /* Not implemented. It only exits Scilab... */
+             std::cout << "VISIT SIMPLEVAR, EXITING NOW..." << std::endl;
+             ConfigVariable::setExitStatus(0);
+             ConfigVariable::setForceQuit(true);
+       }
+
+        void visit (const BoolExp &e)
+        {
+//            visitprivate(e);
+        }
+
+        void visit (const NilExp &e)
+        {
+//            visitprivate(e);
+        }
+
+        void visit (const ColonVar &e)
+        {
+//            visitprivate(e);
+        }
+
+        void visit (const DollarVar &e)
+        {
+//            visitprivate(e);
+        }
+
+        void visit (const ArrayListVar &e)
+        {
+//            visitprivate(e);
+        }
+
+        void visit (const FieldExp &e)
+        {
+//            visitprivate(e);
+        }
+
+
+        void visit (const LogicalOpExp &e)
+        {
+//            visitprivate(e);
+        }
+
+        void visit (const AssignExp &e)
+        {
+//            visitprivate(e);
+        }
+
+        void visit (const CellCallExp &e)
+        {
+//            visitprivate(e);
+        }
+
+        void visit (const CallExp &e)
+        {
+//            visitprivate(e);
+        }
+
+        void visit (const IfExp &e)
+        {
+//            visitprivate(e);
+        }
+
+        void visit (const TryCatchExp &e)
+        {
+//            visitprivate(e);
+        }
+
+        void visit (const WhileExp &e)
+        {
+//            visitprivate(e);
+        }
+
+        void visit (const ForExp &e)
+        {
+//            visitprivate(e);
+        }
+
+        void visit (const BreakExp &e)
+        {
+//            visitprivate(e);
+        }
+
+        void visit (const ContinueExp &e)
+        {
+//            visitprivate(e);
+        }
+
+        void visit (const ReturnExp &e)
+        {
+//            visitprivate(e);
+        }
+
+        void visit (const SelectExp &e)
+        {
+//            visitprivate(e);
+        }
+
+        void visit (const CaseExp &e)
+        {
+//            visitprivate(e);
+        }
+
+        void visit (const ArrayListExp &e)
+        {
+//            visitprivate(e);
+        }
+
+        void visit (const AssignListExp &e)
+        {
+//            visitprivate(e);
+        }
+
+        void visit (const NotExp &e)
+        {
+//            visitprivate(e);
+        }
+
+        void visit (const TransposeExp &e)
+        {
+//            visitprivate(e);
+        }
+
+        void visit (const VarDec &e)
+        {
+//            visitprivate(e);
+        }
+
+        void visit (const FunctionDec &e)
+        {
+//            visitprivate(e);
+        }
+
+        void visit(const ListExp &e)
+        {
+//            visitprivate(e);
+        }
+        void visit (const MatrixExp &e)
+        {
+//            visitprivate(e);
+        }
+
+        void visit (const MatrixLineExp &e)
+        {
+//            visitprivate(e);
+        }
+
+        void visit (const CellExp &e)
+        {
+//            visitprivate(e);
+        }
+
+        void visit (const StringExp &e)
+        {
+//            visitprivate(e);
+        }
+
+        void visit (const CommentExp &e)
+        {
+//            visitprivate(e);
+        }
+       };
+}
+#endif // !AST_JITVISITOR_HXX
+
index c563800..b08e18e 100644 (file)
@@ -88,7 +88,8 @@ src/cpp/backtrace_print.cpp \
 src/cpp/storeCommand.cpp \
 src/cpp/banner.cpp \
 src/cpp/with_module.cpp \
-src/cpp/runner.cpp
+src/cpp/runner.cpp \
+src/cpp/jitter.cpp
 
 if USE_DYNAMIC_STACK
 CORE_C_SOURCES += src/c/scimem64.c
@@ -275,7 +276,8 @@ libscicore_la_CPPFLAGS = \
 -I$(top_srcdir)/modules/functions/includes/ \
 $(EIGEN_CPPFLAGS) \
 $(XML_FLAGS) \
-$(AM_CPPFLAGS)
+$(AM_CPPFLAGS) \
+$(VMKIT_ACPPFLAGS)
 
 # Used by sci_getdebuginfo:
 if TCLTK
diff --git a/scilab/modules/core/includes/jitter.hxx b/scilab/modules/core/includes/jitter.hxx
new file mode 100644 (file)
index 0000000..a0c13d1
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ *  Copyright (C) 2010-2010 - DIGITEO - Bruno JOFRET
+ *
+ *  This file must be used under the terms of the CeCILL.
+ *  This source file is licensed as described in the file COPYING, which
+ *  you should have received as part of this distribution.  The terms
+ *  are also available at
+ *  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
+ *
+ */
+
+#ifndef __JITTER_HXX__
+#define __JITTER_HXX__
+
+#include <iostream>
+#include "exp.hxx"
+#include "execvisitor.hxx"
+#include "JITvisitor.hxx"
+
+extern "C"
+{
+#include "Thread_Wrapper.h"
+#include "dynlib_core_gw.h"
+}
+
+#include "threadId.hxx"
+
+class CORE_GW_IMPEXP Jitter
+{
+private :
+       Jitter(ast::Exp* _theProgram, ast::JITVisitor *_visitor)
+    {
+        m_theProgram = _theProgram;
+        m_visitor = _visitor;
+    }
+    ~Jitter()
+    {
+        delete m_theProgram;
+        delete m_visitor;
+    }
+
+public :
+
+    static void init();
+
+    static void execAndWait(ast::Exp* _theProgram, ast::JITVisitor *_visitor);
+
+    void exec(ast::Exp* _theProgram, ast::JITVisitor *_visitor);
+
+    ast::JITVisitor *getVisitor()
+    {
+        return m_visitor;
+    }
+
+    ast::Exp* getProgram()
+    {
+        return m_theProgram;
+    }
+
+    __threadId getThreadId(void)
+    {
+        return m_threadId;
+    }
+
+    void setThreadId(__threadId _threadId)
+    {
+        m_threadId = _threadId;
+    }
+
+    __threadKey getThreadKey(void)
+    {
+        return m_threadKey;
+    }
+
+    void setThreadKey(__threadKey _threadId)
+    {
+        m_threadKey = _threadId;
+    }
+
+    static void UnlockPrompt();
+
+    static void LockPrompt();
+
+private :
+    static void *launch(void *args);
+
+private :
+    __threadKey m_threadKey;
+    __threadId m_threadId;
+    ast::Exp*           m_theProgram;
+    ast::JITVisitor*   m_visitor;
+
+private :
+    static __threadSignal m_awakeScilab;
+    static __threadSignalLock m_awakeScilabLock;
+    static __threadLock m_lock;
+};
+#endif /* !__RUNNER_HXX__ */
diff --git a/scilab/modules/core/src/cpp/jitter.cpp b/scilab/modules/core/src/cpp/jitter.cpp
new file mode 100644 (file)
index 0000000..2df62ac
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
+ *  Copyright (C) 2011-2011 - DIGITEO - Bruno JOFRET
+ *
+ *  This file must be used under the terms of the CeCILL.
+ *  This source file is licensed as described in the file COPYING, which
+ *  you should have received as part of this distribution.  The terms
+ *  are also available at
+ *  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
+ *
+ */
+
+#include "jitter.hxx"
+
+__threadLock Jitter::m_lock;
+__threadSignal Jitter::m_awakeScilab;
+__threadSignalLock Jitter::m_awakeScilabLock;
+
+void Jitter::init()
+{
+    __InitSignal(&m_awakeScilab);
+    __InitSignalLock(&m_awakeScilabLock);
+}
+
+void *Jitter::launch(void *args)
+{
+    bool bdoUnlock = false;
+    //try to lock locker ( waiting parent thread register me )
+    __Lock(&m_lock);
+    //just release locker
+    __UnLock(&m_lock);
+
+    //exec !
+    Jitter *me = (Jitter *)args;
+    try
+    {
+        me->getProgram()->accept(*(me->getVisitor()));
+        ConfigVariable::clearLastError();
+    }
+    catch(ScilabException se)
+    {
+        scilabErrorW(se.GetErrorMessage().c_str());
+    }
+
+    __threadKey currentThreadKey = __GetCurrentThreadKey();
+
+    //change thread status
+    ThreadId* pThread = ConfigVariable::getThread(currentThreadKey);
+    if(pThread->getStatus() != ThreadId::Aborted)
+    {
+        pThread->setStatus(ThreadId::Done);
+        bdoUnlock = true;
+    }
+
+    //unregister thread
+    ConfigVariable::deleteThread(currentThreadKey);
+
+    delete me;
+
+    if(bdoUnlock)
+    {
+        UnlockPrompt();
+    }
+    return NULL;
+}
+
+void Jitter::LockPrompt()
+{
+    __LockSignal(&m_awakeScilabLock);
+    //free locker to release thread
+    __UnLock(&m_lock);
+    __Wait(&m_awakeScilab, &m_awakeScilabLock);
+    __UnLockSignal(&m_awakeScilabLock);
+}
+
+void Jitter::UnlockPrompt()
+{
+    __LockSignal(&m_awakeScilabLock);
+    __Signal(&m_awakeScilab);
+    __UnLockSignal(&m_awakeScilabLock);
+}
+
+
+void Jitter::execAndWait(ast::Exp* _theProgram, ast::JITVisitor *_visitor)
+{
+    try
+    {
+        Jitter *runMe = new Jitter(_theProgram, _visitor);
+        __threadKey threadKey;
+        __threadId threadId;
+
+        //init locker
+        __InitLock(&m_lock);
+        //lock locker
+        __Lock(&m_lock);
+        //launch thread but is can't really start since locker is locked
+        __CreateThreadWithParams(&threadId, &threadKey, &Jitter::launch, runMe);
+        runMe->setThreadId(threadId);
+        runMe->setThreadKey(threadKey);
+
+        //register thread
+        ConfigVariable::addThread(new ThreadId(threadId, threadKey));
+        //free locker to release thread && wait and of thread execution
+        LockPrompt();
+
+        types::ThreadId* pExecThread = ConfigVariable::getThread(threadKey);
+        if(pExecThread == NULL)
+        {//call pthread_join to clean stack allocation
+            __WaitThreadDie(threadId);
+        }
+    }
+    catch(ScilabException se)
+    {
+        throw se;
+    }
+}
+
+void Jitter::exec(ast::Exp* _theProgram, ast::JITVisitor *_visitor)
+{
+    m_theProgram = _theProgram;
+    m_visitor = _visitor;
+    __CreateThreadWithParams(&m_threadId, &m_threadKey, &Jitter::launch, this);
+}
index 7a7af5c..a2d59cb 100644 (file)
 #include "visitor.hxx"
 #include "printvisitor.hxx"
 #include "execvisitor.hxx"
+#include "JITvisitor.hxx"
 #include "timedvisitor.hxx"
 #include "debugvisitor.hxx"
 #include "stepvisitor.hxx"
 #include "configvariable.hxx"
 
+#if defined(VMKIT_ENABLED)
+
+//Needed as both llvm and scilab has #define ...
+#undef ID
+#undef LT
+
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/IRBuilder.h"
+#include "llvm/LLVMContext.h"
+#include "llvm/Module.h"
+#include "llvm/Analysis/Verifier.h"
+#include <cstdio>
+#include <string>
+#include <map>
+#include <vector>
+#endif
+
 #include "scilabWrite.hxx"
 #include "runner.hxx"
+#include "jitter.hxx"
 
 #define SCILAB_START    L"/etc/scilab.start"
 #define SCILAB_QUIT     L"/etc/scilab.quit"
@@ -164,9 +184,12 @@ void execAstTask(ast::Exp* tree, bool timed, bool ASTtimed, bool execVerbose, bo
         exec = new ast::ExecVisitor();
     }
 
-    if (ASTrunVMKit) {
-        printf("VMKit implementation goes here\n");
-        exit(1);
+    if(ASTrunVMKit)
+    {
+        ast::JITVisitor *jitExec;
+
+       jitExec = new ast::JITVisitor();
+       Jitter::execAndWait(tree, jitExec);
     } else {
         Runner::execAndWait(tree, exec);
         //delete exec;